<commit_before>var path = require('path');
var _ = require('lodash');
var getParameterNames = require('get-parameter-names');

var factoryKey = '__di_factory';
var fileKey = '__di_filename';
var limitCharacters = /[^a-z0-9]+/ig;
var appendedNumbers = /^[0-9]+/;

/**
 * @param {string[]} args
 * @param {object} dependencies
 * @returns {string}
 */
function getMissingDependencies(args, dependencies) {
	return _.remove(_.map(args, function(value, index) {
		return dependencies[index] === null ? value : null;
	})).join(', ');
}

/**
 * @param {function} [errorHandler]
 * @param {diFactory.Error|DiError} error
 * @throws
 */
function handleError(errorHandler, error) {
	if(typeof errorHandler !== 'function') {
		throw error;
	}
	errorHandler(error);
}

/**
 * @param {string|string[]} file
 * @param {function} onError
 * @param {string} diName
 * @returns {*}
 * @private
 */
function getFileContents(file, onError, diName) {
	var contents;
	file = _.isArray(file) ? path.join.apply(path, file) : file;
	try {
		contents = require(file);
		typeof contents === 'function' && Object.defineProperty(contents, fileKey, {
			enumerable: false,
			value: file
		});
		return contents;
	} catch(error) {
		handleError(onError, new DiError(DiError.COULD_NOT_REQUIRE, diName, 'Could not require file', null, error));
		return null;
	}
}

/**
 * @param {string} name - accessible via `.diName` and be able to request a specific
 *      service from a parent di by using this prefix like di(function(prefixService) {});
 * @param {di|di[]} [imports] - parent di to lock for, if dependency was not found in this one
 * @returns {di}
 */
function diFactory(name, imports) {
	// sanitized injector name in lowercase
	var diName = String(name).replace(limitCharacters, '').replace(appendedNumbers, '').toLowerCase();

	// public and private dependencies - key is lowercase: { name: value } and { <di-name>name: value }
	var _registers = {};

	// imported di instances
	var _imports = [];

	// once a dependency was found in an import, { name: value } is saved here ... is being cleared on .import()
	var _importCache = {};

	// public dependency names - key is lowercase: { name: true } and { <di-name>name: true }
	var _public = {};

	// public and private dependency names for .showDependencies() - key is lowercase: { name: true }
	var _names = {};

	/**
	 * dependency inject on fn
	 * @name di
	 * @throws Error if fn is not a function
	 * @throws Error if at least one dependency is missing
	 * @param {function} fn
	 * @param {object} [custom] overwrite injections with custom values
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @returns {*}
	 */
	function di(fn, custom, onError) {
		var args, injections;

		if(typeof fn !== 'function') {
			handleError(onError, new DiError(DiError.NOT_A_FUNCTION, diName, 'fn must be typeof function'));
			return null;
		}

		args = getParameterNames(fn);
		injections = custom ? args.map(function(arg) {
			// allow every custom value besides null (change null => undefined)
			return custom.hasOwnProperty(arg) ? (custom[arg] === null ? undefined : custom[arg]) : di.get(arg);
		}) : args.map(di.get);

		if(injections.indexOf(null) !== -1) {
			handleError(onError, new DiError(DiError.DEPENDENCY_NOT_FOUND, diName, 'could not inject "' + getMissingDependencies(args, injections) + '" (either missing or not setPublic() if imported)', fn));
			return null;
		}

		return fn.apply(fn, injections);
	}

	/**
	 * alias
	 * @type {di}
	 */
	di.invoke = di;

	/**
	 * alias
	 */
	di.diFactory = diFactory;

	/**
	 * dependency inject on file if module.exports is function
	 * @name di
	 * @throws Error if fn is not a function
	 * @throws Error if at least one dependency is missing
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @param {object} [custom] overwrite injections with custom values
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @returns {*}
	 */
	di.file = function(file, custom, onError) {
		var fn;
		if((fn = getFileContents(file, onError, diName)) === null) {
			return null;
		}
		if(typeof fn !== 'function') {
			handleError(onError, new DiError(DiError.NOT_A_FUNCTION, diName, 'require("' + file + '") did not return a function'));
			return null;
		}
		return di(fn, custom, onError);
	};

	/**
	 * @param {di|di[]} imports
	 * @returns {di}
	 */
	di.import = function(imports) {
		_.each([].concat(imports), function(d) {
			if(d && d.diName && _imports.indexOf(d) === -1 && d !== di) {
				_imports.push(d);
				_importCache = {};
			}
		});
		return di;
	};

	/**
	 * print dependencies to console.log or fn (if provided)
	 * @param {function(output)} [fn]
	 * @param {boolean} [inherited=false] - only show public
	 * @param {object} [processed] - already processed di names
	 */
	di.showDependencies = function(fn, inherited, processed) {
		var indent = function(str) { return '      ' + str; }
		var add = function(str) { str && lines.push(str); }
		var lines = [];

		processed = processed || {};
		if(processed.hasOwnProperty(diName)) {
			return;
		}
		processed[diName] = true;

		if(!inherited) {
			lines.push('Dependency Injector: ' + diName, '');
		}

		lines.push('  ' + diName + (inherited ? ' (inherited)' : ''));
		lines = lines.concat('    public', _.intersection(_.keys(_names), _.keys(_public)).map(indent));

		if(!inherited) {
			lines = lines.concat('    private', _.difference(_.keys(_names), _.keys(_public)).map(indent));
		}

		_.invoke(_imports, 'showDependencies', add, true, processed);

		;(fn || console.log)(lines.join('\n') + (inherited ? '' : '\n'));
	};

	/**
	 * @throws Error if name is a factory and factory does not find a dependency
	 * @param {string} name
	 * @param {boolean} [publicOnly]
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @returns {*|null}
	 */
	di.get = function(name, publicOnly, onError) {
		var index, dependency, key = name.toLowerCase();

		if(_registers.hasOwnProperty(key) && (publicOnly !== true || _public[key])) {
			if(_registers[key] && _registers[key][factoryKey]) {
				_registers[key] = _registers[key]({ __di_onError: onError });
			}
			return _registers[key];
		}

		if(_importCache.hasOwnProperty(key)) {
			return _importCache[key];
		}

		for(index = 0; index < _imports.length; index += 1) {
			if((dependency = _imports[index].get(key, true, onError)) !== null) {
				return _importCache[key] = dependency;
			}
		}

		return null;
	};

	/**
	 * same as get(), but throws an error, if name could not become resolved
	 * @throws Error if dependency was not found
	 * @param {string} name
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
 	 * @returns {*}
	 */
	di.require = function(name, onError) {
		var dependency;
		if((dependency = di.get(name, null, onError)) === null) {
			handleError(onError, new DiError(DiError.DEPENDENCY_NOT_FOUND, diName, '"' + name + '" required, but not registered'));
			return null;
		}

		return dependency;
	};

	/**
	 * @param {string} name
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @constructor
	 */
	function Dependency(name, onError) {
		this.di = di;
		this.name = String(name).replace(limitCharacters, '').replace(appendedNumbers, '').toLowerCase();
		this.onError = onError;
	}

	/**
	 * set dependency public
	 * @returns {Dependency}
	 */
	Dependency.prototype.public = function() {
		_public[this.name] = _public[diName + this.name] = true;
		return this;
	};

	/**
	 * @param {*} value
	 * @returns {Dependency}
	 */
	Dependency.prototype.value = function(value) {
		_registers[this.name] = _registers[diName + this.name] = value;
		_names[this.name] = true;
		return this;
	};

	/**
	 * register a namespace, that becomes dependency injected itself and is executed once on first request
	 * @throws Error if fn is not a function
	 * @param {function} fn
	 * @returns {Dependency}
	 */
	Dependency.prototype.factory = function(fn) {
		if(typeof fn !== 'function') {
			handleError(this.onError, new DiError(DiError.NOT_A_FUNCTION, diName, '"' + name + '" was defined as factory but is not typeof function'));
			return this;
		}

		var callback = di.callback(fn);
		callback[factoryKey] = true;
		this.value(callback);
		return this;
	};

	/**
	 * require file and this.factory() if module.exports is function, otherwise this.value()
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @returns {Dependency}
	 */
	Dependency.prototype.file = function(file) {
		var contents;
		if((contents = getFileContents(file, this.onError, diName)) !== null) {
			this[typeof contents === 'function' ? 'factory' : 'value'](contents);
		}
		return this;
	};

	/**
	 * require file and this.value() its contents
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @returns {Dependency}
	 */
	Dependency.prototype.fileValue = function(file) {
		var contents;
		if((contents = getFileContents(file, this.onError, diName)) !== null) {
			this.value(contents);
		}
		return this;
	};

	/**
	 * require file and this.factory() its contents
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @returns {Dependency}
	 */
	Dependency.prototype.fileFactory = function(file) {
		var contents;
		if((contents = getFileContents(file, this.onError, diName)) !== null) {
			this.factory(contents);
		}
		return this;
	};

	/**
	 * register a namespace
	 * @param {string} name
	 * @param {function} [onError]
	 * @returns {diFactory.Dependency}
	 */
	di.register = function(name, onError) {
		return new Dependency(name, onError);
	};

	/**
	 * @param {string} name
	 * @param {di|di[]} [imports]
	 * @returns {di}
	 */
	di.newChild = function(name, imports) {
		return diFactory(name, [di].concat(imports || []));
	};

	/**
	 * @returns {string[]}
	 */
	di.getImportNames = function() {
		return _.map(imports, function(d) {
			return d.diName;
		});
	};

	/**
	 * returns a callback that does not execute fn immediately
	 * @param {function} fn
	 * @param {object} [custom]
	 * @param {function(err)} [onError]
	 * @returns {Function}
	 */
	di.callback = function(fn, custom, onError) {
		/**
		 * @param {object} [opt]
		 * @param {function(err)} [opt.__di_onError] - internal pass error handler on lazy loading
		 */
		return function() {
			return di.invoke(fn, custom, (arguments[0] && arguments[0].__di_onError) || onError);
		};
	};

	di.diName = diName;
	di.import(imports);
	di.register('di').value(di);
	return di;
}

/**
 * invoke fn with each di in "dis" and return array of results
 * @param {di[]} dis
 * @param {function} fn
 * @returns {*[]}
 */
diFactory.mapInvoke = function(dis, fn) {
	return _.invoke(dis, 'invoke', fn);
};

/**
 * @name DependencyInjectionError
 */
var DiError = diFactory.Error = diFactory.DependencyInjectionError = (function() {
	/**
	 * @param {number} code
	 * @param {string} name
	 * @param {string} message
	 * @param {function} [context]
	 * @param {string} [context.__di_filename]
	 * @param {Error} [error] inherit stack from existing error
	 * @constructor
	 */
	function DependencyInjectionError(code, name, message, context, error) {
		this.code = code;
		this.message = this.name + ': ' + message + ' (di: ' + name + ')';
		this.message += context && context[fileKey] ? '\n    at file (' + context[fileKey] + ':1:0)' : '';
		this.message += context ? [].concat('', '... context ...', context.toString().split('\n').splice(0, 5), '...', '').join('\n') : '';
		if(error instanceof Error) {
			this.stack = this.message + '\n' + error.stack;
		} else if(Error.captureStackTrace) {
			Error.captureStackTrace(this, DependencyInjectionError);
		}
	}

	DependencyInjectionError.prototype = new Error();
	DependencyInjectionError.prototype.constructor = DependencyInjectionError;
	DependencyInjectionError.prototype.name = 'DependencyInjectionError';

	DependencyInjectionError.COULD_NOT_REQUIRE = 101;
	DependencyInjectionError.NOT_A_FUNCTION = 102;
	DependencyInjectionError.DEPENDENCY_NOT_FOUND = 103;

	return DependencyInjectionError;
}());

