<commit_before>module.exports = function (sails) {

  /**
   * Module dependencies
   */

  var Err = require('../../../errors'),
    path  = require('path'),
    ChildProcess = require('child_process');

  return {

    /**
     * Initialize this project's Grunt tasks
     * and execute the environment-specific gruntfile
     *
     */
    initialize: function (cb) {

      sails.log.verbose('Loading app Gruntfile...');

      // Start task depending on environment
      if(sails.config.environment === 'production'){
        return this.runTask('prod', cb);
      }

      this.runTask('default', cb);
    },

    /**
     * Fork Grunt child process
     *
     * @param {String} taskName - grunt task to run
     * @param {Function} cb - optional, fires when the Grunt task has been started (non-production) or finished (production)
     */
    runTask: function (taskName, cb_afterTaskStarted) {
      cb_afterTaskStarted = cb_afterTaskStarted || function () {};

      var pathToSails = path.resolve(__dirname, '../../../');

      if (!taskName) {
        taskName = '';
      }

      var execArgs = process.execArgv.slice(0);
      if(execArgs.indexOf('--debug') !== -1) {
        execArgs.splice(execArgs.indexOf('--debug'),1);
      }

      // Fork Grunt child process
      var child = ChildProcess.fork(

        // cwd for child process
        path.join(__dirname, 'grunt-wrapper.js'),

        // cmd args+opts for child process
        [
          taskName,
          '--pathToSails='+pathToSails,

          // Backwards compatibility for v0.9.x
          '--gdsrc='+ pathToSails + '/node_modules'
        ],

        // opts to pass to node's `child_process` logic
        {
          silent: true,
          stdio: 'pipe',
          execArgv: execArgs
        }
      );

      var errorMsg = '';
      var stackTrace = '';

      // Log output as it comes in to the appropriate log channel
      child.stdout.on('data', function (consoleMsg) {

        // store all the output
        consoleMsg = consoleMsg.toString();
        errorMsg += consoleMsg;

        // Clean out all the whitespace
        var trimmedStackTrace = (typeof stackTrace === 'string') ? stackTrace : '';
        trimmedStackTrace = trimmedStackTrace.replace(/[\n\s]*$/,'');
        trimmedStackTrace = trimmedStackTrace.replace(/^[\n\s]*/,'');
        var trimmedConsoleMsg = (typeof consoleMsg === 'string') ? consoleMsg : '';
        trimmedConsoleMsg = trimmedConsoleMsg.replace(/[\n\s]*$/,'');
        trimmedConsoleMsg = trimmedConsoleMsg.replace(/^[\n\s]*/,'');

        // Remove '--force to continue' message since it makes no sense
        // in this context:
        trimmedConsoleMsg = trimmedConsoleMsg.replace(/Use --force to continue\./i, '');
        trimmedStackTrace = trimmedStackTrace.replace(/Use --force to continue\./i, '');

        // Find the Stack Trace related to this warning
        stackTrace = errorMsg.substring(errorMsg.lastIndexOf('Running "'));

    //     if (consoleMsg.match(/Use --force to continue/)) {
        // //   sails.log.warn('** Grunt :: Warning **');
        // //   sails.log.warn(errorMsg,trimmedStackTrace);
        // }

        // Handle fatal errors, like missing grunt dependency, etc.
        if (consoleMsg.match(/Fatal error/g)) {

          // If no Gruntfile exists, don't crash- just display a warning.
          if (consoleMsg.match(/Unable to find Gruntfile/i)) {
            sails.log.info('Gruntfile could not be found.');
            sails.log.info('(no grunt tasks will be run.)');
            if(sails.config.environment === 'production'){
              cb_afterTaskStarted();
            }
            return;
          }

          Err.fatal.__GruntAborted__(trimmedConsoleMsg, trimmedStackTrace);
          return;
        }

        // Handle fatal Grunt errors by killing Sails process as well
        if (consoleMsg.match(/Aborted due to warnings/)) {
          sails.log.error('** Grunt :: An error occurred. **');
          // sails.log.warn(trimmedStackTrace);
          // sails.emit('hook:grunt:error', trimmedStackTrace);
          Err.fatal.__GruntAborted__(trimmedConsoleMsg, trimmedStackTrace);
          return;
        }

        if (consoleMsg.match(/ParseError/)) {
          sails.log.warn('** Grunt :: Parse Warning **');
          sails.log.warn(trimmedStackTrace);
        }

        // Only display console message if it has content besides whitespace
        else if ( !consoleMsg.match(/^\s*$/) ) {
          sails.log.verbose('Grunt :: ' + trimmedConsoleMsg);
        }
      });

      // Handle general-case grunt output:
      child.stdout.on('error', function (gruntOutput) {
        sails.log.error('Grunt ::', _sanitize(gruntOutput));
      });
      child.stderr.on('data', function (gruntOutput) {
        gruntOutput = _sanitize(gruntOutput);
        // Ignore the "debugger listening" message from node --debug
        if (gruntOutput.match(/debugger listening on port/)) {
          return;
        }
        sails.log.error('Grunt ::', gruntOutput);
      });
      child.stderr.on('error', function (gruntOutput) {
        sails.log.error('Grunt ::', _sanitize(gruntOutput));
      });

      // When process is complete, fire event on `sails`
      child.on('exit', function (code, s) { // TODO: unused variable s
        if ( code !== 0 ) return sails.emit('hook:grunt:error');
        sails.emit('hook:grunt:done');

        // Fire finish after grunt is done in production
        if(sails.config.environment === 'production'){
          cb_afterTaskStarted();
        }
      });

      // Since there's likely a watch task involved, and we may need
      // to flush the whole thing, we need a way to grab hold of the child process
      // So we save a reference to it
      sails.log.verbose('Tracking new grunt child process...');
      sails.childProcesses.push(child);

      // Go ahead and get out of here, since Grunt might sit there backgrounded
      if(sails.config.environment !== 'production'){
         cb_afterTaskStarted();
      }
    }
  };
};

/**
 * After ensuring a chunk is a string, trim any leading or
 * trailing whitespace.  If chunk cannot be nicely casted to a string,
 * pass it straight through.
 *
 * @param  {*} chunk
 * @return {*}
 */
function _sanitize (chunk) {

  if (chunk && typeof chunk === 'object' && chunk.toString) {
    chunk = chunk.toString();
  }
  if (typeof chunk === 'string') {
    chunk = chunk.replace(/^[\s\n]*/, '');
    chunk = chunk.replace(/[\s\n]*$/, '');
  }
  return chunk;
}
<commit_msg>Really fix #2670<commit_after>module.exports = function (sails) {

  /**
   * Module dependencies
   */

  var Err = require('../../../errors'),
    path  = require('path'),
    ChildProcess = require('child_process');

  return {

    /**
     * Initialize this project's Grunt tasks
     * and execute the environment-specific gruntfile
     *
     */
    initialize: function (cb) {

      sails.log.verbose('Loading app Gruntfile...');

      // Start task depending on environment
      if(sails.config.environment === 'production'){
        return this.runTask('prod', cb);
      }

      this.runTask('default', cb);
    },

    /**
     * Fork Grunt child process
     *
     * @param {String} taskName - grunt task to run
     * @param {Function} cb - optional, fires when the Grunt task has been started (non-production) or finished (production)
     */
    runTask: function (taskName, cb_afterTaskStarted) {
      cb_afterTaskStarted = cb_afterTaskStarted || function () {};

      var pathToSails = path.resolve(__dirname, '../../../');

      if (!taskName) {
        taskName = '';
      }

      // Fork Grunt child process
      var child = ChildProcess.fork(

        // cwd for child process
        path.join(__dirname, 'grunt-wrapper.js'),

        // cmd args+opts for child process
        [
          taskName,
          '--pathToSails='+pathToSails,

          // Backwards compatibility for v0.9.x
          '--gdsrc='+ pathToSails + '/node_modules'
        ],

        // opts to pass to node's `child_process` logic
        {
          silent: true,
          stdio: 'pipe',
          // pass all current node process arguments to the child process,
          // except the debug-related arguments, see issue #2670
          execArgv: process.execArgv.slice(0).filter(function (param) {
            return !(new RegExp('--debug(-brk=[0-9]+)?').test(param));
          });
        }
      );

      var errorMsg = '';
      var stackTrace = '';

      // Log output as it comes in to the appropriate log channel
      child.stdout.on('data', function (consoleMsg) {

        // store all the output
        consoleMsg = consoleMsg.toString();
        errorMsg += consoleMsg;

        // Clean out all the whitespace
        var trimmedStackTrace = (typeof stackTrace === 'string') ? stackTrace : '';
        trimmedStackTrace = trimmedStackTrace.replace(/[\n\s]*$/,'');
        trimmedStackTrace = trimmedStackTrace.replace(/^[\n\s]*/,'');
        var trimmedConsoleMsg = (typeof consoleMsg === 'string') ? consoleMsg : '';
        trimmedConsoleMsg = trimmedConsoleMsg.replace(/[\n\s]*$/,'');
        trimmedConsoleMsg = trimmedConsoleMsg.replace(/^[\n\s]*/,'');

        // Remove '--force to continue' message since it makes no sense
        // in this context:
        trimmedConsoleMsg = trimmedConsoleMsg.replace(/Use --force to continue\./i, '');
        trimmedStackTrace = trimmedStackTrace.replace(/Use --force to continue\./i, '');

        // Find the Stack Trace related to this warning
        stackTrace = errorMsg.substring(errorMsg.lastIndexOf('Running "'));

    //     if (consoleMsg.match(/Use --force to continue/)) {
        // //   sails.log.warn('** Grunt :: Warning **');
        // //   sails.log.warn(errorMsg,trimmedStackTrace);
        // }

        // Handle fatal errors, like missing grunt dependency, etc.
        if (consoleMsg.match(/Fatal error/g)) {

          // If no Gruntfile exists, don't crash- just display a warning.
          if (consoleMsg.match(/Unable to find Gruntfile/i)) {
            sails.log.info('Gruntfile could not be found.');
            sails.log.info('(no grunt tasks will be run.)');
            if(sails.config.environment === 'production'){
              cb_afterTaskStarted();
            }
            return;
          }

          Err.fatal.__GruntAborted__(trimmedConsoleMsg, trimmedStackTrace);
          return;
        }

        // Handle fatal Grunt errors by killing Sails process as well
        if (consoleMsg.match(/Aborted due to warnings/)) {
          sails.log.error('** Grunt :: An error occurred. **');
          // sails.log.warn(trimmedStackTrace);
          // sails.emit('hook:grunt:error', trimmedStackTrace);
          Err.fatal.__GruntAborted__(trimmedConsoleMsg, trimmedStackTrace);
          return;
        }

        if (consoleMsg.match(/ParseError/)) {
          sails.log.warn('** Grunt :: Parse Warning **');
          sails.log.warn(trimmedStackTrace);
        }

        // Only display console message if it has content besides whitespace
        else if ( !consoleMsg.match(/^\s*$/) ) {
          sails.log.verbose('Grunt :: ' + trimmedConsoleMsg);
        }
      });

      // Handle general-case grunt output:
      child.stdout.on('error', function (gruntOutput) {
        sails.log.error('Grunt ::', _sanitize(gruntOutput));
      });
      child.stderr.on('data', function (gruntOutput) {
        gruntOutput = _sanitize(gruntOutput);
        // Ignore the "debugger listening" message from node --debug
        if (gruntOutput.match(/debugger listening on port/)) {
          return;
        }
        sails.log.error('Grunt ::', gruntOutput);
      });
      child.stderr.on('error', function (gruntOutput) {
        sails.log.error('Grunt ::', _sanitize(gruntOutput));
      });

      // When process is complete, fire event on `sails`
      child.on('exit', function (code, s) { // TODO: unused variable s
        if ( code !== 0 ) return sails.emit('hook:grunt:error');
        sails.emit('hook:grunt:done');

        // Fire finish after grunt is done in production
        if(sails.config.environment === 'production'){
          cb_afterTaskStarted();
        }
      });

      // Since there's likely a watch task involved, and we may need
      // to flush the whole thing, we need a way to grab hold of the child process
      // So we save a reference to it
      sails.log.verbose('Tracking new grunt child process...');
      sails.childProcesses.push(child);

      // Go ahead and get out of here, since Grunt might sit there backgrounded
      if(sails.config.environment !== 'production'){
         cb_afterTaskStarted();
      }
    }
  };
};

