<commit_before>var mainApp = angular.module('myApp');

//start of temporary array
var moduleList = [];

var mod1 = {"moduleCode":"ACC1002","moduleTitle":"Financial Accounting","moduleCredit": "4"};
var mod2 = {"moduleCode":"ACC1002X","moduleTitle":"Financial Accounting","moduleCredit": "4"};
var mod3 = {"moduleCode":"ACC1006","moduleTitle":"Accounting Information Systems","moduleCredit": "4"};
var mod4 = {"moduleCode":"ACC2002","moduleTitle":"Managerial Accounting","moduleCredit": "4"};

moduleList.push(mod1);
moduleList.push(mod2);
moduleList.push(mod3);
moduleList.push(mod4);
//end of temporary array

mainApp.factory('Mapper', ['Module', function(Module) {

  var Mapper = {
  modules : [],
  core : [],
  csBD : [],
  gem : [],
  ue : [],
  totalMC : 0,
  coreMC : 0,
  csBDMC : 0,
  gemMC : 0,
  ueMC : 0,
  message : "",
  };
// init Prereq

	Module.getPrereq().then((data) => {
		//lexical this (comes with the arrow, ES6 function)
		Mapper.prereq = data;
	});

  //Mapper is an object with an attribute modules which is an empty array
  var mods = Mapper.modules; //mods is an array of modules, to count total MCs
  var core = Mapper.core; //core tracks core mods taken
  var csBD = Mapper.csBD; //BD tracks BD mods taken
  var gem = Mapper.gem; //gem tracks gem mods taken
  var ue = Mapper.ue; //ue tracks ue mods taken
  var m = Mapper;

  Mapper.add = (module) => {//add is a method of object Mapper
  	module = JSON.parse(module);
  	var valid = addCheck(module);
  	var addedmc = parseInt(module.moduleCredit);
  	if(valid){
    	mods.push(module);
    	m.totalMC += addedmc;
    	if (isCore(module) && !inCore(module)){ //&& clearedPrereq(module)
    		core.push(module);
    		m.coreMC += addedmc;
    	} else if(isGem(module) && !inGem(module) && m.gemMC < 20 && !samePillar(module)){
    		gem.push(module);
    		m.gemMC += addedmc;
    	} else{
    		ue.push(module);
    		m.ueMC += addedmc;
    		console.log("fku");
    	}
	} else{
		console.log("omginvalid");
	}

	function addCheck(module){	// applies binary or to all filters
		console.log(inCore(module));
		console.log(inMapper(module));
		console.log(isCore(module));
		return inMapper(module);
	}

	function inMapper(module){  // true is valid, false is invalid
		var added = false;
  		for(i = 0; i < mods.length; i++){
	  		if(angular.equals(mods[i],module)){
	  			added = true;
	  		}
  		}
  	return !added;
	}

//START OF CORE MODULES CONDITIONS
	function isCore(module){
		for(i = 0; i < moduleList.length; i++){ //check if it is a core
			if(angular.equals(moduleList[i],module)){
				return true;
			}
		}
		return false;
	}

	function inCore(module){
		for(i = 0; i < core.length; i++){ //check if it has been added to core array yet
			if(angular.equals(core[i],module)){
				return true;
			}
		}
		return false;
	}
//END OF CORE MODULES CONDITIONS

//START OF GEM MODULES CONDITIONS
	function isGem(module){ //check if it is a GEM module
		var str = module.moduleCode;
		if((str.slice(0,3) == "GEH") || (str.slice(0,3) == "GES") || (str.slice(0,3) == "GET") || str.slice(0,3) == "GER" || str.slice(0,2) == "GEQ"){
			return true;
		}
		return false;
	}

	function inGem(module){ //check if already added into GEM module list
		for(i = 0; i < gem.length; i++){
			if(angular.equals(gem[i],module)){
				return true;
			}
		}
		return false;
	}

	function samePillar(module){ //check if same pillar GEM already taken
		var str = module.moduleCode;
		for(i = 0; i < gem.length; i++){
			if(str.slice(0,3) == gem[i].moduleCode.slice(0,3)){
				return true;
			}
		}
		return false;
	}

	function maxGem(module){ //check if already 5 modules worth of GEMs
		if(m.gemMC == 20){
			return true;
		}
		return false;
	}
//END OF GEM MODULES CONDITIONS

//START OF PRE-REQUISITE CONDITIONS
	function clearedPrereq(module){
		var prereq = module.prerequisite; //in prerequisite list
		for(i = 0; i < prereq.length; i++){ //how to retrieve array of prerequisites
			for(j = 0; j < mods.length; j++){
				if(angular.equals(prereq[i],mods[j])){
					return true;
				}
			}
		}
		return false;
	}

	function isPreclu(module){ //check if module has been taken before
		for(i = 0; i < mods.length; i++){
			if(mods[i].preclusion.length > 1){ //how to retrieve array of preclusions
				var preclu = mods[i].preclusion.length;
				for(j = 0; j < preclu; j++){
					if(angular.equals(preclu[j],module)){
						return true;
					}
				}
			}
		}
		return false;
	}

//END OF PRE-REQUISITE CONDITIONS
  }

//REMOVE FUNCTIONS
  Mapper.remove = (index) => {
    var removed = mods.splice(index,1)[0];
    var removedmc = parseInt(removed.moduleCredit);
    for(i = 0; i < core.length; i++){
    	if(angular.equals(core[i], removed)){
    		core.splice(i,1);
    		m.coreMC = m.coreMC - removedmc;
    	}
    }for(i = 0; i < ue.length; i++){
    	if(angular.equals(ue[i], removed)){
    		ue.splice(i,1);
    		m.ueMC = m.ueMC - removedmc;
    	}

    }for(i = 0; i < gem.length; i++){
    	if(angular.equals(gem[i], removed)){
    		gem.splice(i,1);
    		m.gemMC = m.gemMC - removedmc;
    	}
    }
    m.totalMC -= removedmc;
  }
//END OF REMOVE FUNCTIONS

return Mapper;
}]);<commit_msg>added eval fn logic<commit_after>var mainApp = angular.module('myApp');

//start of temporary array
var moduleList = [];

var mod1 = {"moduleCode":"ACC1002","moduleTitle":"Financial Accounting","moduleCredit": "4"};
var mod2 = {"moduleCode":"ACC1002X","moduleTitle":"Financial Accounting","moduleCredit": "4"};
var mod3 = {"moduleCode":"ACC1006","moduleTitle":"Accounting Information Systems","moduleCredit": "4"};
var mod4 = {"moduleCode":"ACC2002","moduleTitle":"Managerial Accounting","moduleCredit": "4"};

moduleList.push(mod1);
moduleList.push(mod2);
moduleList.push(mod3);
moduleList.push(mod4);
//end of temporary array

mainApp.factory('Mapper', ['Module', function(Module) {

  var Mapper = {
  modules : [],
  core : [],
  csBD : [],
  gem : [],
  ue : [],
  totalMC : 0,
  coreMC : 0,
  csBDMC : 0,
  gemMC : 0,
  ueMC : 0,
  message : "",
  };
// init Prereq

	Module.getPrereq().then((data) => {
		//lexical this (comes with the arrow, ES6 function)
		Mapper.prereq = data;
	});

  //Mapper is an object with an attribute modules which is an empty array
  var mods = Mapper.modules; //mods is an array of modules, to count total MCs
  var core = Mapper.core; //core tracks core mods taken
  var csBD = Mapper.csBD; //BD tracks BD mods taken
  var gem = Mapper.gem; //gem tracks gem mods taken
  var ue = Mapper.ue; //ue tracks ue mods taken
  var m = Mapper;

  Mapper.add = (module) => {//add is a method of object Mapper
  	module = JSON.parse(module);
  	var valid = addCheck(module);
  	var addedmc = parseInt(module.moduleCredit);
  	if(valid){
    	mods.push(module);
    	m.totalMC += addedmc;
    	if (isCore(module) && !inCore(module)){ //&& clearedPrereq(module)
    		core.push(module);
    		m.coreMC += addedmc;
    	} else if(isGem(module) && !inGem(module) && m.gemMC < 20 && !samePillar(module)){
    		gem.push(module);
    		m.gemMC += addedmc;
    	} else{
    		ue.push(module);
    		m.ueMC += addedmc;
    		console.log("fku");
    	}
	} else{
		console.log("omginvalid");
	}

	function addCheck(module){	// applies binary or to all filters
		console.log(inCore(module));
		console.log(inMapper(module));
		console.log(isCore(module));
		return inMapper(module);
	}

	function inMapper(module){  // true is valid, false is invalid
		var added = false;
  		for(i = 0; i < mods.length; i++){
	  		if(angular.equals(mods[i],module)){
	  			added = true;
	  		}
  		}
  	return !added;
	}

//START OF CORE MODULES CONDITIONS
	function isCore(module){
		for(i = 0; i < moduleList.length; i++){ //check if it is a core
			if(angular.equals(moduleList[i],module)){
				return true;
			}
		}
		return false;
	}

	function inCore(module){
		for(i = 0; i < core.length; i++){ //check if it has been added to core array yet
			if(angular.equals(core[i],module)){
				return true;
			}
		}
		return false;
	}
//END OF CORE MODULES CONDITIONS

//START OF GEM MODULES CONDITIONS
	function isGem(module){ //check if it is a GEM module
		var str = module.moduleCode;
		if((str.slice(0,3) == "GEH") || (str.slice(0,3) == "GES") || (str.slice(0,3) == "GET") || str.slice(0,3) == "GER" || str.slice(0,2) == "GEQ"){
			return true;
		}
		return false;
	}

	function inGem(module){ //check if already added into GEM module list
		for(i = 0; i < gem.length; i++){
			if(angular.equals(gem[i],module)){
				return true;
			}
		}
		return false;
	}

	function samePillar(module){ //check if same pillar GEM already taken
		var str = module.moduleCode;
		for(i = 0; i < gem.length; i++){
			if(str.slice(0,3) == gem[i].moduleCode.slice(0,3)){
				return true;
			}
		}
		return false;
	}

	function maxGem(module){ //check if already 5 modules worth of GEMs
		if(m.gemMC == 20){
			return true;
		}
		return false;
	}
//END OF GEM MODULES CONDITIONS

//START OF PRE-REQUISITE CONDITIONS
	function clearedPrereq(module){
		var prereq = module.prerequisite; //in prerequisite list
		for(i = 0; i < prereq.length; i++){ //how to retrieve array of prerequisites
			for(j = 0; j < mods.length; j++){
				if(angular.equals(prereq[i],mods[j])){
					return true;
				}
			}
		}
		return false;
	}

	function isPreclu(module){ //check if module has been taken before
		for(i = 0; i < mods.length; i++){
			if(mods[i].preclusion.length > 1){ //how to retrieve array of preclusions
				var preclu = mods[i].preclusion.length;
				for(j = 0; j < preclu; j++){
					if(angular.equals(preclu[j],module)){
						return true;
					}
				}
			}
		}
		return false;
	}
	/*
	Expected input: prerequisite param of module, either a string or a json object
	output: true if module can be added, false if otherwise
	*/
	function eval_hasPrereq(prereq){
		if(angular.isString(prereq)){
			return mods.contains(prereq);  // THIS IS PSEUDOCODE PLEASE A FUNCTION TO CHECK IF PREREQ IS IN MAPPER
		} else if(prereq.or){	//PREREQ IS JSON OBJECT. TYPECHECK TO MAKE SURE IT IS NOT A STRING. IF IT IS STRING. JSONIFY IT
			if(prereq.or.length >1){
				return eval_hasPrereq(prereq.or[0]) || eval_hasPrereq({"or" : prereq.or.splice(0,1)});
			} else{
				return mods.contains(prereq.or[0]);
			}
		} else if(prereq.and){
			if(prereq.and.length >1){
				return eval_hasPrereq(prereq.and[0]) || eval_hasPrereq({"and" : prereq.and.splice(0,1)});
			} else{
				return mods.contains(prereq.and[0]);
			}
		} else{
			alert("error in input");
		}
	}

//END OF PRE-REQUISITE CONDITIONS
  }

//REMOVE FUNCTIONS
  Mapper.remove = (index) => {
    var removed = mods.splice(index,1)[0];
    var removedmc = parseInt(removed.moduleCredit);
    for(i = 0; i < core.length; i++){
    	if(angular.equals(core[i], removed)){
    		core.splice(i,1);
    		m.coreMC = m.coreMC - removedmc;
    	}
    }for(i = 0; i < ue.length; i++){
    	if(angular.equals(ue[i], removed)){
    		ue.splice(i,1);
    		m.ueMC = m.ueMC - removedmc;
    	}

    }for(i = 0; i < gem.length; i++){
    	if(angular.equals(gem[i], removed)){
    		gem.splice(i,1);
    		m.gemMC = m.gemMC - removedmc;
    	}
    }
    m.totalMC -= removedmc;
  }
//END OF REMOVE FUNCTIONS

return Mapper;
}]);<|endoftext|>


