<commit_before>var react = require('react')
  , utils = require('./utils')
  , observables = require('./observables.js')
  , coordinator = require('./coordinator.js')
  , pelletReactMixin = require('./pellet-react-mixin.js');

/**
 * @class pellet
 *
 */
function pellet() {
  this.readyFnQue = [];
  this.initFnQue = [];
  this.coordinators = {};
  this.coordinatorSpecs = {};
  this.components = {};
  this.locales = {};

  this.middlewareStack = [];
}

/**
 *
 * @type {observables}
 */
pellet.prototype.observables = observables;

/**
 *
 * @type {exports}
 */
pellet.prototype.createClass = function(spec) {
  if(!spec.mixins) {
    spec.mixins = [];
  }

  if(!(pelletReactMixin in spec.mixins)) {
    spec.mixins.push(pelletReactMixin);
  }

  if(spec.onRoute) {
    var _onRoute = spec.onRoute;
    delete spec.onRoute;
  }

  if(typeof spec.routes !== 'undefined') {
    var i, allRoutes;

    if(typeof spec.routes === 'string') {
      allRoutes = [spec.routes];
    } else if(spec.routes instanceof Array) {
      allRoutes = spec.routes;
    }

    delete spec.routes;
  }

  var reactClass = react.createClass(spec);
  if(allRoutes) {
    for(i in allRoutes) {
      this.addComponentRoute(allRoutes[i], reactClass, {});
    }
  }
  if(_onRoute) {
    reactClass.__$onRoute = _onRoute;
  }

  return reactClass;
};

pellet.prototype.setLocaleLookupFn = function(lookupFn) {
  this.suggestLocales = lookupFn;
};

pellet.prototype.loadTranslation = function(locale, fn) {
  this.locales[locale] = fn;
};

pellet.prototype.loadManifestComponents = function(manifest) {
  var last, id, key, keys;

  if(!manifest || typeof(manifest) !== 'object') {
    return;
  }

  keys = Object.keys(manifest);

  keys.sort().reverse();
  for(var i in keys) {
    key = keys[i];
    id = key.substring(0, key.indexOf('@'));
    if(id) {
      if(last !== id) {
        if(this.components[id]) {
          console.warn('duplicate manifest component loaded:', id)
        }

        this.components[id] = manifest[key];
        last = id;
      }

      this.components[key] = manifest[key];
    }
  }
};

/**
 *
 * @param key
 * @param isGlobal
 * @param options
 * @returns {*}
 */
pellet.prototype.getCoordinator = function(name, type) {
  var instance;

  if(!name) {
    throw new Error('name is required');
  }

  if(instance = this.coordinators[name]) {
    return instance;
  }

  type = type || name;

  if(!this.coordinatorSpecs[type]) {
    throw new Error('Cannot find ' + type + ' coordinator spec');
  }

  var instance = new coordinator();
  utils.mixInto(instance, this.coordinatorSpecs[type], false, ['initialize', 'load']);
  instance.initialize();

  this.coordinators[name] = instance;

  return instance;
};

/**
 * register the coordinator spec that creates the new coordinator
 * of type name.
 *
 * @param name
 * @param fn
 */
pellet.prototype.registerCoordinator = function(name, spec) {
  if(!spec || !name) {
    throw new Error('Spec and name are required for all coordinators.');
  }

  if(this.coordinatorSpecs[name]) {
    console.error('Error duplicate store specs:', name);
    throw new Error('Cannot have duplicate store specs');
  }

  this.coordinatorSpecs[name] = spec;
};

/**
 * register a function to be called once pellet is ready
 * @param fn
 */
pellet.prototype.onReady = function(fn) {
  // if all ready running fire immediately with the last know err (or null if no errors)
  if(typeof(this.readyError) != 'undefined') {
    setTimeout(function() {
      fn(module.exports.readyError);
    }, 1);

    return;
  }

  this.readyFnQue.push(fn);
};

/**
 * register a function needed to complete before pellet is ready
 * @param fn
 */
pellet.prototype.registerInitFn = function(fn) {
  this.initFnQue.push(fn);
};

/**
 * Called after everyone has register their load functions
 */
pellet.prototype.startInit = function(config) {
  if(typeof(this.readyError) != 'undefined') {
    throw new Error('Cannot reinit because pellet is all ready running.');
  }

  this.config = config;

  var cbCount = this.initFnQue.length;
  function done(err) {
    if(err) {
      // console log the error and safe the most recent error
      console.error('Error init pellet because:', err.message);
      module.exports.readyError = err;
    }

    if(--cbCount <= 0) {
      // if all callback had no error set to null
      if(!module.exports.readyError) {
        module.exports.readyError = null;
      }

      var fn;
      while(fn = module.exports.readyFnQue.pop()) {
        fn(module.exports.readyError);
      }
    }
  }

  if(cbCount === 0) {
    done(null);
    return;
  }

  // now call all init fn and wait until all done
  for(i in this.initFnQue) {
    this.initFnQue[i](done);
  }
};

/**
 *
 * @param renderOptions
 * @param component
 * @param options
 * @returns {locals|*|js.locals|module.locals|app.locals|string}
 */
pellet.prototype.suggestLocales = function(renderOptions, component, options) {
  // todo: if server read (Accept-Language) and push it onto array after en
  // todo: if broswer we can use navigator.language etc.
  // final this can be overwrite by a cookie or by url/host

  return module.exports.config.locales || 'en';
}

if(process.env.SERVER_ENV) {
  module.exports = global.__pellet__ref = new pellet();
}
else if(process.env.BROWSER_ENV) {
  module.exports = window.__pellet__ref = new pellet();
}
<commit_msg>feat: as a dev I want to pass options to my registered coordinators<commit_after>var react = require('react')
  , utils = require('./utils')
  , observables = require('./observables.js')
  , coordinator = require('./coordinator.js')
  , pelletReactMixin = require('./pellet-react-mixin.js');

/**
 * @class pellet
 *
 */
function pellet() {
  this.readyFnQue = [];
  this.initFnQue = [];
  this.coordinators = {};
  this.coordinatorSpecs = {};
  this.components = {};
  this.locales = {};

  this.middlewareStack = [];
}

/**
 *
 * @type {observables}
 */
pellet.prototype.observables = observables;

/**
 *
 * @type {exports}
 */
pellet.prototype.createClass = function(spec) {
  if(!spec.mixins) {
    spec.mixins = [];
  }

  if(!(pelletReactMixin in spec.mixins)) {
    spec.mixins.push(pelletReactMixin);
  }

  if(spec.onRoute) {
    var _onRoute = spec.onRoute;
    delete spec.onRoute;
  }

  if(typeof spec.routes !== 'undefined') {
    var i, allRoutes;

    if(typeof spec.routes === 'string') {
      allRoutes = [spec.routes];
    } else if(spec.routes instanceof Array) {
      allRoutes = spec.routes;
    }

    delete spec.routes;
  }

  var reactClass = react.createClass(spec);
  if(allRoutes) {
    for(i in allRoutes) {
      this.addComponentRoute(allRoutes[i], reactClass, {});
    }
  }
  if(_onRoute) {
    reactClass.__$onRoute = _onRoute;
  }

  return reactClass;
};

pellet.prototype.setLocaleLookupFn = function(lookupFn) {
  this.suggestLocales = lookupFn;
};

pellet.prototype.loadTranslation = function(locale, fn) {
  this.locales[locale] = fn;
};

pellet.prototype.loadManifestComponents = function(manifest) {
  var last, id, key, keys;

  if(!manifest || typeof(manifest) !== 'object') {
    return;
  }

  keys = Object.keys(manifest);

  keys.sort().reverse();
  for(var i in keys) {
    key = keys[i];
    id = key.substring(0, key.indexOf('@'));
    if(id) {
      if(last !== id) {
        if(this.components[id]) {
          console.warn('duplicate manifest component loaded:', id)
        }

        this.components[id] = manifest[key];
        last = id;
      }

      this.components[key] = manifest[key];
    }
  }
};

/**
 *
 * @param key
 * @param isGlobal
 * @param options
 * @returns {*}
 */
pellet.prototype.getCoordinator = function(name, type, options) {
  if(!name) {
    throw new Error('name is required');
  }

  if(instance = this.coordinators[name]) {
    return instance;
  }

  if(typeof type !== 'string') {
    type = name;
    if(typeof type === 'object') {
      options = type;
    }
  }

  // now create a global coordinator
  var instance = this.createCoordinator(type, options);
  this.coordinators[name] = instance;

  return instance;
};

/**
 *
 * @param key
 * @param isGlobal
 * @param options
 * @returns {*}
 */
pellet.prototype.createCoordinator = function(type, options) {
  if(!type) {
    throw new Error('type is required');
  }

  if(!this.coordinatorSpecs[type]) {
    throw new Error('Cannot find ' + type + ' coordinator spec');
  }

  var instance = new coordinator();
  utils.mixInto(instance, this.coordinatorSpecs[type], false, ['initialize', 'load', 'release']);
  instance.initialize(options);

  return instance;
};

/**
 * register the coordinator spec that creates the new coordinator
 * of type name.
 *
 * @param name
 * @param fn
 */
pellet.prototype.registerCoordinatorSpec = function(name, spec) {
  if(!spec || !name) {
    throw new Error('Spec and name are required for all coordinators.');
  }

  if(this.coordinatorSpecs[name]) {
    console.error('Error duplicate store specs:', name);
    throw new Error('Cannot have duplicate store specs');
  }

  this.coordinatorSpecs[name] = spec;
};

