<commit_before>// @flow
import { HKT } from './HKT'
import type { Functor } from './Functor'

export interface Apply<F> extends Functor<F> {
  ap<A, B>(fab: HKT<F, (a: A) => B>, fa: HKT<F, A>): HKT<F, B>
}

export function liftA2<F, A, B, C>(apply: Apply<F>, f: (a: A, b: B) => C): (fa: HKT<F, A>, fb: HKT<F, B>) => HKT<F, C> {
  const cf = a => b => f(a, b)
  return (fa, fb) => apply.ap(apply.map(cf, fa), fb)
}
<commit_msg>add liftA3, liftA4<commit_after>// @flow
import { HKT } from './HKT'
import type { Functor } from './Functor'

export interface Apply<F> extends Functor<F> {
  ap<A, B>(fab: HKT<F, (a: A) => B>, fa: HKT<F, A>): HKT<F, B>
}

export function liftA2<F, A, B, C>(apply: Apply<F>, f: (a: A, b: B) => C): (fa: HKT<F, A>, fb: HKT<F, B>) => HKT<F, C> {
  const cf = a => b => f(a, b)
  return (fa, fb) => apply.ap(apply.map(cf, fa), fb)
}

export function liftA3<F, A, B, C, D>(apply: Apply<F>, f: (a: A, b: B, c: C) => D): (fa: HKT<F, A>, fb: HKT<F, B>, fc: HKT<F, C>) => HKT<F, D> {
  const cf = a => b => c => f(a, b, c)
  return (fa, fb, fc) => apply.ap(apply.ap(apply.map(cf, fa), fb), fc)
}

export function liftA4<F, A, B, C, D, E>(apply: Apply<F>, f: (a: A, b: B, c: C, d: D) => E): (fa: HKT<F, A>, fb: HKT<F, B>, fc: HKT<F, C>, fd: HKT<F, D>) => HKT<F, E> {
  const cf = a => b => c => d => f(a, b, c, d)
  return (fa, fb, fc, fd) => apply.ap(apply.ap(apply.ap(apply.map(cf, fa), fb), fc), fd)
}
<|endoftext|>


<commit_before>var Game = require('crtrdg-gameloop');
var Keyboard = require('crtrdg-keyboard');
var Mouse = require('crtrdg-mouse');
var Player = require('./player.js')
var Camera = require('./camera.js')
var World = require('./world.js')

var game = new Game({
  canvas: 'game',
  width: 900,
  height: 500
});

var keyboard = new Keyboard(game)
var mouse = new Mouse(game)
var world = new World()

var player = new Player({
  position: { x: 0, y: 0 },
  orientation: 0,
  size: { x: 2, y: 2 },
  velocity: { x: 0, y: 0 },
  speed: .7,
  friction: 0.9,
  color: '#EB7576'
});

var camera = new Camera({
  position: {x: 0, y:0, z: 80},
  orientation: 0,
  speed: 2,
  velocity: 0,
  friction: 0.9,
  velocity: { x: 0, y: 0, z: 0},
  yoked: false
})

player.addTo(game)
camera.addTo(game)

player.on('update', function(interval) {
  this.keyboardInput(keyboard);
  this.move(this.velocity)
  this.velocity.x *= this.friction;
  this.velocity.y *= this.friction;
  this.checkBoundaries();
});

camera.on('update', function(interval) {
  this.keyboardInput(keyboard)
  this.move(this.velocity)
  this.velocity.x *= this.friction
  this.velocity.y *= this.friction
  this.velocity.z *= this.friction
})

game.on('draw-background', function(context) {
  context.fillStyle = '#F7F7F7'
  context.fillRect(0, 0, game.width, game.height)
})

game.on('update', function(interval){
  // get camera coordinates
  // draw world within those coordinates
  // need a function that renders a world given a camera (zoom, position, orientation)
});

game.on('draw', function(context){
  if (camera.yoked){
    camera.position.x = player.position.x * 0.1 * camera.position.z
    camera.position.y = player.position.y * 0.1 * camera.position.z
    camera.orientation = player.orientation
  }
  world.render(context, camera)
  player.render(context, camera)
});

game.on('pause', function(){});

game.on('resume', function(){});
<commit_msg>Put in 1st person mode<commit_after>var Game = require('crtrdg-gameloop');
var Keyboard = require('crtrdg-keyboard');
var Mouse = require('crtrdg-mouse');
var Player = require('./player.js')
var Camera = require('./camera.js')
var World = require('./world.js')

var game = new Game({
  canvas: 'game',
  width: 900,
  height: 500
});

var keyboard = new Keyboard(game)
var mouse = new Mouse(game)
var world = new World()

var player = new Player({
  position: { x: 0, y: 0 },
  orientation: 0,
  size: { x: 2, y: 2 },
  velocity: { x: 0, y: 0 },
  speed: .7,
  friction: 0.9,
  color: '#EB7576'
});

var camera = new Camera({
  position: {x: 0, y:0, z: 80},
  orientation: 0,
  speed: 2,
  velocity: 0,
  friction: 0.9,
  velocity: { x: 0, y: 0, z: 0},
  yoked: true
})

player.addTo(game)
camera.addTo(game)

player.on('update', function(interval) {
  this.keyboardInput(keyboard);
  this.move(this.velocity)
  this.velocity.x *= this.friction;
  this.velocity.y *= this.friction;
  this.checkBoundaries();
});

camera.on('update', function(interval) {
  this.keyboardInput(keyboard)
  this.move(this.velocity)
  this.velocity.x *= this.friction
  this.velocity.y *= this.friction
  this.velocity.z *= this.friction
})

game.on('draw-background', function(context) {
  context.fillStyle = '#F7F7F7'
  context.fillRect(0, 0, game.width, game.height)
})

game.on('update', function(interval){
  // get camera coordinates
  // draw world within those coordinates
  // need a function that renders a world given a camera (zoom, position, orientation)
});

game.on('draw', function(context){
  if (camera.yoked){
    camera.position.x = player.position.x * 0.1 * camera.position.z
    camera.position.y = player.position.y * 0.1 * camera.position.z
    camera.orientation = player.orientation
  }
  world.render(context, camera)
  player.render(context, camera)
});

game.on('pause', function(){});

game.on('resume', function(){});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Maxwell Dreytser
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// If you would like IE 8 support, include the polyfill here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Compatibility
/**
 * Adds a speech bubble above or below the specified element.
 * @param {HTMLElement} element - Element that the
 * @param {string} content - What the bubble will contain (html is ok).
 * @param {string} [additionalcssclass] The CSS class to add to the element.
 * @returns {HTMLElement} The Speech Bubble element.
 */
window.SpeechBubble = function(element, content, additionalcssclass){
	// http://stackoverflow.com/a/34014786/1610754 and http://stackoverflow.com/a/442474/1610754
	function getOffset(elm) {
		// Find the offset of elm from the body or html element
		var _x = 0;
		var _y = 0;
		while( elm && !isNaN( elm.offsetLeft ) && !isNaN( elm.offsetTop ) )
		{
			_x += elm.offsetLeft - elm.scrollLeft + elm.clientLeft;
			_y += elm.offsetTop - elm.scrollTop + elm.clientTop;
			elm = elm.offsetParent;
		}
		return { top: _y, left: _x };
	}

	var SpeechDiv = document.createElement('div');
	if (additionalcssclass) {
		SpeechDiv.className = 'speech-bubble-main speech-bubble-top ' + additionalcssclass;
	} else {
		SpeechDiv.className = 'speech-bubble-main speech-bubble-top';
	}
	SpeechDiv.innerHTML = content;
	SpeechDiv.setAttribute("style", "");
	document.getElementsByTagName('body')[0].appendChild(SpeechDiv);

	var SpeechStyle = document.createElement('style');
	document.getElementsByTagName('body')[0].appendChild(SpeechStyle);

	function DoAutoPosition() {
		var elmXY = getOffset(element);

		var speechX;
		var speechY;

		var elmWidth = (element.clientWidth || element.offsetWidth);
		var elmHeight = (element.clientHeight || element.offsetHeight);

		if (elmXY.top + elmHeight + SpeechDiv.clientHeight + 23 > (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight)) {
			var appliedClasses = SpeechDiv.className.split(' ');
			for ( var i = 0; i < appliedClasses.length; i++ ) {
				if (appliedClasses[i] == 'speech-bubble-top') {
					appliedClasses[i] = 'speech-bubble-bottom';
				}
			}
			SpeechDiv.className = appliedClasses.join(' ');

			speechY = elmXY.top - SpeechDiv.clientHeight - 28;
		} else {
			var appliedClasses = SpeechDiv.className.split(' ');
			for ( var i = 0; i < appliedClasses.length; i++ ) {
				if (appliedClasses[i] == 'speech-bubble-bottom') {
					appliedClasses[i] = 'speech-bubble-top';
				}
			}
			SpeechDiv.className = appliedClasses.join(' ');

			speechY = elmXY.top + elmHeight + 18;
		}

		if (SpeechDiv.clientWidth < element.clientWidth)
			speechX = elmXY.left + (element.clientWidth - SpeechDiv.clientWidth) / 2;
		else
			speechX = elmXY.left;

		SpeechStyle.innerHTML =
			'.speech-bubble-main {' +
			'  left: ' + speechX + 'px;' +
			'  top: ' + speechY + 'px;' +
			'}' +
			'.speech-bubble-main:before {';
		if (SpeechDiv.clientWidth < elmWidth)
			SpeechStyle.innerHTML += '  left: ' + ((SpeechDiv.clientWidth - 20) / 2 - 7) + 'px';
		else
			SpeechStyle.innerHTML += '  left: ' + (elmWidth / 2 - 27) + 'px;';
		SpeechStyle.innerHTML +=
			'}' +
			'.speech-bubble-main:after {';
		if (SpeechDiv.clientWidth < elmWidth)
			SpeechStyle.innerHTML += '  left: ' + ((SpeechDiv.clientWidth - 20) / 2) + 'px';
		else
			SpeechStyle.innerHTML += '  left: ' + (elmWidth / 2 - 20) + 'px;';
		SpeechStyle.innerHTML += '}';
	}

	DoAutoPosition();

	window.addEventListener('resize', function(){
		DoAutoPosition();
	}, true);

	SpeechDiv.removeBubble = function() {
		SpeechStyle.parentNode.removeChild(SpeechStyle);
		SpeechDiv.parentNode.removeChild(SpeechDiv);

		for ( var i = 0; i < OpenSpeechBubbles.length; i++ ) {
			if (OpenSpeechBubbles[i] == SpeechDiv) {
				OpenSpeechBubbles.splice(i, 1);
			}
		}
	};

	OpenSpeechBubbles.push(SpeechDiv);

	return SpeechDiv;
};

window.OpenSpeechBubbles = [];<commit_msg>Minor naming change.<commit_after>/*
 * Copyright (c) 2016 Maxwell Dreytser
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// If you would like IE 8 support, include the polyfill here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Compatibility
/**
 * Adds a speech bubble above or below the specified element.
 * @param {HTMLElement} element - Element that the
 * @param {string} content - What the bubble will contain (html is ok).
 * @param {string} [additionalcssclasses] The CSS class to add to the element.
 * @returns {HTMLElement} The Speech Bubble element.
 */
