<commit_before>const childProcess = require('child_process')
const { sleep, Service } = require('clean-scripts')
const util = require('util')

const execAsync = util.promisify(childProcess.exec)

const elasticVersion = '5.5.2'

const tsFiles = `"src/**/*.ts" "spec/**/*.ts" "static/**/*.ts" "static_spec/**/*.ts" "test/**/*.ts" "screenshots/**/*.ts" "prerender/**/*.ts"`
const jsFiles = `"*.config.js" "static/**/*.config.js" "static_spec/**/*.config.js"`
const lessFiles = `"static/**/*.less"`

module.exports = {
  build: [
    `types-as-schema src/types.ts --json static/ --protobuf static/protocol.proto`,
    {
      back: [
        `file2variable-cli src/sql/*.sql -o src/variables.ts --base src/sql`,
        `rimraf dist/`,
        `tsc -p src`
      ],
      front: {
        js: [
          `file2variable-cli static/*.template.html static/protocol.proto static/request-protocol.json static/response-protocol.json -o static/variables.ts --html-minify --json --protobuf --base static`,
          `tsc -p static`,
          `webpack --display-modules --config static/webpack.config.js`
        ],
        css: {
          vendor: `cleancss ./node_modules/github-fork-ribbon-css/gh-fork-ribbon.css ./node_modules/tab-container-component/tab-container.min.css -o ./static/vendor.bundle.css`,
          index: [
            `lessc ./static/index.less > ./static/index.css`,
            `postcss ./static/index.css -o ./static/index.postcss.css`,
            `cleancss ./static/index.postcss.css -o ./static/index.bundle.css`
          ]
        },
        clean: `rimraf static/*.bundle-*.js static/vendor.bundle-*.css static/index.bundle-*.css`
      }
    },
    `rev-static --config static/rev-static.config.js`
  ],
  lint: {
    ts: `tslint ${tsFiles}`,
    js: `standard ${jsFiles}`,
    less: `stylelint ${lessFiles}`,
    export: `no-unused-export ${tsFiles} ${lessFiles}`
  },
  test: {
    jasmine: [
      'tsc -p spec',
      'jasmine'
    ],
    karma: [
      'tsc -p static_spec',
      'karma start static_spec/karma.config.js'
    ],
    check: [
      'mkdirp vendors',
      `tsc -p test`,
      `node test/vendor.js`,
      new Service(`./vendors/elasticsearch-${elasticVersion}/bin/elasticsearch`),
      () => sleep(60000),
      new Service(`node ./dist/index.js`),
      () => sleep(10000),
      `node test/initialize.js`,
      () => sleep(5000),
      `node test/save-log-by-http.js`,
      () => sleep(5000),
      `node test/save-log-by-ws.js`,
      async () => {
        const { stdout } = await execAsync('git status -s')
        if (stdout) {
          console.log(stdout)
          throw new Error(`generated files doesn't match.`)
        }
      }
    ]
  },
  fix: {
    ts: `tslint --fix ${tsFiles}`,
    js: `standard --fix ${jsFiles}`,
    less: `stylelint --fix ${lessFiles}`
  },
  release: `clean-release`,
  watch: {
    schema: `watch-then-execute "src/types.ts" --script "clean-scripts build[0]"`,
    sql: `file2variable-cli src/sql/*.sql -o src/variables.ts --base src/sql --watch`,
    back: `tsc -p src --watch`,
    template: `file2variable-cli static/*.template.html static/protocol.proto static/request-protocol.json static/response-protocol.json -o static/variables.ts --html-minify --json --protobuf --base static --watch`,
    front: `tsc -p static --watch`,
    webpack: `webpack --config static/webpack.config.js --watch`,
    less: `watch-then-execute "./static/index.less" --script "clean-scripts build[1].front.css.index"`,
    rev: `rev-static --config static/rev-static.config.js --watch`
  },
  screenshot: [
    new Service(`node ./dist/index.js`),
    `tsc -p screenshots`,
    `node screenshots/index.js`
  ],
  prerender: [
    new Service(`node ./dist/index.js`),
    `tsc -p prerender`,
    `node prerender/index.js`,
    `clean-scripts build[2]`
  ]
}
<commit_msg>fix CI on windows<commit_after>const childProcess = require('child_process')
const { sleep, Service } = require('clean-scripts')
const util = require('util')

const execAsync = util.promisify(childProcess.exec)

const elasticVersion = '5.5.2'

const tsFiles = `"src/**/*.ts" "spec/**/*.ts" "static/**/*.ts" "static_spec/**/*.ts" "test/**/*.ts" "screenshots/**/*.ts" "prerender/**/*.ts"`
const jsFiles = `"*.config.js" "static/**/*.config.js" "static_spec/**/*.config.js"`
const lessFiles = `"static/**/*.less"`

