<commit_before>export { BoundsArraySet };

import * as ConvBiasActivation from "../ConvBiasActivation.js";
import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ValueDesc from "../../Unpacker/ValueDesc.js";
import * as Weights from "../../Unpacker/Weights.js";
import { ChannelPartInfo } from  "./Depthwise_ChannelPartInfo.js";

/**
 * The element value bounds set for depthwise convolution-bias-activation.
 *
 */
class BoundsArraySet extends ConvBiasActivation.BoundsArraySet {

  /**
   */
  constructor( inputChannelCount, outputChannelCount ) {
    super( inputChannelCount, outputChannelCount );
  }

//!!! ...unfinished... (2022/01/07) What about ( bDepthwise == false )?

  /**
   *
   * @param {ConvBiasActivation.BoundsArraySet} previous_ConvBiasActivation_BoundsArraySet
   *   The value bounds set of the previous convolution-bias-activation.
   *
   * @param {Depthwise.ChannelPartInfo[]} inChannelPartInfoArray
   *   The input channel range array which describe lower/higher half channels index range.
   *
   * @param {number} channelMultiplier
   *   The channel multiplier of this depthwise operation.
   *
   * @param {number} nActivationId
   *   The activation function id (ValueDesc.ActivationFunction.Singleton.Ids.Xxx) of this depthwise convolution.
   *
   * @param {number[]} filtersArray
   *   The weights of the depthwise convolution. Its content will not be used. Only be tested against null. If ( filtersArray != null ),
   * this is a depthwise convolution. If ( filtersArray == null ), this is an avg/max pooling (i.e. no filters weights).
   *
   * @param {number[]} biasesArray
   *   The weights of the bias. Its content will not be used. Only be tested against null. If ( biasesArray != null ),
   * there is bias operation. If ( biasesArray == null ), there is no bias operation.
   */
  set_all_by_inChannelPartInfoArray(
    previous_ConvBiasActivation_BoundsArraySet, inChannelPartInfoArray,
    channelMultiplier, nActivationId, filtersArray, biasesArray
  ) {

    // Because they are extracted from Weights which should have been regulated by Weights.Base.ValueBounds.Float32Array_RestrictedClone().
    const filtersValueBounds = Weights.Base.ValueBounds;
    const biasesValueBounds = Weights.Base.ValueBounds;

    let theActivationFunctionInfo = ValueDesc.ActivationFunction.Singleton.getInfoById( nActivationId );

    // 1. Determine .input
    //
    // Note: Even if avg/max pooling, input value bounds is the same as the previous ooutput value bounds
    this.input.set_all_byBoundsArray( previous_ConvBiasActivation_BoundsArraySet.output );

    // ( inChannelPartIndex == 0 ), lower half channels. (or, all channels)
    // ( inChannelPartIndex == 1 ), higher half channels.
    for ( let inChannelPartIndex = 0; inChannelPartIndex < inChannelPartInfoArray.length; ++inChannelPartIndex ) {
      let inChannelPartInfo = inChannelPartInfoArray[ inChannelPartIndex ];
      let inChannelBegin = inChannelPartInfo.beginIndex;
      let inChannelEnd = inChannelPartInfo.endIndex;

      let outChannel = inChannelBegin * channelMultiplier;

      for ( let inChannel = inChannelBegin; inChannel < inChannelEnd; ++inChannel ) {

        let undoScale = previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleArraySet.undo.scales[ inChannel ];

        // 2. Determine .afterUndoPreviousActivationEscaping
        this.afterUndoPreviousActivationEscaping.set_one_byBoundsArray( inChannel, this.input, inChannel );
        this.afterUndoPreviousActivationEscaping.multiply_one_byN( inChannel, undoScale );

        for ( let outChannelSub = 0; outChannelSub < channelMultiplier; ++outChannelSub, ++outChannel ) {

          // 3. Determine .afterFilter
          this.afterFilter.set_one_byBoundsArray( outChannel, this.afterUndoPreviousActivationEscaping, inChannel );
          if ( filtersArray ) {

            if ( inChannelPartInfo.bPassThrough ) { // For pass-through half channels.
              // Do nothing. The value bounds does not change at all because it is just be past through.

            } else { // Non pass-through half channels.
              this.afterFilter
                .multiply_one_byBounds( outChannel, filtersValueBounds )
                .multiply_one_byN( outChannel, this.filterSize );
            }

          } else { // ( !filtersArray ). No filters array to be extracted. (i.e. avg/max pooling)
            // Do nothing. The value bounds does not change for avg/max pooling.
          }

          // 4. Determine .afterBias
          this.afterBias.set_one_byBoundsArray( outChannel, this.afterFilter, outChannel );
          if ( biasesArray ) {

            if ( inChannelPartInfo.bPassThrough ) { // For pass-through half channels.
              // Do nothing. The value bounds does not change at all because it is just be past through.

            } else { // Non pass-through half channels.
              this.afterBias.add_one_byBounds( outChannel, biasesValueBounds ); // Shift the value bounds by the bias bounds.
            }

          } else { // ( !biasesArray ). No biases array to be extracted.
            // Do nothing. The value bounds does not change since no bias.
          }

          // 6. Determine .afterActivationEscaping
          {
            // 6.1 Determine .activationEscaping_ScaleArraySet
            {
              // 6.1.1 Determine .do

              if ( nActivationId == ValueDesc.ActivationFunction.Singleton.Ids.NONE ) {

                // Since no activation function, no need to escape. (i.e. scale = 1 for no scale)
                this.activationEscaping_ScaleArraySet.do.set_one_byN( outChannel, 1 );

              } else {

                if ( inChannelPartInfo.bPassThrough ) { // For pass-through half channels.

                  // Calculate the scale for escaping bias result from activation function's non-linear domain into linear domain.
                  //
                  // Note: This does not work for avg/max pooling.
                  this.activationEscaping_ScaleArraySet.do.set_one_by_fromLowerUpper_toLowerUpper( outChannel,
                    this.afterBias.lowers[ outChannel ], this.afterBias.uppers[ outChannel ],
                    theActivationFunctionInfo.inputDomainLinear.lower, theActivationFunctionInfo.inputDomainLinear.upper
                  );

                  let doScale = this.activationEscaping_ScaleArraySet.do.scales[ outChannel ];
                  tf.util.assert( ( Number.isNaN( doScale ) == false ),
                    `Depthwise.FiltersArray_BiasesArray.set_boundsArraySet_by_inChannelPartInfoArray(): `
                      + `this.activationEscaping_ScaleArraySet.do.scales[ ${outChannel} ] ( ${doScale} ) `
                      + `should not be NaN. `
                      + `Please use activation function (e.g. tanh()) which has both negative and positive parts near origin point.`
                  );

                } else { // Non pass-through half channels.
                  // Since non-pass-through, no need to escape. (i.e. scale = 1 for no scale)
                  this.activationEscaping_ScaleArraySet.do.set_one_byN( outChannel, 1 );
                }
              }

              // 6.1.2 Determine .undo (Prepared for the next convolution-bias-activation. Not for this.)
              this.activationEscaping_ScaleArraySet.undo.set_one_byUndo_ScaleArray(
                outChannel, this.activationEscaping_ScaleArraySet.do, outChannel );
            }

            // 6.2 Determine .afterActivationEscaping
            this.afterActivationEscaping
              .set_one_byBoundsArray( outChannel, this.afterBias, outChannel )
              .multiply_one_byNs( outChannel, this.activationEscaping_ScaleArraySet.do.scales, outChannel );
          }

          // 7. Determine .afterActivation
          {
            // If no activation function, the output range is determined by .afterActivationEscaping.
            if ( this.nActivationId == ValueDesc.ActivationFunction.Singleton.Ids.NONE ) {
              this.afterActivation.set_one_byBoundsArray( outChannel, this.afterActivationEscaping, outChannel )

            // Otherwise, the activation function dominates the output range.
            } else {
              this.afterActivation.set_one_byBounds( outChannel, theActivationFunctionInfo.outputRange );
            }
          }

        } // outChannelSub, outChannel
      } // inChannel
    } // inChannelPartIndex

  }

//!!! (2022/01/07 Remarked) seems not used. because should be channel by channel.
//
// //!!! ...unfinished... (2021/12/27) should become BoundsArray_byChannelIndex.
//
//   /**
//    *
//    * @param {ConvBiasActivation.BoundsArraySet} previous_ConvBiasActivation_BoundsArraySet
//    *   The previous convolution-bias-activation value bounds set of this depthwise convolution.
//    *
//    * @param {boolean} bDepthwise
//    *   If true, the depthwise convolution (with/without bias, with/without activation) exists.
//    *
//    * @param {number} filterHeight
//    *   The filter height of the depthwise convolution.
//    *
//    * @param {number} filterWidth
//    *   The filter width of the depthwise convolution.
//    *
//    * @param {boolean} bBias
//    *   If true, the bias operation exists.
//    *
//    * @param {number} nActivationId
//    *   The activation function id (ValueDesc.ActivationFunction.Singleton.Ids.Xxx) after the bias operation.
//    */
//    set_by( previous_ConvBiasActivation_BoundsArraySet, bDepthwise, filterHeight, filterWidth, bBias, nActivationId ) {
//
//     // 0. Default as BoundsArraySet.output of previous convolution-bias-activation.
//     this.reset_byBounds( previous_ConvBiasActivation_BoundsArraySet.output );
//
//     // 1. No operation at all.
//     if ( !bDepthwise )
//       return;
//
//     // 2. Before activation function.
//     {
//       // Because they are extracted from Weights which should have been regulated by Weights.Base.ValueBounds.Float32Array_RestrictedClone().
//       const filtersValueBounds = Weights.Base.ValueBounds;
//       const biasesValueBounds = Weights.Base.ValueBounds;
//
//       // Note: For maximum pooling, the multiply_Bounds is a little bit overestimated (but should be acceptable).
//       let filterSize = filterHeight * filterWidth;
//       this.beforeActivation.multiply_all_byBounds( filtersValueBounds ).multiply_all_byN( filterSize );
//
//       if ( bBias )
//         this.beforeActivation.add_all_byBounds( biasesValueBounds );
//
//
// //!!! ...unfinished... (2021/12/26)
// // The .undo should also be applied to the real filter value and bias value of this convolution-bias (i.e. not just applied here ScaleTranslate).
// //
// // Problem: What if this convolution-bias-activation could only undo partially (e.g. this convolution does not have bias)?
// //   How should the .undo of this convolution-bias-activation be calculated?
//       {
//         this.beforeActivation.multiply_all_byN(
//           previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleTranslateArraySet.undo.scale );
//
//         if ( this.bBias )
//           this.beforeActivation.add_all_byN(
//             previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleTranslateArraySet.undo.translate );
//       }
//
//     }
//
//     // 3. Output.
//     this.set_output_by_beforeActivation_ActivationId( nActivationId );
//
//     // 4. ActivationEscaping.ScaleTranslateArraySet.
//     this.activationEscaping_ScaleTranslateArraySet.set_by_currentBoundsArraySet_previousActivationEscaping(
//       this, previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleTranslateArraySet );
//   }

}

