<commit_before>var _ = require("lodash");
var ktypes = require("krl-stdlib/types");

var isBlank = function(str){
    return !ktypes.isString(str) || str.trim().length === 0;
};

var cleanEventRules = function(rules){
    if(ktypes.isNull(rules)){
        return [];
    }
    if( ! _.isArray(rules)){
        throw new Error("`policy.event.<allow|deny>` must be an Array of rules");
    }
    return _.map(rules, function(rule_orig){
        if( ! ktypes.isMap(rule_orig)){
            throw new Error("Policy rules must be Maps, not " + ktypes.typeOf(rule_orig));
        }
        var rule = {};
        if(!isBlank(rule_orig.domain)){
            rule.domain = rule_orig.domain.trim();
        }
        if(!isBlank(rule_orig.type)){
            rule.type = rule_orig.type.trim();
        }
        return rule;
    });
};

var cleanQueryRules = function(rules){
    if(ktypes.isNull(rules)){
        return [];
    }
    if( ! _.isArray(rules)){
        throw new Error("`policy.query.<allow|deny>` must be an Array of rules");
    }
    return _.map(rules, function(rule_orig){
        if( ! ktypes.isMap(rule_orig)){
            throw new Error("Policy rules must be Maps, not " + ktypes.typeOf(rule_orig));
        }
        var rule = {};
        if(!isBlank(rule_orig.rid)){
            rule.rid = rule_orig.rid.trim();
        }
        if(!isBlank(rule_orig.name)){
            rule.name = rule_orig.name.trim();
        }
        return rule;
    });
};

var clean = function(policy){

    if(isBlank(policy.name)){
        throw new Error("missing `policy.name`");
    }

    return {
        name: policy.name.trim(),
        event: {
            deny : cleanEventRules(policy.event && policy.event.deny),
            allow: cleanEventRules(policy.event && policy.event.allow),
        },
        query: {
            deny:  cleanQueryRules(policy.query && policy.query.deny),
            allow: cleanQueryRules(policy.query && policy.query.allow),
        },
    };
};

var doesMatchEvent = function(events, event){
    return _.find(events, function(s){
        if(_.has(s, "domain") && s.domain !== event.domain){
            return false;
        }
        if(_.has(s, "type") && s.type !== event.type){
            return false;
        }
        return true;
    });
};

var checkEvent = function(policy, event){
    if( ! policy || ! policy.event){
        //TODO remove this
        return true;
    }
    if(doesMatchEvent(policy.event.deny, event)){
        return false;
    }
    return doesMatchEvent(policy.event.allow, event);
};

var doesMatchQuery = function(rules, query){
    return _.find(rules, function(rule){
        if(_.has(rule, "rid") && rule.rid !== query.rid){
            return false;
        }
        if(_.has(rule, "name") && rule.name !== query.name){
            return false;
        }
        return true;
    });
};

var checkQuery = function(policy, query){
    if( ! policy || ! policy.query){
        //TODO remove this
        return true;
    }
    if(doesMatchQuery(policy.query.deny, query)){
        return false;
    }
    return doesMatchQuery(policy.query.allow, query);
};

module.exports = {
    clean: clean,
    assert: function(policy, type, data){
        var ok = false;
        if(type === "event"){
            ok = checkEvent(policy, data);
        }else if(type === "query"){
            ok = checkQuery(policy, data);
        }else{
            throw new Error("Channel can only assert type's \"event\" and \"query\"");
        }
        if( ! ok){
            throw new Error("denied by policy");
        }
    },
};
<commit_msg>reusing allow/deny logic for both queries and events<commit_after>var _ = require("lodash");
var ktypes = require("krl-stdlib/types");

var isBlank = function(str){
    return !ktypes.isString(str) || str.trim().length === 0;
};

var cleanEventRules = function(rules){
    if(ktypes.isNull(rules)){
        return [];
    }
    if( ! _.isArray(rules)){
        throw new Error("`policy.event.<allow|deny>` must be an Array of rules");
    }
    return _.map(rules, function(rule_orig){
        if( ! ktypes.isMap(rule_orig)){
            throw new Error("Policy rules must be Maps, not " + ktypes.typeOf(rule_orig));
        }
        var rule = {};
        if(!isBlank(rule_orig.domain)){
            rule.domain = rule_orig.domain.trim();
        }
        if(!isBlank(rule_orig.type)){
            rule.type = rule_orig.type.trim();
        }
        return rule;
    });
};

var cleanQueryRules = function(rules){
    if(ktypes.isNull(rules)){
        return [];
    }
    if( ! _.isArray(rules)){
        throw new Error("`policy.query.<allow|deny>` must be an Array of rules");
    }
    return _.map(rules, function(rule_orig){
        if( ! ktypes.isMap(rule_orig)){
            throw new Error("Policy rules must be Maps, not " + ktypes.typeOf(rule_orig));
        }
        var rule = {};
        if(!isBlank(rule_orig.rid)){
            rule.rid = rule_orig.rid.trim();
        }
        if(!isBlank(rule_orig.name)){
            rule.name = rule_orig.name.trim();
        }
        return rule;
    });
};

var clean = function(policy){

    if(isBlank(policy.name)){
        throw new Error("missing `policy.name`");
    }

    return {
        name: policy.name.trim(),
        event: {
            deny : cleanEventRules(policy.event && policy.event.deny),
            allow: cleanEventRules(policy.event && policy.event.allow),
        },
        query: {
            deny:  cleanQueryRules(policy.query && policy.query.deny),
            allow: cleanQueryRules(policy.query && policy.query.allow),
        },
    };
};

var eventRuleMatcher = function(event){
    return function(rule){
        if(_.has(rule, "domain") && rule.domain !== event.domain){
            return false;
        }
        if(_.has(rule, "type") && rule.type !== event.type){
            return false;
        }
        return true;
    };
};

var queryRuleMatcher = function(query){
    return function(rule){
        if(_.has(rule, "rid") && rule.rid !== query.rid){
            return false;
        }
        if(_.has(rule, "name") && rule.name !== query.name){
            return false;
        }
        return true;
    };
};

module.exports = {
    clean: clean,
    assert: function(policy, type, data){

        var matcher;
        if(type === "event"){
            matcher = eventRuleMatcher(data);
        }else if(type === "query"){
            matcher = queryRuleMatcher(data);
        }else{
            throw new Error("Channel can only assert type's \"event\" and \"query\"");
        }

        if( ! policy || ! policy[type]){
            //TODO remove this
            return;
        }

        if(_.find(policy[type].deny, matcher)){
            throw new Error("denied by policy");
        }
        if( ! _.find(policy[type].allow, matcher)){
            throw new Error("denied by policy");
        }
        //allowed
    },
};
<|endoftext|>


<commit_before>var os = require("os");
var o = require('atom').o(module);
var oo = require('atom').oo(module);
var _o = require('bond')._o(module);

/******************************************************************************
 * @class SwaggerDescriptorGenerator
 */
module.exports = oo({

  /**********************************************************************
   * generateSwaggerDescriptor
   */
  generateSwaggerDescriptor: function(service, req) {
    // XXX _hostname? Should we just use default here?
    var host = (service.hostname || os.hostname()) + ":" + service.port

    // if req is present, update host to reflect the client's perspective
    // (e.g., 127.0.0.1 instead of 0.0.0.0)
    if (typeof req !== 'undefined') {
      // XXX: req as passed to a handler by express does not contain a "port"
      //      property... the host header should contain the port
      host = req.get('host')
    }

    var descriptor = {
      "swagger": 2.0,
      "info": {
        "version": "1.0.0", // XXX ?
        "title": service.serviceName || "Service",
        "description": service.description
      },
      "host":  host,
      "basePath": service.apiRoot || '',
      "schemes": ["http"],
      "consumes": ["application/json"],
      "produces": ["application/json"],
      "paths" : this._generateEndpointPaths(service.endpoints, service.path),
      "securityDefinitions": this._generateSecurityDefinitions(service)
    }

    return descriptor
  },

  /**********************************************************************
   * _generateEndpointPaths
   */
  _generateEndpointPaths: function(endpoints, path, result) {
    result = result || {}

    path = path || ""
    if (endpoints) {
      for (var endpointPath in endpoints) {
        this._generateEndpointPath(endpoints[endpointPath], path + "/" + endpointPath, result)
      }
    }

    return result
  },

  /**********************************************************************
   * _generateEndpointPath
   */
  _generateEndpointPath: function(endpoint, path, result) {
    var descriptorPath = this._pathToSwaggerPath(path)
    result[descriptorPath] = this._generatePathDescriptor(endpoint, descriptorPath)
    this._generateEndpointPaths(endpoint.endpoints, path, result)
  },

  /**********************************************************************
   * _generatePathDescriptor
   */
  _generatePathDescriptor: function(endpoint, descriptorPath) {
    var result = {}
    var self = this
    endpoint.supportedMethods().forEach(function(method) {
      if (method === 'options') {
        if (endpoint.service.generateOptionsMethodsInDocs) {
          result[method] = self._generateMethodDescriptor(endpoint, method)
        }
      } else {
        result[method] = self._generateMethodDescriptor(endpoint, method)
      }
    })

    return result
  },

  /**********************************************************************
   * _generateMethodDescriptor
   */
  _generateMethodDescriptor: function(endpoint, method) {
    var result = {
      produces: ["application/json"],
      parameters: this._generateOperationParameters(endpoint, method),
      tags: this._generateEndpointTags(endpoint.path),
      responses: this._generateOperationResponses(endpoint, method)
    }

    return result
  },

  /**********************************************************************
   * _generateOperationParameters
   */
  _generateOperationParameters: function(endpoint, method) {
    var result = []

    // params defined on operation
    var operation = endpoint[method]
    var operationParameters = {}
    if (operation) {
      operationParameters = operation.getAllParameters() || {}
      for (parameterName in operationParameters) {
        var parameter = operationParameters[parameterName]
        var swaggerParameterObject = this._makeSwaggerParamaterObject(parameter)
        result.push(swaggerParameterObject)
      }
    }

    // path params can be auto-generated even if not explicitly defined
    var pathParameters = this._getPathParameters(endpoint.path)
    if (pathParameters) {
      pathParameters.forEach(function(param) {
        var paramName = param.substring(1) // XXX hack
        if (!operationParameters[paramName]) { // only if not defined explicitly
          result.push({
            'name': paramName,
            'description': paramName,
            'in': "path",
            // We can't really do type well here since we allow for non-scalar schemas here
            'required': true, // XXX Check on :id? vs :id support in swagger. Seems they don't support
            'schema': {}
          })
        }
      })
    }
    return result
  },

  /**********************************************************************
   * _makeSwaggerParamaterObject
   */
  _makeSwaggerParamaterObject: function(parameterDefinition) {
    var result = {}

    result.name = parameterDefinition.name
    result.description = parameterDefinition.description
    result.in = parameterDefinition.location
    // XXX: setting schema to {} to make swagger-ui 2.4.1 happy, should probably be removed in the future
    result.schema = {}
    if (parameterDefinition.location === "body") {
      result.schema = parameterDefinition.schema || {}
    } else if (parameterDefinition.schema) {
      var supportedFields = [
        'type',
        'items',
        'format',
        'description',
        'maximum',
        'exclusiveMaximum',
        'minimum',
        'exclusiveMinimum',
        'maxLength',
        'minLength',
        'pattern',
        'maxItems',
        'minItems',
        'uniqueItems',
        'enum'
      ]

      supportedFields.forEach(function (field) {
        result[field] = parameterDefinition.schema[field]
      })
    }

    return result
  },

  /**********************************************************************
   * _generateEndpointTags
   */
  _generateEndpointTags: function(path) {
    var result = []
    var pathArr = path.split('/')
    var tag
    for (var i = 0; i <= pathArr.length; i++) {
      if (i === pathArr.length || pathArr[i][0] === ':') {
        if (pathArr[0] === '') {
          tag = pathArr.slice(0, i).join('/')
        } else {
          tag = [''].concat(pathArr.slice(0, i)).join('/')
        }
        result.push(tag)
        break
      }
    }

    return result
  },

  /**********************************************************************
   * _generateOperationResponses
   */
  _generateOperationResponses: function(endpoint, method) {
    var result = {}

    // params defined on operation
    var operation = endpoint[method]
    if (operation) {
      operation.responses.forEach(function(response) {
        result[response.statusCode.toString()] = {
          description: response.description,
          schema: response.schema || {}
        }
      })
    }

    return result
  },

  /**********************************************************************
   * _pathToSwaggerPath
   */
  _pathToSwaggerPath: function(path) {
    var re = /:(\w+)/g
    return path.replace(re, "{$1}")
  },

  /**********************************************************************
   * _getPathParameters
   */
  _getPathParameters: function(path) {
    var re = /:(\w+)/g
    return path.match(re, "{$1}")
  },

  /**********************************************************************
   * _getSecurityDefinitions
   */
  _generateSecurityDefinitions: function(service) {
    var definition = null

    if (!service.authenticator) {
      // noop
    } else if (service.authenticator instanceof _o('./security/ApiKeyAuthenticator')) {
      definition = {
        api_key: {
          type: 'apiKey',
          name: service.authenticator.apiKeyParameterName,
          in: service.authenticator.apiKeyLocation
        }
      }
    } else if (service.authenticator instanceof _o('./security/HttpBasicAuthenticator')) {
      definition = {
        basic: {
          type: 'basic'
        }
      }
    }

    return definition
  }

})
<commit_msg>update comment to match method name<commit_after>var os = require("os");
var o = require('atom').o(module);
var oo = require('atom').oo(module);
var _o = require('bond')._o(module);