window.SpeechBubble = function(element, content, additionalcssclasses){
	// http://stackoverflow.com/a/34014786/1610754 and http://stackoverflow.com/a/442474/1610754
	function getOffset(elm) {
		// Find the offset of elm from the body or html element
		var _x = 0;
		var _y = 0;
		while( elm && !isNaN( elm.offsetLeft ) && !isNaN( elm.offsetTop ) )
		{
			_x += elm.offsetLeft - elm.scrollLeft + elm.clientLeft;
			_y += elm.offsetTop - elm.scrollTop + elm.clientTop;
			elm = elm.offsetParent;
		}
		return { top: _y, left: _x };
	}

	var SpeechDiv = document.createElement('div');
	if (additionalcssclasses) {
		SpeechDiv.className = 'speech-bubble-main speech-bubble-top ' + additionalcssclasses;
	} else {
		SpeechDiv.className = 'speech-bubble-main speech-bubble-top';
	}
	SpeechDiv.innerHTML = content;
	SpeechDiv.setAttribute("style", "");
	document.getElementsByTagName('body')[0].appendChild(SpeechDiv);

	var SpeechStyle = document.createElement('style');
	document.getElementsByTagName('body')[0].appendChild(SpeechStyle);

	function DoAutoPosition() {
		var elmXY = getOffset(element);

		var speechX;
		var speechY;

		var elmWidth = (element.clientWidth || element.offsetWidth);
		var elmHeight = (element.clientHeight || element.offsetHeight);

		if (elmXY.top + elmHeight + SpeechDiv.clientHeight + 23 > (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight)) {
			var appliedClasses = SpeechDiv.className.split(' ');
			for ( var i = 0; i < appliedClasses.length; i++ ) {
				if (appliedClasses[i] == 'speech-bubble-top') {
					appliedClasses[i] = 'speech-bubble-bottom';
				}
			}
			SpeechDiv.className = appliedClasses.join(' ');

			speechY = elmXY.top - SpeechDiv.clientHeight - 28;
		} else {
			var appliedClasses = SpeechDiv.className.split(' ');
			for ( var i = 0; i < appliedClasses.length; i++ ) {
				if (appliedClasses[i] == 'speech-bubble-bottom') {
					appliedClasses[i] = 'speech-bubble-top';
				}
			}
			SpeechDiv.className = appliedClasses.join(' ');

			speechY = elmXY.top + elmHeight + 18;
		}

		if (SpeechDiv.clientWidth < element.clientWidth)
			speechX = elmXY.left + (element.clientWidth - SpeechDiv.clientWidth) / 2;
		else
			speechX = elmXY.left;

		SpeechStyle.innerHTML =
			'.speech-bubble-main {' +
			'  left: ' + speechX + 'px;' +
			'  top: ' + speechY + 'px;' +
			'}' +
			'.speech-bubble-main:before {';
		if (SpeechDiv.clientWidth < elmWidth)
			SpeechStyle.innerHTML += '  left: ' + ((SpeechDiv.clientWidth - 20) / 2 - 7) + 'px';
		else
			SpeechStyle.innerHTML += '  left: ' + (elmWidth / 2 - 27) + 'px;';
		SpeechStyle.innerHTML +=
			'}' +
			'.speech-bubble-main:after {';
		if (SpeechDiv.clientWidth < elmWidth)
			SpeechStyle.innerHTML += '  left: ' + ((SpeechDiv.clientWidth - 20) / 2) + 'px';
		else
			SpeechStyle.innerHTML += '  left: ' + (elmWidth / 2 - 20) + 'px;';
		SpeechStyle.innerHTML += '}';
	}

	DoAutoPosition();

	window.addEventListener('resize', function(){
		DoAutoPosition();
	}, true);

	SpeechDiv.removeBubble = function() {
		SpeechStyle.parentNode.removeChild(SpeechStyle);
		SpeechDiv.parentNode.removeChild(SpeechDiv);

		for ( var i = 0; i < OpenSpeechBubbles.length; i++ ) {
			if (OpenSpeechBubbles[i] == SpeechDiv) {
				OpenSpeechBubbles.splice(i, 1);
			}
		}
	};

	OpenSpeechBubbles.push(SpeechDiv);

	return SpeechDiv;
};

window.OpenSpeechBubbles = [];<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Thread from './Thread';
import ThreadList from './ThreadList';
import ThreadSubmitForm from './ThreadSubmitForm';
import './styles/Board.css';

class Board extends Component {
  constructor(props) {
    super(props);

    this.state = {
      info: {
        name: 'Loading',
        abbreviation: props.params.abbreviation,
        description: ''
      }
    };
  }

  componentDidMount() {
    // fetch initial state when the Board component is used for the first time
    this.fetchBoardInfo();
  }

  componentDidUpdate(oldProps) {
    // user probably switched from a board to another board, ignore if old board === this board
    if (oldProps.params.abbreviation !== this.props.params.abbreviation)
      this.fetchBoardInfo();
  }

  fetchBoardInfo() {
    fetch('/api/boards/' + this.props.params.abbreviation).then((data, err) => {
      if (err) {
        // TODO: UI for API errors
        console.error(this.constructor.name, err);
        return;
      }
      data.json().then(jsonData => {
        console.log("Board::fetchBoardInfo", "Got board info!", jsonData);
        if (!jsonData || jsonData.status !== 'Success') {
          throw new Error('Parsed data was bad! ' + data);
        }
        this.setState({ info: jsonData.data });
      });
    })
      .catch(err => {
        console.error("Board::fetchBoardInfo", 'Error while fetching posts!', err);
      });
  }

  getChildToShow() {
    // yes, I know what the ?: is but this is more readable
    if (this.props.params.threadId) {
      // we are in the `/boards/b/:threadId` path
      return (<Thread abbreviation={this.props.params.abbreviation} id={this.props.params.threadId} />);
    } else {
      // we are in the `boards/b/` path
      return (<ThreadList abbreviation={this.props.params.abbreviation} />);
    }
  }

  submitNewThread(formData) {
    formData.board = this.props.params.abbreviation;
    if (this.props.params.threadId) {
      // set the thread we're replying to if we're in an existing thread,
      // otherwise we're creating a new thread
      formData.topic_id = this.props.params.threadId;
    }

    fetch('/api/boards/' + this.props.params.abbreviation + '/posts/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        'Accept': 'application/json'
      },
      body: JSON.stringify(formData)
    })
      .then((data, err) => {
        console.log("Board::submitNewThread", data);
      });
  }

  render() {
    console.log("Board props", this.props);
    let name = this.state.info.name;
    let description = this.state.info.description;

    let childToShow = this.getChildToShow();

    return (

          /{this.props.params.abbreviation}/ - {name}

          {description}

        <ThreadSubmitForm submit={this.submitNewThread.bind(this) } />
        {childToShow}

    );
  }
}

export default Board;
<commit_msg>Add reload after new post<commit_after>import React, { Component } from 'react';
import Thread from './Thread';
import ThreadList from './ThreadList';
import ThreadSubmitForm from './ThreadSubmitForm';
import './styles/Board.css';

class Board extends Component {
  constructor(props) {
    super(props);

    this.state = {
      info: {
        name: 'Loading',
        abbreviation: props.params.abbreviation,
        description: ''
      }
    };
  }

  componentDidMount() {
    // fetch initial state when the Board component is used for the first time
    this.fetchBoardInfo();
  }

  componentDidUpdate(oldProps) {
    // user probably switched from a board to another board, ignore if old board === this board
    if (oldProps.params.abbreviation !== this.props.params.abbreviation)
      this.fetchBoardInfo();
  }

  fetchBoardInfo() {
    fetch('/api/boards/' + this.props.params.abbreviation).then((data, err) => {
      if (err) {
        // TODO: UI for API errors
        console.error(this.constructor.name, err);
        return;
      }
      data.json().then(jsonData => {
        console.log("Board::fetchBoardInfo", "Got board info!", jsonData);
        if (!jsonData || jsonData.status !== 'Success') {
          throw new Error('Parsed data was bad! ' + data);
        }
        this.setState({ info: jsonData.data });
      });
    })
      .catch(err => {
        console.error("Board::fetchBoardInfo", 'Error while fetching posts!', err);
      });
  }

  getChildToShow() {
    // yes, I know what the ?: is but this is more readable
    if (this.props.params.threadId) {
      // we are in the `/boards/b/:threadId` path
      return (<Thread abbreviation={this.props.params.abbreviation} id={this.props.params.threadId} />);
    } else {
      // we are in the `boards/b/` path
      return (<ThreadList abbreviation={this.props.params.abbreviation} />);
    }
  }

  submitNewThread(formData) {
    formData.board = this.props.params.abbreviation;
    if (this.props.params.threadId) {
      // set the thread we're replying to if we're in an existing thread,
      // otherwise we're creating a new thread
      formData.topic_id = this.props.params.threadId;
    }

    fetch('/api/boards/' + this.props.params.abbreviation + '/posts/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        'Accept': 'application/json'
      },
      body: JSON.stringify(formData)
    })
      .then((data, err) => {
        console.log("Board::submitNewThread", data);
        window.location.reload();
      });
  }

  render() {
    console.log("Board props", this.props);
    let name = this.state.info.name;
    let description = this.state.info.description;

    let childToShow = this.getChildToShow();

    return (

          /{this.props.params.abbreviation}/ - {name}

          {description}

        <ThreadSubmitForm submit={this.submitNewThread.bind(this) } />
        {childToShow}

    );
  }
}

export default Board;
<|endoftext|>


