<commit_before>import React from 'react';
import styled from 'styled-components';

import utils from '../lib/utils';
import Tile from './Tile';

const TILE_CONSTANTS = {
  width: 90,
  height: 90,
  count: 4,
};

class App extends React.Component {
  constructor(props) {
    super(props);

    const tiles = utils.range((TILE_CONSTANTS.count) ** 2).map(tileIndex => {
      const { row, column, top, left } = this._getTilePosition(tileIndex);
      const number = this.props.levelData.tileSet[row][column];
      const isEmpty = number === null;

      return {
        number,
        row,
        column,
        top,
        left,
        width: TILE_CONSTANTS.width,
        height: TILE_CONSTANTS.height,
        empty: isEmpty,
        correct: false,
      };
    });

    this.state = {
      tiles,
    };
  }

  render() {
    return (

            {this._renderTiles()}

    );
  }

  _renderTiles() {
    return this.state.tiles.map((tile, tileId) => {
      if (tile.empty) {
        return null;
      }

      return (
        <Tile
          key={`tile-${tileId}`}
          {...tile}
          onClick={this._onTileClick.bind(this, tileId)}
        />
      );
    });
  }

  _getTilePosition(tileIndex) {
    const column = tileIndex % TILE_CONSTANTS.count;
    const row = Math.floor(tileIndex / TILE_CONSTANTS.count);

    return {
      column,
      row,
      left: column * TILE_CONSTANTS.width,
      top: row * TILE_CONSTANTS.height,
    };
  }

  _isTilePositionedOk(tileIndex, tileNumber) {
    const { row, column } = this._getTilePosition(tileIndex);
    return this.props.levelData.tileSet[row][column] === tileNumber;
  }

  _onTileClick(tileId) {
    let { row, column, left, top } = this._getTilePosition(tileId);

    // Find empty
    const emptyTilePosition = this.state.tiles.findIndex(t => t.empty);
    let emptyTile = Object.assign(
      {
        width: TILE_CONSTANTS.width,
        height: TILE_CONSTANTS.height,
        empty: true,
      },
      this._getTilePosition(emptyTilePosition),
    );

    // Is this tale neighbouring the empty tile? If so, switch them.
    if (row === emptyTile.row && Math.abs(column - emptyTile.column) === 1) {
      left += TILE_CONSTANTS.width * (emptyTile.column - column);
      column = emptyTile.column;
    } else if (
      column === emptyTile.column && Math.abs(row - emptyTile.row) === 1
    ) {
      top += TILE_CONSTANTS.height * (emptyTile.row - row);
      row = emptyTile.row;
    } else {
      return;
    }

    // Re-render entire grid
    this.setState({
      tiles: this.state.tiles.map((tile, tileIndex) => {
        if (tileId === tileIndex) {
          return emptyTile;
        }

        if (emptyTilePosition === tileIndex) {
          const number = this.state.tiles[tileId].number;
          const correct = this._isTilePositionedOk(tileIndex, number);

          return Object.assign({}, tile, {
            number,
            empty: false,
            row,
            left,
            top,
            column,
            correct,
          });
        }

        return tile;
      }),
    });
  }
}

App.propTypes = {
  levelData: React.PropTypes.shape({
    moves: React.PropTypes.number.isRequired,
    tileSet: React.PropTypes.arrayOf(
      React.PropTypes.arrayOf(React.PropTypes.number),
    ).isRequired,
  }),
};

export default styled(App)`
  flex: 1;
  display: flex;
  flex-direction: column;

  .content {
    flex: 1 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .grid {
    width: ${props => TILE_CONSTANTS.height * TILE_CONSTANTS.count}px;
    height: ${props => TILE_CONSTANTS.height * TILE_CONSTANTS.count}px;
    position: relative;
  }
`;
<commit_msg>Implement tile randomization<commit_after>import React from 'react';
import styled from 'styled-components';

import utils from '../lib/utils';
import Tile from './Tile';

const TILE_CONSTANTS = {
  width: 90,
  height: 90,
  count: 4,
};

class App extends React.Component {
  constructor(props) {
    super(props);

    const randomTiles = this.props.levelData.tileSet.map(row => {
      return utils.randomSubarray(row, row.length);
    });

    const tiles = utils.range((TILE_CONSTANTS.count) ** 2).map(tileIndex => {
      const { row, column, top, left } = this._getTilePosition(tileIndex);
      const number = randomTiles[row][column];
      const isEmpty = number === null;

      return {
        number,
        row,
        column,
        top,
        left,
        width: TILE_CONSTANTS.width,
        height: TILE_CONSTANTS.height,
        empty: isEmpty,
        correct: number === this.props.levelData.tileSet[row][column],
      };
    });

    this.state = {
      tiles,
      tileSet: this.props.levelData.tileSet,
    };
  }

  render() {
    return (

            {this._renderTiles()}

    );
  }

  _renderTiles() {
    return this.state.tiles.map((tile, tileId) => {
      if (tile.empty) {
        return null;
      }

      return (
        <Tile
          key={`tile-${tileId}`}
          {...tile}
          onClick={this._onTileClick.bind(this, tileId)}
        />
      );
    });
  }

  _getTilePosition(tileIndex) {
    const column = tileIndex % TILE_CONSTANTS.count;
    const row = Math.floor(tileIndex / TILE_CONSTANTS.count);

    return {
      column,
      row,
      left: column * TILE_CONSTANTS.width,
      top: row * TILE_CONSTANTS.height,
    };
  }

  _isTilePositionedOk(tileIndex, tileNumber) {
    const { row, column } = this._getTilePosition(tileIndex);
    return this.props.levelData.tileSet[row][column] === tileNumber;
  }

  _onTileClick(tileId) {
    let { row, column, left, top } = this._getTilePosition(tileId);

    // Find empty
    const emptyTilePosition = this.state.tiles.findIndex(t => t.empty);
    let emptyTile = Object.assign(
      {
        width: TILE_CONSTANTS.width,
        height: TILE_CONSTANTS.height,
        empty: true,
      },
      this._getTilePosition(emptyTilePosition),
    );

    // Is this tale neighbouring the empty tile? If so, switch them.
    if (row === emptyTile.row && Math.abs(column - emptyTile.column) === 1) {
      left += TILE_CONSTANTS.width * (emptyTile.column - column);
      column = emptyTile.column;
    } else if (
      column === emptyTile.column && Math.abs(row - emptyTile.row) === 1
    ) {
      top += TILE_CONSTANTS.height * (emptyTile.row - row);
      row = emptyTile.row;
    } else {
      return;
    }

    // Re-render entire grid
    this.setState({
      tiles: this.state.tiles.map((tile, tileIndex) => {
        if (tileId === tileIndex) {
          return emptyTile;
        }

        if (emptyTilePosition === tileIndex) {
          const number = this.state.tiles[tileId].number;
          const correct = this._isTilePositionedOk(tileIndex, number);

          return Object.assign({}, tile, {
            number,
            empty: false,
            row,
            left,
            top,
            column,
            correct,
          });
        }

        return tile;
      }),
    });
  }
}

App.propTypes = {
  levelData: React.PropTypes.shape({
    moves: React.PropTypes.number.isRequired,
    tileSet: React.PropTypes.arrayOf(
      React.PropTypes.arrayOf(React.PropTypes.number),
    ).isRequired,
  }),
};

export default styled(App)`
  flex: 1;
  display: flex;
  flex-direction: column;

  .content {
    flex: 1 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .grid {
    width: ${props => TILE_CONSTANTS.height * TILE_CONSTANTS.count}px;
    height: ${props => TILE_CONSTANTS.height * TILE_CONSTANTS.count}px;
    position: relative;
  }
`;
<|endoftext|>


<commit_before>import React, {Component} from "react";
import Controls from "./Controls";
import Grid from "./Grid";
import {
    getColor,
    getNeighborsCoord,
    getCellCoordinates,
    getCenterCoordinates,
    getCellCoordinatesToDraw
        } from "../utils/helpers";
import PropTypes from "prop-types";

class App extends Component {
    state = {
        gridWidth: "501px",
        gridHeight: "381px",
        cellSize: 9
    }

    static propTypes = {
        /**
         * Game grid length
         */
        gridWidth: PropTypes.string,
        /**
         * Game grid height
         */
        gridHeight: PropTypes.string,
        /**
         * Gets called when game grid updates: at initial run and Reset
         */
        onUpdate: PropTypes.func,
        /**
         * Gets called when user resets game state
         */
        handleReset: PropTypes.func,
        /**
         * Gets called when user clicks game start buttons
         */
        handleStart: PropTypes.func
    }

    /**
     * Draws cell grid on update
     * @param {number} length Canvas length
     * @param {number} height Canvas height
     */
    handleUpdateCanvas = (length, height) => {
        var canvas = document.getElementById("game-grid");
        var context = canvas.getContext("2d");
        for (let x = 0.5; x < length; x += 10) {
            context.moveTo(x, 0);
            context.lineTo(x, height);
        }

        for (let y = 0.5; y < height; y += 10) {
            context.moveTo(0, y);
            context.lineTo(length, y);
        }

        context.strokeStyle = "#ddd";
        context.stroke();
    }

    handleStart = () => {

        let centerCoordinates = getCenterCoordinates();
        let canvas = document.getElementById("game-grid");
        let ctx = canvas.getContext("2d");

        for (let coordinates of centerCoordinates) {
            let cellColor = getColor(ctx, ...coordinates);

            // if ( cellColor === 16776960 ) { // decimal for yellow color
                // console.log(`Cell is filled. Coordinates: ${coordinates}`)

                let neighbors = getNeighborsCoord(...coordinates);
                // console.log(neighbors)

                for (let neighbor of neighbors) {
                    let neigborsCount = 0;
                    // console.log(neighbor);
                    // console.log(getColor(ctx, ...neighbor));
                    neigborsCount = (getColor(ctx, ...neighbor) !== 0) ? neigborsCount + 1 : neigborsCount;
                    console.log(neigborsCount);
                }
            // }
        }
    }

    handleReset = () => {
        let canvas = document.getElementById("game-grid");
        let ctx = canvas.getContext("2d");

        let width = parseInt(this.state.gridWidth, 10);
        let height = parseInt(this.state.gridHeight, 10);

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        this.handleUpdateCanvas(width, height);
    }

