<commit_before>
/*
 * subdomain middleware
 * keep shipping next()
 */

module.exports = function(options) {

  // options?
  options = options || {};

  if (!options.base) {
    throw new Error('options.base required!');
  } else {
    options.removeWWW = options.removeWWW || false;
    options.debug = options.debug || false;
    options.ignoreWWW = options.ignoreWWW || false;
  };

  // return middleware
  return function(request, response, next) {

    // get host & protocol
    var host = request.headers.host
      , protocol = request.socket.encrypted ? 'https' : 'http';

    // remove 'www' prefix from URL? (tacky, right?)
    if (options.removeWWW === true) {
      if (/^www/.test(host)) {
        return response.redirect(protocol + '://' + host.replace(/^www\./, '') + request.url);
      };
    };

    // subdomain specific middleware
    if (host === options.base || host === 'localhost:8000') {
      // not a subdomain
      next();
    } else {
      if(options.ignoreWWW && /^www\./.test(host)){
        return next();
      }
      // test for subdomain
      var matches = host.match(new RegExp('(.*)\.' + options.base));
      // subdomain
      if (matches && matches.length === 2) {
        request.url = '/subdomain/' + matches[1] + request.url;
        next();
      } else {
        next();
      }
    };
  };

};
<commit_msg>added ignore logic to first if instead of adding a nested condition<commit_after>
/*
 * subdomain middleware
 * keep shipping next()
 */

module.exports = function(options) {

  // options?
  options = options || {};

  if (!options.base) {
    throw new Error('options.base required!');
  } else {
    options.removeWWW = options.removeWWW || false;
    options.debug = options.debug || false;
    options.ignoreWWW = options.ignoreWWW || false;
  };

  // return middleware
  return function(request, response, next) {

    // get host & protocol
    var host = request.headers.host
      , protocol = request.socket.encrypted ? 'https' : 'http';

    // remove 'www' prefix from URL? (tacky, right?)
    if (options.removeWWW === true) {
      if (/^www/.test(host)) {
        return response.redirect(protocol + '://' + host.replace(/^www\./, '') + request.url);
      };
    };

    // subdomain specific middleware
    if (host === options.base || host === 'localhost:8000'
        || (options.ignoreWWW && /^www\./.test(host))) {
      // not a subdomain or ignoring www subdomain
      next();
    } else {
      // test for subdomain
      var matches = host.match(new RegExp('(.*)\.' + options.base));
      // subdomain
      if (matches && matches.length === 2) {
        request.url = '/subdomain/' + matches[1] + request.url;
        next();
      } else {
        next();
      }
    };
  };

};
<|endoftext|>


<commit_before>const readline = require('readline')
const EventEmitter = require('events')

class Cli extends EventEmitter {

  constructor (options) {
    super()
    this.name = options.name
    process.title = this.name
    this.pid = process.pid
    this.version = options.version
    this.default = options.command || options.default

    this.command = undefined
    this.arguments = []
    this.options = {}

    this.setupEvents()
  }

  setupEvents () {
    this.events = {
      exit: [],
      missing: []
    }

    process.on('exit', () => this.trigger('exit'))
    process.on('SIGINT', () => this.exit())
  }

  start () {
    this.getArguments()
    this.trigger((this.command || this.default), this.arguments)
  }

  getArguments () {
    delete process.argv[0] // node
    delete process.argv[1] // script
    process.argv.forEach((arg, index) => {
      if (this.arguments.length === 0 && this.command === undefined && arg[0] !== '-') {
        this.command = arg
        return
      }

      if (arg[0] === '-') {
        if (arg.indexOf('=') !== -1) {
          this.options[arg.split('=')[0] + '='] = arg.split('=')[1]
        } else {
          if (arg[1] === '-') {
            this.options[arg] = true
            return
          }

          var chars = arg.replace('-', '').split('')
          for (let char of chars) {
            this.options['-' + char] = true
          }
        }
        return
      }

      this.arguments.push(arg)
    })
  }

  on (commands, callback) {
    if (typeof commands === 'string') {
      commands = [commands]
    }

    for (let command of commands) {
      if (this.events[command] === undefined) {
        this.events[command] = []
      }

      this.events[command].push(callback)
    }

    return this
  }

  trigger (command, args) {
    if (this.events[command] === undefined) {
      return this.trigger('missing')
    }

    for (let event of this.events[command]) {
      event.apply(this, args)
    }

    return this
  }

  has (options) {
    if (typeof options === 'string') {
      options = [options]
    }

    for (let option of options) {
      if (this.options[option] !== undefined) {
        return this.options[option]
      }
    }

    return false
  }

  missing (callback) {
    this.on('missing', callback)
    return this
  }

  static prompt (question, callback) {
    return new Promise((resolve, reject) => {
      const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
      })

      rl.question(question + ' ', (result) => {
        resolve(result)
        rl.close()
      })
    })
  }

  exit (code) {
    process.exit(code)
  }

}

module.exports = Cli
<commit_msg>Set process title automaticly or specify it by the title option<commit_after>const readline = require('readline')
const EventEmitter = require('events')

class Cli extends EventEmitter {

  constructor (options = {}) {
    super()
    this.pid = process.pid

    this.command = undefined
    this.arguments = []
    this.options = options

    this.setProcessTitle()
    this.setupEvents()
  }

  /**
   * Setup process events
   * @private
   */
  setupEvents () {
    process.on('exit', () => this.emit('exit'))
    process.on('SIGINT', () => this.exit())
  }

  /**
   * Set the process title by options or give it the script name
   * @private
   */
  setProcessTitle () {
    let title = process.argv[1].split('/')[process.argv[1].split('/').length-1]
    process.title = this.options.title || title
  }

  /**
   * Run
   * @public
   */
  run () {
    this.parseArguments()
    this.emit((this.command || this.default), ...this.arguments)
  }

  /**
   * Parse arguments
   * @private
   */
  parseArguments () {
    let args = process.argv
    delete args[0]
    delete args[1]
    args.forEach((arg, index) => {
      if (this.arguments.length === 0 && this.command === undefined && arg[0] !== '-') {
        this.command = arg
        return
      }

      if (arg[0] === '-') {
        if (arg.indexOf('=') !== -1) {
          this.options[arg.split('=')[0] + '='] = arg.split('=')[1]
        } else {
          if (arg[1] === '-') {
            this.options[arg] = true
            return
          }

          var chars = arg.replace('-', '').split('')
          for (let char of chars) {
            this.options['-' + char] = true
          }
        }
        return
      }

      this.arguments.push(arg)
    })
  }

  /**
   * Has options
   * TODO change options param to ...options instead of an array
   * @public
   */
  has (options) {
    if (typeof options === 'string') {
      options = [options]
    }

    for (let option of options) {
      if (this.options[option] !== undefined) {
        return this.options[option]
      }
    }

    return false
  }

  /**
   * Promt for a question
   * @public
   */
  prompt (question, callback) {
    return new Promise((resolve, reject) => {
      const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
      })

      rl.question(question + ' ', (result) => {
        resolve(result)
        rl.close()
      })
    })
  }

  /**
   * Exit script
   * @public
   */
  exit (code) {
    process.exit(code)
  }

}

module.exports = Cli
<|endoftext|>


<commit_before>// IO status/error codes used by RPC and HTTP servers

exports.OK                  = 200;
exports.REDIRECT            = 302;
exports.NOT_MODIFIED        = 304;
exports.BAD_REQUEST         = 400;
exports.NOT_AUTHORIZED      = 401;
exports.NOT_FOUND           = 404;
exports.CLIENT_ERROR        = 460;
exports.INVALID_CSRF_TOKEN  = 461;
exports.APP_ERROR           = 500;
exports.ECOMMUNICATION      = 1000;
exports.EWRONGVER           = 1001;
<commit_msg>Added missed use strict<commit_after>// IO status/error codes used by RPC and HTTP servers
'use strict';

exports.OK                  = 200;
exports.REDIRECT            = 302;
exports.NOT_MODIFIED        = 304;
exports.BAD_REQUEST         = 400;
exports.NOT_AUTHORIZED      = 401;
exports.NOT_FOUND           = 404;
exports.CLIENT_ERROR        = 460;
exports.INVALID_CSRF_TOKEN  = 461;
exports.APP_ERROR           = 500;
exports.ECOMMUNICATION      = 1000;
exports.EWRONGVER           = 1001;
<|endoftext|>


<commit_before>var util = require('util') // Native Node util module
  , path = require('path')
  , EventEmitter = require('events').EventEmitter
  , Task
  , TaskBase
  , utils = require('../utils')
  , async = require('async')
  , rule; // Lazy-require this at the bottom

var UNDEFINED_VALUE;

/**
  @name jake
  @namespace jake
*/
/**
  @name jake.Task
  @constructor
  @augments EventEmitter
  @description A Jake Task

  @param {String} name The name of the Task
  @param {Array} [prereqs] Prerequisites to be run before this task
  @param {Function} [action] The action to perform for this task
  @param {Object} [opts]
    @param {Array} [opts.asyc=false] Perform this task asynchronously.
    If you flag a task with this option, you must call the global
    `complete` method inside the task's action, for execution to proceed
    to the next task.
 */
Task = function () {
  // Do constructor-work only on actual instances, not when used
  // for inheritance
  if (arguments.length) {
    this.init.apply(this, arguments);
  }
};

util.inherits(Task, EventEmitter);