/**
 * After ensuring a chunk is a string, trim any leading or
 * trailing whitespace.  If chunk cannot be nicely casted to a string,
 * pass it straight through.
 *
 * @param  {*} chunk
 * @return {*}
 */
function _sanitize (chunk) {

  if (chunk && typeof chunk === 'object' && chunk.toString) {
    chunk = chunk.toString();
  }
  if (typeof chunk === 'string') {
    chunk = chunk.replace(/^[\s\n]*/, '');
    chunk = chunk.replace(/[\s\n]*$/, '');
  }
  return chunk;
}
<|endoftext|>


<commit_before><commit_msg>Fix lots of typos<commit_after><|endoftext|>


<commit_before>/**
 * Local dependencies
 */
const crypto = require('@trust/webcrypto')
const base64url = require('base64url')
const {JWT} = require('@trust/jose')
const IDTokenSchema = require('./schemas/IDTokenSchema')

/**
 * IDToken
 */
class IDToken extends JWT {

  /**
   * Schema
   */
  static get schema () {
    return IDTokenSchema
  }

  /**
   * issue
   */
  static issue (request, response) {
    let {params, code, provider, client, subject} = request
    let {issuer, keys} = provider

    let alg = client['id_token_signed_response_alg'] || 'RS256'
    let key = keys['id_token'].signing[alg].privateKey
    let kid = keys['id_token'].signing[alg].publicJwk.kid
    let iss = issuer
    let jti = request.random(8)
    let iat = Math.floor(Date.now() / 1000)
    let aud, sub, max, nonce

    // authentication request
    if (!code) {
      aud = client['client_id']
      sub = subject['_id']
      max = parseInt(params['max_age']) || client['default_max_age'] || 3600
      nonce = params.nonce

    // token request
    } else {
      aud = code.aud
      sub = code.sub
      max = parseInt(code['max']) || client['default_max_age'] || 3600
      nonce = code.nonce
    }

    let exp = iat + max

    let len = alg.match(/(256|384|512)$/)[0]

    // generate
    return Promise.all([
      IDToken.hashClaim(response['access_token'], len),
      IDToken.hashClaim(response['code'], len)
    ])

    // build the id_token
    .then(hashes => {
      let [at_hash, c_hash] = hashes
      let header = {alg, kid}
      let payload = {iss, aud, sub, exp, iat, jti, nonce, at_hash, c_hash}
      return new IDToken({header, payload, key})
    })

    // sign id token and add to response
    .then(jwt => {
      return jwt.encode().then(compact => {
        response['id_token'] = compact
        return response
      })
    })
  }

  /**
   * hashClaim
   *
   * @description
   * Create a hash for at_hash or c_hash claim
   *
   * @param {string} token
   * @param {string} hashLength
   *
   * @returns {Promise}
   */
  static hashClaim (value, hashLength) {
    if (value) {
      let alg = { name: `SHA-${hashLength}`}
      let octets = new Buffer(value, 'ascii')

      return crypto.subtle.digest(alg, new Uint8Array(octets)).then(digest => {
        let hash = Buffer.from(digest)
        let half = hash.slice(0, hash.byteLength / 2)
        return base64url(half)
      })
    }
  }
}

/**
 * Export
 */
module.exports = IDToken
<commit_msg>fix(IDToken): Use static random() (since it was removed from BaseRequest)<commit_after>/**
 * Local dependencies
 */
const crypto = require('@trust/webcrypto')
const base64url = require('base64url')
const {JWT} = require('@trust/jose')
const IDTokenSchema = require('./schemas/IDTokenSchema')

/**
 * IDToken
 */
class IDToken extends JWT {

  /**
   * Schema
   */
  static get schema () {
    return IDTokenSchema
  }

  /**
   * issue
   */
  static issue (request, response) {
    let {params, code, provider, client, subject} = request
    let {issuer, keys} = provider

    let alg = client['id_token_signed_response_alg'] || 'RS256'
    let key = keys['id_token'].signing[alg].privateKey
    let kid = keys['id_token'].signing[alg].publicJwk.kid
    let iss = issuer
    let jti = IDToken.random(8)
    let iat = Math.floor(Date.now() / 1000)
    let aud, sub, max, nonce

    // authentication request
    if (!code) {
      aud = client['client_id']
      sub = subject['_id']
      max = parseInt(params['max_age']) || client['default_max_age'] || 3600
      nonce = params.nonce

    // token request
    } else {
      aud = code.aud
      sub = code.sub
      max = parseInt(code['max']) || client['default_max_age'] || 3600
      nonce = code.nonce
    }

    let exp = iat + max

    let len = alg.match(/(256|384|512)$/)[0]

    // generate
    return Promise.all([
      IDToken.hashClaim(response['access_token'], len),
      IDToken.hashClaim(response['code'], len)
    ])

    // build the id_token
    .then(hashes => {
      let [at_hash, c_hash] = hashes
      let header = {alg, kid}
      let payload = {iss, aud, sub, exp, iat, jti, nonce, at_hash, c_hash}
      return new IDToken({header, payload, key})
    })

    // sign id token and add to response
    .then(jwt => {
      return jwt.encode().then(compact => {
        response['id_token'] = compact
        return response
      })
    })
  }

  /**
   * hashClaim
   *
   * @description
   * Create a hash for at_hash or c_hash claim
   *
   * @param {string} token
   * @param {string} hashLength
   *
   * @returns {Promise}
   */
  static hashClaim (value, hashLength) {
    if (value) {
      let alg = { name: `SHA-${hashLength}`}
      let octets = new Buffer(value, 'ascii')

      return crypto.subtle.digest(alg, new Uint8Array(octets)).then(digest => {
        let hash = Buffer.from(digest)
        let half = hash.slice(0, hash.byteLength / 2)
        return base64url(half)
      })
    }
  }

  static random (byteLen) {
    let value = crypto.getRandomValues(new Uint8Array(byteLen))
    return Buffer.from(value).toString('hex')
  }
}

/**
 * Export
 */
module.exports = IDToken
<|endoftext|>


<commit_before>/**
 * @preserve Copyright (c) 2010, CloudMade
 * Leaflet is a BSD-licensed JavaScript library for map display and interaction.
 * Check out the source on GitHub: http://github.com/CloudMade/Leaflet/
 */

var L = {
	VERSION: '0.1a3',

	ROOT_URL: (function() {
		var scripts = document.getElementsByTagName('script');
		for (var i = 0, len = scripts.length; i < len; i++) {
			var src = scripts[i].src,
				res = src && src.match(/^(.*\/)leaflet-*\w*\.js.*$/);
			if (res && res[1]) { return res[1]; }
		}
		return '../dist/';
	})(),

	noConflict: function() {
		L = this._originalL;
		return this;
	},

	_originalL: L
};<commit_msg>bump version<commit_after>/**
 * @preserve Copyright (c) 2010, CloudMade
 * Leaflet is a BSD-licensed JavaScript library for map display and interaction.
 * Check out the source on GitHub: http://github.com/CloudMade/Leaflet/
 */

var L = {
	VERSION: '0.1a4',

	ROOT_URL: (function() {
		var scripts = document.getElementsByTagName('script');
		for (var i = 0, len = scripts.length; i < len; i++) {
			var src = scripts[i].src,
				res = src && src.match(/^(.*\/)leaflet-*\w*\.js.*$/);
			if (res && res[1]) { return res[1]; }
		}
		return '../dist/';
	})(),

	noConflict: function() {
		L = this._originalL;
		return this;
	},

	_originalL: L
};<|endoftext|>


<commit_before>"use strict";

/**
 * @fileoverview SIP Subscriber (SIP-Specific Event Notifications RFC6665)
 */

/**
 * @augments SIP
 * @class Class creating a SIP Subscription.
 */