    render() {
        let width= this.state.gridWidth;
        let height = this.state.gridHeight;

        return(

                <Controls handleReset={this.handleReset}
                          handleStart={this.handleStart}/>
                <Grid gridWidth={width}
                      gridHeight={height}
                      onUpdate={this.handleUpdateCanvas}/>

        );
    }
}

export default App;
<commit_msg>Game feature development<commit_after>import React, {Component} from "react";
import Controls from "./Controls";
import Grid from "./Grid";
import {
    getColor,
    getNeighborsCoord,
    getCellCoordinates,
    getCenterCoordinates,
    getCellCoordinatesToDraw
        } from "../utils/helpers";
import PropTypes from "prop-types";

class App extends Component {
    state = {
        gridWidth: "501px",
        gridHeight: "381px",
        cellSize: 9
    }

    static propTypes = {
        /**
         * Game grid length
         */
        gridWidth: PropTypes.string,
        /**
         * Game grid height
         */
        gridHeight: PropTypes.string,
        /**
         * Gets called when game grid updates: at initial run and Reset
         */
        onUpdate: PropTypes.func,
        /**
         * Gets called when user resets game state
         */
        handleReset: PropTypes.func,
        /**
         * Gets called when user clicks game start buttons
         */
        handleStart: PropTypes.func
    }

    /**
     * Draws cell grid on update
     * @param {number} length Canvas length
     * @param {number} height Canvas height
     */
    handleUpdateCanvas = (length, height) => {
        var canvas = document.getElementById("game-grid");
        var context = canvas.getContext("2d");
        for (let x = 0.5; x < length; x += 10) {
            context.moveTo(x, 0);
            context.lineTo(x, height);
        }

        for (let y = 0.5; y < height; y += 10) {
            context.moveTo(0, y);
            context.lineTo(length, y);
        }

        context.strokeStyle = "#ddd";
        context.stroke();
    }

    handleStart = () => {

        let centerCoordinates = getCenterCoordinates();
        let canvas = document.getElementById("game-grid");
        let ctx = canvas.getContext("2d");

        for (let coordinates of centerCoordinates) {
            let cellColor = getColor(ctx, ...coordinates);

            // if ( cellColor === 16776960 ) { // decimal for yellow color
                // console.log(`Cell is filled. Coordinates: ${coordinates}`)

                let neighbors = getNeighborsCoord(...coordinates);
                // console.log(neighbors)
                let neigborsCount = 0;
                for (let neighbor of neighbors) {

                    // console.log(neighbor);
                    // console.log(getColor(ctx, ...neighbor));
                    neigborsCount = (getColor(ctx, ...neighbor) !== 0) ? neigborsCount + 1 : neigborsCount;
                }
                if (neigborsCount === 3) { console.log(neigborsCount, coordinates) }
            // }
        }
    }

    handleReset = () => {
        let canvas = document.getElementById("game-grid");
        let ctx = canvas.getContext("2d");

        let width = parseInt(this.state.gridWidth, 10);
        let height = parseInt(this.state.gridHeight, 10);

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        this.handleUpdateCanvas(width, height);
    }

    render() {
        let width= this.state.gridWidth;
        let height = this.state.gridHeight;

        return(

                <Controls handleReset={this.handleReset}
                          handleStart={this.handleStart}/>
                <Grid gridWidth={width}
                      gridHeight={height}
                      onUpdate={this.handleUpdateCanvas}/>

        );
    }
}

export default App;
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import Search from './Search'
import List from './List'

import '../styles/App.sass'

const list = [
  {
    title: 'React',
    url: 'https://facebook.github.io/react/',
    author: 'Jordan Walke',
    num_comments: 3,
    points: 4,
    objectID: 0,
  },
  {
    title: 'Redux',
    url: 'https://github.com/reactjs/redux',
    author: 'Dan Abramov, Andrew Clark',
    num_comments: 2,
    points: 5,
    objectID: 1,
  },
  {
    title: 'HaNews',
    url: 'https://nayed.github.io/hanews',
    author: 'Nayed Saïd Ali',
    num_comments: 6,
    points: 2,
    objectID: 2,
  },
]

class App extends Component {
  constructor(props) {
    super(props)

    this.state = {
      list,
      searchTerm: ''
    }

    this.onDismiss = this.onDismiss.bind(this)
    this.onSearchChange = this.onSearchChange.bind(this)
  }

  onDismiss(id) {
    const isNotId = item => item.objectID !== id
    const updatedList = this.state.list.filter(isNotId)
    this.setState({ list: updatedList })
  }

  onSearchChange(event) {
    this.setState({ searchTerm: event.target.value })
  }

  render() {
    const { searchTerm, list } = this.state

    return (

              <Search
                value={searchTerm}
                onChange={this.onSearchChange}
                className="search"
              >
                Search
              </Search>

          <List
            list={list}
            pattern={searchTerm}
            onDismiss={this.onDismiss}
          />

    )
  }
}

export default App
<commit_msg>yo hackernews api<commit_after>import React, { Component } from 'react'
import Search from './Search'
import List from './List'

import '../styles/App.sass'

const DEFAULT_QUERY = 'ruby'

const PATH_BASE = 'https://hn.algolia.com/api/v1'
const PATH_SEARCH = '/search'
const PARAM_SEARCH = 'query='

class App extends Component {
  constructor(props) {
    super(props)

    this.state = {
      result: null,
      searchTerm: DEFAULT_QUERY
    }

    this.setSearchTopStories = this.setSearchTopStories.bind(this)
    this.fetchSearchTopStories = this.fetchSearchTopStories.bind(this)
    this.onDismiss = this.onDismiss.bind(this)
    this.onSearchChange = this.onSearchChange.bind(this)
  }

  setSearchTopStories(result) {
    this.setState({ result })
  }

  fetchSearchTopStories(searchTerm) {
    fetch(`${PATH_BASE}${PATH_SEARCH}?${PARAM_SEARCH}${searchTerm}`)
      .then(response => response.json())
      .then(result => this.setSearchTopStories(result))
  }

  componentDidMount() {
    const { searchTerm } = this.state
    this.fetchSearchTopStories(searchTerm)
  }

  onDismiss(id) {
    const isNotId = item => item.objectID !== id
    const updatedList = this.state.list.filter(isNotId)
    this.setState({ list: updatedList })
  }

  onSearchChange(event) {
    this.setState({ searchTerm: event.target.value })
  }

  render() {
    const { searchTerm, result } = this.state

    if (!result) return null

    return (

              <Search
                value={searchTerm}
                onChange={this.onSearchChange}
                className="search"
              >
                Search
              </Search>

          <List
            list={result.hits}
            pattern={searchTerm}
            onDismiss={this.onDismiss}
          />

    )
  }
}

export default App
<|endoftext|>


<commit_before>'use strict'

const { css } = require('glamor')
const propTypes = require('prop-types')

const h = require('../utils/h')
const sort = require('../utils/sort')
const getStatus = require('../selectors/getStatus')
const { NAV_MIN_WIDTH, NAV_WIDTH, CONTENT_MIN_WIDTH } = require('../constants/sizes')

const NavGroup = require('./NavGroup')
const NavItem = require('./NavItem')

const style = {

	self: css({
		display: 'flex',
		flexDirection: 'column',
		minWidth: NAV_MIN_WIDTH,
		width: `calc(${ NAV_WIDTH } - var(--currentSize-horizontal, 0px))`,
		maxWidth: `calc(100% - ${ CONTENT_MIN_WIDTH })`
	}),

	scroller: css({
		flexGrow: '1',
		padding: '1em 0 1em 1em',
		height: '100%',
		overflow: 'auto',
		WebkitOverflowScrolling: 'touch'
	})

}

module.exports = ({ statuses, components, currentComponent, currentTab }) => {

	const toNavGroup = (group) => (
		h(NavGroup, {
			key: group,
			label: group
		})
	)

	const toNavItem = (component) => (
		h(NavItem, {
			key: component.id,
			id: component.id,
			label: component.name,
			status: getStatus(statuses, component),
			active: component.id===currentComponent.id,
			currentTab
		})
	)

	const items = sort(components, toNavGroup, toNavItem)

	return (
		h('nav', { className: style.self.toString() },
			h('div', { className: style.scroller.toString() },
				items
			)
		)
	)

}

module.exports.propTypes = {

	statuses: propTypes.object.isRequired,
	components: propTypes.array.isRequired,
	currentComponent: propTypes.object.isRequired,
	currentTab: propTypes.object.isRequired

}<commit_msg>Reduced amount of scrolling containers<commit_after>'use strict'

const { css } = require('glamor')
const propTypes = require('prop-types')

const h = require('../utils/h')
const sort = require('../utils/sort')
const getStatus = require('../selectors/getStatus')
const { NAV_MIN_WIDTH, NAV_WIDTH, CONTENT_MIN_WIDTH } = require('../constants/sizes')

const NavGroup = require('./NavGroup')
const NavItem = require('./NavItem')

const style = {

	self: css({
		padding: '1em 0 1em 1em',
		minWidth: NAV_MIN_WIDTH,
		width: `calc(${ NAV_WIDTH } - var(--currentSize-horizontal, 0px))`,
		maxWidth: `calc(100% - ${ CONTENT_MIN_WIDTH })`,
		overflow: 'auto',
		WebkitOverflowScrolling: 'touch'
	})

}

module.exports = ({ statuses, components, currentComponent, currentTab }) => {

	const toNavGroup = (group) => (
		h(NavGroup, {
			key: group,
			label: group
		})
	)

	const toNavItem = (component) => (
		h(NavItem, {
			key: component.id,
			id: component.id,
			label: component.name,
			status: getStatus(statuses, component),
			active: component.id===currentComponent.id,
			currentTab
		})
	)

	const items = sort(components, toNavGroup, toNavItem)

	return (
		h('nav', { className: style.self.toString() },
			items
		)
	)

}

module.exports.propTypes = {

	statuses: propTypes.object.isRequired,
	components: propTypes.array.isRequired,
	currentComponent: propTypes.object.isRequired,
	currentTab: propTypes.object.isRequired

}<|endoftext|>


<commit_before>import React, { Component } from 'react';

