<commit_before>function swap(arr, i, j) {
  if (i === j) {
    return;
  }
  const tmp = arr[i];
  arr[i] = arr[j];
  arr[j] = tmp;
}

function checkArray(arr) {
  if (!Array.isArray(arr)) {
    throw new Error("Expect input to be an array.");
  }
}

/**
 * Bubble sort, sorted by swapping item pairs(if needed) from the start postion to the end of the
 * array.
 * First round will have a largest item swapped to the array end, and second round will have the
 * second largest item swapped to array end - 1 position, and so on until all items are sorted.
 *
 * Time complexity: O(N, N^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function bubbleSort(array) {
  const arr = array.slice();
  checkArray(arr);
  let hasSwap = false;
  for (let i = arr.length - 1; i > 0; i--) {
    for (let j = 0; j < i; j++) {
      if (arr[j] > arr[j + 1]) {
        swap(arr, j, j + 1);
        hasSwap = true;
      }
    }
    if (!hasSwap) {
      return arr;
    }
  }
  return arr;
}

/**
 * Selection sort, sorted by selecting min to max items for the start to the end position of the
 * array.
 *
 * Time complexity: O(N^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function selectionSort(array) {
  const arr = array.slice();
  checkArray(arr);
  for (let i = 0; i < arr.length - 1; i++) {
    let min = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[min] >= arr[j]) {
        min = j;
      }
    }
    swap(arr, i, min);
  }
  return arr;
}

/**
 * Insertion sort, sorted by inserting each item into a proper position of the sorted part of the
 * array before it.
 * The second item is the first one to insert, this carries on until the last item is inserted into
 * the sorted part of the array before it.
 * Insertion sort is extra fast when the array to sort is small, or is partially sorted.
 *
 * Time complexity: O(N, N^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function insertionSort(array) {
  const arr = array.slice();
  checkArray(arr);
  for (let i = 1; i < arr.length; i++) {
    let cur = i;
    const curVal = arr[cur];
    while (cur > 0 && arr[cur - 1] > curVal) {
      arr[cur] = arr[cur - 1];
      cur -= 1;
    }
    arr[cur] = curVal;
  }
  return arr;
}

/**
 * Shell sort, a type of insertion sort, sorted by swapping each gapped array items. The gap reduces
 * after the gapped array items are sorted. This goes on until the array is sorted.
 * The gap number is determined by a base number, for example, if the base number is 2, then for an
 * array of 16 items, its gap range will be 7, 3, 1.
 *
 * Time complexity: O(NlogN, N(logN)^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function shellSort(array, base = 3) {
  const arr = array.slice();
  const len = arr.length;
  let gap = 1;

  while (gap < len / base) {
    gap = gap * base + 1;
  }
  while (gap > 0) {
    for (let init = gap; init < len; init++) {
      const tmp = arr[init];
      let pos = init;
      for (; pos >= gap && arr[pos - gap] > tmp; pos -= gap) {
        arr[pos] = arr[pos - gap];
      }
      arr[pos] = tmp;
    }
    gap = Math.floor(gap / base);
  }

  return arr;
}

/**
 * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is
 * done for the left/right partitioned parts, and so on.
 * The partition process will swap pairs of items until the left part are all smaller than pivot,
 * and right part are all larger.
 * This function implemented it by creating extra partitioned array upon each partition process.
 * It's concise and easy to read, but has extra space complexity.
 *
 * Time complexity: O(NlogN, N^2)
 * Space complexity: O(N)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function quickSortWithArray(array) {
  const arr = array.slice();
  checkArray(arr);
  if (arr.length < 2) {
    return arr;
  }
  const [pivot, ...rest] = arr;
  const larger = rest.filter((item) => item > pivot);
  const smaller = rest.filter((item) => item <= pivot);

  return [...quickSortWithArray(smaller), pivot, ...quickSortWithArray(larger)];
}

/**
 * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is
 * done for the left/right partitioned parts, and so on.
 * The partition process will swap pairs of items until the left part are all smaller than pivot,
 * and right part are all larger.
 *
 * Time complexity: O(NlogN, N^2)
 * Space complexity: O(logN)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function quickSort(array, lo, hi) {
  checkArray(array);
  lo = typeof lo === "number" ? lo : 0;
  hi = typeof hi === "number" ? hi : array.length;
  if (hi <= lo) return array;

  const partition = (arr, left, right) => {
    let start = left;
    let end = right;
    const pivot = arr[left];

    while (start < end) {
      while (arr[++start] <= pivot) if (start === right) break; // eslint-disable-line no-plusplus
      while (arr[--end] >= pivot) if (end === left) break; // eslint-disable-line no-plusplus
      if (start >= end) break;
      swap(arr, start, end);
    }
    swap(arr, left, end);
    return end;
  };
  const pivot = partition(array, lo, hi);
  quickSort(array, lo, pivot);
  quickSort(array, pivot + 1, hi);

  return array;
}

/**
 * Merge sort, sorted by recursively dividing the array into two sub-arrays and merging
 * corresponding sub-arrays back into a sorted array. The merge process ensures that the merged
 * array is sorted.
 *
 * Time complexity: O(NlogN)
 * Space complexity: O(N)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function mergeSort(array) {
  const arr = array.slice();
  checkArray(arr);
  if (arr.length < 2) return arr;

  const merge = (left, right) => {
    const result = [];
    let i = 0;
    let j = 0;
    while (i < left.length && j < right.length) {
      if (left[i] <= right[j]) {
        result.push(left[i]);
        i += 1;
      }
      if (left[i] >= right[j]) {
        result.push(right[j]);
        j += 1;
      }
    }
    return result.concat(left.slice(i), right.slice(j));
  };

  const mid = Math.floor(arr.length / 2);
  return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)));
}

/**
 * Heap sort, sorted by using the heapify process of the Heap data structure.
 * The Heap data structure looks like a binary tree, but there cannot be `null` gap within it.
 * A proper Heap should have the property that all parent nodes are larger than or equal to its
 * child nodes.
 * The heapify process can find the largest item of the array at a time, and then swap the largest
 * item to the end of the array. This process is repeated until all the array become sorted.
 *
 * Time complexity: O(NlogN)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function heapSort(array) {
  const arr = array.slice();
  checkArray(arr);
  if (arr.length < 2) return arr;

  const heapify = (list, index, end = list.length - 1) => {
    const parentIndex = Math.ceil(index / 2) - 1;
    if (index < 0 || parentIndex < 0) {
      return;
    }
    const isLeft = index % 2 === 1;
    const peerIndex = isLeft ? index + 1 : index - 1;

    let largest = parentIndex;
    if (list[index] > list[largest]) largest = index;
    if (peerIndex <= end && list[peerIndex] > list[largest]) largest = peerIndex;
    if (largest !== parentIndex) swap(list, largest, parentIndex);

    heapify(list, index - 2, end);
  };

  for (let last = arr.length - 1; last > 0; last -= 1) {
    heapify(arr, last, last);
    swap(arr, 0, last);
  }

  return arr;
}<commit_msg>refactored quick sort iterative.<commit_after>function swap(arr, i, j) {
  if (i === j) {
    return;
  }
  const tmp = arr[i];
  arr[i] = arr[j];
  arr[j] = tmp;
}

function checkArray(arr) {
  if (!Array.isArray(arr)) {
    throw new Error("Expect input to be an array.");
  }
}

/**
 * Bubble sort, sorted by swapping item pairs(if needed) from the start postion to the end of the
 * array.
 * First round will have a largest item swapped to the array end, and second round will have the
 * second largest item swapped to array end - 1 position, and so on until all items are sorted.
 *
 * Time complexity: O(N, N^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function bubbleSort(array) {
  const arr = array.slice();
  checkArray(arr);
  let hasSwap = false;
  for (let i = arr.length - 1; i > 0; i--) {
    for (let j = 0; j < i; j++) {
      if (arr[j] > arr[j + 1]) {
        swap(arr, j, j + 1);
        hasSwap = true;
      }
    }
    if (!hasSwap) {
      return arr;
    }
  }
  return arr;
}

/**
 * Selection sort, sorted by selecting min to max items for the start to the end position of the
 * array.
 *
 * Time complexity: O(N^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function selectionSort(array) {
  const arr = array.slice();
  checkArray(arr);
  for (let i = 0; i < arr.length - 1; i++) {
    let min = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[min] >= arr[j]) {
        min = j;
      }
    }
    swap(arr, i, min);
  }
  return arr;
}

/**
 * Insertion sort, sorted by inserting each item into a proper position of the sorted part of the
 * array before it.
 * The second item is the first one to insert, this carries on until the last item is inserted into
 * the sorted part of the array before it.
 * Insertion sort is extra fast when the array to sort is small, or is partially sorted.
 *
 * Time complexity: O(N, N^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function insertionSort(array) {
  const arr = array.slice();
  checkArray(arr);
  for (let i = 1; i < arr.length; i++) {
    let cur = i;
    const curVal = arr[cur];
    while (cur > 0 && arr[cur - 1] > curVal) {
      arr[cur] = arr[cur - 1];
      cur -= 1;
    }
    arr[cur] = curVal;
  }
  return arr;
}

/**
 * Shell sort, a type of insertion sort, sorted by swapping each gapped array items. The gap reduces
 * after the gapped array items are sorted. This goes on until the array is sorted.
 * The gap number is determined by a base number, for example, if the base number is 2, then for an
 * array of 16 items, its gap range will be 7, 3, 1.
 *
 * Time complexity: O(NlogN, N(logN)^2)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function shellSort(array, base = 3) {
  const arr = array.slice();
  const len = arr.length;
  let gap = 1;

  while (gap < len / base) {
    gap = gap * base + 1;
  }
  while (gap > 0) {
    for (let init = gap; init < len; init++) {
      const tmp = arr[init];
      let pos = init;
      for (; pos >= gap && arr[pos - gap] > tmp; pos -= gap) {
        arr[pos] = arr[pos - gap];
      }
      arr[pos] = tmp;
    }
    gap = Math.floor(gap / base);
  }

  return arr;
}

/**
 * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is
 * done for the left/right partitioned parts, and so on.
 * The partition process will swap pairs of items until the left part are all smaller than pivot,
 * and right part are all larger.
 * This function implemented it by creating extra partitioned array upon each partition process.
 * It's concise and easy to read, but has extra space complexity.
 *
 * Time complexity: O(NlogN, N^2)
 * Space complexity: O(N)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function quickSortWithArray(array) {
  const arr = array.slice();
  checkArray(arr);
  if (arr.length < 2) {
    return arr;
  }
  const [pivot, ...rest] = arr;
  const larger = rest.filter((item) => item > pivot);
  const smaller = rest.filter((item) => item <= pivot);

  return [...quickSortWithArray(smaller), pivot, ...quickSortWithArray(larger)];
}

/**
 * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is
 * done for the left/right partitioned parts, and so on.
 * The partition process will swap pairs of items until the left part are all smaller than pivot,
 * and right part are all larger.
 *
 * Time complexity: O(NlogN, N^2)
 * Space complexity: O(logN)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function quickSort(array, lo = 0, hi = array.length) {
  checkArray(array);
  if (array.length <= 1 || hi <= lo) return array;

  const partition = (arr, left, right) => {
    let i = left;
    let j = right;
    const pivot = arr[left];

    while (i < j) {
      while (arr[++i] <= pivot) if (i === right) break; // eslint-disable-line no-plusplus
      while (arr[--j] >= pivot) if (j === left) break; // eslint-disable-line no-plusplus
      if (i < j) swap(arr, i, j);
    }
    swap(arr, left, j);
    return j;
  };
  const pivotIndex = partition(array, lo, hi);
  quickSort(array, lo, pivotIndex);
  quickSort(array, pivotIndex + 1, hi);

  return array;
}

/**
 * Merge sort, sorted by recursively dividing the array into two sub-arrays and merging
 * corresponding sub-arrays back into a sorted array. The merge process ensures that the merged
 * array is sorted.
 *
 * Time complexity: O(NlogN)
 * Space complexity: O(N)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function mergeSort(array) {
  const arr = array.slice();
  checkArray(arr);
  if (arr.length < 2) return arr;

  const merge = (left, right) => {
    const result = [];
    let i = 0;
    let j = 0;
    while (i < left.length && j < right.length) {
      if (left[i] <= right[j]) {
        result.push(left[i]);
        i += 1;
      }
      if (left[i] >= right[j]) {
        result.push(right[j]);
        j += 1;
      }
    }
    return result.concat(left.slice(i), right.slice(j));
  };

  const mid = Math.floor(arr.length / 2);
  return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)));
}

/**
 * Heap sort, sorted by using the heapify process of the Heap data structure.
 * The Heap data structure looks like a binary tree, but there cannot be `null` gap within it.
 * A proper Heap should have the property that all parent nodes are larger than or equal to its
 * child nodes.
 * The heapify process can find the largest item of the array at a time, and then swap the largest
 * item to the end of the array. This process is repeated until all the array become sorted.
 *
 * Time complexity: O(NlogN)
 * Space complexity: O(1)
 *
 * @param {Array} array
 * @return {Array}
 *
 */