<commit_msg>Update Depthwise_BoundsArraySet.js<commit_after>export { BoundsArraySet };

import * as ConvBiasActivation from "../ConvBiasActivation.js";
import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ValueDesc from "../../Unpacker/ValueDesc.js";
import * as Weights from "../../Unpacker/Weights.js";
import { ChannelPartInfo } from  "./Depthwise_ChannelPartInfo.js";

/**
 * The element value bounds set for depthwise convolution-bias-activation.
 *
 */
class BoundsArraySet extends ConvBiasActivation.BoundsArraySet {

  /**
   */
  constructor( inputChannelCount, outputChannelCount ) {
    super( inputChannelCount, outputChannelCount );
  }

//!!! ...unfinished... (2022/01/07) What about ( bDepthwise == false )?

//!!! ...unfinished... (2022/01/09)
// Even if ( this.AvgMax_Or_ChannelMultiplier == ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.NONE ),
// this function should work correctly and BoundsArraySet should result in pass-through input to output.

  /**
   *
   * @param {ConvBiasActivation.BoundsArraySet} previous_ConvBiasActivation_BoundsArraySet
   *   The value bounds set of the previous convolution-bias-activation.
   *
   * @param {Depthwise.ChannelPartInfo[]} inChannelPartInfoArray
   *   The input channel range array which describe lower/higher half channels index range.
   *
   * @param {number} channelMultiplier
   *   The channel multiplier of this depthwise operation.
   *
   * @param {number} nActivationId
   *   The activation function id (ValueDesc.ActivationFunction.Singleton.Ids.Xxx) of this depthwise convolution.
   *
   * @param {number[]} filtersArray
   *   The weights of the depthwise convolution. Its content will not be used. Only be tested against null. If ( filtersArray != null ),
   * this is a depthwise convolution. If ( filtersArray == null ), this is an avg/max pooling (i.e. no filters weights).
   *
   * @param {number[]} biasesArray
   *   The weights of the bias. Its content will not be used. Only be tested against null. If ( biasesArray != null ),
   * there is bias operation. If ( biasesArray == null ), there is no bias operation.
   */
  set_all_by_inChannelPartInfoArray(
    previous_ConvBiasActivation_BoundsArraySet, inChannelPartInfoArray,
    channelMultiplier, nActivationId, filtersArray, biasesArray
  ) {

    // Because they are extracted from Weights which should have been regulated by Weights.Base.ValueBounds.Float32Array_RestrictedClone().
    const filtersValueBounds = Weights.Base.ValueBounds;
    const biasesValueBounds = Weights.Base.ValueBounds;

    let theActivationFunctionInfo = ValueDesc.ActivationFunction.Singleton.getInfoById( nActivationId );

    // 1. Determine .input
    //
    // Note: Even if avg/max pooling, input value bounds is the same as the previous ooutput value bounds
    this.input.set_all_byBoundsArray( previous_ConvBiasActivation_BoundsArraySet.output );

    // ( inChannelPartIndex == 0 ), lower half channels. (or, all channels)
    // ( inChannelPartIndex == 1 ), higher half channels.
    for ( let inChannelPartIndex = 0; inChannelPartIndex < inChannelPartInfoArray.length; ++inChannelPartIndex ) {
      let inChannelPartInfo = inChannelPartInfoArray[ inChannelPartIndex ];
      let inChannelBegin = inChannelPartInfo.beginIndex;
      let inChannelEnd = inChannelPartInfo.endIndex;

      let outChannel = inChannelBegin * channelMultiplier;

      for ( let inChannel = inChannelBegin; inChannel < inChannelEnd; ++inChannel ) {

        let undoScale = previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleArraySet.undo.scales[ inChannel ];

        // 2. Determine .afterUndoPreviousActivationEscaping
        this.afterUndoPreviousActivationEscaping.set_one_byBoundsArray( inChannel, this.input, inChannel );
        this.afterUndoPreviousActivationEscaping.multiply_one_byN( inChannel, undoScale );

        for ( let outChannelSub = 0; outChannelSub < channelMultiplier; ++outChannelSub, ++outChannel ) {

          // 3. Determine .afterFilter
          this.afterFilter.set_one_byBoundsArray( outChannel, this.afterUndoPreviousActivationEscaping, inChannel );
          if ( filtersArray ) {

            if ( inChannelPartInfo.bPassThrough ) { // For pass-through half channels.
              // Do nothing. The value bounds does not change at all because it is just be past through.

            } else { // Non pass-through half channels.
              this.afterFilter
                .multiply_one_byBounds( outChannel, filtersValueBounds )
                .multiply_one_byN( outChannel, this.filterSize );
            }

          } else { // ( !filtersArray ). No filters array to be extracted. (i.e. avg/max pooling)
            // Do nothing. The value bounds does not change for avg/max pooling.
          }

          // 4. Determine .afterBias
          this.afterBias.set_one_byBoundsArray( outChannel, this.afterFilter, outChannel );
          if ( biasesArray ) {

            if ( inChannelPartInfo.bPassThrough ) { // For pass-through half channels.
              // Do nothing. The value bounds does not change at all because it is just be past through.

            } else { // Non pass-through half channels.
              this.afterBias.add_one_byBounds( outChannel, biasesValueBounds ); // Shift the value bounds by the bias bounds.
            }

          } else { // ( !biasesArray ). No biases array to be extracted.
            // Do nothing. The value bounds does not change since no bias.
          }

          // 6. Determine .afterActivationEscaping
          {
            // 6.1 Determine .activationEscaping_ScaleArraySet
            {
              // 6.1.1 Determine .do

              if ( nActivationId == ValueDesc.ActivationFunction.Singleton.Ids.NONE ) {

                // Since no activation function, no need to escape. (i.e. scale = 1 for no scale)
                this.activationEscaping_ScaleArraySet.do.set_one_byN( outChannel, 1 );

              } else {

                if ( inChannelPartInfo.bPassThrough ) { // For pass-through half channels.

                  // Calculate the scale for escaping bias result from activation function's non-linear domain into linear domain.
                  //
                  // Note: This does not work for avg/max pooling.
                  this.activationEscaping_ScaleArraySet.do.set_one_by_fromLowerUpper_toLowerUpper( outChannel,
                    this.afterBias.lowers[ outChannel ], this.afterBias.uppers[ outChannel ],
                    theActivationFunctionInfo.inputDomainLinear.lower, theActivationFunctionInfo.inputDomainLinear.upper
                  );

                  let doScale = this.activationEscaping_ScaleArraySet.do.scales[ outChannel ];
                  tf.util.assert( ( Number.isNaN( doScale ) == false ),
                    `Depthwise.FiltersArray_BiasesArray.set_boundsArraySet_by_inChannelPartInfoArray(): `
                      + `this.activationEscaping_ScaleArraySet.do.scales[ ${outChannel} ] ( ${doScale} ) `
                      + `should not be NaN. `
                      + `Please use activation function (e.g. tanh()) which has both negative and positive parts near origin point.`
                  );

                } else { // Non pass-through half channels.
                  // Since non-pass-through, no need to escape. (i.e. scale = 1 for no scale)
                  this.activationEscaping_ScaleArraySet.do.set_one_byN( outChannel, 1 );
                }
              }

              // 6.1.2 Determine .undo (Prepared for the next convolution-bias-activation. Not for this.)
              this.activationEscaping_ScaleArraySet.undo.set_one_byUndo_ScaleArray(
                outChannel, this.activationEscaping_ScaleArraySet.do, outChannel );
            }

            // 6.2 Determine .afterActivationEscaping
            this.afterActivationEscaping
              .set_one_byBoundsArray( outChannel, this.afterBias, outChannel )
              .multiply_one_byNs( outChannel, this.activationEscaping_ScaleArraySet.do.scales, outChannel );
          }

          // 7. Determine .afterActivation
          {
            // If no activation function, the output range is determined by .afterActivationEscaping.
            if ( this.nActivationId == ValueDesc.ActivationFunction.Singleton.Ids.NONE ) {
              this.afterActivation.set_one_byBoundsArray( outChannel, this.afterActivationEscaping, outChannel )

            // Otherwise, the activation function dominates the output range.
            } else {
              this.afterActivation.set_one_byBounds( outChannel, theActivationFunctionInfo.outputRange );
            }
          }

        } // outChannelSub, outChannel
      } // inChannel
    } // inChannelPartIndex

  }

//!!! (2022/01/07 Remarked) seems not used. because should be channel by channel.
//
// //!!! ...unfinished... (2021/12/27) should become BoundsArray_byChannelIndex.
//
//   /**
//    *
//    * @param {ConvBiasActivation.BoundsArraySet} previous_ConvBiasActivation_BoundsArraySet
//    *   The previous convolution-bias-activation value bounds set of this depthwise convolution.
//    *
//    * @param {boolean} bDepthwise
//    *   If true, the depthwise convolution (with/without bias, with/without activation) exists.
//    *
//    * @param {number} filterHeight
//    *   The filter height of the depthwise convolution.
//    *
//    * @param {number} filterWidth
//    *   The filter width of the depthwise convolution.
//    *
//    * @param {boolean} bBias
//    *   If true, the bias operation exists.
//    *
//    * @param {number} nActivationId
//    *   The activation function id (ValueDesc.ActivationFunction.Singleton.Ids.Xxx) after the bias operation.
//    */
//    set_by( previous_ConvBiasActivation_BoundsArraySet, bDepthwise, filterHeight, filterWidth, bBias, nActivationId ) {
//
//     // 0. Default as BoundsArraySet.output of previous convolution-bias-activation.
//     this.reset_byBounds( previous_ConvBiasActivation_BoundsArraySet.output );
//
//     // 1. No operation at all.
//     if ( !bDepthwise )
//       return;
//
//     // 2. Before activation function.
//     {
//       // Because they are extracted from Weights which should have been regulated by Weights.Base.ValueBounds.Float32Array_RestrictedClone().
//       const filtersValueBounds = Weights.Base.ValueBounds;
//       const biasesValueBounds = Weights.Base.ValueBounds;
//
//       // Note: For maximum pooling, the multiply_Bounds is a little bit overestimated (but should be acceptable).
//       let filterSize = filterHeight * filterWidth;
//       this.beforeActivation.multiply_all_byBounds( filtersValueBounds ).multiply_all_byN( filterSize );
//
//       if ( bBias )
//         this.beforeActivation.add_all_byBounds( biasesValueBounds );
//
//
// //!!! ...unfinished... (2021/12/26)
// // The .undo should also be applied to the real filter value and bias value of this convolution-bias (i.e. not just applied here ScaleTranslate).
// //
// // Problem: What if this convolution-bias-activation could only undo partially (e.g. this convolution does not have bias)?
// //   How should the .undo of this convolution-bias-activation be calculated?
//       {
//         this.beforeActivation.multiply_all_byN(
//           previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleTranslateArraySet.undo.scale );
//
//         if ( this.bBias )
//           this.beforeActivation.add_all_byN(
//             previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleTranslateArraySet.undo.translate );
//       }
//
//     }
//
//     // 3. Output.
//     this.set_output_by_beforeActivation_ActivationId( nActivationId );
//
//     // 4. ActivationEscaping.ScaleTranslateArraySet.
//     this.activationEscaping_ScaleTranslateArraySet.set_by_currentBoundsArraySet_previousActivationEscaping(
//       this, previous_ConvBiasActivation_BoundsArraySet.activationEscaping_ScaleTranslateArraySet );
//   }

}

