<commit_before>
// --------------------------------------------------------------------
// Graph creation and editing
// TODO: Transactional
// --------------------------------------------------------------------

Meteor.methods({
  'graph.create': function(params) {
    if (!Meteor.userId()) {
      throw new Meteor.Error("not-authorized");
    }

    var user = Meteor.user();
    if (!TALCH.user.hasCreateGraphPermission(user)) {
      throw new Meteor.Error("not-authorized");
    }

    var _id = Nodes.insert({
      name: params.name,
      description: params.description,
      type: 'R',
      elements: {
        nodes: [],
        edges: []
      },
      createdAt: new Date(),
      createdBy: user._id
    });

    Nodes.findAndModify({
      query: { _id: _id },
      update: {
        $push: {
          'elements.nodes': Nodes.graph.createNode(Nodes.findOne({ _id: _id }))
        }
      }
    });

    if (!TALCH.user.isAdmin(user)) {
      Roles.addUsersToRoles(user._id, ['admin'], _id);
    }
  },
  'graph.node.add': function(params) {
    if (!hasEditGraphPermission(params.root._id)) {
      throw new Meteor.Error("not-authorized");
    }

    params.node._id = Nodes.insert({
      name: params.node.name,
      type: params.node.type,
      roots: [params.root._id]
    });

    Nodes.findAndModify({
      query: { _id: params.root._id },
      update: {
        $push: {
          'elements.nodes': Nodes.graph.createNode(params.node),
          'elements.edges': {
            $each: Nodes.graph.createEdges(Lazy(params.parents).pluck('_id'), params.node._id)
          }
        }
      }
    });
  },
  'graph.node.remove': function(nodeId, rootId) {
    if (!hasEditGraphPermission(rootId)) {
      throw new Meteor.Error("not-authorized");
    }

    var node = Nodes.findOne({ _id: nodeId });
    if (node.roots.length === 1) {
      Nodes.remove({ _id: nodeId });
    }

    Nodes.findAndModify({
      query: { _id: rootId },
      update: {
        $pull: {
          'elements.nodes': { 'data.id': nodeId },
          'elements.edges': {
            $or: [
              { 'data.target': nodeId },
              { 'data.source': nodeId }
            ]
          }
        }
      }
    });
  },
  'graph.parent.add': function(rootId, nodeId, parentId) {
    if (!hasEditGraphPermission(rootId)) {
      throw new Meteor.Error("not-authorized");
    }

    Nodes.findAndModify({
      query: { _id: rootId },
      update: {
        $push: {
          'elements.edges': Nodes.graph.createEdge(parentId, nodeId)
        }
      }
    });
  },
  'graph.parent.remove': function(rootId, nodeId, parentId) {
    if (!hasEditGraphPermission(rootId)) {
      throw new Meteor.Error("not-authorized");
    }

    Nodes.findAndModify({
      query: { _id: rootId },
      update: {
        $pull: {
          'elements.edges': { 'data.source': parentId, 'data.target': nodeId }
        }
      }
    });
  },
  'graph.role.update': function(userId, graphId, role) {
    if (!Meteor.userId()) {
      throw new Meteor.Error("not-authorized");
    }

    var user = Meteor.user();
    if (!TALCH.user.isGraphAdmin(user)) {
      throw new Meteor.Error("not-authorized");
    }

    Roles.setUserRoles(userId, [role], graphId);
  }
});

// --------------------------------------------------------------------
// Helpers
// --------------------------------------------------------------------

function hasEditGraphPermission(graphId) {
  if (!Meteor.userId()) {
    return false;
  }

  var user = Meteor.user();
  if (!TALCH.user.hasEditGraphPermission(user, graphId)) {
    return false;
  }

  return true;
}
<commit_msg>Remove user role method<commit_after>
// --------------------------------------------------------------------
// Graph creation and editing
// TODO: Transactional
// --------------------------------------------------------------------

Meteor.methods({
  'graph.create': function(params) {
    if (!Meteor.userId()) {
      throw new Meteor.Error("not-authorized");
    }

    var user = Meteor.user();
    if (!TALCH.user.hasCreateGraphPermission(user)) {
      throw new Meteor.Error("not-authorized");
    }

    var _id = Nodes.insert({
      name: params.name,
      description: params.description,
      type: 'R',
      elements: {
        nodes: [],
        edges: []
      },
      createdAt: new Date(),
      createdBy: user._id
    });

    Nodes.findAndModify({
      query: { _id: _id },
      update: {
        $push: {
          'elements.nodes': Nodes.graph.createNode(Nodes.findOne({ _id: _id }))
        }
      }
    });

    if (!TALCH.user.isAdmin(user)) {
      Roles.addUsersToRoles(user._id, ['admin'], _id);
    }
  },
  'graph.node.add': function(params) {
    if (!hasEditGraphPermission(params.root._id)) {
      throw new Meteor.Error("not-authorized");
    }

    params.node._id = Nodes.insert({
      name: params.node.name,
      type: params.node.type,
      roots: [params.root._id]
    });

    Nodes.findAndModify({
      query: { _id: params.root._id },
      update: {
        $push: {
          'elements.nodes': Nodes.graph.createNode(params.node),
          'elements.edges': {
            $each: Nodes.graph.createEdges(Lazy(params.parents).pluck('_id'), params.node._id)
          }
        }
      }
    });
  },
  'graph.node.remove': function(nodeId, rootId) {
    if (!hasEditGraphPermission(rootId)) {
      throw new Meteor.Error("not-authorized");
    }

    var node = Nodes.findOne({ _id: nodeId });
    if (node.roots.length === 1) {
      Nodes.remove({ _id: nodeId });
    }

    Nodes.findAndModify({
      query: { _id: rootId },
      update: {
        $pull: {
          'elements.nodes': { 'data.id': nodeId },
          'elements.edges': {
            $or: [
              { 'data.target': nodeId },
              { 'data.source': nodeId }
            ]
          }
        }
      }
    });
  },
  'graph.parent.add': function(rootId, nodeId, parentId) {
    if (!hasEditGraphPermission(rootId)) {
      throw new Meteor.Error("not-authorized");
    }

    Nodes.findAndModify({
      query: { _id: rootId },
      update: {
        $push: {
          'elements.edges': Nodes.graph.createEdge(parentId, nodeId)
        }
      }
    });
  },
  'graph.parent.remove': function(rootId, nodeId, parentId) {
    if (!hasEditGraphPermission(rootId)) {
      throw new Meteor.Error("not-authorized");
    }

    Nodes.findAndModify({
      query: { _id: rootId },
      update: {
        $pull: {
          'elements.edges': { 'data.source': parentId, 'data.target': nodeId }
        }
      }
    });
  },
  'graph.role.update': function(userId, graphId, role) {
    if (!Meteor.userId()) {
      throw new Meteor.Error("not-authorized");
    }

    var user = Meteor.user();
    if (!TALCH.user.isGraphAdmin(user)) {
      throw new Meteor.Error("not-authorized");
    }

    Roles.setUserRoles(userId, [role], graphId);
  },
  'graph.role.remove': function(userId, graphId) {
    if (!Meteor.userId()) {
      throw new Meteor.Error("not-authorized");
    }

    var user = Meteor.user();
    if (!TALCH.user.isGraphAdmin(user)) {
      throw new Meteor.Error("not-authorized");
    }

    Roles.setUserRoles(userId, [], graphId);
  }
});

// --------------------------------------------------------------------
// Helpers
// --------------------------------------------------------------------

function hasEditGraphPermission(graphId) {
  if (!Meteor.userId()) {
    return false;
  }

  var user = Meteor.user();
  if (!TALCH.user.hasEditGraphPermission(user, graphId)) {
    return false;
  }

  return true;
}
<|endoftext|>