module.exports = function (SIP) {
SIP.Subscription = function (ua, target, event, options) {
  options = Object.create(options || Object.prototype);
  this.extraHeaders = options.extraHeaders = (options.extraHeaders || []).slice();

  this.id = null;
  this.state = 'init';

  if (!event) {
    throw new TypeError('Event necessary to create a subscription.');
  } else {
    //TODO: check for valid events here probably make a list in SIP.C; or leave it up to app to check?
    //The check may need to/should probably occur on the other side,
    this.event = event;
  }

  if(typeof options.expires !== 'number'){
    ua.logger.warn('expires must be a number. Using default of 3600.');
    this.expires = 3600;
  } else {
    this.expires = options.expires;
  }

  options.extraHeaders.push('Event: ' + this.event);
  options.extraHeaders.push('Expires: ' + this.expires);

  if (options.body) {
    this.body = options.body;
  }

  this.contact = ua.contact.toString();

  options.extraHeaders.push('Contact: '+ this.contact);
  options.extraHeaders.push('Allow: '+ SIP.Utils.getAllowedMethods(ua));

  SIP.Utils.augment(this, SIP.ClientContext, [ua, SIP.C.SUBSCRIBE, target, options]);

  this.logger = ua.getLogger('sip.subscription');

  this.dialog = null;
  this.timers = {N: null, sub_duration: null};
  this.errorCodes  = [404,405,410,416,480,481,482,483,484,485,489,501,604];
};

SIP.Subscription.prototype = {
  subscribe: function() {
    var sub = this;

    SIP.Timers.clearTimeout(this.timers.sub_duration);
    SIP.Timers.clearTimeout(this.timers.N);
    this.timers.N = SIP.Timers.setTimeout(sub.timer_fire.bind(sub), SIP.Timers.TIMER_N);

    this.send();

    this.state = 'notify_wait';

    return this;
  },

  refresh: function () {
    if (this.state === 'terminated' || this.state === 'pending' || this.state === 'notify_wait') {
      return;
    }

    this.dialog.sendRequest(this, SIP.C.SUBSCRIBE, {
      extraHeaders: this.extraHeaders,
      body: this.body
    });
  },

  receiveResponse: function(response) {
    var expires, sub = this,
        cause = SIP.Utils.getReasonPhrase(response.status_code);

    if (this.errorCodes.indexOf(response.status_code) !== -1) {
      this.failed(response, null);
    } else if (/^2[0-9]{2}$/.test(response.status_code)){
      expires = response.getHeader('Expires');
      SIP.Timers.clearTimeout(this.timers.N);

      if (this.createConfirmedDialog(response,'UAC')) {
        this.id = this.dialog.id.toString();
        this.ua.subscriptions[this.id] = this;
        this.emit('accepted', response, cause);
        // UPDATE ROUTE SET TO BE BACKWARDS COMPATIBLE?
      }

      if (expires && expires <= this.expires) {
        this.timers.sub_duration = SIP.Timers.setTimeout(sub.refresh.bind(sub), expires * 900);
      } else {
        if (!expires) {
          this.logger.warn('Expires header missing in a 200-class response to SUBSCRIBE');
          this.failed(response, SIP.C.EXPIRES_HEADER_MISSING);
        } else {
          this.logger.warn('Expires header in a 200-class response to SUBSCRIBE with a higher value than the one in the request');
          this.failed(response, SIP.C.INVALID_EXPIRES_HEADER);
        }
      }
    } //Used to just ignore provisional responses; now ignores everything except errorCodes and 2xx
  },

  unsubscribe: function() {
    var extraHeaders = [], sub = this;

    this.state = 'terminated';

    extraHeaders.push('Event: ' + this.event);
    extraHeaders.push('Expires: 0');

    extraHeaders.push('Contact: '+ this.contact);
    extraHeaders.push('Allow: '+ SIP.Utils.getAllowedMethods(this.ua));

    this.request = new SIP.OutgoingRequest(this.method, this.request.to.uri.toString(), this.ua, null, extraHeaders);

    //MAYBE, may want to see state
    this.receiveResponse = function(){};

    SIP.Timers.clearTimeout(this.timers.sub_duration);
    SIP.Timers.clearTimeout(this.timers.N);
    this.timers.N = SIP.Timers.setTimeout(sub.timer_fire.bind(sub), SIP.Timers.TIMER_N);

    this.send();
  },

  /**
  * @private
  */
  timer_fire: function(){
    if (this.state === 'terminated') {
      this.close();
    } else if (this.state === 'pending' || this.state === 'notify_wait') {
      this.state = 'terminated';
      this.close();
    } else {
      this.refresh();
    }
  },

  /**
  * @private
  */
  close: function() {
    if(this.state !== 'terminated') {
      this.unsubscribe();
    }

    this.terminateDialog();
    SIP.Timers.clearTimeout(this.timers.N);
    SIP.Timers.clearTimeout(this.timers.sub_duration);

    delete this.ua.subscriptions[this.id];
  },

  /**
  * @private
  */
  createConfirmedDialog: function(message, type) {
    var dialog;

    this.terminateDialog();
    dialog = new SIP.Dialog(this, message, type);

    if(!dialog.error) {
      this.dialog = dialog;
      return true;
    }
    // Dialog not created due to an error
    else {
      return false;
    }
  },

  /**
  * @private
  */
  terminateDialog: function() {
    if(this.dialog) {
      delete this.ua.subscriptions[this.id];
      this.dialog.terminate();
      delete this.dialog;
    }
  },

  /**
  * @private
  */
  receiveRequest: function(request) {
    var sub_state, sub = this;

    function setExpiresTimeout() {
      if (sub_state.expires) {
        sub_state.expires = Math.min(sub.expires,
                                     Math.max(sub_state.expires, 0));
        sub.timers.sub_duration = SIP.Timers.setTimeout(sub.refresh.bind(sub),
                                                    sub_state.expires * 900);
      }
    }

    if (!this.matchEvent(request)) { //checks event and subscription_state headers
      request.reply(489);
      return;
    }

    sub_state = request.parseHeader('Subscription-State');

    request.reply(200, SIP.C.REASON_200);

    SIP.Timers.clearTimeout(this.timers.N);
    SIP.Timers.clearTimeout(this.timers.sub_duration);

    this.emit('notify', {request: request});

    switch (sub_state.state) {
      case 'active':
        this.state = 'active';
        setExpiresTimeout();
        break;
      case 'pending':
        if (this.state === 'notify_wait') {
          setExpiresTimeout();
        }
        this.state = 'pending';
        break;
      case 'terminated':
        if (sub_state.reason) {
          this.logger.log('terminating subscription with reason '+ sub_state.reason);
          switch (sub_state.reason) {
            case 'deactivated':
            case 'timeout':
              this.subscribe();
              return;
            case 'probation':
            case 'giveup':
              if(sub_state.params && sub_state.params['retry-after']) {
                this.timers.sub_duration = SIP.Timers.setTimeout(sub.subscribe.bind(sub), sub_state.params['retry-after']);
              } else {
                this.subscribe();
              }
              return;
            case 'rejected':
            case 'noresource':
            case 'invariant':
              break;
          }
        }
        this.close();
        break;
    }
  },

  failed: function(response, cause) {
    this.close();
    this.emit('failed', response, cause);
    return this;
  },

  /**
  * @private
  */
  matchEvent: function(request) {
    var event;

    // Check mandatory header Event
    if (!request.hasHeader('Event')) {
      this.logger.warn('missing Event header');
      return false;
    }
    // Check mandatory header Subscription-State
    if (!request.hasHeader('Subscription-State')) {
      this.logger.warn('missing Subscription-State header');
      return false;
    }

    // Check whether the event in NOTIFY matches the event in SUBSCRIBE
    event = request.parseHeader('event').event;

    if (this.event !== event) {
      this.logger.warn('event match failed');
      request.reply(481, 'Event Match Failed');
      return false;
    } else {
      return true;
    }
  }
};
};
<commit_msg>Resolves onsip/SIP.js#234<commit_after>"use strict";

/**
 * @fileoverview SIP Subscriber (SIP-Specific Event Notifications RFC6665)
 */

/**
 * @augments SIP
 * @class Class creating a SIP Subscription.
 */
module.exports = function (SIP) {
SIP.Subscription = function (ua, target, event, options) {
  options = Object.create(options || Object.prototype);
  this.extraHeaders = options.extraHeaders = (options.extraHeaders || []).slice();

  this.id = null;
  this.state = 'init';

  if (!event) {
    throw new TypeError('Event necessary to create a subscription.');
  } else {
    //TODO: check for valid events here probably make a list in SIP.C; or leave it up to app to check?
    //The check may need to/should probably occur on the other side,
    this.event = event;
  }

  if(typeof options.expires !== 'number'){
    ua.logger.warn('expires must be a number. Using default of 3600.');
    this.expires = 3600;
  } else {
    this.expires = options.expires;
  }

  options.extraHeaders.push('Event: ' + this.event);
  options.extraHeaders.push('Expires: ' + this.expires);

  if (options.body) {
    this.body = options.body;
  }

  this.contact = ua.contact.toString();

  options.extraHeaders.push('Contact: '+ this.contact);
  options.extraHeaders.push('Allow: '+ SIP.Utils.getAllowedMethods(ua));

  SIP.Utils.augment(this, SIP.ClientContext, [ua, SIP.C.SUBSCRIBE, target, options]);

  this.logger = ua.getLogger('sip.subscription');

  this.dialog = null;
  this.timers = {N: null, sub_duration: null};
  this.errorCodes  = [404,405,410,416,480,481,482,483,484,485,489,501,604];
};

SIP.Subscription.prototype = {
  subscribe: function() {
    var sub = this;

    SIP.Timers.clearTimeout(this.timers.sub_duration);
    SIP.Timers.clearTimeout(this.timers.N);
    this.timers.N = SIP.Timers.setTimeout(sub.timer_fire.bind(sub), SIP.Timers.TIMER_N);

    this.send();

    this.state = 'notify_wait';

    return this;
  },

  refresh: function () {
    if (this.state === 'terminated' || this.state === 'pending' || this.state === 'notify_wait') {
      return;
    }

    this.dialog.sendRequest(this, SIP.C.SUBSCRIBE, {
      extraHeaders: this.extraHeaders,
      body: this.body
    });
  },

  receiveResponse: function(response) {
    var expires, sub = this,
        cause = SIP.Utils.getReasonPhrase(response.status_code);

    if (this.errorCodes.indexOf(response.status_code) !== -1) {
      this.failed(response, null);
    } else if (/^2[0-9]{2}$/.test(response.status_code)){
      expires = response.getHeader('Expires');
      SIP.Timers.clearTimeout(this.timers.N);

      if (this.createConfirmedDialog(response,'UAC')) {
        this.id = this.dialog.id.toString();
        this.ua.subscriptions[this.id] = this;
        this.emit('accepted', response, cause);
        // UPDATE ROUTE SET TO BE BACKWARDS COMPATIBLE?
      }

      if (expires && expires <= this.expires) {
        this.timers.sub_duration = SIP.Timers.setTimeout(sub.refresh.bind(sub), expires * 900);
      } else {
        if (!expires) {
          this.logger.warn('Expires header missing in a 200-class response to SUBSCRIBE');
          this.failed(response, SIP.C.EXPIRES_HEADER_MISSING);
        } else {
          this.logger.warn('Expires header in a 200-class response to SUBSCRIBE with a higher value than the one in the request');
          this.failed(response, SIP.C.INVALID_EXPIRES_HEADER);
        }
      }
    } //Used to just ignore provisional responses; now ignores everything except errorCodes and 2xx
  },

  unsubscribe: function() {
    var extraHeaders = [], sub = this;

    this.state = 'terminated';

    extraHeaders.push('Event: ' + this.event);
    extraHeaders.push('Expires: 0');

    extraHeaders.push('Contact: '+ this.contact);
    extraHeaders.push('Allow: '+ SIP.Utils.getAllowedMethods(this.ua));

    this.request = new SIP.OutgoingRequest(this.method, this.request.to.uri.toString(), this.ua, null, extraHeaders);

    //MAYBE, may want to see state
    this.receiveResponse = function(){};

    SIP.Timers.clearTimeout(this.timers.sub_duration);
    SIP.Timers.clearTimeout(this.timers.N);
    this.timers.N = SIP.Timers.setTimeout(sub.timer_fire.bind(sub), SIP.Timers.TIMER_N);

    this.send();
  },

  /**
  * @private
  */
  timer_fire: function(){
    if (this.state === 'terminated') {
      this.close();
    } else if (this.state === 'pending' || this.state === 'notify_wait') {
      this.state = 'terminated';
      this.close();
    } else {
      this.refresh();
    }
  },

  /**
  * @private
  */
  close: function() {
    if(this.state !== 'terminated') {
      this.unsubscribe();
    }

    this.terminateDialog();
    SIP.Timers.clearTimeout(this.timers.N);
    SIP.Timers.clearTimeout(this.timers.sub_duration);

    delete this.ua.subscriptions[this.id];
  },

  /**
  * @private
  */
  createConfirmedDialog: function(message, type) {
    var dialog;

    this.terminateDialog();
    dialog = new SIP.Dialog(this, message, type);

    if(!dialog.error) {
      this.dialog = dialog;
      return true;
    }
    // Dialog not created due to an error
    else {
      return false;
    }
  },

  /**
  * @private
  */
  terminateDialog: function() {
    if(this.dialog) {
      delete this.ua.subscriptions[this.id];
      this.dialog.terminate();
      delete this.dialog;
    }
  },

  /**
  * @private
  */
  receiveRequest: function(request) {
    var sub_state, sub = this;

    function setExpiresTimeout() {
      if (sub_state.expires) {
        sub_state.expires = Math.min(sub.expires,
                                     Math.max(sub_state.expires, 0));
        sub.timers.sub_duration = SIP.Timers.setTimeout(sub.refresh.bind(sub),
                                                    sub_state.expires * 900);
      }
    }

    if (!this.matchEvent(request)) { //checks event and subscription_state headers
      request.reply(489);
      return;
    }

    sub_state = request.parseHeader('Subscription-State');

    request.reply(200, SIP.C.REASON_200);

    SIP.Timers.clearTimeout(this.timers.N);
    SIP.Timers.clearTimeout(this.timers.sub_duration);

    this.emit('notify', {request: request});

    switch (sub_state.state) {
      case 'active':
        this.state = 'active';
        setExpiresTimeout();
        break;
      case 'pending':
        if (this.state === 'notify_wait') {
          setExpiresTimeout();
        }
        this.state = 'pending';
        break;
      case 'terminated':
        if (sub_state.reason) {
          this.logger.log('terminating subscription with reason '+ sub_state.reason);
          switch (sub_state.reason) {
            case 'deactivated':
            case 'timeout':
              this.terminateDialog();
              this.request = new SIP.OutgoingRequest(this.method, this.request.to.uri.toString(), this.ua, null, this.extraHeaders.slice());
              this.subscribe();
              return;
            case 'probation':
            case 'giveup':
              if(sub_state.params && sub_state.params['retry-after']) {
                this.timers.sub_duration = SIP.Timers.setTimeout(sub.subscribe.bind(sub), sub_state.params['retry-after']);
              } else {
                this.subscribe();
              }
              return;
            case 'rejected':
            case 'noresource':
            case 'invariant':
              break;
          }
        }
        this.close();
        break;
    }
  },

  failed: function(response, cause) {
    this.close();
    this.emit('failed', response, cause);
    return this;
  },

  /**
  * @private
  */
  matchEvent: function(request) {
    var event;

    // Check mandatory header Event
    if (!request.hasHeader('Event')) {
      this.logger.warn('missing Event header');
      return false;
    }
    // Check mandatory header Subscription-State
    if (!request.hasHeader('Subscription-State')) {
      this.logger.warn('missing Subscription-State header');
      return false;
    }

    // Check whether the event in NOTIFY matches the event in SUBSCRIBE
    event = request.parseHeader('event').event;

    if (this.event !== event) {
      this.logger.warn('event match failed');
      request.reply(481, 'Event Match Failed');
      return false;
    } else {
      return true;
    }
  }
};
};
<|endoftext|>


