<commit_before>/* @flow */

import * as React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { SchemaModel, Schema } from 'rsuite-schema';
import classNames from 'classnames';

import { getUnhandledProps, prefix } from './utils';
import { defaultClassPrefix } from './utils/prefix';

type Props = {
  className?: string,
  layout?: 'horizontal' | 'vertical' | 'inline',
  fluid?: boolean,
  formValue?: Object,
  formDefaultValue?: Object,
  formError?: Object,
  checkDelay?: number,
  checkTrigger?: 'change' | 'blur' | 'none',
  onChange?: (formValue: Object, event: SyntheticEvent<*>) => void,
  onError?: (formError: Object) => void,
  onCheck?: (formError: Object) => void,
  model: typeof Schema,
  classPrefix: string
};

type State = {
  formError?: Object,
  formValue?: Object
};

class Form extends React.Component<Props, State> {
  static defaultProps = {
    classPrefix: defaultClassPrefix('form'),
    model: SchemaModel({}),
    layout: 'vertical',
    formDefaultValue: {},
    checkDelay: 500,
    checkTrigger: 'change'
  };

  static childContextTypes = {
    form: PropTypes.object.isRequired
  };

  constructor(props: Props) {
    super(props);
    this.state = {
      formError: props.formError || {},
      formValue: props.formDefaultValue
    };
  }
  getChildContext() {
    const { formDefaultValue, formValue, model, checkTrigger } = this.props;
    const formError = this.getFormError();
    return {
      form: {
        onFieldChange: this.handleFieldChange,
        onFieldError: this.handleFieldError,
        onFieldSuccess: this.handleFieldSuccess,
        checkTrigger,
        formValue,
        formDefaultValue,
        formError,
        model
      }
    };
  }
  getFormValue() {
    const { formValue } = this.props;
    return _.isUndefined(formValue) ? this.state.formValue : formValue;
  }

  getFormError() {
    const { formError } = this.props;
    return _.isUndefined(formError) ? this.state.formError : formError;
  }

  /**
   * public APIs
   */
  check = (callback: (formError: Object) => void) => {
    const formValue = this.getFormValue() || {};
    const { model, onCheck, onError } = this.props;
    const formError = {};
    let errorCount = 0;

    Object.keys(model.schema).forEach(key => {
      const checkResult = model.checkForField(key, formValue[key]);

      if (checkResult.hasError === true) {
        errorCount += 1;
        formError[key] = checkResult.errorMessage;
      }
    });

    this.setState({ formError });
    onCheck && onCheck(formError);
    callback && callback(formError);
    if (errorCount > 0) {
      onError && onError(formError);
      return false;
    }

    return true;
  };

  /**
   * public APIs
   */
  cleanErrors(callback: () => void) {
    this.setState({ formError: {} }, callback);
  }

  /**
   * public APIs
   */
  resetErrors(formError: Object = {}, callback: () => void) {
    this.setState({ formError }, callback);
  }

  handleFieldError = (name: string, errorMessage: string) => {
    const { onError, onCheck } = this.props;
    const formError = {
      ...this.state.formError,
      [name]: errorMessage
    };

    this.setState({ formError }, () => {
      onError && onError(formError);
      onCheck && onCheck(formError);
    });
  };

  handleFieldSuccess = (name: string) => {
    const { onCheck } = this.props;
    const formError = _.omit(this.state.formError, [name]);
    this.setState({ formError }, () => {
      onCheck && onCheck(formError);
    });
  };

  handleFieldChange = (name: string, value: any, event: SyntheticEvent<*>) => {
    const { onChange } = this.props;
    const formValue = this.getFormValue();
    const nextFormValue = {
      ...formValue,
      [name]: value
    };
    onChange && onChange(nextFormValue, event);
  };

  render() {
    const { layout, classPrefix, fluid, className, ...props } = this.props;
    const addPrefix = prefix(classPrefix);
    const clesses = classNames(
      classPrefix,
      addPrefix(layout),
      className,
      addPrefix(fluid && layout === 'vertical' ? 'fluid' : 'fixed-width')
    );
    const unhandled = getUnhandledProps(Form, props);

    return <form {...unhandled} onSubmit={e => e.preventDefault()} className={clesses} />;
  }
}

export default Form;
<commit_msg>Fixes RSUITE-143<commit_after>/* @flow */

import * as React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { SchemaModel, Schema } from 'rsuite-schema';
import classNames from 'classnames';

import { getUnhandledProps, prefix } from './utils';
import { defaultClassPrefix } from './utils/prefix';

type Props = {
  className?: string,
  layout?: 'horizontal' | 'vertical' | 'inline',
  fluid?: boolean,
  formValue?: Object,
  formDefaultValue?: Object,
  formError?: Object,
  checkDelay?: number,
  checkTrigger?: 'change' | 'blur' | 'none',
  onChange?: (formValue: Object, event: SyntheticEvent<*>) => void,
  onError?: (formError: Object) => void,
  onCheck?: (formError: Object) => void,
  model: typeof Schema,
  classPrefix: string
};

type State = {
  formError?: Object,
  formValue?: Object
};

class Form extends React.Component<Props, State> {
  static defaultProps = {
    classPrefix: defaultClassPrefix('form'),
    model: SchemaModel({}),
    layout: 'vertical',
    formDefaultValue: {},
    checkDelay: 500,
    checkTrigger: 'change'
  };

  static childContextTypes = {
    form: PropTypes.object.isRequired
  };

  constructor(props: Props) {
    super(props);
    this.state = {
      formError: props.formError || {},
      formValue: props.formDefaultValue
    };
  }
  getChildContext() {
    const { formDefaultValue, formValue, model, checkTrigger } = this.props;
    const formError = this.getFormError();
    return {
      form: {
        onFieldChange: this.handleFieldChange,
        onFieldError: this.handleFieldError,
        onFieldSuccess: this.handleFieldSuccess,
        checkTrigger,
        formValue,
        formDefaultValue,
        formError,
        model
      }
    };
  }
  getFormValue() {
    const { formValue } = this.props;
    return _.isUndefined(formValue) ? this.state.formValue : formValue;
  }

  getFormError() {
    const { formError } = this.props;
    return _.isUndefined(formError) ? this.state.formError : formError;
  }

  /**
   * public APIs
   */
  check = (callback: (formError: Object) => void) => {
    const formValue = this.getFormValue() || {};
    const { model, onCheck, onError } = this.props;
    const formError = {};
    let errorCount = 0;

    Object.keys(model.schema).forEach(key => {
      const checkResult = model.checkForField(key, formValue[key]);
      if (checkResult.hasError === true) {
        errorCount += 1;
        formError[key] = checkResult.errorMessage;
      }
    });

    this.setState({ formError });
    onCheck && onCheck(formError);
    callback && callback(formError);
    if (errorCount > 0) {
      onError && onError(formError);
      return false;
    }

    return true;
  };

  /**
   * public APIs
   */
  cleanErrors(callback: () => void) {
    this.setState({ formError: {} }, callback);
  }

  /**
   * public APIs
   */
  resetErrors(formError: Object = {}, callback: () => void) {
    this.setState({ formError }, callback);
  }

  handleFieldError = (name: string, errorMessage: string) => {
    const { onError, onCheck } = this.props;
    const formError = {
      ...this.state.formError,
      [name]: errorMessage
    };

    this.setState({ formError }, () => {
      onError && onError(formError);
      onCheck && onCheck(formError);
    });
  };

  handleFieldSuccess = (name: string) => {
    const { onCheck } = this.props;
    const formError = _.omit(this.state.formError, [name]);
    this.setState({ formError }, () => {
      onCheck && onCheck(formError);
    });
  };

  handleFieldChange = (name: string, value: any, event: SyntheticEvent<*>) => {
    const { onChange } = this.props;
    const formValue = this.getFormValue();
    const nextFormValue = {
      ...formValue,
      [name]: value
    };
    this.setState({
      formValue: nextFormValue
    });
    onChange && onChange(nextFormValue, event);
  };

  render() {
    const { layout, classPrefix, fluid, className, ...props } = this.props;
    const addPrefix = prefix(classPrefix);
    const clesses = classNames(
      classPrefix,
      addPrefix(layout),
      className,
      addPrefix(fluid && layout === 'vertical' ? 'fluid' : 'fixed-width')
    );
    const unhandled = getUnhandledProps(Form, props);

    return <form {...unhandled} onSubmit={e => e.preventDefault()} className={clesses} />;
  }
}

export default Form;
<|endoftext|>


<commit_before>/**
 *
 * The Game state is the main game loop. All game related logic will reside in this state. Upon completion of the game the Game state will
 * start the Achievements state to display to the user the prize they one.
 *
 */

Game.Game = function(game) { };

var map;
var layer;
var tiles;
var player;
var cursors;
var startPosX;
var startPosY;
var spd;
var wasd;
var gridsize;
var marker;
var directions;
var opposites;
var current;
var turnPoint;
var threshold;
var turning;
var turnSpeed;
var treats;
var sTreats;
var sTreatsIndex;
var safetile;
var upButton;
var downButton;
var leftButton;
var rightButton;
var startX;
var startY;
var endX;
var endY;