<commit_before>pc.asset = {};
pc.extend(pc.asset, function () {
    /**
    * @name pc.asset.Asset
    * @class An asset record that can be loaded by the engine. Aside from detail like resourceId and name,
    * the asset class contains one or both of 'file' and 'data' properties.
    * 'file' contains the details of the file to load (filename, url), 'data' contains a JSON blob which
    * contains either more information about the file or the actual asset data itself.
    * @constructor Create a new Asset record. Generaly, Assets are created in the Pack loading process and you won't need to create them by hand.
    * @param {String} name A non-unique but human-readable name which can be later used to retrieve the asset.
    * @param {String} type Type of asset. One of ["animation", "audio", "image", "json", "material", "model", "text", "texture"]
    * @param {Object} file Details about the file the asset is made from. For assets that don't contain file data use null.
    * @example
    * var file = {
    *   filename: "filename.txt",
    *   url: "/example/filename.txt",
    * }
    * @param {Object} [data] JSON object with additional data about the asset (e.g. for texture and model assets) or contains the asset data itself (e.g. in the case of materials)
    * @param {String} [prefix] URL prefix to prepend to the file URL when return getFileUrl()
    * @example
    * var asset = new pc.Asset("a texture", pc.asset.ASSET_TEXTURE, {
    *        filename: "texture.png",
    *        url: "http://example.com/my/assets/here/texture.png"
    *    });
    */
    var Asset = function (name, type, file, data, prefix) {
        var file, data, prefix; // optional arguments

        this.resourceId = pc.guid.create();

        this.name = arguments[0];
        this.type = arguments[1];
        this.file = arguments[2] ? {
            filename: file.filename,
            size: file.size,
            hash: file.hash,
            url: file.url
        } : null;
        this.data = arguments[3] || {};
        this.prefix = arguments[4] || "";

        pc.extend(this, pc.events);
    };

    Asset.prototype = {
        /**
        * @name pc.asset.Asset#getFileUrl
        * @function
        * @description Return the URL required to fetch the file for this asset.
        * @returns {String} The URL
        * @example
        * var assets = context.assets.find("My Image", pc.asset.ASSET_IMAGE);
        * var img = "";
        */
        getFileUrl: function () {
            if (!this.file) {
                return null;
            }

            var url = this.file.url;
            var prefix = "";
            // Non-exported files use the Corazon API to load, so they need an added prefix
            if (this.prefix) {
                prefix = this.prefix;
            }
            return pc.path.join(prefix, url);
        }
    };

    return {
        Asset: Asset,
        ASSET_ANIMATION: 'animation',
        ASSET_AUDIO: 'audio',
        ASSET_IMAGE: 'image',
        ASSET_JSON: 'json',
        ASSET_MODEL: 'model',
        ASSET_MATERIAL: 'material',
        ASSET_TEXT: 'text',
        ASSET_TEXTURE: 'texture'
    };
}());
<commit_msg>Added docs for asset namespace<commit_after>/**
* @name pc.asset
* @namespace Contains classes related to Assets.
*/
pc.asset = {};
pc.extend(pc.asset, function () {
    /**
    * @name pc.asset.Asset
    * @class An asset record that can be loaded by the engine. Aside from detail like resourceId and name,
    * the asset class contains one or both of 'file' and 'data' properties.
    * 'file' contains the details of the file to load (filename, url), 'data' contains a JSON blob which
    * contains either more information about the file or the actual asset data itself.
    * @constructor Create a new Asset record. Generaly, Assets are created in the Pack loading process and you won't need to create them by hand.
    * @param {String} name A non-unique but human-readable name which can be later used to retrieve the asset.
    * @param {String} type Type of asset. One of ["animation", "audio", "image", "json", "material", "model", "text", "texture"]
    * @param {Object} file Details about the file the asset is made from. For assets that don't contain file data use null.
    * @example
    * var file = {
    *   filename: "filename.txt",
    *   url: "/example/filename.txt",
    * }
    * @param {Object} [data] JSON object with additional data about the asset (e.g. for texture and model assets) or contains the asset data itself (e.g. in the case of materials)
    * @param {String} [prefix] URL prefix to prepend to the file URL when return getFileUrl()
    * @example
    * var asset = new pc.Asset("a texture", pc.asset.ASSET_TEXTURE, {
    *        filename: "texture.png",
    *        url: "http://example.com/my/assets/here/texture.png"
    *    });
    */
    var Asset = function (name, type, file, data, prefix) {
        var file, data, prefix; // optional arguments

        this.resourceId = pc.guid.create();

        this.name = arguments[0];
        this.type = arguments[1];
        this.file = arguments[2] ? {
            filename: file.filename,
            size: file.size,
            hash: file.hash,
            url: file.url
        } : null;
        this.data = arguments[3] || {};
        this.prefix = arguments[4] || "";

        pc.extend(this, pc.events);
    };

    Asset.prototype = {
        /**
        * @name pc.asset.Asset#getFileUrl
        * @function
        * @description Return the URL required to fetch the file for this asset.
        * @returns {String} The URL
        * @example
        * var assets = context.assets.find("My Image", pc.asset.ASSET_IMAGE);
        * var img = "";
        */
        getFileUrl: function () {
            if (!this.file) {
                return null;
            }

            var url = this.file.url;
            var prefix = "";
            // Non-exported files use the Corazon API to load, so they need an added prefix
            if (this.prefix) {
                prefix = this.prefix;
            }
            return pc.path.join(prefix, url);
        }
    };

    return {
        Asset: Asset,
        ASSET_ANIMATION: 'animation',
        ASSET_AUDIO: 'audio',
        ASSET_IMAGE: 'image',
        ASSET_JSON: 'json',
        ASSET_MODEL: 'model',
        ASSET_MATERIAL: 'material',
        ASSET_TEXT: 'text',
        ASSET_TEXTURE: 'texture'
    };
}());
<|endoftext|>


<commit_before>import Piece from './piece';
import { NullPiece } from './pieces/index';
import _ from 'lodash';
import * as CONST from './constants/boardTypes';

export default class Board {
  constructor(board = undefined) {
    board ? this.setBoard(board) : this.setBoard(CONST.USI_INITIAL_BOARD);
  }

  setBoard(board) {
    this.board = this.createBoard(board);
  }

  createBoard(board) {
    const _board = board.map((row, y) => {
      const yCor = this.transposeToCorY(y);
      const rows = row.map((type, x) => {
        const xCor = this.transposeToCorX(x);
        return Piece.create({ type: type, x: xCor, y: yCor });
      });
      return(rows);
    });

    return _board;
  }

  movePiece(fromPiece, toPiece) {
    this.checkPieceExistence(fromPiece);
    this.checkPieceExistence(toPiece);

    if (fromPiece.equals(toPiece)) {
      return this.cloneBoard().clearAttrs();
    }

    if (! this.enhanceMovablePoint(fromPiece).findPiece(toPiece).movable) {
      return this.cloneBoard().clearAttrs();
    }

    return this.movePosition(fromPiece, toPiece).clearAttrs();
  }

  movePosition(fromPiece, toPiece) {
    const newBoard = this.cloneBoard();

    const [toCorX, toCorY] = [toPiece.x, toPiece.y];
    const [toIdxX, toIdxY] = this.invertCor(toCorX, toCorY);
    const [fromCorX, fromCorY] = [fromPiece.x, fromPiece.y];
    const [fromIdxX, fromIdxY] = this.invertCor(fromCorX, fromCorY);

    fromPiece.x = toCorX;
    fromPiece.y = toCorY;

    newBoard.board[toIdxY][toIdxX] = fromPiece;
    newBoard.board[fromIdxY][fromIdxX] = new NullPiece({ x: fromCorX, y: fromCorY });

    if (this.isTakingPiece(fromPiece, toPiece)) {
      newBoard.capturedPiece = toPiece;
    }

    return newBoard;
  }

  enhanceMovablePoint(piece) {
    this.checkPieceExistence(piece);
    const moveDef = piece.moveDef();

    if (typeof moveDef === 'undefined') {
      return this;
    }

    const newBoard = this.cloneBoard();

    // if moveDef has just property, piece moves just coordinates on board.
    //
    if (moveDef.just) {
      newBoard.movablePointsByJust(piece);
    }

    // if moveDef has fly property, piece moves recursion on board.
    //
    if (moveDef.fly) {
      newBoard.movablePointsByFly(piece);
    }

    return newBoard;
  }

  enhanceCanDropPosition(placePiece) {
    let pawnXcors;

    if (placePiece.type === 'P' || placePiece.type === 'p') {
      pawnXcors = this.xCorsOfPiece(placePiece);
    }

    const newBoard = this.cloneBoard();
    const moveDef = placePiece.moveDef();

    newBoard.board.forEach((rows, y) => {
      rows.forEach((piece, x) => {
        if (placePiece.type === 'P' || placePiece.type === 'p') {
          // NOTE: NIFU
          if (_.includes(pawnXcors, this.invertToIndexX(x))) return;
        }

        if (placePiece.type === 'L') {
          if (y + moveDef.fly[0][1] < 0) return;
        }

        if (placePiece.type === 'l') {
          if (y + moveDef.fly[0][1] > 8) return;
        }

        if (placePiece.type === 'N' || placePiece.type === 'P') {
          if (y + moveDef.just[0][1] < 0) return;
        }

        if (placePiece.type === 'n' || placePiece.type === 'p') {
          if (y + moveDef.just[0][1] > 8) return;
        }

        if (piece.type == '*') { piece.isDrop = true; }
      });
    });

    return newBoard;
  }

  dropPiece(holdingPiece, destPiece) {
    this.checkPieceExistence(destPiece);

    const [destX, destY] = [destPiece.x, destPiece.y];
    const [destXidx, destYidx] = this.invertCor(destX, destY);

    const piece = this.enhanceCanDropPosition(holdingPiece).findPiece(destPiece);

    // NOTE: If destination piece is not found or does not have `isDrop` property,
    //       do nothing and return this.
    if (typeof piece === 'undefined' || !piece.isDrop) return this;

    const newBoard = this.cloneBoard();

    holdingPiece.x = destX;
    holdingPiece.y = destY;
    newBoard.board[destYidx][destXidx] = holdingPiece;
    return newBoard;
  }