<commit_before>'use strict';

var net   = require('net');
var debug = require('debug')('instrumental');

class Instrumental {

  constructor() {
    this.queuedCalls = [];
    this.enabled = false;
  }

  configure(options){
    this.apiKey  = options.apiKey;
    this.enabled = options.enabled === undefined ? true : options.enabled;
    this.host    = options.host || 'collector.instrumentalapp.com';
  }

  connect(){
    debug('Opening Instrumental connection');

    this.socket = net.createConnection({ host: this.host, port: 8000 });
    this.socket.setEncoding('ascii');

    this.socket.on('connect', () => {
      debug('Authenticating Instrumental connection');
      this.socket.write('hello version node/instrumental_agent/0.1\n');
      this.socket.write('authenticate ' + this.apiKey + '\n');
    });

    this.socket.on('error', (err) => {
      debug('Connection Error ' + err);
    });

    this.socket.on('close', (hadError) => {
      debug('Closing Instrumental connection - ' + hadError);
      if (hadError) { this.socket.destroy(); }
      this.socket.removeAllListeners();
      this.connected = false;
      this.socket = null;
      if(this.queuedCalls.length > 0){
        setTimeout(() => { this.connect(); }, 5000);
      }
    });

    this.socket.on('data', (data) => {
      if (data === 'ok\nok\n') {
        debug('Instrumental connected!');
        this.connected = true;
        this.socket.write(this.queuedCalls.join());
        this.queuedCalls = [];
      } else if (data === 'ok\nfail\n') {
        debug('Instrumental authentication failed!');
        this.connected = false;
        this.socket.end();
      }
    });
  }

  apiCall(type, metric, value, time, count){
    if(!this.enabled){ return; }
    if(!time){ time = Date.now(); }
    setImmediate(() => { this.apiCallInner(type, metric, value, time, count); });
  }

  apiCallInner(type, metric, value, time, count){
    if(!metric){
      debug('Metric name required');
      return;
    }

    value = Number(value);
    if(!isFinite(value)){
      debug('Metric value is invalid');
      return;
    }

    if(count === null || count === undefined){ count = 1; }
    count = Number(count);
    if(!isFinite(count)){
      debug('Metric count is invalid');
      return;
    }

    if(!time){ time = Date.now(); }
    time = Math.round(Number(time) / 1000);

    var line = [type, metric, value, time, count].join(' ') + '\n';
    if(this.connected){
      this.socket.write(line);
    } else {
      if(!this.socket){ this.connect(); }
      if(this.queuedCalls.length > 1000){
        debug('Queue too large - dropping metric');
        return;
      }
      this.queuedCalls.push(line);
    }
  }

  increment(metric, value, time, count){
    if(value === 0){ return; }
    if(value === null || value === undefined){ value = 1; }
    this.apiCall('increment', metric, value, time, count);
  }

  gauge(metric, value, time, count){
    this.apiCall('gauge', metric, value, time, count);
  }

}

module.exports = Instrumental;
<commit_msg>never make more than one socket<commit_after>'use strict';

var net   = require('net');
var debug = require('debug')('instrumental');

class Instrumental {

  constructor() {
    this.queuedCalls = [];
    this.enabled = false;
  }

  configure(options){
    this.apiKey  = options.apiKey;
    this.enabled = options.enabled === undefined ? true : options.enabled;
    this.host    = options.host || 'collector.instrumentalapp.com';
  }

  connect(){
    if(this.socket){ return; }

    debug('Opening Instrumental connection');
    this.socket = net.createConnection({ host: this.host, port: 8000 });
    this.socket.setEncoding('ascii');

    this.socket.on('connect', () => {
      debug('Authenticating Instrumental connection');
      this.socket.write('hello version node/instrumental_agent/0.1\n');
      this.socket.write('authenticate ' + this.apiKey + '\n');
    });

    this.socket.on('error', (err) => {
      debug('Connection Error ' + err);
    });

    this.socket.on('close', (hadError) => {
      debug('Closing Instrumental connection - ' + hadError);
      if (hadError) { this.socket.destroy(); }
      this.socket.removeAllListeners();
      this.connected = false;
      this.socket = null;
      if(this.queuedCalls.length > 0){
        setTimeout(() => { this.connect(); }, 5000);
      }
    });

    this.socket.on('data', (data) => {
      if (data === 'ok\nok\n') {
        debug('Instrumental connected!');
        this.connected = true;
        this.socket.write(this.queuedCalls.join());
        this.queuedCalls = [];
      } else if (data === 'ok\nfail\n') {
        debug('Instrumental authentication failed!');
        this.connected = false;
        this.socket.end();
      }
    });
  }

  apiCall(type, metric, value, time, count){
    if(!this.enabled){ return; }
    if(!time){ time = Date.now(); }
    setImmediate(() => { this.apiCallInner(type, metric, value, time, count); });
  }

  apiCallInner(type, metric, value, time, count){
    if(!metric){
      debug('Metric name required');
      return;
    }

    value = Number(value);
    if(!isFinite(value)){
      debug('Metric value is invalid');
      return;
    }

    if(count === null || count === undefined){ count = 1; }
    count = Number(count);
    if(!isFinite(count)){
      debug('Metric count is invalid');
      return;
    }

    if(!time){ time = Date.now(); }
    time = Math.round(Number(time) / 1000);

    var line = [type, metric, value, time, count].join(' ') + '\n';
    if(this.connected){
      this.socket.write(line);
    } else {
      if(!this.socket){ this.connect(); }
      if(this.queuedCalls.length > 1000){
        debug('Queue too large - dropping metric');
        return;
      }
      this.queuedCalls.push(line);
    }
  }

  increment(metric, value, time, count){
    if(value === 0){ return; }
    if(value === null || value === undefined){ value = 1; }
    this.apiCall('increment', metric, value, time, count);
  }

  gauge(metric, value, time, count){
    this.apiCall('gauge', metric, value, time, count);
  }

}

module.exports = Instrumental;
<|endoftext|>


<commit_before>'use strict';

var estraverse = require('estraverse'),
    escodegen = require('escodegen'),
    escallmatch = require('escallmatch'),
    espurify = require('espurify'),
    deepCopy = require('./ast-deepcopy'),
    typeName = require('type-name'),
    syntax = estraverse.Syntax,
    supportedNodeTypes = [
        syntax.Identifier,
        syntax.MemberExpression,
        syntax.CallExpression,
        syntax.UnaryExpression,
        syntax.BinaryExpression,
        syntax.LogicalExpression,
        syntax.AssignmentExpression,
        syntax.ObjectExpression,
        syntax.NewExpression,
        syntax.ArrayExpression,
        syntax.ConditionalExpression,
        syntax.UpdateExpression,
        syntax.Property
    ],
    canonicalCodeOptions = {
        format: {
            indent: {
                style: ''
            },
            newline: ''
        },
        verbatim: 'x-verbatim-espower'
    };

// see: https://github.com/Constellation/escodegen/issues/115
if (typeof define === 'function' && define.amd) {
    escodegen = window.escodegen;
}

function Instrumentor (options) {
    ensureOptionPrerequisites(options);
    this.options = options;
    this.matchers = options.patterns.map(function (pt) { return escallmatch(pt); });
}