Game.Game.prototype = {

    create: function(game){

        //players starting position
        startPosX = 18;
        startPosY = 24;

        //speed of travel
        threshold = 20;
        spd = 150;
        turnSpeed = 150;

        //set tile/grid size
        gridsize = 32;

        //direction arrays
        // direction holds info surrounding tiles
        directions = [null, null, null, null, null];
        // opposite holds the opposite values of direction
        opposites = [ Phaser.NONE, Phaser.RIGHT, Phaser.LEFT, Phaser.DOWN, Phaser.UP ];

        //Grid coordinate where the player is located
        marker = new Phaser.Point();

        //Grid coordinate where the player wants to turn to
        turnPoint = new Phaser.Point();

        //direction the player is currently facing
        current = Phaser.RIGHT;

        //the direction that the player is wanting to turn to
        turning = Phaser.NONE;

        //sets the value of the tiles that are passable
        safetile = 10;
        sTreatsIndex = 78;

        game.stage.smoothed = true;

        map = this.add.tilemap('pupmap', gridsize, gridsize);
        map.addTilesetImage('ptiles');
        layer = map.createLayer(0);

        treats = this.add.physicsGroup();
        sTreats = this.add.physicsGroup();

        map.createFromTiles(safetile, safetile, 'femur', layer, treats);
        map.createFromTiles(sTreatsIndex, safetile, 'ham', layer, sTreats);

        treats.setAll('x', 6, false, false, 1);
        treats.setAll('y', 6, false, false, 1);

        sTreats.setAll('y', 9, false, false, 1);

        map.setCollisionByExclusion( [safetile] , true, layer);

        layer.resizeWorld();

        player = this.add.sprite((startPosX * gridsize) + (gridsize/2), (startPosY * gridsize) + (gridsize/2), 'pup', 0);
        player.anchor.setTo(0.5);
        player.animations.add('walkLeft', [0, 1 , 2 , 1], 20, true);
        player.animations.add('walkRight', [3, 4, 5, 3], 20, true);
        player.animations.add('walkUp', [6, 7, 8, 6], 20, true);
        player.animations.add('walkDown', [9, 10, 11, 10], 20, true);

        this.physics.arcade.enable(player);
        player.body.setSize(gridsize, gridsize, 0, 0);

        // upButton = this.add.button((9.5 * gridsize), (23 * gridsize), 'up', this.actionOnClick, this);
        // upButton.scale.setTo(2.5,2.5);
        // upButton.animations.add('press', [0,1,2,1],20, false);
        //
        // downButton = this.add.sprite((9.5 * gridsize), (25 * gridsize), 'down', 0);
        // downButton.scale.setTo(2.5,2.5);
        // downButton.animations.add('press', [0,1,2,1],20, false);
        //
        // rightButton = this.add.sprite((11 * gridsize), (24 * gridsize), 'right', 0);
        // rightButton.scale.setTo(2,2);
        // rightButton.animations.add('press', [0,1,2,1],20, false);
        //
        // leftButton = this.add.sprite((8.25 * gridsize), (24 * gridsize), 'left', 0);
        // leftButton.scale.setTo(2,2);
        // leftButton.animations.add('press', [0,1,2,1],20, false);

        cursors = this.input.keyboard.createCursorKeys();

        //add the WASD keys to the possible input
        wasd = {

            up : game.input.keyboard.addKey(Phaser.Keyboard.W),
            down: game.input.keyboard.addKey(Phaser.Keyboard.S),
            right: game.input.keyboard.addKey(Phaser.Keyboard.D),
            left: game.input.keyboard.addKey(Phaser.Keyboard.A),
        }

        this.move(Phaser.RIGHT);

        game.input.onDown.add(this.beginSwipe, this);

    },

    beginSwipe : function(){
      startX = this.game.input.worldX;
      startY = this.game.input.worldY;
      this.game.input.onDown.remove(this.beginSwipe);
      this.game.input.onUp.add(this.endSwipe, this);

    },

    endSwipe : function () {
        endX = this.game.input.worldX;
        endY = this.game.input.worldY;

        var distX = startX-endX;
        var distY = startY-endY;

        if(Math.abs(distX)>Math.abs(distY)*2 && Math.abs(distX) > 10){
            if(distX> 0 && current !== Phaser.LEFT){
                this.checkDirection(Phaser.LEFT);
            }else if(distX < 0 && current !== Phaser.RIGHT){
                this.checkDirection(Phaser.RIGHT);
            }
        }
        if(Math.abs(distY)>Math.abs(distX)*2 && Math.abs(distY)>10){
            if(distY>0 && current !== Phaser.UP){
                this.checkDirection(Phaser.UP);
            }else if (distY < 0 && current !== Phaser.DOWN){
                this.checkDirection(Phaser.DOWN);
            }
        }
        this.game.input.onDown.add(this.beginSwipe, this);
        this.game.input.onUp.remove(this.endSwipe);
    },

    checkKeys: function () {

        //if the left key is pressed and the player not currently facing left
        if((cursors.left.isDown  || wasd.left.isDown )  && current !== Phaser.LEFT){

            this.checkDirection(Phaser.LEFT);

        }else if((cursors.right.isDown || wasd.right.isDown)  && current !== Phaser.RIGHT){

            this.checkDirection(Phaser.RIGHT );

        }else if((cursors.up.isDown || wasd.up.isDown)  && current !== Phaser.UP){

            this.checkDirection(Phaser.UP);

        }else if((cursors.down.isDown  || wasd.down.isDown )  && current !== Phaser.DOWN){

            this.checkDirection(Phaser.DOWN);

        }
    },

    move: function (dir){

        var speed = spd;

        if (dir === Phaser.LEFT  || dir === Phaser.UP){

            speed = -speed;
        }

        if (dir === Phaser.LEFT || dir === Phaser.RIGHT ){

            player.body.velocity.x = speed;

        }else{

            player.body.velocity.y = speed;

        }

        player.scale.x = 1;
        player.angle = 0;

        if(dir === Phaser.RIGHT)
            player.play('walkRight');
        else if(dir === Phaser.LEFT)
            player.play('walkLeft');
        else if(dir === Phaser.UP)
            player.play('walkUp');
        else if (dir === Phaser.DOWN)
            player.play('walkDown');

        current = dir;

    },

    checkDirection : function(turningTo) {
        //3 conditions to check:
        //The player is set to turn in that direction
        //There isn't a tile in that direction
        //The tile isn't a wall

        if (turning === turningTo ||
            directions[turningTo] === null ||
            directions[turningTo].index !== safetile){

            //if they are already set to turn in that direction or
            //if there isn't a tile there, or the tile's index is 0

            return;
        }

        if(current === opposites[turningTo]){
            //if the player wants to turn 180

            this.move(turningTo);

        }else{

            turning = turningTo;

            turnPoint.x = (marker.x * gridsize) + (gridsize / 2);
            turnPoint.y = (marker.y * gridsize) + (gridsize / 2);
        }
    },

    turn: function(){

        //take in the floor of the players position
        var plX = Math.floor(player.x);
        var plY = Math.floor(player.y);

        //if the player's cooridinates and the turning point
        //not within the alloted threshold, return false
        if(!this.math.fuzzyEqual(plX, turnPoint.x, threshold) ||
            !this.math.fuzzyEqual(plY, turnPoint.y, threshold)){

            return false;
        }

        //otherwise, we will align the player with the grid and
        //allow turning
        player.x = turnPoint.x;
        player.y = turnPoint.y;

        player.body.reset(turnPoint.x, turnPoint.y);

        //allow the player to turn in the desired direction
        this.move(turning);

        //reset the desired turning to none.
        turning = Phaser.NONE;

        return true;

    },

    eatTreats: function (player, treat){
        treat.kill();

        if(treats.total === 0){
            treats.callAll('revive');
        }
    },

    eatSTreats: function (player, treat){
        treat.kill();

        if(treats.total === 0){
            treats.callAll('revive');
        }
    },

    update: function(game) {

        //make sure the level collides with the player
        this.physics.arcade.collide(player, layer);

        //ensure the player interacts with the treat
        this.physics.arcade.overlap(player, treats, this.eatTreats, null, this);
        this.physics.arcade.overlap(player, sTreats, this.eatSTreats, null, this);

        //find out where player is with grid coordinates
        marker.x = this.math.snapToFloor(Math.floor(player.x), gridsize) / gridsize;
        marker.y = this.math.snapToFloor(Math.floor(player.y), gridsize) / gridsize;

        var i = layer.index;
        var x = marker.x;
        var y = marker.y;

        //store the tiles around the player in the directions array
        //to be able to check if we can turn into the tile
        directions[Phaser.LEFT] = map.getTileLeft(i, x, y);
        directions[Phaser.RIGHT] = map.getTileRight(i, x, y);
        directions[Phaser.UP] = map.getTileAbove(i, x, y);
        directions[Phaser.DOWN] = map.getTileBelow(i, x, y);

        //every frame check to see if the a key is being pressed
        this.checkKeys();

        if(turning !== Phaser.NONE){
            this.turn();
        }

    },

};
<commit_msg>add timer system add score system add gameover system<commit_after>/**
 *
 * The Game state is the main game loop. All game related logic will reside in this state. Upon completion of the game the Game state will
 * start the Achievements state to display to the user the prize they one.
 *
 */

Game.Game = function(game) { };

var map;
var layer;
var tiles;
var player;
var cursors;
var startPosX;
var startPosY;
var spd;
var wasd;
var gridsize;
var marker;
var directions;
var opposites;
var current;
var turnPoint;
var threshold;
var turning;
var turnSpeed;
var treats;
var sTreats;
var sTreatsIndex;
var safetile;
var upButton;
var downButton;
var leftButton;
var rightButton;
var startX;
var startY;
var endX;
var endY;
var score;
var scoreText;
var timer;
var time;
var timeText;
var gameOverText;

