<commit_before>define(function(require, exports, module) {
    var View           = require('famous/core/View');
    var Surface        = require('famous/core/Surface');
    var Transform      = require('famous/core/Transform');
    var Modifier       = require('famous/core/Modifier');
    var StateModifier  = require('famous/modifiers/StateModifier');
    var MouseSync      = require('famous/inputs/MouseSync');
    var Transitionable = require('famous/transitions/Transitionable');
    var Easing         = require('famous/transitions/Easing');
    var GameBoard = require('views/GameBoard');

    function RotatingLogic() {
        View.apply(this, arguments);

        this.position = [0, 0]; //mouse movement
        this.state = [0,0,1]; //current front face
        this.nVec = [0,-1,0]; //current top face
        this.rVec = [1,0,0]; //current right face
        this.index = [0,0,0]; //90 degree turn unit
        this.left = 0; //rotate left
        this.down = 0; //rotate down
        this.rotation = Transform.rotate(0,0,0); //initial transfrom matrix

        this.transitionable = new Transitionable(0);

        _createRotateModifier.call(this);
        _createBackground.call(this);
        _setBackgroundListeners.call(this);
        _createGameBoard.call(this);
        _setListeners.call(this);
    }

    RotatingLogic.prototype = Object.create(View.prototype);
    RotatingLogic.prototype.constructor = RotatingLogic;

    RotatingLogic.prototype.setDestroyerPosition = function(pos){
      this.gameBoard.setDestroyerPosition(pos);
    }

    RotatingLogic.DEFAULT_OPTIONS = {
      mainCubeSize: 400,
      destroyer: undefined,
      smallCube: undefined
    };

    function _createGameBoard() {
      this.gameBoard = new GameBoard({
        mainCubeSize: this.options.mainCubeSize,
        destroyer: this.options.destroyer,
        smallCube: this.options.smallCube
      });
      this.node.add(this.gameBoard);
    }

    function _createBackground () {
        this.backgroundSurface = new Surface({
            size: [undefined, undefined]
        });

        this.add(this.backgroundSurface);
    }

    function _createRotateModifier () {
        var self = this;

        var rotateModifier = new Modifier({
          transform: function () {
            var rotateAng = this.transitionable.get();
            if (rotateAng  > 0.99999){
              this.rotation = mapStateTransition(this.state, this.nVec);
              this.index = [0,0,0];
              this.position = [0,0];
              this.left = 0;
              this.down = 0;
              this.transitionable.reset(0);
              this.transitionable.halt();

              var updateObj = {
                nVec: this.nVec,
                rVec: this.rVec
              };
              this._eventOutput.emit('coordinateUpdate', updateObj);
            }

            var rotTrans = Transform.rotate((this.index[0]*rotateAng)*Math.PI/2,
              (this.index[1]*rotateAng)*Math.PI/2,
              (this.index[2]*rotateAng)*Math.PI/2);
            return Transform.multiply(this.rotation, rotTrans);
          }.bind(this)
        });

        this.node = this.add(rotateModifier);
    }

    function _setBackgroundListeners () {
        this.parentCubeSync = new MouseSync();

        this.backgroundSurface.pipe(this.parentCubeSync);

        this.parentCubeSync.on('update', function (data) {
            this.position[0] += data.delta[0];
            this.position[1] += data.delta[1];
        }.bind(this));

        this.parentCubeSync.on('end', function () {
            if (Math.abs(this.position[0]) > Math.abs(this.position[1])){
                this.left = this.position[0] > 0 ? -1 : 1;
            } else{
                this.down = this.position[1] > 0 ? 1 : -1;
            }

            updateStateTransition.call(this,this.left,this.down);

            this.transitionable.set(1, {
                duration: 500, curve: Easing.outBack
            });
            // console.log('left: ', this.left);
            // console.log('down: ', this.down);
            // console.log('state: ', this.state);
            // console.log('nVec: ', this.nVec);
            // console.log('rVec', this.rVec);
        }.bind(this));
    }

    function _setListeners() {
        this.gameBoard.pipe(this._eventInput);
        this.gameBoard.subscribe(this._eventOutput);

        this._eventInput.on('movingCubeToRL', function(data){
          // console.log('from BG to RC', data);
          this._eventOutput.emit('movingCubeToGL', data);
        }.bind(this));

        this._eventInput.on('is2d', function(data){
          console.log('RL is2d', data);
          if (data){
            this.backgroundSurface.unpipe(this.parentCubeSync);
            this.backgroundSurface.setProperties({pointerEvents: 'none'});
          } else{
            this.backgroundSurface.pipe(this.parentCubeSync);
            this.backgroundSurface.setProperties({pointerEvents: 'auto'});
          }
          this._eventOutput.emit('is2d', data);
        }.bind(this));
    }

    function updateStateTransition(left, down){
      // console.log('test', this.nVec);
      if(this.state[2] === 1){ //[0,0,1]
        var tempState = this.state;
        if (this.nVec[1] !== 0){ //[0,1,0] or [0,-1,0]
          if (down !== 0){
            this.index = [down*this.nVec[1], 0, 0];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [-left*this.nVec[1],0,0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }else{ //this.nVec = [1,0,0] or [-1,0,0]
          if (down !== 0){
            this.index = [0, -down*this.nVec[0], 0];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0, left*this.nVec[0],0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }
      }else if(this.state[2] === -1){ //[0,0,-1]
        var tempState = this.state;
        if (this.nVec[1] !== 0){ //[0,1,0] or [0,-1,0]
          if (down !== 0){
            this.index = [-down*this.nVec[1], 0, 0];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [left*this.nVec[1],0,0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }else{
          if (down !== 0){ //[1,0,0] or [-1,0,0]
            this.index = [0, down*this.nVec[0], 0];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0, -left*this.nVec[0],0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }
      }else if(this.state[1] === 1){//[0,1,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [-down*this.nVec[2], 0, 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [left*this.nVec[2],0,0];
            this.rVec = [0,-left*tempState[1],0];
          }
        }else{
          if (down !== 0){ //[1,0,0] or [-1,0,0]
            this.index = [0, 0, down*this.nVec[0]];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0,0,-left*this.nVec[0]];
            this.rVec = [0,-left*tempState[1],0];
          }
        }
      }else if(this.state[1] === -1){ //[0,-1,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [down*this.nVec[2], 0, 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [-left*this.nVec[2],0,0];
            this.rVec = [0,-left*tempState[1],0];
          }
        }else{
          if (down !== 0){ //[1,0,0] or [-1,0,0]
            this.index = [0, 0, -down*this.nVec[0]];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0,0,left*this.nVec[0]];
            this.rVec = [0,-left*tempState[1],0];
          }
        }
      }else if(this.state[0] === 1){ //[1,0,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [0, down*this.nVec[2], 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [0,-left*this.nVec[2],0];
            this.rVec = [-left*tempState[0],0,0];
          }
        }else{
          if (down !== 0){ //[0,1,0] or [0,-1,0]
            this.index = [0, 0, -down*this.nVec[1]];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [0,0,left*this.nVec[1]];
            this.rVec = [-left*tempState[0],0,0];
          }
        }
      }else{ //[-1,0,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [0, -down*this.nVec[2], 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [0,left*this.nVec[2],0];
            this.rVec = [-left*tempState[0],0,0];
          }
        }else{
          if (down !== 0){ //[0,1,0] or [0,-1,0]
            this.index = [0, 0, down*this.nVec[1]];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [0,0, -left*this.nVec[1]];
            this.rVec = [-left*tempState[0],0,0];
          }
        }
      }
    }

    function mapStateTransition(state, nVec){
      var rotationMap = {
        '1,0,0':  {'rotate': [0,-1,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [2,0,0],
                   '0,0,1':  [1,0,0],
                   '0,0,-1': [-1,0,0]},
        '-1,0,0': {'rotate': [0,1,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [2,0,0],
                   '0,0,1':  [1,0,0],
                   '0,0,-1': [-1,0,0]},
        '0,-1,0': {'rotate': [-1,0,0],
                   '0,0,-1': [0,0,0],
                   '0,0,1':  [0,2,0],
                   '1,0,0':  [0,1,0],
                   '-1,0,0': [0,-1,0]},
        '0,1,0':  {'rotate': [1,0,0],
                   '0,0,1': [0,0,0],
                   '0,0,-1':  [0,2,0],
                   '1,0,0':  [0,-1,0],
                   '-1,0,0': [0,1,0]},
        '0,0,-1': {'rotate': [0,2,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [0,0,2],
                   '1,0,0':  [0,0,-1],
                   '-1,0,0': [0,0,1]},
        '0,0,1':  {'rotate': [0,0,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [0,0,2],
                   '1,0,0':  [0,0,-1],
                   '-1,0,0': [0,0,1]}
      };

      var first = rotationMap[state]['rotate'];
      var second =  rotationMap[state][nVec];

      var trans = Transform.multiply(Transform.rotate(first[0]*Math.PI/2,first[1]*Math.PI/2,first[2]*Math.PI/2),
        Transform.rotate(second[0]*Math.PI/2,second[1]*Math.PI/2,second[2]*Math.PI/2));

      return trans;
    }

    module.exports = RotatingLogic;
});
<commit_msg>Parent Cube only rotates with mouse movement delta > 5px<commit_after>define(function(require, exports, module) {
    var View           = require('famous/core/View');
    var Surface        = require('famous/core/Surface');
    var Transform      = require('famous/core/Transform');
    var Modifier       = require('famous/core/Modifier');
    var StateModifier  = require('famous/modifiers/StateModifier');
    var MouseSync      = require('famous/inputs/MouseSync');
    var Transitionable = require('famous/transitions/Transitionable');
    var Easing         = require('famous/transitions/Easing');
    var GameBoard = require('views/GameBoard');

    function RotatingLogic() {
        View.apply(this, arguments);

        this.position = [0, 0]; //mouse movement
        this.state = [0,0,1]; //current front face
        this.nVec = [0,-1,0]; //current top face
        this.rVec = [1,0,0]; //current right face
        this.index = [0,0,0]; //90 degree turn unit
        this.left = 0; //rotate left
        this.down = 0; //rotate down
        this.rotation = Transform.rotate(0,0,0); //initial transfrom matrix

        this.transitionable = new Transitionable(0);

        _createRotateModifier.call(this);
        _createBackground.call(this);
        _setBackgroundListeners.call(this);
        _createGameBoard.call(this);
        _setListeners.call(this);
    }

    RotatingLogic.prototype = Object.create(View.prototype);
    RotatingLogic.prototype.constructor = RotatingLogic;

    RotatingLogic.prototype.setDestroyerPosition = function(pos){
      this.gameBoard.setDestroyerPosition(pos);
    }

    RotatingLogic.DEFAULT_OPTIONS = {
      mainCubeSize: 400,
      destroyer: undefined,
      smallCube: undefined
    };

    function _createGameBoard() {
      this.gameBoard = new GameBoard({
        mainCubeSize: this.options.mainCubeSize,
        destroyer: this.options.destroyer,
        smallCube: this.options.smallCube
      });
      this.node.add(this.gameBoard);
    }

    function _createBackground () {
        this.backgroundSurface = new Surface({
            size: [undefined, undefined]
        });

        this.add(this.backgroundSurface);
    }

    function _createRotateModifier () {
        var self = this;

        var rotateModifier = new Modifier({
          transform: function () {
            var rotateAng = this.transitionable.get();
            if (rotateAng  > 0.99999){
              this.rotation = mapStateTransition(this.state, this.nVec);
              this.index = [0,0,0];
              this.position = [0,0];
              this.left = 0;
              this.down = 0;
              this.transitionable.reset(0);
              this.transitionable.halt();

              var updateObj = {
                nVec: this.nVec,
                rVec: this.rVec
              };
              this._eventOutput.emit('coordinateUpdate', updateObj);
            }

            var rotTrans = Transform.rotate((this.index[0]*rotateAng)*Math.PI/2,
              (this.index[1]*rotateAng)*Math.PI/2,
              (this.index[2]*rotateAng)*Math.PI/2);
            return Transform.multiply(this.rotation, rotTrans);
          }.bind(this)
        });

        this.node = this.add(rotateModifier);
    }

    function _setBackgroundListeners () {
        this.parentCubeSync = new MouseSync();

        this.backgroundSurface.pipe(this.parentCubeSync);

        this.parentCubeSync.on('update', function (data) {
            this.position[0] += data.delta[0];
            this.position[1] += data.delta[1];
        }.bind(this));

        this.parentCubeSync.on('end', function () {
            if (Math.abs(this.position[0]) < 5 && Math.abs(this.position[1]) < 5) {
              this.position = [0, 0];
              return false;
            }
            if (Math.abs(this.position[0]) > Math.abs(this.position[1])){
                this.left = this.position[0] > 0 ? -1 : 1;
            } else{
                this.down = this.position[1] > 0 ? 1 : -1;
            }

            updateStateTransition.call(this,this.left,this.down);

            this.transitionable.set(1, {
                duration: 500, curve: Easing.outBack
            });
            // console.log('left: ', this.left);
            // console.log('down: ', this.down);
            // console.log('state: ', this.state);
            // console.log('nVec: ', this.nVec);
            // console.log('rVec', this.rVec);
        }.bind(this));
    }

    function _setListeners() {
        this.gameBoard.pipe(this._eventInput);
        this.gameBoard.subscribe(this._eventOutput);

        this._eventInput.on('movingCubeToRL', function(data){
          // console.log('from BG to RC', data);
          this._eventOutput.emit('movingCubeToGL', data);
        }.bind(this));

        this._eventInput.on('is2d', function(data){
          console.log('RL is2d', data);
          if (data){
            this.backgroundSurface.unpipe(this.parentCubeSync);
            this.backgroundSurface.setProperties({pointerEvents: 'none'});
          } else{
            this.backgroundSurface.pipe(this.parentCubeSync);
            this.backgroundSurface.setProperties({pointerEvents: 'auto'});
          }
          this._eventOutput.emit('is2d', data);
        }.bind(this));
    }

    function updateStateTransition(left, down){
      // console.log('test', this.nVec);
      if(this.state[2] === 1){ //[0,0,1]
        var tempState = this.state;
        if (this.nVec[1] !== 0){ //[0,1,0] or [0,-1,0]
          if (down !== 0){
            this.index = [down*this.nVec[1], 0, 0];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [-left*this.nVec[1],0,0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }else{ //this.nVec = [1,0,0] or [-1,0,0]
          if (down !== 0){
            this.index = [0, -down*this.nVec[0], 0];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0, left*this.nVec[0],0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }
      }else if(this.state[2] === -1){ //[0,0,-1]
        var tempState = this.state;
        if (this.nVec[1] !== 0){ //[0,1,0] or [0,-1,0]
          if (down !== 0){
            this.index = [-down*this.nVec[1], 0, 0];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [left*this.nVec[1],0,0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }else{
          if (down !== 0){ //[1,0,0] or [-1,0,0]
            this.index = [0, down*this.nVec[0], 0];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,0,-down*tempState[2]];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0, -left*this.nVec[0],0];
            this.rVec = [0,0,-left*tempState[2]];
          }
        }
      }else if(this.state[1] === 1){//[0,1,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [-down*this.nVec[2], 0, 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [left*this.nVec[2],0,0];
            this.rVec = [0,-left*tempState[1],0];
          }
        }else{
          if (down !== 0){ //[1,0,0] or [-1,0,0]
            this.index = [0, 0, down*this.nVec[0]];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0,0,-left*this.nVec[0]];
            this.rVec = [0,-left*tempState[1],0];
          }
        }
      }else if(this.state[1] === -1){ //[0,-1,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [down*this.nVec[2], 0, 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [-left*this.nVec[2],0,0];
            this.rVec = [0,-left*tempState[1],0];
          }
        }else{
          if (down !== 0){ //[1,0,0] or [-1,0,0]
            this.index = [0, 0, -down*this.nVec[0]];
            this.state = [down*this.nVec[0],0,0];
            this.nVec = [0,-down*tempState[1],0];
          }else{
            this.index = [left*this.nVec[0], 0, 0];
            this.state = [0,0,left*this.nVec[0]];
            this.rVec = [0,-left*tempState[1],0];
          }
        }
      }else if(this.state[0] === 1){ //[1,0,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [0, down*this.nVec[2], 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [0,-left*this.nVec[2],0];
            this.rVec = [-left*tempState[0],0,0];
          }
        }else{
          if (down !== 0){ //[0,1,0] or [0,-1,0]
            this.index = [0, 0, -down*this.nVec[1]];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [0,0,left*this.nVec[1]];
            this.rVec = [-left*tempState[0],0,0];
          }
        }
      }else{ //[-1,0,0]
        var tempState = this.state;
        if (this.nVec[2] !== 0){ //[0,0,1] or [0,0,-1]
          if (down !== 0){
            this.index = [0, -down*this.nVec[2], 0];
            this.state = [0,0,down*this.nVec[2]];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, 0, left*this.nVec[2]];
            this.state = [0,left*this.nVec[2],0];
            this.rVec = [-left*tempState[0],0,0];
          }
        }else{
          if (down !== 0){ //[0,1,0] or [0,-1,0]
            this.index = [0, 0, down*this.nVec[1]];
            this.state = [0,down*this.nVec[1],0];
            this.nVec = [-down*tempState[0],0,0];
          }else{
            this.index = [0, left*this.nVec[1], 0];
            this.state = [0,0, -left*this.nVec[1]];
            this.rVec = [-left*tempState[0],0,0];
          }
        }
      }
    }

    function mapStateTransition(state, nVec){
      var rotationMap = {
        '1,0,0':  {'rotate': [0,-1,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [2,0,0],
                   '0,0,1':  [1,0,0],
                   '0,0,-1': [-1,0,0]},
        '-1,0,0': {'rotate': [0,1,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [2,0,0],
                   '0,0,1':  [1,0,0],
                   '0,0,-1': [-1,0,0]},
        '0,-1,0': {'rotate': [-1,0,0],
                   '0,0,-1': [0,0,0],
                   '0,0,1':  [0,2,0],
                   '1,0,0':  [0,1,0],
                   '-1,0,0': [0,-1,0]},
        '0,1,0':  {'rotate': [1,0,0],
                   '0,0,1': [0,0,0],
                   '0,0,-1':  [0,2,0],
                   '1,0,0':  [0,-1,0],
                   '-1,0,0': [0,1,0]},
        '0,0,-1': {'rotate': [0,2,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [0,0,2],
                   '1,0,0':  [0,0,-1],
                   '-1,0,0': [0,0,1]},
        '0,0,1':  {'rotate': [0,0,0],
                   '0,-1,0': [0,0,0],
                   '0,1,0':  [0,0,2],
                   '1,0,0':  [0,0,-1],
                   '-1,0,0': [0,0,1]}
      };

      var first = rotationMap[state]['rotate'];
      var second =  rotationMap[state][nVec];

      var trans = Transform.multiply(Transform.rotate(first[0]*Math.PI/2,first[1]*Math.PI/2,first[2]*Math.PI/2),
        Transform.rotate(second[0]*Math.PI/2,second[1]*Math.PI/2,second[2]*Math.PI/2));

      return trans;
    }

    module.exports = RotatingLogic;
});
<|endoftext|>


<commit_before>
var sbOutputService = {

	depth : 0,
	content : "",
	isAuto : false,
	optionAll   : true,
	optionFrame : false,

	/**
	 * window.arguments[0]: true means is auto mode
	 */
	init : function()
	{
		if (window.arguments && window.arguments[0]) this.isAuto = true;
		document.documentElement.getButton("accept").label = sbCommonUtils.lang("scrapbook", "START_BUTTON");
		sbTreeHandler.init(true);
		this.selectAllFolders();
		if ( this.isAuto )
		{
			document.getElementById("ScrapBookOutputOptionO").checked = false;
			this.start();
		}
	},

	selectAllFolders : function()
	{
		if ( document.getElementById('ScrapBookOutputOptionA').checked )
		{
			sbTreeHandler.toggleAllFolders(true);
			sbTreeHandler.TREE.view.selection.selectAll();
			sbTreeHandler.TREE.treeBoxObject.focused = true;
		}
		this.optionAll = true;
	},

	toggleAllSelection : function()
	{
		if ( this.optionAll )
		{
			document.getElementById("ScrapBookOutputOptionA").checked = false;
			this.optionAll = false;
		}
	},

	start : function()
	{
		this.optionFrame = document.getElementById("ScrapBookOutputOptionF").checked;
		this.optionAll ? this.execAll() : this.exec();
		sbTreeHandler.toggleAllFolders(true);
		if ( this.isAuto ) setTimeout(function(){ window.close(); }, 1000);
	},

	execAll : function()
	{
		this.content = this.getHTMLHead();
		this.processRescursively(sbTreeHandler.TREE.resource);
		this.finalize();
	},

	exec : function()
	{
		this.content = this.getHTMLHead();
		var selResList = sbTreeHandler.getSelection(true, 1);
		this.content += "
\n";
		for ( var i = 0; i < selResList.length; i++ )
		{
			this.content += '
';
			this.content += this.getHTMLBody(selResList[i]);
			this.processRescursively(selResList[i]);
			this.content += "
\n";
		}
		this.content += "
\n";
		this.finalize();
	},

	finalize : function()
	{
		var dir = sbCommonUtils.getScrapBookDir().clone();
		dir.append("tree");
		if ( !dir.exists() ) dir.create(dir.DIRECTORY_TYPE, 0700);
		var urlHash = {
			"chrome://scrapbook/skin/output.css"     : "output.css",
			"chrome://scrapbook/skin/treeitem.png"   : "treeitem.png",
			"chrome://scrapbook/skin/treenote.png"   : "treenote.png",
			"chrome://scrapbook/skin/treenotex.png"  : "treenotex.png",
			"chrome://scrapbook/skin/treefolder.png" : "folder.png",
			"chrome://scrapbook/skin/toolbar_toggle.png" : "toggle.png",
		};
		for ( var url in urlHash )
		{
			var destFile = dir.clone();
			destFile.append(urlHash[url]);
			sbCommonUtils.saveTemplateFile(url, destFile);
		}
		var frameFile = dir.clone();
		frameFile.append("frame.html");
		if ( !frameFile.exists() ) frameFile.create(frameFile.NORMAL_FILE_TYPE, 0666);
		sbCommonUtils.writeFile(frameFile, this.getHTMLFrame(), "UTF-8");
		var indexFile = dir.clone();
		indexFile.append("index.html");
		if ( !indexFile.exists() ) indexFile.create(indexFile.NORMAL_FILE_TYPE, 0666);
		this.content += this.getHTMLFoot();
		sbCommonUtils.writeFile(indexFile, this.content, "UTF-8");
		var fileName = this.optionFrame ? "frame.html" : "index.html";
		if ( document.getElementById("ScrapBookOutputOptionO").checked )
		{
			sbCommonUtils.loadURL(sbCommonUtils.convertFilePathToURL(dir.path) + fileName, true);
		}
	},

	processRescursively : function(aContRes)
	{
		this.depth++;
		var id = sbDataSource.getProperty(aContRes, "id") || "root";
		this.content += '
\n';
		var resList = sbDataSource.flattenResources(aContRes, 0, false);
		for (var i = 1; i < resList.length; i++) {
			this.content += '
';
			this.content += this.getHTMLBody(resList[i]);
			if (sbDataSource.isContainer(resList[i]))
				this.processRescursively(resList[i]);
			this.content += "
\n";
		}
		this.content += "
\n";
		this.depth--;
	},

	getHTMLHead : function()
	{
		var HTML = '<!DOCTYPE html>\n'
			+ '\n\n'
			+ '\n'
			+ '	<meta charset="UTF-8">\n'
			+ '	<title>' + document.title + '</title>\n'
			+ '	<meta name="viewport" content="width=device-width">\n'
			+ '	<link rel="stylesheet" type="text/css" href="output.css" media="all">\n'
			+ '	\n'
			+ '\n\n'
			+ '\n'
			+ '
ScrapBook
\n'
		return HTML;
	},

	getHTMLBody : function(aRes)
	{
		var id    = sbDataSource.getProperty(aRes, "id");
		var type  = sbDataSource.getProperty(aRes, "type");
		var icon  = sbDataSource.getProperty(aRes, "icon");
		var title = sbDataSource.getProperty(aRes, "title");
		var source = sbDataSource.getProperty(aRes, "source");
		if ( icon.match(/(\/data\/\d{14}\/.*$)/) ) icon = ".." + RegExp.$1;
		if ( !icon ) icon = sbCommonUtils.escapeFileName(sbCommonUtils.getFileName( sbCommonUtils.getDefaultIcon(type) ));
		icon = sbCommonUtils.escapeHTML(icon);
		title = sbCommonUtils.escapeHTML(title);
		source = sbCommonUtils.escapeHTML(source);
		var ret;
		switch (type) {
			case "separator":
				ret = '' + title + ' ----------------------------------------' + '';
				break;
			case "folder":
				ret = ''
				    + '' + title + '\n';
				break;
			case "bookmark":
				ret = ''
				    + '' + title + '';
				break;
			default:
				var href = sbCommonUtils.escapeHTML("../data/" + id + "/index.html");
				var target = this.optionFrame ? ' target="main"' : "";
				ret = ''
				    + '' + title + '';
				if (!source) break;
				ret += ' ➤';
				break;
		}
		return ret;
	},

	getHTMLFoot : function()
	{
		var HTML = "\n\n\n";
		return HTML;
	},

	getHTMLFrame : function()
	{
		var HTML = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">\n'
			+ '\n'
			+ '\n'
			+ '	<meta charset="UTF-8">\n'
			+ '	<title>' + document.title + '</title>\n'
			+ '\n'
			+ '<frameset cols="200,*">\n'
			+ '	<frame name="side" src="index.html">\n'
			+ '	<frame name="main">\n'
			+ '</frameset>\n'
			+ '\n';
		return HTML;
	},

};

<commit_msg>Remove the window close delay in auto mode.<commit_after>
var sbOutputService = {

	depth : 0,
	content : "",
	isAuto : false,
	optionAll   : true,
	optionFrame : false,

	/**
	 * window.arguments[0]: true means is auto mode
	 */
	init : function()
	{
		if (window.arguments && window.arguments[0]) this.isAuto = true;
		document.documentElement.getButton("accept").label = sbCommonUtils.lang("scrapbook", "START_BUTTON");
		sbTreeHandler.init(true);
		this.selectAllFolders();
		if ( this.isAuto )
		{
			document.getElementById("ScrapBookOutputOptionO").checked = false;
			this.start();
		}
	},

	selectAllFolders : function()
	{
		if ( document.getElementById('ScrapBookOutputOptionA').checked )
		{
			sbTreeHandler.toggleAllFolders(true);
			sbTreeHandler.TREE.view.selection.selectAll();
			sbTreeHandler.TREE.treeBoxObject.focused = true;
		}
		this.optionAll = true;
	},

	toggleAllSelection : function()
	{
		if ( this.optionAll )
		{
			document.getElementById("ScrapBookOutputOptionA").checked = false;
			this.optionAll = false;
		}
	},

	start : function()
	{
		this.optionFrame = document.getElementById("ScrapBookOutputOptionF").checked;
		this.optionAll ? this.execAll() : this.exec();
		sbTreeHandler.toggleAllFolders(true);
		if ( this.isAuto ) window.close();
	},

	execAll : function()
	{
		this.content = this.getHTMLHead();
		this.processRescursively(sbTreeHandler.TREE.resource);
		this.finalize();
	},

	exec : function()
	{
		this.content = this.getHTMLHead();
		var selResList = sbTreeHandler.getSelection(true, 1);
		this.content += "
\n";
		for ( var i = 0; i < selResList.length; i++ )
		{
			this.content += '
';
			this.content += this.getHTMLBody(selResList[i]);
			this.processRescursively(selResList[i]);
			this.content += "
\n";
		}
		this.content += "
\n";
		this.finalize();
	},

	finalize : function()
	{
		var dir = sbCommonUtils.getScrapBookDir().clone();
		dir.append("tree");
		if ( !dir.exists() ) dir.create(dir.DIRECTORY_TYPE, 0700);
		var urlHash = {
			"chrome://scrapbook/skin/output.css"     : "output.css",
			"chrome://scrapbook/skin/treeitem.png"   : "treeitem.png",
			"chrome://scrapbook/skin/treenote.png"   : "treenote.png",
			"chrome://scrapbook/skin/treenotex.png"  : "treenotex.png",
			"chrome://scrapbook/skin/treefolder.png" : "folder.png",
			"chrome://scrapbook/skin/toolbar_toggle.png" : "toggle.png",
		};
		for ( var url in urlHash )
		{
			var destFile = dir.clone();
			destFile.append(urlHash[url]);
			sbCommonUtils.saveTemplateFile(url, destFile);
		}
		var frameFile = dir.clone();
		frameFile.append("frame.html");
		if ( !frameFile.exists() ) frameFile.create(frameFile.NORMAL_FILE_TYPE, 0666);
		sbCommonUtils.writeFile(frameFile, this.getHTMLFrame(), "UTF-8");
		var indexFile = dir.clone();
		indexFile.append("index.html");
		if ( !indexFile.exists() ) indexFile.create(indexFile.NORMAL_FILE_TYPE, 0666);
		this.content += this.getHTMLFoot();
		sbCommonUtils.writeFile(indexFile, this.content, "UTF-8");
		var fileName = this.optionFrame ? "frame.html" : "index.html";
		if ( document.getElementById("ScrapBookOutputOptionO").checked )
		{
			sbCommonUtils.loadURL(sbCommonUtils.convertFilePathToURL(dir.path) + fileName, true);
		}
	},

	processRescursively : function(aContRes)
	{
		this.depth++;
		var id = sbDataSource.getProperty(aContRes, "id") || "root";
		this.content += '
\n';
		var resList = sbDataSource.flattenResources(aContRes, 0, false);
		for (var i = 1; i < resList.length; i++) {
			this.content += '
';
			this.content += this.getHTMLBody(resList[i]);
			if (sbDataSource.isContainer(resList[i]))
				this.processRescursively(resList[i]);
			this.content += "
\n";
		}
		this.content += "
\n";
		this.depth--;
	},

	getHTMLHead : function()
	{
		var HTML = '<!DOCTYPE html>\n'
			+ '\n\n'
			+ '\n'
			+ '	<meta charset="UTF-8">\n'
			+ '	<title>' + document.title + '</title>\n'
			+ '	<meta name="viewport" content="width=device-width">\n'
			+ '	<link rel="stylesheet" type="text/css" href="output.css" media="all">\n'
			+ '	\n'
			+ '\n\n'
			+ '\n'
			+ '
ScrapBook
\n'
		return HTML;
	},

	getHTMLBody : function(aRes)
	{
		var id    = sbDataSource.getProperty(aRes, "id");
		var type  = sbDataSource.getProperty(aRes, "type");
		var icon  = sbDataSource.getProperty(aRes, "icon");
		var title = sbDataSource.getProperty(aRes, "title");
		var source = sbDataSource.getProperty(aRes, "source");
		if ( icon.match(/(\/data\/\d{14}\/.*$)/) ) icon = ".." + RegExp.$1;
		if ( !icon ) icon = sbCommonUtils.escapeFileName(sbCommonUtils.getFileName( sbCommonUtils.getDefaultIcon(type) ));
		icon = sbCommonUtils.escapeHTML(icon);
		title = sbCommonUtils.escapeHTML(title);
		source = sbCommonUtils.escapeHTML(source);
		var ret;
		switch (type) {
			case "separator":
				ret = '' + title + ' ----------------------------------------' + '';
				break;
			case "folder":
				ret = ''
				    + '' + title + '\n';
				break;
			case "bookmark":
				ret = ''
				    + '' + title + '';
				break;
			default:
				var href = sbCommonUtils.escapeHTML("../data/" + id + "/index.html");
				var target = this.optionFrame ? ' target="main"' : "";
				ret = ''
				    + '' + title + '';
				if (!source) break;
				ret += ' ➤';
				break;
		}
		return ret;
	},

	getHTMLFoot : function()
	{
		var HTML = "\n\n\n";
		return HTML;
	},

	getHTMLFrame : function()
	{
		var HTML = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">\n'
			+ '\n'
			+ '\n'
			+ '	<meta charset="UTF-8">\n'
			+ '	<title>' + document.title + '</title>\n'
			+ '\n'
			+ '<frameset cols="200,*">\n'
			+ '	<frame name="side" src="index.html">\n'
			+ '	<frame name="main">\n'
			+ '</frameset>\n'
			+ '\n';
		return HTML;
	},

};

<|endoftext|>


<commit_before>$.widget( "kalamu.kalamuDashboardWidget", {

    options: {
        explorer: null,
        context: null,
        type: null,
        identifier: null,
        params: null
    },
    _create: function() {
        this.element.addClass('kalamu-dashboard-widget col-md-12');
        this.refresh();
    },

    refresh: function(){
        this.options.params.push({name: 'parent_md_size', value: this.element.parents('.kalamu-dashboard-col').kalamuDashboardCol('option', 'md')});

        this.element.text('');
        editLink = $(' Modifier');
        delete_link = $(' supprimer le widget');

        this.element.prepend( $('
').append(editLink).append(delete_link) );

        this._on( editLink, { click: this.edit });
        this._on( delete_link, { click: this._delete });

        element_api = this.options.explorer.kalamuElementExplorer('option', 'element_api');

        $.ajax({
            url: element_api+this.options.context+'/'+this.options.type+'/'+this.options.identifier,
            data: this.options.params,
            method: 'GET',
            dataType: 'json',
            context: this,
            success: function(datas){
                if(datas.content){
                    this.element.append(datas.content);
                }else if(datas.error){
                    this.element.append('
'+datas.error+'
');
                }
            },
            error: function(){
                this.element.append('
'+Translator.trans('unknown.error', {}, 'kalamu')+'
');
            }
        });
    },

    export: function(){
        return {
            type: this.options.type,
            identifier: this.options.identifier,
            params: this.options.params
        };
    },

    edit: function(e){
        e.preventDefault();

        this.element.parents('.kalamu-dashboard-col').kalamuDashboardCol('editElement', this);
    },

    _delete: function(e){
        e.preventDefault();

        dashboard = this.options.explorer.kalamuElementExplorer('option', 'dashboard').element;
        this.element.remove();
        dashboard.trigger('kalamu.dashboard.widget_added');
    }

});<commit_msg>fix widget rendering if inner content is not inside a col-*<commit_after>$.widget( "kalamu.kalamuDashboardWidget", {

    options: {
        explorer: null,
        context: null,
        type: null,
        identifier: null,
        params: null
    },
    _create: function() {
        this.element.addClass('kalamu-dashboard-widget col-md-12');
        this.refresh();
    },

    refresh: function(){
        this.options.params.push({name: 'parent_md_size', value: this.element.parents('.kalamu-dashboard-col').kalamuDashboardCol('option', 'md')});

        this.element.text('');
        editLink = $(' Modifier');
        delete_link = $(' supprimer le widget');

        this.element.prepend( $('
').append(editLink).append(delete_link) );

        this._on( editLink, { click: this.edit });
        this._on( delete_link, { click: this._delete });

        element_api = this.options.explorer.kalamuElementExplorer('option', 'element_api');

        $.ajax({
            url: element_api+this.options.context+'/'+this.options.type+'/'+this.options.identifier,
            data: this.options.params,
            method: 'GET',
            dataType: 'json',
            context: this,
            success: function(datas){
                if(datas.content){
                    this.element.append( $('
').append(datas.content) );
                }else if(datas.error){
                    this.element.append('
'+datas.error+'
');
                }
            },
            error: function(){
                this.element.append('
'+Translator.trans('unknown.error', {}, 'kalamu')+'
');
            }
        });
    },

    export: function(){
        return {
            type: this.options.type,
            identifier: this.options.identifier,
            params: this.options.params
        };
    },

    edit: function(e){
        e.preventDefault();

        this.element.parents('.kalamu-dashboard-col').kalamuDashboardCol('editElement', this);
    },

    _delete: function(e){
        e.preventDefault();

        dashboard = this.options.explorer.kalamuElementExplorer('option', 'dashboard').element;
        this.element.remove();
        dashboard.trigger('kalamu.dashboard.widget_added');
    }

});<|endoftext|>


<commit_before>"use strict";

Components.utils.import("resource://gre/modules/Services.jsm");

var RspamdSpamness = {
    customHeaders: new Array(),
    customDBHeaders: new Array(),
    previousSpamnessHeader: "",
    trainingButtonDefaultAction: "move"
};

RspamdSpamness.getImageSrc = function(normalized) {
    var img, level;
    if (isNaN(normalized)) {
        img = "chrome://messenger/skin/icons/symbol-null.png";
    } else if (normalized < 0) {
        level = Math.round(Math.log(Math.abs(normalized) + 1));
        level = (level >= 5) ? 4 : level;
        img = "chrome://rspamd-spamness/skin/ham" + level + ".png";
    } else {
        level = Math.round(Math.log(normalized + 1));
        level = (level >= 5) ? 4 : level;
        img = "chrome://rspamd-spamness/skin/spam" + level + ".png";
    }
    return img;
};

RspamdSpamness.getMetricClass = function (rule) {
    if (rule.match(/^GREYLIST\(/))
        return "linkDisplayButtonGreyl";

    var metric = rule.match(/\(([-\d.]+)\)$/);
    var metricScore = (metric)
        ? metric[1]
        : null;
    if (metricScore < 0) {
        return "linkDisplayButtonHam";
    } else if (metricScore > 0) {
        return "linkDisplayButtonSpam";
    } else {
        return null;
    }
};

RspamdSpamness.getHeaderStr = function(hdr) {
    var header = Services.prefs.getCharPref("extensions.rspamd-spamness.header").toLowerCase();
    var headerStr = hdr.getStringProperty(header);
    return (headerStr) ? headerStr : null;
};

RspamdSpamness.syncHeaderPrefs = function(prefVal) {
    if (!prefVal) {
        prefVal = document.getElementById("headerNameForm").value;
    }
    var prefEl = document.getElementById("headerNameForm");
    const prefs = Services.prefs;
    RspamdSpamness.previousSpamnessHeader = prefs.getCharPref("extensions.rspamd-spamness.header").toLowerCase();

    RspamdSpamness.customDBHeaders = getHeadersPref("mailnews.customDBHeaders", /\s+/);
    RspamdSpamness.customHeaders   = getHeadersPref("mailnews.customHeaders", /\s*:\s*/);

    if (prefVal !== RspamdSpamness.previousSpamnessHeader) {
        if (!isRFC5322HeaderName(prefVal)) {
            var bundle = document.getElementById("bundle_custom");
            var alertText = bundle.getString("colonInHeaderName");
            window.alert(alertText);
            if (prefEl) prefEl.focus();
            return false;
        }

        var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
        if (RspamdSpamness.customHeaders.length + 1 >= (nsMsgSearchAttrib.kNumMsgSearchAttributes - nsMsgSearchAttrib.OtherHeader - 1)) {
            var bundle = document.getElementById("bundle_custom");
            var alertText = bundle.getString("customHeaderOverflow");
            window.alert(alertText);
            if (prefEl) prefEl.focus();
            return false;
        }
    }

    setHeadersPref("mailnews.customDBHeaders", RspamdSpamness.customDBHeaders, " ",
        RspamdSpamness.previousSpamnessHeader, prefVal);
    setHeadersPref("mailnews.customHeaders",   RspamdSpamness.customHeaders,   ": ",
        RspamdSpamness.previousSpamnessHeader, [prefVal, "x-spam-score"]);

    prefs.setCharPref("extensions.rspamd-spamness.header", prefVal);
    RspamdSpamness.previousSpamnessHeader = prefVal;

    // flush to disk
    prefs.savePrefFile(null);
    return true;

    function getHeadersPref(prefName, separator) {
        var chdrs = prefs.getCharPref(prefName).trim();
        return (chdrs === "")
            ? []
            : chdrs.split(separator);
    }

    function isRFC5322HeaderName(str) {
        return /^[\x21-\x39\x3B-\x7E]+$/.test(str);
    }

    function setHeadersPref(prefName, arr, separator, rmvHeaders, addHeaders) {
        let modified;
        if (typeof rmvHeaders === "string")
            rmvHeaders = [rmvHeaders];
        if (typeof addHeaders === "string")
            addHeaders = [addHeaders];

        rmvHeaders.forEach(function (hdr) {
            const i = arr.indexOf(hdr);
            if (i >= 0 && addHeaders.indexOf(hdr) === -1) {
                arr.splice(i, 1);
                modified = true;
            }
        });
        addHeaders.forEach(function (hdr) {
            if (arr.indexOf(hdr) === -1) {
                arr.push(hdr);
                modified = true;
            }
        });
        if (modified) {
            var newPref = arr.join(separator);
            prefs.setCharPref(prefName, newPref);
        }
    }
};

RspamdSpamness.log = function(msg) {
    Services.console.logStringMessage(msg);
};

RspamdSpamness.err = function(msg) {
    Services.console.logStringMessage("ERROR: " + msg);
};

RspamdSpamness.addSpamnessColumn = function() {
    // from chrome://messenger/content/folderDisplay.js
    var fdw = FolderDisplayWidget.prototype;
    fdw.DEFAULT_COLUMNS.push("spamScoreCol");
    fdw.COLUMN_DEFAULT_TESTERS["spamScoreCol"] = function(viewWrapper) {
        return viewWrapper.isIncomingFolder;
    };
};

RspamdSpamness.openTab = function(url) {
    let tabmail = document.getElementById("tabmail");
    if (!tabmail) {
        let mail3PaneWindow = Services.wm.getMostRecentWindow("mail:3pane");
        if (mail3PaneWindow) {
            tabmail = mail3PaneWindow.document.getElementById("tabmail");
            mail3PaneWindow.focus();
        }
    }

    if (tabmail)
        tabmail.openTab("contentTab", {contentPage: url});
    else
        window.openDialog("chrome://messenger/content/", "_blank",
            "chrome,dialog=no,all", null,
            { tabType: "contentTab",
                tabParams: { contentPage: url }});
};

RspamdSpamness.greet = function() {
    let greetPage = "chrome://rspamd-spamness/content/installed.xul";
    RspamdSpamness.openTab(greetPage);
};

RspamdSpamness.moveMessage = function (folder, isDefault) {
    var destination = MailUtils.getFolderForURI(Services.prefs.getCharPref("extensions.rspamd-spamness.uri.folder" + folder));
    if (isDefault && RspamdSpamness.trainingButtonDefaultAction === "copy" ||
        !isDefault && RspamdSpamness.trainingButtonDefaultAction !== "copy")
        MsgCopyMessage(destination);
    else
        MsgMoveMessage(destination);
};

RspamdSpamness.setBtnCmdLabels = function () {
    function setLabel(id, label) {
        const el = document.getElementById(id);
        if (el)
            el.setAttribute("label", label);
    }

    RspamdSpamness.trainingButtonDefaultAction = Services.prefs.getCharPref("extensions.rspamd-spamness.trainingButtons.defaultAction");

    if (RspamdSpamness.trainingButtonDefaultAction === "copy") {
        setLabel("btnHamCmdPrimary", "Copy");
        setLabel("btnSpamCmdPrimary", "Copy");
        setLabel("btnHamCmdSecondary", "Move");
        setLabel("btnSpamCmdSecondary", "Move");
    } else {
        setLabel("btnHamCmdPrimary", "Move");
        setLabel("btnSpamCmdPrimary", "Move");
        setLabel("btnHamCmdSecondary", "Copy");
        setLabel("btnSpamCmdSecondary", "Copy");
    }
};
<commit_msg>[Refactor] Remove unnecessary 'else'<commit_after>"use strict";

Components.utils.import("resource://gre/modules/Services.jsm");

var RspamdSpamness = {
    customHeaders: new Array(),
    customDBHeaders: new Array(),
    previousSpamnessHeader: "",
    trainingButtonDefaultAction: "move"
};

RspamdSpamness.getImageSrc = function(normalized) {
    var img, level;
    if (isNaN(normalized)) {
        img = "chrome://messenger/skin/icons/symbol-null.png";
    } else if (normalized < 0) {
        level = Math.round(Math.log(Math.abs(normalized) + 1));
        level = (level >= 5) ? 4 : level;
        img = "chrome://rspamd-spamness/skin/ham" + level + ".png";
    } else {
        level = Math.round(Math.log(normalized + 1));
        level = (level >= 5) ? 4 : level;
        img = "chrome://rspamd-spamness/skin/spam" + level + ".png";
    }
    return img;
};

RspamdSpamness.getMetricClass = function (rule) {
    if (rule.match(/^GREYLIST\(/))
        return "linkDisplayButtonGreyl";

    var metric = rule.match(/\(([-\d.]+)\)$/);
    var metricScore = (metric)
        ? metric[1]
        : null;
    if (metricScore < 0) {
        return "linkDisplayButtonHam";
    } else if (metricScore > 0) {
        return "linkDisplayButtonSpam";
    }
    return null;
};

RspamdSpamness.getHeaderStr = function(hdr) {
    var header = Services.prefs.getCharPref("extensions.rspamd-spamness.header").toLowerCase();
    var headerStr = hdr.getStringProperty(header);
    return (headerStr) ? headerStr : null;
};

RspamdSpamness.syncHeaderPrefs = function(prefVal) {
    if (!prefVal) {
        prefVal = document.getElementById("headerNameForm").value;
    }
    var prefEl = document.getElementById("headerNameForm");
    const prefs = Services.prefs;
    RspamdSpamness.previousSpamnessHeader = prefs.getCharPref("extensions.rspamd-spamness.header").toLowerCase();

    RspamdSpamness.customDBHeaders = getHeadersPref("mailnews.customDBHeaders", /\s+/);
    RspamdSpamness.customHeaders   = getHeadersPref("mailnews.customHeaders", /\s*:\s*/);

    if (prefVal !== RspamdSpamness.previousSpamnessHeader) {
        if (!isRFC5322HeaderName(prefVal)) {
            var bundle = document.getElementById("bundle_custom");
            var alertText = bundle.getString("colonInHeaderName");
            window.alert(alertText);
            if (prefEl) prefEl.focus();
            return false;
        }

        var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
        if (RspamdSpamness.customHeaders.length + 1 >= (nsMsgSearchAttrib.kNumMsgSearchAttributes - nsMsgSearchAttrib.OtherHeader - 1)) {
            var bundle = document.getElementById("bundle_custom");
            var alertText = bundle.getString("customHeaderOverflow");
            window.alert(alertText);
            if (prefEl) prefEl.focus();
            return false;
        }
    }

    setHeadersPref("mailnews.customDBHeaders", RspamdSpamness.customDBHeaders, " ",
        RspamdSpamness.previousSpamnessHeader, prefVal);
    setHeadersPref("mailnews.customHeaders",   RspamdSpamness.customHeaders,   ": ",
        RspamdSpamness.previousSpamnessHeader, [prefVal, "x-spam-score"]);

    prefs.setCharPref("extensions.rspamd-spamness.header", prefVal);
    RspamdSpamness.previousSpamnessHeader = prefVal;

    // flush to disk
    prefs.savePrefFile(null);
    return true;

    function getHeadersPref(prefName, separator) {
        var chdrs = prefs.getCharPref(prefName).trim();
        return (chdrs === "")
            ? []
            : chdrs.split(separator);
    }

    function isRFC5322HeaderName(str) {
        return /^[\x21-\x39\x3B-\x7E]+$/.test(str);
    }

    function setHeadersPref(prefName, arr, separator, rmvHeaders, addHeaders) {
        let modified;
        if (typeof rmvHeaders === "string")
            rmvHeaders = [rmvHeaders];
        if (typeof addHeaders === "string")
            addHeaders = [addHeaders];

        rmvHeaders.forEach(function (hdr) {
            const i = arr.indexOf(hdr);
            if (i >= 0 && addHeaders.indexOf(hdr) === -1) {
                arr.splice(i, 1);
                modified = true;
            }
        });
        addHeaders.forEach(function (hdr) {
            if (arr.indexOf(hdr) === -1) {
                arr.push(hdr);
                modified = true;
            }
        });
        if (modified) {
            var newPref = arr.join(separator);
            prefs.setCharPref(prefName, newPref);
        }
    }
};

RspamdSpamness.log = function(msg) {
    Services.console.logStringMessage(msg);
};

RspamdSpamness.err = function(msg) {
    Services.console.logStringMessage("ERROR: " + msg);
};

RspamdSpamness.addSpamnessColumn = function() {
    // from chrome://messenger/content/folderDisplay.js
    var fdw = FolderDisplayWidget.prototype;
    fdw.DEFAULT_COLUMNS.push("spamScoreCol");
    fdw.COLUMN_DEFAULT_TESTERS["spamScoreCol"] = function(viewWrapper) {
        return viewWrapper.isIncomingFolder;
    };
};

RspamdSpamness.openTab = function(url) {
    let tabmail = document.getElementById("tabmail");
    if (!tabmail) {
        let mail3PaneWindow = Services.wm.getMostRecentWindow("mail:3pane");
        if (mail3PaneWindow) {
            tabmail = mail3PaneWindow.document.getElementById("tabmail");
            mail3PaneWindow.focus();
        }
    }

    if (tabmail)
        tabmail.openTab("contentTab", {contentPage: url});
    else
        window.openDialog("chrome://messenger/content/", "_blank",
            "chrome,dialog=no,all", null,
            { tabType: "contentTab",
                tabParams: { contentPage: url }});
};

RspamdSpamness.greet = function() {
    let greetPage = "chrome://rspamd-spamness/content/installed.xul";
    RspamdSpamness.openTab(greetPage);
};

RspamdSpamness.moveMessage = function (folder, isDefault) {
    var destination = MailUtils.getFolderForURI(Services.prefs.getCharPref("extensions.rspamd-spamness.uri.folder" + folder));
    if (isDefault && RspamdSpamness.trainingButtonDefaultAction === "copy" ||
        !isDefault && RspamdSpamness.trainingButtonDefaultAction !== "copy")
        MsgCopyMessage(destination);
    else
        MsgMoveMessage(destination);
};

RspamdSpamness.setBtnCmdLabels = function () {
    function setLabel(id, label) {
        const el = document.getElementById(id);
        if (el)
            el.setAttribute("label", label);
    }

    RspamdSpamness.trainingButtonDefaultAction = Services.prefs.getCharPref("extensions.rspamd-spamness.trainingButtons.defaultAction");

    if (RspamdSpamness.trainingButtonDefaultAction === "copy") {
        setLabel("btnHamCmdPrimary", "Copy");
        setLabel("btnSpamCmdPrimary", "Copy");
        setLabel("btnHamCmdSecondary", "Move");
        setLabel("btnSpamCmdSecondary", "Move");
    } else {
        setLabel("btnHamCmdPrimary", "Move");
        setLabel("btnSpamCmdPrimary", "Move");
        setLabel("btnHamCmdSecondary", "Copy");
        setLabel("btnSpamCmdSecondary", "Copy");
    }
};
<|endoftext|>


<commit_before>//	***********************************************
//	WINE LIFE
//	CHECK-IN WINDOW  - CheckInWindow.js
//
//	MEN+1
//	Programmer:  Ivan Rodriguez & David Wells
//	***********************************************

function CheckInsWindow(title) {
	var global = require('ui/common/globals');
	// Creates the default window with global color scheme
	var self = global.createWindow(title);

	// "Search for wine" text field
	var wines = Titanium.UI.createTextField({
		backgroundColor:'#FFF',
		top:20,
		//left:20,
		width:'80%',
		height:40,
		hintText:'  Search for a wine...',
		paddingLeft:8,
		paddingRight:8,
		borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
		backgroundColor:'images/lightpaperfibers.png'

	});

	//window to put results
	// This is where I am going put all the results.
	var search_results = global.createWindow(title);

//******

	// add my search field to my
	search_results.add(wines);

	// This is the function that fires when someone hides the keyboard.
	// Maybe a button event or whatever you want.
	wines.addEventListener('blur', function(){
		// This is the search api.
		// The firsty value should be the query followed by an anonymous function
		// that will be called once the data has been retrieved. This won't be called
		// if there is a failure.
		global.api.search(wines.value, function(result){
			// get a view with the results.
			var view = global.api.search_results(result);
			// Add this view to the view in the whole page.
			search_results.add(view);
		});
	});
	// add overview to the window.
	self.add(wines);

	// NEED SOMETHING HERE *****

//*******

	// "Year" text field
	var year = Titanium.UI.createTextField({
		backgroundColor:'#FFF',
		bottom:170,
		left:20,
		width:'40%',
		height:40,
		hintText:'  Year...',
		paddingLeft:8,
		paddingRight:8,
		borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
		backgroundColor:'images/lightpaperfibers.png'

	});

	// "Style" text field
	var style = Titanium.UI.createTextField({
		backgroundColor:'#FFF',
		bottom:170,
		right:20,
		width:'40%',
		height:40,
		hintText:'  Style...',
		paddingLeft:8,
		paddingRight:8,
		borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
		backgroundColor:'images/lightpaperfibers.png'

	});

	// Creates "Look-Up" button
	var btn = Titanium.UI.createButton({
		color:'#000',
		title:"Look-Up",
		color: global.colors.dark,
		borderColor: global.colors.dark,
		borderRadius: 5,
		borderWidth: 1,
		backgroundColor: global.colors.lightest,
		backgroundImage: 'none',
		font:{fontSize:18,fontWeight:'normal',fontFamily:'Helvetica Neue'},
		top: 70,
		width:'80%',
		height:35

	});

	// Creates "Browse" button
	var btn2 = Titanium.UI.createButton({
		color:'#000',
		title:"Browse",
		color: global.colors.dark,
		borderColor: global.colors.dark,
		borderRadius: 5,
		borderWidth: 1,
		backgroundColor: global.colors.lightest,
		backgroundImage: 'none',
		font:{fontSize:18,fontWeight:'normal',fontFamily:'Helvetica Neue'},
		bottom:120,
		width:'80%',
		height:35
	});

	// Creates label for "browsing by year/style"
	var label1 = Titanium.UI.createLabel({
		color:'#000',            // Black color
		text:'Browse By Year/Style',
		font:{fontSize:18,fontFamily:'Helvetica Neue'},
		textAlign:'center',
		top: 130,
		width:'auto'
	});

	// Displays pop-up message after clicking buttons
	btn.addEventListener("click", function(e){
		alert(e.source + " RESULTS FOR SEARCH");
	});
	btn2.addEventListener("click", function(e){
		alert(e.source + " RESULTS FOR BROWSING");
	});

	self.add(wines);
	self.add(year);
	self.add(style);
	self.add(btn);
	self.add(btn2);
	self.add(label1);
	//self.open();
	global.outputHook(self);
	return self;
};

module.exports = CheckInsWindow;<commit_msg>Revert "fixed graphics around textfields on checkin page"<commit_after>//	***********************************************
//	WINE LIFE
//	CHECK-IN WINDOW  - CheckInWindow.js
//
//	MEN+1
//	Programmer:  Ivan Rodriguez & David Wells
//	***********************************************

function CheckInsWindow(title) {
	var global = require('ui/common/globals');
	// Creates the default window with global color scheme
	var self = global.createWindow(title);

	// "Search for wine" text field
	var wines = Titanium.UI.createTextField({
		backgroundColor:'#FFF',
		top:20,
		//left:20,
		width:'80%',
		height:40,
		hintText:'  Search for a wine...',
		paddingLeft:8,
		paddingRight:8,
		borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		keyboardType:Titanium.UI.KEYBOARD_DEFAULT,

	});

	//window to put results
	// This is where I am going put all the results.
	var search_results = global.createWindow(title);

//******

	// add my search field to my
	search_results.add(wines);

	// This is the function that fires when someone hides the keyboard.
	// Maybe a button event or whatever you want.
	wines.addEventListener('blur', function(){
		// This is the search api.
		// The firsty value should be the query followed by an anonymous function
		// that will be called once the data has been retrieved. This won't be called
		// if there is a failure.
		global.api.search(wines.value, function(result){
			// get a view with the results.
			var view = global.api.search_results(result);
			// Add this view to the view in the whole page.
			search_results.add(view);
		});
	});
	// add overview to the window.
	self.add(wines);

	// NEED SOMETHING HERE *****

//*******

	// "Year" text field
	var year = Titanium.UI.createTextField({
		backgroundColor:'#FFF',
		bottom:170,
		left:20,
		width:'40%',
		height:40,
		hintText:'  Year...',
		paddingLeft:8,
		paddingRight:8,
		borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		keyboardType:Titanium.UI.KEYBOARD_DEFAULT,

	});

	// "Style" text field
	var style = Titanium.UI.createTextField({
		backgroundColor:'#FFF',
		bottom:170,
		right:20,
		width:'40%',
		height:40,
		hintText:'  Style...',
		paddingLeft:8,
		paddingRight:8,
		borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
		keyboardType:Titanium.UI.KEYBOARD_DEFAULT,

	});

	// Creates "Look-Up" button
	var btn = Titanium.UI.createButton({
		color:'#000',
		title:"Look-Up",
		color: global.colors.dark,
		borderColor: global.colors.dark,
		borderRadius: 5,
		borderWidth: 1,
		backgroundColor: global.colors.lightest,
		backgroundImage: 'none',
		font:{fontSize:18,fontWeight:'normal',fontFamily:'Helvetica Neue'},
		top: 70,
		width:'80%',
		height:35

	});

	// Creates "Browse" button
	var btn2 = Titanium.UI.createButton({
		color:'#000',
		title:"Browse",
		color: global.colors.dark,
		borderColor: global.colors.dark,
		borderRadius: 5,
		borderWidth: 1,
		backgroundColor: global.colors.lightest,
		backgroundImage: 'none',
		font:{fontSize:18,fontWeight:'normal',fontFamily:'Helvetica Neue'},
		bottom:120,
		width:'80%',
		height:35
	});

	// Creates label for "browsing by year/style"
	var label1 = Titanium.UI.createLabel({
		color:'#000',            // Black color
		text:'Browse By Year/Style',
		font:{fontSize:18,fontFamily:'Helvetica Neue'},
		textAlign:'center',
		top: 130,
		width:'auto'
	});

	// Displays pop-up message after clicking buttons
	btn.addEventListener("click", function(e){
		alert(e.source + " RESULTS FOR SEARCH");
	});
	btn2.addEventListener("click", function(e){
		alert(e.source + " RESULTS FOR BROWSING");
	});

	self.add(wines);
	self.add(year);
	self.add(style);
	self.add(btn);
	self.add(btn2);
	self.add(label1);
	//self.open();
	global.outputHook(self);
	return self;
};

module.exports = CheckInsWindow;<|endoftext|>


<commit_before>(function() {
    const Order = require('./order.js');

    class OrderUpHtmlParser {
        parse(containerElement) {

            var highlight = element => {
                element.style.background = 'repeating-linear-gradient(45deg, yellow, yellow 10px, #fafa0a 10px, #fafa0a 20px )';
                element.title = 'OrderSplitter is using this value';
            };

            var untaxedFees = 0, tip, tax, people;

            var summaryTable = Array.from(containerElement.querySelectorAll('#order-confirmation-page tr'));
            if (summaryTable) {
                [people] = summaryTable.map(tr => Array.from(tr.querySelectorAll('td'))).filter(tds => tds.length).reduce(function([people, lastItemCost], [left_td, center_td, right_td]) {
                    let name, price;

                    if (right_td && right_td.classList.contains('price-table')) {
                        price = right_td.innerText;
                        highlight(right_td);
                        lastItemCost = Number(price.match('\\$([0-9.]+)')[1]);
                    }

                    if (center_td && (name = center_td.querySelector('li strong'))) {
                        highlight(name);
                        name = name.innerText;
                        people[name] = lastItemCost;
                        lastItemCost = null;
                    }

                    return [people, lastItemCost];
                }, [{}, null]);
            }

            var infoTable = Array.from(containerElement.querySelectorAll('div.order-information tr'));
            if (infoTable) {
                infoTable.map(tr => Array.from(tr.querySelectorAll('td'))).filter(tds => tds.length).forEach(function([left, right]) {

                    let match = right.textContent.match('\\$([0-9.]+)');
                    var value = match && Number(match[1]);

                    switch (left.textContent.trim()) {
                        case 'Sales Tax':
                            tax = value;
                            highlight(right);
                            break;
                        case 'Processing Fee':
                        case 'Delivery Fee':
                            untaxedFees += value;
                            highlight(right);
                            break;
                        case 'Tip':
                            tip = value;
                            highlight(right);
                            break;
                    }
                });
            }
            return Order.split({people, untaxedFees, tip, tax});
        }
    }

    class QueryStringParser {
        /**
         * Parses input from a URL query string into an Order.
         * @example
         * parse('tax=0.30&fee=1.50&tip=1.25&Gus=5.00');
         * @param {string} queryString - The URL query string
         * @returns {Order} An order parsed from the URL query string
         */
        parse(queryString) {
            if (!location.search.length) {
                return undefined;
            }
            var params = location.search.slice(1).split('&');
            console.debug('params', params);

            let people={}, untaxedFees, tax, tip;

            params.map(param=>param.split('=')).forEach(function([key,value]) {
                key = decodeURIComponent(key);
                value = Number(decodeURIComponent(value));
                switch (key) {
                    case 'fee':
                        untaxedFees = value;
                        break;
                    case 'tax':
                        tax = value;
                        break;
                    case 'tip':
                        tip = value;
                        break;
                    default:
                        people[key] = value;
                }
            });

            return Order.split({people, untaxedFees, tax, tip});
        }
    }

    class OrderUpParser {

        /**
         * Parses the confirmation summary from an OrderUp.com order
         * @param {string} orderUpText - The confirmation summary from OrderUp.com
         * @param {number} fee
         * @param {number} tax
         * @param {number} tip - The tip (either a fixed value or percentage)
         * @param {boolean} isTipPercentage - True if the tip is a percentage as opposed to a fixed value
         * @return {Order} An order parsed from the OrderUp.com confirmation summary
         */
        parse(orderUpText, fee=0, tax=0, tip=0, isTipPercentage=false) {
            let order = new Order()
                .withNonTaxedFees(fee)
                .withTax(tax)
                .withTip(tip, isTipPercentage);

            var lines = orderUpText.split('\n');

            lines.reduce((lastItemCost, line) => {
                let itemCostMatch, nameMatch;

                if(!lastItemCost) {
                    if (itemCostMatch = line.match('.*\\$([0-9.]+)')) {
                        let itemCost = Number(itemCostMatch[1]);
                        return itemCost;
                    }
                }

                if (nameMatch = line.match('.*Label for:(.*)')) {
                    let name = nameMatch[1];
                    order.withPerson(name, lastItemCost);
                    return;
                }

                return lastItemCost;
            }, null);

            return order;
        }
    }

    class CsvParser {
        parse(csv) {
            const order = new Order();

            const lines = csv.split('\n');
            for(let line of lines) {
                if(line.trim() !== '') {
                    const [name, ...priceStrings] = line.split(',');
                    const price = priceStrings.map(ps => Number(ps.trim().replace('$',''))).reduce((p,acc) => p+acc, 0);
                    if(name === 'fee') {
                        order.withNonTaxedFees(price);
                    }
                    else if(name === 'tax') {
                        order.withTax(price);
                    }
                    else if(name === 'tip') {
                        order.withTip(price);
                    }
                    else {
                        order.withPerson(name, price);
                    }
                }
            }

            return order;
        }
    }
    module.exports = {OrderUpParser, QueryStringParser, CsvParser, OrderUpHtmlParser};
})();
<commit_msg>Fix parser to handle multiple items per person (#44)<commit_after>(function() {
    const Order = require('./order.js');

    class OrderUpHtmlParser {
        parse(containerElement) {

            var highlight = element => {
                element.style.background = 'repeating-linear-gradient(45deg, yellow, yellow 10px, #fafa0a 10px, #fafa0a 20px )';
                element.title = 'OrderSplitter is using this value';
            };

            var untaxedFees = 0, tip, tax, people;

            var summaryTable = Array.from(containerElement.querySelectorAll('#order-confirmation-page tr'));
            if (summaryTable) {
                [people] = summaryTable.map(tr => Array.from(tr.querySelectorAll('td'))).filter(tds => tds.length).reduce(function([people, lastItemCost], [left_td, center_td, right_td]) {
                    let name, price;

                    if (right_td && right_td.classList.contains('price-table')) {
                        price = right_td.innerText;
                        highlight(right_td);
                        lastItemCost = Number(price.match('\\$([0-9.]+)')[1]);
                    }

                    if (center_td && (name = center_td.querySelector('li strong'))) {
                        highlight(name);
                        name = name.innerText;
                        people[name] = people[name] || 0;
                        people[name] += lastItemCost;
                        lastItemCost = null;
                    }

                    return [people, lastItemCost];
                }, [{}, null]);
            }

            var infoTable = Array.from(containerElement.querySelectorAll('div.order-information tr'));
            if (infoTable) {
                infoTable.map(tr => Array.from(tr.querySelectorAll('td'))).filter(tds => tds.length).forEach(function([left, right]) {

                    let match = right.textContent.match('\\$([0-9.]+)');
                    var value = match && Number(match[1]);

                    switch (left.textContent.trim()) {
                        case 'Sales Tax':
                            tax = value;
                            highlight(right);
                            break;
                        case 'Processing Fee':
                        case 'Delivery Fee':
                            untaxedFees += value;
                            highlight(right);
                            break;
                        case 'Tip':
                            tip = value;
                            highlight(right);
                            break;
                    }
                });
            }
            return Order.split({people, untaxedFees, tip, tax});
        }
    }

    class QueryStringParser {
        /**
         * Parses input from a URL query string into an Order.
         * @example
         * parse('tax=0.30&fee=1.50&tip=1.25&Gus=5.00');
         * @param {string} queryString - The URL query string
         * @returns {Order} An order parsed from the URL query string
         */
        parse(queryString) {
            if (!location.search.length) {
                return undefined;
            }
            var params = location.search.slice(1).split('&');
            console.debug('params', params);

            let people={}, untaxedFees, tax, tip;

            params.map(param=>param.split('=')).forEach(function([key,value]) {
                key = decodeURIComponent(key);
                value = Number(decodeURIComponent(value));
                switch (key) {
                    case 'fee':
                        untaxedFees = value;
                        break;
                    case 'tax':
                        tax = value;
                        break;
                    case 'tip':
                        tip = value;
                        break;
                    default:
                        people[key] = value;
                }
            });

            return Order.split({people, untaxedFees, tax, tip});
        }
    }

    class OrderUpParser {

        /**
         * Parses the confirmation summary from an OrderUp.com order
         * @param {string} orderUpText - The confirmation summary from OrderUp.com
         * @param {number} fee
         * @param {number} tax
         * @param {number} tip - The tip (either a fixed value or percentage)
         * @param {boolean} isTipPercentage - True if the tip is a percentage as opposed to a fixed value
         * @return {Order} An order parsed from the OrderUp.com confirmation summary
         */
        parse(orderUpText, fee=0, tax=0, tip=0, isTipPercentage=false) {
            let order = new Order()
                .withNonTaxedFees(fee)
                .withTax(tax)
                .withTip(tip, isTipPercentage);

            var lines = orderUpText.split('\n');

            lines.reduce((lastItemCost, line) => {
                let itemCostMatch, nameMatch;

                if(!lastItemCost) {
                    if (itemCostMatch = line.match('.*\\$([0-9.]+)')) {
                        let itemCost = Number(itemCostMatch[1]);
                        return itemCost;
                    }
                }

                if (nameMatch = line.match('.*Label for:(.*)')) {
                    let name = nameMatch[1];
                    order.withPerson(name, lastItemCost);
                    return;
                }

                return lastItemCost;
            }, null);

            return order;
        }
    }

    class CsvParser {
        parse(csv) {
            const order = new Order();

            const lines = csv.split('\n');
            for(let line of lines) {
                if(line.trim() !== '') {
                    const [name, ...priceStrings] = line.split(',');
                    const price = priceStrings.map(ps => Number(ps.trim().replace('$',''))).reduce((p,acc) => p+acc, 0);
                    if(name === 'fee') {
                        order.withNonTaxedFees(price);
                    }
                    else if(name === 'tax') {
                        order.withTax(price);
                    }
                    else if(name === 'tip') {
                        order.withTip(price);
                    }
                    else {
                        order.withPerson(name, price);
                    }
                }
            }

            return order;
        }
    }
    module.exports = {OrderUpParser, QueryStringParser, CsvParser, OrderUpHtmlParser};
})();
<|endoftext|>


<commit_before>var ajaxWait = window.__env.AJAX_WAIT; // delay in ms to wait for ajax requests
var footworkAnimationClass = 'fw-entity-resolved';
var loadedModules = {};
var registerFootworkEntity;
var registerEntity;
var specWrappers = {};
var environment;

var testResults = {
  passed: 0,
  failed: 0,
  pending: 0
};

var allTestFiles = [];
var TEST_REGEXP = /(spec)\.js$/i;

var clientNavigator = navigator.userAgent.toLowerCase();
var isExploder = (clientNavigator.indexOf('msie') != -1);
var ieVersion = isExploder ? parseInt(clientNavigator.split('msie')[1]) : undefined;

/**
 * Determine whether the passed in file is listed in the tests array (or if tests is undefined or 'all' then return true always)
 *
 * @param {string} file the filename to check against
 * @param {array|string} tests [tests] to run, or if a 'string' is supplied it will always return true (ie: pass in 'all')
 * @returns {boolean} True if the test should be run, false if not
 */
function shouldRunTest(file, tests) {
  if(Object.prototype.toString.call(tests) === '[object Array]') {
    var shouldRun = false;
    tests.forEach(function(validTestModule) {
      if(file.match(validTestModule)) {
        shouldRun = true;
      }
    });
    return shouldRun;
  }
  return true;
}

// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    // Normalize paths to RequireJS module names.
    // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
    // then do not normalize the paths
    var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');

    // use the shouldRunTest callback below to limit the tests to an individual file or files
    /* shouldRunTest(normalizedTestModule, [
      'viewModel',
      'dataModel',
      'router',
      'namespace',
      'collection',
      'component',
      'broadcast-receive'
    ]) && */ allTestFiles.push(normalizedTestModule);
  }
});

require.config({
  // Karma serves files under /base, which is the basePath from your config file
  baseUrl: '/base',

  // dynamically load all test files
  deps: allTestFiles,

  waitSeconds: 600,

  paths: {
    /**
     * Note that if you add any new bower assets you will need to also add a reference
     * to them in the files section of karma.conf.js. This will allow the unit tests to
     * have access to them.
     */
    "text": "bower_components/requirejs-text/text",
    "footwork": "build/footwork",
    "lodash": "bower_components/lodash/dist/lodash",
    "jquery": "bower_components/jquery/dist/jquery",
    "history": "bower_components/history.js/scripts/bundled/html5/native.history",
    "customMatchers": "tests/assets/customMatchers",
    "tools": "tests/assets/tools",
    "reporter": "tests/assets/reporter",
    "container": "tests/assets/container",
    "fetch-mock": "node_modules/fetch-mock/es5/client-browserified",
    "es5-shim": "bower_components/es5-shim/es5-shim"
  },

  // we have to kickoff jasmine, as it is asynchronous
  callback: function() {
    function runTests (fw) {
      window.fw = fw; // export footwork so the user has access to it in the console
      fixture.setBase('tests/assets/fixtures');
      setTimeout(window.__karma__.start, ajaxWait);
    }

    if(isExploder && ieVersion < 9) {
      // ie < 9 requires shimming
      require(['es5-shim'], function() {
        require(['footwork', 'reporter', 'container'], runTests);
      });
    } else {
      require(['footwork', 'reporter', 'container'], runTests);
    }
  }
});
<commit_msg>removed superfluous comment<commit_after>var ajaxWait = window.__env.AJAX_WAIT; // delay in ms to wait for ajax requests
var footworkAnimationClass = 'fw-entity-resolved';
var loadedModules = {};
var registerFootworkEntity;
var registerEntity;
var specWrappers = {};
var environment;

var testResults = {
  passed: 0,
  failed: 0,
  pending: 0
};

var allTestFiles = [];
var TEST_REGEXP = /(spec)\.js$/i;

var clientNavigator = navigator.userAgent.toLowerCase();
var isExploder = (clientNavigator.indexOf('msie') != -1);
var ieVersion = isExploder ? parseInt(clientNavigator.split('msie')[1]) : undefined;

/**
 * Determine whether the passed in file is listed in the tests array (or if tests is undefined or 'all' then return true always)
 *
 * @param {string} file the filename to check against
 * @param {array|string} tests [tests] to run, or if a 'string' is supplied it will always return true (ie: pass in 'all')
 * @returns {boolean} True if the test should be run, false if not
 */
function shouldRunTest(file, tests) {
  if(Object.prototype.toString.call(tests) === '[object Array]') {
    var shouldRun = false;
    tests.forEach(function(validTestModule) {
      if(file.match(validTestModule)) {
        shouldRun = true;
      }
    });
    return shouldRun;
  }
  return true;
}

// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    // Normalize paths to RequireJS module names.
    // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
    // then do not normalize the paths
    var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');

    // use the shouldRunTest callback below to limit the tests to an individual file or files
    /* shouldRunTest(normalizedTestModule, [
      'viewModel',
      'dataModel',
      'router',
      'namespace',
      'collection',
      'component',
      'broadcast-receive'
    ]) && */ allTestFiles.push(normalizedTestModule);
  }
});

require.config({
  // Karma serves files under /base, which is the basePath from your config file
  baseUrl: '/base',

  // dynamically load all test files
  deps: allTestFiles,

  waitSeconds: 600,

  paths: {
    "text": "bower_components/requirejs-text/text",
    "footwork": "build/footwork",
    "lodash": "bower_components/lodash/dist/lodash",
    "jquery": "bower_components/jquery/dist/jquery",
    "history": "bower_components/history.js/scripts/bundled/html5/native.history",
    "customMatchers": "tests/assets/customMatchers",
    "tools": "tests/assets/tools",
    "reporter": "tests/assets/reporter",
    "container": "tests/assets/container",
    "fetch-mock": "node_modules/fetch-mock/es5/client-browserified",
    "es5-shim": "bower_components/es5-shim/es5-shim"
  },

  // we have to kickoff jasmine, as it is asynchronous
  callback: function() {
    function runTests (fw) {
      window.fw = fw; // export footwork so the user has access to it in the console
      fixture.setBase('tests/assets/fixtures');
      setTimeout(window.__karma__.start, ajaxWait);
    }

    if(isExploder && ieVersion < 9) {
      // ie < 9 requires shimming
      require(['es5-shim'], function() {
        require(['footwork', 'reporter', 'container'], runTests);
      });
    } else {
      require(['footwork', 'reporter', 'container'], runTests);
    }
  }
});
<|endoftext|>


<commit_before>var test = require('tape')
var level = require('level')
var multilevel = require('multilevel')
var ls = require('level-live-stream')
var db = level('./testdb/')
var cuid = require('cuid')
var hash = require('crypto-browserify/create-hash')

ls.install(db)

// use nimoy to manage sessions & to compile module library

var sessions = {edit:[]}
var pass = hash('sha256').update('nimoy').digest('hex')

var server = multilevel.server(db, {
  auth : function (user, cb) {
    if (!user.token && pass===user.pass) {
      var sess = cuid()
      sessions[user.name].push(sess)
      cb(null, {value:sess})
      return null
    } else if (user.token) {
      var exists = _.find(session[user.name],function (s) {
        if(s===user.token) return true
      })
      if (exists) cb(null, {token:user.token})
    } else cb(new Error('bad login!'), null)
  },
  access : function (u,db,m,a) {}
})

var client = multilevel.client(require('../static/manifest.json'))
server.pipe(client.createRpcStream()).pipe(server)

var library = require('../library.json')

library['mod1'] = {
  name : './tests/mod1'
}

library['mod2'] = {
  name : './tests/mod2'
}

var brico = require('../_bricoleur.js')(client,'edit',library)
              .on('error', console.error)

var cmds = [
  {cmd:'+@edit nimoy', from:'auth'},
  {cmd:'+mod1', from:'add-mod1'},
  {cmd:'+mod2', from:'add-mod2'},
  {cmd:'?mod2', from:'find-mod2'}
]

test('TEST BRICOLEUR', function (t) {
  t.plan(9)

  var pipe, m1, m2

  cmds.forEach(function (c) {
    brico.write(c)
  })

  brico.on('data', function (d) {
    if (d.key.match(cmds[0].from)) {
      t.equal(d.value,sessions['edit'][0], 'auth succesfull')
    }
    if (d.key.match(cmds[1].from)) {
      t.equal(isCuid(d.value), true, 'placed module1')
      m1 = d.value
    }
    if (d.key.match(cmds[2].from)) {
      t.equal(isCuid(d.value), true, 'placed module2')
      m2 = d.value
    }
    if (d.key.match(cmds[3].from)) {
      t.equal(d.value instanceof Array, true, 'search complete')
      brico.write({cmd:'+'+m1+'|'+m2,from:'pipe'})
    }
    if (d.key.slice(2) === 'pipe') {
      pipe = d.value
      t.equal(isCuid(pipe),true, 'piped modules')
      brico.write({cmd:'+#cvs',from:'save'})
    }
    if (d.key.match('save')) {
      t.equal(d.value,'#:cvs', 'saved')
      brico.write({cmd:'!#cvs',from:'load'})
    }
    if (d.key.match('load')) {
      t.equal(d.value,'#:cvs', 'loaded')
      brico.write({cmd:'-'+pipe,from:'unpipe'})
    }
    if (d.key.match('unpipe')) {
      t.equal(d.value,pipe, 'unpiped modules')
      brico.write({cmd:'-@edit',from:'logout'})
    }
    if (d.key.match('logout')) {
      t.equal(d.value, 'edit', 'logged out')
    }
  })
})

function isCuid (id) {
  var r = (typeof id==='string' && id.length===25 && id[0]==='c') ? true : false
  return r
}
<commit_msg>simplify bricoleur testss<commit_after>var _ = require('underscore')
var test = require('tape')
var level = require('level')
var multilevel = require('multilevel')
var ls = require('level-live-stream')
var db = level('./testdb/')
var cuid = require('cuid')
var hash = require('crypto-browserify/create-hash')

ls.install(db)

// use nimoy to manage sessions & to compile module library

var sessions = {edit:[]}
var pass = hash('sha256').update('nimoy').digest('hex')

var server = multilevel.server(db, {
  auth : function (user, cb) {
    if (!user.token && pass===user.pass) {
      var sess = cuid()
      sessions[user.name].push(sess)
      cb(null, {key:'@'+user.name,value:sess})
      return null
    } else if (user.token) {
      var exists = _.find(session[user.name],function (s) {
        if(s===user.token) return true
      })
      if (exists) cb(null, {token:user.token})
    } else cb(new Error('bad login!'), null)
  },
  access : function (u,db,m,a) {}
})

var client = multilevel.client(require('../static/manifest.json'))
server.pipe(client.createRpcStream()).pipe(server)

var library = require('../library.json')
library['mod1'] = { name : './tests/mod1' }
library['mod2'] = { name : './tests/mod2' }

var brico = require('../_bricoleur.js')(client,'edit',library)
              .on('error', console.error)

var cmds = [
  {cmd:'+@edit nimoy', from:'auth'},
  {cmd:'+mod1', from:'addMod1'},
  {cmd:'+mod2', from:'addMod2'},
  {cmd:'?mod2', from:'findMod2'}
]

test('TEST BRICOLEUR', function (t) {
  var pipe, m1, m2

  var tests = {
    auth : function (d) {
      t.equal(d.value,sessions['edit'][0], 'auth succesfull')
    },
    addMod1 : function (d) {
      t.equal(isCuid(d.value), true, 'placed module1')
      m1 = d.value
    },
    addMod2 : function (d) {
      t.equal(isCuid(d.value), true, 'placed module2')
      m2 = d.value
    },
    findMod2 : function (d) {
      t.equal(d.value instanceof Array, true, 'search complete')
      brico.write({cmd:'+'+m1+'|'+m2,from:'pipe'})
    },
    pipe: function (d) {
      pipe = d.value
      t.equal(isCuid(pipe),true, 'piped modules')
      brico.write({cmd:'+#cvs',from:'save'})
    },
    save: function (d) {
      t.equal(d.value,'#:cvs', 'saved')
      brico.write({cmd:'!#cvs',from:'load'})
    },
    load: function (d) {
      t.equal(d.value,'#:cvs', 'loaded')
      brico.write({cmd:'-'+pipe,from:'unpipe'})
    },
    unpipe: function (d) {
      t.equal(d.value,pipe, 'unpiped modules')
      brico.write({cmd:'-@edit',from:'logout'})
    },
    logout: function (d) {
      t.equal(d.value, 'edit', 'logged out')
    }
  }

  t.plan(_.keys(tests).length)

  cmds.forEach(function (c) {
    brico.write(c)
  })

  brico.on('data', function (d) {
    var path = d.key.split(':')
    var k = path[path.length-1]
    tests[k](d)
  })

})

function isCuid (id) {
  var r = (typeof id==='string' && id.length===25 && id[0]==='c') ? true : false
  return r
}
<|endoftext|>