Instrumentor.prototype.instrument = function (ast) {
    ensureAstPrerequisites(ast, this.options);
    var that = this,
        assertionPath,
        argumentPath,
        canonicalCode,
        powerAssertCallee,
        lineNum,
        argumentModified = false,
        skipping = false,
        result = (this.options.destructive) ? ast : deepCopy(ast);

    estraverse.replace(result, {
        enter: function (currentNode, parentNode) {
            var controller = this,
                path = controller.path(),
                currentPath = path ? path[path.length - 1] : null;
            //console.log('enter currentNode:' + currentNode.type + ' parentNode: ' + parentNode.type + ' path: ' + path);

            if (argumentPath) {
                if ((!isSupportedNodeType(currentNode)) ||
                    (isLeftHandSideOfAssignment(parentNode, currentPath)) ||
                    (isObjectLiteralKey(parentNode, currentPath)) ||
                    (isUpdateExpression(parentNode)) ||
                    (isCallExpressionWithNonComputedMemberExpression(currentNode, parentNode, currentPath)) ||
                    (isTypeOfOrDeleteUnaryExpression(currentNode, parentNode, currentPath))) {
                    skipping = true;
                    return estraverse.VisitorOption.Skip;
                }
            } else {
                if (!parentNode) {
                    return undefined;
                }
                if (that.matchers.some(function (matcher) { return matcher.test(currentNode); })) {
                    // entering target assertion
                    lineNum = currentNode.loc.start.line;
                    canonicalCode = generateCanonicalCode(currentNode);
                    assertionPath = [].concat(path);
                    powerAssertCallee = guessPowerAssertCalleeFor(currentNode.callee);
                    return undefined;
                }
                if (parentNode.type !== syntax.CallExpression || !isSupportedNodeType(currentNode)) {
                    return undefined;
                }
                if (parentNode.callee === currentNode) {
                    // skip callee
                    return undefined;
                }

                var argumentMatchResults = that.matchers.map(function (matcher) {
                    return matcher.matchArgument(currentNode, parentNode);
                }).filter(function (result) {
                    return result !== null;
                });
                if (argumentMatchResults.length === 1) {
                    if (argumentMatchResults[0].name === 'message' && argumentMatchResults[0].kind === 'optional') {
                        // skip optional message argument
                        return undefined;
                    }
                    // entering target argument
                    argumentPath = [].concat(path);
                    return undefined;
                }
            }
            return undefined;
        },

        leave: function (currentNode, parentNode) {
            var controller = this,
                path = controller.path(),
                resultTree = currentNode,
                relativeEsPath;
            //console.log('leave ' + currentNode.type + ' path: ' + path);

            if (skipping) {
                skipping = false;
                return undefined;
            }

            if (isPathIdentical(assertionPath, path)) {
                // leaving target assertion
                canonicalCode = null;
                lineNum = null;
                assertionPath = null;
                powerAssertCallee = null;
                return undefined;
            }

            if (!argumentPath) {
                return undefined;
            }

            if (isLastPieceOfFunctionCall(parentNode, currentNode)) {
                return undefined;
            }

            relativeEsPath = path.slice(assertionPath.length);

            //console.log('leave ' + currentNode.type + ' path: ' + path + ' ' + currentNode.name);
            switch(currentNode.type) {
            case syntax.Identifier:
            case syntax.MemberExpression:
            case syntax.CallExpression:
            case syntax.UnaryExpression:
            case syntax.BinaryExpression:
            case syntax.LogicalExpression:
            case syntax.AssignmentExpression:
            case syntax.UpdateExpression:
            case syntax.NewExpression:
                resultTree = that.captureNode(currentNode, relativeEsPath, powerAssertCallee);
                argumentModified = true;
                break;
            default:
                break;
            }

            if (isPathIdentical(argumentPath, path)) {
                // leaving target argument
                argumentPath = null;
                if (argumentModified) {
                    argumentModified = false;
                    return that.captureArgument(resultTree, canonicalCode, powerAssertCallee, lineNum);
                }
            }

            return resultTree;
        }
    });
    return result;
};

Instrumentor.prototype.captureArgument = function (node, canonicalCode, powerAssertCallee, lineNum) {
    var n = newNodeWithLocationCopyOf(node),
        props = [],
        newCallee = updateLocRecursively(espurify(powerAssertCallee), n);
    addLiteralTo(props, n, 'content', canonicalCode);
    addLiteralTo(props, n, 'filepath', this.options.path);
    addLiteralTo(props, n, 'line', lineNum);
    return n({
        type: syntax.CallExpression,
        callee: n({
            type: syntax.MemberExpression,
            computed: false,
            object: newCallee,
            property: n({
                type: syntax.Identifier,
                name: '_expr'
            })
        }),
        arguments: [node].concat(n({
            type: syntax.ObjectExpression,
            properties: props
        }))
    });
};

Instrumentor.prototype.captureNode = function (target, relativeEsPath, powerAssertCallee) {
    var n = newNodeWithLocationCopyOf(target),
        newCallee = updateLocRecursively(espurify(powerAssertCallee), n);
    return n({
        type: syntax.CallExpression,
        callee: n({
            type: syntax.MemberExpression,
            computed: false,
            object: newCallee,
            property: n({
                type: syntax.Identifier,
                name: '_capt'
            })
        }),
        arguments: [
            target,
            n({
                type: syntax.Literal,
                value: relativeEsPath.join('/')
            })
        ]
    });
};

function updateLocRecursively (node, n) {
    estraverse.replace(node, {
        leave: function (currentNode, parentNode) {
            return n(currentNode);
        }
    });
    return node;
}

function guessPowerAssertCalleeFor (node) {
    switch(node.type) {
    case syntax.Identifier:
        return node;
    case syntax.MemberExpression:
        return node.object; // Returns browser.assert when browser.assert.element(selector)
    }
    return null;
}

function generateCanonicalCode(node) {
    var ast = deepCopy(node);
    estraverse.replace(ast, {
        leave: function (currentNode, parentNode) {
            if (currentNode.type === syntax.Literal && typeof currentNode.raw !== 'undefined') {
                currentNode['x-verbatim-espower'] = {
                    content : currentNode.raw,
                    precedence : escodegen.Precedence.Primary
                };
                return currentNode;
            } else {
                return undefined;
            }
        }
    });
    return escodegen.generate(ast, canonicalCodeOptions);
}

function addLiteralTo(props, createNode, name, data) {
    if (data) {
        addToProps(props, createNode, name, createNode({
            type: syntax.Literal,
            value: data
        }));
    }
}

function addToProps(props, createNode, name, value) {
    props.push(createNode({
        type: syntax.Property,
        key: createNode({
            type: syntax.Identifier,
            name: name
        }),
        value: value,
        kind: 'init'
    }));
}

function isLastPieceOfFunctionCall(parentNode, currentNode) {
    return (parentNode.type === syntax.CallExpression || parentNode.type === syntax.NewExpression) &&
        parentNode.callee === currentNode;
}

function isLeftHandSideOfAssignment(parentNode, currentPath) {
    // Do not instrument left due to 'Invalid left-hand side in assignment'
    return parentNode.type === syntax.AssignmentExpression && currentPath === 'left';
}

function isObjectLiteralKey(parentNode, currentPath) {
    // Do not instrument Object literal key
    return parentNode.type === syntax.Property && parentNode.kind === 'init' && currentPath === 'key';
}

function isUpdateExpression(parentNode) {
    // Just wrap UpdateExpression, not digging in.
    return parentNode.type === syntax.UpdateExpression;
}

function isCallExpressionWithNonComputedMemberExpression(currentNode, parentNode, currentPath) {
    // Do not instrument non-computed property of MemberExpression within CallExpression.
    return currentNode.type === syntax.Identifier && parentNode.type === syntax.MemberExpression && !parentNode.computed && currentPath === 'property';
}

function isTypeOfOrDeleteUnaryExpression(currentNode, parentNode, currentPath) {
    // 'typeof Identifier' or 'delete Identifier' is not instrumented
    return currentNode.type === syntax.Identifier && parentNode.type === syntax.UnaryExpression && (parentNode.operator === 'typeof' || parentNode.operator === 'delete') && currentPath === 'argument';
}

function isPathIdentical(path1, path2) {
    if (!path1 || !path2) {
        return false;
    }
    return path1.join('/') === path2.join('/');
}

function newNodeWithLocationCopyOf (original) {
    return function (newNode) {
        if (typeof original.loc !== 'undefined') {
            newNode.loc = deepCopy(original.loc);
        }
        if (typeof original.range !== 'undefined') {
            newNode.range = deepCopy(original.range);
        }
        return newNode;
    };
}

function isSupportedNodeType (node) {
    return supportedNodeTypes.indexOf(node.type) !== -1;
}

function ensureAstPrerequisites (ast, options) {
    var errorMessage;
    if (typeof ast.loc === 'undefined') {
        errorMessage = 'JavaScript AST should contain location information.';
        if (options.path) {
            errorMessage += ' path: ' + options.path;
        }
        throw new Error(errorMessage);
    }
}

function ensureOptionPrerequisites (options) {
    if (typeName(options.destructive) !== 'boolean') {
        throw new Error('options.destructive should be a boolean value.');
    }
    if (typeName(options.patterns) !== 'Array') {
        throw new Error('options.patterns should be an array.');
    }
}

module.exports = Instrumentor;
<commit_msg>refactor(espower): seeking for better name<commit_after>'use strict';

var estraverse = require('estraverse'),
    escodegen = require('escodegen'),
    escallmatch = require('escallmatch'),
    espurify = require('espurify'),
    deepCopy = require('./ast-deepcopy'),
    typeName = require('type-name'),
    syntax = estraverse.Syntax,
    supportedNodeTypes = [
        syntax.Identifier,
        syntax.MemberExpression,
        syntax.CallExpression,
        syntax.UnaryExpression,
        syntax.BinaryExpression,
        syntax.LogicalExpression,
        syntax.AssignmentExpression,
        syntax.ObjectExpression,
        syntax.NewExpression,
        syntax.ArrayExpression,
        syntax.ConditionalExpression,
        syntax.UpdateExpression,
        syntax.Property
    ],
    canonicalCodeOptions = {
        format: {
            indent: {
                style: ''
            },
            newline: ''
        },
        verbatim: 'x-verbatim-espower'
    };