Game.Game.prototype = {

    create: function(game){

        //players starting position
        startPosX = 18;
        startPosY = 24;

        //speed of travel
        threshold = 20;
        spd = 150;
        turnSpeed = 150;

        //set tile/grid size
        gridsize = 32;

        //direction arrays
        // direction holds info surrounding tiles
        directions = [null, null, null, null, null];
        // opposite holds the opposite values of direction
        opposites = [ Phaser.NONE, Phaser.RIGHT, Phaser.LEFT, Phaser.DOWN, Phaser.UP ];

        //Grid coordinate where the player is located
        marker = new Phaser.Point();

        //Grid coordinate where the player wants to turn to
        turnPoint = new Phaser.Point();

        //direction the player is currently facing
        current = Phaser.RIGHT;

        //the direction that the player is wanting to turn to
        turning = Phaser.NONE;

        //sets the value of the tiles that are passable
        safetile = 10;
        sTreatsIndex = 78;

        game.stage.smoothed = true;

        map = this.add.tilemap('pupmap', gridsize, gridsize);
        map.addTilesetImage('ptiles');
        layer = map.createLayer(0);

        treats = this.add.physicsGroup();
        sTreats = this.add.physicsGroup();

        map.createFromTiles(safetile, safetile, 'femur', layer, treats);
        map.createFromTiles(sTreatsIndex, safetile, 'ham', layer, sTreats);

        treats.setAll('x', 6, false, false, 1);
        treats.setAll('y', 6, false, false, 1);

        sTreats.setAll('y', 9, false, false, 1);

        map.setCollisionByExclusion( [safetile] , true, layer);

        layer.resizeWorld();

        //create the timer
        timer = this.time.create(false);
        timer.loop(1000, this.updateCounter, this);
        timer.start();
        time = 60;
        timeText = this.add.text(400, 32, 'Time Left : ' + time , { fontSize: '32px', fill: '#ffffff' } );
        timeText.visibility = true;

        //create the player
        player = this.add.sprite((startPosX * gridsize) + (gridsize/2), (startPosY * gridsize) + (gridsize/2), 'pup', 0);
        player.anchor.setTo(0.5);
        player.animations.add('walkLeft', [0, 1 , 2 , 1], 20, true);
        player.animations.add('walkRight', [3, 4, 5, 3], 20, true);
        player.animations.add('walkUp', [6, 7, 8, 6], 20, true);
        player.animations.add('walkDown', [9, 10, 11, 10], 20, true);

        this.physics.arcade.enable(player);
        player.body.setSize(gridsize, gridsize, 0, 0);

        //set the score to zero
        score = 0;
        scoreText = this.add.text(32 ,32, 'score : 0', { fontSize: '32px', fill: '#ffffff'});
        scoreText.visibilty = true;

        //set the gameOverText and set it to not visible
        gameOverText = this.add.text((this.worldX/2) (this.worldY/2), 'Congratulation! You Scored : ' + score , { fontSize: '32px', fill: '#ffffff'});
        gameOverText.visible = false;

        // upButton = this.add.button((9.5 * gridsize), (23 * gridsize), 'up', this.actionOnClick, this);
        // upButton.scale.setTo(2.5,2.5);
        // upButton.animations.add('press', [0,1,2,1],20, false);
        //
        // downButton = this.add.sprite((9.5 * gridsize), (25 * gridsize), 'down', 0);
        // downButton.scale.setTo(2.5,2.5);
        // downButton.animations.add('press', [0,1,2,1],20, false);
        //
        // rightButton = this.add.sprite((11 * gridsize), (24 * gridsize), 'right', 0);
        // rightButton.scale.setTo(2,2);
        // rightButton.animations.add('press', [0,1,2,1],20, false);
        //
        // leftButton = this.add.sprite((8.25 * gridsize), (24 * gridsize), 'left', 0);
        // leftButton.scale.setTo(2,2);
        // leftButton.animations.add('press', [0,1,2,1],20, false);

        cursors = this.input.keyboard.createCursorKeys();

        //add the WASD keys to the possible input
        wasd = {

            up : game.input.keyboard.addKey(Phaser.Keyboard.W),
            down: game.input.keyboard.addKey(Phaser.Keyboard.S),
            right: game.input.keyboard.addKey(Phaser.Keyboard.D),
            left: game.input.keyboard.addKey(Phaser.Keyboard.A),
        }

        this.move(Phaser.RIGHT);

        game.input.onDown.add(this.beginSwipe, this);

    },
    updateCounter : function(){
        time--;
        timeText.text = 'Time Left : ' + time;
        if(time === 0){
            this.gameOver();
        }
    },

    beginSwipe : function(){
      startX = this.game.input.worldX;
      startY = this.game.input.worldY;
      this.game.input.onDown.remove(this.beginSwipe);
      this.game.input.onUp.add(this.endSwipe, this);

    },

    endSwipe : function () {
        endX = this.game.input.worldX;
        endY = this.game.input.worldY;

        var distX = startX-endX;
        var distY = startY-endY;

        if(Math.abs(distX)>Math.abs(distY)*2 && Math.abs(distX) > 10){
            if(distX> 0 && current !== Phaser.LEFT){
                this.checkDirection(Phaser.LEFT);
            }else if(distX < 0 && current !== Phaser.RIGHT){
                this.checkDirection(Phaser.RIGHT);
            }
        }
        if(Math.abs(distY)>Math.abs(distX)*2 && Math.abs(distY)>10){
            if(distY>0 && current !== Phaser.UP){
                this.checkDirection(Phaser.UP);
            }else if (distY < 0 && current !== Phaser.DOWN){
                this.checkDirection(Phaser.DOWN);
            }
        }
        this.game.input.onDown.add(this.beginSwipe, this);
        this.game.input.onUp.remove(this.endSwipe);
    },

    checkKeys: function () {

        //if the left key is pressed and the player not currently facing left
        if((cursors.left.isDown  || wasd.left.isDown )  && current !== Phaser.LEFT){

            this.checkDirection(Phaser.LEFT);

        }else if((cursors.right.isDown || wasd.right.isDown)  && current !== Phaser.RIGHT){

            this.checkDirection(Phaser.RIGHT );

        }else if((cursors.up.isDown || wasd.up.isDown)  && current !== Phaser.UP){

            this.checkDirection(Phaser.UP);

        }else if((cursors.down.isDown  || wasd.down.isDown )  && current !== Phaser.DOWN){

            this.checkDirection(Phaser.DOWN);

        }
    },

    move: function (dir){

        var speed = spd;

        if (dir === Phaser.LEFT  || dir === Phaser.UP){

            speed = -speed;
        }

        if (dir === Phaser.LEFT || dir === Phaser.RIGHT ){

            player.body.velocity.x = speed;

        }else{

            player.body.velocity.y = speed;

        }

        player.scale.x = 1;
        player.angle = 0;

        if(dir === Phaser.RIGHT)
            player.play('walkRight');
        else if(dir === Phaser.LEFT)
            player.play('walkLeft');
        else if(dir === Phaser.UP)
            player.play('walkUp');
        else if (dir === Phaser.DOWN)
            player.play('walkDown');

        current = dir;

    },

    checkDirection : function(turningTo) {
        //3 conditions to check:
        //The player is set to turn in that direction
        //There isn't a tile in that direction
        //The tile isn't a wall

        if (turning === turningTo ||
            directions[turningTo] === null ||
            directions[turningTo].index !== safetile){

            //if they are already set to turn in that direction or
            //if there isn't a tile there, or the tile's index is 0

            return;
        }

        if(current === opposites[turningTo]){
            //if the player wants to turn 180

            this.move(turningTo);

        }else{

            turning = turningTo;

            turnPoint.x = (marker.x * gridsize) + (gridsize / 2);
            turnPoint.y = (marker.y * gridsize) + (gridsize / 2);
        }
    },

    turn: function(){

        //take in the floor of the players position
        var plX = Math.floor(player.x);
        var plY = Math.floor(player.y);

        //if the player's cooridinates and the turning point
        //not within the alloted threshold, return false
        if(!this.math.fuzzyEqual(plX, turnPoint.x, threshold) ||
            !this.math.fuzzyEqual(plY, turnPoint.y, threshold)){

            return false;
        }

        //otherwise, we will align the player with the grid and
        //allow turning
        player.x = turnPoint.x;
        player.y = turnPoint.y;

        player.body.reset(turnPoint.x, turnPoint.y);

        //allow the player to turn in the desired direction
        this.move(turning);

        //reset the desired turning to none.
        turning = Phaser.NONE;

        return true;

    },

    eatTreats: function (player, treat){
        //remove the femur
        treat.kill();

        //update the score
        score += 20;
        scoreText.text = 'Score: ' + score;

    },

    eatSTreats: function (player, treat){
        //remove the ham
        treat.kill();

        //update the score
        score += 50;
        scoreText.text = 'Score: ' + score;

    },

    gameOver: function(){
        //stop the timer
        timer.stop();

        //remove the player
        player.kill();

        //set the visibilty of the text
        gameOverText.text = 'Congratulation! You Scored : ' + score;
        gameOverText.visibilty = true;
        scoreText.visibilty = false;
        timeText.visibility = false;

    },

    update: function(game) {

        //make sure the level collides with the player
        this.physics.arcade.collide(player, layer);

        //ensure the player interacts with the treat
        this.physics.arcade.overlap(player, treats, this.eatTreats, null, this);
        this.physics.arcade.overlap(player, sTreats, this.eatSTreats, null, this);

        //find out where player is with grid coordinates
        marker.x = this.math.snapToFloor(Math.floor(player.x), gridsize) / gridsize;
        marker.y = this.math.snapToFloor(Math.floor(player.y), gridsize) / gridsize;

        var i = layer.index;
        var x = marker.x;
        var y = marker.y;

        //store the tiles around the player in the directions array
        //to be able to check if we can turn into the tile
        directions[Phaser.LEFT] = map.getTileLeft(i, x, y);
        directions[Phaser.RIGHT] = map.getTileRight(i, x, y);
        directions[Phaser.UP] = map.getTileAbove(i, x, y);
        directions[Phaser.DOWN] = map.getTileBelow(i, x, y);

        //every frame check to see if the a key is being pressed
        this.checkKeys();

        //as long as you have a vaild direction to turn in, turn
        if(turning !== Phaser.NONE){
            this.turn();
        }
        //win condition
        if(treats.total === 0  && sTreats.total == 0){
            // treats.callAll('revive');
            // sTreats.callAll('revive');
            this.gameOver();
        }

    },

};
<|endoftext|>


<commit_before>import React from "react";
import objectAssign from "object-assign";
import BezierComponent from "./BezierComponent";

function range (from, to, step) {
  const t = [];
  for (let i=from; i<to; i+=step)
    t.push(i);
  return t;
}

function sameShadowObject (a, b) {
  const aKeys = Object.keys(a);
  const bKeys = Object.keys(b);
  if (aKeys.length !== bKeys.length) return false;
  for (let i in a) {
    if (a[i] !== b[i])
      return false;
  }
  return true;
}

export default class Grid extends BezierComponent {

  gridX (div) {
    var step = 1 / div;
    return range(0, 1, step).map(this.x);
  }

  gridY (div) {
    var step = 1 / div;
    return range(0, 1, step).map(this.y);
  }

  shouldComponentUpdate(nextProps) {
    if (super.shouldComponentUpdate(nextProps)) return true;
    const {
      background,
      gridColor,
      textStyle
    } = this.props;
    return nextProps.background !== background ||
      nextProps.gridColor !== gridColor ||
      !sameShadowObject(nextProps.textStyle, textStyle);
  }

  render() {
    const { x, y } = this;
    const {
      background,
      gridColor,
      textStyle
    } = this.props;

    const sx = x(0);
    const sy = y(0);
    const ex = x(1);
    const ey = y(1);

    const xhalf = this.gridX(2);
    const yhalf = this.gridY(2);
    const xtenth = this.gridX(10);
    const ytenth = this.gridY(10);

    const gridbg = [
      "M"+[sx,sy],
      "L"+[sx,ey],
      "L"+[ex,ey],
      "L"+[ex,sy],
      "Z"
    ].join(" ");

    const tenth =
      xtenth
      .map(xp => [ "M"+[xp,sy], "L"+[xp,ey] ] )
      .concat(ytenth.map(yp => [ "M"+[sx,yp], "L"+[ex,yp] ]))
      .join(" ");

    const half =
      xhalf
      .map(xp => [ "M"+[xp,sy], "L"+[xp,ey] ])
      .concat(yhalf.map(yp => [ "M"+[sx,yp], "L"+[ex,yp] ]))
      .concat([ "M"+[sx,sy], "L"+[ex,ey] ])
      .join(" ");

    const ticksLeft =
      ytenth.map( (yp, i) => {
        const w = 3 + (i % 5 === 0 ? 2 : 0);
        return [ "M"+[sx,yp], "L"+[sx-w,yp] ];
      }).join(" ");

    const ticksBottom =
      xtenth.map((xp, i) => {
        const h = 3 + (i % 5 === 0 ? 2 : 0);
        return [ "M"+[xp,sy], "L"+[xp,sy+h] ];
      }).join(" ");

    return <g>
      <path
        fill={background}
        d={gridbg} />
      <path
        strokeWidth="1px"
        stroke={gridColor}
        d={tenth} />
      <path
        strokeWidth="2px"
        stroke={gridColor}
        d={half} />
      <path
        strokeWidth="1px"
        stroke={gridColor}
        d={ticksLeft} />
      <text
        style={objectAssign({ textAnchor: "end" }, textStyle)}
        transform="rotate(-90)"
        x={-this.y(1)}
        y={this.x(0)-8}
      >Progress Percentage</text>
      <path
        strokeWidth="1px"
        stroke={gridColor}
        d={ticksBottom} />
      <text
        style={objectAssign({ dominantBaseline: "text-before-edge" }, textStyle)}
        textAnchor="end"
        x={this.x(1)}
        y={this.y(0)+5}>Time Percentage</text>
    </g>;
  }
}
<commit_msg>Fix Grid for Firefox<commit_after>import React from "react";
import objectAssign from "object-assign";
import BezierComponent from "./BezierComponent";

function range (from, to, step) {
  const t = [];
  for (let i=from; i<to; i+=step)
    t.push(i);
  return t;
}

function sameShadowObject (a, b) {
  const aKeys = Object.keys(a);
  const bKeys = Object.keys(b);
  if (aKeys.length !== bKeys.length) return false;
  for (let i in a) {
    if (a[i] !== b[i])
      return false;
  }
  return true;
}

export default class Grid extends BezierComponent {

  gridX (div) {
    var step = 1 / div;
    return range(0, 1, step).map(this.x);
  }

  gridY (div) {
    var step = 1 / div;
    return range(0, 1, step).map(this.y);
  }

  shouldComponentUpdate(nextProps) {
    if (super.shouldComponentUpdate(nextProps)) return true;
    const {
      background,
      gridColor,
      textStyle
    } = this.props;
    return nextProps.background !== background ||
      nextProps.gridColor !== gridColor ||
      !sameShadowObject(nextProps.textStyle, textStyle);
  }