<commit_before>$(function() {

window.onload = function() {

    var game = new Phaser.Game(1536, 864, Phaser.AUTO, '', { preload: preload, create: create, update: update });

    var jumping = "0";

    var score = 0;
    var lives = 3;

    var lookdir;

    function preload() {

        game.load.image('bob', 'assets/images/bob.png');
        game.load.image('background', 'assets/images/background.png');
        game.load.image('ocean', 'assets/images/ocean.png');
        cursors = game.input.keyboard.createCursorKeys();
        //game.load.audio('jumpsound', 'assets/sounds/jump.wav');

    }

    function create() {

        //  A simple background for our game
        game.add.sprite(0, 0, 'background');

        //Game Objects
        player = game.add.sprite(550, game.world.height - 300, 'bob');

        //sound
        //jumpsound = game.add.audio('jumpsound');
        //jumpsound.allowMultiple = false;

        //hiding this for now its in the way
        //var fatty1 = game.add.sprite(0, 0, 'fatty1');

        //Uncaught TypeError: Cannot read property 'velocity' of null
        //fatty1.body.velocity.x=20;

        ocean = game.add.sprite(0, game.world.height - 400, 'ocean');

        //fatty1 = game.add.sprite(450, game.world.height - 300, 'fatty1');
        //fatty2 = game.add.sprite(450, game.world.height - 300, 'fatty2');
        //fatty3 = game.add.sprite(450, game.world.height - 300, 'fatty3');

        //ocean
        game.physics.enable(ocean, Phaser.Physics.ARCADE);
        ocean.body.immovable = true;

        //start physics
        game.physics.startSystem(Phaser.Physics.ARCADE);
        game.physics.arcade.enable(player);
        game.physics.arcade.enableBody(player);
        //Player physics properties.
        //player.body.bounce.y = 0.3;
        //player.body.gravity.y = 800;
        player.body.collideWorldBounds = true;

        //start the player looking right
        //lookdir = "right";

    }

    function update() {

        //ocean collision
        game.physics.arcade.collide(player, ocean);

        //  Reset the players velocity (movement)
        player.body.velocity.x = 0;
        player.body.velocity.y = 0;

        if (cursors.left.isDown)
        {
            if (cursors.up.isDown)
            {
                //  Move to the left+up
                player.body.velocity.x = -100;
                player.body.velocity.y = -100;
            }
            else if (cursors.down.isDown)
            {
                //  Move to the left+down
                player.body.velocity.x = -100;
                player.body.velocity.y = 100;
            }
            else
            {
                //  Move to the left
                player.body.velocity.x = -180;
            }

        }

        else if (cursors.right.isDown)
        {
            if (cursors.up.isDown)
            {
                //  Move to the right+up
                player.body.velocity.x = 100;
                player.body.velocity.y = -100;
            }
            else if (cursors.down.isDown)
            {
                //  Move to the right+down
                player.body.velocity.x = 100;
                player.body.velocity.y = 100;
            }
            else
            {
                //  Move to the right
                player.body.velocity.x = 180;
            }

        }
        else if (cursors.up.isDown)
        {
            //  Move to the up
            player.body.velocity.y = -180;
        }
        else if (cursors.down.isDown)
        {
            //  Move to the down
            player.body.velocity.y = 180;
        }

        }

};
});<commit_msg>Spawns<commit_after>$(function() {

window.onload = function() {

    var game = new Phaser.Game(1536, 864, Phaser.AUTO, '', { preload: preload, create: create, update: update });

    var jumping = "0";

    var score = 0;
    var lives = 3;

    var lookdir;

    function preload() {

        game.load.image('bob', 'assets/images/bob.png');
        game.load.image('background', 'assets/images/background.png');
        game.load.image('ocean', 'assets/images/ocean.png');
        cursors = game.input.keyboard.createCursorKeys();
        //game.load.audio('jumpsound', 'assets/sounds/jump.wav');

    }

    function create() {

        //  A simple background for our game
        game.add.sprite(0, 0, 'background');

        //Game Objects
        player = game.add.sprite(775, game.world.height - 150, 'bob');

        //sound
        //jumpsound = game.add.audio('jumpsound');
        //jumpsound.allowMultiple = false;

        //hiding this for now its in the way
        //var fatty1 = game.add.sprite(0, 0, 'fatty1');

        //Uncaught TypeError: Cannot read property 'velocity' of null
        //fatty1.body.velocity.x=20;

        ocean = game.add.sprite(0, game.world.height - 237, 'ocean');

        //fatty1 = game.add.sprite(450, game.world.height - 300, 'fatty1');
        //fatty2 = game.add.sprite(450, game.world.height - 300, 'fatty2');
        //fatty3 = game.add.sprite(450, game.world.height - 300, 'fatty3');

        //ocean
        game.physics.enable(ocean, Phaser.Physics.ARCADE);
        ocean.body.immovable = true;

        //start physics
        game.physics.startSystem(Phaser.Physics.ARCADE);
        game.physics.arcade.enable(player);
        game.physics.arcade.enableBody(player);
        //Player physics properties.
        //player.body.bounce.y = 0.3;
        //player.body.gravity.y = 800;
        player.body.collideWorldBounds = true;

        //start the player looking right
        //lookdir = "right";

    }

    function update() {

        //ocean collision
        game.physics.arcade.collide(player, ocean);

        //  Reset the players velocity (movement)
        player.body.velocity.x = 0;
        player.body.velocity.y = 0;

        if (cursors.left.isDown)
        {
            if (cursors.up.isDown)
            {
                //  Move to the left+up
                player.body.velocity.x = -100;
                player.body.velocity.y = -100;
            }
            else if (cursors.down.isDown)
            {
                //  Move to the left+down
                player.body.velocity.x = -100;
                player.body.velocity.y = 100;
            }
            else
            {
                //  Move to the left
                player.body.velocity.x = -180;
            }

        }

        else if (cursors.right.isDown)
        {
            if (cursors.up.isDown)
            {
                //  Move to the right+up
                player.body.velocity.x = 100;
                player.body.velocity.y = -100;
            }
            else if (cursors.down.isDown)
            {
                //  Move to the right+down
                player.body.velocity.x = 100;
                player.body.velocity.y = 100;
            }
            else
            {
                //  Move to the right
                player.body.velocity.x = 180;
            }

        }
        else if (cursors.up.isDown)
        {
            //  Move to the up
            player.body.velocity.y = -180;
        }
        else if (cursors.down.isDown)
        {
            //  Move to the down
            player.body.velocity.y = 180;
        }

        }

};
});<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');

const test = require('ava');
const mockFs = require('mock-fs');

const writeArtifact = require('../../../lib/artifacts').writeArtifact;

test.afterEach(() => mockFs.restore());

test('should create dest dir by dest', async t => {
    mockFs({
        'source-dir': {}
    });

    await writeArtifact({ dest: 'dest-dir', patterns: ['source-dir/'] });

    const files = fs.readdirSync('dest-dir');

    t.deepEqual(files, ['source-dir']);
});

test('should create dest dir from root', async t => {
    mockFs({
        '/root/source-dir': {}
    });

    await writeArtifact({ root: '/root', dest: 'dest-dir', patterns: ['source-dir/'] });

    const stats = fs.statSync('/root/dest-dir/');

    t.true(stats.isDirectory());
});

test('should create dir by depth path', async t => {
    mockFs({
        'source-dir': {}
    });

    await writeArtifact({ dest: './path/to/dest-dir/', patterns: 'source-dir/' });

    const stats = fs.statSync('./path/to/dest-dir/');

    t.true(stats.isDirectory());
});
<commit_msg>test(write-artifact): add case with name field<commit_after>'use strict';

const fs = require('fs');

const test = require('ava');
const mockFs = require('mock-fs');

const writeArtifact = require('../../../lib/artifacts').writeArtifact;

test.afterEach(() => mockFs.restore());

test('should create artifact dir by name', async t => {
    mockFs({
        'source-dir': {}
    });

    await writeArtifact({ name: 'artifact-dir', patterns: ['source-dir/'] });

    const files = fs.readdirSync('artifact-dir');

    t.deepEqual(files, ['source-dir']);
});

test('should create dest dir by dest', async t => {
    mockFs({
        'source-dir': {}
    });

    await writeArtifact({ dest: 'dest-dir', patterns: ['source-dir/'] });

    const files = fs.readdirSync('dest-dir');

    t.deepEqual(files, ['source-dir']);
});

test('should create dest dir from root', async t => {
    mockFs({
        '/root/source-dir': {}
    });

    await writeArtifact({ root: '/root', dest: 'dest-dir', patterns: ['source-dir/'] });

    const stats = fs.statSync('/root/dest-dir/');

    t.true(stats.isDirectory());
});

test('should create dir by depth path', async t => {
    mockFs({
        'source-dir': {}
    });

    await writeArtifact({ dest: './path/to/dest-dir/', patterns: 'source-dir/' });

    const stats = fs.statSync('./path/to/dest-dir/');

    t.true(stats.isDirectory());
});
<|endoftext|>


<commit_before>'use strict';

const Hoek = require('hoek');

const internals = {};

exports.Player = module.exports.Player = internals.Player = function (id) {

    Hoek.assert(this instanceof internals.Player, 'Player must be instantiated using new');
    this.id = id;
};

exports.Team = module.exports.Team = internals.Team = function (id) {

    Hoek.assert(this instanceof internals.Team, 'Team must be instantiated using new');
    this.id = id;
    this.players = [];
    this.spymaster = null;
};

exports.BoardElement = module.exports.BoardElement = internals.BoardElement = function (value, type) {

    Hoek.assert(this instanceof internals.BoardElement, 'BoardElement must be instantiated using new');
    this.value = value;
    this.type = type;
};

//--    Game
exports.Game = module.exports.Game = internals.Game = function (id, creatorId) {

    Hoek.assert(this instanceof internals.Game, 'Game must be instantiated using new');
    this.id = id;
    this.players = [];
    this.players.push(creatorId);
    this.teams = [new internals.Team(0), new internals.Team(1)];  //note hardcoded to 2 teams
    this.unteamedPlayerCount = 1;
    //count down to 0 when all conditions to start game is meet
    //1 count for spymasters chosen, which requires players to have teamed up already
    const READY_TO_START_CONDITION_MAX = 1;
    this.readyToStart = READY_TO_START_CONDITION_MAX;
    this.gameStarted = false;

    this.BOARD_SIZE = 25;
};

//--    Game setup
internals.Game.prototype.AddPlayer = function (playerId) {

    if (this.players.indexOf(playerId) === -1) {
        this.players.push(playerId);
        ++(this.unteamedPlayerCount);
    }

};

internals.Game.prototype.getPlayers = function () {

    return this.players;
};

internals.Game.prototype.AssignPlayerToTeam = function (playerId, teamId) {

    const otherTeamId = (teamId === 0) ? 1 : 0;    //note: hardcoded to 2 teams
    const index = this.teams[otherTeamId].players.indexOf(playerId);
    if (index !== -1) {
        this.teams[otherTeamId].players.splice(index, 1);
        ++(this.unteamedPlayerCount);
        if (this.teams[otherTeamId].spymaster === playerId) {
            this.teams[otherTeamId].spymaster = null;
        }
    }

    if (this.teams[teamId].players.indexOf(playerId) === -1) {
        this.teams[teamId].players.push(playerId);
        --(this.unteamedPlayerCount);
    }
};

internals.Game.prototype.AssignTeamsRandomly = function () {

    if (this.players.length < 4) {
        throw 'There must be at least 4 players';
    }

    this.teams[0] = new internals.Team(0);
    this.teams[1] = new internals.Team(1);
    this.unteamedPlayerCount = this.players.length;

    const firstTeamSize = Math.floor(this.players.length / 2);    //take the floor for this one
    const secondTeamSize = this.players.length - firstTeamSize;

    while (this.teams[0].players.length < firstTeamSize) {
        const randomIndex = Math.floor(Math.random() * this.players.length);
        this.AssignPlayerToTeam(this.players[randomIndex], 0);
    }

    while (this.teams[1].players.length < secondTeamSize) {
        const randomIndex = Math.floor(Math.random() * this.players.length);
        //Make sure the player isn't in the other team already
        if ((this.teams[0].players.indexOf(this.players[randomIndex])) === -1) {
            this.AssignPlayerToTeam(this.players[randomIndex], 1);
        }
    }
};

internals.Game.prototype.AssignSpymaster = function (teamId, playerId) {

    this.AssignPlayerToTeam(playerId, teamId);
    this.teams[teamId].spymaster = playerId;
};

internals.Game.prototype.ChooseSpymasters = function () {

    if (this.unteamedPlayerCount !== 0) {
        let verb = 'are';
        if (this.unteamedPlayerCount === 1) {
            verb = 'is';
        }
        throw 'Players need to team up first. There ' + verb + ' players unteamed.';
    }

    let randomIndex = Math.floor(Math.random() * this.teams[0].players.length);
    this.teams[0].spymaster = this.teams[0].players[randomIndex];

    randomIndex = Math.floor(Math.random() * this.teams[1].players.length);
    this.teams[1].spymaster = this.teams[1].players[randomIndex];
};