// see: https://github.com/Constellation/escodegen/issues/115
if (typeof define === 'function' && define.amd) {
    escodegen = window.escodegen;
}

function Instrumentor (options) {
    ensureOptionPrerequisites(options);
    this.options = options;
    this.matchers = options.patterns.map(function (pt) { return escallmatch(pt); });
}

Instrumentor.prototype.instrument = function (ast) {
    ensureAstPrerequisites(ast, this.options);
    var that = this,
        assertionPath,
        argumentPath,
        canonicalCode,
        powerAssertCallee,
        lineNum,
        argumentModified = false,
        skipping = false,
        result = (this.options.destructive) ? ast : deepCopy(ast);

    estraverse.replace(result, {
        enter: function (currentNode, parentNode) {
            var controller = this,
                path = controller.path(),
                currentPath = path ? path[path.length - 1] : null;
            //console.log('enter currentNode:' + currentNode.type + ' parentNode: ' + parentNode.type + ' path: ' + path);

            if (argumentPath) {
                if ((!isSupportedNodeType(currentNode)) ||
                    (isLeftHandSideOfAssignment(parentNode, currentPath)) ||
                    (isObjectLiteralKey(parentNode, currentPath)) ||
                    (isUpdateExpression(parentNode)) ||
                    (isCallExpressionWithNonComputedMemberExpression(currentNode, parentNode, currentPath)) ||
                    (isTypeOfOrDeleteUnaryExpression(currentNode, parentNode, currentPath))) {
                    skipping = true;
                    return estraverse.VisitorOption.Skip;
                }
            } else {
                if (!parentNode) {
                    return undefined;
                }
                if (that.matchers.some(function (matcher) { return matcher.test(currentNode); })) {
                    // entering target assertion
                    lineNum = currentNode.loc.start.line;
                    canonicalCode = generateCanonicalCode(currentNode);
                    assertionPath = [].concat(path);
                    powerAssertCallee = guessPowerAssertCalleeFor(currentNode.callee);
                    return undefined;
                }
                if (parentNode.type !== syntax.CallExpression || !isSupportedNodeType(currentNode)) {
                    return undefined;
                }
                if (parentNode.callee === currentNode) {
                    // skip callee
                    return undefined;
                }

                var argumentMatchResults = that.matchers.map(function (matcher) {
                    return matcher.matchArgument(currentNode, parentNode);
                }).filter(function (result) {
                    return result !== null;
                });
                if (argumentMatchResults.length === 1) {
                    if (argumentMatchResults[0].name === 'message' && argumentMatchResults[0].kind === 'optional') {
                        // skip optional message argument
                        return undefined;
                    }
                    // entering target argument
                    argumentPath = [].concat(path);
                    return undefined;
                }
            }
            return undefined;
        },

        leave: function (currentNode, parentNode) {
            var controller = this,
                path = controller.path(),
                resultTree = currentNode,
                relativeEsPath;
            //console.log('leave ' + currentNode.type + ' path: ' + path);

            if (skipping) {
                skipping = false;
                return undefined;
            }

            if (isPathIdentical(assertionPath, path)) {
                // leaving target assertion
                canonicalCode = null;
                lineNum = null;
                assertionPath = null;
                powerAssertCallee = null;
                return undefined;
            }

            if (!argumentPath) {
                return undefined;
            }

            if (isCalleeOfParent(currentNode, parentNode)) {
                return undefined;
            }

            relativeEsPath = path.slice(assertionPath.length);

            //console.log('leave ' + currentNode.type + ' path: ' + path + ' ' + currentNode.name);
            switch(currentNode.type) {
            case syntax.Identifier:
            case syntax.MemberExpression:
            case syntax.CallExpression:
            case syntax.UnaryExpression:
            case syntax.BinaryExpression:
            case syntax.LogicalExpression:
            case syntax.AssignmentExpression:
            case syntax.UpdateExpression:
            case syntax.NewExpression:
                resultTree = that.captureNode(currentNode, relativeEsPath, powerAssertCallee);
                argumentModified = true;
                break;
            default:
                break;
            }

            if (isPathIdentical(argumentPath, path)) {
                // leaving target argument
                argumentPath = null;
                if (argumentModified) {
                    argumentModified = false;
                    return that.captureArgument(resultTree, canonicalCode, powerAssertCallee, lineNum);
                }
            }

            return resultTree;
        }
    });
    return result;
};

Instrumentor.prototype.captureArgument = function (node, canonicalCode, powerAssertCallee, lineNum) {
    var n = newNodeWithLocationCopyOf(node),
        props = [],
        newCallee = updateLocRecursively(espurify(powerAssertCallee), n);
    addLiteralTo(props, n, 'content', canonicalCode);
    addLiteralTo(props, n, 'filepath', this.options.path);
    addLiteralTo(props, n, 'line', lineNum);
    return n({
        type: syntax.CallExpression,
        callee: n({
            type: syntax.MemberExpression,
            computed: false,
            object: newCallee,
            property: n({
                type: syntax.Identifier,
                name: '_expr'
            })
        }),
        arguments: [node].concat(n({
            type: syntax.ObjectExpression,
            properties: props
        }))
    });
};

Instrumentor.prototype.captureNode = function (target, relativeEsPath, powerAssertCallee) {
    var n = newNodeWithLocationCopyOf(target),
        newCallee = updateLocRecursively(espurify(powerAssertCallee), n);
    return n({
        type: syntax.CallExpression,
        callee: n({
            type: syntax.MemberExpression,
            computed: false,
            object: newCallee,
            property: n({
                type: syntax.Identifier,
                name: '_capt'
            })
        }),
        arguments: [
            target,
            n({
                type: syntax.Literal,
                value: relativeEsPath.join('/')
            })
        ]
    });
};

function updateLocRecursively (node, n) {
    estraverse.replace(node, {
        leave: function (currentNode, parentNode) {
            return n(currentNode);
        }
    });
    return node;
}

function guessPowerAssertCalleeFor (node) {
    switch(node.type) {
    case syntax.Identifier:
        return node;
    case syntax.MemberExpression:
        return node.object; // Returns browser.assert when browser.assert.element(selector)
    }
    return null;
}

function generateCanonicalCode(node) {
    var ast = deepCopy(node);
    estraverse.replace(ast, {
        leave: function (currentNode, parentNode) {
            if (currentNode.type === syntax.Literal && typeof currentNode.raw !== 'undefined') {
                currentNode['x-verbatim-espower'] = {
                    content : currentNode.raw,
                    precedence : escodegen.Precedence.Primary
                };
                return currentNode;
            } else {
                return undefined;
            }
        }
    });
    return escodegen.generate(ast, canonicalCodeOptions);
}

function addLiteralTo(props, createNode, name, data) {
    if (data) {
        addToProps(props, createNode, name, createNode({
            type: syntax.Literal,
            value: data
        }));
    }
}

function addToProps(props, createNode, name, value) {
    props.push(createNode({
        type: syntax.Property,
        key: createNode({
            type: syntax.Identifier,
            name: name
        }),
        value: value,
        kind: 'init'
    }));
}

function isCalleeOfParent(currentNode, parentNode) {
    return (parentNode.type === syntax.CallExpression || parentNode.type === syntax.NewExpression) &&
        parentNode.callee === currentNode;
}

function isLeftHandSideOfAssignment(parentNode, currentPath) {
    // Do not instrument left due to 'Invalid left-hand side in assignment'
    return parentNode.type === syntax.AssignmentExpression && currentPath === 'left';
}

function isObjectLiteralKey(parentNode, currentPath) {
    // Do not instrument Object literal key
    return parentNode.type === syntax.Property && parentNode.kind === 'init' && currentPath === 'key';
}

function isUpdateExpression(parentNode) {
    // Just wrap UpdateExpression, not digging in.
    return parentNode.type === syntax.UpdateExpression;
}

function isCallExpressionWithNonComputedMemberExpression(currentNode, parentNode, currentPath) {
    // Do not instrument non-computed property of MemberExpression within CallExpression.
    return currentNode.type === syntax.Identifier && parentNode.type === syntax.MemberExpression && !parentNode.computed && currentPath === 'property';
}

function isTypeOfOrDeleteUnaryExpression(currentNode, parentNode, currentPath) {
    // 'typeof Identifier' or 'delete Identifier' is not instrumented
    return currentNode.type === syntax.Identifier && parentNode.type === syntax.UnaryExpression && (parentNode.operator === 'typeof' || parentNode.operator === 'delete') && currentPath === 'argument';
}

function isPathIdentical(path1, path2) {
    if (!path1 || !path2) {
        return false;
    }
    return path1.join('/') === path2.join('/');
}

function newNodeWithLocationCopyOf (original) {
    return function (newNode) {
        if (typeof original.loc !== 'undefined') {
            newNode.loc = deepCopy(original.loc);
        }
        if (typeof original.range !== 'undefined') {
            newNode.range = deepCopy(original.range);
        }
        return newNode;
    };
}

function isSupportedNodeType (node) {
    return supportedNodeTypes.indexOf(node.type) !== -1;
}

function ensureAstPrerequisites (ast, options) {
    var errorMessage;
    if (typeof ast.loc === 'undefined') {
        errorMessage = 'JavaScript AST should contain location information.';
        if (options.path) {
            errorMessage += ' path: ' + options.path;
        }
        throw new Error(errorMessage);
    }
}

function ensureOptionPrerequisites (options) {
    if (typeName(options.destructive) !== 'boolean') {
        throw new Error('options.destructive should be a boolean value.');
    }
    if (typeName(options.patterns) !== 'Array') {
        throw new Error('options.patterns should be an array.');
    }
}

module.exports = Instrumentor;
<|endoftext|>


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

var table = db.table('issuer', {

});

exports = module.exports = table;
<commit_msg>Consistent table naming for issuer model<commit_after>var db = require('../lib/db');

var table = db.table('issuers', {

});

exports = module.exports = table;
<|endoftext|>