  render() {
    const { x, y } = this;
    const {
      background,
      gridColor,
      textStyle
    } = this.props;

    const sx = x(0);
    const sy = y(0);
    const ex = x(1);
    const ey = y(1);

    const xhalf = this.gridX(2);
    const yhalf = this.gridY(2);
    const xtenth = this.gridX(10);
    const ytenth = this.gridY(10);

    const gridbg = [
      "M"+[sx,sy],
      "L"+[sx,ey],
      "L"+[ex,ey],
      "L"+[ex,sy],
      "Z"
    ].join(" ");

    const tenth =
      xtenth
      .map(xp => `M${xp},${sy} L${xp},${ey}`)
      .concat(ytenth.map(yp => `M${sx},${yp} L${ex},${yp}`))
      .join(" ");

    const half =
      xhalf
      .map(xp => `M${xp},${sy} L${xp},${ey}`)
      .concat(yhalf.map(yp => `M${sx},${yp} L${ex},${yp}`))
      .concat([ "M"+[sx,sy]+" L"+[ex,ey] ])
      .join(" ");

    const ticksLeft =
      ytenth.map( (yp, i) => {
        const w = 3 + (i % 5 === 0 ? 2 : 0);
        return `M${sx},${yp} L${sx-w},${yp}`;
      }).join(" ");

    const ticksBottom =
      xtenth.map((xp, i) => {
        const h = 3 + (i % 5 === 0 ? 2 : 0);
        return `M${xp},${sy} L${xp},${sy+h}`;
      }).join(" ");

    return <g>
      <path
        fill={background}
        d={gridbg} />
      <path
        strokeWidth="1px"
        stroke={gridColor}
        d={tenth} />
      <path
        strokeWidth="2px"
        stroke={gridColor}
        d={half} />
      <path
        strokeWidth="1px"
        stroke={gridColor}
        d={ticksLeft} />
      <text
        style={objectAssign({ textAnchor: "end" }, textStyle)}
        transform="rotate(-90)"
        x={-this.y(1)}
        y={this.x(0)-8}
      >Progress Percentage</text>
      <path
        strokeWidth="1px"
        stroke={gridColor}
        d={ticksBottom} />
      <text
        style={objectAssign({ dominantBaseline: "text-before-edge" }, textStyle)}
        textAnchor="end"
        x={this.x(1)}
        y={this.y(0)+5}>Time Percentage</text>
    </g>;
  }
}
<|endoftext|>


<commit_before>/**
 * @flow
 */

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableHighlight,
  ListView,
  RefreshControl,
} from 'react-native';

import {connect} from 'react-redux';
import { Actions } from 'react-native-router-flux'
import HTMLView from 'react-native-htmlview';

import theme from './util/theme';
import openBrowser from './util/openBrowser';
import I18n from './util/i18n';

import Spinner from './components/Spinner';
import ContainerStyle from './components/ContainerStyle';

import {
  initializeAPI,
  loadToken,
  saveToken,
  removeToken,
} from './actions'

const mapStateToProps = store => ({
  api: store.api,
  token: store.token,
});

const mapDispatchToProps = dispatch => ({
  removeToken () {
    return dispatch(removeToken())
  },
});

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: null,
      timeline: null,
      refreshing: false,
    };
  }
  _logout () {
    this.props.removeToken().then(() => {
      Actions.login();
    });
  }
  componentDidMount() {
    if (this.props.token) {
      this._fetch();
    }
  }
  _fetch() {
    console.log(this.props.api.token)
    this.props.api.getCurrentAccount().then((resp) => {
      console.log(resp);
      if (!resp.status) {
        this.setState({username: resp.username, refreshing: false});
      } else if (resp.status===401) {
        this._logout();
      }
    });
    this.props.api.getTimeline().then((resp) => {
      console.log(resp);
      if (!resp.status) {
        let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.setState({timeline: ds.cloneWithRows(resp)});
      }
    });
  }
  _onRefresh() {
    this.setState({refreshing: true});
    this._fetch();
  }
  render() {
    // console.log(this.props)
    return (
      <View style={styles.container}>
        {(() => {
          if (this.state.timeline) {
            return <ListView
              dataSource={this.state.timeline}
              renderRow={(twoot) => <Twoot twoot={twoot} />}
              style={[styles.timeline, ContainerStyle]}
              refreshControl={
                <RefreshControl
                  refreshing={this.state.refreshing}
                  onRefresh={this._onRefresh.bind(this)}
                />
              }
            />;
          } else if (this.state.username) {
            return (
              <Text style={styles.instructions}>
                {I18n.t('Welcome')} {this.state.username}
              </Text>
            );
          } else {
            return <Spinner error={false} />;
          }
        })()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: theme.color.bg,
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: theme.color.tint,
    marginBottom: 5,
  },
  timeline: {
    flex: 1,
    flexDirection: 'column',
  }
});

export default connect(mapStateToProps, mapDispatchToProps)(Home)

const Twoot = (props) => {
  const style = StyleSheet.create({
    container: {
      flex: 1,
      padding: 10,
      borderBottomWidth: 1,
      borderBottomColor: theme.color.gray,
      minHeight: 60,
    },
    span: {
      color: theme.color.tint,
      // color: 'white',
    },
    p: {
      color: 'white',
    },
  });
  return (
    <View style={style.container}>
      <HTMLView
        value={props.twoot.content}
        onLinkPress={(url) => openBrowser(url)}
        stylesheet={style}
      />
    </View>
  );
};

<commit_msg>add icon<commit_after>/**
 * @flow
 */

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  Image,
  TouchableHighlight,
  ListView,
  RefreshControl,
} from 'react-native';

import {connect} from 'react-redux';
import { Actions } from 'react-native-router-flux'
import HTMLView from 'react-native-htmlview';

import theme from './util/theme';
import openBrowser from './util/openBrowser';
import I18n from './util/i18n';

import Spinner from './components/Spinner';
import ContainerStyle from './components/ContainerStyle';

import {
  initializeAPI,
  loadToken,
  saveToken,
  removeToken,
} from './actions'

const mapStateToProps = store => ({
  api: store.api,
  token: store.token,
});

const mapDispatchToProps = dispatch => ({
  removeToken () {
    return dispatch(removeToken())
  },
});

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: null,
      timeline: null,
      refreshing: false,
    };
  }
  _logout () {
    this.props.removeToken().then(() => {
      Actions.login();
    });
  }
  componentDidMount() {
    if (this.props.token) {
      this._fetch();
    }
  }
  _fetch() {
    console.log(this.props.api.token)
    this.props.api.getCurrentAccount().then((resp) => {
      console.log(resp);
      if (!resp.status) {
        this.setState({username: resp.username, refreshing: false});
      } else if (resp.status===401) {
        this._logout();
      }
    });
    this.props.api.getTimeline().then((resp) => {
      console.log(resp);
      if (!resp.status) {
        let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.setState({timeline: ds.cloneWithRows(resp)});
      }
    });
  }
  _onRefresh() {
    this.setState({refreshing: true});
    this._fetch();
  }
  render() {
    // console.log(this.props)
    return (
      <View style={styles.container}>
        {(() => {
          if (this.state.timeline) {
            return <ListView
              dataSource={this.state.timeline}
              renderRow={(twoot) => <Twoot twoot={twoot} />}
              style={[styles.timeline, ContainerStyle]}
              refreshControl={
                <RefreshControl
                  refreshing={this.state.refreshing}
                  onRefresh={this._onRefresh.bind(this)}
                />
              }
            />;
          } else if (this.state.username) {
            return (
              <Text style={styles.instructions}>
                {I18n.t('Welcome')} {this.state.username}
              </Text>
            );
          } else {
            return <Spinner error={false} />;
          }
        })()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: theme.color.bg,
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: theme.color.tint,
    marginBottom: 5,
  },
  timeline: {
    flex: 1,
    flexDirection: 'column',
  }
});

export default connect(mapStateToProps, mapDispatchToProps)(Home)

const Twoot = (props) => {
  const style = StyleSheet.create({
    container: {
      flex: 1,
      flexDirection: 'row',
      padding: 10,
      borderBottomWidth: 1,
      borderBottomColor: theme.color.gray,
      minHeight: 60,
    },
    span: {
      color: theme.color.tint,
      // color: 'white',
    },
    p: {
      color: 'white',
    },
    icon: {
      width: 50,
      height: 50,
    },
    username: {
      color: 'white',
    },
    body: {
      marginLeft: 10,
    }
  });
  return (
    <View style={style.container}>
      <Image source={{uri: props.twoot.account.avatar_static}} style={style.icon} />
      <View style={style.body}>
        <Text style={style.username}>{props.twoot.account.username}</Text>
        <HTMLView
          value={props.twoot.content}
          onLinkPress={(url) => openBrowser(url)}
          stylesheet={style}
        />
      </View>
    </View>
  );
};

<|endoftext|>


<commit_before>var _ = require('lodash');
var hb = require('handlebars');
var fs = require('fs');

module.exports = function(bosco) {

    var createKey = require('./AssetHelper')(bosco).createKey;

    return {
        createHtmlFiles:createHtmlFiles
    }

    function createHtmlFiles(staticAssets, next) {

        var htmlAssets = {},
            port = bosco.config.get('cdn:port') || "7334";

        _.forOwn(staticAssets, function(value, key) {

            var html,
                htmlFile = createKey(value.tag, value.type, 'html', 'html'),
                cdn = bosco.config.get('aws:cdn') ? bosco.config.get('aws:cdn') : 'http://localhost:' + port;

            if ((value.type == 'js' && value.extname == '.js') || value.type == 'css') {

                htmlAssets[htmlFile] = htmlAssets[htmlFile] || {
                    content: "<!-- Generated by Bosco -->",
                    type: "html",
                    assetType: value.type,
                    tag: value.tag,
                    extname: ".html"
                };

                if (value.type == 'js') {
                    htmlAssets[htmlFile].content += _.template('<script src="<%= url %>"></script>\n', {
                        'url': cdn + "/" + key
                    });
                } else {
                    htmlAssets[htmlFile].content += _.template('<link rel="stylesheet" href="<%=url %>" type="text/css" media="screen" />\n', {
                        'url': cdn + "/" + key
                    });
                }
            }

        });

        staticAssets = _.merge(htmlAssets, staticAssets);

        staticAssets.formattedAssets = formattedAssets(staticAssets);

        next(null, staticAssets);

    }

    function formattedAssets(staticAssets) {

        var assets = {html: [], js: [], css: [], plain: []},
            templateContent = fs.readFileSync(__dirname + '/../templates/assetList.html'),
            template = hb.compile(templateContent.toString());

        _.map(staticAssets, function(asset, key) {
            assets[asset.type].push(key);
        });

        assets.user = bosco.config.get('github:user');
        assets.date = (new Date()).toString();

        return template(assets);

    }
}<commit_msg>Added carriage return<commit_after>var _ = require('lodash');
var hb = require('handlebars');
var fs = require('fs');