module.exports = {
  build: [
    `types-as-schema src/types.ts --json static/ --protobuf static/protocol.proto`,
    {
      back: [
        `file2variable-cli src/sql/*.sql -o src/variables.ts --base src/sql`,
        `rimraf dist/`,
        `tsc -p src`
      ],
      front: {
        js: [
          `file2variable-cli static/*.template.html static/protocol.proto static/request-protocol.json static/response-protocol.json -o static/variables.ts --html-minify --json --protobuf --base static`,
          `tsc -p static`,
          `webpack --display-modules --config static/webpack.config.js`
        ],
        css: {
          vendor: `cleancss ./node_modules/github-fork-ribbon-css/gh-fork-ribbon.css ./node_modules/tab-container-component/tab-container.min.css -o ./static/vendor.bundle.css`,
          index: [
            `lessc ./static/index.less > ./static/index.css`,
            `postcss ./static/index.css -o ./static/index.postcss.css`,
            `cleancss ./static/index.postcss.css -o ./static/index.bundle.css`
          ]
        },
        clean: `rimraf static/*.bundle-*.js static/vendor.bundle-*.css static/index.bundle-*.css`
      }
    },
    `rev-static --config static/rev-static.config.js`
  ],
  lint: {
    ts: `tslint ${tsFiles}`,
    js: `standard ${jsFiles}`,
    less: `stylelint ${lessFiles}`,
    export: `no-unused-export ${tsFiles} ${lessFiles}`
  },
  test: {
    jasmine: [
      'tsc -p spec',
      'jasmine'
    ],
    karma: [
      'tsc -p static_spec',
      'karma start static_spec/karma.config.js'
    ],
    check: [
      'mkdirp vendors',
      `tsc -p test`,
      `node test/vendor.js`,
      new Service(process.platform === 'win32'
        ? `.\\vendors\\elasticsearch-${elasticVersion}\\bin\\elasticsearch.bat`
        : `./vendors/elasticsearch-${elasticVersion}/bin/elasticsearch`),
      () => sleep(60000),
      new Service(`node ./dist/index.js`),
      () => sleep(10000),
      `node test/initialize.js`,
      () => sleep(5000),
      `node test/save-log-by-http.js`,
      () => sleep(5000),
      `node test/save-log-by-ws.js`,
      async () => {
        const { stdout } = await execAsync('git status -s')
        if (stdout) {
          console.log(stdout)
          throw new Error(`generated files doesn't match.`)
        }
      }
    ]
  },
  fix: {
    ts: `tslint --fix ${tsFiles}`,
    js: `standard --fix ${jsFiles}`,
    less: `stylelint --fix ${lessFiles}`
  },
  release: `clean-release`,
  watch: {
    schema: `watch-then-execute "src/types.ts" --script "clean-scripts build[0]"`,
    sql: `file2variable-cli src/sql/*.sql -o src/variables.ts --base src/sql --watch`,
    back: `tsc -p src --watch`,
    template: `file2variable-cli static/*.template.html static/protocol.proto static/request-protocol.json static/response-protocol.json -o static/variables.ts --html-minify --json --protobuf --base static --watch`,
    front: `tsc -p static --watch`,
    webpack: `webpack --config static/webpack.config.js --watch`,
    less: `watch-then-execute "./static/index.less" --script "clean-scripts build[1].front.css.index"`,
    rev: `rev-static --config static/rev-static.config.js --watch`
  },
  screenshot: [
    new Service(`node ./dist/index.js`),
    `tsc -p screenshots`,
    `node screenshots/index.js`
  ],
  prerender: [
    new Service(`node ./dist/index.js`),
    `tsc -p prerender`,
    `node prerender/index.js`,
    `clean-scripts build[2]`
  ]
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012, Sid Nallu, Chris Umbel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/*
 * contribution by sidred123
 */

/*
 * Compute the Levenshtein distance between two strings.
 * Algorithm based from Speech and Language Processing - Daniel Jurafsky and James H. Martin.
 */

var _ = require('underscore');

function LevenshteinDistance (source, target, options) {
    options = options || {};
    if(isNaN(options.insertion_cost)) options.insertion_cost = 1;
    if(isNaN(options.deletion_cost)) options.deletion_cost = 1;
    if(isNaN(options.substitution_cost)) options.substitution_cost = 1;

    var sourceLength = source.length;
    var targetLength = target.length;
    var distanceMatrix = [[{cost: 0}]];

    for (var row =  1; row <= sourceLength; row++) {
        distanceMatrix[row] = [];
        distanceMatrix[row][0] = {cost: distanceMatrix[row-1][0].cost + options.deletion_cost};
    }

    for (var column = 1; column <= targetLength; column++) {
        if (options.search) {
          distanceMatrix[0][column] = {cost: 0};
        } else {
          distanceMatrix[0][column] = {cost: distanceMatrix[0][column-1].cost + options.insertion_cost};
        }
    }

    for (var row = 1; row <= sourceLength; row++) {
        for (var column = 1; column <= targetLength; column++) {
            var costToInsert = distanceMatrix[row][column-1].cost + options.insertion_cost;
            var costToDelete = distanceMatrix[row-1][column].cost + options.deletion_cost;

            var sourceElement = source[row-1];
            var targetElement = target[column-1];
            var costToSubstitute = distanceMatrix[row-1][column-1].cost;
            if (sourceElement !== targetElement) {
                costToSubstitute = costToSubstitute + options.substitution_cost;
            }

            var possibleParents = [
              {cost: costToInsert, coordinates: {row: row, column: column-1}},
              {cost: costToDelete, coordinates: {row: row-1, column: column}},
              {cost: costToSubstitute, coordinates: {row: row-1, column: column-1}}
            ];

            var minCostParent = _.min(possibleParents, function(p) { return p.cost; });

            distanceMatrix[row][column] = {cost: minCostParent.cost, parentCell: minCostParent.coordinates};
        }
    }
    return distanceMatrix[sourceLength][targetLength].cost;
}

module.exports = LevenshteinDistance;
<commit_msg>mDantas/LevenshteinSearch - Calculate closest matching substring<commit_after>/*
Copyright (c) 2012, Sid Nallu, Chris Umbel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/*
 * contribution by sidred123
 */

/*
 * Compute the Levenshtein distance between two strings.
 * Algorithm based from Speech and Language Processing - Daniel Jurafsky and James H. Martin.
 */

var _ = require('underscore');

function _getMatchStart(distanceMatrix, matchEnd, sourceLength) {
  var row = sourceLength;
  var column = matchEnd;
  var tmpRow;
  var tmpColumn;

  while(row > 1) {
   tmpRow = row;
   tmpColumn = column;
   row = distanceMatrix[tmpRow][tmpColumn].parentCell.row;
   column = distanceMatrix[tmpRow][tmpColumn].parentCell.column;
  }

  return column-1;
}

function getMinCostSubstring(distanceMatrix, source, target) {
  var sourceLength = source.length;
  var targetLength = target.length;
  var minDistance = sourceLength + targetLength;
  var matchEnd = targetLength;

  for (var column = 1; column <= targetLength; column++) {
    if (minDistance > distanceMatrix[sourceLength][column].cost) {
      minDistance = distanceMatrix[sourceLength][column].cost;
      matchEnd = column;
    }
  }

  matchStart = _getMatchStart(distanceMatrix, matchEnd, sourceLength);
  return {substring: target.slice(matchStart, matchEnd), distance: minDistance};
}

function LevenshteinDistance (source, target, options) {
    options = options || {};
    if(isNaN(options.insertion_cost)) options.insertion_cost = 1;
    if(isNaN(options.deletion_cost)) options.deletion_cost = 1;
    if(isNaN(options.substitution_cost)) options.substitution_cost = 1;

    if(typeof options.search !== 'boolean') options.search = false;

    var sourceLength = source.length;
    var targetLength = target.length;
    var distanceMatrix = [[{cost: 0}]];

    for (var row =  1; row <= sourceLength; row++) {
        distanceMatrix[row] = [];
        distanceMatrix[row][0] = {cost: distanceMatrix[row-1][0].cost + options.deletion_cost};
    }

    for (var column = 1; column <= targetLength; column++) {
        if (options.search) {
          distanceMatrix[0][column] = {cost: 0};
        } else {
          distanceMatrix[0][column] = {cost: distanceMatrix[0][column-1].cost + options.insertion_cost};
        }
    }

    for (var row = 1; row <= sourceLength; row++) {
        for (var column = 1; column <= targetLength; column++) {
            var costToInsert = distanceMatrix[row][column-1].cost + options.insertion_cost;
            var costToDelete = distanceMatrix[row-1][column].cost + options.deletion_cost;

            var sourceElement = source[row-1];
            var targetElement = target[column-1];
            var costToSubstitute = distanceMatrix[row-1][column-1].cost;
            if (sourceElement !== targetElement) {
                costToSubstitute = costToSubstitute + options.substitution_cost;
            }

            var possibleParents = [
              {cost: costToInsert, coordinates: {row: row, column: column-1}},
              {cost: costToDelete, coordinates: {row: row-1, column: column}},
              {cost: costToSubstitute, coordinates: {row: row-1, column: column-1}}
            ];

            var minCostParent = _.min(possibleParents, function(p) { return p.cost; });

            distanceMatrix[row][column] = {cost: minCostParent.cost, parentCell: minCostParent.coordinates};
        }
    }

    if (!options.search) {
      return distanceMatrix[sourceLength][targetLength].cost;
    }

    return getMinCostSubstring(distanceMatrix, source, target);
}

module.exports = LevenshteinDistance;
<|endoftext|>


<commit_before>angular.module('bolt.auth', [])

.controller('AuthController', function ($scope, $window, $location, Auth) {
  $scope.user = {};

  $scope.signin = function () {
    Auth.signin($scope.user)
      .then(function (token) {
        $window.localStorage.setItem('com.bolt', token);
        $location.path('/links');
      })
      .catch(function (error) {
        console.error(error);
      });
  };

  $scope.signup = function () {
    Auth.signup($scope.user)
      .then(function (token) {
        $window.localStorage.setItem('com.bolt', token);
        $location.path('/');
      })
      .catch(function (error) {
        console.error(error);
      });
  };

});
<commit_msg>Make default page after signin the bolt page<commit_after>angular.module('bolt.auth', [])

.controller('AuthController', function ($scope, $window, $location, Auth) {
  $scope.user = {};

  $scope.signin = function () {
    Auth.signin($scope.user)
      .then(function (token) {
        $window.localStorage.setItem('com.bolt', token);
        $location.path('/');
      })
      .catch(function (error) {
        console.error(error);
      });
  };

  $scope.signup = function () {
    Auth.signup($scope.user)
      .then(function (token) {
        $window.localStorage.setItem('com.bolt', token);
        $location.path('/');
      })
      .catch(function (error) {
        console.error(error);
      });
  };

});
<|endoftext|>


<commit_before>// Create our grid module namespace
var grid = angular.module('game.grid', []);

// Returns a tile object
grid.factory('TileModel', function() {
  var Tile = function(tilespec) {
    this.x = tilespec.x || null;
    this.y = tilespec.y || null;
    this.img = this.getImage(tilespec.id);
    this.val = tilespec.val || 2;
    this.orientation = tilespec.orientation;
    this.meeples = null;
    this.features = tilespec.features;
  }
  Tile.prototype.getImage = function(id) {
    // Grab an image from our asset folder to set as img attribute
    return 'assets/img/Tiles/' + id.toUpperCase() + '.png'
  };
  Tile.prototype.rotateRight = function() {
    this.orientation = (this.orientation + 1) % 4;

    var temp = {};
    for (var key in this.features){
      temp[key] = this.features[key];
    }

    this.features.n = temp.w;
    this.features.e = temp.n;
    this.features.s = temp.e;
    this.features.w = temp.s;
  };
  return Tile;
});

grid.service('GridService', function(TileModel) {

  this.createEmptyGameBoard = function() {
    var grid = [];
    var size = 72;
    for (var x = 0; x < size; x++) {
      grid[x] = [];
      for (var y = 0; y < size; y++) {
        grid[x][y] = null;
      }
    }
    return grid;
  };

});

grid.controller('gridCtrl', function($scope, TileModel, GridService){
  $scope.orientation = 0;
  $scope.src = null;

  $scope.range = function(n) {
    return new Array(n);
  };
  $scope.rotate = function() {
    $scope.orientation = ($scope.orientation + 1) % 4;
    $scope.currentTile.rotateRight();
  };
  $scope.init = function() {
    // Create board
    $scope.grid = GridService.createEmptyGameBoard();
    placeInitialTile();

    socket.on('nextTurn', function(gamestate) {
      if (!gamestate.lastTile) {
        $scope.currentTile = new TileModel(gamestate.nextTile);
      } else {
        $scope.currentTile = new TileModel(gamestate.nextTile);
        updateGrid(gamestate.lastTile.x, gamestate.lastTile.y, gamestate.lastTile);
        setCell(gamestate.lastTile);
      }
      // Create a tile model
      $scope.playerId = gamestate.nextPlayer;
      $scope.src = $scope.currentTile.img;
      $scope.$apply();
    });
  };

  $scope.clickCell = function(x, y) {
    // Check if it's current player's turn
    if ($scope.playerId === socket.id) {
      if (!cellAlreadyExists(x, y)) {
        // Get out current tile generated from nextTurn
        var tile = $scope.currentTile;
        tile.x = x;
        tile.y = y;

        if (validPlacement(tile)) {
          // We push a new tile onto the grid at xy
          updateGrid(x, y, tile);
          // Set the background image of grid cell
          setCell(tile);
          // emit endturn
          $scope.orientation = 0;
          socket.emit('endTurn', tile);
        } else {
          console.log('Not a valid placement.')
        }
      }
    } else {
      console.log('not your turn');
    }
  };

  var getImage = function(id) {
    // Grab an image from our asset folder to set as img attribute
    return 'assets/img/Tiles/' + id.toUpperCase() + '.png';
  };

  var validPlacement = function(tile) {
    var canPlace = 0;

    try {
      var northernTile = $scope.grid[tile.y-1][tile.x];
      var easternTile = $scope.grid[tile.y][tile.x+1];
      var westernTile = $scope.grid[tile.y][tile.x-1];
      var southernTile = $scope.grid[tile.y+1][tile.x];
    } catch (err) {
      console.log('tile issues', err);
    }

    if ( (northernTile === null) || (tile.features.n === northernTile.features.s)) {
      canPlace += 1;
    }
    if ( (easternTile === null) || (tile.features.e === easternTile.features.w)) {
      canPlace += 1;
    }
    if ( (southernTile === null) || (tile.features.s === southernTile.features.n)) {
      canPlace += 1;
    }
    if ( (westernTile === null) || (tile.features.w === westernTile.features.e)) {
      canPlace += 1;
    }
    return canPlace === 4;
    // console.log('North', northernTile);
    // console.log('East', easternTile);
    // console.log('West', westernTile);
    // console.log('South', southernTile);
  };

  // These functions should be moved into a factory/service
  var updateGrid = function(x, y, tile) {
    $scope.grid[y][x] = tile;
    // console.log($scope.grid[y]);
  };

  var cellAlreadyExists = function(x, y) {
    return $scope.grid[y][x] !== null;
  };

  var setCell = function(tile) {
    var id = '#' + 'x-' + tile.x + '-y-' + tile.y;
    angular.element(document).ready(function() {
      var domElement = angular.element(document.querySelector(id));
      domElement.css('background-size', 'contain');
      domElement.css('background-image', 'url(' + tile.img + ')');
      domElement.css('transform', 'rotate(' + tile.orientation*90 + 'deg)');
    });
  };

  var placeInitialTile = function() {
    var x = $scope.grid.length/2, y = $scope.grid.length/2;
    // var x = 0, y = 0;
    var DTile = new TileModel({
      x: x,
      y: y,
      id: 'd',
      features: {

      },
      orientation: 0
    });
    updateGrid(x, y, DTile);
    setCell(DTile);
  };

  // Initialize game board
  $scope.init();
});
<commit_msg>tile placement validation fully working<commit_after>// Create our grid module namespace
var grid = angular.module('game.grid', []);

// Returns a tile object
grid.factory('TileModel', function() {
  var Tile = function(tilespec) {
    this.x = tilespec.x || null;
    this.y = tilespec.y || null;
    this.img = this.getImage(tilespec.id);
    this.val = tilespec.val || 2;
    this.orientation = tilespec.orientation;
    this.meeples = null;
    this.features = tilespec.features;
  };
  Tile.prototype.getImage = function(id) {
    // Grab an image from our asset folder to set as img attribute
    return 'assets/img/Tiles/' + id.toUpperCase() + '.png';
  };
  Tile.prototype.rotateRight = function() {
    this.orientation = (this.orientation + 1) % 4;

    var temp = {};
    for (var key in this.features){
      temp[key] = this.features[key];
    }

    this.features.n = temp.w;
    this.features.e = temp.n;
    this.features.s = temp.e;
    this.features.w = temp.s;
  };
  return Tile;
});

grid.service('GridService', function(TileModel) {
  this.createEmptyGameBoard = function() {
    var grid = [];
    var size = 72;
    for (var x = 0; x < size; x++) {
      grid[x] = [];
      for (var y = 0; y < size; y++) {
        grid[x][y] = null;
      }
    }
    return grid;
  };
});

grid.controller('gridCtrl', function($scope, TileModel, GridService){
  $scope.orientation = 0;
  $scope.src = null;

  $scope.range = function(n) {
    return new Array(n);
  };

  $scope.rotate = function() {
    if ($scope.playerId === socket.id) {
      $scope.orientation = ($scope.orientation + 1) % 4;
      $scope.currentTile.rotateRight();
      // console.log($scope.currentTile);
    }
    // console.log($scope.grid[$scope.currentTile.y][$scope.currentTile.x]);
  };

  $scope.init = function() {
    // Create board
    $scope.grid = GridService.createEmptyGameBoard();
    placeInitialTile();

    socket.on('nextTurn', function(gamestate) {
      if (!gamestate.lastTile) {
        $scope.currentTile = new TileModel(gamestate.nextTile);
      } else {
        $scope.currentTile = new TileModel(gamestate.nextTile);
        updateGrid(gamestate.lastTile.x, gamestate.lastTile.y, gamestate.lastTile);
        setCell(gamestate.lastTile);
      }
      // Create a tile model
      $scope.playerId = gamestate.nextPlayer;
      $scope.src = $scope.currentTile.img;
      $scope.$apply();
    });
  };

  $scope.clickCell = function(x, y) {
    // Check if it's current player's turn
    if ($scope.playerId === socket.id) {
      if (!cellAlreadyExists(x, y)) {
        // Get out current tile generated from nextTurn
        var tile = $scope.currentTile;
        tile.x = x;
        tile.y = y;

        if (validPlacement(tile)) {
          // We push a new tile onto the grid at xy
          updateGrid(x, y, tile);
          // Set the background image of grid cell
          setCell(tile);
          // emit endturn
          $scope.orientation = 0;
          socket.emit('endTurn', tile);
        } else {
          console.log('Not a valid placement.')
        }
      }
    } else {
      console.log('not your turn');
    }
  };

  var getImage = function(id) {
    // Grab an image from our asset folder to set as img attribute
    return 'assets/img/Tiles/' + id.toUpperCase() + '.png';
  };

  var validPlacement = function(tile) {
    var canPlace = 0, northernTile, southernTile, easternTile, westernTile;

    ($scope.grid[tile.y-1] !== undefined) &&
      (northernTile = $scope.grid[tile.y-1][tile.x]);

    ($scope.grid[tile.y][tile.x+1] !== undefined) &&
      (easternTile = $scope.grid[tile.y][tile.x+1]);

    ($scope.grid[tile.y][tile.x-1] !== undefined) &&
      (westernTile = $scope.grid[tile.y][tile.x-1]);

    ($scope.grid[tile.y+1] !== undefined) &&
      (southernTile = $scope.grid[tile.y+1][tile.x]);

    if (
      (northernTile !== undefined) &&
      ((northernTile === null) || (tile.features.n === northernTile.features.s)) ) {
        canPlace += 1;
    }
    if (
      (easternTile !== undefined) &&
      ((easternTile === null) || (tile.features.e === easternTile.features.w)) ) {
        canPlace += 1;
    }
    if (
      (southernTile !== undefined) &&
      ((southernTile === null) || (tile.features.s === southernTile.features.n)) ) {
        canPlace += 1;
    }
    if (
      (westernTile !== undefined) &&
      ((westernTile === null) || (tile.features.w === westernTile.features.e)) ) {
        canPlace += 1;
    }

    if (
      northernTile === null &&
      easternTile  === null &&
      westernTile  === null &&
      southernTile === null ) {
        return false;
    } else {
      return canPlace === 4;
    }
  };

  // These functions should be moved into a factory/service
  var updateGrid = function(x, y, tile) {
    $scope.grid[y][x] = tile;
    // console.log($scope.grid[y]);
  };

  var cellAlreadyExists = function(x, y) {
    return $scope.grid[y][x] !== null;
  };

  var setCell = function(tile) {
    var id = '#' + 'x-' + tile.x + '-y-' + tile.y;
    angular.element(document).ready(function() {
      var domElement = angular.element(document.querySelector(id));
      domElement.css('background-size', 'contain');
      domElement.css('background-image', 'url(' + tile.img + ')');
      domElement.css('transform', 'rotate(' + tile.orientation*90 + 'deg)');
    });
  };

  var placeInitialTile = function() {
    var x = $scope.grid.length/2, y = $scope.grid.length/2;
    // var x = 0, y = 0;
    var DTile = new TileModel({
      x: x,
      y: y,
      id: 'd',
      features: {
        n: 'city',
        e: 'road',
        w: 'road',
        s: 'grass'
      },
      orientation: 0
    });
    updateGrid(x, y, DTile);
    setCell(DTile);
  };

  // Initialize game board
  $scope.init();
});
<|endoftext|>


<commit_before>angular.module('zeus.user', [])
  .controller('UserController', function($scope, User, $routeParams) {
    $scope.username = "wilson.palooza4";
    // $scope.userId = User.getUserId($scope.username)

    $scope.profilePic = "https://lh3.googleusercontent.com/-kKTmPYr4dZI/AAAAAAAAAAI/AAAAAAAAAMw/D7Ak_C3TSWY/photo.jpg";
    $scope.email = "hardcoded@email.com";
    $scope.reviews = {}; //or [];
    $scope.favorites = {}; // or [];

    var getUserReviews = function () {
      User.getUserReviews($scope.username) //username will change, so probably better to pass user id here
        .then(function(reviews) {
          console.log('------------------');
          console.log(reviews);
          $scope.reviews = reviews.data;

        });
    };
    getUserReviews();

    var getUserFavorites = function() {
      User.getUserFavorites($scope.username)
        .then(function(favorites) {
          $scope.favorites = favorites.data;
        });
    };
    getUserFavorites();
  });<commit_msg>- Uses getUserId to populate $scope variables for user based on username in routeParams<commit_after>angular.module('zeus.user', [])
  .controller('UserController', function($scope, User, $routeParams) {
    console.log('user page loaded');
    $scope.username = $routeParams.username;

    //set up user information based on username given in route
    User.getUserId($routeParams.username)
      .then(function(user){
        var userObj = user;
        console.log('--------- userObj -------');
        console.log(userObj);
        $scope.userId = userObj._id;
        $scope.profilePic = userObj.profilePicLink;
        $scope.email = userObj.email;
        $scope.favorites = userObj.favorites;
      });

    var getUserReviews = function () {
      User.getUserReviews($scope.username) //username will change, so probably better to pass user id here
        .then(function(reviews) {
          $scope.reviews = reviews.data;
        });
    };
    getUserReviews();

    var getUserFavorites = function() {
      User.getUserFavorites($scope.username)
        .then(function(favorites) {
          $scope.favorites = favorites.data;
        });
    };
    getUserFavorites();
  });<|endoftext|>


<commit_before>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// NAMESPACE //

/**
* Top-level namespace.
*
* @namespace string
*/
var string = {};

/**
* @name capitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/capitalize}
*/
setReadOnly( string, 'capitalize', require( '@stdlib/string/capitalize' ) );

/**
* @name endsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ends-with}
*/
setReadOnly( string, 'endsWith', require( '@stdlib/string/ends-with' ) );

/**
* @name lpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lpad}
*/
setReadOnly( string, 'lpad', require( '@stdlib/string/left-pad' ) );

/**
* @name ltrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ltrim}
*/
setReadOnly( string, 'ltrim', require( '@stdlib/string/left-trim' ) );

/**
* @name lowercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lowercase}
*/
setReadOnly( string, 'lowercase', require( '@stdlib/string/lowercase' ) );

/**
* @name pad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/pad}
*/
setReadOnly( string, 'pad', require( '@stdlib/string/pad' ) );

/**
* @name removeInterpunctuation
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-interpunctuation}
*/
setReadOnly( string, 'removeInterpunctuation', require( '@stdlib/string/remove-interpunctuation' ) );

/**
* @name repeat
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/repeat}
*/
setReadOnly( string, 'repeat', require( '@stdlib/string/repeat' ) );

/**
* @name replace
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/replace}
*/
setReadOnly( string, 'replace', require( '@stdlib/string/replace' ) );

/**
* @name rpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-pad}
*/
setReadOnly( string, 'rpad', require( '@stdlib/string/right-pad' ) );

/**
* @name rtrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-trim}
*/
setReadOnly( string, 'rtrim', require( '@stdlib/string/right-trim' ) );

/**
* @name startsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/starts-with}
*/
setReadOnly( string, 'startsWith', require( '@stdlib/string/starts-with' ) );

/**
* @name trim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/trim}
*/
setReadOnly( string, 'trim', require( '@stdlib/string/trim' ) );

/**
* @name uncapitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uncapitalize}
*/
setReadOnly( string, 'uncapitalize', require( '@stdlib/string/uncapitalize' ) );

/**
* @name uppercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uppercase}
*/
setReadOnly( string, 'uppercase', require( '@stdlib/string/uppercase' ) );

// EXPORTS //

module.exports = string;
<commit_msg>Fix require statement<commit_after>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// NAMESPACE //

/**
* Top-level namespace.
*
* @namespace string
*/
var string = {};

/**
* @name capitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/capitalize}
*/
setReadOnly( string, 'capitalize', require( '@stdlib/string/capitalize' ) );

/**
* @name endsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ends-with}
*/
setReadOnly( string, 'endsWith', require( '@stdlib/string/ends-with' ) );

/**
* @name lpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lpad}
*/
setReadOnly( string, 'lpad', require( '@stdlib/string/left-pad' ) );

/**
* @name ltrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ltrim}
*/
setReadOnly( string, 'ltrim', require( '@stdlib/string/left-trim' ) );

/**
* @name lowercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lowercase}
*/
setReadOnly( string, 'lowercase', require( '@stdlib/string/lowercase' ) );

/**
* @name pad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/pad}
*/
setReadOnly( string, 'pad', require( '@stdlib/string/pad' ) );

/**
* @name removePunctuation
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-punctuation}
*/
setReadOnly( string, 'removePunctuation', require( '@stdlib/string/remove-punctuation' ) );

/**
* @name repeat
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/repeat}
*/
setReadOnly( string, 'repeat', require( '@stdlib/string/repeat' ) );

/**
* @name replace
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/replace}
*/
setReadOnly( string, 'replace', require( '@stdlib/string/replace' ) );

/**
* @name rpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-pad}
*/
setReadOnly( string, 'rpad', require( '@stdlib/string/right-pad' ) );

/**
* @name rtrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-trim}
*/
setReadOnly( string, 'rtrim', require( '@stdlib/string/right-trim' ) );

/**
* @name startsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/starts-with}
*/
setReadOnly( string, 'startsWith', require( '@stdlib/string/starts-with' ) );

/**
* @name trim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/trim}
*/
setReadOnly( string, 'trim', require( '@stdlib/string/trim' ) );

/**
* @name uncapitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uncapitalize}
*/
setReadOnly( string, 'uncapitalize', require( '@stdlib/string/uncapitalize' ) );

/**
* @name uppercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uppercase}
*/
setReadOnly( string, 'uppercase', require( '@stdlib/string/uppercase' ) );

// EXPORTS //

module.exports = string;
<|endoftext|>


<commit_before>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace string
*/
var string = {};

/**
* @name capitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/capitalize}
*/
setReadOnly( string, 'capitalize', require( '@stdlib/string/capitalize' ) );

/**
* @name endsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ends-with}
*/
setReadOnly( string, 'endsWith', require( '@stdlib/string/ends-with' ) );

/**
* @name lpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lpad}
*/
setReadOnly( string, 'lpad', require( '@stdlib/string/left-pad' ) );

/**
* @name ltrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ltrim}
*/
setReadOnly( string, 'ltrim', require( '@stdlib/string/left-trim' ) );

/**
* @name lowercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lowercase}
*/
setReadOnly( string, 'lowercase', require( '@stdlib/string/lowercase' ) );

/**
* @name pad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/pad}
*/
setReadOnly( string, 'pad', require( '@stdlib/string/pad' ) );

/**
* @name removePunctuation
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-punctuation}
*/
setReadOnly( string, 'removePunctuation', require( '@stdlib/string/remove-punctuation' ) );

/**
* @name removeUTF8BOM
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-utf-8-bom}
*/
setReadOnly( string, 'removeUTF8BOM', require( '@stdlib/string/remove-utf-8-bom' ) );

/**
* @name repeat
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/repeat}
*/
setReadOnly( string, 'repeat', require( '@stdlib/string/repeat' ) );

/**
* @name replace
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/replace}
*/
setReadOnly( string, 'replace', require( '@stdlib/string/replace' ) );

/**
* @name reverse
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/reverse}
*/
setReadOnly( string, 'reverse', require( '@stdlib/string/reverse' ) );

/**
* @name rpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-pad}
*/
setReadOnly( string, 'rpad', require( '@stdlib/string/right-pad' ) );

/**
* @name rtrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-trim}
*/
setReadOnly( string, 'rtrim', require( '@stdlib/string/right-trim' ) );

/**
* @name startsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/starts-with}
*/
setReadOnly( string, 'startsWith', require( '@stdlib/string/starts-with' ) );

/**
* @name trim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/trim}
*/
setReadOnly( string, 'trim', require( '@stdlib/string/trim' ) );

/**
* @name uncapitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uncapitalize}
*/
setReadOnly( string, 'uncapitalize', require( '@stdlib/string/uncapitalize' ) );

/**
* @name uppercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uppercase}
*/
setReadOnly( string, 'uppercase', require( '@stdlib/string/uppercase' ) );

// EXPORTS //

module.exports = string;
<commit_msg>Update namespace<commit_after>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace string
*/
var string = {};

/**
* @name capitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/capitalize}
*/
setReadOnly( string, 'capitalize', require( '@stdlib/string/capitalize' ) );

/**
* @name endsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ends-with}
*/
setReadOnly( string, 'endsWith', require( '@stdlib/string/ends-with' ) );

/**
* @name lpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lpad}
*/
setReadOnly( string, 'lpad', require( '@stdlib/string/left-pad' ) );

/**
* @name ltrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/ltrim}
*/
setReadOnly( string, 'ltrim', require( '@stdlib/string/left-trim' ) );

/**
* @name lowercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/lowercase}
*/
setReadOnly( string, 'lowercase', require( '@stdlib/string/lowercase' ) );

/**
* @name pad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/pad}
*/
setReadOnly( string, 'pad', require( '@stdlib/string/pad' ) );

/**
* @name removeFirst
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-first}
*/
setReadOnly( string, 'removeFirst', require( '@stdlib/string/remove-first' ) );

/**
* @name removePunctuation
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-punctuation}
*/
setReadOnly( string, 'removePunctuation', require( '@stdlib/string/remove-punctuation' ) );

/**
* @name removeUTF8BOM
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/remove-utf-8-bom}
*/
setReadOnly( string, 'removeUTF8BOM', require( '@stdlib/string/remove-utf-8-bom' ) );

/**
* @name repeat
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/repeat}
*/
setReadOnly( string, 'repeat', require( '@stdlib/string/repeat' ) );

/**
* @name replace
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/replace}
*/
setReadOnly( string, 'replace', require( '@stdlib/string/replace' ) );

/**
* @name reverse
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/reverse}
*/
setReadOnly( string, 'reverse', require( '@stdlib/string/reverse' ) );

/**
* @name rpad
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-pad}
*/
setReadOnly( string, 'rpad', require( '@stdlib/string/right-pad' ) );

/**
* @name rtrim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/right-trim}
*/
setReadOnly( string, 'rtrim', require( '@stdlib/string/right-trim' ) );

/**
* @name startsWith
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/starts-with}
*/
setReadOnly( string, 'startsWith', require( '@stdlib/string/starts-with' ) );

/**
* @name trim
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/trim}
*/
setReadOnly( string, 'trim', require( '@stdlib/string/trim' ) );

/**
* @name uncapitalize
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uncapitalize}
*/
setReadOnly( string, 'uncapitalize', require( '@stdlib/string/uncapitalize' ) );

/**
* @name uppercase
* @memberof string
* @readonly
* @type {Function}
* @see {@link module:@stdlib/string/uppercase}
*/
setReadOnly( string, 'uppercase', require( '@stdlib/string/uppercase' ) );

// EXPORTS //

module.exports = string;
<|endoftext|>


<commit_before>// Math
function absorbance(calib, transmittance) {
  return (calib - transmittance) / calib;
}
function duty_cycle_to_percent(duty_cycle) {
  return (duty_cycle * 100).toFixed(0);
}
function convert_timezones(datestr) {
  var date = new Date(datestr);
  return date.toString();
}

// Strings
function time_text(data) {
  if (data) {
    return "Updated " + convert_timezones(data[0]) + ".";
  }
}
function start_text(data) {
  if (data) {
    return "Fermenter started at: " + convert_timezones(data);
  } else {
    return "Fermenter has not yet started.";
  }
}
function stop_text(data, since) {
  if (data) {
    $('form#startbutton').show();
    $('form#stopbutton').hide();
    return "Fermenter stopped at: " + convert_timezones(data);
  } else {
    $('form#startbutton').hide();
    $('form#stopbutton').show();
    return "Fermenter has been running for " + since.toFixed(2) + " hours.";
  }
}
function now_text(data) {
  return "Last update: " + data;
}
function temp_text(data) {
  if (data) {
    return "Vessel temperature: " + data[1].toFixed(2) + " °C";
  } else {
    return "Vessel temperature will be updated soon!";
  }
}
function heater_text(data) {
  if (data) {
    return "Heater duty cycle: " + duty_cycle_to_percent(data[1]) + " %";
  } else {
    return "Heater duty cycle will be updated soon!";
  }
}
function impeller_text(data) {
  if (data) {
    return "Impeller duty cycle: " + duty_cycle_to_percent(data[1]) + " %";
  } else {
    return "Impeller duty cycle will be updated soon!";
  }
}
function ambient_text(data) {
  if (data) {
    return "Ambient light: " + ~~(data[1]);
  } else {
    return "Ambient light will be updated soon!";
  }
}
function red_text(red_calib, data) {
  if (data) {
    return "OD: " + absorbance(red_calib, data[1]).toFixed(2);
  } else {
    return "OD will be updated soon!";
  }
}
function green_text(green_calib, data) {
  if (data) {
    return "Green absorbance: " + absorbance(green_calib, data[1]).toFixed(2);
  } else {
    return "Green absorbance will be updated soon!";
  }
}

$(document).ready(function () {
  namespace = "/socket";
  var socket = io.connect("http://" + document.domain + ":" + location.port + namespace);
  socket.on("connect", function () {
    socket.emit("socket event", {data: "Successful connection!"});
  });
  socket.on("stats update", function (msg) {
    $("#start").text(start_text(msg.start));
    $("#stop").text(stop_text(msg.stop, msg.since));
    $("#now").text(now_text(msg.now));
    $('#impeller').text(impeller_text(msg.impeller));
    $('#temp_update_time').text(time_text(msg.temp));
    $('#temp').text(temp_text(msg.temp));
    $('#heater').text(heater_text(msg.heater));
    $('#optics_update_time').text(time_text(msg.optics.ambient));
    $('#ambient').text(ambient_text(msg.optics.ambient));
    $('#red').text(red_text(msg.optics.calibration.red, msg.optics.red));
    $('#green').text(green_text(msg.optics.calibration.green, msg.optics.green));
  });
  socket.on("optics plot update", function(msg) {
    $('#optics_plot_cache').attr("data", "/plots/optics?" + msg.time);
    $('#environ_plot_cache').attr("data", "/plots/environ?" + msg.time);
  });
  socket.on("temp plot update", function(msg) {
    $('#temp_plot_cache').attr("data", "/plots/temp?" + msg.time);
  });
  socket.on("duty cycles plot update", function(msg) {
    $('#duty_cycles_plot_cache').attr("data", "/plots/duty_cycles?" + msg.time);
  });
  document.getElementById('optics_plot_cache').addEventListener("load", function () {
    $('#optics_plot').attr("data", $('#optics_plot_cache').attr("data"));
  });
  document.getElementById('environ_plot_cache').addEventListener("load", function () {
    $('#environ_plot').attr("data", $('#environ_plot_cache').attr("data"));
  });
  document.getElementById('temp_plot_cache').addEventListener("load", function () {
    $('#temp_plot').attr("data", $('#temp_plot_cache').attr("data"));
  });
  document.getElementById('duty_cycles_plot_cache').addEventListener("load", function () {
    $('#duty_cycles_plot').attr("data", $('#duty_cycles_plot_cache').attr("data"));
  });
  $('form#startbutton').submit(function(event) {
    socket.emit("fermenter start", {});
    return false;
  });
  $('form#stopbutton').submit(function(event) {
    socket.emit("fermenter stop", {});
    return false;
  });
  $('form#impellermenu').change(function(event) {
    socket.emit("impeller set", {data: $('#impellerduty').val()});
    return false;
  });
  $('form#recalibrate').submit(function(event) {
    socket.emit("recalibrate optics", {});
    return false;
  });
});
<commit_msg>Found one more timezone adjustment fix.<commit_after>// Math
function absorbance(calib, transmittance) {
  return (calib - transmittance) / calib;
}
function duty_cycle_to_percent(duty_cycle) {
  return (duty_cycle * 100).toFixed(0);
}
function convert_timezones(datestr) {
  var date = new Date(datestr);
  return date.toString();
}

// Strings
function time_text(data) {
  if (data) {
    return "Updated: " + convert_timezones(data[0]) + ".";
  }
}
function start_text(data) {
  if (data) {
    return "Fermenter started at: " + convert_timezones(data);
  } else {
    return "Fermenter has not yet started.";
  }
}
function stop_text(data, since) {
  if (data) {
    $('form#startbutton').show();
    $('form#stopbutton').hide();
    return "Fermenter stopped at: " + convert_timezones(data);
  } else {
    $('form#startbutton').hide();
    $('form#stopbutton').show();
    return "Fermenter has been running for " + since.toFixed(2) + " hours.";
  }
}
function now_text(data) {
  return "Now: " + convert_timezones(data);
}
function temp_text(data) {
  if (data) {
    return "Vessel temperature: " + data[1].toFixed(2) + " °C";
  } else {
    return "Vessel temperature will be updated soon!";
  }
}
function heater_text(data) {
  if (data) {
    return "Heater duty cycle: " + duty_cycle_to_percent(data[1]) + " %";
  } else {
    return "Heater duty cycle will be updated soon!";
  }
}
function impeller_text(data) {
  if (data) {
    return "Impeller duty cycle: " + duty_cycle_to_percent(data[1]) + " %";
  } else {
    return "Impeller duty cycle will be updated soon!";
  }
}
function ambient_text(data) {
  if (data) {
    return "Ambient light: " + ~~(data[1]);
  } else {
    return "Ambient light will be updated soon!";
  }
}
function red_text(red_calib, data) {
  if (data) {
    return "OD: " + absorbance(red_calib, data[1]).toFixed(2);
  } else {
    return "OD will be updated soon!";
  }
}
function green_text(green_calib, data) {
  if (data) {
    return "Green absorbance: " + absorbance(green_calib, data[1]).toFixed(2);
  } else {
    return "Green absorbance will be updated soon!";
  }
}

$(document).ready(function () {
  namespace = "/socket";
  var socket = io.connect("http://" + document.domain + ":" + location.port + namespace);
  socket.on("connect", function () {
    socket.emit("socket event", {data: "Successful connection!"});
  });
  socket.on("stats update", function (msg) {
    $("#start").text(start_text(msg.start));
    $("#stop").text(stop_text(msg.stop, msg.since));
    $("#now").text(now_text(msg.now));
    $('#impeller').text(impeller_text(msg.impeller));
    $('#temp_update_time').text(time_text(msg.temp));
    $('#temp').text(temp_text(msg.temp));
    $('#heater').text(heater_text(msg.heater));
    $('#optics_update_time').text(time_text(msg.optics.ambient));
    $('#ambient').text(ambient_text(msg.optics.ambient));
    $('#red').text(red_text(msg.optics.calibration.red, msg.optics.red));
    $('#green').text(green_text(msg.optics.calibration.green, msg.optics.green));
  });
  socket.on("optics plot update", function(msg) {
    $('#optics_plot_cache').attr("data", "/plots/optics?" + msg.time);
    $('#environ_plot_cache').attr("data", "/plots/environ?" + msg.time);
  });
  socket.on("temp plot update", function(msg) {
    $('#temp_plot_cache').attr("data", "/plots/temp?" + msg.time);
  });
  socket.on("duty cycles plot update", function(msg) {
    $('#duty_cycles_plot_cache').attr("data", "/plots/duty_cycles?" + msg.time);
  });
  document.getElementById('optics_plot_cache').addEventListener("load", function () {
    $('#optics_plot').attr("data", $('#optics_plot_cache').attr("data"));
  });
  document.getElementById('environ_plot_cache').addEventListener("load", function () {
    $('#environ_plot').attr("data", $('#environ_plot_cache').attr("data"));
  });
  document.getElementById('temp_plot_cache').addEventListener("load", function () {
    $('#temp_plot').attr("data", $('#temp_plot_cache').attr("data"));
  });
  document.getElementById('duty_cycles_plot_cache').addEventListener("load", function () {
    $('#duty_cycles_plot').attr("data", $('#duty_cycles_plot_cache').attr("data"));
  });
  $('form#startbutton').submit(function(event) {
    socket.emit("fermenter start", {});
    return false;
  });
  $('form#stopbutton').submit(function(event) {
    socket.emit("fermenter stop", {});
    return false;
  });
  $('form#impellermenu').change(function(event) {
    socket.emit("impeller set", {data: $('#impellerduty').val()});
    return false;
  });
  $('form#recalibrate').submit(function(event) {
    socket.emit("recalibrate optics", {});
    return false;
  });
});
<|endoftext|>


<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2012 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of TeapotNet.                                     *
 *                                                                       *
 *   TeapotNet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   TeapotNet is distributed in the hope that it will be useful, but    *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the        *
 *   GNU Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with TeapotNet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

if(!String.escape) {
	String.prototype.escape = function() {
		return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/([^ ]{50})/g, "$1\- ");
		// Last "replace" adds dash and space when a single words has more than 50 chars
	}
}

