<commit_before>define([
	'goo/math/Vector3'
], function (
	Vector3
) {
	'use strict';

	function Spline(controlPoints) {
		// array of any sort of Vector
		this.controlPoints = controlPoints; // clone?
		this.nSegments = (this.controlPoints.length - 1) / 3;
	}

	(function () {
		var term0 = new Vector3();
		var term1 = new Vector3();
		var term2 = new Vector3();
		var term3 = new Vector3();

		// this needs be extracted in mathutils
		function cubicInterpolation(p0, p1, p2, p3, t, store) {
			// B(t) =
			// (1 - t)^3 * P0 +
			// 3 * (1 - t)^2 * t * P1 +
			// 3 * (1 - t) * t^2 * P2 +
			// t^3 * P3

			var t2 = t * t;
			var t3 = t2 * t;

			var it = 1 - t;
			var it2 = it * it;
			var it3 = it2 * it;

			term0.setVector(p0).scale(it3);
			term1.setVector(p1).scale(it2 * t * 3);
			term2.setVector(p2).scale(it * t2 * 3);
			term3.setVector(p3).scale(t3);

			store.setVector(term0).addVector(term1).addVector(term2).addVector(term3);
		}

		/**
		 *
		 * @param {number} t
		 * @param {Vector} store
		 */
		Spline.prototype.getPoint = function (t, store) {
			if (t >= 1) {
				store.setVector(this.controlPoints[this.controlPoints.length - 1]);
				return;
			}

			var point = this.nSegments * t;
			var index = Math.floor(point);
			var fraction = point - index;

			var p0 = this.controlPoints[index * 3 + 0];
			var p1 = this.controlPoints[index * 3 + 1];
			var p2 = this.controlPoints[index * 3 + 2];
			var p3 = this.controlPoints[index * 3 + 3];

			cubicInterpolation(p0, p1, p2, p3, fraction, store);
		};
	})();

	Spline.getEquidistantPoint = function (t, increment) {
		// compute distance in smaller increments until the increment parameter is satisfied
	};

	return Spline;
});
<commit_msg>Refactored a bit; added quadratic interpolation for fonts<commit_after>define([
	'goo/math/Vector4'
], function (
	Vector4
) {
	'use strict';

	function Spline(controlPoints) {
		// array of any sort of Vector
		this.controlPoints = controlPoints; // clone?
		this.nSegments = (this.controlPoints.length - 1) / 3;
	}

	(function () {
		// should be of the same type as p0, p1, p2
		// using Vector4 here because it can hold instances of Vector2/3/4
		var term0 = new Vector4();
		var term1 = new Vector4();
		var term2 = new Vector4();

		Spline.quadraticInterpolation = function (p0, p1, p2, t, store) {
			// B(t) =
			// (1 - t)^2 * P0 +
			// 2 * (1 - t) * t * P1 +
			// t^2 * P2

			var t2 = t * t;

			var it = 1 - t;
			var it2 = it * it;

			term0.setVector(p0).scale(it2);
			term1.setVector(p1).scale(it * t * 2);
			term2.setVector(p2).scale(t2);

			store.setVector(term0).addVector(term1).addVector(term2).addVector(term3);
		};
	})();

	(function () {
		// should be of the same type as p0, p1, p2, p3
		// using Vector4 here because it can hold instances of Vector2/3/4
		var term0 = new Vector4();
		var term1 = new Vector4();
		var term2 = new Vector4();
		var term3 = new Vector4();

		Spline.cubicInterpolation = function (p0, p1, p2, p3, t, store) {
			// B(t) =
			// (1 - t)^3 * P0 +
			// 3 * (1 - t)^2 * t * P1 +
			// 3 * (1 - t) * t^2 * P2 +
			// t^3 * P3

			var t2 = t * t;
			var t3 = t2 * t;

			var it = 1 - t;
			var it2 = it * it;
			var it3 = it2 * it;

			term0.setVector(p0).scale(it3);
			term1.setVector(p1).scale(it2 * t * 3);
			term2.setVector(p2).scale(it * t2 * 3);
			term3.setVector(p3).scale(t3);

			store.setVector(term0).addVector(term1).addVector(term2).addVector(term3);
		};
	})();

	/**
	 *
	 * @param {number} t
	 * @param {Vector} store
	 */
	Spline.prototype.getPoint = function (t, store) {
		if (t >= 1) {
			store.setVector(this.controlPoints[this.controlPoints.length - 1]);
			return;
		}

		var point = this.nSegments * t;
		var index = Math.floor(point);
		var fraction = point - index;

		var p0 = this.controlPoints[index * 3 + 0];
		var p1 = this.controlPoints[index * 3 + 1];
		var p2 = this.controlPoints[index * 3 + 2];
		var p3 = this.controlPoints[index * 3 + 3];

		Spline.cubicInterpolation(p0, p1, p2, p3, fraction, store);
	};

	Spline.getEquidistantPoint = function (t, increment) {
		// compute distance in smaller increments until the increment parameter is satisfied
	};

	return Spline;
});
<|endoftext|>


<commit_before>import React from 'react';
import _ from 'underscore';

class Column extends React.Component {
  static propTypes = {

  }

  constructor(props) {
    super(props);
  }

  getStyles() {
    let styles = {
      flexGrow: 1,
      height: 'auto',
      width: 'auto',
    };

    return _.extend(styles, this.props.style);
  }

  render() {
    return (

        {this.props.children}

    );
  }
}

export default Column;
<commit_msg>Column: Replace Underscore with Lodash.<commit_after>import React from 'react';
import _ from 'lodash';

class Column extends React.Component {
  static propTypes = {

  }

  constructor(props) {
    super(props);
  }

  getStyles() {
    let styles = {
      flexGrow: 1,
      height: 'auto',
      width: 'auto',
    };

    return _.merge(styles, this.props.style);
  }

  render() {
    return (

        {this.props.children}

    );
  }
}

export default Column;
<|endoftext|>