module.exports = function(bosco) {

    var createKey = require('./AssetHelper')(bosco).createKey;

    return {
        createHtmlFiles:createHtmlFiles
    }

    function createHtmlFiles(staticAssets, next) {

        var htmlAssets = {},
            port = bosco.config.get('cdn:port') || "7334";

        _.forOwn(staticAssets, function(value, key) {

            var html,
                htmlFile = createKey(value.tag, value.type, 'html', 'html'),
                cdn = bosco.config.get('aws:cdn') ? bosco.config.get('aws:cdn') : 'http://localhost:' + port;

            if ((value.type == 'js' && value.extname == '.js') || value.type == 'css') {

                htmlAssets[htmlFile] = htmlAssets[htmlFile] || {
                    content: "<!-- Generated by Bosco -->\n",
                    type: "html",
                    assetType: value.type,
                    tag: value.tag,
                    extname: ".html"
                };

                if (value.type == 'js') {
                    htmlAssets[htmlFile].content += _.template('<script src="<%= url %>"></script>\n', {
                        'url': cdn + "/" + key
                    });
                } else {
                    htmlAssets[htmlFile].content += _.template('<link rel="stylesheet" href="<%=url %>" type="text/css" media="screen" />\n', {
                        'url': cdn + "/" + key
                    });
                }
            }

        });

        staticAssets = _.merge(htmlAssets, staticAssets);

        staticAssets.formattedAssets = formattedAssets(staticAssets);

        next(null, staticAssets);

    }

    function formattedAssets(staticAssets) {

        var assets = {html: [], js: [], css: [], plain: []},
            templateContent = fs.readFileSync(__dirname + '/../templates/assetList.html'),
            template = hb.compile(templateContent.toString());

        _.map(staticAssets, function(asset, key) {
            assets[asset.type].push(key);
        });

        assets.user = bosco.config.get('github:user');
        assets.date = (new Date()).toString();

        return template(assets);

    }
}<|endoftext|>


<commit_before>// Don't change to `import * from`, since _bootstrap modifies module.exports
var tags = module.exports = require('./src/tags-all')

import ReactNative from 'react-native'
import {_bootstrap} from './src/tags-all'
import { each, map, isFunction, create } from 'lodash'

var CursorManager = require('react-native-macos').NativeModules.CursorManager
module.exports.Tappable = function(callback) {
	return {
		onPress: function() {
			callback()
		},
		onMouseEnter: function() {
			CursorManager.pointingHandCursor()
		},
		onMouseLeave: function() {
			CursorManager.arrowCursor()
		}
	}
}

class TagsStyleSheet {
	_isTagsStyleSheet () { return true }
	constructor(id) {
		this._tagsStyleSheetId = id
	}
}

tags.StyleSheet = create(ReactNative.StyleSheet, {
	create: function createStyleSheet(props) {
		var res = {}
		var reactStyles = ReactNative.StyleSheet.create(props)
		each(reactStyles, (styleSheetId, key) => {
			res[key] = new TagsStyleSheet(styleSheetId)
		})
		return res
	}
})

// These keys cause runtime warnings and errors when accessed (e.g
// `ReactNative.AppStateIOS` in react-native or
// `ReactNative.Navigator` in react-native-macos)
var avoidBadKeys = {
	// react-native:
	PushNotificationIOS: true, AppStateIOS: true, LinkingIOS: true,
	// react-native-macos:
	StatusBar: true, Navigator: true, TouchableHighlight: true,
}

_bootstrap(_getNativeComponents(avoidBadKeys), function renderNativeApp(AppComponent, name) {
	ReactNative.AppRegistry.registerComponent(name || 'TagsReactNativeApp', () => AppComponent);
})

function _getNativeComponents(avoidBadKeys) {
	var components = {}
	for (var name in ReactNative) {
		if (avoidBadKeys[name]) {
			continue
		}
		if (_isReactComponent(ReactNative[name])) {
			components[name] = ReactNative[name]
		}
	}

	components.Input = components.TextInput

	return components
}

function _isReactComponent(val) {
	return val.prototype && val.prototype.isReactComponent
}
<commit_msg>Be explicit about export statement<commit_after>// Don't change to `import * from`, since _bootstrap modifies module.exports
module.exports = require('./src/tags-all')

import ReactNative from 'react-native'
import {_bootstrap} from './src/tags-all'
import { each, map, isFunction, create } from 'lodash'

var CursorManager = require('react-native-macos').NativeModules.CursorManager
module.exports.Tappable = function(callback) {
	return {
		onPress: function() {
			callback()
		},
		onMouseEnter: function() {
			CursorManager.pointingHandCursor()
		},
		onMouseLeave: function() {
			CursorManager.arrowCursor()
		}
	}
}

class TagsStyleSheet {
	_isTagsStyleSheet () { return true }
	constructor(id) {
		this._tagsStyleSheetId = id
	}
}

module.exports.StyleSheet = create(ReactNative.StyleSheet, {
	create: function createStyleSheet(props) {
		var res = {}
		var reactStyles = ReactNative.StyleSheet.create(props)
		each(reactStyles, (styleSheetId, key) => {
			res[key] = new TagsStyleSheet(styleSheetId)
		})
		return res
	}
})

// These keys cause runtime warnings and errors when accessed (e.g
// `ReactNative.AppStateIOS` in react-native or
// `ReactNative.Navigator` in react-native-macos)
var avoidBadKeys = {
	// react-native:
	PushNotificationIOS: true, AppStateIOS: true, LinkingIOS: true,
	// react-native-macos:
	StatusBar: true, Navigator: true, TouchableHighlight: true,
}

_bootstrap(_getNativeComponents(avoidBadKeys), function renderNativeApp(AppComponent, name) {
	ReactNative.AppRegistry.registerComponent(name || 'TagsReactNativeApp', () => AppComponent);
})

function _getNativeComponents(avoidBadKeys) {
	var components = {}
	for (var name in ReactNative) {
		if (avoidBadKeys[name]) {
			continue
		}
		if (_isReactComponent(ReactNative[name])) {
			components[name] = ReactNative[name]
		}
	}

	components.Input = components.TextInput

	return components
}

function _isReactComponent(val) {
	return val.prototype && val.prototype.isReactComponent
}
<|endoftext|>


<commit_before>import { curry, compose } from './Func';

export const id = (x) => x;

export const negate = (x) => !x;

//:: (a -> b) -> [a] -> void
export const each = curry((fn, xs) => xs.forEach(fn));

//:: (a -> b) -> [a] -> [b]
export const map = curry((fn, xs) => xs.map(fn));

//:: (a -> Bool) -> [a] -> [a]
export const filter = curry((fn, xs) => xs.filter(fn));

//:: [a] -> [a]
export const compact = filter(id);

//:: (a -> Bool) -> [a] -> [a]
export const reject = curry((fn, xs) => xs.filter(compose(fn, negate)));

//:: ((a, b) -> a) -> [b] -> a
export const reduce = curry((fn, xs) => xs.reduce(fn));

//:: (a -> Bool) -> [a] -> [[a] [a]]
export const partition = curry((fn, xs) => {
  let passed = [];
  let failed = [];
  xs.forEach((x) => (fn(x) ? passed : failed ).push(x));
  return [passed, failed];
});

//:: (a -> Bool) -> [a] -> a
export const find = curry((fn, [x, ...xs]) => x
  ? fn(x) ? x : find(fn, xs)
  : undefined
);

//:: [a] -> a
export const head = (xs) => xs[0];

//:: [a] -> [a]
export const tail = ([x, ...xs]) => xs;

//:: [a] -> a
export const first = head;

//:: [a] -> a
export const last = (xs) => xs.slice(-1)[0];

//:: [a] -> [a]
export const initial = (xs) => !xs.length ? undefined : xs.slice(0, -1);

//:: [a] -> Bool
export const empty = (xs) => !xs.length;

//:: [a] -> [a]
export const reverse = (xs) => xs.concat().reverse();

//:: (a -> b) -> [a] -> [a]
export const uniqueBy = curry((f, xs) => {
  let memo = {};
  xs.map(f).forEach((x) => {
    const key = `K_${x}`;
    if (!memo[key]) {
      memo[key] = x;
    }
  });
  return Object.values(memo);
});

//:: [a] -> [a]
export const unique = (xs) => uniqueBy(id, xs);

//:: (b -> a -> b) -> b -> [a] -> b
export const foldl = curry((fn, memo, xs) => xs.reduce(fn, memo));

//:: (a -> a -> a) -> [a] -> a
export const foldl1 = curry((fn, xs) => xs.reduce(fn, 0));

//:: (b -> a -> b) -> b -> [a] -> b
export const foldr = curry((fn, memo, xs) => {
  for (let i = xs.length - 1; i >= 0; i--) {
    memo = fn(xs[i], memo);
  }
  return memo;
});

//:: (a -> a -> a) -> [a] -> a
export const foldr1 = curry((fn, xs) => foldr(fn, 0, xs));

//:: (a -> [b]) -> [a] -> [b]
export const unfoldr = curry((fn, b) => {
  let result = [];
  let x = b;
  let that;
  while ((that = fn(b))) {
    result.push(that[0]);
    x = that[1];
  }
  return result;
});

// aliases

export const fold = foldl;

export const fold1 = foldl1;

export default {
  each,
  map,
  filter,
  compact,
  reject,
  reduce,
  partition,
  find,
  head,
  tail,
  first,
  last,
  initial,
  empty,
  reverse,
  uniqueBy,
  unique,
  fold,
  fold1,
  foldl,
  foldl1,
  foldr,
  foldr1
};
<commit_msg>implement new functions: concat, concatMap<commit_after>import { curry, compose } from './Func';

export const id = (x) => x;

export const negate = (x) => !x;

//:: (a -> b) -> [a] -> void
export const each = curry((fn, xs) => xs.forEach(fn));

//:: (a -> b) -> [a] -> [b]
export const map = curry((fn, xs) => xs.map(fn));

//:: (a -> Bool) -> [a] -> [a]
export const filter = curry((fn, xs) => xs.filter(fn));

//:: [a] -> [a]
export const compact = filter(id);

//:: (a -> Bool) -> [a] -> [a]
export const reject = curry((fn, xs) => xs.filter(compose(fn, negate)));

//:: ((a, b) -> a) -> [b] -> a
export const reduce = curry((fn, xs) => xs.reduce(fn));

//:: (a -> Bool) -> [a] -> [[a] [a]]
export const partition = curry((fn, xs) => {
  let passed = [];
  let failed = [];
  xs.forEach((x) => (fn(x) ? passed : failed ).push(x));
  return [passed, failed];
});

//:: (a -> Bool) -> [a] -> a
export const find = curry((fn, [x, ...xs]) => x
  ? fn(x) ? x : find(fn, xs)
  : undefined
);

//:: [a] -> a
export const head = (xs) => xs[0];

//:: [a] -> [a]
export const tail = ([x, ...xs]) => xs;

//:: [a] -> a
export const first = head;

//:: [a] -> a
export const last = (xs) => xs.slice(-1)[0];

//:: [a] -> [a]
export const initial = (xs) => !xs.length ? undefined : xs.slice(0, -1);

//:: [a] -> Bool
export const empty = (xs) => !xs.length;

//:: [a] -> [a]
export const reverse = (xs) => xs.concat().reverse();

//:: (a -> b) -> [a] -> [a]
export const uniqueBy = curry((f, xs) => {
  let memo = {};
  xs.map(f).forEach((x) => {
    const key = `K_${x}`;
    if (!memo[key]) {
      memo[key] = x;
    }
  });
  return Object.values(memo);
});

//:: [a] -> [a]
export const unique = (xs) => uniqueBy(id, xs);

//:: (b -> a -> b) -> b -> [a] -> b
export const foldl = curry((fn, memo, xs) => xs.reduce(fn, memo));

//:: (a -> a -> a) -> [a] -> a
export const foldl1 = curry((fn, xs) => xs.reduce(fn, 0));

//:: (b -> a -> b) -> b -> [a] -> b
export const foldr = curry((fn, memo, xs) => {
  for (let i = xs.length - 1; i >= 0; i--) {
    memo = fn(xs[i], memo);
  }
  return memo;
});

//:: (a -> a -> a) -> [a] -> a
export const foldr1 = curry((fn, xs) => foldr(fn, 0, xs));