export function heapSort(array) {
  const arr = array.slice();
  checkArray(arr);
  if (arr.length < 2) return arr;

  const heapify = (list, index, end = list.length - 1) => {
    const parentIndex = Math.ceil(index / 2) - 1;
    if (index < 0 || parentIndex < 0) {
      return;
    }
    const isLeft = index % 2 === 1;
    const peerIndex = isLeft ? index + 1 : index - 1;

    let largest = parentIndex;
    if (list[index] > list[largest]) largest = index;
    if (peerIndex <= end && list[peerIndex] > list[largest]) largest = peerIndex;
    if (largest !== parentIndex) swap(list, largest, parentIndex);

    heapify(list, index - 2, end);
  };

  for (let last = arr.length - 1; last > 0; last -= 1) {
    heapify(arr, last, last);
    swap(arr, 0, last);
  }

  return arr;
}<|endoftext|>


<commit_before>process.env.BABEL_ENV = process.env.BABEL_ENV || "production";
process.env.NODE_ENV = process.env.NODE_ENV || "production";

require("soya-next/config/default");

process.on("unhandledRejection", err => {
  throw err;
});

// @remove-on-eject-begin
const conf = require("../next.config");
// @remove-on-eject-end
const build = require("next/dist/server/build").default;

const { appDir } = require("../config/paths");
const buildSoya = require("./utils/build-soya");
build(
  appDir
  // @remove-on-eject-begin
  , conf
  // @remove-on-eject-end
)
  .then(
    () => buildSoya(),
    err => {
      if (err.code !== "MODULE_NOT_FOUND") {
        throw err;
      }
    }
  )
  .catch(err => {
    // eslint-disable-next-line no-console
    console.error(err.stack);
    process.exit(1);
  });
<commit_msg>Use next-build new path<commit_after>process.env.BABEL_ENV = process.env.BABEL_ENV || "production";
process.env.NODE_ENV = process.env.NODE_ENV || "production";

require("soya-next/config/default");

process.on("unhandledRejection", err => {
  throw err;
});

// @remove-on-eject-begin
const conf = require("../next.config");
// @remove-on-eject-end
const build = require("next/dist/build").default;

const { appDir } = require("../config/paths");
const buildSoya = require("./utils/build-soya");
build(
  appDir
  // @remove-on-eject-begin
  , conf
  // @remove-on-eject-end
)
  .then(
    () => buildSoya(),
    err => {
      if (err.code !== "MODULE_NOT_FOUND") {
        throw err;
      }
    }
  )
  .catch(err => {
    // eslint-disable-next-line no-console
    console.error(err.stack);
    process.exit(1);
  });
<|endoftext|>