<commit_before>/**
 * @author patcla
 */
var DEBUG = false,
	TEST = false, // not used for Jasmine testing, used for off line development
	TEST_USE_FILTERID = false;
var DEFAULT_VALUES = {
	"timeout": 200000 // 20 seconds
	,"AllowNotifications" : "false"
	,"PopupReverseOrder": "false"
	,"DifferentiateApproved": "true"
	,"URL":"http://stash.my-domain.com/"
	,"API":"/rest/inbox/latest/pull-requests?role=reviewer&limit=20"
	,"AuthorAPI":"/rest/inbox/latest/pull-requests?role=author&limit=20"
	,"AuthorTabEnabled": "true"
	,"PopupTitle":"Ready for Review"
	,"PopupTemplate":'{{#stash}}'+
'\n'+
'\n	 {{date createdDate}} {{title}}'+
'\n
'+
'\n
{{title}}
'+
'\n
Created by: {{author.user.displayName}}. Comments: {{attributes.commentCount}}
'+
'\n
{{description}}
'+
'\n
'+
'\n
Reviewers:
 '+
'\n			{{#reviewers}}'+
'\n				{{user.displayName}}'+
'\n			{{/reviewers}}'+
'\n
'+
'\n
'+
'\n
Participants:
 '+
'\n			{{#participants}}'+
'\n				{{user.displayName}}
'+
'\n			{{/participants}}'+
'\n
'+
'\n
'+
'\n'+
'\n{{/stash}}'
	,"PopupDateformat":"d MMM"
    ,"RefreshTime":60
	,"StashCSS": "/* to style previously approved PRs use html[data-previously-approved='true']{...} */"+
"\nhtml[stash-pull-request-notifier] .previously-approved-counter {"+
"\n		margin-left: 6px;"+
"\n}"+
"\nhtml[stash-pull-request-notifier] .previously-approved-counter::before {"+
"\n		content: attr(data-counter);"+
"\n}"+
"\nhtml[stash-pull-request-notifier][data-previously-approved='true'] .aui-page-panel {"+
"\n		background-color: #ffe;"+
"\n}"
	,"StashJS": "console.log( 'Hello from stash pull request extension, typeof zepto = ', typeof($) );"
	,"InsertCSS": "false"
	,"TESTVALUE":"ABC"
};
var HELP = {
	"timeout": 'Length of time to wait before assuming the connection has failed'
	,"AllowNotifications": 'Allow popup notifications (can be very irritating)'
	,"DifferentiateApproved": 'Visually differentiate items that have been approved by anyone'
	,"URL":'Your STASH URL e.g. http://stash.my-domain.com/'
	,"API":'Relative path e.g. /rest/inbox/latest/pull-requests?role=reviewer&limit=10
role - must be one of [AUTHOR, REVIEWER, PARTICIPANT]
limit - max number of results'
	,"PopupTitle":'Title of the filter to show in the extension popup'
	,"PopupTitleLink": 'Optional, link for the title text on the popup, from the Stash URL, e.g. /projects/MYREPOS/repos/MYPROJECT/pull-requests'
	,"PopupTemplate":'HTML template used for each ticket by the extension popup (mustache format) view stash item json'
	,"PopupDateformat": 'Date format used by the mustache template, see datejs wiki for supported formats. Example usage {{date createdDate}}'
	,"RefreshTime":'Frequency to check server for changes (in seconds)'
	,"PopupReverseOrder":'Reverse the display order (default is newest first)'
	,"AuthorTabEnabled": 'Show pull requests you created in the popup'
	,"StashCSS": 'Optional CSS to inject into Stash pull request page'
	,"StashJS": 'Optional JS to inject into Stash pull request page'
	,"InsertCSS": 'Insert CSS into Stash (e.g. to distinguish previously approved pull requests)'
}
<commit_msg>Update constants.js<commit_after>/**
 * @author patcla
 */
var DEBUG = false,
	TEST = false, // not used for Jasmine testing, used for off line development
	TEST_USE_FILTERID = false;
var DEFAULT_VALUES = {
	"timeout": 200000 // 20 seconds
	,"AllowNotifications" : "false"
	,"PopupReverseOrder": "false"
	,"DifferentiateApproved": "true"
	,"URL":"http://stash.my-domain.com/"
	,"API":"/rest/api/latest/inbox/pull-requests?role=reviewer&limit=20"
	,"AuthorAPI":"/rest/api/latest/inbox/pull-requests?role=author&limit=20"
	,"AuthorTabEnabled": "true"
	,"PopupTitle":"Ready for Review"
	,"PopupTemplate":'{{#stash}}'+
'\n'+
'\n	 {{date createdDate}} {{title}}'+
'\n
'+
'\n
{{title}}
'+
'\n
Created by: {{author.user.displayName}}. Comments: {{attributes.commentCount}}
'+
'\n
{{description}}
'+
'\n
'+
'\n
Reviewers:
 '+
'\n			{{#reviewers}}'+
'\n				{{user.displayName}}'+
'\n			{{/reviewers}}'+
'\n
'+
'\n
'+
'\n
Participants:
 '+
'\n			{{#participants}}'+
'\n				{{user.displayName}}
'+
'\n			{{/participants}}'+
'\n
'+
'\n
'+
'\n'+
'\n{{/stash}}'
	,"PopupDateformat":"d MMM"
    ,"RefreshTime":60
	,"StashCSS": "/* to style previously approved PRs use html[data-previously-approved='true']{...} */"+
"\nhtml[stash-pull-request-notifier] .previously-approved-counter {"+
"\n		margin-left: 6px;"+
"\n}"+
"\nhtml[stash-pull-request-notifier] .previously-approved-counter::before {"+
"\n		content: attr(data-counter);"+
"\n}"+
"\nhtml[stash-pull-request-notifier][data-previously-approved='true'] .aui-page-panel {"+
"\n		background-color: #ffe;"+
"\n}"
	,"StashJS": "console.log( 'Hello from stash pull request extension, typeof zepto = ', typeof($) );"
	,"InsertCSS": "false"
	,"TESTVALUE":"ABC"
};
var HELP = {
	"timeout": 'Length of time to wait before assuming the connection has failed'
	,"AllowNotifications": 'Allow popup notifications (can be very irritating)'
	,"DifferentiateApproved": 'Visually differentiate items that have been approved by anyone'
	,"URL":'Your STASH URL e.g. http://stash.my-domain.com/'
	,"API":'Relative path e.g. /rest/api/latest/inbox/pull-requests?role=reviewer&limit=10
role - must be one of [AUTHOR, REVIEWER, PARTICIPANT]
limit - max number of results'
	,"PopupTitle":'Title of the filter to show in the extension popup'
	,"PopupTitleLink": 'Optional, link for the title text on the popup, from the Stash URL, e.g. /projects/MYREPOS/repos/MYPROJECT/pull-requests'
	,"PopupTemplate":'HTML template used for each ticket by the extension popup (mustache format) view stash item json'
	,"PopupDateformat": 'Date format used by the mustache template, see datejs wiki for supported formats. Example usage {{date createdDate}}'
	,"RefreshTime":'Frequency to check server for changes (in seconds)'
	,"PopupReverseOrder":'Reverse the display order (default is newest first)'
	,"AuthorTabEnabled": 'Show pull requests you created in the popup'
	,"StashCSS": 'Optional CSS to inject into Stash pull request page'
	,"StashJS": 'Optional JS to inject into Stash pull request page'
	,"InsertCSS": 'Insert CSS into Stash (e.g. to distinguish previously approved pull requests)'
}
<|endoftext|>


<commit_before>import DS from 'ember-data';

var Prompt = DS.Model.extend({
  blanks: DS.hasMany('blank'),  //e.g. we collect info about your _blank_
  response: DS.attr('string'), //what going in the blank, e.g. "location"
  stepNumber: DS.attr('integer')
});

export default Prompt;
<commit_msg>added fixtures for prompts<commit_after>import DS from 'ember-data';

var Prompt = DS.Model.extend({
  content: DS.attr('string'),
  blanks: DS.hasMany('blank'),  //e.g. we collect info about your _blank_
  response: DS.attr('string'), //what going in the blank, e.g. "location"
  step: DS.attr('integer')
});

Prompt.reopenClass({
  FIXTURES: [
  {'id': 1, 'step': 1, 'content': 'My business is called'}
  ]
});

export default Prompt;
<|endoftext|>


<commit_before>var later = require(".."),
    forward = require("event-emitter-forward"),
    EventEmitter = require("events").EventEmitter,
    Promise = require("es6-promise").Promise,
    https = require("https"),
    http = require("http"),
    fs = require("fs"),
    express = require("express"),
    prop = require("propertize"),
    resolve = require("path").resolve,
    cat = require("concat-stream"),
    request = require("request");

// ensure color support enabled
require("colors");

/**
 * HTTP later server object.
 * @constructor
 * @augments {EventEmitter}
 * @param {LaterStorage} storage
 */
function LaterServer(storage) {
    EventEmitter.call(this);

    prop.internal(this, "servers", []);
    prop.internal(this, "storage", storage);

    /**
     * @name LaterServer#express
     * @type {function}
     * @readonly
     */
    prop.readonly(this, "express", express());

    // forward Express app events to this object
    forward("connection", this.express, this);
    forward("error", this.express, this);
    forward("request", this.express, this);
    forward("checkContinue", this.express, this);
    forward("connect", this.express, this);
    forward("upgrade", this.express, this);
    forward("clientError", this.express, this);

    // setup Express app
    this.express.all("*", this.createMiddleware());
}

LaterServer.prototype = Object.create(EventEmitter.prototype);
LaterServer.prototype.constructor = LaterServer;

/**
 * Create a server object.
 * @param {LaterStorage} storage
 */
LaterServer.create = function(storage) {
    return new LaterServer(storage);
};

/**
 * Return true if the request method is allowed.
 * @param {http.IncomingMessage} req
 * @param {object} req.later
 * @param {string} [req.later.method]
 * @param {string} [req.later.methods]
 * @returns {boolean}
 */