<|endoftext|>


<commit_before>var nodemiral = require('nodemiral');
var fs = require('fs');
var path = require('path');
var util = require('util');

var SCRIPT_DIR = path.resolve(__dirname, '../../scripts/linux');
var TEMPLATES_DIR = path.resolve(__dirname, '../../templates/linux');

exports.setup = function(config) {
  var taskList = nodemiral.taskList('Setup (linux)');

  // Installation
  if(config.setupNode) {
    taskList.executeScript('Installing Node.js', {
      script: path.resolve(SCRIPT_DIR, 'install-node.sh'),
      vars: {
        nodeVersion: config.nodeVersion
      }
    });
  }

  if(config.setupPhantom) {
    taskList.executeScript('Installing PhantomJS', {
      script: path.resolve(SCRIPT_DIR, 'install-phantomjs.sh')
    });
  }

  taskList.executeScript('Setting up Environment', {
    script: path.resolve(SCRIPT_DIR, 'setup-env.sh'),
    vars: {
      appName: config.appName
    }
  });

  if(config.setupMongo) {
    taskList.copy('Copying MongoDB configuration', {
      src: path.resolve(TEMPLATES_DIR, 'mongodb.conf'),
      dest: '/etc/mongodb.conf'
    });

    taskList.executeScript('Installing MongoDB', {
      script: path.resolve(SCRIPT_DIR, 'install-mongodb.sh')
    });
  }

  if(config.ssl) {
    installStud(taskList);
    configureStud(taskList, config.ssl.pem, config.ssl.backendPort);
  }

  //Configurations
  taskList.copy('Configuring upstart', {
    src: path.resolve(TEMPLATES_DIR, 'meteor.conf'),
    dest: '/etc/init/' + config.appName + '.conf',
    vars: {
      appName: config.appName
    }
  });

  return taskList;
};

exports.deploy = function(bundlePath, env, deployCheckWaitTime, appName, enableUploadProgressBar) {
  var taskList = nodemiral.taskList("Deploy app '" + appName + "' (linux)");

  taskList.copy('Uploading bundle', {
    src: bundlePath,
    dest: '/opt/' + appName + '/tmp/bundle.tar.gz',
    progressBar: enableUploadProgressBar
  });

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  // deploying
  taskList.executeScript('Invoking deployment process', {
    script: path.resolve(TEMPLATES_DIR, 'deploy.sh'),
    vars: {
      deployCheckWaitTime: deployCheckWaitTime || 10,
      appName: appName
    }
  });

  return taskList;
};