<commit_before>'use strict';

const rethinkDB = require('rethinkdb');

const common = require('./../common');
const log = require('./../log');
const idMapper = require('./../idMapper');

const dbp = require('./DungeonBluePrints');
const sbp = require('./SurfaceBluePrints');
const customLocations = require('./customLocations');

export class WorldGenerator {
  constructor (conn, worldSize, locationSize, numDungeon, postProcessor) {
    this.conn = conn;
    this.worldSize = worldSize;
    this.locationSize = locationSize;
    this.numDungeon = numDungeon;
    this.idMapper = new idMapper.IdMapper();;
    this.postProcessor = postProcessor;

    this.world = [];
    for (let i = 0; i < this.worldSize; i++) this.world.push([]);

    this.dungeons = {};
    this.dungeonBluePrints = new dbp.DungeonBluePrints(this.numDungeon, this.worldSize, this.locationSize);
    this.postProcessor.increment(this.dungeonBluePrints.generate());

    this.surfaceBluePrints = new sbp.SurfaceBluePrints(this.worldSize, this.dungeonBluePrints);
    this.postProcessor.increment(this.surfaceBluePrints.generate());
  }

  getLocation (locationId, locationType, dungeonBP) {
    const location = customLocations[locationType];
    return new location(this.conn,
      this.locationSize,
      locationId,
      dungeonBP,
      this.idMapper,
      this.postProcessor);
  }

  writeWorldMap () {
    let buffer = [];

    for (let locationId in this.surfaceBluePrints.blueprints) {
      const locationElem = this.surfaceBluePrints.getBluePrints(locationId);
      locationElem.location = locationId;

      buffer.push(locationElem);
    }

    for (let locationId in this.dungeonBluePrints.blueprints) {
      const bp = this.dungeonBluePrints.getBluePrints(locationId);

      for (let dungLocationId in bp.neighbors) {
        const locationElem = bp.neighbors[dungLocationId];
        locationElem.location = dungLocationId;
        buffer.push(locationElem);
      }
    }

    rethinkDB
      .tableCreate('worldMap')
      .run(this.conn, (err) => {
        if (err) throw err;

        log.info(`Table for world map created`);

        rethinkDB
          .table('worldMap')
          .insert(buffer)
          .run(this.conn, (err) => {
            if (err) throw err;

            log.info(`World's map created and written to the disk.`)
            this.postProcessor.decrement(1);
          });
      });
  }

  createDungeons () {
    for (let locationId in this.dungeonBluePrints.blueprints) {
      const dungeonBP = this.dungeonBluePrints.getBluePrints(locationId);
      const dungeonId = dungeonBP.dungeonId;

      for (let i = 0; i < dungeonBP.levels; i++) {
        const dungLocationId = dbp.DungeonBluePrints.getDungeonLocationId(dungeonId, i);
        const locationType = dungeonBP.neighbors[dungLocationId].locationType;

        this.dungeons[locationId] = this.getLocation(dungLocationId, locationType, dungeonBP);
        this.dungeons[locationId].generate(i);
      }
    }
  }

  createSurface () {
    for (let locationId in this.surfaceBluePrints.blueprints) {
      const dungeonBP = this.dungeonBluePrints.getBluePrints(locationId);
      const surfaceBP = this.surfaceBluePrints.getBluePrints(locationId);

      const location = this.getLocation(locationId, surfaceBP.locationType, dungeonBP);
      location.generate();
    }
  }

  generate () {
    rethinkDB
    rethinkDB
    .tableCreate('locations')
    .run(this.conn, (err) => {
      if (err) throw err;

      this.createDungeons();
      this.createSurface();

      this.writeWorldMap();
    });

    return this.surfaceBluePrints.getStartLocationId();
  }
}
<commit_msg>fix typo<commit_after>'use strict';

const rethinkDB = require('rethinkdb');

const common = require('./../common');
const log = require('./../log');
const idMapper = require('./../idMapper');

const dbp = require('./DungeonBluePrints');
const sbp = require('./SurfaceBluePrints');
const customLocations = require('./customLocations');

export class WorldGenerator {
  constructor (conn, worldSize, locationSize, numDungeon, postProcessor) {
    this.conn = conn;
    this.worldSize = worldSize;
    this.locationSize = locationSize;
    this.numDungeon = numDungeon;
    this.idMapper = new idMapper.IdMapper();
    this.postProcessor = postProcessor;

    this.world = [];
    for (let i = 0; i < this.worldSize; i++) this.world.push([]);

    this.dungeons = {};
    this.dungeonBluePrints = new dbp.DungeonBluePrints(this.numDungeon, this.worldSize, this.locationSize);
    this.postProcessor.increment(this.dungeonBluePrints.generate());

    this.surfaceBluePrints = new sbp.SurfaceBluePrints(this.worldSize, this.dungeonBluePrints);
    this.postProcessor.increment(this.surfaceBluePrints.generate());
  }

  getLocation (locationId, locationType, dungeonBP) {
    const location = customLocations[locationType];
    return new location(this.conn,
      this.locationSize,
      locationId,
      dungeonBP,
      this.idMapper,
      this.postProcessor);
  }

  writeWorldMap () {
    let buffer = [];

    for (let locationId in this.surfaceBluePrints.blueprints) {
      const locationElem = this.surfaceBluePrints.getBluePrints(locationId);
      locationElem.location = locationId;

      buffer.push(locationElem);
    }

    for (let locationId in this.dungeonBluePrints.blueprints) {
      const bp = this.dungeonBluePrints.getBluePrints(locationId);

      for (let dungLocationId in bp.neighbors) {
        const locationElem = bp.neighbors[dungLocationId];
        locationElem.location = dungLocationId;
        buffer.push(locationElem);
      }
    }

    rethinkDB
      .tableCreate('worldMap')
      .run(this.conn, (err) => {
        if (err) throw err;

        log.info(`Table for world map created`);

        rethinkDB
          .table('worldMap')
          .insert(buffer)
          .run(this.conn, (err) => {
            if (err) throw err;

            log.info(`World's map created and written to the disk.`)
            this.postProcessor.decrement(1);
          });
      });
  }

  createDungeons () {
    for (let locationId in this.dungeonBluePrints.blueprints) {
      const dungeonBP = this.dungeonBluePrints.getBluePrints(locationId);
      const dungeonId = dungeonBP.dungeonId;

      for (let i = 0; i < dungeonBP.levels; i++) {
        const dungLocationId = dbp.DungeonBluePrints.getDungeonLocationId(dungeonId, i);
        const locationType = dungeonBP.neighbors[dungLocationId].locationType;

        this.dungeons[locationId] = this.getLocation(dungLocationId, locationType, dungeonBP);
        this.dungeons[locationId].generate(i);
      }
    }
  }

  createSurface () {
    for (let locationId in this.surfaceBluePrints.blueprints) {
      const dungeonBP = this.dungeonBluePrints.getBluePrints(locationId);
      const surfaceBP = this.surfaceBluePrints.getBluePrints(locationId);

      const location = this.getLocation(locationId, surfaceBP.locationType, dungeonBP);
      location.generate();
    }
  }

  generate () {
    rethinkDB
    rethinkDB
    .tableCreate('locations')
    .run(this.conn, (err) => {
      if (err) throw err;

      this.createDungeons();
      this.createSurface();

      this.writeWorldMap();
    });

    return this.surfaceBluePrints.getStartLocationId();
  }
}
<|endoftext|>


<commit_before>var async        = require('async');
var Member       = require('./../../db/models/member.js');
var Company      = require('./../../db/models/company.js');
var Speaker      = require('./../../db/models/speaker.js');
var Notification = require('./../../db/models/notification.js');

exports = module.exports = notify;

function notify(memberId, thread, thingName, thingType, memberName) {

  var members = [];
  async.series([
    getMembers,
    saveNotification
  ], done);

  function getMembers(cb) {
    Member.findAll(gotMembers);

    function gotMembers(err, result) {
      if (err)
        return cb(err);

      for(var member in result) {
        if(result[member].id != memberId){
          members.push(result[member].id);
        }
      }
      cb();
    }
  }

  function saveNotification(cb) {
    var newNotification = new Notification({
      thread: thread,
      member: memberId,
      description: memberName+' created a new ' +thingType+ ' named ' +thingName+'.',
      unread: members,
      posted: Date.now()
    });

    newNotification.save(function (err, reply){
      if (err) { return cb('Hipcup on the DB' + err);}
      cb();
    });
  }

  function done(err) {
    if (err) {
      console.log("There was an error! "+ err);
    } else {
      console.log("Notification saved!");
    }
  }

}
<commit_msg>nothing<commit_after>var async        = require('async');
var Member       = require('./../../db/models/member.js');
var Company      = require('./../../db/models/company.js');
var Speaker      = require('./../../db/models/speaker.js');
var Notification = require('./../../db/models/notification.js');