LaterServer.prototype.methodAllowed = function(req) {
    var methods;

    if (req.later.methods) methods = req.later.methods.split(":");
    else if (req.later.method) methods = [req.later.method];

    if (methods) return methods.indexOf(req.method) >= 0;
    return true;
};

/**
 * Return true if the request path is acceptable.
 * @param {http.IncomingMessage} req
 * @param {object} req.later
 * @param {string} [req.later.path]
 * @param {string} [req.later.paths]
 * @returns {boolean}
 */
LaterServer.prototype.pathAcceptable = function(req) {
    var paths;

    if (req.later.paths) paths = req.later.paths.split(":");
    else if (req.later.path) paths = [req.later.path];

    if (paths) return paths.some(function(path) {
        return req.path.substr(0, path.length) === path;
    });

    return true;
};

/**
 * Begin replaying queued requests.
 */
LaterServer.prototype.replay = function() {
    var later = this,
        storage = this.storage,
        unqueued = 0,
        backoff = [1,1];

    this.emit("replay");

    function replay() {
        storage.unqueue(function(err, req) {
            var delay;

            if (err) {
                later.emit("error", err.message);
            } else if (req) {
                later.deserialize(req).then(function(res) {
                    later.emit("response", res, req);
                }).catch(function(err) {
                    later.emit("error", err.message);
                });

                unqueued++;
                replay();
            } else {
                later.emit("drain");

                // if requests were unqueued, restart replay
                if (unqueued) later.replay();

                // if there were no requests, apply backoff
                else {
                    later.emit("backoff");
                    backoff.push(backoff[0] + backoff[1]);
                    backoff.shift();
                    delay = backoff[1];
                    setTimeout(replay, delay);
                }
            }
        });
    }

    // initiate replay
    setTimeout(replay, 0);
};

/**
 * Begin accepting requests into queue.
 * @param {object} opts
 * @param {string} [opts.host]      virtual host to accept
 * @param {number} [opts.port]      listen port (if not default)
 * @param {string} [opts.path]      path prefix to handle; 404 on rest
 * @param {object} [opts.tls]       TLS options; https defaults to port 443
 * @param {string} [opts.tls.pfx]   path to key-pair/ca file
 * @param {string} [opts.tls.cert]  path of TLS cert file
 * @param {string} [opts.tls.key]   path of TLS private key file
 * @param {string} [opts.tls.ca]    path of TLS CA cert file
 */
LaterServer.prototype.accept = function(opts) {
    var later = this,
        name,
        host, port,
        server;

    // wrap Express listener so req is decorated with accept opts
    function option(opts, listener) {
        return function(req, res, next) {
            req.later = opts;
            return listener(req, res, next);
        };
    }

    // read in any TLS files
    if (opts.tls) {
        for (name in opts.tls) {
            opts.tls[name] = readFileSync(opts.tls[name], this.tlsDir);
        }
    }

    // create new server
    server = opts.tls
        ? https.createServer(opts.tls, option(opts, this.express))
        : http.createServer(option(opts, this.express));
    server.laterOpts = opts;
    this.servers.push(server);

    host = opts.host;
    port = opts.port || (opts.tls ? 443 : 80);

    server.on("listening", function() {
        later.emit("listening", server);
    });

    if (host) server.listen(port, host);
    else server.listen(port);
};

/**
 * Serialize a request.
 * @param {http.IncomingMessage} req
 * @returns {Promise}
 */
LaterServer.prototype.serialize = function(req) {
    var serialized = {},
        needLen = true,
        name;

    serialized.httpVersion = req.httpVersion;
    serialized.method = req.method;
    serialized.url = req.url;

    // serialize headers
    serialized.headers = {};
    for (name in req.headers) {
        // skip transfer-encoding which is not relevant once stored
        if (name.toLowerCase() === "transfer-encoding") continue;

        // track if content-length has been set
        if (name.toLowerCase() === "content-type") needLen = false;

        // copy header
        serialized.headers[name] = req.headers[name];
    }

    // serialize body, wrap in Promise and return
    return new Promise(function(resolve, reject) {
        req.pipe(cat({encoding: "string"}, function(body) {
            serialized.body = body;
            if (needLen) serialized.headers["Content-Length"] = body.length;
            resolve(serialized);
        }));
    });
};

/**
 * Deserialize a request.
 * @param {object} req
 * @returns {Promise}
 */
LaterServer.prototype.deserialize = function(req) {
    var url, name, host, laterHost,
        opts, deserialized,
        scheme = "https";

    // find host header
    for (name in req.headers) {
        switch (name.toLowerCase()) {
            case "host":
                host = req.headers[name];
                delete req.headers[name];
                break;

            case "x-later-host":
                laterHost = req.headers[name];
                delete req.headers[name];
                break;

            case "x-later-insecure":
                scheme = "http";
                delete req.headers[name];
                break;
        }
    }

    // build request opts
    if (laterHost && host) req.headers["X-Later-Server"] = host;
    req.headers["Host"] = laterHost || host;
    url = scheme + "://" + req.headers["Host"] + req.url;
    opts = {method: req.method, headers: req.headers, uri: url};

    // make request and wrap in Promise result
    return new Promise(function(resolve, reject) {
        deserialized = request(opts, function(err, res, body) {
            var deserialized = {};

            if (err) reject(err);
            else {
                deserialized.httpVersion = res.httpVersion;
                deserialized.headers = res.headers;
                deserialized.statusCode = res.statusCode;
                deserialized.statusMessage = res.statusMessage;
                deserialized.body = body;
                resolve(deserialized);
            }
        });

        // write request body
        if (req.body) {
            deserialized.write(req.body);
            deserialized.end();
        }
    });
};

/**
 * Store a request.  Return a Promise which resolves to the storage key.
 * @param {http.IncomingMessage} req
 * @returns {Promise}
 */
LaterServer.prototype.store = function(req) {
    var storage = this.storage;

    return this.serialize(req).then(function(req) {
        return new Promise(function(resolve, reject) {
            storage.queue(req, function(err, key) {
                if (err) reject(err);
                else resolve(key);
            });
        });
    });
};

/**
 * Stop the server from accepting new conections.
 * @param {function} [callback]
 */
LaterServer.prototype.close = function(callback) {
    var later = this,
        closing = this.servers.splice(0, this.servers.length);

    // add listener
    if (callback) this.on("close", callback);

    // for each closing server
    closing.forEach(function(server) {
        // close the server
        server.close(function() {
            // remove server from list
            var index = closing.indexOf(server);
            if (index >= 0) {
                closing.splice(index, 1);

                // emit close event once all servers are closed
                if (closing.length === 0) {
                    later.emit("close");
                }
            }
        });
    });
};

/**
 * Create Express middleware for this server.
 * @returns {function}
 */
LaterServer.prototype.createMiddleware = function() {
    var later = this;

    return function(req, res) {
        var opts = req.later;

        if (!later.pathAcceptable(req)) {
            res.writeHead(404, {"Content-Type": "text/plain"});
            res.end("Not Found");
            later.emit("request", res, req);
        }

        else if (!later.methodAllowed(req)) {
            res.writeHead(405, {
                "Allow": (opts.methods || opts.method).replace(":", ","),
                "Content-Type": "text/plain"
            });
            res.end("Method Not Allowed");
            later.emit("request", res, req);
        }

        // accept anything else
        else {
            later.store(req)
            .then(function(key) {
                res.writeHead(202, {"X-Later-Key": key});
                res.end();
                later.emit("request", res, req);
            })
            .catch(function(err) {
                res.writeHead(500, {"Content-Type": "text/plain"});
                res.end("Internal Server Error: " + err.message);
                later.emit("request", res, req);
            });
        }
    };
};

/**
 * Synchronously read a file relative to an optional base directory.
 * @param {string} path
 * @param {string} [base]
 * @returns {string}
 */
function readFileSync(path, base) {
    if (base) path = resolve(base, path);
    return fs.readFileSync(path);
}

/** export LaterServer class */
module.exports = LaterServer;
<commit_msg>rename store -> queue<commit_after>var later = require(".."),
    forward = require("event-emitter-forward"),
    EventEmitter = require("events").EventEmitter,
    Promise = require("es6-promise").Promise,
    https = require("https"),
    http = require("http"),
    fs = require("fs"),
    express = require("express"),
    prop = require("propertize"),
    resolve = require("path").resolve,
    cat = require("concat-stream"),
    request = require("request");

// ensure color support enabled
require("colors");

/**
 * HTTP later server object.
 * @constructor
 * @augments {EventEmitter}
 * @param {LaterStorage} storage
 */
function LaterServer(storage) {
    EventEmitter.call(this);

    prop.internal(this, "servers", []);
    prop.internal(this, "storage", storage);

    /**
     * @name LaterServer#express
     * @type {function}
     * @readonly
     */
    prop.readonly(this, "express", express());

    // forward Express app events to this object
    forward("connection", this.express, this);
    forward("error", this.express, this);
    forward("request", this.express, this);
    forward("checkContinue", this.express, this);
    forward("connect", this.express, this);
    forward("upgrade", this.express, this);
    forward("clientError", this.express, this);

    // setup Express app
    this.express.all("*", this.createMiddleware());
}

LaterServer.prototype = Object.create(EventEmitter.prototype);
LaterServer.prototype.constructor = LaterServer;

/**
 * Create a server object.
 * @param {LaterStorage} storage
 */
LaterServer.create = function(storage) {
    return new LaterServer(storage);
};

/**
 * Return true if the request method is allowed.
 * @param {http.IncomingMessage} req
 * @param {object} req.later
 * @param {string} [req.later.method]
 * @param {string} [req.later.methods]
 * @returns {boolean}
 */
LaterServer.prototype.methodAllowed = function(req) {
    var methods;

    if (req.later.methods) methods = req.later.methods.split(":");
    else if (req.later.method) methods = [req.later.method];

    if (methods) return methods.indexOf(req.method) >= 0;
    return true;
};

/**
 * Return true if the request path is acceptable.
 * @param {http.IncomingMessage} req
 * @param {object} req.later
 * @param {string} [req.later.path]
 * @param {string} [req.later.paths]
 * @returns {boolean}
 */