internals.Game.prototype.GetTeams = function () {

    return this.teams;
};

internals.Game.prototype.GetTeam = function (teamId) {

    return this.teams[teamId];
};

internals.Game.prototype.Start = function (board) {

    if (this.IsReadyToStart() === false) {

        throw 'Start game requirements has not been met.';
    }

    this.board = board;

    this.activeTeam = 0;    //team to start first

    this.gameStarted = true;
};

internals.Game.prototype.IsReadyToStart = function () {

    const enoughPlayers = ((this.teams[0].players.length >= 2) && (this.teams[1].players.length >= 2));
    const spymastersAssigned = ((this.teams[0].spymaster !== null) && (this.teams[1].spymaster !== null));

    return (enoughPlayers && spymastersAssigned);
};

internals.Game.prototype.SubmitChoice = function (elementValue) {

    const index = this.board.indexOf(elementValue);
    if (index === -1) {
        Hoek.assert(0, 'Value submitted does not exist.');
    }

    const otherTeamId = (teamId === 0) ? 1 : 0;    //note: hardcoded to 2 teams
    this.activeTeam = otherTeamId;

    return (this.board[index]);
};

internals.Game.prototype._CreditReadyToStartCondition = function () {

    Hoek.assert(this.IsReadyToStart() === false, 'Ready to start condition out of sync');
    --this.readyToStart;
};

internals.Game.prototype._DebitReadyToStartCondition = function () {

    Hoek.assert(this.readyToStart !== READY_TO_START_CONDITION_MAX, 'Ready to start condition out of sync');
    ++this.readyToStart;
};
<commit_msg>Added new functions for game<commit_after>'use strict';

const Fs = require('fs');
const Hoek = require('hoek');

const internals = {};

exports.Player = module.exports.Player = internals.Player = function (id) {

    Hoek.assert(this instanceof internals.Player, 'Player must be instantiated using new');
    this.id = id;
};

exports.Team = module.exports.Team = internals.Team = function (id) {

    Hoek.assert(this instanceof internals.Team, 'Team must be instantiated using new');
    this.id = id;
    this.players = [];
    this.spymaster = null;
};

exports.BoardElement = module.exports.BoardElement = internals.BoardElement = function (value, type) {

    Hoek.assert(this instanceof internals.BoardElement, 'BoardElement must be instantiated using new');
    this.value = value;
    this.type = type;
};

//--    Game
exports.Game = module.exports.Game = internals.Game = function (id, creatorId) {

    Hoek.assert(this instanceof internals.Game, 'Game must be instantiated using new');
    this.id = id;
    this.players = [];
    this.players.push(creatorId);
    this.teams = [new internals.Team(0), new internals.Team(1)];  //note hardcoded to 2 teams

    this.NUM_RED_CARDS = 8;
    this.NUM_BLUE_CARDS = 8;
    this.NUM_GRAY_CARDS = 7;
    this.NUM_BLACK_CARDS = 1;
    this.BOARD_SIZE = 25;

    // Define phases of the game
    this.phases = {
        SETUP: 0,
        GIVE_CLUE: 1,
        SELECT_WORD: 2,
        GAME_OVER: 3
    };

    // Define phases of the game
    this.cardColors = {
        RED: 0,
        BLUE: 1,
        GRAY: 2,
        BLACK: 3,
        NONE: 4
    };

    this._LoadWords();
    this._LoadDictionary();

    this.phase = this.phases.SETUP;
    this.activeTeam = 0;
    this.remainingGuesses = 0;
    this.remainingRedCards = 0;
    this.remainingBlueCards = 0;
    this.board = [];
    this.winner = null;
};

internals.Game.prototype.Reset = function () {

    this.players = [];
    this.players.push(creatorId);
    this.teams = [new internals.Team(0), new internals.Team(1)];

    this.phase = this.phases.SETUP;
    this.activeTeam = 0;
    this.remainingGuesses = 0;
    this.remainingRedCards = 0;
    this.remainingBlueCards = 0;
    this.board = [];
    this.winner = null;
};

//--    Game setup
internals.Game.prototype.AddPlayer = function (playerId) {

    // Throw an error if game is not in setup
    if (this.phase !== this.phases.SETUP) {
        throw 'Cannot add player in current phase';
    }

    if (this.players.indexOf(playerId) !== -1) {
        throw playerId + ' is already a player';
    }

    this.players.push(playerId);
};

internals.Game.prototype.RemovePlayer = function (playerId) {

    const indexOfPlayer = this.players.indexOf(playerId);

    // If the player is a current player:
    if (indexOfPlayer !== -1) {
        this.players.slice(index, 1);
    }

    // Loop for each team:
    for (const team of this.teams) {

        const indexOfPlayerInTeam = team.players.indexOf(playerId);

        // If the player is on this team, remove him:
        if (indexOfPlayerInTeam !== -1) {
            team.players.slice(indexOfPlayerInTeam, 1);
        }

        // If the player is the spymaster on this team, remove him:
        if (team.spymaster === playerId) {
            team.spymaster = null;
        }
    }
};

internals.Game.prototype.getPlayers = function () {

    return this.players;
};

internals.Game.prototype.AssignPlayerToTeam = function (playerId, teamId) {

    // Throw an error if playerId is not a current player
    if (this.players.indexOf(playerId) === -1) {
        throw playerId + ' is not a current player';
    }

    // Throw an error if teamId is not a valid team
    if ((teamId !== 0) && (teamId !== 1)) {
        throw teamId + ' is an invalid team';
    }

    // Throw an error if game is not in setup
    if (this.phase !== this.phases.SETUP) {
        throw 'Cannot assign player to team in current phase';
    }

    const otherTeamId = (teamId === 0) ? 1 : 0;    //note: hardcoded to 2 teams
    const index = this.teams[otherTeamId].players.indexOf(playerId);

    // If the player is already on the other team
    if (index !== -1) {

        // Remove player from other team
        this.teams[otherTeamId].players.splice(index, 1);

        // If needed, remove player as other team's spymaster
        if (this.teams[otherTeamId].spymaster === playerId) {
            this.teams[otherTeamId].spymaster = null;
        }
    }

    // Add player to specified team if he is not already on it
    if (this.teams[teamId].players.indexOf(playerId) === -1) {
        this.teams[teamId].players.push(playerId);
    }
};

internals.Game.prototype.AssignTeamsRandomly = function () {

    // Throw an error if game is not in setup
    if (this.phase !== this.phases.SETUP) {
        throw 'Cannot assign teams randomly in current phase';
    }

    this.teams[0] = new internals.Team(0);
    this.teams[1] = new internals.Team(1);

    const firstTeamSize = Math.floor(this.players.length / 2);

    while (this.teams[0].players.length < firstTeamSize) {
        const randomIndex = Math.floor(Math.random() * this.players.length);
        this.AssignPlayerToTeam(this.players[randomIndex], 0);
    }

    for (const playerId of this.players) {

        // If this player is not on the first team, assign him to the second team:
        if (this.teams[0].players.indexOf(playerId) === -1) {
            this.AssignPlayerToTeam(playerId, 1);
        }
    }
};

internals.Game.prototype.AssignSpymaster = function (teamId, playerId) {

    // Throw an error if game is not in setup
    if (this.phase !== this.phases.SETUP) {
        throw 'Cannot assign spymasters in current phase';
    }

    this.AssignPlayerToTeam(playerId, teamId);
    this.teams[teamId].spymaster = playerId;
};

internals.Game.prototype.ChooseSpymasters = function () {

    // Throw an error if game is not in setup
    if (this.phase !== this.phases.SETUP) {
        throw 'Cannot randomly assign spymasters in current phase';
    }

    if (this.teams[0].players.length > 0) {
        const randomIndex = Math.floor(Math.random() * this.teams[0].players.length);
        this.teams[0].spymaster = this.teams[0].players[randomIndex];
    }

    if (this.teams[1].players.length > 0) {
        const randomIndex = Math.floor(Math.random() * this.teams[1].players.length);
        this.teams[1].spymaster = this.teams[1].players[randomIndex];
    }
};

internals.Game.prototype.GetTeams = function () {

    return this.teams;
};

internals.Game.prototype.GetTeam = function (teamId) {

    // Throw an error if teamId is not a valid team
    if ((teamId !== 0) && (teamId !== 1)) {
        throw teamId + ' is an invalid team';
    }

    return this.teams[teamId];
};

internals.Game.prototype.Start = function () {

    if (this.IsReadyToStart() === false) {
        throw 'Start game requirements has not been met.';
    }

    this._RandomizeBoardWords();
    this._RandomizeBoardMap();

    this.gameStarted = true;
    this.phase = this.phases.GIVE_CLUE;
};

internals.Game.prototype.IsReadyToStart = function () {

    const enoughPlayers = ((this.teams[0].players.length >= 2) && (this.teams[1].players.length >= 2));
    const spymastersAssigned = ((this.teams[0].spymaster !== null) && (this.teams[1].spymaster !== null));

    return (enoughPlayers && spymastersAssigned);
};

internals.Game.prototype.GiveClue = function (playerId, word, count) {

    // Throw an error if playerId is not a current player
    if (this.players.indexOf(playerId) === -1) {
        throw playerId + ' is not a current player';
    }

    // Throw an error if the current phase is not GIVE_CLUE
    if (this.phase !== this.phases.GIVE_CLUE) {
        throw 'Current phase is not \'GIVE CLUE\'';
    }

    // Throw an error if playerId is not spymaster
    if (!this._IsPlayerSpymaster(playerId)) {
        throw playerId + ' is not spymaster';
    }

    // Throw an error if player's team is not active
    if (this._GetTeamIdFromPlayer(playerId) !== this.activeTeam) {
        throw playerId + ' is not on active team';
    }

    // Throw an error if count is invalid
    if (isNaN(count) || count < 0) {
        throw count + ' is invalid value';
    }

    const card = this._GetCardFromWord(word);

    // Throw an error if the clue exists on the board and is not selected:
    if ((card !== null) && (card.selected === false)) {
        throw word + ' cannot be used as a clue';
    }

    // Throw an error if this word is not in the dictionary
    if (!this.dictionary.has(word)) {
        throw word + ' is not in the dictionary';
    }

    this.clue = { wordClue: word, count: count };
    this.remainingGuesses = count;
    this.phase = this.phases.SELECT_WORD;
};

