<commit_before>/**
 * ngBoxFill
 *
 * A directive to fit your text into its parent box.
 *
 * @link https://github.com/OpenServicesEU/ngBoxFill
 * @author Michael Fladischer <michael@openservices.at>
 * @license MIT License, http://www.opensource.org/licenses/MIT
 */

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(function () {
      return factory(root.angular);
    });
  } else if (typeof exports === 'object') {
    module.exports = factory(root.angular || (window && window.angular));
  } else {
    factory(root.angular);
  }
})(this, function (angular) {
  'use strict';

  angular.module('ngBoxFill', [])
  .directive(
    'ngBoxFill',
    [
      '$window',
      '$timeout',
      function (
        $window,
        $timeout
      ) {
        return {
          restrict: 'A',
          scope: {
            ngBoxFill: '&'
          },
          transclude: true,
          link: function (scope, element, attrs, ctrl, transclude) {
            console.log(scope, element, attrs, ctrl, transclude);
            var container = angular.element('
');
            transclude(scope.$parent, function(clone, scope) {
              container.append(clone);
            });
            element.append(container);
            var timer;
            var resize = function() {
              // A primitive debounce.
              $timeout.cancel(timer);
              timer = $timeout(function() {
                var width = element.prop('offsetWidth') - element.prop('offsetLeft');
                var height = element.prop('offsetHeight') - element.prop('offsetTop');
                var horizonalScale = width / container.prop('offsetWidth');
                var verticalScale = height / container.prop('offsetHeight');
                var scale = horizonalScale > verticalScale ? verticalScale : horizonalScale;
                container.css('transform', 'scale(' + (horizonalScale > verticalScale ? verticalScale : horizonalScale) + ')');
                container.removeClass('boxFillInitial');
              }, 100);
            };
            scope.$watchGroup(
              [
                function () { return element.prop('offsetHeight'); },
                function () { return element.prop('offsetWidth'); }
              ],
              resize
            );
            angular.element($window).on('resize', resize);
          }
        };
      }
    ]
  );
});
<commit_msg>Remove debugging to console.<commit_after>/**
 * ngBoxFill
 *
 * A directive to fit your text into its parent box.
 *
 * @link https://github.com/OpenServicesEU/ngBoxFill
 * @author Michael Fladischer <michael@openservices.at>
 * @license MIT License, http://www.opensource.org/licenses/MIT
 */

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(function () {
      return factory(root.angular);
    });
  } else if (typeof exports === 'object') {
    module.exports = factory(root.angular || (window && window.angular));
  } else {
    factory(root.angular);
  }
})(this, function (angular) {
  'use strict';

  angular.module('ngBoxFill', [])
  .directive(
    'ngBoxFill',
    [
      '$window',
      '$timeout',
      function (
        $window,
        $timeout
      ) {
        return {
          restrict: 'A',
          scope: {
            ngBoxFill: '&'
          },
          transclude: true,
          link: function (scope, element, attrs, ctrl, transclude) {
            var container = angular.element('
');
            transclude(scope.$parent, function(clone, scope) {
              container.append(clone);
            });
            element.append(container);
            var timer;
            var resize = function() {
              // A primitive debounce.
              $timeout.cancel(timer);
              timer = $timeout(function() {
                var width = element.prop('offsetWidth') - element.prop('offsetLeft');
                var height = element.prop('offsetHeight') - element.prop('offsetTop');
                var horizonalScale = width / container.prop('offsetWidth');
                var verticalScale = height / container.prop('offsetHeight');
                var scale = horizonalScale > verticalScale ? verticalScale : horizonalScale;
                container.css('transform', 'scale(' + (horizonalScale > verticalScale ? verticalScale : horizonalScale) + ')');
                container.removeClass('boxFillInitial');
              }, 100);
            };
            scope.$watchGroup(
              [
                function () { return element.prop('offsetHeight'); },
                function () { return element.prop('offsetWidth'); }
              ],
              resize
            );
            angular.element($window).on('resize', resize);
          }
        };
      }
    ]
  );
});
<|endoftext|>


<commit_before>/*
 * Common classes / functions for Selenium RC format.
 */

load('formatCommandOnlyAdapter.js');

function formatHeader(testCase) {
    var className = testCase.getTitle();
	if (!className) {
		className = "NewTest";
	}

	var formatLocal = testCase.formatLocal(this.name);
	methodName = testMethodName(className.replace(/Test$/, "").replace(/^Test/, "").
								replace(/^[A-Z]/, function(str) { return str.toLowerCase() }));
	var header = (options.getHeader ? options.getHeader() : options.header).
		replace(/\$\{className\}/g, className).
		replace(/\$\{methodName\}/g, methodName).
		replace(/\$\{baseURL\}/g, testCase.getBaseURL()).
		replace(/\$\{([a-zA-Z0-9_]+)\}/g, function(str, name) { return options[name] });
	this.lastIndent = indents(parseInt(options.initialIndents));
	formatLocal.header = header;
	return formatLocal.header;
}

function formatFooter(testCase) {
	var formatLocal = testCase.formatLocal(this.name);
	formatLocal.footer = options.footer;
	return formatLocal.footer;
}

function indents(num) {
	function repeat(c, n) {
		var str = "";
		for (var i = 0; i < n; i++) {
			str += c;
		}
		return str;
	}
	var indent = options.indent;
	if ('tab' == indent) {
		return repeat("\t", num);
	} else {
		return repeat(" ", num * parseInt(options.indent));
	}
}

function capitalize(string) {
	return string.replace(/^[a-z]/, function(str) { return str.toUpperCase(); });
}

function underscore(text) {
	return text.replace(/[A-Z]/g, function(str) {
			return '_' + str.toLowerCase();
		});
}

function notOperator() {
	return "!";
}

function logicalAnd(conditions) {
    return conditions.join(" && ");
}

function equals(e1, e2) {
	return new Equals(e1, e2);
}

function Equals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
}

Equals.prototype.invert = function() {
	return new NotEquals(this.e1, this.e2);
}

function NotEquals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
	this.negative = true;
}

NotEquals.prototype.invert = function() {
	return new Equals(this.e1, this.e2);
}

function RegexpMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
}

RegexpMatch.prototype.invert = function() {
	return new RegexpNotMatch(this.pattern, this.expression);
}

RegexpMatch.prototype.assert = function() {
	return assertTrue(this.toString());
}

RegexpMatch.prototype.verify = function() {
	return verifyTrue(this.toString());
}

function RegexpNotMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
	this.negative = true;
}

RegexpNotMatch.prototype.invert = function() {
	return new RegexpMatch(this.pattern, this.expression);
}

RegexpNotMatch.prototype.toString = function() {
	return notOperator() + RegexpMatch.prototype.toString.call(this);
}

RegexpNotMatch.prototype.assert = function() {
	return assertFalse(this.invert());
}

RegexpNotMatch.prototype.verify = function() {
	return verifyFalse(this.invert());
}

function seleniumEquals(type, pattern, expression) {
	if (type == 'String[]') {
		return seleniumEquals('String', pattern.replace(/\\,/g, ',') , joinExpression(expression));
	} else if (type == 'String' && pattern.match(/^regexp:/)) {
		return new RegexpMatch(pattern.substring(7), expression);
	} else if (type == 'String' && pattern.match(/^regex:/)) {
		return new RegexpMatch(pattern.substring(6), expression);
	} else if (type == 'String' && (pattern.match(/^glob:/) || pattern.match(/[\*\?]/))) {
		pattern = pattern.replace(/^glob:/, '');
		pattern = pattern.replace(/([\]\[\\\{\}\$\(\).])/g, "\\$1");
		pattern = pattern.replace(/\?/g, "[\\s\\S]");
		pattern = pattern.replace(/\*/g, "[\\s\\S]*");
		return new RegexpMatch("^" + pattern + "$", expression);
	} else {
		pattern = pattern.replace(/^exact:/, '');
		return new Equals(xlateValue(type, pattern), expression);
	}
}