/******************************************************************************
 * @class SwaggerDescriptorGenerator
 */
module.exports = oo({

  /**********************************************************************
   * generateSwaggerDescriptor
   */
  generateSwaggerDescriptor: function(service, req) {
    // XXX _hostname? Should we just use default here?
    var host = (service.hostname || os.hostname()) + ":" + service.port

    // if req is present, update host to reflect the client's perspective
    // (e.g., 127.0.0.1 instead of 0.0.0.0)
    if (typeof req !== 'undefined') {
      // XXX: req as passed to a handler by express does not contain a "port"
      //      property... the host header should contain the port
      host = req.get('host')
    }

    var descriptor = {
      "swagger": 2.0,
      "info": {
        "version": "1.0.0", // XXX ?
        "title": service.serviceName || "Service",
        "description": service.description
      },
      "host":  host,
      "basePath": service.apiRoot || '',
      "schemes": ["http"],
      "consumes": ["application/json"],
      "produces": ["application/json"],
      "paths" : this._generateEndpointPaths(service.endpoints, service.path),
      "securityDefinitions": this._generateSecurityDefinitions(service)
    }

    return descriptor
  },

  /**********************************************************************
   * _generateEndpointPaths
   */
  _generateEndpointPaths: function(endpoints, path, result) {
    result = result || {}

    path = path || ""
    if (endpoints) {
      for (var endpointPath in endpoints) {
        this._generateEndpointPath(endpoints[endpointPath], path + "/" + endpointPath, result)
      }
    }

    return result
  },

  /**********************************************************************
   * _generateEndpointPath
   */
  _generateEndpointPath: function(endpoint, path, result) {
    var descriptorPath = this._pathToSwaggerPath(path)
    result[descriptorPath] = this._generatePathDescriptor(endpoint, descriptorPath)
    this._generateEndpointPaths(endpoint.endpoints, path, result)
  },

  /**********************************************************************
   * _generatePathDescriptor
   */
  _generatePathDescriptor: function(endpoint, descriptorPath) {
    var result = {}
    var self = this
    endpoint.supportedMethods().forEach(function(method) {
      if (method === 'options') {
        if (endpoint.service.generateOptionsMethodsInDocs) {
          result[method] = self._generateMethodDescriptor(endpoint, method)
        }
      } else {
        result[method] = self._generateMethodDescriptor(endpoint, method)
      }
    })

    return result
  },

  /**********************************************************************
   * _generateMethodDescriptor
   */
  _generateMethodDescriptor: function(endpoint, method) {
    var result = {
      produces: ["application/json"],
      parameters: this._generateOperationParameters(endpoint, method),
      tags: this._generateEndpointTags(endpoint.path),
      responses: this._generateOperationResponses(endpoint, method)
    }

    return result
  },

  /**********************************************************************
   * _generateOperationParameters
   */
  _generateOperationParameters: function(endpoint, method) {
    var result = []

    // params defined on operation
    var operation = endpoint[method]
    var operationParameters = {}
    if (operation) {
      operationParameters = operation.getAllParameters() || {}
      for (parameterName in operationParameters) {
        var parameter = operationParameters[parameterName]
        var swaggerParameterObject = this._makeSwaggerParamaterObject(parameter)
        result.push(swaggerParameterObject)
      }
    }

    // path params can be auto-generated even if not explicitly defined
    var pathParameters = this._getPathParameters(endpoint.path)
    if (pathParameters) {
      pathParameters.forEach(function(param) {
        var paramName = param.substring(1) // XXX hack
        if (!operationParameters[paramName]) { // only if not defined explicitly
          result.push({
            'name': paramName,
            'description': paramName,
            'in': "path",
            // We can't really do type well here since we allow for non-scalar schemas here
            'required': true, // XXX Check on :id? vs :id support in swagger. Seems they don't support
            'schema': {}
          })
        }
      })
    }
    return result
  },

  /**********************************************************************
   * _makeSwaggerParamaterObject
   */
  _makeSwaggerParamaterObject: function(parameterDefinition) {
    var result = {}

    result.name = parameterDefinition.name
    result.description = parameterDefinition.description
    result.in = parameterDefinition.location
    // XXX: setting schema to {} to make swagger-ui 2.4.1 happy, should probably be removed in the future
    result.schema = {}
    if (parameterDefinition.location === "body") {
      result.schema = parameterDefinition.schema || {}
    } else if (parameterDefinition.schema) {
      var supportedFields = [
        'type',
        'items',
        'format',
        'description',
        'maximum',
        'exclusiveMaximum',
        'minimum',
        'exclusiveMinimum',
        'maxLength',
        'minLength',
        'pattern',
        'maxItems',
        'minItems',
        'uniqueItems',
        'enum'
      ]

      supportedFields.forEach(function (field) {
        result[field] = parameterDefinition.schema[field]
      })
    }

    return result
  },

  /**********************************************************************
   * _generateEndpointTags
   */
  _generateEndpointTags: function(path) {
    var result = []
    var pathArr = path.split('/')
    var tag
    for (var i = 0; i <= pathArr.length; i++) {
      if (i === pathArr.length || pathArr[i][0] === ':') {
        if (pathArr[0] === '') {
          tag = pathArr.slice(0, i).join('/')
        } else {
          tag = [''].concat(pathArr.slice(0, i)).join('/')
        }
        result.push(tag)
        break
      }
    }

    return result
  },

  /**********************************************************************
   * _generateOperationResponses
   */
  _generateOperationResponses: function(endpoint, method) {
    var result = {}

    // params defined on operation
    var operation = endpoint[method]
    if (operation) {
      operation.responses.forEach(function(response) {
        result[response.statusCode.toString()] = {
          description: response.description,
          schema: response.schema || {}
        }
      })
    }

    return result
  },

  /**********************************************************************
   * _pathToSwaggerPath
   */
  _pathToSwaggerPath: function(path) {
    var re = /:(\w+)/g
    return path.replace(re, "{$1}")
  },

  /**********************************************************************
   * _getPathParameters
   */
  _getPathParameters: function(path) {
    var re = /:(\w+)/g
    return path.match(re, "{$1}")
  },

  /**********************************************************************
   * _generateSecurityDefinitions
   */
  _generateSecurityDefinitions: function(service) {
    var definition = null

    if (!service.authenticator) {
      // noop
    } else if (service.authenticator instanceof _o('./security/ApiKeyAuthenticator')) {
      definition = {
        api_key: {
          type: 'apiKey',
          name: service.authenticator.apiKeyParameterName,
          in: service.authenticator.apiKeyLocation
        }
      }
    } else if (service.authenticator instanceof _o('./security/HttpBasicAuthenticator')) {
      definition = {
        basic: {
          type: 'basic'
        }
      }
    }

    return definition
  }

})
<|endoftext|>


<commit_before>/* eslint-env browser */
'use strict'

let	d3 = require('d3'),
	tntTree = require('tnt.tree'),
	parser = require('tnt.newick')

let currentState = 'vertical',
	scaled = true, // Default: Scaling is on.
	scaleFactor = 0.85

/**
 * Updates the back-end layout property of the tree to vertical display.
 *
 * @param {any} tree The tree to be modified.
 */
function updateVertical(tree) {
	tree.layout(tntTree.layout.vertical().width(window.innerWidth * scaleFactor))
	currentState = 'vertical'
}

/**
 * Updates the back-end layout property of the tree to radial display.
 *
 * @param {any} tree The tree to be modified.
 */
function updateRadial(tree) {
	tree.layout(tntTree.layout.radial().width(Math.min(window.innerWidth * scaleFactor, window.innerHeight * scaleFactor)))
	currentState = 'radial'
}