internals.Game.prototype.SelectWord = function (playerId, word) {

    // Throw an error if playerId is not a current player
    if (this.players.indexOf(playerId) === -1) {
        throw playerId + ' is not a current player';
    }

    // Throw an error if the current phase is not GIVE_CLUE
    if (this.phase !== this.phases.SELECT_WORD) {
        throw 'Current phase is not \'SELECT WORD\'';
    }

    // Throw an error if playerId is spymaster
    if (this._IsPlayerSpymaster(playerId)) {
        throw playerId + ' is a spymaster';
    }

    // Throw an error if player's team is not active
    if (this._GetTeamIdFromPlayer(playerId) !== this.activeTeam) {
        throw playerId + ' is not on active team';
    }

    const card = this._GetCardFromWord(word);

    // Throw an error if word does not exist on board
    if (card === null) {
        throw word + ' does not exist on board';
    }

    // Throw an error if word is already selected
    if (card.selected === true) {
        throw word + ' does not exist on board';
    }

    card.selected = true;
    --this.remainingGuesses;

    if (card.color === this.cardColors.RED) {
        --this.numRedCardsRemaining;
    }
    else if (card.color === this.cardColors.BLUE) {
        --this.numBlueCardsRemaining;
    }

    // If either team has no more cards remaining:
    if ((this.numRedCardsRemaining === 0) || (this.numBlueCardsRemaining === 0)) {

        // Select the winner
        if (this.numRedCardsRemaining === 0) {
            this.winner = this.cardColors.RED;
        }
        else {
            this.winner = this.cardColors.BLUE;
        }

        // End the game
        this.phase = this.phases.GAME_OVER;
    }
    // Otherwise, if the active team chose the other team's card or a neutral card:
    else if ((card.color === this._GetInactiveTeam()) || (card.color === this.cardColors.GRAY)) {

        // End this team's turn
        this.remainingGuesses = 0;
        this.activeTeam = this._GetInactiveTeam();
        this.phase = this.phases.GIVE_CLUE;
    }
    // Otherwise, if the active team chose the assassin:
    else if (card.color === this.cardColors.BLACK ) {

        // The other team is automatically the winner
        this.winner = this._GetInactiveTeam();

        this.phase = this.phases.GAME_OVER;
    }
};

internals.Game.prototype.PassTurn = function (playerId) {

    // Throw an error if playerId is not a current player
    if (this.players.indexOf(playerId) === -1) {
        throw playerId + ' is not a current player';
    }

    // Throw an error if the current phase is not GIVE_CLUE
    if (this.phase !== this.phases.SELECT_WORD) {
        throw 'Current phase is not \'SELECT WORD\'';
    }

    // Throw an error if playerId is spymaster
    if (this._IsPlayerSpymaster(playerId)) {
        throw playerId + ' is a spymaster';
    }

    // Throw an error if player's team is not active
    if (this._GetTeamIdFromPlayer(playerId) !== this.activeTeam) {
        throw playerId + ' is not on active team';
    }

    // End this team's turn
    this.remainingGuesses = 0;
    this.activeTeam = this._GetInactiveTeam();
    this.phase = this.phases.GIVE_CLUE;
};

internals.Game.prototype.GetGameState = function () {

    return {
        phase: this.phase,
        activeTeam: this.activeTeam,
        remainingGuesses: this.remainingGuesses,
        remainingRedCards: this.remaingRedCards,
        remainingBlueCards: this.remainingBlueCards,
        board: this.board,
        winner: this.winner
    };
};

internals.Game.prototype._GetTeamIdFromPlayer = function (playerId) {

    for (const team of this.teams) {

        if (team.players.indexOf(playerId) !== -1) {
            return team.id;
        }
    }

    return null;
};

internals.Game.prototype._IsPlayerSpymaster = function (playerId) {

    for (const team of this.teams) {

        if (team.spymaster === playerId) {
            return true;
        }
    }

    return false;
};

internals.Game.prototype._GetCardFromWord = function (word) {

    for (card of this.board) {

        if (card.word === word) {
            return card;
        }
    }

    return null;
};

internals.Game.prototype._GetInactiveTeam = function () {

    const inactiveTeam = (this.activeTeam === 1) ? 0 : 1;

    return inactiveTeam;
};

internals.Game.prototype._LoadWords = function () {

    this.words = Fs.readFileSync(__dirname + '/resources/words.txt').toString().split('\n');
};

internals.Game.prototype._LoadDictionary = function () {

    this.dictionary = new Set();

    const dictionaryArray = Fs.readFileSync(__dirname + '/resources/dictionary.txt').toString().split('\n');

    for (const word of dictionaryArray) {
        this.dictionary.add(word);
    }
};

internals.Game.prototype._RandomizeBoardWords = function () {

    const wordSet = new Set();

    while (this.board.size < this.BOARD_SIZE) {

        const randomIndex = Math.floor(Math.random() * this.words.length);
        const randomWord = this.words[randomIndex];

        if (!wordSet.has(randomWord)) {
            this.board.push({ word: randomWord, color: this.cardColors.NONE, selected: false });
            wordSet.add(randomWord);
        }
    }
};

internals.Game.prototype._RandomizeBoardMap = function () {

    let numRedCardsRemaining = this.NUM_READ_CARDS;
    let numBlueCardsRemaining = this.NUM_BLUE_CARDS;
    let numGrayCardsRemaining = this.NUM_GRAY_CARDS;
    let numBlackCardsRemaining = this.NUM_BLACK_CARDS;

    const randomCoin = Math.floor(Math.random() * 2);

    if (randomCoin === 0) {
        ++numRedCardsRemaining;
        this.activeTeam = 0;
    }
    else {
        ++numBlueCardsRemaining;
        this.activeTeam = 1;
    }

    this.remainingRedCards = numRedCardsRemaining;
    this.remainingBlueCards = numBlueCardsRemaining;

    for (const card of this.board) {

        if (numRedCardsRemaining > 0) {
            card.color = this.cardColors.RED;
            --numRedCardsRemaining;
        }
        else if (numBlueCardsRemaining > 0) {
            card.color = this.cardColors.BLUE;
            --numBlueCardsRemaining;
        }
        else if (numGrayCardsRemaining > 0) {
            card.color = this.cardColors.GRAY;
            --numGrayCardsRemaining;
        }
        else {
            card.color = this.cardColors.BLACK;
            --numBlackCardsRemaining;
        }
    }

    // Shuffle the board again to shuffle the color assignments
    this._ShuffleBoard();
};

internals.Game.prototype._ShuffleBoard = function () {

    for (let i = this.board.length - 1; i > 0; --i) {

        // Add 1 to allow all cards an equal chance of being selected
        const randomIndex = Math.floor(Math.random() * (i + 1));

        // Swap a card at random index with index i
        const tempCard = this.board[i];
        this.board[i] = this.board[randomIndex];
        this.board[randomIndex] = tempCard;
    }
};
<|endoftext|>


<commit_before>function Choir(voices) {
  var that = Object.create(Choir.prototype);

  that._voices = voices;

  return that;
}

Choir.prototype
.advanceChord = function() {
  this._time = this._voices.reduce(function(minTime, voice){
    return voice.nextNoteStartMin(minTime);
  }, Fraction(Infinity, 1));

  var that = this;
  var chord = this._voices.map(function(voice) {
    return voice.advanceTime(that._time);
  });

  var lowestNote = this.lowest(chord);
  var frequencies = this.getFrequencies(chord, lowestNote);
  this.playFrequencies(frequencies);
};

Choir.prototype
.getFrequencies = function(notes, lowestNote) {
  var i = 1;
  var partials = null;
  while(!partials) {
    var suggestedF0 = lowestNote.getSubPartial(i++);
    partials = this.nearestPartialsOrNull(suggestedF0, notes);
  }

  return partials;
};

Choir.prototype
.nearestPartialsOrNull = function(suggestedF0, notes) {
  var partials = notes.map(function(note) {
    return note.nearestPartial(suggestedF0);
  });

  var nullFound = partials.reduce(function(nullFound, partial) {
    return nullFound || (partial === null);
  }, false);

  return nullFound ? null : partials;
};

Choir.prototype
.lowest = function(notes) {
  var lowestNote = notes.reduce(function(minTone, tone){
    return tone.toneMin(minTone);
  }, Note(Infinity));

  return lowestNote;
};

Choir.prototype
.playFrequencies = function() {

};
<commit_msg>Clarifying refactorization.<commit_after>function Choir(voices) {
  var that = Object.create(Choir.prototype);

  that._voices = voices;

  return that;
}

Choir.prototype
.advanceChord = function() {
  var nextNoteStartMin = this._voices.reduce(function(minTime, voice){
    return voice.nextNoteStartMin(minTime);
  }, Fraction(Infinity, 1));

  var chord = this._voices.map(function(voice) {
    return voice.advanceTime(nextNoteStartMin);
  });

  this._time = nextNoteStartMin;

  var lowestNote = this.lowest(chord);
  var frequencies = this.getFrequencies(chord, lowestNote);
  this.playFrequencies(frequencies);
};

Choir.prototype
.getFrequencies = function(notes, lowestNote) {
  var i = 1;
  var partials = null;
  while(!partials) {
    var suggestedF0 = lowestNote.getSubPartial(i++);
    partials = this.nearestPartialsOrNull(suggestedF0, notes);
  }

  return partials;
};

Choir.prototype
.nearestPartialsOrNull = function(suggestedF0, notes) {
  var partials = notes.map(function(note) {
    return note.nearestPartial(suggestedF0);
  });

  var nullFound = partials.reduce(function(nullFound, partial) {
    return nullFound || (partial === null);
  }, false);

  return nullFound ? null : partials;
};

Choir.prototype
.lowest = function(notes) {
  var lowestNote = notes.reduce(function(minTone, tone){
    return tone.toneMin(minTone);
  }, Note(Infinity));

  return lowestNote;
};

Choir.prototype
.playFrequencies = function() {

};
<|endoftext|>


<commit_before>test('script_proxy_dynamic.php', function (assert, document) {
    var h1s = document.getElementsByTagName('h1');
    assert.equal(h1s.length, 1, "There should be one <H1> element on the page");
    assert.equal(h1s[0].textContent, 'Hello, World!', "The <H1> should say 'Hello, World!'");

    var scripts = document.getElementsByTagName('script');
    assert.ok(scripts.length >= 1, "There should be one or more <SCRIPT> elements on the page");
    assert.ok(/script_proxy\.js/.test(scripts[0].src), "The first <SCRIPT> src should contain the name of the script");
    assert.ok(!/phast\.php/.test(scripts[0].src), "The first <SCRIPT> src should not contain phast.php");
});
<commit_msg>Fix timing issue with browser test<commit_after>test('script_proxy_dynamic.php', function (assert, document) {
    wait(assert, function () {
        return document.getElementsByTagName('h1').length > 0;
    }, function () {
        var h1s = document.getElementsByTagName('h1');
        assert.equal(h1s.length, 1, "There should be one <H1> element on the page");
        assert.equal(h1s[0].textContent, 'Hello, World!', "The <H1> should say 'Hello, World!'");

        var scripts = document.getElementsByTagName('script');
        assert.ok(scripts.length >= 1, "There should be one or more <SCRIPT> elements on the page");
        assert.ok(/script_proxy\.js/.test(scripts[0].src), "The first <SCRIPT> src should contain the name of the script");
        assert.ok(!/phast\.php/.test(scripts[0].src), "The first <SCRIPT> src should not contain phast.php");
    });
});
<|endoftext|>


<commit_before>/**
 * Main Class of the tooltip plugin.
 * Initalizes and handles the the Item Instances.
 */