//:: (a -> [b]) -> [a] -> [b]
export const unfoldr = curry((fn, b) => {
  let result = [];
  let x = b;
  let that;
  while ((that = fn(b))) {
    result.push(that[0]);
    x = that[1];
  }
  return result;
});

//:: [[a]] -> [a]
export const concat = (xss) =>
  [].concat.apply([], xss);

//:: (a -> [b]) -> [a] -> [b]
export const concatMap = curry((fn, xs) => {
  return [].concat.apply([], xs.map(fn));
});

// aliases

export const fold = foldl;

export const fold1 = foldl1;

export default {
  each,
  map,
  filter,
  compact,
  reject,
  reduce,
  partition,
  find,
  head,
  tail,
  first,
  last,
  initial,
  empty,
  reverse,
  uniqueBy,
  unique,
  fold,
  fold1,
  foldl,
  foldl1,
  foldr,
  foldr1,
  unfoldr,
  concat,
  concatMap
};
<|endoftext|>


<commit_before><commit_msg>update<commit_after><|endoftext|>


<commit_before>var Account = require('../models/account');

module.exports.index = index;
module.exports.register = register;
module.exports.login = login;
module.exports.logOut = logOut;
module.exports.user = user;

function index(req, res){
	res.send({'user': req.user});
};

function login(req, res){
	console.log('Login!');
	res.send({username : req.body.username, auth : true});
};

function register(req, res, next){
	console.log('Registeration!');
	var username = req.body.username;
	Account.register(new Account({username: req.body.username}), req.body.password, function(err) {
		if (err) {
			console.log('error while user register!', err);
			return next(err);
		}
		console.log('user registered!');
		res.send({'username' : username});

	});
};

function logOut(req, res){
	console.log('logout');
	req.logout();
	res.send({'logout' : true});
};

function user(req, res){
	var username = req.param.username;
	console.log(username);
	Account.findOne({ 'username': username }, function(err, score) {
	  if (err)
	  	return console.error(err);
	  else {
	  	res.send(score);
	  	console.log(score);}
	});
};
<commit_msg>fixed some errors<commit_after>var Account = require('../models/account');

module.exports.index = index;
module.exports.register = register;
module.exports.login = login;
module.exports.logOut = logOut;
module.exports.user = user;

function index(req, res){
	res.send({'user': req.user});
};

function login(req, res){
	console.log('Login!');
	res.send({username : req.body.username, auth : true});
};

function register(req, res, next){
	console.log('Registeration!');
	var username = req.body.username;
	Account.register(new Account({username: req.body.username}), req.body.password, function(err) {
		if (err) {
			console.log('error while user register!', err);
			return next(err);
		}
		console.log('user registered!');
		res.send({'username' : username});

	});
};

function logOut(req, res){
	console.log('logout');
	req.logout();
	res.send({'logout' : true});
};

function user(req, res){
	var username = req.params.username;
	console.log(username);
	Account.findOne({ 'username': username }, function(err, score) {
	  if (err)
	  	return console.error(err);
	  else {
	  	res.send(score);
	  	console.log(score);}
	});
};
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var request = require('request');
var jsdom = require("jsdom");
var models = require("../model/models");

var parseAvito = function () {
    var source = "Avito";
    var base = 'https://www.avito.ru';

    var headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'accept-encoding': 'gzip,deflate,sdch',
        'accept-language': 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
        'cache-control': 'no-cache',
        'cookie': 'u=1stmee8v.lqg4o6.em0occsjdh; dfp_group=81; sessid=b71a201747c8fe3655fcb69853e4d876.1415424228; v=1415517641; __utma=99926606.1087434079.1415211490.1415514483.1415517640.9; __utmb=99926606.10.10.1415517640; __utmc=99926606; __utmz=99926606.1415211490.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
        'pragma': 'no-cache',
        'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'
    };
    var parseItems = function (items) {
        if (items.length == 0) {
            console.log("---- PARSE ITEMS BUNCH FINISHED ----");
            return;
        }
        var item = items.pop();

        var scheduleNextParse = function (delay) {
            setTimeout(function () {
                // start next parsing
                parseItems(items);
            }, delay ? delay : Math.random() * 10000 + 3000);
        }

        models.Apartment.findOne({id: item.id, source: source}, function (err, a) {
            if (err) return console.error(err);
            if (a) {
                console.log("skipped Avito: " + item.id);
                scheduleNextParse(0);
                return;
            }

            var link = base + item.url;
            request({
                url: link,
                encoding: 'utf8',
                timeout: 60000,
                gzip: true,
                jar: true,
                headers: headers
            }, function (error, response, body) {
                console.log("Item page " + link);
                if (!error && response.statusCode == 200) {
                    jsdom.env(body, ["http://code.jquery.com/jquery.js"], function (errors, window) {
                        try {
                            if (errors) return console.error("parse item jsdom error", errors);
                            var $ = window.$;
                            var p = $("h1[itemprop=name]")[0].innerHTML.match(/(\d+)[^,]+,\s(\d+)[^,]+,\s(\d+\/\d+)/);
                            var rooms;
                            var area;
                            var floor;
                            if (!p) {
                                // another case "Студия, 36 м², 5/10 эт."
                                p = $("h1[itemprop=name]")[0].innerHTML.match(/[^,]+,\s(\d+)[^,]+,\s(\d+\/\d+)/);
                                rooms = 0.5;
                                area = p[1];
                                floor = p[2];
                            } else {
                                rooms = p[1];
                                area = p[2];
                                floor = p[3];
                            }
                            var price = $(".description__price .description_price span[itemprop=price]")[0].innerHTML.replace(/[^\d]+/g, "");
                            var address = $(".description_content_company[itemprop=address] span[itemprop=streetAddress]")[0].innerHTML;
                            var district = $(".description_content_company[itemprop=address] span")[0].innerHTML.match(/[^,]+/)[0].split(" ")[1];
                            var description = $("#desc_text")[0].innerHTML;

                            var created;
                            var createdEl = $(".g_92 .item-subtitle");
                            var date = createdEl[0].innerHTML.match(/(\d+) (нояб|дек|сен|окт)\./);
                            if (!date) {
                                date = createdEl[0].innerHTML.match(/(вчера|сегодня)/);
                                if (date) {
                                    switch (date[1]) {
                                        case "вчера":
                                            created = new Date(new Date() - 86400000);
                                            break;
                                        case "сегодня":
                                            created = new Date();
                                            break;
                                    }
                                }
                            } else {
                                switch (date[2]) {
                                    case "сен":
                                        created = new Date(2014, 9, date[1]);
                                        break;
                                    case "окт":
                                        created = new Date(2014, 10, date[1]);
                                        break;
                                    case "нояб":
                                        created = new Date(2014, 11, date[1]);
                                        break;
                                    case "дек":
                                        created = new Date(2014, 12, date[1]);
                                        break;
                                }
                            }
                            if (created) {
                                var a = new models.Apartment({
                                    id: item.id,
                                    url: link,
                                    source: source,
                                    description: description,
                                    district: district,
                                    address: address,
                                    rooms: rooms,
                                    area: area,
                                    floor: floor,
                                    price: price,
                                    parsedAt: new Date(),
                                    createdAt: created
                                });

                                a.save();
                            } else {
                                console.warn("Can't recognize date", createdEl);
                            }
                            console.log('Saved Avito: ' + item.id);
                        } catch (e) {
                            console.warn("Skipped due to parse error", e, e.line, body);
                        }
                        scheduleNextParse();
                    });

                } else {
                    console.error(link, error, response ? response.statusCode : "");
                }
            });
        });
    };

    var parsePage = function (link) {
        request({
            url: link,
            encoding: 'utf8',
            timeout: 60000,
            gzip: true,
            jar: true,
            headers: headers
        }, function (error, response, body) {
            console.log("Page " + link);
            if (!error && response.statusCode == 200) {
                jsdom.env(body, ["http://code.jquery.com/jquery.js"], function (errors, window) {
                    try {
                        if (errors) return console.error("parse page jsdom error", errors, body);
                        var $ = window.$;

                        // iterate through items
                        var items = [];
                        $("div.item").each(function (idx, item) {
                            var url = $(item).find("h3.title a").attr('href');
                            items.push({id: item.id, url: url});
                        });
                        parseItems(items);

                        // get next link
                        var nextEl = $("div.pagination__nav a.pagination__page");
                        if (nextEl.length == 1 && nextEl[0].innerHTML.indexOf("→") < 0) {
                            // if there is no next button reset nextEl
                            nextEl = null;
                        }
                        if (nextEl) {
                            var link = nextEl[nextEl.length == 1 ? 0 : 1].href;
                            link = link.replace(/file:[\/]+(c:)?/, '');
                            setTimeout(function () {
                                parsePage(base + link);
                            }, Math.random() * 10000 + 10000);
                        } else {
                            console.log("---- PARSE PAGES FINISHED ----")
                        }
                    } catch (e) {
                        console.warn("Skipped due to parse error", e, e.line, body);
                    }
                });
            } else {
                console.error(link, error, response ? response.statusCode : "");
            }
        });
    };

    var startLink = 'https://www.avito.ru/izhevsk/kvartiry/prodam/vtorichka/ne_pervyy_i_ne_posledniy?pmax=2000000&pmin=1500000&district=164-165-166&f=59_920b.575_5930';
    parsePage(startLink);
}

router.get('/', function (req, res) {
    parseAvito();
    res.send("Started");
});

module.exports = router;

<commit_msg>fixed Avito parse bug with dates<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');
var jsdom = require("jsdom");
var models = require("../model/models");