  xCorsOfPiece(searchPiece) {
    const pieces = _.zip(...this.board).map((col) => {
      const piece = col.find((piece) => {
        return piece.type === searchPiece.type;
      });

      return piece ? piece.x : undefined;
    });

    return _.compact(pieces);
  }

  promotePiece(piece) {
    this.checkPieceExistence(piece);
    const newBoard = this.cloneBoard();

    newBoard.findPiece(piece).promote();

    return newBoard;
  }

  clearAttrs() {
    this.board.map((row) => {
      return row.map((piece) => {
        piece.movable = false;
        piece.isDrop = false;
      });
    });

    return this;
  }

  // NOTE: No check the piece existance. because this method is used private method.
  isTakingPiece(fromPiece, toPiece) {
    if (typeof fromPiece.team() === 'undefined') { return false; }
    if (typeof toPiece.team() === 'undefined') { return false; }

    return fromPiece.team() !== toPiece.team();
  }

  // if piece of argument is match in the board, return true, else return false
  //
  matchPiece(piece) {
    const isUndefined = typeof this.findPiece(piece) === 'undefined';
    const isEqualPiece = this.findPiece(piece).equals(
      Piece.create({
        x: piece.x,
        y: piece.y,
        type: piece.type,
        movable: piece.movable
      })
    );

    return (isUndefined || isEqualPiece);
  }

  checkPieceExistence(piece) {
    if (this.matchPiece(piece)) {
      return true;
    } else {
      const message = `type = ${piece.type}, xCor = ${piece.x}, yCor = ${piece.y}`;
      throw new Error(`Does not match coordinates in board. ${message}`);
    }
  }

  // if moveDef has just property, piece moves just coordinates on board.
  //
  movablePointsByJust(piece) {
    const [xCor, yCor] = [piece.x, piece.y];
    const moveDef = piece.moveDef();
    const [x, y] = this.invertCor(xCor, yCor);

    moveDef.just.forEach((def) => {
      const [defX, defY] = def;
      const fetchedPiece = this.fetchPiece(x + defX, y + defY);

      if (fetchedPiece && !piece.isOwnTeam(fetchedPiece)) {
        fetchedPiece.movable = true;
      }
    });
  }

  movablePointsByFly(piece) {
    const [xCor, yCor] = [piece.x, piece.y];
    const moveDef = piece.moveDef();
    const [x, y] = this.invertCor(xCor, yCor);

    moveDef.fly.forEach((def) => {
      const [defX, defY] = def;

      let dx = x + defX;
      let dy = y + defY;
      let fetchedPiece = this.fetchPiece(dx, dy);

      while (fetchedPiece) {
        if (fetchedPiece.type === '*') {
          fetchedPiece.movable = true;
        } else if (piece.isOwnTeam(fetchedPiece)) {
          break;
        } else {
          fetchedPiece.movable = true;
          break;
        }

        dx = dx + defX;
        dy = dy + defY;

        fetchedPiece = this.fetchPiece(dx, dy);
      }
    });
  }

  cloneBoard() {
    const dupBoard = _.cloneDeep(this.board);
    const newBoard = new Board;
    newBoard.board = dupBoard;
    return newBoard;
  }

  transposeToCorX(xIndex) {
    return 10 - xIndex - 1;
  }

  transposeToCorY(yIndex) {
    return yIndex + 1;
  }

  invertToIndexX(xCor) {
    return 9 - xCor;
  }

  invertToIndexY(yCor) {
    return yCor - 1;
  }

  invertCor(xCor, yCor) {
    return [this.invertToIndexX(xCor), this.invertToIndexY(yCor)];
  }

  fetchPiece(xIndex, yIndex) {
    const row = this.board[yIndex];
    return row ? row[xIndex] : undefined;
  }

  findPiece(piece) {
    const [toCorX, toCorY] = [piece.x, piece.y];
    const [toIdxX, toIdxY] = this.invertCor(toCorX, toCorY);
    return this.fetchPiece(toIdxX, toIdxY);
  }

  toArray() {
    return this.board.map((row) => {
      return row.map((piece) => {
        return piece.type;
      });
    });
  }
};
<commit_msg>Rename. transposeToCor(X|Y) -> convertToCor(X|Y)<commit_after>import Piece from './piece';
import { NullPiece } from './pieces/index';
import _ from 'lodash';
import * as CONST from './constants/boardTypes';

export default class Board {
  constructor(board = undefined) {
    board ? this.setBoard(board) : this.setBoard(CONST.USI_INITIAL_BOARD);
  }

  setBoard(board) {
    this.board = this.createBoard(board);
  }

  createBoard(board) {
    const _board = board.map((row, y) => {
      const yCor = this.convertToCorY(y);
      const rows = row.map((type, x) => {
        const xCor = this.convertToCorX(x);
        return Piece.create({ type: type, x: xCor, y: yCor });
      });
      return(rows);
    });

    return _board;
  }

  movePiece(fromPiece, toPiece) {
    this.checkPieceExistence(fromPiece);
    this.checkPieceExistence(toPiece);

    if (fromPiece.equals(toPiece)) {
      return this.cloneBoard().clearAttrs();
    }

    if (! this.enhanceMovablePoint(fromPiece).findPiece(toPiece).movable) {
      return this.cloneBoard().clearAttrs();
    }

    return this.movePosition(fromPiece, toPiece).clearAttrs();
  }

  movePosition(fromPiece, toPiece) {
    const newBoard = this.cloneBoard();

    const [toCorX, toCorY] = [toPiece.x, toPiece.y];
    const [toIdxX, toIdxY] = this.invertCor(toCorX, toCorY);
    const [fromCorX, fromCorY] = [fromPiece.x, fromPiece.y];
    const [fromIdxX, fromIdxY] = this.invertCor(fromCorX, fromCorY);

    fromPiece.x = toCorX;
    fromPiece.y = toCorY;

    newBoard.board[toIdxY][toIdxX] = fromPiece;
    newBoard.board[fromIdxY][fromIdxX] = new NullPiece({ x: fromCorX, y: fromCorY });

    if (this.isTakingPiece(fromPiece, toPiece)) {
      newBoard.capturedPiece = toPiece;
    }

    return newBoard;
  }

  enhanceMovablePoint(piece) {
    this.checkPieceExistence(piece);
    const moveDef = piece.moveDef();

    if (typeof moveDef === 'undefined') {
      return this;
    }

    const newBoard = this.cloneBoard();

    // if moveDef has just property, piece moves just coordinates on board.
    //
    if (moveDef.just) {
      newBoard.movablePointsByJust(piece);
    }

    // if moveDef has fly property, piece moves recursion on board.
    //
    if (moveDef.fly) {
      newBoard.movablePointsByFly(piece);
    }

    return newBoard;
  }

  enhanceCanDropPosition(placePiece) {
    let pawnXcors;

    if (placePiece.type === 'P' || placePiece.type === 'p') {
      pawnXcors = this.xCorsOfPiece(placePiece);
    }

    const newBoard = this.cloneBoard();
    const moveDef = placePiece.moveDef();

    newBoard.board.forEach((rows, y) => {
      rows.forEach((piece, x) => {
        if (placePiece.type === 'P' || placePiece.type === 'p') {
          // NOTE: NIFU
          if (_.includes(pawnXcors, this.invertToIndexX(x))) return;
        }

        if (placePiece.type === 'L') {
          if (y + moveDef.fly[0][1] < 0) return;
        }

        if (placePiece.type === 'l') {
          if (y + moveDef.fly[0][1] > 8) return;
        }

        if (placePiece.type === 'N' || placePiece.type === 'P') {
          if (y + moveDef.just[0][1] < 0) return;
        }

        if (placePiece.type === 'n' || placePiece.type === 'p') {
          if (y + moveDef.just[0][1] > 8) return;
        }

        if (piece.type == '*') { piece.isDrop = true; }
      });
    });

    return newBoard;
  }

  dropPiece(holdingPiece, destPiece) {
    this.checkPieceExistence(destPiece);

    const [destX, destY] = [destPiece.x, destPiece.y];
    const [destXidx, destYidx] = this.invertCor(destX, destY);

    const piece = this.enhanceCanDropPosition(holdingPiece).findPiece(destPiece);

    // NOTE: If destination piece is not found or does not have `isDrop` property,
    //       do nothing and return this.
    if (typeof piece === 'undefined' || !piece.isDrop) return this;

    const newBoard = this.cloneBoard();

    holdingPiece.x = destX;
    holdingPiece.y = destY;
    newBoard.board[destYidx][destXidx] = holdingPiece;
    return newBoard;
  }

  xCorsOfPiece(searchPiece) {
    const pieces = _.zip(...this.board).map((col) => {
      const piece = col.find((piece) => {
        return piece.type === searchPiece.type;
      });

      return piece ? piece.x : undefined;
    });

    return _.compact(pieces);
  }

  promotePiece(piece) {
    this.checkPieceExistence(piece);
    const newBoard = this.cloneBoard();

    newBoard.findPiece(piece).promote();

    return newBoard;
  }

  clearAttrs() {
    this.board.map((row) => {
      return row.map((piece) => {
        piece.movable = false;
        piece.isDrop = false;
      });
    });

    return this;
  }