function xlateArgument(value) {
	value = value.replace(/^\s+/, '');
	value = value.replace(/\s+$/, '');
	var r;
	if ((r = /^javascript\{([\d\D]*)\}$/.exec(value))) {
		var js = r[1];
		var parts = [];
		var prefix = "";
		var r2;
		while ((r2 = /storedVars\['(.*?)'\]/.exec(js))) {
			parts.push(string(prefix + js.substring(0, r2.index) + "'"));
			parts.push(variableName(r2[1]));
			js = js.substring(r2.index + r2[0].length);
			prefix = "'";
		}
		parts.push(string(prefix + js));
		return new CallSelenium("getEval", [concatString(parts)]);
	} else if ((r = /\$\{/.exec(value))) {
		var parts = [];
		var regexp = /\$\{(.*?)\}/g;
		var lastIndex = 0;
		var r2;
		while (r2 = regexp.exec(value)) {
		    if (this.declaredVars && this.declaredVars[r2[1]]) {
    			if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(variableName(r2[1]));
    			lastIndex = regexp.lastIndex;
    		} else if (r2[1] == "nbsp") {
    		    if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(nonBreakingSpace());
    			lastIndex = regexp.lastIndex;
    		}
		}
		if (lastIndex < value.length) {
			parts.push(string(value.substring(lastIndex, value.length)));
		}
		return concatString(parts);
	} else {
		return string(value);
	}
}

function addDeclaredVar(variable) {
	if (this.declaredVars == null) {
		this.declaredVars = {};
	}
	this.declaredVars[variable] = true;
}

function newVariable(prefix, index) {
	if (index == null) index = 1;
	if (this.declaredVars && this.declaredVars[prefix + index]) {
		return newVariable(prefix, index + 1);
	} else {
		addDeclaredVar(prefix + index);
		return prefix + index;
	}
}

function variableName(value) {
	return value;
}

function concatString(array) {
	return array.join(" + ");
}

function string(value) {
	if (value != null) {
		//value = value.replace(/^\s+/, '');
		//value = value.replace(/\s+$/, '');
		value = value.replace(/\\/g, '\\\\');
		value = value.replace(/\"/g, '\\"');
		value = value.replace(/\r/g, '\\r');
		value = value.replace(/\n/g, '\\n');
		return '"' + value + '"';
	} else {
		return '""';
	}
}

function CallSelenium(message, args) {
	this.message = message;
	if (args) {
		this.args = args;
	} else {
		this.args = [];
	}
}

CallSelenium.prototype.invert = function() {
	var call = new CallSelenium(this.message);
	call.args = this.args;
	call.negative = !this.negative;
	return call;
}

function xlateArrayElement(value) {
	return value.replace(/\\(.)/g, "$1");
}

function parseArray(value) {
	var start = 0;
	var list = [];
	for (var i = 0; i < value.length; i++) {
		if (value.charAt(i) == ',') {
			list.push(xlateArrayElement(value.substring(start, i)));
			start = i + 1;
		} else if (value.charAt(i) == '\\') {
			i++;
		}
	}
	list.push(xlateArrayElement(value.substring(start, value.length)));
	return list;
}

function xlateValue(type, value) {
	if (type == 'String[]') {
		return array(parseArray(value));
	} else {
		return xlateArgument(value);
	}
}

function formatCommand(command) {
	var line = null;
	if (command.type == 'command') {
		var def = command.getDefinition();
		if (def && def.isAccessor) {
			var call = new CallSelenium(def.name);
			for (var i = 0; i < def.params.length; i++) {
				call.args.push(xlateArgument(command.getParameterAt(i)));
			}
			var extraArg = command.getParameterAt(def.params.length)
			if (def.name.match(/^is/)) { // isXXX
				if (command.command.match(/^assert/) ||
					(this.assertOrVerifyFailureOnNext && command.command.match(/^verify/))) {
					line = (def.negative ? assertFalse : assertTrue)(call);
				} else if (command.command.match(/^verify/)) {
					line = (def.negative ? verifyFalse : verifyTrue)(call);
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable('boolean', extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					line = waitFor(def.negative ? call.invert() : call);
				}
			} else { // getXXX
				if (command.command.match(/^(verify|assert)/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
					line = eq[method]();
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable(def.returnType, extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					line = waitFor(eq);
				}
			}
		} else if (this.pause && 'pause' == command.command) {
			line = pause(command.target);
		} else if (this.echo && 'echo' == command.command) {
			line = echo(command.target);
		} else if ('store' == command.command) {
			addDeclaredVar(command.value);
			line = statement(assignToVariable('String', command.value, xlateArgument(command.target)));
		} else if (command.command.match(/^(assert|verify)Selected$/)) {
			var optionLocator = command.value;
			var flavor = 'Label';
			var value = optionLocator;
			var r = /^(index|label|value|id)=(.*)$/.exec(optionLocator);
			if (r) {
				flavor = r[1].replace(/^[a-z]/, function(str) { return str.toUpperCase() });
				value = r[2];
			}
			var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
			var call = new CallSelenium("getSelected" + flavor);
			call.args.push(xlateArgument(command.target));
			var eq = seleniumEquals('String', value, call);
			line = statement(eq[method]());
		} else if (def) {
			if (def.name.match(/^(assert|verify)(Error|Failure)OnNext$/)) {
				this.assertOrVerifyFailureOnNext = true;
				this.assertFailureOnNext = def.name.match(/^assert/);
				this.verifyFailureOnNext = def.name.match(/^verify/);
			} else {
				var call = new CallSelenium(def.name);
                if ("open" == def.name && options.urlSuffix && !command.target.match(/^\w+:\/\//)) {
                    // urlSuffix is used to translate core-based test
                    call.args.push(xlateArgument(options.urlSuffix + command.target));
                } else {
                    for (var i = 0; i < def.params.length; i++) {
                        call.args.push(xlateArgument(command.getParameterAt(i)));
                    }
                }
				line = statement(call, command);
			}
		} else {
			this.log.info("unknown command: <" + command.command + ">");
			// TODO
			var call = new CallSelenium(command.command);
			if ((command.target != null && command.target.length > 0)
				|| (command.value != null && command.value.length > 0)) {
				call.args.push(string(command.target));
				if (command.value != null && command.value.length > 0) {
					call.args.push(string(command.value));
				}
			}
			line = formatComment(new Comment(statement(call)));
		}
	}
	if (line && this.assertOrVerifyFailureOnNext) {
		line = assertOrVerifyFailure(line, this.assertFailureOnNext);
		this.assertOrVerifyFailureOnNext = false;
		this.assertFailureOnNext = false;
		this.verifyFailureOnNext = false;
	}
	return line;
}

this.remoteControl = true;
this.playable = false;

<commit_msg>AdamGoucher - when called from a format plugin, the load() isn't in the namespace or somesuch so putting what it does in place rather than the nice function<commit_after>/*
 * Common classes / functions for Selenium RC format.
 */

var subScriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
subScriptLoader.loadSubScript('chrome://selenium-ide/content/formats/formatCommandOnlyAdapter.js');

function formatHeader(testCase) {
    var className = testCase.getTitle();
	if (!className) {
		className = "NewTest";
	}

	var formatLocal = testCase.formatLocal(this.name);
	methodName = testMethodName(className.replace(/Test$/, "").replace(/^Test/, "").
								replace(/^[A-Z]/, function(str) { return str.toLowerCase() }));
	var header = (options.getHeader ? options.getHeader() : options.header).
		replace(/\$\{className\}/g, className).
		replace(/\$\{methodName\}/g, methodName).
		replace(/\$\{baseURL\}/g, testCase.getBaseURL()).
		replace(/\$\{([a-zA-Z0-9_]+)\}/g, function(str, name) { return options[name] });
	this.lastIndent = indents(parseInt(options.initialIndents));
	formatLocal.header = header;
	return formatLocal.header;
}

function formatFooter(testCase) {
	var formatLocal = testCase.formatLocal(this.name);
	formatLocal.footer = options.footer;
	return formatLocal.footer;
}

function indents(num) {
	function repeat(c, n) {
		var str = "";
		for (var i = 0; i < n; i++) {
			str += c;
		}
		return str;
	}
	var indent = options.indent;
	if ('tab' == indent) {
		return repeat("\t", num);
	} else {
		return repeat(" ", num * parseInt(options.indent));
	}
}

function capitalize(string) {
	return string.replace(/^[a-z]/, function(str) { return str.toUpperCase(); });
}

function underscore(text) {
	return text.replace(/[A-Z]/g, function(str) {
			return '_' + str.toLowerCase();
		});
}

function notOperator() {
	return "!";
}

function logicalAnd(conditions) {
    return conditions.join(" && ");
}

function equals(e1, e2) {
	return new Equals(e1, e2);
}

function Equals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
}

Equals.prototype.invert = function() {
	return new NotEquals(this.e1, this.e2);
}

function NotEquals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
	this.negative = true;
}

NotEquals.prototype.invert = function() {
	return new Equals(this.e1, this.e2);
}

function RegexpMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
}

RegexpMatch.prototype.invert = function() {
	return new RegexpNotMatch(this.pattern, this.expression);
}

RegexpMatch.prototype.assert = function() {
	return assertTrue(this.toString());
}

RegexpMatch.prototype.verify = function() {
	return verifyTrue(this.toString());
}

function RegexpNotMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
	this.negative = true;
}

RegexpNotMatch.prototype.invert = function() {
	return new RegexpMatch(this.pattern, this.expression);
}

RegexpNotMatch.prototype.toString = function() {
	return notOperator() + RegexpMatch.prototype.toString.call(this);
}

RegexpNotMatch.prototype.assert = function() {
	return assertFalse(this.invert());
}

RegexpNotMatch.prototype.verify = function() {
	return verifyFalse(this.invert());
}

function seleniumEquals(type, pattern, expression) {
	if (type == 'String[]') {
		return seleniumEquals('String', pattern.replace(/\\,/g, ',') , joinExpression(expression));
	} else if (type == 'String' && pattern.match(/^regexp:/)) {
		return new RegexpMatch(pattern.substring(7), expression);
	} else if (type == 'String' && pattern.match(/^regex:/)) {
		return new RegexpMatch(pattern.substring(6), expression);
	} else if (type == 'String' && (pattern.match(/^glob:/) || pattern.match(/[\*\?]/))) {
		pattern = pattern.replace(/^glob:/, '');
		pattern = pattern.replace(/([\]\[\\\{\}\$\(\).])/g, "\\$1");
		pattern = pattern.replace(/\?/g, "[\\s\\S]");
		pattern = pattern.replace(/\*/g, "[\\s\\S]*");
		return new RegexpMatch("^" + pattern + "$", expression);
	} else {
		pattern = pattern.replace(/^exact:/, '');
		return new Equals(xlateValue(type, pattern), expression);
	}
}

function xlateArgument(value) {
	value = value.replace(/^\s+/, '');
	value = value.replace(/\s+$/, '');
	var r;
	if ((r = /^javascript\{([\d\D]*)\}$/.exec(value))) {
		var js = r[1];
		var parts = [];
		var prefix = "";
		var r2;
		while ((r2 = /storedVars\['(.*?)'\]/.exec(js))) {
			parts.push(string(prefix + js.substring(0, r2.index) + "'"));
			parts.push(variableName(r2[1]));
			js = js.substring(r2.index + r2[0].length);
			prefix = "'";
		}
		parts.push(string(prefix + js));
		return new CallSelenium("getEval", [concatString(parts)]);
	} else if ((r = /\$\{/.exec(value))) {
		var parts = [];
		var regexp = /\$\{(.*?)\}/g;
		var lastIndex = 0;
		var r2;
		while (r2 = regexp.exec(value)) {
		    if (this.declaredVars && this.declaredVars[r2[1]]) {
    			if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(variableName(r2[1]));
    			lastIndex = regexp.lastIndex;
    		} else if (r2[1] == "nbsp") {
    		    if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(nonBreakingSpace());
    			lastIndex = regexp.lastIndex;
    		}
		}
		if (lastIndex < value.length) {
			parts.push(string(value.substring(lastIndex, value.length)));
		}
		return concatString(parts);
	} else {
		return string(value);
	}
}

function addDeclaredVar(variable) {
	if (this.declaredVars == null) {
		this.declaredVars = {};
	}
	this.declaredVars[variable] = true;
}

function newVariable(prefix, index) {
	if (index == null) index = 1;
	if (this.declaredVars && this.declaredVars[prefix + index]) {
		return newVariable(prefix, index + 1);
	} else {
		addDeclaredVar(prefix + index);
		return prefix + index;
	}
}

function variableName(value) {
	return value;
}

function concatString(array) {
	return array.join(" + ");
}

function string(value) {
	if (value != null) {
		//value = value.replace(/^\s+/, '');
		//value = value.replace(/\s+$/, '');
		value = value.replace(/\\/g, '\\\\');
		value = value.replace(/\"/g, '\\"');
		value = value.replace(/\r/g, '\\r');
		value = value.replace(/\n/g, '\\n');
		return '"' + value + '"';
	} else {
		return '""';
	}
}

function CallSelenium(message, args) {
	this.message = message;
	if (args) {
		this.args = args;
	} else {
		this.args = [];
	}
}

CallSelenium.prototype.invert = function() {
	var call = new CallSelenium(this.message);
	call.args = this.args;
	call.negative = !this.negative;
	return call;
}

function xlateArrayElement(value) {
	return value.replace(/\\(.)/g, "$1");
}

function parseArray(value) {
	var start = 0;
	var list = [];
	for (var i = 0; i < value.length; i++) {
		if (value.charAt(i) == ',') {
			list.push(xlateArrayElement(value.substring(start, i)));
			start = i + 1;
		} else if (value.charAt(i) == '\\') {
			i++;
		}
	}
	list.push(xlateArrayElement(value.substring(start, value.length)));
	return list;
}

function xlateValue(type, value) {
	if (type == 'String[]') {
		return array(parseArray(value));
	} else {
		return xlateArgument(value);
	}
}

function formatCommand(command) {
	var line = null;
	if (command.type == 'command') {
		var def = command.getDefinition();
		if (def && def.isAccessor) {
			var call = new CallSelenium(def.name);
			for (var i = 0; i < def.params.length; i++) {
				call.args.push(xlateArgument(command.getParameterAt(i)));
			}
			var extraArg = command.getParameterAt(def.params.length)
			if (def.name.match(/^is/)) { // isXXX
				if (command.command.match(/^assert/) ||
					(this.assertOrVerifyFailureOnNext && command.command.match(/^verify/))) {
					line = (def.negative ? assertFalse : assertTrue)(call);
				} else if (command.command.match(/^verify/)) {
					line = (def.negative ? verifyFalse : verifyTrue)(call);
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable('boolean', extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					line = waitFor(def.negative ? call.invert() : call);
				}
			} else { // getXXX
				if (command.command.match(/^(verify|assert)/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
					line = eq[method]();
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable(def.returnType, extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					line = waitFor(eq);
				}
			}
		} else if (this.pause && 'pause' == command.command) {
			line = pause(command.target);
		} else if (this.echo && 'echo' == command.command) {
			line = echo(command.target);
		} else if ('store' == command.command) {
			addDeclaredVar(command.value);
			line = statement(assignToVariable('String', command.value, xlateArgument(command.target)));
		} else if (command.command.match(/^(assert|verify)Selected$/)) {
			var optionLocator = command.value;
			var flavor = 'Label';
			var value = optionLocator;
			var r = /^(index|label|value|id)=(.*)$/.exec(optionLocator);
			if (r) {
				flavor = r[1].replace(/^[a-z]/, function(str) { return str.toUpperCase() });
				value = r[2];
			}
			var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
			var call = new CallSelenium("getSelected" + flavor);
			call.args.push(xlateArgument(command.target));
			var eq = seleniumEquals('String', value, call);
			line = statement(eq[method]());
		} else if (def) {
			if (def.name.match(/^(assert|verify)(Error|Failure)OnNext$/)) {
				this.assertOrVerifyFailureOnNext = true;
				this.assertFailureOnNext = def.name.match(/^assert/);
				this.verifyFailureOnNext = def.name.match(/^verify/);
			} else {
				var call = new CallSelenium(def.name);
                if ("open" == def.name && options.urlSuffix && !command.target.match(/^\w+:\/\//)) {
                    // urlSuffix is used to translate core-based test
                    call.args.push(xlateArgument(options.urlSuffix + command.target));
                } else {
                    for (var i = 0; i < def.params.length; i++) {
                        call.args.push(xlateArgument(command.getParameterAt(i)));
                    }
                }
				line = statement(call, command);
			}
		} else {
			this.log.info("unknown command: <" + command.command + ">");
			// TODO
			var call = new CallSelenium(command.command);
			if ((command.target != null && command.target.length > 0)
				|| (command.value != null && command.value.length > 0)) {
				call.args.push(string(command.target));
				if (command.value != null && command.value.length > 0) {
					call.args.push(string(command.value));
				}
			}
			line = formatComment(new Comment(statement(call)));
		}
	}
	if (line && this.assertOrVerifyFailureOnNext) {
		line = assertOrVerifyFailure(line, this.assertFailureOnNext);
		this.assertOrVerifyFailureOnNext = false;
		this.assertFailureOnNext = false;
		this.verifyFailureOnNext = false;
	}
	return line;
}

this.remoteControl = true;
this.playable = false;

<|endoftext|>


<commit_before>(function(window, angular, Math) {
  angular.module('tourcms.ng-tourcms', [])
 .factory('tourcmsApiService', function($http) {

    var baseUrl = 'https://api.tourcms.com';

    var apiKey = '';
    var marketplaceId = 0;
    var channelId = 0;

    var makeRequest = function(a) {
      // Sensible defaults
      if(typeof a.channelId == "undefined")
        a.channelId = 0;

      if(typeof a.verb == "undefined")
        a.verb = 'GET';

      //console.log(a.postData);

      if(typeof a.postData == "undefined") {
        var apiParams = "";
      } else {
        var s = new XMLSerializer();
        var apiParams = s.serializeToString(a.postData);
      }

      // Get the current time
      var outboundTime = generateTime();

      // Generate the signature
      var signature = generateSignature(a.path, a.channelId, a.verb, outboundTime);

      // Full URL to call
      var apiUrl = baseUrl + a.path;

      // Make the call using Angular $http
      return $http({
                method: a.verb,
                url: apiUrl,
                params: apiParams,
                headers: {
                  'x-tourcms-date': outboundTime,
                  'Authorization': 'TourCMS ' + a.channelId + ':' + marketplaceId + ':' + signature,
                  'Content-type': 'text/xml;charset="utf-8"'
                },
                transformResponse: function(data) {
                  if(typeof X2JS !== 'undefined') {
                    var x2js = new X2JS();
                    var json = x2js.xml_str2json( data );
                    return json;
                  } else {
                    return data;
                  }
                }
      });
    };

    // Generate the signature required to sign API calls
    var generateSignature = function(path, channelId, verb, outboundTime) {
      var stringToSign = channelId + "/" + marketplaceId + "/" + verb + "/" + outboundTime + path;
      var signature = rawurlencode(b64_hmac_sha256(apiKey, stringToSign) + "=");

      return signature;
    }

    // Generate the current Unix Timestamp (PHP style)
    var generateTime = function() {
      return Math.floor(new Date().getTime() / 1000);
    }

    var rawurlencode = function(str) {
    //From http://phpjs.org/functions/rawurlencode/
    str = (str + '')
      .toString();

      return encodeURIComponent(str)
        .replace(/!/g, '%21')
        .replace(/'/g, '%27')
        .replace(/\(/g, '%28')
        .
      replace(/\)/g, '%29')
        .replace(/\*/g, '%2A');
    }

    var toQueryString = function(obj) {
    var parts = [];
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
        }
    }
        return parts.join("&");
    }

    // Return our singleton
    return {
        apiRateLimitStatus: function(a) {
                                a.path = '/api/rate_limit_status.xml';
                                return makeRequest(a);
        },
        searchTours: function(a) {

                              // Convert/set search params
                                // If undefined
                            		if(typeof a.qs === "undefined") {
                            			a.qs = "";
                                // If array of key value pairs
                                } else if(typeof a.qs === 'object') {
                                  a.qs = toQueryString(a.qs);
                                }
                                // Otherwise leave alone (already a query string)

                              // Channel ID
                                // If undefined, use object level channelId
                            		if(typeof a.channelId === "undefined")
                            			a.channelId = channelId;

                              // Set API path
                            		if(a.channelId==0)
                            			a.path = '/p/tours/search.xml?' + a.qs;
                            		else
                            			a.path = '/c/tours/search.xml?' + a.qs;

                                return makeRequest(a);
        }
    };

});
})(this, this.angular, Math);
<commit_msg>Tweaked Rate Limit Channel ID logic to match Search Tours<commit_after>(function(window, angular, Math) {
  angular.module('tourcms.ng-tourcms', [])
 .factory('tourcmsApiService', function($http) {

    var baseUrl = 'https://api.tourcms.com';

    var apiKey = '';
    var marketplaceId = 0;
    var channelId = 0;

    var makeRequest = function(a) {
      // Sensible defaults
      if(typeof a.channelId == "undefined")
        a.channelId = 0;

      if(typeof a.verb == "undefined")
        a.verb = 'GET';

      //console.log(a.postData);

      if(typeof a.postData == "undefined") {
        var apiParams = "";
      } else {
        var s = new XMLSerializer();
        var apiParams = s.serializeToString(a.postData);
      }

      // Get the current time
      var outboundTime = generateTime();

      // Generate the signature
      var signature = generateSignature(a.path, a.channelId, a.verb, outboundTime);

      // Full URL to call
      var apiUrl = baseUrl + a.path;

      // Make the call using Angular $http
      return $http({
                method: a.verb,
                url: apiUrl,
                params: apiParams,
                headers: {
                  'x-tourcms-date': outboundTime,
                  'Authorization': 'TourCMS ' + a.channelId + ':' + marketplaceId + ':' + signature,
                  'Content-type': 'text/xml;charset="utf-8"'
                },
                transformResponse: function(data) {
                  if(typeof X2JS !== 'undefined') {
                    var x2js = new X2JS();
                    var json = x2js.xml_str2json( data );
                    return json;
                  } else {
                    return data;
                  }
                }
      });
    };

    // Generate the signature required to sign API calls
    var generateSignature = function(path, channelId, verb, outboundTime) {
      var stringToSign = channelId + "/" + marketplaceId + "/" + verb + "/" + outboundTime + path;
      var signature = rawurlencode(b64_hmac_sha256(apiKey, stringToSign) + "=");

      return signature;
    }

    // Generate the current Unix Timestamp (PHP style)
    var generateTime = function() {
      return Math.floor(new Date().getTime() / 1000);
    }

    var rawurlencode = function(str) {
    //From http://phpjs.org/functions/rawurlencode/
    str = (str + '')
      .toString();

      return encodeURIComponent(str)
        .replace(/!/g, '%21')
        .replace(/'/g, '%27')
        .replace(/\(/g, '%28')
        .
      replace(/\)/g, '%29')
        .replace(/\*/g, '%2A');
    }

    var toQueryString = function(obj) {
    var parts = [];
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
        }
    }
        return parts.join("&");
    }

    // Return our singleton
    return {
        apiRateLimitStatus: function(a) {
                              // Channel ID
                                // If undefined, use object level channelId
                                if(typeof a.channelId === "undefined")
                                  a.channelId = channelId;

                                a.path = '/api/rate_limit_status.xml';
                                return makeRequest(a);
        },
        searchTours: function(a) {

                              // Convert/set search params
                                // If undefined
                            		if(typeof a.qs === "undefined") {
                            			a.qs = "";
                                // If array of key value pairs
                                } else if(typeof a.qs === 'object') {
                                  a.qs = toQueryString(a.qs);
                                }
                                // Otherwise leave alone (already a query string)

                              // Channel ID
                                // If undefined, use object level channelId
                            		if(typeof a.channelId === "undefined")
                            			a.channelId = channelId;

                              // Set API path
                            		if(a.channelId==0)
                            			a.path = '/p/tours/search.xml?' + a.qs;
                            		else
                            			a.path = '/c/tours/search.xml?' + a.qs;

                                return makeRequest(a);
        }
    };

});
})(this, this.angular, Math);
<|endoftext|>


<commit_before>function dismissPopupAndReload(win) {
    document.location.reload();
    win.close();
};
function dismissRelatedImageLookupPopup(win, chosenId, chosenThumbnailUrl, chosenDescriptionTxt) {
    var name = windowname_to_id(win.name);
    var img_name = name + '_thumbnail_img';
    var txt_name = name + '_description_txt';
    var elem = document.getElementById(name);
    document.getElementById(name).value = chosenId;
    document.getElementById(img_name).src = chosenThumbnailUrl;
    document.getElementById(txt_name).innerHTML = chosenDescriptionTxt;
    win.close();
};
function dismissRelatedFolderLookupPopup(win, chosenId, chosenName) {
    var id = windowname_to_id(win.name);
    var id_name = id + '_name';
    alert(id_name);
    document.getElementById(id).value = chosenId;
    document.getElementById(id_name).innerHTML = chosenName;
    win.close();
};
<commit_msg>Remove debug output (cherry picked from commit cc5dcaae49c3e676e5d86cc0f4a78574494d1a13)<commit_after>function dismissPopupAndReload(win) {
    document.location.reload();
    win.close();
};
function dismissRelatedImageLookupPopup(win, chosenId, chosenThumbnailUrl, chosenDescriptionTxt) {
    var name = windowname_to_id(win.name);
    var img_name = name + '_thumbnail_img';
    var txt_name = name + '_description_txt';
    var elem = document.getElementById(name);
    document.getElementById(name).value = chosenId;
    document.getElementById(img_name).src = chosenThumbnailUrl;
    document.getElementById(txt_name).innerHTML = chosenDescriptionTxt;
    win.close();
};
function dismissRelatedFolderLookupPopup(win, chosenId, chosenName) {
    var id = windowname_to_id(win.name);
    var id_name = id + '_name';
    document.getElementById(id).value = chosenId;
    document.getElementById(id_name).innerHTML = chosenName;
    win.close();
};
<|endoftext|>


<commit_before>var module = angular.module('ngProgress', []);

module.provider('progressbar', function() {
    //Default values for provider
    this.count = 0;
    this.height = '2px';
    this.color = 'firebrick';

    this.$get = function($document, $window) {
        var count = this.count;
        var height = this.height;
        var color = this.color;
        var $body = $document.find('body');
        // Create elements that is needed
        var progressbarContainer = angular.element('

');
        var progressbar = angular.element('

');

        //Add CSS3 styles for transition smoothing
        var css = document.createElement("style");
        css.type = "text/css";
        css.innerHTML = ".progressbar {-webkit-transition: all 0.5s ease-in-out; -moz-transition: all 0.5s ease-in-out; -o-transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;}";
        document.body.appendChild(css);

        //Styling for the progressbar-container
        progressbarContainer.css('position', 'fixed');
        progressbarContainer.css('margin', '0');
        progressbarContainer.css('padding', '0');
        progressbarContainer.css('top', '0px');
        progressbarContainer.css('left', '0px');
        progressbarContainer.css('right', '0px');

        //Styling for the progressbar itself
        progressbar.css('height', height);
        progressbar.css('box-shadow', '0px 0px 10px 0px ' + color);
        progressbar.css('width', count+'%');
        progressbar.css('margin', '0');
        progressbar.css('padding', '0');
        progressbar.css('background-color', color);

        //Add progressbar to progressbar-container and progressbar-container
        // to body
        progressbarContainer.append(progressbar);
        $body.append(progressbarContainer);

        return {
            // Starts the animation and adds between 0 - 5 percent to loading
            // each 400 milliseconds. Should always be finished with progressbar.complete()
            // to hide it
            start: function() {
                progressbar.css('width', count + '%');
                progressbar.css('opacity', '1');
                $window.interval = setInterval(function(){
                    if(count + 1 >= 100) {
                        clearInterval($window.interval);
                    } else {
                        var random = Math.floor(Math.random()*5)
                        count = count + random;
                        progressbar.css('width', count + '%');
                    }
                }, 400);
            },
            // Sets the height of the progressbar. Use any valid CSS value
            // Eg '10px', '1em' or '1%'
            height: function(new_height) {
                progressbar.css('height', new_height);
            },
            // Sets the color of the progressbar and it's shadow. Use any valid HTML
            // color
            color: function(color) {
                progressbar.css('box-shadow', '0px 0px 10px 0px ' + color);
                progressbar.css('background-color', color);
            },
            // Returns on how many percent the progressbar is at. Should'nt be needed
            status: function() {
                return this.count;
            },
            // Stops the progressbar at it's current location
            stop: function() {
                clearInterval($window.interval);
            },
            // Set's the progressbar percentage. Use a number between 0 - 100.
            // If 100 is provided, complete will be called.
            set: function(new_count) {
                if(new_count >= 100) {
                    this.complete();
                }
                count = new_count;
                progressbar.css('width', count + '%');
                progressbar.css('opacity', '1');
                return count;
            },
            // Resets the progressbar to percetage 0 and therefore will be hided after
            // it's rollbacked
            reset: function() {
                count = 0;
                progressbar.css('width', count + '%');
                progressbar.css('opacity', '1');
                return 0;
            },
            // Jumps to 100% progress and fades away progressbar.
            complete: function() {
                count = 100;
                progressbar.css('width', count + '%');
                setTimeout(function(){
                    progressbar.css('opacity', '0');
                }, 500);
                setTimeout(function(){
                    count = 0;
                    progressbar.css('width', count + '%');
                }, 1000);
                return count;
            }
        }
    };

    this.setColor = function(color) {
        this.color = color;
    };

    this.setHeight = function(height) {
        this.height = height;
    };

});<commit_msg>Add clearInterval to set, reset and complete<commit_after>var module = angular.module('ngProgress', []);

module.provider('progressbar', function() {
    //Default values for provider
    this.count = 0;
    this.height = '2px';
    this.color = 'firebrick';

    this.$get = function($document, $window) {
        var count = this.count;
        var height = this.height;
        var color = this.color;
        var $body = $document.find('body');
        // Create elements that is needed
        var progressbarContainer = angular.element('

');
        var progressbar = angular.element('

');

        //Add CSS3 styles for transition smoothing
        var css = document.createElement("style");
        css.type = "text/css";
        css.innerHTML = ".progressbar {-webkit-transition: all 0.5s ease-in-out; -moz-transition: all 0.5s ease-in-out; -o-transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;}";
        document.body.appendChild(css);

        //Styling for the progressbar-container
        progressbarContainer.css('position', 'fixed');
        progressbarContainer.css('margin', '0');
        progressbarContainer.css('padding', '0');
        progressbarContainer.css('top', '0px');
        progressbarContainer.css('left', '0px');
        progressbarContainer.css('right', '0px');

        //Styling for the progressbar itself
        progressbar.css('height', height);
        progressbar.css('box-shadow', '0px 0px 10px 0px ' + color);
        progressbar.css('width', count+'%');
        progressbar.css('margin', '0');
        progressbar.css('padding', '0');
        progressbar.css('background-color', color);

        //Add progressbar to progressbar-container and progressbar-container
        // to body
        progressbarContainer.append(progressbar);
        $body.append(progressbarContainer);

        return {
            // Starts the animation and adds between 0 - 5 percent to loading
            // each 400 milliseconds. Should always be finished with progressbar.complete()
            // to hide it
            start: function() {
                progressbar.css('width', count + '%');
                progressbar.css('opacity', '1');
                $window.interval = setInterval(function(){
                    if(count + 1 >= 100) {
                        clearInterval($window.interval);
                    } else {
                        var random = Math.floor(Math.random()*5)
                        count = count + random;
                        progressbar.css('width', count + '%');
                    }
                }, 400);
            },
            // Sets the height of the progressbar. Use any valid CSS value
            // Eg '10px', '1em' or '1%'
            height: function(new_height) {
                progressbar.css('height', new_height);
            },
            // Sets the color of the progressbar and it's shadow. Use any valid HTML
            // color
            color: function(color) {
                progressbar.css('box-shadow', '0px 0px 10px 0px ' + color);
                progressbar.css('background-color', color);
            },
            // Returns on how many percent the progressbar is at. Should'nt be needed
            status: function() {
                return this.count;
            },
            // Stops the progressbar at it's current location
            stop: function() {
                clearInterval($window.interval);
            },
            // Set's the progressbar percentage. Use a number between 0 - 100.
            // If 100 is provided, complete will be called.
            set: function(new_count) {
                clearInterval($window.interval);
                if(new_count >= 100) {
                    this.complete();
                }
                count = new_count;
                progressbar.css('width', count + '%');
                progressbar.css('opacity', '1');
                return count;
            },
            // Resets the progressbar to percetage 0 and therefore will be hided after
            // it's rollbacked
            reset: function() {
                clearInterval($window.interval);
                count = 0;
                progressbar.css('width', count + '%');
                progressbar.css('opacity', '1');
                return 0;
            },
            // Jumps to 100% progress and fades away progressbar.
            complete: function() {
                clearInterval($window.interval);
                count = 100;
                progressbar.css('width', count + '%');
                setTimeout(function(){
                    progressbar.css('opacity', '0');
                }, 500);
                setTimeout(function(){
                    count = 0;
                    progressbar.css('width', count + '%');
                }, 1000);
                return count;
            }
        }
    };

    this.setColor = function(color) {
        this.color = color;
    };

    this.setHeight = function(height) {
        this.height = height;
    };

});<|endoftext|>


<commit_before>// @flow

import Logger from 'jitsi-meet-logger';
import md5 from 'js-md5';

const logger = Logger.getLogger(__filename);

/**
 * The name of the localStorage store where the app persists its values to.
 */
const PERSISTED_STATE_NAME = 'jitsi-state';

/**
 * Mixed type of the element (subtree) config. If it's a boolean,
 * (and is true) we persist the entire subtree. If it's an object,
 * we perist a filtered subtree based on the properties in the
 * config object.
 */
declare type ElementConfig = Object | boolean;

/**
 * The type of the name-config pairs stored in this reducer.
 */
declare type PersistencyConfigMap = { [name: string]: ElementConfig };

/**
 * A registry to allow features to register their redux store subtree to be
 * persisted and also handles the persistency calls too.
 */
class PersistenceRegistry {
    _checksum: string;

    _elements: PersistencyConfigMap;

    /**
     * Initializes a new {@ code PersistenceRegistry} instance.
     */
    constructor() {
        this._elements = {};
    }

    /**
     * Returns the persisted redux state. This function takes the
     * {@link #_elements} into account as we may have persisted something in the
     * past that we don't want to retreive anymore. The next
     * {@link #persistState} will remove those values.
     *
     * @returns {Object}
     */
    getPersistedState() {
        let filteredPersistedState = {};
        let persistedState = window.localStorage.getItem(PERSISTED_STATE_NAME);

        if (persistedState) {
            try {
                persistedState = JSON.parse(persistedState);
            } catch (error) {
                logger.error(
                    'Error parsing persisted state',
                    persistedState,
                    error);
                persistedState = {};
            }

            filteredPersistedState
                = this._getFilteredState(persistedState);
        }

        this._checksum = this._calculateChecksum(filteredPersistedState);
        logger.info('redux state rehydrated as', filteredPersistedState);

        return filteredPersistedState;
    }

    /**
     * Initiates a persist operation, but its execution will depend on the
     * current checksums (checks changes).
     *
     * @param {Object} state - The redux state.
     * @returns {void}
     */
    persistState(state: Object) {
        const filteredState = this._getFilteredState(state);
        const newCheckSum = this._calculateChecksum(filteredState);

        if (newCheckSum !== this._checksum) {
            try {
                window.localStorage.setItem(
                    PERSISTED_STATE_NAME,
                    JSON.stringify(filteredState));
                logger.info(
                    `redux state persisted. ${this._checksum} -> ${
                        newCheckSum}`);
                this._checksum = newCheckSum;
            } catch (error) {
                logger.error('Error persisting redux state', error);
            }
        }
    }

    /**
     * Registers a new subtree config to be used for the persistency.
     *
     * @param {string} name - The name of the subtree the config belongs to.
     * @param {ElementConfig} config - The config object, or boolean
     * if the entire subtree needs to be persisted.
     * @returns {void}
     */
    register(name: string, config?: ElementConfig = true) {
        this._elements[name] = config;
    }

    /**
     * Calculates the checksum of the current or the new values of the state.
     *
     * @private
     * @param {Object} filteredState - The filtered/persisted redux state.
     * @returns {string}
     */
    _calculateChecksum(filteredState: Object) {
        try {
            return md5.hex(JSON.stringify(filteredState) || '');
        } catch (error) {
            logger.error(
                'Error calculating checksum for state',
                filteredState,
                error);

            return '';
        }
    }

    /**
     * Prepares a filtered state from the actual or the persisted redux state,
     * based on this registry.
     *
     * @private
     * @param {Object} state - The actual or persisted redux state.
     * @returns {Object}
     */
    _getFilteredState(state: Object) {
        const filteredState = {};

        for (const name of Object.keys(this._elements)) {
            if (state[name]) {
                filteredState[name] = this._getFilteredSubtree(
                    state[name],
                    this._elements[name]);
            }
        }

        return filteredState;
    }

    /**
     * Prepares a filtered subtree based on the config for persisting or for
     * retrieval.
     *
     * @private
     * @param {Object} subtree - The redux state subtree.
     * @param {ElementConfig} subtreeConfig - The related config.
     * @returns {Object}
     */
    _getFilteredSubtree(subtree, subtreeConfig) {
        let filteredSubtree;

        if (subtreeConfig === true) {
            // we persist the entire subtree
            filteredSubtree = subtree;
        } else if (typeof subtreeConfig === 'object') {
            // only a filtered subtree gets persisted, based on the
            // subtreeConfig object.
            filteredSubtree = {};
            for (const persistedKey of Object.keys(subtree)) {
                if (subtreeConfig[persistedKey]) {
                    filteredSubtree[persistedKey] = subtree[persistedKey];
                }
            }
        }

        return filteredSubtree;
    }
}

export default new PersistenceRegistry();
<commit_msg>Split storage keys to features<commit_after>// @flow

import Logger from 'jitsi-meet-logger';
import md5 from 'js-md5';

const logger = Logger.getLogger(__filename);

/**
 * The name of the localStorage store where the app persists its values to.
 */
const PERSISTED_STATE_NAME = 'jitsi-state';

/**
 * Mixed type of the element (subtree) config. If it's a boolean,
 * (and is true) we persist the entire subtree. If it's an object,
 * we perist a filtered subtree based on the properties in the
 * config object.
 */
declare type ElementConfig = Object | boolean;

/**
 * The type of the name-config pairs stored in this reducer.
 */
declare type PersistencyConfigMap = { [name: string]: ElementConfig };

/**
 * A registry to allow features to register their redux store subtree to be
 * persisted and also handles the persistency calls too.
 */
class PersistenceRegistry {
    _checksum: string;

    _elements: PersistencyConfigMap;

    /**
     * Initializes a new {@ code PersistenceRegistry} instance.
     */
    constructor() {
        this._elements = {};
    }

    /**
     * Returns the persisted redux state. This function takes the
     * {@link #_elements} into account as we may have persisted something in the
     * past that we don't want to retreive anymore. The next
     * {@link #persistState} will remove those values.
     *
     * @returns {Object}
     */
    getPersistedState() {
        let filteredPersistedState = {};
        let persistedState = window.localStorage.getItem(PERSISTED_STATE_NAME);

        if (persistedState) {
            // This is the legacy implementation,
            // must be removed in a later version.
            try {
                persistedState = JSON.parse(persistedState);
            } catch (error) {
                logger.error(
                    'Error parsing persisted state',
                    persistedState,
                    error);
                persistedState = {};
            }

            filteredPersistedState
                = this._getFilteredState(persistedState);

            // legacy values must be written to the new store format and
            // old values to be deleted, so then it'll never be used again.
            this.persistState(filteredPersistedState);
            window.localStorage.removeItem(PERSISTED_STATE_NAME);
        } else {
            // new, split-keys implementation
            for (const subtreeName of Object.keys(this._elements)) {
                /*
                 * this assumes that the persisted value is stored under the
                 * same key as the feature's redux state name.
                 * We'll need to introduce functions later that can control
                 * the persist key's name. Similar to control serialization
                 * and deserialization.
                 * But that should be a straightforward change.
                 */
                const persistedSubtree
                    = this._getPersistedSubtree(
                        subtreeName,
                        this._elements[subtreeName]
                    );

                if (persistedSubtree !== undefined) {
                    filteredPersistedState[subtreeName] = persistedSubtree;
                }
            }
        }

        // initialize checksum
        this._checksum = this._calculateChecksum(filteredPersistedState);

        this._checksum = this._calculateChecksum(filteredPersistedState);
        logger.info('redux state rehydrated as', filteredPersistedState);

        return filteredPersistedState;
    }

    /**
     * Initiates a persist operation, but its execution will depend on the
     * current checksums (checks changes).
     *
     * @param {Object} state - The redux state.
     * @returns {void}
     */
    persistState(state: Object) {
        const filteredState = this._getFilteredState(state);
        const newCheckSum = this._calculateChecksum(filteredState);

        if (newCheckSum !== this._checksum) {
            for (const subtreeName of Object.keys(filteredState)) {
                try {
                    window.localStorage.setItem(
                        subtreeName,
                        JSON.stringify(filteredState[subtreeName]));
                } catch (error) {
                    logger.error('Error persisting redux subtree',
                        subtreeName,
                        filteredState[subtreeName],
                        error
                    );
                }
            }
            logger.info(
                `redux state persisted. ${this._checksum} -> ${
                    newCheckSum}`);
            this._checksum = newCheckSum;
        }
    }

    /**
     * Registers a new subtree config to be used for the persistency.
     *
     * @param {string} name - The name of the subtree the config belongs to.
     * @param {ElementConfig} config - The config object, or boolean
     * if the entire subtree needs to be persisted.
     * @returns {void}
     */
    register(name: string, config?: ElementConfig = true) {
        this._elements[name] = config;
    }

    /**
     * Calculates the checksum of the current or the new values of the state.
     *
     * @private
     * @param {Object} filteredState - The filtered/persisted redux state.
     * @returns {string}
     */
    _calculateChecksum(filteredState: Object) {
        try {
            return md5.hex(JSON.stringify(filteredState) || '');
        } catch (error) {
            logger.error(
                'Error calculating checksum for state',
                filteredState,
                error);

            return '';
        }
    }

    /**
     * Retreives a persisted subtree from the storage.
     *
     * @private
     * @param {string} subtreeName - The name of the subtree.
     * @param {Object} subtreeConfig - The config of the subtree
     * from this._elements.
     * @returns {Object}
     */
    _getPersistedSubtree(subtreeName, subtreeConfig) {
        let persistedSubtree = window.localStorage.getItem(subtreeName);

        if (persistedSubtree) {
            try {
                persistedSubtree = JSON.parse(persistedSubtree);
                const filteredSubtree
                    = this._getFilteredSubtree(persistedSubtree, subtreeConfig);

                if (filteredSubtree !== undefined) {
                    return filteredSubtree;
                }
            } catch (error) {
                logger.error(
                    'Error parsing persisted subtree',
                    subtreeName,
                    persistedSubtree,
                    error);
            }
        }

        return null;
    }

    /**
     * Prepares a filtered state from the actual or the persisted redux state,
     * based on this registry.
     *
     * @private
     * @param {Object} state - The actual or persisted redux state.
     * @returns {Object}
     */
    _getFilteredState(state: Object) {
        const filteredState = {};

        for (const name of Object.keys(this._elements)) {
            if (state[name]) {
                filteredState[name] = this._getFilteredSubtree(
                    state[name],
                    this._elements[name]);
            }
        }

        return filteredState;
    }

    /**
     * Prepares a filtered subtree based on the config for persisting or for
     * retrieval.
     *
     * @private
     * @param {Object} subtree - The redux state subtree.
     * @param {ElementConfig} subtreeConfig - The related config.
     * @returns {Object}
     */
    _getFilteredSubtree(subtree, subtreeConfig) {
        let filteredSubtree;

        if (subtreeConfig === true) {
            // we persist the entire subtree
            filteredSubtree = subtree;
        } else if (typeof subtreeConfig === 'object') {
            // only a filtered subtree gets persisted, based on the
            // subtreeConfig object.
            filteredSubtree = {};
            for (const persistedKey of Object.keys(subtree)) {
                if (subtreeConfig[persistedKey]) {
                    filteredSubtree[persistedKey] = subtree[persistedKey];
                }
            }
        }

        return filteredSubtree;
    }
}

export default new PersistenceRegistry();
<|endoftext|>


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

const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('../webpack.config.js');
const devServers = {};

function run(conf) {
  conf = conf || {};
  if (!devServers[conf.index]) {
    const compiler = webpack( config );
    const devServerConfig = {
      publicPath: '/',
      historyApiFallback: true,
      noInfo: true,
      hot: conf.hot || true,
      https: conf.https || false
    };
    devServers[conf.index] = (new WebpackDevServer( compiler, devServerConfig));

    const host = '127.0.0.1';
    const port = conf.port || process.env.PORT || 3100;

    devServers[conf.index].listen( port, host, err => {
      if ( err ) console.log( err );
      console.log(`Listening at ${host}:${port}`);
    });
  } else {
    console.log('You already have a webpack-dev-server for ' + conf.index + ' running.');
  }
}

function stop(index) {
  devServers[index].close();
}

module.exports = {
  run: run,
  stop: stop,
  devServers: devServers
};
<commit_msg>fix path reference to webpack.config<commit_after>/**
* (C) Copyright IBM Corp. 2016. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('../../webpack.config.js');
const devServers = {};

function run(conf) {
  conf = conf || {};
  if (!devServers[conf.index]) {
    const compiler = webpack( config );
    const devServerConfig = {
      publicPath: '/',
      historyApiFallback: true,
      noInfo: true,
      hot: conf.hot || true,
      https: conf.https || false
    };
    devServers[conf.index] = (new WebpackDevServer( compiler, devServerConfig));

    const host = '127.0.0.1';
    const port = conf.port || process.env.PORT || 3100;

    devServers[conf.index].listen( port, host, err => {
      if ( err ) console.log( err );
      console.log(`Listening at ${host}:${port}`);
    });
  } else {
    console.log('You already have a webpack-dev-server for ' + conf.index + ' running.');
  }
}

function stop(index) {
  devServers[index].close();
}

module.exports = {
  run: run,
  stop: stop,
  devServers: devServers
};
<|endoftext|>


<commit_before>'use strict';

const {identity, apply} = require('fantasy-combinators');
const {of, chain} = require('..');

/**

### Monad

1. `m.of(a).chain(f)` is equivalent to `f(a)` (left identity)
2. `m.chain(m.of)` is equivalent to `m` (right identity)

**/

const leftIdentity = t => eq => x => {
    const a = t[of](x)[chain](identity);
    const b = identity(x);
    return eq(a, b);
};

const rightIdentity = t => eq => x => {
    const a = t[of](x)[chain](t[of]);
    const b = t[of](x);
    return eq(a, b);
};

module.exports = { leftIdentity
                 , rightIdentity
                 };<commit_msg>laws/monad: fix leftIdentity (#171)<commit_after>'use strict';

const {of, chain} = require('..');

/**

### Monad

1. `m.of(a).chain(f)` is equivalent to `f(a)` (left identity)
2. `m.chain(m.of)` is equivalent to `m` (right identity)

**/

const leftIdentity = t => eq => x => f => {
    const a = t[of](x)[chain](f);
    const b = f(x);
    return eq(a, b);
};

const rightIdentity = t => eq => x => {
    const a = t[of](x)[chain](t[of]);
    const b = t[of](x);
    return eq(a, b);
};

module.exports = { leftIdentity
                 , rightIdentity
                 };
<|endoftext|>


<commit_before>'use strict';

var kue = require('kue');
var path = require('path');
var _ = require('lodash');
var nodemailer = require('nodemailer');
var smtpPool = require('nodemailer-smtp-pool');
var templatesDir   = path.resolve(__dirname, '../templates');
var emailTemplates = require('email-templates').EmailTemplate;
var db = require(path.resolve('./config/lib/sequelize')).models;
var User = db.user;
//var mg = require('nodemailer-mailgun-transport');
var async = require('async');
var moment = require('moment');

/*var emailQueue = kue.createQueue({
    prefix: 'q',
    redis: {
        port: 9099,
        host: process.env.REDIS_HOST,
        auth: process.env.REDIS_PASSWORD,
        db: process.env.REDIS_DATABASE
    }
});*/

var mailerConfig = _.omit({
    service: process.env.EMAIL_SERVICE,
    auth: _.omit({
        user: process.env.EMAIL_ADDRESS,
        pass: process.env.EMAIL_PASSWORD
    }, _.isUndefined),
    host: process.env.HOST,
    port: process.env.PORT,
    secure: true,
    tls: {
        rejectUnauthorized:false
    }
}, _.isEmpty);

/*var auth = {
    auth: {
        api_key: process.env.MAILGUN_API_KEY,
        domain: process.env.MAILGUN_DOMAIN
    }
};*/

//var nodemailerMailgun = nodemailer.createTransport(mg(auth));
var transporter = nodemailer.createTransport(mailerConfig);
var poolTransporter = nodemailer.createTransport(smtpPool(mailerConfig));

var sendEmail = function(data, done) {

    console.log("IN SEND MAIL FUNCTION");

    if (process.env.TEST_EMAIL === 'true') {
        console.log("\n\n========= ", data.to, " =============", "\n\n============= BEGIN TEST EMAIL CONTENT =============\n\n", data.html,
            '\n\n============= TEXT =============\n\n', data.text, "\n\n============= END TEST EMAIL CONTENT =============\n\n");
        done();
    } else {

        /*nodemailerMailgun.sendMail(data, function(err, info) {
           if(err){
               console.log("ERROR SENDING EMAIL: ", err);
               done(err);
           } else {
               console.log("EMAIL SENT: ", info);
               done(info);
           }
        });*/
        if(data.bulk) {
            poolTransporter.sendMail(data, function(err) {
                console.log("USING POOL TRANSPORTER\n");
                console.log("DATA: ", data);
               if(err) {
                   console.log(err);
               }
                done(err);
            });
        } else {
            transporter.sendMail(data, function(err) {
                console.log("USING REGULAR TRANSPORTER\n");
                console.log("DATA: ", data);
                if(err) {
                    console.log(err);
                }
                done(err);
            });
       }
    }
};

var createEmailJob = function(from, to, subject, template, locals, bulk, cb) {
  var data = {
      from: from,
      to: to,
      subject: subject,
      template: template,
      locals: locals,
      bulk: bulk
  };

    console.log("\n\n===== MAILING LIST =====\n\n");
    console.log(to);
    /*_.each(data.to, function(user) {
        console.log(user);
    });*/

    var renderTemplate = new emailTemplates(path.join(templatesDir, data.template));
    async.each(to, function(email, callback) {
        renderTemplate.render(locals, function(err, results) {
            if(err) {
                console.log("ERR RENDERING TEMPLATE: ", err);
                return cb(err);
            }

            if(results !== null) {
                data.html = results;
                data.to = email;

                /*emailQueue.create('send email', data)
                 .priority('medium')
                 .removeOnComplete(true)
                 .save(function(err) {
                 cb(err);
                 });*/

                sendEmail(data, cb);
                callback();
            }

        }, function (err) {
            cb(err);
        });
   });
};

/*emailQueue.process('send email', 20, function (job, done) {
    sendEmail(job.data, done);
});*/

exports.sendChallengeCreatedNotification = function(req, res) {

    var challenger;
    var challengee;

    /*kue.Job.rangeByState( 'inactive', 0, 50, 'asc', function( err, jobs ) {
        jobs.forEach( function( job ) {
            job.remove( function(){
                console.log( 'removed ', job.id ) ;
            });
        });
    });*/

    User.findById(req.body.challengerUserId).then(function(challengerUserObj) {
        challenger = challengerUserObj;

        User.findById(req.body.challengeeUserId).then(function(challengeeUserObj) {
            challengee = challengeeUserObj;

            var locals = {
                challengerName : challenger.firstName,
                challengedName : challengee.firstName,
                challengeId: req.body.challengeId,
                acceptingUserId: challengee.id,
                timeString: moment(req.body.scheduledTime).format('dddd, MMMM Do [at] h:mmA'),
                subject: "Default Subject"
            };

            var emails = [challengee.email];

            createEmailJob(process.env.EMAIL_FROM, emails, locals.challengerName + " challenged " + " you on gametrunk!", 'challenge-created', locals, true, function(err) {
                if(err) {
                    res.status(400).end(err);
                } else {
                    res.status(200).end();
                }
            });
        });
    });
};

exports.sendChallengeResponseNotification = function(req, res) {

    var challenger;
    var challengee;
    var responseText;
    var summaryText;

    if(req.body.accept === 1) {
        responseText = "accepted";
        summaryText = "You can change the details of this challenge on the My Challenges card on your gametrunk dashboard.";
    } else {
        responseText = "declined";
        summaryText = "You will not play this challenge, but you will be moved up to your opponent's rank by forfeit!";
    }

    User.findById(req.body.challengeObj.challengerUserId).then(function(challengerUserObj) {
        challenger = challengerUserObj;

        User.findById(req.body.challengeObj.challengeeUserId).then(function(challengeeUserObj) {
            challengee = challengeeUserObj;

            var locals = {
                challengeeName : challengee.firstName,
                challengeId: req.body.challengeObj.challengeId,
                timeString: moment(req.body.challengeObj.scheduledTime).format('dddd, MMMM Do [at] h:mmA'),
                responseText: responseText,
                summaryText: summaryText,
                subject: "Default Subject"
            };

            var emails = [challenger.email];

            createEmailJob(process.env.EMAIL_FROM, emails, locals.challengeeName + " " + responseText + " your challenge on Gametrunk!", 'challenge-response', locals, false, function(err) {
                if(err) {
                    res.status(400).end(err);
                } else {
                    res.status(200).end();
                }
            });
        });
    });
};

exports.sendChallengeTimeChangedNotification = function(req, res) {

    var changedTimeUser;
    var otherUser;

    User.findById(req.body.changedTimeUserId).then(function(changedTimeUserObj) {
        changedTimeUser = changedTimeUserObj;

        User.findById(req.body.otherUserId).then(function(otherUserObj) {
            otherUser = otherUserObj;

            var locals = {
                changedTimeName : changedTimeUser.firstName,
                challengeId: req.body.challengObj.id,
                timeString: moment(req.body.challengObj.scheduledTime).format('dddd, MMMM Do [at] h:mmA'),
                subject: "Default Subject"
            };

            var emails = [otherUser.email];

            createEmailJob(process.env.EMAIL_FROM, emails, locals.changedTimeName + " changed the time of your challenge on Gametrunk!", 'challenge-time-changed', locals, false, function(err) {
                if(err) {
                    res.status(400).end(err);
                } else {
                    res.status(200).end();
                }
            });
        });
    });
};
<commit_msg>removed console.log statements<commit_after>'use strict';

var kue = require('kue');
var path = require('path');
var _ = require('lodash');
var nodemailer = require('nodemailer');
var smtpPool = require('nodemailer-smtp-pool');
var templatesDir   = path.resolve(__dirname, '../templates');
var emailTemplates = require('email-templates').EmailTemplate;
var db = require(path.resolve('./config/lib/sequelize')).models;
var User = db.user;
var async = require('async');
var moment = require('moment');

var mailerConfig = _.omit({
    service: process.env.EMAIL_SERVICE,
    auth: _.omit({
        user: process.env.EMAIL_ADDRESS,
        pass: process.env.EMAIL_PASSWORD
    }, _.isUndefined),
    host: process.env.HOST,
    port: process.env.PORT,
    secure: true,
    tls: {
        rejectUnauthorized:false
    }
}, _.isEmpty);

var transporter = nodemailer.createTransport(mailerConfig);
var poolTransporter = nodemailer.createTransport(smtpPool(mailerConfig));

var sendEmail = function(data, done) {

    console.log("IN SEND MAIL FUNCTION");

    if (process.env.TEST_EMAIL === 'true') {
        console.log("\n\n========= ", data.to, " =============", "\n\n============= BEGIN TEST EMAIL CONTENT =============\n\n", data.html,
            '\n\n============= TEXT =============\n\n', data.text, "\n\n============= END TEST EMAIL CONTENT =============\n\n");
        done();
    } else {

        poolTransporter.sendMail(data, function (err) {
            if (err) {
                console.log(err);
            }
            done(err);
        });
    }
};

var createEmailJob = function(from, to, subject, template, locals, bulk, cb) {
  var data = {
      from: from,
      to: to,
      subject: subject,
      template: template,
      locals: locals,
      bulk: bulk
  };

    console.log("\n\n===== MAILING LIST =====\n\n");
    console.log(to);
    /*_.each(data.to, function(user) {
        console.log(user);
    });*/

    var renderTemplate = new emailTemplates(path.join(templatesDir, data.template));
    async.each(to, function(email, callback) {
        renderTemplate.render(locals, function(err, results) {
            if(err) {
                console.log("ERR RENDERING TEMPLATE: ", err);
                return cb(err);
            }

            if(results !== null) {
                data.html = results;
                data.to = email;

                sendEmail(data, cb);
                callback();
            }

        }, function (err) {
            cb(err);
        });
   });
};

exports.sendChallengeCreatedNotification = function(req, res) {

    var challenger;
    var challengee;

    User.findById(req.body.challengerUserId).then(function(challengerUserObj) {
        challenger = challengerUserObj;

        User.findById(req.body.challengeeUserId).then(function(challengeeUserObj) {
            challengee = challengeeUserObj;

            var locals = {
                challengerName : challenger.firstName,
                challengedName : challengee.firstName,
                challengeId: req.body.challengeId,
                acceptingUserId: challengee.id,
                timeString: moment(req.body.scheduledTime).format('dddd, MMMM Do [at] h:mmA'),
                subject: "Default Subject"
            };

            var emails = [challengee.email];

            createEmailJob(process.env.EMAIL_FROM, emails, locals.challengerName + " challenged " + " you on gametrunk!", 'challenge-created', locals, true, function(err) {
                if(err) {
                    res.status(400).end(err);
                } else {
                    res.status(200).end();
                }
            });
        });
    });
};

exports.sendChallengeResponseNotification = function(req, res) {

    var challenger;
    var challengee;
    var responseText;
    var summaryText;

    if(req.body.accept === 1) {
        responseText = "accepted";
        summaryText = "You can change the details of this challenge on the My Challenges card on your gametrunk dashboard.";
    } else {
        responseText = "declined";
        summaryText = "You will not play this challenge, but you will be moved up to your opponent's rank by forfeit!";
    }

    User.findById(req.body.challengeObj.challengerUserId).then(function(challengerUserObj) {
        challenger = challengerUserObj;

        User.findById(req.body.challengeObj.challengeeUserId).then(function(challengeeUserObj) {
            challengee = challengeeUserObj;

            var locals = {
                challengeeName : challengee.firstName,
                challengeId: req.body.challengeObj.challengeId,
                timeString: moment(req.body.challengeObj.scheduledTime).format('dddd, MMMM Do [at] h:mmA'),
                responseText: responseText,
                summaryText: summaryText,
                subject: "Default Subject"
            };

            var emails = [challenger.email];

            createEmailJob(process.env.EMAIL_FROM, emails, locals.challengeeName + " " + responseText + " your challenge on Gametrunk!", 'challenge-response', locals, false, function(err) {
                if(err) {
                    res.status(400).end(err);
                } else {
                    res.status(200).end();
                }
            });
        });
    });
};

exports.sendChallengeTimeChangedNotification = function(req, res) {

    var changedTimeUser;
    var otherUser;

    User.findById(req.body.changedTimeUserId).then(function(changedTimeUserObj) {
        changedTimeUser = changedTimeUserObj;

        User.findById(req.body.otherUserId).then(function(otherUserObj) {
            otherUser = otherUserObj;

            var locals = {
                changedTimeName : changedTimeUser.firstName,
                challengeId: req.body.challengObj.id,
                timeString: moment(req.body.challengObj.scheduledTime).format('dddd, MMMM Do [at] h:mmA'),
                subject: "Default Subject"
            };

            var emails = [otherUser.email];

            createEmailJob(process.env.EMAIL_FROM, emails, locals.changedTimeName + " changed the time of your challenge on Gametrunk!", 'challenge-time-changed', locals, false, function(err) {
                if(err) {
                    res.status(400).end(err);
                } else {
                    res.status(200).end();
                }
            });
        });
    });
};
<|endoftext|>


<commit_before>'use strict';

angular.module('roles')
    .controller('controllerPermissionMatrix', controllerPermissionMatrix)
    .filter('accessHasRole', filterAccessHasRole);

// -----------------------------------------------------------------------------------
//
// CONTROLLER: Permission Matrix
//
// -----------------------------------------------------------------------------------
controllerPermissionMatrix.$inject = ['sRoles', 'rTargetObject', 'rTargetObjectType', '_', '$modalInstance'];
/* @ngInject */
function controllerPermissionMatrix(sRoles, rTargetObject, rTargetObjectType, _, $modalInstance) {
	var permMatrix = this;

	permMatrix.permissions = {}; //rTargetObject.access;
	permMatrix.keys = ['read', 'write', 'watch'];

	_.each(permMatrix.keys, function(key) {
		permMatrix.permissions[key] = [];
	});

	// get system roles
	sRoles.getRoles().then( function(res) {
	 	permMatrix.roles = res.data;
	});

	// on save, pass complete permission structure to the server
	permMatrix.ok = function () {
		$modalInstance.close();
	};
	permMatrix.cancel = function () { $modalInstance.dismiss('cancel'); };

	permMatrix.togglePermission = function(role, key) {
		if (_.indexOf( permMatrix.permissions[key], role ) > -1) {
			// it's here so remove it.
			_.pull(permMatrix.permissions[key], role);
		} else {
			// it's not here, add it.
			permMatrix.permissions[key].push(role);
		}
	};

}
// -----------------------------------------------------------------------------------
//
// FILTER: Has role.
//
// -----------------------------------------------------------------------------------
filterAccessHasRole.$inject = ['_'];
/* @ngInject */
function filterAccessHasRole(_) {
	return function(perms, role, key) {
		return _.indexOf(perms[key], role) > -1;
	}
}<commit_msg>- fixed issue causing build-time jshint failure.<commit_after>'use strict';

angular.module('roles')
    .controller('controllerPermissionMatrix', controllerPermissionMatrix)
    .filter('accessHasRole', filterAccessHasRole);

// -----------------------------------------------------------------------------------
//
// CONTROLLER: Permission Matrix
//
// -----------------------------------------------------------------------------------
controllerPermissionMatrix.$inject = ['sRoles', 'rTargetObject', 'rTargetObjectType', '_', '$modalInstance'];
/* @ngInject */
function controllerPermissionMatrix(sRoles, rTargetObject, rTargetObjectType, _, $modalInstance) {
    var permMatrix = this;

    permMatrix.permissions = {}; //rTargetObject.access;
    permMatrix.keys = ['read', 'write', 'watch'];

    _.each(permMatrix.keys, function (key) {
        permMatrix.permissions[key] = [];
    });

    // get system roles
    sRoles.getRoles().then(function (res) {
        permMatrix.roles = res.data;
    });

    // on save, pass complete permission structure to the server
    permMatrix.ok = function () {
        $modalInstance.close();
    };
    permMatrix.cancel = function () {
        $modalInstance.dismiss('cancel');
    };

    permMatrix.togglePermission = function (role, key) {
        if (_.indexOf(permMatrix.permissions[key], role) > -1) {
            // it's here so remove it.
            _.pull(permMatrix.permissions[key], role);
        } else {
            // it's not here, add it.
            permMatrix.permissions[key].push(role);
        }
    };

}
// -----------------------------------------------------------------------------------
//
// FILTER: Has role.
//
// -----------------------------------------------------------------------------------
filterAccessHasRole.$inject = ['_'];
/* @ngInject */
function filterAccessHasRole(_) {
    return function (perms, role, key) {
        return _.indexOf(perms[key], role) > -1;
    };
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name        YouTube video info button
// @namespace   youtube-video-info-button
// @description Adds a button to youtube pages that, when clicked, will display infomation about YouTube video in Markdown format.
// @include     http://www.youtube.com/watch?*
// @include     https://www.youtube.com/watch?*
// @match       http://www.youtube.com/watch?*
// @match       https://www.youtube.com/watch?*
// @grant       GM_xmlhttpRequest
// @author      Phil
// @license     MIT License
// @updateURL   https://github.com/PhilboBaggins/grease-monkey-scripts/raw/master/youtube-video-info-button.user.js
// @version     1.1
// ==/UserScript==

function parseQuery(query) {
    if (!query)
        return;
    var retVal = {};
    var vars = query.split('&');
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        var key = pair[0];
        retVal[key] = pair[1];
    }
    return retVal;
}

function getVideoData(callback) {
    var query = window.location.search.substring(1);
    var items = parseQuery(query);
    if (items && items.v) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'https://gdata.youtube.com/feeds/api/videos/' + items.v + '?v=2&alt=jsonc',
            onload: function(xhr) {
                var data = JSON.parse(xhr.responseText);
                callback(data);
            }
        });
    }
}

function addButton(video) {
    var markdownData = '# ' + video.data.title
                     + '\n'
                     + '\n* URL: https://www.youtube.com/watch?v=' + video.data.id
                     + '\n* Uploaded: ' + video.data.uploaded
                     + '\n* Updated: ' + video.data.updated
                     + '\n* Uploaded by: [' + video.data.uploader + '](https://www.youtube.com/user/' + video.data.uploader + ')'
                     + '\n'
                     + '\n## Description'
                     + '\n'
                     + '\n' + video.data.description
                     + '\n';

    var videoTitleElm = document.getElementById('eow-title');
    videoTitleElm.innerHTML += '<input id="show-youtube-video-info-button" type="button" value="Show video info" />';

    var button = document.getElementById('show-youtube-video-info-button');
    button.addEventListener('click', function() { alert(markdownData); }, true);
}

window.addEventListener('load', function(e) {
    getVideoData(addButton);
}, false);
<commit_msg>Improve description for youtube-video-info-button.user.js<commit_after>// ==UserScript==
// @name        YouTube video info button
// @namespace   youtube-video-info-button
// @description Adds a button to Youtube video pages that you can click to display infomation about the video in Markdown format.
// @include     http://www.youtube.com/watch?*
// @include     https://www.youtube.com/watch?*
// @match       http://www.youtube.com/watch?*
// @match       https://www.youtube.com/watch?*
// @grant       GM_xmlhttpRequest
// @author      Phil
// @license     MIT License
// @updateURL   https://github.com/PhilboBaggins/grease-monkey-scripts/raw/master/youtube-video-info-button.user.js
// @version     1.1
// ==/UserScript==

function parseQuery(query) {
    if (!query)
        return;
    var retVal = {};
    var vars = query.split('&');
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        var key = pair[0];
        retVal[key] = pair[1];
    }
    return retVal;
}

function getVideoData(callback) {
    var query = window.location.search.substring(1);
    var items = parseQuery(query);
    if (items && items.v) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'https://gdata.youtube.com/feeds/api/videos/' + items.v + '?v=2&alt=jsonc',
            onload: function(xhr) {
                var data = JSON.parse(xhr.responseText);
                callback(data);
            }
        });
    }
}

function addButton(video) {
    var markdownData = '# ' + video.data.title
                     + '\n'
                     + '\n* URL: https://www.youtube.com/watch?v=' + video.data.id
                     + '\n* Uploaded: ' + video.data.uploaded
                     + '\n* Updated: ' + video.data.updated
                     + '\n* Uploaded by: [' + video.data.uploader + '](https://www.youtube.com/user/' + video.data.uploader + ')'
                     + '\n'
                     + '\n## Description'
                     + '\n'
                     + '\n' + video.data.description
                     + '\n';

    var videoTitleElm = document.getElementById('eow-title');
    videoTitleElm.innerHTML += '<input id="show-youtube-video-info-button" type="button" value="Show video info" />';

    var button = document.getElementById('show-youtube-video-info-button');
    button.addEventListener('click', function() { alert(markdownData); }, true);
}

window.addEventListener('load', function(e) {
    getVideoData(addButton);
}, false);
<|endoftext|>