String.prototype.smileys = function() {
	var smileys = {
		':)' : 'smile.png\" height=15 width=24',
		':-)' : 'smile.png\" height=15 width=24',
		':-('  : 'sad.png\" height=15 width=24',
		':('  : 'sad.png\" height=15 width=24',
		':\'-('  : 'sad.png\" height=15 width=24',
		':S'  : 'embarrassed.png\" height=17 width=26',
		':@'  : 'angry.png\" height=24 width=36'
	}, url = "\"/", patterns = [], metachars = /[[\]{}()*+?.\\|^$\-,&#\s]/g;

	for (var i in smileys)
	{
		if (smileys.hasOwnProperty(i))
		{
			patterns.push('('+i.replace(metachars, "\\$&")+')');
		}
	}

  	return this.replace(new RegExp(patterns.join('|'),'g'), function (match)
		{
	   		 return typeof smileys[match] != 'undefined' ?
		   	'' :
		   	match;
 		 });

}

if(!String.linkify) {
	String.prototype.linkify = function() {

		// http://, https://, ftp://
		var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9\-+&@#\/%?=~_|!:,.;]*[a-z0-9\-+&@#\/%=~_|]/gim;

		// www. without http:// or https://
		var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;

		// Email addresses
		var emailAddressPattern = /[a-zA-Z0-9_\-]+@[a-zA-Z0-9_\-]+?(?:\.[a-zA-Z]{2,6})+/gim;

		return this
		    .replace(urlPattern, '$&')
		    .replace(pseudoUrlPattern, '$1$2')
		    .replace(emailAddressPattern, '$&');
      };
}

if(!String.capitalize) {
	String.prototype.capitalize = function () {
		return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
	};
}

if(!String.contains) {
	String.prototype.contains = function(it) {
		return this.indexOf(it) != -1;
	};
}

function formatTime(timestamp) {
	var date = new Date(timestamp*1000);
	return date.toLocaleDateString() + " " + date.toLocaleTimeString();
}

function popup(url, redirect) {

	w = window.open(url, "_blank", "status=0,toolbar=0,scrollbars=0,menubar=0,directories=0,resizeable=1,width=310,height=500");
	if(window.focus) w.focus();
	if(typeof redirect !== 'undefined') document.location.href = redirect;
	return false;
}

function transition(selector, html) {

	var elem = $(selector);
	if(elem.html() == html) return elem;
	return elem.fadeOut('slow', function() {
	  	$(this).html(html);
		$(this).fadeIn('slow');
	});
}

function resizeContent() {

	var content = $('#content');
	if(content.length)
	{
		var wh = $(window).height();
		var ct = content.offset().top;
		var h = Math.max(wh - ct - 40, 240);
		content.height(h);
	}

	var chatpanel = $('#chatpanel');
	var chatpanelmessage = $('#chatpanel .message');
	if(chatpanel.length && chatpanelmessage.length)
        {
		chatpanelmessage.height(Math.max(chatpanel.height()-10, 20));
        }
}

function displayLoading()
{
	if($(document.documentElement).hasClass('loading'))
		$(document.documentElement).addClass('animloading');
}

if (document.documentElement) {
	$(document.documentElement).addClass('loading');
	setTimeout(displayLoading, 300);
}

$(document).ready( function() {
	if($(document.documentElement).hasClass('loading')) {
		$(document.documentElement).removeClass('loading');
		if($(document.documentElement).hasClass('animloading')) {
			  $(document.documentElement).removeClass('animloading');
			  $(document.body).hide();
			  $(document.body).fadeIn(300);
		}
	}
	resizeContent();

	$('table.files tr').css('cursor', 'pointer').click(function() {
		window.location.href = $(this).find('a').attr('href');
	});

	$('table.contacts tr').css('cursor', 'pointer').click(function() {
		window.location.href = $(this).find('a').attr('href');
	});

	$('table.menu tr').css('cursor', 'pointer').click(function() {
		window.location.href = $(this).find('a').attr('href');
	});
});

$(window).resize( function() {
	resizeContent();
});

var MessageSound;
if((new Audio()).canPlayType('audio/ogg; codecs="vorbis"') != "") MessageSound = new Audio('/message.ogg');
else MessageSound = new Audio('/message.m4a');
if(MessageSound != null) MessageSound.load();

function playMessageSound() {
	if(MessageSound != null) MessageSound.play();
}

function setCallback(url, period, callback) {

	$.ajax({
		url: url,
		dataType: 'json',
		timeout: period,
		success: function(data) {
			callback(data);
		}
	})
	.done(function(data) {
		setTimeout(function() {
			setCallback(url, period, callback);
		}, period);
	})
	.fail(function(jqXHR, textStatus) {
		setTimeout(function() {
			setCallback(url, period, callback);
		}, period);
	});
}

function setMessagesReceiver(url, object) {

	$(window).blur(function() {
		$(object).find('.message').addClass('oldmessage');
	});

	setMessagesReceiverRec(url, object, '');
}

var BaseDocumentTitle = document.title;
var NbNewMessages = 0;

$(window).focus(function() {
	document.title = BaseDocumentTitle;
	NbNewMessages = 0;
});

$(window).blur(function() {
	document.title = BaseDocumentTitle;
	NbNewMessages = 0;
});

var stopBool = false;

function updateMessagesReceiver(url, object) {
	stopBool = true;
	$(object).html("");
	setTimeout(function() {
		setMessagesReceiver(url, object);
		stopBool = false;
	}, 100);
}

function clickedReply(id)
{
	$('#'+id.id).css('display','block');
	$('textarea[name=\"'+id.id+'\"]').focus();
}

function submitReply(object, idParent)
{
	post(object, idParent);
	return false;
}

var title = document.title;

var saveData;

function displayContacts(url, period, object) {

	setCallback(url, period, function(data)
	{

		if(data!=null)
		{
				saveData = data;
				var totalmessages = 0;
				var play = false;
				var visible = false;
				$.each(data, function(uname, info)
				{
					if ($('#contact_'+info.name).length == 0) // if div does not exist
					{
						$(object).append('
'+info.name+'

'+info.name+'@'+info.tracker+'  Files Chat
');
						$('#InfosContact_'+uname).hide();
					}

					function displayInfosContact(uname)
					{
						if(visible)
						{
							$('#InfosContact_'+uname).slideUp();
							timeout = setTimeout(function() { visible = false; }, 200);
						}
						else
						{
							$('#InfosContact_'+uname).slideDown();
							timeout = setTimeout(function() { visible = true; }, 200);
						}
					}
					/*document.getElementById('contact_'+uname).onmouseover = function()
					{
						displayInfosContact(uname);
					}*/
					document.getElementById('contact_'+uname).onclick = function()
					{
						displayInfosContact(uname)
					}
					$('#contact_'+uname).attr('class', info.status);
					//document.getElementById('contact_'+uname).classList.add(info.status);
					transition($('#contact_'+uname+' .status'), info.status.capitalize());
					var count = parseInt(info.messages);
					var tmp = '';
					if(count != 0) tmp = ' ('+count+')';
					transition($('#contact_'+uname+' .messagescount'), tmp);
					totalmessages+= count;
					if(info.newmessages == 'true') play = true;
				});
				if(totalmessages != 0) document.title = title+' ('+totalmessages+')';
				else document.title = title;
				if(play) playMessageSound();

		}
		else
		{
			// TODO
		}
	});

}

function setMessagesReceiverRec(url, object, last) {

	var timeout;

	if(stopBool)
	{
		//alert('Function stopped !');
		clearTimeout(timeout);
	}

	var baseUrl = url;

	if(last != '')
	{
		if(url.contains('?')) url+= '&last=' + last;
		else url+= '?last=' + last;
	}

	$.ajax({
		url: url,
		dataType: 'json',
		timeout: 60000
	})
	.done(function(data) {
		if(data != null) {
			for(var i=0; i<data.length; i++) {
				var message = data[i];
				var id = "message_" + message.stamp;
				last = message.stamp;

				if(message.public)
				{
					var idReply = "replyTo" + id;

					if(!message.parent)
					{
						$(object).prepend('

 '+message.headers.from.escape()+' '+message.content.escape().smileys().linkify()+'
 '+formatTime(message.time).escape()+'

');
					}
					else
					{
						$('#'+message.parent).parent().append('
 '+message.headers.from.escape()+' '+message.content.escape().smileys().linkify()+'
 '+formatTime(message.time).escape()+'
');
						$('#'+id).addClass('childmessage');
					}

					$('#'+id).addClass('statusdisplay');
					if(!message.incoming) $('#'+id).addClass('me');

					// Reply form
					$('#'+id).parent().append('
<form name=\"formReplyTo'+id+'\" action="#" method="post" enctype="application/x-www-form-urlencoded"><textarea class="replyinput" name=\"replyTo'+id+'\"></textarea></form>
');

				}
				else
				{
					$(object).append('
'+formatTime(message.time).escape()+' '+message.headers.from.escape()+' '+message.content.escape().smileys().linkify()+'
');
					if(message.incoming && !message.isread) NbNewMessages++;
					if(message.isread) $('#'+id).addClass('oldmessage');
					if(message.incoming) $('#'+id).addClass('in');
					else $('#'+id).addClass('out');
$(object).scrollTop($(object)[0].scrollHeight);
				}
			}

			if(NbNewMessages) {
				document.title = '(' + NbNewMessages + ') ' + BaseDocumentTitle;
				playMessageSound();
			}
		}

		timeout = setTimeout(function() {
			setMessagesReceiverRec(baseUrl, object, last);
		}, 1000);

	})
	.fail(function(jqXHR, textStatus) {
		timeout = setTimeout(function() {
			setMessagesReceiverRec(baseUrl, object, last);
		}, 1000);

	});

	if(stopBool)
	{
		//alert('Function stopped !');
		timeout = setTimeout(function() {clearTimeout(timeout);}, 1000); // ugly but tricks slowness of javascript
	}
}
<commit_msg>Removed slow animation for mobile devices<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2012 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of TeapotNet.                                     *
 *                                                                       *
 *   TeapotNet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   TeapotNet is distributed in the hope that it will be useful, but    *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the        *
 *   GNU Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with TeapotNet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

if(!String.escape) {
	String.prototype.escape = function() {
		return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/([^ ]{50})/g, "$1\- ");
		// Last "replace" adds dash and space when a single words has more than 50 chars
	}
}

String.prototype.smileys = function() {
	var smileys = {
		':)' : 'smile.png\" height=15 width=24',
		':-)' : 'smile.png\" height=15 width=24',
		':-('  : 'sad.png\" height=15 width=24',
		':('  : 'sad.png\" height=15 width=24',
		':\'-('  : 'sad.png\" height=15 width=24',
		':S'  : 'embarrassed.png\" height=17 width=26',
		':@'  : 'angry.png\" height=24 width=36'
	}, url = "\"/", patterns = [], metachars = /[[\]{}()*+?.\\|^$\-,&#\s]/g;

	for (var i in smileys)
	{
		if (smileys.hasOwnProperty(i))
		{
			patterns.push('('+i.replace(metachars, "\\$&")+')');
		}
	}

  	return this.replace(new RegExp(patterns.join('|'),'g'), function (match)
		{
	   		 return typeof smileys[match] != 'undefined' ?
		   	'' :
		   	match;
 		 });

}

if(!String.linkify) {
	String.prototype.linkify = function() {

		// http://, https://, ftp://
		var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9\-+&@#\/%?=~_|!:,.;]*[a-z0-9\-+&@#\/%=~_|]/gim;

		// www. without http:// or https://
		var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;

		// Email addresses
		var emailAddressPattern = /[a-zA-Z0-9_\-]+@[a-zA-Z0-9_\-]+?(?:\.[a-zA-Z]{2,6})+/gim;

		return this
		    .replace(urlPattern, '$&')
		    .replace(pseudoUrlPattern, '$1$2')
		    .replace(emailAddressPattern, '$&');
      };
}

if(!String.capitalize) {
	String.prototype.capitalize = function () {
		return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
	};
}

if(!String.contains) {
	String.prototype.contains = function(it) {
		return this.indexOf(it) != -1;
	};
}

function formatTime(timestamp) {
	var date = new Date(timestamp*1000);
	return date.toLocaleDateString() + " " + date.toLocaleTimeString();
}

function popup(url, redirect) {

	w = window.open(url, "_blank", "status=0,toolbar=0,scrollbars=0,menubar=0,directories=0,resizeable=1,width=310,height=500");
	if(window.focus) w.focus();
	if(typeof redirect !== 'undefined') document.location.href = redirect;
	return false;
}

function transition(selector, html) {

	var elem = $(selector);
	if(elem.html() == html) return elem;
	return elem.fadeOut('slow', function() {
	  	$(this).html(html);
		$(this).fadeIn('slow');
	});
}

function resizeContent() {

	var content = $('#content');
	if(content.length)
	{
		var wh = $(window).height();
		var ct = content.offset().top;
		var h = Math.max(wh - ct - 40, 240);
		content.height(h);
	}

	var chatpanel = $('#chatpanel');
	var chatpanelmessage = $('#chatpanel .message');
	if(chatpanel.length && chatpanelmessage.length)
        {
		chatpanelmessage.height(Math.max(chatpanel.height()-10, 20));
        }
}

function displayLoading()
{
	if($(document.documentElement).hasClass('loading'))
		$(document.documentElement).addClass('animloading');
}

if (document.documentElement) {
	$(document.documentElement).addClass('loading');
	setTimeout(displayLoading, 300);
}

$(document).ready( function() {
	if($(document.documentElement).hasClass('loading')) {
		$(document.documentElement).removeClass('loading');
		if($(document.documentElement).hasClass('animloading')) {
			  $(document.documentElement).removeClass('animloading');
			  $(document.body).hide();
			  $(document.body).fadeIn(300);
		}
	}
	resizeContent();

	$('table.files tr').css('cursor', 'pointer').click(function() {
		window.location.href = $(this).find('a').attr('href');
	});

	$('table.contacts tr').css('cursor', 'pointer').click(function() {
		window.location.href = $(this).find('a').attr('href');
	});

	$('table.menu tr').css('cursor', 'pointer').click(function() {
		window.location.href = $(this).find('a').attr('href');
	});
});

$(window).resize( function() {
	resizeContent();
});

var MessageSound;
if((new Audio()).canPlayType('audio/ogg; codecs="vorbis"') != "") MessageSound = new Audio('/message.ogg');
else MessageSound = new Audio('/message.m4a');
if(MessageSound != null) MessageSound.load();

function playMessageSound() {
	if(MessageSound != null) MessageSound.play();
}

function setCallback(url, period, callback) {

	$.ajax({
		url: url,
		dataType: 'json',
		timeout: period,
		success: function(data) {
			callback(data);
		}
	})
	.done(function(data) {
		setTimeout(function() {
			setCallback(url, period, callback);
		}, period);
	})
	.fail(function(jqXHR, textStatus) {
		setTimeout(function() {
			setCallback(url, period, callback);
		}, period);
	});
}

function setMessagesReceiver(url, object) {

	$(window).blur(function() {
		$(object).find('.message').addClass('oldmessage');
	});

	setMessagesReceiverRec(url, object, '');
}

var BaseDocumentTitle = document.title;
var NbNewMessages = 0;

$(window).focus(function() {
	document.title = BaseDocumentTitle;
	NbNewMessages = 0;
});

$(window).blur(function() {
	document.title = BaseDocumentTitle;
	NbNewMessages = 0;
});

var stopBool = false;

function updateMessagesReceiver(url, object) {
	stopBool = true;
	$(object).html("");
	setTimeout(function() {
		setMessagesReceiver(url, object);
		stopBool = false;
	}, 100);
}

function clickedReply(id)
{
	$('#'+id.id).css('display','block');
	$('textarea[name=\"'+id.id+'\"]').focus();
}

function submitReply(object, idParent)
{
	post(object, idParent);
	return false;
}

var title = document.title;

var saveData;

function displayContacts(url, period, object) {

	setCallback(url, period, function(data)
	{

		if(data!=null)
		{
			saveData = data;
			var totalmessages = 0;
			var play = false;
			var visible = false;
			$.each(data, function(uname, info)
			{
				if ($('#contact_'+info.name).length == 0) // if div does not exist
				{
					$(object).append('
'+info.name+'

'+info.name+'@'+info.tracker+'  Files Chat
');
					$('#InfosContact_'+uname).hide();
				}

				function displayInfosContact(uname)
				{
					if(visible)
					{
						if ($("#rightcolumn").css("width") == "320px" || $("#rightcolumn").css("width") == "700px") // No animation for tablet and mobile (too slow)
						{
							$('#InfosContact_'+uname).hide();
						}
						else
						{
						$('#InfosContact_'+uname).slideUp();
						}

						timeout = setTimeout(function() { visible = false; }, 200);
					}
					else
					{
						if ($("#rightcolumn").css("width") == "320px" || $("#rightcolumn").css("width") == "700px") // No animation for tablet and mobile (too slow)
						{
							$('#InfosContact_'+uname).show();
						}
						else
						{
						$('#InfosContact_'+uname).slideDown();
						}

						timeout = setTimeout(function() { visible = true; }, 200);
					}
				}
				/*document.getElementById('contact_'+uname).onmouseover = function()
				{
					displayInfosContact(uname);
				}*/
				document.getElementById('contact_'+uname).onclick = function()
				{
					displayInfosContact(uname)
				}
				$('#contact_'+uname).attr('class', info.status);
				//document.getElementById('contact_'+uname).classList.add(info.status);
				transition($('#contact_'+uname+' .status'), info.status.capitalize());
				var count = parseInt(info.messages);
				var tmp = '';
				if(count != 0) tmp = ' ('+count+')';
				transition($('#contact_'+uname+' .messagescount'), tmp);
				totalmessages+= count;
				if(info.newmessages == 'true') play = true;
			});
			if(totalmessages != 0) document.title = title+' ('+totalmessages+')';
			else document.title = title;
			if(play) playMessageSound();

		}
		else
		{
			// TODO
		}
	});

}

function setMessagesReceiverRec(url, object, last) {

	var timeout;

	if(stopBool)
	{
		//alert('Function stopped !');
		clearTimeout(timeout);
	}

	var baseUrl = url;

	if(last != '')
	{
		if(url.contains('?')) url+= '&last=' + last;
		else url+= '?last=' + last;
	}

	$.ajax({
		url: url,
		dataType: 'json',
		timeout: 60000
	})
	.done(function(data) {
		if(data != null) {
			for(var i=0; i<data.length; i++) {
				var message = data[i];
				var id = "message_" + message.stamp;
				last = message.stamp;

				if(message.public)
				{
					var idReply = "replyTo" + id;

					if(!message.parent)
					{
						$(object).prepend('

 '+message.headers.from.escape()+' '+message.content.escape().smileys().linkify()+'
 '+formatTime(message.time).escape()+'

');
					}
					else
					{
						$('#'+message.parent).parent().append('
 '+message.headers.from.escape()+' '+message.content.escape().smileys().linkify()+'
 '+formatTime(message.time).escape()+'
');
						$('#'+id).addClass('childmessage');
					}

					$('#'+id).addClass('statusdisplay');
					if(!message.incoming) $('#'+id).addClass('me');

					// Reply form
					$('#'+id).parent().append('
<form name=\"formReplyTo'+id+'\" action="#" method="post" enctype="application/x-www-form-urlencoded"><textarea class="replyinput" name=\"replyTo'+id+'\"></textarea></form>
');

				}
				else
				{
					$(object).append('
'+formatTime(message.time).escape()+' '+message.headers.from.escape()+' '+message.content.escape().smileys().linkify()+'
');
					if(message.incoming && !message.isread) NbNewMessages++;
					if(message.isread) $('#'+id).addClass('oldmessage');
					if(message.incoming) $('#'+id).addClass('in');
					else $('#'+id).addClass('out');
$(object).scrollTop($(object)[0].scrollHeight);
				}
			}

			if(NbNewMessages) {
				document.title = '(' + NbNewMessages + ') ' + BaseDocumentTitle;
				playMessageSound();
			}
		}

		timeout = setTimeout(function() {
			setMessagesReceiverRec(baseUrl, object, last);
		}, 1000);

	})
	.fail(function(jqXHR, textStatus) {
		timeout = setTimeout(function() {
			setMessagesReceiverRec(baseUrl, object, last);
		}, 1000);

	});

	if(stopBool)
	{
		//alert('Function stopped !');
		timeout = setTimeout(function() {clearTimeout(timeout);}, 1000); // ugly but tricks slowness of javascript
	}
}
<|endoftext|>


<commit_before>import isVirtual from './isVirtual';
import isResource from './isResource';

// check if target is the actual NaN value:
// NaN is the only value that is not equal to itself.
function isRealNaN(target) {
  return target !== target; // eslint-disable-line no-self-compare
}

export default async function evaluate(value, options = {}) {
  //console.log('evaluate', value);
  let result = value;

  if (typeof result === 'function') {
    //console.log('evaluate function');
    result = result(...(options.functionParameters || []));
    return this.evaluate(result, options);
  }

  const promiseResult = await Promise.resolve(result);
  if (promiseResult !== result && (!isRealNaN(promiseResult) || !isRealNaN(result))) {
    //console.log('evaluate promise result', promiseResult, result);
    return this.evaluate(promiseResult, options);
  }

  result = {};

  if (isVirtual(result)) {
    //console.log('evaluate virtual');
    const { result: virtualResult, webmiddle } = await this.callVirtual(result);
    if (virtualResult !== result) {
      return webmiddle.evaluate(virtualResult, options);
    }
  }

  if (!isResource(result) && options.expectResource) {
    throw new Error(`Expected a resource from ${JSON.stringify(value)}, got ${JSON.stringify(result)}`);
  }

  return result;
};
<commit_msg>Remove debug code<commit_after>import isVirtual from './isVirtual';
import isResource from './isResource';

// check if target is the actual NaN value:
// NaN is the only value that is not equal to itself.
function isRealNaN(target) {
  return target !== target; // eslint-disable-line no-self-compare
}

export default async function evaluate(value, options = {}) {
  //console.log('evaluate', value);
  let result = value;

  if (typeof result === 'function') {
    //console.log('evaluate function');
    result = result(...(options.functionParameters || []));
    return this.evaluate(result, options);
  }

  const promiseResult = await Promise.resolve(result);
  if (promiseResult !== result && (!isRealNaN(promiseResult) || !isRealNaN(result))) {
    //console.log('evaluate promise result', promiseResult, result);
    return this.evaluate(promiseResult, options);
  }

  if (isVirtual(result)) {
    //console.log('evaluate virtual');
    const { result: virtualResult, webmiddle } = await this.callVirtual(result);
    if (virtualResult !== result) {
      return webmiddle.evaluate(virtualResult, options);
    }
  }

  if (!isResource(result) && options.expectResource) {
    throw new Error(`Expected a resource from ${JSON.stringify(value)}, got ${JSON.stringify(result)}`);
  }

  return result;
};
<|endoftext|>


<commit_before>
function runCallRoulette() {
    if (!rtcninja.hasWebRTC()) {
        console.log("WebRTC is NOT supported!");
	alertify.error('Your browser does not support WebRTC');
	return;
    }

    console.log("WebRTC is supported!");
    alertify.success('Your browser supports WebRTC');

    // CallRoulette!

    function CallRoulette(view) {
        if (!view) {
            throw Error('invalid view element!');
        }

        this._view = view;

        this._localStream = null;
        this._remoteStream = null;

        this._state = 'stopped';

        this._conn = null;
        this._ws = null;

        this.onstatechanged = null;
    }

    // Public API

    CallRoulette.prototype.getState = function() {
        var self = this;

        return self._state;
    }

    CallRoulette.prototype.start = function() {
        var self = this;

        console.log('Start');
        self._setState('starting');

        rtcninja.getUserMedia({audio: true, video: true},
            // success
            function(stream) {
                self._localStream = stream;
                console.log("Local media stream acquired successfully");
                rtcninja.attachMediaStream(self._view, stream);
                self._ws = new WebSocket("ws://" + document.location.host + "/ws", "callroulette");
                self._ws.onmessage = function(event) {
                    self._processMessages(event.data);
                };
                self._ws.onopen = function(event) {
                    console.log('WS connected');
                    self._setState('started');
                };
                self._ws.onclose = function(event) {
                    console.log('WS closedi');
                    self.stop();
                }
            },
            // error
            function(error) {
	        alertify.error("Error getting local media stream: " + error);
                self.stop();
            });
    }

    CallRoulette.prototype.stop = function() {
        var self = this;

        if (self._state === 'stopped') {
            return;
        }

        console.log('Stop');
        self._setState('stopped');

        if (self._ws !== null) {
            self._ws.close();
            self._ws = null;
        }

        if (self._localStream !== null) {
            rtcninja.closeMediaStream(self._localStream);
            self._localStream = null;
        }

        if (self._remoteStream !== null) {
            rtcninja.closeMediaStream(self._remoteStream);
            self._remoteStream = null;
        }

        if (self._conn !== null) {
            self._conn.close();
            self._conn = null;
        }
    }

    // Private API

    CallRoulette.prototype._setState = function(state) {
        var self = this;
        var prevState = self._state;

        if (prevState === state) {
            return;
        }

        self._state = state;
        if (typeof self.onstatechanged === 'function') {
            window.setTimeout(self.onstatechanged, 0, prevState, state);
        }
    }

    CallRoulette.prototype._processMessages = function(data) {
        var self = this;
        var msg = JSON.parse(data);

        if (msg.yo !== 'yo') {
            console.log('Invalid message: ' + data);
            self.stop();
            return;
        }

        if (!msg.jsep) {
            console.log('Got offer request');
            self._initConnection();
            self._createLocalDescription(
                'offer',
                // onSuccess
                function(sdp) {
                    var reply = {yo: 'yo', jsep: {type: 'offer', sdp: sdp}};
                    self._ws.send(JSON.stringify(reply));
                },
                // onFailure
                function(error) {
                    console.log('Error getting local SDP: ' + error);
                    self.stop()
                }
            );
        } else if (msg.jsep.type == 'offer') {
            console.log('Got offer');
            self._initConnection();
            self._conn.setRemoteDescription(
                new rtcninja.RTCSessionDescription(msg.jsep),
                // success
                function() {
                    self._createLocalDescription(
                        'answer',
                        // onSuccess
                        function(sdp) {
                            var reply = {yo: 'yo', jsep: {type: 'answer', sdp: sdp}};
                            self._ws.send(JSON.stringify(reply));
                        },
                        // onFailure
                        function(error) {
                            console.log('Error getting local SDP: ' + error);
                            self.stop()
                        }
                    );
                },
                // failure
                function(error) {
                    console.log('Error setting remote description: ' + error);
                    onFailure(error);
                }
            );
        } else if (msg.jsep.type == 'answer') {
            console.log('Got answer');

            if (self._conn === null) {
                throw new Error('Connection does not exist yet');
            }

            self._conn.setRemoteDescription(
                new rtcninja.RTCSessionDescription(msg.jsep),
                // success
                function() {
                },
                // failure
                function(error) {
                    self.stop();
                }
            );
        } else {
            console.log('Invalid message: ' + data);
        }
    }

    CallRoulette.prototype._initConnection = function() {
        var self = this;
        // TODO: make these configurable
        var pcConfig = {iceServers: []};

        if (self._conn !== null) {
            throw new Error('Connection already exists');
        }

        if (self._localStream === null) {
            throw new Error('Local stream is not set');
        }

        self._conn = new rtcninja.RTCPeerConnection(pcConfig);
        self._conn.addStream(self._localStream);
        self._conn.onaddstream = function(event, stream) {
                                    if (self._remoteStream !== null) {
                                        // only one stream is supported
                                        return;
                                    }
                                    self._remoteStream = stream;
                                    console.log('Remote stream added');
                                    rtcninja.attachMediaStream(self._view, stream);
                                    self._setState('established');
                                };

    }

    CallRoulette.prototype._createLocalDescription = function(type, onSuccess, onFailure) {
        var self = this;

        if (type === 'offer') {
            self._conn.createOffer(
                // success
                createSucceeded,
                // failure
                function(error) {
                    onFailure(error);
                },
                // constraints
                null
            );
        } else if (type === 'answer') {
            self._conn.createAnswer(
                // success
                createSucceeded,
                // failure
                function(error) {
                    onFailure(error);
                },
                // constraints
                null
            );
        } else {
            throw new Error('type must be "offer" or "answer", but "' +type+ '" was given');
        }

        // createAnswer or createOffer succeeded
        function createSucceeded(desc) {
            self._conn.onicecandidate = function(event, candidate) {
                if (!candidate) {
                    self._conn.onicecandidate = null;
                    if (onSuccess) {
                        onSuccess(self._conn.localDescription.sdp);
                        onSuccess = null;
                    }
                }
            };
            self._conn.setLocalDescription(
                desc,
                // success
                function() {
                    if (self._conn.iceGatheringState === 'complete') {
                        if (onSuccess) {
                            onSuccess(self._conn.localDescription.sdp);
                            onSuccess = null;
                        }
                    }
                },
                // failure
                function(error) {
                    if (onFailure) {
                        onFailure(error);
                    }
                }
            );
        }
    }

    var videoView = document.querySelector('.videoView video');
    var callRoulette = new CallRoulette(videoView);
    callRoulette.onstatechanged = onStateChanged;

    var startStopButton = document.querySelector('#startStopButton');
    startStopButton.classList.add('enabled');
    startStopButton.addEventListener('click', onStartStopButtonClick, false);

    function onStartStopButtonClick() {
        var state = callRoulette.getState();

        console.log('State: ' + state);
        if (state === 'stopped') {
            callRoulette.start();
        } else {
            callRoulette.stop();
        }
    }

    function onStateChanged(prevState, curState) {
        console.log('State changed: ' + prevState + ' -> ' + curState);
        switch (curState) {
            case 'starting':
	        startStopButton.textContent = 'Connecting...';
                break;
            case 'started':
	        startStopButton.textContent = 'Connected, waiting...';
                break;
            case 'established':
	        startStopButton.textContent = 'Established';
                break;
            case 'stopped':
	        startStopButton.textContent = 'Start';
                break;
            default:
                break;
        }
    }

}

(function (fn) {
    if (document.readyState != 'loading'){
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
})(runCallRoulette);

<commit_msg>Don't use the button to render status<commit_after>
function runCallRoulette() {
    if (!rtcninja.hasWebRTC()) {
        console.log("WebRTC is NOT supported!");
	alertify.error('Your browser does not support WebRTC');
	return;
    }

    console.log("WebRTC is supported!");
    alertify.success('Your browser supports WebRTC');

    // CallRoulette!

    function CallRoulette(view) {
        if (!view) {
            throw Error('invalid view element!');
        }

        this._view = view;

        this._localStream = null;
        this._remoteStream = null;

        this._state = 'stopped';

        this._conn = null;
        this._ws = null;

        this.onstatechanged = null;
    }

    // Public API

    CallRoulette.prototype.getState = function() {
        var self = this;

        return self._state;
    }

    CallRoulette.prototype.start = function() {
        var self = this;

        console.log('Start');
        self._setState('starting');

        rtcninja.getUserMedia({audio: true, video: true},
            // success
            function(stream) {
                self._localStream = stream;
                console.log("Local media stream acquired successfully");
                rtcninja.attachMediaStream(self._view, stream);
                self._ws = new WebSocket("ws://" + document.location.host + "/ws", "callroulette");
                self._ws.onmessage = function(event) {
                    self._processMessages(event.data);
                };
                self._ws.onopen = function(event) {
                    console.log('WS connected');
                    self._setState('started');
                };
                self._ws.onclose = function(event) {
                    console.log('WS closedi');
                    self.stop();
                }
            },
            // error
            function(error) {
	        alertify.error("Error getting local media stream: " + error);
                self.stop();
            });
    }

    CallRoulette.prototype.stop = function() {
        var self = this;

        if (self._state === 'stopped') {
            return;
        }

        console.log('Stop');
        self._setState('stopped');

        if (self._ws !== null) {
            self._ws.close();
            self._ws = null;
        }

        if (self._localStream !== null) {
            rtcninja.closeMediaStream(self._localStream);
            self._localStream = null;
        }

        if (self._remoteStream !== null) {
            rtcninja.closeMediaStream(self._remoteStream);
            self._remoteStream = null;
        }

        if (self._conn !== null) {
            self._conn.close();
            self._conn = null;
        }
    }

    // Private API

    CallRoulette.prototype._setState = function(state) {
        var self = this;
        var prevState = self._state;

        if (prevState === state) {
            return;
        }

        self._state = state;
        if (typeof self.onstatechanged === 'function') {
            window.setTimeout(self.onstatechanged, 0, prevState, state);
        }
    }

    CallRoulette.prototype._processMessages = function(data) {
        var self = this;
        var msg = JSON.parse(data);

        if (msg.yo !== 'yo') {
            console.log('Invalid message: ' + data);
            self.stop();
            return;
        }

        if (!msg.jsep) {
            console.log('Got offer request');
            self._initConnection();
            self._createLocalDescription(
                'offer',
                // onSuccess
                function(sdp) {
                    var reply = {yo: 'yo', jsep: {type: 'offer', sdp: sdp}};
                    self._ws.send(JSON.stringify(reply));
                },
                // onFailure
                function(error) {
                    console.log('Error getting local SDP: ' + error);
                    self.stop()
                }
            );
        } else if (msg.jsep.type == 'offer') {
            console.log('Got offer');
            self._initConnection();
            self._conn.setRemoteDescription(
                new rtcninja.RTCSessionDescription(msg.jsep),
                // success
                function() {
                    self._createLocalDescription(
                        'answer',
                        // onSuccess
                        function(sdp) {
                            var reply = {yo: 'yo', jsep: {type: 'answer', sdp: sdp}};
                            self._ws.send(JSON.stringify(reply));
                        },
                        // onFailure
                        function(error) {
                            console.log('Error getting local SDP: ' + error);
                            self.stop()
                        }
                    );
                },
                // failure
                function(error) {
                    console.log('Error setting remote description: ' + error);
                    onFailure(error);
                }
            );
        } else if (msg.jsep.type == 'answer') {
            console.log('Got answer');

            if (self._conn === null) {
                throw new Error('Connection does not exist yet');
            }

            self._conn.setRemoteDescription(
                new rtcninja.RTCSessionDescription(msg.jsep),
                // success
                function() {
                },
                // failure
                function(error) {
                    self.stop();
                }
            );
        } else {
            console.log('Invalid message: ' + data);
        }
    }

    CallRoulette.prototype._initConnection = function() {
        var self = this;
        // TODO: make these configurable
        var pcConfig = {iceServers: []};

        if (self._conn !== null) {
            throw new Error('Connection already exists');
        }

        if (self._localStream === null) {
            throw new Error('Local stream is not set');
        }

        self._conn = new rtcninja.RTCPeerConnection(pcConfig);
        self._conn.addStream(self._localStream);
        self._conn.onaddstream = function(event, stream) {
                                    if (self._remoteStream !== null) {
                                        // only one stream is supported
                                        return;
                                    }
                                    self._remoteStream = stream;
                                    console.log('Remote stream added');
                                    rtcninja.attachMediaStream(self._view, stream);
                                    self._setState('established');
                                };

    }

    CallRoulette.prototype._createLocalDescription = function(type, onSuccess, onFailure) {
        var self = this;

        if (type === 'offer') {
            self._conn.createOffer(
                // success
                createSucceeded,
                // failure
                function(error) {
                    onFailure(error);
                },
                // constraints
                null
            );
        } else if (type === 'answer') {
            self._conn.createAnswer(
                // success
                createSucceeded,
                // failure
                function(error) {
                    onFailure(error);
                },
                // constraints
                null
            );
        } else {
            throw new Error('type must be "offer" or "answer", but "' +type+ '" was given');
        }

        // createAnswer or createOffer succeeded
        function createSucceeded(desc) {
            self._conn.onicecandidate = function(event, candidate) {
                if (!candidate) {
                    self._conn.onicecandidate = null;
                    if (onSuccess) {
                        onSuccess(self._conn.localDescription.sdp);
                        onSuccess = null;
                    }
                }
            };
            self._conn.setLocalDescription(
                desc,
                // success
                function() {
                    if (self._conn.iceGatheringState === 'complete') {
                        if (onSuccess) {
                            onSuccess(self._conn.localDescription.sdp);
                            onSuccess = null;
                        }
                    }
                },
                // failure
                function(error) {
                    if (onFailure) {
                        onFailure(error);
                    }
                }
            );
        }
    }

    var videoView = document.querySelector('.videoView video');
    var callRoulette = new CallRoulette(videoView);
    callRoulette.onstatechanged = onStateChanged;

    var startStopButton = document.querySelector('#startStopButton');
    startStopButton.classList.add('enabled');
    startStopButton.addEventListener('click', onStartStopButtonClick, false);

    function onStartStopButtonClick() {
        var state = callRoulette.getState();

        console.log('State: ' + state);
        if (state === 'stopped') {
            callRoulette.start();
        } else {
            callRoulette.stop();
        }
    }

    function onStateChanged(prevState, curState) {
        console.log('State changed: ' + prevState + ' -> ' + curState);
        if (curState == 'stopped') {
	    startStopButton.textContent = 'Start';
        } else {
	    startStopButton.textContent = 'Stop';
        }
        switch (curState) {
            case 'starting':
                alertify.message('Connecting...');
                break;
            case 'started':
                alertify.message('Connected, waiting...');
                break;
            case 'established':
                alertify.message('Established');
                break;
            case 'stopped':
                alertify.message('Stopped');
                break;
            default:
                break;
        }
    }

}

(function (fn) {
    if (document.readyState != 'loading'){
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
})(runCallRoulette);

<|endoftext|>