module.exports = diFactory;<commit_msg>fix jsdoc return value on .register() for code completion in WebStorm<commit_after>var path = require('path');
var _ = require('lodash');
var getParameterNames = require('get-parameter-names');

var factoryKey = '__di_factory';
var fileKey = '__di_filename';
var limitCharacters = /[^a-z0-9]+/ig;
var appendedNumbers = /^[0-9]+/;

/**
 * @param {string[]} args
 * @param {object} dependencies
 * @returns {string}
 */
function getMissingDependencies(args, dependencies) {
	return _.remove(_.map(args, function(value, index) {
		return dependencies[index] === null ? value : null;
	})).join(', ');
}

/**
 * @param {function} [errorHandler]
 * @param {diFactory.Error|DiError} error
 * @throws
 */
function handleError(errorHandler, error) {
	if(typeof errorHandler !== 'function') {
		throw error;
	}
	errorHandler(error);
}

/**
 * @param {string|string[]} file
 * @param {function} onError
 * @param {string} diName
 * @returns {*}
 * @private
 */
function getFileContents(file, onError, diName) {
	var contents;
	file = _.isArray(file) ? path.join.apply(path, file) : file;
	try {
		contents = require(file);
		typeof contents === 'function' && Object.defineProperty(contents, fileKey, {
			enumerable: false,
			value: file
		});
		return contents;
	} catch(error) {
		handleError(onError, new DiError(DiError.COULD_NOT_REQUIRE, diName, 'Could not require file', null, error));
		return null;
	}
}

/**
 * @param {string} name - accessible via `.diName` and be able to request a specific
 *      service from a parent di by using this prefix like di(function(prefixService) {});
 * @param {di|di[]} [imports] - parent di to lock for, if dependency was not found in this one
 * @returns {di}
 */
function diFactory(name, imports) {
	// sanitized injector name in lowercase
	var diName = String(name).replace(limitCharacters, '').replace(appendedNumbers, '').toLowerCase();

	// public and private dependencies - key is lowercase: { name: value } and { <di-name>name: value }
	var _registers = {};

	// imported di instances
	var _imports = [];

	// once a dependency was found in an import, { name: value } is saved here ... is being cleared on .import()
	var _importCache = {};

	// public dependency names - key is lowercase: { name: true } and { <di-name>name: true }
	var _public = {};

	// public and private dependency names for .showDependencies() - key is lowercase: { name: true }
	var _names = {};

	/**
	 * dependency inject on fn
	 * @name di
	 * @throws Error if fn is not a function
	 * @throws Error if at least one dependency is missing
	 * @param {function} fn
	 * @param {object} [custom] overwrite injections with custom values
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @returns {*}
	 */
	function di(fn, custom, onError) {
		var args, injections;

		if(typeof fn !== 'function') {
			handleError(onError, new DiError(DiError.NOT_A_FUNCTION, diName, 'fn must be typeof function'));
			return null;
		}

		args = getParameterNames(fn);
		injections = custom ? args.map(function(arg) {
			// allow every custom value besides null (change null => undefined)
			return custom.hasOwnProperty(arg) ? (custom[arg] === null ? undefined : custom[arg]) : di.get(arg);
		}) : args.map(di.get);

		if(injections.indexOf(null) !== -1) {
			handleError(onError, new DiError(DiError.DEPENDENCY_NOT_FOUND, diName, 'could not inject "' + getMissingDependencies(args, injections) + '" (either missing or not setPublic() if imported)', fn));
			return null;
		}

		return fn.apply(fn, injections);
	}

	/**
	 * alias
	 * @type {di}
	 */
	di.invoke = di;

	/**
	 * alias
	 */
	di.diFactory = diFactory;

	/**
	 * dependency inject on file if module.exports is function
	 * @name di
	 * @throws Error if fn is not a function
	 * @throws Error if at least one dependency is missing
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @param {object} [custom] overwrite injections with custom values
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @returns {*}
	 */
	di.file = function(file, custom, onError) {
		var fn;
		if((fn = getFileContents(file, onError, diName)) === null) {
			return null;
		}
		if(typeof fn !== 'function') {
			handleError(onError, new DiError(DiError.NOT_A_FUNCTION, diName, 'require("' + file + '") did not return a function'));
			return null;
		}
		return di(fn, custom, onError);
	};

	/**
	 * @param {di|di[]} imports
	 * @returns {di}
	 */
	di.import = function(imports) {
		_.each([].concat(imports), function(d) {
			if(d && d.diName && _imports.indexOf(d) === -1 && d !== di) {
				_imports.push(d);
				_importCache = {};
			}
		});
		return di;
	};

	/**
	 * print dependencies to console.log or fn (if provided)
	 * @param {function(output)} [fn]
	 * @param {boolean} [inherited=false] - only show public
	 * @param {object} [processed] - already processed di names
	 */
	di.showDependencies = function(fn, inherited, processed) {
		var indent = function(str) { return '      ' + str; }
		var add = function(str) { str && lines.push(str); }
		var lines = [];

		processed = processed || {};
		if(processed.hasOwnProperty(diName)) {
			return;
		}
		processed[diName] = true;

		if(!inherited) {
			lines.push('Dependency Injector: ' + diName, '');
		}

		lines.push('  ' + diName + (inherited ? ' (inherited)' : ''));
		lines = lines.concat('    public', _.intersection(_.keys(_names), _.keys(_public)).map(indent));

		if(!inherited) {
			lines = lines.concat('    private', _.difference(_.keys(_names), _.keys(_public)).map(indent));
		}

		_.invoke(_imports, 'showDependencies', add, true, processed);

		;(fn || console.log)(lines.join('\n') + (inherited ? '' : '\n'));
	};

	/**
	 * @throws Error if name is a factory and factory does not find a dependency
	 * @param {string} name
	 * @param {boolean} [publicOnly]
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @returns {*|null}
	 */
	di.get = function(name, publicOnly, onError) {
		var index, dependency, key = name.toLowerCase();

		if(_registers.hasOwnProperty(key) && (publicOnly !== true || _public[key])) {
			if(_registers[key] && _registers[key][factoryKey]) {
				_registers[key] = _registers[key]({ __di_onError: onError });
			}
			return _registers[key];
		}

		if(_importCache.hasOwnProperty(key)) {
			return _importCache[key];
		}

		for(index = 0; index < _imports.length; index += 1) {
			if((dependency = _imports[index].get(key, true, onError)) !== null) {
				return _importCache[key] = dependency;
			}
		}

		return null;
	};

	/**
	 * same as get(), but throws an error, if name could not become resolved
	 * @throws Error if dependency was not found
	 * @param {string} name
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
 	 * @returns {*}
	 */
	di.require = function(name, onError) {
		var dependency;
		if((dependency = di.get(name, null, onError)) === null) {
			handleError(onError, new DiError(DiError.DEPENDENCY_NOT_FOUND, diName, '"' + name + '" required, but not registered'));
			return null;
		}

		return dependency;
	};

	/**
	 * @param {string} name
	 * @param {function(err)} [onError] - callback to catch errors, if no callback is provided,
	 *      this method throws on error on error
	 * @constructor
	 */
	function Dependency(name, onError) {
		this.di = di;
		this.name = String(name).replace(limitCharacters, '').replace(appendedNumbers, '').toLowerCase();
		this.onError = onError;
	}

	/**
	 * set dependency public
	 * @returns {Dependency}
	 */
	Dependency.prototype.public = function() {
		_public[this.name] = _public[diName + this.name] = true;
		return this;
	};

	/**
	 * @param {*} value
	 * @returns {Dependency}
	 */
	Dependency.prototype.value = function(value) {
		_registers[this.name] = _registers[diName + this.name] = value;
		_names[this.name] = true;
		return this;
	};

	/**
	 * register a namespace, that becomes dependency injected itself and is executed once on first request
	 * @throws Error if fn is not a function
	 * @param {function} fn
	 * @returns {Dependency}
	 */
	Dependency.prototype.factory = function(fn) {
		if(typeof fn !== 'function') {
			handleError(this.onError, new DiError(DiError.NOT_A_FUNCTION, diName, '"' + name + '" was defined as factory but is not typeof function'));
			return this;
		}

		var callback = di.callback(fn);
		callback[factoryKey] = true;
		this.value(callback);
		return this;
	};

	/**
	 * require file and this.factory() if module.exports is function, otherwise this.value()
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @returns {Dependency}
	 */
	Dependency.prototype.file = function(file) {
		var contents;
		if((contents = getFileContents(file, this.onError, diName)) !== null) {
			this[typeof contents === 'function' ? 'factory' : 'value'](contents);
		}
		return this;
	};

	/**
	 * require file and this.value() its contents
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @returns {Dependency}
	 */
	Dependency.prototype.fileValue = function(file) {
		var contents;
		if((contents = getFileContents(file, this.onError, diName)) !== null) {
			this.value(contents);
		}
		return this;
	};

	/**
	 * require file and this.factory() its contents
	 * @param {string|string[]} file - if file === string[], then path.join(file)
	 * @returns {Dependency}
	 */
	Dependency.prototype.fileFactory = function(file) {
		var contents;
		if((contents = getFileContents(file, this.onError, diName)) !== null) {
			this.factory(contents);
		}
		return this;
	};

	/**
	 * register a namespace
	 * @param {string} name
	 * @param {function} [onError]
	 * @returns {Dependency}
	 */
	di.register = function(name, onError) {
		return new Dependency(name, onError);
	};

	/**
	 * @param {string} name
	 * @param {di|di[]} [imports]
	 * @returns {di}
	 */
	di.newChild = function(name, imports) {
		return diFactory(name, [di].concat(imports || []));
	};

	/**
	 * @returns {string[]}
	 */
	di.getImportNames = function() {
		return _.map(imports, function(d) {
			return d.diName;
		});
	};

	/**
	 * returns a callback that does not execute fn immediately
	 * @param {function} fn
	 * @param {object} [custom]
	 * @param {function(err)} [onError]
	 * @returns {Function}
	 */
	di.callback = function(fn, custom, onError) {
		/**
		 * @param {object} [opt]
		 * @param {function(err)} [opt.__di_onError] - internal pass error handler on lazy loading
		 */
		return function() {
			return di.invoke(fn, custom, (arguments[0] && arguments[0].__di_onError) || onError);
		};
	};

	di.diName = diName;
	di.import(imports);
	di.register('di').value(di);
	return di;
}

/**
 * invoke fn with each di in "dis" and return array of results
 * @param {di[]} dis
 * @param {function} fn
 * @returns {*[]}
 */
diFactory.mapInvoke = function(dis, fn) {
	return _.invoke(dis, 'invoke', fn);
};

/**
 * @name DependencyInjectionError
 */