/**
 * Toggles on/off the scaling of the tree and changes the text in the controlBar to
 * correspond with this change. Also updates all related local variables.
 *
 * @param {any} tree The tree to be modified.
 */
function updateScale(tree) {
	let textUpdate = d3.select('.scalingOption')
	if (currentState === 'vertical' && scaled === false) {
		tree.layout(tntTree.layout.vertical().width(window.innerWidth * scaleFactor)
			.scale(true))
		tree.update()
		scaled = true
		textUpdate.text('Turn Off Scaling')
	}
	else if (currentState === 'radial' && scaled === false) {
		tree.layout(tntTree.layout.radial().width(Math.min(window.innerWidth * scaleFactor, window.innerHeight * scaleFactor))
			.scale(true))
		tree.update()
		scaled = true
		textUpdate.text('Turn Off Scaling')
	}
	else if (currentState === 'vertical' && scaled === true) {
		tree.layout(tntTree.layout.vertical().width(window.innerWidth * scaleFactor)
			.scale(false))
		tree.update()
		scaled = false
		textUpdate.text('Turn On Scaling')
	}
	else {
		tree.layout(tntTree.layout.radial().width(Math.min(window.innerWidth * scaleFactor, window.innerHeight * scaleFactor))
			.scale(false))
		tree.update()
		scaled = false
		textUpdate.text('Turn On Scaling')
	}
}

// Exporting the following functions for use in phylogician.js:
exports.updateVertical = updateVertical
exports.updateRadial = updateRadial
exports.updateScale = updateScale
<commit_msg>removed unnecessary variable<commit_after>/* eslint-env browser */
'use strict'

let	d3 = require('d3'),
	tntTree = require('tnt.tree')

let currentState = 'vertical',
	scaled = true, // Default: Scaling is on.
	scaleFactor = 0.85

/**
 * Updates the back-end layout property of the tree to vertical display.
 *
 * @param {any} tree The tree to be modified.
 */
function updateVertical(tree) {
	tree.layout(tntTree.layout.vertical().width(window.innerWidth * scaleFactor))
	currentState = 'vertical'
}

/**
 * Updates the back-end layout property of the tree to radial display.
 *
 * @param {any} tree The tree to be modified.
 */
function updateRadial(tree) {
	tree.layout(tntTree.layout.radial().width(Math.min(window.innerWidth * scaleFactor, window.innerHeight * scaleFactor)))
	currentState = 'radial'
}

/**
 * Toggles on/off the scaling of the tree and changes the text in the controlBar to
 * correspond with this change. Also updates all related local variables.
 *
 * @param {any} tree The tree to be modified.
 */
function updateScale(tree) {
	let textUpdate = d3.select('.scalingOption')
	if (currentState === 'vertical' && scaled === false) {
		tree.layout(tntTree.layout.vertical().width(window.innerWidth * scaleFactor)
			.scale(true))
		tree.update()
		scaled = true
		textUpdate.text('Turn Off Scaling')
	}
	else if (currentState === 'radial' && scaled === false) {
		tree.layout(tntTree.layout.radial().width(Math.min(window.innerWidth * scaleFactor, window.innerHeight * scaleFactor))
			.scale(true))
		tree.update()
		scaled = true
		textUpdate.text('Turn Off Scaling')
	}
	else if (currentState === 'vertical' && scaled === true) {
		tree.layout(tntTree.layout.vertical().width(window.innerWidth * scaleFactor)
			.scale(false))
		tree.update()
		scaled = false
		textUpdate.text('Turn On Scaling')
	}
	else {
		tree.layout(tntTree.layout.radial().width(Math.min(window.innerWidth * scaleFactor, window.innerHeight * scaleFactor))
			.scale(false))
		tree.update()
		scaled = false
		textUpdate.text('Turn On Scaling')
	}
}

// Exporting the following functions for use in phylogician.js:
exports.updateVertical = updateVertical
exports.updateRadial = updateRadial
exports.updateScale = updateScale
<|endoftext|>


<commit_before>/**
 * Simple HTTP Server
 *
 * Author: phen
 *
 * @param {Object} opts
 * @param {Object} appLifeCycle - handle different life cycle phases for registering requests to the express app instance
 * @param {function} appLifeCycle.phase1 - executed before the files listener is attached
 * @param {function} appLifeCycle.fileFilter - filter for files and folders which will not be send to client (return file name or undefined to filter out)
 * @param {function} appLifeCycle.onUploadFile - listener will be called if file is successfully saves on file system
 * @param {function} appLifeCycle.onDeleteFile - listener will be called if file is successfully deleted from file system
 * @returns {function}
 */
function main(opts, appLifeCycle) {

    var fs = require('fs'),
        folderUtil = require('./lib/folderUtil'),
        express = require('express'),
        busboy = require('connect-busboy'),
        serveIndex = require('serve-index'),
        thumbNail = require('./lib/thumbNail')(opts.fileStorageName, 'tmb_'),
        app,
        finalhandler = require('finalhandler'),
        serveStatic = require('serve-static'),
        serve = serveStatic(opts.dirName),
        index = serveIndex(opts.dirName, {'icons': true}),
        acceptedImageExtensions = ['jpeg', 'jpg', 'png', 'gif'];

    app = express();
    app.use(busboy());

    app.get(['/dist/*'], function (req, res) {
        var done = finalhandler(req, res);
        serve(req, res, function onNext(err) {
            if (err) {
                return done(err);
            }
            index(req, res, done);
        });
    });

    app.get('/files*', function (req, res) {
        console.log('app:files*');
        var done = finalhandler(req, res);
        serve(req, res, function onNext(err) {
            if (err) {
                return done(err);
            }
            index(req, res, done);
        });
    });

    appLifeCycle && appLifeCycle.phase1 && appLifeCycle.phase1(app);

    /**
     * match except for folder dist
     *
     * If the URL has a dot inside it expect to send a files. Otherwise it sends the index.
     */
    app.get(/^((?!^(\/dist)).)*$/, function (req, res) {
        if (/\./.test(req.path)) {
            // contains a . - looks like a file request so check the files system
            fs.exists(opts.fileStorageName + req.path, function (exists) {
                if (exists) {
                    // not sure if it is good by default but - needs to be configurable
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

                    if (/\?tmb/.test(req.url)) {

                        thumbNail.create(req.path, function (file) {
                            if (file) {
                                res.sendFile(file);
                            } else {
                                res.sendFile(opts.fileStorageName + req.path);
                            }
                        });

                    } else {
                        res.sendFile(opts.fileStorageName + req.path, {dotfiles : 'allow'});
                    }
                } else {
                    // no file found - send 404 file
                    res.sendFile(opts.dirName + '404.html');
                }
            });

        } else {
            // send index
            res.sendFile(opts.dirName + 'index.html');

        }
    });

    app.post('/uploadFile', function (req, res) {
        var fstream, folder = folderUtil.formatFolder(req.query.folder);

        req.pipe(req.busboy);
        req.busboy.on('file', function (fieldname, file, filename) {
            // replace all spaces with underscores
            // TODO it's not a good idea to rename file - because there are people they put spaces in a file name
            var fName = filename; //.split(' ').join('_');

            function writeFile() {

                fstream = fs.createWriteStream(opts.fileStorageName + folder + fName);
                file.pipe(fstream);
                fstream.on('close', function () {
                    // TODO add correct type
                    var extension = fName.split('.').pop();
                    if (acceptedImageExtensions.indexOf(extension) !== -1) {
                        res.status(200).send({file: folder + fName, name: fName, type: 'image/jpg'});
                    } else {
                        res.status(200).send({file: folder + fName, name: fName, type: extension});
                    }
                });
            }

            appLifeCycle && appLifeCycle.onUploadFile && appLifeCycle.onUploadFile(req, {
                    rootFolder : opts.fileStorageName,
                    fileName : folder + fName
                });
            folderUtil.createFolder(opts.fileStorageName, folder, writeFile);
        });
    });

    /**
     * get all available files
     */
    app.post('/getFiles', function (req, res) {
        var folder = '';

        req.on("data", function (chunk) {
            folder += chunk.toString();
            console.log('app:getFiles folder', folder);
        });

        req.on("end", function () {
            folder = folderUtil.formatFolder(folder);
            fs.readdir(opts.fileStorageName + folder, function (err, files) {

                var fileList = [],
                    length;

                if (err === null) {
                    files = files.filter(function (fileName) {
                        return fileName.split('/').pop().startsWith('tmb_') ? undefined : fileName
                    });
                    if (appLifeCycle && appLifeCycle.fileFilter) {
                        files = files.filter(appLifeCycle.fileFilter);
                    }
                    length = files.length;
                    files.forEach(function (file) {
                        fs.stat(opts.fileStorageName + folder + file, function (err, stats) {
                            if (stats.isFile()) {
                                // TODO add correct type
                                var extension = file.split('.').pop();

                                if (acceptedImageExtensions.indexOf(extension) !== -1) {
                                    fileList.push({file: folder + file, name: file, type: 'image/jpg'});
                                } else {
                                    fileList.push({file: folder + file, name: file, type: extension});
                                }
                            } else if (stats.isDirectory()) {
                                // filter out directories - if we need directories we should ask separately for it
                                console.log('Found a directory named:', file);
                            }
                            length--;
                            if (length <= 0) {
                                res.status(200).send(fileList);
                            }
                        });
                    });
                }
            });
        });
    });

    /**
     * get all available folders
     */
    app.post('/getFolders', function (req, res) {
        // get a list of all folders
        var folder = '';

        req.on("data", function (chunk) {
            folder += chunk.toString();
        });

        req.on("end", function () {
            folder = folderUtil.formatFolder(folder);
            fs.readdir(opts.fileStorageName + folder, function (err, files) {
                var fileList = [],
                    length;

                if (err === null) {
                    length = files.length;
                    files.forEach(function (file) {
                        fs.stat(opts.fileStorageName + folder + file, function (err, stats) {
                            if (err) {
                                console.log("app:path not exists:", err);
                                return;
                            }
                            if (stats.isDirectory()) {
                                fileList.push(file);
                            }
                            length--;
                            if (length <= 0) {
                                res.status(200).send(fileList);
                            }
                        });
                    });
                }
            });
        });
    });

    /**
     * delete a file
     */
    app.post('/deleteFile', function (req, res) {
        var fileName;
        if (req.query.hasOwnProperty('filename')) {
            console.log('app:deleteFile', req.query.filename);
            fileName = req.query.filename;
            if (fileName[0] !== '/') {
                fileName = '/' + fileName;
            }
            fs.unlink(opts.fileStorageName + fileName, function () {
                appLifeCycle && appLifeCycle.onDeleteFile && appLifeCycle.onDeleteFile(req, {
                    rootFolder : opts.fileStorageName,
                    fileName : fileName
                });
                res.status(200).send(req.query.filename);
            });
            thumbNail.remove(fileName);
        } else {
            res.status(200).send(false);
        }
    });

    return app;
}