var parseAvito = function () {
    var source = "Avito";
    var base = 'https://www.avito.ru';

    var headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'accept-encoding': 'gzip,deflate,sdch',
        'accept-language': 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
        'cache-control': 'no-cache',
        'cookie': 'u=1stmee8v.lqg4o6.em0occsjdh; dfp_group=81; sessid=b71a201747c8fe3655fcb69853e4d876.1415424228; v=1415517641; __utma=99926606.1087434079.1415211490.1415514483.1415517640.9; __utmb=99926606.10.10.1415517640; __utmc=99926606; __utmz=99926606.1415211490.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
        'pragma': 'no-cache',
        'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'
    };
    var parseItems = function (items) {
        if (items.length == 0) {
            console.log("---- PARSE ITEMS BUNCH FINISHED ----");
            return;
        }
        var item = items.pop();

        var scheduleNextParse = function (delay) {
            setTimeout(function () {
                // start next parsing
                parseItems(items);
            }, delay ? delay : Math.random() * 10000 + 3000);
        }

        models.Apartment.findOne({id: item.id, source: source}, function (err, a) {
            if (err) return console.error(err);
            if (a) {
                console.log("skipped Avito: " + item.id);
                scheduleNextParse(0);
                return;
            }

            var link = base + item.url;
            request({
                url: link,
                encoding: 'utf8',
                timeout: 60000,
                gzip: true,
                jar: true,
                headers: headers
            }, function (error, response, body) {
                console.log("Item page " + link);
                if (!error && response.statusCode == 200) {
                    jsdom.env(body, ["http://code.jquery.com/jquery.js"], function (errors, window) {
                        try {
                            if (errors) return console.error("parse item jsdom error", errors);
                            var $ = window.$;
                            var p = $("h1[itemprop=name]")[0].innerHTML.match(/(\d+)[^,]+,\s(\d+)[^,]+,\s(\d+\/\d+)/);
                            var rooms;
                            var area;
                            var floor;
                            if (!p) {
                                // another case "Студия, 36 м², 5/10 эт."
                                p = $("h1[itemprop=name]")[0].innerHTML.match(/[^,]+,\s(\d+)[^,]+,\s(\d+\/\d+)/);
                                rooms = 0.5;
                                area = p[1];
                                floor = p[2];
                            } else {
                                rooms = p[1];
                                area = p[2];
                                floor = p[3];
                            }
                            var price = $(".description__price .description_price span[itemprop=price]")[0].innerHTML.replace(/[^\d]+/g, "");
                            var address = $(".description_content_company[itemprop=address] span[itemprop=streetAddress]")[0].innerHTML;
                            var district = $(".description_content_company[itemprop=address] span")[0].innerHTML.match(/[^,]+/)[0].split(" ")[1];
                            var description = $("#desc_text")[0].innerHTML;

                            var created;
                            var createdEl = $(".g_92 .item-subtitle");
                            var date = createdEl[0].innerHTML.match(/(\d+) (нояб|дек|сен|окт)\./);
                            if (!date) {
                                date = createdEl[0].innerHTML.match(/(вчера|сегодня)/);
                                if (date) {
                                    switch (date[1]) {
                                        case "вчера":
                                            created = new Date(new Date() - 86400000);
                                            break;
                                        case "сегодня":
                                            created = new Date();
                                            break;
                                    }
                                }
                            } else {
                                switch (date[2]) {
                                    case "сен":
                                        created = new Date(2014, 8, date[1]);
                                        break;
                                    case "окт":
                                        created = new Date(2014, 9, date[1]);
                                        break;
                                    case "нояб":
                                        created = new Date(2014, 10, date[1]);
                                        break;
                                    case "дек":
                                        created = new Date(2014, 11, date[1]);
                                        break;
                                }
                            }
                            if (created) {
                                var a = new models.Apartment({
                                    id: item.id,
                                    url: link,
                                    source: source,
                                    description: description,
                                    district: district,
                                    address: address,
                                    rooms: rooms,
                                    area: area,
                                    floor: floor,
                                    price: price,
                                    parsedAt: new Date(),
                                    createdAt: created
                                });

                                a.save();
                            } else {
                                console.warn("Can't recognize date", createdEl);
                            }
                            console.log('Saved Avito: ' + item.id);
                        } catch (e) {
                            console.warn("Skipped due to parse error", e, e.line, body);
                        }
                        scheduleNextParse();
                    });

                } else {
                    console.error(link, error, response ? response.statusCode : "");
                }
            });
        });
    };

    var parsePage = function (link) {
        request({
            url: link,
            encoding: 'utf8',
            timeout: 60000,
            gzip: true,
            jar: true,
            headers: headers
        }, function (error, response, body) {
            console.log("Page " + link);
            if (!error && response.statusCode == 200) {
                jsdom.env(body, ["http://code.jquery.com/jquery.js"], function (errors, window) {
                    try {
                        if (errors) return console.error("parse page jsdom error", errors, body);
                        var $ = window.$;

                        // iterate through items
                        var items = [];
                        $("div.item").each(function (idx, item) {
                            var url = $(item).find("h3.title a").attr('href');
                            items.push({id: item.id, url: url});
                        });
                        parseItems(items);

                        // get next link
                        var nextEl = $("div.pagination__nav a.pagination__page");
                        if (nextEl.length == 1 && nextEl[0].innerHTML.indexOf("→") < 0) {
                            // if there is no next button reset nextEl
                            nextEl = null;
                        }
                        if (nextEl) {
                            var link = nextEl[nextEl.length == 1 ? 0 : 1].href;
                            link = link.replace(/file:[\/]+(c:)?/, '');
                            setTimeout(function () {
                                parsePage(base + link);
                            }, Math.random() * 10000 + 10000);
                        } else {
                            console.log("---- PARSE PAGES FINISHED ----")
                        }
                    } catch (e) {
                        console.warn("Skipped due to parse error", e, e.line, body);
                    }
                });
            } else {
                console.error(link, error, response ? response.statusCode : "");
            }
        });
    };

    var startLink = 'https://www.avito.ru/izhevsk/kvartiry/prodam/vtorichka/ne_pervyy_i_ne_posledniy?pmax=2000000&pmin=1500000&district=164-165-166&f=59_920b.575_5930';
    parsePage(startLink);
};

router.get('/', function (req, res) {
    parseAvito();
    res.send("Started");
});

module.exports = router;

<|endoftext|>


<commit_before>// @
// Copyright (c) 2017 Google Inc. All rights reserved.
// This code may only be used under the BSD style license found at
// http://polymer.github.io/LICENSE.txt
// Code distributed by Google as part of this project is also
// subject to an additional IP rights grant found at
// http://polymer.github.io/PATENTS.txt
'use strict';

const assert = require('assert');
const tracing = require("tracelib");
const scheduler = require('./scheduler.js');

class ViewBase {
  constructor(type, arc, name, id) {
    var trace = tracing.start({cat: 'view', name: 'ViewBase::constructor', args: {type: type.key, name: name}});
    this._type = type;
    this._arc = arc;
    this._listeners = new Map();
    this.name = name;
    this._version = 0;
    this.id = id || this._arc.generateID();
    trace.end();
  }

  generateID() {
    return this._arc.generateID();
  }

  get type() {
    return this._type;
  }
  // TODO: add 'once' which returns a promise.
  on(kind,  callback, target) {
    assert(target !== undefined, "must provide a target to register a view event handler");
    let listeners = this._listeners.get(kind) || new Map();
    listeners.set(callback, {version: -Infinity, target});
    this._listeners.set(kind, listeners);
  }

  _fire(kind, details) {
    var listenerMap = this._listeners.get(kind);
    if (!listenerMap || listenerMap.size == 0)
      return;

    var callTrace = tracing.start({cat: 'view', name: 'ViewBase::_fire', args: {kind, type: this._type.key,
        name: this.name, listeners: listenerMap.size}});

    // TODO: wire up a target (particle)
    let eventRecords = [];

    for (let [callback, registration] of listenerMap.entries()) {
      let target = registration.target;
      eventRecords.push({target, callback, kind, details});
    }

    scheduler.enqueue(this, eventRecords);

    callTrace.end();
  }
}

class View extends ViewBase {
  constructor(type, arc, name, id) {
    super(type, arc, name, id);
    this._items = new Map();
  }

  clone() {
    var view = new View(this._type, this._arc, this.name);
    view._items = new Map();
    [...this._items.keys()].forEach(key => view._items.set(key, this._items.get(key)));
    view._version = this._version;
    view.description = this.description;
    return view;
  }

  get(id) {
    return this._items.get(id);
  }
  traceInfo() {
    return {items: this._items.size};
  }
  // HACK: replace this with some kind of iterator thing?
  toList() {
    return [...this._items.values()];
  }
  // thing()

  store(entity) {
    var trace = tracing.start({cat: "view", name: "View::store", args: {name: this.name}});
    var entityWasPresent = this._items.has(entity.id);

    this._items.set(entity.id, entity);
    this._version++;
    trace.update({ entity });
    if (!entityWasPresent)
      this._fire('change', {add: [entity], version: this._version});
    trace.end();
  }

  remove(id) {
    var trace = tracing.start({cat: "view", name: "View::remove", args: {name: this.name}});
    if (!this._items.has(id)) {
      return;
    }
    let entity = this._items.get(id);
    assert(this._items.delete(id));
    this._version++;
    trace.update({ entity });
    this._fire('change', {remove: [entity], version: this._version});
    trace.end();
  }

  // TODO: Something about iterators??
  // TODO: Something about changing order?

  extractEntities(set) {
    this._items.forEach(a => set.add(a));
  }

  serialize(list) {
    list.push({
      id: this.id,
      sort: 'view',
      type: this.type.toLiteral(),
      name: this.name,
      values: this.toList().map(a => a.id),
      version: this._version
    });
  }

  serializeMappingRecord(list) {
    list.push({
      id: this.id,
      sort: 'view',
      type: this.type.toLiteral(),
      name: this.name,
      version: this._version,
      arc: this._arc.id
    })
  }
}

class Variable extends ViewBase {
  constructor(type, arc, name, id) {
    super(type, arc, name, id);
    this._stored = null;
  }

  clone() {
    var variable = new Variable(this._type, this._arc, this.name);
    variable._stored = this._stored;
    variable._version = this._version;
    return variable;
  }

  traceInfo() {
    return {stored: this._stored !== null};
  }

  get() {
    return this._stored;
  }

  set(entity) {
    this._stored = entity;
    this._version++;
    this._fire('change', {data: this._stored, version: this._version});
  }

  clear() {
    this.set(undefined);
  }

  extractEntities(set) {
    if (!this._stored) {
      return;
    }
    set.add(this._stored);
  }

  serialize(list) {
    if (this._stored == undefined)
      return;
    list.push({
      id: this.id,
      sort: 'variable',
      type: this.type.toLiteral(),
      name: this.name,
      value: this._stored.id,
      version: this._version
    });
  }

  serializeMappingRecord(list) {
    list.push({
      id: this.id,
      sort: 'variable',
      type: this.type.toLiteral(),
      name: this.name,
      version: this._version,
      arc: this._arc.id
    })
  }
}

Object.assign(module.exports, {
  View,
  Variable,
});
<commit_msg>update view clone method<commit_after>// @
// Copyright (c) 2017 Google Inc. All rights reserved.
// This code may only be used under the BSD style license found at
// http://polymer.github.io/LICENSE.txt
// Code distributed by Google as part of this project is also
// subject to an additional IP rights grant found at
// http://polymer.github.io/PATENTS.txt
'use strict';

const assert = require('assert');
const tracing = require("tracelib");
const scheduler = require('./scheduler.js');

class ViewBase {
  constructor(type, arc, name, id) {
    var trace = tracing.start({cat: 'view', name: 'ViewBase::constructor', args: {type: type.key, name: name}});
    this._type = type;
    this._arc = arc;
    this._listeners = new Map();
    this.name = name;
    this._version = 0;
    this.id = id || this._arc.generateID();
    trace.end();
  }

  generateID() {
    return this._arc.generateID();
  }

  get type() {
    return this._type;
  }
  // TODO: add 'once' which returns a promise.
  on(kind,  callback, target) {
    assert(target !== undefined, "must provide a target to register a view event handler");
    let listeners = this._listeners.get(kind) || new Map();
    listeners.set(callback, {version: -Infinity, target});
    this._listeners.set(kind, listeners);
  }

  _fire(kind, details) {
    var listenerMap = this._listeners.get(kind);
    if (!listenerMap || listenerMap.size == 0)
      return;

    var callTrace = tracing.start({cat: 'view', name: 'ViewBase::_fire', args: {kind, type: this._type.key,
        name: this.name, listeners: listenerMap.size}});

    // TODO: wire up a target (particle)
    let eventRecords = [];

    for (let [callback, registration] of listenerMap.entries()) {
      let target = registration.target;
      eventRecords.push({target, callback, kind, details});
    }

    scheduler.enqueue(this, eventRecords);

    callTrace.end();
  }
}

class View extends ViewBase {
  constructor(type, arc, name, id) {
    super(type, arc, name, id);
    this._items = new Map();
  }

  clone() {
    var view = new View(this._type, this._arc, this.name);
    view._items = new Map(this._items);
    view._version = this._version;
    view.description = this.description;
    return view;
  }

  get(id) {
    return this._items.get(id);
  }
  traceInfo() {
    return {items: this._items.size};
  }
  // HACK: replace this with some kind of iterator thing?
  toList() {
    return [...this._items.values()];
  }
  // thing()