export default class App extends Component {
	constructor(props) {
		super(props);
		this.state = {
			peopleCount: null
		}

		this.dict = {
			6: ['预言家', '女巫', '猎人', '白痴', '狼人', '狼人', '平民', '平民', '平民', '平民', '平民', '平民'],
			7: ['预言家', '女巫', '猎人', '白痴', '狼人', '狼人', '平民', '平民', '平民', '平民', '平民', '平民', '平民', '平民'],
			8: ['预言家', '女巫', '猎人', '白痴', '狼人', '狼人', '平民', '平民', '平民', '平民', '平民', '平民', '平民', '平民', '狼人', '守卫']
		}

		this.onInputChange = this.onInputChange.bind(this);
		this.renderTable = this.renderTable.bind(this);
		this.renderRows = this.renderRows.bind(this);
		this.shuffle = this.shuffle.bind(this);
	}

	onInputChange(event) {
		this.setState({
			peopleCount: parseInt(event.target.value)
		})
	}

	shuffle(array) {
	  let currentIndex = array.length;
	  let temporaryValue;
	  let randomIndex;

	  // While there remain elements to shuffle...
	  while (0 !== currentIndex) {

	    // Pick a remaining element...
	    randomIndex = Math.floor(Math.random() * currentIndex);
	    currentIndex -= 1;

	    // And swap it with the current element.
	    temporaryValue = array[currentIndex];
	    array[currentIndex] = array[randomIndex];
	    array[randomIndex] = temporaryValue;
	  }

	  return array;
	}

	renderRows(count, shuffleRoles1, shuffleRoles2) {
		let res=[];
		let i;

		for (i=0; i<count; i++) {
			res.push(

					{i}
					{shuffleRoles1[i]}
					{shuffleRoles2[i]}

				)
		}
		return res;
	}

	renderTable() {

		let resTable = null;
		const count = this.state.peopleCount;
		let flag = true;

		if (typeof(count) === 'number' && count > 5 && count < 9) {
			const roles = this.dict[count];
			let shuffleRoles1;
			let shuffleRoles2;
			while(flag) {
				const shuffleRoles = this.shuffle(roles);
				shuffleRoles1 = shuffleRoles.slice(0, count);
				shuffleRoles2 = shuffleRoles.slice(count);
				let i;
				for (i=0;i<count;i++) {
					if(shuffleRoles1[i] === '狼人' && shuffleRoles2[i] === '狼人') flag = true;
					if((shuffleRoles1[i] === '狼人' && shuffleRoles2[i] === '预言家') || (shuffleRoles2[i] === '狼人' && shuffleRoles1[i] === '预言家')) flag = true;
				}
				if ( i===count) {
					flag = false;
				}
			}
			resTable = this.renderRows(count, shuffleRoles1, shuffleRoles2);

		}

		return resTable;
	}

	render() {
	return (

	        <input
	          placeholder="请输入参与人数(6-8)"
	          className="form-control"
	          value={this.state.term}
	          onChange={this.onInputChange} />

			    		编号
			    		职业1
			    		职业2

		    		{this.renderTable()}

	);
	}
}
<commit_msg>Update app.js<commit_after>import React, { Component } from 'react';

export default class App extends Component {
	constructor(props) {
		super(props);
		this.state = {
			peopleCount: null
		}

		this.dict = {
			6: ['预言家', '女巫', '猎人', '白痴', '狼人', '狼人', '平民', '平民', '平民', '平民', '平民', '平民'],
			7: ['预言家', '花蝴蝶', '猎人', '白痴', '狼人', '狼人', '守卫', '平民', '平民', '平民', '平民', '平民', '平民', '平民'],
			8: ['预言家', '女巫', '猎人', '白痴', '狼人', '狼人', '平民', '平民', '平民', '平民', '平民', '平民', '平民', '平民', '狼人', '守卫']
		}

		this.onInputChange = this.onInputChange.bind(this);
		this.renderTable = this.renderTable.bind(this);
		this.renderRows = this.renderRows.bind(this);
		this.shuffle = this.shuffle.bind(this);
	}

	onInputChange(event) {
		this.setState({
			peopleCount: parseInt(event.target.value)
		})
	}

	shuffle(array) {
	  let currentIndex = array.length;
	  let temporaryValue;
	  let randomIndex;

	  // While there remain elements to shuffle...
	  while (0 !== currentIndex) {

	    // Pick a remaining element...
	    randomIndex = Math.floor(Math.random() * currentIndex);
	    currentIndex -= 1;

	    // And swap it with the current element.
	    temporaryValue = array[currentIndex];
	    array[currentIndex] = array[randomIndex];
	    array[randomIndex] = temporaryValue;
	  }

	  return array;
	}

	renderRows(count, shuffleRoles1, shuffleRoles2) {
		let res=[];
		let i;

		for (i=0; i<count; i++) {
			res.push(

					{i}
					{shuffleRoles1[i]}
					{shuffleRoles2[i]}

				)
		}
		return res;
	}

	renderTable() {

		let resTable = null;
		const count = this.state.peopleCount;
		let flag = true;

		if (typeof(count) === 'number' && count > 5 && count < 9) {
			const roles = this.dict[count];
			let shuffleRoles1;
			let shuffleRoles2;
			while(flag) {
				const shuffleRoles = this.shuffle(roles);
				shuffleRoles1 = shuffleRoles.slice(0, count);
				shuffleRoles2 = shuffleRoles.slice(count);
				let i;
				for (i=0;i<count;i++) {
					if(shuffleRoles1[i] === '狼人' && shuffleRoles2[i] === '狼人') flag = true;
					if((shuffleRoles1[i] === '狼人' && shuffleRoles2[i] === '预言家') || (shuffleRoles2[i] === '狼人' && shuffleRoles1[i] === '预言家')) flag = true;
				}
				if ( i===count) {
					flag = false;
				}
			}
			resTable = this.renderRows(count, shuffleRoles1, shuffleRoles2);

		}

		return resTable;
	}

	render() {
	return (

	        <input
	          placeholder="请输入参与人数(6-8)"
	          className="form-control"
	          value={this.state.term}
	          onChange={this.onInputChange} />

			    		编号
			    		职业1
			    		职业2

		    		{this.renderTable()}

	);
	}
}
<|endoftext|>


<commit_before>import React from 'react';

import Card from './card';
import NewCardForm from './newcardform';

class CRC extends React.Component {
    constructor (props) {
        super(props);

        this.state = {
            cards: localStorage.cards ? JSON.parse(localStorage.cards) : [],
            newFormVisible: false
        };
    }

    componentDidUpdate (prevProps, prevState) {
        // Sync cards in state object with localStorage
        localStorage.cards = JSON.stringify(this.state.cards);
    }

    addCard (data) {
        // Parse data from form
        var newCard = {
            name             : data.name,
            super            : data.super,
            sub              : data.sub,
            abstract         : data.type == 2,
            interface        : data.type == 3,
            responsibilities : data.responsibilities.split('\n'),
            collaborators    : data.collaborators.split('\n')
        };

        // Add to array in state
        var cardsData = this.state.cards;
        cardsData.push(newCard);

        this.setState({
            cards: cardsData
        });
    }

    removeCard (id) {

    }

    toggleNewCardForm () {
        this.setState({
            newFormVisible: !this.state.newFormVisible
        });
    }

    removeAllCards () {
        this.setState({
            cards: []
        });
    }

    togglePrint () {
        alert('toggleprint');
    }

    render () {
        return (

CRC Card Generator

                    <button onClick={this.toggleNewCardForm.bind(this)}>New card</button>
                    <button onClick={this.removeAllCards.bind(this)}>Remove all</button>
                    <button onClick={this.togglePrint.bind(this)}>Toggle print view</button>

                    { this.state.newFormVisible ? <NewCardForm onAdd={this.addCard.bind(this)} /> : null }

                { this.state.cards.map((cardData, i) =>
                    <Card key={i} data={cardData} />
                ) }

        );
    }
}

export default CRC;
<commit_msg>Toggle header<commit_after>import React from 'react';

import Card from './card';
import NewCardForm from './newcardform';

class CRC extends React.Component {
    constructor (props) {
        super(props);

        this.state = {
            cards: localStorage.cards ? JSON.parse(localStorage.cards) : [],
            newFormVisible: false,
            uiVisible: true,
        };
    }

    componentDidMount () {
        // Toggle print view on `T` key press
        document.body.addEventListener('keydown', (evt) => {
            if (evt.keyCode === 84) {
                this.togglePrint();
            }
        });
    }

    componentDidUpdate (prevProps, prevState) {
        // Sync cards in state object with localStorage
        localStorage.cards = JSON.stringify(this.state.cards);
    }

    addCard (data) {
        // Parse data from form
        var newCard = {
            name             : data.name,
            super            : data.super,
            sub              : data.sub,
            abstract         : data.type == 2,
            interface        : data.type == 3,
            responsibilities : data.responsibilities.split('\n'),
            collaborators    : data.collaborators.split('\n')
        };

        // Add to array in state
        var cardsData = this.state.cards;
        cardsData.push(newCard);

        this.setState({
            cards: cardsData
        });
    }

    removeCard (id) {

    }

    toggleNewCardForm () {
        this.setState({
            newFormVisible: !this.state.newFormVisible
        });
    }

    removeAllCards () {
        if (confirm('Remove all cards?')) {
            this.setState({
                cards: []
            });
        }
    }

    togglePrint () {
        this.setState({
            uiVisible: !this.state.uiVisible
        });
    }

    render () {
        return (

                { this.state.uiVisible ?

CRC Card Generator

                            <button onClick={this.toggleNewCardForm.bind(this)}>New card</button>
                            <button onClick={this.removeAllCards.bind(this)}>Remove all</button>
                            <button onClick={this.togglePrint.bind(this)}>Toggle print view [T key]</button>

                            { this.state.newFormVisible ? <NewCardForm onAdd={this.addCard.bind(this)} /> : null }

                    : null }

                { this.state.cards.map((cardData, i) =>
                    <Card key={i} data={cardData} />
                ) }

        );
    }
}

export default CRC;
<|endoftext|>


<commit_before>import React from 'react';

export default () => (

Log in

);
<commit_msg>Adding an alert<commit_after>import React from 'react';

class Nav extends React.Component {
  openLogin() {
    alert('hi');
  }

  render() {
    return (

Log in

    );
  }
}

export default Nav;
<|endoftext|>


<commit_before>/**
* Configure the Aurelia-KendoUI-plugin
*/
export class KendoConfigBuilder {