var DiError = diFactory.Error = diFactory.DependencyInjectionError = (function() {
	/**
	 * @param {number} code
	 * @param {string} name
	 * @param {string} message
	 * @param {function} [context]
	 * @param {string} [context.__di_filename]
	 * @param {Error} [error] inherit stack from existing error
	 * @constructor
	 */
	function DependencyInjectionError(code, name, message, context, error) {
		this.code = code;
		this.message = this.name + ': ' + message + ' (di: ' + name + ')';
		this.message += context && context[fileKey] ? '\n    at file (' + context[fileKey] + ':1:0)' : '';
		this.message += context ? [].concat('', '... context ...', context.toString().split('\n').splice(0, 5), '...', '').join('\n') : '';
		if(error instanceof Error) {
			this.stack = this.message + '\n' + error.stack;
		} else if(Error.captureStackTrace) {
			Error.captureStackTrace(this, DependencyInjectionError);
		}
	}

	DependencyInjectionError.prototype = new Error();
	DependencyInjectionError.prototype.constructor = DependencyInjectionError;
	DependencyInjectionError.prototype.name = 'DependencyInjectionError';

	DependencyInjectionError.COULD_NOT_REQUIRE = 101;
	DependencyInjectionError.NOT_A_FUNCTION = 102;
	DependencyInjectionError.DEPENDENCY_NOT_FOUND = 103;

	return DependencyInjectionError;
}());

module.exports = diFactory;<|endoftext|>


<commit_before>var ipc = require('ipc');
var fs = require('fs');

var container = document.getElementById("editor");
var hot = new Handsontable(container, {
  colHeaders: true,
  rowHeaders: true,
  columnSorting: true,
  contextMenu: false
});

container.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  if (hot.getSelected()[0] == 0) {
    rowAbove.enabled = false
  }
  if (hot.getSelected()[1] == 0) {
    columnLeft.enabled = false
  }
  menu.popup(remote.getCurrentWindow());
  rowAbove.enabled = true
  columnLeft.enabled = true
}, false);

ipc.on('loadData', function(data) {
  csv = $.csv.toArrays(data);
  hot.loadData(csv);
  refactorColumns(csv);
  fixRaggedRows(csv);
});

ipc.on('saveData', function(fileName) {
  data = hot.getData().map(function(d) { return d.join(",") }).join("\r\n")
  fs.writeFile(fileName, data, function (err) {
  });
  document.title = fileName;
});

ipc.on('getCSV', function() {
  data = hot.getData().map(function(d) { return d.join(",") }).join("\r\n")
  ipc.send('sendCSV', data);
})

ipc.on('validate', function() {
  validate();
});

// How to use:
// getValidation("Example,CSV,content\na,b,c\n")
//  .then(function(validation) {console.log(validation)})

function getValidation(content) {
  request = require('request');
  content = new Buffer(content).toString("base64");
  content = "editor.csv;data:text/csv;base64," + content;
  return new Promise(function(resolve, reject) {
    request.post("http://csvlint.io/package.json", { formData: {"files_data[]": content } }, function(error, response, body) {

      if (error) return reject(error);

      var packageURL = JSON.parse(response.body).package.url;
      var interval = setInterval(function() {
        request.get(packageURL + ".json", function(error, response, body) {
          try {
            var validationURL = JSON.parse(body).package.validations[0].url;
            clearInterval(interval);
            request.get(validationURL + ".json", function(error, response, body) {
              if (error) return reject(error);
              resolve(JSON.parse(body));
            });
          } catch(e) {}
        });
      }, 1000);

    });
  });
}

// Splits validation returned from CSVLint into errors, warnings and info messages

function validate() {
  data = hot.getData().map(function(d) { return d.join(",") }).join("\r\n")
  $('#right-panel').removeClass("hidden")
  getValidation(data).then(function(json_validation) {
    errors = json_validation.validation.errors
    warnings = json_validation.validation.warnings
    info_messages = json_validation.validation.info
    console.error(errors)
    console.warn(warnings)
    console.info(info_messages);
    displayValidationMessages(json_validation.validation);
  });
}

function displayValidationMessages(validation) {
  var $messagePanel = $('#message-panel');
  var messageTemplate = _.template('<div class="<%= cssClass %>">
<%= type %> <% if (row) print("on row " + row) %> <% if (col) print("on column " + col) %>

');
  var messages = _.flatten([
    _.map(validation.errors,   function(d) { return _.extend({}, d, { cssClass: 'message validation-error' }) }),
    _.map(validation.warnings, function(d) { return _.extend({}, d, { cssClass: 'message validation-warning' }) }),
    _.map(validation.info,     function(d) { return _.extend({}, d, { cssClass: 'message validation-info' }) })
  ]);
  if (messages.length) {
    var html = _.map(messages, messageTemplate);
    $messagePanel.html(html);
  } else {
    $messagePanel.html('
CSV Valid!
');
  }
}

function refactorColumns(csv) {
  col_add = getMaxColumns(csv) - hot.countCols()
  // adds a column by default if the amount parameter is 0, hence conditional
  if (col_add != 0) {
    hot.alter('insert_col', null, col_add)
  }
}

function getMaxColumns(csv) {
  max_columns = 0
  for (var i = 0; i < csv.length; i++) {
    col_length = csv[i].length
    if (col_length > max_columns) {
      max_columns = col_length
    }
  }
  return max_columns
}

// Fills undefined cells with an empty string, keeping the table in a
// rectangular format

function fixRaggedRows(csv) {
  ragged_rows = 0;
  //
  for (var y = 0; y < hot.countRows(); y++) {
    for (var x = 0; x < getMaxColumns(csv); x++) {
      if (hot.getDataAtCell(y,x) === undefined) {
        if (ragged_rows == 0) {
          if (confirm("Your file has ragged rows, do you want to correct this?")) {
            ragged_rows = 1
            fixCell(x,y)
          }
          else {ragged_rows = -1}
        }
        else if (ragged_rows == 1) {
          fixCell(x,y)
        }
      }
    }
  }
}

function fixCell(x,y) {
  hot.setDataAtCell(y,x,"")
  console.log("Cell (" + String.fromCharCode(97 + y).toUpperCase() + "," + (x + 1) + ") has been added to file")
}
<commit_msg>Show loading meessage<commit_after>var ipc = require('ipc');
var fs = require('fs');

var container = document.getElementById("editor");
var hot = new Handsontable(container, {
  colHeaders: true,
  rowHeaders: true,
  columnSorting: true,
  contextMenu: false
});

container.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  if (hot.getSelected()[0] == 0) {
    rowAbove.enabled = false
  }
  if (hot.getSelected()[1] == 0) {
    columnLeft.enabled = false
  }
  menu.popup(remote.getCurrentWindow());
  rowAbove.enabled = true
  columnLeft.enabled = true
}, false);

ipc.on('loadData', function(data) {
  csv = $.csv.toArrays(data);
  hot.loadData(csv);
  refactorColumns(csv);
  fixRaggedRows(csv);
});

ipc.on('saveData', function(fileName) {
  data = hot.getData().map(function(d) { return d.join(",") }).join("\r\n")
  fs.writeFile(fileName, data, function (err) {
  });
  document.title = fileName;
});

ipc.on('getCSV', function() {
  data = hot.getData().map(function(d) { return d.join(",") }).join("\r\n")
  ipc.send('sendCSV', data);
})

ipc.on('validate', function() {
  validate();
});

// How to use:
// getValidation("Example,CSV,content\na,b,c\n")
//  .then(function(validation) {console.log(validation)})

function getValidation(content) {
  request = require('request');
  content = new Buffer(content).toString("base64");
  content = "editor.csv;data:text/csv;base64," + content;
  return new Promise(function(resolve, reject) {
    request.post("http://csvlint.io/package.json", { formData: {"files_data[]": content } }, function(error, response, body) {

      if (error) return reject(error);

      var packageURL = JSON.parse(response.body).package.url;
      var interval = setInterval(function() {
        request.get(packageURL + ".json", function(error, response, body) {
          try {
            var validationURL = JSON.parse(body).package.validations[0].url;
            clearInterval(interval);
            request.get(validationURL + ".json", function(error, response, body) {
              if (error) return reject(error);
              resolve(JSON.parse(body));
            });
          } catch(e) {}
        });
      }, 1000);

    });
  });
}

// Splits validation returned from CSVLint into errors, warnings and info messages