/**
 * register a function to be called once pellet is ready
 * @param fn
 */
pellet.prototype.onReady = function(fn) {
  // if all ready running fire immediately with the last know err (or null if no errors)
  if(typeof(this.readyError) != 'undefined') {
    setTimeout(function() {
      fn(module.exports.readyError);
    }, 1);

    return;
  }

  this.readyFnQue.push(fn);
};

/**
 * register a function needed to complete before pellet is ready
 * @param fn
 */
pellet.prototype.registerInitFn = function(fn) {
  this.initFnQue.push(fn);
};

/**
 * Called after everyone has register their load functions
 */
pellet.prototype.startInit = function(config) {
  if(typeof(this.readyError) != 'undefined') {
    throw new Error('Cannot reinit because pellet is all ready running.');
  }

  this.config = config;

  var cbCount = this.initFnQue.length;
  function done(err) {
    if(err) {
      // console log the error and safe the most recent error
      console.error('Error init pellet because:', err.message);
      module.exports.readyError = err;
    }

    if(--cbCount <= 0) {
      // if all callback had no error set to null
      if(!module.exports.readyError) {
        module.exports.readyError = null;
      }

      var fn;
      while(fn = module.exports.readyFnQue.pop()) {
        fn(module.exports.readyError);
      }
    }
  }

  if(cbCount === 0) {
    done(null);
    return;
  }

  // now call all init fn and wait until all done
  for(i in this.initFnQue) {
    this.initFnQue[i](done);
  }
};

/**
 *
 * @param renderOptions
 * @param component
 * @param options
 * @returns {locals|*|js.locals|module.locals|app.locals|string}
 */
pellet.prototype.suggestLocales = function(renderOptions, component, options) {
  // todo: if server read (Accept-Language) and push it onto array after en
  // todo: if broswer we can use navigator.language etc.
  // final this can be overwrite by a cookie or by url/host

  return module.exports.config.locales || 'en';
}

if(process.env.SERVER_ENV) {
  module.exports = global.__pellet__ref = new pellet();
}
else if(process.env.BROWSER_ENV) {
  module.exports = window.__pellet__ref = new pellet();
} else {
  module.exports = new pellet();
}
<|endoftext|>


<commit_before>#! /usr/bin/env node

var args = process.argv.slice(2);

// Usage info
if (!args.length || args[0] === '-h') return console.log(
  require('./help/usage')
); else if (args[0] === '--help') return console.log('\n' + [
  require('./help/synopsis'),
  require('./help/description'),
  require('./help/examples'),
  require('./help/popularPlugins'),
].join('\n\n\n'));

// Imports
var doxie = require('doxie-core');
var toJson = require('stream-to-json');
var implode = require('1-liners/implode');

var messagePrefix = require('chalk').cyan('[doxie]') + ' ';
var tinyError = require('tiny-error')({
  prefix: messagePrefix,
});

function fail (content) {
  process.stderr.write(messagePrefix + content + '\n');
  process.exit(1);
};

// Argument parsing
var pluginName = /^--(.+)$/;

var plugins = args.reduce(function(plugins, argument, index) {
  var parsedPluginName = pluginName.exec(argument);
  var indexOfLastPlugin = plugins.length;

  if (parsedPluginName) return plugins.concat({
    maker: require('doxie.' + parsedPluginName[1] + '/cli-plugin'),
      // TODO: Check if `maker` is a function
    args: [],
  });

  else if (indexOfLastPlugin) {
    plugins[indexOfLastPlugin].args.push(argument);
    return plugins;
  }

  throw tinyError('Unrecognized argument: ' +
    '“' + argument + '” ' +
    '(position ' + (index + 1) + ').'
  );
}, []);

// The logic
toJson(process.stdin, function (error, data) {
  if (error) fail(
    'Invalid JSON input: “' + error.message + '”.\n'
  );

  doxie(
    plugins.map(function(plugin) {
      return implode(plugin.maker)(plugin.args);
    }),
    {
      stdout: process.stdout,
      stderr: process.stderr,
    }
  )(data);
});
<commit_msg>Sort out output and exit codes<commit_after>#! /usr/bin/env node

var args = process.argv.slice(2);

const leave = (message) => {
  process.stdout.write(`${message}\n`);
  process.exit(0);
};

const flee = (message) => {
  process.stderr.write(`${message}\n`);
  process.exit(1);
};

// Usage info
if (!args.length) flee(
  require('./help/usage')
);

if (args[0] === '-h') leave(
  require('./help/usage')
);

if (args[0] === '--help') leave(
  '\n' + [
    require('./help/synopsis'),
    require('./help/description'),
    require('./help/examples'),
    require('./help/popularPlugins'),
  ].join('\n\n\n')
);

// Imports
var doxie = require('doxie-core');
var toJson = require('stream-to-json');
var implode = require('1-liners/implode');

var prefix = require('chalk').cyan('[doxie]') + ' ';
var tinyError = require('tiny-error')({prefix});

// Argument parsing
var pluginName = /^--(.+)$/;

var plugins = args.reduce(function(plugins, argument, index) {
  var parsedPluginName = pluginName.exec(argument);
  var indexOfLastPlugin = plugins.length;

  if (parsedPluginName) return plugins.concat({
    maker: require('doxie.' + parsedPluginName[1] + '/cli-plugin'),
      // TODO: Check if `maker` is a function
    args: [],
  });

  else if (indexOfLastPlugin) {
    plugins[indexOfLastPlugin].args.push(argument);
    return plugins;
  }

  throw tinyError('Unrecognized argument: ' +
    '“' + argument + '” ' +
    '(position ' + (index + 1) + ').'
  );
}, []);

// The logic
toJson(process.stdin, function (error, data) {
  if (error) flee(
    `${prefix}Invalid JSON input: “${error.message}”.\n`
  );

  doxie(
    plugins.map(function(plugin) {
      return implode(plugin.maker)(plugin.args);
    }),
    {
      stdout: process.stdout,
      stderr: process.stderr,
    }
  )(data);
});
<|endoftext|>


<commit_before>  'use strict';

  var pluginName = 'insight',
      defaults = {
        fn: null,
        classIn:      'insight',
        classAbove:   'insight-above',
        classBelow:   'insight-below',
        classLeft:    'insight-left',
        classRight:   'insight-right',
        container:    $(window),
      };

  function InSight(element, options) {
    this.el = element;
    this.$el = $(this.el);
    this.options = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
  }

  InSight.prototype = {

    init: function() {
      var _this = this;
      var el = _this.el;
      var $el = _this.$el;
      var options = _this.options;

      function handler(e, rect, wWidth, wHeight, insight, position) {

        try {
          rect = el.getBoundingClientRect();
          wWidth = options.container.width();
          wHeight = options.container.height();
          insight = rect.top < wHeight &&
                    rect.bottom > 0 &&
                    rect.left < wWidth &&
                    rect.right > 0;
          position = {
            above: rect.top < 0 && rect.bottom <= 0,
            left: rect.left < 0 && rect.right <= 0,
            right: rect.left >= wWidth && rect.right > wWidth,
            below: rect.top >= wHeight && rect.bottom > wHeight,
          };

          if (insight) {
            $el.addClass(options.classIn);
          }

          if (position.above) {
            $el.addClass(options.classAbove);
          }
          else {
            $el.removeClass(options.classAbove);
          }

          if (position.below) {
            $el.addClass(options.classBelow);
          }
          else {
            $el.removeClass(options.classBelow);
          }

          if (position.left) {
            $el.addClass(options.classLeft);
          }
          else {
            $el.removeClass(options.classLeft);
          }

          if (position.right) {
            $el.addClass(options.classRight);
          }
          else {
            $el.removeClass(options.classRight);
          }
        }
        catch(e) {}
        options.fn && options.fn.apply(el, [insight, position]);
      }

      $(window)
        .off('DOMContentLoaded load resize', handler.bind(_this))
        .on('DOMContentLoaded load resize', handler.bind(_this));
      options.container
        .off('scroll', handler.bind(_this))
        .on('scroll', handler.bind(_this))
        .trigger('scroll');
    }
  };

  // A really lightweight plugin wrapper around the constructor,
  // preventing against multiple instantiations
  $.fn[pluginName] = function(options) {
    return this.each(function() {
      if (!$(this).data(pluginName)) {
        $(this).data(pluginName, new InSight(this, options));
      }
    });
  };