TaskBase = new (function () {

  // Parse any positional args attached to the task-name
  var parsePrereqName = function (name) {
        var taskArr = name.split('[')
          , taskName = taskArr[0]
          , taskArgs = [];
        if (taskArr[1]) {
          taskArgs = taskArr[1].replace(/\]$/, '');
          taskArgs = taskArgs.split(',');
        }
        return {
          name: taskName
        , args: taskArgs
        };
      };

  /**
    @name jake.Task#event:complete
    @event
   */

  this.init = function (name, prereqs, action, options) {
    var opts = options || {};

    this._currentPrereqIndex = 0;

    this.name = name;
    this.prereqs = prereqs;
    this.action = action;
    this.async = false;
    this.done = false;
    this.fullName = null;
    this.description = null;
    this.args = [];
    this.value = UNDEFINED_VALUE;
    this.namespace = null;

    // Support legacy async-flag -- if not explicitly passed or falsy, will
    // be set to empty-object
    if (typeof opts == 'boolean' && opts === true) {
      this.async = true;
    }
    else {
      if (opts.async) {
        this.async = true;
      }
      if (opts.runparallel) {
        this.runparallel = opts.runparallel;
      }
    }
  };

  /**
    @name jake.Task#invoke
    @function
    @description Runs prerequisites, then this task. If the task has already
    been run, will not run the task again.
   */
  this.invoke = function () {
    jake._invocationChain.push(this);
    this.args = Array.prototype.slice.call(arguments);
    this.runPrereqs();
  };

  /**
    @name jake.Task#execute
    @function
    @description Runs prerequisites, then this task. If the task has already
    been run, will not run the task again.
   */
  this.execute = function () {
    jake._invocationChain.push(this);
    this.args = Array.prototype.slice.call(arguments);
    this.reenable();
    this.run();
  };

  this.runPrereqs = function () {
    if (this.prereqs && this.prereqs.length) {
      if(this.runparallel > 1) {
        console.log("Run prereqs for '"+this.name+"' in parallel", this.prereqs);
        var currenttask = this;
        async.eachLimit(currenttask.prereqs,currenttask.runparallel,function(name, cb) {

          parsed = parsePrereqName(name);

          prereq = currenttask.namespace.resolveTask(parsed.name) ||
          jake.attemptRule(name, currenttask.namespace, 0) ||
          jake.createPlaceholderFileTask(name, currenttask.namespace);

          if (!prereq) {
            throw new Error('Unknown task "' + name + '"');
          }

          if (prereq.done) {
            //prereq already done, return
            cb();
          } else {
            //wait for complete before calling cb
            prereq.once('complete', function () {
              cb();
            });
            prereq.invoke.apply(prereq, parsed.args);
          }
        }, function(err) {
          //async callback is called after all prereqs have run.
          console.log("All prereqs for task '"+currenttask.name+"' done.");
          currenttask.run();
        });
      } else {
        this.nextPrereq();
      }
    }
    else {
      this.run();
    }
  };

  this.nextPrereq = function () {
    var self = this
      , index = this._currentPrereqIndex
      , name = this.prereqs[index]
      , prereq
      , parsed
      , filePath
      , stats;

    if (name) {

      parsed = parsePrereqName(name);

      prereq = this.namespace.resolveTask(parsed.name) ||
          jake.attemptRule(name, this.namespace, 0) ||
          jake.createPlaceholderFileTask(name, this.namespace);

      if (!prereq) {
        throw new Error('Unknown task "' + name + '"');
      }

      // Do when done
      if (prereq.done) {
        self.handlePrereqComplete(prereq);
      } else {
        prereq.once('complete', function () {
          self.handlePrereqComplete(prereq);
        });
        prereq.invoke.apply(prereq, parsed.args);
      }
    }
  };

  /**
    @name jake.Task#reenable
    @function
    @description Reenables a task so that it can be run again.
   */
  this.reenable = function (deep) {
    var prereqs
      , prereq;
    this.done = false;
    this.value = UNDEFINED_VALUE;
    if (deep && this.prereqs) {
      prereqs = this.prereqs;
      for (var i = 0, ii = prereqs.length; i < ii; i++) {
        prereq = jake.Task[prereqs[i]];
        if (prereq) {
          prereq.reenable(deep);
        }
      }
    }
  };

  this.handlePrereqComplete = function (prereq) {
    var self = this;
    this._currentPrereqIndex++;
    if (this._currentPrereqIndex < this.prereqs.length) {
      setTimeout(function () {
        self.nextPrereq();
      }, 0);
    }
    else {
      this.run();
    }
  };

  this.isNeeded = function () {
    if (this.done || typeof this.action != 'function') {
      return false;
    }
    return true;
  };

  this.run = function () {
    var runAction = this.isNeeded()
      , val;

    if (runAction) {
      this.emit('start');
      try {
        val = this.action.apply(this, this.args);

        if (typeof val == 'object' && typeof val.then == 'function') {
          this.async = true;

          val.then(
            function(result) {
              setTimeout(function() {
                  complete(result);
                },
                0);
            },
            function(err) {
              setTimeout(function() {
                  fail(err);
                },
                0);
            });
        }
      }
      catch (e) {
        this.emit('error', e);
        return; // Bail out, not complete
      }
    }
    else {
      this.emit('skip');
    }

    if (!(runAction && this.async)) {
      complete(val);
    }
  };

  this.complete = function (val) {
    //console.log("chain=", jake._invocationChain.map(function(c) {return c.name}));
    //console.log("will remove:", this.name);
    jake._invocationChain.splice(jake._invocationChain.indexOf(this),1);

    this._currentPrereqIndex = 0;
    this.done = true;

    // If 'complete' getting called because task has been
    // run already, value will not be passed -- leave in place
    if (typeof val != 'undefined') {
      this.value = val;
    }

    this.emit('complete', this.value);
  };

})();
utils.mixin(Task.prototype, TaskBase);

Task.getBaseNamespacePath = function (fullName) {
  return fullName.split(':').slice(0, -1).join(':');
};

Task.getBaseTaskName = function (fullName) {
  return fullName.split(':').pop();
};

exports.Task = Task;

// Lazy-require
rule = require('../rule');

<commit_msg>default to 1 parallel dependency<commit_after>var util = require('util') // Native Node util module
  , path = require('path')
  , EventEmitter = require('events').EventEmitter
  , Task
  , TaskBase
  , utils = require('../utils')
  , async = require('async')
  , rule; // Lazy-require this at the bottom

var UNDEFINED_VALUE;

/**
  @name jake
  @namespace jake
*/
/**
  @name jake.Task
  @constructor
  @augments EventEmitter
  @description A Jake Task

  @param {String} name The name of the Task
  @param {Array} [prereqs] Prerequisites to be run before this task
  @param {Function} [action] The action to perform for this task
  @param {Object} [opts]
    @param {Array} [opts.asyc=false] Perform this task asynchronously.
    If you flag a task with this option, you must call the global
    `complete` method inside the task's action, for execution to proceed
    to the next task.
 */
Task = function () {
  // Do constructor-work only on actual instances, not when used
  // for inheritance
  if (arguments.length) {
    this.init.apply(this, arguments);
  }
};

util.inherits(Task, EventEmitter);

TaskBase = new (function () {

  // Parse any positional args attached to the task-name
  var parsePrereqName = function (name) {
        var taskArr = name.split('[')
          , taskName = taskArr[0]
          , taskArgs = [];
        if (taskArr[1]) {
          taskArgs = taskArr[1].replace(/\]$/, '');
          taskArgs = taskArgs.split(',');
        }
        return {
          name: taskName
        , args: taskArgs
        };
      };

  /**
    @name jake.Task#event:complete
    @event
   */

  this.init = function (name, prereqs, action, options) {
    var opts = options || {};

    this._currentPrereqIndex = 0;

    this.name = name;
    this.prereqs = prereqs;
    this.action = action;
    this.async = false;
    this.done = false;
    this.fullName = null;
    this.description = null;
    this.args = [];
    this.value = UNDEFINED_VALUE;
    this.namespace = null;
    this.runparallel = 1;

    // Support legacy async-flag -- if not explicitly passed or falsy, will
    // be set to empty-object
    if (typeof opts == 'boolean' && opts === true) {
      this.async = true;
    }
    else {
      if (opts.async) {
        this.async = true;
      }
      if (opts.runparallel) {
        this.runparallel = opts.runparallel;
      }
    }
  };

  /**
    @name jake.Task#invoke
    @function
    @description Runs prerequisites, then this task. If the task has already
    been run, will not run the task again.
   */
  this.invoke = function () {
    jake._invocationChain.push(this);
    this.args = Array.prototype.slice.call(arguments);
    this.runPrereqs();
  };

  /**
    @name jake.Task#execute
    @function
    @description Runs prerequisites, then this task. If the task has already
    been run, will not run the task again.
   */
  this.execute = function () {
    jake._invocationChain.push(this);
    this.args = Array.prototype.slice.call(arguments);
    this.reenable();
    this.run();
  };

  this.runPrereqs = function () {
    if (this.prereqs && this.prereqs.length) {
      if(this.runparallel > 1) {
        console.log("Run prereqs for '"+this.name+"' in parallel", this.prereqs);
        var currenttask = this;
        async.eachLimit(currenttask.prereqs,currenttask.runparallel,function(name, cb) {

          parsed = parsePrereqName(name);

          prereq = currenttask.namespace.resolveTask(parsed.name) ||
          jake.attemptRule(name, currenttask.namespace, 0) ||
          jake.createPlaceholderFileTask(name, currenttask.namespace);

          if (!prereq) {
            throw new Error('Unknown task "' + name + '"');
          }

          if (prereq.done) {
            //prereq already done, return
            cb();
          } else {
            //wait for complete before calling cb
            prereq.once('complete', function () {
              cb();
            });
            prereq.invoke.apply(prereq, parsed.args);
          }
        }, function(err) {
          //async callback is called after all prereqs have run.
          console.log("All prereqs for task '"+currenttask.name+"' done.");
          currenttask.run();
        });
      } else {
        this.nextPrereq();
      }
    }
    else {
      this.run();
    }
  };

  this.nextPrereq = function () {
    var self = this
      , index = this._currentPrereqIndex
      , name = this.prereqs[index]
      , prereq
      , parsed
      , filePath
      , stats;

    if (name) {

      parsed = parsePrereqName(name);

      prereq = this.namespace.resolveTask(parsed.name) ||
          jake.attemptRule(name, this.namespace, 0) ||
          jake.createPlaceholderFileTask(name, this.namespace);

      if (!prereq) {
        throw new Error('Unknown task "' + name + '"');
      }

      // Do when done
      if (prereq.done) {
        self.handlePrereqComplete(prereq);
      } else {
        prereq.once('complete', function () {
          self.handlePrereqComplete(prereq);
        });
        prereq.invoke.apply(prereq, parsed.args);
      }
    }
  };

  /**
    @name jake.Task#reenable
    @function
    @description Reenables a task so that it can be run again.
   */
  this.reenable = function (deep) {
    var prereqs
      , prereq;
    this.done = false;
    this.value = UNDEFINED_VALUE;
    if (deep && this.prereqs) {
      prereqs = this.prereqs;
      for (var i = 0, ii = prereqs.length; i < ii; i++) {
        prereq = jake.Task[prereqs[i]];
        if (prereq) {
          prereq.reenable(deep);
        }
      }
    }
  };

  this.handlePrereqComplete = function (prereq) {
    var self = this;
    this._currentPrereqIndex++;
    if (this._currentPrereqIndex < this.prereqs.length) {
      setTimeout(function () {
        self.nextPrereq();
      }, 0);
    }
    else {
      this.run();
    }
  };

  this.isNeeded = function () {
    if (this.done || typeof this.action != 'function') {
      return false;
    }
    return true;
  };

  this.run = function () {
    var runAction = this.isNeeded()
      , val;

    if (runAction) {
      this.emit('start');
      try {
        val = this.action.apply(this, this.args);

        if (typeof val == 'object' && typeof val.then == 'function') {
          this.async = true;

          val.then(
            function(result) {
              setTimeout(function() {
                  complete(result);
                },
                0);
            },
            function(err) {
              setTimeout(function() {
                  fail(err);
                },
                0);
            });
        }
      }
      catch (e) {
        this.emit('error', e);
        return; // Bail out, not complete
      }
    }
    else {
      this.emit('skip');
    }

    if (!(runAction && this.async)) {
      complete(val);
    }
  };

  this.complete = function (val) {
    //console.log("chain=", jake._invocationChain.map(function(c) {return c.name}));
    //console.log("will remove:", this.name);
    jake._invocationChain.splice(jake._invocationChain.indexOf(this),1);

    this._currentPrereqIndex = 0;
    this.done = true;

    // If 'complete' getting called because task has been
    // run already, value will not be passed -- leave in place
    if (typeof val != 'undefined') {
      this.value = val;
    }

    this.emit('complete', this.value);
  };

})();
utils.mixin(Task.prototype, TaskBase);