exports = module.exports = notify;

function notify(memberId, thread, thingName, thingType, memberName) {

  var members = [];
  async.series([
    getMembers,
    saveNotification
  ], done);

  function getMembers(cb) {
    Member.findAll(gotMembers);

    function gotMembers(err, result) {
      if (err)
        return cb(err);

      for(var member in result) {
        if(result[member].id != memberId){
          members.push(result[member].id);
        }
      }
      cb();
    }
  }

  function saveNotification(cb) {
    var newNotification = new Notification({
      thread: thread,
      member: memberId,
      description: memberName+' created a new ' +thingType+ ' named ' +thingName+'.',
      unread: members,
      posted: Date.now()
    });

    newNotification.save(function (err, reply){
      if (err) {
        cb('Hipcup on the DB' + err);
      }
      else {
        cb();
      }
    });
  }

  function done(err) {
    if (err) {
      console.log("There was an error! "+ err);
    } else {
      console.log("Notification saved!");
    }
  }

}
<|endoftext|>


<commit_before>define(function() {
    'use strict';

    var models = {};
    var collections = {};

    models.Release = Backbone.Model.extend({
        urlRoot: '/api/releases'
    });

    models.Releases = Backbone.Collection.extend({
        model: models.Release,
        url: '/api/releases'
    });

    models.Cluster = Backbone.Model.extend({
        urlRoot: '/api/clusters',
        validate: function(attrs) {
            var errors = {};
            if (!attrs.name || attrs.name.length == 0) {
                errors.name = 'Cluster name cannot be empty';
            } else if (attrs.name.length > 100) {
                errors.name = 'Cluster name is too long';
            }
            if (!attrs.release) {
                errors.release = 'Please choose OpenStack release';
            }
            if (attrs.mode == 'ha') {
                if (_.isNaN(attrs.redundancy)) {
                    errors.redundancy = 'Please enter integer number';
                } else if (attrs.redundancy < 2 || attrs.redundancy > 9) {
                    errors.redundancy = 'Please enter number between 2 and 9';
                }
            }
            return _.isEmpty(errors) ? null : errors;
        },
        task: function(taskName, status) {
            var options = {name: taskName};
            if (status) {
                options.status = status;
            }
            return this.get('tasks') && this.get('tasks').where(options)[0];
        },
        hasChanges: function() {
            return _.any(this.get('nodes').pluck('redeployment_needed'));
        },
        availableModes: function() {
            return ['simple', 'ha'];
        },
        availableTypes: function() {
            return ['both', 'compute', 'storage'];
        },
        availableRoles: function() {
            var roles = [];
            if (this.get('type') == 'storage') {
                roles = ['controller', 'storage'];
            } else if (this.get('type') == 'compute') {
                roles = ['controller', 'compute'];
            } else {
                roles = ['controller', 'compute', 'storage'];
            }
            return roles;
        },
        parse: function(response) {
            response.release = new models.Release(response.release);
            response.nodes = new models.Nodes(response.nodes);
            response.nodes.cluster = this;
            response.tasks = new models.Tasks(response.tasks);
            response.tasks.cluster = this;
            return response;
        }
    });

    models.Clusters = Backbone.Collection.extend({
        model: models.Cluster,
        url: '/api/clusters',
        toJSON: function(options) {
            return this.pluck('id');
        }
    });

    models.Node = Backbone.Model.extend({
        urlRoot: '/api/nodes',
        fullProductName: function() {
            return (this.get('manufacturer') ? this.get('manufacturer') + ' ' + this.get('platform_name') : this.get('platform_name')) || 'Unknown Platform';
        },
        resource: function(resourceName) {
            return this.get('info')[resourceName];
        }
    });

    models.Nodes = Backbone.Collection.extend({
        model: models.Node,
        url: '/api/nodes',
        toJSON: function(options) {
            return this.pluck('id');
        },
        resources: function(resourceName) {
            var resources = this.map(function(node) {return node.resource(resourceName);});
            return _.reduce(resources, function(sum, n) {return sum + n;}, 0);
        }
    });

    models.Task = Backbone.Model.extend({
        urlRoot: '/api/tasks'
    });

    models.Tasks = Backbone.Collection.extend({
        model: models.Task,
        url: '/api/tasks',
        toJSON: function(options) {
            return this.pluck('id');
        }
    });

    models.Settings = Backbone.Model.extend({
        urlRoot: '/api/clusters/'
    });

    models.Network = Backbone.Model.extend({
        urlRoot: '/api/networks',
        validate: function(attrs) {
            var errors = {};
            if (!_.isString(attrs.cidr) || !/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/.test(attrs.cidr)) {
                errors.cidr = 'Invalid CIDR';
            }
            if (!_.isNumber(attrs.vlan_id) || attrs.vlan_id < 1 || attrs.vlan_id > 4094) {
                errors.vlan_id = 'Invalid VLAN ID';
            }
            return _.isEmpty(errors) ? null : errors;
        }
    });

    models.Networks = Backbone.Collection.extend({
        model: models.Network,
        url: '/api/networks'
    });

    return models;
});
<commit_msg>Extended CIDR validation<commit_after>define(function() {
    'use strict';

    var models = {};
    var collections = {};

    models.Release = Backbone.Model.extend({
        urlRoot: '/api/releases'
    });

    models.Releases = Backbone.Collection.extend({
        model: models.Release,
        url: '/api/releases'
    });

    models.Cluster = Backbone.Model.extend({
        urlRoot: '/api/clusters',
        validate: function(attrs) {
            var errors = {};
            if (!attrs.name || attrs.name.length == 0) {
                errors.name = 'Cluster name cannot be empty';
            } else if (attrs.name.length > 100) {
                errors.name = 'Cluster name is too long';
            }
            if (!attrs.release) {
                errors.release = 'Please choose OpenStack release';
            }
            if (attrs.mode == 'ha') {
                if (_.isNaN(attrs.redundancy)) {
                    errors.redundancy = 'Please enter integer number';
                } else if (attrs.redundancy < 2 || attrs.redundancy > 9) {
                    errors.redundancy = 'Please enter number between 2 and 9';
                }
            }
            return _.isEmpty(errors) ? null : errors;
        },
        task: function(taskName, status) {
            var options = {name: taskName};
            if (status) {
                options.status = status;
            }
            return this.get('tasks') && this.get('tasks').where(options)[0];
        },
        hasChanges: function() {
            return _.any(this.get('nodes').pluck('redeployment_needed'));
        },
        availableModes: function() {
            return ['simple', 'ha'];
        },
        availableTypes: function() {
            return ['both', 'compute', 'storage'];
        },
        availableRoles: function() {
            var roles = [];
            if (this.get('type') == 'storage') {
                roles = ['controller', 'storage'];
            } else if (this.get('type') == 'compute') {
                roles = ['controller', 'compute'];
            } else {
                roles = ['controller', 'compute', 'storage'];
            }
            return roles;
        },
        parse: function(response) {
            response.release = new models.Release(response.release);
            response.nodes = new models.Nodes(response.nodes);
            response.nodes.cluster = this;
            response.tasks = new models.Tasks(response.tasks);
            response.tasks.cluster = this;
            return response;
        }
    });

    models.Clusters = Backbone.Collection.extend({
        model: models.Cluster,
        url: '/api/clusters',
        toJSON: function(options) {
            return this.pluck('id');
        }
    });

    models.Node = Backbone.Model.extend({
        urlRoot: '/api/nodes',
        fullProductName: function() {
            return (this.get('manufacturer') ? this.get('manufacturer') + ' ' + this.get('platform_name') : this.get('platform_name')) || 'Unknown Platform';
        },
        resource: function(resourceName) {
            return this.get('info')[resourceName];
        }
    });

    models.Nodes = Backbone.Collection.extend({
        model: models.Node,
        url: '/api/nodes',
        toJSON: function(options) {
            return this.pluck('id');
        },
        resources: function(resourceName) {
            var resources = this.map(function(node) {return node.resource(resourceName);});
            return _.reduce(resources, function(sum, n) {return sum + n;}, 0);
        }
    });

    models.Task = Backbone.Model.extend({
        urlRoot: '/api/tasks'
    });

    models.Tasks = Backbone.Collection.extend({
        model: models.Task,
        url: '/api/tasks',
        toJSON: function(options) {
            return this.pluck('id');
        }
    });

    models.Settings = Backbone.Model.extend({
        urlRoot: '/api/clusters/'
    });

    models.Network = Backbone.Model.extend({
        urlRoot: '/api/networks',
        validate: function(attrs) {
            var errors = {};
            if (_.isString(attrs.cidr)) {
                var cidrRegexp = /^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2]\d|3[0-2])$/;
                var match = attrs.cidr.match(cidrRegexp);
                if (match) {
                    var prefix = parseInt(match[1], 10);
                    if (prefix < 2) {
                        errors.cidr = 'Network is too large';
                    } else if (prefix > 31) {
                        errors.cidr = 'Network is too small';
                    }
                } else {
                    errors.cidr = 'Invalid CIDR';
                }
            } else {
                errors.cidr = 'Invalid CIDR';
            }
            if (!_.isNumber(attrs.vlan_id) || attrs.vlan_id < 1 || attrs.vlan_id > 4094) {
                errors.vlan_id = 'Invalid VLAN ID';
            }
            return _.isEmpty(errors) ? null : errors;
        }
    });

    models.Networks = Backbone.Collection.extend({
        model: models.Network,
        url: '/api/networks'
    });

    return models;
});
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
import fs from 'fs'
import {spawn} from 'child_process'
import hooks from './hooks'

/**
 * Runner class.
 *
 * @class Runner
 * @classdesc Automatically runs a specified hook script once instantiated from
 * within a Git hook script ($GIT_DIR/hooks/<hook-name>). Can be used elsewhere
 */
export default class Runner {
  /**
   * Constructs an instance of Runner.
   *
   * @param {string} hook - Name of hook script.
   * @param {string} [config=../../package.json] - Path to target JSON config.
   * @constructs Runner
   */
  constructor (hook, config = './package.json') {
    this.hook = this._validate(hook)
    this.commands = this._parse(config)
  }

  /**
   * Asynchronously runs "npm test -s" when this Runner's hook script is called
   * by Git by spawning a child process.
   *
   * Parent process shares readable and writable stream objects with the child
   * process to preserve child process' STDOUT formatting.
   *
   * For more see {@link
   * https://nodejs.org/api/child_process.html#child_process_options_stdio |
   * child_process options.stdio "inherit"}.
   *
   * @method run
   * @public
   */
  run () {
    spawn('npm', ['test', '-s'], {
      stdio: [process.stdin, process.stdout, process.stderr]
    })
  }

  /**
   * Validates whether or not a provided hook is recognized by Git.
   *
   * @method _validate
   * @param {*} hook - Hook name to validate.
   * @throws {Error} Thrown if hook is not recognized by Git.
   * @returns {string} Valid hook name.
   * @protected
   */
  _validate (hook) {
    if (typeof hook === 'undefined') {
      throw new Error('Missing required hook argument')
    }

    if (hooks.indexOf(hook) === -1) {
      throw new Error(`"${hook}" is not valid hook name`)
    }

    return hook
  }