<commit_msg>add destroy function to remove the instance and all event listeners<commit_after>  'use strict';

  var pluginName = 'insight',
      defaults = {
        fn: null,
        classIn:      'insight',
        classAbove:   'insight-above',
        classBelow:   'insight-below',
        classLeft:    'insight-left',
        classRight:   'insight-right',
        container:    $(window),
      };

  function InSight(element, options) {
    this.el = element;
    this.$el = $(this.el);
    this.options = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
  }

  InSight.prototype = {

    init: function() {
      this.handler = this._handler.bind(this);
      $(window)
        .off('DOMContentLoaded load resize', this.handler)
        .on('DOMContentLoaded load resize', this.handler);
      this.options.container
        .off('scroll', this.handler)
        .on('scroll', this.handler)
        .trigger('scroll');
    },
    destroy: function() {
      $(window)
        .off('DOMContentLoaded load resize', this.handler);
      this.options.container
        .off('scroll', this.handler);
      this.$el.removeData(pluginName);
    },
    _handler: function(e, rect, wWidth, wHeight, insight, position) {
      try {
        rect = this.el.getBoundingClientRect();
        wWidth = this.options.container.width();
        wHeight = this.options.container.height();
        insight = rect.top < wHeight &&
                  rect.bottom > 0 &&
                  rect.left < wWidth &&
                  rect.right > 0;
        position = {
          above: rect.top < 0 && rect.bottom <= 0,
          left: rect.left < 0 && rect.right <= 0,
          right: rect.left >= wWidth && rect.right > wWidth,
          below: rect.top >= wHeight && rect.bottom > wHeight,
        };

        if (insight) {
          this.$el.addClass(this.options.classIn);
        }

        if (position.above) {
          this.$el.addClass(this.options.classAbove);
        }
        else {
          this.$el.removeClass(this.options.classAbove);
        }

        if (position.below) {
          this.$el.addClass(this.options.classBelow);
        }
        else {
          this.$el.removeClass(this.options.classBelow);
        }

        if (position.left) {
          this.$el.addClass(this.options.classLeft);
        }
        else {
          this.$el.removeClass(this.options.classLeft);
        }

        if (position.right) {
          this.$el.addClass(this.options.classRight);
        }
        else {
          this.$el.removeClass(this.options.classRight);
        }
      }
      catch(e) {}
      this.options.fn && this.options.fn.apply(this.el, [insight, position]);
    }
  };

  $.fn[pluginName] = function(options) {
    return this.each(function() {

      var $el = $(this);
      var inst = $el.data(pluginName);

      if(!inst) {
        inst = new InSight(this, options);
        $el.data(pluginName, inst);
      }

      else if (options === 'destroy') {
        inst.destroy();
      }

    });
  };
<|endoftext|>


<commit_before>// Timeout cached values

'use strict';

var aFrom      = require('es5-ext/array/from')
  , noop       = require('es5-ext/function/noop')
  , forEach    = require('es5-ext/object/for-each')
  , timeout    = require('timers-ext/valid-timeout')
  , extensions = require('../lib/registered-extensions')

  , max = Math.max, min = Math.min, create = Object.create;

extensions.maxAge = function (maxAge, conf, options) {
	var timeouts, postfix, preFetchAge, preFetchTimeouts;

	maxAge = timeout(maxAge);
	if (!maxAge) return;

	timeouts = create(null);
	postfix = ((options.async && extensions.async) || (options.promise && extensions.promise))
		? 'async' : '';
	conf.on('set' + postfix, function (id) {
		timeouts[id] = setTimeout(function () { conf.delete(id); }, maxAge);
		if (!preFetchTimeouts) return;
		if (preFetchTimeouts[id]) clearTimeout(preFetchTimeouts[id]);
		preFetchTimeouts[id] = setTimeout(function () {
			delete preFetchTimeouts[id];
		}, preFetchAge);
	});
	conf.on('delete' + postfix, function (id) {
		clearTimeout(timeouts[id]);
		delete timeouts[id];
		if (!preFetchTimeouts) return;
		clearTimeout(preFetchTimeouts[id]);
		delete preFetchTimeouts[id];
	});

	if (options.preFetch) {
		if ((options.preFetch === true) || isNaN(options.preFetch)) {
			preFetchAge = 0.333;
		} else {
			preFetchAge = max(min(Number(options.preFetch), 1), 0);
		}
		if (preFetchAge) {
			preFetchTimeouts = {};
			preFetchAge = (1 - preFetchAge) * maxAge;
			conf.on('get' + postfix, function (id, args, context) {
				if (!preFetchTimeouts[id]) {
					preFetchTimeouts[id] =  setTimeout(function () {
						delete preFetchTimeouts[id];
						conf.delete(id);
						if (options.async) {
							args = aFrom(args);
							args.push(noop);
						}
						conf.memoized.apply(context, args);
					}, 0);
				}
			});
		}
	}

	conf.on('clear' + postfix, function () {
		forEach(timeouts, function (id) { clearTimeout(id); });
		timeouts = {};
		if (preFetchTimeouts) {
			forEach(preFetchTimeouts, function (id) { clearTimeout(id); });
			preFetchTimeouts = {};
		}
	});
};
<commit_msg>Prefetch result in nextTick<commit_after>// Timeout cached values

'use strict';

var aFrom      = require('es5-ext/array/from')
  , noop       = require('es5-ext/function/noop')
  , forEach    = require('es5-ext/object/for-each')
  , nextTick   = require('next-tick')
  , timeout    = require('timers-ext/valid-timeout')
  , extensions = require('../lib/registered-extensions')

  , max = Math.max, min = Math.min, create = Object.create;

extensions.maxAge = function (maxAge, conf, options) {
	var timeouts, postfix, preFetchAge, preFetchTimeouts;

	maxAge = timeout(maxAge);
	if (!maxAge) return;

	timeouts = create(null);
	postfix = ((options.async && extensions.async) || (options.promise && extensions.promise))
		? 'async' : '';
	conf.on('set' + postfix, function (id) {
		timeouts[id] = setTimeout(function () { conf.delete(id); }, maxAge);
		if (!preFetchTimeouts) return;
		if (preFetchTimeouts[id]) {
			if (preFetchTimeouts[id] !== 'nextTick') clearTimeout(preFetchTimeouts[id]);
		}
		preFetchTimeouts[id] = setTimeout(function () {
			delete preFetchTimeouts[id];
		}, preFetchAge);
	});
	conf.on('delete' + postfix, function (id) {
		clearTimeout(timeouts[id]);
		delete timeouts[id];
		if (!preFetchTimeouts) return;
		if (preFetchTimeouts[id] !== 'nextTick') clearTimeout(preFetchTimeouts[id]);
		delete preFetchTimeouts[id];
	});

	if (options.preFetch) {
		if ((options.preFetch === true) || isNaN(options.preFetch)) {
			preFetchAge = 0.333;
		} else {
			preFetchAge = max(min(Number(options.preFetch), 1), 0);
		}
		if (preFetchAge) {
			preFetchTimeouts = {};
			preFetchAge = (1 - preFetchAge) * maxAge;
			conf.on('get' + postfix, function (id, args, context) {
				if (!preFetchTimeouts[id]) {
					preFetchTimeouts[id] = 'nextTick';
					nextTick(function () {
						if (preFetchTimeouts[id] !== 'nextTick') return;
						delete preFetchTimeouts[id];
						conf.delete(id);
						if (options.async) {
							args = aFrom(args);
							args.push(noop);
						}
						conf.memoized.apply(context, args);
					});
				}
			});
		}
	}

	conf.on('clear' + postfix, function () {
		forEach(timeouts, function (id) { clearTimeout(id); });
		timeouts = {};
		if (preFetchTimeouts) {
			forEach(preFetchTimeouts, function (id) {
				if (id !== 'nextTick') clearTimeout(id);
			});
			preFetchTimeouts = {};
		}
	});
};
<|endoftext|>


<commit_before>var PathUtils = require('./PathUtils');

var STATE_KEY_QUERY_PARAM = '_sk';

function getHashPath() {
  return decodeURI(
    // We can't use window.location.hash here because it's not
    // consistent across browsers - Firefox will pre-decode it!
    window.location.href.split('#')[1] || ''
  );
}

function getWindowPath() {
  return decodeURI(
    window.location.pathname + window.location.search
  );
}

function getState(path) {
  var stateID = getStateID(path);
  var serializedState = stateID && window.sessionStorage.getItem(stateID);
  return serializedState ? JSON.parse(serializedState) : null;
}

function getStateID(path) {
  var query = PathUtils.extractQuery(path);
  return query && query[STATE_KEY_QUERY_PARAM];
}

function withStateID(path, stateID) {
  var query = Path.extractQuery(path) || {};
  query[STATE_KEY_QUERY_PARAM] = stateID;
  return PathUtils.withQuery(PathUtils.withoutQuery(path), query);
}

function withoutStateID(path) {
  var query = PathUtils.extractQuery(path);

  if (STATE_KEY_QUERY_PARAM in query) {
    delete query[STATE_KEY_QUERY_PARAM];
    return PathUtils.withQuery(PathUtils.withoutQuery(path), query);
  }

  return path;
}

function saveState(state) {
  var stateID = state.id;

  if (stateID == null)
    stateID = state.id = Math.random().toString(36).slice(2);

  window.sessionStorage.setItem(
    stateID,
    JSON.stringify(state)
  );

  return stateID;
}

function withState(path, state) {
  var stateID = state != null && saveState(state);
  return stateID ? withStateID(path, stateID) : withoutStateID(path);
}

module.exports = {
  getHashPath,
  getWindowPath,
  getState,
  getStateID,
  withStateID,
  withoutStateID,
  saveState,
  withState
};
<commit_msg>Remove unused util methods<commit_after>/**
 * Returns the current URL path.
 */
function getWindowPath() {
  return decodeURI(
    window.location.pathname + window.location.search
  );
}

/**
 * Returns the URL path contained in the hash portion of the URL,
 * which HashHistory uses to store the current path.
 */
function getHashPath() {
  return decodeURI(
    // We can't use window.location.hash here because it's not
    // consistent across browsers - Firefox will pre-decode it!
    window.location.href.split('#')[1] || ''
  );
}