  // NOTE: No check the piece existance. because this method is used private method.
  isTakingPiece(fromPiece, toPiece) {
    if (typeof fromPiece.team() === 'undefined') { return false; }
    if (typeof toPiece.team() === 'undefined') { return false; }

    return fromPiece.team() !== toPiece.team();
  }

  // if piece of argument is match in the board, return true, else return false
  //
  matchPiece(piece) {
    const isUndefined = typeof this.findPiece(piece) === 'undefined';
    const isEqualPiece = this.findPiece(piece).equals(
      Piece.create({
        x: piece.x,
        y: piece.y,
        type: piece.type,
        movable: piece.movable
      })
    );

    return (isUndefined || isEqualPiece);
  }

  checkPieceExistence(piece) {
    if (this.matchPiece(piece)) {
      return true;
    } else {
      const message = `type = ${piece.type}, xCor = ${piece.x}, yCor = ${piece.y}`;
      throw new Error(`Does not match coordinates in board. ${message}`);
    }
  }

  // if moveDef has just property, piece moves just coordinates on board.
  //
  movablePointsByJust(piece) {
    const [xCor, yCor] = [piece.x, piece.y];
    const moveDef = piece.moveDef();
    const [x, y] = this.invertCor(xCor, yCor);

    moveDef.just.forEach((def) => {
      const [defX, defY] = def;
      const fetchedPiece = this.fetchPiece(x + defX, y + defY);

      if (fetchedPiece && !piece.isOwnTeam(fetchedPiece)) {
        fetchedPiece.movable = true;
      }
    });
  }

  movablePointsByFly(piece) {
    const [xCor, yCor] = [piece.x, piece.y];
    const moveDef = piece.moveDef();
    const [x, y] = this.invertCor(xCor, yCor);

    moveDef.fly.forEach((def) => {
      const [defX, defY] = def;

      let dx = x + defX;
      let dy = y + defY;
      let fetchedPiece = this.fetchPiece(dx, dy);

      while (fetchedPiece) {
        if (fetchedPiece.type === '*') {
          fetchedPiece.movable = true;
        } else if (piece.isOwnTeam(fetchedPiece)) {
          break;
        } else {
          fetchedPiece.movable = true;
          break;
        }

        dx = dx + defX;
        dy = dy + defY;

        fetchedPiece = this.fetchPiece(dx, dy);
      }
    });
  }

  cloneBoard() {
    const dupBoard = _.cloneDeep(this.board);
    const newBoard = new Board;
    newBoard.board = dupBoard;
    return newBoard;
  }

  convertToCorX(xIndex) {
    return 10 - xIndex - 1;
  }

  convertToCorY(yIndex) {
    return yIndex + 1;
  }

  invertToIndexX(xCor) {
    return 9 - xCor;
  }

  invertToIndexY(yCor) {
    return yCor - 1;
  }

  invertCor(xCor, yCor) {
    return [this.invertToIndexX(xCor), this.invertToIndexY(yCor)];
  }

  fetchPiece(xIndex, yIndex) {
    const row = this.board[yIndex];
    return row ? row[xIndex] : undefined;
  }

  findPiece(piece) {
    const [toCorX, toCorY] = [piece.x, piece.y];
    const [toIdxX, toIdxY] = this.invertCor(toCorX, toCorY);
    return this.fetchPiece(toIdxX, toIdxY);
  }

  toArray() {
    return this.board.map((row) => {
      return row.map((piece) => {
        return piece.type;
      });
    });
  }
};
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HA<commit_msg>Work in Progress<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAI<|endoftext|>


<commit_before>'use strict';

const defaults = require('lodash.defaultsdeep');
const got = require('./utils/gotWrapper');
const findOwnPackageJSON = require('./utils/findOwnPackageJSON');

const packageJSON = findOwnPackageJSON() || { name: '@badgeup/badgeup-node-client', version: 'unknown' };

// client library defaults
var requestDefaults = {
    json: true,
    timeout: 5000,
    baseUrl: 'https://api.useast1.badgeup.io', // default API endpoint
    headers: {
        'User-Agent': packageJSON.name + '/' + packageJSON.version + ' (https://www.badgeup.io/)',
        'Accept': 'application/json'
    }
};

class BadgeUpHttp {
    // Constructor for the HTTP stack for BadgeUp
    // @param globalOpts: Options from the user for BadgeUp as a whole.
    constructor(globalReqOpts) {
        this.globalReqOpts = globalReqOpts || {};
    }

    /**
     * Performs a HTTP request given the collective options
     * @param {object} [reqOpts] Request options from this library's functions.
     * @param {object} [userOpts] Option overrides from the user. Highest priority.
     * @return {Promise} Returns a Promise that resolves with the request data
     */
    makeRequest(reqOpts, userOpts) {
        const options = defaults({}, userOpts, reqOpts, this.globalReqOpts, requestDefaults);

        // for internal unit tests
        if (options._validate) {
            options._validate(options);
        }

        // for internal unit tests
        if (options._payload) {
            return Promise.resolve(options._payload(options));
        }

        return got(options).then(function(response) {
            // TODO implement error response translation
            return response.body;
        });
    }

}

module.exports = BadgeUpHttp;
<commit_msg>doc fixes<commit_after>'use strict';

const defaults = require('lodash.defaultsdeep');
const got = require('./utils/gotWrapper');
const findOwnPackageJSON = require('./utils/findOwnPackageJSON');

const packageJSON = findOwnPackageJSON() || { name: '@badgeup/badgeup-node-client', version: 'unknown' };

// client library defaults
var requestDefaults = {
    json: true,
    timeout: 5000,
    baseUrl: 'https://api.useast1.badgeup.io', // default API endpoint
    headers: {
        'User-Agent': packageJSON.name + '/' + packageJSON.version + ' (https://www.badgeup.io/)',
        'Accept': 'application/json'
    }
};

class BadgeUpHttp {
    // Constructor for the HTTP stack for BadgeUp
    // @param globalOpts: Options from the user for BadgeUp as a whole.
    constructor(globalReqOpts) {
        this.globalReqOpts = globalReqOpts || {};
    }

    /**
     * Performs a HTTP request given the collective options
     * @param {object} reqOpts Request options from this library's functions.
     * @param {object} userOpts Option overrides from the user. Highest priority.
     * @return {Promise} Returns a Promise that resolves with the request data
     */
    makeRequest(reqOpts, userOpts) {
        const options = defaults({}, userOpts, reqOpts, this.globalReqOpts, requestDefaults);

        // for internal unit tests
        if (options._validate) {
            options._validate(options);
        }

        // for internal unit tests
        if (options._payload) {
            return Promise.resolve(options._payload(options));
        }

        return got(options).then(function(response) {
            // TODO implement error response translation
            return response.body;
        });
    }

}

module.exports = BadgeUpHttp;
<|endoftext|>


<commit_before>import {AbstractLevelDOWN, AbstractIterator} from "abstract-leveldown"
import xtend from "xtend"

const serialize = function(value) {
  if (value == null || value === "") return {NULL: true}

  const type = value.constructor.name
  const reduce = function(value) {
    return Object.keys(value).reduce(function(acc, key) {
      acc[key] = serialize(value[key])
      return acc
    }, {})
  }

  switch (type) {
    case "String"  : return {S: value}
    case "Buffer"  : return {B: value.toString("base64")}
    case "Boolean" : return {BOOL: value}
    case "Number"  : return {N: String(value)}
    case "Array"   : return {L: value.map(serialize)}
    case "Object"  : return {M: reduce(value)}
    // TODO: Support sets

    default        : throw new Error(`Cannot serialize ${type}`)
  }
}

const parse = function(val) {
  const type = Object.keys(val)[0]
  const value = val[type]
  const reduce = function(value) {
    return Object.keys(value).reduce(function(acc, key) {
      acc[key] = parse(value[key])
      return acc
    }, {})
  }

  switch (type) {
    case "NULL" : return null
    case "S"    : return value
    case "B"    : return Buffer(value, "base64")
    case "BOOL" : return value
    case "N"    : return parseFloat(value, 10)
    case "L"    : return value.map(parse)
    case "M"    : return reduce(value)
    // TODO: Support sets

    default     : throw new Error(`Cannot parse ${type}.`)
  }
}