(function (root, factory) {

	'use strict';

	if (typeof define === 'function' && define.amd) {
		define([
			'jquery',
			'./Constants',
			'./Item'
		], factory);
	} else if (typeof exports === 'object') {
		module.exports = factory(
			require('jquery'),
			require('./Constants'),
			require('./Item')
		);
	} else {
		root.ProtipClass = factory(
			root.jQuery,
			root.ProtipConstants,
			root.ProtipItemClass
		);
	}
}(this, function ($, C, ProtipItemClass) {

	'use strict';

	// Lower the interval time, we don't need that much accuracy.
	window.MutationObserver._period = 100;

	/**
	 * The Protip main class
	 *
	 * @param settings [Object] Overridable configuration options
	 * @returns {ProtipClass}
	 * @constructor
	 */
	var ProtipClass = function(settings){
		return this._Construct(settings);
	};

// Define the ProtipClass members
	$.extend(true, ProtipClass.prototype, {

		/**
		 * Default configuration options
		 *
		 * @memberOf ProtipClass
		 * @type Object
		 * @private
		 */
		_defaults: {
			/** @type String    Selector for clickable protips */
			selector:           C.DEFAULT_SELECTOR,
			/** @type String    Namespace of the data attributes */
			namespace:          C.DEFAULT_NAMESPACE,
			/** @type String    Template of protip element */
			protipTemplate:     C.TEMPLATE_PROTIP,
			/** @type String    Template of the arrow element */
			arrowTemplate:      C.TEMPLATE_ARROW,
			/** @type String    Template of protip icon */
			iconTemplate:       C.TEMPLATE_ICON,
			/** @type Boolean   Should we observe whole document for assertions and removals */
			observer:           true,
			/** @type String    Default skin to use */
			skin:               C.SKIN_DEFAULT,
			/** @type String    Default size to use (provided by the Default skin only) */
			size:               C.SIZE_DEFAULT,
			/** @type String    Default color scheme to use (provided by the Default skin only) */
			scheme:             C.SCHEME_DEFAULT,
			/** @type Boolean   Global animation? */
			animate:            false,
			/** @type Number    Global offset of all tooltips. */
			offset:             0
		},

		/**
		 * @memberOf ProtipClass
		 * @param settings
		 * @returns {ProtipClass}
		 * @private
		 */
		_Construct: function(settings){
			/**
			 * Overridden configuration options (extends defaults)
			 *
			 * @type Object
			 */
			this.settings = $.extend({}, this._defaults, settings);

			/**
			 * Object storing the Item Class Instances
			 *
			 * @type {Object.<Number>.<ProtipItemClass>}
			 * @private
			 */
			this._itemInstances = {};

			/**
			 * Object storing the MutationObserver instance
			 *
			 * @type MutationObserver
			 * @private
			 */
			this._observerInstance = undefined;

			/**
			 * Array storing the the Item Instances which were visible
			 * before window resize.
			 *
			 * @type {Array.<ProtipItemInstance>}
			 * @private
			 */
			this._visibleBeforeResize = [];

			/**
			 * Object storing timeout tasks.
			 *
			 * @type {Object}
			 * @private
			 */
			this._task = {
				delayIn:  undefined,
				delayOut: undefined,
				resize:   undefined
			};

			// Do some initial things
			this._fetchElements();
			this._bind();

			return this;
		},

		/**
		 * Method to destroy a class instance.
		 * Calls each item classes destroy method.
		 * Does unbind.
		 * Makes some local references empty.
		 */
		destroy: function(){
			this._unbind();

			$.each(this._itemInstances, $.proxy(function(key){
				this.destroyItemInstance(key);
			}, this));

			this._itemInstances    = undefined;
			this.settings          = undefined;
			$._protipClassInstance = undefined;
		},

		/**
		 * Return a namespaced version of a data property's name.
		 *
		 * @param string {string} The input string. eq: action
		 * @returns {string} eg: ptAction
		 */
		namespaced: function(string){
			return this.settings.namespace + string.charAt(0).toUpperCase() + string.slice(1);
		},

		/**
		 * Deletes the locally stored instance
		 * and calls the item's destroy method.
		 *
		 * @param key {string} Item instance identifier.
		 */
		destroyItemInstance: function(key){
			this._itemInstances[key].destroy();
			delete this._itemInstances[key];
		},

		/**
		 * Creates a ProtipItemClass instance
		 * and stores locally the instance.
		 *
		 * @param el {jQuery} Source element which has the tooltip.
		 * @param override {object} data-pt-* overrides
		 * @returns {ProtipItemClass}
		 */
		createItemInstance: function(el, override){
			var id = this._generateId();
			this._itemInstances[id] = new ProtipItemClass(id, el, this, override);
			return this._itemInstances[id];
		},

		/**
		 * Fully reloads an ItemClass instance.
		 * Destroy + Create
		 *
		 * @param el {jQuery} Element we reload on.
		 */
		reloadItemInstance: function(el){
			var key = el.data(this.namespaced(C.PROP_IDENTIFIER));
			this.destroyItemInstance(key);
			this.createItemInstance(el);
		},

		/**
		 * Getter for retriving an ItemClass instance based on the passwed element.
		 * In case this element doesn't have ItemClass yet this method will also create a new one.
		 *
		 * @param el       {jQuery} The element we're searching it's instance for.
		 * @param override {object} data-pt-* overridables
		 * @returns {ProtipItemClass}
		 */
		getItemInstance: function(el, override){
			var identifier = el.data(this.namespaced(C.PROP_IDENTIFIER));
			return this._isInited(el) ? this._itemInstances[identifier] : this.createItemInstance(el, override);
		},

		/**
		 * Fetches DOM elements with the specified protip selector
		 * and creates an ItemClass instance for them.
		 *
		 * @private
		 */
		_fetchElements: function(){
			$(this.settings.selector).each($.proxy(function(index, el){
				this.createItemInstance($(el));
			}, this));
		},

		/**
		 * Generates a unique ID to be used as identfier.
		 *
		 * @returns {string}
		 * @private
		 */
		_generateId: function(){
			return new Date().valueOf() + Math.floor(Math.random() * 10000).toString();
		},

		/**
		 * Tells us if the passed element already has an ItemClass instance or not.
		 *
		 * @param el
		 * @returns {boolean}
		 * @private
		 */
		_isInited: function(el){
			return !!el.data(this.namespaced(C.PROP_INITED));
		},

		/**
		 * Method to hide all protips.
		 *
		 * @private
		 */
		_hideAll: function(){
			$.each(this._itemInstances, $.proxy(function(index, item){
				item.isVisible() && this._visibleBeforeResize.push(item) && item.hide();
			}, this));
		},

		/**
		 * Method to show all protips.
		 *
		 * @private
		 */
		_showAll: function(){
			this._visibleBeforeResize.forEach(function(item){
				item.show();
			});
		},

		/**
		 * Common event handler to every action.
		 *
		 * @param ev {Event} Event object.
		 * @private
		 */
		_onAction: function(ev){
			ev.type === C.EVENT_CLICK && ev.preventDefault();

			var el = $(ev.currentTarget);
			this.getItemInstance(el).actionHandler(ev.type);
		},

		/**
		 * OnResize event callback handler.
		 *
		 * @private
		 */
		_onResize: function(){
			!this._task.resize && this._hideAll();
			this._task.resize && clearTimeout(this._task.resize);
			this._task.resize = setTimeout(function () {
				this._showAll();
				this._task.resize = undefined;
				this._visibleBeforeResize = [];
			}.bind(this), 100);
		},

		/**
		 * OnBodyClick event callback handler.
		 *
		 * @param ev {Event} Event object.
		 * @private
		 */
		_onBodyClick: function(ev){
			var el = $(ev.target);
			var parent = el.parents('.' + C.SELECTOR_PREFIX + C.SELECTOR_CONTAINER);
			var selector = C.SELECTOR_PREFIX + C.SELECTOR_CONTAINER;
			var container = el.hasClass(selector) ? el : parent.size() ? parent : false;

			var instance = this._isInited(el) ? this.getItemInstance(el) : false;

			if (!instance || (instance.data.trigger !== C.TRIGGER_CLICK)) {
				$.each(this._itemInstances, function (index, item) {
					item.isVisible()
					&& item.data.trigger === C.TRIGGER_CLICK
					&& (!container || item.el.protip.get(0) !== container.get(0))
					&& item.hide();
				});
			}
		},

		/**
		 *  Click event callback handler for closing elements.
		 *
		 * @param ev {Event} Event object.
		 * @private
		 */
		_onCloseClick: function(ev){
			var identifier = $(ev.currentTarget).parents('.' + C.SELECTOR_PREFIX + C.SELECTOR_CONTAINER).data(this.namespaced(C.PROP_IDENTIFIER));
			this._itemInstances[identifier] && this._itemInstances[identifier].hide();
		},

		/**
		 * Handles add/removed nodes.
		 *
		 * @param mutations {<Array>MutationRecord}
		 * @private
		 */
		_mutationObserverCallback: function(mutations) {
			mutations.forEach(function(mutation) {
				for (var i = 0; i < mutation.addedNodes.length; i++) {
					var els = $(mutation.addedNodes[i].parentNode).find(this.settings.selector);
					els.each(function(index, el){
						el = $(el);
						if (el.data(this.namespaced(C.PROP_TRIGGER)) === C.TRIGGER_STICKY){
							this.getItemInstance(el).show();
						}
					}.bind(this));
				}

				for (var i = 0; i < mutation.removedNodes.length; i++) {
					var el = $(mutation.removedNodes[i]);
					el.find(this.settings.selector).each(function(index, item){
						this.getItemInstance($(item)).destroy();
					}.bind(this));

					if (el.hasClass(this.settings.selector.replace('.', ''))) {
						this.getItemInstance(el).destroy();
					}
				}
			}.bind(this));
		},

		/**
		 * Binds up all events.
		 *
		 * @private
		 */
		_bind: function(){
			var body = $(C.SELECTOR_BODY);

			body.on(C.EVENT_CLICK, $.proxy(this._onBodyClick, this))
				.on(C.EVENT_MOUSEOVER, this.settings.selector, $.proxy(this._onAction, this))
				.on(C.EVENT_MOUSEOUT, this.settings.selector, $.proxy(this._onAction, this))
				.on(C.EVENT_CLICK, this.settings.selector, $.proxy(this._onAction, this))
				.on(C.EVENT_CLICK, C.SELECTOR_CLOSE, $.proxy(this._onCloseClick, this));

			$(window).on(C.EVENT_RESIZE, $.proxy(this._onResize, this));

			if (this.settings.observer) {
				this._observerInstance = new MutationObserver(this._mutationObserverCallback.bind(this));

				this._observerInstance.observe(body.get(0), {
					attributes: false,
					childList: true,
					characterData: false,
					subtree: true
				});
			}
		},

		/**
		 * Unbinds all events.
		 *
		 * @private
		 */
		_unbind: function(){
			$(C.SELECTOR_BODY)
				.off(C.EVENT_CLICK, $.proxy(this._onBodyClick, this))
				.off(C.EVENT_MOUSEOVER, this.settings.selector, $.proxy(this._onAction, this))
				.off(C.EVENT_MOUSEOUT, this.settings.selector, $.proxy(this._onAction, this))
				.off(C.EVENT_CLICK, this.settings.selector, $.proxy(this._onAction, this))
				.off(C.EVENT_CLICK, C.SELECTOR_CLOSE, $.proxy(this._onCloseClick, this));

			$(window).off(C.EVENT_RESIZE, $.proxy(this._onResize, this));

			if (this.settings.observer) {
				this._observerInstance.disconnect();
			}
		}
	});

	return ProtipClass;

}));
<commit_msg>Event handler fix<commit_after>/**
 * Main Class of the tooltip plugin.
 * Initalizes and handles the the Item Instances.
 */