/**
 * Returns the current scroll position of the window as { x, y }.
 */
function getWindowScrollPosition() {
  return {
    x: window.pageXOffset || document.documentElement.scrollLeft,
    y: window.pageYOffset || document.documentElement.scrollTop
  };
}

module.exports = {
  getWindowPath,
  getHashPath,
  getWindowScrollPosition
};
<|endoftext|>


<commit_before>(function (window, undefined) {
    "use strict";

    if (!window.Trios2D)
        throw new Error("You must include Trios2D in your HTML");

    var Trios2D = window.Trios2D,
        Vector = Trios2D.Vector,
        GameObject = Trios2D.GameObject;

    /*
     * Creates a new Text object.
     */
    function Text(text, options) {
        // Calling GameObject Constructor
        GameObject.apply(this);

        this.text = text;
        this.size = options.size || 10;
        this.font_family = options.font_family || "sans-serif";
        this.font_misc = options.font_misc || "";
        this.textAlign = options.textAlign || "start";
        this.baselineAlign = options.baselineAlign || "alphabetic";
        this.drawMode = options.drawMode || "fill";
        this.color = options.color;
        this.lineColor = options.lineColor;

    }

    Text.prototype = Object.create(GameObject.prototype);

    Text.prototype.render = function render(context, parentPosition) {
        var defaultFont = context.font,
            defaultAlign = context.textAlign,
            defaultBase = context.textBaseline,
            fillStyle = context.fillStyle,
            strokeStyle = context.strokeStyle;

        context.font = this.font_misc + " " + this.size + "px " + this.font_family;
        context.textAlign = this.textAlign;
        context.textBaseline = this.baselineAlign;
        context.fillStyle = this.color || fillStyle;
        context.strokeStyle = this.lineColor || strokeStyle;

        if (this.drawMode === "fill" || this.drawMode === "fillNStroke") {
            context.fillText(this.text, this.absolutePosition.x, this.absolutePosition.y);
        }

        if (this.drawMode === "stroke" || this.drawMode === "fillNStroke") {
            context.strokeText(this.text, this.absolutePosition.x, this.absolutePosition.y);
        }

        context.font = defaultFont;
        context.textAlign = defaultAlign;
        context.textBaseline = defaultBase;
        context.fillStyle = fillStyle;
        context.strokeStyle = strokeStyle;

    };

    window.Trios2D.GameText = Text;

}(window));
<commit_msg>Now size is not overwriten, more efficient way to save the context configurarion in render<commit_after>(function (window, undefined) {
    "use strict";

    if (!window.Trios2D)
        throw new Error("You must include Trios2D in your HTML");

    var Trios2D = window.Trios2D,
        Vector = Trios2D.Vector,
        GameObject = Trios2D.GameObject;

    /*
     * Creates a new Text object.
     */
    function Text(text, options) {
        // Calling GameObject Constructor
        GameObject.apply(this);

        this.text = text;
        this.font_size = options.size || 10;
        this.font_family = options.font_family || "sans-serif";
        this.font_misc = options.font_misc || "";
        this.textAlign = options.textAlign || "start";
        this.baselineAlign = options.baselineAlign || "alphabetic";
        this.drawMode = options.drawMode || "fill";
        this.color = options.color;
        this.lineColor = options.lineColor;

    }

    Text.prototype = Object.create(GameObject.prototype);

    Text.prototype.render = function render(context, parentPosition) {
        context.save(); // before render

        context.font = this.font_misc + " " + this.font_size + "px " + this.font_family;
        context.textAlign = this.textAlign;
        context.textBaseline = this.baselineAlign;
        context.fillStyle = this.color || fillStyle;
        context.strokeStyle = this.lineColor || strokeStyle;

        if (this.drawMode === "fill" || this.drawMode === "fillNStroke") {
            context.fillText(this.text, this.absolutePosition.x, this.absolutePosition.y);
        }

        if (this.drawMode === "stroke" || this.drawMode === "fillNStroke") {
            context.strokeText(this.text, this.absolutePosition.x, this.absolutePosition.y);
        }

        context.restore(); // after render

    };

    window.Trios2D.GameText = Text;

}(window));
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
const { console } = Cu.import("resource://gre/modules/Console.jsm", {});
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});

this.EXPORTED_SYMBOLS = ["Runtime"];

this.Runtime = {
  start(appFile) {
    registerChromePrefix(appFile.parent.path);

    const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].
                            createInstance(Ci.nsIPrincipal);

    const sandbox = new Cu.Sandbox(systemPrincipal, {
      wantComponents: true,
    });

    Services.scriptloader.loadSubScript(`chrome://app/content/${appFile.leafName}`, sandbox, 'UTF-8');
  },
};

function readFile(file) {
  let stream = NetUtil.newChannel({
    uri: file,
    loadUsingSystemPrincipal: true,
  }).open2();
  let count = stream.available();
  let data = NetUtil.readInputStreamToString(stream, count);
  stream.close();
  return data;
}

// XXX Clean up all this code, most of which is copied from some test head
// and seems to contain some redundancy.

function registerChromePrefix(path) {
  let manifestText = `content app ${path}/`;
  createManifestTemporarily(gDirSvc.get("ProfD", Ci.nsIFile), manifestText);
}

var gDirSvc    = Cc["@mozilla.org/file/directory_service;1"].
  getService(Ci.nsIDirectoryService).QueryInterface(Ci.nsIProperties);

var gChromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
                    getService(Ci.nsIXULChromeRegistry);

function copyToTemporaryFile(f) {
  let tmpd = gDirSvc.get("ProfD", Ci.nsIFile);
  tmpf = tmpd.clone();
  tmpf.append("temp.manifest");
  tmpf.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
  tmpf.remove(false);
  f.copyTo(tmpd, tmpf.leafName);
  return tmpf;
}

function createManifestTemporarily(tempDir, manifestText) {
  tempDir.append("temp.manifest");

  let foStream = Cc["@mozilla.org/network/file-output-stream;1"]
                   .createInstance(Ci.nsIFileOutputStream);
  foStream.init(tempDir,
                0x02 | 0x08 | 0x20, 0o664, 0); // write, create, truncate
  foStream.write(manifestText, manifestText.length);
  foStream.close();
  let tempfile = copyToTemporaryFile(tempDir);

  Components.manager.QueryInterface(Ci.nsIComponentRegistrar).
    autoRegister(tempfile);

  gChromeReg.checkForNewChrome();
  // tempfile.fileSize = 0; // truncate the manifest
}
<commit_msg>clean up chrome registering code<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
const { console } = Cu.import("resource://gre/modules/Console.jsm", {});
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const ChromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);

this.EXPORTED_SYMBOLS = ["Runtime"];

this.Runtime = {
  start(appFile) {
    registerChromePrefix(appFile.parent.path);

    const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].
                            createInstance(Ci.nsIPrincipal);

    const sandbox = new Cu.Sandbox(systemPrincipal, {
      wantComponents: true,
    });

    Services.scriptloader.loadSubScript(`chrome://app/content/${appFile.leafName}`, sandbox, 'UTF-8');
  },
};

function readFile(file) {
  let stream = NetUtil.newChannel({
    uri: file,
    loadUsingSystemPrincipal: true,
  }).open2();
  let count = stream.available();
  let data = NetUtil.readInputStreamToString(stream, count);
  stream.close();
  return data;
}

function registerChromePrefix(path) {
  let manifestText = `content app ${path}/`;

  const tempFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
  tempFile.append("temp.manifest");
  tempFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);

  let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
  fileStream.init(tempFile, 0x02 | 0x08 | 0x20, 0o664, 0); // write, create, truncate
  fileStream.write(manifestText, manifestText.length);
  fileStream.close();

  Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(tempFile);
  ChromeRegistry.checkForNewChrome();

  tempFile.remove(false);
}
<|endoftext|>


<commit_before>// Export javascript style and css style vendor prefixes.
// Based on "transform" support test.

import isInBrowser from 'is-in-browser'

let js = ''
let css = ''
let browser = ''

// We should not do anything if required serverside.
if (isInBrowser) {
  // Order matters. We need to check Webkit the last one because
  // other vendors use to add Webkit prefixes to some properties
  const jsCssMap = {
    Moz: '-moz-',
    ms: '-ms-',
    O: '-o-',
    Webkit: '-webkit-'
  }

  const {style} = document.createElement('p')
  const testProp = 'Transform'

  for (const key in jsCssMap) {
    if (key + testProp in style) {
      js = key
      css = jsCssMap[key]
      break
    }
  }

  // Correctly detect the Edge browser.
  if (js === 'Webkit' && 'msHyphens' in style) {
    js = 'ms'
    css = jsCssMap.ms
  }

  // Correctly detect the Safari browser.
  if (js === 'Webkit' && Object.keys(style).includes('appleTrailingWord')) {
    browser = 'safari'
    css = jsCssMap.safari
  }
}

/**
 * Vendor prefix string for the current browser.
 *
 * @type {{js: String, css: String}}
 * @api public
 */
export default {js, css, browser}
<commit_msg>Removed css variable assign in prefix.js if browser is safari<commit_after>// Export javascript style and css style vendor prefixes.
// Based on "transform" support test.

import isInBrowser from 'is-in-browser'

let js = ''
let css = ''
let browser = ''