class DynamoIterator extends AbstractIterator {
  constructor(db, options) {
    super(db)

    this._limit = Infinity
    if (options.limit !== -1) this._limit = options.limit

    this._reverse = false
    if (options.reverse === true) this._reverse = true

    if ("gt" in options || "gte" in options) {
      this._lowerBound = {
        key: options.gt || options.gte,
        inclusive: "gte" in options
      }
    }

    if ("lt" in options || "lte" in options) {
      this._upperBound = {
        key: options.lt || options.lte,
        inclusive: "lte" in options
      }
    }

    this._params = {
      TableName: this.db._table.name,
      KeyConditions: {}
    }

    if (this._limit !== Infinity) this._params.Limit = this._limit
    if (this._reverse) this._params.ScanIndexForward = false

    this._params.KeyConditions[this.db._schema.hash.name] = {
      ComparisonOperator: "EQ",
      AttributeValueList: [serialize(this.db._schema.hash.value)]
    }

    if (this._lowerBound && this._upperBound) {
      this._params.KeyConditions[this.db._schema.range.name] = {
        ComparisonOperator: "BETWEEN",
        AttributeValueList: [
          serialize(this._lowerBound.key),
          serialize(this._upperBound.key)
        ]
      }
    }

    else if (this._lowerBound) {
      this._params.KeyConditions[this.db._schema.range.name] = {
        ComparisonOperator: this._lowerBound.inclusive ? "GE" : "GT",
        AttributeValueList: [serialize(this._lowerBound.key)]
      }
    }

    else if (this._upperBound) {
      this._params.KeyConditions[this.db._schema.range.name] = {
        ComparisonOperator: this._upperBound.inclusive ? "LE" : "LT",
        AttributeValueList: [serialize(this._upperBound.key)]
      }
    }

    this._items = []
    this._cursor = 0
  }

  _next(cb) {
    const item = this._items[this._cursor]

    if (item) {
      // make sure not excluded from gt/lt key conditions
      setImmediate(cb, null, item.key, item.value)
      delete this._items[this._cursor]
      this._cursor++
      return
    }

    if (item === null || this._cursor === this._limit) {
      setImmediate(cb)
      return
    }

    this.db._db.query(this._params, (err, data) => {
      if (err) return cb(err)

      const {Items, LastEvaluatedKey} = data

      for (let item of Items) this._items.push(this.db._toKV(item))

      if (!LastEvaluatedKey) this._items.push(null)

      this._params.ExclusiveStartKey = LastEvaluatedKey
      this._next(cb)
    })
  }
}

class DynamoDOWN extends AbstractLevelDOWN {
  constructor(db, location) {
    super(location)

    const [table, hash] = location.split("/")

    this._db = db
    this._table = {name: table}
    this._schema = {
      hash: {value: hash},
      range: {}
    }
  }

  _toItem({key, value}) {
    const item = xtend(value)

    item[this._schema.hash.name] = this._schema.hash.value
    item[this._schema.range.name] = key

    return serialize(item).M
  }

  _toKV(item) {
    const value = parse({M: item})
    const key = value[this._schema.range.name]

    delete value[this._schema.range.name]
    delete value[this._schema.hash.name]

    return {key, value}
  }

  _open(options, cb) {
    const params = {TableName: this._table.name}
    const ontable = (err, data) => {
      if (err) return cb(err)

      for (let {KeyType, AttributeName} of data.Table.KeySchema) {
        this._schema[KeyType.toLowerCase()].name = AttributeName
      }

      cb()
    }

    this._db.describeTable(params, ontable)
  }

  _get(key, options, cb) {
    const TableName = this._table.name
    const {valueEncoding} = options
    const Key = this._toItem({key})
    const params = {TableName, Key}

    this._db.getItem(params, (err, data) => {
      if (err) return cb(err)

      if (!data.Item) return cb(new Error("NotFound"))

      const {value} = this._toKV(data.Item)
      const isValue = valueEncoding !== "json"

      let item = isValue ? value.value : JSON.stringify(value)
      if (options.asBuffer !== false) item = new Buffer(item)

      cb(null, item)
    })
  }

  _put(key, value, options, cb) {
    const TableName = this._table.name
    const {valueEncoding} = options

    value = valueEncoding === "json" ? JSON.parse(value) : {value}

    const Item = this._toItem({key, value})
    const params = {TableName, Item}

    this._db.putItem(params, err => cb(err))
  }

  _del(key, options, cb) {
    const TableName = this._table.name
    const Key = this._toItem({key})
    const params = {TableName, Key}

    this._db.deleteItem(params, err => cb(err))
  }

  _iterator(options) {
    return new DynamoIterator(this, options)
  }

  _batch(array, options, cb) {
    const TableName = this._table.name

    const ops = array.map(({type, key, value}) => (
      type === "del"
        ? {DeleteRequest: {Key: this._toItem({key})}}
        : {PutRequest: {Item: this._toItem({key, value})}}
    ))

    const params = {RequestItems: {}}

    const loop = (err, data) => {
      if (err) return cb(err)

      const reqs = []

      if (data && data.UnprocessedItems && data.UnprocessedItems[TableName]) {
        reqs.push(...data.UnprocessedItems[TableName])
      }

      reqs.push(...ops.splice(0, 25 - reqs.length))

      if (reqs.length === 0) return cb()

      params.RequestItems[TableName] = reqs

      this._db.batchWriteItem(params, loop)
    }

    loop()
  }
}

export default db => location => new DynamoDOWN(db, location)
<commit_msg>don't need sets<commit_after>import {AbstractLevelDOWN, AbstractIterator} from "abstract-leveldown"
import xtend from "xtend"

const serialize = function(value) {
  if (value == null || value === "") return {NULL: true}

  const type = value.constructor.name
  const reduce = function(value) {
    return Object.keys(value).reduce(function(acc, key) {
      acc[key] = serialize(value[key])
      return acc
    }, {})
  }

  switch (type) {
    case "String"  : return {S: value}
    case "Buffer"  : return {B: value.toString("base64")}
    case "Boolean" : return {BOOL: value}
    case "Number"  : return {N: String(value)}
    case "Array"   : return {L: value.map(serialize)}
    case "Object"  : return {M: reduce(value)}

    default        : throw new Error(`Cannot serialize ${type}`)
  }
}

const parse = function(val) {
  const type = Object.keys(val)[0]
  const value = val[type]
  const reduce = function(value) {
    return Object.keys(value).reduce(function(acc, key) {
      acc[key] = parse(value[key])
      return acc
    }, {})
  }

  switch (type) {
    case "NULL" : return null
    case "S"    : return value
    case "B"    : return Buffer(value, "base64")
    case "BOOL" : return value
    case "N"    : return parseFloat(value, 10)
    case "L"    : return value.map(parse)
    case "M"    : return reduce(value)

    default     : throw new Error(`Cannot parse ${type}.`)
  }
}

class DynamoIterator extends AbstractIterator {
  constructor(db, options) {
    super(db)

    this._limit = Infinity
    if (options.limit !== -1) this._limit = options.limit

    this._reverse = false
    if (options.reverse === true) this._reverse = true

    if ("gt" in options || "gte" in options) {
      this._lowerBound = {
        key: options.gt || options.gte,
        inclusive: "gte" in options
      }
    }

    if ("lt" in options || "lte" in options) {
      this._upperBound = {
        key: options.lt || options.lte,
        inclusive: "lte" in options
      }
    }

    this._params = {
      TableName: this.db._table.name,
      KeyConditions: {}
    }

    if (this._limit !== Infinity) this._params.Limit = this._limit
    if (this._reverse) this._params.ScanIndexForward = false

    this._params.KeyConditions[this.db._schema.hash.name] = {
      ComparisonOperator: "EQ",
      AttributeValueList: [serialize(this.db._schema.hash.value)]
    }

    if (this._lowerBound && this._upperBound) {
      this._params.KeyConditions[this.db._schema.range.name] = {
        ComparisonOperator: "BETWEEN",
        AttributeValueList: [
          serialize(this._lowerBound.key),
          serialize(this._upperBound.key)
        ]
      }
    }

    else if (this._lowerBound) {
      this._params.KeyConditions[this.db._schema.range.name] = {
        ComparisonOperator: this._lowerBound.inclusive ? "GE" : "GT",
        AttributeValueList: [serialize(this._lowerBound.key)]
      }
    }

    else if (this._upperBound) {
      this._params.KeyConditions[this.db._schema.range.name] = {
        ComparisonOperator: this._upperBound.inclusive ? "LE" : "LT",
        AttributeValueList: [serialize(this._upperBound.key)]
      }
    }

    this._items = []
    this._cursor = 0
  }

  _next(cb) {
    const item = this._items[this._cursor]

    if (item) {
      // make sure not excluded from gt/lt key conditions
      setImmediate(cb, null, item.key, item.value)
      delete this._items[this._cursor]
      this._cursor++
      return
    }

    if (item === null || this._cursor === this._limit) {
      setImmediate(cb)
      return
    }

    this.db._db.query(this._params, (err, data) => {
      if (err) return cb(err)

      const {Items, LastEvaluatedKey} = data

      for (let item of Items) this._items.push(this.db._toKV(item))

      if (!LastEvaluatedKey) this._items.push(null)

      this._params.ExclusiveStartKey = LastEvaluatedKey
      this._next(cb)
    })
  }
}

class DynamoDOWN extends AbstractLevelDOWN {
  constructor(db, location) {
    super(location)

    const [table, hash] = location.split("/")

    this._db = db
    this._table = {name: table}
    this._schema = {
      hash: {value: hash},
      range: {}
    }
  }

  _toItem({key, value}) {
    const item = xtend(value)

    item[this._schema.hash.name] = this._schema.hash.value
    item[this._schema.range.name] = key

    return serialize(item).M
  }

