<commit_before>// Senseway, a multi-channel timeline.
//

exports.add = (wayA, wayB) => {
  return wayA.map((ch, c) => ch.map((q, t) => q + wayB[c][t]))
}

exports.after = (way, t, len) => {
  if (typeof len === 'undefined') { len = way[0].length - t }
  return exports.slice(way, t, t + len)
}

exports.average = (ways) => {
  // Average way in the given array of ways.
  if (ways.length === 0) {
    return []
  }
  const initAcc = exports.fill(ways[0], 0)
  const waySum = ways.reduce((acc, w) => exports.add(acc, w), initAcc)
  return exports.scale(waySum, 1 / ways.length)
}

exports.before = (way, t, len) => {
  // Pick %len frames immediately before t, exclude frame t.
  //
  if (typeof len === 'undefined') { len = Math.max(0, t) }
  return exports.slice(way, t - len, t)
}

exports.channel = (way, c) => {
  // Pick one channel for a way.
  return [way[c]]
}

exports.channels = (way, cs) => {
  // Pick multiple channels
  return cs.map(c => way[c])
}

exports.clone = (way) => {
  return way.map((ch) => {
    return ch.slice()
  })
}

exports.create = (width, len, fill) => {
  if (typeof fill !== 'number') {
    throw new Error('Fill must be number')
  }

  const channels = [];
  let i, j, ch;
  for (i = 0; i < width; i += 1) {
    ch = [];
    for (j = 0; j < len; j += 1) {
      ch.push(fill)
    }
    channels.push(ch)
  }
  return channels
};

exports.dropAt = (way, t) => {
  // Remove frame at t
  const w = exports.clone(way)
  w.map((ch) => {
    return ch.splice(t, 1)
  })
  return w
}

exports.dropChannel = (way, channel) => {
  return way.filter((ch, c) => c !== channel)
}

exports.each = (way, iteratee) => {
  way.forEach((ch, c) => ch.forEach((q, t) => iteratee(q, c, t)))
}

exports.equal = (wayA, wayB) => {
  let i, j, ch
  for (i = 0; i < wayA.length; i += 1) {
    for (j = 0; j < wayA[0].length; j += 1) {
      if (wayA[i][j] !== wayB[i][j]) {
        return false
      }
    }
  }
  return true
}

exports.fill = (way, filler) => {
  // Same size, quanta replaced with filler.
  return way.map(ch => ch.map(q => filler))
}

exports.first = (way, n) => {
  // First n frames; the oldest
  return way.map(ch => ch.slice(0, n))
}

exports.frame = (way, t) => {
  return way.map(ch => [ch[t]]) // frame is an array of arrays
}

exports.increase = (way, addition) => {
  return way.map(ch => ch.map(quantum => quantum + addition))
}

exports.join = (wayA, wayB) => {
  if (wayA.length !== wayB.length) {
    throw new Error('Number of channels must match.')
  }
  return wayA.map((ch, c) => [].concat(ch, wayB[c]))
}

exports.last = (way, n) => {
  // Last n frames; the most recent
  return way.map(ch => ch.slice(ch.length - n, ch.length))
}

exports.len = (way) => {
  return way[0].length
}

exports.map = (way, fn) => {
  return way.map((ch, c) => ch.map((q, t) => fn(q, c, t)))
}

exports.map2 = (wayA, wayB, fn) => {
  return wayA.map((ch, c) => ch.map((q, t) => fn(q, wayB[c][t], c, t)))
}

exports.max = (way) => {
  // Largest value in the way. Returns scalar.
  return way.reduce((acc, ch) => {
    return ch.reduce((ac, q) => {
      return q > ac ? q : ac
    }, acc)
  }, way[0][0])
}

exports.mean = (way) => {
  // Returns a frame.
  return way.map((ch) => {
    return [ch.reduce((acc, q) => acc + q, 0) / ch.length]
  })
}

exports.min = (way) => {
  // Smallest value in the way.
  return way.reduce((acc, ch) => {
    return ch.reduce((ac, q) => {
      return q < ac ? q : ac
    }, acc)
  }, way[0][0])
}

exports.mix = (wayA, wayB) => {
  if (wayA[0].length !== wayB[0].length) {
    throw new Error('Length of channels must match.')
  }
  return [].concat(wayA, wayB)
}

exports.multiply = (wayA, wayB) => {
  return wayA.map((ch, c) => ch.map((q, t) => q * wayB[c][t]))
}

exports.normalize = (way) => {
  // Scale values within 0..1
  const minq = exports.min(way)
  const maxq = exports.max(way)
  if (minq === maxq) {
    if (minq === 0) {
      // All zeros
      return way
    }
    if (minq < 0) {
      return exports.map(way, q => 0)
    }
    return exports.map(way, q => 1)
  }
  return exports.map(way, q => (q - minq) / (maxq - minq))
}

exports.padLeft = (way, len, filler) => {
  if (way[0].length >= len) {
    return way
  }
  const head = exports.create(way.length, len - way[0].length, filler)
  return exports.join(head, way)
}

exports.padRight = (way, len, filler) => {
  if (way[0].length >= len) {
    return way
  }
  const tail = exports.create(way.length, len - way[0].length, filler)
  return exports.join(way, tail)
}

exports.reduce = (way, iteratee, acc) => {
  return way.reduce((ac, ch, c) => {
    return ch.reduce((a, q, t) => {
      return iteratee(a, q, c, t)
    }, ac)
  }, acc)
}

exports.repeatAt = (way, t) => {
  // Repeat frame at
  const w = exports.clone(way)
  w.map(ch => {
    const val = ch[t]
    return ch.splice(t, 0, val)
  })
  return w
}

exports.repeatChannel = (way, c) => {
  const w = way.slice()
  w.splice(c, 0, way[c])
  return w
}

exports.scale = (way, multiplier) => {
  return way.map(ch => ch.map(quantum => quantum * multiplier))
}

exports.set = (way, c, t, value) => {
  // Set value of a cell
  const w = exports.clone(way)
  w[c][t] = value
  return w
}

exports.slice = (way, begin, end) => {
  // Get a part of the way.
  //
  // Fill frames outside of way with zeros:
  //
  //   Example t=-1, e=1:
  //                          [w0] [w1] [w2]
  //                     [ 0] [ 0]
  //                     [ 0] [w0]
  //   -----------------b---------e---------------------
  //         -3   -2   -1    0    1    2    3    4
  //
  //   Example b=2, e=4:
  //                          [w0] [w1] [w2]
  //                                    [ 0] [ 0]
  //                                    [w2] [ 0]
  //   --------------------------------b---------e------
  //         -3   -2   -1    0    1    2    3    4
  //
  //   Example b=-1, e=4:
  //                          [w0] [w1] [w2]
  //                     [ 0] [ 0] [ 0] [ 0] [ 0]
  //                     [ 0] [w0] [w1] [w2] [ 0]
  //   -----------------b------------------------e------
  //         -3   -2   -1    0    1    2    3    4
  //                    |
  //                 t - len
  //
  const len = end - begin
  const width = exports.width(way)
  const wayLen = way[0].length

  const filler = 0
  const leftPadLen = Math.min(len, Math.max(0, -begin))
  const leftPad = exports.create(width, leftPadLen, filler)
  const rightPadLen = Math.min(len, Math.max(0, end - wayLen))
  const rightPad = exports.create(width,rightPadLen, filler)

  const a = Math.min(wayLen, Math.max(0, begin))
  const b = Math.min(wayLen, Math.max(0, end))
  const wayPart = way.map(ch => ch.slice(a, b))

  const leftPadded = exports.join(leftPad, wayPart)
  return exports.join(leftPadded, rightPad)
}

exports.sum = (way) => {
  // Sum quanta together.
  return way.reduce((acc, ch) => ch.reduce((ac, q) => ac + q, acc), 0)
}

exports.trim = (way, trimmee) => {
  // Remove leading and trailing frames whose cells only contain the trimmee.
  // For example way.trim(w, 1) trims:
  //   [[1, 0, 1],   to   [[0],
  //    [1, 1, 1]]         [1]]
  //
  trimmee = typeof trimmee === 'undefined' ? 0 : trimmee

  let begin = 0
  let end = 0

  const len = way[0].length
  for (let t = 0; t < len; t += 1) {
    if (way.some(ch => ch[t] !== trimmee)) {
      begin = t
      break
    }
  }

  for (let t = begin; t < len; t += 1) {
    if (way.some(ch => ch[t] !== trimmee)) {
      end = t + 1
    }
  }

  return way.map(ch => ch.slice(begin, end))
}

exports.width = (way) => {
  return way.length
}
<commit_msg>way.html<commit_after>// Senseway, a multi-channel timeline.
//

exports.add = (wayA, wayB) => {
  return wayA.map((ch, c) => ch.map((q, t) => q + wayB[c][t]))
}

exports.after = (way, t, len) => {
  if (typeof len === 'undefined') { len = way[0].length - t }
  return exports.slice(way, t, t + len)
}

exports.average = (ways) => {
  // Average way in the given array of ways.
  if (ways.length === 0) {
    return []
  }
  const initAcc = exports.fill(ways[0], 0)
  const waySum = ways.reduce((acc, w) => exports.add(acc, w), initAcc)
  return exports.scale(waySum, 1 / ways.length)
}

exports.before = (way, t, len) => {
  // Pick %len frames immediately before t, exclude frame t.
  //
  if (typeof len === 'undefined') { len = Math.max(0, t) }
  return exports.slice(way, t - len, t)
}

exports.channel = (way, c) => {
  // Pick one channel for a way.
  return [way[c]]
}

exports.channels = (way, cs) => {
  // Pick multiple channels
  return cs.map(c => way[c])
}

exports.clone = (way) => {
  return way.map((ch) => {
    return ch.slice()
  })
}

exports.create = (width, len, fill) => {
  if (typeof fill !== 'number') {
    throw new Error('Fill must be number')
  }

  const channels = [];
  let i, j, ch;
  for (i = 0; i < width; i += 1) {
    ch = [];
    for (j = 0; j < len; j += 1) {
      ch.push(fill)
    }
    channels.push(ch)
  }
  return channels
};

exports.dropAt = (way, t) => {
  // Remove frame at t
  const w = exports.clone(way)
  w.map((ch) => {
    return ch.splice(t, 1)
  })
  return w
}

exports.dropChannel = (way, channel) => {
  return way.filter((ch, c) => c !== channel)
}

exports.each = (way, iteratee) => {
  way.forEach((ch, c) => ch.forEach((q, t) => iteratee(q, c, t)))
}

exports.equal = (wayA, wayB) => {
  let i, j, ch
  for (i = 0; i < wayA.length; i += 1) {
    for (j = 0; j < wayA[0].length; j += 1) {
      if (wayA[i][j] !== wayB[i][j]) {
        return false
      }
    }
  }
  return true
}

exports.fill = (way, filler) => {
  // Same size, quanta replaced with filler.
  return way.map(ch => ch.map(q => filler))
}

exports.first = (way, n) => {
  // First n frames; the oldest
  return way.map(ch => ch.slice(0, n))
}

exports.frame = (way, t) => {
  return way.map(ch => [ch[t]]) // frame is an array of arrays
}

exports.html = (way, opts) => {
  const rev = opts.reversed ? true : false

  const len = exports.len(way)
  const width = exports.width(way)

  let tbegin = 0
  let tend = len
  let dt = 1
  if (rev) {
    tbegin = len - 1
    tend = -1
    dt = -1
  }

  let str = '
'
  for (let t = tbegin; (rev ? t > tend : t < tend); t += dt) {
    str += '
'
    for (let c = 0; c < width; c += 1) {
      const q = way[c][t]
      const title = q + ' @[' + c + '][' + t + ']'
      str += '
'
      str += '
'
    }
    str += '
'
  }
  str += '
'
  return str
}

exports.increase = (way, addition) => {
  return way.map(ch => ch.map(quantum => quantum + addition))
}

exports.join = (wayA, wayB) => {
  if (wayA.length !== wayB.length) {
    throw new Error('Number of channels must match.')
  }
  return wayA.map((ch, c) => [].concat(ch, wayB[c]))
}