module.exports = main;<commit_msg>compare file type extension lower case<commit_after>/**
 * Simple HTTP Server
 *
 * Author: phen
 *
 * @param {Object} opts
 * @param {Object} appLifeCycle - handle different life cycle phases for registering requests to the express app instance
 * @param {function} appLifeCycle.phase1 - executed before the files listener is attached
 * @param {function} appLifeCycle.fileFilter - filter for files and folders which will not be send to client (return file name or undefined to filter out)
 * @param {function} appLifeCycle.onUploadFile - listener will be called if file is successfully saves on file system
 * @param {function} appLifeCycle.onDeleteFile - listener will be called if file is successfully deleted from file system
 * @returns {function}
 */
function main(opts, appLifeCycle) {

    var fs = require('fs'),
        folderUtil = require('./lib/folderUtil'),
        express = require('express'),
        busboy = require('connect-busboy'),
        serveIndex = require('serve-index'),
        thumbNail = require('./lib/thumbNail')(opts.fileStorageName, 'tmb_'),
        app,
        finalhandler = require('finalhandler'),
        serveStatic = require('serve-static'),
        serve = serveStatic(opts.dirName),
        index = serveIndex(opts.dirName, {'icons': true}),
        acceptedImageExtensions = ['jpeg', 'jpg', 'png', 'gif'];

    app = express();
    app.use(busboy());

    app.get(['/dist/*'], function (req, res) {
        var done = finalhandler(req, res);
        serve(req, res, function onNext(err) {
            if (err) {
                return done(err);
            }
            index(req, res, done);
        });
    });

    app.get('/files*', function (req, res) {
        console.log('app:files*');
        var done = finalhandler(req, res);
        serve(req, res, function onNext(err) {
            if (err) {
                return done(err);
            }
            index(req, res, done);
        });
    });

    appLifeCycle && appLifeCycle.phase1 && appLifeCycle.phase1(app);

    /**
     * match except for folder dist
     *
     * If the URL has a dot inside it expect to send a files. Otherwise it sends the index.
     */
    app.get(/^((?!^(\/dist)).)*$/, function (req, res) {
        if (/\./.test(req.path)) {
            // contains a . - looks like a file request so check the files system
            fs.exists(opts.fileStorageName + req.path, function (exists) {
                if (exists) {
                    // not sure if it is good by default but - needs to be configurable
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

                    if (/\?tmb/.test(req.url)) {

                        thumbNail.create(req.path, function (file) {
                            if (file) {
                                res.sendFile(file);
                            } else {
                                res.sendFile(opts.fileStorageName + req.path);
                            }
                        });

                    } else {
                        res.sendFile(opts.fileStorageName + req.path, {dotfiles : 'allow'});
                    }
                } else {
                    // no file found - send 404 file
                    res.sendFile(opts.dirName + '404.html');
                }
            });

        } else {
            // send index
            res.sendFile(opts.dirName + 'index.html');

        }
    });

    app.post('/uploadFile', function (req, res) {
        var fstream, folder = folderUtil.formatFolder(req.query.folder);

        req.pipe(req.busboy);
        req.busboy.on('file', function (fieldname, file, filename) {
            // replace all spaces with underscores
            // TODO it's not a good idea to rename file - because there are people they put spaces in a file name
            var fName = filename; //.split(' ').join('_');

            function writeFile() {

                fstream = fs.createWriteStream(opts.fileStorageName + folder + fName);
                file.pipe(fstream);
                fstream.on('close', function () {
                    // TODO add correct type
                    var extension = fName.split('.').pop();
                    if (extension && acceptedImageExtensions.indexOf(extension.toLowerCase()) !== -1) {
                        res.status(200).send({file: folder + fName, name: fName, type: 'image/jpg'});
                    } else {
                        res.status(200).send({file: folder + fName, name: fName, type: extension});
                    }
                });
            }

            appLifeCycle && appLifeCycle.onUploadFile && appLifeCycle.onUploadFile(req, {
                    rootFolder : opts.fileStorageName,
                    fileName : folder + fName
                });
            folderUtil.createFolder(opts.fileStorageName, folder, writeFile);
        });
    });

    /**
     * get all available files
     */
    app.post('/getFiles', function (req, res) {
        var folder = '';

        req.on("data", function (chunk) {
            folder += chunk.toString();
            console.log('app:getFiles folder', folder);
        });

        req.on("end", function () {
            folder = folderUtil.formatFolder(folder);
            fs.readdir(opts.fileStorageName + folder, function (err, files) {

                var fileList = [],
                    length;

                if (err === null) {
                    files = files.filter(function (fileName) {
                        return fileName.split('/').pop().startsWith('tmb_') ? undefined : fileName
                    });
                    if (appLifeCycle && appLifeCycle.fileFilter) {
                        files = files.filter(appLifeCycle.fileFilter);
                    }
                    length = files.length;
                    files.forEach(function (file) {
                        fs.stat(opts.fileStorageName + folder + file, function (err, stats) {
                            if (stats.isFile()) {
                                // TODO add correct type
                                var extension = file.split('.').pop();

                                if (extension && acceptedImageExtensions.indexOf(extension.toLowerCase()) !== -1) {
                                    fileList.push({file: folder + file, name: file, type: 'image/jpg'});
                                } else {
                                    fileList.push({file: folder + file, name: file, type: extension});
                                }
                            } else if (stats.isDirectory()) {
                                // filter out directories - if we need directories we should ask separately for it
                                console.log('Found a directory named:', file);
                            }
                            length--;
                            if (length <= 0) {
                                res.status(200).send(fileList);
                            }
                        });
                    });
                }
            });
        });
    });

    /**
     * get all available folders
     */
    app.post('/getFolders', function (req, res) {
        // get a list of all folders
        var folder = '';

        req.on("data", function (chunk) {
            folder += chunk.toString();
        });

        req.on("end", function () {
            folder = folderUtil.formatFolder(folder);
            fs.readdir(opts.fileStorageName + folder, function (err, files) {
                var fileList = [],
                    length;

                if (err === null) {
                    length = files.length;
                    files.forEach(function (file) {
                        fs.stat(opts.fileStorageName + folder + file, function (err, stats) {
                            if (err) {
                                console.log("app:path not exists:", err);
                                return;
                            }
                            if (stats.isDirectory()) {
                                fileList.push(file);
                            }
                            length--;
                            if (length <= 0) {
                                res.status(200).send(fileList);
                            }
                        });
                    });
                }
            });
        });
    });

    /**
     * delete a file
     */
    app.post('/deleteFile', function (req, res) {
        var fileName;
        if (req.query.hasOwnProperty('filename')) {
            console.log('app:deleteFile', req.query.filename);
            fileName = req.query.filename;
            if (fileName[0] !== '/') {
                fileName = '/' + fileName;
            }
            fs.unlink(opts.fileStorageName + fileName, function () {
                appLifeCycle && appLifeCycle.onDeleteFile && appLifeCycle.onDeleteFile(req, {
                    rootFolder : opts.fileStorageName,
                    fileName : fileName
                });
                res.status(200).send(req.query.filename);
            });
            thumbNail.remove(fileName);
        } else {
            res.status(200).send(false);
        }
    });

    return app;
}

module.exports = main;<|endoftext|>


<commit_before>'use strict'
// require
const { app, BrowserWindow, protocol, ipcMain } = require('electron')
const path = require('path')
const url = require('url')
const fs = require('fs')

//open server
require('./server/app.js')

// const
const dirname = '__dirname'
const PATH_DATA = JSON.parse(fs.readFileSync('./screen_info.json', 'utf-8'))

// global
let win

app.on('ready', () => {
  protocol.interceptFileProtocol('file', (req, callback) => {
    let requrl = req.url.substr(7)

    // ルート以下の1番目を抽出
    if(requrl.split('/')[1] === dirname) {
      // /__dirnameをパース
      requrl = requrl.replace(/\/__dirname/, __dirname)
    }
    // ノーマライズして返す
    callback(path.normalize(requrl))
  })
})

function createWindow(){
  win = new BrowserWindow({
    'width': 1200,
    'height': 800,
    'icon': __dirname + '/resource/img/icon@128px.png',
  })

  win.loadURL(url.format({
    pathname: __dirname + PATH_DATA.splash_path,
    protocol: 'file:',
    slashes: true,
  }))

  win.on('closed', () => {
    win = null
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if(process.platform !== 'darwin'){
    app.quit()
  }
})

app.on('activate', () => {
  if(win === null){
    createWindow()
  }
})

ipcMain.on(PATH_DATA.event, (event, req) => {
  switch(req){
    case PATH_DATA.edit_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.edit_path,
        protocol: 'file:',
        slashes: true,
      }))
      break
    case PATH_DATA.main_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.main_path,
        protocol: 'file:',
        slashes: true,
      }))
      break
    case PATH_DATA.pdf_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.pdf_path,
        protocol: 'file:',
        slashes: true,
      }))
      break
    case PATH_DATA.settings_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.settings_path,
        protocol: 'file:',
        slashes: true,
    }))
    break
  }
})
<commit_msg>add URLパラメータ除去<commit_after>'use strict'
// require
const { app, BrowserWindow, protocol, ipcMain } = require('electron')
const path = require('path')
const url = require('url')
const fs = require('fs')

//open server
require('./server/app.js')

// const
const dirname = '__dirname'
const PATH_DATA = JSON.parse(fs.readFileSync('./screen_info.json', 'utf-8'))

// global
let win

app.on('ready', () => {
  protocol.interceptFileProtocol('file', (req, callback) => {
    let requrl = req.url.substr(7)

    // ルート以下の1番目を抽出
    if(requrl.split('/')[1] === dirname) {
      // /__dirnameをパース
      requrl = requrl.replace(/\/__dirname/, __dirname)
      // URLパラメータを除去
      requrl = requrl.replace(/\?.*/, '')
    }
    // ノーマライズして返す
    callback(path.normalize(requrl))
  })
})