Task.getBaseNamespacePath = function (fullName) {
  return fullName.split(':').slice(0, -1).join(':');
};

Task.getBaseTaskName = function (fullName) {
  return fullName.split(':').pop();
};

exports.Task = Task;

// Lazy-require
rule = require('../rule');

<|endoftext|>


<commit_before>'use strict';
/*global require, module, self*/

(function(module) {
	var templates = {
			cache: {},
			globals: {}
		},
		helpers = {},
		loader,
		worker;

	var regexes = {
		nestedConditionals: /(?!^)<!-- IF([\s\S]*?)ENDIF[ a-zA-Z0-9\._:]*-->(?!$)/gi,
		conditionalBlock: /[\r\n?\n]*?<!-- ELSE -->[\r\n?\n]*?/,
		conditionalHelper: /IF function.([\s\S]*?)-->/i,
		removeTabspace: /^\t*?|^\r\n?\t*?|\t?$|\r\n?\t*?$/g,
		removeWhitespace: /(^[\r\n?|\n]*)|([\r\n\t]*$)/g,
		cleanupEmptyLoops: /\s*<!-- BEGIN([\s\S]*?)END ([\s\S]*?)-->/gi,
		cleanupMissingKeys: /[\r\n]*?\{[a-zA-Z0-9\.]+[\r\n]*?\}/g,
		getUndefinedKeys: /<!-- IF[\s!]*([\s\S]*?)[\s]*-->/gi,
		backReferenceFix: /\$+/g
	};

	if (typeof self !== 'undefined' && self.addEventListener) {
		self.addEventListener('message', function(ev) {
			var data = ev.data;

			self.postMessage({
				result: !data.block ? templates.parse(data.template, data.object) : templates.parse(data.template, data.block, data.object),
				signature: data.signature
			});
		}, false);
	}

	var callbacks = {},
		signature = 0,
		MAX_SAFE_INT = Math.pow(2, 53) - 1;

	templates.setupWebWorker = function(pathToScript) {
		try {
			worker = new Worker(pathToScript);

			worker.addEventListener('message', function(e) {
				callbacks[e.data.signature](e.data.result);
			}, false);
		} catch (err) {}
	};

	function launchWorker(template, obj, block, callback) {
		signature++;
		if (signature > MAX_SAFE_INT) {
			signature = 0;
		}

		worker.postMessage({
			template: template,
			object: obj,
			block: block,
			signature: signature
		});

		callbacks[signature] = function(result) {
			callback(result);
			delete callbacks[signature];
		};
	}

	templates.parse = function(template, block, obj, callback) {
		if (typeof block !== 'string') {
			callback = obj;
			obj = block;
			block = false;
		}

		if (!template) {
			return callback ? callback('') : '';
		}

		obj = registerGlobals(obj || {});

		if (loader && callback) {
			if (!templates.cache[template]) {
				loader(template, function(loaded) {
					templates.cache[template] = loaded;

					launchCallback(loaded, obj, block, callback);
				});
			} else {
				launchCallback(templates.cache[template], obj, block, callback);
			}
		} else if (callback) {
			launchCallback(template, obj, block, callback);
		} else {
			return parseTemplate(block, template, obj);
		}
	};

	function launchCallback(template, obj, block, callback) {
		if (worker) {
			launchWorker(template, obj, block, callback);
		} else {
			callback(parseTemplate(block, template, obj));
		}
	}

	function parseTemplate(block, template, obj) {
		block = !block ? template : templates.getBlock(template, block);
		template = parse(block, obj);

		return parseFunctions(template, template, obj);
	}

	templates.registerHelper = function(name, func) {
		helpers[name] = func;
	};

	templates.registerLoader = function(func) {
		loader = func;
	};

	templates.setGlobal = function(key, value) {
		templates.globals[key] = value;
	};

	templates.getBlock = function(template, block) {
		return template.replace(new RegExp('[\\s\\S]*(<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + block + '[\\s]*-->)[\\s\\S]*', 'g'), '$1');
	};

	templates.flush = function() {
		templates.cache = {};
	};

	function express(filename, options, fn) {
		var fs = require('fs'),
			tpl = filename.replace(options.settings.views + '/', '');

		options._locals = null;

		if (!templates.cache[tpl]) {
			fs.readFile(filename, function(err, html) {
				templates.cache[tpl] = (html || '').toString();
				return fn(err, templates.parse(templates.cache[tpl], options));
			});
		} else {
			return fn(null, templates.parse(templates.cache[tpl], options));
		}
	}

	function replace(string, regex, value) {
		return string.replace(regex, value.toString().replace(regexes.backReferenceFix, '$$$'));
	}

	function replaceValue(template, namespacedKey, value) {
		var string = generateSubspacedRegex(namespacedKey);
		return replace(template, new RegExp('{' + string + '}', 'g'), value);
	}

	function generateSubspacedRegex(namespacedKey) {
		var prefix = '';

		if (namespacedKey.substring(0,1) === '!') {
			prefix = '!';
			namespacedKey = namespacedKey.substring(1);
		}

		var subspace = namespacedKey.split('.'),
			key = subspace.pop(),
			string = [];

		while(subspace.length) {
			string.push(subspace.join('.') + '.');
			subspace.shift();
		}

		string = string ? ('(' + string.join('|') + ')?' + key) : key;
		return prefix + string;
	}

	function makeRegex(block, namespace) {
		namespace = '(' + namespace + ')?';
		return new RegExp('[\\t ]*<!--[\\s]*BEGIN ' + namespace + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + namespace + block + '[\\s]*-->');
	}

	function makeBlockRegex(block, namespace) {
		namespace = '(' + namespace + ')?';
		return new RegExp('([\\t ]*<!--[\\s]*BEGIN ' + namespace + block + '[\\s]*-->[\\r\\n?|\\n]?)|(<!--[\\s]*END ' + namespace + block + '[\\s]*-->)', 'g');
	}

	function makeConditionalRegex(namespacedKey) {
		var block = generateSubspacedRegex(namespacedKey);
		return new RegExp('<!--[\\s]*IF ' + block + '[\\s]*-->([\\s\\S]*?)<!--[\\s]*ENDIF ' + block.split(',')[0] + '[\\s]*-->', 'g');
	}

	function makeStatementRegex(namespacedKey) {
		var key = generateSubspacedRegex(namespacedKey);
		return new RegExp('(<!--[\\s]*IF ' + key + '[\\s]*-->)|(<!--[\\s]*ENDIF ' + key.split(',')[0] + '[\\s]*-->)', 'g');
	}

	function registerGlobals(obj) {
		for (var g in templates.globals) {
			if (templates.globals.hasOwnProperty(g)) {
				obj[g] = obj[g] || templates.globals[g];
			}
		}

		return obj;
	}

	function checkConditionals(template, key, value, dev) {
		return checkConditional(checkConditional(template, '!' + key, !value, dev), key, value, dev);
	}

	function checkConditional(template, key, value, dev) {
		var matches = template.match(makeConditionalRegex(key));

		if (matches !== null) {
			for (var i = 0, ii = matches.length; i < ii; i++) {
				var statement = makeStatementRegex(key),
					nestedConditionals = matches[i].match(regexes.nestedConditionals),
					match = replace(matches[i].replace(statement, ''), regexes.nestedConditionals, '<!-- NESTED -->'),
					conditionalBlock = match.split(regexes.conditionalBlock);

				if (conditionalBlock[1]) {
					// there is an else statement
					template = replace(template, matches[i], replace(conditionalBlock[value ? 0 : 1], regexes.removeWhitespace, ''));
				} else {
					// regular if statement
					template = replace(template, matches[i], value ? replace(match, regexes.removeWhitespace, '') : '');
				}

				if (nestedConditionals) {
					for (var x = 0, xx = nestedConditionals.length; x < xx; x++) {
						template = replace(template, '<!-- NESTED -->', nestedConditionals[x]);
					}
				}
			}
		}

		return template;
	}

	function checkConditionalHelpers(template, obj) {
		var string,
			func;

		while ((string = template.match(regexes.conditionalHelper)) !== null) {
			var fn = string[1].trim(),
				args = fn.split(/[ ]*,[ ]*/);

			func = args[0];

			if (helpers[func]) {
				args.shift();
				args.unshift(obj);
				template = checkConditionals(template, 'function.' + fn, helpers[func].apply(null, args), 'dev');
			} else {
				template = template.replace(makeConditionalRegex('function.' + fn));
			}
		}

		return template;
	}

	function callMethod(method, parameters) {
		return method.apply(templates, parameters);
	}

	function parseFunctions(block, result, obj) {
		var functions = block.match(/{function.*?}/gi, '');
		if (!functions) {
			return result;
		}

		for (var i=0, ii=functions.length; i<ii; ++i) {
			var search = functions[i],
				fn = functions[i].replace('{function.', '').split('}').shift().split(/[ ]*,[ ]*/),
				method = fn.shift(),
				parameters = [];

			if (fn.length) {
				for (var j = 0, jj = fn.length; j < jj; j++) {
					parameters.push(obj[fn[j]]);
				}
			} else {
				parameters = [obj];
			}

			if (helpers[method]) {
				result = replace(result, new RegExp(search, 'gi'), callMethod(helpers[method], parameters));
			}
		}

		return result;
	}

	function parseObject(template, array, key, namespace) {
		return parseArray(template, array, key, namespace, true);
	}

	function parseArray(template, array, key, namespace, isObject) {
		template = checkConditionals(template, namespace  + key + '.length', array[key].length);

		var regex = makeRegex(key, namespace), block, result;

		if (!array[key].length && !isObject) {
			return template.replace(regex, '');
		}

		while ((block = template.match(regex)) !== null) {
			block = block[0].replace(makeBlockRegex(key, namespace), '');
			result = parseArrayBlock(template, block, array[key], namespace + key + '.', isObject);
			template = replace(template, regex, result.replace(regexes.removeWhitespace, ''));
		}

		return template;
	}

	function parseArrayBlock(template, block, array, namespace, isObject) {
		var numblocks = array.length - 1,
			result = '';

		for (var iterator in array) {
			if (array.hasOwnProperty(iterator)) {
				if (!isObject) {
					iterator = parseInt(iterator, 10);
				}

				result += parse(block, array[iterator], namespace);
				if (!isObject) {
					result = checkConditionals(result, '@first', iterator === 0);
					result = checkConditionals(result, '@last', iterator === numblocks);
				}

				result = result
					.replace(regexes.removeTabspace, '');

				if (!isObject) {
					result = result.replace('@index', iterator);
				} else {
					result = result
						.replace('@key', iterator)
						.replace('@value', array[iterator]);
				}

				result = parseFunctions(block, result, array[iterator]);
			}
		}

		return result;
	}

	function parseValue(template, key, value) {
		template = checkConditionals(template, key, value);
		return replaceValue(template, key, value);
	}

	function parse(template, obj, namespace) {
		namespace = namespace || '';

		for (var key in obj) {
			if (obj.hasOwnProperty(key)) {
				if (typeof obj[key] === 'undefined' || typeof obj[key] === 'function') {
					continue;
				} else if (obj[key] === null) {
					template = replaceValue(template, namespace + key, '');
				} else if (obj[key].constructor === Array) {
					template = replaceValue(template, namespace + key + '.length', obj[key].length);
					template = parseArray(template, obj, key, namespace);
				} else if (obj[key] instanceof Object) {
					template = parseObject(template, obj, key, namespace);
					template = checkConditionals(template, key, obj[key]);
					template = parse(template, obj[key], namespace + key + '.');
				} else {
					template = parseValue(template, namespace + key, obj[key]);
				}
			}
		}

		if (namespace) {
			template = template.replace(new RegExp('{' + namespace + '\\.[\\s\\S]*?}', 'g'), '');
			namespace = '';
		} else {
			template = checkConditionalHelpers(template, obj);
			template = cleanup(template);
		}

		return template;
	}

	function cleanup(template) {
		template = template
			.replace(regexes.cleanupEmptyLoops, '')
			.replace(regexes.cleanupMissingKeys, '');

		var undefinedKey,
			undefinedKeys = {},
			parseUndefined;

		while ((undefinedKey = regexes.getUndefinedKeys.exec(template)) !== null) {
			undefinedKeys[undefinedKey[1]] = false;
			parseUndefined = true;
		}

		return parseUndefined ? parse(template, undefinedKeys, '') : template;
	}

	module.exports = templates;
	module.exports.__express = express;

	if ('undefined' !== typeof window) {
		window.templates = module.exports;
	}

})('undefined' === typeof module ? {
	module: {
		exports: {}
	}
} : module);
<commit_msg>removing cleanupMissingKeys<commit_after>'use strict';
/*global require, module, self*/

(function(module) {
	var templates = {
			cache: {},
			globals: {}
		},
		helpers = {},
		loader,
		worker;

	var regexes = {
		nestedConditionals: /(?!^)<!-- IF([\s\S]*?)ENDIF[ a-zA-Z0-9\._:]*-->(?!$)/gi,
		conditionalBlock: /[\r\n?\n]*?<!-- ELSE -->[\r\n?\n]*?/,
		conditionalHelper: /IF function.([\s\S]*?)-->/i,
		removeTabspace: /^\t*?|^\r\n?\t*?|\t?$|\r\n?\t*?$/g,
		removeWhitespace: /(^[\r\n?|\n]*)|([\r\n\t]*$)/g,
		cleanupEmptyLoops: /\s*<!-- BEGIN([\s\S]*?)END ([\s\S]*?)-->/gi,
		cleanupMissingKeys: /[\r\n]*?\{[a-zA-Z0-9\.]+[\r\n]*?\}/g,
		getUndefinedKeys: /<!-- IF[\s!]*([\s\S]*?)[\s]*-->/gi,
		backReferenceFix: /\$+/g
	};

	if (typeof self !== 'undefined' && self.addEventListener) {
		self.addEventListener('message', function(ev) {
			var data = ev.data;

			self.postMessage({
				result: !data.block ? templates.parse(data.template, data.object) : templates.parse(data.template, data.block, data.object),
				signature: data.signature
			});
		}, false);
	}

	var callbacks = {},
		signature = 0,
		MAX_SAFE_INT = Math.pow(2, 53) - 1;

	templates.setupWebWorker = function(pathToScript) {
		try {
			worker = new Worker(pathToScript);

			worker.addEventListener('message', function(e) {
				callbacks[e.data.signature](e.data.result);
			}, false);
		} catch (err) {}
	};

	function launchWorker(template, obj, block, callback) {
		signature++;
		if (signature > MAX_SAFE_INT) {
			signature = 0;
		}

		worker.postMessage({
			template: template,
			object: obj,
			block: block,
			signature: signature
		});

		callbacks[signature] = function(result) {
			callback(result);
			delete callbacks[signature];
		};
	}

	templates.parse = function(template, block, obj, callback) {
		if (typeof block !== 'string') {
			callback = obj;
			obj = block;
			block = false;
		}

		if (!template) {
			return callback ? callback('') : '';
		}

		obj = registerGlobals(obj || {});

		if (loader && callback) {
			if (!templates.cache[template]) {
				loader(template, function(loaded) {
					templates.cache[template] = loaded;

					launchCallback(loaded, obj, block, callback);
				});
			} else {
				launchCallback(templates.cache[template], obj, block, callback);
			}
		} else if (callback) {
			launchCallback(template, obj, block, callback);
		} else {
			return parseTemplate(block, template, obj);
		}
	};

	function launchCallback(template, obj, block, callback) {
		if (worker) {
			launchWorker(template, obj, block, callback);
		} else {
			callback(parseTemplate(block, template, obj));
		}
	}

	function parseTemplate(block, template, obj) {
		block = !block ? template : templates.getBlock(template, block);
		template = parse(block, obj);

		return parseFunctions(template, template, obj);
	}

	templates.registerHelper = function(name, func) {
		helpers[name] = func;
	};

	templates.registerLoader = function(func) {
		loader = func;
	};

	templates.setGlobal = function(key, value) {
		templates.globals[key] = value;
	};

	templates.getBlock = function(template, block) {
		return template.replace(new RegExp('[\\s\\S]*(<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + block + '[\\s]*-->)[\\s\\S]*', 'g'), '$1');
	};

	templates.flush = function() {
		templates.cache = {};
	};

	function express(filename, options, fn) {
		var fs = require('fs'),
			tpl = filename.replace(options.settings.views + '/', '');

		options._locals = null;

		if (!templates.cache[tpl]) {
			fs.readFile(filename, function(err, html) {
				templates.cache[tpl] = (html || '').toString();
				return fn(err, templates.parse(templates.cache[tpl], options));
			});
		} else {
			return fn(null, templates.parse(templates.cache[tpl], options));
		}
	}

	function replace(string, regex, value) {
		return string.replace(regex, value.toString().replace(regexes.backReferenceFix, '$$$'));
	}

	function replaceValue(template, namespacedKey, value) {
		var string = generateSubspacedRegex(namespacedKey);
		return replace(template, new RegExp('{' + string + '}', 'g'), value);
	}

	function generateSubspacedRegex(namespacedKey) {
		var prefix = '';

		if (namespacedKey.substring(0,1) === '!') {
			prefix = '!';
			namespacedKey = namespacedKey.substring(1);
		}

		var subspace = namespacedKey.split('.'),
			key = subspace.pop(),
			string = [];

		while(subspace.length) {
			string.push(subspace.join('.') + '.');
			subspace.shift();
		}

		string = string ? ('(' + string.join('|') + ')?' + key) : key;
		return prefix + string;
	}

	function makeRegex(block, namespace) {
		namespace = '(' + namespace + ')?';
		return new RegExp('[\\t ]*<!--[\\s]*BEGIN ' + namespace + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + namespace + block + '[\\s]*-->');
	}

	function makeBlockRegex(block, namespace) {
		namespace = '(' + namespace + ')?';
		return new RegExp('([\\t ]*<!--[\\s]*BEGIN ' + namespace + block + '[\\s]*-->[\\r\\n?|\\n]?)|(<!--[\\s]*END ' + namespace + block + '[\\s]*-->)', 'g');
	}

	function makeConditionalRegex(namespacedKey) {
		var block = generateSubspacedRegex(namespacedKey);
		return new RegExp('<!--[\\s]*IF ' + block + '[\\s]*-->([\\s\\S]*?)<!--[\\s]*ENDIF ' + block.split(',')[0] + '[\\s]*-->', 'g');
	}

	function makeStatementRegex(namespacedKey) {
		var key = generateSubspacedRegex(namespacedKey);
		return new RegExp('(<!--[\\s]*IF ' + key + '[\\s]*-->)|(<!--[\\s]*ENDIF ' + key.split(',')[0] + '[\\s]*-->)', 'g');
	}

	function registerGlobals(obj) {
		for (var g in templates.globals) {
			if (templates.globals.hasOwnProperty(g)) {
				obj[g] = obj[g] || templates.globals[g];
			}
		}

		return obj;
	}

	function checkConditionals(template, key, value, dev) {
		return checkConditional(checkConditional(template, '!' + key, !value, dev), key, value, dev);
	}

	function checkConditional(template, key, value, dev) {
		var matches = template.match(makeConditionalRegex(key));

		if (matches !== null) {
			for (var i = 0, ii = matches.length; i < ii; i++) {
				var statement = makeStatementRegex(key),
					nestedConditionals = matches[i].match(regexes.nestedConditionals),
					match = replace(matches[i].replace(statement, ''), regexes.nestedConditionals, '<!-- NESTED -->'),
					conditionalBlock = match.split(regexes.conditionalBlock);

				if (conditionalBlock[1]) {
					// there is an else statement
					template = replace(template, matches[i], replace(conditionalBlock[value ? 0 : 1], regexes.removeWhitespace, ''));
				} else {
					// regular if statement
					template = replace(template, matches[i], value ? replace(match, regexes.removeWhitespace, '') : '');
				}

				if (nestedConditionals) {
					for (var x = 0, xx = nestedConditionals.length; x < xx; x++) {
						template = replace(template, '<!-- NESTED -->', nestedConditionals[x]);
					}
				}
			}
		}

		return template;
	}

	function checkConditionalHelpers(template, obj) {
		var string,
			func;

		while ((string = template.match(regexes.conditionalHelper)) !== null) {
			var fn = string[1].trim(),
				args = fn.split(/[ ]*,[ ]*/);

			func = args[0];

			if (helpers[func]) {
				args.shift();
				args.unshift(obj);
				template = checkConditionals(template, 'function.' + fn, helpers[func].apply(null, args), 'dev');
			} else {
				template = template.replace(makeConditionalRegex('function.' + fn));
			}
		}

		return template;
	}

	function callMethod(method, parameters) {
		return method.apply(templates, parameters);
	}

	function parseFunctions(block, result, obj) {
		var functions = block.match(/{function.*?}/gi, '');
		if (!functions) {
			return result;
		}

		for (var i=0, ii=functions.length; i<ii; ++i) {
			var search = functions[i],
				fn = functions[i].replace('{function.', '').split('}').shift().split(/[ ]*,[ ]*/),
				method = fn.shift(),
				parameters = [];

			if (fn.length) {
				for (var j = 0, jj = fn.length; j < jj; j++) {
					parameters.push(obj[fn[j]]);
				}
			} else {
				parameters = [obj];
			}

			if (helpers[method]) {
				result = replace(result, new RegExp(search, 'gi'), callMethod(helpers[method], parameters));
			}
		}

		return result;
	}

	function parseObject(template, array, key, namespace) {
		return parseArray(template, array, key, namespace, true);
	}

	function parseArray(template, array, key, namespace, isObject) {
		template = checkConditionals(template, namespace  + key + '.length', array[key].length);

		var regex = makeRegex(key, namespace), block, result;

		if (!array[key].length && !isObject) {
			return template.replace(regex, '');
		}

		while ((block = template.match(regex)) !== null) {
			block = block[0].replace(makeBlockRegex(key, namespace), '');
			result = parseArrayBlock(template, block, array[key], namespace + key + '.', isObject);
			template = replace(template, regex, result.replace(regexes.removeWhitespace, ''));
		}

		return template;
	}

	function parseArrayBlock(template, block, array, namespace, isObject) {
		var numblocks = array.length - 1,
			result = '';

		for (var iterator in array) {
			if (array.hasOwnProperty(iterator)) {
				if (!isObject) {
					iterator = parseInt(iterator, 10);
				}

				result += parse(block, array[iterator], namespace);
				if (!isObject) {
					result = checkConditionals(result, '@first', iterator === 0);
					result = checkConditionals(result, '@last', iterator === numblocks);
				}

				result = result
					.replace(regexes.removeTabspace, '');

				if (!isObject) {
					result = result.replace('@index', iterator);
				} else {
					result = result
						.replace('@key', iterator)
						.replace('@value', array[iterator]);
				}

				result = parseFunctions(block, result, array[iterator]);
			}
		}

		return result;
	}

	function parseValue(template, key, value) {
		template = checkConditionals(template, key, value);
		return replaceValue(template, key, value);
	}

	function parse(template, obj, namespace) {
		namespace = namespace || '';

		for (var key in obj) {
			if (obj.hasOwnProperty(key)) {
				if (typeof obj[key] === 'undefined' || typeof obj[key] === 'function') {
					continue;
				} else if (obj[key] === null) {
					template = replaceValue(template, namespace + key, '');
				} else if (obj[key].constructor === Array) {
					template = replaceValue(template, namespace + key + '.length', obj[key].length);
					template = parseArray(template, obj, key, namespace);
				} else if (obj[key] instanceof Object) {
					template = parseObject(template, obj, key, namespace);
					template = checkConditionals(template, key, obj[key]);
					template = parse(template, obj[key], namespace + key + '.');
				} else {
					template = parseValue(template, namespace + key, obj[key]);
				}
			}
		}

		if (namespace) {
			template = template.replace(new RegExp('{' + namespace + '\\.[\\s\\S]*?}', 'g'), '');
			namespace = '';
		} else {
			template = checkConditionalHelpers(template, obj);
			template = cleanup(template);
		}

		return template;
	}

	function cleanup(template) {
		template = template
			.replace(regexes.cleanupEmptyLoops, '');
		//.replace(regexes.cleanupMissingKeys, '');

		var undefinedKey,
			undefinedKeys = {},
			parseUndefined;

		while ((undefinedKey = regexes.getUndefinedKeys.exec(template)) !== null) {
			undefinedKeys[undefinedKey[1]] = false;
			parseUndefined = true;
		}

		return parseUndefined ? parse(template, undefinedKeys, '') : template;
	}

	module.exports = templates;
	module.exports.__express = express;

	if ('undefined' !== typeof window) {
		window.templates = module.exports;
	}

})('undefined' === typeof module ? {
	module: {
		exports: {}
	}
} : module);
<|endoftext|>


<commit_before>'use strict'

const urlUtil = require('url')
const pump = require('pump')
const jsonParser = require('body/json')
const validation = require('./validation')
const validateSchema = validation.validate
const serialize = validation.serialize

function bodyParsed (handle, params, req, res) {
  function parsed (err, body) {
    if (err) {
      res.statusCode = 422
      res.end()
      return
    }
    handler(handle, params, req, res, body, null)
  }
  return parsed
}

function routerHandler (node) {
  function handle (params, req, res) {
    const handle = node[req.method]

    if (!handle) {
      res.statusCode = 404
      res.end()
      return
    }

    // Body not required
    if (req.method === 'GET' || req.method === 'DELETE' || req.method === 'HEAD') {
      return handler(handle, params, req, res, null, urlUtil.parse(req.url, true).query)
    }

    // Optional body
    if (req.method === 'OPTIONS') {
      if (req.headers['content-type']) {
        if (req.headers['content-type'] === 'application/json') {
          return jsonParser(req, bodyParsed(handle, params, req, res))
        }
        res.statusCode = 415
        res.end()
        return
      }
      return handler(handle, params, req, res, null, urlUtil.parse(req.url, true).query)
    }

    // Body required
    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      if (req.headers['content-type'] && req.headers['content-type'] === 'application/json') {
        return jsonParser(req, bodyParsed(handle, params, req, res))
      }
      res.statusCode = 415
      res.end()
      return
    }

    res.statusCode = 404
    res.end()
  }
  return handle
}

function build (url, router) {
  const node = {}
  router.on(url, routerHandler(node))

  return node
}

function handler (handle, params, req, res, body, query) {
  if (!handle) {
    res.statusCode = 404
    res.end()
    return
  }

  const valid = validateSchema(handle, params, body, query)
  if (valid !== true) {
    res.statusCode = 400
    res.end(valid)
    return
  }

  const request = new Request(params, req, body, query)
  handle.handler(request, new Reply(res, handle))
}

function Reply (res, handle) {
  this.res = res
  this.handle = handle
}

Reply.prototype.send = function (payload) {
  if (payload instanceof Error) {
    if (!this.res.statusCode) {
      this.res.statusCode = 500
    }
    return this.res.end()
  }

  if (!payload) {
    if (!this.res.statusCode) {
      this.res.statusCode = 204
    }
  }

  if (payload && payload._readableState) {
    if (!this.res.getHeader('Content-Type')) {
      this.res.setHeader('Content-Type', 'application/octet-stream')
    }
    return pump(payload, this.res, err => {
      if (err) this.res.end()
    })
  }

  if (!this.res.getHeader('Content-Type') || this.res.getHeader('Content-Type') === 'application/json') {
    this.res.setHeader('Content-Type', 'application/json')

    const str = serialize(this.handle, payload)
    if (!this.res.getHeader('Content-Length')) {
      this.res.setHeader('Content-Length', Buffer.byteLength(str))
    }
    return this.res.end(str)
  }

  this.res.end(payload)
}

Reply.prototype.header = function (key, value) {
  this.res.setHeader(key, value)
  return this
}

Reply.prototype.code = function (code) {
  this.res.statusCode = code
  return this
}

function Request (params, req, body, query) {
  this.params = params
  this.req = req
  this.body = body
  this.query = query
}

module.exports = build
module.exports[Symbol.for('internals')] = { bodyParsed, routerHandler, Request, handler, Reply }
<commit_msg>First promise support implementation<commit_after>'use strict'

const urlUtil = require('url')
const pump = require('pump')
const jsonParser = require('body/json')
const validation = require('./validation')
const validateSchema = validation.validate
const serialize = validation.serialize

function bodyParsed (handle, params, req, res) {
  function parsed (err, body) {
    if (err) {
      res.statusCode = 422
      res.end()
      return
    }
    handler(handle, params, req, res, body, null)
  }
  return parsed
}

function routerHandler (node) {
  function handle (params, req, res) {
    const handle = node[req.method]

    if (!handle) {
      res.statusCode = 404
      res.end()
      return
    }

    // Body not required
    if (req.method === 'GET' || req.method === 'DELETE' || req.method === 'HEAD') {
      return handler(handle, params, req, res, null, urlUtil.parse(req.url, true).query)
    }

    // Optional body
    if (req.method === 'OPTIONS') {
      if (req.headers['content-type']) {
        if (req.headers['content-type'] === 'application/json') {
          return jsonParser(req, bodyParsed(handle, params, req, res))
        }
        res.statusCode = 415
        res.end()
        return
      }
      return handler(handle, params, req, res, null, urlUtil.parse(req.url, true).query)
    }

    // Body required
    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      if (req.headers['content-type'] && req.headers['content-type'] === 'application/json') {
        return jsonParser(req, bodyParsed(handle, params, req, res))
      }
      res.statusCode = 415
      res.end()
      return
    }

    res.statusCode = 404
    res.end()
  }
  return handle
}