exports.last = (way, n) => {
  // Last n frames; the most recent
  return way.map(ch => ch.slice(ch.length - n, ch.length))
}

exports.len = (way) => {
  return way[0].length
}

exports.map = (way, fn) => {
  return way.map((ch, c) => ch.map((q, t) => fn(q, c, t)))
}

exports.map2 = (wayA, wayB, fn) => {
  return wayA.map((ch, c) => ch.map((q, t) => fn(q, wayB[c][t], c, t)))
}

exports.max = (way) => {
  // Largest value in the way. Returns scalar.
  return way.reduce((acc, ch) => {
    return ch.reduce((ac, q) => {
      return q > ac ? q : ac
    }, acc)
  }, way[0][0])
}

exports.mean = (way) => {
  // Returns a frame.
  return way.map((ch) => {
    return [ch.reduce((acc, q) => acc + q, 0) / ch.length]
  })
}

exports.min = (way) => {
  // Smallest value in the way.
  return way.reduce((acc, ch) => {
    return ch.reduce((ac, q) => {
      return q < ac ? q : ac
    }, acc)
  }, way[0][0])
}

exports.mix = (wayA, wayB) => {
  if (wayA[0].length !== wayB[0].length) {
    throw new Error('Length of channels must match.')
  }
  return [].concat(wayA, wayB)
}

exports.multiply = (wayA, wayB) => {
  return wayA.map((ch, c) => ch.map((q, t) => q * wayB[c][t]))
}

exports.normalize = (way) => {
  // Scale values within 0..1
  const minq = exports.min(way)
  const maxq = exports.max(way)
  if (minq === maxq) {
    if (minq === 0) {
      // All zeros
      return way
    }
    if (minq < 0) {
      return exports.map(way, q => 0)
    }
    return exports.map(way, q => 1)
  }
  return exports.map(way, q => (q - minq) / (maxq - minq))
}

exports.padLeft = (way, len, filler) => {
  if (way[0].length >= len) {
    return way
  }
  const head = exports.create(way.length, len - way[0].length, filler)
  return exports.join(head, way)
}

exports.padRight = (way, len, filler) => {
  if (way[0].length >= len) {
    return way
  }
  const tail = exports.create(way.length, len - way[0].length, filler)
  return exports.join(way, tail)
}

exports.reduce = (way, iteratee, acc) => {
  return way.reduce((ac, ch, c) => {
    return ch.reduce((a, q, t) => {
      return iteratee(a, q, c, t)
    }, ac)
  }, acc)
}

exports.repeatAt = (way, t) => {
  // Repeat frame at
  const w = exports.clone(way)
  w.map(ch => {
    const val = ch[t]
    return ch.splice(t, 0, val)
  })
  return w
}

exports.repeatChannel = (way, c) => {
  const w = way.slice()
  w.splice(c, 0, way[c])
  return w
}

exports.scale = (way, multiplier) => {
  return way.map(ch => ch.map(quantum => quantum * multiplier))
}

exports.set = (way, c, t, value) => {
  // Set value of a cell
  const w = exports.clone(way)
  w[c][t] = value
  return w
}

exports.slice = (way, begin, end) => {
  // Get a part of the way.
  //
  // Fill frames outside of way with zeros:
  //
  //   Example t=-1, e=1:
  //                          [w0] [w1] [w2]
  //                     [ 0] [ 0]
  //                     [ 0] [w0]
  //   -----------------b---------e---------------------
  //         -3   -2   -1    0    1    2    3    4
  //
  //   Example b=2, e=4:
  //                          [w0] [w1] [w2]
  //                                    [ 0] [ 0]
  //                                    [w2] [ 0]
  //   --------------------------------b---------e------
  //         -3   -2   -1    0    1    2    3    4
  //
  //   Example b=-1, e=4:
  //                          [w0] [w1] [w2]
  //                     [ 0] [ 0] [ 0] [ 0] [ 0]
  //                     [ 0] [w0] [w1] [w2] [ 0]
  //   -----------------b------------------------e------
  //         -3   -2   -1    0    1    2    3    4
  //                    |
  //                 t - len
  //
  const len = end - begin
  const width = exports.width(way)
  const wayLen = way[0].length

  const filler = 0
  const leftPadLen = Math.min(len, Math.max(0, -begin))
  const leftPad = exports.create(width, leftPadLen, filler)
  const rightPadLen = Math.min(len, Math.max(0, end - wayLen))
  const rightPad = exports.create(width,rightPadLen, filler)

  const a = Math.min(wayLen, Math.max(0, begin))
  const b = Math.min(wayLen, Math.max(0, end))
  const wayPart = way.map(ch => ch.slice(a, b))

  const leftPadded = exports.join(leftPad, wayPart)
  return exports.join(leftPadded, rightPad)
}

exports.sum = (way) => {
  // Sum quanta together.
  return way.reduce((acc, ch) => ch.reduce((ac, q) => ac + q, acc), 0)
}

exports.trim = (way, trimmee) => {
  // Remove leading and trailing frames whose cells only contain the trimmee.
  // For example way.trim(w, 1) trims:
  //   [[1, 0, 1],   to   [[0],
  //    [1, 1, 1]]         [1]]
  //
  trimmee = typeof trimmee === 'undefined' ? 0 : trimmee

  let begin = 0
  let end = 0

  const len = way[0].length
  for (let t = 0; t < len; t += 1) {
    if (way.some(ch => ch[t] !== trimmee)) {
      begin = t
      break
    }
  }

  for (let t = begin; t < len; t += 1) {
    if (way.some(ch => ch[t] !== trimmee)) {
      end = t + 1
    }
  }

  return way.map(ch => ch.slice(begin, end))
}

exports.width = (way) => {
  return way.length
}
<|endoftext|>


<commit_before>// <%= name %>-model.js - A sequelize model
//
// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.

import Sequelize from 'sequelize';

export default function(sequelize) {
  let <%= name %> = sequelize.define('<%= name %>', {
    text: {
      type: Sequelize.STRING,
      allowNull: false,
      unique: true,
      validate: {
        isAlphaNumeric: { msg: '`text` must only contain alpha numeric characters' }
      }
    }
  }, {
    freezeTableName: true
  });

  <%= name %>.sync({ force: true });

  return <%= name %>;
}<commit_msg>Update sequelize.js<commit_after>// <%= name %>-model.js - A sequelize model
//
// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.

import Sequelize from 'sequelize';

export default function(sequelize) {
  let <%= name %> = sequelize.define('<%= name %>', {
    text: {
      type: Sequelize.STRING,
      allowNull: false,
      unique: true,
      validate: {
        isAlphanumeric: { msg: '`text` must only contain alpha numeric characters' }
      }
    }
  }, {
    freezeTableName: true
  });

  <%= name %>.sync({ force: true });

  return <%= name %>;
}
<|endoftext|>


<commit_before>
// Preloader is platform specific and required for lychee.Builder
(function(lychee, global) {

	var _loading = {},
		_assets = {},
		_data = {},
		_alreadyFired = {},
		_globalIntervalId = null;

	var Class = function(settings) {

		this.settings = lychee.extend({}, this.defaults, settings);

		this.__events = {};
		this.__lastLoadStart = null;

	};

	Class.prototype = {

		defaults: {
			interval:  100,
			timeout:  5000
		},

		bind: function(event, callback, scope) {

			event = typeof event === 'string' ? event : null;
			callback = callback instanceof Function ? callback : null;
			scope = scope !== undefined ? scope : this;

			if (event !== null && callback !== null) {

				this.__events[event] = {
					callback: callback,
					scope: scope
				};

			}

		},

		unbind: function(event) {

			event = typeof event === 'string' ? event : null;

			if (event !== null && this.__events[event] !== undefined) {
				delete this.__events[event];
			}

		},

		trigger: function(event, args) {

			args = Object.prototype.toString.call(args) === '[object Array]' ? args : [];

			if (this.__events[event] !== undefined) {
				this.__events[event].callback.apply(this.__events[event].scope, args);
			}

		},

		load: function(urls, data, forced) {

			data = data !== undefined ? data : null;
			forced = typeof forced === 'string' ? forced : null;

			this.__lastLoadStart = Date.now();

			if (Object.prototype.toString.call(urls) !== '[object Array]') {
				urls = [ urls ];
			}

			if (_globalIntervalId === null) {

				var that = this;
				_globalIntervalId = global.setInterval(function() {
					that.__loop();
				}, this.settings.interval);

			}

			for (var u = 0, l = urls.length; u < l; u++) {

				var url = urls[u];
				var tmp = url.split(/\./);
				var ext = tmp[tmp.length - 1];

				_data[url] = data;

				this.__load(url, forced || ext);

			}

		},

		get: function(url) {

			if (_assets[url] !== undefined) {
				return _assets[url];
			}

			return null;

		},

		__loop: function() {

			var isReady = true;

			var url;
			for (url in _loading) {
				if (_assets[url] === undefined) {
					isReady = false;
				}
			}

			var timedOut = false;
			if (this.__lastLoadStart !== null) {
				timedOut = Date.now() >= this.__lastLoadStart + this.settings.timeout;
			}

			var filtered = {};
			var data = {};
			var errors = {};
			if (
				isReady === true
				|| (timedOut && _globalIntervalId !== null)
			) {

				global.clearInterval(_globalIntervalId);
				_globalIntervalId = null;

				// 1. Handle Loading Failures
				if (timedOut) {

					for (var id in _loading) {
						if (timedOut && _loading[id] === true && _alreadyFired[id] !== true) {
							_alreadyFired[id] = true;
							errors[id] = _data[id] || null;
						}
					}

				}

				// 2. Handle (parsed) Assets
				for (var id in _assets) {
					if (_alreadyFired[id] !== true) {

						_alreadyFired[id] = true;

						// 2.1. Handle incorrect MIME types
						if (_assets[id] === null) {

							errors[id] = _data[id] || null;

						// 2.2. Handle correct MIME types
						} else {

							filtered[id] = _assets[id];
							data[id] = _data[id] || null;

						}

					}
				}

				if (Object.keys(errors).length > 0) {
					this.trigger('error', [ errors ]);
				}

				this.trigger('ready', [ filtered, data ]);

			}

		},

		__load: function(url, type) {

			var that = this;

			if (type.match(/jpg|jpeg|png|bmp|gif/)) {

				_loading[url] = true;

				var img = new Image();
				img.onload = function() {
					_loading[url] = false;
					_assets[url] = this;
				};
				img.src = url;

			} else if (type === 'css') {

				// CSS won't affect JavaScript stuff

				_loading[url] = false;
				_assets[url] = '';

				var link = document.createElement('link');
				link.rel = 'stylesheet';
				link.href = url;

				document.head.appendChild(link);

			} else if (type === 'js') {

				_loading[url] = true;

				var script = document.createElement('script');
				script.async = true;

				script.onload = function() {
					_loading[url] = false;
					_assets[url] = '';
				};

				/*
				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, true);
				xhr.onreadystatechange = function() {

					if (xhr.readyState === 4 && xhr.status === 200 || xhr.status === 304) {
						var data = xhr.responseText || xhr.responseText || null;
						_assets[url] = data;
					}

				};

				xhr.send(null);
				*/

				script.src = url;
				document.body.appendChild(script);

			} else if (type === 'json') {

				_loading[url] = true;

				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, true);
				xhr.setRequestHeader('Content-Type', 'application/json; charset=utf8');

				xhr.onreadystatechange = function() {

					if (xhr.readyState === 4) {

						var data = null;
						try {
							data = JSON.parse(xhr.responseText);
						} catch(e) {
							console.warn('JSON file at ' + url + ' is invalid.');
						}

						// Null will throw MIME errors
						_assets[url] = data;
						_loading[url] = false;

					}

				};

				xhr.send(null);

			} else {

				_loading[url] = true;

				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, true);

				xhr.onreadystatechange = function() {

					if (xhr.readyState === 4 && xhr.status === 200 || xhr.status === 304) {

						var data = xhr.responseText || xhr.responseText || null;

						if (data !== null) {
							_loading[url] = false;
							_assets[url] = data;
						} else {
							_loading[url] = false;
						}

					}

				};

				xhr.send(null);

			}

		}

	};

	lychee.Preloader = Class;

})(this.lychee, this);