LaterServer.prototype.pathAcceptable = function(req) {
    var paths;

    if (req.later.paths) paths = req.later.paths.split(":");
    else if (req.later.path) paths = [req.later.path];

    if (paths) return paths.some(function(path) {
        return req.path.substr(0, path.length) === path;
    });

    return true;
};

/**
 * Begin replaying queued requests.
 */
LaterServer.prototype.replay = function() {
    var later = this,
        storage = this.storage,
        unqueued = 0,
        backoff = [1,1];

    this.emit("replay");

    function replay() {
        storage.unqueue(function(err, req) {
            var delay;

            if (err) {
                later.emit("error", err.message);
            } else if (req) {
                later.deserialize(req).then(function(res) {
                    later.emit("response", res, req);
                }).catch(function(err) {
                    later.emit("error", err.message);
                });

                unqueued++;
                replay();
            } else {
                later.emit("drain");

                // if requests were unqueued, restart replay
                if (unqueued) later.replay();

                // if there were no requests, apply backoff
                else {
                    later.emit("backoff");
                    backoff.push(backoff[0] + backoff[1]);
                    backoff.shift();
                    delay = backoff[1];
                    setTimeout(replay, delay);
                }
            }
        });
    }

    // initiate replay
    setTimeout(replay, 0);
};

/**
 * Begin accepting requests into queue.
 * @param {object} opts
 * @param {string} [opts.host]      virtual host to accept
 * @param {number} [opts.port]      listen port (if not default)
 * @param {string} [opts.path]      path prefix to handle; 404 on rest
 * @param {object} [opts.tls]       TLS options; https defaults to port 443
 * @param {string} [opts.tls.pfx]   path to key-pair/ca file
 * @param {string} [opts.tls.cert]  path of TLS cert file
 * @param {string} [opts.tls.key]   path of TLS private key file
 * @param {string} [opts.tls.ca]    path of TLS CA cert file
 */
LaterServer.prototype.accept = function(opts) {
    var later = this,
        name,
        host, port,
        server;

    // wrap Express listener so req is decorated with accept opts
    function option(opts, listener) {
        return function(req, res, next) {
            req.later = opts;
            return listener(req, res, next);
        };
    }

    // read in any TLS files
    if (opts.tls) {
        for (name in opts.tls) {
            opts.tls[name] = readFileSync(opts.tls[name], this.tlsDir);
        }
    }

    // create new server
    server = opts.tls
        ? https.createServer(opts.tls, option(opts, this.express))
        : http.createServer(option(opts, this.express));
    server.laterOpts = opts;
    this.servers.push(server);

    host = opts.host;
    port = opts.port || (opts.tls ? 443 : 80);

    server.on("listening", function() {
        later.emit("listening", server);
    });

    if (host) server.listen(port, host);
    else server.listen(port);
};

/**
 * Serialize a request.
 * @param {http.IncomingMessage} req
 * @returns {Promise}
 */
LaterServer.prototype.serialize = function(req) {
    var serialized = {},
        needLen = true,
        name;

    serialized.httpVersion = req.httpVersion;
    serialized.method = req.method;
    serialized.url = req.url;

    // serialize headers
    serialized.headers = {};
    for (name in req.headers) {
        // skip transfer-encoding which is not relevant once stored
        if (name.toLowerCase() === "transfer-encoding") continue;

        // track if content-length has been set
        if (name.toLowerCase() === "content-type") needLen = false;

        // copy header
        serialized.headers[name] = req.headers[name];
    }

    // serialize body, wrap in Promise and return
    return new Promise(function(resolve, reject) {
        req.pipe(cat({encoding: "string"}, function(body) {
            serialized.body = body;
            if (needLen) serialized.headers["Content-Length"] = body.length;
            resolve(serialized);
        }));
    });
};

/**
 * Deserialize a request.
 * @param {object} req
 * @returns {Promise}
 */
LaterServer.prototype.deserialize = function(req) {
    var url, name, host, laterHost,
        opts, deserialized,
        scheme = "https";

    // find host header
    for (name in req.headers) {
        switch (name.toLowerCase()) {
            case "host":
                host = req.headers[name];
                delete req.headers[name];
                break;

            case "x-later-host":
                laterHost = req.headers[name];
                delete req.headers[name];
                break;

            case "x-later-insecure":
                scheme = "http";
                delete req.headers[name];
                break;
        }
    }

    // build request opts
    if (laterHost && host) req.headers["X-Later-Server"] = host;
    req.headers["Host"] = laterHost || host;
    url = scheme + "://" + req.headers["Host"] + req.url;
    opts = {method: req.method, headers: req.headers, uri: url};

    // make request and wrap in Promise result
    return new Promise(function(resolve, reject) {
        deserialized = request(opts, function(err, res, body) {
            var deserialized = {};

            if (err) reject(err);
            else {
                deserialized.httpVersion = res.httpVersion;
                deserialized.headers = res.headers;
                deserialized.statusCode = res.statusCode;
                deserialized.statusMessage = res.statusMessage;
                deserialized.body = body;
                resolve(deserialized);
            }
        });

        // write request body
        if (req.body) {
            deserialized.write(req.body);
            deserialized.end();
        }
    });
};

/**
 * Queue a request.  Return a Promise which resolves to the storage key.
 * @param {http.IncomingMessage} req
 * @returns {Promise}
 */
LaterServer.prototype.queue = function(req) {
    var storage = this.storage;

    return this.serialize(req).then(function(req) {
        return new Promise(function(resolve, reject) {
            storage.queue(req, function(err, key) {
                if (err) reject(err);
                else resolve(key);
            });
        });
    });
};

/**
 * Stop the server from accepting new conections.
 * @param {function} [callback]
 */
LaterServer.prototype.close = function(callback) {
    var later = this,
        closing = this.servers.splice(0, this.servers.length);

    // add listener
    if (callback) this.on("close", callback);

    // for each closing server
    closing.forEach(function(server) {
        // close the server
        server.close(function() {
            // remove server from list
            var index = closing.indexOf(server);
            if (index >= 0) {
                closing.splice(index, 1);

                // emit close event once all servers are closed
                if (closing.length === 0) {
                    later.emit("close");
                }
            }
        });
    });
};

/**
 * Create Express middleware for this server.
 * @returns {function}
 */
LaterServer.prototype.createMiddleware = function() {
    var later = this;

    return function(req, res) {
        var opts = req.later;

        if (!later.pathAcceptable(req)) {
            res.writeHead(404, {"Content-Type": "text/plain"});
            res.end("Not Found");
            later.emit("request", res, req);
        }

        else if (!later.methodAllowed(req)) {
            res.writeHead(405, {
                "Allow": (opts.methods || opts.method).replace(":", ","),
                "Content-Type": "text/plain"
            });
            res.end("Method Not Allowed");
            later.emit("request", res, req);
        }

        // accept anything else
        else {
            later.queue(req)
            .then(function(key) {
                res.writeHead(202, {"X-Later-Key": key});
                res.end();
                later.emit("request", res, req);
            })
            .catch(function(err) {
                res.writeHead(500, {"Content-Type": "text/plain"});
                res.end("Internal Server Error: " + err.message);
                later.emit("request", res, req);
            });
        }
    };
};

/**
 * Synchronously read a file relative to an optional base directory.
 * @param {string} path
 * @param {string} [base]
 * @returns {string}
 */
function readFileSync(path, base) {
    if (base) path = resolve(base, path);
    return fs.readFileSync(path);
}

/** export LaterServer class */
module.exports = LaterServer;
<|endoftext|>


<commit_before>'use strict';

var lazyReq = require('lazy-req')(require);
var connect = lazyReq('gulp-connect');
var fsExtra = lazyReq('fs-extra');
var fs = lazyReq('fs');
var path = require('path');
var request = require('request');
var putils = require('./plugin-utils');

module.exports = function (gulp, gutil) {
  var server = require('./server.js')(gulp, gutil);
  var skins = require('./skins.js')(gulp, gutil);

  function cors(req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Headers', '*');
    next();
  }

  /**
   * Filter for downloading mostly image assets right before they are served from local server.
   */
  function downloadAssets(req, res, next) {

    var assetUrl = req.originalUrl.split('?')[0];
    var matches = assetUrl.match(/\/html\/(\S+)/);
    //Ignore urls not matching asset endpoints
    if (!matches) {
      next();
      return;
    }

    if (matches.length < 2) {
      //Url does not match
      putils.logDebug(gutil, 'No file path specified in asset url. Ignoring download for ' + assetUrl);
      next();
      return;
    }
    var assetPath = path.join(matches[1]);
    var fileSystemAssetPath = path.join('web/html', assetPath);
    var pathExists = fs().existsSync(fileSystemAssetPath);
    if (pathExists) {
      //File already served from web/html
      next();
      return;
    }

    var tmpFilePath = path.join(server.localServerDir(), 'html', assetPath);
    pathExists = fs().existsSync(tmpFilePath);
    if (pathExists && fs().statSync(tmpFilePath).size > 0) {
      // File already downloaded to tmp.
      next();
      return;
    }

    var tmpDirPath = path.join(server.localServerDir(), 'html', path.dirname(assetPath));
    fsExtra().mkdirsSync(tmpDirPath);
    var options = {
      rejectUnauthorized: false
    };

    var serverUrl = server.serverUrl();
    if (server.community() && serverUrl.endsWith(server.community())) {
      serverUrl = serverUrl.substr(0, serverUrl.length - server.community().length);
    }

    var urlBld = putils.urlBldr(serverUrl);
    var serverAssetUrl = urlBld.add(assetUrl).build();
    downloadFile(serverAssetUrl, options, tmpFilePath, function(message) {
      putils.logDebug(gutil, message);
      next();
    });
  }

  /**
   * Util method for downloading url to a file specified in dest. The method copies content to a tmp file and renames
   * the file once download is finished.
   * @param url Url for download
   * @param options Request options
   * @param dest file path to destination
   * @param cb Callback function for success or error.
   */
  function downloadFile(url, options, dest, cb) {
    var file = fs().createWriteStream(dest + '.tmp');
    var sendReq = request.get(url, options);
    var errorOnDownload = false;
    // verify response code
    sendReq.on('response', function(response) {
      if (response.statusCode !== 200) {
        errorOnDownload = true;
        return cb('Response status was ' + response.statusCode + ' (for ' + url + ')');
      }
    });
    // check for request errors
    sendReq.on('error', function (err) {
      fs().unlink(file.path);
      if (cb) {
        return cb(err.message);
      }
    });
    sendReq.pipe(file);
    file.on('finish', function() {
      file.close();
      if (!errorOnDownload) {
        fs().renameSync(dest + '.tmp', dest);
        cb('Successfully downloaded asset = ' + dest);
      } else{
        fs().unlinkSync(dest + '.tmp');
      }
    });
    file.on('error', function(err) { // Handle errors
      fs().unlink(dest); // Delete the tmp file
      if (cb) {
        return cb(err.message);
      }
    });
  }

  function startLocalServer() {
    var responsiveOptions = require('./responsive-options.js')(gulp, gutil);
    skins.options().then(function (opts) {
      function runServer() {
        connect().server({
          root: [
            opts.localServerDir,
            'web',
            'plugin/res',
            'plugin/web',
            'src'
          ],
          port: opts.localServerPort,
          middleware: function () {
            return [cors, downloadAssets];
          }
        });
      }

      if (server.useResponsiveConfigsFromServer()) {
        return responsiveOptions.getOptions(server, opts, function (err, config) {
          if (err) throw err;
          opts = skins.setOptionsFromConfig(config, opts);
          return runServer();
        });
      } else {
        return runServer();
      }
    });
  }

  return {
    startLocalServer: startLocalServer,
    downloadAssets: downloadAssets,
    downloadFile: downloadFile
  };
};<commit_msg>LIA-52118 Move the load order of assets for the local server, prioritize the local plugin over the tmp folder.<commit_after>'use strict';