function build (url, router) {
  const node = {}
  router.on(url, routerHandler(node))

  return node
}

function handler (handle, params, req, res, body, query) {
  if (!handle) {
    res.statusCode = 404
    res.end()
    return
  }

  const valid = validateSchema(handle, params, body, query)
  if (valid !== true) {
    res.statusCode = 400
    res.end(valid)
    return
  }

  const request = new Request(params, req, body, query)
  handle.handler(request, new Reply(res, handle))
}

function Reply (res, handle) {
  this.res = res
  this.handle = handle
}

Reply.prototype.send = function (payload) {
  if (payload instanceof Error) {
    if (!this.res.statusCode) {
      this.res.statusCode = 500
    }
    return this.res.end()
  }

  if (payload && typeof payload.then === 'function') {
    return payload.then(wrapSend(this)).catch(wrapSend(this))
  }

  if (!payload) {
    if (!this.res.statusCode) {
      this.res.statusCode = 204
    }
  }

  if (payload && payload._readableState) {
    if (!this.res.getHeader('Content-Type')) {
      this.res.setHeader('Content-Type', 'application/octet-stream')
    }
    return pump(payload, this.res, err => {
      if (err) this.res.end()
    })
  }

  if (!this.res.getHeader('Content-Type') || this.res.getHeader('Content-Type') === 'application/json') {
    this.res.setHeader('Content-Type', 'application/json')

    const str = serialize(this.handle, payload)
    if (!this.res.getHeader('Content-Length')) {
      this.res.setHeader('Content-Length', Buffer.byteLength(str))
    }
    return this.res.end(str)
  }

  this.res.end(payload)
}