(function (root, factory) {

	'use strict';

	if (typeof define === 'function' && define.amd) {
		define([
			'jquery',
			'./Constants',
			'./Item'
		], factory);
	} else if (typeof exports === 'object') {
		module.exports = factory(
			require('jquery'),
			require('./Constants'),
			require('./Item')
		);
	} else {
		root.ProtipClass = factory(
			root.jQuery,
			root.ProtipConstants,
			root.ProtipItemClass
		);
	}
}(this, function ($, C, ProtipItemClass) {

	'use strict';

	// Lower the interval time, we don't need that much accuracy.
	window.MutationObserver._period = 100;

	/**
	 * The Protip main class
	 *
	 * @param settings [Object] Overridable configuration options
	 * @returns {ProtipClass}
	 * @constructor
	 */
	var ProtipClass = function(settings){
		return this._Construct(settings);
	};

// Define the ProtipClass members
	$.extend(true, ProtipClass.prototype, {

		/**
		 * Default configuration options
		 *
		 * @memberOf ProtipClass
		 * @type Object
		 * @private
		 */
		_defaults: {
			/** @type String    Selector for clickable protips */
			selector:           C.DEFAULT_SELECTOR,
			/** @type String    Namespace of the data attributes */
			namespace:          C.DEFAULT_NAMESPACE,
			/** @type String    Template of protip element */
			protipTemplate:     C.TEMPLATE_PROTIP,
			/** @type String    Template of the arrow element */
			arrowTemplate:      C.TEMPLATE_ARROW,
			/** @type String    Template of protip icon */
			iconTemplate:       C.TEMPLATE_ICON,
			/** @type Boolean   Should we observe whole document for assertions and removals */
			observer:           true,
			/** @type String    Default skin to use */
			skin:               C.SKIN_DEFAULT,
			/** @type String    Default size to use (provided by the Default skin only) */
			size:               C.SIZE_DEFAULT,
			/** @type String    Default color scheme to use (provided by the Default skin only) */
			scheme:             C.SCHEME_DEFAULT,
			/** @type Boolean   Global animation? */
			animate:            false,
			/** @type Number    Global offset of all tooltips. */
			offset:             0
		},

		/**
		 * @memberOf ProtipClass
		 * @param settings
		 * @returns {ProtipClass}
		 * @private
		 */
		_Construct: function(settings){
			/**
			 * Overridden configuration options (extends defaults)
			 *
			 * @type Object
			 */
			this.settings = $.extend({}, this._defaults, settings);

			/**
			 * Object storing the Item Class Instances
			 *
			 * @type {Object.<Number>.<ProtipItemClass>}
			 * @private
			 */
			this._itemInstances = {};

			/**
			 * Object storing the MutationObserver instance
			 *
			 * @type MutationObserver
			 * @private
			 */
			this._observerInstance = undefined;

			/**
			 * Array storing the the Item Instances which were visible
			 * before window resize.
			 *
			 * @type {Array.<ProtipItemInstance>}
			 * @private
			 */
			this._visibleBeforeResize = [];

			/**
			 * Object storing timeout tasks.
			 *
			 * @type {Object}
			 * @private
			 */
			this._task = {
				delayIn:  undefined,
				delayOut: undefined,
				resize:   undefined
			};

			// Do some initial things
			this._fetchElements();
			this._bind();

			return this;
		},

		/**
		 * Method to destroy a class instance.
		 * Calls each item classes destroy method.
		 * Does unbind.
		 * Makes some local references empty.
		 */
		destroy: function(){
			this._unbind();

			$.each(this._itemInstances, $.proxy(function(key){
				this.destroyItemInstance(key);
			}, this));

			this._itemInstances    = undefined;
			this.settings          = undefined;
			$._protipClassInstance = undefined;
		},

		/**
		 * Return a namespaced version of a data property's name.
		 *
		 * @param string {string} The input string. eq: action
		 * @returns {string} eg: ptAction
		 */
		namespaced: function(string){
			return this.settings.namespace + string.charAt(0).toUpperCase() + string.slice(1);
		},

		/**
		 * Deletes the locally stored instance
		 * and calls the item's destroy method.
		 *
		 * @param key {string} Item instance identifier.
		 */
		destroyItemInstance: function(key){
			this._itemInstances[key].destroy();
			delete this._itemInstances[key];
		},

		/**
		 * Creates a ProtipItemClass instance
		 * and stores locally the instance.
		 *
		 * @param el {jQuery} Source element which has the tooltip.
		 * @param override {object} data-pt-* overrides
		 * @returns {ProtipItemClass}
		 */
		createItemInstance: function(el, override){
			var id = this._generateId();
			this._itemInstances[id] = new ProtipItemClass(id, el, this, override);
			return this._itemInstances[id];
		},

		/**
		 * Fully reloads an ItemClass instance.
		 * Destroy + Create
		 *
		 * @param el {jQuery} Element we reload on.
		 */
		reloadItemInstance: function(el){
			var key = el.data(this.namespaced(C.PROP_IDENTIFIER));
			this.destroyItemInstance(key);
			this.createItemInstance(el);
		},

		/**
		 * Getter for retriving an ItemClass instance based on the passwed element.
		 * In case this element doesn't have ItemClass yet this method will also create a new one.
		 *
		 * @param el       {jQuery} The element we're searching it's instance for.
		 * @param override [object] data-pt-* overridables
		 * @returns {ProtipItemClass}
		 */
		getItemInstance: function(el, override){
			var identifier = el.data(this.namespaced(C.PROP_IDENTIFIER));
			return this._isInited(el) ? this._itemInstances[identifier] : this.createItemInstance(el, override);
		},

		/**
		 * Fetches DOM elements with the specified protip selector
		 * and creates an ItemClass instance for them.
		 *
		 * @private
		 */
		_fetchElements: function(){
			$(this.settings.selector).each($.proxy(function(index, el){
				this.createItemInstance($(el));
			}, this));
		},

		/**
		 * Generates a unique ID to be used as identfier.
		 *
		 * @returns {string}
		 * @private
		 */
		_generateId: function(){
			return new Date().valueOf() + Math.floor(Math.random() * 10000).toString();
		},

		/**
		 * Tells us if the passed element already has an ItemClass instance or not.
		 *
		 * @param el
		 * @returns {boolean}
		 * @private
		 */
		_isInited: function(el){
			return !!el.data(this.namespaced(C.PROP_INITED));
		},

		/**
		 * Method to hide all protips.
		 *
		 * @private
		 */
		_hideAll: function(){
			$.each(this._itemInstances, $.proxy(function(index, item){
				item.isVisible() && this._visibleBeforeResize.push(item) && item.hide();
			}, this));
		},

		/**
		 * Method to show all protips.
		 *
		 * @private
		 */
		_showAll: function(){
			this._visibleBeforeResize.forEach(function(item){
				item.show();
			});
		},

		/**
		 * Common event handler to every action.
		 *
		 * @param ev {Event} Event object.
		 * @private
		 */
		_onAction: function(ev){
			var el = $(ev.currentTarget);
			var item = this.getItemInstance(el);

			ev.type === C.EVENT_CLICK && item.data.trigger === C.TRIGGER_CLICK && ev.preventDefault();

			item.actionHandler(ev.type);
		},

		/**
		 * OnResize event callback handler.
		 *
		 * @private
		 */
		_onResize: function(){
			!this._task.resize && this._hideAll();
			this._task.resize && clearTimeout(this._task.resize);
			this._task.resize = setTimeout(function () {
				this._showAll();
				this._task.resize = undefined;
				this._visibleBeforeResize = [];
			}.bind(this), 100);
		},

		/**
		 * OnBodyClick event callback handler.
		 *
		 * @param ev {Event} Event object.
		 * @private
		 */
		_onBodyClick: function(ev){
			var el = $(ev.target);
			var parent = el.parents('.' + C.SELECTOR_PREFIX + C.SELECTOR_CONTAINER);
			var selector = C.SELECTOR_PREFIX + C.SELECTOR_CONTAINER;
			var container = el.hasClass(selector) ? el : parent.size() ? parent : false;

			var instance = this._isInited(el) ? this.getItemInstance(el) : false;

			if (!instance || (instance.data.trigger !== C.TRIGGER_CLICK)) {
				$.each(this._itemInstances, function (index, item) {
					item.isVisible()
					&& item.data.trigger === C.TRIGGER_CLICK
					&& (!container || item.el.protip.get(0) !== container.get(0))
					&& item.hide();
				});
			}
		},

		/**
		 *  Click event callback handler for closing elements.
		 *
		 * @param ev {Event} Event object.
		 * @private
		 */
		_onCloseClick: function(ev){
			var identifier = $(ev.currentTarget).parents('.' + C.SELECTOR_PREFIX + C.SELECTOR_CONTAINER).data(this.namespaced(C.PROP_IDENTIFIER));
			this._itemInstances[identifier] && this._itemInstances[identifier].hide();
		},

		/**
		 * Handles add/removed nodes.
		 *
		 * @param mutations {<Array>MutationRecord}
		 * @private
		 */
		_mutationObserverCallback: function(mutations) {
			mutations.forEach(function(mutation) {
				for (var i = 0; i < mutation.addedNodes.length; i++) {
					var els = $(mutation.addedNodes[i].parentNode).find(this.settings.selector);
					els.each(function(index, el){
						el = $(el);
						if (el.data(this.namespaced(C.PROP_TRIGGER)) === C.TRIGGER_STICKY){
							this.getItemInstance(el).show();
						}
					}.bind(this));
				}

				for (var i = 0; i < mutation.removedNodes.length; i++) {
					var el = $(mutation.removedNodes[i]);
					el.find(this.settings.selector).each(function(index, item){
						this.getItemInstance($(item)).destroy();
					}.bind(this));

					if (el.hasClass(this.settings.selector.replace('.', ''))) {
						this.getItemInstance(el).destroy();
					}
				}
			}.bind(this));
		},

		/**
		 * Binds up all events.
		 *
		 * @private
		 */
		_bind: function(){
			var body = $(C.SELECTOR_BODY);

			body.on(C.EVENT_CLICK, $.proxy(this._onBodyClick, this))
				.on(C.EVENT_MOUSEOVER, this.settings.selector, $.proxy(this._onAction, this))
				.on(C.EVENT_MOUSEOUT, this.settings.selector, $.proxy(this._onAction, this))
				.on(C.EVENT_CLICK, this.settings.selector, $.proxy(this._onAction, this))
				.on(C.EVENT_CLICK, C.SELECTOR_CLOSE, $.proxy(this._onCloseClick, this));

			$(window).on(C.EVENT_RESIZE, $.proxy(this._onResize, this));

			if (this.settings.observer) {
				this._observerInstance = new MutationObserver(this._mutationObserverCallback.bind(this));

				this._observerInstance.observe(body.get(0), {
					attributes: false,
					childList: true,
					characterData: false,
					subtree: true
				});
			}
		},

		/**
		 * Unbinds all events.
		 *
		 * @private
		 */
		_unbind: function(){
			$(C.SELECTOR_BODY)
				.off(C.EVENT_CLICK, $.proxy(this._onBodyClick, this))
				.off(C.EVENT_MOUSEOVER, this.settings.selector, $.proxy(this._onAction, this))
				.off(C.EVENT_MOUSEOUT, this.settings.selector, $.proxy(this._onAction, this))
				.off(C.EVENT_CLICK, this.settings.selector, $.proxy(this._onAction, this))
				.off(C.EVENT_CLICK, C.SELECTOR_CLOSE, $.proxy(this._onCloseClick, this));

			$(window).off(C.EVENT_RESIZE, $.proxy(this._onResize, this));

			if (this.settings.observer) {
				this._observerInstance.disconnect();
			}
		}
	});

	return ProtipClass;

}));
<|endoftext|>