function validate() {
  data = hot.getData().map(function(d) { return d.join(",") }).join("\r\n")
  $('#right-panel').removeClass("hidden")
  $('#message-panel').html("

Loading validation results...

");

  getValidation(data).then(function(json_validation) {
    errors = json_validation.validation.errors
    warnings = json_validation.validation.warnings
    info_messages = json_validation.validation.info
    console.error(errors)
    console.warn(warnings)
    console.info(info_messages);
    displayValidationMessages(json_validation.validation);
  });
}

function displayValidationMessages(validation) {
  var $messagePanel = $('#message-panel');
  var messageTemplate = _.template('<div class="<%= cssClass %>">
<%= type %> <% if (row) print("on row " + row) %> <% if (col) print("on column " + col) %>

');
  var messages = _.flatten([
    _.map(validation.errors,   function(d) { return _.extend({}, d, { cssClass: 'message validation-error' }) }),
    _.map(validation.warnings, function(d) { return _.extend({}, d, { cssClass: 'message validation-warning' }) }),
    _.map(validation.info,     function(d) { return _.extend({}, d, { cssClass: 'message validation-info' }) })
  ]);
  if (messages.length) {
    var html = _.map(messages, messageTemplate);
    $messagePanel.html(html);
  } else {
    $messagePanel.html('
CSV Valid!
');
  }
}

function refactorColumns(csv) {
  col_add = getMaxColumns(csv) - hot.countCols()
  // adds a column by default if the amount parameter is 0, hence conditional
  if (col_add != 0) {
    hot.alter('insert_col', null, col_add)
  }
}

function getMaxColumns(csv) {
  max_columns = 0
  for (var i = 0; i < csv.length; i++) {
    col_length = csv[i].length
    if (col_length > max_columns) {
      max_columns = col_length
    }
  }
  return max_columns
}

// Fills undefined cells with an empty string, keeping the table in a
// rectangular format

function fixRaggedRows(csv) {
  ragged_rows = 0;
  //
  for (var y = 0; y < hot.countRows(); y++) {
    for (var x = 0; x < getMaxColumns(csv); x++) {
      if (hot.getDataAtCell(y,x) === undefined) {
        if (ragged_rows == 0) {
          if (confirm("Your file has ragged rows, do you want to correct this?")) {
            ragged_rows = 1
            fixCell(x,y)
          }
          else {ragged_rows = -1}
        }
        else if (ragged_rows == 1) {
          fixCell(x,y)
        }
      }
    }
  }
}

function fixCell(x,y) {
  hot.setDataAtCell(y,x,"")
  console.log("Cell (" + String.fromCharCode(97 + y).toUpperCase() + "," + (x + 1) + ") has been added to file")
}
<|endoftext|>


<commit_before>/**
 * @module color-space/hsl
 */

var rgb = require('./rgb');

module.exports = {
	name: 'hsl',
	min: [0,0,0],
	max: [360,100,100],
	channel: ['hue', 'saturation', 'lightness'],

	rgb: function(hsl) {
		var h = hsl[0] / 360,
				s = hsl[1] / 100,
				l = hsl[2] / 100,
				t1, t2, t3, rgb, val;

		if (s === 0) {
			val = l * 255;
			return [val, val, val];
		}

		if (l < 0.5) {
			t2 = l * (1 + s);
		}
		else {
			t2 = l + s - l * s;
		}
		t1 = 2 * l - t2;

		rgb = [0, 0, 0];
		for (var i = 0; i < 3; i++) {
			t3 = h + 1 / 3 * - (i - 1);
			if (t3 < 0) t3++;
			else if (t3 > 1) t3--;

			if (6 * t3 < 1) {
				val = t1 + (t2 - t1) * 6 * t3;
			}
			else if (2 * t3 < 1) {
				val = t2;
			}
			else if (3 * t3 < 2) {
				val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
			}
			else {
				val = t1;
			}

			rgb[i] = val * 255;
		}

		return rgb;
	}
};

//extend rgb
rgb.hsl = function(rgb) {
	var r = rgb[0]/255,
			g = rgb[1]/255,
			b = rgb[2]/255,
			min = Math.min(r, g, b),
			max = Math.max(r, g, b),
			delta = max - min,
			h, s, l;

	if (max === min) {
		h = 0;
	}
	else if (r === max) {
		h = (g - b) / delta;
	}
	else if (g === max) {
		h = 2 + (b - r) / delta;
	}
	else if (b === max) {
		h = 4 + (r - g)/ delta;
	}

	h = Math.min(h * 60, 360);

	if (h < 0)
		h += 360;

	l = (min + max) / 2;

	if (max === min) {
		s = 0;
	}
	else if (l <= 0.5) {
		s = delta / (max + min);
	}
	else {
		s = delta / (2 - max - min);
	}

	return [h, s * 100, l * 100];
};<commit_msg>Add climate enhancement<commit_after>/**
 * @module color-space/hsl
 */

var rgb = require('./rgb');

module.exports = {
	name: 'hsl',
	min: [0,0,0],
	max: [360,100,100],
	channel: ['hue', 'saturation', 'lightness'],

	rgb: function(hsl) {
		var h = hsl[0] / 360,
				s = hsl[1] / 100,
				l = hsl[2] / 100,
				t1, t2, t3, rgb, val;

		if (s === 0) {
			val = l * 255;
			return [val, val, val];
		}

		if (l < 0.5) {
			t2 = l * (1 + s);
		}
		else {
			t2 = l + s - l * s;
		}
		t1 = 2 * l - t2;

		rgb = [0, 0, 0];
		for (var i = 0; i < 3; i++) {
			t3 = h + 1 / 3 * - (i - 1);
			if (t3 < 0) {
				t3++;
			}
			else if (t3 > 1) {
				t3--;
			}

			if (6 * t3 < 1) {
				val = t1 + (t2 - t1) * 6 * t3;
			}
			else if (2 * t3 < 1) {
				val = t2;
			}
			else if (3 * t3 < 2) {
				val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
			}
			else {
				val = t1;
			}

			rgb[i] = val * 255;
		}

		return rgb;
	}
};

//extend rgb
rgb.hsl = function(rgb) {
	var r = rgb[0]/255,
			g = rgb[1]/255,
			b = rgb[2]/255,
			min = Math.min(r, g, b),
			max = Math.max(r, g, b),
			delta = max - min,
			h, s, l;

	if (max === min) {
		h = 0;
	}
	else if (r === max) {
		h = (g - b) / delta;
	}
	else if (g === max) {
		h = 2 + (b - r) / delta;
	}
	else if (b === max) {
		h = 4 + (r - g)/ delta;
	}

	h = Math.min(h * 60, 360);

	if (h < 0) {
		h += 360;
	}

	l = (min + max) / 2;

	if (max === min) {
		s = 0;
	}
	else if (l <= 0.5) {
		s = delta / (max + min);
	}
	else {
		s = delta / (2 - max - min);
	}

	return [h, s * 100, l * 100];
};<|endoftext|>


<commit_before>/**
 * Represents a wrapped IMP. IMPs are function pointers for methods. The first
 * two arguments are always 1) the object instance the method is being called
 * on, and 2) the SEL selector, respectively. Subsequent arguments are the args
 * that were passed in when invoked.
 */

exports.createWrapperPointer = createWrapperPointer
exports.createUnwrapperFunction = createUnwrapperFunction
var core = require('./core')
  , types = require('./types')

/**
 * Creates an ffi Function Pointer to the passed in 'func' Function. The
 * function gets wrapped in an "wrapper" function, which wraps the passed in
 * arguments, and unwraps the return value.
 */
function createWrapperPointer (func, type) {
  if (func.pointer) {
    // When an 'unwrapper' funtion is passed in, return the original pointer
    return func.pointer
  }
  var rtnType = type[0]
    , argTypes = type[1]
    , ffiCb = new core.Callback(types.convert(type), wrapper)
  function wrapper () {
    var args = core.wrapValues(arguments, argTypes)
      , rtn = func.apply(null, args)
    return core.unwrapValue(rtn, rtnType)
  }
  return ffiCb.getPointer()
}

/**
 * Creates a JS Function from the passed in function pointer. When the returned
 * function is invoked, the passed in arguments are unwrapped before being
 * passed to the native function, and the return value is wrapped up before
 * being returned for real.
 */
function createUnwrapperFunction (funcPtr, type) {
  var rtnType = type[0]
    , argTypes = type[1]
    , converted = types.convert(type)
    , func = core.ForeignFunction.build(funcPtr, converted[0], converted[1])
  converted = null
  function unwrapper () {
    var args = core.unwrapValues(arguments, argTypes)
      , rtn = func.apply(null, args)
    return core.wrapValue(rtn, rtnType)
  }
  unwrapper.rtn = rtnType
  unwrapper.args = argTypes
  unwrapper.pointer = funcPtr
  return unwrapper
}
<commit_msg>Fix typo in comment.<commit_after>/**
 * Represents a wrapped IMP. IMPs are function pointers for methods. The first
 * two arguments are always 1) the object instance the method is being called
 * on, and 2) the SEL selector, respectively. Subsequent arguments are the args
 * that were passed in when invoked.
 */

exports.createWrapperPointer = createWrapperPointer
exports.createUnwrapperFunction = createUnwrapperFunction
var core = require('./core')
  , types = require('./types')

/**
 * Creates an ffi Function Pointer to the passed in 'func' Function. The
 * function gets wrapped in an "wrapper" function, which wraps the passed in
 * arguments, and unwraps the return value.
 */
function createWrapperPointer (func, type) {
  if (func.pointer) {
    // When an 'unwrapper' function is passed in, return the original pointer
    return func.pointer
  }
  var rtnType = type[0]
    , argTypes = type[1]
    , ffiCb = new core.Callback(types.convert(type), wrapper)
  function wrapper () {
    var args = core.wrapValues(arguments, argTypes)
      , rtn = func.apply(null, args)
    return core.unwrapValue(rtn, rtnType)
  }
  return ffiCb.getPointer()
}

/**
 * Creates a JS Function from the passed in function pointer. When the returned
 * function is invoked, the passed in arguments are unwrapped before being
 * passed to the native function, and the return value is wrapped up before
 * being returned for real.
 */
function createUnwrapperFunction (funcPtr, type) {
  var rtnType = type[0]
    , argTypes = type[1]
    , converted = types.convert(type)
    , func = core.ForeignFunction.build(funcPtr, converted[0], converted[1])
  converted = null
  function unwrapper () {
    var args = core.unwrapValues(arguments, argTypes)
      , rtn = func.apply(null, args)
    return core.wrapValue(rtn, rtnType)
  }
  unwrapper.rtn = rtnType
  unwrapper.args = argTypes
  unwrapper.pointer = funcPtr
  return unwrapper
}
<|endoftext|>


<commit_before>// A library for keyboard input
// written by Almenon

// you can set elements listeners are attached to - html5 canvas is default
var element = window.document;
function setElement(input){
  element = input;
}

// actions is an array of functions to call.
var actions = [];

element.addEventListener('keydown', keydown);
element.addEventListener('mousedown', mousedown);

// keyCodes is a dictionary of buttons corresponding to values of e.keyCode
// need more keys?  add codes from https://css-tricks.com/snippets/javascript/javascript-keycodes/
var keyCodes = {
  leftmouse:0, scrollwheel:1, rightmouse:2,
  backspace:8, tab:9, enter:13, shift:16, ctrl:17, alt:18, caps_lock:20, esc:27, space:32, page_up:33, page_down:34,
  end:35, home:36, left:37, up:38, right:39, down:40, insert:45, delete:46,
  0:48, 1:49, 2:50, 3:51, 4:52, 5:53, 6:54, 7:55, 8:56, 9:57,
  a:65, b:66, c:67, d:68, e:69, f:70, g:71, h:72, i:73, j:74,
  k:75, l:76, m:77, n:78, o:79, p:80, q:81, r:82, s:83, t:84,
  u:85, v:86, w:87, x:88, y:89, z:90,
  f1:112, f2:113, f3:114, f4:115, f5:116, f6:117, f7:118, f8:119, f9:120, f10:121, f11:122, f12:123
};

function addListener(button, func){
// the keyCode of the button is mapped to the function
actions[keyCodes[button]] = func;
}

function removeListener(button){
  actions[keyCodes[button]] = undefined;
}

function addListeners(listeners){
  for (var button in listeners){
    addListener(button, listeners[button]);
  }
}

function removeListeners(listeners){
  for (var button in listeners){
    removeListener(button, listeners[button]);
  }
}

function keydown(e){
  if(actions[e.keyCode] !== undefined) actions[e.keyCode]();
}

function mousedown(e){
  if(actions[e.keyCode] !== undefined) actions[e.keyCode]();
}<commit_msg>Fixed mouse input error<commit_after>// A library for keyboard input
// written by Almenon

// you can set elements listeners are attached to - html5 canvas is default
var element = window.document;
function setElement(input){
  element = input;
}

// actions is an array of functions to call.
var actions = [];

element.addEventListener('keydown', keydown);
element.addEventListener('mousedown', mousedown);

// keyCodes is a dictionary of buttons corresponding to values of e.keyCode
// need more keys?  add codes from https://css-tricks.com/snippets/javascript/javascript-keycodes/
var keyCodes = {
  leftmouse:0, scrollwheel:1, rightmouse:2,
  backspace:8, tab:9, enter:13, shift:16, ctrl:17, alt:18, caps_lock:20, esc:27, space:32, page_up:33, page_down:34,
  end:35, home:36, left:37, up:38, right:39, down:40, insert:45, delete:46,
  0:48, 1:49, 2:50, 3:51, 4:52, 5:53, 6:54, 7:55, 8:56, 9:57,
  a:65, b:66, c:67, d:68, e:69, f:70, g:71, h:72, i:73, j:74,
  k:75, l:76, m:77, n:78, o:79, p:80, q:81, r:82, s:83, t:84,
  u:85, v:86, w:87, x:88, y:89, z:90,
  f1:112, f2:113, f3:114, f4:115, f5:116, f6:117, f7:118, f8:119, f9:120, f10:121, f11:122, f12:123
};

function addListener(button, func){
// the keyCode of the button is mapped to the function
actions[keyCodes[button]] = func;
}

function removeListener(button){
  actions[keyCodes[button]] = undefined;
}

function addListeners(listeners){
  for (var button in listeners){
    addListener(button, listeners[button]);
  }
}

function removeListeners(listeners){
  for (var button in listeners){
    removeListener(button, listeners[button]);
  }
}

function keydown(e){
  if(actions[e.keyCode] !== undefined) actions[e.keyCode](e);
}

function mousedown(e){
  if(actions[e.button] !== undefined) actions[e.keyCode](e);
}<|endoftext|>


<commit_before>
window.onload = function() {

	IE = (typeof IE === 'undefined') ? {} : IE;

	document.body.style.background = "#000000";

	makeClasses();

	IE.canvas = document.createElement("canvas");
	IE.canvas.style.position = "fixed";
	IE.canvas.style.background = "#000000";
	//IE.canvas.style.cursor = "none";
	document.body.appendChild(IE.canvas);

	IE.stage = new createjs.Stage(IE.canvas);
	IE.top = new IE.Top();
	IE.stage.addChild(IE.top);

	// IE.mask = new createjs.Shape();
	// IE.mask.graphics.beginFill("#FFF").drawCircle(50, 50, 49.8);
	// IE.stage.mask = IE.mask;

	window.onresize = function() {

		var w = window;
		var d = document;
		var e = d.documentElement;
		var g = d.getElementsByTagName('body')[0];
		var width = w.innerWidth || e.clientWidth || g.clientWidth;
		var height = w.innerHeight || e.clientHeight|| g.clientHeight;

		var size = Math.min(width, height);//*0.96;
		var chx = (width-size)/2.0;
		var chy = (height-size)/2.0;

		IE.canvas.style.width = width.toString()+"px";
		IE.canvas.style.height = height.toString()+"px";
		IE.canvas.style.top = "0px";
		IE.canvas.style.left = "0px";

		IE.canvas.width = IE.canvas.offsetWidth;
		IE.canvas.height = IE.canvas.offsetHeight;

		IE.size = 100;
		IE.top.set({x:chx, y:chy, scaleX:size/IE.size, scaleY:size/IE.size});
		//IE.mask.set({x:chx, y:chy, scaleX:size/IE.size, scaleY:size/IE.size});
		IE.stage.update();
	}

	window.onresize();

	init();
}

function init() {
	IE.state = {
		homes: 0
	}
	IE.currentPage = null;
	IE.pages = IE.pages || {};
	IE.top.showPage('welcome');
}

function makeClasses() {
	IE.Top = function() {
		createjs.Container.call(this);

		this.pageHolder = new createjs.Container();
		this.addChild(this.pageHolder);

		this.addChild(new IE.Question());
		this.addChild(new IE.FullScreen());
	}
	IE.Top.prototype = new createjs.Container();
	IE.Top.prototype.constructor = IE.Top;
	IE.Top.prototype.showPage = function(pageName) {
		IE.state.previousPageName = IE.state.currentPageName;
		IE.state.currentPageName = pageName;
		this.pageHolder.removeChild(IE.currentPage);
		IE.currentPage = new IE.Page(pageName);
		this.pageHolder.addChild(IE.currentPage);
		IE.stage.update();
	}

	////

	IE.Page = function(pageName) {

		createjs.Container.call(this);

		o = get(IE.pages, pageName, {});
		o = isFunction(o) ? o(IE.state.currentPageName) : o;
		//var name = get(o, 'name', 'noName');
		var title = get(o, 'title', "%%%%%%%%%%%%%%%%");
		var titleFont = get(o, 'titleFont', '8px Arial');
		var titleColor = get(o, 'titleColor', '#000000');
		var color1 = get(o, 'color1', "#BFFF00");
		var color2 = get(o, 'color2', "#0000FF");
		var color = get(o, 'color', color2);
		var text = get(o, 'text', 'Text not found.\nUse your imagination.');
		var font = get(o, 'font', '10px Arial');
		var textColor = get(o, 'textColor', '#000000');
		var buttonColor = get(o, 'buttonColor', '#000000');
		var buttonTextColor = get(o, 'buttonTextColor', '#FFFFFF');
		var buttonFont = get(o, 'buttonFont', '3px Arial');
		var buttons = get(o, 'buttons', [
			{
				text: 'Mind Own Business',
				next: 'death'
			}
		]);

		var rect = new createjs.Shape();
		rect.graphics.beginFill(color).drawRect(0, 0, 100, 16);
		this.addChild(rect);

		var rect2 = new createjs.Shape();
		rect2.graphics.beginFill(color1).drawRect(0, 15, 100, 46);
		this.addChild(rect2);

		var rect3 = new createjs.Shape();
		rect3.graphics.beginFill(color2).drawRect(0, 60, 100, 40);
		this.addChild(rect3);

		var t = new createjs.Text(title, titleFont, titleColor);
		t.textAlign = "center";
		//t.textBaseline = "middle";
		t.lineWidth = 90;
		t.width = 100;
		t.x = 50;
		t.y = 8-t.getMeasuredHeight()*0.6;
		this.addChild(t);

		var t2 = new createjs.Text(text, font, textColor);
		t2.textAlign = "center";
		//t.textBaseline = "middle";
		t2.lineWidth = 90;
		t2.width = 100;
		this.addChild(t2);

		var height = t2.getMeasuredHeight();
		var scale = Math.min(1, 35.0/height);
		t2.scaleX = scale;
		t2.scaleY = scale;
		t2.x = 50;
		t2.y = 38-(height*scale)*0.5;

		this.buttonSet = new IE.ButtonSet(buttons, buttonColor, buttonTextColor, buttonFont);
		this.buttonSet.y = 60;
		this.addChild(this.buttonSet);

	}
	IE.Page.prototype = new createjs.Container();
	IE.Page.prototype.constructor = IE.Page;

	////

	IE.ButtonSet = function(buttons, color, textColor, font) {

		createjs.Container.call(this);

		var child = new createjs.Container();
		this.addChild(child);

		var height = 2.5;
		var width = 0;
		for (var i=0; i<buttons.length; i++) {
			var b = buttons[i];
			var button = new IE.Button(b, color, textColor, font);
			button.x = 50-button.width/2;
			button.y = height;
			width = Math.max(width, button.width+5);
			height += button.height+2.5;
			child.addChild(button);
		}

		var scale = Math.min(1, Math.min(100.0/width, 40.0/height));
		child.scaleX = scale;
		child.scaleY = scale;

		child.x = 50-100*scale/2;
		child.y = 20-(height*scale)/2;
	}
	IE.ButtonSet.prototype = new createjs.Container();
	IE.ButtonSet.prototype.constructor = IE.ButtonSet;

	////

	IE.Button = function(o, color, textColor, font) {

		createjs.Container.call(this);

		o = o || {};

		var text = get(o, 'text', '???');
		var textColor = get(o, 'textColor', textColor || "#FFFFFF");
		var color = get(o, 'color', color || "#000000");
		var font = get(o, 'font', font || "8px Arial");
		var next = get(o, 'next', 'death');

		var t = new createjs.Text(text, font, textColor);
		//t.textAlign = "center";
		//t.textBaseline = "middle";
		var width = t.getMeasuredWidth();
		this.width = width + 3;
		var height = t.getMeasuredHeight();
		this.height = height + 3;
		t.x = (this.width-width)/2;
		t.y = (this.height-height-1)/2;		// -1 seems to center text nicely

		var rect = new createjs.Shape();
		rect.graphics.beginFill(color).drawRect(0, 0, this.width, this.height);
		this.addChild(rect);

		this.addChild(t);

		this.addEventListener("click", function(event) {
			IE.top.showPage(next);
		});
	}
	IE.Button.prototype = new createjs.Container();
	IE.Button.prototype.constructor = IE.Button;

	IE.Question = function() {

		createjs.Container.call(this);

		var circle = new createjs.Shape();
		circle.graphics
			.beginFill("#FFFFFF")
			.beginStroke("#000000")
			.setStrokeStyle(0.25)
			.drawCircle(97, 3, 1.5, 1.5);
		this.addChild(circle);

		var t = new createjs.Text('?', '2px Arial', "#000000");
		t.textAlign = "center";
		t.x = 97;
		t.y = 1.7;
		this.addChild(t);

		this.addEventListener("click", function(event) {
			if (IE.state.currentPageName == '?') {
				IE.top.showPage(IE.state.previousPageName);
			} else {
				IE.top.showPage('?');
			}
		});
	}
	IE.Question.prototype = new createjs.Container();
	IE.Question.prototype.constructor = IE.Question;

	IE.FullScreen = function() {

		createjs.Container.call(this);

		var circle = new createjs.Shape();
		circle.graphics
			.beginFill("#FFFFFF")
			.beginStroke("#000000")
			.setStrokeStyle(0.25)
			.drawCircle(3, 3, 1.5, 1.5);
		this.addChild(circle);

		var t = new createjs.Text('+', '2px Arial', "#000000");
		t.textAlign = "center";
		t.x = 3;
		t.y = 1.7;
		this.addChild(t);

		this.addEventListener("click", function(event) {
			fullScreen(IE.canvas);
		});
	}
	IE.FullScreen.prototype = new createjs.Container();
	IE.FullScreen.prototype.constructor = IE.FullScreen;
}

<commit_msg>hand cursor on buttons<commit_after>
window.onload = function() {

	IE = (typeof IE === 'undefined') ? {} : IE;

	document.body.style.background = "#000000";

	makeClasses();

	IE.canvas = document.createElement("canvas");
	IE.canvas.style.position = "fixed";
	IE.canvas.style.background = "#000000";
	//IE.canvas.style.cursor = "none";
	document.body.appendChild(IE.canvas);

	IE.stage = new createjs.Stage(IE.canvas);
	IE.stage.enableMouseOver();
	IE.top = new IE.Top();
	IE.stage.addChild(IE.top);

	// IE.mask = new createjs.Shape();
	// IE.mask.graphics.beginFill("#FFF").drawCircle(50, 50, 49.8);
	// IE.stage.mask = IE.mask;

	window.onresize = function() {

		var w = window;
		var d = document;
		var e = d.documentElement;
		var g = d.getElementsByTagName('body')[0];
		var width = w.innerWidth || e.clientWidth || g.clientWidth;
		var height = w.innerHeight || e.clientHeight|| g.clientHeight;

		var size = Math.min(width, height);//*0.96;
		var chx = (width-size)/2.0;
		var chy = (height-size)/2.0;

		IE.canvas.style.width = width.toString()+"px";
		IE.canvas.style.height = height.toString()+"px";
		IE.canvas.style.top = "0px";
		IE.canvas.style.left = "0px";

		IE.canvas.width = IE.canvas.offsetWidth;
		IE.canvas.height = IE.canvas.offsetHeight;

		IE.size = 100;
		IE.top.set({x:chx, y:chy, scaleX:size/IE.size, scaleY:size/IE.size});
		//IE.mask.set({x:chx, y:chy, scaleX:size/IE.size, scaleY:size/IE.size});
		IE.stage.update();
	}

	window.onresize();

	init();
}

function init() {
	IE.state = {
		homes: 0
	}
	IE.currentPage = null;
	IE.pages = IE.pages || {};
	IE.top.showPage('welcome');
}

function makeClasses() {
	IE.Top = function() {
		createjs.Container.call(this);

		this.pageHolder = new createjs.Container();
		this.addChild(this.pageHolder);

		this.addChild(new IE.Question());
		this.addChild(new IE.FullScreen());

		// IE.cursor = new createjs.Container();
		// for (var i=0; i<3; i++) {
		// 	var c = new createjs.Bitmap("assets/cursor.png");
		// 	c.rotation = (360*i/3+22.5);
		// 	IE.cursor.addChild(c);
		// }

		// IE.cursor.scaleX = 0.01;
		// IE.cursor.scaleY = IE.cursor.scaleX;
		// this.addChild(IE.cursor);

		// var this2 = this;
		// function moveCursor() {
		// 	var pt = this2.globalToLocal(IE.stage.mouseX, IE.stage.mouseY);
		// 	IE.cursor.x = pt.x;
		// 	IE.cursor.y = pt.y;
		// 	IE.stage.update();
		// }
		// IE.stage.on("stagemousemove", moveCursor);
	}
	IE.Top.prototype = new createjs.Container();
	IE.Top.prototype.constructor = IE.Top;
	IE.Top.prototype.showPage = function(pageName) {
		IE.state.previousPageName = IE.state.currentPageName;
		IE.state.currentPageName = pageName;
		this.pageHolder.removeChild(IE.currentPage);
		IE.currentPage = new IE.Page(pageName);
		this.pageHolder.addChild(IE.currentPage);
		IE.stage.update();
	}

	////

	IE.Page = function(pageName) {

		createjs.Container.call(this);

		o = get(IE.pages, pageName, {});
		o = isFunction(o) ? o(IE.state.currentPageName) : o;
		//var name = get(o, 'name', 'noName');
		var title = get(o, 'title', "%%%%%%%%%%%%%%%%");
		var titleFont = get(o, 'titleFont', '8px Arial');
		var titleColor = get(o, 'titleColor', '#000000');
		var color1 = get(o, 'color1', "#BFFF00");
		var color2 = get(o, 'color2', "#0000FF");
		var color = get(o, 'color', color2);
		var text = get(o, 'text', 'Text not found.\nUse your imagination.');
		var font = get(o, 'font', '10px Arial');
		var textColor = get(o, 'textColor', '#000000');
		var buttonColor = get(o, 'buttonColor', '#000000');
		var buttonTextColor = get(o, 'buttonTextColor', '#FFFFFF');
		var buttonFont = get(o, 'buttonFont', '5px Arial');
		var buttons = get(o, 'buttons', [
			{
				text: 'Mind Own Business',
				next: 'death'
			}
		]);

		var rect = new createjs.Shape();
		rect.graphics.beginFill(color).drawRect(0, 0, 100, 16);
		this.addChild(rect);

		var rect2 = new createjs.Shape();
		rect2.graphics.beginFill(color1).drawRect(0, 15, 100, 46);
		this.addChild(rect2);

		var rect3 = new createjs.Shape();
		rect3.graphics.beginFill(color2).drawRect(0, 60, 100, 40);
		this.addChild(rect3);

		var t = new createjs.Text(title, titleFont, titleColor);
		t.textAlign = "center";
		//t.textBaseline = "middle";
		t.lineWidth = 90;
		t.width = 100;
		t.x = 50;
		t.y = 8-t.getMeasuredHeight()*0.6;
		this.addChild(t);

		var t2 = new createjs.Text(text, font, textColor);
		t2.textAlign = "center";
		//t.textBaseline = "middle";
		t2.lineWidth = 90;
		t2.width = 100;
		this.addChild(t2);

		var height = t2.getMeasuredHeight();
		var scale = Math.min(1, 35.0/height);
		t2.scaleX = scale;
		t2.scaleY = scale;
		t2.x = 50;
		t2.y = 38-(height*scale)*0.5;

		this.buttonSet = new IE.ButtonSet(buttons, buttonColor, buttonTextColor, buttonFont);
		this.buttonSet.y = 60;
		this.addChild(this.buttonSet);

	}
	IE.Page.prototype = new createjs.Container();
	IE.Page.prototype.constructor = IE.Page;

	////

	IE.ButtonSet = function(buttons, color, textColor, font) {

		createjs.Container.call(this);

		var child = new createjs.Container();
		this.addChild(child);

		var height = 2.5;
		var width = 0;
		for (var i=0; i<buttons.length; i++) {
			var b = buttons[i];
			var button = new IE.Button(b, color, textColor, font);
			button.x = 50-button.width/2;
			button.y = height;
			width = Math.max(width, button.width+5);
			height += button.height+2.5;
			child.addChild(button);
		}

		var scale = Math.min(1, Math.min(100.0/width, 40.0/height));
		child.scaleX = scale;
		child.scaleY = scale;

		child.x = 50-100*scale/2;
		child.y = 20-(height*scale)/2;
	}
	IE.ButtonSet.prototype = new createjs.Container();
	IE.ButtonSet.prototype.constructor = IE.ButtonSet;

	////

	IE.Button = function(o, color, textColor, font) {

		createjs.Container.call(this);

		o = o || {};

		var text = get(o, 'text', '???');
		var textColor = get(o, 'textColor', textColor || "#FFFFFF");
		var color = get(o, 'color', color || "#000000");
		var font = get(o, 'font', font || "8px Arial");
		var next = get(o, 'next', 'death');

		var t = new createjs.Text(text, font, textColor);
		//t.textAlign = "center";
		//t.textBaseline = "middle";
		var width = t.getMeasuredWidth();
		this.width = width + 3;
		var height = t.getMeasuredHeight();
		this.height = height + 3;
		t.x = (this.width-width)/2;
		t.y = (this.height-height-1)/2;		// -1 seems to center text nicely

		var rect = new createjs.Shape();
		rect.graphics.beginFill(color).drawRect(0, 0, this.width, this.height);
		this.addChild(rect);

		this.addChild(t);

		this.addEventListener("click", function(event) {
			IE.top.showPage(next);
		});
		this.addEventListener("mouseover", function(event) {
		    document.body.style.cursor = 'pointer';
		});
		this.addEventListener("mouseout", function(event) {
		    document.body.style.cursor = 'default';
		});
	}
	IE.Button.prototype = new createjs.Container();
	IE.Button.prototype.constructor = IE.Button;

	IE.Question = function() {

		createjs.Container.call(this);

		var circle = new createjs.Shape();
		circle.graphics
			.beginFill("#FFFFFF")
			.beginStroke("#000000")
			.setStrokeStyle(0.25)
			.drawCircle(97, 3, 1.5, 1.5);
		this.addChild(circle);

		var t = new createjs.Text('?', '2px Arial', "#000000");
		t.textAlign = "center";
		t.x = 97;
		t.y = 1.7;
		this.addChild(t);

		this.addEventListener("click", function(event) {
			if (IE.state.currentPageName == '?') {
				IE.top.showPage(IE.state.previousPageName);
			} else {
				IE.top.showPage('?');
			}
		});

		this.addEventListener("mouseover", function(event) {
		    document.body.style.cursor = 'pointer';
		});
		this.addEventListener("mouseout", function(event) {
		    document.body.style.cursor = 'default';
		});
	}
	IE.Question.prototype = new createjs.Container();
	IE.Question.prototype.constructor = IE.Question;

	IE.FullScreen = function() {

		createjs.Container.call(this);

		var circle = new createjs.Shape();
		circle.graphics
			.beginFill("#FFFFFF")
			.beginStroke("#000000")
			.setStrokeStyle(0.25)
			.drawCircle(3, 3, 1.5, 1.5);
		this.addChild(circle);

		var t = new createjs.Text('+', '2px Arial', "#000000");
		t.textAlign = "center";
		t.x = 3;
		t.y = 1.7;
		this.addChild(t);

		this.addEventListener("click", function(event) {
			fullScreen(IE.canvas);
		});

		this.addEventListener("mouseover", function(event) {
		    document.body.style.cursor = 'pointer';
		});
		this.addEventListener("mouseout", function(event) {
		    document.body.style.cursor = 'default';
		});
	}
	IE.FullScreen.prototype = new createjs.Container();
	IE.FullScreen.prototype.constructor = IE.FullScreen;
}

<|endoftext|>


<commit_before>var Store = {
  asa: {
      name: 'Asa',
      age: 24
  }
};

var Removers = {};

var Jack = {
    config: {
      0: {
        storage: 'memory',
        life: 1000
      },
      1: {
        storage: 'session',
        life: 5000
      }
    },
    get: function(key) {
        return Store[key];
    },
    set: function(key, value, type) {
      type = type || 0;
      var config = this.config[type];
      Store[key] = value;
      this.setupCleanup(key, config);
    },
    setupCleanup: function(key, config) {
      if(Removers[key]) {
        clearTimeout(Removers[key].id);
      }
      var remove = function() {
        delete Store[key];
        delete Removers[key];
      };
      var id = setTimeout(remove, config.life);
      Removers[key] = {
        id: id,
        callback: remove
      };
    }
};
<commit_msg>added hasOwnProperty check to the getter<commit_after>var Store = {
  asa: {
      name: 'Asa',
      age: 24
  }
};

var Removers = {};

var Jack = {
    config: {
      0: {
        storage: 'memory',
        life: 1000
      },
      1: {
        storage: 'session',
        life: 5000
      }
    },
    get: function(key) {
        if(Store.hasOwnProperty(key)){
          return Store[key];
        } else {
          return null;
        }
    },
    set: function(key, value, type) {
      type = type || 0;
      var config = this.config[type];
      Store[key] = value;
      this.setupCleanup(key, config);
    },
    setupCleanup: function(key, config) {
      if(Removers[key]) {
        clearTimeout(Removers[key].id);
      }
      var remove = function() {
        delete Store[key];
        delete Removers[key];
      };
      var id = setTimeout(remove, config.life);
      Removers[key] = {
        id: id,
        callback: remove
      };
    }
};
<|endoftext|>


<commit_before>
// greet :: String -> String
function greet(who){
    return "Hello, "+who+" :)";
}

// power :: Integer -> Integer -> Integer
function power(base, exponent){
    if(exponent == 0){
	return 1;
    }else if(exponent % 2 == 0){
	var p = power(base, exponent/2)
	return p*p;
    }else{
	return base * power(base,exponent-1);
    }
}

// findSolution :: Integer -> String
function findSolution(target){
    function find(start, history){
	if (start == target){
	    return history;
	}else if (start > target){
	    return null;
	}else{
	    return find(start*3, "(" + history + " * 3)") ||
		find(start+5, "(" + history + " + 5)");
	}
    }
    return find(1, "1");
}

// Min :: Integer -> Integer -> Integer
function Min(a,b){
    if(a < b){
	return a ;
    }else{
	return b ;
    }
}

// isEven :: Integer -> Bool
function isEven(n){
    if(n == 0){
	return true;
    }else if(n == 1){
	return false;
    }else{
	return isEven(n-2);
    }
}

// countBs :: String -> Integer
function countBs(s){
    return countChar(s,"B");
}

// countChar :: String -> Char -> Integer
function countChar(s,target){
    var result = 0 ;
    for(i = 0; i < s.length; i++){
	if(s.charAt(i) == target){
	    result++ ;
	}
    }
    return result ;
}

// Objects and Arrays

// The Lycanthrope's Journal

function phi(table){
    return (table[3]*table[0] - table[2]*table[1])/
	Math.sqrt((table[2] + table[3])*
		  (table[0] + table[1])*
		  (table[1] + table[3])*
		  (table[0] + table[2]));
}

function hasEvent(event, entry){
    return entry.events.indexOf(event) != -1;
}

function tableFor(event, journal){
    var table = [0, 0, 0, 0];
    for (var i=0; i < journal.length; i++){
	var entry = journal[i];
	if(hasEvent(event, entry) && entry.squirrel){
	    table[3] += 1;
	}else if (hasEvent(event, entry)){
	    table[1] += 1;
	}else if (entry.squirrel){
	    table[2] += 1;
	}else{
	    table[0] += 1;
	}
    }
    return table;
}

function gatherCorrelations(journal){
    var phis = {};
    journal.forEach(function(entry){
	entry.events.forEach(function(event){
	    if(!(event in phis)){
		phis[event] = phi(tableFor(event, journal));
	    }
	});
    });
    return phis;
}

function range(a,b){
    var result = [];
    var step = arguments[2];
    if(step == null){
	step = 1;
    }
    for(var i=a; ((i-b)*(step/Math.abs(step)) <= 0) ; i += step){
	result.push(i);
    }
    return result ;
}

function sum(ls){
    var result = 0;
    for(var i = 0; i < ls.length; i++){
	result += ls[i];
    }
    return result;
}

function reverseArray(arr){
    var result = [] ;
    for(var i=0; i < arr.length; i++){
	result.unshift(arr[i]);
    }
    return result;
}

function reverseArrayInPlace(arr){
    var l = arr.length ;
    for(var i=0; i < l/2 ;i++){
	var a = arr[i];
	var b = arr[l-1-i];
	arr[i] = b;
	arr[l-i-1] = a;
    }
}

function arrayToList(arr){
    if(arr.length == 0){
	return null;
    }else{
	return {
	    value : arr.shift(),
	    rest: arrayToList(arr)
	};
    }
}

function prepend(el, list){
    return {
	value: el,
	rest: list
    };
}

function nth(n, list){
    if(!list){
	return undefined;
    }else if(n == 0){
	return list.value;
    }else{
	return nth(n-1, list.rest);
    }
}

function listToArray(list){
    var result = [];
    var i = 0;
    while(nth(i,list)){
	result.push(nth(i,list));
	i = i+1;
    }
    return result;
}

// Higher Order Functions

function forEach(arr, action){
    for(var i = 0 ; i < arr.length ; i++){
	action(arr[i]);
    }
}

function filter(arr, test){
    var passed = [];
    arr.forEach(function(el){
	if(test(el)){
	    passed.push(el);
	}
    });
    return passed;
}

function map(arr, transform){
    var result = [];
    arr.forEach(function(el){
	result.push(transform(el));
    });
    return result;
}

function reduce(arr, combine, start){
    var current = start;
    arr.forEach(function(el){
	current = combine(current, el);
    });
    return current;
}

function average(arr){
    function plus(a, b){return a+b}
    return arr.reduce(plus) / arr.length;
}

function male(p){return p.sex == "m"}

function female(p){return p.sex == "f"}

function age(p){return p.died - p.born}

/*

var byName = {};
ancestry.forEach(function(person) {
  byName[person.name] = person;
});

*/

function ageDiffMother(p){
  if((p.mother == null) || (byName[p.mother] == undefined)){
    return null;
  }else{
    return (p.born - byName[p.mother].born);
  }
}

/*

console.log(average(ancestry.map(ageDiffMother).filter(function(diff){return diff})));

var byCentury = {};
var ancestry = JSON.parse(ANCESTRY_FILE);

ancestry.forEach(function(p){
  if(century(p) in byCentury){
     byCentury[century(p)].push(age(p));
  }else{
    byCentury[century(p)] = [age(p)] ;
  }
});
for(var item in byCentury){
  console.log(item + " : " + average(byCentury[item]));
}

*/

function every(arr, action){
  function and(a, b){
    return a && b ;
  }
  return arr.map(action).reduce(and);
}

function some(arr, action){
  function or(a, b){
    return a || b ;
  }
  return arr.map(action).reduce(or);
}

// Object Oriented Programming

function Rabbit(type){
    this.type = type ;
}

Rabbit.prototype.speak = function(line){
    return "The " + this.type + " rabbit says " + line ;
} ;

Rabbit.prototype.toString = function(){
  return "This is a " + this.type + " Rabbit!"
};

// Table Cells Representation

function TextCell(text){
    this.text = text.split("\n");
}

TextCell.prototype.minHeight = function(){
    return this.text.length;
}

TextCell.prototype.minWidth = function(){
    return this.text.reduce(function(width, line){
	return Math.max(width, line.length);
    }, 0)
}

TextCell.prototype.draw = function(width, height){
    var result = [];

    function repeat(string, times){
	var result = "";
	for(var i = 0; i < times; i++){
	    result += string;
	}
	return result;
    }

    for(var i = 0; i < height; i++){
	var line = this.text[i] || "" ;
	result.push(line + repeat(" ", width - line.length));
    }
    return result;
}

// Methods for calculating the minimum heights and widths for the
// rows and columns of table to be drawn out of above table cells

function rowHeights(rows){
    return rows.map(function(row){
	return row.reduce(function(current, cell){
	    return Math.max(current, cell.minHeight());
	}, 0);
    });
}

function colWidths(rows){
    return rows[0].map(function(_, i){
	return rows.reduce(function(current, row){
	    return Math.max(current, row[i].minWidth());
	}, 0);
    });
}

// Draw table method for drawing the tables out of array of arrays of table cells

function drawTable(rows){
    var heights = rowHeights(rows);
    var widths = colWidths(rows);

    function drawLine(blocks, lineNo){
	return blocks.map(function(block){
	    return block[lineNo];
	}).join(" ");
    }

    function drawRow(row, rowNum){
	var blocks = row.map(function(cell, colNum){
	    return cell.draw(widths[colNum], heights[rowNum]);
	});

	return blocks[0].map(function(_, lineNo){
	    return drawLine(blocks, lineNo);
	}).join("\n");
    }

    return rows.map(drawRow).join("\n");

}

// Vector Representation

function Vector(x, y){
    this.x = x;
    this.y = y;
}

Vector.prototype.plus = function(that){
    return new Vector(this.x + that.x, this.y + that.y);
}

Vector.prototype.minus = function(that){
    return new Vector(this.x - that.x, this.y - that.y);
}

Object.defineProperty(Vector.prototype, "length", {
    get: function(){
	return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
    }
});
<commit_msg>Added StretchCell dataType<commit_after>
// greet :: String -> String
function greet(who){
    return "Hello, "+who+" :)";
}

// power :: Integer -> Integer -> Integer
function power(base, exponent){
    if(exponent == 0){
	return 1;
    }else if(exponent % 2 == 0){
	var p = power(base, exponent/2)
	return p*p;
    }else{
	return base * power(base,exponent-1);
    }
}

// findSolution :: Integer -> String
function findSolution(target){
    function find(start, history){
	if (start == target){
	    return history;
	}else if (start > target){
	    return null;
	}else{
	    return find(start*3, "(" + history + " * 3)") ||
		find(start+5, "(" + history + " + 5)");
	}
    }
    return find(1, "1");
}

// Min :: Integer -> Integer -> Integer
function Min(a,b){
    if(a < b){
	return a ;
    }else{
	return b ;
    }
}

// isEven :: Integer -> Bool
function isEven(n){
    if(n == 0){
	return true;
    }else if(n == 1){
	return false;
    }else{
	return isEven(n-2);
    }
}

// countBs :: String -> Integer
function countBs(s){
    return countChar(s,"B");
}

// countChar :: String -> Char -> Integer
function countChar(s,target){
    var result = 0 ;
    for(i = 0; i < s.length; i++){
	if(s.charAt(i) == target){
	    result++ ;
	}
    }
    return result ;
}

// Objects and Arrays

// The Lycanthrope's Journal

function phi(table){
    return (table[3]*table[0] - table[2]*table[1])/
	Math.sqrt((table[2] + table[3])*
		  (table[0] + table[1])*
		  (table[1] + table[3])*
		  (table[0] + table[2]));
}

function hasEvent(event, entry){
    return entry.events.indexOf(event) != -1;
}

function tableFor(event, journal){
    var table = [0, 0, 0, 0];
    for (var i=0; i < journal.length; i++){
	var entry = journal[i];
	if(hasEvent(event, entry) && entry.squirrel){
	    table[3] += 1;
	}else if (hasEvent(event, entry)){
	    table[1] += 1;
	}else if (entry.squirrel){
	    table[2] += 1;
	}else{
	    table[0] += 1;
	}
    }
    return table;
}

function gatherCorrelations(journal){
    var phis = {};
    journal.forEach(function(entry){
	entry.events.forEach(function(event){
	    if(!(event in phis)){
		phis[event] = phi(tableFor(event, journal));
	    }
	});
    });
    return phis;
}

function range(a,b){
    var result = [];
    var step = arguments[2];
    if(step == null){
	step = 1;
    }
    for(var i=a; ((i-b)*(step/Math.abs(step)) <= 0) ; i += step){
	result.push(i);
    }
    return result ;
}

function sum(ls){
    var result = 0;
    for(var i = 0; i < ls.length; i++){
	result += ls[i];
    }
    return result;
}

function reverseArray(arr){
    var result = [] ;
    for(var i=0; i < arr.length; i++){
	result.unshift(arr[i]);
    }
    return result;
}

function reverseArrayInPlace(arr){
    var l = arr.length ;
    for(var i=0; i < l/2 ;i++){
	var a = arr[i];
	var b = arr[l-1-i];
	arr[i] = b;
	arr[l-i-1] = a;
    }
}

function arrayToList(arr){
    if(arr.length == 0){
	return null;
    }else{
	return {
	    value : arr.shift(),
	    rest: arrayToList(arr)
	};
    }
}

function prepend(el, list){
    return {
	value: el,
	rest: list
    };
}

function nth(n, list){
    if(!list){
	return undefined;
    }else if(n == 0){
	return list.value;
    }else{
	return nth(n-1, list.rest);
    }
}

function listToArray(list){
    var result = [];
    var i = 0;
    while(nth(i,list)){
	result.push(nth(i,list));
	i = i+1;
    }
    return result;
}

// Higher Order Functions

function forEach(arr, action){
    for(var i = 0 ; i < arr.length ; i++){
	action(arr[i]);
    }
}

function filter(arr, test){
    var passed = [];
    arr.forEach(function(el){
	if(test(el)){
	    passed.push(el);
	}
    });
    return passed;
}

function map(arr, transform){
    var result = [];
    arr.forEach(function(el){
	result.push(transform(el));
    });
    return result;
}

function reduce(arr, combine, start){
    var current = start;
    arr.forEach(function(el){
	current = combine(current, el);
    });
    return current;
}

function average(arr){
    function plus(a, b){return a+b}
    return arr.reduce(plus) / arr.length;
}

function male(p){return p.sex == "m"}

function female(p){return p.sex == "f"}

function age(p){return p.died - p.born}

/*

var byName = {};
ancestry.forEach(function(person) {
  byName[person.name] = person;
});

*/

function ageDiffMother(p){
  if((p.mother == null) || (byName[p.mother] == undefined)){
    return null;
  }else{
    return (p.born - byName[p.mother].born);
  }
}

/*

console.log(average(ancestry.map(ageDiffMother).filter(function(diff){return diff})));

var byCentury = {};
var ancestry = JSON.parse(ANCESTRY_FILE);

ancestry.forEach(function(p){
  if(century(p) in byCentury){
     byCentury[century(p)].push(age(p));
  }else{
    byCentury[century(p)] = [age(p)] ;
  }
});
for(var item in byCentury){
  console.log(item + " : " + average(byCentury[item]));
}

*/

function every(arr, action){
  function and(a, b){
    return a && b ;
  }
  return arr.map(action).reduce(and);
}

function some(arr, action){
  function or(a, b){
    return a || b ;
  }
  return arr.map(action).reduce(or);
}

// Object Oriented Programming

function Rabbit(type){
    this.type = type ;
}

Rabbit.prototype.speak = function(line){
    return "The " + this.type + " rabbit says " + line ;
} ;

Rabbit.prototype.toString = function(){
  return "This is a " + this.type + " Rabbit!"
};

// Table Cells Representation

function TextCell(text){
    this.text = text.split("\n");
}

TextCell.prototype.minHeight = function(){
    return this.text.length;
}

TextCell.prototype.minWidth = function(){
    return this.text.reduce(function(width, line){
	return Math.max(width, line.length);
    }, 0)
}

function repeat(string, times){
    var result = "";
	for(var i = 0; i < times; i++){
	    result += string;
	}
    return result;
}

TextCell.prototype.draw = function(width, height){
    var result = [];

    for(var i = 0; i < height; i++){
	var line = this.text[i] || "" ;
	result.push(line + repeat(" ", width - line.length));
    }
    return result;
}

function UnderlinedCell(inner){
    this.inner = inner;
}

UnderlinedCell.prototype.minHeight = function(){
    return this.inner.minHeight() + 1;
}

UnderlinedCell.prototype.minWidth = function(){
    return this.inner.minWidth();
}

UnderlinedCell.prototype.draw = function(width, height){
    return this.inner.draw(width, height - 1)
	.concat([repeat("-", width)])
}

function RTextCell(text){
    TextCell.call(this, text);
}

RTextCell.prototype = Object.create(TextCell.prototype);

RTextCell.prototype.draw = function(width, height){
    var result = [];

    for(var i = 0; i < height; i++){
	var line = this.text[i] || "" ;
	result.push(repeat(" ", width - line.length) + line);
    }
    return result;
}

// Methods for calculating the minimum heights and widths for the
// rows and columns of table to be drawn out of above table cells

function rowHeights(rows){
    return rows.map(function(row){
	return row.reduce(function(current, cell){
	    return Math.max(current, cell.minHeight());
	}, 0);
    });
}

function colWidths(rows){
    return rows[0].map(function(_, i){
	return rows.reduce(function(current, row){
	    return Math.max(current, row[i].minWidth());
	}, 0);
    });
}

// Draw table method for drawing the tables out of array of arrays of table cells

function drawTable(rows){
    var heights = rowHeights(rows);
    var widths = colWidths(rows);

    function drawLine(blocks, lineNo){
	return blocks.map(function(block){
	    return block[lineNo];
	}).join("\t");
    }

    function drawRow(row, rowNum){
	var blocks = row.map(function(cell, colNum){
	    return cell.draw(widths[colNum], heights[rowNum]);
	});

	return blocks[0].map(function(_, lineNo){
	    return drawLine(blocks, lineNo);
	}).join("\n");
    }

    return rows.map(drawRow).join("\n");

}

function dataConvert(data){
    var keys = Object.keys(data[0]);
    var keysTable = keys.map(function(key){
	return new UnderlinedCell(new TextCell(key.toString()));
    });
    var dataTable =  data.map(function(entry){
	var row = [];
	keys.forEach(function(key){
	    var el = entry[key];
	    if (typeof el == "number"){
		row.push(new RTextCell(el.toString()));
	    }else{
		row.push(new TextCell(el.toString()));
	    }
	});
	return row;
    });
    dataTable.unshift(keysTable);
    return dataTable;
}

// Vector Representation

function Vector(x, y){
    this.x = x;
    this.y = y;
}

Vector.prototype.plus = function(that){
    return new Vector(this.x + that.x, this.y + that.y);
}

Vector.prototype.minus = function(that){
    return new Vector(this.x - that.x, this.y - that.y);
}

Object.defineProperty(Vector.prototype, "length", {
    get: function(){
	return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
    }
});

// Stretched Cell Representation

function StretchCell(inner, width, height){
    this.inner = inner;
    this.width = width;
    this.height = height;
}

StretchCell.prototype.minHeight = function(){
    return Math.max(this.height, this.inner.minHeight());
}

StretchCell.prototype.minWidth = function(){
    return Math.max(this.width, this.inner.minWidth());
}

StretchCell.prototype.draw = function(width, height){
    return this.inner.draw(Math.max(this.minWidth(), width),
			   Math.max(this.minHeight(), height));
}
<|endoftext|>


<commit_before>var glob = require("glob");
var extend = require('util')._extend;
require('array-sugar');
var path = require('path');
var packageJSON = require('../../package.json');

module.exports = function jspmAureliaBundler(passedOpts) {
	var base = packageJSON.jspm.directories.baseURL;
	var packagesDir = packageJSON.jspm.directories.packages.split('/')[1];
	var configFile = path.relative(base, packageJSON.jspm.configFile);
	var target = 'build.js';
	var options = {	//default
		globJs: {ignore: [packagesDir + '/**', target, configFile], root: base, cwd: base},
		globHtml: {ignore: [packagesDir + '/**', 'index.html'], root: base, cwd: base},
		baseFolder: base,
		target: target
	};

	extend(options, passedOpts);

	var jspm = new require('jspm');
	var builder = jspm.Builder();

	var ignorePackages = [
		'traceur',
		'traceur-runtime',
		'babel',
		'babel-runtime'
	];

	var packages = Object.keys(builder.loader.map).filter(function(pckgName) {
		return ignorePackages.indexOf(pckgName) === -1;
	}).join(' + ');

	glob("**/*.js", options.globJs, function(er, jsFiles) {
		jsFiles.forEach(function(file) {
			packages += ' + ' + file.substr(0, file.length - 3);
		});

		glob('**/*.html', options.globHtml, function(err, htmlFiles) {
			htmlFiles.forEach(function(file) {
				packages += ' + ' + file + '!text';
			});

			console.log('bundling ', packages);

			jspm.bundle(packages, path.join(), {minify: true, inject: true}).then(function() {
				console.log('done');
			});
		});

	});
};

<commit_msg>fixed missing path.join params<commit_after>var glob = require("glob");
var extend = require('util')._extend;
require('array-sugar');
var path = require('path');
var packageJSON = require('../../package.json');

module.exports = function jspmAureliaBundler(passedOpts) {
	var base = packageJSON.jspm.directories.baseURL;
	var packagesDir = packageJSON.jspm.directories.packages.split('/')[1];
	var configFile = path.relative(base, packageJSON.jspm.configFile);
	var target = 'build.js';
	var options = {	//default
		globJs: {ignore: [packagesDir + '/**', target, configFile], root: base, cwd: base},
		globHtml: {ignore: [packagesDir + '/**', 'index.html'], root: base, cwd: base},
		baseFolder: base,
		target: target,
		jspm: {minify: false, inject: true}
	};

	extend(options, passedOpts);

	var jspm = new require('jspm');
	var builder = jspm.Builder();

	var ignorePackages = [
		'traceur',
		'traceur-runtime',
		'babel',
		'babel-runtime'
	];

	var packages = Object.keys(builder.loader.map).filter(function(pckgName) {
		return ignorePackages.indexOf(pckgName) === -1;
	}).join(' + ');

	glob("**/*.js", options.globJs, function(er, jsFiles) {
		jsFiles.forEach(function(file) {
			packages += ' + ' + file.substr(0, file.length - 3);
		});

		glob('**/*.html', options.globHtml, function(err, htmlFiles) {
			htmlFiles.forEach(function(file) {
				//packages += ' + ' + file + '!text';	//TODO fix this as soon as I know how to register the views
			});

			console.log('bundling ', packages);

			jspm.bundle(packages, path.join(options.baseFolder, options.target), options.jspm).then(function() {
				console.log('done');
			});
		});

	});
};<|endoftext|>


<commit_before>monthNames = ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];

function GET(uri) {
	var req = new XMLHttpRequest();
	req.open("GET", uri, false);
	req.send(null);
	return req.responseText;
}

function $(id) {
	return document.getElementById(id);
}

function newDiv(appendObj) {
	var mydiv = document.createElement("div");
	appendObj.appendChild(mydiv);
	return mydiv;
}

function obj2style(obj) {
	stylestr = '';
	for (prop in obj) {
		stylestr += prop + ":" + obj[prop] + ";";
	}
	return stylestr;
}

function datestr2unix(datestr) {
	datestr = datestr.split(' ');
	if (datestr.length != 3 || datestr[2].split(":").length != 3) {
		return false;
	}
	var date = parseInt(datestr[0]);
	var month = monthNames.indexOf(datestr[1]);
	var hour = datestr[2].split(":")[0];
	var minute = datestr[2].split(":")[1];
	var second = datestr[2].split(":")[2];
	return (+new Date(2015, month, date, hour, minute, second)) / 1000;
}

function unix2datestr(unix) {
	var d = new Date(unix * 1000);
	return d.getDate() + " "
		+ monthNames[d.getMonth()] + " "
		+ leadingZero(d.getHours()) + ":"
		+ leadingZero(d.getMinutes()) + ":"
		+ leadingZero(d.getSeconds());
}

function leadingZero(n) {
	if (n < 10) {
		return "0" + n;
	}
	return "" + n;
}

<commit_msg>Add small comment in lib.js<commit_after>// Dutch months. Sorry.
monthNames = ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];

function GET(uri) {
	var req = new XMLHttpRequest();
	req.open("GET", uri, false);
	req.send(null);
	return req.responseText;
}

function $(id) {
	return document.getElementById(id);
}

function newDiv(appendObj) {
	var mydiv = document.createElement("div");
	appendObj.appendChild(mydiv);
	return mydiv;
}

function obj2style(obj) {
	stylestr = '';
	for (prop in obj) {
		stylestr += prop + ":" + obj[prop] + ";";
	}
	return stylestr;
}

function datestr2unix(datestr) {
	datestr = datestr.split(' ');
	if (datestr.length != 3 || datestr[2].split(":").length != 3) {
		return false;
	}
	var date = parseInt(datestr[0]);
	var month = monthNames.indexOf(datestr[1]);
	var hour = datestr[2].split(":")[0];
	var minute = datestr[2].split(":")[1];
	var second = datestr[2].split(":")[2];
	return (+new Date(2015, month, date, hour, minute, second)) / 1000;
}

function unix2datestr(unix) {
	var d = new Date(unix * 1000);
	return d.getDate() + " "
		+ monthNames[d.getMonth()] + " "
		+ leadingZero(d.getHours()) + ":"
		+ leadingZero(d.getMinutes()) + ":"
		+ leadingZero(d.getSeconds());
}

function leadingZero(n) {
	if (n < 10) {
		return "0" + n;
	}
	return "" + n;
}

<|endoftext|>