<commit_msg>lychee.Preloader (html platform): New implementation supports multiple instances that dont collide in their fired events. Preloader is now theoretically movable to core via using a plugin for _load().<commit_after>
// Preloader is platform specific and required for lychee.Builder
(function(lychee, global) {

	var _instances = [];
	var _cache = {};

	var _globalIntervalId = null;
	var _globalInterval   = function() {

		var timedOutInstances = 0;

		for (var i = 0, l = _instances.length; i < l; i++) {

			var instance = _instances[i];
			var isReady  = true;

			for (var url in instance.__pending) {
				if (
					instance.__pending[url] === true
					|| _cache[url] === undefined
				) {
					isReady = false;
				}
			}

			var timedOut = false;
			if (instance.__clock !== null) {
				timedOut = Date.now() >= instance.__clock + instance.__timeout;
			}

			if (isReady === true || timedOut === true) {

				var errors = {};
				var ready  = {};
				var map    = {};

				for (var url in instance.__pending) {

					if (instance.__fired[url] === undefined) {

						if (instance.__pending[url] === false) {

							ready[url] = _cache[url] || null;
							map[url] = instance.__map[url] || null;

						} else {
							errors[url] = null;
						}

						instance.__fired[url] = true;

					}

				}

				if (Object.keys(errors).length > 0) {
					instance.trigger('error', [ errors ]);
				}

				if (Object.keys(ready).length > 0) {
					instance.trigger('ready', [ ready, map ]);
				}

				// Reset the clock if the lychee.Preloader timed out
				if (timedOut === true) {
					timedOutInstances++;
				}

			}

		}

		if (timedOutInstances === _instances.length) {

			if (lychee.debug === true) {
				console.log('lychee.Preloader: Nothing to do, switching to idle mode.');
			}

			for (var i = 0, l = _instances.length; i < l; i++) {
				_instances[i].__clock = null;
			}

			global.clearInterval(_globalIntervalId);
			_globalIntervalId = null;

		}

	};

	var Class = function(data) {

		var settings = lychee.extend({}, data);

		settings.timeout  = typeof settings.timeout === 'number' ? settings.timeout : this.defaults.timeout;

		this.__timeout  = settings.timeout;

		this.__events  = {};
		this.__fired   = {}; // cached fired events per request
		this.__map     = {}; // associated data per request
		this.__pending = {}; // pending requests
		this.__clock   = null;

		_instances.push(this);

		settings = null;

	};

	Class.prototype = {

		defaults: {
			timeout: 3000
		},

		/*
		 * EVENT BINDINGS
		 *
		 * (not using lychee.Events
		 *  due to no-dependency
		 *  reasons)
		 */

		bind: function(event, callback, scope) {

			event = typeof event === 'string' ? event : null;
			callback = callback instanceof Function ? callback : null;
			scope = scope !== undefined ? scope : this;

			if (event !== null && callback !== null) {

				this.__events[event] = {
					callback: callback,
					scope: scope
				};

			}

		},

		unbind: function(event) {

			event = typeof event === 'string' ? event : null;

			if (event !== null && this.__events[event] !== undefined) {
				delete this.__events[event];
				return true;
			}

			return false;

		},

		trigger: function(event, args) {

			args = Object.prototype.toString.call(args) === '[object Array]' ? args : [];

			if (this.__events[event] !== undefined) {
				this.__events[event].callback.apply(this.__events[event].scope, args);
				return true;
			}

			return false;

		},

		/*
		 * PUBLIC API
		 */

		load: function(urls, map, forced) {

			urls = typeof urls === 'string' ? [ urls ] : urls;
			map = map !== undefined ? map : null;
			forced = typeof forced === 'string' ? forced : null;

			if (Object.prototype.toString.call(urls) !== '[object Array]') {
				return false;
			}

			this.__clock = Date.now();

			// 1. Load the assets via platform-specific APIs
			for (var u = 0, l = urls.length; u < l; u++) {

				var url = urls[u];
				var tmp = url.split(/\./);

				if (this.__pending[url] === undefined) {

					if (map !== null) {
						this.__map[url] = map;
					}

					// 1.1 Check if another lychee.Preloader
					// instance already loaded the requested
					// URL to the shared cache.

					if (_cache[url] != null) {

						this.__pending[url] = false;

					} else {

						if (forced !== null) {
							this._load(url, forced);
						} else {
							this._load(url, tmp[tmp.length - 1]);
						}

					}

				}

			}

			// 2. Start the global interval
			if (_globalIntervalId === null) {
				_globalIntervalId = global.setInterval(function() {
					_globalInterval();
				}, 100);
			}

		},

		get: function(url) {

			if (_cache.resource[url] !== undefined) {
				return _cache.resource[url];
			}

			return null;

		},

		/*
		 * PLATFORM-SPECIFIC Implementation
		 */

		_load: function(url, type) {

			var that = this;

			// 1. JavaScript
			if (type === 'js') {

				this.__pending[url] = true;

				var script = document.createElement('script');
				script.async = true;
				script.onload = function() {
					that.__pending[url] = false;
					_cache[url] = '';
				};
				script.src = url;

				document.body.appendChild(script);

			// 2. JSON
			} else if (type === 'json') {

				this.__pending[url] = true;

				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, true);
				xhr.setRequestHeader('Content-Type', 'application/json; charset=utf8');
				xhr.onreadystatechange = function() {

					if (xhr.readyState === 4) {

						var data = null;
						try {
							data = JSON.parse(xhr.responseText);
						} catch(e) {
							console.warn('JSON file at ' + url + ' is invalid.');
						}

						that.__pending[url] = false;
						_cache[url] = data;

					}

				};

				xhr.send(null);

			// 3. Images
			} else if (type.match(/bmp|gif|jpg|jpeg|png/)) {

				this.__pending[url] = true;

				var img = new Image();
				img.onload = function() {
					that.__pending[url] = false;
					_cache[url] = this;
				};
				img.src = url;

			// 4. CSS (won't affect JavaScript anyhow)
			} else if (type === 'css') {

				this.__pending[url] = false;
				_cache[url] = '';

				var link = document.createElement('link');
				link.rel = 'stylesheet';
				link.href = url;

				document.head.appendChild(link);

			// 5. Unknown File Types (will be load as text)
			} else {

				this.__pending[url] = true;

				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, true);
				xhr.onreadystatechange = function() {

					if (xhr.readyState === 4 && xhr.status === 200 || xhr.status === 304) {

						var data = xhr.responseText || xhr.responseXML || null;

						that.__pending[url] = false;
						_cache[url] = data;

					}

				};

				xhr.send(null);

			}

		}

	};

	lychee.Preloader = Class;

})(this.lychee, this);

<|endoftext|>