<commit_before>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake_l@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

function buildTestList() {
    var testList = [];

    function buildTest(file, expectPaths, expectErrors) {
        testList.push({
            path: file,
            expectPaths: expectPaths,
            expectErrors: expectErrors
        });
    }

    //Core Javascript, no symbex / annotations
    buildTest('core/bools.js', 1, 0);
    buildTest('core/recursion.js', 1, 0);
    buildTest('core/lamda.js', 1, 0);

    //Booleans
    buildTest('bool/hello.js', 2, 0);
    buildTest('bool/basic.js', 4, 1);

    //Pure Symbols
    buildTest('pure/pure_symbol.js', 8, 0)

    //Integers
    buildTest('integers/hello.js', 2, 0);
    buildTest('integers/lt.js', 3, 0);
    buildTest('integers/coerce.js', 2, 0);
    buildTest('integers/mul.js', 2, 0);
    buildTest('integers/breaker.js', 1, 0);
    buildTest('integers/infoflow.js', 17, 0);

    //Fractions
    buildTest('fractions/fraction_one.js', 3, 0);

    buildTest('assert/assert.js', 6, 0);

    buildTest('assumes/basic.js', 2, 0);
    buildTest('assumes/wrapped_assume.js', 2, 0);

    //Loops
    buildTest('loops/loop_alot.js', 12, 0);

    //Named methods
    buildTest('named_method/simple.js', 1, 0);

    //Strings
    buildTest('strings/hello_strings.js', 2, 0);
    buildTest('strings/hello_strings2.js', 3, 0);
    buildTest('strings/hello_strings_concat.js', 2, 0);
    buildTest('strings/hello_strings_concat2.js', 1, 0);
    buildTest('strings/hello_strings_len.js', 2, 0);
    buildTest('strings/strings_concat.js', 2, 0);
    buildTest('strings/warning.js', 4, 0);

    buildTest('regex/test/alternatives/simple.js', 4, 4);
    buildTest('regex/test/alternatives/many.js', 4, 4);
    buildTest('regex/test/alternatives/words.js', 4, 4);
    buildTest('regex/test/alternatives/exhaustive_simple.js', 5, 5);
    buildTest('regex/test/alternatives/multiple_related.js', 7, 7);

    buildTest('regex/test/atoms/simple_one.js', 2, 1);
    buildTest('regex/test/atoms/simple_two.js', 2, 1);
    buildTest('regex/test/atoms/long_example.js', 2, 2);
    buildTest('regex/test/atoms/empty_example.js', 2, 2);
    buildTest('regex/test/atoms/mixed_escaped.js', 3, 3); //TODO: Should this be 2
    buildTest('regex/test/atoms/non_alpha.js', 2, 2);
    buildTest('regex/test/atoms/multiple.js', 6, 6);

    buildTest('regex/test/escaping/ranges.js', 8, 8);
    buildTest('regex/test/escaping/negative_ranges.js', 9, 9);

    buildTest('regex/test/star/star.js', 7, 7);
    buildTest('regex/test/star/online.js', 12, 11);
    buildTest('regex/test/star/lazy.js', 7, 7);
    buildTest('regex/test/star/multiple.js', 5, 5);

    buildTest('regex/test/plus/plus.js', 12, 11);
    buildTest('regex/test/plus/lazy.js', 12, 11);
    buildTest('regex/test/plus/online.js', 11, 10);
    buildTest('regex/test/plus/multiple.js', 4, 4);

    buildTest('regex/test/anchors/left.js', 3, 3);
    //buildTest('regex/test/anchors/right.js', 3, 3); TODO: An extra query is generated
    buildTest('regex/test/anchors/none.js', 4, 4);

    buildTest('regex/test/assertions/arbitrary_ahead.js', 3, 3);

    buildTest('regex/test/backreferences/closed.js', 2, 2);

    buildTest('regex/search/simple.js', 2, 2);
    buildTest('regex/search/alt.js', 3, 3);
    buildTest('regex/search/not_at_start.js', 3, 3);
    buildTest('regex/search/test_at_start.js', 5, 5);

    /*
    //Regex
    buildTest('regex/primatives/anchors_one.js', 3, 1);
    buildTest('regex/primatives/anchors_two.js', 5, 2);

    buildTest('regex/primatives/simple_one.js', 2, 0);
    buildTest('regex/primatives/simple_two.js', 2, 1);

    buildTest('regex/primatives/klene_plus_one.js', 3, 1);
    buildTest('regex/primatives/klene_plus_two.js', 3, 1);
    buildTest('regex/primatives/klene_plus_three.js', 2, 0);

    buildTest('regex/primatives/kleene_star_two.js', 3, 2);
    buildTest('regex/primatives/kleene_star_three.js', 2, 1);

    buildTest('regex/primatives/primative_rw_github.js', 2, 1);

    //buildTest('regex/test_three_deep.js', 7, 3);

    buildTest('regex/replace_and_length.js', 5, 0);
    buildTest('regex/replace_and_length.js', 3, 0);
    */

    //Async
    buildTest('async/settimeout.js', 3, 1);

    return testList;
}

exports["default"] = buildTestList();
module.exports = exports["default"];
<commit_msg>Re-add right test<commit_after>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake_l@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

function buildTestList() {
    var testList = [];

    function buildTest(file, expectPaths, expectErrors) {
        testList.push({
            path: file,
            expectPaths: expectPaths,
            expectErrors: expectErrors
        });
    }

    //Core Javascript, no symbex / annotations
    buildTest('core/bools.js', 1, 0);
    buildTest('core/recursion.js', 1, 0);
    buildTest('core/lamda.js', 1, 0);

    //Booleans
    buildTest('bool/hello.js', 2, 0);
    buildTest('bool/basic.js', 4, 1);

    //Pure Symbols
    buildTest('pure/pure_symbol.js', 8, 0)

    //Integers
    buildTest('integers/hello.js', 2, 0);
    buildTest('integers/lt.js', 3, 0);
    buildTest('integers/coerce.js', 2, 0);
    buildTest('integers/mul.js', 2, 0);
    buildTest('integers/breaker.js', 1, 0);
    buildTest('integers/infoflow.js', 17, 0);

    //Fractions
    buildTest('fractions/fraction_one.js', 3, 0);

    buildTest('assert/assert.js', 6, 0);

    buildTest('assumes/basic.js', 2, 0);
    buildTest('assumes/wrapped_assume.js', 2, 0);

    //Loops
    buildTest('loops/loop_alot.js', 12, 0);

    //Named methods
    buildTest('named_method/simple.js', 1, 0);

    //Strings
    buildTest('strings/hello_strings.js', 2, 0);
    buildTest('strings/hello_strings2.js', 3, 0);
    buildTest('strings/hello_strings_concat.js', 2, 0);
    buildTest('strings/hello_strings_concat2.js', 1, 0);
    buildTest('strings/hello_strings_len.js', 2, 0);
    buildTest('strings/strings_concat.js', 2, 0);
    buildTest('strings/warning.js', 4, 0);

    buildTest('regex/test/alternatives/simple.js', 4, 4);
    buildTest('regex/test/alternatives/many.js', 4, 4);
    buildTest('regex/test/alternatives/words.js', 4, 4);
    buildTest('regex/test/alternatives/exhaustive_simple.js', 5, 5);
    buildTest('regex/test/alternatives/multiple_related.js', 7, 7);

    buildTest('regex/test/atoms/simple_one.js', 2, 1);
    buildTest('regex/test/atoms/simple_two.js', 2, 1);
    buildTest('regex/test/atoms/long_example.js', 2, 2);
    buildTest('regex/test/atoms/empty_example.js', 2, 2);
    buildTest('regex/test/atoms/mixed_escaped.js', 3, 3); //TODO: Should this be 2
    buildTest('regex/test/atoms/non_alpha.js', 2, 2);
    buildTest('regex/test/atoms/multiple.js', 6, 6);

    buildTest('regex/test/escaping/ranges.js', 8, 8);
    buildTest('regex/test/escaping/negative_ranges.js', 9, 9);

    buildTest('regex/test/star/star.js', 7, 7);
    buildTest('regex/test/star/online.js', 12, 11);
    buildTest('regex/test/star/lazy.js', 7, 7);
    buildTest('regex/test/star/multiple.js', 5, 5);

    buildTest('regex/test/plus/plus.js', 12, 11);
    buildTest('regex/test/plus/lazy.js', 12, 11);
    buildTest('regex/test/plus/online.js', 11, 10);
    buildTest('regex/test/plus/multiple.js', 4, 4);

    buildTest('regex/test/anchors/left.js', 3, 3);
    buildTest('regex/test/anchors/right.js', 3, 3); //TODO: An extra query is generated
    buildTest('regex/test/anchors/none.js', 4, 4);

    buildTest('regex/test/assertions/arbitrary_ahead.js', 3, 3);

    buildTest('regex/test/backreferences/closed.js', 2, 2);

    buildTest('regex/search/simple.js', 2, 2);
    buildTest('regex/search/alt.js', 3, 3);
    buildTest('regex/search/not_at_start.js', 3, 3);
    buildTest('regex/search/test_at_start.js', 5, 5);

    /*
    //Regex
    buildTest('regex/primatives/anchors_one.js', 3, 1);
    buildTest('regex/primatives/anchors_two.js', 5, 2);

    buildTest('regex/primatives/simple_one.js', 2, 0);
    buildTest('regex/primatives/simple_two.js', 2, 1);

    buildTest('regex/primatives/klene_plus_one.js', 3, 1);
    buildTest('regex/primatives/klene_plus_two.js', 3, 1);
    buildTest('regex/primatives/klene_plus_three.js', 2, 0);

    buildTest('regex/primatives/kleene_star_two.js', 3, 2);
    buildTest('regex/primatives/kleene_star_three.js', 2, 1);

    buildTest('regex/primatives/primative_rw_github.js', 2, 1);

    //buildTest('regex/test_three_deep.js', 7, 3);

    buildTest('regex/replace_and_length.js', 5, 0);
    buildTest('regex/replace_and_length.js', 3, 0);
    */

    //Async
    buildTest('async/settimeout.js', 3, 1);

    return testList;
}

exports["default"] = buildTestList();
module.exports = exports["default"];
<|endoftext|>