Reply.prototype.header = function (key, value) {
  this.res.setHeader(key, value)
  return this
}

Reply.prototype.code = function (code) {
  this.res.statusCode = code
  return this
}

function wrapSend (reply) {
  return function send (payload) {
    return reply.send(payload)
  }
}

function Request (params, req, body, query) {
  this.params = params
  this.req = req
  this.body = body
  this.query = query
}

module.exports = build
module.exports[Symbol.for('internals')] = { bodyParsed, routerHandler, Request, handler, Reply }
<|endoftext|>


<commit_before>const mappings = {
    name: true,
    shortName: 'name',
    file: (obj) => obj.sources.fileName,
    line: (obj) => obj.sources.line,
    description: (obj) => obj.comment && obj.comment.text,
    access: (obj) => obj.flags && obj.flags.isPrivate ? 'private' : 'public', // need to handle protected
    itemtype: 'kindString'
}

function transformExport(input) {
    let output = {
        methods: [],
        events: [],
        properties: []
    };
    for (let key in mappings) {
        let value = mappings[key];
        if (value === true) {
            output[key] = input[key];
        } else if (typeof value === 'string') {
            output[key] = input[value];
        } else if (typeof value === 'function') {
            output[key] = value(input);
        }
    }

    if (input.children) {
        input.children.forEach((child) => {
            const transformed = transformExport(child);
            if (child.kindString === 'Method') {
                output.methods.push(transformed);
            } else if (child.kindString === 'Property') {
                output.properties.push(transformed);
            }
        });
    }
    return output;
}