// We should not do anything if required serverside.
if (isInBrowser) {
  // Order matters. We need to check Webkit the last one because
  // other vendors use to add Webkit prefixes to some properties
  const jsCssMap = {
    Moz: '-moz-',
    ms: '-ms-',
    O: '-o-',
    Webkit: '-webkit-'
  }

  const {style} = document.createElement('p')
  const testProp = 'Transform'

  for (const key in jsCssMap) {
    if (key + testProp in style) {
      js = key
      css = jsCssMap[key]
      break
    }
  }

  // Correctly detect the Edge browser.
  if (js === 'Webkit' && 'msHyphens' in style) {
    js = 'ms'
    css = jsCssMap.ms
  }

  // Correctly detect the Safari browser.
  if (js === 'Webkit' && Object.keys(style).includes('appleTrailingWord')) {
    browser = 'safari'
  }
}

/**
 * Vendor prefix string for the current browser.
 *
 * @type {{js: String, css: String}}
 * @api public
 */
export default {js, css, browser}
<|endoftext|>


<commit_before>const Confax = require('../bot.js')
const fs = require('fs')
const bot = Confax.bot
let bannedWords = Confax.config.bannedWords
let warnedUserIds = Confax.warnedUserIds

bot.on('message', (message) => {
  if (message.author.bot) return

  let lowercaseMessage = message.content.toLowerCase()
  bannedWords = Confax.config.bannedWords
  for (var word in bannedWords) {
    if (lowercaseMessage.includes(bannedWords[word])) {
      let apiCommands = ['addbannedword', 'abw', 'removebannedword', 'rbw']
      if (apiCommands.some(x => { return lowercaseMessage.indexOf(x) >= 0 })) {
        let roles = message.guild.member(message.author.id).roles.array()
        let accepted = ['Bot Commander', 'Moderator']
        for (let i = 0; i < roles.length; i++) {
          if (accepted.includes(roles[i].name)) {
            return
          }
        }
      }
      message.reply(Confax.config.muteWarningMessage.replace('{bannedWord}', bannedWords[word]))
      checkUser(message)
    }
  }
})

function checkUser (message) {
  if (warnedUserIds.includes(message.member.user.id)) {
    addMutedRole(message)
  } else {
    warnedUserIds.push(message.member.user.id)
  }
}

function addMutedRole (message) {
  let role = message.guild.roles.find(role => role.name === Confax.config.roleMuted)

  if (!role) {
    console.log('The role ' + Confax.config.roleMuted + ' does not exists on this server')
    return
  }

  message.member.addRole(role)
}

function persistWarnedUsers () {
  fs.writeFileSync('warneduserids.json', JSON.stringify(warnedUserIds))
}

setInterval(persistWarnedUsers, 10000)
<commit_msg>Fix banwords module to use server-specific configs<commit_after>const Confax = require('../bot.js')
const fs = require('fs')
const bot = Confax.bot
let warnedUserIds = Confax.warnedUserIds

bot.on('message', (message) => {
  const config = Confax.getConfig(message.guild.id)
  const bannedWords = config.bannedWords

  if (message.author.bot) return

  let lowercaseMessage = message.content.toLowerCase()
  for (var word in bannedWords) {
    if (lowercaseMessage.includes(bannedWords[word])) {
      let apiCommands = ['addbannedword', 'abw', 'removebannedword', 'rbw']
      if (apiCommands.some(x => { return lowercaseMessage.indexOf(x) >= 0 })) {
        let roles = message.guild.member(message.author.id).roles.array()
        let accepted = ['Bot Commander', 'Moderator']
        for (let i = 0; i < roles.length; i++) {
          if (accepted.includes(roles[i].name)) {
            return
          }
        }
      }
      message.reply(config.muteWarningMessage.replace('{bannedWord}', bannedWords[word]))
      checkUser(message)
    }
  }
})

function checkUser (message) {
  if (warnedUserIds.includes(message.member.user.id)) {
    addMutedRole(message)
  } else {
    warnedUserIds.push(message.member.user.id)
  }
}

function addMutedRole (message) {
  let role = message.guild.roles.find(role => role.name === config.roleMuted)

  if (!role) {
    console.log('The role ' + config.roleMuted + ' does not exists on this server')
    return
  }

  message.member.addRole(role)
}

function persistWarnedUsers () {
  fs.writeFileSync('warneduserids.json', JSON.stringify(warnedUserIds))
}

setInterval(persistWarnedUsers, 10000)
<|endoftext|>