  store(entity) {
    var trace = tracing.start({cat: "view", name: "View::store", args: {name: this.name}});
    var entityWasPresent = this._items.has(entity.id);

    this._items.set(entity.id, entity);
    this._version++;
    trace.update({ entity });
    if (!entityWasPresent)
      this._fire('change', {add: [entity], version: this._version});
    trace.end();
  }

  remove(id) {
    var trace = tracing.start({cat: "view", name: "View::remove", args: {name: this.name}});
    if (!this._items.has(id)) {
      return;
    }
    let entity = this._items.get(id);
    assert(this._items.delete(id));
    this._version++;
    trace.update({ entity });
    this._fire('change', {remove: [entity], version: this._version});
    trace.end();
  }

  // TODO: Something about iterators??
  // TODO: Something about changing order?

  extractEntities(set) {
    this._items.forEach(a => set.add(a));
  }

  serialize(list) {
    list.push({
      id: this.id,
      sort: 'view',
      type: this.type.toLiteral(),
      name: this.name,
      values: this.toList().map(a => a.id),
      version: this._version
    });
  }

  serializeMappingRecord(list) {
    list.push({
      id: this.id,
      sort: 'view',
      type: this.type.toLiteral(),
      name: this.name,
      version: this._version,
      arc: this._arc.id
    })
  }
}

class Variable extends ViewBase {
  constructor(type, arc, name, id) {
    super(type, arc, name, id);
    this._stored = null;
  }

  clone() {
    var variable = new Variable(this._type, this._arc, this.name);
    variable._stored = this._stored;
    variable._version = this._version;
    return variable;
  }

  traceInfo() {
    return {stored: this._stored !== null};
  }

  get() {
    return this._stored;
  }

  set(entity) {
    this._stored = entity;
    this._version++;
    this._fire('change', {data: this._stored, version: this._version});
  }

  clear() {
    this.set(undefined);
  }

  extractEntities(set) {
    if (!this._stored) {
      return;
    }
    set.add(this._stored);
  }

  serialize(list) {
    if (this._stored == undefined)
      return;
    list.push({
      id: this.id,
      sort: 'variable',
      type: this.type.toLiteral(),
      name: this.name,
      value: this._stored.id,
      version: this._version
    });
  }

  serializeMappingRecord(list) {
    list.push({
      id: this.id,
      sort: 'variable',
      type: this.type.toLiteral(),
      name: this.name,
      version: this._version,
      arc: this._arc.id
    })
  }
}

Object.assign(module.exports, {
  View,
  Variable,
});
<|endoftext|>


<commit_before>import { Map } from 'immutable';
import { handleActions } from 'redux-actions';
import uuid from 'uuid/v4';
import fileReducer from './file';
import {
  FOLDER_OPEN, FILE_NEW, FILE_OPEN, FILE_READ, FILE_CLOSE_CONFIRMED, FILE_SELECT,
  FILE_SAVE_CONFIRMED, FILE_SAVE_AS, FILE_WRITE, FILE_UPDATE, FILE_SELECTION, FILE_DISCARD
} from '../actions/files';
import { REPLACER_FIND, REPLACER_REPLACE, REPLACER_REPLACE_ALL } from '../actions/replacer';

const initialState = Map({
  folder: null,
  files: Map({}),
  paths: Map({}),
  currentFile: null
});

const filesReducer = handleActions({
  [FOLDER_OPEN]: (state, { payload }) => {
    const { path } = payload;
    return state.set('folder', path);
  },
  [FILE_NEW]: (state, { payload }) => {
    const { id } = payload;
    let files = state.get('files');
    const file = fileReducer(undefined, { type: FILE_NEW });
    files = files.set(id, file);
    return state.merge({ currentFile: id, files });
  },
  [FILE_OPEN]: (state, action) => {
    const { payload: { path } } = action;
    const currentFile = state.get('currentFile');
    let paths = state.get('paths');
    let files = state.get('files');
    let file = state.getIn(['files', currentFile]);
    let id;
    if (files.size === 1 && !file.get('path') && file.get('contents') === '') {
      file = fileReducer(file, action);
      id = currentFile;
    } else {
      id = state.getIn(['paths', path], uuid());
      file = state.getIn(['files', id], fileReducer(file, action));
    }
    paths = paths.set(path, id);
    files = files.set(id, file);
    return state.merge({ currentFile: id, files, paths });
  },
  [FILE_READ]: (state, action) => {
    const { payload: { path } } = action;
    const paths = state.get('paths');
    const id = paths.get(path);
    let files = state.get('files');
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    files = files.set(id, file);
    return state.set('files', files);
  },
  [FILE_CLOSE_CONFIRMED]: (state, { payload }) => {
    let { id } = payload;
    if (!id) {
      id = state.get('currentFile');
    }
    const files = state.get('files');
    const paths = state.get('paths');
    const file = files.get(id);
    let currentFile = state.get('currentFile');
    if (id === currentFile) {
      const otherFile = files.filter((f, idx) => idx !== id).last();
      if (otherFile) {
        currentFile = paths.get(otherFile.get('path'));
      } else {
        currentFile = null;
      }
    }
    return state.merge({ currentFile, files: files.delete(id), paths: paths.delete(file.get('path')) });
  },
  [FILE_DISCARD]: (state, { payload }) => {
    const { id } = payload;
    const files = state.get('files');
    const paths = state.get('paths');
    const file = files.get(id);
    let currentFile = state.get('currentFile');
    if (id === currentFile) {
      const otherFile = files.filter((f, idx) => idx !== id).last();
      if (otherFile) {
        currentFile = paths.get(otherFile.get('path'));
      } else {
        currentFile = null;
      }
    }
    return state.merge({ currentFile, files: files.delete(id), paths: paths.delete(file.get('path')) });
  },
  [FILE_SELECT]: (state, { payload }) => {
    const { id } = payload;
    return state.set('currentFile', id);
  },
  [FILE_UPDATE]: (state, action) => {
    const id = state.get('currentFile');
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  },
  [FILE_SELECTION]: (state, action) => {
    const id = state.get('currentFile');
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  },
  [FILE_SAVE_CONFIRMED]: (state, action) => {
    let { payload: { id } } = action;
    if (!id) {
      id = state.get('currentFile');
    }
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  },
  [FILE_SAVE_AS]: (state, action) => {
    const { payload: { id, path } } = action;
    let file = state.getIn(['files', id]);
    let paths = state.get('paths');
    paths = paths.set(path, id);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file).set('paths', paths);
  },
  [FILE_WRITE]: (state, action) => {
    let { payload: { id } } = action;
    if (!id) {
      id = state.get('currentFile');
    }
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  },
  [REPLACER_FIND]: (state, action) => {
    const id = state.get('currentFile');
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  },
  [REPLACER_REPLACE]: (state, action) => {
    const id = state.get('currentFile');
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  },
  [REPLACER_REPLACE_ALL]: (state, action) => {
    const id = state.get('currentFile');
    let file = state.getIn(['files', id]);
    file = fileReducer(file, action);
    return state.setIn(['files', id], file);
  }
}, initialState);

export default filesReducer;
<commit_msg>Cleanup files reducer using `updateIn` and `update`<commit_after>import { Map } from 'immutable';
import { handleActions } from 'redux-actions';
import uuid from 'uuid/v4';
import fileReducer from './file';
import {
  FOLDER_OPEN, FILE_NEW, FILE_OPEN, FILE_READ, FILE_CLOSE_CONFIRMED, FILE_SELECT,
  FILE_SAVE_CONFIRMED, FILE_SAVE_AS, FILE_WRITE, FILE_UPDATE, FILE_SELECTION, FILE_DISCARD
} from '../actions/files';
import { REPLACER_FIND, REPLACER_REPLACE, REPLACER_REPLACE_ALL } from '../actions/replacer';

const initialState = Map({
  folder: null,
  files: Map({}),
  paths: Map({}),
  currentFile: null
});

const filesReducer = handleActions({
  [FOLDER_OPEN]: (state, { payload }) => {
    const { path } = payload;
    return state.set('folder', path);
  },
  [FILE_NEW]: (state, { payload }) => {
    const { id } = payload;
    return state
      .update('files', files => files.set(id, fileReducer(undefined, { type: FILE_NEW })))
      .set('currentFile', id);
  },
  [FILE_OPEN]: (state, action) => {
    const { payload: { path } } = action;
    const currentFile = state.get('currentFile');
    let paths = state.get('paths');
    let files = state.get('files');
    let file = state.getIn(['files', currentFile]);
    let id;
    if (files.size === 1 && !file.get('path') && file.get('contents') === '') {
      file = fileReducer(file, action);
      id = currentFile;
    } else {
      id = state.getIn(['paths', path], uuid());
      file = state.getIn(['files', id], fileReducer(file, action));
    }
    paths = paths.set(path, id);
    files = files.set(id, file);
    return state.merge({ currentFile: id, files, paths });
  },
  [FILE_READ]: (state, action) => {
    const { payload: { path } } = action;
    const paths = state.get('paths');
    const id = paths.get(path);
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [FILE_CLOSE_CONFIRMED]: (state, { payload }) => {
    let { id } = payload;
    if (!id) {
      id = state.get('currentFile');
    }
    const files = state.get('files');
    const paths = state.get('paths');
    const file = files.get(id);
    let currentFile = state.get('currentFile');
    if (id === currentFile) {
      const otherFile = files.filter((f, idx) => idx !== id).last();
      if (otherFile) {
        currentFile = paths.get(otherFile.get('path'));
      } else {
        currentFile = null;
      }
    }
    return state.merge({ currentFile, files: files.delete(id), paths: paths.delete(file.get('path')) });
  },
  [FILE_DISCARD]: (state, { payload }) => {
    const { id } = payload;
    const files = state.get('files');
    const paths = state.get('paths');
    const file = files.get(id);
    let currentFile = state.get('currentFile');
    if (id === currentFile) {
      const otherFile = files.filter((f, idx) => idx !== id).last();
      if (otherFile) {
        currentFile = paths.get(otherFile.get('path'));
      } else {
        currentFile = null;
      }
    }
    return state.merge({ currentFile, files: files.delete(id), paths: paths.delete(file.get('path')) });
  },
  [FILE_SELECT]: (state, { payload }) => {
    const { id } = payload;
    return state.set('currentFile', id);
  },
  [FILE_UPDATE]: (state, action) => {
    const id = state.get('currentFile');
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [FILE_SELECTION]: (state, action) => {
    const id = state.get('currentFile');
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [FILE_SAVE_CONFIRMED]: (state, action) => {
    let { payload: { id } } = action;
    if (!id) {
      id = state.get('currentFile');
    }
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [FILE_SAVE_AS]: (state, action) => {
    const { payload: { id, path } } = action;
    return state
      .update('paths', paths => paths.set(path, id))
      .updateIn(['files', id], file => fileReducer(file, action));
  },
  [FILE_WRITE]: (state, action) => {
    let { payload: { id } } = action;
    if (!id) {
      id = state.get('currentFile');
    }
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [REPLACER_FIND]: (state, action) => {
    const id = state.get('currentFile');
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [REPLACER_REPLACE]: (state, action) => {
    const id = state.get('currentFile');
    return state.updateIn(['files', id], file => fileReducer(file, action));
  },
  [REPLACER_REPLACE_ALL]: (state, action) => {
    const id = state.get('currentFile');
    return state.updateIn(['files', id], file => fileReducer(file, action));
  }
}, initialState);

export default filesReducer;
<|endoftext|>