	resources: string[] = [];
  useGlobalResources: boolean = true;

  /**
  * Globally register all Kendo Core wrappers
  */
  core(): KendoConfigBuilder {
    this.kendoAutoComplete()
      .kendoButton()
      .kendoTemplateSupport()
      .kendoTabStrip();
    return this;
  }

  /**
  * Globally register all Kendo Core and Kendo Pro wrappers
  */
  pro(): KendoConfigBuilder {
    this.core()
      .kendoGrid()
      .kendoChart();
    return this;
  }

  /**
  * Don't globalize any resources
  * Allows you to import wrappers yourself via <require></require>
  */
  withoutGlobalResources(): KendoConfigBuilder {
    this.useGlobalResources = false;
    return this;
  }

    /**
  * Registers value converters (wrappers around kendo functions)
  */
  useValueConverters(): KendoConfigBuilder {
    this.resources.push('valueconverters/valueconverters');
    return this;
  }

  /**
  * Adds kendo templating support
  */
  kendoTemplateSupport(): KendoConfigBuilder {
    this.resources.push('common/k-template');
    return this;
  }

  kendoAutoComplete(): KendoConfigBuilder {
    this.resources.push('autocomplete/autocomplete');
    return this;
  }

  kendoButton(): KendoConfigBuilder {
    this.resources.push('button/button');
    return this;
  }

  kendoGrid(): KendoConfigBuilder {
    this.resources.push('grid/grid');
    this.resources.push('grid/k-col');
    return this;
  }

  kendoChart(): KendoConfigBuilder {
    this.resources.push('chart/chart');
    return this;
  }

  kendoTabStrip(): KendoConfigBuilder {
    this.resources.push('tabstrip/tabstrip');
    return this;
  }
}
<commit_msg>chore(all): remove tabstrip<commit_after>/**
* Configure the Aurelia-KendoUI-plugin
*/
export class KendoConfigBuilder {

	resources: string[] = [];
  useGlobalResources: boolean = true;

  /**
  * Globally register all Kendo Core wrappers
  */
  core(): KendoConfigBuilder {
    this.kendoAutoComplete()
      .kendoButton()
      .kendoTemplateSupport();
    return this;
  }

  /**
  * Globally register all Kendo Core and Kendo Pro wrappers
  */
  pro(): KendoConfigBuilder {
    this.core()
      .kendoGrid()
      .kendoChart();
    return this;
  }

  /**
  * Don't globalize any resources
  * Allows you to import wrappers yourself via <require></require>
  */
  withoutGlobalResources(): KendoConfigBuilder {
    this.useGlobalResources = false;
    return this;
  }

    /**
  * Registers value converters (wrappers around kendo functions)
  */
  useValueConverters(): KendoConfigBuilder {
    this.resources.push('valueconverters/valueconverters');
    return this;
  }

  /**
  * Adds kendo templating support
  */
  kendoTemplateSupport(): KendoConfigBuilder {
    this.resources.push('common/k-template');
    return this;
  }

  kendoAutoComplete(): KendoConfigBuilder {
    this.resources.push('autocomplete/autocomplete');
    return this;
  }

  kendoButton(): KendoConfigBuilder {
    this.resources.push('button/button');
    return this;
  }

  kendoGrid(): KendoConfigBuilder {
    this.resources.push('grid/grid');
    this.resources.push('grid/k-col');
    return this;
  }

  kendoChart(): KendoConfigBuilder {
    this.resources.push('chart/chart');
    return this;
  }
}
<|endoftext|>


<commit_before>export default {
  api: 'http://ubuntu:5000',
  auth: {
    apiUrl:'http://ubuntu:5000',
    authProviderPaths:{
      github: '/auth/github',
      oauth2: '/auth/oauth2'
    }
  }
}
<commit_msg>* signoutpath suite for koapi<commit_after>let api = 'http://ubuntu:5000';

export default {
  api,
  auth: {
    apiUrl:api,
    signOutPath: '/oauth/token',
    tokenValidationPath: '/oauth/token',
    authProviderPaths:{
      github: '/auth/github',
      oauth2: '/auth/oauth2'
    }
  }
}
<|endoftext|>


<commit_before>import React from 'react-native';
const {
  Image,
  TouchableOpacity,
  StyleSheet,
  Text,
  View,
  TabBarIOS,
  StatusBar
} = React;
import TabBarItemIOS from 'react-native';
import { Scene, Router, Actions } from 'react-native-router-flux'
import Search from '../components/Search';
import Login from '../components/Login';
import Signup from '../components/Signup';
import Results from '../components/Results';
// import Results from '../components/resultsList';
import Favorites from '../components/Favorite';
import favoritesTab from '../assets/images/TabBar-Favorite-Icon@3x.png'
import activeFav from '../assets/images/TabBar-Favorite-Icon-Active@3x.png'
import searchTab from '../assets/images/TabBar-House-Icon@3x.png'
import activeSearch from '../assets/images/TabBar-House-Icon-Active@3x.png'

const scenes = Actions.create(
  <Scene key="root" >
    <Scene type="push" key="Login" initial={true} direction='horizontal' component={Login} duration={100} title='Login' />
    <Scene type="push" key="Search" component={Search} />
    <Scene type="push" key="SignUp" component={Signup} direction='horizontal' duration={100} title='Signup' />
    <Scene type="push" key="Results" component={Results} direction='horizontal' duration={100} title='Results'backTitle="Search" panHandlers={null}/>
    <Scene type="push" key="Favorites" component={Favorites} direction='horizontal' duration={100} title='Favorites'backTitle="Results" panHandlers={null}/>
    <Scene type="push" key="Login"  direction='horizontal' component={Login} title='Login'backTitle="Signup" />
  </Scene>
);

const App = () => (
 <View style={{ flex: 1 }}>
  <StatusBar
    hidden={false}
    showHideTransition="slide"
    animated={true}
  />
  <Router scenes={scenes} />
  <View style={styles.tabbar}>
  <TabBarIOS  style={{ flex:1 }}>
  <TabBarIOS.Item
    title="Search"
    onPress={()=> Actions.Search()}
    icon={searchTab}
    selectedIcon={activeSearch}>
  </TabBarIOS.Item>
    <TabBarIOS.Item
      title="Results"
      onPress={()=> Actions.Results()}
      icon={favoritesTab}
      selectedIcon={activeFav}>
    </TabBarIOS.Item>
    <TabBarIOS.Item
      title="Favorites"
      onPress={()=> Actions.Favorites()}
      icon={favoritesTab}
      selectedIcon={activeFav}>
    </TabBarIOS.Item>
    </TabBarIOS >

  </View>
 </View>
)

const styles = StyleSheet.create({
  tabbar: {
    width: 375,
    height: 49,
    shadowColor: 'black',
     shadowOffset: { height: -2, width: 0 },
     shadowOpacity: 0.05,
     shadowRadius: 3,
    flexDirection: 'row',
    justifyContent: 'center'
  }
});

export default App;<commit_msg>hide navbar<commit_after>import React from 'react-native';
const {
  Image,
  TouchableOpacity,
  StyleSheet,
  Text,
  View,
  TabBarIOS,
  StatusBar
} = React;
import TabBarItemIOS from 'react-native';
import { Scene, Router, Actions } from 'react-native-router-flux'
import Search from '../components/Search';
import Login from '../components/Login';
import Signup from '../components/Signup';
import Results from '../components/Results';
// import Results from '../components/resultsList';
import Favorites from '../components/Favorite';
import favoritesTab from '../assets/images/TabBar-Favorite-Icon@3x.png'
import activeFav from '../assets/images/TabBar-Favorite-Icon-Active@3x.png'
import searchTab from '../assets/images/TabBar-House-Icon@3x.png'
import activeSearch from '../assets/images/TabBar-House-Icon-Active@3x.png'

const scenes = Actions.create(
  <Scene key="root" hideNavBar={true}>
    <Scene type="push" key="Login" initial={true} direction='horizontal' component={Login} duration={100} title='Login' />
    <Scene type="push" key="Search" component={Search} panHandlers={null} />
    <Scene type="push" key="SignUp" component={Signup} direction='horizontal' duration={100} title='Signup' />
    <Scene type="push" key="Results" component={Results} direction='horizontal' duration={100} title='Results'backTitle="Search" panHandlers={null}/>
    <Scene type="push" key="Favorites" component={Favorites} direction='horizontal' duration={100} title='Favorites'backTitle="Results" panHandlers={null}/>
    <Scene type="push" key="Login"  direction='horizontal' component={Login} title='Login'backTitle="Signup" />
  </Scene>
);

const App = () => (
 <View style={{ flex: 1 }}>
  <StatusBar
    translucent={true}
    backgroundColor="rgba(0, 0, 0, 0.2)"
    barStyle="light-content"
    hidden={true}
    showHideTransition="slide"
  />
  <Router scenes={scenes} />
  <View style={styles.tabbar}>
  <TabBarIOS  style={{ flex:1 }}>
  <TabBarIOS.Item
    title="Search"
    onPress={()=> Actions.Search()}
    icon={searchTab}
    selectedIcon={activeSearch}>
  </TabBarIOS.Item>
    <TabBarIOS.Item
      title="Results"
      onPress={()=> Actions.Results()}
      icon={favoritesTab}
      selectedIcon={activeFav}>
    </TabBarIOS.Item>
    <TabBarIOS.Item
      title="Favorites"
      onPress={()=> Actions.Favorites()}
      icon={favoritesTab}
      selectedIcon={activeFav}>
    </TabBarIOS.Item>
    </TabBarIOS >

  </View>
 </View>
)

const styles = StyleSheet.create({
  tabbar: {
    width: 375,
    height: 49,
    shadowColor: 'black',
     shadowOffset: { height: -2, width: 0 },
     shadowOpacity: 0.05,
     shadowRadius: 3,
    flexDirection: 'row',
    justifyContent: 'center'
  }
});

export default App;
<|endoftext|>


<commit_before>import React from 'react-native'
import {connect} from 'react-redux/native'
import * as serverActions from '../redux/actions/serverActions'
import LinksFeedContainer from './LinksFeedContainer'
import AuthContainer from './AuthContainer'
import CustomScrollableTabView from '../components/CustomScrollableTabView'
import CustomTabBar from '../components/CustomTabBar'

class App extends React.Component {
  constructor(props) {
    super(props)
  }