<commit_before>// Copyright (C) 2016 The Android Open Source Project
//
// 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.
(function() {
  'use strict';

  Polymer({
    is: 'gr-messages-list',

    properties: {
      changeNum: Number,
      messages: {
        type: Array,
        value: function() { return []; },
      },
      reviewerUpdates: {
        type: Array,
        value: function() { return []; },
      },
      comments: Object,
      projectConfig: Object,
      showReplyButtons: {
        type: Boolean,
        value: false,
      },

      _expanded: {
        type: Boolean,
        value: false,
      },
      _hideAutomated: {
        type: Boolean,
        value: false,
      },
    },

    scrollToMessage: function(messageID) {
      var el = this.$$('[data-message-id="' + messageID + '"]');
      if (!el) { return; }

      el.expanded = true;
      var top = el.offsetTop;
      for (var offsetParent = el.offsetParent;
           offsetParent;
           offsetParent = offsetParent.offsetParent) {
        top += offsetParent.offsetTop;
      }
      window.scrollTo(0, top);
      this._highlightEl(el);
    },

    _computeItems: function(messages, reviewerUpdates) {
      messages = messages || [];
      reviewerUpdates = reviewerUpdates || [];
      var mi = 0;
      var ri = 0;
      var result = [];
      var mDate;
      var rDate;
      for (var i = 0; i < messages.length; i++) {
        messages[i]._index = i;
      }
      while (mi < messages.length || ri < reviewerUpdates.length) {
        if (mi >= messages.length) {
          result = result.concat(reviewerUpdates.slice(ri));
          break;
        }
        if (ri >= reviewerUpdates.length) {
          result = result.concat(messages.slice(mi));
          break;
        }
        mDate = mDate || util.parseDate(messages[mi].date);
        rDate = rDate || util.parseDate(reviewerUpdates[ri].updated);
        if (rDate < mDate) {
          result.push(reviewerUpdates[ri++]);
          rDate = null;
        } else {
          result.push(messages[mi++]);
          mDate = null;
        }
      }
      return result;
    },

    _highlightEl: function(el) {
      var highlightedEls =
          Polymer.dom(this.root).querySelectorAll('.highlighted');
      for (var i = 0; i < highlightedEls.length; i++) {
        highlightedEls[i].classList.remove('highlighted');
      }
      function handleAnimationEnd() {
        el.removeEventListener('animationend', handleAnimationEnd);
        el.classList.remove('highlighted');
      }
      el.addEventListener('animationend', handleAnimationEnd);
      el.classList.add('highlighted');
    },

    _handleExpandCollapseTap: function(e) {
      e.preventDefault();
      this._expanded = !this._expanded;
      var messageEls = Polymer.dom(this.root).querySelectorAll('gr-message');
      for (var i = 0; i < messageEls.length; i++) {
        messageEls[i].expanded = this._expanded;
      }
    },

    _handleAutomatedMessageToggleTap: function(e) {
      e.preventDefault();
      this._hideAutomated = !this._hideAutomated;
    },

    _handleScrollTo: function(e) {
      this.scrollToMessage(e.detail.message.id);
    },

    _hasAutomatedMessages: function(messages) {
      for (var i = 0; messages && i < messages.length; i++) {
        if (messages[i].tag &&
            messages[i].tag.indexOf('autogenerated') === 0) {
          return true;
        }
      }
      return false;
    },

    _computeExpandCollapseMessage: function(expanded) {
      return expanded ? 'Collapse all' : 'Expand all';
    },

    _computeAutomatedToggleText: function(hideAutomated) {
      return hideAutomated ? 'Show automated' : 'Hide automated';
    },

    /**
     * Computes message author's file comments for change's message.
     * Method uses this.messages to find next message and relies on messages
     * to be sorted by date field descending.
     * @param {!Object} comments Hash of arrays of comments, filename as key.
     * @param {!Object} message
     * @return {!Object} Hash of arrays of comments, filename as key.
     */
    _computeCommentsForMessage: function(comments, message) {
      if (message._index === undefined || !comments || !this.messages) {
        return [];
      }
      var messages = this.messages || [];
      var index = message._index;
      var authorId = message.author._account_id;
      var mDate = util.parseDate(message.date).getTime();
      // NB: Messages array has oldest messages first.
      var nextMDate;
      if (index > 0) {
        for (var i = index - 1; i >= 0; i--) {
          if (messages[i].author._account_id === authorId) {
            nextMDate = util.parseDate(messages[i].date).getTime();
            break;
          }
        }
      }
      var msgComments = {};
      for (var file in comments) {
        var fileComments = comments[file];
        for (var i = 0; i < fileComments.length; i++) {
          if (fileComments[i].author._account_id !== authorId) {
            continue;
          }
          var cDate = util.parseDate(fileComments[i].updated).getTime();
          if (cDate <= mDate) {
            if (nextMDate && cDate <= nextMDate) {
              continue;
            }
            msgComments[file] = msgComments[file] || [];
            msgComments[file].push(fileComments[i]);
          }
        }
      }
      return msgComments;
    },
  });
})();
<commit_msg>Fix issue where keyboard shortcuts don't appear<commit_after>// Copyright (C) 2016 The Android Open Source Project
//
// 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.
(function() {
  'use strict';

  Polymer({
    is: 'gr-messages-list',

    properties: {
      changeNum: Number,
      messages: {
        type: Array,
        value: function() { return []; },
      },
      reviewerUpdates: {
        type: Array,
        value: function() { return []; },
      },
      comments: Object,
      projectConfig: Object,
      showReplyButtons: {
        type: Boolean,
        value: false,
      },

      _expanded: {
        type: Boolean,
        value: false,
      },
      _hideAutomated: {
        type: Boolean,
        value: false,
      },
    },

    scrollToMessage: function(messageID) {
      var el = this.$$('[data-message-id="' + messageID + '"]');
      if (!el) { return; }

      el.expanded = true;
      var top = el.offsetTop;
      for (var offsetParent = el.offsetParent;
           offsetParent;
           offsetParent = offsetParent.offsetParent) {
        top += offsetParent.offsetTop;
      }
      window.scrollTo(0, top);
      this._highlightEl(el);
    },

    _computeItems: function(messages, reviewerUpdates) {
      messages = messages || [];
      reviewerUpdates = reviewerUpdates || [];
      var mi = 0;
      var ri = 0;
      var result = [];
      var mDate;
      var rDate;
      for (var i = 0; i < messages.length; i++) {
        messages[i]._index = i;
      }
      while (mi < messages.length || ri < reviewerUpdates.length) {
        if (mi >= messages.length) {
          result = result.concat(reviewerUpdates.slice(ri));
          break;
        }
        if (ri >= reviewerUpdates.length) {
          result = result.concat(messages.slice(mi));
          break;
        }
        mDate = mDate || util.parseDate(messages[mi].date);
        rDate = rDate || util.parseDate(reviewerUpdates[ri].updated);
        if (rDate < mDate) {
          result.push(reviewerUpdates[ri++]);
          rDate = null;
        } else {
          result.push(messages[mi++]);
          mDate = null;
        }
      }
      return result;
    },

    _highlightEl: function(el) {
      var highlightedEls =
          Polymer.dom(this.root).querySelectorAll('.highlighted');
      for (var i = 0; i < highlightedEls.length; i++) {
        highlightedEls[i].classList.remove('highlighted');
      }
      function handleAnimationEnd() {
        el.removeEventListener('animationend', handleAnimationEnd);
        el.classList.remove('highlighted');
      }
      el.addEventListener('animationend', handleAnimationEnd);
      el.classList.add('highlighted');
    },

    _handleExpandCollapseTap: function(e) {
      e.preventDefault();
      this._expanded = !this._expanded;
      var messageEls = Polymer.dom(this.root).querySelectorAll('gr-message');
      for (var i = 0; i < messageEls.length; i++) {
        messageEls[i].expanded = this._expanded;
      }
      if (e && e.target) {
        e.target.blur();
      }
    },

    _handleAutomatedMessageToggleTap: function(e) {
      e.preventDefault();
      this._hideAutomated = !this._hideAutomated;
      if (e && e.target) {
        e.target.blur();
      }
    },

    _handleScrollTo: function(e) {
      this.scrollToMessage(e.detail.message.id);
    },

    _hasAutomatedMessages: function(messages) {
      for (var i = 0; messages && i < messages.length; i++) {
        if (messages[i].tag &&
            messages[i].tag.indexOf('autogenerated') === 0) {
          return true;
        }
      }
      return false;
    },

    _computeExpandCollapseMessage: function(expanded) {
      return expanded ? 'Collapse all' : 'Expand all';
    },

    _computeAutomatedToggleText: function(hideAutomated) {
      return hideAutomated ? 'Show automated' : 'Hide automated';
    },

    /**
     * Computes message author's file comments for change's message.
     * Method uses this.messages to find next message and relies on messages
     * to be sorted by date field descending.
     * @param {!Object} comments Hash of arrays of comments, filename as key.
     * @param {!Object} message
     * @return {!Object} Hash of arrays of comments, filename as key.
     */
    _computeCommentsForMessage: function(comments, message) {
      if (message._index === undefined || !comments || !this.messages) {
        return [];
      }
      var messages = this.messages || [];
      var index = message._index;
      var authorId = message.author._account_id;
      var mDate = util.parseDate(message.date).getTime();
      // NB: Messages array has oldest messages first.
      var nextMDate;
      if (index > 0) {
        for (var i = index - 1; i >= 0; i--) {
          if (messages[i].author._account_id === authorId) {
            nextMDate = util.parseDate(messages[i].date).getTime();
            break;
          }
        }
      }
      var msgComments = {};
      for (var file in comments) {
        var fileComments = comments[file];
        for (var i = 0; i < fileComments.length; i++) {
          if (fileComments[i].author._account_id !== authorId) {
            continue;
          }
          var cDate = util.parseDate(fileComments[i].updated).getTime();
          if (cDate <= mDate) {
            if (nextMDate && cDate <= nextMDate) {
              continue;
            }
            msgComments[file] = msgComments[file] || [];
            msgComments[file].push(fileComments[i]);
          }
        }
      }
      return msgComments;
    },
  });
})();
<|endoftext|>


<commit_before><commit_msg>re-order each model sequencetionally after deleting one model<commit_after><|endoftext|>


<commit_before>dojo.provide("dijit.form.Slider");

dojo.require("dijit.form._FormWidget");
dojo.require("dijit._Container");
dojo.require("dojo.dnd.move");
dojo.require("dijit.form.Button");