var lazyReq = require('lazy-req')(require);
var connect = lazyReq('gulp-connect');
var fsExtra = lazyReq('fs-extra');
var fs = lazyReq('fs');
var path = require('path');
var request = require('request');
var putils = require('./plugin-utils');

module.exports = function (gulp, gutil) {
  var server = require('./server.js')(gulp, gutil);
  var skins = require('./skins.js')(gulp, gutil);

  function cors(req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Headers', '*');
    next();
  }

  /**
   * Filter for downloading mostly image assets right before they are served from local server.
   */
  function downloadAssets(req, res, next) {

    var assetUrl = req.originalUrl.split('?')[0];
    var matches = assetUrl.match(/\/html\/(\S+)/);
    //Ignore urls not matching asset endpoints
    if (!matches) {
      next();
      return;
    }

    if (matches.length < 2) {
      //Url does not match
      putils.logDebug(gutil, 'No file path specified in asset url. Ignoring download for ' + assetUrl);
      next();
      return;
    }
    var assetPath = path.join(matches[1]);
    var fileSystemAssetPath = path.join('web/html', assetPath);
    var pathExists = fs().existsSync(fileSystemAssetPath);
    if (pathExists) {
      //File already served from web/html
      next();
      return;
    }

    var tmpFilePath = path.join(server.localServerDir(), 'html', assetPath);
    pathExists = fs().existsSync(tmpFilePath);
    if (pathExists && fs().statSync(tmpFilePath).size > 0) {
      // File already downloaded to tmp.
      next();
      return;
    }

    var tmpDirPath = path.join(server.localServerDir(), 'html', path.dirname(assetPath));
    fsExtra().mkdirsSync(tmpDirPath);
    var options = {
      rejectUnauthorized: false
    };

    var serverUrl = server.serverUrl();
    if (server.community() && serverUrl.endsWith(server.community())) {
      serverUrl = serverUrl.substr(0, serverUrl.length - server.community().length);
    }

    var urlBld = putils.urlBldr(serverUrl);
    var serverAssetUrl = urlBld.add(assetUrl).build();
    downloadFile(serverAssetUrl, options, tmpFilePath, function(message) {
      putils.logDebug(gutil, message);
      next();
    });
  }

  /**
   * Util method for downloading url to a file specified in dest. The method copies content to a tmp file and renames
   * the file once download is finished.
   * @param url Url for download
   * @param options Request options
   * @param dest file path to destination
   * @param cb Callback function for success or error.
   */
  function downloadFile(url, options, dest, cb) {
    var file = fs().createWriteStream(dest + '.tmp');
    var sendReq = request.get(url, options);
    var errorOnDownload = false;
    // verify response code
    sendReq.on('response', function(response) {
      if (response.statusCode !== 200) {
        errorOnDownload = true;
        return cb('Response status was ' + response.statusCode + ' (for ' + url + ')');
      }
    });
    // check for request errors
    sendReq.on('error', function (err) {
      fs().unlink(file.path);
      if (cb) {
        return cb(err.message);
      }
    });
    sendReq.pipe(file);
    file.on('finish', function() {
      file.close();
      if (!errorOnDownload) {
        fs().renameSync(dest + '.tmp', dest);
        cb('Successfully downloaded asset = ' + dest);
      } else{
        fs().unlinkSync(dest + '.tmp');
      }
    });
    file.on('error', function(err) { // Handle errors
      fs().unlink(dest); // Delete the tmp file
      if (cb) {
        return cb(err.message);
      }
    });
  }

  function startLocalServer() {
    var responsiveOptions = require('./responsive-options.js')(gulp, gutil);
    skins.options().then(function (opts) {
      function runServer() {
        connect().server({
          root: [
            'web',
            'plugin/res',
            'plugin/web',
            'src',
            opts.localServerDir
          ],
          port: opts.localServerPort,
          middleware: function () {
            return [cors, downloadAssets];
          }
        });
      }

      if (server.useResponsiveConfigsFromServer()) {
        return responsiveOptions.getOptions(server, opts, function (err, config) {
          if (err) throw err;
          opts = skins.setOptionsFromConfig(config, opts);
          return runServer();
        });
      } else {
        return runServer();
      }
    });
  }

  return {
    startLocalServer: startLocalServer,
    downloadAssets: downloadAssets,
    downloadFile: downloadFile
  };
};<|endoftext|>


<commit_before>import React from 'react';
import firebase from '../firebase';
import moment from 'moment';

const AdminSpike = ({ spike, createSpike, updateSpike, deleteSpike }, key ) => {
  return (

Spike Topic:
 {spike.title}

Description:
 {spike.description}

Created by:  {spike.createdBy}

Spike Hosts:  {spike.hosts}

Attendees:

        {spike.attendees ?
          spike.attendees.map((attendee, index) => {
            return
{attendee}

          })
          :
No Attendees Have Joined

        }

        Date Submitted:  {moment(spike.created_at).format("MM-DD-YYYY")}

        Spike Session Date:
          {moment(spike.spikeDate).format('MM-DD-YYYY')}

        Notes for Staff:
          {spike.notes}

      <form className="location-form">

Assign a location:

          <select
            className="ApproveButton"
            name='location'
            onChange={(e)=>updateSpike(spike, 'location', e.target.value)}
          >
            <option value='none'>none</option>
            <option value='Classroom A'>Classroom A</option>
            <option value='Classroom B'>Classroom B</option>
            <option value='Classroom C'>Classroom C</option>
            <option value='Classroom D'>Classroom D</option>
            <option value='Classroom E'>Classroom E</option>
            <option value='Classroom F'>Classroom F</option>
            <option value='Classroom G'>Classroom G</option>
            <option value='Classroom H'>Classroom H</option>
            <option value='Grand Room'>Grand Room</option>
            <option value='Vault Study'>Vault Study</option>
          </select>

          Assigned Location:  {spike.location}

Approval Status:
          {spike.appr ?  'Approved' : 'Pending'}

        <button
          className="ApproveButton"
          onClick={(e)=> {
            e.preventDefault();
            updateSpike(spike, 'appr', true);
          }}
          disabled={spike.location === ''}>
          Approve
        </button>
        <button
          className="DeleteButton"
          onClick={(e)=> {
            e.preventDefault()
            deleteSpike(spike)
          }}>
          Delete
        </button>
      </form>

  )
}

export default AdminSpike;
<commit_msg>remove white space<commit_after>import React from 'react';
import firebase from '../firebase';
import moment from 'moment';

const AdminSpike = ({ spike, createSpike, updateSpike, deleteSpike }, key ) => {
  return (

Spike Topic:
 {spike.title}

Description:
 {spike.description}

Created by:  {spike.createdBy}

Spike Hosts:  {spike.hosts}

Attendees:

        {spike.attendees ?
          spike.attendees.map((attendee, index) => {
            return
{attendee}

          })
          :
No Attendees Have Joined

        }

        Date Submitted:  {moment(spike.created_at).format("MM-DD-YYYY")}

        Spike Session Date:
          {moment(spike.spikeDate).format('MM-DD-YYYY')}

        Notes for Staff:
          {spike.notes}

      <form className="location-form">

Assign a location:

          <select
            className="ApproveButton"
            name='location'
            onChange={(e)=>updateSpike(spike, 'location', e.target.value)}
          >
            <option value='none'>none</option>
            <option value='Classroom A'>Classroom A</option>
            <option value='Classroom B'>Classroom B</option>
            <option value='Classroom C'>Classroom C</option>
            <option value='Classroom D'>Classroom D</option>
            <option value='Classroom E'>Classroom E</option>
            <option value='Classroom F'>Classroom F</option>
            <option value='Classroom G'>Classroom G</option>
            <option value='Classroom H'>Classroom H</option>
            <option value='Grand Room'>Grand Room</option>
            <option value='Vault Study'>Vault Study</option>
          </select>

          Assigned Location:  {spike.location}

Approval Status:
          {spike.appr ? 'Approved' : 'Pending'}

        <button
          className="ApproveButton"
          onClick={(e)=> {
            e.preventDefault();
            updateSpike(spike, 'appr', true);
          }}
          disabled={spike.location === ''}>
          Approve
        </button>
        <button
          className="DeleteButton"
          onClick={(e)=> {
            e.preventDefault()
            deleteSpike(spike)
          }}>
          Delete
        </button>
      </form>

  )
}

export default AdminSpike;
<|endoftext|>