<commit_before>var playField = (function () {

    const PUZZLE_HOVER_TINT = '#009900';

    var _stage,
        _canvas,
        _img,
        _pieces,
        _puzzleWidth,
        _puzzleHeight,
        _pieceWidth,
        _pieceHeight,
        _currentPiece,
        _currentDropPiece,
        _mouse,
        _puzzle_difficulty,
        mouse,
        puzzlePiece,
        playField;

    mouse = (function () {
        var mouse = Object.create({});

        Object.defineProperty(mouse, 'init', {
            value: function (x, y) {
                this.x = x;
                this.y = y;
                return this;
            }
        });

        Object.defineProperty(mouse, 'x', {
            get: function () {
                return this._x;
            },
            set: function (value) {
                this._x = value;
            }
        });

        Object.defineProperty(mouse, 'y', {
            get: function () {
                return this._y;
            },
            set: function (value) {
                this._y = value;
            }
        });

        return mouse;
    }());

    puzzlePiece = (function () {
        var piece = Object.create({});

        Object.defineProperty(piece, 'init', {
            value: function (startX, startY) {
                this.startX = startX;
                this.startY = startY;
                this.currentX = startX;
                this.currentY = startY;
                return this;
            }
        });

        Object.defineProperty(piece, 'startX', {
            get: function () {
                return this._startX;
            },
            set: function (value) {
                this._startX = value;
            }
        });

        Object.defineProperty(piece, 'startY', {
            get: function () {
                return this._startY;
            },
            set: function (value) {
                this._startY = value;
            }
        });

        Object.defineProperty(piece, 'currentX', {
            get: function () {
                return this._currentX;
            },
            set: function (value) {
                this._currentX = value;
            }
        });

        Object.defineProperty(piece, 'currentY', {
            get: function () {
                return this._currentY;
            },
            set: function (value) {
                this._currentY = value;
            }
        });

        return piece;
    }());

    playField = (function () {
        var playfield = Object.create({});

        Object.defineProperty(playfield, 'init', {
            value: function (imageSrc, difficulty) {
                _img = new Image();
                _img.addEventListener('load', playField.onImage, false);
                _img.src = imageSrc;
                _puzzle_difficulty = difficulty;
                return this;
            }
        });

        Object.defineProperty(playfield, 'onImage', {
            value: function (e) {
                _pieceWidth = Math.floor(_img.width / _puzzle_difficulty);
                _pieceHeight = Math.floor(_img.height / _puzzle_difficulty);
                _puzzleWidth = _pieceWidth * _puzzle_difficulty;
                _puzzleHeight = _pieceHeight * _puzzle_difficulty;
                playField.setCanvas();
                playField.initPuzzle();
            }
        });

        Object.defineProperty(playfield, 'setCanvas', {
            value: function () {
                _canvas = document.getElementById('canvas');
                _stage = _canvas.getContext('2d');
                _canvas.width = _puzzleWidth;
                _canvas.height = _puzzleHeight;
                _canvas.style.border = "1px solid black";
            }
        });

        Object.defineProperty(playfield, 'initPuzzle', {
            value: function () {
                _pieces = [];
                _mouse = Object.create(mouse).init(0, 0);
                _currentPiece = null;
                _currentDropPiece = null;
                _stage.drawImage(_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight);
                playField.createTitle("Click to Start Puzzle");
                playField.buildPieces();
            }
        });

        Object.defineProperty(playfield, 'createTitle', {
            value: function (msg) {
                _stage.fillStyle = "#000000";
                _stage.globalAlpha = .4;
                _stage.fillRect(100, _puzzleHeight - 40, _puzzleWidth - 200, 40);
                _stage.fillStyle = "#FFFFFF";
                _stage.globalAlpha = 1;
                _stage.textAlign = "center";
                _stage.textBaseline = "middle";
                _stage.font = "20px Arial";
                _stage.fillText(msg, _puzzleWidth / 2, _puzzleHeight - 20);
            }
        });

        Object.defineProperty(playfield, 'buildPieces', {
            value: function () {
                var i,
                    piece,
                    puzzleDifficulty = _puzzle_difficulty * _puzzle_difficulty,
                    xPos = 0,
                    yPos = 0;

                for (i = 0; i < puzzleDifficulty; i += 1) {
                    piece = Object.create(puzzlePiece).init(xPos, yPos);
                    _pieces.push(piece);
                    xPos += _pieceWidth;
                    if (xPos >= _puzzleWidth) {
                        xPos = 0;
                        yPos += _pieceHeight;
                    }
                }
                _canvas.onmousedown = playField.shufflePuzzle;
            }
        });

        Object.defineProperty(playfield, 'shufflePuzzle', {
            value: function () {
                _pieces = playField.shuffleArray(_pieces);
                _stage.clearRect(0, 0, _puzzleWidth, _puzzleHeight);
                var i;
                var piece;
                var xPos = 0;
                var yPos = 0;
                for (i = 0; i < _pieces.length; i++) {
                    piece = _pieces[i];
                    piece.currentX = xPos;
                    piece.currentY = yPos;
                    _stage.drawImage(_img, piece.startX, piece.startY, _pieceWidth, _pieceHeight, xPos, yPos, _pieceWidth, _pieceHeight);
                    _stage.strokeRect(xPos, yPos, _pieceWidth, _pieceHeight);
                    xPos += _pieceWidth;
                    if (xPos >= _puzzleWidth) {
                        xPos = 0;
                        yPos += _pieceHeight;
                    }
                }
                _canvas.onmousedown = playField.onPuzzleClick;
            }
        });

        Object.defineProperty(playfield, 'onPuzzleClick', {
            value: function (e) {
                if (e.layerX || e.layerX == 0) {
                    _mouse.x = e.layerX - _canvas.offsetLeft;
                    _mouse.y = e.layerY - _canvas.offsetTop;
                }
                else if (e.offsetX || e.offsetX == 0) {
                    _mouse.x = e.offsetX - _canvas.offsetLeft;
                    _mouse.y = e.offsetY - _canvas.offsetTop;
                }
                _currentPiece = playField.checkPieceClicked();
                if (_currentPiece != null) {
                    _stage.clearRect(_currentPiece.currentX, _currentPiece.currentY, _pieceWidth, _pieceHeight);
                    _stage.save();
                    _stage.globalAlpha = .9;
                    _stage.drawImage(_img, _currentPiece.startX, _currentPiece.startY, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
                    _stage.restore();
                    _canvas.onmousemove = playField.updatePuzzle;
                    _canvas.onmouseup = playField.pieceDropped;
                }
            }
        });

        Object.defineProperty(playfield, 'checkPieceClicked', {
            value: function () {
                var i,
                    len,
                    piece;

                for (i = 0, len = _pieces.length; i < len; i += 1) {
                    piece = _pieces[i];
                    if (_mouse.x < piece.currentX || _mouse.x > (piece.currentX + _pieceWidth) || _mouse.y < piece.currentY || _mouse.y > (piece.currentY + _pieceHeight)) {
                        //PIECE NOT HIT
                    }
                    else {
                        return piece;
                    }
                }
                return null;
            }
        });

        Object.defineProperty(playfield, 'updatePuzzle', {
            value: function (e) {
                var i,
                    len,
                    piece;

                _currentDropPiece = null;

                if (e.layerX || e.layerX == 0) {
                    _mouse.x = e.layerX - _canvas.offsetLeft;
                    _mouse.y = e.layerY - _canvas.offsetTop;
                } else if (e.offsetX || e.offsetX == 0) {
                    _mouse.x = e.offsetX - _canvas.offsetLeft;
                    _mouse.y = e.offsetY - _canvas.offsetTop;
                }

                _stage.clearRect(0, 0, _puzzleWidth, _puzzleHeight);

                for (i = 0, len = _pieces.length; i < len; i += 1) {
                    piece = _pieces[i];
                    if (piece == _currentPiece) {
                        continue;
                    }
                    _stage.drawImage(_img, piece.startX, piece.startY, _pieceWidth, _pieceHeight, piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    _stage.strokeRect(piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    if (_currentDropPiece == null) {
                        if (_mouse.x < piece.currentX || _mouse.x > (piece.currentX + _pieceWidth) || _mouse.y < piece.currentY || _mouse.y > (piece.currentY + _pieceHeight)) {
                            //NOT OVER
                        }
                        else {
                            _currentDropPiece = piece;
                            _stage.save();
                            _stage.globalAlpha = .4;
                            _stage.fillStyle = PUZZLE_HOVER_TINT;
                            _stage.fillRect(_currentDropPiece.currentX, _currentDropPiece.currentY, _pieceWidth, _pieceHeight);
                            _stage.restore();
                        }
                    }
                }

                _stage.save();
                _stage.globalAlpha = .6;
                _stage.drawImage(_img, _currentPiece.startX, _currentPiece.startY, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
                _stage.restore();
                _stage.strokeRect(_mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
            }
        });

        Object.defineProperty(playfield, 'pieceDropped', {
            value: function (e) {
                var tmp;

                _canvas.onmousemove = null;
                _canvas.onmouseup = null;
                if (_currentDropPiece != null) {
                    tmp = { xPos: _currentPiece.currentX, yPos: _currentPiece.currentY };
                    _currentPiece.currentX = _currentDropPiece.currentX;
                    _currentPiece.currentY = _currentDropPiece.currentY;
                    _currentDropPiece.currentX = tmp.xPos;
                    _currentDropPiece.currentY = tmp.yPos;
                }
                playField.resetPuzzleAndCheckWin();
            }
        });

        Object.defineProperty(playfield, 'resetPuzzleAndCheckWin', {
            value: function () {
                var i,
                    len,
                    piece,
                    gameWin = true;

                _stage.clearRect(0, 0, _puzzleWidth, _puzzleHeight);

                for (i = 0, len = _pieces.length; i < len; i += 1) {
                    piece = _pieces[i];
                    _stage.drawImage(_img, piece.startX, piece.startY, _pieceWidth, _pieceHeight, piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    _stage.strokeRect(piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    if (piece.currentX != piece.startX || piece.currentY != piece.startY) {
                        gameWin = false;
                    }
                }
                if (gameWin) {
                    setTimeout(playField.gameOver, 500);
                }
            }
        });

        Object.defineProperty(playfield, 'gameOver', {
            value: function () {
                _canvas.onmousedown = null;
                _canvas.onmousemove = null;
                _canvas.onmouseup = null;
                playField.initPuzzle();
            }
        });

        Object.defineProperty(playfield, 'shuffleArray', {
            value: function (o) {
                var j,
                    x,
                    i;

                for (j, x, i = o.length - 1; i > 0; i -= 1) {
                    j = parseInt(Math.random() * i);
                    x = o[i];
                    o[i] = o[j];
                    o[j] = x;
                }
                return o;
            }
        });

        return playfield;
    }());

    return playField;
}());

function createPlayField(imageSrc, difficulty) {
    var plr = Object.create(playField).init(imageSrc, difficulty);
}<commit_msg>Added functionality to resize uploaded image if it's larger than the size of the canvas<commit_after>var mainCanvas = document.getElementById('canvas');
const MAX_CANVAS_WIDTH = mainCanvas.width;
const MAX_CANVAS_HEIGHT = mainCanvas.height;

var playField = (function () {

    const PUZZLE_HOVER_TINT = '#009900';

    var _stage,
        _canvas,
        _img,
        _pieces,
        _puzzleWidth,
        _puzzleHeight,
        _pieceWidth,
        _pieceHeight,
        _currentPiece,
        _currentDropPiece,
        _mouse,
        _puzzle_difficulty,
        mouse,
        puzzlePiece,
        playField;

    mouse = (function () {
        var mouse = Object.create({});

        Object.defineProperty(mouse, 'init', {
            value: function (x, y) {
                this.x = x;
                this.y = y;
                return this;
            }
        });

        Object.defineProperty(mouse, 'x', {
            get: function () {
                return this._x;
            },
            set: function (value) {
                this._x = value;
            }
        });

        Object.defineProperty(mouse, 'y', {
            get: function () {
                return this._y;
            },
            set: function (value) {
                this._y = value;
            }
        });

        return mouse;
    }());

    puzzlePiece = (function () {
        var piece = Object.create({});

        Object.defineProperty(piece, 'init', {
            value: function (startX, startY) {
                this.startX = startX;
                this.startY = startY;
                this.currentX = startX;
                this.currentY = startY;
                return this;
            }
        });

        Object.defineProperty(piece, 'startX', {
            get: function () {
                return this._startX;
            },
            set: function (value) {
                this._startX = value;
            }
        });

        Object.defineProperty(piece, 'startY', {
            get: function () {
                return this._startY;
            },
            set: function (value) {
                this._startY = value;
            }
        });

        Object.defineProperty(piece, 'currentX', {
            get: function () {
                return this._currentX;
            },
            set: function (value) {
                this._currentX = value;
            }
        });

        Object.defineProperty(piece, 'currentY', {
            get: function () {
                return this._currentY;
            },
            set: function (value) {
                this._currentY = value;
            }
        });

        return piece;
    }());

    playField = (function () {
        var playfield = Object.create({});

        Object.defineProperty(playfield, 'init', {
            value: function (imageSrc, difficulty) {
                _img = new Image();
                _img.addEventListener('load', playField.onImage, false);
                _img.src = imageSrc;
                _puzzle_difficulty = difficulty;
                return this;
            }
        });

        Object.defineProperty(playfield, 'onImage', {
            value: function (e) {
                if (_img.width > MAX_CANVAS_WIDTH || _img.height > MAX_CANVAS_HEIGHT) {
                    var resizedImageSrc = resizeImage(_img);
                    _img.setAttribute('src', resizedImageSrc);
                }

                _pieceWidth = Math.floor(_img.width / _puzzle_difficulty);
                _pieceHeight = Math.floor(_img.height / _puzzle_difficulty);
                _puzzleWidth = _pieceWidth * _puzzle_difficulty;
                _puzzleHeight = _pieceHeight * _puzzle_difficulty;
                playField.setCanvas();
                playField.initPuzzle();
            }
        });

        Object.defineProperty(playfield, 'setCanvas', {
            value: function () {
                _canvas = document.getElementById('canvas');
                _stage = _canvas.getContext('2d');
                _canvas.width = _puzzleWidth;
                _canvas.height = _puzzleHeight;
                _canvas.style.border = "1px solid black";
            }
        });

        Object.defineProperty(playfield, 'initPuzzle', {
            value: function () {
                _pieces = [];
                _mouse = Object.create(mouse).init(0, 0);
                _currentPiece = null;
                _currentDropPiece = null;
                _stage.drawImage(_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight);
                playField.createTitle("Click to Start Puzzle");
                playField.buildPieces();
            }
        });

        Object.defineProperty(playfield, 'createTitle', {
            value: function (msg) {
                _stage.fillStyle = "#000000";
                _stage.globalAlpha = .4;
                _stage.fillRect(100, _puzzleHeight - 40, _puzzleWidth - 200, 40);
                _stage.fillStyle = "#FFFFFF";
                _stage.globalAlpha = 1;
                _stage.textAlign = "center";
                _stage.textBaseline = "middle";
                _stage.font = "20px Arial";
                _stage.fillText(msg, _puzzleWidth / 2, _puzzleHeight - 20);
            }
        });

        Object.defineProperty(playfield, 'buildPieces', {
            value: function () {
                var i,
                    piece,
                    puzzleDifficulty = _puzzle_difficulty * _puzzle_difficulty,
                    xPos = 0,
                    yPos = 0;

                for (i = 0; i < puzzleDifficulty; i += 1) {
                    piece = Object.create(puzzlePiece).init(xPos, yPos);
                    _pieces.push(piece);
                    xPos += _pieceWidth;
                    if (xPos >= _puzzleWidth) {
                        xPos = 0;
                        yPos += _pieceHeight;
                    }
                }
                _canvas.onmousedown = playField.shufflePuzzle;
            }
        });

        Object.defineProperty(playfield, 'shufflePuzzle', {
            value: function () {
                _pieces = playField.shuffleArray(_pieces);
                _stage.clearRect(0, 0, _puzzleWidth, _puzzleHeight);
                var i;
                var piece;
                var xPos = 0;
                var yPos = 0;
                for (i = 0; i < _pieces.length; i++) {
                    piece = _pieces[i];
                    piece.currentX = xPos;
                    piece.currentY = yPos;
                    _stage.drawImage(_img, piece.startX, piece.startY, _pieceWidth, _pieceHeight, xPos, yPos, _pieceWidth, _pieceHeight);
                    _stage.strokeRect(xPos, yPos, _pieceWidth, _pieceHeight);
                    xPos += _pieceWidth;
                    if (xPos >= _puzzleWidth) {
                        xPos = 0;
                        yPos += _pieceHeight;
                    }
                }
                _canvas.onmousedown = playField.onPuzzleClick;
            }
        });

        Object.defineProperty(playfield, 'onPuzzleClick', {
            value: function (e) {
                if (e.layerX || e.layerX == 0) {
                    _mouse.x = e.layerX - _canvas.offsetLeft;
                    _mouse.y = e.layerY - _canvas.offsetTop;
                }
                else if (e.offsetX || e.offsetX == 0) {
                    _mouse.x = e.offsetX - _canvas.offsetLeft;
                    _mouse.y = e.offsetY - _canvas.offsetTop;
                }
                _currentPiece = playField.checkPieceClicked();
                if (_currentPiece != null) {
                    _stage.clearRect(_currentPiece.currentX, _currentPiece.currentY, _pieceWidth, _pieceHeight);
                    _stage.save();
                    _stage.globalAlpha = .9;
                    _stage.drawImage(_img, _currentPiece.startX, _currentPiece.startY, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
                    _stage.restore();
                    _canvas.onmousemove = playField.updatePuzzle;
                    _canvas.onmouseup = playField.pieceDropped;
                }
            }
        });

        Object.defineProperty(playfield, 'checkPieceClicked', {
            value: function () {
                var i,
                    len,
                    piece;

                for (i = 0, len = _pieces.length; i < len; i += 1) {
                    piece = _pieces[i];
                    if (_mouse.x < piece.currentX || _mouse.x > (piece.currentX + _pieceWidth) || _mouse.y < piece.currentY || _mouse.y > (piece.currentY + _pieceHeight)) {
                        //PIECE NOT HIT
                    }
                    else {
                        return piece;
                    }
                }
                return null;
            }
        });

        Object.defineProperty(playfield, 'updatePuzzle', {
            value: function (e) {
                var i,
                    len,
                    piece;

                _currentDropPiece = null;

                if (e.layerX || e.layerX == 0) {
                    _mouse.x = e.layerX - _canvas.offsetLeft;
                    _mouse.y = e.layerY - _canvas.offsetTop;
                } else if (e.offsetX || e.offsetX == 0) {
                    _mouse.x = e.offsetX - _canvas.offsetLeft;
                    _mouse.y = e.offsetY - _canvas.offsetTop;
                }

                _stage.clearRect(0, 0, _puzzleWidth, _puzzleHeight);

                for (i = 0, len = _pieces.length; i < len; i += 1) {
                    piece = _pieces[i];
                    if (piece == _currentPiece) {
                        continue;
                    }
                    _stage.drawImage(_img, piece.startX, piece.startY, _pieceWidth, _pieceHeight, piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    _stage.strokeRect(piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    if (_currentDropPiece == null) {
                        if (_mouse.x < piece.currentX || _mouse.x > (piece.currentX + _pieceWidth) || _mouse.y < piece.currentY || _mouse.y > (piece.currentY + _pieceHeight)) {
                            //NOT OVER
                        }
                        else {
                            _currentDropPiece = piece;
                            _stage.save();
                            _stage.globalAlpha = .4;
                            _stage.fillStyle = PUZZLE_HOVER_TINT;
                            _stage.fillRect(_currentDropPiece.currentX, _currentDropPiece.currentY, _pieceWidth, _pieceHeight);
                            _stage.restore();
                        }
                    }
                }

                _stage.save();
                _stage.globalAlpha = .6;
                _stage.drawImage(_img, _currentPiece.startX, _currentPiece.startY, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
                _stage.restore();
                _stage.strokeRect(_mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
            }
        });

        Object.defineProperty(playfield, 'pieceDropped', {
            value: function (e) {
                var tmp;

                _canvas.onmousemove = null;
                _canvas.onmouseup = null;
                if (_currentDropPiece != null) {
                    tmp = { xPos: _currentPiece.currentX, yPos: _currentPiece.currentY };
                    _currentPiece.currentX = _currentDropPiece.currentX;
                    _currentPiece.currentY = _currentDropPiece.currentY;
                    _currentDropPiece.currentX = tmp.xPos;
                    _currentDropPiece.currentY = tmp.yPos;
                }
                playField.resetPuzzleAndCheckWin();
            }
        });

        Object.defineProperty(playfield, 'resetPuzzleAndCheckWin', {
            value: function () {
                var i,
                    len,
                    piece,
                    gameWin = true;

                _stage.clearRect(0, 0, _puzzleWidth, _puzzleHeight);

                for (i = 0, len = _pieces.length; i < len; i += 1) {
                    piece = _pieces[i];
                    _stage.drawImage(_img, piece.startX, piece.startY, _pieceWidth, _pieceHeight, piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    _stage.strokeRect(piece.currentX, piece.currentY, _pieceWidth, _pieceHeight);
                    if (piece.currentX != piece.startX || piece.currentY != piece.startY) {
                        gameWin = false;
                    }
                }
                if (gameWin) {
                    setTimeout(playField.gameOver, 500);
                }
            }
        });

        Object.defineProperty(playfield, 'gameOver', {
            value: function () {
                _canvas.onmousedown = null;
                _canvas.onmousemove = null;
                _canvas.onmouseup = null;
                playField.initPuzzle();
            }
        });

        Object.defineProperty(playfield, 'shuffleArray', {
            value: function (o) {
                var j,
                    x,
                    i;

                for (j, x, i = o.length - 1; i > 0; i -= 1) {
                    j = parseInt(Math.random() * i);
                    x = o[i];
                    o[i] = o[j];
                    o[j] = x;
                }
                return o;
            }
        });

        return playfield;
    }());

    return playField;
}());

function createPlayField(imageSrc, difficulty) {
    var plr = Object.create(playField).init(imageSrc, difficulty);
}

function resizeImage(img) {
    // Create off-screen canvas for resizing purposes
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

    var width = img.width;
    var height = img.height;

    // Scale image
    if (width > height) {
      if (width > MAX_CANVAS_WIDTH) {
        height *= MAX_CANVAS_WIDTH / width;
        width = MAX_CANVAS_WIDTH;
      }
    } else {
      if (height > MAX_CANVAS_HEIGHT) {
        width *= MAX_CANVAS_HEIGHT / height;
        height = MAX_CANVAS_HEIGHT;
      }
    }

    // Set dimension to target size
    canvas.width = width;
    canvas.height = height;

    // Draw source image into the off-screen canvas:
    ctx.drawImage(img, 0, 0, width, height);

    // Encode image to Base64
    var newImage = canvas.toDataURL("image/png");
    return newImage;
}<|endoftext|>


<commit_before>import * as ActionCreators from './auth';
import initialState from '../reducers/initialState';

import { expect } from 'chai';

describe('actions.auth', () => {
  const appState = initialState;

  it('should create an action to login', () => {
    const actual = ActionCreators.login(appState);
    const expected = {
      type: 'LOGIN'
    };

    expect(actual).to.deep.equal(expected); // Notice use of deep because it's a nested object
    // expect(actual).to.equal(expected); // Fails. Not deeply equal
  });
});
<commit_msg>no need for appState<commit_after>import * as ActionCreators from './auth';

import { expect } from 'chai';

describe('actions.auth', () => {

  it('should create an action to login', () => {
    const actual = ActionCreators.login();
    const expected = {
      type: 'LOGIN'
    };

    expect(actual).to.deep.equal(expected); // Notice use of deep because it's a nested object
    // expect(actual).to.equal(expected); // Fails. Not deeply equal
  });
});
<|endoftext|>


<commit_before>// extracted from https://github.com/developit/propTypes README
function validateProps(props, propTypes) {
  for (const prop in propTypes) {
    if (propTypes.hasOwnProperty(prop)) {
      const err = propTypes[prop](props, prop, 'name', 'prop');
      if (err) {
        console.warn(err);
        return false;
      }
    }
  }
  return true;
}

function getWebmiddleAncestors(webmiddle) {
  const ancestors = [];

  let currentWebmiddle = webmiddle;
  while (currentWebmiddle.parent) {
    currentWebmiddle = currentWebmiddle.parent;
    ancestors.push(currentWebmiddle);
  }

  return ancestors;
}

function getTopWebmiddle(webmiddle) {
  const ancestors = getWebmiddleAncestors(webmiddle);
  return (ancestors.length > 0) ? ancestors[ancestors.length - 1] : webmiddle;
}

// Two webmiddles are related if they are the same
// or if one is ancestor of the other
function areWebmiddlesRelated(first, second) {
  const firstAncestors = getWebmiddleAncestors(first);
  const secondAncestors = getWebmiddleAncestors(second);
  return (first === second) ||
         (firstAncestors.indexOf(second) !== -1 || secondAncestors.indexOf(first) !== -1);
}

// Call the service multiple times based on the "retries" prop.
async function callService(service, props) {
  try {
    const result = await service(props);
    return result;
  } catch (err) {
    const retries = props.options.retries || 0;
    if (retries === 0) { // < 0 for infinite retries
      throw err;
    }
    console.error((err instanceof Error) ? err.stack : err);
    console.log('Retries left:', (retries < 0) ? '(infinity)' : retries);
    return callService(service, {
      ...props,
      options: {
        ...props.options,
        retries: (retries < 0) ? retries : (retries - 1),
      },
    });
  }
}

export default async function callVirtual(virtual, options = {}) {
  const service = virtual.type;

  if (typeof service !== 'function') {
    return { result: virtual, webmiddle: this, linkedWebmiddle: null };
  }

  const webmiddle = service.webmiddle || this;

  const linkedWebmiddle = areWebmiddlesRelated(this, webmiddle) ? null : getTopWebmiddle(webmiddle);
  if (linkedWebmiddle) {
    // link (set temp parent)
    linkedWebmiddle.parent = this;
  }

  const props = {
    ...virtual.attributes,
    children: virtual.children,
    webmiddle,
    options,
  };
  // options prop
  const serviceOptions = (typeof service.options === 'function') ?
    service.options(props) : service.options;
  props.options = {
    ...options,
    ...(serviceOptions || {}),
  };

  if (service.propTypes) {
    validateProps(virtual.attributes, service.propTypes);
  }

  const result = await callService(service, props);

  return { result, webmiddle, linkedWebmiddle };
};
<commit_msg>webmiddle: fix validateProps message<commit_after>// extracted from https://github.com/developit/propTypes README
function validateProps(props, propTypes, service) {
  for (const prop in propTypes) {
    if (propTypes.hasOwnProperty(prop)) {
      const err = propTypes[prop](props, prop, service, 'prop');
      if (err) {
        console.warn(err);
        return false;
      }
    }
  }
  return true;
}

function getWebmiddleAncestors(webmiddle) {
  const ancestors = [];

  let currentWebmiddle = webmiddle;
  while (currentWebmiddle.parent) {
    currentWebmiddle = currentWebmiddle.parent;
    ancestors.push(currentWebmiddle);
  }

  return ancestors;
}

function getTopWebmiddle(webmiddle) {
  const ancestors = getWebmiddleAncestors(webmiddle);
  return (ancestors.length > 0) ? ancestors[ancestors.length - 1] : webmiddle;
}

// Two webmiddles are related if they are the same
// or if one is ancestor of the other
function areWebmiddlesRelated(first, second) {
  const firstAncestors = getWebmiddleAncestors(first);
  const secondAncestors = getWebmiddleAncestors(second);
  return (first === second) ||
         (firstAncestors.indexOf(second) !== -1 || secondAncestors.indexOf(first) !== -1);
}

// Call the service multiple times based on the "retries" prop.
async function callService(service, props) {
  try {
    const result = await service(props);
    return result;
  } catch (err) {
    const retries = props.options.retries || 0;
    if (retries === 0) { // < 0 for infinite retries
      throw err;
    }
    console.error((err instanceof Error) ? err.stack : err);
    console.log('Retries left:', (retries < 0) ? '(infinity)' : retries);
    return callService(service, {
      ...props,
      options: {
        ...props.options,
        retries: (retries < 0) ? retries : (retries - 1),
      },
    });
  }
}

export default async function callVirtual(virtual, options = {}) {
  const service = virtual.type;

  if (typeof service !== 'function') {
    return { result: virtual, webmiddle: this, linkedWebmiddle: null };
  }

  const webmiddle = service.webmiddle || this;

  const linkedWebmiddle = areWebmiddlesRelated(this, webmiddle) ? null : getTopWebmiddle(webmiddle);
  if (linkedWebmiddle) {
    // link (set temp parent)
    linkedWebmiddle.parent = this;
  }

  const props = {
    ...virtual.attributes,
    children: virtual.children,
    webmiddle,
    options,
  };
  // options prop
  const serviceOptions = (typeof service.options === 'function') ?
    service.options(props) : service.options;
  props.options = {
    ...options,
    ...(serviceOptions || {}),
  };

  if (service.propTypes) {
    validateProps(virtual.attributes, service.propTypes, service);
  }

  const result = await callService(service, props);

  return { result, webmiddle, linkedWebmiddle };
};
<|endoftext|>


<commit_before>/* global API_WS */
import WebSocket from 'reconnecting-websocket';

import history from '../history';
import { setStream } from '.';

let socket;
export let emit; // eslint-disable-line one-var

// the types of payloads we can expect from the server
export const actions = [
  'RUSTLERS_SET',
  'STREAM_SET',
  'STREAMS_SET',
  'STREAM_GET',
  'STREAM_BANNED',
].reduce((acc, curr) => {
  acc[curr] = Symbol(curr);
  return acc;
}, {});

// thunks for these payloads
const thunks = {
  RUSTLERS_SET: payload => (dispatch, getState) => {
    const state = getState();
    const [ id ] = payload;
    if (!state.streams[id]) {
      emit('getStream', id);
    }
    else {
      dispatch({
        type: actions.RUSTLERS_SET,
        payload,
      });
    }
  },
  STREAM_BANNED: () => (dispatch) => {
    history.push('/beand');
    dispatch({
      type: actions.STREAM_BANNED,
      payload: null,
    });
  },
};

export const init = store => {
  socket = new WebSocket(API_WS || `ws://${location.host}`);
  let messageQueue = [];
  let wasReconnect = false;
  emit = (...args) => {
    if (socket.readyState !== 1) {
      messageQueue.push(args);
    }
    else {
      socket.send(JSON.stringify(args));
    }
  };

  const ping = () => socket.send('');
  let pingInterval;

  socket.onopen = function onopen(event) {
    pingInterval = setInterval(ping, 20000);
    messageQueue.forEach(args => emit(...args));
    messageQueue = [];
    if (wasReconnect) {
      // resend setStream on reconnect if we're watching one
      const state = store.getState();
      const stream = state.streams[state.stream];
      if (stream) {
        if (stream.overrustle_id) {
          store.dispatch(setStream(stream.overrustle_id));
        }
        else {
          store.dispatch(setStream(stream.channel, stream.service));
        }
      }
    }
    wasReconnect = true;
  };

  socket.onclose = function onclose(event) {
    clearInterval(pingInterval);
  };

  socket.onmessage = function onmessage(event) {
    // eslint-disable-next-line no-console
    console.log('socket message', event);

    const { data } = event;
    try {
      const [ ws_action, ...args ] = JSON.parse(data);
      const action = actions[ws_action];
      // make sure we know what to do with this action
      if (!action) {
        throw new TypeError(`Invalid action "${ws_action}"`);
      }
      // call any 'hook' thunks if they exist
      if (thunks[ws_action]) {
        store.dispatch(thunks[ws_action](args));
      }
      // just dispatch the action if no hooks exist
      else {
        store.dispatch({
          type: action,
          payload: args,
        });
      }
    }
    catch (err) {
      console.error(`Failed to handle incoming websocket action\n${data}\n`, err);
    }
  };
};

// expose this for testing
window.__emit__ = emit;
<commit_msg>disable client-side ws logging in production<commit_after>/* global API_WS process */
import WebSocket from 'reconnecting-websocket';

import history from '../history';
import { setStream } from '.';

let socket;
export let emit; // eslint-disable-line one-var

// the types of payloads we can expect from the server
export const actions = [
  'RUSTLERS_SET',
  'STREAM_SET',
  'STREAMS_SET',
  'STREAM_GET',
  'STREAM_BANNED',
].reduce((acc, curr) => {
  acc[curr] = Symbol(curr);
  return acc;
}, {});

// thunks for these payloads
const thunks = {
  RUSTLERS_SET: payload => (dispatch, getState) => {
    const state = getState();
    const [ id ] = payload;
    if (!state.streams[id]) {
      emit('getStream', id);
    }
    else {
      dispatch({
        type: actions.RUSTLERS_SET,
        payload,
      });
    }
  },
  STREAM_BANNED: () => (dispatch) => {
    history.push('/beand');
    dispatch({
      type: actions.STREAM_BANNED,
      payload: null,
    });
  },
};

export const init = store => {
  socket = new WebSocket(API_WS || `ws://${location.host}`);
  let messageQueue = [];
  let wasReconnect = false;
  emit = (...args) => {
    if (socket.readyState !== 1) {
      messageQueue.push(args);
    }
    else {
      socket.send(JSON.stringify(args));
    }
  };

  const ping = () => socket.send('');
  let pingInterval;

  socket.onopen = function onopen(event) {
    pingInterval = setInterval(ping, 20000);
    messageQueue.forEach(args => emit(...args));
    messageQueue = [];
    if (wasReconnect) {
      // resend setStream on reconnect if we're watching one
      const state = store.getState();
      const stream = state.streams[state.stream];
      if (stream) {
        if (stream.overrustle_id) {
          store.dispatch(setStream(stream.overrustle_id));
        }
        else {
          store.dispatch(setStream(stream.channel, stream.service));
        }
      }
    }
    wasReconnect = true;
  };

  socket.onclose = function onclose(event) {
    clearInterval(pingInterval);
  };

  socket.onmessage = function onmessage(event) {
    if (process.env.NODE_ENV !== 'production') {
      // eslint-disable-next-line no-console
      console.log('socket message', event);
    }

    const { data } = event;
    try {
      const [ ws_action, ...args ] = JSON.parse(data);
      const action = actions[ws_action];
      // make sure we know what to do with this action
      if (!action) {
        throw new TypeError(`Invalid action "${ws_action}"`);
      }
      // call any 'hook' thunks if they exist
      if (thunks[ws_action]) {
        store.dispatch(thunks[ws_action](args));
      }
      // just dispatch the action if no hooks exist
      else {
        store.dispatch({
          type: action,
          payload: args,
        });
      }
    }
    catch (err) {
      console.error(`Failed to handle incoming websocket action\n${data}\n`, err);
    }
  };
};

// expose this for testing
window.__emit__ = emit;
<|endoftext|>


<commit_before>(function (Socket) {
    var _socket = io.connect('http://' + location.host, {
            transports: ['websocket'],
            reconnectionDelay: 0,
            timeout: 500
            });

    var _roomId;
    var _user;

    _socket.on('connect', function () {
        console.log('Connected');
        Socket.emit('join', user, location.hash);
    });

    _socket.on('join', function (room_id) {
        console.log('Joined: ' + room_id);
        _roomId = room_id;
    });

    _socket.on('user', function (user) {
        _user = user;
    });

    ///
    Socket.on = function () {
        _socket.on.apply(_socket, arguments);
    };

    ///
    Socket.emit = function () {
        _socket.emit.apply(_socket, arguments);
    };

    ///
    Socket.reconnect = function () {
        _socket.emit('join', user, location.hash);
    };
})(this.Socket || (this.Socket = {}));
<commit_msg>Fix reconnectDelay<commit_after>(function (Socket) {
    var _socket = io.connect('http://' + location.host, {
            transports: ['websocket'],
            reconnectionDelay: 0,
            timeout: 1000
            });

    var _roomId;
    var _user;

    _socket.on('connect', function () {
        console.log('Connected');
        Socket.emit('join', user, location.hash);
    });

    _socket.on('join', function (room_id) {
        console.log('Joined: ' + room_id);
        _roomId = room_id;
    });

    _socket.on('user', function (user) {
        _user = user;
    });

    ///
    Socket.on = function () {
        _socket.on.apply(_socket, arguments);
    };

    ///
    Socket.emit = function () {
        _socket.emit.apply(_socket, arguments);
    };

    ///
    Socket.reconnect = function () {
        _socket.emit('join', user, location.hash);
    };
})(this.Socket || (this.Socket = {}));
<|endoftext|>


<commit_before>// Hackish for now.

var Fact = require('./fact.js');
var Engine = require('./engine.js');
var state;
var stateHash;
var STATE_KEY = "lastState-v11";
var SIZE_MULTIPLIER = 4;
// ==== Stubs for node.js usage ====
if (typeof document == 'undefined') {
	function Node() {};
	Node.prototype = {
		style: {},
		appendChild: function(){},
		removeChild: function(){},
	};

	document = {
		createElement:function() {return new Node();},
		getElementById:function() {return new Node();},
	};

	window = {
		addEventListener: function(){},
	};

	history = {
		pushState: function(){},
	}
}

if (typeof localStorage === "undefined" || localStorage === null) {
  var LocalStorage = require('node-localstorage').LocalStorage;
  localStorage = new LocalStorage('./scratch');
}

// ==== END stubs ====

function removeClass(node, className) {
    while (node.className.match(className)) {
        node.className = node.className.replace(className,'');
    }
}

function newVarNamer() {
    var names = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'];
    var map = {};
    return function(obj) {
        if (!map[obj]) {
            map[obj] = names.shift();
        }
        return map[obj];
    };
}

function makeTree(doc, fact, exp, path, inputTot, varNamer, spanMap, cb) {
    var termSpan;
    spanMap[path] = termSpan;
    var width = 0;
    var height = 0;

    if (Array.isArray(exp)) {
		termSpan = doc.createElement("span");
        var termName = fact.Skin.TermNames[exp[0]];
		if (!termName) throw new Error("Bad term " + exp);
        var arity = exp.length - 1;
        var children = [];
        for (var i = 1; i <= arity; i++) {
            path.push(i);
            children.push(makeTree(doc, fact, exp[i], path, arity, varNamer,
								   spanMap, cb));
            path.pop();
        }
        switch (arity) {
        case 2:
            var rowSpan = doc.createElement("span");
            path.push("r");
            spanMap[path] = rowSpan;
            path.pop();
            termSpan.appendChild(rowSpan);
            rowSpan.className += " hyprow";
            var opSpan = doc.createElement("a");
            path.push("0");
            spanMap[path] = opSpan;
			//opSpan.href = "#" + tag + "=" + path;
			opSpan.onclick = cb(path);
            path.pop();
            rowSpan.appendChild(children[0].span);
            rowSpan.appendChild(opSpan);
            opSpan.className += " operator";
            var txtSpan = doc.createElement("span");
            opSpan.appendChild(txtSpan);
            opSpan.className += " txtBox";
            txtSpan.innerHTML = termName;
            txtSpan.className = " txt";
            width = children[0].width + children[1].width;
            height = children[0].height + children[1].height;
            var opWidth = children[1].width;
            var opHeight = children[0].height;
            opSpan.style.height = "100%";
            children[0].span.style.height = "100%";
            rowSpan.style.height = "" + (100 * children[0].height / height) + "%";
            children[1].span.style.height = "" + (100 * children[1].height / height) + "%";

            rowSpan.style.width = "100%";
            children[0].span.style.width = "" + (100 * children[0].width / width) + "%";
            opSpan.style.width =  "" + (100 * children[1].width / width) + "%";
            children[1].span.style.width = opSpan.style.width;
            termSpan.appendChild(children[1].span);
            break;
        default:
            console.log("TODO: XXX Only arity 2 supported:" + termName);
            throw new Error("TODO: XXX Only arity 2 supported: " + termName);
        }
    } else {
		termSpan = doc.createElement("a");
		//termSpan.href = "#" + tag + "=" + path;
		termSpan.onclick = cb(path);
        termSpan.className += " variable";
        termSpan.className += " var" + varNamer(exp);
        width = 1;
        height = 1;
        var txtSpan = doc.createElement("span");
        txtSpan.className = " txt";
        txtSpan.style.width="100%";
        txtSpan.style.height="100%";
        termSpan.appendChild(txtSpan);
        termSpan.className += " txtBox";
        var innerHTML = varNamer(exp);
        var whichChild = path[path.length - 1];
        for (var i = path.length  - 1; (i >= 0) && path[i] == whichChild; i--) {
            if (whichChild == 1) {
                innerHTML = innerHTML + ")";
            } else if (whichChild == 0) {
                innerHTML = "(" + innerHTML;
            }
        }
        txtSpan.innerHTML = innerHTML;
    }
    termSpan.className += " term";
    termSpan.className += " depth" + path.length;
    if (path.length > 0) {
        var inputNum = path[path.length - 1];
        termSpan.className += " input" + inputNum + "of" + inputTot;
    }
    return ({span:termSpan, width:width, height:height});
}

function makeThmBox(fact, exp, cb) {
    var termBox = document.createElement("span");
    termBox.className += " termbox";
    var spanMap = {};
    var tree = makeTree(document, fact, exp, [], -1, newVarNamer(), spanMap,
						cb);
    termBox.appendChild(tree.span);
    tree.span.style.width = "100%";
    tree.span.style.height = "100%";
    termBox.style.width = "" + (2 * tree.width) + "em";
    termBox.style.height ="" + (2 * tree.height) + "em";
    termBox.spanMap = spanMap;
    termBox.tree = tree;
    return termBox;
}

function size(thmBox, ems) {
    thmBox.style.width = ems + "em";
    thmBox.style.height = ems + "em";
    thmBox.tree.span.style["font-size"] = "" + (50 * ems / thmBox.tree.width) + "%";
}

function addToShooter(factData) {
	var fact = Engine.canonicalize(new Fact(factData));
	localStorage.setItem(fact.Skin.Name, JSON.stringify(fact));
	Engine.onAddFact(fact);
	if (fact.Core[Fact.CORE_HYPS].length == 0) {
		var box;
		var factOnclickMaker = function(path) {
			var factPath = path.slice();
			if (factPath[factPath.length-1] == 0) {
				factPath.pop();
			}
			return function() {
				try {
					state.url = "#f=" + path + ";" + fact.Skin.Name;
					if (state.workPath != null) {
						console.log("calling applyFact: " +
									JSON.stringify(state.work) + "\n" +
									JSON.stringify(state.workPath) + "\n" +
									JSON.stringify(fact) + "\n" +
									JSON.stringify(factPath) + "\n");
						setWork(Engine.applyFact(state.work,
												 state.workPath,
												 fact, factPath));
						message("");
						delete state.workPath;
						state.url = "";
					} else if (factPath.length==0) {
						console.log("calling ground: " +
									JSON.stringify(state.work) + "\n" +
									JSON.stringify(fact) + "\n");
						var thm = Engine.ground(state.work, fact);
						var newFact = addToShooter(thm);
						currentLand().thms.push(newFact.Skin.Name);
						message("");
						nextGoal();
					} else {
						console.log("wtf? " + JSON.stringify(factPath));
					}
				} catch (e) {
					console.log("Error in applyFact: " + e);
					console.log(e.stack);
					message(e);
				}
				redraw();
			};
		};
		box = makeThmBox(fact, fact.Core[Fact.CORE_STMT], factOnclickMaker);
		size(box, 2 * SIZE_MULTIPLIER);
		document.getElementById("shooterTape").appendChild(box);
	} // TODO: handle axioms with hyps
	return fact;
}

function workOnclickMaker(path) {
	var goalPath = path.slice();
	if (goalPath[goalPath.length-1] == 0) {
		goalPath.pop();
	}
	return function() {
		state.workPath = goalPath;
		state.url = "#g=" + goalPath;
		save();
	}
}

function startWork(fact) {
    var work = new Fact(fact);
    work.setHyps([work.Core[Fact.CORE_STMT]]);
    work.Skin.HypNames = ["Hyps.0"];
    if (!work.Tree.Cmd) {
        work.setCmd("thm");
    }
    work.setProof(["Hyps.0"]);
    return Engine.canonicalize(work);
}

function setWork(work) {
	state.work = work;
	state.workHash = Engine.fingerprint(work);
	save();
}

function save() {
	var hash = Engine.fingerprint(state);
	if (hash != stateHash) {
		localStorage.setItem(hash, JSON.stringify(state));
		localStorage.setItem(STATE_KEY, hash);
		localStorage.setItem("parentOf-" + hash, stateHash);
		localStorage.setItem("childOf-" + stateHash, hash);
		console.log("XXXX Setting " + "childOf-" + stateHash + " = " + hash);
		stateHash = hash;
		history.pushState(state, "state", "#s=" + hash + state.url);
	}
}

function currentLand() {
	return state.lands[state.lands.length-1];
}
function nextGoal() {
	var land = currentLand();
	var goal = land.goals.shift();
	if (!goal) {
		var nextLand = landDepMap[land.name]; // XXX
		if (nextLand) {
			enterLand(nextLand);
			goal = nextGoal();
		} else {
			message("No more lands! You win! Now go write a land.");
		}
	}
	state.work = startWork(goal);
	save();
}

function redraw() {
	var well = document.getElementById("well");
	well.removeChild(well.firstChild);
	console.log("Redrawing: " + JSON.stringify(state.work));
	var box = makeThmBox(state.work,
						 state.work.Core[Fact.CORE_HYPS][0],
						 workOnclickMaker);
	size(box, box.tree.width * SIZE_MULTIPLIER);
	well.appendChild(box);
}

function loadState(flat) {
	state = flat;
	state.work = new Fact(state.work);
}

function enterLand(landData) {
	var land = {
		name:landData.name,
		thms:[],             // hash values
		goals:[],            // structs
	};
	state.lands.push(land);
	land.goals = landData.goals.slice();
	landData.axioms.forEach(function(data) {
		var fact = addToShooter(data);
		land.thms.push(fact.Skin.Name);
	});
	currentLand().thms.push.apply(currentLand(), landData.axioms);
}

function message(msg) {
	console.log("Tacro: " + msg);
	document.getElementById("message").innerText = msg;
}

var allLands = require('./all_lands.js');
var landMap = {};
var landDepMap = {}; // XXX
allLands.forEach(function(land) {
	landMap[land.name] = land;
	landDepMap[land.depends[0]] = land;
});

window.addEventListener('popstate', function(ev) {
	console.log("popstate to " + ev.state);
	if (ev.state) {
		loadState(ev.state);
		save();
		redraw();
	}
});
document.getElementById("rewind").onclick = function() {
	var parentHash = localStorage.getItem("parentOf-" + stateHash);
	console.log("XXXX Rewinding from " + stateHash + "  to " + parentHash);
	if (parentHash) {
		loadState(JSON.parse(localStorage.getItem(parentHash)));
		stateHash = parentHash;
		redraw();
		// Don't save() or we'll get stuck in a loop
		document.getElementById("forward").style.visibility="visible";
	}
	return false;
};
document.getElementById("forward").onclick = function() {
	var childHash = localStorage.getItem("childOf-" + stateHash);
	console.log("XXXX Forwarding from " + stateHash + " to " + childHash);
	if (childHash) {
		loadState(JSON.parse(localStorage.getItem(childHash)));
		stateHash = childHash;
		redraw();
		// Don't save() or we'll get stuck in a loop
	} else {
		document.getElementById("forward").style.visibility="hidden";
	}
	return false;
}
var stateHash = localStorage.getItem(STATE_KEY);
if (stateHash) {
	loadState(JSON.parse(localStorage.getItem(stateHash)));
	state.lands.forEach(function(land) {
		console.log("Processing land " + land.name + " #" + land.thms.length);
		land.thms.forEach(function(thmName) {
			var factData = JSON.parse(localStorage.getItem(thmName));
			console.log("adding " + thmName + "=" + JSON.stringify(factData));
			var fact = addToShooter(factData);

		})
	});
} else {
	state = {
		lands: [],
		url:"",
	};
	var firstLand = landDepMap[undefined]; // XXX
	enterLand(firstLand);
	nextGoal();
	state.url = "";
}

save();
redraw();
<commit_msg>Untabify. Fix transition to land_not<commit_after>// Hackish for now.

var Fact = require('./fact.js');
var Engine = require('./engine.js');
var state;
var stateHash;
var STATE_KEY = "lastState-v11";
var SIZE_MULTIPLIER = 4;
// ==== Stubs for node.js usage ====
if (typeof document == 'undefined') {
    function Node() {};
    Node.prototype = {
        style: {},
        appendChild: function(){},
        removeChild: function(){},
    };

    document = {
        createElement:function() {return new Node();},
        getElementById:function() {return new Node();},
    };

    window = {
        addEventListener: function(){},
    };

    history = {
        pushState: function(){},
    }
}

if (typeof localStorage === "undefined" || localStorage === null) {
  var LocalStorage = require('node-localstorage').LocalStorage;
  localStorage = new LocalStorage('./scratch');
}

// ==== END stubs ====

function removeClass(node, className) {
    while (node.className.match(className)) {
        node.className = node.className.replace(className,'');
    }
}

function newVarNamer() {
    var names = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'];
    var map = {};
    return function(obj) {
        if (!map[obj]) {
            map[obj] = names.shift();
        }
        return map[obj];
    };
}

function makeTree(doc, fact, exp, path, inputTot, varNamer, spanMap, cb) {
    var termSpan;
    spanMap[path] = termSpan;
    var width = 0;
    var height = 0;

    if (Array.isArray(exp)) {
        termSpan = doc.createElement("span");
        var termName = fact.Skin.TermNames[exp[0]];
        if (!termName) throw new Error("Bad term " + exp);
        var arity = exp.length - 1;
        var children = [];
        for (var i = 1; i <= arity; i++) {
            path.push(i);
            children.push(makeTree(doc, fact, exp[i], path, arity, varNamer,
                                   spanMap, cb));
            path.pop();
        }
        switch (arity) {
        case 2:
            var rowSpan = doc.createElement("span");
            path.push("r");
            spanMap[path] = rowSpan;
            path.pop();
            termSpan.appendChild(rowSpan);
            rowSpan.className += " hyprow";
            var opSpan = doc.createElement("a");
            path.push("0");
            spanMap[path] = opSpan;
            //opSpan.href = "#" + tag + "=" + path;
            opSpan.onclick = cb(path);
            path.pop();
            rowSpan.appendChild(children[0].span);
            rowSpan.appendChild(opSpan);
            opSpan.className += " operator";
            var txtSpan = doc.createElement("span");
            opSpan.appendChild(txtSpan);
            opSpan.className += " txtBox";
            txtSpan.innerHTML = termName;
            txtSpan.className = " txt";
            width = children[0].width + children[1].width;
            height = children[0].height + children[1].height;
            opSpan.style.height = "100%";
            children[0].span.style.height = "100%";
            rowSpan.style.height = "" + (100 * children[0].height / height) + "%";
            children[1].span.style.height = "" + (100 * children[1].height / height) + "%";

            rowSpan.style.width = "100%";
            children[0].span.style.width = "" + (100 * children[0].width / width) + "%";
            opSpan.style.width =  "" + (100 * children[1].width / width) + "%";
            children[1].span.style.width = opSpan.style.width;
            termSpan.appendChild(children[1].span);
            break;
        case 1:
            var opSpan = doc.createElement("a");
            path.push("0");
            spanMap[path] = opSpan;
            //opSpan.href = "#" + tag + "=" + path;
            opSpan.onclick = cb(path);
            path.pop();
            termSpan.appendChild(opSpan);
            opSpan.className += " operator";
            var txtSpan = doc.createElement("span");
            opSpan.appendChild(txtSpan);
            opSpan.className += " txtBox";
            txtSpan.innerHTML = termName;
            txtSpan.className = " txt";
            width = 1 + children[0].width;
            height = 1 + children[0].height;
            opSpan.style.height = "100%";
            opSpan.style.width = "100%";
            children[0].span.style.height = "" + (100 * children[0].height / height) + "%";
            children[0].span.style.width = "" + (100 * children[0].width / width) + "%";

            termSpan.appendChild(children[0].span);
            break;
        default:
            console.log("TODO: XXX Only arity 1-2 supported:"+termName);
            throw new Error("TODO: XXX Only arity 1-2 supported: "+termName);
        }
    } else {
        termSpan = doc.createElement("a");
        //termSpan.href = "#" + tag + "=" + path;
        termSpan.onclick = cb(path);
        termSpan.className += " variable";
        termSpan.className += " var" + varNamer(exp);
        width = 1;
        height = 1;
        var txtSpan = doc.createElement("span");
        txtSpan.className = " txt";
        txtSpan.style.width="100%";
        txtSpan.style.height="100%";
        termSpan.appendChild(txtSpan);
        termSpan.className += " txtBox";
        var innerHTML = varNamer(exp);
        var whichChild = path[path.length - 1];
        for (var i = path.length  - 1; (i >= 0) && path[i] == whichChild; i--) {
            if (whichChild == 1) {
                innerHTML = innerHTML + ")";
            } else if (whichChild == 0) {
                innerHTML = "(" + innerHTML;
            }
        }
        txtSpan.innerHTML = innerHTML;
    }
    termSpan.className += " term";
    termSpan.className += " depth" + path.length;
    if (path.length > 0) {
        var inputNum = path[path.length - 1];
        termSpan.className += " input" + inputNum + "of" + inputTot;
    }
    return ({span:termSpan, width:width, height:height});
}

function makeThmBox(fact, exp, cb) {
    var termBox = document.createElement("span");
    termBox.className += " termbox";
    var spanMap = {};
    var tree = makeTree(document, fact, exp, [], -1, newVarNamer(), spanMap,
                        cb);
    termBox.appendChild(tree.span);
    tree.span.style.width = "100%";
    tree.span.style.height = "100%";
    termBox.style.width = "" + (2 * tree.width) + "em";
    termBox.style.height ="" + (2 * tree.height) + "em";
    termBox.spanMap = spanMap;
    termBox.tree = tree;
    return termBox;
}

function size(thmBox, ems) {
    thmBox.style.width = ems + "em";
    thmBox.style.height = ems + "em";
    thmBox.tree.span.style["font-size"] = "" + (50 * ems / thmBox.tree.width) + "%";
}

function addToShooter(factData) {
    var fact = Engine.canonicalize(new Fact(factData));
    localStorage.setItem(fact.Skin.Name, JSON.stringify(fact));
    Engine.onAddFact(fact);
    if (fact.Core[Fact.CORE_HYPS].length == 0) {
        var box;
        var factOnclickMaker = function(path) {
            var factPath = path.slice();
            if (factPath[factPath.length-1] == 0) {
                factPath.pop();
            }
            return function() {
                try {
                    state.url = "#f=" + path + ";" + fact.Skin.Name;
                    if (state.workPath != null) {
                        console.log("calling applyFact: " +
                                    JSON.stringify(state.work) + "\n" +
                                    JSON.stringify(state.workPath) + "\n" +
                                    JSON.stringify(fact) + "\n" +
                                    JSON.stringify(factPath) + "\n");
                        setWork(Engine.applyFact(state.work,
                                                 state.workPath,
                                                 fact, factPath));
                        message("");
                        delete state.workPath;
                        state.url = "";
                    } else if (factPath.length==0) {
                        console.log("calling ground: " +
                                    JSON.stringify(state.work) + "\n" +
                                    JSON.stringify(fact) + "\n");
                        var thm = Engine.ground(state.work, fact);
                        var newFact = addToShooter(thm);
                        currentLand().thms.push(newFact.Skin.Name);
                        message("");
                        nextGoal();
                    } else {
                        console.log("wtf? " + JSON.stringify(factPath));
                    }
                } catch (e) {
                    console.log("Error in applyFact: " + e);
                    console.log(e.stack);
                    message(e);
                }
                redraw();
            };
        };
        box = makeThmBox(fact, fact.Core[Fact.CORE_STMT], factOnclickMaker);
        size(box, 2 * SIZE_MULTIPLIER);
        document.getElementById("shooterTape").appendChild(box);
    } // TODO: handle axioms with hyps
    return fact;
}

function workOnclickMaker(path) {
    var goalPath = path.slice();
    if (goalPath[goalPath.length-1] == 0) {
        goalPath.pop();
    }
    return function() {
        state.workPath = goalPath;
        state.url = "#g=" + goalPath;
        save();
    }
}

function startWork(fact) {
    var work = new Fact(fact);
    work.setHyps([work.Core[Fact.CORE_STMT]]);
    work.Skin.HypNames = ["Hyps.0"];
    if (!work.Tree.Cmd) {
        work.setCmd("thm");
    }
    work.setProof(["Hyps.0"]);
    return Engine.canonicalize(work);
}

function setWork(work) {
    state.work = work;
    state.workHash = Engine.fingerprint(work);
    save();
}

function save() {
    var hash = Engine.fingerprint(state);
    if (hash != stateHash) {
        localStorage.setItem(hash, JSON.stringify(state));
        localStorage.setItem(STATE_KEY, hash);
        localStorage.setItem("parentOf-" + hash, stateHash);
        localStorage.setItem("childOf-" + stateHash, hash);
        console.log("XXXX Setting " + "childOf-" + stateHash + " = " + hash);
        stateHash = hash;
        history.pushState(state, "state", "#s=" + hash + state.url);
    }
}

function currentLand() {
    return state.lands[state.lands.length-1];
}
function nextGoal() {
    var land = currentLand();
    var goal = land.goals.shift();
    console.log("XXXX Next goal is " + JSON.stringify(goal));
    if (!goal) {
        var nextLand = landDepMap[land.name]; // XXX
        if (nextLand) {
            enterLand(nextLand);
            return nextGoal();
        } else {
            message("No more lands! You win! Now go write a land.");
        }
    }
    state.work = startWork(goal);
    save();
    return goal;
}

function redraw() {
    var well = document.getElementById("well");
    console.log("Redrawing: " + JSON.stringify(state.work));
    try {
        var box = makeThmBox(state.work,
                             state.work.Core[Fact.CORE_HYPS][0],
                             workOnclickMaker);
        size(box, box.tree.width * SIZE_MULTIPLIER);
        well.removeChild(well.firstChild);
        well.appendChild(box);
    } catch (e) {
        message(e);
    }
}

function loadState(flat) {
    state = flat;
    state.work = new Fact(state.work);
    message("");
}

function enterLand(landData) {
    var land = {
        name:landData.name,
        thms:[],             // hash values
        goals:[],            // structs
    };
    state.lands.push(land);
    land.goals = landData.goals.slice();
    console.log("XXXX First Land goal: " + JSON.stringify(land.goals[0]));
    landData.axioms.forEach(function(data) {
        var fact = addToShooter(data);
        land.thms.push(fact.Skin.Name);
    });
    currentLand().thms.push.apply(currentLand(), landData.axioms);
}

function message(msg) {
    console.log("Tacro: " + msg);
    document.getElementById("message").innerText = msg;
}

var allLands = require('./all_lands.js');
var landMap = {};
var landDepMap = {}; // XXX
allLands.forEach(function(land) {
    landMap[land.name] = land;
    landDepMap[land.depends[0]] = land;
});

window.addEventListener('popstate', function(ev) {
    console.log("popstate to " + ev.state);
    if (ev.state) {
        loadState(ev.state);
        save();
        redraw();
    }
});
document.getElementById("rewind").onclick = function() {
    var parentHash = localStorage.getItem("parentOf-" + stateHash);
    console.log("XXXX Rewinding from " + stateHash + "  to " + parentHash);
    if (parentHash) {
        loadState(JSON.parse(localStorage.getItem(parentHash)));
        stateHash = parentHash;
        redraw();
        // Don't save() or we'll get stuck in a loop
        document.getElementById("forward").style.visibility="visible";
    }
    return false;
};
document.getElementById("forward").onclick = function() {
    var childHash = localStorage.getItem("childOf-" + stateHash);
    console.log("XXXX Forwarding from " + stateHash + " to " + childHash);
    if (childHash) {
        loadState(JSON.parse(localStorage.getItem(childHash)));
        stateHash = childHash;
        redraw();
        // Don't save() or we'll get stuck in a loop
    } else {
        document.getElementById("forward").style.visibility="hidden";
    }
    return false;
}
var stateHash = localStorage.getItem(STATE_KEY);
if (stateHash) {
    loadState(JSON.parse(localStorage.getItem(stateHash)));
    state.lands.forEach(function(land) {
        console.log("Processing land " + land.name + " #" + land.thms.length);
        land.thms.forEach(function(thmName) {
            var factData = JSON.parse(localStorage.getItem(thmName));
            console.log("adding " + thmName + "=" + JSON.stringify(factData));
            var fact = addToShooter(factData);

        })
    });
} else {
    state = {
        lands: [],
        url:"",
    };
    var firstLand = landDepMap[undefined]; // XXX
    enterLand(firstLand);
    nextGoal();
    state.url = "";
}

save();
redraw();
<|endoftext|>


<commit_before>/*eslint no-useless-escape:0*/

/**
 * Function to extract *tags
 */
function tagExtractor(msg) {
	let issue;
	issue = msg.match(/\*\w\w+\b/g) || null;
	if (!issue) return null;

	let random = getRandomInt(0, issue.length - 1);
	let tag = issue[random];
	tag = tag.replace("*", "");
	return tag;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive)
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

module.exports = tagExtractor;
<commit_msg>linting stuffs<commit_after>/*eslint no-useless-escape:0*/

/**
 * Function to extract *tags
 */
function tagExtractor(msg) {
	let issue;
	issue = msg.match(/\*\w\w+\b/g) || null;
	if (!issue) return null;

	let random = getRandomInt(0, issue.length - 1);
	let tag = issue[random];
	tag = tag.replace('*', '');
	return tag;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive)
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

module.exports = tagExtractor;
<|endoftext|>


<commit_before>/**
 * ingestion.js
 * expects:
 * 1. path of directory
 * 2. parentpid
 * 3. namespace
 * 4. model
 *   (note: basic image,large image,audio,video, collection, pdf, binary -- all require
 * the "ibsp" in the command string, book requires the "ibbp" part in the drush command.)
 * output:
 *  log of drush run
 * errors:
 *  if parameters missing
 *  if first command did not run
 *  if first command did run but did not prep ingest
 *  if first command ran with a good ingest but second command did not run
 *  if second ran but did not ingest
 *
 * @param target directory path
 * @param parentpid
 * @param namespace
 * @param model
 * @return $message
 *
 */
// for testing
//
var param = process.argv;
console.log('hi');
target = String(param[2]);
parentpid = String(param[3]);
namespace = String(param[4]);
model = String(param[5]);

function ingestion(target,parentpid,namespace,model) {
  // build command pieces
  // serveruri is the location of the drupal_home on the drupal server
  var drupalhome = '/vhosts/dlwork/web/collections';
  console.log('drupalhome = '.drupalhome);
  var serveruri = 'http://dlwork.lib.utk.edu/dev/';
  console.log('serveruri = '.serveruri);
  console.log('parentpid = '.parentpid.'\n');
  // namespace
  console.log('namespace = '.namespace.'\n');
  // target is the local directory holding the ingest files
  console.log('target = '.target.'\n');
  // make mongo connection
  /*
  var mongoose = require('mongoose');
  mongoose.connect('mongodb://localhost/ibu');
  var conn = mongoose.connection;
  */
  //
  var $message = 'ingest did not happen';
  var contentmodel = '';
  if ((model)&& (model==='basic')) {
    contentmodel = 'islandora:sp_basic_image';
  }
  if ((model)&&(model==='large')) {
    contentmodel = 'islandora:sp_Large_image';
  }
  console.log('model = '.model.'\n');
  // execute first drush command
  var exec = require('child_process').exec;
  var cmd = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' ibsp --content_models='.contentmodel.' --type=directory --parent='.parentpid.' --namespace='.namespace.' --target='target;
  if ((target!='')&&(contentmodel!='')&&(parentpid!='')&&(namespace!='')) {
    exec(cmd, function(error, stdout, stderr) {
     // command output is in stdout
     console.log(stdout);
     // test command log for success indication
     // test for substr in stdout
     $message = 'ingest prep drush command success';
     status.push("$message");
    });
  }// end if
  else {
      console.log('parameters for first command missing, ingest not started.\n');
      $message = 'parameters for first command missing, ingest not started.';
      return $message;
  }
  // exec second drush command
  //var exec2 = require('child_process').exec;
  var cmd2 = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' islandora_batch_ingest';
  if ($message = 'ingest prep drush command success') {
    exec(cmd2, function(error, stdout, stderr) {
     // command output is in stdout
     console.log(stdout);
     // test command log for success indication
     // test for substr in stdout
     $message = 'ingest drush command success';
     status.push("$message");
    });
  }// end if
  return $message;
}// end function
//export default ingestion;
ingestion();
<commit_msg>remove linefeed from console log statement to show parentpid.<commit_after>/**
 * ingestion.js
 * expects:
 * 1. path of directory
 * 2. parentpid
 * 3. namespace
 * 4. model
 *   (note: basic image,large image,audio,video, collection, pdf, binary -- all require
 * the "ibsp" in the command string, book requires the "ibbp" part in the drush command.)
 * output:
 *  log of drush run
 * errors:
 *  if parameters missing
 *  if first command did not run
 *  if first command did run but did not prep ingest
 *  if first command ran with a good ingest but second command did not run
 *  if second ran but did not ingest
 *
 * @param target directory path
 * @param parentpid
 * @param namespace
 * @param model
 * @return $message
 *
 */
// for testing
//
var param = process.argv;
console.log('hi');
target = String(param[2]);
parentpid = String(param[3]);
namespace = String(param[4]);
model = String(param[5]);

function ingestion(target,parentpid,namespace,model) {
  // build command pieces
  // serveruri is the location of the drupal_home on the drupal server
  var drupalhome = '/vhosts/dlwork/web/collections';
  console.log('drupalhome = '.drupalhome);
  var serveruri = 'http://dlwork.lib.utk.edu/dev/';
  console.log('serveruri = '.serveruri);
  console.log('parentpid = '.parentpid);
  // namespace
  console.log('namespace = '.namespace.'\n');
  // target is the local directory holding the ingest files
  console.log('target = '.target.'\n');
  // make mongo connection
  /*
  var mongoose = require('mongoose');
  mongoose.connect('mongodb://localhost/ibu');
  var conn = mongoose.connection;
  */
  //
  var $message = 'ingest did not happen';
  var contentmodel = '';
  if ((model)&& (model==='basic')) {
    contentmodel = 'islandora:sp_basic_image';
  }
  if ((model)&&(model==='large')) {
    contentmodel = 'islandora:sp_Large_image';
  }
  console.log('model = '.model.'\n');
  // execute first drush command
  var exec = require('child_process').exec;
  var cmd = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' ibsp --content_models='.contentmodel.' --type=directory --parent='.parentpid.' --namespace='.namespace.' --target='target;
  if ((target!='')&&(contentmodel!='')&&(parentpid!='')&&(namespace!='')) {
    exec(cmd, function(error, stdout, stderr) {
     // command output is in stdout
     console.log(stdout);
     // test command log for success indication
     // test for substr in stdout
     $message = 'ingest prep drush command success';
     status.push("$message");
    });
  }// end if
  else {
      console.log('parameters for first command missing, ingest not started.\n');
      $message = 'parameters for first command missing, ingest not started.';
      return $message;
  }
  // exec second drush command
  //var exec2 = require('child_process').exec;
  var cmd2 = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' islandora_batch_ingest';
  if ($message = 'ingest prep drush command success') {
    exec(cmd2, function(error, stdout, stderr) {
     // command output is in stdout
     console.log(stdout);
     // test command log for success indication
     // test for substr in stdout
     $message = 'ingest drush command success';
     status.push("$message");
    });
  }// end if
  return $message;
}// end function
//export default ingestion;
ingestion();
<|endoftext|>


<commit_before>/**
 * ingestion.js
 * expects:
 * 1. path of directory
 * 2. parentpid
 * 3. namespace
 * 4. model
 * output:
 *  log of drush run
 * errors:
 *  if parameters missing
 *  if first command did not run
 *  if first command did run but did not prep ingest
 *  if first command ran with a good ingest but second command did not run
 *  if second ran but did not ingest
 *
 * @param target directory path
 * @param parentpid
 * @param namespace
 * @param model
 * @return $message
 *
 */
function ingestion(target,parentpid,namespace,model) {
  // build command pieces
  // serveruri is the location of the drupal_home on the drupal server
  let drupalhome = '/vhosts/digital/web/collections';
  let serveruri = 'http://dlwork.lib.utk.edu/dev/';
  let parentpid = '';
  console.log('parentpid = '.parentpid.'\n');
  // namespace
  let namespace = '';
  console.log('namespace = '.namespace.'\n');
  // target is the local directory holding the ingest files
  let target = '';
  console.log('target = '.target.'\n');

  var $message = 'ingest did not happen';
  var contentmodel = '';
  if ((model)&& (model==='basic')) {
    contentmodel = 'islandora:sp_basic_image';
  }
  if ((model)&&(model==='large')) {
    contentmodel = 'islandora:sp_Large_image';
  }
  console.log('model = '.model.'\n');
  // execute first drush command
  var exec = require('child_process').exec;
  var cmd = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' ibsp --content_models='.contentmodel.' --type=directory --parent='.parentpid.' --namespace='.namespace.' --target='target;
  if ((target!='')&&(contentmodel!='')&&(parentpid!='')&&(namespace!='')) {
    exec(cmd, function(error, stdout, stderr) {
     // command output is in stdout
     //console.log(stdout);
     $message = 'ingest prep drush command success';
     status.push("$message");
    });
  }// end if
  else {
      console.log('parameters for first command missing\n');
      $message = 'parameters for first command missing';
      return $message;
  }
  // exec second drush command
  //var exec2 = require('child_process').exec;
  var cmd2 = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' islandora_batch_ingest';
  if ($message = 'ingest prep drush command success') {
    exec(cmd2, function(error, stdout, stderr) {
     // command output is in stdout
     console.log(stdout);
     $message = 'ingest drush command success';
     status.push("$message");
    });
  }// end if
  return $message;
}// end function
export default ingestion;
<commit_msg>Update ingestion.js<commit_after>/**
 * ingestion.js
 * expects:
 * 1. path of directory
 * 2. parentpid
 * 3. namespace
 * 4. model
 *   (note: basic image,large image,audio,video, collection, pdf, binary -- all require
 * the "ibsp" in the command string, book requires the "ibbp" part in the drush command.)
 * output:
 *  log of drush run
 * errors:
 *  if parameters missing
 *  if first command did not run
 *  if first command did run but did not prep ingest
 *  if first command ran with a good ingest but second command did not run
 *  if second ran but did not ingest
 *
 * @param target directory path
 * @param parentpid
 * @param namespace
 * @param model
 * @return $message
 *
 */
function ingestion(target,parentpid,namespace,model) {
  // build command pieces
  // serveruri is the location of the drupal_home on the drupal server
  let drupalhome = '/vhosts/digital/web/collections';
  let serveruri = 'http://dlwork.lib.utk.edu/dev/';
  let parentpid = '';
  console.log('parentpid = '.parentpid.'\n');
  // namespace
  let namespace = '';
  console.log('namespace = '.namespace.'\n');
  // target is the local directory holding the ingest files
  let target = '';
  console.log('target = '.target.'\n');

  var $message = 'ingest did not happen';
  var contentmodel = '';
  if ((model)&& (model==='basic')) {
    contentmodel = 'islandora:sp_basic_image';
  }
  if ((model)&&(model==='large')) {
    contentmodel = 'islandora:sp_Large_image';
  }
  console.log('model = '.model.'\n');
  // execute first drush command
  var exec = require('child_process').exec;
  var cmd = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' ibsp --content_models='.contentmodel.' --type=directory --parent='.parentpid.' --namespace='.namespace.' --target='target;
  if ((target!='')&&(contentmodel!='')&&(parentpid!='')&&(namespace!='')) {
    exec(cmd, function(error, stdout, stderr) {
     // command output is in stdout
     //console.log(stdout);
     $message = 'ingest prep drush command success';
     status.push("$message");
    });
  }// end if
  else {
      console.log('parameters for first command missing\n');
      $message = 'parameters for first command missing';
      return $message;
  }
  // exec second drush command
  //var exec2 = require('child_process').exec;
  var cmd2 = 'drush -r '.drupalhome.'-v -u=1 --uri='.serveruri.' islandora_batch_ingest';
  if ($message = 'ingest prep drush command success') {
    exec(cmd2, function(error, stdout, stderr) {
     // command output is in stdout
     console.log(stdout);
     $message = 'ingest drush command success';
     status.push("$message");
    });
  }// end if
  return $message;
}// end function
export default ingestion;
<|endoftext|>


<commit_before>var currentTimeout;
function actionWrapper(searchAction){
  return function(){
    const DEFAULT_TIMEOUT = 5000;
    var context = this;
    var args = arguments;
    if(currentTimeout){
      //Cancel previous search action.
      window.clearTimeout(currentTimeout);
    }
    currentTimeout = window.setTimeout(
      function(){
        searchAction.apply(context, args)
      },
      DEFAULT_TIMEOUT
    );
    return currentTimeout;
  };
}
module.exports = actionWrapper;
<commit_msg>[search-wrapper] Fix bug in the wrapper<commit_after>var currentTimeout;
function actionWrapper(searchAction){
  return function(){
    const DEFAULT_TIMEOUT = 5000;
    var context = this || {};
    var args = arguments;
    if(currentTimeout){
      //Cancel previous search action.
      window.clearTimeout(currentTimeout);
    }
    currentTimeout = window.setTimeout(
      function(){
        searchAction.apply(context, args)
      },
      DEFAULT_TIMEOUT
    );
    return currentTimeout;
  };
}
module.exports = actionWrapper;
<|endoftext|>