dojo.declare(
	"dijit.form.HorizontalSlider",
	[dijit.form._FormWidget, dijit._Container],
{
	// summary
	//	A form widget that allows one to select a value with a horizontally draggable image

	templatePath: dojo.moduleUrl('dijit.form','templates/HorizontalSlider.html'),
	value: 0,

	// showButtons: boolean
	//	Show increment/decrement buttons at the ends of the slider?
	showButtons: true,

	// minimum:: integer
	//	The minimum value allowed.
	minimum: 0,

	// maximum: integer
	//	The maximum allowed value.
	maximum: 100,

	// discreteValues: integer
	//	The maximum allowed values dispersed evenly between minimum and maximum (inclusive).
	discreteValues: Infinity,

	// pageIncrement: integer
	//	The amount of change with shift+arrow
	pageIncrement: 2,

	// clickSelect: boolean
	//	If clicking the progress bar changes the value or not
	clickSelect: true,

	widgetsInTemplate: true,

	_mousePixelCoord: "pageX",
	_pixelCount: "w",
	_startingPixelCoord: "x",
	_startingPixelCount: "l",
	_handleOffsetCoord: "left",
	_progressPixelSize: "width",
	_upsideDown: false,

	 setDisabled: function(/*Boolean*/ disabled){
		if(this.showButtons){
			this.incrementButton.disabled = disabled;
			this.decrementButton.disabled = disabled;
		}
		dijit.form.HorizontalSlider.superclass.setDisabled.apply(this, arguments);
	 },

	_onKeyPress: function(/*Event*/ e){
		if(this.disabled || e.altKey || e.ctrlKey){ return; }
		switch(e.keyCode){
			case dojo.keys.HOME:
				this.setValue(this.minimum);
				break;
			case dojo.keys.END:
				this.setValue(this.maximum);
				break;
			case dojo.keys.UP_ARROW:
			case dojo.keys.RIGHT_ARROW:
			case dojo.keys.PAGE_UP:
				this.increment(e);
				break;
			case dojo.keys.DOWN_ARROW:
			case dojo.keys.LEFT_ARROW:
			case dojo.keys.PAGE_DOWN:
				this.decrement(e);
				break;
			default:
				this.inherited("_onKeyPress", arguments);
				return;
		}
		dojo.stopEvent(e);
	},

	_onHandleClick: function(e){
		if(this.disabled){ return; }
		dijit.focus(this.sliderHandle);
		dojo.stopEvent(e);
	},

	_onBarClick: function(e){
		if(this.disabled || !this.clickSelect){ return; }
		dojo.stopEvent(e);
		var abspos = dojo.coords(this.sliderBarContainer, true);
		var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
		this._setPixelValue(this._upsideDown ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true);
	},

	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean, optional*/ priorityChange){
		pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
		var count = this.discreteValues;
		if(count > maxPixels){ count = maxPixels; }
		count--;
		var pixelsPerValue = maxPixels / count;
		var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
		this.setValue((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange);
	},

	setValue: function(/*Number*/ value, /*Boolean, optional*/ priorityChange){
		this.valueNode.value = this.value = value;
		this.inherited('setValue', arguments);
		var percent = (value - this.minimum) / (this.maximum - this.minimum);
		this.progressBar.style[this._progressPixelSize] = (percent*100) + "%";
		this.remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%";
	},

	_bumpValue: function(signedChange){
		var s = dojo.getComputedStyle(this.sliderBarContainer);
		var c = dojo._getContentBox(this.sliderBarContainer, s);
		var count = this.discreteValues;
		if(count > c[this._pixelCount]){ count = c[this._pixelCount]; }
		count--;
		var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
		if(value < 0){ value = 0; }
		if(value > count){ value = count; }
		value = value * (this.maximum - this.minimum) / count + this.minimum;
		this.setValue(value);
	},

	decrement: function(e){
		// summary
		//	decrement slider by 1 unit
		this._bumpValue(e.keyCode == dojo.keys.PAGE_DOWN?-this.pageIncrement:-1);
	},

	increment: function(e){
		// summary
		//	increment slider by 1 unit
		this._bumpValue(e.keyCode == dojo.keys.PAGE_UP?this.pageIncrement:1);
	},

	_mouseWheeled: function(/*Event*/ evt){
		dojo.stopEvent(evt);
		var scrollAmount = 0;
		if(typeof evt.wheelDelta == 'number'){ // IE
			scrollAmount = evt.wheelDelta;
		}else if(typeof evt.detail == 'number'){ // Mozilla+Firefox
			scrollAmount = -evt.detail;
		}
		if(scrollAmount > 0){
			this.increment(evt);
		}else if(scrollAmount < 0){
			this.decrement(evt);
		}
	},

	startup: function(){
		dojo.forEach(this.getChildren(), function(child){
			if(this[child.container] != this.containerNode){
				this[child.container].appendChild(child.domNode);
			}
		}, this);
	},

	_onBlur: function(){
		dijit.form.HorizontalSlider.superclass.setValue.call(this, this.value, true);
	},

	postCreate: function(){
		if(this.showButtons){
			this.incrementButton.domNode.style.display="";
			this.decrementButton.domNode.style.display="";
		}
		this.sliderHandle.widget = this;

		this.connect(this.domNode, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
		new dojo.dnd.Moveable(this.sliderHandle, {mover: dijit.form._slider});
		this.inherited('postCreate', arguments);
	}
});

dojo.declare(
	"dijit.form.VerticalSlider",
	dijit.form.HorizontalSlider,
{
	// summary
	//	A form widget that allows one to select a value with a vertically draggable image

	templatePath: dojo.moduleUrl('dijit.form','templates/VerticalSlider.html'),
	_mousePixelCoord: "pageY",
	_pixelCount: "h",
	_startingPixelCoord: "y",
	_startingPixelCount: "t",
	_handleOffsetCoord: "top",
	_progressPixelSize: "height",
	_upsideDown: true
});

dojo.declare("dijit.form._slider",
	dojo.dnd.Mover,
{
	onMouseMove: function(e){
		var widget = this.node.widget;
		var c = this.constraintBox;
		if(!c){
			var container = widget.sliderBarContainer;
			var s = dojo.getComputedStyle(container);
			var c = dojo._getContentBox(container, s);
			c[widget._startingPixelCount] = 0;
			this.constraintBox = c;
		}
		var m = this.marginBox;
		var pixelValue = m[widget._startingPixelCount] + e[widget._mousePixelCoord];
		dojo.hitch(widget, "_setPixelValue")(widget._upsideDown? (c[widget._pixelCount]-pixelValue) : pixelValue, c[widget._pixelCount]);
	},

	destroy: function(e){
		var widget = this.node.widget;
		widget.setValue(widget.value, true);
		this.inherited('destroy', arguments);
	}
});

dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
{
	//	Summary:
	//		Create hash marks for the Horizontal slider
	templateString: '

',

	// count: Integer
	//      Number of hash marks to generate
	count: 3,

	// container: Node
	//      If this is a child widget, connect it to this parent node
	container: "containerNode",

	// ruleStyle: String
	//      CSS style to apply to individual hash marks
	ruleStyle: "",

	_positionPrefix: '

',

	_genHTML: function(pos, ndx){
		return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
	},

	postCreate: function(){
		if(this.count==1){
			var innerHTML = this._genHTML(50, 0);
		}else{
			var innerHTML = this._genHTML(0, 0);
			var interval = 100 / (this.count-1);
			for(var i=1; i < this.count-1; i++){
				innerHTML += this._genHTML(interval*i, i);
			}
			innerHTML += this._genHTML(100, this.count-1);
		}
		this.domNode.innerHTML = innerHTML;
	}
});

dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
{
	//	Summary:
	//		Create hash marks for the Vertical slider
	templateString: '

',
	_positionPrefix: '<div class="RuleMark VerticalRuleMark" style="top:'
});

dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
{
	//	Summary:
	//		Create labels for the Horizontal slider
	templateString: '

',

	// labelStyle: String
	//      CSS style to apply to individual text labels
	labelStyle: "",

	// labels: Array
	//	Array of text labels to render - evenly spaced from left-to-right or bottom-to-top
	labels: [],

	_positionPrefix: '
',
	_suffix: '
',

	_calcPosition: function(pos){
		return pos;
	},

	_genHTML: function(pos, ndx){
		return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle + this._labelPrefix + this.labels[ndx] + this._suffix;
	},

	postMixInProperties: function(){
		dijit.form.HorizontalRuleLabels.superclass.postMixInProperties.apply(this);
		if(!this.labels.length){
			// for markup creation, labels are specified as child elements
			this.labels = dojo.query("> li", this.srcNodeRef).map(function(node){
				return String(node.innerHTML);
			});
		}
		this.srcNodeRef.innerHTML="";
	},

	postCreate: function(){
		this.count = this.labels.length;
		dijit.form.HorizontalRuleLabels.superclass.postCreate.apply(this);
	}
});

dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
{
	//	Summary:
	//		Create labels for the Vertical slider
	templateString: '

',

	_positionPrefix: '
',

	_calcPosition: function(pos){
		return 100-pos;
	}
});
<commit_msg>Fixes #3983.  Special case discreteValues <= 1<commit_after>dojo.provide("dijit.form.Slider");

dojo.require("dijit.form._FormWidget");
dojo.require("dijit._Container");
dojo.require("dojo.dnd.move");
dojo.require("dijit.form.Button");