exports.reconfig = function(env, appName) {
  var taskList = nodemiral.taskList("Updating configurations (linux)");

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.restart = function(appName) {
  var taskList = nodemiral.taskList("Restarting Application (linux)");

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.stop = function(appName) {
  var taskList = nodemiral.taskList("Stopping Application (linux)");

  //stopping
  taskList.execute('Stopping app', {
    command: '(sudo stop ' + appName + ')'
  });

  return taskList;
};

exports.start = function(appName) {
  var taskList = nodemiral.taskList("Starting Application (linux)");

  //starting
  taskList.execute('Starting app', {
    command: '(sudo start ' + appName + ')'
  });

  return taskList;
};

function installStud(taskList) {
  taskList.executeScript('Installing Stud', {
    script: path.resolve(SCRIPT_DIR, 'install-stud.sh')
  });
}

function configureStud(taskList, pemFilePath, port) {
  var backend = {host: '127.0.0.1', port: port};

  taskList.copy('Configuring Stud for Upstart', {
    src: path.resolve(TEMPLATES_DIR, 'stud.init.conf'),
    dest: '/etc/init/stud.conf'
  });

  taskList.copy('Configuring SSL', {
    src: pemFilePath,
    dest: '/opt/stud/ssl.pem'
  });

  taskList.copy('Configuring Stud', {
    src: path.resolve(TEMPLATES_DIR, 'stud.conf'),
    dest: '/opt/stud/stud.conf',
    vars: {
      backend: util.format('[%s]:%d', backend.host, backend.port)
    }
  });

  taskList.execute('Verifying SSL Configurations (ssl.pem)', {
    command: 'stud --test --config=/opt/stud/stud.conf'
  });

  //restart stud
  taskList.execute('Strating Stud', {
    command: '(sudo stop stud || :) && (sudo start stud || :)'
  });
}
<commit_msg>Fixed Typo<commit_after>var nodemiral = require('nodemiral');
var fs = require('fs');
var path = require('path');
var util = require('util');

var SCRIPT_DIR = path.resolve(__dirname, '../../scripts/linux');
var TEMPLATES_DIR = path.resolve(__dirname, '../../templates/linux');

exports.setup = function(config) {
  var taskList = nodemiral.taskList('Setup (linux)');

  // Installation
  if(config.setupNode) {
    taskList.executeScript('Installing Node.js', {
      script: path.resolve(SCRIPT_DIR, 'install-node.sh'),
      vars: {
        nodeVersion: config.nodeVersion
      }
    });
  }

  if(config.setupPhantom) {
    taskList.executeScript('Installing PhantomJS', {
      script: path.resolve(SCRIPT_DIR, 'install-phantomjs.sh')
    });
  }

  taskList.executeScript('Setting up Environment', {
    script: path.resolve(SCRIPT_DIR, 'setup-env.sh'),
    vars: {
      appName: config.appName
    }
  });

  if(config.setupMongo) {
    taskList.copy('Copying MongoDB configuration', {
      src: path.resolve(TEMPLATES_DIR, 'mongodb.conf'),
      dest: '/etc/mongodb.conf'
    });

    taskList.executeScript('Installing MongoDB', {
      script: path.resolve(SCRIPT_DIR, 'install-mongodb.sh')
    });
  }

  if(config.ssl) {
    installStud(taskList);
    configureStud(taskList, config.ssl.pem, config.ssl.backendPort);
  }

  //Configurations
  taskList.copy('Configuring upstart', {
    src: path.resolve(TEMPLATES_DIR, 'meteor.conf'),
    dest: '/etc/init/' + config.appName + '.conf',
    vars: {
      appName: config.appName
    }
  });

  return taskList;
};

exports.deploy = function(bundlePath, env, deployCheckWaitTime, appName, enableUploadProgressBar) {
  var taskList = nodemiral.taskList("Deploy app '" + appName + "' (linux)");

  taskList.copy('Uploading bundle', {
    src: bundlePath,
    dest: '/opt/' + appName + '/tmp/bundle.tar.gz',
    progressBar: enableUploadProgressBar
  });

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  // deploying
  taskList.executeScript('Invoking deployment process', {
    script: path.resolve(TEMPLATES_DIR, 'deploy.sh'),
    vars: {
      deployCheckWaitTime: deployCheckWaitTime || 10,
      appName: appName
    }
  });

  return taskList;
};

exports.reconfig = function(env, appName) {
  var taskList = nodemiral.taskList("Updating configurations (linux)");

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.restart = function(appName) {
  var taskList = nodemiral.taskList("Restarting Application (linux)");

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.stop = function(appName) {
  var taskList = nodemiral.taskList("Stopping Application (linux)");

  //stopping
  taskList.execute('Stopping app', {
    command: '(sudo stop ' + appName + ')'
  });

  return taskList;
};

exports.start = function(appName) {
  var taskList = nodemiral.taskList("Starting Application (linux)");

  //starting
  taskList.execute('Starting app', {
    command: '(sudo start ' + appName + ')'
  });

  return taskList;
};

function installStud(taskList) {
  taskList.executeScript('Installing Stud', {
    script: path.resolve(SCRIPT_DIR, 'install-stud.sh')
  });
}

function configureStud(taskList, pemFilePath, port) {
  var backend = {host: '127.0.0.1', port: port};

  taskList.copy('Configuring Stud for Upstart', {
    src: path.resolve(TEMPLATES_DIR, 'stud.init.conf'),
    dest: '/etc/init/stud.conf'
  });

  taskList.copy('Configuring SSL', {
    src: pemFilePath,
    dest: '/opt/stud/ssl.pem'
  });

  taskList.copy('Configuring Stud', {
    src: path.resolve(TEMPLATES_DIR, 'stud.conf'),
    dest: '/opt/stud/stud.conf',
    vars: {
      backend: util.format('[%s]:%d', backend.host, backend.port)
    }
  });

  taskList.execute('Verifying SSL Configurations (ssl.pem)', {
    command: 'stud --test --config=/opt/stud/stud.conf'
  });

  //restart stud
  taskList.execute('Starting Stud', {
    command: '(sudo stop stud || :) && (sudo start stud || :)'
  });
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return /* Your Expression */;
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return /* Your Expression */;
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<commit_msg>commiting rockpaperscissors.js file with conditional assignment expressions added. this was chapt 3 hmwk.<commit_after>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return move || getInput();
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return move || randomPlay();
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<|endoftext|>


<commit_before>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return /* Your Expression */;
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return /* Your Expression */;
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<commit_msg>added return expressions to getPlayerMove() & getComputerMove()<commit_after>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return move || getInput();
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return move || randomPlay();
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<|endoftext|>


<commit_before>'use strict';
const fs = require("fs");
const async = require("async");
const formidable = require('formidable');
const EasyZip = require('easy-zip').EasyZip;

const helper = require("./helper");

let modelName = "mongo";
const externalModules = {
	ci: {
		module: require("../ci/index")
	},
	catalog: {
		module: require("../catalog/index")
	},
	endpoint: {
		module: require("../apiBuilder/index")
	}
};

const lib = {
	initBLModel: function (module, cb) {
		externalModules[module].module.init(modelName, cb);
	},

	checkReturnError: function (req, mainCb, data, cb) {
		if (data.error) {
			if (typeof (data.error) === 'object') {
				req.soajs.log.error(data.error);
			}
			return mainCb({"code": data.code, "msg": data.config.errors[data.code]});
		} else {
			if (cb) {
				return cb();
			}
		}
	}
};

const BL = {

	"import": (config, req, res, cbMain) => {
		let context = {
			errors: [],
			config: config
		};

		/**
		 * 1- unzip the file
		 * 2- parse the file
		 * 3- check mandatory
		 * 4- check duplicates
		 * 5- save file
		 */
		async.series({
			"parse": (mCb) => {
				let form = new formidable.IncomingForm();
				form.encoding = 'utf-8';
				form.keepExtensions = true;

				//unzip and parse the json file, assign it to the context.template if ok
				helper.parse(req, form, context, mCb);
			},
			"checkMandatory": (mCb) => {
				//check that the template has the minimum required schema before proceeding
				let validator = new req.soajs.validator.Validator();
				helper.checkMandatoryTemplateSchema(req, BL, lib, context, validator, mCb);
			},
			"checkDuplicates": (mCb) => {
				helper.checkDuplicate(req, BL, context, lib, () => {
					if (context.errors && context.errors.length > 0) {

						let now = new Date();
						let expires = new Date(now);
						expires.setSeconds(expires.getSeconds() + (7 * 24 * 3600));

						context.template.expires = expires;
						context.template.type = '_import';

						//transform the . -> __dot__
						for(let stage in context.template.deploy){
							for (let group in context.template.deploy[stage]){
								for(let section in context.template.deploy[stage][group]){
									if(section.indexOf(".") !== -1){
										let newSection = section.replace(/\./g, "__dot__");
										context.template.deploy[stage][group][newSection] = JSON.parse(JSON.stringify(context.template.deploy[stage][group][section]));
										delete context.template.deploy[stage][group][section];
									}
								}
							}
						}

						BL.model.insertEntry(req.soajs, {
							collection: 'templates',
							record: context.template
						}, (error, record) => {
							lib.checkReturnError(req, mCb, {config: config, error: error, code: 600}, () => {
								//inject template id as part of the error response
								context.template.id = record[0]._id;
								context.errors.unshift({code: 173, "msg": "id => " + context.template.id.toString()});
								return mCb(context.errors);
							});
						});
					}
					else{
						return mCb(null, true);
					}
				});
			},
			"save": (mCb) => {
				/*
					1 - save ci
					2 - save cd
					3 - save endpoints
					3.1 - publish endpoints
					4 - create deployment template
					4.1 - save deployment template
				 */

				//save information
				async.series({
					"saveContent": (vCb) => {
						helper.saveContent(req, BL, context, lib, vCb);
					},
					"generateDeploymentTemplate": (vCb) => {
						helper.generateDeploymentTemplate(req, config, BL, context, lib, vCb);
					}
				}, (error) => {
					return mCb(error);
				});
			}
		}, (error) => {
			helper.cleanUp(context.fileName, () => {
				return cbMain(null, error);
			});
		});
	},

	"correct": (config, req, res, cbMain) => {
		let context = {
			errors: [],
			config: config
		};

		/**
		 * 1- unzip the file
		 * 2- parse the file
		 * 3- check mandatory
		 * 4- check duplicates
		 * 5- save file
		 */
		async.series({
			"validateInputs": (mCb) => {
				if (!req.soajs.inputmaskData || !req.soajs.inputmaskData.id || !req.soajs.inputmaskData.correction || typeof(req.soajs.inputmaskData.correction) !== 'object') {
					return mCb({
						"code": 173,
						"msg": "Invalid Inputs provided to correct the previously imported template!"
					});
				}
				return mCb();
			},
			"merge": (mCb) => {
				//unzip and parse the json file, assign it to the context.template if ok
				helper.mergeToTemplate(req, config, BL, context, lib, mCb);
			},
			"checkMandatory": (mCb) => {
				//check that the template has the minimum required schema before proceeding
				let validator = new req.soajs.validator.Validator();
				helper.checkMandatoryTemplateSchema(req, BL, lib, context, validator, mCb);
			},
			"checkDuplicates": (mCb) => {
				helper.checkDuplicate(req, BL, context, lib, () => {
					if (context.errors && context.errors.length > 0) {
						BL.model.saveEntry(req.soajs, {
							collection: 'templates',
							record: context.template
						}, (error) => {
							lib.checkReturnError(req, mCb, {config: config, error: error, code: 600}, () => {
								//inject template id as part of the error response
								context.errors.unshift({"id": context.template._id.toString()});
								return mCb(context.errors);
							});
						});
					}
					return mCb(null, true);
				});
			},
			"save": (mCb) => {
				/*
					1 - save ci
					2 - save cd
					3 - save endpoints
					3.1 - publish endpoints
					4 - create deployment template
					4.1 - save deployment template
				 */

				//save information
				async.series({
					"saveContent": (vCb) => {
						helper.saveContent(req, BL, context, lib, vCb);
					},
					"generateDeploymentTemplate": (vCb) => {
						helper.generateDeploymentTemplate(req, config, BL, context, lib, vCb);
					}
				}, (error) => {
					return mCb(error);
				});
			}
		}, (error) => {
			return cbMain(null, error);
		});
	},

	"export": (config, req, res, cbMain) => {
		let context = {
			config,
			dbData: {},
			template : {
				"name": "New Template " + new Date().toISOString(),
				"description": "",
				"link": "",
				"content": {},
				"deploy": {}
			}
		};

		//there is nothing to export !
		if(!req.soajs.inputmaskData.ci && !req.soajs.inputmaskData.deployment && !req.soajs.inputmaskData.endpoints){
			return cbMain({code: 481, msg: config.errors[481]});
		}

		helper.fetchDataFromDB(req, BL, context, lib, (error) => {
			lib.checkReturnError(req, mCb, {config: config, error: error, code: (error && error.code) ? error.code : 600 }, () => {
				BL.model.closeConnection(req.soajs);

				helper.populateTemplate(context);

				let execDir = __dirname + "/downloads/";
				let zipFileName = "soajs_template-" + new Date().toISOString();

				let output = "module.exports = " + context.template + ";";
				fs.writeFile(zipFileName + ".js", output, 'utf8', (error) =>{
					lib.checkReturnError(req, mCb, {config: config, error: error, code: 482 }, () => {

						//genrate zip file and return response
						let stat = fs.statSync(execDir + zipFileName + ".zip");
						let readStream = fs.createReadStream(execDir + zipFileName + ".zip");

						//set the headers to applicaiton/zip and send the file in the response
						res.writeHead(200, {
							'Content-Type': "application/zip",
							'Content-Length': stat.size
						});
						readStream.pipe(res);

					});
				});
			});
		});
	}
};

module.exports = {
	"init": function (modelName, cb) {
		var modelPath;

		if (!modelName) {
			return cb(new Error("No Model Requested!"));
		}

		modelPath = __dirname + "/../../models/" + modelName + ".js";
		return requireModel(modelPath, cb);

		/**
		 * checks if model file exists, requires it and returns it.
		 * @param filePath
		 * @param cb
		 */
		function requireModel(filePath, cb) {
			//check if file exist. if not return error
			fs.exists(filePath, function (exists) {
				if (!exists) {
					return cb(new Error("Requested Model Not Found!"));
				}

				BL.model = require(filePath);
				return cb(null, BL);
			});
		}
	}
};
<commit_msg>minor adjustment to import flow of execution.<commit_after>'use strict';
const fs = require("fs");
const async = require("async");
const formidable = require('formidable');
const EasyZip = require('easy-zip').EasyZip;

const helper = require("./helper");

let modelName = "mongo";
const externalModules = {
	ci: {
		module: require("../ci/index")
	},
	catalog: {
		module: require("../catalog/index")
	},
	endpoint: {
		module: require("../apiBuilder/index")
	}
};

const lib = {
	initBLModel: function (module, cb) {
		externalModules[module].module.init(modelName, cb);
	},

	checkReturnError: function (req, mainCb, data, cb) {
		if (data.error) {
			if (typeof (data.error) === 'object') {
				req.soajs.log.error(data.error);
			}
			return mainCb({"code": data.code, "msg": data.config.errors[data.code]});
		} else {
			if (cb) {
				return cb();
			}
		}
	}
};

const BL = {

	"import": (config, req, res, cbMain) => {
		let context = {
			errors: [],
			config: config
		};

		/**
		 * 1- unzip the file
		 * 2- parse the file
		 * 3- check mandatory
		 * 4- check duplicates
		 * 5- save file
		 */
		async.series({
			"parse": (mCb) => {
				let form = new formidable.IncomingForm();
				form.encoding = 'utf-8';
				form.keepExtensions = true;

				//unzip and parse the json file, assign it to the context.template if ok
				helper.parse(req, form, context, mCb);
			},
			"checkMandatory": (mCb) => {
				//check that the template has the minimum required schema before proceeding
				let validator = new req.soajs.validator.Validator();
				helper.checkMandatoryTemplateSchema(req, BL, lib, context, validator, mCb);
			},
			"checkDuplicates": (mCb) => {
				if(context.errors && context.errors.length > 0){
					return mCb(context.errors);
				}

				helper.checkDuplicate(req, BL, context, lib, () => {
					if (context.errors && context.errors.length > 0) {

						let now = new Date();
						let expires = new Date(now);
						expires.setSeconds(expires.getSeconds() + (7 * 24 * 3600));

						context.template.expires = expires;
						context.template.type = '_import';

						//transform the . -> __dot__
						for(let stage in context.template.deploy){
							for (let group in context.template.deploy[stage]){
								for(let section in context.template.deploy[stage][group]){
									if(section.indexOf(".") !== -1){
										let newSection = section.replace(/\./g, "__dot__");
										context.template.deploy[stage][group][newSection] = JSON.parse(JSON.stringify(context.template.deploy[stage][group][section]));
										delete context.template.deploy[stage][group][section];
									}
								}
							}
						}

						BL.model.insertEntry(req.soajs, {
							collection: 'templates',
							record: context.template
						}, (error, record) => {
							lib.checkReturnError(req, mCb, {config: config, error: error, code: 600}, () => {
								//inject template id as part of the error response
								context.template.id = record[0]._id;
								context.errors.unshift({code: 173, "msg": "id => " + context.template.id.toString()});
								return mCb(context.errors);
							});
						});
					}
					else{
						return mCb(null, true);
					}
				});
			},
			"save": (mCb) => {
				/*
					1 - save ci
					2 - save cd
					3 - save endpoints
					3.1 - publish endpoints
					4 - create deployment template
					4.1 - save deployment template
				 */

				//save information
				async.series({
					"saveContent": (vCb) => {
						helper.saveContent(req, BL, context, lib, vCb);
					},
					"generateDeploymentTemplate": (vCb) => {
						helper.generateDeploymentTemplate(req, config, BL, context, lib, vCb);
					}
				}, (error) => {
					return mCb(error);
				});
			}
		}, (error) => {
			helper.cleanUp(context.fileName, () => {
				return cbMain(null, error);
			});
		});
	},

	"correct": (config, req, res, cbMain) => {
		let context = {
			errors: [],
			config: config
		};

		/**
		 * 1- unzip the file
		 * 2- parse the file
		 * 3- check mandatory
		 * 4- check duplicates
		 * 5- save file
		 */
		async.series({
			"validateInputs": (mCb) => {
				if (!req.soajs.inputmaskData || !req.soajs.inputmaskData.id || !req.soajs.inputmaskData.correction || typeof(req.soajs.inputmaskData.correction) !== 'object') {
					return mCb({
						"code": 173,
						"msg": "Invalid Inputs provided to correct the previously imported template!"
					});
				}
				return mCb();
			},
			"merge": (mCb) => {
				//unzip and parse the json file, assign it to the context.template if ok
				helper.mergeToTemplate(req, config, BL, context, lib, mCb);
			},
			"checkMandatory": (mCb) => {
				//check that the template has the minimum required schema before proceeding
				let validator = new req.soajs.validator.Validator();
				helper.checkMandatoryTemplateSchema(req, BL, lib, context, validator, mCb);
			},
			"checkDuplicates": (mCb) => {
				helper.checkDuplicate(req, BL, context, lib, () => {
					if (context.errors && context.errors.length > 0) {
						BL.model.saveEntry(req.soajs, {
							collection: 'templates',
							record: context.template
						}, (error) => {
							lib.checkReturnError(req, mCb, {config: config, error: error, code: 600}, () => {
								//inject template id as part of the error response
								context.errors.unshift({"id": context.template._id.toString()});
								return mCb(context.errors);
							});
						});
					}
					return mCb(null, true);
				});
			},
			"save": (mCb) => {
				/*
					1 - save ci
					2 - save cd
					3 - save endpoints
					3.1 - publish endpoints
					4 - create deployment template
					4.1 - save deployment template
				 */

				//save information
				async.series({
					"saveContent": (vCb) => {
						helper.saveContent(req, BL, context, lib, vCb);
					},
					"generateDeploymentTemplate": (vCb) => {
						helper.generateDeploymentTemplate(req, config, BL, context, lib, vCb);
					}
				}, (error) => {
					return mCb(error);
				});
			}
		}, (error) => {
			return cbMain(null, error);
		});
	},

	"export": (config, req, res, cbMain) => {
		let context = {
			config,
			dbData: {},
			template : {
				"name": "New Template " + new Date().toISOString(),
				"description": "",
				"link": "",
				"content": {},
				"deploy": {}
			}
		};

		//there is nothing to export !
		if(!req.soajs.inputmaskData.ci && !req.soajs.inputmaskData.deployment && !req.soajs.inputmaskData.endpoints){
			return cbMain({code: 481, msg: config.errors[481]});
		}

		helper.fetchDataFromDB(req, BL, context, lib, (error) => {
			lib.checkReturnError(req, mCb, {config: config, error: error, code: (error && error.code) ? error.code : 600 }, () => {
				BL.model.closeConnection(req.soajs);

				helper.populateTemplate(context);

				let execDir = __dirname + "/downloads/";
				let zipFileName = "soajs_template-" + new Date().toISOString();

				let output = "module.exports = " + context.template + ";";
				fs.writeFile(zipFileName + ".js", output, 'utf8', (error) =>{
					lib.checkReturnError(req, mCb, {config: config, error: error, code: 482 }, () => {

						//genrate zip file and return response
						let stat = fs.statSync(execDir + zipFileName + ".zip");
						let readStream = fs.createReadStream(execDir + zipFileName + ".zip");

						//set the headers to applicaiton/zip and send the file in the response
						res.writeHead(200, {
							'Content-Type': "application/zip",
							'Content-Length': stat.size
						});
						readStream.pipe(res);

					});
				});
			});
		});
	}
};

module.exports = {
	"init": function (modelName, cb) {
		var modelPath;

		if (!modelName) {
			return cb(new Error("No Model Requested!"));
		}

		modelPath = __dirname + "/../../models/" + modelName + ".js";
		return requireModel(modelPath, cb);

		/**
		 * checks if model file exists, requires it and returns it.
		 * @param filePath
		 * @param cb
		 */
		function requireModel(filePath, cb) {
			//check if file exist. if not return error
			fs.exists(filePath, function (exists) {
				if (!exists) {
					return cb(new Error("Requested Model Not Found!"));
				}

				BL.model = require(filePath);
				return cb(null, BL);
			});
		}
	}
};
<|endoftext|>


<commit_before>'use strict';

const builder = require('botbuilder');
const jira = require('../services/jira');
const auth = require('../services/auth');

const lib = new builder.Library('worklog');

const empty = (arr) => {
    return !arr || arr.length === 0;
};

const find = (...args) => {
    const el = builder.EntityRecognizer.findEntity.call(this, ...args);
    return el ? el.entity : null;
};

const findTimePart = (entities) => {
    const entity = find.call(this, ...[entities, 'timeSpent']) || find.call(this, ...[entities, 'builtin.datetimeV2.duration']);
    if (entity) {
        return String.prototype.split.call(entity, /\s/g).join('').replace(/([mhd])/g, '$1 ').trim();
    }
    return null;
};

const findDatePart = (entities) => {
    const ResolutionProp = 'resolution';

    const entity = builder.EntityRecognizer.findEntity.call(this, ...[entities, 'builtin.datetimeV2.date']);
    const resolution = Object.prototype.hasOwnProperty.call(entity, 'resolution') ? entity[ResolutionProp] : null;
    const datetimeValues = resolution ? resolution.values : [];

    const isvalidDate = (val) => {
        const dt = new Date(val);
        if (Object.prototype.toString.call(dt) === '[object Date]') {
            return !isNaN(dt.getTime());
        }
        return false;
    };

    const date = Array.prototype.find.call(datetimeValues, (el) => {
        return el.type === 'date' ? isvalidDate.call(this, ...[el.value]) : false;
    });

    return date ? new Date(date.value) : null;
};

lib.dialog('/', [
        (session, args) => {

            if (!session.userData.profile) {
                return session.send(`Looks like you haven't signed in.`).replaceDialog('greet:/');
            } else if (empty.call(this, ...session.userData.jira)) {
                return session.send(`Looks like you don't have JIRA access.`).replaceDialog('greet:/');
            }

            session.dialogData.args = args;
            session.beginDialog('/task', args);
        },

        (session, results) => {

            if (!results.response) {
                return session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            }
            session.dialogData.task = results.response.task;
            session.dialogData.project = results.response.project;
            session.beginDialog('/time-spent', session.dialogData.args);
        },

        (session, results) => {

            if (!results.response) {
                return session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            }
            session.dialogData.timeSpent = results.response
            session.beginDialog('/date-started', session.dialogData.args);
        },

        (session, results, next) => {

            if (!results.response) {
                return session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            }
            session.dialogData.dateStarted = results.response;
            session.beginDialog('/complete', session.dialogData);
        }
    ])
    .triggerAction({
        matches: ['/worklog']
    })
    .cancelAction('/worklog-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/task', [
        (session, args, next) => {

            const {
                entities
            } = args.intent;
            const task = find.call(this, ...[entities, 'task']);

            if (task) {
                next({
                    response: String.prototype.replace.call(task, /\s/g, '')
                });
            } else {
                session.send(`I don't know *what task* to log (worry)`)
                    .endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
            }
        },

        (session, results, next) => {

            const task = results.response;
            const {
                emailAddress
            } = session.userData.profile;

            session.sendTyping();

            auth.authorize(emailAddress, task)
                .then((response) => {
                    session.endDialogWithResult({
                        response: {
                            project: response.project,
                            task,
                        }
                    });
                })
                .catch((error) => {
                    const {
                        statusCode
                    } = error;

                    switch (statusCode) {
                        case 401:
                            session.send(`Oops! Looks like you don't have access to that project. Talk to IT Services.`);
                            break;
                        case 404:
                            session.send(`Oops! Cannot find that task. May be it doesn't exists or not created yet.`);
                            break;
                        default:
                            session.send(`Oops! Something went wrong. Shame on us! Try a bit later.`);
                            break;
                    }

                    session.endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
                });
        }
    ])
    .cancelAction('/task-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/time-spent', [
        (session, args) => {
            const {
                entities
            } = args.intent;

            const timeSpent = findTimePart.call(this, ...[entities]);

            if (timeSpent) {
                session.endDialogWithResult({
                    response: timeSpent
                });
            } else {
                session.send(`I don't know how much *time you spent*.`)
                    .endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
            }
        }
    ])
    .cancelAction('/time-spent-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/date-started', [
        (session, args, next) => {

            const {
                entities
            } = args.intent;
            const dateStarted = findDatePart.call(this, ...[entities]);

            if (dateStarted) {
                session.endDialogWithResult({
                    response: dateStarted.toISOString().replace('Z', '+0000')
                });
            } else {
                return session.send(`Sorry! I don't know *when you started* it (worry)`)
                    .endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
            }
        }
    ])
    .cancelAction('/date-started-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/complete', [
    (session, args) => {

        const {
            task,
            project,
            dateStarted,
            timeSpent
        } = args;

        const {
            text
        } = session.message;

        const worklog = {
            comment: text,
            started: dateStarted,
            timeSpent: timeSpent
        };

        session.sendTyping();

        jira.addWorklog(project, task, worklog)
            .then((response) => {
                session.send('(y)')
                    .endDialog();
            })
            .catch((error) => {
                const {
                    statusCode
                } = error;

                const {
                    goodname
                } = session.userData.profile;

                switch (statusCode) {
                    case 401:
                        session.send(`Your JIRA credentials no longer working, ${goodname}. Just talk to IT Services about it.`);
                        break;

                    case 404:
                        session.send(`Oops! ${task} task doesn't exists or you don't have permission, ${goodname}.`);
                        break;

                    default:
                        session.send(`Oops! Something went wrong. Shame on us (facepalm). Let's try again in few mins.`);
                        break;
                }

                session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            });
    }
]);

module.exports = exports = {
    createNew: () => {
        return lib.clone();
    }
};<commit_msg>#17 getting rid of unused args.<commit_after>'use strict';

const builder = require('botbuilder');
const jira = require('../services/jira');
const auth = require('../services/auth');

const lib = new builder.Library('worklog');

const empty = (arr) => {
    return !arr || arr.length === 0;
};

const find = (...args) => {
    const el = builder.EntityRecognizer.findEntity.call(this, ...args);
    return el ? el.entity : null;
};

const findTimePart = (entities) => {
    const entity = find.call(this, ...[entities, 'timeSpent']) || find.call(this, ...[entities, 'builtin.datetimeV2.duration']);
    if (entity) {
        return String.prototype.split.call(entity, /\s/g).join('').replace(/([mhd])/g, '$1 ').trim();
    }
    return null;
};

const findDatePart = (entities) => {
    const ResolutionProp = 'resolution';

    const entity = builder.EntityRecognizer.findEntity.call(this, ...[entities, 'builtin.datetimeV2.date']);
    const resolution = Object.prototype.hasOwnProperty.call(entity, 'resolution') ? entity[ResolutionProp] : null;
    const datetimeValues = resolution ? resolution.values : [];

    const isvalidDate = (val) => {
        const dt = new Date(val);
        if (Object.prototype.toString.call(dt) === '[object Date]') {
            return !isNaN(dt.getTime());
        }
        return false;
    };

    const date = Array.prototype.find.call(datetimeValues, (el) => {
        return el.type === 'date' ? isvalidDate.call(this, ...[el.value]) : false;
    });

    return date ? new Date(date.value) : null;
};

lib.dialog('/', [
        (session, args) => {

            if (!session.userData.profile) {
                return session.send(`Looks like you haven't signed in.`).replaceDialog('greet:/');
            } else if (empty.call(this, ...session.userData.jira)) {
                return session.send(`Looks like you don't have JIRA access.`).replaceDialog('greet:/');
            }

            session.dialogData.args = args;
            session.beginDialog('/task', args);
        },

        (session, results) => {

            if (!results.response) {
                return session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            }
            session.dialogData.task = results.response.task;
            session.dialogData.project = results.response.project;
            session.beginDialog('/time-spent', session.dialogData.args);
        },

        (session, results) => {

            if (!results.response) {
                return session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            }
            session.dialogData.timeSpent = results.response
            session.beginDialog('/date-started', session.dialogData.args);
        },

        (session, results) => {

            if (!results.response) {
                return session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            }
            session.dialogData.dateStarted = results.response;
            session.beginDialog('/complete', session.dialogData);
        }
    ])
    .triggerAction({
        matches: ['/worklog']
    })
    .cancelAction('/worklog-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/task', [
        (session, args, next) => {

            const {
                entities
            } = args.intent;
            const task = find.call(this, ...[entities, 'task']);

            if (task) {
                next({
                    response: String.prototype.replace.call(task, /\s/g, '')
                });
            } else {
                session.send(`I don't know *what task* to log (worry)`)
                    .endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
            }
        },

        (session, results) => {

            const task = results.response;
            const {
                emailAddress
            } = session.userData.profile;

            session.sendTyping();

            auth.authorize(emailAddress, task)
                .then((response) => {
                    session.endDialogWithResult({
                        response: {
                            project: response.project,
                            task,
                        }
                    });
                })
                .catch((error) => {
                    const {
                        statusCode
                    } = error;

                    switch (statusCode) {
                        case 401:
                            session.send(`Oops! Looks like you don't have access to that project. Talk to IT Services.`);
                            break;
                        case 404:
                            session.send(`Oops! Cannot find that task. May be it doesn't exists or not created yet.`);
                            break;
                        default:
                            session.send(`Oops! Something went wrong. Shame on us! Try a bit later.`);
                            break;
                    }

                    session.endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
                });
        }
    ])
    .cancelAction('/task-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/time-spent', [
        (session, args) => {
            const {
                entities
            } = args.intent;

            const timeSpent = findTimePart.call(this, ...[entities]);

            if (timeSpent) {
                session.endDialogWithResult({
                    response: timeSpent
                });
            } else {
                session.send(`I don't know how much *time you spent*.`)
                    .endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
            }
        }
    ])
    .cancelAction('/time-spent-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/date-started', [
        (session, args) => {

            const {
                entities
            } = args.intent;
            const dateStarted = findDatePart.call(this, ...[entities]);

            if (dateStarted) {
                session.endDialogWithResult({
                    response: dateStarted.toISOString().replace('Z', '+0000')
                });
            } else {
                return session.send(`Sorry! I don't know *when you started* it (worry)`)
                    .endDialogWithResult({
                        resumed: builder.ResumeReason.notCompleted
                    });
            }
        }
    ])
    .cancelAction('/date-started-cancel', '(y)', {
        matches: [/^(cancel|nevermind)$/g]
    });

lib.dialog('/complete', [
    (session, args) => {

        const {
            task,
            project,
            dateStarted,
            timeSpent
        } = args;

        const {
            text
        } = session.message;

        const worklog = {
            comment: text,
            started: dateStarted,
            timeSpent: timeSpent
        };

        session.sendTyping();

        jira.addWorklog(project, task, worklog)
            .then((response) => {
                session.send('(y)')
                    .endDialog();
            })
            .catch((error) => {
                const {
                    statusCode
                } = error;

                const {
                    goodname
                } = session.userData.profile;

                switch (statusCode) {
                    case 401:
                        session.send(`Your JIRA credentials no longer working, ${goodname}. Just talk to IT Services about it.`);
                        break;

                    case 404:
                        session.send(`Oops! ${task} task doesn't exists or you don't have permission, ${goodname}.`);
                        break;

                    default:
                        session.send(`Oops! Something went wrong. Shame on us (facepalm). Let's try again in few mins.`);
                        break;
                }

                session.endDialogWithResult({
                    resumed: builder.ResumeReason.notCompleted
                });
            });
    }
]);

module.exports = exports = {
    createNew: () => {
        return lib.clone();
    }
};<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

function SupervisoryNodeSearchController($scope, $location, SupervisoryNodesSearch) {

  $scope.previousQuery = '';
  $scope.previousSearchOption = undefined;

  $scope.searchOptions = [
    {value: "node", name: "option.value.supervisory.node"},
    {value: "parent", name: "option.value.supervisory.node.parent"}
  ];

  $scope.selectedSearchOption = $scope.searchOptions[0];

  $scope.selectSearchType = function (searchOption) {
    $scope.selectedSearchOption = searchOption;
    var searchOption = $scope.selectedSearchOption.value === 'parent' ? true : false;
    $scope.currentPage = undefined;
    if ($scope.previousSearchOption !== searchOption) $scope.previousQuery = '';
    $scope.showSupervisoryNodeSearchResults();

  };

  $scope.showSupervisoryNodeSearchResults = function () {
    if (!$scope.currentPage)
      $scope.currentPage = 1;
    var query = $scope.query;

    var len = (query === undefined) ? 0 : query.length;

    var searchOption = $scope.selectedSearchOption.value === 'parent' ? true : false;

    var page = $scope.pagination ? $scope.pagination.page : undefined;
    if (len >= 3) {
      if ($scope.previousQuery.substr(0, 3) === query.substr(0, 3) && $scope.currentPage === page) {
        $scope.previousQuery = query;
        filterSupervisoryNode(query);
        return true;
      }
      $scope.previousQuery = query;
      $scope.previousSearchOption = searchOption;
      SupervisoryNodesSearch.get({page: $scope.currentPage, param: $scope.query.substr(0, 3), parent: searchOption}, function (data) {
        $scope.supervisoryNodeList = data.supervisoryNodes;
        $scope.pagination = data.pagination;
        filterSupervisoryNode(query);
      }, {});
      return true;
    } else {
      return false;
    }
  };

  $scope.$on('$routeUpdate', function () {
    $scope.showSupervisoryNodeSearchResults();
  });

  $scope.$watch('currentPage', function () {
    $location.search('page', $scope.currentPage);
  });

  $scope.clearSearch = function () {
    $scope.query = "";
    $scope.resultCount = 0;
    angular.element("#searchSupervisoryNode").focus();
  };

  var filterSupervisoryNode = function (query) {
    $scope.filteredNodes = [];
    query = query || "";

    angular.forEach($scope.supervisoryNodeList, function (supervisoryNode) {
      var name = $scope.parent ? supervisoryNode.parent.name : supervisoryNode.name;

      if (name.toLowerCase().indexOf(query.trim().toLowerCase()) >= 0) {
        $scope.filteredNodes.push(supervisoryNode);
      }
    });
    $scope.resultCount = $scope.pagination.totalRecords;
  };
}<commit_msg># 1465|Fixing jshint error<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

function SupervisoryNodeSearchController($scope, $location, SupervisoryNodesSearch) {

  $scope.previousQuery = '';
  $scope.previousSearchOption = undefined;

  $scope.searchOptions = [
    {value: "node", name: "option.value.supervisory.node"},
    {value: "parent", name: "option.value.supervisory.node.parent"}
  ];

  $scope.selectedSearchOption = $scope.searchOptions[0];

  $scope.selectSearchType = function (searchOption) {
    $scope.selectedSearchOption = searchOption;
    searchOption = $scope.selectedSearchOption.value === 'parent' ? true : false;
    $scope.currentPage = undefined;
    if ($scope.previousSearchOption !== searchOption) $scope.previousQuery = '';
    $scope.showSupervisoryNodeSearchResults();

  };

  $scope.showSupervisoryNodeSearchResults = function () {
    if (!$scope.currentPage)
      $scope.currentPage = 1;
    var query = $scope.query;

    var len = (query === undefined) ? 0 : query.length;

    var searchOption = $scope.selectedSearchOption.value === 'parent' ? true : false;

    var page = $scope.pagination ? $scope.pagination.page : undefined;
    if (len >= 3) {
      if ($scope.previousQuery.substr(0, 3) === query.substr(0, 3) && $scope.currentPage === page) {
        $scope.previousQuery = query;
        filterSupervisoryNode(query);
        return true;
      }
      $scope.previousQuery = query;
      $scope.previousSearchOption = searchOption;
      SupervisoryNodesSearch.get({page: $scope.currentPage, param: $scope.query.substr(0, 3), parent: searchOption}, function (data) {
        $scope.supervisoryNodeList = data.supervisoryNodes;
        $scope.pagination = data.pagination;
        filterSupervisoryNode(query);
      }, {});
      return true;
    } else {
      return false;
    }
  };

  $scope.$on('$routeUpdate', function () {
    $scope.showSupervisoryNodeSearchResults();
  });

  $scope.$watch('currentPage', function () {
    $location.search('page', $scope.currentPage);
  });

  $scope.clearSearch = function () {
    $scope.query = "";
    $scope.resultCount = 0;
    angular.element("#searchSupervisoryNode").focus();
  };

  var filterSupervisoryNode = function (query) {
    $scope.filteredNodes = [];
    query = query || "";

    angular.forEach($scope.supervisoryNodeList, function (supervisoryNode) {
      var name = $scope.parent ? supervisoryNode.parent.name : supervisoryNode.name;

      if (name.toLowerCase().indexOf(query.trim().toLowerCase()) >= 0) {
        $scope.filteredNodes.push(supervisoryNode);
      }
    });
    $scope.resultCount = $scope.pagination.totalRecords;
  };
}<|endoftext|>


<commit_before>/*
    View.close() method which makes sure the View is propperly destroyed, and
    the events are unbound

    Also triggers a nice close event!

    This method is needed to make sure we don't get any zombie views that don't
    exist in the users view, but are still bound to events (like user
    interaction events or model events)
*/
Backbone.View.prototype.close = function() {
  this.remove();
  this.unbind();
  if (this.onClose) {
    this.onClose();
  }
  this.trigger('close');
};
<commit_msg>commented out code for debugging<commit_after>/*
    View.close() method which makes sure the View is propperly destroyed, and
    the events are unbound

    Also triggers a nice close event!

    This method is needed to make sure we don't get any zombie views that don't
    exist in the users view, but are still bound to events (like user
    interaction events or model events)
*/
Backbone.View.prototype.close = function() {
  this.remove();
  this.unbind();
  if (this.onClose) {
    this.onClose();
  }
  this.trigger('close');
};

/*
window.bekijks={};
Backbone.View.prototype.constructor = function(options) {
  this.cid = _.uniqueId('view');
  console.info('+CID ', this.cid);
  window.bekijks[this.cid]=this;
     this._configure(options || {});
     this._ensureElement();
     this.initialize.apply(this, arguments);
     this.delegateEvents();
     this.on('close', function(){console.info('-CID', this.cid);delete window.bekijks[this.cid];},this);
}
*/<|endoftext|>


<commit_before>/**
 * Created by meathill on 15/7/3.
 */
'use strict';
(function (ns) {
  /**
   * @class
   */
  ns.AddOnList = ns.BaseList.extend({
    autoFetch: false,
    initialize: function (options) {
      options = _.extend({
        container: 'tbody'
      }, options, this.$el.data());
      this.options = options;
      this.collection = tp.model.ListCollection.getInstance();
      ns.BaseList.prototype.initialize.call(this, options);

      var id = this.$el.data('collection-id')
        , key = this.$el.data('key')
        , collection = tp.model.ListCollection.getInstance({
          collectionId: id
        });
      collection.on('data:' + key, this.collection_dataHandler, this);
    },
    collection_dataHandler: function (list, collection) {
      if (collection.options) {
        this.collection.model = Backbone.Model.extend({
          defaults: collection.options
        });
      }
      this.collection.reset(list);

      if (this.options.amount) {
        var data = this.collection.getAmount(this.options.omits);
        this.collection_addHandler(data, null, {immediately: true});
      }
    }
  });
}(Nervenet.createNameSpace('tp.component')));<commit_msg>  去掉多余行<commit_after>/**
 * Created by meathill on 15/7/3.
 */
'use strict';
(function (ns) {
  /**
   * @class
   */
  ns.AddOnList = ns.BaseList.extend({
    autoFetch: false,
    initialize: function (options) {
      options = _.extend({
        container: 'tbody'
      }, options, this.$el.data());
      this.options = options;
      this.collection = tp.model.ListCollection.getInstance();
      ns.BaseList.prototype.initialize.call(this, options);

      var id = this.$el.data('collection-id')
        , key = this.$el.data('key')
        , collection = tp.model.ListCollection.getInstance({
          collectionId: id
        });
      collection.on('data:' + key, this.collection_dataHandler, this);
    },
    collection_dataHandler: function (list, collection) {
      if (collection.options) {
        this.collection.model = Backbone.Model.extend({
          defaults: collection.options
        });
      }
      this.collection.reset(list);
      if (this.options.amount) {
        var data = this.collection.getAmount(this.options.omits);
        this.collection_addHandler(data, null, {immediately: true});
      }
    }
  });
}(Nervenet.createNameSpace('tp.component')));<|endoftext|>


<commit_before>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return /* Your Expression */;
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return /* Your Expression */;
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<commit_msg>unit 4 hw<commit_after>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move)
{
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
  return move || getInput();
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return move || randomPlay();
}

function getWinner(playerMove,computerMove) {
    var winner = "tie";
    if (playerMove == "rock"){
    	if (computerMove == "paper") {
    		winner = "computer";
    	}else if (computerMove == "scissors") {
    		winner = "player";
    	}
    }
    if (playerMove == "paper"){
    	if (computerMove == "rock") {
    		winner = "player";
    	}else if (computerMove == "scissors") {
    		winner = "computer";
    	}
    }
    if (playerMove == "scissors"){
    	if (computerMove == "paper") {
    		winner = "player";
    	}else if (computerMove == "rock") {
    		winner = "computer";
    	}
    }
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<|endoftext|>