<commit_before>define([
	'goo/math/MathUtils'
], function (
	MathUtils
	) {
	'use strict';

	/**
	 * Abstract vector class
	 */
	function Vector(size) {

		/**
		 * @hidden
		 * @deprecated
		 */
		this._size = size;
	}

	var COMPONENT_NAMES = ['x', 'y', 'z', 'w'];
	// #ifdef DEBUG
	var COMPONENT_NAMES = ['_x', '_y', '_z', '_w'];
	// #endif

	/**
	 * Binds aliases to the different vector components.
	 * @hidden
	 * @param {Object} prototype The prototype to bind to.
	 * @param {Array<Array<string>>} aliases Array of component aliases for each component index.
	 */
	Vector.setupAliases = function (prototype, aliases) {
		aliases.forEach(function (aliasesPerComponent, index) {
			var componentName = COMPONENT_NAMES[index];

			aliasesPerComponent.forEach(function (alias) {
				Object.defineProperty(prototype, alias, {
					get: function () {
						return this[componentName];
					},
					set: function (value) {
						this[componentName] = value;

						// #ifdef DEBUG
						if (isNaN(this[componentName])) {
							throw new Error('Tried setting NaN to vector component ' + alias);
						}
						// #endif
					}
				});
			});
		});
	};

	// #ifdef DEBUG
	Vector.setupIndices = function (prototype, count) {
		var raise = function () {
			throw new Error('Vector component access through indices is not supported anymore');
		};

		for (var i = 0; i < count; i++) {
			Object.defineProperty(prototype, i, {
				get: raise,
				set: raise
			});
		}
	};

	/**
	 * Replaces the supplied method of object and wraps it in a integrity check
	 * @hidden
	 * @param {Object} object The object to attach the post-check to
	 * @param {string} methodName The name of the original method the check is attached to
	 */
	Vector.addReturnCheck = function (object, methodName) {
		var originalMethod = object[methodName];
		object[methodName] = function () {
			var ret = originalMethod.apply(this, arguments);
			if (isNaN(ret)) {
				throw new Error('Vector method ' + methodName + ' returned NaN');
			}

			return ret;
		};
	};

	/**
	 * Adds more validators at once
	 * @hidden
	 * @param {Object} object
	 * @param {Array<string>} methodNames
	 */
	Vector.addReturnChecks = function (object, methodNames) {
		methodNames.forEach(Vector.addReturnCheck.bind(null, object));
	};
	// #endif

	// SHIM START
	Object.defineProperty(Vector.prototype, 'data', {
		get: function () {
			var data = [];
			var that = this;
			console.warn('The .data property of Vector was removed, dont use it.');
			Object.defineProperties(data, {
				'0': {
					get: function () {
						return that.x;
					},
					set: function (value) {
						that.x = value;
					}
				},
				'1': {
					get: function () {
						return that.y;
					},
					set: function (value) {
						that.y = value;
					}
				},
				'2': {
					get: function () {
						return that.z;
					},
					set: function (value) {
						that.z = value;
					}
				},
				'3': {
					get: function () {
						return that.w;
					},
					set: function (value) {
						that.w = value;
					}
				}
			});
			return data;
		}
	});

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.add = function (lhs, rhs, target) {
		console.warn('Vector.add is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] + rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.add = function (rhs) {
		console.warn('Vector.prototype.add is deprecated.');
		return Vector.add(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.sub = function (lhs, rhs, target) {
		console.warn('Vector.sub is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] - rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.sub = function (rhs) {
		console.warn('Vector.prototype.sub is deprecated.');
		return Vector.sub(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.mul = function (lhs, rhs, target) {
		console.warn('Vector.mul is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] * rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.mul = function (rhs) {
		console.warn('Vector.prototype.mul is deprecated.');
		return Vector.mul(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.div = function (lhs, rhs, target) {
		console.warn('Vector.div is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] / rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.div = function (rhs) {
		console.warn('Vector.prototype.div is deprecated.');
		return Vector.div(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.copy = function (source, target) {
		console.warn('Vector.copy is deprecated.');
		var size = source._size;

		if (!target) {
			target = new Vector(size);
		}

		for(var i=0; i<size; i++){
			target.data[i] = source.data[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.copy = function (source) {
		console.warn('Vector.prototype.copy  is deprecated.');
		var size = source._size;
		for(var i=0; i<size; i++){
			this.data[i] = source.data[i];
		}
		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.dot = function (lhs, rhs) {
		console.warn('Vector.dot is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		var sum = 0;

		for (var i = 0; i < size; i++) {
			sum += ldata[i] * rdata[i];
		}

		return sum;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.dot = function (rhs) {
		console.warn('Vector.prototype.dot is deprecated.');
		return Vector.dot(this, rhs);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.apply = function (lhs, rhs, target) {
		console.warn('Vector.apply is deprecated.');
		var rows = lhs.rows;
		var cols = lhs.cols;
		var size = rhs._size;

		if (!target) {
			target = new Vector(rows);
		}

		if (target === rhs) {
			return Vector.copy(Vector.apply(lhs, rhs), target);
		}

		for (var c = 0; c < cols; c++) {
			var o = c * rows;

			for (var r = 0; r < rows; r++) {
				var sum = 0.0;

				for (var i = 0; i < size; i++) {
					sum += lhs.data[i * lhs.rows + r] * rhs.data[i];
				}

				target.data[o + r] = sum;
			}
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.apply = function (lhs) {
		console.warn('Vector.prototype.apply is deprecated.');
		return Vector.apply(lhs, this, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.equals = function (lhs, rhs) {
		console.warn('Vector.equals is deprecated.');
		var lhsLength = lhs._size;
		if (lhsLength !== rhs._size) {
			return false;
		}

		for (var i = 0; i < lhsLength; i++) {
			// why the backwards check? because otherwise if NaN is present in either lhs or rhs
			// then Math.abs(NaN) is NaN which is neither bigger or smaller than EPSILON
			// which never satisfies the condition
			// NaN is not close to to NaN and we want to preserve that for vectors as well
			if (!(Math.abs(lhs.data[i] - rhs.data[i]) <= MathUtils.EPSILON)) {
				return false;
			}
		}

		return true;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.equals = function (rhs) {
		console.warn('Vector.prototype.equals is deprecated.');
		return Vector.equals(this, rhs);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.distanceSquared = function (lhs, rhs) {
		console.warn('Vector.distanceSquared is deprecated.');
		return Vector.sub(lhs, rhs).lengthSquared();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.distanceSquared = function (rhs) {
		console.warn('Vector.prototype.distanceSquared is deprecated.');
		return Vector.sub(this, rhs).lengthSquared();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.distance = function (lhs, rhs) {
		console.warn('Vector.distance is deprecated.');
		return Vector.sub(lhs, rhs).length();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.distance = function (rhs) {
		console.warn('Vector.prototype.distance is deprecated.');
		return Vector.sub(this, rhs).length();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.lengthSquared = function () {
		console.warn('Vector.prototype.lengthSquared is deprecated.');
		return Vector.dot(this, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.length = function () {
		console.warn('Vector.prototype.length is deprecated.');
		return Math.sqrt(Vector.dot(this, this));
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.scale = function(factor) {
		console.warn('Vector.prototype.scale is deprecated.');
		for (var i = this._size - 1; i >= 0; i--) {
			this.data[i] *= factor;
		}
		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.invert = function () {
		console.warn('Vector.prototype.invert is deprecated.');
		for (var i = 0; i < this._size; i++) {
			this.data[i] = 0.0 - this.data[i];
		}

		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.normalize = function () {
		console.warn('Vector.prototype.normalize is deprecated.');
		var l = this.length();
		var dataLength = this._size;

		if (l < MathUtils.EPSILON) {
			for (var i = 0; i < dataLength; i++) {
				this.data[i] = 0;
			}
		} else {
			l = 1.0 / l;
			for (var i = 0; i < dataLength; i++) {
				this.data[i] *= l;
			}
		}

		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.clone = function () {
		console.warn('Vector.prototype.clone is deprecated.');
		return Vector.copy(this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.set = function () {
		console.warn('Vector.prototype.set is deprecated.');
		if (arguments.length === 1 && typeof arguments[0] === 'object') {
			if (arguments[0] instanceof Vector) {
				this.copy(arguments[0]);
			} else {
				for (var i = 0; i < arguments[0].length; i++) {
					this.data[i] = arguments[0][i];
				}
			}
		} else {
			for (var i = 0; i < arguments.length; i++) {
				this.data[i] = arguments[i];
			}
		}

		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.toString = function () {
		console.warn('Vector.prototype.toString is deprecated.');
		var string = '';

		string += '[';

		for (var i = 0; i < this._size; i++) {
			string += this.data[i];
			string += i !== this._size - 1 ? ', ' : '';
		}

		string += ']';

		return string;
	};
	// SHIM END

	return Vector;
});
<commit_msg>friendlier warning for Vector .data<commit_after>define([
	'goo/math/MathUtils'
], function (
	MathUtils
	) {
	'use strict';

	/**
	 * Abstract vector class
	 */
	function Vector(size) {

		/**
		 * @hidden
		 * @deprecated
		 */
		this._size = size;
	}

	var COMPONENT_NAMES = ['x', 'y', 'z', 'w'];
	// #ifdef DEBUG
	var COMPONENT_NAMES = ['_x', '_y', '_z', '_w'];
	// #endif

	/**
	 * Binds aliases to the different vector components.
	 * @hidden
	 * @param {Object} prototype The prototype to bind to.
	 * @param {Array<Array<string>>} aliases Array of component aliases for each component index.
	 */
	Vector.setupAliases = function (prototype, aliases) {
		aliases.forEach(function (aliasesPerComponent, index) {
			var componentName = COMPONENT_NAMES[index];

			aliasesPerComponent.forEach(function (alias) {
				Object.defineProperty(prototype, alias, {
					get: function () {
						return this[componentName];
					},
					set: function (value) {
						this[componentName] = value;

						// #ifdef DEBUG
						if (isNaN(this[componentName])) {
							throw new Error('Tried setting NaN to vector component ' + alias);
						}
						// #endif
					}
				});
			});
		});
	};

	// #ifdef DEBUG
	Vector.setupIndices = function (prototype, count) {
		var raise = function () {
			throw new Error('Vector component access through indices is not supported anymore');
		};

		for (var i = 0; i < count; i++) {
			Object.defineProperty(prototype, i, {
				get: raise,
				set: raise
			});
		}
	};

	/**
	 * Replaces the supplied method of object and wraps it in a integrity check
	 * @hidden
	 * @param {Object} object The object to attach the post-check to
	 * @param {string} methodName The name of the original method the check is attached to
	 */
	Vector.addReturnCheck = function (object, methodName) {
		var originalMethod = object[methodName];
		object[methodName] = function () {
			var ret = originalMethod.apply(this, arguments);
			if (isNaN(ret)) {
				throw new Error('Vector method ' + methodName + ' returned NaN');
			}

			return ret;
		};
	};

	/**
	 * Adds more validators at once
	 * @hidden
	 * @param {Object} object
	 * @param {Array<string>} methodNames
	 */
	Vector.addReturnChecks = function (object, methodNames) {
		methodNames.forEach(Vector.addReturnCheck.bind(null, object));
	};
	// #endif

	// SHIM START
	Object.defineProperty(Vector.prototype, 'data', {
		get: function () {
			var data = [];
			var that = this;
			console.warn('The .data property of Vector was removed, please use the .x, .y, .z, .w properties instead.');
			Object.defineProperties(data, {
				'0': {
					get: function () {
						return that.x;
					},
					set: function (value) {
						that.x = value;
					}
				},
				'1': {
					get: function () {
						return that.y;
					},
					set: function (value) {
						that.y = value;
					}
				},
				'2': {
					get: function () {
						return that.z;
					},
					set: function (value) {
						that.z = value;
					}
				},
				'3': {
					get: function () {
						return that.w;
					},
					set: function (value) {
						that.w = value;
					}
				}
			});
			return data;
		}
	});

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.add = function (lhs, rhs, target) {
		console.warn('Vector.add is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] + rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.add = function (rhs) {
		console.warn('Vector.prototype.add is deprecated.');
		return Vector.add(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.sub = function (lhs, rhs, target) {
		console.warn('Vector.sub is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] - rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.sub = function (rhs) {
		console.warn('Vector.prototype.sub is deprecated.');
		return Vector.sub(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.mul = function (lhs, rhs, target) {
		console.warn('Vector.mul is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] * rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.mul = function (rhs) {
		console.warn('Vector.prototype.mul is deprecated.');
		return Vector.mul(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.div = function (lhs, rhs, target) {
		console.warn('Vector.div is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		if (!target) {
			target = new Vector(size);
		}

		for (var i = 0; i < size; i++) {
			target.data[i] = ldata[i] / rdata[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.div = function (rhs) {
		console.warn('Vector.prototype.div is deprecated.');
		return Vector.div(this, rhs, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.copy = function (source, target) {
		console.warn('Vector.copy is deprecated.');
		var size = source._size;

		if (!target) {
			target = new Vector(size);
		}

		for(var i=0; i<size; i++){
			target.data[i] = source.data[i];
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.copy = function (source) {
		console.warn('Vector.prototype.copy  is deprecated.');
		var size = source._size;
		for(var i=0; i<size; i++){
			this.data[i] = source.data[i];
		}
		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.dot = function (lhs, rhs) {
		console.warn('Vector.dot is deprecated.');
		var ldata = lhs.data || lhs;
		var rdata = rhs.data || rhs;
		var size = lhs._size;

		var sum = 0;

		for (var i = 0; i < size; i++) {
			sum += ldata[i] * rdata[i];
		}

		return sum;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.dot = function (rhs) {
		console.warn('Vector.prototype.dot is deprecated.');
		return Vector.dot(this, rhs);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.apply = function (lhs, rhs, target) {
		console.warn('Vector.apply is deprecated.');
		var rows = lhs.rows;
		var cols = lhs.cols;
		var size = rhs._size;

		if (!target) {
			target = new Vector(rows);
		}

		if (target === rhs) {
			return Vector.copy(Vector.apply(lhs, rhs), target);
		}

		for (var c = 0; c < cols; c++) {
			var o = c * rows;

			for (var r = 0; r < rows; r++) {
				var sum = 0.0;

				for (var i = 0; i < size; i++) {
					sum += lhs.data[i * lhs.rows + r] * rhs.data[i];
				}

				target.data[o + r] = sum;
			}
		}

		return target;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.apply = function (lhs) {
		console.warn('Vector.prototype.apply is deprecated.');
		return Vector.apply(lhs, this, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.equals = function (lhs, rhs) {
		console.warn('Vector.equals is deprecated.');
		var lhsLength = lhs._size;
		if (lhsLength !== rhs._size) {
			return false;
		}

		for (var i = 0; i < lhsLength; i++) {
			// why the backwards check? because otherwise if NaN is present in either lhs or rhs
			// then Math.abs(NaN) is NaN which is neither bigger or smaller than EPSILON
			// which never satisfies the condition
			// NaN is not close to to NaN and we want to preserve that for vectors as well
			if (!(Math.abs(lhs.data[i] - rhs.data[i]) <= MathUtils.EPSILON)) {
				return false;
			}
		}

		return true;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.equals = function (rhs) {
		console.warn('Vector.prototype.equals is deprecated.');
		return Vector.equals(this, rhs);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.distanceSquared = function (lhs, rhs) {
		console.warn('Vector.distanceSquared is deprecated.');
		return Vector.sub(lhs, rhs).lengthSquared();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.distanceSquared = function (rhs) {
		console.warn('Vector.prototype.distanceSquared is deprecated.');
		return Vector.sub(this, rhs).lengthSquared();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.distance = function (lhs, rhs) {
		console.warn('Vector.distance is deprecated.');
		return Vector.sub(lhs, rhs).length();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.distance = function (rhs) {
		console.warn('Vector.prototype.distance is deprecated.');
		return Vector.sub(this, rhs).length();
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.lengthSquared = function () {
		console.warn('Vector.prototype.lengthSquared is deprecated.');
		return Vector.dot(this, this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.length = function () {
		console.warn('Vector.prototype.length is deprecated.');
		return Math.sqrt(Vector.dot(this, this));
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.scale = function(factor) {
		console.warn('Vector.prototype.scale is deprecated.');
		for (var i = this._size - 1; i >= 0; i--) {
			this.data[i] *= factor;
		}
		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.invert = function () {
		console.warn('Vector.prototype.invert is deprecated.');
		for (var i = 0; i < this._size; i++) {
			this.data[i] = 0.0 - this.data[i];
		}

		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.normalize = function () {
		console.warn('Vector.prototype.normalize is deprecated.');
		var l = this.length();
		var dataLength = this._size;

		if (l < MathUtils.EPSILON) {
			for (var i = 0; i < dataLength; i++) {
				this.data[i] = 0;
			}
		} else {
			l = 1.0 / l;
			for (var i = 0; i < dataLength; i++) {
				this.data[i] *= l;
			}
		}

		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.clone = function () {
		console.warn('Vector.prototype.clone is deprecated.');
		return Vector.copy(this);
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.set = function () {
		console.warn('Vector.prototype.set is deprecated.');
		if (arguments.length === 1 && typeof arguments[0] === 'object') {
			if (arguments[0] instanceof Vector) {
				this.copy(arguments[0]);
			} else {
				for (var i = 0; i < arguments[0].length; i++) {
					this.data[i] = arguments[0][i];
				}
			}
		} else {
			for (var i = 0; i < arguments.length; i++) {
				this.data[i] = arguments[i];
			}
		}

		return this;
	};

	/**
	 * @hidden
	 * @deprecated
	 */
	Vector.prototype.toString = function () {
		console.warn('Vector.prototype.toString is deprecated.');
		var string = '';

		string += '[';

		for (var i = 0; i < this._size; i++) {
			string += this.data[i];
			string += i !== this._size - 1 ? ', ' : '';
		}

		string += ']';

		return string;
	};
	// SHIM END

	return Vector;
});
<|endoftext|>


<commit_before>require('dotenv/config')
const { DefinePlugin } = require('webpack')
const BabiliPlugin = require('babili-webpack-plugin')

const {
  API_SCHEME,
  API_HOSTNAME,
  API_PORT,
  NODE_ENV
} = process.env

const API_URL = `${API_SCHEME}://${API_HOSTNAME}:${API_PORT}`

const define = new DefinePlugin({
  'process.env.API_URL': JSON.stringify(API_URL)
})

module.exports = {
  webpack: config => {
    const plugins = config.plugins
      .filter(({ constructor }) => constructor.name !== 'UglifyJsPlugin')
      .concat(define)
    if (NODE_ENV === 'production') {
      plugins.push(new BabiliPlugin())
    }
    return { ...config, plugins }
  }
}
<commit_msg>Fixed erroneous next.config.js. #1<commit_after>require('dotenv/config')
const { DefinePlugin } = require('webpack')
const BabiliPlugin = require('babili-webpack-plugin')

const {
  API_SCHEME,
  API_HOSTNAME,
  API_PORT,
  NODE_ENV
} = process.env

const API_URL = `${API_SCHEME}://${API_HOSTNAME}:${API_PORT}`

const define = new DefinePlugin({
  'process.env.API_URL': JSON.stringify(API_URL)
})

module.exports = {
  webpack: config => {
    config.plugins = config.plugins
      .filter(({ constructor }) => constructor.name !== 'UglifyJsPlugin')
      .concat(define)
    if (NODE_ENV === 'production') {
      config.plugins.push(new BabiliPlugin())
    }
    return config
  }
}
<|endoftext|>


<commit_before>/**
 * @jsx React.DOM
 */

"use strict";

var React = require("react/addons");
var _ = require("underscore");
var Router = require("react-router-component");
var Locations = Router.Locations;
var Location = Router.Location;
var NotFound = Router.NotFound;
var UserModel = require("./models/UserModel.js");

require("./vendor/react.backbone.js");

var Pages = require("./pages.js");
var GoogleAnalytics = require("./utils/GoogleAnalytics.js");

// CSS
require("../styles/reset.scss");
require("../styles/icons.css");
require("../styles/app.scss");

var App = React.createClass({
  mixins: [Router.NavigatableMixin],
  getInitialState: function() {
    var userData = _.extend({}, CS.user, {loading: _.isUndefined(CS.user)});
    return {
      user: new UserModel(userData)
    };
  },
  /*jshint ignore:start */
  render: function() {
    if (this.state.user.cortex.loading.val()) {
      return (
        <Locations onNavigation={GoogleAnalytics.TrackNavigation}>
          <NotFound handler={Pages.Login} />
        </Locations>
      );
    } else {
      var user = this.state.user;
      return (
        <Locations onNavigation={GoogleAnalytics.TrackNavigation}>
          <Location path="/" user={user} handler={Pages.Home} />
          <Location path="/query/" user={user} handler={Pages.Search} />
          <Location path="/query/:query" user={user} handler={Pages.Search} />
          <Location path="/profile" user={user} handler={Pages.Profile} />
          <Location path="/articles/:articleId" user={user} handler={Pages.Article} />
          <Location path="/authors/:authorId" user={user} handler={Pages.Author} />
          <Location path="/login" user={user} handler={Pages.Login} />
          <Location path="/logout" user={user} handler={Pages.Logout} />
          <Location path="/signup" user={user} handler={Pages.Signup} />
          <NotFound handler={Pages.NotFound} />
        </Locations>
      );
    }
  }
  /*jshint ignore:end */
});

React.renderComponent(<App />, document.getElementById("page")); // jshint ignore:line

module.exports = App;
<commit_msg>Use hash navigation so that we don't have to worry about serving from /beta<commit_after>/**
 * @jsx React.DOM
 */

"use strict";

var React = require("react/addons");
var _ = require("underscore");
var Router = require("react-router-component");
var Locations = Router.Locations;
var Location = Router.Location;
var NotFound = Router.NotFound;
var UserModel = require("./models/UserModel.js");

require("./vendor/react.backbone.js");

var Pages = require("./pages.js");
var GoogleAnalytics = require("./utils/GoogleAnalytics.js");

// CSS
require("../styles/reset.scss");
require("../styles/icons.css");
require("../styles/app.scss");

var App = React.createClass({
  mixins: [Router.NavigatableMixin],
  getInitialState: function() {
    var userData = _.extend({}, CS.user, {loading: _.isUndefined(CS.user)});
    return {
      user: new UserModel(userData)
    };
  },
  /*jshint ignore:start */
  render: function() {
    if (this.state.user.cortex.loading.val()) {
      return (
        <Locations onNavigation={GoogleAnalytics.TrackNavigation} hash>
          <NotFound handler={Pages.Login} />
        </Locations>
      );
    } else {
      var user = this.state.user;
      return (
        <Locations onNavigation={GoogleAnalytics.TrackNavigation} hash>
          <Location path="/" user={user} handler={Pages.Home} />
          <Location path="/query/" user={user} handler={Pages.Search} />
          <Location path="/query/:query" user={user} handler={Pages.Search} />
          <Location path="/profile" user={user} handler={Pages.Profile} />
          <Location path="/articles/:articleId" user={user} handler={Pages.Article} />
          <Location path="/authors/:authorId" user={user} handler={Pages.Author} />
          <Location path="/login" user={user} handler={Pages.Login} />
          <Location path="/logout" user={user} handler={Pages.Logout} />
          <Location path="/signup" user={user} handler={Pages.Signup} />
          <NotFound handler={Pages.NotFound} />
        </Locations>
      );
    }
  }
  /*jshint ignore:end */
});

React.renderComponent(<App />, document.getElementById("page")); // jshint ignore:line

module.exports = App;
<|endoftext|>


<commit_before>import React from 'react'
import Bubbles from './Bubbles'

export default class Welcome extends React.Component {
  render() {
    const { opacity } = this.props

    const containerStyle = {
      background: '#E64369',
      bottom: 0,
      color: 'white',
      display: 'flex',
      flexDirection: 'column',
      fontFamily: 'Helvetica Neue, Helvetica',
      fontSize: 30,
      fontWeight: '100',
      justifyContent: 'center',
      left: 0,
      position: 'absolute',
      right: 0,
      textAlign: 'center',
      top: 0,
    }

    const openSourceProject = {
      color: 'white',
      fontSize: 16,
      margin: 0,
      opacity: 0.5,
      padding: 5,
      position: 'absolute',
      right: 0,
      textDecoration: 'none',
      top: 0,
    }

    return (

          <Bubbles />

Searching videos outside of your bubble…

          What is this?

    )
  }
}
<commit_msg>Remove opacity from “What is this?” link 💋<commit_after>import React from 'react'
import Bubbles from './Bubbles'

export default class Welcome extends React.Component {
  render() {
    const { opacity } = this.props

    const containerStyle = {
      background: '#E64369',
      bottom: 0,
      color: 'white',
      display: 'flex',
      flexDirection: 'column',
      fontFamily: 'Helvetica Neue, Helvetica',
      fontSize: 30,
      fontWeight: '100',
      justifyContent: 'center',
      left: 0,
      position: 'absolute',
      right: 0,
      textAlign: 'center',
      top: 0,
    }

    const openSourceProject = {
      color: 'white',
      fontSize: 16,
      margin: 0,
      padding: 5,
      position: 'absolute',
      right: 0,
      textDecoration: 'none',
      top: 0,
    }

    return (

          <Bubbles />

Searching videos outside of your bubble…

          What is this?

    )
  }
}
<|endoftext|>


<commit_before>pc.extend(pc, (function () {
    'use strict';

    var shaderChunks = {};
    var shaderCache = {};

    var attrib2Semantic = {};
    attrib2Semantic["vertex_position"] = pc.SEMANTIC_POSITION;
    attrib2Semantic["vertex_normal"] = pc.SEMANTIC_NORMAL;
    attrib2Semantic["vertex_tangent"] = pc.SEMANTIC_TANGENT;
    attrib2Semantic["vertex_texCoord0"] = pc.SEMANTIC_TEXCOORD0;
    attrib2Semantic["vertex_texCoord1"] = pc.SEMANTIC_TEXCOORD1;
    attrib2Semantic["vertex_color"] = pc.SEMANTIC_COLOR;

    shaderChunks.collectAttribs = function (vsCode) {
        var attribs = {};
        var attrs = 0;

        var found = vsCode.indexOf("attribute");
        while (found >= 0) {
            var endOfLine = vsCode.indexOf(';', found);
            var startOfAttribName = vsCode.lastIndexOf(' ', endOfLine);
            var attribName = vsCode.substr(startOfAttribName + 1, endOfLine - (startOfAttribName + 1));

            var semantic = attrib2Semantic[attribName];
            if (semantic!==undefined) {
                attribs[attribName] = semantic;
            }

            found = vsCode.indexOf("attribute", found + 1);
        }
        return attribs;
    };

    shaderChunks.createShader = function(device, vsName, psName) {
        var vsCode = shaderChunks[vsName];
        var psCode = pc.programlib.precisionCode(device) + "\n" + shaderChunks[psName];
        var attribs = this.collectAttribs(vsCode);

        return new pc.Shader(device, {
            attributes: attribs,
            vshader: vsCode,
            fshader: psCode
        });
    };

    shaderChunks.createShaderFromCode = function(device, vsCode, psCode, uName) {
        var cached = shaderCache[uName];
        if (cached !== undefined) return cached;

        psCode = pc.programlib.precisionCode(device) + "\n" + psCode;
        var attribs = this.collectAttribs(vsCode);
        shaderCache[uName] = new pc.Shader(device, {
            attributes: attribs,
            vshader: vsCode,
            fshader: psCode
        });
        return shaderCache[uName];
    };

    return {
        shaderChunks: shaderChunks
    };
}()));
<commit_msg>hotfix collectAttribs<commit_after>pc.extend(pc, (function () {
    'use strict';

    var shaderChunks = {};
    var shaderCache = {};

    var attrib2Semantic = {};
    attrib2Semantic["vertex_position"] = pc.SEMANTIC_POSITION;
    attrib2Semantic["vertex_normal"] = pc.SEMANTIC_NORMAL;
    attrib2Semantic["vertex_tangent"] = pc.SEMANTIC_TANGENT;
    attrib2Semantic["vertex_texCoord0"] = pc.SEMANTIC_TEXCOORD0;
    attrib2Semantic["vertex_texCoord1"] = pc.SEMANTIC_TEXCOORD1;
    attrib2Semantic["vertex_color"] = pc.SEMANTIC_COLOR;

    shaderChunks.collectAttribs = function (vsCode) {
        var attribs = {};
        var attrs = 0;

        var found = vsCode.indexOf("attribute");
        while (found >= 0) {
            var endOfLine = vsCode.indexOf(';', found);
            var startOfAttribName = vsCode.lastIndexOf(' ', endOfLine);
            var attribName = vsCode.substr(startOfAttribName + 1, endOfLine - (startOfAttribName + 1));

            var semantic = attrib2Semantic[attribName];
            if (semantic!==undefined) {
                attribs[attribName] = semantic;
            } else {
                attribs[attribName] = "ATTR" + attrs;
                attrs++;
            }

            found = vsCode.indexOf("attribute", found + 1);
        }
        return attribs;
    };

    shaderChunks.createShader = function(device, vsName, psName) {
        var vsCode = shaderChunks[vsName];
        var psCode = pc.programlib.precisionCode(device) + "\n" + shaderChunks[psName];
        var attribs = this.collectAttribs(vsCode);

        return new pc.Shader(device, {
            attributes: attribs,
            vshader: vsCode,
            fshader: psCode
        });
    };

    shaderChunks.createShaderFromCode = function(device, vsCode, psCode, uName) {
        var cached = shaderCache[uName];
        if (cached !== undefined) return cached;

        psCode = pc.programlib.precisionCode(device) + "\n" + psCode;
        var attribs = this.collectAttribs(vsCode);
        shaderCache[uName] = new pc.Shader(device, {
            attributes: attribs,
            vshader: vsCode,
            fshader: psCode
        });
        return shaderCache[uName];
    };

    return {
        shaderChunks: shaderChunks
    };
}()));
<|endoftext|>


<commit_before>import angular from 'angular';
import ngMaterial from 'angular-material';
import ngSortable from 'angular-legacy-sortablejs-maintained';
import cgBusy from '@cgross/angular-busy';
import $ from 'jquery';

import Graph from './utils/graph';
import Filter from './utils/filter';

import 'font-awesome/css/font-awesome.css';
import 'angular-material/angular-material.css';
import '@cgross/angular-busy/dist/angular-busy.css';
import '../style/app.css';

let app = () => {
  return {
    template: require('./app.html'),
    controller: 'AppCtrl',
    controllerAs: 'app'
  }
};

const MODULE_NAME = 'app';
angular.module(MODULE_NAME, [ngMaterial, 'ng-sortable', cgBusy])
  .directive('app', app)
  .controller('AppCtrl', /*@ngInject*/ ($scope, $http) => {
      //init some inital data
      $scope.filters = [];
      $scope.searchItem = null;
      $scope.data = {};
      $scope.ctxMenu = {top: 0, left: 0, show: false, items: []};
      $scope.sidebarHidden = false;
      //configuration for the sortable filter list
      $scope.sortableConf = {
          animation: 150,
          ghostClass: "ghost",
          onUpdate: (evt) => {
              //refresh our graph when the list get rearranged
              $scope.refreshGraph();
          }
      };
      //setup the graph
      $scope.graph = new Graph("#graph", (d, e) => {
          //context menu handler, this function shows our context menu for nodes
          //set menu position
          $scope.ctxMenu.top = e.clientY;
          $scope.ctxMenu.left = e.clientX;

          if(d.id.startsWith("r_")) { //menu for representatives
              $scope.ctxMenu.items = [
                {name: "Add Donating SuperPACs", action: () => {
                    //a menu item that adds all the superpacs that donated to this representative
                    let names = [];
                    let id = d.id.substring(2);
                    //loop over all the donations getting matches
                    Object.keys($scope.data.donations || {}).forEach((key) => {
                        if($scope.data.donations[key].destination == id) {
                            names.push($scope.data.committees[$scope.data.donations[key].source].name);
                        }
                    });

                    //create a multi node filter
                    let predicateFactory = Filter.multiNodeFilterFactory(names, Filter.type.COMMITTEE);

                    //add the filter to our list of filters, initially in additive mode
                    $scope.filters.unshift({
                        name: d.name+"'s SuperPACs",
                        type: Filter.type.COMMITTEE,
                        predicate: predicateFactory(true),
                        predicateFactory,
                        additive: true
                    });

                    //refresh our graph
                    $scope.refreshGraph();
                }}
              ];
          } else if(d.id.startsWith("c_")) {//menu for committees
              $scope.ctxMenu.items = [
                {name: "Add Politicians Donated To", action: () => {
                    //a menu item that adds all the representatives that superpac donated to
                    let names = [];
                    let id = d.id.substring(2);
                    //loop over all the donations getting matches
                    Object.keys($scope.data.donations || {}).forEach((key) => {
                        if($scope.data.donations[key].source == id) {
                            names.push($scope.data.representatives[$scope.data.donations[key].destination].name);
                        }
                    });

                    //create a multi node filter
                    let predicateFactory = Filter.multiNodeFilterFactory(names, Filter.type.REPRESENTATIVE);

                    //add the filter to our list of filters, initially in additive mode
                    $scope.filters.unshift({
                        name: d.name+"'s Recipents",
                        type: Filter.type.REPRESENTATIVE,
                        predicate: predicateFactory(true),
                        predicateFactory,
                        additive: true
                    });

                    //refresh our graph
                    $scope.refreshGraph();
                }}
              ];
          }

          //show the menu
          $scope.ctxMenu.show = true;
          $scope.$apply();
      });

      //gets rid of our context menu when the user clicks elsewhere or presses escape
      let hideCtxMenu = (e) => {
          if($scope.ctxMenu.show) {
              if(e && e.target && (e.target.id == "ctxMenu" || $(e.target).parents("#ctxMenu").length)) {
                  return;
              }
              $scope.ctxMenu.show = false;
              $scope.$apply();
          }
      };
      $(document).mousedown(hideCtxMenu);
      $(window).blur(hideCtxMenu);
      $(document).keyup((e) => {
          if (e.keyCode == 27) { // escape key maps to keycode `27`
              hideCtxMenu();
          }
      });

      //this function gets called whenever someone types in the search box, with their query so far
      $scope.searchQuery = (query) => {
          //make a call to our api with the query
          return $http
            .get('/api/search', {params: { query: query }})
            .then(function(response) {
                // Map the server's response to a format we can use.
                let data = [];

                //add matching special filters we have client size
                for(const f of Filter.general.filter((f) => {return f.name.toLowerCase().indexOf(query.toLowerCase()) != -1})) {
                    data.push({name: f.name, type: Filter.type.GENERAL, predicateFactory: f.predicateFactory});
                }

                //add matching representatives as filters
                for(const rep of response.data['representatives']) {
                    data.push({name: rep.name, type: Filter.type.REPRESENTATIVE});
                }

                //add matching committees as filters
                for(const committee of response.data['committees']) {
                    data.push({name: committee.name, type: Filter.type.COMMITTEE});
                }

                //todo add bills

                return data;
          });
      };

      //this gets called whenever the user selects a filter with the search box
      $scope.$watch('searchItem', () => {
          //make sure its a valid object
          if($scope.searchItem instanceof Object) {
              //get the item and its respective filter factory
              let item = $scope.searchItem;
              let predicateFactory = item.type == Filter.type.GENERAL ?
                          item.predicateFactory : Filter.nodeFilterFactory(item);

              //add the filter to our list of filters, initially in additive mode
              $scope.filters.unshift({
                  name: item.name,
                  type: item.type,
                  predicate: predicateFactory(true),
                  predicateFactory,
                  additive: true
              });

              //clear the user's selected item
              $scope.searchItem = null;
              $scope.searchText = "";

              //refresh our graph
              $scope.refreshGraph();
          }
      });

      //this gets triggered whenever the sidebar gets hidden, it causes the graph to resize
      $scope.$watch('sidebarHidden', () => {
          setTimeout(() => {
              $scope.graph.resize();
          }, 10);
      });
      //removes the given filter from the filter list and refreshes the graph
      $scope.removeFilter = (filter) => {
          $scope.filters.splice($scope.filters.indexOf(filter), 1);
          $scope.refreshGraph();
      };

      $scope.clearAll = () => {
        for(i = $scope.filters.length; i > 0; i--){
          $scope.filters.splice(i-1, 1);
          $scope.refreshGraph();
        }
      }

      //flips the given filter's additive mode and refreshes the graph
      $scope.flipFilter = (filter) => {
          filter.additive = !filter.additive;
          filter.predicate = filter.predicateFactory(filter.additive);
          $scope.refreshGraph();
      };

      //refreshes the graph
      $scope.refreshGraph = () => {
          let filteredData = Filter.filter($scope.filters, $scope.data);
          $scope.graph.draw(filteredData);
      };

      //get our entire donation dataset from the server
      $scope.donationPromise = $http.get('/api/donations').then((response) => {
          $scope.data = response.data;
          $scope.refreshGraph();
      });
  });

export default MODULE_NAME;
<commit_msg>Update app.js<commit_after>import angular from 'angular';
import ngMaterial from 'angular-material';
import ngSortable from 'angular-legacy-sortablejs-maintained';
import cgBusy from '@cgross/angular-busy';
import $ from 'jquery';

import Graph from './utils/graph';
import Filter from './utils/filter';

import 'font-awesome/css/font-awesome.css';
import 'angular-material/angular-material.css';
import '@cgross/angular-busy/dist/angular-busy.css';
import '../style/app.css';

let app = () => {
  return {
    template: require('./app.html'),
    controller: 'AppCtrl',
    controllerAs: 'app'
  }
};

const MODULE_NAME = 'app';
angular.module(MODULE_NAME, [ngMaterial, 'ng-sortable', cgBusy])
  .directive('app', app)
  .controller('AppCtrl', /*@ngInject*/ ($scope, $http) => {
      //init some inital data
      $scope.filters = [];
      $scope.searchItem = null;
      $scope.data = {};
      $scope.ctxMenu = {top: 0, left: 0, show: false, items: []};
      $scope.sidebarHidden = false;
      //configuration for the sortable filter list
      $scope.sortableConf = {
          animation: 150,
          ghostClass: "ghost",
          onUpdate: (evt) => {
              //refresh our graph when the list get rearranged
              $scope.refreshGraph();
          }
      };
      //setup the graph
      $scope.graph = new Graph("#graph", (d, e) => {
          //context menu handler, this function shows our context menu for nodes
          //set menu position
          $scope.ctxMenu.top = e.clientY;
          $scope.ctxMenu.left = e.clientX;

          if(d.id.startsWith("r_")) { //menu for representatives
              $scope.ctxMenu.items = [
                {name: "Add Donating SuperPACs", action: () => {
                    //a menu item that adds all the superpacs that donated to this representative
                    let names = [];
                    let id = d.id.substring(2);
                    //loop over all the donations getting matches
                    Object.keys($scope.data.donations || {}).forEach((key) => {
                        if($scope.data.donations[key].destination == id) {
                            names.push($scope.data.committees[$scope.data.donations[key].source].name);
                        }
                    });

                    //create a multi node filter
                    let predicateFactory = Filter.multiNodeFilterFactory(names, Filter.type.COMMITTEE);

                    //add the filter to our list of filters, initially in additive mode
                    $scope.filters.unshift({
                        name: d.name+"'s SuperPACs",
                        type: Filter.type.COMMITTEE,
                        predicate: predicateFactory(true),
                        predicateFactory,
                        additive: true
                    });

                    //refresh our graph
                    $scope.refreshGraph();
                }}
              ];
          } else if(d.id.startsWith("c_")) {//menu for committees
              $scope.ctxMenu.items = [
                {name: "Add Politicians Donated To", action: () => {
                    //a menu item that adds all the representatives that superpac donated to
                    let names = [];
                    let id = d.id.substring(2);
                    //loop over all the donations getting matches
                    Object.keys($scope.data.donations || {}).forEach((key) => {
                        if($scope.data.donations[key].source == id) {
                            names.push($scope.data.representatives[$scope.data.donations[key].destination].name);
                        }
                    });

                    //create a multi node filter
                    let predicateFactory = Filter.multiNodeFilterFactory(names, Filter.type.REPRESENTATIVE);

                    //add the filter to our list of filters, initially in additive mode
                    $scope.filters.unshift({
                        name: d.name+"'s Recipents",
                        type: Filter.type.REPRESENTATIVE,
                        predicate: predicateFactory(true),
                        predicateFactory,
                        additive: true
                    });

                    //refresh our graph
                    $scope.refreshGraph();
                }}
              ];
          }

          //show the menu
          $scope.ctxMenu.show = true;
          $scope.$apply();
      });

      //gets rid of our context menu when the user clicks elsewhere or presses escape
      let hideCtxMenu = (e) => {
          if($scope.ctxMenu.show) {
              if(e && e.target && (e.target.id == "ctxMenu" || $(e.target).parents("#ctxMenu").length)) {
                  return;
              }
              $scope.ctxMenu.show = false;
              $scope.$apply();
          }
      };
      $(document).mousedown(hideCtxMenu);
      $(window).blur(hideCtxMenu);
      $(document).keyup((e) => {
          if (e.keyCode == 27) { // escape key maps to keycode `27`
              hideCtxMenu();
          }
      });

      //this function gets called whenever someone types in the search box, with their query so far
      $scope.searchQuery = (query) => {
          //make a call to our api with the query
          return $http
            .get('/api/search', {params: { query: query }})
            .then(function(response) {
                // Map the server's response to a format we can use.
                let data = [];

                //add matching special filters we have client size
                for(const f of Filter.general.filter((f) => {return f.name.toLowerCase().indexOf(query.toLowerCase()) != -1})) {
                    data.push({name: f.name, type: Filter.type.GENERAL, predicateFactory: f.predicateFactory});
                }

                //add matching representatives as filters
                for(const rep of response.data['representatives']) {
                    data.push({name: rep.name, type: Filter.type.REPRESENTATIVE});
                }

                //add matching committees as filters
                for(const committee of response.data['committees']) {
                    data.push({name: committee.name, type: Filter.type.COMMITTEE});
                }

                //todo add bills

                return data;
          });
      };

      //this gets called whenever the user selects a filter with the search box
      $scope.$watch('searchItem', () => {
          //make sure its a valid object
          if($scope.searchItem instanceof Object) {
              //get the item and its respective filter factory
              let item = $scope.searchItem;
              let predicateFactory = item.type == Filter.type.GENERAL ?
                          item.predicateFactory : Filter.nodeFilterFactory(item);

              //add the filter to our list of filters, initially in additive mode
              $scope.filters.unshift({
                  name: item.name,
                  type: item.type,
                  predicate: predicateFactory(true),
                  predicateFactory,
                  additive: true
              });

              //clear the user's selected item
              $scope.searchItem = null;
              $scope.searchText = "";

              //refresh our graph
              $scope.refreshGraph();
          }
      });

      //this gets triggered whenever the sidebar gets hidden, it causes the graph to resize
      $scope.$watch('sidebarHidden', () => {
          setTimeout(() => {
              $scope.graph.resize();
          }, 10);
      });
      //removes the given filter from the filter list and refreshes the graph
      $scope.removeFilter = (filter) => {
          $scope.filters.splice($scope.filters.indexOf(filter), 1);
          $scope.refreshGraph();
      };

      $scope.clearAll = () => {
        filters = [];
        $scope.refreshGraph();
      };

      //flips the given filter's additive mode and refreshes the graph
      $scope.flipFilter = (filter) => {
          filter.additive = !filter.additive;
          filter.predicate = filter.predicateFactory(filter.additive);
          $scope.refreshGraph();
      };

      //refreshes the graph
      $scope.refreshGraph = () => {
          let filteredData = Filter.filter($scope.filters, $scope.data);
          $scope.graph.draw(filteredData);
      };

      //get our entire donation dataset from the server
      $scope.donationPromise = $http.get('/api/donations').then((response) => {
          $scope.data = response.data;
          $scope.refreshGraph();
      });
  });

export default MODULE_NAME;
<|endoftext|>


<commit_before>
/* Contains all source code modules assigned to RG. */

const RG = require('./rg');

RG.Verify = require('./verify');

RG.EventPool = require('./eventpool');

// No deps to RG.SubElems
RG.Random = require('./random');
RG.GameObject = require('./game-object');
RG.Mixin = require('./mixin');
RG.Geometry = require('./geometry');
RG.Time = require('./time');
RG.Template = require('./template');
RG.Animation = require('./animation');

// Minor deps to other exports
RG.Component = require('./component');
RG.Item = require('./item');
RG.Spell = require('./spell');
RG.System = require('./system');
RG.BTree = require('./aisequence');

RG.Goals = require('./goals');
RG.GoalsBattle = require('./goals-battle');
RG.GoalsTop = require('./goals-top');

RG.Brain = require('./brain');
RG.Brain.Memory = require('./brain.memory');
RG.Inv = require('./inv');
RG.Actor = require('./actor');
RG.Element = require('./element');

RG.Cell = require('./map.cell');
RG.Map = require('./map');
RG.Map.Level = require('./level');
RG.LevelGenerator = require('./level-generator');
RG.MountainGenerator = require('./mountain-generator');
RG.DungeonGenerator = require('./dungeon-generator');
RG.CaveGenerator = require('./cave-generator');

RG.World = require('./world');

RG.Effects = require('../data/effects');
RG.ObjectShell = require('./objectshellparser');

RG.Game = require('./game');
RG.Factory = require('./factory');
RG.Factory.World = require('./factory.world');
RG.Factory.Zone = require('./factory.zone');

RG.Names = require('../data/name-gen');
RG.LevelGen = require('../data/level-gen');

RG.OW = require('./overworld.map');
RG.Overworld = require('./overworld');

RG.Game.FromJSON = require('./game.fromjson');
RG.Chunk = require('./chunk-manager');

RG.Factory.Game = require('./factory.game');

module.exports = RG;

<commit_msg>Added System.Manager.<commit_after>
/* Contains all source code modules assigned to RG. */

const RG = require('./rg');

RG.Verify = require('./verify');

RG.EventPool = require('./eventpool');

// No deps to RG.SubElems
RG.Random = require('./random');
RG.GameObject = require('./game-object');
RG.Mixin = require('./mixin');
RG.Geometry = require('./geometry');
RG.Time = require('./time');
RG.Template = require('./template');
RG.Animation = require('./animation');

// Minor deps to other exports
RG.Component = require('./component');
RG.Item = require('./item');
RG.Spell = require('./spell');
RG.System = require('./system');
RG.System.Manager = require('./system/system.manager');
RG.BTree = require('./aisequence');

RG.Goals = require('./goals');
RG.GoalsBattle = require('./goals-battle');
RG.GoalsTop = require('./goals-top');

RG.Brain = require('./brain');
RG.Brain.Memory = require('./brain.memory');
RG.Inv = require('./inv');
RG.Actor = require('./actor');
RG.Element = require('./element');

RG.Cell = require('./map.cell');
RG.Map = require('./map');
RG.Map.Level = require('./level');
RG.LevelGenerator = require('./level-generator');
RG.MountainGenerator = require('./mountain-generator');
RG.DungeonGenerator = require('./dungeon-generator');
RG.CaveGenerator = require('./cave-generator');

RG.World = require('./world');

RG.Effects = require('../data/effects');
RG.ObjectShell = require('./objectshellparser');

RG.Game = require('./game');
RG.Factory = require('./factory');
RG.Factory.World = require('./factory.world');
RG.Factory.Zone = require('./factory.zone');

RG.Names = require('../data/name-gen');
RG.LevelGen = require('../data/level-gen');

RG.OW = require('./overworld.map');
RG.Overworld = require('./overworld');

RG.Game.FromJSON = require('./game.fromjson');
RG.Chunk = require('./chunk-manager');

RG.Factory.Game = require('./factory.game');

module.exports = RG;

<|endoftext|>


<commit_before>import tr from "i18next";
import createBrowserHistory from "history/createBrowserHistory";
import formatter from "utils/formatter";
import alertStackCreate from "components/alertStack";
import Rest from "./utils/rest";
import theme from "./theme";

import rootConfig from "./config";

export default ({config, layout}) => {
  const context = {
    rest: Rest(),
    theme: theme(),
    tr,
    formatter: formatter("en"),
    history: createBrowserHistory(),
    config: {...rootConfig, ...config}
  };
  context.alertStack = alertStackCreate(context, { limit: 3 });
  return context;
};
<commit_msg>remove createBrowserHistory warning<commit_after>import tr from "i18next";
import { createBrowserHistory } from "history";
import formatter from "utils/formatter";
import alertStackCreate from "components/alertStack";
import Rest from "./utils/rest";
import theme from "./theme";

import rootConfig from "./config";

export default ({ config }) => {
  const context = {
    rest: Rest(),
    theme: theme(),
    tr,
    formatter: formatter("en"),
    history: createBrowserHistory(),
    config: { ...rootConfig, ...config }
  };
  context.alertStack = alertStackCreate(context, { limit: 3 });
  return context;
};
<|endoftext|>


<commit_before>all();
function all() {
   /**
    * Function is alias to {@link Session.init}
    * @param {string} [host] Host socket.io is connecting to
    * @param {object} clientDescription User specified description of client
    * @returns {Session.init} Instance of session
    *
    * @alias Session
    * @constructor
    */
   var Session = function(host, clientDescription) {
      return new Session.init(host, clientDescription);
   };

   /**
    * Check if uuid is valid
    * @param {string} uuid uuid to check
    * @returns {boolean}
    */
   var isUUID = function(uuid) {
      var uuidRegexp = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      return uuidRegexp.test(uuid);
   };

//   var //Returns true if object is a DOM node
//      isNode = function(o) {
//         return (typeof Node === "object" ? o instanceof Node :
//            o && typeof o === "object" && typeof o.nodeType === "number"
//               && typeof o.nodeName === "string");
//      }
//      , //Returns true if object is a DOM element
//      isElement = function(o) {
//         return (typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
//            o && typeof o === "object" && o !== null && o.nodeType === 1
//               && typeof o.nodeName === "string");
//      }
//      , //Returns true if object is jQuery element
//      isJQueryElement = function(o) {
//         return (o instanceof Session.modules.$);
//      }
//      , //Check if object is empty
//      isEmpty = function(obj) {
//         for (var key in obj) {
//            if (obj.hasOwnProperty(key))
//               return false;
//         }
//         return true;
//      }
//      , //default drag callback
//      defaultDragCallback = function(ev) {
//         var $ = Session.modules.$;
//
//      };

   /**
    * Is true when {@link Session.init#socket socket} is connected and
    * {@link Session.init#MTObjects MT objects} initialized
    * @type {boolean}
    */
   Session.READY = false;

   /**
    * All events that sent to server
    * @type {{}}
    */
   var io_send_calls = {
      new_connection:       "CONN"
      , subscribe_mt_event: "MT_EVENT_SUBSCRIBE"
      , message_sent:       "SEND_MSG"
      , broadcast_sent:     "SEND_BROADCAST"
   };
   /**
    * All events that received from server
    * @type {{}}
    */
   var io_recv_calls = Session.when = {
      connection_ok:        "CONN_OK"
      , user_connected:     "CONN_USER"
      , user_disconnected:  "DEL_USER"
      , message_received:   "RECV_MSG"
      , broadcast_received: "RECV_BROADCAST"
   };
   io_recv_calls.has = function(target) {
      for (var i in this) {
         if (this[i] === target) {
            return true;
         }
      }
      return false;
   };
   //   Session.events = new Session.modules.ev();

   /**
    * Function initializes new session instance
    * @param {string} [host] Host socket.io is connecting to
    * @param {object} clientDescription User specified description of client
    * @returns {Session.init} Instance of session
    *
    * @constructor
    */
   Session.init = function(host, clientDescription) {
      if (typeof host !== "string") {
         clientDescription = host;
         host = undefined;
      }
      var self = this;

      /**
       * Description of client for current session
       * @type {Object}
       */
      this.description = clientDescription;
      /**
       * Objects that has multi-touch properties
       * @type {Array}
       */
      this.MTObjects = [];
      this.MTSelector = "";

      /**
       * Array with all clients connected to server except this
       * @type {Array}
       */
      this.otherClients = [];

      /**
       * Socket to the host for the current session
       * @type {*|io.Socket}
       */
      this.socket = Session.modules.io.connect(host);

      this.socket.emit(io_send_calls.new_connection, {
         description: clientDescription
      });
      this.socket.once(io_recv_calls.connection_ok, function(data) {
         self.uuid = data.data.uuid;
         self.otherClients = data.data.otherClients;

         //TODO fire event or something similar when connection happened
      });
      this.socket.on(io_recv_calls.user_connected, function(data) {
         self.otherClients.push(data.data.client);

         //TODO fire event
      });
      this.socket.on(io_recv_calls.user_disconnected, function(data) {
         if (self.otherClients.length > 0) {
            var toDelete = -1, i;
            for (i = 0; i < self.otherClients.length && toDelete === -1; i++) {
               if (self.otherClients[i].uuid === data.data.client.uuid) {toDelete = i;}
            }
            if (toDelete != -1) {
               self.otherClients.splice(toDelete, 1);
            }

            //TODO fire event
         }
      });
      this.socket.on(io_recv_calls.message_received, function(data) {
//         console.log(data);
         //TODO fire event
      });
      this.socket.on(io_recv_calls.broadcast_received, function(data) {
//         console.log(data);
         //TODO fire event
      });

      Session.READY = true;
      return this;
   };

   Session.init.prototype = {
      /**
       * All multitouch events from Hammer
       * @type {string[]}
       */
      MTEvents: [
         "hold", "tap", "doubletap", "drag", "dragstart", "dragend", "dragup",
         "dragdown", "dragleft", "dragright", "swipe", "swipeup", "swipedown",
         "swipeleft", "swiperight", "transform", "transformstart", "transformend",
         "rotate", "pinch", "pinchin", "pinchout", "touch", "release"
      ],

      /**
       * Specify on which element multitouch is started
       * @param {jQuery} elem Jquery array of elements
       */
      addMT: function(elem) {
         //TODO make hammer start on body and move items only with certain classes
         //FIXME --bug 1--
         // when we pass clean js array of html elements (not $),
         // and we push each element into MTObjects array, inside "on" function
         // callback on elements is not called.
         // Also. When in MTObjects was pushed instance of Hammer, "on" function
         // was not calling callback on elements. (On github wiki it is working)
         for (var i = 0, len = elem.length; i < len; i++) {
            var newMTObj = new Session.modules.Hammer(elem[i], {
               prevent_default: true,
               no_mouseevents: true
            });
//            this.MTObjects.push(newMTObj);
         }
         this.MTObjects.push(elem);
      },

      // TODO check on idea of starting MT on body and only allowing
      // to interact with elements with certain selector
//      startMT: function (selector) {
//         new Session.modules.Hammer(document.body, {
//            prevent_default: true,
//            no_mouseevents: true
//         });
//         this.MTSelector = selector;
//      },

      /**
       * Send data to server through {@link Session.init#socket|socket}
       * @param {string} type Type of event created on server
       * @param {string|object} data Object to send
       */
      emit: function(type, data) {
         var self = this;
         this.socket.emit(type, {
            uuid: self.uuid,
            msg: data
         });
      },

      /**
       * Register callback on specified event
       * @param {string|string[]} types On which types fire callback
       * @param {function} callback Function to execute
       */
      on: function(types, callback) {
         var self = this;
         types.split(' ').forEach(function(type) { // in case types is given as string of few events
            if (type === "shake") {
               window.addEventListener(type, callback, false);
            } else if (io_recv_calls.has(type)) { // one of internal events
               self.socket.on(type, function(data) {
                  callback(data.data);
               });
            } else if (self.MTEvents.indexOf(type) != -1) { // if this event is from hammer
               self.MTObjects.forEach(function (MTObj) { // to all mt objects we attach listener
                  MTObj.on(type, function (ev) { //listener callback
                     var touches = ev.originalEvent.gesture.touches;
                     var event = {
                           type: type,
                           element: []
                        };
                     for (var i = 0; i < touches.length; i++) {
                        var touch = touches[i];
                        event.element.push({
                           tag: touch.target.tagName,
                           id: touch.target.id,
                           className: touch.target.className,
                           innerHTML: touch.target.innerHTML,
                           x: touch.pageX,
                           y: touch.pageY
                        });
                     }
                     self.emit(type, event);

                     //FIXME --bug 1-- continued
                     // cont from higher - this callback is not called when event is
                     // generated. Right before callback any console.log is called,
                     // but right inside this callback none of console.log are called
                     callback(ev);
                  });
               });
            } else {
               self.socket.on(type, function (data) {
                  callback(data);
               });
            }
         });
      },

      /**
       * Stop listening for events of these types
       * @param {string|string[]} types
       * @param {function} callback specify which function should be unsubscribed
       */
      off: function(types, callback) {
         var self = this;
         types.split(' ').forEach(function(type) { // in case types is given as string of few events
            if (type === "shake") {
               window.removeEventListener(type, callback, false);
            } else if (self.MTEvents.indexOf(type) != -1) {
               self.MTObjects.off(type, callback);
               self.socket.removeListener(type, callback);
            }
            else {
               self.socket.removeListener(type, callback);
            }
         });
      },

      /**
       * Register callback on event type from remote server
       * @param {string|string[]} types On which types fire callback
       * @param {function} callback Function to execute
       */
      onRemote: function(types, callback) {
         var self = this;
         self.emit(io_send_calls.subscribe_mt_event, {
            eventType: types
         });
         types.split(' ').forEach(function(type) {
            self.socket.on(type, function(data) {
               callback(data.data);
            });
         });
      },

      /**
       * Send message to specified clients through server
       * @param {string[]} targets Array of target uuids
       * @param {String|object} msg message
       */
      sendMSG: function(targets, msg) {
         var self = this;
         self.emit(io_send_calls.message_sent, {
            targets: targets,
            msg: msg
         });
      },

      /**
       * Send message to all clients through server
       * @param {String|object} msg message
       */
      broadcastMSG: function(msg) {
         var self = this;
         self.emit(io_send_calls.broadcast_sent, {
            msg: msg
         });
      },

      //FIXME rewrite better without return in the middle of for
      getDescription: function(uuid) {
         if (!isUUID(uuid)) {
//            console.error("Provide correct uuid");
            return undefined;
         }
         for (var i = 0; i < this.otherClients.length; i++) {
            if (this.otherClients[i].uuid === uuid) {
               return this.otherClients[i].description;
            }
         }
         return undefined;
      }
   };

   /*
    //Shared dic
    var dic = {};
    this.socket.on("DIC_SNAPSHOT", function(data) {
    dic = data;
    });
    this.socket.on("DIC_UPDATE", function(data) {
    dic[data.attr] = data.value;
    console.log(dic);
    });
    console.log(dic);
    this.socket.emit("PUSH_TO_DIC", {
    attr: "uuid", value: this.uuid
    });
    dic["uuid"] = this.uuid;
    console.log(dic);
    //Shared dic end
    */

   // Taken from Hammer.js and modified
   // Based off Lo-Dash's excellent UMD wrapper (slightly modified) - https://github.com/bestiejs/lodash/blob/master/lodash.js#L5515-L5543
   // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
   if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
      // define as module
      define(["jquery", "hammer", "socket.io"],
         function ($, Hammer, io) {
            if (!Session.modules) {
               Session.modules = {};
            }
            Session.modules.$ = $;
            Session.modules.Hammer = Hammer;
            Session.modules.io = io;

            return Session;
         });
   }
   // Browserify support
   else if(typeof module === 'object' && typeof module.exports === 'object') {
      var $ = require('');
      var Hammer = require('hammerjs');
      var io = require('socket.io-client');

      Session.modules.$ = $;
      Session.modules.Hammer = Hammer;
      Session.modules.io = io;

      module.exports = Session;
   }
   // If we have no plugins
   else {
      Session.modules.$ = window.jQuery;
      Session.modules.Hammer = window.Hammer;
      Session.modules.io = window.io;

      window.Session = Session;
   }
}<commit_msg>feat(session): wrap every message into data field and add source uuid<commit_after>all();
function all() {
   /**
    * Function is alias to {@link Session.init}
    * @param {string} [host] Host socket.io is connecting to
    * @param {object} clientDescription User specified description of client
    * @returns {Session.init} Instance of session
    *
    * @alias Session
    * @constructor
    */
   var Session = function(host, clientDescription) {
      return new Session.init(host, clientDescription);
   };

   /**
    * Check if uuid is valid
    * @param {string} uuid uuid to check
    * @returns {boolean}
    */
   var isUUID = function(uuid) {
      var uuidRegexp = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      return uuidRegexp.test(uuid);
   };

//   var //Returns true if object is a DOM node
//      isNode = function(o) {
//         return (typeof Node === "object" ? o instanceof Node :
//            o && typeof o === "object" && typeof o.nodeType === "number"
//               && typeof o.nodeName === "string");
//      }
//      , //Returns true if object is a DOM element
//      isElement = function(o) {
//         return (typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
//            o && typeof o === "object" && o !== null && o.nodeType === 1
//               && typeof o.nodeName === "string");
//      }
//      , //Returns true if object is jQuery element
//      isJQueryElement = function(o) {
//         return (o instanceof Session.modules.$);
//      }
//      , //Check if object is empty
//      isEmpty = function(obj) {
//         for (var key in obj) {
//            if (obj.hasOwnProperty(key))
//               return false;
//         }
//         return true;
//      }
//      , //default drag callback
//      defaultDragCallback = function(ev) {
//         var $ = Session.modules.$;
//
//      };

   /**
    * Is true when {@link Session.init#socket socket} is connected and
    * {@link Session.init#MTObjects MT objects} initialized
    * @type {boolean}
    */
   Session.READY = false;

   /**
    * All events that sent to server
    * @type {{}}
    */
   var io_send_calls = {
      new_connection:       "CONN"
      , subscribe_mt_event: "MT_EVENT_SUBSCRIBE"
      , message_sent:       "SEND_MSG"
      , broadcast_sent:     "SEND_BROADCAST"
   };
   /**
    * All events that received from server
    * @type {{}}
    */
   var io_recv_calls = Session.when = {
      connection_ok:        "CONN_OK"
      , user_connected:     "CONN_USER"
      , user_disconnected:  "DEL_USER"
      , message_received:   "RECV_MSG"
      , broadcast_received: "RECV_BROADCAST"
   };
   io_recv_calls.has = function(target) {
      for (var i in this) {
         if (this[i] === target) {
            return true;
         }
      }
      return false;
   };
   //   Session.events = new Session.modules.ev();

   /**
    * Function initializes new session instance
    * @param {string} [host] Host socket.io is connecting to
    * @param {object} clientDescription User specified description of client
    * @returns {Session.init} Instance of session
    *
    * @constructor
    */
   Session.init = function(host, clientDescription) {
      if (typeof host !== "string") {
         clientDescription = host;
         host = undefined;
      }
      var self = this;

      /**
       * Description of client for current session
       * @type {Object}
       */
      this.description = clientDescription;
      /**
       * Objects that has multi-touch properties
       * @type {Array}
       */
      this.MTObjects = [];
      this.MTSelector = "";

      /**
       * Array with all clients connected to server except this
       * @type {Array}
       */
      this.otherClients = [];

      /**
       * Socket to the host for the current session
       * @type {*|io.Socket}
       */
      this.socket = Session.modules.io.connect(host);

      this.socket.emit(io_send_calls.new_connection, {
         description: clientDescription
      });
      this.socket.once(io_recv_calls.connection_ok, function(data) {
         self.uuid = data.data.uuid;
         self.otherClients = data.data.otherClients;

         //TODO fire event or something similar when connection happened
      });
      this.socket.on(io_recv_calls.user_connected, function(data) {
         self.otherClients.push(data.data.client);

         //TODO fire event
      });
      this.socket.on(io_recv_calls.user_disconnected, function(data) {
         if (self.otherClients.length > 0) {
            var toDelete = -1, i;
            for (i = 0; i < self.otherClients.length && toDelete === -1; i++) {
               if (self.otherClients[i].uuid === data.data.client.uuid) {toDelete = i;}
            }
            if (toDelete != -1) {
               self.otherClients.splice(toDelete, 1);
            }

            //TODO fire event
         }
      });
      this.socket.on(io_recv_calls.message_received, function(data) {
//         console.log(data);
         //TODO fire event
      });
      this.socket.on(io_recv_calls.broadcast_received, function(data) {
//         console.log(data);
         //TODO fire event
      });

      Session.READY = true;
      return this;
   };

   Session.init.prototype = {
      /**
       * All multitouch events from Hammer
       * @type {string[]}
       */
      MTEvents: [
         "hold", "tap", "doubletap", "drag", "dragstart", "dragend", "dragup",
         "dragdown", "dragleft", "dragright", "swipe", "swipeup", "swipedown",
         "swipeleft", "swiperight", "transform", "transformstart", "transformend",
         "rotate", "pinch", "pinchin", "pinchout", "touch", "release"
      ],

      /**
       * Specify on which element multitouch is started
       * @param {jQuery} elem Jquery array of elements
       */
      addMT: function(elem) {
         //TODO make hammer start on body and move items only with certain classes
         //FIXME --bug 1--
         // when we pass clean js array of html elements (not $),
         // and we push each element into MTObjects array, inside "on" function
         // callback on elements is not called.
         // Also. When in MTObjects was pushed instance of Hammer, "on" function
         // was not calling callback on elements. (On github wiki it is working)
         for (var i = 0, len = elem.length; i < len; i++) {
            var newMTObj = new Session.modules.Hammer(elem[i], {
               prevent_default: true,
               no_mouseevents: true
            });
//            this.MTObjects.push(newMTObj);
         }
         this.MTObjects.push(elem);
      },

      // TODO check on idea of starting MT on body and only allowing
      // to interact with elements with certain selector
//      startMT: function (selector) {
//         new Session.modules.Hammer(document.body, {
//            prevent_default: true,
//            no_mouseevents: true
//         });
//         this.MTSelector = selector;
//      },

      /**
       * Send data to server through {@link Session.init#socket|socket}
       * @param {string} type Type of event created on server
       * @param {string|object} data Object to send
       */
      emit: function(type, data) {
         var self = this;
         this.socket.emit(type, {
            source: self.uuid,
            data: data
         });
      },

      /**
       * Register callback on specified event
       * @param {string|string[]} types On which types fire callback
       * @param {function} callback Function to execute
       */
      on: function(types, callback) {
         var self = this;
         types.split(' ').forEach(function(type) { // in case types is given as string of few events
            if (type === "shake") {
               window.addEventListener(type, callback, false);
            } else if (io_recv_calls.has(type)) { // one of internal events
               self.socket.on(type, function(data) {
                  callback(data.data);
               });
            } else if (self.MTEvents.indexOf(type) != -1) { // if this event is from hammer
               self.MTObjects.forEach(function (MTObj) { // to all mt objects we attach listener
                  MTObj.on(type, function (ev) { //listener callback
                     var touches = ev.originalEvent.gesture.touches;
                     var event = {
                           type: type,
                           element: []
                        };
                     for (var i = 0; i < touches.length; i++) {
                        var touch = touches[i];
                        event.element.push({
                           tag: touch.target.tagName,
                           id: touch.target.id,
                           className: touch.target.className,
                           innerHTML: touch.target.innerHTML,
                           x: touch.pageX,
                           y: touch.pageY
                        });
                     }
                     self.emit(type, event);

                     //FIXME --bug 1-- continued
                     // cont from higher - this callback is not called when event is
                     // generated. Right before callback any console.log is called,
                     // but right inside this callback none of console.log are called
                     callback(ev);
                  });
               });
            } else {
               self.socket.on(type, function (data) {
                  callback(data);
               });
            }
         });
      },

      /**
       * Stop listening for events of these types
       * @param {string|string[]} types
       * @param {function} callback specify which function should be unsubscribed
       */
      off: function(types, callback) {
         var self = this;
         types.split(' ').forEach(function(type) { // in case types is given as string of few events
            if (type === "shake") {
               window.removeEventListener(type, callback, false);
            } else if (self.MTEvents.indexOf(type) != -1) {
               self.MTObjects.off(type, callback);
               self.socket.removeListener(type, callback);
            }
            else {
               self.socket.removeListener(type, callback);
            }
         });
      },

      /**
       * Register callback on event type from remote server
       * @param {string|string[]} types On which types fire callback
       * @param {function} callback Function to execute
       */
      onRemote: function(types, callback) {
         var self = this;
         self.emit(io_send_calls.subscribe_mt_event, {
            eventType: types
         });
         types.split(' ').forEach(function(type) {
            self.socket.on(type, function(data) {
               callback(data.data);
            });
         });
      },

      /**
       * Send message to specified clients through server
       * @param {string[]} targets Array of target uuids
       * @param {String|object} msg message
       */
      sendMSG: function(targets, msg) {
         var self = this;
         self.emit(io_send_calls.message_sent, {
            targets: targets,
            msg: msg
         });
      },

      /**
       * Send message to all clients through server
       * @param {String|object} msg message
       */
      broadcastMSG: function(msg) {
         var self = this;
         self.emit(io_send_calls.broadcast_sent, {
            msg: msg
         });
      },

      //FIXME rewrite better without return in the middle of for
      getDescription: function(uuid) {
         if (!isUUID(uuid)) {
//            console.error("Provide correct uuid");
            return undefined;
         }
         for (var i = 0; i < this.otherClients.length; i++) {
            if (this.otherClients[i].uuid === uuid) {
               return this.otherClients[i].description;
            }
         }
         return undefined;
      }
   };

   /*
    //Shared dic
    var dic = {};
    this.socket.on("DIC_SNAPSHOT", function(data) {
    dic = data;
    });
    this.socket.on("DIC_UPDATE", function(data) {
    dic[data.attr] = data.value;
    console.log(dic);
    });
    console.log(dic);
    this.socket.emit("PUSH_TO_DIC", {
    attr: "uuid", value: this.uuid
    });
    dic["uuid"] = this.uuid;
    console.log(dic);
    //Shared dic end
    */

   // Taken from Hammer.js and modified
   // Based off Lo-Dash's excellent UMD wrapper (slightly modified) - https://github.com/bestiejs/lodash/blob/master/lodash.js#L5515-L5543
   // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
   if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
      // define as module
      define(["jquery", "hammer", "socket.io"],
         function ($, Hammer, io) {
            if (!Session.modules) {
               Session.modules = {};
            }
            Session.modules.$ = $;
            Session.modules.Hammer = Hammer;
            Session.modules.io = io;

            return Session;
         });
   }
   // Browserify support
   else if(typeof module === 'object' && typeof module.exports === 'object') {
      var $ = require('');
      var Hammer = require('hammerjs');
      var io = require('socket.io-client');

      Session.modules.$ = $;
      Session.modules.Hammer = Hammer;
      Session.modules.io = io;

      module.exports = Session;
   }
   // If we have no plugins
   else {
      Session.modules.$ = window.jQuery;
      Session.modules.Hammer = window.Hammer;
      Session.modules.io = window.io;

      window.Session = Session;
   }
}<|endoftext|>


<commit_before>/**
 * @file Crumbs component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import classNames from 'classnames';

import Crumb from '../_Crumb';
import Tip from '../Tip';
import Theme from '../Theme';

import PureRender from '../_vendors/PureRender';
import Util from '../_vendors/Util';

@PureRender
class Crumbs extends Component {

    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.itemRender = ::this.itemRender;

    }

    itemRender(item, index) {

        if (item.renderer) {
            return item.renderer(item, index);
        }

        const {itemRenderer, onItemTouchTap} = this.props;
        if (itemRenderer) {
            return itemRenderer(item, index);
        }

        return <Crumb {...item}
                      onTouchTap={e => {
                          item.onTouchTap && item.onTouchTap(e);
                          onItemTouchTap && onItemTouchTap(e, item, index);
                      }}/>;

    }

    render() {

        const {className, style, data, separator, showLastSeparator} = this.props,

            crumbsClassName = classNames('crumbs', {
                [className]: className
            });

        return (

                {
                    data && data.map((item, index) =>

                            {this.itemRender(item, index)}

                            {
                                !showLastSeparator && index === data.length - 1 ?
                                    null
                                    :

                                        {separator}

                            }

                    )
                }

        );

    }
};

if (process.env.NODE_ENV === 'development') {

    const PropTypes = require('prop-types');

    Crumbs.propTypes = {

        /**
         * The CSS class name of the root element.
         */
        className: PropTypes.string,

        /**
         * Override the styles of the root element.
         */
        style: PropTypes.object,

        /**
         * The theme of the Crumbs.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        /**
         * Crumbs data config.
         */
        data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

            /**
             * The CSS class name of the list button.
             */
            className: PropTypes.string,

            /**
             * Override the styles of the list button.
             */
            style: PropTypes.object,

            /**
             * The theme of the list button.
             */
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            /**
             * The url of crumb.
             */
            href: PropTypes.string,

            /**
             * The text value of the list button.Type can be string or number.
             */
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The list item's display text. Type can be string, number or bool.
             */
            text: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The desc value of the list button. Type can be string or number.
             */
            desc: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * If true,the list item will be disabled.
             */
            disabled: PropTypes.bool,

            /**
             * If true,the button will be have loading effect.
             */
            isLoading: PropTypes.bool,

            /**
             * If true,the element's ripple effect will be disabled.
             */
            disableTouchRipple: PropTypes.bool,

            /**
             * Use this property to display an icon. It will display on the left.
             */
            iconCls: PropTypes.string,

            /**
             * Use this property to display an icon. It will display on the right.
             */
            rightIconCls: PropTypes.string,

            /**
             * The message of tip.
             */
            tip: PropTypes.string,

            /**
             * The position of tip.
             */
            tipPosition: PropTypes.oneOf(Util.enumerateValue(Tip.Position)),

            /**
             * If true,the item will have center displayed ripple effect.
             */
            rippleDisplayCenter: PropTypes.bool,

            /**
             * You can create a complicated renderer callback instead of value and desc prop.
             */
            renderer: PropTypes.func,

            /**
             * Callback function fired when a list item touch-tapped.
             */
            onTouchTap: PropTypes.func

        }), PropTypes.string, PropTypes.number])).isRequired,

        separator: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        showLastSeparator: PropTypes.bool,

        /**
         * Crumbs data renderer callback.
         */
        itemRenderer: PropTypes.func,

        onItemTouchTap: PropTypes.func

    };

}

Crumbs.defaultProps = {

    className: null,
    style: null,
    theme: Theme.DEFAULT,

    data: null,

    separator: '>',
    showLastSeparator: false

};

export default Crumbs;<commit_msg>update Crumbs<commit_after>/**
 * @file Crumbs component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import classNames from 'classnames';

import Crumb from '../_Crumb';
import Tip from '../Tip';
import Theme from '../Theme';

import PureRender from '../_vendors/PureRender';
import Util from '../_vendors/Util';

@PureRender
class Crumbs extends Component {

    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.itemRender = ::this.itemRender;

    }

    itemRender(item, index) {

        if (item.renderer) {
            return item.renderer(item, index);
        }

        const {itemRenderer, onItemTouchTap} = this.props;
        if (itemRenderer) {
            return itemRenderer(item, index);
        }

        return <Crumb {...item}
                      onTouchTap={e => {
                          item.onTouchTap && item.onTouchTap(e);
                          onItemTouchTap && onItemTouchTap(e, item, index);
                      }}/>;

    }

    render() {

        const {className, style, data, separator, showLastSeparator} = this.props,

            crumbsClassName = classNames('crumbs', {
                [className]: className
            });

        return (

                {
                    data && data.map((item, index) =>

                            {this.itemRender(item, index)}

                            {
                                !showLastSeparator && index === data.length - 1 ?
                                    null
                                    :

                                        {separator}

                            }

                    )
                }

        );

    }
};

if (process.env.NODE_ENV === 'development') {

    const PropTypes = require('prop-types');

    Crumbs.propTypes = {

        /**
         * The CSS class name of the root element.
         */
        className: PropTypes.string,

        /**
         * Override the styles of the root element.
         */
        style: PropTypes.object,

        /**
         * The theme of the Crumbs.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        /**
         * Crumbs data config.
         */
        data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

            /**
             * The CSS class name of the list button.
             */
            className: PropTypes.string,

            /**
             * Override the styles of the list button.
             */
            style: PropTypes.object,

            /**
             * The theme of the list button.
             */
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            /**
             * The url of crumb.
             */
            href: PropTypes.string,

            /**
             * The text value of the list button.Type can be string or number.
             */
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The list item's display text. Type can be string, number or bool.
             */
            text: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The desc value of the list button. Type can be string or number.
             */
            desc: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * If true,the list item will be disabled.
             */
            disabled: PropTypes.bool,

            /**
             * If true,the button will be have loading effect.
             */
            isLoading: PropTypes.bool,

            /**
             * If true,the element's ripple effect will be disabled.
             */
            disableTouchRipple: PropTypes.bool,

            /**
             * Use this property to display an icon. It will display on the left.
             */
            iconCls: PropTypes.string,

            /**
             * Use this property to display an icon. It will display on the right.
             */
            rightIconCls: PropTypes.string,

            /**
             * The message of tip.
             */
            tip: PropTypes.string,

            /**
             * The position of tip.
             */
            tipPosition: PropTypes.oneOf(Util.enumerateValue(Tip.Position)),

            /**
             * If true,the item will have center displayed ripple effect.
             */
            rippleDisplayCenter: PropTypes.bool,

            /**
             * You can create a complicated renderer callback instead of value and desc prop.
             */
            renderer: PropTypes.func,

            /**
             * Callback function fired when a list item touch-tapped.
             */
            onTouchTap: PropTypes.func

        }), PropTypes.string, PropTypes.number])).isRequired,

        separator: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        showLastSeparator: PropTypes.bool,

        /**
         * Crumbs data renderer callback.
         */
        itemRenderer: PropTypes.func,

        onItemTouchTap: PropTypes.func

    };

}

Crumbs.defaultProps = {

    theme: Theme.DEFAULT,

    separator: '>',
    showLastSeparator: false

};

export default Crumbs;<|endoftext|>