  /**
   * Parses default or provided JSON config for hooks.
   *
   * @method _parse
   * @param {string} config - JSON config file to parse.
   * @returns {string[]} Commands to be parsed to child_process.spawn().
   * @protected
   */
  _parse (config) {
    try {
      const file = fs.readFileSync(config, 'utf8')
      const parsed = JSON.parse(file)
      const commands = parsed.hooks[this.hook].split(' ')

      return [commands.shift(), commands]
    } catch (err) {
      return false
    }
  }
}
<commit_msg>Replace stubbed "npm test -s" for provided command<commit_after>/**
 * Module dependencies.
 */
import fs from 'fs'
import {spawn} from 'child_process'
import hooks from './hooks'

/**
 * Runner class.
 *
 * @class Runner
 * @classdesc Automatically runs a specified hook script once instantiated from
 * within a Git hook script ($GIT_DIR/hooks/<hook-name>). Can be used elsewhere
 */
export default class Runner {
  /**
   * Constructs an instance of Runner.
   *
   * @param {string} hook - Name of hook script.
   * @param {string} [config=../../package.json] - Path to target JSON config.
   * @constructs Runner
   */
  constructor (hook, config = './package.json') {
    this.hook = this._validate(hook)
    this.commands = this._parse(config)
  }

  /**
   * Asynchronously runs this runner's command as a child process.
   *
   * Parent process shares readable and writable stream objects with the child
   * process to preserve child process' STDOUT formatting.
   *
   * For more see {@link
   * https://nodejs.org/api/child_process.html#child_process_options_stdio |
   * child_process options.stdio "inherit"}.
   *
   * @method run
   * @public
   */
  run () {
    const cmd = this.commands

    if (cmd) {
      spawn(cmd[0], cmd[1], {
        stdio: [process.stdin, process.stdout, process.stderr]
      })
    }
  }

  /**
   * Validates whether or not a provided hook is recognized by Git.
   *
   * @method _validate
   * @param {*} hook - Hook name to validate.
   * @throws {Error} Thrown if hook is not recognized by Git.
   * @returns {string} Valid hook name.
   * @protected
   */
  _validate (hook) {
    if (typeof hook === 'undefined') {
      throw new Error('Missing required hook argument')
    }

    if (hooks.indexOf(hook) === -1) {
      throw new Error(`"${hook}" is not valid hook name`)
    }

    return hook
  }

  /**
   * Parses default or provided JSON config for hooks.
   *
   * @method _parse
   * @param {string} config - JSON config file to parse.
   * @returns {string[]} Commands to be parsed to child_process.spawn().
   * @protected
   */
  _parse (config) {
    try {
      const file = fs.readFileSync(config, 'utf8')
      const parsed = JSON.parse(file)
      const commands = parsed.hooks[this.hook].split(' ')

      return [commands.shift(), commands]
    } catch (err) {
      return false
    }
  }
}
<|endoftext|>


<commit_before>/**
 * Created by steve on 15/09/15.
 */
import React from 'react';
import ComposedComponent from './ComposedComponent';
import MenuItem from '@material-ui/core/MenuItem';
import MuiSelect from '@material-ui/core/Select';

class Select extends React.Component {

    constructor(props) {
        super(props);
        this.onSelected = this.onSelected.bind(this);
        var possibleValue = this.getModelKey(this.props.model, this.props.form.key);
        this.state = {
            currentValue: this.props.model !== undefined && possibleValue ? possibleValue : this.props.form.titleMap != null ? this.props.form.titleMap[0].value : ''
        };
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.model && nextProps.form.key) {
            this.setState({
                currentValue: this.getModelKey(nextProps.model, nextProps.form.key)
                || (nextProps.form.titleMap != null ? nextProps.form.titleMap[0].value : '')
            });
        }
    }

    getModelKey(model, key) {
        if (Array.isArray(key)) {
            return key.reduce((cur, nxt) => (cur[nxt] || {}), model);
        } else {
            return model[key];
        }
    }

    onSelected(event, selectedIndex, menuItem) {

        this.setState({
            currentValue: menuItem
        });
        event.target.value = menuItem;
        this.props.onChangeValidate(event);
    }

    render() {
        const menuItems = this.props.form.titleMap.map((item, idx) => (
          <MenuItem key={idx} value={item.value}>{item.name}</MenuItem>
        ));

        return (

                <MuiSelect
                    value={this.state.currentValue}
                    placeholder={this.props.form.title}
                    disabled={this.props.form.readonly}
                    onChange={this.onSelected}
                    fullWidth >
                    {menuItems}
                </MuiSelect>

        );
    }
}

// Select.propTypes = {
//
// };

export default ComposedComponent(Select);
<commit_msg>Fix initial value for Select<commit_after>/**
 * Created by steve on 15/09/15.
 */
import React from 'react';
import ComposedComponent from './ComposedComponent';
import MenuItem from '@material-ui/core/MenuItem';
import MuiSelect from '@material-ui/core/Select';

class Select extends React.Component {

    state = {
        currentValue: this.getInitialValue(this.props.model, this.props.form)
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.model && nextProps.form.key) {
            this.setState({
                currentValue: this.getInitialValue(nextProps.model, nextProps.form)
            });
        }
    }

    getInitialValue (model, form) {
        return this.getModelValue(model, form.key) || (form.titleMap != null ? form.titleMap[0].value : '')
    }

    getModelValue(model, key) {
        if (Array.isArray(key)) {
            return key.reduce((cur, nxt) => cur && cur[nxt], model);
        } else {
            return model[key];
        }
    }

    onSelected = (event) => {
        let currentValue = event.target.value
        this.setState({
            currentValue
        });
        this.props.onChangeValidate(event);
    }

    render() {
        const menuItems = this.props.form.titleMap.map((item, idx) => (
            <MenuItem key={idx} value={item.value}>{item.name}</MenuItem>
        ));
        return (

                <MuiSelect
                    value={this.state.currentValue}
                    placeholder={this.props.form.title}
                    disabled={this.props.form.readonly}
                    onChange={this.onSelected}
                    fullWidth >
                    {menuItems}
                </MuiSelect>

        );
    }
}

// Select.propTypes = {
//
// };

export default ComposedComponent(Select);
<|endoftext|>


<commit_before>const assert = require('assert');

// Turn the string into an array
// For example: if the input string is "Hello-World", then your program
// should return the string "hELLo-wORLD"
// loop through the array-swap letter cases
// uppercase -> lowercase
// lowercase -> uppercase
// return modified array as a string

const swapCase = str => {
  const chars = str.split('');

  for (let i = 0; i < chars.length; i += 1) {
    if (chars[i] === chars[i].toUpperCase()) {
      chars[i] = chars[i].toLowerCase();
    } else if (chars[i] === chars[i].toLowerCase()) {
      chars[i] = chars[i].toUpperCase();
    }
  }

  const caseStr = chars.join('');
  // console.log(caseStr);
  return caseStr;

};

const in1 = 'Hello-World'; // input
const expect1 = 'hELLO-wORLD'; // output
const test1 = swapCase(in1);
assert.strictEqual(test1, expect1, `should be ${expect1}`);
// console.log('swapCase');

t2 = swapCase('LengThforC');
console.log(t2);
assert(t2);
<commit_msg>prettier fix spacing, comment out console.log, edit test<commit_after>const assert = require('assert');

// Turn the string into an array
// For example: if the input string is "Hello-World", then your program
// should return the string "hELLo-wORLD"
// loop through the array-swap letter cases
// uppercase -> lowercase
// lowercase -> uppercase
// return modified array as a string

const swapCase = (str) => {
  const chars = str.split('');

  for (let i = 0; i < chars.length; i += 1) {
    if (chars[i] === chars[i].toUpperCase()) {
      chars[i] = chars[i].toLowerCase();
    } else if (chars[i] === chars[i].toLowerCase()) {
      chars[i] = chars[i].toUpperCase();
    }
  }

  const caseStr = chars.join('');
  // console.log(caseStr);
  return caseStr;
};

const in1 = 'Hello-World'; // input
const expect1 = 'hELLO-wORLD'; // output
const test1 = swapCase(in1);
assert.strictEqual(test1, expect1, `should be ${expect1}`);
// console.log('swapCase');

const t2 = swapCase('LengThforC');
assert(t2);
// console.log(t2);
<|endoftext|>


<commit_before>'use strict';

var express = require('express'),
    cookieParser = require('cookie-parser'),
    bodyParser = require('body-parser'),
    session = require('express-session'),
    async = require('async'),
    passport = require('passport'),
    GoogleStrategy = require('passport-google').Strategy,

    MongoClient = require('mongodb').MongoClient,
    ObjectID = require('mongodb').ObjectID,

    PetController = require('./PetController'),
    UserController = require('./UserController'),
    hostname = 'localhost';

var Server = function(opts) {
    opts = opts || {};
    this.port = opts.port || 8888;
    this.mongoURI = process.env.MONGO_URI || 'localhost:27017/homeward-bound';

    // Configure Models
    this.models = {
        pet: null,
        user: null
    };

    this.configureModels(function() {
        // Configure Controllers
        this.controllers = {
            pet: new PetController(this.models.user, this.models.pet),
            user: new UserController(this.models.user, this.models.pet)
        };

        // Configure authentication
        this.configureAuthentication();

        // Configure app endpoints
        this.app = express();
        this.configureEndpoints();

        // If the server has already been started
        if (this.onStart !== null) {
            this.start(this.onStart);
        }
    }.bind(this));
};

Server.prototype.configureAuthentication = function() {
    passport.serializeUser(function(user, done) {
        done(null, user._id);
    });
    passport.deserializeUser(function(id, done) {
        this.models.user.findOne({_id: ObjectID(id)}, function(err, user) {
            done(err, user);
        });
    }.bind(this));

    passport.use(new GoogleStrategy({
        returnURL: 'http://'+hostname+':'+this.port+'/auth/google/return',
        realm: 'http://'+hostname+':'+this.port
    }, function(identifier, profile, done) {
        // Find the user or create the user
        this.models.user.findOne({openId: identifier}, /*{limit: 1},*/ function(err, user) {
            if (!user) {
                this.models.user.insert({openId: identifier,
                                         email: profile.emails[0].value},  // First email
                                         function(err, res) {
                    done(err, res);
                }.bind(this));
            } else {
                done(err, user);
            }
        }.bind(this));
    }.bind(this)));
};

Server.prototype.configureModels = function(callback) {
    MongoClient.connect(this.mongoURI, function(err, db) {
        if (err) {
            throw new Error(err);
        }
        this.models.pet = db.collection('pets');
        this.models.user = db.collection('users');
        console.log('Connected to database at', this.mongoURI.split('@').pop());

        callback();
    }.bind(this));
};