  _toKV(item) {
    const value = parse({M: item})
    const key = value[this._schema.range.name]

    delete value[this._schema.range.name]
    delete value[this._schema.hash.name]

    return {key, value}
  }

  _open(options, cb) {
    const params = {TableName: this._table.name}
    const ontable = (err, data) => {
      if (err) return cb(err)

      for (let {KeyType, AttributeName} of data.Table.KeySchema) {
        this._schema[KeyType.toLowerCase()].name = AttributeName
      }

      cb()
    }

    this._db.describeTable(params, ontable)
  }

  _get(key, options, cb) {
    const TableName = this._table.name
    const {valueEncoding} = options
    const Key = this._toItem({key})
    const params = {TableName, Key}

    this._db.getItem(params, (err, data) => {
      if (err) return cb(err)

      if (!data.Item) return cb(new Error("NotFound"))

      const {value} = this._toKV(data.Item)
      const isValue = valueEncoding !== "json"

      let item = isValue ? value.value : JSON.stringify(value)
      if (options.asBuffer !== false) item = new Buffer(item)

      cb(null, item)
    })
  }

  _put(key, value, options, cb) {
    const TableName = this._table.name
    const {valueEncoding} = options

    value = valueEncoding === "json" ? JSON.parse(value) : {value}

    const Item = this._toItem({key, value})
    const params = {TableName, Item}

    this._db.putItem(params, err => cb(err))
  }

  _del(key, options, cb) {
    const TableName = this._table.name
    const Key = this._toItem({key})
    const params = {TableName, Key}

    this._db.deleteItem(params, err => cb(err))
  }

  _iterator(options) {
    return new DynamoIterator(this, options)
  }

  _batch(array, options, cb) {
    const TableName = this._table.name

    const ops = array.map(({type, key, value}) => (
      type === "del"
        ? {DeleteRequest: {Key: this._toItem({key})}}
        : {PutRequest: {Item: this._toItem({key, value})}}
    ))

    const params = {RequestItems: {}}

    const loop = (err, data) => {
      if (err) return cb(err)

      const reqs = []

      if (data && data.UnprocessedItems && data.UnprocessedItems[TableName]) {
        reqs.push(...data.UnprocessedItems[TableName])
      }

      reqs.push(...ops.splice(0, 25 - reqs.length))

      if (reqs.length === 0) return cb()

      params.RequestItems[TableName] = reqs

      this._db.batchWriteItem(params, loop)
    }

    loop()
  }
}

export default db => location => new DynamoDOWN(db, location)
<|endoftext|>


<commit_before>import test from 'ava';
import toLines from './to-lines';

test('should return an array for empty input', t => {
	t.deepEqual(toLines(), []);
});

test('should return an array for empty string input', t => {
	t.deepEqual(toLines(''), ['']);
});

test('should split LF newlines', t => {
	t.deepEqual(toLines('some\nweird\ntext'), ['some', 'weird', 'text']);
});

test('should split CR+LF newlines', t => {
	t.deepEqual(toLines('some\r\nweird\r\ntext'), ['some', 'weird', 'text']);
});
<commit_msg>test(core): add failing test for null input<commit_after>import test from 'ava';
import toLines from './to-lines';

test('should return an array for empty input', t => {
	t.deepEqual(toLines(), []);
});

test.failing('should return an array for null input', t => {
	t.deepEqual(toLines(null), []);
});

test('should return an array for empty string input', t => {
	t.deepEqual(toLines(''), ['']);
});

test('should split LF newlines', t => {
	t.deepEqual(toLines('some\nweird\ntext'), ['some', 'weird', 'text']);
});

test('should split CR+LF newlines', t => {
	t.deepEqual(toLines('some\r\nweird\r\ntext'), ['some', 'weird', 'text']);
});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var kstest = require( '@stdlib/math/generics/statistics/kstest' );
var round = require( '@stdlib/math/base/special/round' );
var isnan = require( '@stdlib/math/base/utils/is-nan' );
var factory = require( './../lib/factory.js' );

// VARIABLES //

var opts = {
	'skip': ( process.env.TEST_MODE === 'coverage' )
};

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof factory, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function returns a pseudorandom number generator (no seed)', function test( t ) {
	var chisquare;
	var r;
	var i;

	// When binding distribution parameter...
	chisquare = factory( 2 );
	for ( i = 0; i < 100; i++ ) {
		r = chisquare();
		t.equal( typeof r, 'number', 'returns a number' );
	}

	// Without binding distribution parameter...
	chisquare = factory();
	for ( i = 0; i < 100; i++ ) {
		r = chisquare( 100.0 );
		t.equal( typeof r, 'number', 'returns a number' );
	}

	t.end();
});

tape( 'the function returns a seeded pseudorandom number generator', function test( t ) {
	var chisquare1;
	var chisquare2;
	var seed;
	var r1;
	var r2;
	var i;

	seed = round( Date.now() / 1000 );

	chisquare1 = factory( 35, {
		'seed': seed
	});
	chisquare2 = factory( 35, {
		'seed': seed
	});

	t.notEqual( chisquare1, chisquare2, 'separate generators' );

	for ( i = 0; i < 100; i++ ) {
		r1 = chisquare1();
		r2 = chisquare2();
		t.equal( r1, r2, 'both return same number' );
	}
	t.end();
});

tape( 'attached to the returned function is the generator name', function test( t ) {
	var chisquare = factory();
	t.equal( chisquare.NAME, 'chisquare', 'has `NAME` property' );
	t.end();
});

tape( 'attached to the returned function is the underlying PRNG', function test( t ) {
	var chisquare = factory();
	t.equal( typeof chisquare.PRNG, 'function', 'has `PRNG` property' );
	t.end();
});

tape( 'attached to the returned function is the generator seed', function test( t ) {
	var chisquare = factory({
		'seed': 12345
	});
	t.equal( typeof chisquare.SEED, 'number', 'has `SEED` property' );
	t.equal( chisquare.SEED, 12345, 'equal to provided seed' );
	t.end();
});

tape( 'the function throws an error if degrees of freedom `k` is not a positive number (no options)', function test( t ) {
	var values;
	var i;

	values = [
		-2,
		0,
		'5',
		null,
		true,
		undefined,
		NaN,
		[],
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( value );
		};
	}
});

tape( 'the function throws an error if degrees of freedom `k` is not a positive number (options)', function test( t ) {
	var values;
	var i;

	values = [
		-2,
		0,
		'5',
		null,
		true,
		undefined,
		NaN,
		[],
		{},
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( value, {} );
		};
	}
});

tape( 'the function throws an error if  provided an options argument which is not an object (when `k` is not supplied)', function test( t ) {
	var values;
	var i;

	values = [
		'abc',
		null,
		true,
		undefined,
		NaN,
		[],
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( value );
		};
	}
});

tape( 'the function throws an error if provided an options argument which is not an object (when `k` is supplied)', function test( t ) {
	var values;
	var i;

	values = [
		'abc',
		5,
		null,
		true,
		undefined,
		NaN,
		[],
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( 10, value );
		};
	}
});

tape( 'when called without arguments, the function returns a PRNG that returns `NaN` when provided a first argument equal to `NaN`', function test( t ) {
	var chisquare;
	var r;

	chisquare = factory();
	r = chisquare( NaN );

	t.strictEqual( isnan( r ), true, 'returns NaN' );
	t.end();
});

tape( 'when called without arguments, the function returns a PRNG that returns `NaN` when provided a first argument which is not a positive number', function test( t ) {
	var chisquare;
	var r;

	chisquare = factory();

	r = chisquare( 0 );
	t.strictEqual( isnan( r ), true, 'returns NaN' );

	r = chisquare( -1 );
	t.strictEqual( isnan( r ), true, 'returns NaN' );

	r = chisquare( -3.14 );
	t.strictEqual( isnan( r ), true, 'returns NaN' );

	t.end();
});

tape( 'the function returns a PRNG for generating random numbers from a chi-square distribution', opts, function test( t ) {
	var chisquare;
	var rejected;
	var pValue;
	var N;
	var k;
	var i;
	var j;
	var x;

	k = 4;
	chisquare = factory( k, {
		'seed': 675
	});

	x = new Array( 1e3 );
	rejected = 0;
	N = 300;
	for ( i = 0; i < N; i++ ) {
		for ( j = 0; j < x.length; j++ ) {
			x[ j ] = chisquare();
		}
		// Test using Kolmogorov-Smirnov goodness-of-fit test:
		pValue = kstest( x, 'chisquare', k ).pValue;
		t.equal( typeof pValue, 'number', 'returns a p-value' );
		if ( pValue < 0.05 ) {
			rejected += 1;
		}
	}
	// Account for small sample sizes and few repeats...
	t.ok( rejected / N < 0.10, 'null hypothesis (i.e., that numbers are drawn from Chisquare('+k+') is rejected in less than 10% of cases ('+rejected+' of '+N+')' );
	t.end();
});
<commit_msg>Run KS tests with different seeds<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var kstest = require( '@stdlib/math/generics/statistics/kstest' );
var round = require( '@stdlib/math/base/special/round' );
var isnan = require( '@stdlib/math/base/utils/is-nan' );
var factory = require( './../lib/factory.js' );