module.exports = function transform(input) {
    let output = {
        name: input.name,
        type: 'project',
        modules: input.children.map(transformExport)
    };

    return output;
};<commit_msg>Add more mapped doc properties<commit_after>const mappings = {
    name: true,
    shortName: 'name',
    file: (obj) => obj.sources.fileName,
    line: (obj) => obj.sources.line,
    description: (obj) => obj.comment && obj.comment.text,
    access: (obj) => obj.flags && obj.flags.isPrivate ? 'private' : 'public', // need to handle protected
    itemtype: 'kindString',
    implements: (obj) => obj.implementedTypes && obj.implementedTypes.map((type) => type.name),
    parameters: (obj) => obj.signatures && obj.signatures[0].parameters.map((param) => { return {name: param.name, type: param.type.name} })
}

function transformExport(input) {
    let output = {
        methods: [],
        events: [],
        properties: []
    };
    for (let key in mappings) {
        let value = mappings[key];
        if (value === true) {
            output[key] = input[key];
        } else if (typeof value === 'string') {
            output[key] = input[value];
        } else if (typeof value === 'function') {
            let keyValue = value(input);
            if (keyValue) {
                output[key] = keyValue;
            }
        }
    }

    if (input.children) {
        input.children.forEach((child) => {
            const transformed = transformExport(child);
            if (child.kindString === 'Method') {
                output.methods.push(transformed);
            } else if (child.kindString === 'Property') {
                output.properties.push(transformed);
            }
        });
    }
    return output;
}