// Endpoints:
//    GET       /                   Landing page
//    GET       /pets               Get all owner's pets
//    PATCH     /pets/id            Update the given pets
//    DELETE    /pets/id            Delete the given pets
//    PUT       /pets               Create a new pets
Server.prototype.configureEndpoints = function() {
    // Authentication
    this.app.use(bodyParser());
    this.app.use(cookieParser());
    this.app.use(session({ secret: 'somerandasdfodsecret' }));
    this.app.use(passport.initialize());
    this.app.use(passport.session());

    this.app.get('/auth/google', passport.authenticate('google'));
    this.app.get('/auth/google/return',
        passport.authenticate('google', {successRedirect: '/pets',
                                         failureRedirect: '/'}));

    // Landing page
    this.app.get('/', function(req, res) {
        // TODO: Send an html page...
        res.sendFile(__dirname+'/index.html');
    });

    // Get index
    this.app.get('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.index);

    // Update
    this.app.patch('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.update);

    // Delete
    this.app.delete('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.destroy);

    // Create
    this.app.put('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.create);
};

Server.prototype.ensureAuthenticated = function(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }
    res.redirect('/');
};

Server.prototype.start = function(callback) {
    callback = callback || function(){};
    if (this.app) {
        this.app.listen(this.port, function() {
            console.log('App listening on port', this.port);
            callback();
        }.bind(this));
    } else {
        this.onStart = callback;
    }
};

module.exports = Server;
<commit_msg>Fixed typo<commit_after>'use strict';

var express = require('express'),
    cookieParser = require('cookie-parser'),
    bodyParser = require('body-parser'),
    session = require('express-session'),
    async = require('async'),
    passport = require('passport'),
    GoogleStrategy = require('passport-google').Strategy,

    MongoClient = require('mongodb').MongoClient,
    ObjectID = require('mongodb').ObjectID,

    PetController = require('./PetController'),
    UserController = require('./UserController'),
    hostname = 'localhost';

var Server = function(opts) {
    opts = opts || {};
    this.port = opts.port || 8888;
    this.mongoURI = process.env.MONGO_URI || 'mongodb://localhost:27017/homeward-bound';

    // Configure Models
    this.models = {
        pet: null,
        user: null
    };

    this.configureModels(function() {
        // Configure Controllers
        this.controllers = {
            pet: new PetController(this.models.user, this.models.pet),
            user: new UserController(this.models.user, this.models.pet)
        };

        // Configure authentication
        this.configureAuthentication();

        // Configure app endpoints
        this.app = express();
        this.configureEndpoints();

        // If the server has already been started
        if (this.onStart !== null) {
            this.start(this.onStart);
        }
    }.bind(this));
};

Server.prototype.configureAuthentication = function() {
    passport.serializeUser(function(user, done) {
        done(null, user._id);
    });
    passport.deserializeUser(function(id, done) {
        this.models.user.findOne({_id: ObjectID(id)}, function(err, user) {
            done(err, user);
        });
    }.bind(this));

    passport.use(new GoogleStrategy({
        returnURL: 'http://'+hostname+':'+this.port+'/auth/google/return',
        realm: 'http://'+hostname+':'+this.port
    }, function(identifier, profile, done) {
        // Find the user or create the user
        this.models.user.findOne({openId: identifier}, /*{limit: 1},*/ function(err, user) {
            if (!user) {
                this.models.user.insert({openId: identifier,
                                         email: profile.emails[0].value},  // First email
                                         function(err, res) {
                    done(err, res);
                }.bind(this));
            } else {
                done(err, user);
            }
        }.bind(this));
    }.bind(this)));
};

Server.prototype.configureModels = function(callback) {
    MongoClient.connect(this.mongoURI, function(err, db) {
        if (err) {
            throw new Error(err);
        }
        this.models.pet = db.collection('pets');
        this.models.user = db.collection('users');
        console.log('Connected to database at', this.mongoURI.split('@').pop());

        callback();
    }.bind(this));
};

// Endpoints:
//    GET       /                   Landing page
//    GET       /pets               Get all owner's pets
//    PATCH     /pets/id            Update the given pets
//    DELETE    /pets/id            Delete the given pets
//    PUT       /pets               Create a new pets
Server.prototype.configureEndpoints = function() {
    // Authentication
    this.app.use(bodyParser());
    this.app.use(cookieParser());
    this.app.use(session({ secret: 'somerandasdfodsecret' }));
    this.app.use(passport.initialize());
    this.app.use(passport.session());

    this.app.get('/auth/google', passport.authenticate('google'));
    this.app.get('/auth/google/return',
        passport.authenticate('google', {successRedirect: '/pets',
                                         failureRedirect: '/'}));

    // Landing page
    this.app.get('/', function(req, res) {
        // TODO: Send an html page...
        res.sendFile(__dirname+'/index.html');
    });

    // Get index
    this.app.get('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.index);

    // Update
    this.app.patch('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.update);

    // Delete
    this.app.delete('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.destroy);

    // Create
    this.app.put('/pets',
        this.ensureAuthenticated,
        this.controllers.pet.create);
};

Server.prototype.ensureAuthenticated = function(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }
    res.redirect('/');
};

Server.prototype.start = function(callback) {
    callback = callback || function(){};
    if (this.app) {
        this.app.listen(this.port, function() {
            console.log('App listening on port', this.port);
            callback();
        }.bind(this));
    } else {
        this.onStart = callback;
    }
};

module.exports = Server;
<|endoftext|>


<commit_before>var contracts = { };

contracts.map = function(f,arr) {
  var dest = [ ];
  for (var i = 0; i < arr.length; i++) {
    dest.push(f(arr[i]));
  }
  return dest;
};

contracts.zipWith = function(f,arr1,arr2) {
  var dest = [ ];
  for (var i = 0; i < arr1.length; i++) {
    dest.push(f(arr1[i],arr2[i]));
  }
  return dest;
};

contracts.blame = function(guilty,expected,received,message,loc) {
  var guiltyMsg = typeof(guilty) == "string"
                    ? guilty : guilty.value;
  var msg = guiltyMsg + " violated the contract at " + loc + "; expected " +
             expected + " but received " + received + "; " + message;
  var err = new Error(msg);
  err.guilty = msg;
  err.blamed = guiltyMsg;
  err.expected = expected;
  err.received = received;
  err.guardLoc = loc;
  try { console.log(err); } catch(_) { };
  throw err;
}

// The type of a contract combinator is: name -> args ... -> contract
//
// name is a human-readable name for the contract.  args .. are constructor-
// specified arguments and contract is the resulting contract.

contracts.flat = function(name) {
  return function(pred) {
    return {
      pred: function(val) { return pred(val); },
      server: function(s,loc) {
        return function(val) {
          if (pred(val)) {
            return val;
            }
          else {
            contracts.blame(s,name,val,"does not satisfy the predicate",loc);
         }
        };
      },
      client: function(s,loc) {
        return function(val) { return val; };
      }
    };
  };
};

contracts.unsizedArray = function(name) {
  return function(elt) {
    return {
      pred: function(val) {
        return val instanceof Array;
        for (var i = 0; i < val.length; i++) {
          if (!(elt.flat(val[i]))) { return false; }
        }
        return true;
      },
      server: function(s,loc) {
        return function(val) {
          if (val instanceof Array) {
            return contracts.map(elt.server(s,loc),val);
          }
          else {
            contracts.blame(s, name, val, "not an array",loc);
          }
        };
      },
      client: function(s,loc) {
        return function(val) {
          if (val instanceof Array) {
            return contracts.map(elt.client(s,loc),val);
          }
          else {
            return val;
          }
        }
      }
    };
  };
};

contracts.fixedArray = function(name) {
  return function() {
    var elts = arguments;
    return {
      pred: function(val) {
        if  (!(val instanceof Array && val.length == elts.length)) {
          return false;
        }
        for (var i = 0; i < val.length; i++) {
          if (!elts[i].flat(val[i])) { return false; }
        }
        return true;
      },
      server: function(s,loc) {
        return function(val) {
          if (val instanceof Array && val.length == elts.length) {
            var result = [ ];
            for (var i = 0; i < elts.length; i++) {
              result.push(elts[i].server(s,loc)(val[i]));
            }
            return result;
          }
          else {
            contracts.blame(s,name,val,"not an array of the right size",loc);
          }
        };
      },
      client: function(s,loc) {
        return function(val) {
          if (val instanceof Array && val.length == elts.length) {
            var result = [ ];
            for (var i = 0; i < elts.length; i++) {
              result.push(elts[i].client(s,loc)(val[i]));
            }
            return result;
          }
          else {
            return val;
          }
        }
      }
    };
  };
};

contracts.isUndefined = contracts.flat(function(val) {
  return val === undefined;
});

contracts.varArityFunc = function(name) {
  return function(fixedArgs,restArgs,result) {
    return {
      isHigherOrder: true,
      flat: function(val) { return typeof(val) == "function"; },
      server: function(s,loc) {
        return function(proc) {
          if (typeof(proc) == "function") {
            return function() {
              var guardedArgs = contracts.zipWith(function(ctc,arg) {
                return ctc.client(s,loc)(arg);
              }, fixedArgs, arguments);
              for (var i = fixedArgs.length; i < arguments.length; i++) {
                guardedArgs.push(restArgs.client(s,loc)(arguments[i]));
              }
              return result.server(s,loc)(proc.apply(this, guardedArgs));
            };
          }
          else { contracts.blame(s,name, proc,"not a function",loc); }
        }
      },
      client: function(s,loc) {
        return function(proc) {
          if (typeof(proc) == "function") {
            return function() {
              var guardedArgs = contracts.zipWith(function(ctc,arg) {
                return ctc.server(s,loc)(arg);
              }, fixedArgs, arguments);
              for (var i = fixedArgs.length; i < arguments.length; i++) {
                guardedArgs.push(restArgs.server(s,loc)(arguments[i]));
              }
              return result.client(s,loc)(proc.apply(this, guardedArgs));
            };
          }
          else {
            return proc;
          }
        };
      }
    };
  };
};

// Ensures value is an instanceof constr before checking that its shape
// matches sig. constrId is a human-readable name for the constructor.
contracts.instance = function(name) {
  return function(constr, sig) {
    return {
      flat: function(val) {
        return (typeof(val) == "object" || typeof(val) == "function") &&
               (val instanceof constr) && sig.flat(val);
      },
      server: function(s,loc) { return function(val) {
        if ((typeof(val) == "object" || typeof(val) == "function") &&
            (val instanceof constr)) {
          return sig.server(s,loc)(val);
        }
        else {
          contracts.blame(s, name, val, "wrong instance",loc);
        }
      } },
      client: function(s,loc) { return function(val) {
        if ((typeof(val) == "object" || typeof(val) == "function") &&
            (val instanceof constr)) {
          return sig.client(s,loc)(val);
        }
        else {
          return val;
        }
      } }
    };
  };
};

contracts.obj = function(name) {
  return function(sig) {
    return {
      flat: function(val) {
        for (var field in sig) {
          if (!(sig[field].flat(val[field]))) { return false; }
        }
        return true;
      },
      server: function(s,loc) {
        return function (obj) {
          var constr = function() { };
          constr.prototype = obj;
          var guardedObj = new constr();

          for (var field in sig) {
            guardedObj[field] = sig[field].server(s,loc)(obj[field]);
          }
          return guardedObj;
        };
      },
      client: function(s,loc) {
        return function (obj) {
          var constr = function() { };
          constr.prototype = obj;
          var guardedObj = new constr();

          for (var field in sig) {
            guardedObj[field] = sig[field].client(s,loc)(obj[field]);
          }
          return guardedObj;
        };
      }
    };
  };
};

// pos is the name of val.  neg should be the name of the calling context.
// Since we do not rewrite call-sites, neg is simply "client".
// However, if ctc.isHigherOrder, we can determine the name of the calling
// context by examining the stack when val is called.
// if !ctc.isHigherOrder, the name of the calling context is the name of the
// definition point (neg)
contracts.guard = function(ctc,val,pos,neg,loc) {
  if (ctc.isHigherOrder) {
    if (typeof(val) != "function") {
      contracts.blame(pos, "a function", proc, "not a function","guard");
    }
    else {
      var deferredNeg = { value: "not called" };
      var fn = ctc.client(deferredNeg,loc)(ctc.server(pos,loc)(val));
      return function() {
        deferredNeg.value = contracts.stackTrace();
        return fn.apply(this,arguments);
      };
    }
  }
  else {
    return ctc.client(neg,loc)(ctc.server(pos,loc)(val));
  }
};

// Derived from http://eriwen.com/javascript/js-stack-trace/
contracts.stackTrace = function() {
  var callstack = [];
  var isCallstackPopulated = false;
  try {
      i.dont.exist+=0; //does not exist - that's the point
  } catch(e) {
      if (e.stack) { //Firefox
          var lines = e.stack.split("\n");
          for (var i = 0, len = lines.length; i < len; i++) {
              if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
                  callstack.push(lines[i]);
              }
          }
          //Remove call to printStackTrace()
          callstack.shift();
          isCallstackPopulated = true;
      }
      else if (window.opera && e.message) { //Opera
          var lines = e.message.split("\n");
          for (var i = 0, len = lines.length; i < len; i++) {
              if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
                  var entry = lines[i];
                  //Append next line also since it has the file info
                  if (lines[i+1]) {
                      entry += " at " + lines[i+1];
                      i++;
                  }
                  callstack.push(entry);
              }
          }
          //Remove call to printStackTrace()
          callstack.shift();
          isCallstackPopulated = true;
      }
  }
  if (!isCallstackPopulated) { //IE and Safari
      var currentFunction = arguments.callee.caller;
      while (currentFunction) {
          var fn = currentFunction.toString();
          //If we can't get the function name set to "anonymous"
          var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf("(")) || "anonymous";
          callstack.push(fname);
          currentFunction = currentFunction.caller;
      }
  }

  return callstack.length == 0 ? "client" : callstack.join(" ");
};
<commit_msg>typo, fixedArray and flat predicate is called flat<commit_after>var contracts = { };

contracts.map = function(f,arr) {
  var dest = [ ];
  for (var i = 0; i < arr.length; i++) {
    dest.push(f(arr[i]));
  }
  return dest;
};

contracts.zipWith = function(f,arr1,arr2) {
  var dest = [ ];
  for (var i = 0; i < arr1.length; i++) {
    dest.push(f(arr1[i],arr2[i]));
  }
  return dest;
};

contracts.blame = function(guilty,expected,received,message,loc) {
  var guiltyMsg = typeof(guilty) == "string"
                    ? guilty : guilty.value;
  var msg = guiltyMsg + " violated the contract at " + loc + "; expected " +
             expected + " but received " + received + "; " + message;
  var err = new Error(msg);
  err.guilty = msg;
  err.blamed = guiltyMsg;
  err.expected = expected;
  err.received = received;
  err.guardLoc = loc;
  try { console.log(err); } catch(_) { };
  throw err;
}

// The type of a contract combinator is: name -> args ... -> contract
//
// name is a human-readable name for the contract.  args .. are constructor-
// specified arguments and contract is the resulting contract.

contracts.flat = function(name) {
  return function(pred) {
    return {
      flat: function(val) { return pred(val); },
      server: function(s,loc) {
        return function(val) {
          if (flat(val)) {
            return val;
            }
          else {
            contracts.blame(s,name,val,"does not satisfy the predicate",loc);
         }
        };
      },
      client: function(s,loc) {
        return function(val) { return val; };
      }
    };
  };
};

contracts.unsizedArray = function(name) {
  return function(elt) {
    return {
      flat: function(val) {
        return val instanceof Array;
        for (var i = 0; i < val.length; i++) {
          if (!(elt.flat(val[i]))) { return false; }
        }
        return true;
      },
      server: function(s,loc) {
        return function(val) {
          if (val instanceof Array) {
            return contracts.map(elt.server(s,loc),val);
          }
          else {
            contracts.blame(s, name, val, "not an array",loc);
          }
        };
      },
      client: function(s,loc) {
        return function(val) {
          if (val instanceof Array) {
            return contracts.map(elt.client(s,loc),val);
          }
          else {
            return val;
          }
        }
      }
    };
  };
};

contracts.fixedArray = function(name) {
  return function() {
    var elts = arguments;
    return {
      flat: function(val) {
        if  (!(val instanceof Array && val.length == elts.length)) {
          return false;
        }
        for (var i = 0; i < val.length; i++) {
          if (!elts[i].flat(val[i])) { return false; }
        }
        return true;
      },
      server: function(s,loc) {
        return function(val) {
          if (val instanceof Array && val.length == elts.length) {
            var result = [ ];
            for (var i = 0; i < elts.length; i++) {
              result.push(elts[i].server(s,loc)(val[i]));
            }
            return result;
          }
          else {
            contracts.blame(s,name,val,"not an array of the right size",loc);
          }
        };
      },
      client: function(s,loc) {
        return function(val) {
          if (val instanceof Array && val.length == elts.length) {
            var result = [ ];
            for (var i = 0; i < elts.length; i++) {
              result.push(elts[i].client(s,loc)(val[i]));
            }
            return result;
          }
          else {
            return val;
          }
        }
      }
    };
  };
};

contracts.isUndefined = contracts.flat(function(val) {
  return val === undefined;
});

contracts.varArityFunc = function(name) {
  return function(fixedArgs,restArgs,result) {
    return {
      isHigherOrder: true,
      flat: function(val) { return typeof(val) == "function"; },
      server: function(s,loc) {
        return function(proc) {
          if (typeof(proc) == "function") {
            return function() {
              var guardedArgs = contracts.zipWith(function(ctc,arg) {
                return ctc.client(s,loc)(arg);
              }, fixedArgs, arguments);
              for (var i = fixedArgs.length; i < arguments.length; i++) {
                guardedArgs.push(restArgs.client(s,loc)(arguments[i]));
              }
              return result.server(s,loc)(proc.apply(this, guardedArgs));
            };
          }
          else { contracts.blame(s,name, proc,"not a function",loc); }
        }
      },
      client: function(s,loc) {
        return function(proc) {
          if (typeof(proc) == "function") {
            return function() {
              var guardedArgs = contracts.zipWith(function(ctc,arg) {
                return ctc.server(s,loc)(arg);
              }, fixedArgs, arguments);
              for (var i = fixedArgs.length; i < arguments.length; i++) {
                guardedArgs.push(restArgs.server(s,loc)(arguments[i]));
              }
              return result.client(s,loc)(proc.apply(this, guardedArgs));
            };
          }
          else {
            return proc;
          }
        };
      }
    };
  };
};

// Ensures value is an instanceof constr before checking that its shape
// matches sig. constrId is a human-readable name for the constructor.
contracts.instance = function(name) {
  return function(constr, sig) {
    return {
      flat: function(val) {
        return (typeof(val) == "object" || typeof(val) == "function") &&
               (val instanceof constr) && sig.flat(val);
      },
      server: function(s,loc) { return function(val) {
        if ((typeof(val) == "object" || typeof(val) == "function") &&
            (val instanceof constr)) {
          return sig.server(s,loc)(val);
        }
        else {
          contracts.blame(s, name, val, "wrong instance",loc);
        }
      } },
      client: function(s,loc) { return function(val) {
        if ((typeof(val) == "object" || typeof(val) == "function") &&
            (val instanceof constr)) {
          return sig.client(s,loc)(val);
        }
        else {
          return val;
        }
      } }
    };
  };
};

contracts.obj = function(name) {
  return function(sig) {
    return {
      flat: function(val) {
        for (var field in sig) {
          if (!(sig[field].flat(val[field]))) { return false; }
        }
        return true;
      },
      server: function(s,loc) {
        return function (obj) {
          var constr = function() { };
          constr.prototype = obj;
          var guardedObj = new constr();

          for (var field in sig) {
            guardedObj[field] = sig[field].server(s,loc)(obj[field]);
          }
          return guardedObj;
        };
      },
      client: function(s,loc) {
        return function (obj) {
          var constr = function() { };
          constr.prototype = obj;
          var guardedObj = new constr();

          for (var field in sig) {
            guardedObj[field] = sig[field].client(s,loc)(obj[field]);
          }
          return guardedObj;
        };
      }
    };
  };
};

// pos is the name of val.  neg should be the name of the calling context.
// Since we do not rewrite call-sites, neg is simply "client".
// However, if ctc.isHigherOrder, we can determine the name of the calling
// context by examining the stack when val is called.
// if !ctc.isHigherOrder, the name of the calling context is the name of the
// definition point (neg)
contracts.guard = function(ctc,val,pos,neg,loc) {
  if (ctc.isHigherOrder) {
    if (typeof(val) != "function") {
      contracts.blame(pos, "a function", proc, "not a function","guard");
    }
    else {
      var deferredNeg = { value: "not called" };
      var fn = ctc.client(deferredNeg,loc)(ctc.server(pos,loc)(val));
      return function() {
        deferredNeg.value = contracts.stackTrace();
        return fn.apply(this,arguments);
      };
    }
  }
  else {
    return ctc.client(neg,loc)(ctc.server(pos,loc)(val));
  }
};

// Derived from http://eriwen.com/javascript/js-stack-trace/
contracts.stackTrace = function() {
  var callstack = [];
  var isCallstackPopulated = false;
  try {
      i.dont.exist+=0; //does not exist - that's the point
  } catch(e) {
      if (e.stack) { //Firefox
          var lines = e.stack.split("\n");
          for (var i = 0, len = lines.length; i < len; i++) {
              if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
                  callstack.push(lines[i]);
              }
          }
          //Remove call to printStackTrace()
          callstack.shift();
          isCallstackPopulated = true;
      }
      else if (window.opera && e.message) { //Opera
          var lines = e.message.split("\n");
          for (var i = 0, len = lines.length; i < len; i++) {
              if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
                  var entry = lines[i];
                  //Append next line also since it has the file info
                  if (lines[i+1]) {
                      entry += " at " + lines[i+1];
                      i++;
                  }
                  callstack.push(entry);
              }
          }
          //Remove call to printStackTrace()
          callstack.shift();
          isCallstackPopulated = true;
      }
  }
  if (!isCallstackPopulated) { //IE and Safari
      var currentFunction = arguments.callee.caller;
      while (currentFunction) {
          var fn = currentFunction.toString();
          //If we can't get the function name set to "anonymous"
          var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf("(")) || "anonymous";
          callstack.push(fname);
          currentFunction = currentFunction.caller;
      }
  }

  return callstack.length == 0 ? "client" : callstack.join(" ");
};
<|endoftext|>