  shouldComponentUpdate() {
    return false
  }

  render() {
    return (
        <CustomScrollableTabView style={{marginTop:12}}
            tabBarUnderlineColor={'#FF3B7F'}
            tabBarActiveTextColor={'#FF3B7F'}
            renderTabBar={() => <CustomTabBar />}
            onChangeTab={() => {
              console.log('on change tab')
              const { fetchLinksReceived } = this.props
              fetchLinksReceived()
            }}
        >
          <LinksFeedContainer tabLabel="Inbox" />
          <AuthContainer tabLabel="Friends" />
        </CustomScrollableTabView>
    )
  }
}
// TOFIX: hack for now to get links list to update when swiping over
export default connect(
  (state) => { return state},
  (dispatch) => {
    return {
      fetchLinksReceived: () => dispatch(serverActions.fetchLinksReceived()),
    }
  }
)(App)

// export default App
<commit_msg>hack: make a friends fetch call here to keep the share extension updated<commit_after>import React from 'react-native'
import {connect} from 'react-redux/native'
import * as serverActions from '../redux/actions/serverActions'
import LinksFeedContainer from './LinksFeedContainer'
import AuthContainer from './AuthContainer'
import CustomScrollableTabView from '../components/CustomScrollableTabView'
import CustomTabBar from '../components/CustomTabBar'

class App extends React.Component {
  constructor(props) {
    super(props)
  }

  shouldComponentUpdate() {
    return false
  }

  render() {
    return (
        <CustomScrollableTabView style={{marginTop:12}}
            tabBarUnderlineColor={'#FF3B7F'}
            tabBarActiveTextColor={'#FF3B7F'}
            renderTabBar={() => <CustomTabBar />}
            onChangeTab={() => {
              console.log('tab changed!')
              const { fetchLinksReceived, fetchFriends } = this.props
              fetchLinksReceived()
              //TOFIX: call this from elsewhere!!! this is just to keep the share extension friends list updated for now
              fetchFriends()
            }}
        >
          <LinksFeedContainer tabLabel="Inbox" />
          <AuthContainer tabLabel="Friends" />
        </CustomScrollableTabView>
    )
  }
}
// TOFIX: hack for now to get links list to update when swiping over
export default connect(
  (state) => { return state},
  (dispatch) => {
    return {
      fetchLinksReceived: () => dispatch(serverActions.fetchLinksReceived()),
      fetchFriends: () => dispatch(serverActions.fetchFriends()),
    }
  }
)(App)

// export default App
<|endoftext|>


<commit_before>import * as Events from './events';

class Observer {

	/**
	 * @param host | The host element
	 */
	constructor(host) {
		this.host = host;
		this.shadowRoot = this.host.shadowRoot;
		this.currentObservedElements = [];

		this.setDistributedNodes();
		this.observeHost();
	}

	/**
	 * Returns all currently distributed nodes. This is needed for comparison when
	 * searching the content elements for new or removes nodes.
	 *
	 * @returns {Array.<*>}
	 */
	get allCurrentDistributedNodes() {
		return [].concat(...this.currentObservedElements.map(a => a.distributedNodes));
	}

	/**
	 * Returns all content elements within the shadowRoot of the host element
	 *
	 * @returns {Array}
	 */
	get contentElements() {
		return Array.from(this.shadowRoot.querySelectorAll('content'));
	}

	/**
	 * Finds all the distributed nodes. Runs when the constructor is called to get
	 * the initial elements the component starts with
	 */
	setDistributedNodes() {
		this.contentElements.forEach(content => {
			let distributedNodes = Array.from(content.getDistributedNodes());
			this.currentObservedElements.push({
				content,
				distributedNodes
			});
		});
	}

	/**
	 * Compares the currently distributed nodes against the original set of
	 * distributed nodes and determines if any are new. If any new are found
	 * they are added to the registry and an event is fired
	 */
	findNewNodes() {
		this.contentElements.forEach(content => {
			let currentDistributedNodes = Array.from(content.getDistributedNodes());

			let entry = this.currentObservedElements.find(obj => obj.content == content);

			let addedNodes = currentDistributedNodes
				.filter(node => !entry.distributedNodes.includes(node));

			if (addedNodes.length) {
				entry.distributedNodes = currentDistributedNodes;
				Events.nodesAddedToContentEvent(content, addedNodes);
			}
		});
	}

	/**
	 * Compares the currently distributed nodes against the original set of
	 * distributed nodes and determines if any are missing. If any new are missing
	 * they are removed from the registry and an event is fired
	 */
	findRemovedNodes() {
		this.contentElements.forEach(content => {
			let currentDistributedNodes = Array.from(content.getDistributedNodes());

			let entry = this.currentObservedElements.find(obj => obj.content == content);

			let removedNodes = entry.distributedNodes
				.filter(node => !currentDistributedNodes.includes(node));

			if (removedNodes.length) {
				entry.distributedNodes = currentDistributedNodes;
				Events.nodesRemovedFromContentEvent(content, removedNodes);
			}
		});
	}

	/**
	 * Sets a MutationObserver on the host element. Watches for additions and
	 * deletions and attribute changes to all types of nodes, including Text Nodes
	 */
	observeHost() {
		let observer = new MutationObserver(mutations => {

			mutations.forEach(mutation => {

				/**
				 * If nodes were added or removed from the host element (childlist mutation type),
				 * then search for added or removed nodes
				 */
				if (mutation.type === 'childList') {
					if (mutation.addedNodes.length) {
						this.findNewNodes();
					}
					if (mutation.removedNodes.length) {
						this.findRemovedNodes();
					}
				}

				/**
				 * If the mutation contains an exact target and that target is included
				 * in a watched content element, then fire an event letting the
				 * component know a node was changed
				 */
				if (mutation.target && this.allCurrentDistributedNodes.some(el => el.contains(mutation.target))) {
					this.contentElements.forEach(content => {
						let targetElementIsDistributed = Array.from(content.getDistributedNodes())
							.some(node => node.contains(mutation.target));

						if (targetElementIsDistributed) {
							Events.contentChangeEvent(content, mutation);
						}
					});
				}

				/**
				 * This is needed to determine if an element becomes distributed, or
				 * is no longer distributed because of an attribute change. For example,
				 * say a content element selects "h3.foo". And the h3 loses the foo class
				 * at some point, the element is now no longer a distributed element
				 */
				if (mutation.type === 'attributes' && mutation.target.parentNode === this.host) {
					console.log('IOops');
					this.findNewNodes();
					this.findRemovedNodes();
				}
			});
		});

		observer.observe(this.host, {
			childList: true,
			attributes: true,
			characterData: true,
			subtree: true
		});
	}
}

export default {
	watch: (...args) => new Observer(...args)
}
<commit_msg>Remove accidental console.log<commit_after>import * as Events from './events';

class Observer {

	/**
	 * @param host | The host element
	 */
	constructor(host) {
		this.host = host;
		this.shadowRoot = this.host.shadowRoot;
		this.currentObservedElements = [];

		this.setDistributedNodes();
		this.observeHost();
	}

	/**
	 * Returns all currently distributed nodes. This is needed for comparison when
	 * searching the content elements for new or removes nodes.
	 *
	 * @returns {Array.<*>}
	 */
	get allCurrentDistributedNodes() {
		return [].concat(...this.currentObservedElements.map(a => a.distributedNodes));
	}

	/**
	 * Returns all content elements within the shadowRoot of the host element
	 *
	 * @returns {Array}
	 */
	get contentElements() {
		return Array.from(this.shadowRoot.querySelectorAll('content'));
	}

	/**
	 * Finds all the distributed nodes. Runs when the constructor is called to get
	 * the initial elements the component starts with
	 */
	setDistributedNodes() {
		this.contentElements.forEach(content => {
			let distributedNodes = Array.from(content.getDistributedNodes());
			this.currentObservedElements.push({
				content,
				distributedNodes
			});
		});
	}

	/**
	 * Compares the currently distributed nodes against the original set of
	 * distributed nodes and determines if any are new. If any new are found
	 * they are added to the registry and an event is fired
	 */
	findNewNodes() {
		this.contentElements.forEach(content => {
			let currentDistributedNodes = Array.from(content.getDistributedNodes());

			let entry = this.currentObservedElements.find(obj => obj.content == content);

			let addedNodes = currentDistributedNodes
				.filter(node => !entry.distributedNodes.includes(node));

			if (addedNodes.length) {
				entry.distributedNodes = currentDistributedNodes;
				Events.nodesAddedToContentEvent(content, addedNodes);
			}
		});
	}

	/**
	 * Compares the currently distributed nodes against the original set of
	 * distributed nodes and determines if any are missing. If any new are missing
	 * they are removed from the registry and an event is fired
	 */
	findRemovedNodes() {
		this.contentElements.forEach(content => {
			let currentDistributedNodes = Array.from(content.getDistributedNodes());

			let entry = this.currentObservedElements.find(obj => obj.content == content);

			let removedNodes = entry.distributedNodes
				.filter(node => !currentDistributedNodes.includes(node));

			if (removedNodes.length) {
				entry.distributedNodes = currentDistributedNodes;
				Events.nodesRemovedFromContentEvent(content, removedNodes);
			}
		});
	}

	/**
	 * Sets a MutationObserver on the host element. Watches for additions and
	 * deletions and attribute changes to all types of nodes, including Text Nodes
	 */
	observeHost() {
		let observer = new MutationObserver(mutations => {

			mutations.forEach(mutation => {

				/**
				 * If nodes were added or removed from the host element (childlist mutation type),
				 * then search for added or removed nodes
				 */
				if (mutation.type === 'childList') {
					if (mutation.addedNodes.length) {
						this.findNewNodes();
					}
					if (mutation.removedNodes.length) {
						this.findRemovedNodes();
					}
				}

				/**
				 * If the mutation contains an exact target and that target is included
				 * in a watched content element, then fire an event letting the
				 * component know a node was changed
				 */
				if (mutation.target && this.allCurrentDistributedNodes.some(el => el.contains(mutation.target))) {
					this.contentElements.forEach(content => {
						let targetElementIsDistributed = Array.from(content.getDistributedNodes())
							.some(node => node.contains(mutation.target));

						if (targetElementIsDistributed) {
							Events.contentChangeEvent(content, mutation);
						}
					});
				}

				/**
				 * This is needed to determine if an element becomes distributed, or
				 * is no longer distributed because of an attribute change. For example,
				 * say a content element selects "h3.foo". And the h3 loses the foo class
				 * at some point, the element is now no longer a distributed element
				 */
				if (mutation.type === 'attributes' && mutation.target.parentNode === this.host) {
					this.findNewNodes();
					this.findRemovedNodes();
				}
			});
		});

		observer.observe(this.host, {
			childList: true,
			attributes: true,
			characterData: true,
			subtree: true
		});
	}
}