// VARIABLES //

var opts = {
	'skip': ( process.env.TEST_MODE === 'coverage' )
};

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof factory, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function returns a pseudorandom number generator (no seed)', function test( t ) {
	var chisquare;
	var r;
	var i;

	// When binding distribution parameter...
	chisquare = factory( 2 );
	for ( i = 0; i < 100; i++ ) {
		r = chisquare();
		t.equal( typeof r, 'number', 'returns a number' );
	}

	// Without binding distribution parameter...
	chisquare = factory();
	for ( i = 0; i < 100; i++ ) {
		r = chisquare( 100.0 );
		t.equal( typeof r, 'number', 'returns a number' );
	}

	t.end();
});

tape( 'the function returns a seeded pseudorandom number generator', function test( t ) {
	var chisquare1;
	var chisquare2;
	var seed;
	var r1;
	var r2;
	var i;

	seed = round( Date.now() / 1000 );

	chisquare1 = factory( 35, {
		'seed': seed
	});
	chisquare2 = factory( 35, {
		'seed': seed
	});

	t.notEqual( chisquare1, chisquare2, 'separate generators' );

	for ( i = 0; i < 100; i++ ) {
		r1 = chisquare1();
		r2 = chisquare2();
		t.equal( r1, r2, 'both return same number' );
	}
	t.end();
});

tape( 'attached to the returned function is the generator name', function test( t ) {
	var chisquare = factory();
	t.equal( chisquare.NAME, 'chisquare', 'has `NAME` property' );
	t.end();
});

tape( 'attached to the returned function is the underlying PRNG', function test( t ) {
	var chisquare = factory();
	t.equal( typeof chisquare.PRNG, 'function', 'has `PRNG` property' );
	t.end();
});

tape( 'attached to the returned function is the generator seed', function test( t ) {
	var chisquare = factory({
		'seed': 12345
	});
	t.equal( typeof chisquare.SEED, 'number', 'has `SEED` property' );
	t.equal( chisquare.SEED, 12345, 'equal to provided seed' );
	t.end();
});

tape( 'the function throws an error if degrees of freedom `k` is not a positive number (no options)', function test( t ) {
	var values;
	var i;

	values = [
		-2,
		0,
		'5',
		null,
		true,
		undefined,
		NaN,
		[],
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( value );
		};
	}
});

tape( 'the function throws an error if degrees of freedom `k` is not a positive number (options)', function test( t ) {
	var values;
	var i;

	values = [
		-2,
		0,
		'5',
		null,
		true,
		undefined,
		NaN,
		[],
		{},
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( value, {} );
		};
	}
});

tape( 'the function throws an error if  provided an options argument which is not an object (when `k` is not supplied)', function test( t ) {
	var values;
	var i;

	values = [
		'abc',
		null,
		true,
		undefined,
		NaN,
		[],
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( value );
		};
	}
});

tape( 'the function throws an error if provided an options argument which is not an object (when `k` is supplied)', function test( t ) {
	var values;
	var i;

	values = [
		'abc',
		5,
		null,
		true,
		undefined,
		NaN,
		[],
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function() {
			factory( 10, value );
		};
	}
});

tape( 'when called without arguments, the function returns a PRNG that returns `NaN` when provided a first argument equal to `NaN`', function test( t ) {
	var chisquare;
	var r;

	chisquare = factory();
	r = chisquare( NaN );

	t.strictEqual( isnan( r ), true, 'returns NaN' );
	t.end();
});

tape( 'when called without arguments, the function returns a PRNG that returns `NaN` when provided a first argument which is not a positive number', function test( t ) {
	var chisquare;
	var r;

	chisquare = factory();

	r = chisquare( 0 );
	t.strictEqual( isnan( r ), true, 'returns NaN' );

	r = chisquare( -1 );
	t.strictEqual( isnan( r ), true, 'returns NaN' );

	r = chisquare( -3.14 );
	t.strictEqual( isnan( r ), true, 'returns NaN' );

	t.end();
});

tape( 'the function returns a PRNG for generating random numbers from a chi-square distribution', opts, function test( t ) {
	var chisquare;
	var rejected;
	var pValue;
	var N;
	var k;
	var i;
	var j;
	var x;

	k = 4;

	x = new Array( 1e3 );
	rejected = 0;
	N = 300;
	for ( i = 0; i < N; i++ ) {
		chisquare = factory( k );
		t.ok( true, 'seed: '+chisquare.SEED );
		for ( j = 0; j < x.length; j++ ) {
			x[ j ] = chisquare();
		}
		// Test using Kolmogorov-Smirnov goodness-of-fit test:
		pValue = kstest( x, 'chisquare', k ).pValue;
		t.equal( typeof pValue, 'number', 'returns a p-value: '+pValue );
		if ( pValue < 0.05 ) {
			rejected += 1;
		}
	}
	// Account for small sample sizes and few repeats...
	t.ok( rejected / N < 0.10, 'null hypothesis (i.e., that numbers are drawn from Chisquare('+k+') is rejected in less than 10% of cases ('+rejected+' of '+N+')' );
	t.end();
});
<|endoftext|>


<commit_before>/********************************
* EZ-TC Plugin by jd            *
* Makes adding trainer cards EZ *
********************************/
const sugar = require('sugar');
var fs = require('fs');
var serialize = require('node-serialize');
var trainerCards = {};

function loadTrainerCards () {
	try {
		trainerCards = serialize.unserialize(fs.readFileSync('config/trainercards.json', 'utf8'));
		Object.merge(CommandParser.commands, trainerCards);
	} catch (e) {}
}

setTimeout(function load() {
	loadTrainerCards();
}, 1000);

function saveTrainerCards() {
	fs.writeFileSync('config/trainercards.json', serialize.serialize(trainerCards));
	Object.merge(CommandParser.commands, trainerCards);
}