<commit_before>armylister.addArmy("Tau", {
  "equipment": [
    //Battlesuit Weapon Systems
    {"name": "Airbusting Fragmentation Projector", "points": 20, "flags": ["battlesuit weapon", "special issue"]},
    {"name": "Burst cannon", "points": 8, "flags": ["battlesuit weapon"]},
    {"name": "Burst cannon Twin-Linked", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Cyclic Ion Blaser", "points": 15, "flags": ["battlesuit weapon", "special issue"]},
    {"name": "Flamer", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Flamer Twin-Linked", "points": 18, "flags": ["battlesuit weapon"]},
    {"name": "Fusion blaster", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Fusion blaster Twin-Linked", "points": 18, "flags": ["battlesuit weapon"]},
    {"name": "Missle pod", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Missle pod Twin-Linked", "points": 18, "flags": ["battlesuit weapon"]},
    {"name": "Plasma rifle", "points": 20, "flags": ["battlesuit weapon"]},
    {"name": "Plasma rifle Twin-Linked", "points": 30, "flags": ["battlesuit weapon"]},
    //Battlesuit support systems
    {"name": "Advanced Stabilisation System", "points": 10, "flags": ["battlesuit support"]},
    {"name": "Blacksun Filter", "points": 3, "flags": ["battlesuit support"]},
    {"name": "Command & Control node", "points": 10, "flags": ["battlesuit support", "special issue"]},
    {"name": "Drone Controller", "points": 0, "flags": ["battlesuit support"]},
    {"name": "Multi-Tracker", "points": 5, "flags": ["battlesuit support"]},
    {"name": "Positional Relay", "points": 15, "flags": ["battlesuit support", "special issue"]},
    {"name": "Shield generator", "points": 20, "flags": ["battlesuit support"]},
    {"name": "Target lock", "points": 5, "flags": ["battlesuit support"]},
    {"name": "Targetting array", "points": 10, "flags": ["battlesuit support"]},
    {"name": "Vectored retro-thrusters", "points": 10, "flags": ["battlesuit support", "special issue"]},
    //Battelsuit Wargear
    {"name": "Bonding Knife", "points": 5, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Ejection System", "points": 15, "flags": ["battlesuit wargear", "special issue"]},
    {"name": "Failsafe detonator", "points": 15, "flags": ["battlesuit wargear", "special issue"]},
    {"name": "Gun Drone", "points": 10, "flags": ["battlesuit wargear"]},
    {"name": "Iridium Armor", "points": 20, "flags": ["battlesuit wargear"]},
    {"name": "Hard-wired blacksun filter", "points": 3, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Hard-wired drone controller", "points": 0, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Hard-wired multi-tracker", "points": 5, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Hard-wired target lock", "points": 5, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Marker drone", "points": 30, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Shield Drone", "points": 15, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Stimulant injector", "points": 10, "flags": ["battlesuit wargear", "special issue", "infantry"]}
    //Infantry Wargear (rest is already included above)
    {"name": "EMP Grenades", "points":  5, "flags": ["infantry"]},
    {"name": "Honour Blade", "points":  10, "flags": ["ethereal"]},
    //Vehicle Upgrade
    {"name": "Sensor spines", "points":  10, "flags": ["vehicle"]},
    {"name": "Targeting array", "points":  5, "flags": ["vehicle"]},
    {"name": "Multi-tracker", "points":  10, "flags": ["vehicle"]},
    {"name": "Blacksun Filter", "points":  5, "flags": ["vehicle"]},
    {"name": "Target Lock", "points":  5, "flags": ["vehicle"]},
    {"name": "Flechette Discharger", "points":  10, "flags": ["vehicle"]},
    {"name": "Disruption Pod", "points":  5, "flags": ["vehicle"]},
    {"name": "Decoy launchers", "points":  5, "flags": ["vehicle"]},
    {"name": "seeker missle", "points":  10, "maxcount": 2, "flags": ["vehicle"]},
  ],
  "units": [
    {"name": "Commander", "mincount": 1, "type": "HQ"
      "troops": [
        {"name": "Shas'o", "points": 75, "mincount": 1, "maxcount": 1,
          "upgrades": [{"name": "Shas'el", "points": 25},
            {"type": "equipment", "filter": ["+battlesuit support", "+battlesuit weapon"], "mincount": 3, "maxcount": 3},
            {"type": "equipment", "filter": ["+battlesuit wargear"]}
          ]}
        {"name": "Shas'vre", "points": 35, "mincount": 0, "maxcount": 2,
          "upgrades": [{"type": "equipment", "filter": ["+battlesuit support", "+battlesuit weapon"], "mincount": 3, "maxcount": 3},
            {"type": "equipment", "filter": ["+battlesuit wargear"]}
        ]}
       ]
    },
    {"name": "Ethereal", "type": "HQ",
      "troops": [{"name": "Ethereal", "points": 50,
        "upgrades": [{"type": "equipment", "filter": ["+infantry", "+ethereal"]}]},
      //TODO: Special Firewarrior unit
      ]
    },
    {"name": "XV8 'Crisis' Battlesuit Team", "type": "Elite",
      "troops": [{"name": "Shas'ui", "points": 25, "upgrades": [
        {"type": "equipment", "filter": ["+battlesuit support", "+battlesuit weapon"], "mincount": 3, "maxcount": 3},
        {"name": "Team Leader", "points": 5, "maxcount": 1, "upgrades": [
          {"type": "equipment", "filter": ["+battlesuit wargear", "-special issue"]},
          {"name": "Shas'vre", "points": 5, "maxcount": 1, "upgrades": [{"type": "equipment", "filter": ["+battlesuit wargear"]}]}
        ]}]}
      ]
    }
    {"name": "Stealth Team", "type": "Elite",
      "troops":[{"name": "Shas'ui", "points": 30, "notes": [
        "Either all or none select wargear upgrades",
        "Max. 1 in 3 models may upgrade to fusion blaster"
      ], "upgrades": [{"name": "Team Leader", "points": 5, "maxcount": 1, "upgrades": [
          {"type": "equipment", "filter": ["+battlesuit wargear", "-special issue"]},
          {"name": "Shas'vre", "points": 5, "maxcount": 1, "upgrades": [
            {"type": "equipment", "name": "markerlight", "points": 10}]}
        ]}]}]
    }
  ]
});<commit_msg>Firewarriors<commit_after>armylister.addArmy("Tau", {
  "organization": {
    {"name": "HQ", "mincount": 1, "maxcount": 2},
    {"name": "Elite", "maxcount": 3},
    {"name": "Troops", "mincount": 1, "maxcount": 6},
    {"name": "Fast Attack", "maxcount": 3},
    {"name": "Heavy Support", "maxcount": 3},
  },
  "equipment": [
    //Battlesuit Weapon Systems
    {"name": "Airbusting Fragmentation Projector", "points": 20, "flags": ["battlesuit weapon", "special issue"]},
    {"name": "Burst cannon", "points": 8, "flags": ["battlesuit weapon"]},
    {"name": "Burst cannon Twin-Linked", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Cyclic Ion Blaser", "points": 15, "flags": ["battlesuit weapon", "special issue"]},
    {"name": "Flamer", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Flamer Twin-Linked", "points": 18, "flags": ["battlesuit weapon"]},
    {"name": "Fusion blaster", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Fusion blaster Twin-Linked", "points": 18, "flags": ["battlesuit weapon"]},
    {"name": "Missle pod", "points": 12, "flags": ["battlesuit weapon"]},
    {"name": "Missle pod Twin-Linked", "points": 18, "flags": ["battlesuit weapon"]},
    {"name": "Plasma rifle", "points": 20, "flags": ["battlesuit weapon"]},
    {"name": "Plasma rifle Twin-Linked", "points": 30, "flags": ["battlesuit weapon"]},
    //Battlesuit support systems
    {"name": "Advanced Stabilisation System", "points": 10, "flags": ["battlesuit support"]},
    {"name": "Blacksun Filter", "points": 3, "flags": ["battlesuit support"]},
    {"name": "Command & Control node", "points": 10, "flags": ["battlesuit support", "special issue"]},
    {"name": "Drone Controller", "points": 0, "flags": ["battlesuit support"]},
    {"name": "Multi-Tracker", "points": 5, "flags": ["battlesuit support"]},
    {"name": "Positional Relay", "points": 15, "flags": ["battlesuit support", "special issue"]},
    {"name": "Shield generator", "points": 20, "flags": ["battlesuit support"]},
    {"name": "Target lock", "points": 5, "flags": ["battlesuit support"]},
    {"name": "Targetting array", "points": 10, "flags": ["battlesuit support"]},
    {"name": "Vectored retro-thrusters", "points": 10, "flags": ["battlesuit support", "special issue"]},
    //Battelsuit Wargear
    {"name": "Bonding Knife", "points": 5, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Ejection System", "points": 15, "flags": ["battlesuit wargear", "special issue"]},
    {"name": "Failsafe detonator", "points": 15, "flags": ["battlesuit wargear", "special issue"]},
    {"name": "Gun Drone", "points": 10, "flags": ["battlesuit wargear"]},
    {"name": "Iridium Armor", "points": 20, "flags": ["battlesuit wargear"]},
    {"name": "Hard-wired blacksun filter", "points": 3, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Hard-wired drone controller", "points": 0, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Hard-wired multi-tracker", "points": 5, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Hard-wired target lock", "points": 5, "count": 0, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Marker drone", "points": 30, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Shield Drone", "points": 15, "flags": ["battlesuit wargear", "infantry"]},
    {"name": "Stimulant injector", "points": 10, "flags": ["battlesuit wargear", "special issue", "infantry"]}
    //Infantry Wargear (rest is already included above)
    {"name": "EMP Grenades", "points":  5, "flags": ["infantry"]},
    {"name": "Honour Blade", "points":  10, "flags": ["ethereal"]},
    //Vehicle Upgrade
    {"name": "Sensor spines", "points":  10, "flags": ["vehicle"]},
    {"name": "Targeting array", "points":  5, "flags": ["vehicle"]},
    {"name": "Multi-tracker", "points":  10, "flags": ["vehicle"]},
    {"name": "Blacksun Filter", "points":  5, "flags": ["vehicle"]},
    {"name": "Target Lock", "points":  5, "flags": ["vehicle"]},
    {"name": "Flechette Discharger", "points":  10, "flags": ["vehicle"]},
    {"name": "Disruption Pod", "points":  5, "flags": ["vehicle"]},
    {"name": "Decoy launchers", "points":  5, "flags": ["vehicle"]},
    {"name": "seeker missle", "points":  10, "maxcount": 2, "flags": ["vehicle"]},
  ],
  "units": [
    {"name": "Commander", "mincount": 1, "type": "HQ"
      "troops": [
        {"name": "Shas'o", "points": 75, "mincount": 1, "maxcount": 1,
          "upgrades": [{"name": "Shas'el", "points": 25},
            {"type": "equipment", "filter": ["+battlesuit support", "+battlesuit weapon"], "mincount": 3, "maxcount": 3},
            {"type": "equipment", "filter": ["+battlesuit wargear"]}
          ]}
        {"name": "Shas'vre", "points": 35, "mincount": 0, "maxcount": 2,
          "upgrades": [{"type": "equipment", "filter": ["+battlesuit support", "+battlesuit weapon"], "mincount": 3, "maxcount": 3},
            {"type": "equipment", "filter": ["+battlesuit wargear"]}
        ]}
       ]
    },
    {"name": "Ethereal", "type": "HQ",
      "troops": [{"name": "Ethereal", "points": 50,
        "upgrades": [{"type": "equipment", "filter": ["+infantry", "+ethereal"]}]},
      //TODO: Special Firewarrior unit
      ]
    },
    {"name": "XV8 'Crisis' Battlesuit Team", "type": "Elite",
      "troops": [{"name": "Shas'ui", "points": 25, "upgrades": [
        {"type": "equipment", "filter": ["+battlesuit support", "+battlesuit weapon"], "mincount": 3, "maxcount": 3},
        {"name": "Team Leader", "points": 5, "maxcount": 1, "upgrades": [
          {"type": "equipment", "filter": ["+battlesuit wargear", "-special issue"]},
          {"name": "Shas'vre", "points": 5, "maxcount": 1, "upgrades": [{"type": "equipment", "filter": ["+battlesuit wargear"]}]}
        ]}]}
      ]
    },
    {"name": "Stealth Team", "type": "Elite",
      "troops":[{"name": "Shas'ui", "points": 30, "notes": [
        "Either all or none select wargear upgrades",
        "Max. 1 in 3 models may upgrade to fusion blaster"
      ], "upgrades": [{"name": "Fusion blaster", "type": "equipment", "points": 2},
          {"name": "Team Leader", "points": 5, "maxcount": 1, "upgrades": [
            {"type": "equipment", "filter": ["+battlesuit wargear", "-special issue"]},
            {"name": "Shas'vre", "points": 5, "maxcount": 1, "upgrades": [
              {"type": "equipment", "name": "markerlight", "points": 10}]}]}
        ]}]
    },
    {"name": "Fire Warriors", "type": "Troops", "mincount": 1,
      "troops":[{"name": "Shas'la", "points": 10, "mincount": 6, "maxcount": 12, "upgrades": [
        {"name": "Pulse rifle", "type": "equipment", "points": 0},
        {"name": "EMP grenades", "type": "equipment", "points": 3, "all": true},
        {"name": "Photon grenades", "type": "equipment", "points": 1, "all": true}
        {"name": "Shas'ui", "points": 10, "upgrades": [
          {"type": "equipment", "filter": ["+infantry", "-special issue"]},
          {"type": "equipment", "name": "markerlight", "points": 10}
          ]}
        {"name": "Devilfish", "type": "equipment", "points": 80, "maxcount": 1,
          "upgrades": [{"name": "Smart missle system", "type": "equipment", "points": 20}
            {"type": "equipment", "filter": ["+vehicle", "-special issue"]},
          ]
        } //devilfish
        ]}]
    },
    {"name": "Kroot Carnivore Squad", "type": "Troops", }
  ]
});<|endoftext|>


<commit_before>var d = require ('dequeue');
var seatStateStore = require("./SeatStateStore");
var redis = require("redis");
var rClient = redis.createClient();
var dgram = require("dgram");

var FIFO = new d();

fetcher();

var udpserver = dgram.createSocket("udp4");

udpserver.on("message",
    function (msg, rinfo) {

        FIFO.push(msg);
    }
);

udpserver.bind(4444);
var index;
function fetcher () {
    while (FIFO.length > 0) {
        index++;
        var msg = FIFO.shift();
        console.log(msg);
        //rClient.hset("raw", "data"+index, msg);
        seatStateStore.parseMessage(msg);
        process.nextTick(fetcher);
    }
}

///<commit_msg>Update UDPefef<commit_after>var d = require ('dequeue');
var seatStateStore = require("./SeatStateStore");
var redis = require("redis");
var rClient = redis.createClient();
var dgram = require("dgram");

var FIFO = new d();

fetcher();

var udpserver = dgram.createSocket("udp4");

udpserver.on("message",
    function (msg, rinfo) {

        FIFO.push(msg);
    }
);

udpserver.bind(4444);

function fetcher () {
    while (FIFO.length > 0) {

        var msg = FIFO.shift();
        console.log("Goi tin: ", msg);
        //rClient.hset("raw", "data"+index, msg);
        seatStateStore.parseMessage(msg);
        process.nextTick(fetcher);
    }
}

///<|endoftext|>


<commit_before>var d = require ('dequeue');
var seatStateStore = require("./SeatStateStore");
var redis = require("redis");
var rClient = redis.createClient();
var dgram = require("dgram");

var FIFO = new d();

fetcher();

var udpserver = dgram.createSocket("udp4");

udpserver.on("message",
    function (msg, rinfo) {
        FIFO.push(msg.toString());
        //console.log("MSG", msg);
    }
);

udpserver.bind(4444);

function fetcher () {
    while (FIFO.length > 0)
    {
        var msg = FIFO.shift();
        //seatStateStore.parseMessage(msg);
        console.log("mg:", msg);
        console.log("vc", FIFO);
    }
    setImmediate(fetcher); //make this function continuously run
}

///<commit_msg>Update UDPefef<commit_after>var d = require ('dequeue');
var seatStateStore = require("./SeatStateStore");
var redis = require("redis");
var rClient = redis.createClient();
var dgram = require("dgram");

var FIFO = new d();

fetcher();

var udpserver = dgram.createSocket("udp4");

udpserver.on("message",
    function (msg, rinfo) {
        FIFO.push(msg.toString());
        //console.log("MSG", msg);
    }
);

udpserver.bind(4444);
var index =0;
function fetcher () {
    while (FIFO.length > 0)
    {
        index++;
        var msg = FIFO.shift();
        rClient.hset("raw", "data"+index, msg);
    }
    setImmediate(fetcher); //make this function continuously run
}

///<|endoftext|>


<commit_before>//load env vars
require('dotenv-safe').load();

const http = require('http');
const Stats = require('./application/stats.js');
const stats = new Stats(process.env.STATS_PATH);

const server = http.createServer((req, res) => {
    stats.collect((err, data) => {
        if(err){
            res.statusCode = 403;
            res.end(err);
            return;
        }
        res.end(data);
    });
});

const host = process.env.WEB_HOST || 'localhost';
const port = process.env.WEB_PORT || 3000;
server.listen(port, host, () => {

    console.log(`Server running at http://${host}:${port}/`);
});
<commit_msg>Changed default host<commit_after>//load env vars
require('dotenv-safe').load();

const http = require('http');
const Stats = require('./application/stats.js');
const stats = new Stats(process.env.STATS_PATH);

const server = http.createServer((req, res) => {
    stats.collect((err, data) => {
        if(err){
            res.statusCode = 403;
            res.end(err);
            return;
        }
        res.end(data);
    });
});

const host = process.env.WEB_HOST || '127.0.0.1';
const port = process.env.WEB_PORT || 3000;
server.listen(port, host, () => {

    console.log(`Server running at http://${host}:${port}/`);
});
<|endoftext|>


<commit_before>'use strict'

const ipcMain = require('electron').ipcMain
const EventEmitter = require('events').EventEmitter
const {BrowserWindow} = process.atomBinding('window')

Object.setPrototypeOf(BrowserWindow.prototype, EventEmitter.prototype)

BrowserWindow.prototype._init = function () {
  // avoid recursive require.
  var app, menu
  app = require('electron').app

  // Simulate the application menu on platforms other than OS X.
  if (process.platform !== 'darwin') {
    menu = app.getApplicationMenu()
    if (menu != null) {
      this.setMenu(menu)
    }
  }

  // Make new windows requested by links behave like "window.open"
  this.webContents.on('-new-window', (event, url, frameName, disposition) => {
    var options
    options = {
      show: true,
      width: 800,
      height: 600
    }
    return ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, disposition, options)
  })

  // window.resizeTo(...)
  // window.moveTo(...)
  this.webContents.on('move', (event, size) => {
    this.setBounds(size)
  })

  // Hide the auto-hide menu when webContents is focused.
  this.webContents.on('activate', () => {
    if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
      this.setMenuBarVisibility(false)
    }
  })

  // Forward the crashed event.
  this.webContents.on('crashed', () => {
    this.emit('crashed')
  })

  // Change window title to page title.
  this.webContents.on('page-title-updated', (event, title) => {
    // The page-title-updated event is not emitted immediately (see #3645), so
    // when the callback is called the BrowserWindow might have been closed.
    if (this.isDestroyed()) return

    // Route the event to BrowserWindow.
    this.emit('page-title-updated', event, title)
    if (!event.defaultPrevented) this.setTitle(title)
  })

  // Sometimes the webContents doesn't get focus when window is shown, so we have
  // to force focusing on webContents in this case. The safest way is to focus it
  // when we first start to load URL, if we do it earlier it won't have effect,
  // if we do it later we might move focus in the page.
  // Though this hack is only needed on OS X when the app is launched from
  // Finder, we still do it on all platforms in case of other bugs we don't know.
  this.webContents.once('load-url', function () {
    this.focus()
  })

  // Redirect focus/blur event to app instance too.
  this.on('blur', (event) => {
    app.emit('browser-window-blur', event, this)
  })
  this.on('focus', (event) => {
    app.emit('browser-window-focus', event, this)
  })

  // Subscribe to visibilityState changes and pass to renderer process.
  let isVisible = this.isVisible() && !this.isMinimized()
  let visibilityChanged = () => {
    let newState = this.isVisible() && !this.isMinimized()
    if (isVisible !== newState) {
      isVisible = newState
      this.webContents.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', isVisible ? 'visible' : 'hidden')
    }
  }
  this.on('show', visibilityChanged)
  this.on('hide', visibilityChanged)
  this.on('minimize', visibilityChanged)
  this.on('restore', visibilityChanged)
  this.on('maximize', visibilityChanged)

  // Notify the creation of the window.
  app.emit('browser-window-created', {}, this)

  // Be compatible with old APIs.
  this.webContents.on('devtools-focused', () => {
    this.emit('devtools-focused')
  })
  this.webContents.on('devtools-opened', () => {
    this.emit('devtools-opened')
  })
  this.webContents.on('devtools-closed', () => {
    this.emit('devtools-closed')
  })

  Object.defineProperty(this, 'devToolsWebContents', {
    enumerable: true,
    configurable: false,
    get: function () {
      return this.webContents.devToolsWebContents
    }
  })
}

BrowserWindow.getFocusedWindow = function () {
  var i, len, window, windows
  windows = BrowserWindow.getAllWindows()
  for (i = 0, len = windows.length; i < len; i++) {
    window = windows[i]
    if (window.isFocused()) {
      return window
    }
  }
  return null
}

BrowserWindow.fromWebContents = function (webContents) {
  var i, len, ref1, window, windows
  windows = BrowserWindow.getAllWindows()
  for (i = 0, len = windows.length; i < len; i++) {
    window = windows[i]
    if ((ref1 = window.webContents) != null ? ref1.equal(webContents) : void 0) {
      return window
    }
  }
}

BrowserWindow.fromDevToolsWebContents = function (webContents) {
  var i, len, ref1, window, windows
  windows = BrowserWindow.getAllWindows()
  for (i = 0, len = windows.length; i < len; i++) {
    window = windows[i]
    if ((ref1 = window.devToolsWebContents) != null ? ref1.equal(webContents) : void 0) {
      return window
    }
  }
}

// Helpers.

BrowserWindow.prototype.loadURL = function () {
  return this.webContents.loadURL.apply(this.webContents, arguments)
}

BrowserWindow.prototype.getURL = function () {
  return this.webContents.getURL()
}

BrowserWindow.prototype.reload = function () {
  return this.webContents.reload.apply(this.webContents, arguments)
}

BrowserWindow.prototype.send = function () {
  return this.webContents.send.apply(this.webContents, arguments)
}

BrowserWindow.prototype.openDevTools = function () {
  return this.webContents.openDevTools.apply(this.webContents, arguments)
}

BrowserWindow.prototype.closeDevTools = function () {
  return this.webContents.closeDevTools()
}

BrowserWindow.prototype.isDevToolsOpened = function () {
  return this.webContents.isDevToolsOpened()
}

BrowserWindow.prototype.isDevToolsFocused = function () {
  return this.webContents.isDevToolsFocused()
}

BrowserWindow.prototype.toggleDevTools = function () {
  return this.webContents.toggleDevTools()
}

BrowserWindow.prototype.inspectElement = function () {
  return this.webContents.inspectElement.apply(this.webContents, arguments)
}

BrowserWindow.prototype.inspectServiceWorker = function () {
  return this.webContents.inspectServiceWorker()
}

module.exports = BrowserWindow
<commit_msg>Remove BrowserWindow events now on WebContents<commit_after>'use strict'

const ipcMain = require('electron').ipcMain
const EventEmitter = require('events').EventEmitter
const {BrowserWindow} = process.atomBinding('window')

Object.setPrototypeOf(BrowserWindow.prototype, EventEmitter.prototype)

BrowserWindow.prototype._init = function () {
  // avoid recursive require.
  var app, menu
  app = require('electron').app

  // Simulate the application menu on platforms other than OS X.
  if (process.platform !== 'darwin') {
    menu = app.getApplicationMenu()
    if (menu != null) {
      this.setMenu(menu)
    }
  }

  // Make new windows requested by links behave like "window.open"
  this.webContents.on('-new-window', (event, url, frameName, disposition) => {
    var options
    options = {
      show: true,
      width: 800,
      height: 600
    }
    return ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, disposition, options)
  })

  // window.resizeTo(...)
  // window.moveTo(...)
  this.webContents.on('move', (event, size) => {
    this.setBounds(size)
  })

  // Hide the auto-hide menu when webContents is focused.
  this.webContents.on('activate', () => {
    if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
      this.setMenuBarVisibility(false)
    }
  })

  // Forward the crashed event.
  this.webContents.on('crashed', () => {
    this.emit('crashed')
  })

  // Change window title to page title.
  this.webContents.on('page-title-updated', (event, title) => {
    // The page-title-updated event is not emitted immediately (see #3645), so
    // when the callback is called the BrowserWindow might have been closed.
    if (this.isDestroyed()) return

    // Route the event to BrowserWindow.
    this.emit('page-title-updated', event, title)
    if (!event.defaultPrevented) this.setTitle(title)
  })

  // Sometimes the webContents doesn't get focus when window is shown, so we have
  // to force focusing on webContents in this case. The safest way is to focus it
  // when we first start to load URL, if we do it earlier it won't have effect,
  // if we do it later we might move focus in the page.
  // Though this hack is only needed on OS X when the app is launched from
  // Finder, we still do it on all platforms in case of other bugs we don't know.
  this.webContents.once('load-url', function () {
    this.focus()
  })

  // Redirect focus/blur event to app instance too.
  this.on('blur', (event) => {
    app.emit('browser-window-blur', event, this)
  })
  this.on('focus', (event) => {
    app.emit('browser-window-focus', event, this)
  })

  // Subscribe to visibilityState changes and pass to renderer process.
  let isVisible = this.isVisible() && !this.isMinimized()
  let visibilityChanged = () => {
    let newState = this.isVisible() && !this.isMinimized()
    if (isVisible !== newState) {
      isVisible = newState
      this.webContents.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', isVisible ? 'visible' : 'hidden')
    }
  }
  this.on('show', visibilityChanged)
  this.on('hide', visibilityChanged)
  this.on('minimize', visibilityChanged)
  this.on('restore', visibilityChanged)
  this.on('maximize', visibilityChanged)

  // Notify the creation of the window.
  app.emit('browser-window-created', {}, this)

  Object.defineProperty(this, 'devToolsWebContents', {
    enumerable: true,
    configurable: false,
    get: function () {
      return this.webContents.devToolsWebContents
    }
  })
}

BrowserWindow.getFocusedWindow = function () {
  var i, len, window, windows
  windows = BrowserWindow.getAllWindows()
  for (i = 0, len = windows.length; i < len; i++) {
    window = windows[i]
    if (window.isFocused()) {
      return window
    }
  }
  return null
}

BrowserWindow.fromWebContents = function (webContents) {
  var i, len, ref1, window, windows
  windows = BrowserWindow.getAllWindows()
  for (i = 0, len = windows.length; i < len; i++) {
    window = windows[i]
    if ((ref1 = window.webContents) != null ? ref1.equal(webContents) : void 0) {
      return window
    }
  }
}

BrowserWindow.fromDevToolsWebContents = function (webContents) {
  var i, len, ref1, window, windows
  windows = BrowserWindow.getAllWindows()
  for (i = 0, len = windows.length; i < len; i++) {
    window = windows[i]
    if ((ref1 = window.devToolsWebContents) != null ? ref1.equal(webContents) : void 0) {
      return window
    }
  }
}

// Helpers.

BrowserWindow.prototype.loadURL = function () {
  return this.webContents.loadURL.apply(this.webContents, arguments)
}

BrowserWindow.prototype.getURL = function () {
  return this.webContents.getURL()
}

BrowserWindow.prototype.reload = function () {
  return this.webContents.reload.apply(this.webContents, arguments)
}

BrowserWindow.prototype.send = function () {
  return this.webContents.send.apply(this.webContents, arguments)
}

BrowserWindow.prototype.openDevTools = function () {
  return this.webContents.openDevTools.apply(this.webContents, arguments)
}

BrowserWindow.prototype.closeDevTools = function () {
  return this.webContents.closeDevTools()
}

BrowserWindow.prototype.isDevToolsOpened = function () {
  return this.webContents.isDevToolsOpened()
}

BrowserWindow.prototype.isDevToolsFocused = function () {
  return this.webContents.isDevToolsFocused()
}

BrowserWindow.prototype.toggleDevTools = function () {
  return this.webContents.toggleDevTools()
}

BrowserWindow.prototype.inspectElement = function () {
  return this.webContents.inspectElement.apply(this.webContents, arguments)
}

BrowserWindow.prototype.inspectServiceWorker = function () {
  return this.webContents.inspectServiceWorker()
}

module.exports = BrowserWindow
<|endoftext|>


<commit_before>(function() {
    "use strict";
    angular.module("countrySelect", []).constant('csConfig', {
        allowExtensions: false,
        autoFormat: true,
        autoHideDialCode: true,
        autoPlaceholder: true,
        customPlaceholder: null,
        defaultCountry: "",
        geoIpLookup: null,
        nationalMode: true,
        numberType: "MOBILE",
        onlyCountries: void 0,
        preferredCountries: ['us', 'gb'],
        utilsScript: ""
    }).directive('countrySelect', [
        '$timeout', 'csConfig', function($timeout, csConfig) {
            return {
                restrict: 'A',
                require: '^ngModel',
                scope: {
                    ngModel: '=',
                    country: '='
                },
                link: function(scope, element, attrs, ctrl) {
                    var handleWhatsSupposedToBeAnArray, options, read, watchOnce;
                    if (ctrl) {
                        if (element.val() !== '') {
                            $timeout(function() {
                                element.intlTelInput('setNumber', element.val());
                                return ctrl.$setViewValue(element.val());
                            }, 0);
                        }
                    }
                    read = function() {
                        return ctrl.$setViewValue(element.val());
                    };
                    handleWhatsSupposedToBeAnArray = function(value) {
                        if (value instanceof Array) {
                            return value;
                        } else {
                            return value.toString().replace(/[ ]/g, '').split(',');
                        }
                    };
                    options = angular.copy(csConfig);
                    angular.forEach(options, function(value, key) {
                        var option;
                        if (!(attrs.hasOwnProperty(key) && angular.isDefined(attrs[key]))) {
                            return;
                        }
                        option = attrs[key];
                        if (key === 'preferredCountries') {
                            return options.preferredCountries = handleWhatsSupposedToBeAnArray(option);
                        } else if (key === 'onlyCountries') {
                            return options.onlyCountries = handleWhatsSupposedToBeAnArray(option);
                        } else if (typeof value === "boolean") {
                            return options[key] = option === "true";
                        } else {
                            return options[key] = option;
                        }
                    });
                    watchOnce = scope.$watch('ngModel', function(newValue) {
                        return scope.$$postDigest(function() {
                            if (newValue !== null && newValue !== void 0 && newValue.length > 0) {
                                if (newValue[0] !== '+') {
                                    newValue = '+' + newValue;
                                }
                                element.val(newValue);
                            }
                            element.intlTelInput(options);
                            if (!(attrs.skipUtilScriptDownload !== void 0 || options.utilsScript)) {
                                element.intlTelInput('loadUtils', '/bower_components/country-select-js/build/js/countrySelect.min.js');
                            }
                            return watchOnce();
                        });
                    });
                    scope.$watch('country', function(newValue) {
                        if (newValue !== null && newValue !== void 0 && newValue !== '') {
                            return element.intlTelInput("selectCountry", newValue);
                        }
                    });
                    ctrl.$formatters.push(function(value) {
                        if (!value) {
                            return value;
                        }
                        element.intlTelInput('setNumber', value);
                        return element.val();
                    });
                    ctrl.$parsers.push(function(value) {
                        if (!value) {
                            return value;
                        }
                        return value.replace(/[^\d]/g, '');
                    });
                    ctrl.$validators.internationalPhoneNumber = function(value) {
                        var selectedCountry;
                        selectedCountry = element.intlTelInput('getSelectedCountryData');
                        if (!value || (selectedCountry && selectedCountry.dialCode === value)) {
                            return true;
                        }
                        return element.intlTelInput("isValidNumber");
                    };
                    element.on('blur keyup change', function(event) {
                        return scope.$apply(read);
                    });
                    return element.on('$destroy', function() {
                        element.intlTelInput('destroy');
                        return element.off('blur keyup change');
                    });
                }
            };
        }
    ]);

}).call(this);<commit_msg>new version<commit_after>(function() {
    "use strict";
    angular.module("countrySelect", []).constant('csConfig', {

    }).directive('countrySelect', function() {
            return {
                restrict: 'A',
                require: '^ngModel',
                scope: {
                    ngModel: '=',
                    country: '='
                },
                link: function(scope, element) {
                    element.countrySelect();
                }
            };
        }
    );

}).call(this);<|endoftext|>


<commit_before>/*!
 * Copyright (c) 2016 Naufal Rabbani (http://github.com/BosNaufal),
 * ,Licensed Under MIT (http://opensource.org/licenses/MIT),
 * ,
 * ,Vue 2 Autocomplete @ Version 0.0.3,
 *
 */
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Vue2Autocomplete=e():t.Vue2Autocomplete=e()}(this,function(){return function(t){function e(o){if(s[o])return s[o].exports;var n=s[o]={exports:{},id:o,loaded:!1};return t[o].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var s={};return e.m=t,e.c=s,e.p="../dist/",e(0)}([function(t,e,s){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}var n=s(2),i=o(n);t.exports=i.default},function(t,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});/*! Copyright (c) 2016 Naufal Rabbani (http://github.com/BosNaufal)
	* Licensed Under MIT (http://opensource.org/licenses/MIT)
	*
	* Vue 2 Autocomplete @ Version 0.0.1
	*
	*/
/*!
	*  javascript-debounce 1.0.0
	*
	*  A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function.
	*
	*  Source code available at: https://github.com/jgarber623/javascript-debounce
	*
	*  (c) 2015-present Jason Garber (http://sixtwothree.org)
	*
	*  javascript-debounce may be freely distributed under the MIT license.
	*/
var s=function(t,e){var s;return function(){var o=this,n=arguments;clearTimeout(s),s=setTimeout(function(){t.apply(o,n)},e)}};e.default={props:{id:String,className:String,placeholder:String,initValue:{type:String,default:""},anchor:{type:String,required:!0},label:String,debounce:Number,url:{type:String,required:!0},param:{type:String,default:"q"},customParams:Object,customHeaders:Object,min:{type:Number,default:0},process:Function,onInput:Function,onShow:Function,onBlur:Function,onHide:Function,onFocus:Function,onSelect:Function,onBeforeAjax:Function,onAjaxProgress:Function,onAjaxLoaded:Function},data:function(){return{showList:!1,type:"",json:[],focusList:""}},methods:{clearInput:function(){this.showList=!1,this.type="",this.json=[],this.focusList=""},cleanUp:function(t){return JSON.parse(JSON.stringify(t))},input:function(t){this.showList=!0,this.onInput?this.onInput(t):null,this.debouncedGetData&&this.debounce===this.oldDebounce||(this.oldDebounce=this.debounce,this.debouncedGetData=this.debounce?s(this.getData.bind(this),this.debounce):this.getData),this.debouncedGetData(t)},showAll:function(){this.json=[],this.getData(""),this.onShow?this.onShow():null,this.showList=!0},hideAll:function(t){var e=this;this.onBlur?this.onBlur(t):null,setTimeout(function(){e.onHide?e.onHide():null,e.showList=!1},250)},focus:function(t){this.focusList=0,this.onFocus?this.onFocus(t):null},mousemove:function(t){this.focusList=t},keydown:function(t){var e=t.keyCode;if(this.showList){switch(e){case 40:this.focusList++;break;case 38:this.focusList--;break;case 13:this.selectList(this.json[this.focusList]),this.showList=!1;break;case 27:this.showList=!1}var s=this.json.length-1;this.focusList=this.focusList>s?0:this.focusList<0?s:this.focusList}},activeClass:function(t){return{"focus-list":t==this.focusList}},selectList:function(t){var e=this.cleanUp(t);this.type=e[this.anchor],this.showList=!1,this.onSelect?this.onSelect(e):null},getData:function(t){var e=this,s=this;if(!(t.length<this.min)&&null!=this.url){this.onBeforeAjax?this.onBeforeAjax(t):null;var o=new XMLHttpRequest,n="";this.customParams&&Object.keys(this.customParams).forEach(function(t){n+="&"+t+"="+e.customParams[t]}),o.open("GET",this.url+"?"+this.param+"="+t+n,!0),this.customHeaders&&Object.keys(this.customHeaders).forEach(function(t){o.setRequestHeader(t,e.customHeaders[t])}),o.send(),o.addEventListener("progress",function(t){t.lengthComputable&&(this.onAjaxProgress?this.onAjaxProgress(t):null)}),o.addEventListener("loadend",function(t){var e=JSON.parse(this.responseText);this.onAjaxLoaded?this.onAjaxLoaded(e):null,s.json=s.process?s.process(e):e})}},setValue:function(t){this.type=t}},created:function(){this.type=this.initValue?this.initValue:null}}},function(t,e,s){var o=s(3)(s(1),s(4),null,null);t.exports=o.exports},function(t,e){t.exports=function(t,e,s,o){var n,i=t=t||{},u=typeof t.default;"object"!==u&&"function"!==u||(n=t,i=t.default);var c="function"==typeof i?i.options:i;if(e&&(c.render=e.render,c.staticRenderFns=e.staticRenderFns),s&&(c._scopeId=s),o){var a=Object.create(c.computed||null);Object.keys(o).forEach(function(t){var e=o[t];a[t]=function(){return e}}),c.computed=a}return{esModule:n,exports:i,options:c}}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",{class:(t.className?t.className+"-wrapper ":"")+"autocomplete-wrapper"},[s("input",{directives:[{name:"model",rawName:"v-model",value:t.type,expression:"type"}],class:(t.className?t.className:"")+" autocomplete-input",attrs:{type:"text",id:t.id,placeholder:t.placeholder,autocomplete:"off"},domProps:{value:t._s(t.type)},on:{input:[function(e){e.target.composing||(t.type=e.target.value)},function(e){t.input(t.type)}],dblclick:t.showAll,blur:t.hideAll,keydown:t.keydown,focus:t.focus}}),t._v(" "),s("div",{directives:[{name:"show",rawName:"v-show",value:t.showList,expression:"showList"}],class:(t.className?t.className+"-list ":"")+"autocomplete transition autocomplete-list"},[s("ul",t._l(t.json,function(e,o){return s("li",{class:t.activeClass(o),attrs:{transition:"showAll"}},[s("a",{attrs:{href:"#"},on:{click:function(s){s.preventDefault(),t.selectList(e)},mousemove:function(e){t.mousemove(o)}}},[s("b",[t._v(t._s(e[t.anchor]))]),t._v(" "),s("span",[t._v(t._s(e[t.label]))])])])}))])])},staticRenderFns:[]}}])});<commit_msg>syncing dist files<commit_after>/*!
 * Copyright (c) 2016 Naufal Rabbani (http://github.com/BosNaufal),
 * ,Licensed Under MIT (http://opensource.org/licenses/MIT),
 * ,
 * ,Vue 2 Autocomplete @ Version 0.0.3,
 *
 */
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Vue2Autocomplete=e():t.Vue2Autocomplete=e()}(this,function(){return function(t){function e(o){if(s[o])return s[o].exports;var n=s[o]={exports:{},id:o,loaded:!1};return t[o].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var s={};return e.m=t,e.c=s,e.p="../dist/",e(0)}([function(t,e,s){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}var n=s(2),i=o(n);t.exports=i.default},function(t,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});/*! Copyright (c) 2016 Naufal Rabbani (http://github.com/BosNaufal)
	* Licensed Under MIT (http://opensource.org/licenses/MIT)
	*
	* Vue 2 Autocomplete @ Version 0.0.1
	*
	*/
/*!
	*  javascript-debounce 1.0.0
	*
	*  A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function.
	*
	*  Source code available at: https://github.com/jgarber623/javascript-debounce
	*
	*  (c) 2015-present Jason Garber (http://sixtwothree.org)
	*
	*  javascript-debounce may be freely distributed under the MIT license.
	*/
var s=function(t,e){var s;return function(){var o=this,n=arguments;clearTimeout(s),s=setTimeout(function(){t.apply(o,n)},e)}};e.default={props:{id:String,className:String,placeholder:String,initValue:{type:String,default:""},anchor:{type:String,required:!0},label:String,debounce:Number,url:{type:String,required:!0},param:{type:String,default:"q"},customParams:Object,customHeaders:Object,min:{type:Number,default:0},process:Function,onInput:Function,onShow:Function,onBlur:Function,onHide:Function,onFocus:Function,onSelect:Function,onBeforeAjax:Function,onAjaxProgress:Function,onAjaxLoaded:Function},data:function(){return{showList:!1,type:"",json:[],focusList:""}},methods:{clearInput:function(){this.showList=!1,this.type="",this.json=[],this.focusList=""},cleanUp:function(t){return JSON.parse(JSON.stringify(t))},input:function(t){this.showList=!0,this.onInput?this.onInput(t):null,this.debouncedGetData&&this.debounce===this.oldDebounce||(this.oldDebounce=this.debounce,this.debouncedGetData=this.debounce?s(this.getData.bind(this),this.debounce):this.getData),this.debouncedGetData(t)},showAll:function(){this.json=[],this.getData(""),this.onShow?this.onShow():null,this.showList=!0},hideAll:function(t){var e=this;this.onBlur?this.onBlur(t):null,setTimeout(function(){e.onHide?e.onHide():null,e.showList=!1},250)},focus:function(t){this.focusList=0,this.onFocus?this.onFocus(t):null},mousemove:function(t){this.focusList=t},keydown:function(t){var e=t.keyCode;if(this.showList){switch(e){case 40:this.focusList++;break;case 38:this.focusList--;break;case 13:this.selectList(this.json[this.focusList]),this.showList=!1;break;case 27:this.showList=!1}var s=this.json.length-1;this.focusList=this.focusList>s?0:this.focusList<0?s:this.focusList}},activeClass:function(t){return{"focus-list":t==this.focusList}},selectList:function(t){var e=this.cleanUp(t);this.type=e[this.anchor],this.showList=!1,this.onSelect?this.onSelect(e):null},getData:function(t){var e=this,s=this;if(!(t.length<this.min)&&null!=this.url){this.onBeforeAjax?this.onBeforeAjax(t):null;var o=new XMLHttpRequest,n="";this.customParams&&Object.keys(this.customParams).forEach(function(t){n+="&"+t+"="+e.customParams[t]}),o.open("GET",this.url+"?"+this.param+"="+t+n,!0),this.customHeaders&&Object.keys(this.customHeaders).forEach(function(t){o.setRequestHeader(t,e.customHeaders[t])}),o.send(),o.addEventListener("progress",function(t){t.lengthComputable&&(this.onAjaxProgress?this.onAjaxProgress(t):null)}),o.addEventListener("loadend",function(t){var e=JSON.parse(this.responseText);this.onAjaxLoaded?this.onAjaxLoaded(e):null,s.json=s.process?s.process(e):e})}},setValue:function(t){this.type=t}},created:function(){this.type=this.initValue?this.initValue:null}}},function(t,e,s){var o=s(3)(s(1),s(4),null,null);t.exports=o.exports},function(t,e){t.exports=function(t,e,s,o){var n,i=t=t||{},u=typeof t.default;"object"!==u&&"function"!==u||(n=t,i=t.default);var c="function"==typeof i?i.options:i;if(e&&(c.render=e.render,c.staticRenderFns=e.staticRenderFns),s&&(c._scopeId=s),o){var a=Object.create(c.computed||null);Object.keys(o).forEach(function(t){var e=o[t];a[t]=function(){return e}}),c.computed=a}return{esModule:n,exports:i,options:c}}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",{class:(t.className?t.className+"-wrapper ":"")+"autocomplete-wrapper"},[s("input",{directives:[{name:"model",rawName:"v-model",value:t.type,expression:"type"}],class:(t.className?t.className+"-input ":"")+"autocomplete-input",attrs:{type:"text",id:t.id,placeholder:t.placeholder,autocomplete:"off"},domProps:{value:t._s(t.type)},on:{input:[function(e){e.target.composing||(t.type=e.target.value)},function(e){t.input(t.type)}],dblclick:t.showAll,blur:t.hideAll,keydown:t.keydown,focus:t.focus}}),t._v(" "),s("div",{directives:[{name:"show",rawName:"v-show",value:t.showList,expression:"showList"}],class:(t.className?t.className+"-list ":"")+"autocomplete transition autocomplete-list"},[s("ul",t._l(t.json,function(e,o){return s("li",{class:t.activeClass(o),attrs:{transition:"showAll"}},[s("a",{attrs:{href:"#"},on:{click:function(s){s.preventDefault(),t.selectList(e)},mousemove:function(e){t.mousemove(o)}}},[s("b",[t._v(t._s(e[t.anchor]))]),t._v(" "),s("span",[t._v(t._s(e[t.label]))])])])}))])])},staticRenderFns:[]}}])});<|endoftext|>


<commit_before>(function ($) {

	"use strict";

	var app = angular.module('RbsChange');

	function changeEditorServiceFn ($timeout, $rootScope, $log, $location, FormsManager, MainMenu, Utils, ArrayUtils, Actions, Breadcrumb) {

		// Used internally to store compiled informations in data attributes.
		var FIELDS_DATA_KEY_NAME = 'chg-form-fields';

		/**
		 * Prepares the scope to be a Document editor.
		 *
		 * @param scope
		 * @param element
		 */
		function prepareScope (scope, element) {

			// scope.original has been set via the data-bindings of the editor's directive.
			// We copy the original document into the 'document' property of the scope:
			// scope.document is now the working copy, on which the form controls are working on.
			scope.document = angular.copy(scope.original);

			if (scope._isPrepared) {
				return;
			}

			scope.$on('Change:UpdateDocumentProperties', function onUpdateDocumentPropertiesFn (event, properties) {
				angular.extend(scope.document, properties);
				scope.submit();
			});

			/**
			 * Reset the form back to the originally loaded document (scope.original).
			 */
			scope.reset = function resetFn () {
				scope.document = angular.copy(scope.original);
			};

			/**
			 * Tells wether the editor has changes or not.
			 * @return Boolean
			 */
			scope.isUnchanged = function isUnchangedFn () {
				return angular.equals(scope.document, scope.original);
			};

			// Computes a list of changes on the fields in each digest cycle.
			scope.changes = [];
			scope.$watch(function scopeWatchFn () {
				ArrayUtils.clear(scope.changes);
				angular.forEach(scope.document, function (value, name) {
					var original = angular.isDefined(scope.original[name]) ? scope.original[name] : '';
					if (name !== 'META$' && ! angular.equals(original, value)) {
						scope.changes.push(name);
					}
				});
			});

			// Ask confirmation when leaving a form with unsaved changes.
			var locationChangeStartDeregistrationFn = $rootScope.$on('$locationChangeStart', function (event) {
				if (! scope.isUnchanged() && ! window.confirm("Des données n'ont pas été enregistrées. Si vous quittez la page, ces données seront perdues.\nSouhaitez-vous réellement quitter cette page ?")) {
					event.preventDefault();
				}
			});
			// De-register the $locationChangeStart handler when this scope is destroyed.
			scope.$on('$destroy', function () {
				locationChangeStartDeregistrationFn();
			});

			/**
			 * Sends the changes to the server, via a POST (creation) or a PUT (update) request.
			 */
			scope.submit = function submitFn () {
				var promise = null,
				    hadCorrection = scope.document.hasCorrection();

				function doSubmit () {

					function getSectionOfField (fieldName) {
						var result = null;
						angular.forEach(scope.menu, function (entry) {
							if (entry.type === 'section') {
								angular.forEach(entry.fields, function (field) {
									if (field.id === fieldName) {
										result = entry;
									}
								});
							}
						});
						return result;
					}

					function markFieldAsInvalid (fieldName, messages) {
						getSectionOfField(fieldName).invalid.push(fieldName);
					}

					function clearInvalidFields () {
						$(element).find('.control-group.property.error').removeClass('error');
						angular.forEach(scope.menu, function (entry) {
							if (entry.type === 'section') {
								ArrayUtils.clear(entry.invalid);
							}
						});
					}

					function saveSuccessHandler (docs) {
						var doc = docs[0];

						scope.original = angular.copy(doc);

						if (doc.hasCorrection() !== hadCorrection) {
							scope.$emit('Change:DocumentUpdated', doc);
						}

						clearInvalidFields();

						if (FormsManager.isCascading()) {
							FormsManager.uncascade(doc);
						} else {
							$rootScope.$broadcast('Change:DocumentSaved', doc);
							if (angular.isFunction(scope.onSave)) {
								scope.onSave(doc);
							}
						}
					}

					function saveErrorHandler (reason) {
						clearInvalidFields();
						if (angular.isObject(reason) && angular.isObject(reason.data) && angular.isObject(reason.data['properties-errors'])) {
							angular.forEach(reason.data['properties-errors'], function (messages, propertyName) {
								$(element).find('label[for="'+propertyName+'"]').each(function () {
									$(this).closest('.control-group.property').addClass('error');
									$(this).nextAll('.controls').find(':input').first().focus();
								});
								markFieldAsInvalid(propertyName, messages);
							});
						}
					}

					if (angular.isFunction(scope.beforeSave)) {
						scope.beforeSave(scope.document);
					}

					Actions.execute(
						'save',
						{
							'$docs'                : [ scope.document ],
							'$propertyInfoProvider': element ? element.data(FIELDS_DATA_KEY_NAME) : null,
							'$scope'               : scope,
							'$currentTreeNode'     : Breadcrumb.getCurrentNode()
						}
					).then(saveSuccessHandler, saveErrorHandler);
				}

				if (angular.isFunction(scope.preSubmit)) {
					promise = scope.preSubmit(scope.document);
				}

				if (promise) {
					promise.then(doSubmit);
				} else {
					doSubmit();
				}

			};

			scope.canCancelCascade = function canCancelCascadeFn () {
				return FormsManager.isCascading();
			};

			scope.cancelCascade = function cancelCascadeFn () {
				if (FormsManager.isCascading()) {
					FormsManager.uncascade(scope.document);
				}
			};

			scope.canGoBack = function canGoBackFn () {
				return scope.isUnchanged();
			};

			scope.goBack = function goBackFn () {
				if (angular.isFunction(scope.onCancel)) {
					scope.onCancel();
				}
			};

			scope.isNew = function isNewFn () {
				return Utils.isNew(scope.original);
			};

			scope.hasStatus = function hasStatusFn (status) {
				if (!scope.document) {
					return false;
				}
				var args = [scope.document];
				ArrayUtils.append(args, arguments);
				return Utils.hasStatus.apply(Utils, args);
			};

			scope.hasCorrectionOnProperty = function hasCorrectionOnPropertyFn (property) {
				return scope.document && scope.document.META$ && scope.document.META$.correction && ArrayUtils.inArray(property, scope.document.META$.correction.propertiesNames) !== -1;
			};

			scope.hasCorrection = function hasCorrectionFn () {
				return Utils.hasCorrection(scope.document);
			};

			scope.isCascading = function isCascadingFn () {
				return FormsManager.isCascading();
			};

			scope.onCancel = function onCancelFn () {
				Breadcrumb.goParent();
			};

			scope._isPrepared = true;

		}

		/**
		 * Parses the editor and finds sections used to automatically build the MainMenu on the left.
		 */
		function compileSectionsAndFields (tElement) {
			var menu = [],
			    fields = {},
			    groups = {},
			    matches;

			tElement.data(FIELDS_DATA_KEY_NAME, fields);

			tElement.find('fieldset').each(function (index, fieldset) {
				var $fs = jQuery(fieldset),
				    fsData = $fs.data(),
				    section,
				    entry;

				if (angular.isDefined(fsData.formSectionGroup) && angular.isUndefined(groups[fsData.formSectionGroup])) {
					groups[fsData.formSectionGroup] = true;
					menu.push({
						'label': fsData.formSectionGroup,
						'type' : 'group'
					});
				}

				section = fsData.ngShow || $fs.attr('ng-show') || $fs.attr('x-ng-show');
				if (section) {
					matches = (/section\s*==\s*'([\w\d\\-]*)'/).exec(section);
					if (matches.length !== 2) {
						console.error("Could not find section ID on fieldset.");
					}
					section = matches[1];
				} else {
					section = fsData.ngSwitchWhen || $fs.attr('ng-switch-when') || $fs.attr('x-ng-switch-when');
				}

				entry = {
					'type'     : 'section',
					'id'       : section || '',
					'label'    : fsData.formSectionLabel,
					'fields'   : [],
					'required' : [],
					'invalid'  : [],
					'corrected': []
				};

				if ( ! FormsManager.isCascading() ) {
					if (section && section.length) {
						entry.url = Utils.makeUrl($location.absUrl(), { 'section': section });
					} else {
						entry.url = Utils.makeUrl($location.absUrl(), { 'section': null });
					}
				}

				menu.push(entry);

				$fs.find('div.control-group.property').each(function (index, ctrlGrp) {
					var $ctrlGrp = $(ctrlGrp),
					    $lbl = $ctrlGrp.find('label[for]').first();

					fields[$lbl.attr('for')] = {
						'label'   : $lbl.text(),
						'section' :
						{
							'id'    : section,
							'label' : entry.label
						}
					};

					entry.fields.push({
						'id'    : $lbl.attr('for'),
						'label' : $lbl.text()
					});
					if ($ctrlGrp.hasClass('required')) {
						entry.required.push($lbl.attr('for'));
					}
					if ($ctrlGrp.hasClass('success')) { // TODO Change class name?
						entry.corrected.push($lbl.attr('for'));
					}
				});

			});

			return menu;
		}

		this.initScope = function scopeWatchOriginal (scope, element, callback) {
			scope.$watch('original', function () {
				prepareScope(scope, element);
				if (element) {
					$timeout(function () {
						scope.menu = compileSectionsAndFields(element);
						MainMenu.build(scope);
					});
				}
				if (angular.isFunction(callback)) {
					callback.apply(scope);
				}
			}, true);
		};

	}

	changeEditorServiceFn.$inject = [
		'$timeout', '$rootScope', '$log', '$location',
		'RbsChange.FormsManager',
		'RbsChange.MainMenu',
		'RbsChange.Utils',
		'RbsChange.ArrayUtils',
		'RbsChange.Actions',
		'RbsChange.Breadcrumb'
	];

	app.service('RbsChange.Editor', changeEditorServiceFn);

})(window.jQuery);<commit_msg>Disabled confirmation message when switching between sections.<commit_after>(function ($) {

	"use strict";

	var app = angular.module('RbsChange');

	function changeEditorServiceFn ($timeout, $rootScope, $log, $location, FormsManager, MainMenu, Utils, ArrayUtils, Actions, Breadcrumb) {

		// Used internally to store compiled informations in data attributes.
		var FIELDS_DATA_KEY_NAME = 'chg-form-fields';

		/**
		 * Prepares the scope to be a Document editor.
		 *
		 * @param scope
		 * @param element
		 */
		function prepareScope (scope, element) {

			// scope.original has been set via the data-bindings of the editor's directive.
			// We copy the original document into the 'document' property of the scope:
			// scope.document is now the working copy, on which the form controls are working on.
			scope.document = angular.copy(scope.original);

			if (scope._isPrepared) {
				return;
			}

			scope.$on('Change:UpdateDocumentProperties', function onUpdateDocumentPropertiesFn (event, properties) {
				angular.extend(scope.document, properties);
				scope.submit();
			});

			/**
			 * Reset the form back to the originally loaded document (scope.original).
			 */
			scope.reset = function resetFn () {
				scope.document = angular.copy(scope.original);
			};

			/**
			 * Tells wether the editor has changes or not.
			 * @return Boolean
			 */
			scope.isUnchanged = function isUnchangedFn () {
				return angular.equals(scope.document, scope.original);
			};

			// Computes a list of changes on the fields in each digest cycle.
			scope.changes = [];
			scope.$watch(function scopeWatchFn () {
				ArrayUtils.clear(scope.changes);
				angular.forEach(scope.document, function (value, name) {
					var original = angular.isDefined(scope.original[name]) ? scope.original[name] : '';
					if (name !== 'META$' && ! angular.equals(original, value)) {
						scope.changes.push(name);
					}
				});
			});

			/*
			FIXME: Ask for confirmation when leaving the page but not when switching between sections.
			// Ask confirmation when leaving a form with unsaved changes.
			var locationChangeStartDeregistrationFn = $rootScope.$on('$locationChangeStart', function (event) {
				if (! scope.isUnchanged() && ! window.confirm("Des données n'ont pas été enregistrées. Si vous quittez la page, ces données seront perdues.\nSouhaitez-vous réellement quitter cette page ?")) {
					event.preventDefault();
				}
			});
			// De-register the $locationChangeStart handler when this scope is destroyed.
			scope.$on('$destroy', function () {
				locationChangeStartDeregistrationFn();
			});
			*/

			/**
			 * Sends the changes to the server, via a POST (creation) or a PUT (update) request.
			 */
			scope.submit = function submitFn () {
				var promise = null,
				    hadCorrection = scope.document.hasCorrection();

				function doSubmit () {

					function getSectionOfField (fieldName) {
						var result = null;
						angular.forEach(scope.menu, function (entry) {
							if (entry.type === 'section') {
								angular.forEach(entry.fields, function (field) {
									if (field.id === fieldName) {
										result = entry;
									}
								});
							}
						});
						return result;
					}

					function markFieldAsInvalid (fieldName, messages) {
						getSectionOfField(fieldName).invalid.push(fieldName);
					}

					function clearInvalidFields () {
						$(element).find('.control-group.property.error').removeClass('error');
						angular.forEach(scope.menu, function (entry) {
							if (entry.type === 'section') {
								ArrayUtils.clear(entry.invalid);
							}
						});
					}

					function saveSuccessHandler (docs) {
						var doc = docs[0];

						scope.original = angular.copy(doc);

						if (doc.hasCorrection() !== hadCorrection) {
							scope.$emit('Change:DocumentUpdated', doc);
						}

						clearInvalidFields();

						if (FormsManager.isCascading()) {
							FormsManager.uncascade(doc);
						} else {
							$rootScope.$broadcast('Change:DocumentSaved', doc);
							if (angular.isFunction(scope.onSave)) {
								scope.onSave(doc);
							}
						}
					}

					function saveErrorHandler (reason) {
						clearInvalidFields();
						if (angular.isObject(reason) && angular.isObject(reason.data) && angular.isObject(reason.data['properties-errors'])) {
							angular.forEach(reason.data['properties-errors'], function (messages, propertyName) {
								$(element).find('label[for="'+propertyName+'"]').each(function () {
									$(this).closest('.control-group.property').addClass('error');
									$(this).nextAll('.controls').find(':input').first().focus();
								});
								markFieldAsInvalid(propertyName, messages);
							});
						}
					}

					if (angular.isFunction(scope.beforeSave)) {
						scope.beforeSave(scope.document);
					}

					Actions.execute(
						'save',
						{
							'$docs'                : [ scope.document ],
							'$propertyInfoProvider': element ? element.data(FIELDS_DATA_KEY_NAME) : null,
							'$scope'               : scope,
							'$currentTreeNode'     : Breadcrumb.getCurrentNode()
						}
					).then(saveSuccessHandler, saveErrorHandler);
				}

				if (angular.isFunction(scope.preSubmit)) {
					promise = scope.preSubmit(scope.document);
				}

				if (promise) {
					promise.then(doSubmit);
				} else {
					doSubmit();
				}

			};

			scope.canCancelCascade = function canCancelCascadeFn () {
				return FormsManager.isCascading();
			};

			scope.cancelCascade = function cancelCascadeFn () {
				if (FormsManager.isCascading()) {
					FormsManager.uncascade(scope.document);
				}
			};

			scope.canGoBack = function canGoBackFn () {
				return scope.isUnchanged();
			};

			scope.goBack = function goBackFn () {
				if (angular.isFunction(scope.onCancel)) {
					scope.onCancel();
				}
			};

			scope.isNew = function isNewFn () {
				return Utils.isNew(scope.original);
			};

			scope.hasStatus = function hasStatusFn (status) {
				if (!scope.document) {
					return false;
				}
				var args = [scope.document];
				ArrayUtils.append(args, arguments);
				return Utils.hasStatus.apply(Utils, args);
			};

			scope.hasCorrectionOnProperty = function hasCorrectionOnPropertyFn (property) {
				return scope.document && scope.document.META$ && scope.document.META$.correction && ArrayUtils.inArray(property, scope.document.META$.correction.propertiesNames) !== -1;
			};

			scope.hasCorrection = function hasCorrectionFn () {
				return Utils.hasCorrection(scope.document);
			};

			scope.isCascading = function isCascadingFn () {
				return FormsManager.isCascading();
			};

			scope.onCancel = function onCancelFn () {
				Breadcrumb.goParent();
			};

			scope._isPrepared = true;

		}

		/**
		 * Parses the editor and finds sections used to automatically build the MainMenu on the left.
		 */
		function compileSectionsAndFields (tElement) {
			var menu = [],
			    fields = {},
			    groups = {},
			    matches;

			tElement.data(FIELDS_DATA_KEY_NAME, fields);

			tElement.find('fieldset').each(function (index, fieldset) {
				var $fs = jQuery(fieldset),
				    fsData = $fs.data(),
				    section,
				    entry;

				if (angular.isDefined(fsData.formSectionGroup) && angular.isUndefined(groups[fsData.formSectionGroup])) {
					groups[fsData.formSectionGroup] = true;
					menu.push({
						'label': fsData.formSectionGroup,
						'type' : 'group'
					});
				}

				section = fsData.ngShow || $fs.attr('ng-show') || $fs.attr('x-ng-show');
				if (section) {
					matches = (/section\s*==\s*'([\w\d\\-]*)'/).exec(section);
					if (matches.length !== 2) {
						console.error("Could not find section ID on fieldset.");
					}
					section = matches[1];
				} else {
					section = fsData.ngSwitchWhen || $fs.attr('ng-switch-when') || $fs.attr('x-ng-switch-when');
				}

				entry = {
					'type'     : 'section',
					'id'       : section || '',
					'label'    : fsData.formSectionLabel,
					'fields'   : [],
					'required' : [],
					'invalid'  : [],
					'corrected': []
				};

				if ( ! FormsManager.isCascading() ) {
					if (section && section.length) {
						entry.url = Utils.makeUrl($location.absUrl(), { 'section': section });
					} else {
						entry.url = Utils.makeUrl($location.absUrl(), { 'section': null });
					}
				}

				menu.push(entry);

				$fs.find('div.control-group.property').each(function (index, ctrlGrp) {
					var $ctrlGrp = $(ctrlGrp),
					    $lbl = $ctrlGrp.find('label[for]').first();

					fields[$lbl.attr('for')] = {
						'label'   : $lbl.text(),
						'section' :
						{
							'id'    : section,
							'label' : entry.label
						}
					};

					entry.fields.push({
						'id'    : $lbl.attr('for'),
						'label' : $lbl.text()
					});
					if ($ctrlGrp.hasClass('required')) {
						entry.required.push($lbl.attr('for'));
					}
					if ($ctrlGrp.hasClass('success')) { // TODO Change class name?
						entry.corrected.push($lbl.attr('for'));
					}
				});

			});

			return menu;
		}

		this.initScope = function scopeWatchOriginal (scope, element, callback) {
			scope.$watch('original', function () {
				prepareScope(scope, element);
				if (element) {
					$timeout(function () {
						scope.menu = compileSectionsAndFields(element);
						MainMenu.build(scope);
					});
				}
				if (angular.isFunction(callback)) {
					callback.apply(scope);
				}
			}, true);
		};

	}

	changeEditorServiceFn.$inject = [
		'$timeout', '$rootScope', '$log', '$location',
		'RbsChange.FormsManager',
		'RbsChange.MainMenu',
		'RbsChange.Utils',
		'RbsChange.ArrayUtils',
		'RbsChange.Actions',
		'RbsChange.Breadcrumb'
	];

	app.service('RbsChange.Editor', changeEditorServiceFn);

})(window.jQuery);<|endoftext|>