module.exports = function transform(input) {
    let output = {
        name: input.name,
        type: 'project',
        modules: input.children.map(transformExport)
    };

    return output;
};<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * How porcelain works
 * When a new file is created , it will add a ?? before the file
 * When a file is modified, it shows ' M'. Yes, one space and M (this has a reason)
 * When a file was modified and added to the staging area, and modified once again, it shows MM
 * (that's why there is an space for the modified files, to show the output aligned)
 */
(function () {
    'use strict';

    var childProcess = require('child_process'),
        inquirer = require('inquirer'),
        utils = require('../bin/utils');

    init();

    function init() {
        var gitStatusPorcelain = childProcess.exec('git status --porcelain');

        gitStatusPorcelain.stdout.on('data', function (data) {
            var files = getNoStagedFiles(data);

            if (!files) {
                utils.showError('No files to add');
                return;
            }
            promptFileSelection(files);
        });
    }

    /**
     * returns string 'file1 file2 file2'
     * @param data
     */
    function getNoStagedFiles(data) {
        var newFiles = data.match(newFilesRegex(data)) || [], //with ?? and M string
            formattedArray = [];

        newFiles.forEach(function (item, index) {
            item = item.replace(/^ M/, '');
            item = item.replace(/^MM/, '');
            item = item.replace(/\?\?./, '');
            formattedArray.push(item);
        });
        return formattedArray;
    }

    function newFilesRegex() {
        return new RegExp('(\\?\\?.*)|(^( M|MM).*)', 'mg');
    }

    function promptFileSelection(files) {
        inquirer.prompt([
            {
                type: 'checkbox',
                message: 'Select files to add',
                name: 'files',
                choices: files
            }
        ]).then(function (selection) {
            var command = 'git add ' + selection.files.join(' '),
                gitAdd = childProcess.exec(command);

            gitAdd.stdout.on('data', function (data) {
                console.log(data);
            });

            gitAdd.stderr.on('err', function (err) {
                console.log(err);
            });
        });
    }
})();
<commit_msg>[FIX] turbo-add: fix showError calls<commit_after>#!/usr/bin/env node
/**
 * How porcelain works
 * When a new file is created , it will add a ?? before the file
 * When a file is modified, it shows ' M'. Yes, one space and M (this has a reason)
 * When a file was modified and added to the staging area, and modified once again, it shows MM
 * (that's why there is an space for the modified files, to show the output aligned)
 */
(function () {
    'use strict';

    var childProcess = require('child_process'),
        inquirer = require('inquirer'),
        utils = require('../bin/utils')();

    init();

    function init() {
        var gitStatusPorcelain = childProcess.exec('git status --porcelain');

        gitStatusPorcelain.stdout.on('data', function (data) {
            var files = getNoStagedFiles(data);

            if (!files) {
                utils.showError('No files to add');
                return;
            }
            promptFileSelection(files);
        });
    }

    /**
     * returns string 'file1 file2 file2'
     * @param data
     */
    function getNoStagedFiles(data) {
        var newFiles = data.match(newFilesRegex(data)) || [], //with ?? and M string
            formattedArray = [];

        newFiles.forEach(function (item, index) {
            item = item.replace(/^ M/, '');
            item = item.replace(/^MM/, '');
            item = item.replace(/\?\?./, '');
            formattedArray.push(item);
        });
        return formattedArray;
    }

    function newFilesRegex() {
        return new RegExp('(\\?\\?.*)|(^( M|MM).*)', 'mg');
    }

    function promptFileSelection(files) {
        inquirer.prompt([
            {
                type: 'checkbox',
                message: 'Select files to add',
                name: 'files',
                choices: files
            }
        ]).then(function (selection) {
            var command = 'git add ' + selection.files.join(' '),
                gitAdd = childProcess.exec(command);

            gitAdd.stdout.on('data', function (data) {
                console.log(data);
            });

            gitAdd.stderr.on('err', function (err) {
                console.log(err);
            });
        });
    }
})();
<|endoftext|>


<commit_before>angular.module("omniFactories")
	.factory("Orderbook",["$http","DExOrder","DExOffer","BalanceSocket","Transaction","Account","Wallet","ModalManager","MIN_MINER_FEE", "WHOLE_UNIT", "SATOSHI_UNIT",
		function OrderbookFactory($http, DExOrder,DExOffer,BalanceSocket,Transaction,Account,Wallet,ModalManager,MIN_MINER_FEE,WHOLE_UNIT,SATOSHI_UNIT){
			var Orderbook = function(tradingPair){
				var self = this;

				self.initialize = function(){
					self.tradingPair=tradingPair;
					self.title = "Trade " + tradingPair.selling.name + " for " + tradingPair.desired.name;
					self.active = true;
					self.disabled = !self.active;
					self.buyOrder = {
						desired : tradingPair.selling,
						selling : tradingPair.desired,
						amounts : {
							desired: 0,
							selling: 0
						},
						price: 0,
						feeType: 'normal'
					};
					self.sellOrder = {
						desired : tradingPair.desired,
						selling : tradingPair.selling,
						amounts : {
							desired: 0,
							selling: 0
						},
						price: 0,
						feeType: 'normal'
					};

					self.selling = tradingPair.selling;
					self.desired = tradingPair.desired;
					self.marketData = [];
					self.chartConfig = {
			            chart: {
			                type: 'candlestickBarChart',
			                height: 450,
			                margin : {
			                    top: 20,
			                    right: 20,
			                    bottom: 66,
			                    left: 60
			                },
			                x: function(d){ return d['date']; },
			                y: function(d){ return d['close']; },
			                duration: 100,

			                xAxis: {
			                    axisLabel: 'Dates',
			                    tickFormat: function(d) {
			                        return d3.time.format('%x')(new Date(d * 86400000));
			                    },
			                    showMaxMin: false
			                },

			                yAxis: {
			                    axisLabel: 'Price',
			                    tickFormat: function(d){
			                        return '$' + d3.format(',.1f')(d);
			                    },
			                    showMaxMin: false
			                },
			                zoom: {
			                    enabled: true,
			                    scaleExtent: [1, 10],
			                    useFixedDomain: false,
			                    useNiceScale: false,
			                    horizontalOff: false,
			                    verticalOff: true,
			                    unzoomEventType: 'dblclick.zoom'
			                }
			            }
			        };

					// TODO:  list only addresses with balance > 0
					self.addresses = Wallet.addresses.filter(function(address){
						return ((address.privkey && address.privkey.length == 58) || address.pubkey)
					});
					self.buyAddresses = self.addresses.filter(function(address){
						return address.getBalance(self.desired.propertyid).gt(0);
					});
					self.buyOrder.address = self.buyAddresses.length > 0 ? self.buyAddresses[0] : undefined;
					self.sellAddresses = self.addresses.filter(function(address){
						return address.getBalance(self.selling.propertyid).gt(0);
					});
					self.sellOrder.address = self.sellAddresses.length > 0 ? self.sellAddresses[0] : undefined;

					self.askBook = [];
					self.bidBook = [];
					self.activeOffers = [];

					BalanceSocket.on("orderbook", function(data){
						console.log("OrderbookFactory.js - orderbook");
						bigbook=data;
						updateAsks(bigbook);
						updateBids(bigbook);
					});

					//process websocket orderbook
					var updateAsks = function(bigbook){
						if (typeof bigbook=="undefined" || typeof bigbook[tradingPair.desired.propertyid]=="undefined" || typeof bigbook[tradingPair.desired.propertyid][tradingPair.selling.propertyid]=="undefined") {
							return // handle errors
						}
						data=bigbook[tradingPair.desired.propertyid][tradingPair.selling.propertyid];
						if (data.status != 200)
							return // handle errors
						var orderbook = [];
						self.parseOrderbook(data.orderbook, orderbook,tradingPair.desired,tradingPair.selling,data.cancels);
						self.askBook = orderbook;
						self.askBook.sort(function(a, b) {
							var priceA = a.price;
							var priceB = b.price;
							return priceA.gt(priceB) ? 1 : priceA.lt(priceB) ? -1 : 0;
						});
					}

					// Initial load of orders for property selling asks
					var updateAsksInitial = function(){
						$http.get("/v1/omnidex/"+tradingPair.desired.propertyid+"/"+tradingPair.selling.propertyid)
						.then(function(response){
							if(response.status != 200 || response.data.status !=200)
								return // handle errors

							var orderbook = [];
							self.parseOrderbook(response.data.orderbook, orderbook,tradingPair.desired,tradingPair.selling,response.data.cancels);
							self.askBook = orderbook;
							self.askBook.sort(function(a, b) {
					          var priceA = a.price;
					          var priceB = b.price;
					          return priceA.gt(priceB) ? 1 : priceA.lt(priceB) ? -1 : 0;
					        });

							//self.updateAsksTimeout = setTimeout(updateAsks,3000);
						})
					}
					updateAsksInitial();

                                        //process websocket orderbook
                                        var updateBids = function(bigbook){
						if (typeof bigbook=="undefined" || typeof bigbook[tradingPair.selling.propertyid]=="undefined" || typeof bigbook[tradingPair.selling.propertyid][tradingPair.desired.propertyid]=="undefined"){
							return // handle errors
						}
                                                data=bigbook[tradingPair.selling.propertyid][tradingPair.desired.propertyid];
                                                if (data.status != 200)
                                                        return // handle errors
                                                var orderbook = [];
                                                self.parseOrderbook(data.orderbook, orderbook,tradingPair.selling,tradingPair.desired,data.cancels);
                                                self.bidBook = orderbook;
                                                self.bidBook.sort(function(a, b) {
                                                        var priceA = a.price;
                                                        var priceB = b.price;
                                                        return priceA.lt(priceB) ? 1 : priceA.gt(priceB) ? -1 : 0;
                                                });
                                        }

					var updateBidsInitial = function(){
						$http.get("/v1/omnidex/"+tradingPair.selling.propertyid+"/"+tradingPair.desired.propertyid)
						.then(function(response){
							if(response.status != 200 || response.data.status != 200)
								return // handle errors

							var orderbook = [];
							self.parseOrderbook(response.data.orderbook, orderbook,tradingPair.selling,tradingPair.desired,response.data.cancels);
							self.bidBook = orderbook;
							self.bidBook.sort(function(a, b) {
					          var priceA = a.price;
					          var priceB = b.price;
					          return priceA.lt(priceB) ? 1 : priceA.gt(priceB) ? -1 : 0;
					        });

							//self.updateBidsTimeout = setTimeout(updateBids, 3000);
						})
					}
					updateBidsInitial();

					$http.get("/v1/omnidex/ohlcv/"+tradingPair.desired.propertyid+"/"+tradingPair.selling.propertyid)
						.then(function(response){
							if(response.status != 200 || response.data.status !=200)
								return // handle errors

							self.marketData=response.data.orderbook;
							self.chartData = [
										{
				                    values: self.marketData
				                }
							]
						})

				};

				self.parseOrderbook =function(orderbook,side,selling,desired,cancels){
					orderbook.forEach(function(offerData){
						// check if there's a pending cancel for this offer
						var iscanceled = cancels.find(function(cancelOffer){
							return cancelOffer.desired_amount == offerData.desired_amount && cancelOffer.total_amount == offerData.total_amount;
						})
						if(!iscanceled){
							var order = null;
							var offer = new DExOffer(offerData,selling,desired,selling == self.tradingPair.selling ? "bid":"ask");
							side.forEach(function(orderData){
								if(orderData.price.eq(offer.price)){
									order = orderData;
									order.addOffer(offer)
								}
							})
							let owner = Wallet.tradableAddresses().find(function(elem){
								return elem.hash == offerData.seller
							})
							if(owner){
								offer.ownerAddress = owner;
								offer.side = selling == self.tradingPair.selling ? "bid":"ask";
								if(!self.activeOffers.find(function(element){return element.time == offer.time;})){
									self.activeOffers.push(offer);
								}
								var confirmed = self.activeOffers.find(function(element){
									return offer.status == 'active' && element.status == 'pending' && element.desired_amount == offer.desired_amount && element.selling_amount == offer.selling_amount;
								});

								if(confirmed){
									self.activeOffers.splice(self.activeOffers.indexOf(confirmed),1);
								}
							}
							if(order == null){
								order = new DExOrder(offer);
								side.push(order);
							}
						} else {
							var cancelled = self.activeOffers.find(function(element){
								return element.status == 'active' && element.rawdata.desired_amount == iscanceled.desired_amount && element.rawdata.total_amount == iscanceled.total_amount;
							});

							if(cancelled){
								self.activeOffers.splice(self.activeOffers.indexOf(cancelled),1);
							}
						}
					});
				}

				self.askCumulative = function(order){
					let index = self.askBook.indexOf(order);
					let cumulative = new Big(0);
					for (let i = 0; i <= index; i++){
						cumulative = cumulative.plus(self.askBook[i].totaldesired)
					}
					return cumulative;
				}
				self.bidCumulative = function(order){
					let index = self.bidBook.indexOf(order);
					let cumulative = new Big(0);
					for (let i = 0; i <= index; i++){
						cumulative = cumulative.plus(self.bidBook[i].remainingforsale)
					}
					return cumulative;
				}

				self.setBuyAddress = function(address){
					self.buyOrder.address = address;
                                        if (typeof address != "undefined") {
					  address.estimateFee().then(function(result){
						self.buyOrder.feeData=result;
						if(self.buyOrder.feeType != 'custom'){
							self.buyOrder.fee = new Big(result.class_c[self.buyOrder.feeType]);
						}
					  });
					};
				};

				self.setSellAddress = function(address){
					self.sellOrder.address = address;
					if (typeof address != "undefined") {
					  address.estimateFee().then(function(result){
						self.sellOrder.feeData=result;
						if(self.sellOrder.feeType != 'custom'){
							self.sellOrder.fee = new Big(result.class_c[self.sellOrder.feeType]);
						}
					  });
					};
				};

				self.updateAmount = function(offer, side) {
					if(side == "bid")
						offer.amounts.selling= parseFloat((offer.amounts.desired * offer.price).toPrecision(8)) ||0;
					else
						offer.amounts.desired= parseFloat((offer.amounts.selling * offer.price).toPrecision(8)) ||0;
				}
				self.updateTotal = function(offer, side) {
					if(side == "bid")
						offer.amounts.desired= parseFloat((offer.amounts.selling / offer.price).toPrecision(8)) ||0;
					else
						offer.amounts.selling= parseFloat((offer.amounts.desired / offer.price).toPrecision(8)) ||0;
				}

				self.submitOffer = function(offer){
					// TODO: Validations
					var fee = offer.fee;
                                        //Account.settings.minerFee || MIN_MINER_FEE;
					var dexOffer = new Transaction(25,offer.address,fee,{
							transaction_version:0,
							propertyidforsale:offer.selling.propertyid,
							amountforsale: new Big(offer.amounts.selling).valueOf(),
							propertiddesired:offer.desired.propertyid,
							amountdesired: new Big(offer.amounts.desired).valueOf()
						});
					ModalManager.openConfirmationModal({
						dataTemplate: '/views/modals/partials/dex_offer.html',
						scope: {
							title:"Confirm DEx Transaction",
							address:offer.address,
							saleCurrency:offer.selling.propertyid,
							saleAmount:offer.amounts.selling,
							desiredCurrency:offer.desired.propertyid,
							desiredAmount:offer.amounts.desired,
							totalCost:dexOffer.totalCost,
							action:"Add",
							confirmText: "Create Transaction",
							successMessage: "Your order was placed successfully"
						},
						transaction:dexOffer
					});
				};

				self.getBalance = function(address, assetId){
					return address && address.getBalance(assetId).valueOf();
				}

				self.initialize();
			}

			return Orderbook;
		}]);
<commit_msg>remove debug logging<commit_after>angular.module("omniFactories")
	.factory("Orderbook",["$http","DExOrder","DExOffer","BalanceSocket","Transaction","Account","Wallet","ModalManager","MIN_MINER_FEE", "WHOLE_UNIT", "SATOSHI_UNIT",
		function OrderbookFactory($http, DExOrder,DExOffer,BalanceSocket,Transaction,Account,Wallet,ModalManager,MIN_MINER_FEE,WHOLE_UNIT,SATOSHI_UNIT){
			var Orderbook = function(tradingPair){
				var self = this;

				self.initialize = function(){
					self.tradingPair=tradingPair;
					self.title = "Trade " + tradingPair.selling.name + " for " + tradingPair.desired.name;
					self.active = true;
					self.disabled = !self.active;
					self.buyOrder = {
						desired : tradingPair.selling,
						selling : tradingPair.desired,
						amounts : {
							desired: 0,
							selling: 0
						},
						price: 0,
						feeType: 'normal'
					};
					self.sellOrder = {
						desired : tradingPair.desired,
						selling : tradingPair.selling,
						amounts : {
							desired: 0,
							selling: 0
						},
						price: 0,
						feeType: 'normal'
					};

					self.selling = tradingPair.selling;
					self.desired = tradingPair.desired;
					self.marketData = [];
					self.chartConfig = {
			            chart: {
			                type: 'candlestickBarChart',
			                height: 450,
			                margin : {
			                    top: 20,
			                    right: 20,
			                    bottom: 66,
			                    left: 60
			                },
			                x: function(d){ return d['date']; },
			                y: function(d){ return d['close']; },
			                duration: 100,

			                xAxis: {
			                    axisLabel: 'Dates',
			                    tickFormat: function(d) {
			                        return d3.time.format('%x')(new Date(d * 86400000));
			                    },
			                    showMaxMin: false
			                },

			                yAxis: {
			                    axisLabel: 'Price',
			                    tickFormat: function(d){
			                        return '$' + d3.format(',.1f')(d);
			                    },
			                    showMaxMin: false
			                },
			                zoom: {
			                    enabled: true,
			                    scaleExtent: [1, 10],
			                    useFixedDomain: false,
			                    useNiceScale: false,
			                    horizontalOff: false,
			                    verticalOff: true,
			                    unzoomEventType: 'dblclick.zoom'
			                }
			            }
			        };

					// TODO:  list only addresses with balance > 0
					self.addresses = Wallet.addresses.filter(function(address){
						return ((address.privkey && address.privkey.length == 58) || address.pubkey)
					});
					self.buyAddresses = self.addresses.filter(function(address){
						return address.getBalance(self.desired.propertyid).gt(0);
					});
					self.buyOrder.address = self.buyAddresses.length > 0 ? self.buyAddresses[0] : undefined;
					self.sellAddresses = self.addresses.filter(function(address){
						return address.getBalance(self.selling.propertyid).gt(0);
					});
					self.sellOrder.address = self.sellAddresses.length > 0 ? self.sellAddresses[0] : undefined;

					self.askBook = [];
					self.bidBook = [];
					self.activeOffers = [];

					BalanceSocket.on("orderbook", function(data){
						bigbook=data;
						updateAsks(bigbook);
						updateBids(bigbook);
					});

					//process websocket orderbook
					var updateAsks = function(bigbook){
						if (typeof bigbook=="undefined" || typeof bigbook[tradingPair.desired.propertyid]=="undefined" || typeof bigbook[tradingPair.desired.propertyid][tradingPair.selling.propertyid]=="undefined") {
							return // handle errors
						}
						data=bigbook[tradingPair.desired.propertyid][tradingPair.selling.propertyid];
						if (data.status != 200)
							return // handle errors
						var orderbook = [];
						self.parseOrderbook(data.orderbook, orderbook,tradingPair.desired,tradingPair.selling,data.cancels);
						self.askBook = orderbook;
						self.askBook.sort(function(a, b) {
							var priceA = a.price;
							var priceB = b.price;
							return priceA.gt(priceB) ? 1 : priceA.lt(priceB) ? -1 : 0;
						});
					}

					// Initial load of orders for property selling asks
					var updateAsksInitial = function(){
						$http.get("/v1/omnidex/"+tradingPair.desired.propertyid+"/"+tradingPair.selling.propertyid)
						.then(function(response){
							if(response.status != 200 || response.data.status !=200)
								return // handle errors

							var orderbook = [];
							self.parseOrderbook(response.data.orderbook, orderbook,tradingPair.desired,tradingPair.selling,response.data.cancels);
							self.askBook = orderbook;
							self.askBook.sort(function(a, b) {
					          var priceA = a.price;
					          var priceB = b.price;
					          return priceA.gt(priceB) ? 1 : priceA.lt(priceB) ? -1 : 0;
					        });

							//self.updateAsksTimeout = setTimeout(updateAsks,3000);
						})
					}
					updateAsksInitial();

                                        //process websocket orderbook
                                        var updateBids = function(bigbook){
						if (typeof bigbook=="undefined" || typeof bigbook[tradingPair.selling.propertyid]=="undefined" || typeof bigbook[tradingPair.selling.propertyid][tradingPair.desired.propertyid]=="undefined"){
							return // handle errors
						}
                                                data=bigbook[tradingPair.selling.propertyid][tradingPair.desired.propertyid];
                                                if (data.status != 200)
                                                        return // handle errors
                                                var orderbook = [];
                                                self.parseOrderbook(data.orderbook, orderbook,tradingPair.selling,tradingPair.desired,data.cancels);
                                                self.bidBook = orderbook;
                                                self.bidBook.sort(function(a, b) {
                                                        var priceA = a.price;
                                                        var priceB = b.price;
                                                        return priceA.lt(priceB) ? 1 : priceA.gt(priceB) ? -1 : 0;
                                                });
                                        }

					var updateBidsInitial = function(){
						$http.get("/v1/omnidex/"+tradingPair.selling.propertyid+"/"+tradingPair.desired.propertyid)
						.then(function(response){
							if(response.status != 200 || response.data.status != 200)
								return // handle errors

							var orderbook = [];
							self.parseOrderbook(response.data.orderbook, orderbook,tradingPair.selling,tradingPair.desired,response.data.cancels);
							self.bidBook = orderbook;
							self.bidBook.sort(function(a, b) {
					          var priceA = a.price;
					          var priceB = b.price;
					          return priceA.lt(priceB) ? 1 : priceA.gt(priceB) ? -1 : 0;
					        });

							//self.updateBidsTimeout = setTimeout(updateBids, 3000);
						})
					}
					updateBidsInitial();

					$http.get("/v1/omnidex/ohlcv/"+tradingPair.desired.propertyid+"/"+tradingPair.selling.propertyid)
						.then(function(response){
							if(response.status != 200 || response.data.status !=200)
								return // handle errors

							self.marketData=response.data.orderbook;
							self.chartData = [
										{
				                    values: self.marketData
				                }
							]
						})

				};

				self.parseOrderbook =function(orderbook,side,selling,desired,cancels){
					orderbook.forEach(function(offerData){
						// check if there's a pending cancel for this offer
						var iscanceled = cancels.find(function(cancelOffer){
							return cancelOffer.desired_amount == offerData.desired_amount && cancelOffer.total_amount == offerData.total_amount;
						})
						if(!iscanceled){
							var order = null;
							var offer = new DExOffer(offerData,selling,desired,selling == self.tradingPair.selling ? "bid":"ask");
							side.forEach(function(orderData){
								if(orderData.price.eq(offer.price)){
									order = orderData;
									order.addOffer(offer)
								}
							})
							let owner = Wallet.tradableAddresses().find(function(elem){
								return elem.hash == offerData.seller
							})
							if(owner){
								offer.ownerAddress = owner;
								offer.side = selling == self.tradingPair.selling ? "bid":"ask";
								if(!self.activeOffers.find(function(element){return element.time == offer.time;})){
									self.activeOffers.push(offer);
								}
								var confirmed = self.activeOffers.find(function(element){
									return offer.status == 'active' && element.status == 'pending' && element.desired_amount == offer.desired_amount && element.selling_amount == offer.selling_amount;
								});

								if(confirmed){
									self.activeOffers.splice(self.activeOffers.indexOf(confirmed),1);
								}
							}
							if(order == null){
								order = new DExOrder(offer);
								side.push(order);
							}
						} else {
							var cancelled = self.activeOffers.find(function(element){
								return element.status == 'active' && element.rawdata.desired_amount == iscanceled.desired_amount && element.rawdata.total_amount == iscanceled.total_amount;
							});

							if(cancelled){
								self.activeOffers.splice(self.activeOffers.indexOf(cancelled),1);
							}
						}
					});
				}

				self.askCumulative = function(order){
					let index = self.askBook.indexOf(order);
					let cumulative = new Big(0);
					for (let i = 0; i <= index; i++){
						cumulative = cumulative.plus(self.askBook[i].totaldesired)
					}
					return cumulative;
				}
				self.bidCumulative = function(order){
					let index = self.bidBook.indexOf(order);
					let cumulative = new Big(0);
					for (let i = 0; i <= index; i++){
						cumulative = cumulative.plus(self.bidBook[i].remainingforsale)
					}
					return cumulative;
				}

				self.setBuyAddress = function(address){
					self.buyOrder.address = address;
                                        if (typeof address != "undefined") {
					  address.estimateFee().then(function(result){
						self.buyOrder.feeData=result;
						if(self.buyOrder.feeType != 'custom'){
							self.buyOrder.fee = new Big(result.class_c[self.buyOrder.feeType]);
						}
					  });
					};
				};

				self.setSellAddress = function(address){
					self.sellOrder.address = address;
					if (typeof address != "undefined") {
					  address.estimateFee().then(function(result){
						self.sellOrder.feeData=result;
						if(self.sellOrder.feeType != 'custom'){
							self.sellOrder.fee = new Big(result.class_c[self.sellOrder.feeType]);
						}
					  });
					};
				};

				self.updateAmount = function(offer, side) {
					if(side == "bid")
						offer.amounts.selling= parseFloat((offer.amounts.desired * offer.price).toPrecision(8)) ||0;
					else
						offer.amounts.desired= parseFloat((offer.amounts.selling * offer.price).toPrecision(8)) ||0;
				}
				self.updateTotal = function(offer, side) {
					if(side == "bid")
						offer.amounts.desired= parseFloat((offer.amounts.selling / offer.price).toPrecision(8)) ||0;
					else
						offer.amounts.selling= parseFloat((offer.amounts.desired / offer.price).toPrecision(8)) ||0;
				}

				self.submitOffer = function(offer){
					// TODO: Validations
					var fee = offer.fee;
                                        //Account.settings.minerFee || MIN_MINER_FEE;
					var dexOffer = new Transaction(25,offer.address,fee,{
							transaction_version:0,
							propertyidforsale:offer.selling.propertyid,
							amountforsale: new Big(offer.amounts.selling).valueOf(),
							propertiddesired:offer.desired.propertyid,
							amountdesired: new Big(offer.amounts.desired).valueOf()
						});
					ModalManager.openConfirmationModal({
						dataTemplate: '/views/modals/partials/dex_offer.html',
						scope: {
							title:"Confirm DEx Transaction",
							address:offer.address,
							saleCurrency:offer.selling.propertyid,
							saleAmount:offer.amounts.selling,
							desiredCurrency:offer.desired.propertyid,
							desiredAmount:offer.amounts.desired,
							totalCost:dexOffer.totalCost,
							action:"Add",
							confirmText: "Create Transaction",
							successMessage: "Your order was placed successfully"
						},
						transaction:dexOffer
					});
				};

				self.getBalance = function(address, assetId){
					return address && address.getBalance(assetId).valueOf();
				}

				self.initialize();
			}

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


<commit_before>App.Router.map(function () {
  this.resource('projects', {path: '/'}, function() {
    this.resource('user-welcome');
    this.resource('project', {path: '/:project_id'}, function() {
      this.resource('investigation', {path: '/:investigation_id'}, function() {
        this.resource('chart', {path: '/:chart_id'}, function(){
          this.route('edit');
        });
      });
    });
  });

});

App.Router.reopen({
  rootURL: '/portal'
});

App.ApplicationRoute = Ember.Route.extend({
  model: function () {
    var self = this;

    return this.store.find('user').then(function(user) {
      if(user) {
        return user.get('firstObject');
      } else {
        return new App.User();
      }
    }, function(error){
      self.render('user/error');
      throw new Error('failed to get user');
    });
  }
});

App.ProjectRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('project', params.project_id);
  },
  renderTemplate: function() {
    this.render('project');
    this.render('project-title', {
      outlet: 'title'
    });
  }
});<commit_msg>Don't throw if the user fails to deserialize<commit_after>App.Router.map(function () {
  this.resource('projects', {path: '/'}, function() {
    this.resource('user-welcome');
    this.resource('project', {path: '/:project_id'}, function() {
      this.resource('investigation', {path: '/:investigation_id'}, function() {
        this.resource('chart', {path: '/:chart_id'}, function(){
          this.route('edit');
        });
      });
    });
  });

});

App.Router.reopen({
  rootURL: '/portal'
});

App.ApplicationRoute = Ember.Route.extend({
  model: function () {
    var self = this;

    return this.store.find('user').then(function(user) {
      if (user) {
        return user.get('firstObject');
      } else {
        return new App.User();
      }
    }, function(error){
      console.log();
    });
  }
});

App.ProjectRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('project', params.project_id);
  },
  renderTemplate: function() {
    this.render('project');
    this.render('project-title', {
      outlet: 'title'
    });
  }
});<|endoftext|>