export default {
	watch: (...args) => new Observer(...args)
}
<|endoftext|>


<commit_before>var ContentBuilder = function(servicoObject) {
	var docContent = [],
		servico = servicoObject;

	function addNewLine() {
		docContent.push('\n');
	}

	function buildCapaServico() {
		docContent.push({ text: servico.nome, style: 'header', pageBreak: 'after'});
	}

	function buildServicoInfo() {
		docContent.push({ text: 'O que é?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.descricao, style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Como esse serviço é chamado?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.nomesPopulares, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Este serviço é gratuito?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.gratuito ? 'Sim' : 'Não', style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Quem pode utilizar este serviço?', style: 'subheader' });
		addNewLine();
		$(servicoObject.solicitantes).each(function(index, solicitante) {
			docContent.push({ text: solicitante.tipo , style: 'subheader' });
			docContent.push({ text: solicitante.requisitos , style: 'paragraph' });
			addNewLine();
		});

		docContent.push({ text: '', style: 'paragraph'});
		docContent.push({ text: 'Qual a sigla?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.sigla, style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Quanto tempo demora esse serviço?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.tempoTotalEstimado.max + ' ' + servicoObject.tempoTotalEstimado.unidade, style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Para quais segmentos da sociedade esse serviço serve?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.segmentos, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Quais áreas de interesse?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.areasDeInteresse, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Quais palavras chaves?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.palavrasChave, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Quais legislações?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.legislacoes, style: 'list', pageBreak: 'after' });
	}

	function buildEtapa(index, etapa) {
		docContent.push({ text: (index + 1) + ' ' + etapa.titulo, style: 'thirdheader' });
		addNewLine();
		docContent.push({ text: etapa.descricao, style: 'paragraph' });
		addNewLine();

		buildDocumentos(etapa.documentos);
		buildCustos(etapa.custos);
		buildCanais(etapa.canaisDePrestacao);
	}

	function buildDocumentos(documentos) {
		docContent.push({ text: 'Quais são os documentos necessários?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: documentos.items, style: 'list' });
		addNewLine();

		$(documentos.casos).each(function(index, caso) {
			docContent.push({ text: 'Caso ' + (index + 1), style: 'subheader' });
			addNewLine();
			docContent.push({ text: caso.descricao, style: 'paragraph' });
			addNewLine();
			docContent.push({ text: 'Quais são os documentos necessários para este caso?', style: 'subheader' });
			addNewLine();
			docContent.push({ ul: caso.items, style: 'list' });
			addNewLine();
		});
	}

	function buildCustos(custos) {
		docContent.push({ text: 'Quais são os custos?', style: 'subheader' });
		addNewLine();
		$(custos.items).each(function(index, custo) {
			docContent.push({ text: custo.descricao, style: 'paragraph' });
			docContent.push({ text: custo.valor, style: 'paragraph' });
			addNewLine();
		});

		$(custos.casos).each(function(index, caso) {
			docContent.push({ text: 'Caso ' + (index + 1), style: 'subheader' });
			addNewLine();
			docContent.push({ text: caso.descricao, style: 'paragraph' });
			addNewLine();
			docContent.push({ text: 'Quais são os custos para este caso?', style: 'subheader' });
			addNewLine();
			$(caso.items).each(function(index, custo) {
				docContent.push({ text: custo.descricao, style: 'paragraph' });
				docContent.push({ text: custo.valor, style: 'paragraph' });
				addNewLine();
			});
		});
	}

	function buildCanais(canais) {
		docContent.push({ text: 'Quais são os canais de prestação?', style: 'subheader' });
		addNewLine();
		$(canais.items).each(function(index, canal) {
			docContent.push({ text: canal.tipo, style: 'paragraph' });
			docContent.push({ text: canal.descricao, style: 'paragraph' });
			addNewLine();
		});

		$(canais.casos).each(function(index, caso) {
			docContent.push({ text: 'Caso ' + (index + 1), style: 'subheader' });
			addNewLine();
			docContent.push({ text: caso.descricao, style: 'paragraph' });
			addNewLine();
			docContent.push({ text: 'Quais são os canais de prestação para este caso?', style: 'subheader' });
			addNewLine();
			$(caso.items).each(function(index, canal) {
				docContent.push({ text: canal.tipo, style: 'paragraph' });
				docContent.push({ text: canal.descricao, style: 'paragraph' });
				addNewLine();
			});
		});
	}

	function buildContent() {
		buildCapaServico();
		buildServicoInfo();

		docContent.push({ text: 'Etapas para a realização desse serviço', style: 'subheader' });
		addNewLine();
		$(servico.etapas).each(function(index, etapa){
			buildEtapa(index, etapa);
		});

		return docContent;
	}

	return {
		buildContent: buildContent,
		buildCapaServico: buildCapaServico,
		documentContent: docContent
	};
};
<commit_msg>Estilos nas etapas<commit_after>var ContentBuilder = function(servicoObject) {
	var docContent = [],
		servico = servicoObject;

	function addNewLine() {
		docContent.push('\n');
	}

	function buildCapaServico() {
		docContent.push({ text: servico.nome, style: 'header', pageBreak: 'after'});
	}

	function buildServicoInfo() {
		docContent.push({ text: 'O que é?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.descricao, style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Como esse serviço é chamado?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.nomesPopulares, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Este serviço é gratuito?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.gratuito ? 'Sim' : 'Não', style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Quem pode utilizar este serviço?', style: 'subheader' });
		addNewLine();
		$(servicoObject.solicitantes).each(function(index, solicitante) {
			docContent.push({ text: solicitante.tipo , style: 'subheader' });
			docContent.push({ text: solicitante.requisitos , style: 'paragraph' });
			addNewLine();
		});

		docContent.push({ text: '', style: 'paragraph'});
		docContent.push({ text: 'Qual a sigla?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.sigla, style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Quanto tempo demora esse serviço?', style: 'subheader' });
		addNewLine();
		docContent.push({ text: servicoObject.tempoTotalEstimado.max + ' ' + servicoObject.tempoTotalEstimado.unidade, style: 'paragraph' });
		addNewLine();
		docContent.push({ text: 'Para quais segmentos da sociedade esse serviço serve?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.segmentos, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Quais áreas de interesse?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.areasDeInteresse, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Quais palavras chaves?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.palavrasChave, style: 'list' });
		addNewLine();
		docContent.push({ text: 'Quais legislações?', style: 'subheader' });
		addNewLine();
		docContent.push({ ul: servicoObject.legislacoes, style: 'list', pageBreak: 'after' });
	}

	function buildEtapa(index, etapa) {
		docContent.push({ text: (index + 1) + ' ' + etapa.titulo, style: 'thirdheader' });
		addNewLine();
		docContent.push({ text: etapa.descricao, style: 'paragraph' });
		addNewLine();

		if(etapa.documentos.items.length > 0) { buildDocumentos(etapa.documentos) };
		if(etapa.custos.items.length > 0) { buildCustos(etapa.custos) };
		if(etapa.canaisDePrestacao.items.length > 0) { buildCanais(etapa.canaisDePrestacao) };
	}

	function buildDocumentos(documentos) {
		docContent.push({ text: 'Documentos necessários para esta etapa:', style: 'thirdheader' });
		addNewLine();
		docContent.push({ ul: documentos.items, style: 'list' });
		addNewLine();

		$(documentos.casos).each(function(index, caso) {
			docContent.push({ text: 'Caso ' + (index + 1) + ' - ' + caso.descricao, style: 'thirdheader' });
			addNewLine();
			docContent.push({ ul: caso.items, style: 'list' });
			addNewLine();
		});
	}

	function buildCustos(custos) {
		docContent.push({ text: 'Custos para esta etapa:', style: 'thirdheader' });
		addNewLine();
		$(custos.items).each(function(index, custo) {
			docContent.push({ text: custo.descricao + ': ' + custo.valor, style: 'paragraph' });
			addNewLine();
		});

		$(custos.casos).each(function(index, caso) {
			docContent.push({ text: 'Caso ' + (index + 1) + ' - ' + caso.descricao, style: 'thirdheader' });
			addNewLine();
			$(caso.items).each(function(index, custo) {
				docContent.push({ text: custo.descricao + ': ' + custo.valor, style: 'paragraph' });
				addNewLine();
			});
		});
	}

	function buildCanais(canais) {
		docContent.push({ text: 'Canais de comunicação com este serviço:', style: 'thirdheader' });
		addNewLine();
		$(canais.items).each(function(index, canal) {
			docContent.push({ text: canal.tipo, style: 'paragraph' });
			docContent.push({ text: canal.descricao, style: 'paragraph' });
			addNewLine();
		});

		$(canais.casos).each(function(index, caso) {
			docContent.push({ text: 'Caso ' + (index + 1) + ' - ' + caso.descricao, style: 'thirdheader' });
			addNewLine();
			$(caso.items).each(function(index, canal) {
				docContent.push({ text: canal.tipo, style: 'paragraph' });
				docContent.push({ text: canal.descricao, style: 'paragraph' });
				addNewLine();
			});
		});
	}

	function buildContent() {
		buildCapaServico();
		buildServicoInfo();

		docContent.push({ text: 'Etapas para a realização desse serviço', style: 'subheader' });
		addNewLine();
		$(servico.etapas).each(function(index, etapa){
			buildEtapa(index, etapa);
		});

		return docContent;
	}

	return {
		buildContent: buildContent,
		buildCapaServico: buildCapaServico,
		documentContent: docContent
	};
};
<|endoftext|>


<commit_before>const Redux = require("redux");

const ops = {
  dot: (o, k) => o[k],
  add: (x, y) => x + y,
  minus: (x, y) => x - y,
  sw: (switcher, ...casePairs) => {
    const { length } = casePairs;
    for (let i = 0; i < length; i += 2) {
      if (switcher === casePairs[i]) {
        return casePairs[i + 1];
      }
    }
    if (length % 2) {
      return casePairs[length - 1];
    }
  },
  eq: (a, b) => a === b,
  iif: (cond, trueVal, falseVal) => (cond ? trueVal : falseVal),
  obj: (...kvs) => {
    const obj = {};
    for (let i = 0; i < kvs.length; i = i + 2) {
      obj[kvs[i]] = kvs[i + 1];
    }
    return obj;
  },
  call: (obj, methodName, ...args) => obj[methodName](...args),
  mutate: (obj, key, value) => (obj[key] = value)
};

const { dot, add } = ops;

let math = dot(global, "Math");
let pow = dot(math, "pow");
let sqrt = dot(math, "sqrt");
let sq5 = pow(5, 2);
let sq12 = pow(12, 2);
let sumsq5n12 = add(sq5, sq12);
let hyp5n12 = sqrt(sumsq5n12);
let hyp = (a, b) => {
  let sqA = pow(a, 2);
  let sqB = pow(b, 2);
  let sumsq = add(sqA, sqB);
  return sqrt(sumsq);
};

console.log(hyp5n12, hyp(5, 12), hyp(60, 11));

const test = {
  z: {
    R: [0] // identity
  },
  a: ["add", 0, [1]], // incrementer
  b: ["minus", 0, [1]], // decrementr
  c: ["sw", 0, ["INCREMENT"], "a", ["DECREMENT"], "b", "z"], // get updater from type
  d: ["dot", 0, ["type"]], // get type
  e: {
    a: ["d", 0], // action type
    R: ["c", { i: "a" }] // get updater from action
  },
  f: {
    a: ["e", 1], // updater
    R: [{ i: "a" }, 0] // counter when not zero
  },
  g: {
    R: [[0]] // get zero
  },
  h: {
    a: ["eq", 0, [undefined]], // is undefined
    b: ["iif", { i: "a" }, "g", "f"], // counter to use
    R: [{ i: "b" }, 1] // counter
  },
  j: ["dot", [global], ["Redux"]], // redux
  k: ["dot", [Redux], ["createStore"]], // create store
  l: ["k", "h"] // counter store
};

const parse = (repo, id) => {
  if (!(id in repo)) {
    throw new Error("You done goofed! Could not find ID in repo: " + id);
  }

  const line = repo[id];

  if (Array.isArray(line)) {
    const func = (...params) => {
      // TODO: hoist unchanging (non-param) slots
      const tokens = line.map(code => {
        if (Array.isArray(code)) {
          return code[0];
        }

        const op = ops[code];
        if (op) {
          return op;
        }

        if (typeof code === "number") {
          return params[code];
        }

        if (code in repo) {
          return parse(repo, code);
        }

        throw new Error("No match found for code, brah! " + code);
      });

      const [head, ...args] = tokens;
      return head(...args);
    };

    if (line.some(code => typeof code === "number")) {
      return func;
    }

    return func();
  }

  const sub = line;
  const subRet = sub.R;

  return (...params) => {
    const tokens = subRet.map(code => {
      if (Array.isArray(code)) {
        return code[0];
      }

      const op = ops[code];
      if (op) {
        return op;
      }

      if (typeof code === "number") {
        return params[code];
      }

      if (typeof code === "object") {
        const { i } = code;
        if (!(i in sub)) {
          throw new Error("Sub-line not found dawg! " + code);
        }

        const subLine = sub[i];

        const tokens = subLine.map(code => {
          if (Array.isArray(code)) {
            return code[0];
          }

          const op = ops[code];
          if (op) {
            return op;
          }

          if (typeof code === "number") {
            return params[code];
          }

          if (code in repo) {
            return parse(repo, code);
          }

          throw new Error("No match found for code, brah! " + code);
        });

        const [head, ...args] = tokens;
        return head(...args);
      }

      if (code in repo) {
        return parse(repo, code);
      }

      throw new Error("No match found for code, brah! " + code);
    });

    const [head, ...args] = tokens;
    return typeof head === "function" ? head(...args) : head;
  };
};

console.log(parse(test, "a")(3), 4);

const zTest = parse(test, "z");
console.log(zTest(321));

const updater = parse(test, "e");
console.log(updater({ type: "INCREMENT" })(4), 5);

const reducer = parse(test, "f");
console.log(
  reducer(0, { type: "INCREMENT" }),
  reducer(3, { type: "DECREMENT" }),
  reducer(5, { type: "INCREMENT" })
);
// const counter = parse(test, "h");
// console.log(counter, counter(3, { type: "INCREMENT" }));
<commit_msg>  refactor: pull out subLine logic into subroutine<commit_after>const Redux = require("redux");

const ops = {
  dot: (o, k) => o[k],
  add: (x, y) => x + y,
  minus: (x, y) => x - y,
  sw: (switcher, ...casePairs) => {
    const { length } = casePairs;
    for (let i = 0; i < length; i += 2) {
      if (switcher === casePairs[i]) {
        return casePairs[i + 1];
      }
    }
    if (length % 2) {
      return casePairs[length - 1];
    }
  },
  eq: (a, b) => a === b,
  iif: (cond, trueVal, falseVal) => (cond ? trueVal : falseVal),
  obj: (...kvs) => {
    const obj = {};
    for (let i = 0; i < kvs.length; i = i + 2) {
      obj[kvs[i]] = kvs[i + 1];
    }
    return obj;
  },
  call: (obj, methodName, ...args) => obj[methodName](...args),
  mutate: (obj, key, value) => (obj[key] = value)
};

const { dot, add } = ops;

let math = dot(global, "Math");
let pow = dot(math, "pow");
let sqrt = dot(math, "sqrt");
let sq5 = pow(5, 2);
let sq12 = pow(12, 2);
let sumsq5n12 = add(sq5, sq12);
let hyp5n12 = sqrt(sumsq5n12);
let hyp = (a, b) => {
  let sqA = pow(a, 2);
  let sqB = pow(b, 2);
  let sumsq = add(sqA, sqB);
  return sqrt(sumsq);
};

console.log(hyp5n12, hyp(5, 12), hyp(60, 11));

const test = {
  z: {
    R: [0] // identity
  },
  a: ["add", 0, [1]], // incrementer
  b: ["minus", 0, [1]], // decrementr
  c: ["sw", 0, ["INCREMENT"], "a", ["DECREMENT"], "b", "z"], // get updater from type
  d: ["dot", 0, ["type"]], // get type
  e: {
    a: ["d", 0], // action type
    R: ["c", { i: "a" }] // get updater from action
  },
  f: {
    a: ["e", 1], // updater
    R: [{ i: "a" }, 0] // counter when not zero
  },
  g: {
    R: [[0]] // get zero
  },
  h: {
    a: ["eq", 0, [undefined]], // is undefined
    b: ["iif", { i: "a" }, "g", "f"], // counter to use
    R: [{ i: "b" }, 1] // counter
  },
  j: ["dot", [global], ["Redux"]], // redux
  k: ["dot", [Redux], ["createStore"]], // create store
  l: ["k", "h"] // counter store
};

const parse = (repo, id) => {
  if (!(id in repo)) {
    throw new Error("You done goofed! Could not find ID in repo: " + id);
  }

  const line = repo[id];

  if (Array.isArray(line)) {
    const func = (...params) => {
      // TODO: hoist unchanging (non-param) slots
      const tokens = line.map(code => {
        if (Array.isArray(code)) {
          return code[0];
        }

        const op = ops[code];
        if (op) {
          return op;
        }

        if (typeof code === "number") {
          return params[code];
        }

        if (code in repo) {
          return parse(repo, code);
        }

        throw new Error("No match found for code, brah! " + code);
      });

      const [head, ...args] = tokens;
      return head(...args);
    };

    return func;

    // if (line.some(code => typeof code === "number")) {
    //   return func;
    // }

    // return func();
  }

  const sub = line;
  const subRet = sub.R;

  return (...params) => {
    const parseSubLine = subLine => {
      const tokens = subLine.map(code => {
        if (Array.isArray(code)) {
          return code[0];
        }

        const op = ops[code];
        if (op) {
          return op;
        }

        if (typeof code === "number") {
          return params[code];
        }

        if (typeof code === "object") {
          const { i } = code;
          if (!(i in sub)) {
            throw new Error("Sub-line not found dawg! " + code);
          }

          const refSubLine = sub[i];

          return parseSubLine(refSubLine);
        }

        if (code in repo) {
          return parse(repo, code);
        }

        throw new Error("No match found for code, brah! " + code);
      });

      const [head, ...args] = tokens;
      return typeof head === "function" ? head(...args) : head;
    };

    return parseSubLine(subRet);
  };
};

console.log(parse(test, "a")(3), 4);

const zTest = parse(test, "z");
console.log(zTest(321), 321);

const updater = parse(test, "e");
console.log(updater({ type: "INCREMENT" })(4), 5);

const reducer = parse(test, "f");
console.log(
  reducer(0, { type: "INCREMENT" }),
  1,
  reducer(3, { type: "DECREMENT" }),
  2,
  reducer(5, { type: "INCREMENT" }),
  6
);

const counter = parse(test, "h");
// console.log(counter, counter(3, { type: "INCREMENT" }));
<|endoftext|>


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

    var express = require('express');
    var io = require('socket.io-client');
    var spawn = require('child_process').spawn;
    var async = require('async');
    var chai = require('chai');
    var expect = chai.expect;

    var app = express();

    var options = {
        'force new connection': true
    };

    var socketURL = 'http://localhost:3000';

    app.get('/load_for/:seconds', function (req, res) {
        var seconds = req.params.seconds || 1;

        setTimeout(function() {
            res.send('Hello!');
        }, seconds*1000);
    });

    app.listen(8080);

    describe('ChromiumPOS', function() {
        this.timeout(60000);

        before(function() {
            var screenshotServer = spawn('xvfb-run', ['-a', './node_modules/nodewebkit/nodewebkit/nw', 'nw-app']);

            screenshotServer.stdout.on('data', function (data) {
                console.log('nw-app stdout: ' + data);
            });

            screenshotServer.stderr.on('data', function (data) {
                console.log('nw-app stderr: ' + data);
            });
        });

        after(function() {
            spawn('killall', ['nw']);
        });

        it('should openURL and return data', function(done) {
            var client = io.connect(socketURL, options);
            client.on('connect', function() {
                client.emit('openURL', {url: 'http://localhost:8080/load_for/1'}, function(data) {
                    expect(data.pageLoadTimeMS).to.be.within(1000, 2000);
                    done();
                });
            });
        });

        it('should hit the timeout', function(done) {
            var client = io.connect(socketURL, options);

            client.on('connect', function() {
                client.emit('openURL', {url: 'http://localhost:8080/load_for/2', 'timeout': 1}, function(data) {
                    expect(data.pageLoadTimeMS).to.be.null;
                    expect(data.loaded).to.be.false;
                    done();
                });
            });
        });

        it('should open urls in parallel', function(done) {
            var client = io.connect(socketURL, options);

            client.on('connect', function() {
                var started = new Date();

                async.parallel([
                function(fDone) {
                    client.emit('openURL', {url: 'http://localhost:8080/load_for/1'}, function(data) {
                        expect(data.pageLoadTimeMS).to.be.within(1000, 1500);
                        fDone();
                    });
                }, function(fDone) {
                    client.emit('openURL', {url: 'http://localhost:8080/load_for/2'}, function(data) {
                        expect(data.pageLoadTimeMS).to.be.within(2000, 2500);
                        fDone();
                    });
                }, function(fDone) {
                    client.emit('openURL', {url: 'http://localhost:8080/load_for/2', timeout: 1}, function(data) {
                        expect(data.loaded).to.be.false;
                        fDone();
                    });
                }], function() {
                    var endedFor = new Date().valueOf() - started.valueOf();
                    expect(endedFor).to.be.within(2000, 3000);
                    done();
                });
            });
        });
    });
})();
<commit_msg>move app.listen in before<commit_after>(function() {
    'use strict';

    var express = require('express');
    var io = require('socket.io-client');
    var spawn = require('child_process').spawn;
    var async = require('async');
    var chai = require('chai');
    var expect = chai.expect;

    var app = express();

    var options = {
        'force new connection': true
    };

    var socketURL = 'http://localhost:3000';

    app.get('/load_for/:seconds', function (req, res) {
        var seconds = req.params.seconds || 1;

        setTimeout(function() {
            res.send('Hello!');
        }, seconds*1000);
    });

    describe('ChromiumPOS', function() {
        this.timeout(60000);

        before(function(done) {
            var screenshotServer = spawn('xvfb-run', ['-a', './node_modules/nodewebkit/nodewebkit/nw', 'nw-app']);

            screenshotServer.stdout.on('data', function (data) {
                console.log('nw-app stdout: ' + data);
            });

            screenshotServer.stderr.on('data', function (data) {
                console.log('nw-app stderr: ' + data);
            });

            app.listen(8080, function() {
                done();
            });
        });

        after(function() {
            spawn('killall', ['nw']);
        });

        it('should openURL and return data', function(done) {
            var client = io.connect(socketURL, options);
            client.on('connect', function() {
                client.emit('openURL', {url: 'http://localhost:8080/load_for/1'}, function(data) {
                    expect(data.pageLoadTimeMS).to.be.within(1000, 2000);
                    done();
                });
            });
        });

        it('should hit the timeout', function(done) {
            var client = io.connect(socketURL, options);

            client.on('connect', function() {
                client.emit('openURL', {url: 'http://localhost:8080/load_for/2', 'timeout': 1}, function(data) {
                    expect(data.pageLoadTimeMS).to.be.null;
                    expect(data.loaded).to.be.false;
                    done();
                });
            });
        });

        it('should open urls in parallel', function(done) {
            var client = io.connect(socketURL, options);

            client.on('connect', function() {
                var started = new Date();

                async.parallel([
                function(fDone) {
                    client.emit('openURL', {url: 'http://localhost:8080/load_for/1'}, function(data) {
                        expect(data.pageLoadTimeMS).to.be.within(1000, 1500);
                        fDone();
                    });
                }, function(fDone) {
                    client.emit('openURL', {url: 'http://localhost:8080/load_for/2'}, function(data) {
                        expect(data.pageLoadTimeMS).to.be.within(2000, 2500);
                        fDone();
                    });
                }, function(fDone) {
                    client.emit('openURL', {url: 'http://localhost:8080/load_for/2', timeout: 1}, function(data) {
                        expect(data.loaded).to.be.false;
                        fDone();
                    });
                }], function() {
                    var endedFor = new Date().valueOf() - started.valueOf();
                    expect(endedFor).to.be.within(2000, 3000);
                    done();
                });
            });
        });
    });
})();
<|endoftext|>


<commit_before>/*global QUnit*/
(function() {
'use strict';

/*global splitSelectors*/
QUnit.test('splitSelectors', function(assert) {
	assert.deepEqual(splitSelectors('foo'), ['foo'], 'Simple selector doesn’t get split');
	assert.deepEqual(splitSelectors('foo,foo\t\n ,\t\n foo'), ['foo', 'foo', 'foo'], 'Simple selectors do get split');
});

/*global isFixedSize*/
QUnit.test('isFixedSize', function(assert) {

	var element = document.createElement('div');
	document.body.appendChild(element);

	assert.equal(isFixedSize(element, 'width'), false, 'Standard
 width');
	assert.equal(isFixedSize(element, 'height'), false, 'Standard
 height');

	element.style.cssText = 'width: 100%; height: 100%';
	assert.equal(isFixedSize(element, 'width'), false, 'Percentage width');
	assert.equal(isFixedSize(element, 'height'), false, 'Percentage height');

	element.style.cssText = 'width: 100px; height: 100px';
	assert.equal(isFixedSize(element, 'width'), true, 'Fixed width');
	assert.equal(isFixedSize(element, 'height'), true, 'Fixed height');

	document.body.removeChild(element);

});

/*global isIntrinsicSize*/
QUnit.test('isIntrinsicSize', function(assert) {

	var element = document.createElement('div');
	document.body.appendChild(element);

	assert.equal(isIntrinsicSize(element, 'width'), false, 'Standard
 width');
	assert.equal(isIntrinsicSize(element, 'height'), true, 'Standard
 height');

	element.style.cssText = 'display: inline';
	assert.equal(isIntrinsicSize(element, 'width'), true, 'Display inline width');
	assert.equal(isIntrinsicSize(element, 'height'), true, 'Display inline height');

	element.style.cssText = 'display: inline-block';
	assert.equal(isIntrinsicSize(element, 'width'), true, 'Display inline-block width');
	assert.equal(isIntrinsicSize(element, 'height'), true, 'Display inline-block height');

	element.style.cssText = 'float: left';
	assert.equal(isIntrinsicSize(element, 'width'), true, 'Float left width');
	assert.equal(isIntrinsicSize(element, 'height'), true, 'Float left height');

	element.style.cssText = 'position: absolute';
	assert.equal(isIntrinsicSize(element, 'width'), true, 'Position absolute width');
	assert.equal(isIntrinsicSize(element, 'height'), true, 'Position absolute height');

	element.style.cssText = 'display: inline-block; width: 100%';
	assert.equal(isIntrinsicSize(element, 'width'), false, 'Percentage width');

	element.style.cssText = 'display: inline-block; width: 100px';
	assert.equal(isIntrinsicSize(element, 'width'), false, 'Pixel width');

	element.style.cssText = 'display: inline-block; height: 100%';
	assert.equal(isIntrinsicSize(element, 'height'), false, 'Percentage height');

	element.style.cssText = 'display: inline-block; height: 100px';
	assert.equal(isIntrinsicSize(element, 'height'), false, 'Pixel height');

	element.style.cssText = 'display: inline; float: left; width: 100px; height: 100px';
	assert.equal(isIntrinsicSize(element, 'width'), false, 'Display inline float left pixel width');
	assert.equal(isIntrinsicSize(element, 'height'), false, 'Display inline float left pixel height');

	document.body.removeChild(element);

});

/*global getSize*/
QUnit.test('getSize', function(assert) {
	var element = document.createElement('div');
	element.style.width = '100px';
	element.style.height = '100px';
	element.style.boxSizing = 'border-box';
	element.style.padding = '1pc';
	element.style.border = '10px solid black';
	document.body.appendChild(element);
	assert.equal(getSize(element, 'width'), 48, 'Width');
	assert.equal(getSize(element, 'height'), 48, 'Height');
	document.body.removeChild(element);
});

/*global getComputedLength*/
QUnit.test('getComputedLength', function(assert) {

	var data = [
		['1px', 1],
		['10px', 10],
		['-0.123px', -0.123],
		['12pt', 16],
		['1pc', 16],
		['1in', 96],
		['2.54cm', 96],
		['25.4mm', 96],
		['1rem', 16],
		['1em', 10],
		['1ex', 5],
		['100vw', window.innerWidth],
		['100vh', window.innerHeight],
		['100vmin', Math.min(window.innerWidth, window.innerHeight)],
		['100vmax', Math.max(window.innerWidth, window.innerHeight)],
	];

	var dummy = document.createElement('div');
	dummy.style.fontSize = '10px';
	document.body.appendChild(dummy);

	data.forEach(function(item) {
		assert.equal(getComputedLength(item[0], dummy), item[1], item[0] + ' == ' + item[1] + 'px');
	});

	document.body.removeChild(dummy);

});

/*global getComputedStyle*/
QUnit.test('getComputedStyle', function(assert) {
	var element = document.createElement('div');
	element.style.width = '100px';
	element.style.height = '1in';
	element.style.cssFloat = 'left';
	document.body.appendChild(element);
	assert.equal(getComputedStyle(element).width, '100px', 'Normal style');
	assert.equal(getComputedStyle(element).height, '96px', 'Converted to pixel');
	assert.equal(getComputedStyle(element).cssFloat, 'left', 'Float left');
	assert.equal(getComputedStyle(element).display, 'block', 'Default style');
	element.style.cssText = 'display: inline; float: left';
	assert.equal(getComputedStyle(element).display, 'block', 'Correct display value');
	document.body.removeChild(element);
});

/*global getOriginalStyle*/
QUnit.test('getOriginalStyle', function(assert) {

	var element = document.createElement('div');
	element.className = 'myel';

	var style = document.createElement('style');
	style.type = 'text/css';
	style.innerHTML = '.myel { width: 100%; height: auto !important }';

	document.head.appendChild(style);
	document.body.appendChild(element);

	assert.equal(getOriginalStyle(element, ['width']).width, '100%', 'Get width from