dojo.declare(
	"dijit.form.HorizontalSlider",
	[dijit.form._FormWidget, dijit._Container],
{
	// summary
	//	A form widget that allows one to select a value with a horizontally draggable image

	templatePath: dojo.moduleUrl('dijit.form','templates/HorizontalSlider.html'),
	value: 0,

	// showButtons: boolean
	//	Show increment/decrement buttons at the ends of the slider?
	showButtons: true,

	// minimum:: integer
	//	The minimum value allowed.
	minimum: 0,

	// maximum: integer
	//	The maximum allowed value.
	maximum: 100,

	// discreteValues: integer
	//	The maximum allowed values dispersed evenly between minimum and maximum (inclusive).
	discreteValues: Infinity,

	// pageIncrement: integer
	//	The amount of change with shift+arrow
	pageIncrement: 2,

	// clickSelect: boolean
	//	If clicking the progress bar changes the value or not
	clickSelect: true,

	widgetsInTemplate: true,

	_mousePixelCoord: "pageX",
	_pixelCount: "w",
	_startingPixelCoord: "x",
	_startingPixelCount: "l",
	_handleOffsetCoord: "left",
	_progressPixelSize: "width",
	_upsideDown: false,

	 setDisabled: function(/*Boolean*/ disabled){
		if(this.showButtons){
			this.incrementButton.disabled = disabled;
			this.decrementButton.disabled = disabled;
		}
		dijit.form.HorizontalSlider.superclass.setDisabled.apply(this, arguments);
	 },

	_onKeyPress: function(/*Event*/ e){
		if(this.disabled || e.altKey || e.ctrlKey){ return; }
		switch(e.keyCode){
			case dojo.keys.HOME:
				this.setValue(this.minimum);
				break;
			case dojo.keys.END:
				this.setValue(this.maximum);
				break;
			case dojo.keys.UP_ARROW:
			case dojo.keys.RIGHT_ARROW:
			case dojo.keys.PAGE_UP:
				this.increment(e);
				break;
			case dojo.keys.DOWN_ARROW:
			case dojo.keys.LEFT_ARROW:
			case dojo.keys.PAGE_DOWN:
				this.decrement(e);
				break;
			default:
				this.inherited("_onKeyPress", arguments);
				return;
		}
		dojo.stopEvent(e);
	},

	_onHandleClick: function(e){
		if(this.disabled){ return; }
		dijit.focus(this.sliderHandle);
		dojo.stopEvent(e);
	},

	_onBarClick: function(e){
		if(this.disabled || !this.clickSelect){ return; }
		dojo.stopEvent(e);
		var abspos = dojo.coords(this.sliderBarContainer, true);
		var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
		this._setPixelValue(this._upsideDown ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true);
	},

	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean, optional*/ priorityChange){
		pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
		var count = this.discreteValues;
		if(count > maxPixels || count <= 1){ count = maxPixels; }
		count--;
		var pixelsPerValue = maxPixels / count;
		var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
		this.setValue((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange);
	},

	setValue: function(/*Number*/ value, /*Boolean, optional*/ priorityChange){
		this.valueNode.value = this.value = value;
		this.inherited('setValue', arguments);
		var percent = (value - this.minimum) / (this.maximum - this.minimum);
		this.progressBar.style[this._progressPixelSize] = (percent*100) + "%";
		this.remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%";
	},

	_bumpValue: function(signedChange){
		var s = dojo.getComputedStyle(this.sliderBarContainer);
		var c = dojo._getContentBox(this.sliderBarContainer, s);
		var count = this.discreteValues;
		if(count > c[this._pixelCount] || count <= 1){ count = c[this._pixelCount]; }
		count--;
		var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
		if(value < 0){ value = 0; }
		if(value > count){ value = count; }
		value = value * (this.maximum - this.minimum) / count + this.minimum;
		this.setValue(value);
	},

	decrement: function(e){
		// summary
		//	decrement slider by 1 unit
		this._bumpValue(e.keyCode == dojo.keys.PAGE_DOWN?-this.pageIncrement:-1);
	},

	increment: function(e){
		// summary
		//	increment slider by 1 unit
		this._bumpValue(e.keyCode == dojo.keys.PAGE_UP?this.pageIncrement:1);
	},

	_mouseWheeled: function(/*Event*/ evt){
		dojo.stopEvent(evt);
		var scrollAmount = 0;
		if(typeof evt.wheelDelta == 'number'){ // IE
			scrollAmount = evt.wheelDelta;
		}else if(typeof evt.detail == 'number'){ // Mozilla+Firefox
			scrollAmount = -evt.detail;
		}
		if(scrollAmount > 0){
			this.increment(evt);
		}else if(scrollAmount < 0){
			this.decrement(evt);
		}
	},

	startup: function(){
		dojo.forEach(this.getChildren(), function(child){
			if(this[child.container] != this.containerNode){
				this[child.container].appendChild(child.domNode);
			}
		}, this);
	},

	_onBlur: function(){
		dijit.form.HorizontalSlider.superclass.setValue.call(this, this.value, true);
	},

	postCreate: function(){
		if(this.showButtons){
			this.incrementButton.domNode.style.display="";
			this.decrementButton.domNode.style.display="";
		}
		this.sliderHandle.widget = this;

		this.connect(this.domNode, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
		new dojo.dnd.Moveable(this.sliderHandle, {mover: dijit.form._slider});
		this.inherited('postCreate', arguments);
	}
});

dojo.declare(
	"dijit.form.VerticalSlider",
	dijit.form.HorizontalSlider,
{
	// summary
	//	A form widget that allows one to select a value with a vertically draggable image

	templatePath: dojo.moduleUrl('dijit.form','templates/VerticalSlider.html'),
	_mousePixelCoord: "pageY",
	_pixelCount: "h",
	_startingPixelCoord: "y",
	_startingPixelCount: "t",
	_handleOffsetCoord: "top",
	_progressPixelSize: "height",
	_upsideDown: true
});

dojo.declare("dijit.form._slider",
	dojo.dnd.Mover,
{
	onMouseMove: function(e){
		var widget = this.node.widget;
		var c = this.constraintBox;
		if(!c){
			var container = widget.sliderBarContainer;
			var s = dojo.getComputedStyle(container);
			var c = dojo._getContentBox(container, s);
			c[widget._startingPixelCount] = 0;
			this.constraintBox = c;
		}
		var m = this.marginBox;
		var pixelValue = m[widget._startingPixelCount] + e[widget._mousePixelCoord];
		dojo.hitch(widget, "_setPixelValue")(widget._upsideDown? (c[widget._pixelCount]-pixelValue) : pixelValue, c[widget._pixelCount]);
	},

	destroy: function(e){
		var widget = this.node.widget;
		widget.setValue(widget.value, true);
		this.inherited('destroy', arguments);
	}
});

dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
{
	//	Summary:
	//		Create hash marks for the Horizontal slider
	templateString: '

',

	// count: Integer
	//      Number of hash marks to generate
	count: 3,

	// container: Node
	//      If this is a child widget, connect it to this parent node
	container: "containerNode",

	// ruleStyle: String
	//      CSS style to apply to individual hash marks
	ruleStyle: "",

	_positionPrefix: '

',

	_genHTML: function(pos, ndx){
		return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
	},

	postCreate: function(){
		if(this.count==1){
			var innerHTML = this._genHTML(50, 0);
		}else{
			var innerHTML = this._genHTML(0, 0);
			var interval = 100 / (this.count-1);
			for(var i=1; i < this.count-1; i++){
				innerHTML += this._genHTML(interval*i, i);
			}
			innerHTML += this._genHTML(100, this.count-1);
		}
		this.domNode.innerHTML = innerHTML;
	}
});

dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
{
	//	Summary:
	//		Create hash marks for the Vertical slider
	templateString: '

',
	_positionPrefix: '<div class="RuleMark VerticalRuleMark" style="top:'
});

dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
{
	//	Summary:
	//		Create labels for the Horizontal slider
	templateString: '

',

	// labelStyle: String
	//      CSS style to apply to individual text labels
	labelStyle: "",

	// labels: Array
	//	Array of text labels to render - evenly spaced from left-to-right or bottom-to-top
	labels: [],

	_positionPrefix: '
',
	_suffix: '
',

	_calcPosition: function(pos){
		return pos;
	},

	_genHTML: function(pos, ndx){
		return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle + this._labelPrefix + this.labels[ndx] + this._suffix;
	},

	postMixInProperties: function(){
		dijit.form.HorizontalRuleLabels.superclass.postMixInProperties.apply(this);
		if(!this.labels.length){
			// for markup creation, labels are specified as child elements
			this.labels = dojo.query("> li", this.srcNodeRef).map(function(node){
				return String(node.innerHTML);
			});
		}
		this.srcNodeRef.innerHTML="";
	},

	postCreate: function(){
		this.count = this.labels.length;
		dijit.form.HorizontalRuleLabels.superclass.postCreate.apply(this);
	}
});

dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
{
	//	Summary:
	//		Create labels for the Vertical slider
	templateString: '

',

	_positionPrefix: '
',

	_calcPosition: function(pos){
		return 100-pos;
	}
});
<|endoftext|>


<commit_before>'use strict';

describe('DateService', function () {

    // load the controller's module
    beforeEach(module('codekvastApp'));

    var dateService,
        now = Date.now();

    // Initialize the services to test
    beforeEach(inject(function (_dateService_) {
        dateService = _dateService_;
    }));

    it('should calculate age since', function () {
        expect(dateService.getAgeSince(now, 0)).toBe("");
        expect(dateService.getAgeSince(now, now)).toBe("");
        expect(dateService.getAgeSince(now, now - 29000)).toBe("29s");
        expect(dateService.getAgeSince(now, now - 30000)).toBe("30s");
        expect(dateService.getAgeSince(now, now - 31000)).toBe("31s");
        expect(dateService.getAgeSince(now, now - 59000)).toBe("59s");
        expect(dateService.getAgeSince(now, now - 60000)).toBe("1m");
        expect(dateService.getAgeSince(now, now - 61000)).toBe("1m 1s");
        expect(dateService.getAgeSince(now, now - 119000)).toBe("1m 59s");
        expect(dateService.getAgeSince(now, now - 120000)).toBe("2m");
        expect(dateService.getAgeSince(now, now - 121000)).toBe("2m 1s");
        expect(dateService.getAgeSince(now, now - 59 * 60000)).toBe("59m");
        expect(dateService.getAgeSince(now, now - 60 * 60000)).toBe("1h");
        expect(dateService.getAgeSince(now, now - 24 * 60 * 60000)).toBe("1d");
        expect(dateService.getAgeSince(now, now - 7 * 24 * 60 * 60000 - 120 * 60000 - 60000 - 30000)).toBe("7d 2h 1m 30s");
    })

    it('should calculate age since', function () {
        expect(dateService.getAge(0)).toBe("");
    })

});
<commit_msg>Improved JavaScript test<commit_after>'use strict';

describe('DateService', function () {

    // load the controller's module
    beforeEach(module('codekvastApp'));

    var dateService,
        now = Date.now();

    // Initialize the services to test
    beforeEach(inject(function (_dateService_) {
        dateService = _dateService_;
    }));

    it('should calculate age since timestamp', function () {
        expect(dateService.getAgeSince(now, 0)).toBe("");
        expect(dateService.getAgeSince(now, now)).toBe("");
        expect(dateService.getAgeSince(now, now - 999)).toBe("");
        expect(dateService.getAgeSince(now, now - 1000)).toBe("1s");
        expect(dateService.getAgeSince(now, now - 1001)).toBe("1s");
        expect(dateService.getAgeSince(now, now - 29000)).toBe("29s");
        expect(dateService.getAgeSince(now, now - 30000)).toBe("30s");
        expect(dateService.getAgeSince(now, now - 31000)).toBe("31s");
        expect(dateService.getAgeSince(now, now - 59000)).toBe("59s");
        expect(dateService.getAgeSince(now, now - 60000)).toBe("1m");
        expect(dateService.getAgeSince(now, now - 61000)).toBe("1m 1s");
        expect(dateService.getAgeSince(now, now - 119000)).toBe("1m 59s");
        expect(dateService.getAgeSince(now, now - 120000)).toBe("2m");
        expect(dateService.getAgeSince(now, now - 121000)).toBe("2m 1s");
        expect(dateService.getAgeSince(now, now - 59 * 60000)).toBe("59m");
        expect(dateService.getAgeSince(now, now - 60 * 60000)).toBe("1h");
        expect(dateService.getAgeSince(now, now - 24 * 60 * 60000)).toBe("1d");
        expect(dateService.getAgeSince(now, now - 7 * 24 * 60 * 60000 - 120 * 60000 - 60000 - 30000)).toBe("7d 2h 1m 30s");
    })

    it('should calculate age since now', function () {
        expect(dateService.getAge(Date.now() - 32999)).toBe("32s");
    })

});
<|endoftext|>