function createWindow(){
  win = new BrowserWindow({
    'width': 1200,
    'height': 800,
    'icon': __dirname + '/resource/img/icon@128px.png',
  })

  win.loadURL(url.format({
    pathname: __dirname + PATH_DATA.splash_path,
    protocol: 'file:',
    slashes: true,
  }))

  win.on('closed', () => {
    win = null
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if(process.platform !== 'darwin'){
    app.quit()
  }
})

app.on('activate', () => {
  if(win === null){
    createWindow()
  }
})

ipcMain.on(PATH_DATA.event, (event, req) => {
  switch(req){
    case PATH_DATA.edit_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.edit_path,
        protocol: 'file:',
        slashes: true,
      }))
      break
    case PATH_DATA.main_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.main_path,
        protocol: 'file:',
        slashes: true,
      }))
      break
    case PATH_DATA.pdf_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.pdf_path,
        protocol: 'file:',
        slashes: true,
      }))
      break
    case PATH_DATA.settings_path:
      win.loadURL(url.format({
        pathname: __dirname + PATH_DATA.settings_path,
        protocol: 'file:',
        slashes: true,
    }))
    break
  }
})
<|endoftext|>


<commit_before>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

//CREATE WELCOME TEXT
var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 8 )
{
  groet = "Goeiemorgen 🌝.  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else
if ( myDate.getHours() >8 )
{
  groet = "Goeiemorgen 🌝 ";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag 🌞";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17&& myDate.getHours() <= 20 )
{
groet = "Goedenavond 🌙";
}
else
if (myDate.getHours() > 20  || myDate.getHours() <= 24 )
{
  groet = "Goedenavond 🌙  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom. ";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
        .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
        .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter)`))
        .then(() => bot.say (`%[Nieuwe hypotheek](postback:hypotheektype_nieuw) `))
        .then(() => bot.say (`%[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
        .then(() => 'speak');
    }
},

  speak: {
          receive: (bot, message) => {

              const upperText = message.text.trim();

              function updateSilent() {
                  switch (upperText) {
                      //THE MORTGAGE STUFF
                      case 'Hoi':
                            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
                            .then(() => 'woningType')
                          break;
                      case 'Starters Hypotheek':
                          return bot.say(`Wat voor type woning zoek je? `)
                          .then(() => bot.say(`%[🏬 Appartement](postback:hypotheekkeuze_appartement) %[🏠 Huis](postback:hypotheekkeuze_huis) %[📭 Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
                          .then(() =>  'woningType')
                              break;
                      case 'Nieuwe hypotheek':
                          return bot.say(`😞 Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
                          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[💼 Zoek Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/jelocatie.aspx)`))
                            .then(() => 'finish')
                          break;
                      case 'Hypotheek oversluiten':
                          return bot.say(`😟 Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
                          .then(()=> bot.say(`Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja, dat wil ik wel](postback:update_ja) %[Nee, dat hoeft niet](postback:update_nee)`))
                            .then(() => 'updateOntvangen')
                          break;
                      //THE REST
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              //CHECK INPUT  FLOW
              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  //BASICALLY ERROR OR NO TXT
                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      } //END OF SPEAK

      woningType(){

      }

});
<commit_msg>script<commit_after>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

//CREATE WELCOME TEXT
var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 8 )
{
  groet = "Goeiemorgen 🌝.  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else
if ( myDate.getHours() >8 )
{
  groet = "Goeiemorgen 🌝 ";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag 🌞";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17&& myDate.getHours() <= 20 )
{
groet = "Goedenavond 🌙";
}
else
if (myDate.getHours() > 20  || myDate.getHours() <= 24 )
{
  groet = "Goedenavond 🌙  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom. ";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
        .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
        .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter)`))
        .then(() => bot.say (`%[Nieuwe hypotheek](postback:hypotheektype_nieuw) `))
        .then(() => bot.say (`%[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
        .then(() => 'speak');
    }
}

  speak: {
          receive: (bot, message) => {

              const upperText = message.text.trim();

              function updateSilent() {
                  switch (upperText) {
                      //THE MORTGAGE STUFF
                      case 'Hoi':
                            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
                            .then(() => 'woningType');
                      case 'Starters Hypotheek':
                          return bot.say(`Wat voor type woning zoek je? `)
                          .then(() => bot.say(`%[🏬 Appartement](postback:hypotheekkeuze_appartement) %[🏠 Huis](postback:hypotheekkeuze_huis) %[📭 Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
                          .then(() =>  'woningType');
                      case 'Nieuwe hypotheek':
                          return bot.say(`😞 Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
                          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[💼 Zoek Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/jelocatie.aspx)`))
                            .then(() => 'finish');
                      case 'Hypotheek oversluiten':
                          return bot.say(`😟 Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
                          .then(()=> bot.say(`Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja, dat wil ik wel](postback:update_ja) %[Nee, dat hoeft niet](postback:update_nee)`))
                            .then(() => 'updateOntvangen');
                      //THE REST
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              };

              function getSilent() {
                  return bot.getProp("silent");
              };
              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }  //END OF SPEAK

});
<|endoftext|>


<commit_before>function fetchExecution(instructions, pc, cycle, branchPredictor) {
	this.setStepInstruction(instructions[pc]);
	this.setStepInstructionCycle(cycle);

	var btbResult;
	let fetchI = this.getStepInstruction();

	if(fetchI && fetchI.type === DATA_TYPES.CONTROL && fetchI.cycle === cycle)
	{//preciso executar se eu tiver um preditor ativo e se a instrucao for de branch
		branchPredictorResult = branchPredictor.predict(fetchI);//branchPredictorResult recebe endereco de previsao se houver
		console.log("predictor result is: " + branchPredictorResult);
        fetchI.btbResult = branchPredictorResult !== undefined;
    }
	else
	{
		console.log("predictor result is: dont see branch");
		branchPredictorResult = undefined;
	}
	return branchPredictorResult;
}

function decodeExecution(dh) {
    var instruction = this.getStepInstruction();
    if (instruction && dh) {
        dh.insert(instruction);
    }
}

function loadExecution() {
    let instruction = this.getStepInstruction();
    instruction.executedCycles++;
}

function executeExecution(branchPredictor) {

	var branchDestination = -1;
	let instruction = this.getStepInstruction();

	if(instruction && instruction.type === DATA_TYPES.ARITHMETIC)
	{
		instruction.result = instruction.executethis();
		//console.log("T0: ", instruction.params.dest);
	}

	if (instruction && instruction.type === DATA_TYPES.CONTROL) {
		if (instruction.name === "BRANCH IF ZERO") {
			instruction.executethis();
			branchPredictor.update(instruction, instruction.params.branchResult);
		}
		//console.log(instruction.params.branchResult);
		if (instruction.params.branchResult)
		{
			branchDestination = instruction.params.branchTo;

		}
    }
}

function storeExecution(dataMemory, dh) {

	let instruction = this.getStepInstruction();

	if(instruction && instruction.result != undefined && instruction.type === DATA_TYPES.ARITHMETIC)
	{
		instruction.params.dest.set(instruction.result);
	}
	// Load and Store
	if(instruction && instruction.type === DATA_TYPES.DATA_TRANSFER)
	{
		instruction.executethis(dataMemory);
    }
    if (instruction && dh) {
        dh.wb(instruction);
    }
}

function DummyPipe() {

	const SimplePipe = this;

	var startedFlushingThisCycle;
	var pc = 0;
	var cycle = 0;
	var flushControl = -5;
	var stopFlushControl = -5;
	var executionReturns = -1;
	var fetchI, decodeI, loadI, executeI, storeI;

    this.name = "Dummy Pipeline";
	var containerPipeline = $('

');
	$("#pipelineDivGoesBeneath").append(containerPipeline);

	this.init = function(dataMemory) {
		SimplePipe.dataMemory = dataMemory;
    }

	this.pipeLoop = function(instructions, loopControl, branchPredictor, dependencyHandler)
	{
		console.log("/////////////////////////////////////////");
        let dhRet = dependencyHandler ? dependencyHandler.getExecutables()[0] : null;
        let nextLoadIns = dependencyHandler && decodeI ? ( dhRet === undefined ? new Instruction("NoOp") : dhRet === null ? decodeI : dhRet) : decodeI;
        let stallDecode = nextLoadIns && nextLoadIns.name === "NoOp" && decodeI;

        this.store.setStepInstruction( executeI );
		this.execute.setStepInstruction( loadI );
		this.load.setStepInstruction( nextLoadIns );
		if (!stallDecode) this.decode.setStepInstruction( fetchI );

        /////////////////// execucao das etapas /////////////////////////////
        // var predictionAddr = this.fetch.execution(instructions, pc, cycle, branchPredictor);
        // this.fetch.render(pc);
        // cycle++;
        var predictionAddr;
        if (stallDecode) { SimplePipe.insertNoOp("load"); }
        else {
            predictionAddr = this.fetch.execution(instructions, pc, cycle, branchPredictor)
            this.fetch.render(pc);
        }

		fetchI = this.fetch.getStepInstruction();
		decodeI = this.decode.getStepInstruction();
		loadI = this.load.getStepInstruction();
		executeI = this.execute.getStepInstruction();
		storeI = this.store.getStepInstruction();

       //console.log(fetchI, decodeI, loadI, executeI, storeI);

        //executo fetch, pois ele apenas pega a proxima instrucao da memoria
		if(decodeI && !stallDecode)
		{
			if(decodeI.cycle <= flushControl + 3)
			{}
			else
			{
                console.log("executing decode");
				this.decode.execution(dependencyHandler);
			}
			this.decode.render("fetch", containerPipeline);
		}

		if(loadI)
		{
			if(loadI.cycle <= flushControl + 3)
			{}
			else
			{
				this.load.execution(pc);
				console.log("executing load");
			}
			if (!stallDecode) this.load.render("decode", containerPipeline);
		}

		if(executeI)
		{
			if(executeI.cycle <= flushControl + 3)
			{}
			else
			{
				this.execute.execution(branchPredictor);//execution returns retorna o destino do branch tomado, -1 se nao houverem branchs
				console.log("executing execute");
			}
			this.execute.render("load", containerPipeline);
		}

		if(storeI)
		{
			if(storeI.cycle <= flushControl + 3 && storeI.cycle != flushControl)
			{
                if (dependencyHandler) dependencyHandler.wb(storeI);
            }
			else
			{
				this.store.execution(SimplePipe.dataMemory, dependencyHandler);
				console.log("executing store");
			}
			this.store.render("execute", containerPipeline);
		}

		this.removeHTMLInstruction(600);

		/////////////////// fim da execucao das etapas /////////////////////////////

		 console.log(this.fetch.getStepInstruction());
		 console.log(this.decode.getStepInstruction());
		 console.log(this.load.getStepInstruction());
		 console.log(this.execute.getStepInstruction());
		 console.log(this.store.getStepInstruction());

		//debugger;

		//////pipeline flushing control //////////////////////
		if(executeI && executeI.type === DATA_TYPES.CONTROL &&  !(executeI.cycle <= flushControl + 3) )//deve existir uma instrucao em execute
		{//se houver um branch que errei a previsao, devo dar flush
			if(executeI.params.branchResult !== executeI.btbResult)//e esses enderecos nao forem iguais, errei munha previsao
			{
				//console.log("mistakes were made, flushing pipe");
				flushControl = executeI.cycle;//flush control recebe o ciclo da instrucao de branch q causou o flush
				stopFlushControl = cycle;//recebe o ciclo onde o flush foi iniciado
			}
		}
		if(cycle === stopFlushControl + 4)//passaram-se 3 ciclos desde o inicio do flush, posso parar
		{
			flushControl = -5;
			stopFlushControl = -5;
		}
		//////end of pipeline flushing control //////////////////////
		console.log("flushControl: " + flushControl + " cycle: " + cycle + " stopFlushControl: " + stopFlushControl);
		//////branch & sequential pc control //////////////////////
		if(executeI && executeI.type === DATA_TYPES.CONTROL && (executeI.cycle === flushControl + 4 || flushControl === -5 || executeI.cycle === flushControl) )
		{//execute tem uma instrucao de branch
			console.log("1: was: " + executeI.params.branchResult + " predicted: " + executeI.btbResult);
			if(executeI.params.branchResult === executeI.btbResult)//eu acertei
            {
				if(predictionAddr)
				{// se houver um novo branch em "decode" ele devera ser executado e tento prevejo seu destino
					pc = predictionAddr;
				}
				else
				{//se nao houver especulacoes, procedo sequencialmente
					if (!stallDecode) pc++;
				}
			}
			else
			{//eu errei a previsao
				if(executeI.params.branchResult)//se eu errei pq houve pulo, previ q nao
				{//pula o pc para a instrucao alvo
					pc = executeI.getTargetAddr();
				}
				else
				{//senao pula o pc para + 1
					pc = executeI.address + 1;
				}
			}
		}
		else
		{
            if(executeI && executeI.type === DATA_TYPES.CONTROL)
			{
				console.log("2: was: " + executeI.params.branchResult + " predicted: " + executeI.btbResult);
			}
			if(predictionAddr)
            {
                pc = predictionAddr;
            }
            else
            {
                if (!stallDecode) pc++;
            }
		}
		//////end of branch & sequential pc control //////////////////////

		if(!stallDecode)
			cycle++;

		console.log("pc: " + pc);

		if (!(fetchI || executeI || loadI || decodeI || storeI))
		{
//			console.log("no u");
			clearInterval(loopControl);
		}
	}

	////////////////end of class declaration ///////////////////////////////////////////////////////////////
    this.fetch = new PipelineStep("fetch", fetchExecution);
	this.decode = new PipelineStep("decode", decodeExecution);
	this.load = new PipelineStep("load", loadExecution);
	this.execute = new PipelineStep("execute", executeExecution);
    this.store = new PipelineStep("store", storeExecution);

    // Overwrite fetch render
    this.fetch.render = function(pc) {
        		//var midCol = $("#pipelineDivGoesBeneath");
		//midCol.append(containerPipeline);
        //var pipeline = $('
\n
');//$(".pipeline");
        var instructionList = $("#instructions");
        instructionList.children('.active').removeClass('active');
        // if (pipeSim.fillNoop > 0) {
        //     var instructionElem = $("
NoOp
");
        //     setTimeout(function() {
        //         //elem.detach();
        //         pipeline.append(instructionElem);
        //     }, 100);
        //     return new Instruction("NoOp");
        // }
        // else
        if (pc > -1) {
            var instruction = this.getStepInstruction();
            //console.log(instruction);
            if (!instruction) { return; }
            var instructionElem = $("
" + instruction.name + "
");
                                    //

            //var elem = instructionList.children(":eq(0)");
            //elem.addClass("out");
            var elem = instructionList.children(`:eq(${pc})`);
            elem.addClass('active');
            $("#instructions").animate({
                scrollTop: 42*(pc-1) - 4
            }, 200);
            setTimeout(function() {
                //elem.detach();
                //console.log(containerPipeline);
                containerPipeline.append(instructionElem);
            }, 60);//talvez nao precise de delay
        }
    }

    // Override execute render - change color to success if executed
    this.execute.render = function(prevStep, containerPipeline) {
        var self = this;
        var count =  containerPipeline.children(`.${prevStep}`).length;
        var instruction = containerPipeline.children(`.${prevStep}:eq(0)`);
        var isFlushing = this.getStepInstruction().cycle - flushControl <= 3;
        if (count) {
            setTimeout(function() {
                instruction.removeClass(prevStep);//muda as caracteristicas do html (abaixo) pra passar cada bloquinho para a proxima etapa
                instruction.addClass(self.getStepName());//"
" + instruction.name + "
"
                if (instruction.hasClass("background-info") && !isFlushing) {//background info eh "azul"
                    instruction.removeClass("background-info");//retira o azul do bloquinho e coloca verde
                    instruction.addClass("background-success");//nota: essas cores estao no .css
                }
                else if (instruction.hasClass('background-info') && isFlushing) {
                    instruction.removeClass("background-info");//retira o azul do bloquinho e coloca verde
                    instruction.addClass("background-disabled");//nota: essas cores estao no .css
                }
            }, 80)
        }
    }

    // Remove First element on store step
    this.removeHTMLInstruction = function(delay) {
        var count =  containerPipeline.children(".store").length;
        var instruction = containerPipeline.children(".store:eq(0)");
        var pipeline = $(".pipeline");
        var instructionList = $("#finalList");
        var instructionElem = $("
" + instruction.text() + "
");

        if (instruction.hasClass("background-success")) {
            instructionElem.addClass("list-group-item-success");
        }
        if (instruction.hasClass("background-danger")) {
            instructionElem.addClass("list-group-item-danger");
        }
        if (instruction.hasClass("background-disabled")) {
            instructionElem.addClass("disabled");
        }

        if (count) {
            instruction.addClass("out");
            setTimeout(function() {
                instruction.detach();
                instructionList.append(instructionElem);
                instructionList.animate({
                    scrollTop: instructionList[0].scrollHeight
                }, 200);
            }, delay);
        }
    }

    this.insertNoOp = function(step) {
        let noop = $(`<div class='pipeline-item ${step} background-danger'>NoOp</div>`);
        containerPipeline.append(noop);
    }
}<commit_msg>commit wut<commit_after>function fetchExecution(instructions, pc, cycle, branchPredictor) {
	if(instructions[pc])
	{
		this.setStepInstruction(instructions[pc].copy());
		this.setStepInstructionCycle(cycle);
	}
	else
		this.setStepInstruction(undefined);

	var btbResult;
	let fetchI = this.getStepInstruction();

	if(fetchI && fetchI.type === DATA_TYPES.CONTROL && fetchI.cycle === cycle)
	{//preciso executar se eu tiver um preditor ativo e se a instrucao for de branch
		branchPredictorResult = branchPredictor.predict(fetchI);//branchPredictorResult recebe endereco de previsao se houver
		console.log("predictor result is: " + branchPredictorResult);
        fetchI.btbResult = branchPredictorResult !== undefined;
    }
	else
	{
		console.log("predictor result is: dont see branch");
		branchPredictorResult = undefined;
	}
	return branchPredictorResult;
}

function decodeExecution(dh) {
    var instruction = this.getStepInstruction();
    if (instruction && dh) {
        dh.insert(instruction);
    }
}

function loadExecution() {
    let instruction = this.getStepInstruction();
    instruction.executedCycles++;
}

function executeExecution(branchPredictor) {

	var branchDestination = -1;
	let instruction = this.getStepInstruction();

	if(instruction && instruction.type === DATA_TYPES.ARITHMETIC)
	{
		instruction.result = instruction.executethis();
		//console.log("T0: ", instruction.params.dest);
	}

	if (instruction && instruction.type === DATA_TYPES.CONTROL) {
		if (instruction.name === "BRANCH IF ZERO") {
			instruction.executethis();
			branchPredictor.update(instruction, instruction.params.branchResult);
		}
		//console.log(instruction.params.branchResult);
		if (instruction.params.branchResult)
		{
			branchDestination = instruction.params.branchTo;

		}
    }
}

function storeExecution(dataMemory, dh) {

	let instruction = this.getStepInstruction();

	if(instruction && instruction.result != undefined && instruction.type === DATA_TYPES.ARITHMETIC)
	{
		instruction.params.dest.set(instruction.result);
	}
	// Load and Store
	if(instruction && instruction.type === DATA_TYPES.DATA_TRANSFER)
	{
		instruction.executethis(dataMemory);
    }
    if (instruction && dh) {
        dh.wb(instruction);
    }
}

function DummyPipe() {

	const SimplePipe = this;

	var startedFlushingThisCycle;
	var pc = 0;
	var cycle = 0;
	var flushControl = -5;
	var stopFlushControl = -5;
	var executionReturns = -1;
	var fetchI, decodeI, loadI, executeI, storeI;

    this.name = "Dummy Pipeline";
	var containerPipeline = $('

');
	$("#pipelineDivGoesBeneath").append(containerPipeline);

	this.init = function(dataMemory) {
		SimplePipe.dataMemory = dataMemory;
    }

	this.pipeLoop = function(instructions, loopControl, branchPredictor, dependencyHandler)
	{
		console.log("/////////////////////////////////////////");
        let dhRet = dependencyHandler ? dependencyHandler.getExecutables()[0] : null;
        let nextLoadIns = dependencyHandler && decodeI ? ( dhRet === undefined ? new Instruction("NoOp") : dhRet === null ? decodeI : dhRet) : decodeI;
        let stallDecode = nextLoadIns && nextLoadIns.name === "NoOp" && decodeI;

        this.store.setStepInstruction( executeI );
		this.execute.setStepInstruction( loadI );
		this.load.setStepInstruction( nextLoadIns );
		if (!stallDecode) this.decode.setStepInstruction( fetchI );

        /////////////////// execucao das etapas /////////////////////////////
        // var predictionAddr = this.fetch.execution(instructions, pc, cycle, branchPredictor);
        // this.fetch.render(pc);
        // cycle++;
        var predictionAddr;
        if (stallDecode) { SimplePipe.insertNoOp("load"); }
        else {
            predictionAddr = this.fetch.execution(instructions, pc, cycle, branchPredictor)
            this.fetch.render(pc);
        }

		fetchI = this.fetch.getStepInstruction();
		decodeI = this.decode.getStepInstruction();
		loadI = this.load.getStepInstruction();
		executeI = this.execute.getStepInstruction();
		storeI = this.store.getStepInstruction();

       //console.log(fetchI, decodeI, loadI, executeI, storeI);

        //executo fetch, pois ele apenas pega a proxima instrucao da memoria
		if(decodeI && !stallDecode)
		{
			if(decodeI.cycle <= flushControl + 3)
			{}
			else
			{
                console.log("executing decode");
				this.decode.execution(dependencyHandler);
			}
			this.decode.render("fetch", containerPipeline);
		}

		if(loadI)
		{
			if(loadI.cycle <= flushControl + 3)
			{}
			else
			{
				this.load.execution(pc);
				console.log("executing load");
			}
			if (!stallDecode) this.load.render("decode", containerPipeline);
		}

		if(executeI)
		{
			if(executeI.cycle <= flushControl + 3)
			{}
			else
			{
				this.execute.execution(branchPredictor);//execution returns retorna o destino do branch tomado, -1 se nao houverem branchs
				console.log("executing execute");
			}
			this.execute.render("load", containerPipeline);
		}

		if(storeI)
		{
			if(storeI.cycle <= flushControl + 3 && storeI.cycle != flushControl)
			{
                if (dependencyHandler) dependencyHandler.wb(storeI);
            }
			else
			{
				this.store.execution(SimplePipe.dataMemory, dependencyHandler);
				console.log("executing store");
			}
			this.store.render("execute", containerPipeline);
		}

		this.removeHTMLInstruction(600);

		/////////////////// fim da execucao das etapas /////////////////////////////

		 console.log(this.fetch.getStepInstruction());
		 console.log(this.decode.getStepInstruction());
		 console.log(this.load.getStepInstruction());
		 console.log(this.execute.getStepInstruction());
		 console.log(this.store.getStepInstruction());

		//debugger;

		//////pipeline flushing control //////////////////////
		if(executeI && executeI.type === DATA_TYPES.CONTROL &&  !(executeI.cycle <= flushControl + 3) )//deve existir uma instrucao em execute
		{//se houver um branch que errei a previsao, devo dar flush
			if(executeI.params.branchResult !== executeI.btbResult)//e esses enderecos nao forem iguais, errei munha previsao
			{
				//console.log("mistakes were made, flushing pipe");
				flushControl = executeI.cycle;//flush control recebe o ciclo da instrucao de branch q causou o flush
				stopFlushControl = cycle;//recebe o ciclo onde o flush foi iniciado
			}
		}
		if(cycle === stopFlushControl + 4)//passaram-se 3 ciclos desde o inicio do flush, posso parar
		{
			flushControl = -5;
			stopFlushControl = -5;
		}
		//////end of pipeline flushing control //////////////////////
		console.log("flushControl: " + flushControl + " cycle: " + cycle + " stopFlushControl: " + stopFlushControl);
		//////branch & sequential pc control //////////////////////
		if(executeI && executeI.type === DATA_TYPES.CONTROL && (executeI.cycle === flushControl + 4 || flushControl === -5 || executeI.cycle === flushControl) )
		{//execute tem uma instrucao de branch
			console.log("1: was: " + executeI.params.branchResult + " predicted: " + executeI.btbResult);
			if(executeI.params.branchResult === executeI.btbResult)//eu acertei
            {
				if(predictionAddr)
				{// se houver um novo branch em "decode" ele devera ser executado e tento prevejo seu destino
					pc = predictionAddr;
				}
				else
				{//se nao houver especulacoes, procedo sequencialmente
					if (!stallDecode) pc++;
				}
			}
			else
			{//eu errei a previsao
				if(executeI.params.branchResult)//se eu errei pq houve pulo, previ q nao
				{//pula o pc para a instrucao alvo
					pc = executeI.getTargetAddr();
				}
				else
				{//senao pula o pc para + 1
					pc = executeI.address + 1;
				}
			}
		}
		else
		{
            if(executeI && executeI.type === DATA_TYPES.CONTROL)
			{
				console.log("2: was: " + executeI.params.branchResult + " predicted: " + executeI.btbResult);
			}
			if(predictionAddr)
            {
                pc = predictionAddr;
            }
            else
            {
                if (!stallDecode) pc++;
            }
		}
		//////end of branch & sequential pc control //////////////////////

		if(!stallDecode)
			cycle++;

		console.log("pc: " + pc);

		if (!(fetchI || executeI || loadI || decodeI || storeI))
		{
//			console.log("no u");
			clearInterval(loopControl);
		}
	}

	////////////////end of class declaration ///////////////////////////////////////////////////////////////
    this.fetch = new PipelineStep("fetch", fetchExecution);
	this.decode = new PipelineStep("decode", decodeExecution);
	this.load = new PipelineStep("load", loadExecution);
	this.execute = new PipelineStep("execute", executeExecution);
    this.store = new PipelineStep("store", storeExecution);

    // Overwrite fetch render
    this.fetch.render = function(pc) {
        		//var midCol = $("#pipelineDivGoesBeneath");
		//midCol.append(containerPipeline);
        //var pipeline = $('
\n
');//$(".pipeline");
        var instructionList = $("#instructions");
        instructionList.children('.active').removeClass('active');
        // if (pipeSim.fillNoop > 0) {
        //     var instructionElem = $("
NoOp
");
        //     setTimeout(function() {
        //         //elem.detach();
        //         pipeline.append(instructionElem);
        //     }, 100);
        //     return new Instruction("NoOp");
        // }
        // else
        if (pc > -1) {
            var instruction = this.getStepInstruction();
            //console.log(instruction);
            if (!instruction) { return; }
            var instructionElem = $("
" + instruction.name + "
");
                                    //

            //var elem = instructionList.children(":eq(0)");
            //elem.addClass("out");
            var elem = instructionList.children(`:eq(${pc})`);
            elem.addClass('active');
            $("#instructions").animate({
                scrollTop: 42*(pc-1) - 4
            }, 200);
            setTimeout(function() {
                //elem.detach();
                //console.log(containerPipeline);
                containerPipeline.append(instructionElem);
            }, 60);//talvez nao precise de delay
        }
    }

    // Override execute render - change color to success if executed
    this.execute.render = function(prevStep, containerPipeline) {
        var self = this;
        var count =  containerPipeline.children(`.${prevStep}`).length;
        var instruction = containerPipeline.children(`.${prevStep}:eq(0)`);
        var isFlushing = this.getStepInstruction().cycle - flushControl <= 3;
        if (count) {
            setTimeout(function() {
                instruction.removeClass(prevStep);//muda as caracteristicas do html (abaixo) pra passar cada bloquinho para a proxima etapa
                instruction.addClass(self.getStepName());//"
" + instruction.name + "
"
                if (instruction.hasClass("background-info") && !isFlushing) {//background info eh "azul"
                    instruction.removeClass("background-info");//retira o azul do bloquinho e coloca verde
                    instruction.addClass("background-success");//nota: essas cores estao no .css
                }
                else if (instruction.hasClass('background-info') && isFlushing) {
                    instruction.removeClass("background-info");//retira o azul do bloquinho e coloca verde
                    instruction.addClass("background-disabled");//nota: essas cores estao no .css
                }
            }, 80)
        }
    }

    // Remove First element on store step
    this.removeHTMLInstruction = function(delay) {
        var count =  containerPipeline.children(".store").length;
        var instruction = containerPipeline.children(".store:eq(0)");
        var pipeline = $(".pipeline");
        var instructionList = $("#finalList");
        var instructionElem = $("
" + instruction.text() + "
");

        if (instruction.hasClass("background-success")) {
            instructionElem.addClass("list-group-item-success");
        }
        if (instruction.hasClass("background-danger")) {
            instructionElem.addClass("list-group-item-danger");
        }
        if (instruction.hasClass("background-disabled")) {
            instructionElem.addClass("disabled");
        }

        if (count) {
            instruction.addClass("out");
            setTimeout(function() {
                instruction.detach();
                instructionList.append(instructionElem);
                instructionList.animate({
                    scrollTop: instructionList[0].scrollHeight
                }, 200);
            }, delay);
        }
    }

    this.insertNoOp = function(step) {
        let noop = $(`<div class='pipeline-item ${step} background-danger'>NoOp</div>`);
        containerPipeline.append(noop);
    }
}<|endoftext|>


<commit_before>/*
 * 0xtrades.info
 * https://github.com/vsergeev/0xtrades.info
 *
 * Copyright (c) 2017 Ivan (Vanya) A. Sergeev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/******************************************************************************/
/* Constants */
/******************************************************************************/

var ERRORS = {
  GET_NETWORK_ID:       1,
  GET_BLOCK_HEIGHT:     2,
  UNSUPPORTED_NETWORK:  3,
};

var ZEROEX_GENESIS_BLOCK = {
  1: 4145578,
  42: 4145578,
};

var ZEROEX_RELAY_ADDRESSES = {
  1: {
    "0xa258b39954cef5cb142fd567a46cddb31a670124": "Radar Relay",
    "0xeb71bad396acaa128aeadbc7dbd59ca32263de01": "Kin Alpha",
    "0xc22d5b2951db72b44cfb8089bb8cd374a3c354ea": "OpenRelay",
  },
  42: {
    "0xa258b39954cef5cb142fd567a46cddb31a670124": "Radar Relay",
  },
};

/* Populated by model */
var ZEROEX_TOKEN_INFOS = {
    /* Pre-load some newer token infos */
    "0x8f8221afbb33998d8584a2b05749ba73c37a938a": {
      name: "Request",
      symbol: "REQ",
      decimals: 18,
    },
    "0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a": {
      name: "Populous Platform",
      symbol: "PPT",
      decimals: 8,
    },
    "0xab16e0d25c06cb376259cc18c1de4aca57605589": {
      name: "FinallyUsableCryptoKarma",
      symbol: "FUCK",
      decimals: 4,
    },
    "0x0e0989b1f9b8a38983c2ba8053269ca62ec9b195": {
      name: "Po.et",
      symbol: "POE",
      decimals: 8,
    },
    "0x8ae4bf2c33a8e667de34b54938b0ccd03eb8cc06": {
      name: "Patientory",
      symbol: "PTOY",
      decimals: 8,
    },
    "0x0f5d2fb29fb7d3cfee444a200298f468908cc942": {
      name: "Decentraland MANA",
      symbol: "MANA",
      decimals: 18,
    },
    "0xea38eaa3c86c8f9b751533ba2e562deb9acded40": {
      name: "Fuel Token",
      symbol: "FUEL",
      decimals: 18,
    },
    "0xf970b8e36e23f7fc3fd752eea86f8be8d83375a6": {
      name: "Ripio Credit Network Token",
      symbol: "RCN",
      decimals: 18,
    },
    "0x386467f1f3ddbe832448650418311a479eecfc57": {
      name: "Embers",
      symbol: "EMB",
      decimals: 0,
    },
    "0x814964b1bceaf24e26296d031eadf134a2ca4105": {
      name: "Newbium",
      symbol: "NEWB",
      decimals: 0,
    },
    "0x2fd41f516fac94ed08e156f489f56ca3a80b04d0": {
      name: "eBTC",
      symbol: "EBTC",
      decimals: 8,
    },
    "0x99ea4db9ee77acd40b119bd1dc4e33e1c070b80d": {
      name: "Quantstamp Token",
      symbol: "QSP",
      decimals: 18,
    },
    "0x56ba2ee7890461f463f7be02aac3099f6d5811a8": {
      name: "BlockCAT Token",
      symbol: "CAT",
      decimals: 18,
    },
    "0x24692791bc444c5cd0b81e3cbcaba4b04acd1f3b": {
      name: "UnikoinGold",
      symbol: "UKG",
      decimals: 18,
    },
};

/* Populated by model */
var ZEROEX_EXCHANGE_ADDRESS = null;

/* Populated by model */
var ZEROEX_TOKEN_ADDRESS = null;

var NETWORK_NAME = {
  1: "Mainnet",
  3: "Ropsten",
  4: "Rinkeby",
  42: "Kovan",
};

var NETWORK_BLOCK_EXPLORER = {
  1: "https://etherscan.io",
  3: "https://ropsten.etherscan.io",
  4: "https://rinkeby.etherscan.io",
  42: "https://kovan.etherscan.io",
};

var PRICE_API_URL = function (symbols, base) {
  return "https://min-api.cryptocompare.com/data/pricemulti?fsyms=" + symbols.join(',') + "&tsyms=" + base;
};

var INFURA_API_URL = "https://mainnet.infura.io/rdkuEWbeKAjSR9jZ6P1h";

var ZEROEX_PORTAL_URL = "https://0xproject.com/portal";

var STATISTICS_TIME_WINDOW = 86400; /* 24 hours */

var BLOCK_FETCH_COUNT = Math.ceil(STATISTICS_TIME_WINDOW/17);

var BLOCK_INFO_RETRY_TIMEOUT = 15*1000;

var PRICE_UPDATE_TIMEOUT = 5*60*1000;

var PRICE_CHART_DEFAULT_PAIR = "ZRX/WETH";

var CHART_DEFAULT_COLORS = ['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c', '#98df8a',
                            '#d62728', '#ff9896', '#9467bd', '#c5b0d5', '#8c564b', '#c49c94',
                            '#e377c2', '#f7b6d2', '#7f7f7f', '#c7c7c7', '#bcbd22', '#dbdb8d',
                            '#17becf', '#9edae5'];

var CHART_DEFAULT_TOOLTIP_CALLBACK = function (item, data) {
  var label = data.labels[item.index];
  var value = data.datasets[item.datasetIndex].tooltips[item.index] || data.datasets[item.datasetIndex].data[item.index];
  return label + ": " + value;
};

/* From http://www.localeplanet.com/api/auto/currencymap.json */
var FIAT_CURRENCY_MAP = {
  "USD": {
    "symbol": "$",
    "symbol_native": "$",
    "decimal_digits": 2,
    "rounding": 0,
    "code": "USD"
  },
  "EUR": {
    "symbol": "€",
    "symbol_native": "€",
    "decimal_digits": 2,
    "rounding": 0,
    "code": "EUR"
  },
  "GBP": {
    "symbol": "£",
    "symbol_native": "£",
    "decimal_digits": 2,
    "rounding": 0,
    "code": "GBP"
  },
  "JPY": {
    "symbol": "¥",
    "symbol_native": "￥",
    "decimal_digits": 0,
    "rounding": 0,
    "code": "JPY"
  },
  "KRW": {
    "symbol": "₩",
    "symbol_native": "₩",
    "decimal_digits": 0,
    "rounding": 0,
    "code": "KRW"
  },
};

var FIAT_CURRENCY_DEFAULT = "USD";
<commit_msg>constants: add TIX token to token infos<commit_after>/*
 * 0xtrades.info
 * https://github.com/vsergeev/0xtrades.info
 *
 * Copyright (c) 2017 Ivan (Vanya) A. Sergeev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/******************************************************************************/
/* Constants */
/******************************************************************************/

var ERRORS = {
  GET_NETWORK_ID:       1,
  GET_BLOCK_HEIGHT:     2,
  UNSUPPORTED_NETWORK:  3,
};

var ZEROEX_GENESIS_BLOCK = {
  1: 4145578,
  42: 4145578,
};

var ZEROEX_RELAY_ADDRESSES = {
  1: {
    "0xa258b39954cef5cb142fd567a46cddb31a670124": "Radar Relay",
    "0xeb71bad396acaa128aeadbc7dbd59ca32263de01": "Kin Alpha",
    "0xc22d5b2951db72b44cfb8089bb8cd374a3c354ea": "OpenRelay",
  },
  42: {
    "0xa258b39954cef5cb142fd567a46cddb31a670124": "Radar Relay",
  },
};

/* Populated by model */
var ZEROEX_TOKEN_INFOS = {
    /* Pre-load some newer token infos */
    "0x8f8221afbb33998d8584a2b05749ba73c37a938a": {
      name: "Request",
      symbol: "REQ",
      decimals: 18,
    },
    "0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a": {
      name: "Populous Platform",
      symbol: "PPT",
      decimals: 8,
    },
    "0xab16e0d25c06cb376259cc18c1de4aca57605589": {
      name: "FinallyUsableCryptoKarma",
      symbol: "FUCK",
      decimals: 4,
    },
    "0x0e0989b1f9b8a38983c2ba8053269ca62ec9b195": {
      name: "Po.et",
      symbol: "POE",
      decimals: 8,
    },
    "0x8ae4bf2c33a8e667de34b54938b0ccd03eb8cc06": {
      name: "Patientory",
      symbol: "PTOY",
      decimals: 8,
    },
    "0x0f5d2fb29fb7d3cfee444a200298f468908cc942": {
      name: "Decentraland MANA",
      symbol: "MANA",
      decimals: 18,
    },
    "0xea38eaa3c86c8f9b751533ba2e562deb9acded40": {
      name: "Fuel Token",
      symbol: "FUEL",
      decimals: 18,
    },
    "0xf970b8e36e23f7fc3fd752eea86f8be8d83375a6": {
      name: "Ripio Credit Network Token",
      symbol: "RCN",
      decimals: 18,
    },
    "0x386467f1f3ddbe832448650418311a479eecfc57": {
      name: "Embers",
      symbol: "EMB",
      decimals: 0,
    },
    "0x814964b1bceaf24e26296d031eadf134a2ca4105": {
      name: "Newbium",
      symbol: "NEWB",
      decimals: 0,
    },
    "0x2fd41f516fac94ed08e156f489f56ca3a80b04d0": {
      name: "eBTC",
      symbol: "EBTC",
      decimals: 8,
    },
    "0x99ea4db9ee77acd40b119bd1dc4e33e1c070b80d": {
      name: "Quantstamp Token",
      symbol: "QSP",
      decimals: 18,
    },
    "0x56ba2ee7890461f463f7be02aac3099f6d5811a8": {
      name: "BlockCAT Token",
      symbol: "CAT",
      decimals: 18,
    },
    "0x24692791bc444c5cd0b81e3cbcaba4b04acd1f3b": {
      name: "UnikoinGold",
      symbol: "UKG",
      decimals: 18,
    },
    "0xea1f346faf023f974eb5adaf088bbcdf02d761f4": {
      name: "Blocktix Token",
      symbol: "TIX",
      decimals: 18,
    },
};

/* Populated by model */
var ZEROEX_EXCHANGE_ADDRESS = null;

/* Populated by model */
var ZEROEX_TOKEN_ADDRESS = null;

var NETWORK_NAME = {
  1: "Mainnet",
  3: "Ropsten",
  4: "Rinkeby",
  42: "Kovan",
};

var NETWORK_BLOCK_EXPLORER = {
  1: "https://etherscan.io",
  3: "https://ropsten.etherscan.io",
  4: "https://rinkeby.etherscan.io",
  42: "https://kovan.etherscan.io",
};

var PRICE_API_URL = function (symbols, base) {
  return "https://min-api.cryptocompare.com/data/pricemulti?fsyms=" + symbols.join(',') + "&tsyms=" + base;
};

var INFURA_API_URL = "https://mainnet.infura.io/rdkuEWbeKAjSR9jZ6P1h";

var ZEROEX_PORTAL_URL = "https://0xproject.com/portal";

var STATISTICS_TIME_WINDOW = 86400; /* 24 hours */

var BLOCK_FETCH_COUNT = Math.ceil(STATISTICS_TIME_WINDOW/17);

var BLOCK_INFO_RETRY_TIMEOUT = 15*1000;

var PRICE_UPDATE_TIMEOUT = 5*60*1000;

var PRICE_CHART_DEFAULT_PAIR = "ZRX/WETH";

var CHART_DEFAULT_COLORS = ['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c', '#98df8a',
                            '#d62728', '#ff9896', '#9467bd', '#c5b0d5', '#8c564b', '#c49c94',
                            '#e377c2', '#f7b6d2', '#7f7f7f', '#c7c7c7', '#bcbd22', '#dbdb8d',
                            '#17becf', '#9edae5'];

var CHART_DEFAULT_TOOLTIP_CALLBACK = function (item, data) {
  var label = data.labels[item.index];
  var value = data.datasets[item.datasetIndex].tooltips[item.index] || data.datasets[item.datasetIndex].data[item.index];
  return label + ": " + value;
};

/* From http://www.localeplanet.com/api/auto/currencymap.json */
var FIAT_CURRENCY_MAP = {
  "USD": {
    "symbol": "$",
    "symbol_native": "$",
    "decimal_digits": 2,
    "rounding": 0,
    "code": "USD"
  },
  "EUR": {
    "symbol": "€",
    "symbol_native": "€",
    "decimal_digits": 2,
    "rounding": 0,
    "code": "EUR"
  },
  "GBP": {
    "symbol": "£",
    "symbol_native": "£",
    "decimal_digits": 2,
    "rounding": 0,
    "code": "GBP"
  },
  "JPY": {
    "symbol": "¥",
    "symbol_native": "￥",
    "decimal_digits": 0,
    "rounding": 0,
    "code": "JPY"
  },
  "KRW": {
    "symbol": "₩",
    "symbol_native": "₩",
    "decimal_digits": 0,
    "rounding": 0,
    "code": "KRW"
  },
};

var FIAT_CURRENCY_DEFAULT = "USD";
<|endoftext|>