exports.commands = {
	eztc: 'trainercard',
	trainercards: 'trainercard',
	tc: 'trainercard',
	trainercard: function (target, room, user) {
		if (!target) target = 'help';
		var parts = target.split(',');
		for (var u in parts) parts[u] = parts[u].trim();

		switch (parts[0]) {
			case 'add':
				if (!this.can('trainercard')) return false;
				if (!parts[2]) return this.sendReply("Usage: /trainercard add, [command name], [html]");
				var commandName = toId(parts[1]);
				if (CommandParser.commands[commandName]) return this.sendReply("/trainercards - The command \"" + commandName + "\" already exists.");
				var html = parts.splice(2, parts.length).join(',');
				trainerCards[commandName] = new Function('target', 'room', 'user', "if (!room.disableTrainerCards) if (!this.runBroadcast()) return; this.sendReplyBox('" + html.replace(/'/g, "\\'") + "');");
				saveTrainerCards();
				this.sendReply("The trainer card \"" + commandName + "\" has been added.");
				this.logModCommand(user.name + " added the trainer card " + commandName);
				break;

			case 'rem':
			case 'del':
			case 'delete':
			case 'remove':
				if (!this.can('trainercard')) return false;
				if (!parts[1]) return this.sendReply("Usage: /trainercard remove, [command name]");
				var commandName = toId(parts[1]);
				if (!trainerCards[commandName]) return this.sendReply("/trainercards - The command \"" + commandName + "\" does not exist, or was added manually.");
				delete CommandParser.commands[commandName];
				delete trainerCards[commandName];
				saveTrainerCards();
				this.sendReply("The trainer card \"" + commandName + "\" has been removed.");
				this.logModCommand(user.name + " removed the trainer card " + commandName);
				break;

			case 'list':
				if (!this.can('trainercard')) return false;
				var output = "There's a total of " + Object.size(trainerCards) + " trainer cards added with this command:
";
				for (var tc in trainerCards) {
					output += tc + "
";
				}
				this.sendReplyBox(output);
				break;

			case 'off':
				if (!this.can('roommod', null, room)) return false;
				if (room.disableTrainerCards) return this.sendReply("Broadcasting trainer cards is already disabled in this room.");
				room.disableTrainerCards = true;
				room.chatRoomData.disableTrainerCards = true;
				Rooms.global.writeChatRoomData();
				this.privateModCommand("(" + user.name + " has disabled broadcasting trainer cards in this room.)");
				break;

			case 'on':
				if (!this.can('roommod', null, room)) return false;
				if (!room.disableTrainerCards) return this.sendReply("Broadcasing trainer cards is already enabled in this room.");
				delete room.disableTrainerCards;
				delete room.chatRoomData.disableTrainerCards;
				Rooms.global.writeChatRoomData();
				this.privateModCommand("(" + user.name + " has enabled broadcasting trainer cards in this room.)");
				break;

			default:
			case 'info':
			case 'help':
				if (!this.runBroadcast()) return;
				this.sendReplyBox(
					"EZ-TC Commands:
" +
					"/trainercard add, [command name], [html] - Adds a trainer card.
" +
					"/trainercard remove, [command name] - Removes a trainer card.
" +
					"/trainercard list - Shows a list of all trainer cards added with this command.
" +
					"/trainercard off - Disables broadcasting trainer cards in the current room.
" +
					"/trainercard on - Enables broadcasting trainer cards in the current room.
" +
					"/trainercard help - Shows this help command.
" +
					"EZ-TC Plugin by jd"
				);
		}
	}
};
<commit_msg>Update from jd's latest code<commit_after>/********************************
* EZ-TC Plugin by jd            *
* Makes adding trainer cards EZ *
********************************/
'use strict';

const fs = require('fs');
const serialize = require('node-serialize');
let trainerCards = {};

function loadTrainerCards() {
	try {
		trainerCards = serialize.unserialize(fs.readFileSync('config/trainercards.json', 'utf8'));
		Object.assign(CommandParser.commands, trainerCards);
	} catch (e) {}
}

setTimeout(function load() {
	loadTrainerCards();
}, 1000);

function saveTrainerCards() {
	fs.writeFileSync('config/trainercards.json', serialize.serialize(trainerCards));
	Object.assign(CommandParser.commands, trainerCards);
}

exports.commands = {
	eztc: 'trainercard',
	trainercards: 'trainercard',
	tc: 'trainercard',
	trainercard: function (target, room, user) {
		if (!target) target = 'help';
		let parts = target.split(',');
		for (let u in parts) parts[u] = parts[u].trim();

		switch (parts[0]) {
		case 'add':
			if (!this.can('trainercard')) return false;
			if (!parts[2]) return this.sendReply("Usage: /trainercard add, [command name], [html]");
			let commandName = toId(parts[1]);
			if (CommandParser.commands[commandName]) return this.sendReply("/trainercards - The command \"" + commandName + "\" already exists.");
			let html = parts.splice(2, parts.length).join(',');
			trainerCards[commandName] = new Function('target', 'room', 'user', "if (!room.disableTrainerCards) if (!this.runBroadcast()) return; this.sendReplyBox('" + html.replace(/'/g, "\\'") + "');"); // eslint-disable-line no-new-func
			saveTrainerCards();
			this.sendReply("The trainer card \"" + commandName + "\" has been added.");
			this.logModCommand(user.name + " added the trainer card " + commandName);
			break;

		case 'rem':
		case 'del':
		case 'delete':
		case 'remove':
			if (!this.can('trainercard')) return false;
			if (!parts[1]) return this.sendReply("Usage: /trainercard remove, [command name]");
			let command = toId(parts[1]);
			if (!trainerCards[command]) return this.sendReply("/trainercards - The command \"" + command + "\" does not exist, or was added manually.");
			delete CommandParser.commands[command];
			delete trainerCards[command];
			saveTrainerCards();
			this.sendReply("The trainer card \"" + command + "\" has been removed.");
			this.logModCommand(user.name + " removed the trainer card " + command);
			break;

		case 'list':
			if (!this.can('trainercard')) return false;
			let output = "There's a total of " + Object.keys(trainerCards).length + " trainer cards added with this command:
";
			for (let tc in trainerCards) {
				output += tc + "
";
			}
			this.sendReplyBox(output);
			break;

		case 'off':
			if (!this.can('roommod', null, room)) return false;
			if (room.disableTrainerCards) return this.sendReply("Broadcasting trainer cards is already disabled in this room.");
			room.disableTrainerCards = true;
			room.chatRoomData.disableTrainerCards = true;
			Rooms.global.writeChatRoomData();
			this.privateModCommand("(" + user.name + " has disabled broadcasting trainer cards in this room.)");
			break;

		case 'on':
			if (!this.can('roommod', null, room)) return false;
			if (!room.disableTrainerCards) return this.sendReply("Broadcasing trainer cards is already enabled in this room.");
			delete room.disableTrainerCards;
			delete room.chatRoomData.disableTrainerCards;
			Rooms.global.writeChatRoomData();
			this.privateModCommand("(" + user.name + " has enabled broadcasting trainer cards in this room.)");
			break;

		default:
		case 'info':
		case 'help':
			if (!this.runBroadcast()) return;
			this.sendReplyBox(
				"EZ-TC Commands:
" +
				"/trainercard add, [command name], [html] - Adds a trainer card.
" +
				"/trainercard remove, [command name] - Removes a trainer card.
" +
				"/trainercard list - Shows a list of all trainer cards added with this command.
" +
				"/trainercard off - Disables broadcasting trainer cards in the current room.
" +
				"/trainercard on - Enables broadcasting trainer cards in the current room.
" +
				"/trainercard help - Shows this help command.
" +
				"EZ-TC Plugin by jd"
			);
		}
	},
};
<|endoftext|>


<commit_before>/**
 * @module tombo
**/
module.exports = Family;

function onComponentRemovedFromEntity (entity, component, componentConstructor) {
	if (this.entities.has(entity) && this.components.has(componentConstructor)) {
		this.remove(entity);
	}
}

/**
 * @class Family
 * @constructor
 * @param {Object} schema
**/
function Family (schema) {
	/**
	 * @property entities
	 * @type {Map}
	 * @default new Map()
	**/
	// KEY: entity instance | VALUE: entity node
	this.entities = new Map();

	/**
	 * @property components
	 * @private
	 * @type {Map}
	 * @default new Map()
	**/
	// KEY: component constructor | VALUE: component link name
	this.components = new Map();

	for (var componentName in schema) {
		this.components.set(schema[componentName], componentName);
	}

	//TODO: throw error when schema is empty
}

/**
 * @method add
 * @chainable
 * @param {Entity} entity
 * @return {Family}
**/
Family.prototype.add = function add (entity) {
	if (!this.entities.has(entity) && this.match(entity)) {

		// TODO: use pooling for nodes
		var node = {};
		for (var [componentConstructor, componentName] of this.components) {
			node[componentName] = entity.get(componentConstructor);
		}

		entity.on('component:removed', onComponentRemovedFromEntity, this);
		this.entities.set(entity, node);
	}

	return this;
};

/**
 * @method remove
 * @chainable
 * @param {Entity} entity
 * @return {Family}
**/
Family.prototype.remove = function remove (entity) {
	if (this.entities.has(entity)) {
		entity.off('component:removed', onComponentRemovedFromEntity, this);

		// TODO: use pooling for nodes
		this.entities.delete(entity);
	}

	return this;
};

/**
 * @method has
 * @param {Entity} entity
 * @return {Boolean}
**/
Family.prototype.has = function has (entity) {
	return this.entities.has(entity);
};

/**
 * @method match
 * @param {Entity} entity
 * @return {Boolean}
**/
Family.prototype.match = function (entity) {
	for (var componentConstructor of this.components.keys()) {
		if (!entity.has(componentConstructor)) {
			return false;
		}
	}

	return true;
};<commit_msg>object pooling pre-work<commit_after>/**
 * @module tombo
**/
module.exports = Family;

function onComponentRemovedFromEntity (entity, component, componentConstructor) {
	if (this.entities.has(entity) && this.components.has(componentConstructor)) {
		this.remove(entity);
	}
}

/**
 * @class Family
 * @constructor
 * @param {Object} schema
**/
function Family (schema) {
	/**
	 * @property entities
	 * @type {Map}
	 * @default new Map()
	**/
	// entity | node
	this.entities = new Map();

	/**
	 * @property components
	 * @private
	 * @type {Map}
	 * @default new Map()
	**/
	// component constructor | property name
	this.components = new Map();

	/*
	this.pool = new Pool();
	*/

	for (var componentName in schema) {
		this.components.set(schema[componentName], componentName);
	}

	//TODO: throw error when schema is empty
}

/**
 * @method add
 * @chainable
 * @param {Entity} entity
 * @return {Family}
**/
Family.prototype.add = function add (entity) {
	if (!this.entities.has(entity) && this.match(entity)) {

		/*
		var node = this.pool.acquire();
		*/

		// TODO: use pooling for nodes
		var node = {};
		for (var [componentConstructor, componentName] of this.components) {
			node[componentName] = entity.get(componentConstructor);
		}

		entity.on('component:removed', onComponentRemovedFromEntity, this);
		this.entities.set(entity, node);
	}

	return this;
};

/**
 * @method remove
 * @chainable
 * @param {Entity} entity
 * @return {Family}
**/
Family.prototype.remove = function remove (entity) {
	if (this.entities.has(entity)) {
		entity.off('component:removed', onComponentRemovedFromEntity, this);

		/*
		this.pool.release(this.entities.get(entity));
		*/

		// TODO: use pooling for nodes
		this.entities.delete(entity);
	}

	return this;
};

/**
 * @method has
 * @param {Entity} entity
 * @return {Boolean}
**/
Family.prototype.has = function has (entity) {
	return this.entities.has(entity);
};

/**
 * @method match
 * @param {Entity} entity
 * @return {Boolean}
**/
Family.prototype.match = function (entity) {
	for (var componentConstructor of this.components.keys()) {
		if (!entity.has(componentConstructor)) {
			return false;
		}
	}

	return true;
};<|endoftext|>