<commit_before>"use strict";
// A program that models multi-dimensional cellular automata.
// Capable of representing Elementary cellular automata,
// Conway's Game of Life, Langton's Ant, and more.

// Wolfram - 20 Cellular automata problems.
// http://www.stephenwolfram.com/publications/articles/ca/85-twenty/3/text.html
// Lyapunov exponent

// Rule numbers for Elementary automata are inverted (110 -> 145)
// Colors are also inverted wrt standard.

// Common neighborhoods

var NEIGHBORHOODS = {
  ELEMENTARY: [[-1], [0], [1]],
  ELEMENTARY2: [[-2],[-1], [0], [1],[2]],
  ELEMENTARY3: [[-3], [-2], [-1], [0], [1], [2], [3]],
  VON_NEUMANN: [[0,0], [0,1], [-1,0], [0,-1], [1,0]],
  MOORE: [[0,0], [0,1], [-1,0], [0,-1], [1,0],[1,1],[1,-1],[-1,1],[-1,-1]]
  // MARGOLUS NEIGHBORHOOD...
};

// Utility funcitons.

var isArray = function (o) {
  return (o instanceof Array) ||
    (Object.prototype.toString.apply(o) === '[object Array]');
};

var sum = function(xs){
  var r = 0;
  for (var i=0; i < xs.length; i++){
    r += xs[i];
  }
  return r;
};

var flatten = function(arr){
  var A = [];
  for (var i=0; i < arr.length; i++){
    if (isArray(arr[i])){
      A = A.concat(flatten(arr[i]));
    } else {
      A.push(arr[i]);
    }

  }
  return A;
};

var range = function(start, end){
  if (end === undefined){
    end = start;
    start = 0;
  }

  var A = [];
  for (var i=start; i < end; i++){
    A.push(i);
  }
  return A;
};

var randomChoice = function(arr){
  return arr[Math.floor(Math.random() * arr.length)];
};

// Entropy of a ca is undecidable:
// http://people.unipmn.it/manzini/papers/tcs03.pdf

var entropy = function(xs){
  var total = 0;
  var frequencies = {};
  for (var i=0; i < xs.length; i++){
    total += 1;
    if (xs[i] in frequencies){
      frequencies[xs[i]] += 1;
    } else {
      frequencies[xs[i]] = 1;
    }
  }
  var s = 0;
  for (var k in frequencies){
    if (frequencies.hasOwnProperty(k)){
      var freq = frequencies[k] / total;
      s += freq * (Math.log(freq) / Math.LN2);
    }

  }
  return (-1 * s);
};

// from http://pmav.eu/stuff/javascript-hashing-functions/source.html
var simpleHash = function(s, tableSize) {
  var hash = 0;
  for (var i = 0; i < s.length; i++) {
    hash += (s[i].charCodeAt() * (i+1));
  }
    return Math.abs(hash) % tableSize;
};

var hammingDistance = function(xs, ys){
  var n = 0;
  for (var i=0; i < xs.length; i++){
    if (xs[i] !== ys[i]){
      n += 1;
    }
  }
  return n;
};

var hammingNeighbors = function(xs, states){
  // Strings similar to xs with a hamming distance of 1.

  var subNeighbors = function(xs, index, states){
    var b = [];
    var val = xs[index];
    for (var i=0; i < states; i++){
      if (i !== val){
        var tmp = xs.slice(0);
        tmp[index] = i;
        b.push(tmp);
      }
    }
    return b;
  };

  var a = [];
  for (var i=0; i < xs.length; i++){
    var ns = subNeighbors(xs, i, states);
    a = a.concat(ns);
  }
  return a;
};

// Family: Life
var makeLifeStyleRule = function(deadStates, liveStates){

  return function(states){
    var state = states[0];
    var neighbors = sum(states.slice(1));
    if (state === 0 && deadStates.indexOf(neighbors) > -1){ return 1; }
    if (state === 1 && liveStates.indexOf(neighbors) > -1){ return 1; }
    return 0;
  };
};

var forgotRule = makeLifeStyleRule([2], []);
var gameOfLifeRule = makeLifeStyleRule([3], [2,3]);
var morleyRule = makeLifeStyleRule([3,6,8], [2,4,5]); // Named after Stephen Morley; also called Move. Supports very high-period and slow spaceships
var dayAndNightRule = makeLifeStyleRule([3,6,7,8], [3,4,6,7,8]);
var highLifeRule = makeLifeStyleRule([3,6], [2,3]);
var twoByTwoRule = makeLifeStyleRule([3,6], [1,2,5]);
var mazeRule = makeLifeStyleRule([1,2,3,4,5], [3]);
var serviettesRule = makeLifeStyleRule([], [2,3,4]);
var walledCitiesRule = makeLifeStyleRule([2,3,4,5], [4,5,6,7,8]);

var randomWalkRule = function(state){
  return randomChoice([[0,1],[1,0],[-1,0],[0,-1]]);
};

var upAntRule = function(state){
  return [0,-1];
};

var staticRule = function(state){
  return [[0,-1], [1, 0]][state];
};

var langtonsAntRule = function(boardState, internalState){
  var moves = [[0,1],[1,0],[0,-1],[-1,0]];
  return moves[internalState];
};

// Adder ant was caused by a bug in the state rule funcion.
// Action on cellState 0 was nothing; only changed state (left 90 degrees) on seeing a 1.
//var adderAntRule = function(boardState, internalState){
//  var moves = [[0,1],[1,0],[0,-1],[-1,0]]
//  return moves[internalState];
//}

var makeAnt = function(position, rule, board){
  //var moves = [[0,1],[1,0],[-1,0],[0,-1]]

  // Pass state logic as a parameter.
  var internalState = 0;

  var updateInternalState = function(cellState){
    if (cellState === 0){
      internalState = (internalState + 1) % 4;
    } else {
      internalState = (internalState + 3) % 4;
    }
  };

  var move = function(){
    // Change the value of the cell occupied cell.
    var cellState = getValue(position, board.state());
    updateInternalState(cellState);
    board.updateValue(position);

    var move = rule(cellState, internalState);
    position = addPoints(board.dimensions, position, move);
    return position;
  };

  return {

    getPosition: function() { return position; },

    moves: function(n){
      for (var i=0; i<n; i++){
        move();
      }
    },

    move: move

  };
};

var makeBoard = function(dimensions, cellStates, neighbors, random){

  var neighborStates = Math.pow(cellStates, neighbors.length); // Number of possible cell arrangements.
  var ruleSets = Math.pow(2, neighborStates);

  var startFunc = function() { return (random ? randomStart(dimensions, cellStates) : canonicalStart(dimensions)); };
  var state = startFunc();

  var rule, ruleTable;

  var setRule = function(r){
    rule = r;
  };

  var setRuleByNumber = function(n){
    setTableRule(createRuleTable(n));
  };

  var array2binary = function(a){
    // Create a decimal number from an array.
    // Is this a bug?
    var n = 0;
    for (var i=0; i < a.length; i++){
      n = n << 1;
      n += a[i];
    }
  };

  var setTableRule = function(t){
    ruleTable = t;
    setRule(function(s){ return t[parseInt(s.join(""), 2)]; });
    //setRule(function(s){ return t[array2binary(s)]; });
  };

  var setRandomRule = function(){
    var s = randomStart([neighborStates], cellStates);
    setTableRule(s);
  };

  // awkward.
  var createRuleTable = function(n){
    var arr = n.toString(2).split("").map( function(s){ return parseInt(s, 10); } );
    while (arr.length < neighborStates){ arr.unshift(0); } // left-fill with zeros.
    return arr;
  };

  var createRule = function(n){
    var arr = createRuleTable(n);
    return function(s){ return arr[parseInt(s.join(""), 2)]; };
    //return function(s){ return t[array2binary(s)]; }
  };

  var generateNextState = function(table){

    var calculateState = function(cell){
      var a = [];
      for (var i=0; i < neighbors.length; i++){
        var n = addPoints(dimensions, cell, neighbors[i]);
        var v = getValue(n, table);
        a.push(v);
      }
      return rule(a);
    };

    var indexes = getIndexes(dimensions);
    var newTable = canonicalStart(dimensions);

    for (var i=0; i < indexes.length; i++){
      setValue(indexes[i], calculateState(indexes[i]), newTable);
    }
    return newTable;
  };

  return {
    state: function() { return state; },
    setRule: setRule,
    setRandomRule: setRandomRule,
    setTableRule: setTableRule,
    setRuleByNumber: setRuleByNumber,
    dimensions: dimensions,
    ruleTable: function(){ return ruleTable; },
    cellStates: cellStates,

    reset: function() { state = startFunc(); },

    updateValue: function(point){
      var s = getValue(point, state);
      var ns = (s + 1) % cellStates;
      setValue(point, ns, state);
      return ns;
    },

    next: function(){
      state = generateNextState(state);
      return state;
    }

  };
};

// Functions for making and manipulating the matrixes.

// Create an array with values generated by a callback.
var makeArray = function(dimensions, callback){
  // Turn this into a map?
  // Fix the redundant code...
  var i;
  var arr = [];
  if (dimensions.length === 0){
    // pass
  } else if (dimensions.length === 1){
    for (i=0; i < dimensions[0]; i++){ arr.push(callback()); }
  } else {
    for (i=0; i<dimensions[0]; i++){
      arr.push(makeArray(dimensions.slice(1), callback));
    }

  }
  return arr;
};

var randomStart = function (dimensions, states, limit) {
  // Cutoff stops making sense with more than 2 states.
  // Need a probability distribution.

  var sectorSize = 1 / states;

  var f = function(){
    var cutoff = 0;
    var r = Math.random();
    for (var i=0; i < states; i++){
      cutoff += sectorSize;
      if (r < cutoff) {
        return i;
      }
    }
  };

  return makeArray(dimensions, f);
};

var canonicalStart = function(dimensions) {
  var a = makeArray(dimensions, function(){ return 0; });
  var center = dimensions.map(function(e){ return Math.floor((e-1)/2); });
  setValue(center, 1, a);
  return a;
};

var getIndexes = function(dimensions){
  // Given dimensions like [3,4,3], return [[0,0,0],...[2,4,2]
  if (dimensions.length === 0){
    return [[]]; // One empty list.
  } else {
    var arr = [];
    for (var i=0; i < dimensions[0]; i++){
      // is this optimal?
      var sub = getIndexes(dimensions.slice(1));
      for (var j=0; j < sub.length; j++){
        var m = sub[j];
        m.unshift(i);
        arr.push(m);
      }
    }
    return arr;
  }
};

// Sub these into table object.
// Make them not recursive.

// Matrix state management.

var getDimensions = function(table){
  var D = []
  while (isArray(table)){
    D.push(table.length)
    table = table[0]
  }
  return D
}

var createMatrix = function(matrix){

  var dimensions = getDimensions(matrix);

  return {
    state: function() {return matrix; },

    move: function(p1, p2){
      var l = [];
      for (var i=0; i<p1.length; i++){
        var dimension = dimensions[i];
        var v = (p1[i] + p2[i] + dimension) % dimension;
        l.push(v);
      }
      return l;
    },

    get: function(key){
      var res = matrix;
      for (var i=0; i < key.length; i++){
        res = res[key[i]];
      }
      return res;
    },

    set: function(key, value){
      var res = matrix
      for (var i=0; i < (key.length - 1); i++){
        res = res[key[i]];
      }
      res[key[i]] = value
    }

  };
};

var getValue = function(p, table){
  // Given a value like [1,4,7], pull those indexes from a nested array.
  if (p.length === 0){
    return table;
  } else {
    return getValue(p.slice(1), table[p[0]]);
  }
};

var setValue = function(p, value, table){
  if (p.length === 1){
    table[p[0]] = value;
  } else {
    return setValue(p.slice(1), value, table[p[0]]);
  }
};

// This is actually summing two vectors.
// Used to identify node neighbors.
var addPoints = function(dimensions, p1, p2){
  var l = [];
  for (var i=0; i<p1.length; i++){
    var dimension = dimensions[i];
    var v = (p1[i] + p2[i] + dimension) % dimension;
    l.push(v);
  }
  return l;
};

<commit_msg>Rearrange sections of automata.js.<commit_after>"use strict";
// A program that models multi-dimensional cellular automata.
// Capable of representing Elementary cellular automata,
// Conway's Game of Life, Langton's Ant, and more.

// Wolfram - 20 Cellular automata problems.
// http://www.stephenwolfram.com/publications/articles/ca/85-twenty/3/text.html
// Lyapunov exponent

// Rule numbers for Elementary automata are inverted (110 -> 145)
// Colors are also inverted wrt standard.

// Common neighborhoods
var NEIGHBORHOODS = {
  ELEMENTARY: [[-1], [0], [1]],
  ELEMENTARY2: [[-2],[-1], [0], [1],[2]],
  ELEMENTARY3: [[-3], [-2], [-1], [0], [1], [2], [3]],
  VON_NEUMANN: [[0,0], [0,1], [-1,0], [0,-1], [1,0]],
  MOORE: [[0,0], [0,1], [-1,0], [0,-1], [1,0],[1,1],[1,-1],[-1,1],[-1,-1]]
  // MARGOLUS NEIGHBORHOOD...
};

// 2-Dimensional
// Family: Life
var makeLifeStyleRule = function(deadStates, liveStates){

  return function(states){
    var state = states[0];
    var neighbors = sum(states.slice(1));
    if (state === 0 && deadStates.indexOf(neighbors) > -1){ return 1; }
    if (state === 1 && liveStates.indexOf(neighbors) > -1){ return 1; }
    return 0;
  };
};

var forgotRule = makeLifeStyleRule([2], []);
var gameOfLifeRule = makeLifeStyleRule([3], [2,3]);
var morleyRule = makeLifeStyleRule([3,6,8], [2,4,5]); // Named after Stephen Morley; also called Move. Supports very high-period and slow spaceships
var dayAndNightRule = makeLifeStyleRule([3,6,7,8], [3,4,6,7,8]);
var highLifeRule = makeLifeStyleRule([3,6], [2,3]);
var twoByTwoRule = makeLifeStyleRule([3,6], [1,2,5]);
var mazeRule = makeLifeStyleRule([1,2,3,4,5], [3]);
var serviettesRule = makeLifeStyleRule([], [2,3,4]);
var walledCitiesRule = makeLifeStyleRule([2,3,4,5], [4,5,6,7,8]);

// Ant Rules

var randomWalkRule = function(state){
  return randomChoice([[0,1],[1,0],[-1,0],[0,-1]]);
};

var upAntRule = function(state){
  return [0,-1];
};

var staticRule = function(state){
  return [[0,-1], [1, 0]][state];
};

var langtonsAntRule = function(boardState, internalState){
  var moves = [[0,1],[1,0],[0,-1],[-1,0]];
  return moves[internalState];
};

// Adder ant was caused by a bug in the state rule funcion.
// Action on cellState 0 was nothing; only changed state (left 90 degrees) on seeing a 1.
//var adderAntRule = function(boardState, internalState){
//  var moves = [[0,1],[1,0],[0,-1],[-1,0]]
//  return moves[internalState];
//}

var makeAnt = function(position, rule, board){
  //var moves = [[0,1],[1,0],[-1,0],[0,-1]]

  // Pass state logic as a parameter.
  var internalState = 0;

  var updateInternalState = function(cellState){
    if (cellState === 0){
      internalState = (internalState + 1) % 4;
    } else {
      internalState = (internalState + 3) % 4;
    }
  };

  var move = function(){
    // Change the value of the cell occupied cell.
    var cellState = getValue(position, board.state());
    updateInternalState(cellState);
    board.updateValue(position);

    var move = rule(cellState, internalState);
    position = addPoints(board.dimensions, position, move);
    return position;
  };

  return {

    getPosition: function() { return position; },

    moves: function(n){
      for (var i=0; i<n; i++){
        move();
      }
    },

    move: move

  };
};

var makeBoard = function(dimensions, cellStates, neighbors, random){

  var neighborStates = Math.pow(cellStates, neighbors.length); // Number of possible cell arrangements.
  var ruleSets = Math.pow(2, neighborStates);

  var startFunc = function() { return (random ? randomStart(dimensions, cellStates) : canonicalStart(dimensions)); };
  var state = startFunc();

  var rule, ruleTable;

  // 6 rule functions is far too many.
  var setRule = function(r){
    rule = r;
  };

  var setRuleByNumber = function(n){
    setTableRule(createRuleTable(n));
  };

  var setTableRule = function(t){
    ruleTable = t;
    setRule(function(s){ return t[parseInt(s.join(""), 2)]; });
    //setRule(function(s){ return t[array2binary(s)]; });
  };

  var setRandomRule = function(){
    var s = randomStart([neighborStates], cellStates);
    setTableRule(s);
  };

  var createRuleTable = function(n){
    var arr = n.toString(2).split("").map( function(s){ return parseInt(s, 10); } );
    while (arr.length < neighborStates){ arr.unshift(0); } // left-fill with zeros.
    return arr;
  };

  var createRule = function(n){
    var arr = createRuleTable(n);
    return function(s){ return arr[parseInt(s.join(""), 2)]; };
    //return function(s){ return t[array2binary(s)]; }
  };

  var generateNextState = function(table){

    var calculateState = function(cell){
      var a = [];
      for (var i=0; i < neighbors.length; i++){
        var n = addPoints(dimensions, cell, neighbors[i]);
        var v = getValue(n, table);
        a.push(v);
      }
      return rule(a);
    };

    var indexes = getIndexes(dimensions);
    var newTable = canonicalStart(dimensions);

    for (var i=0; i < indexes.length; i++){
      setValue(indexes[i], calculateState(indexes[i]), newTable);
    }
    return newTable;
  };

  return {
    state: function() { return state; },
    setRule: setRule,
    setRandomRule: setRandomRule,
    setTableRule: setTableRule,
    setRuleByNumber: setRuleByNumber,
    dimensions: dimensions,
    ruleTable: function(){ return ruleTable; },
    cellStates: cellStates,

    reset: function() { state = startFunc(); },

    updateValue: function(point){
      var s = getValue(point, state);
      var ns = (s + 1) % cellStates;
      setValue(point, ns, state);
      return ns;
    },

    next: function(){
      state = generateNextState(state);
      return state;
    }

  };
};

// Functions for making and manipulating the matrixes.

// Create an array with values generated by a callback.
var makeArray = function(dimensions, callback){
  // Turn this into a map?
  // Fix the redundant code...
  var i;
  var arr = [];
  if (dimensions.length === 0){
    // pass
  } else if (dimensions.length === 1){
    for (i=0; i < dimensions[0]; i++){ arr.push(callback()); }
  } else {
    for (i=0; i<dimensions[0]; i++){
      arr.push(makeArray(dimensions.slice(1), callback));
    }

  }
  return arr;
};

var randomStart = function (dimensions, states, limit) {
  // Cutoff stops making sense with more than 2 states.
  // Need a probability distribution.

  var sectorSize = 1 / states;

  var f = function(){
    var cutoff = 0;
    var r = Math.random();
    for (var i=0; i < states; i++){
      cutoff += sectorSize;
      if (r < cutoff) {
        return i;
      }
    }
  };

  return makeArray(dimensions, f);
};

var canonicalStart = function(dimensions) {
  var a = makeArray(dimensions, function(){ return 0; });
  var center = dimensions.map(function(e){ return Math.floor((e-1)/2); });
  setValue(center, 1, a);
  return a;
};

var getIndexes = function(dimensions){
  // Given dimensions like [3,4,3], return [[0,0,0],...[2,4,2]
  if (dimensions.length === 0){
    return [[]]; // One empty list.
  } else {
    var arr = [];
    for (var i=0; i < dimensions[0]; i++){
      // is this optimal?
      var sub = getIndexes(dimensions.slice(1));
      for (var j=0; j < sub.length; j++){
        var m = sub[j];
        m.unshift(i);
        arr.push(m);
      }
    }
    return arr;
  }
};

// Sub these into table object.
// Make them not recursive.

// Matrix state management.

var getDimensions = function(table){
  var D = []
  while (isArray(table)){
    D.push(table.length)
    table = table[0]
  }
  return D
}

var createMatrix = function(matrix){

  var dimensions = getDimensions(matrix);

  return {
    state: function() {return matrix; },

    move: function(p1, p2){
      var l = [];
      for (var i=0; i<p1.length; i++){
        var dimension = dimensions[i];
        var v = (p1[i] + p2[i] + dimension) % dimension;
        l.push(v);
      }
      return l;
    },

    get: function(key){
      var res = matrix;
      for (var i=0; i < key.length; i++){
        res = res[key[i]];
      }
      return res;
    },

    set: function(key, value){
      var res = matrix
      for (var i=0; i < (key.length - 1); i++){
        res = res[key[i]];
      }
      res[key[i]] = value
    }

  };
};

var getValue = function(p, table){
  // Given a value like [1,4,7], pull those indexes from a nested array.
  if (p.length === 0){
    return table;
  } else {
    return getValue(p.slice(1), table[p[0]]);
  }
};

var setValue = function(p, value, table){
  if (p.length === 1){
    table[p[0]] = value;
  } else {
    return setValue(p.slice(1), value, table[p[0]]);
  }
};

// This is actually summing two vectors.
// Used to identify node neighbors.
var addPoints = function(dimensions, p1, p2){
  var l = [];
  for (var i=0; i<p1.length; i++){
    var dimension = dimensions[i];
    var v = (p1[i] + p2[i] + dimension) % dimension;
    l.push(v);
  }
  return l;
};

// Utility funcitons.

var isArray = function (o) {
  return (o instanceof Array) ||
    (Object.prototype.toString.apply(o) === '[object Array]');
};

var sum = function(xs){
  var r = 0;
  for (var i=0; i < xs.length; i++){
    r += xs[i];
  }
  return r;
};

var flatten = function(arr){
  var A = [];
  for (var i=0; i < arr.length; i++){
    if (isArray(arr[i])){
      A = A.concat(flatten(arr[i]));
    } else {
      A.push(arr[i]);
    }

  }
  return A;
};

var range = function(start, end){
  if (end === undefined){
    end = start;
    start = 0;
  }

  var A = [];
  for (var i=start; i < end; i++){
    A.push(i);
  }
  return A;
};

var randomChoice = function(arr){
  return arr[Math.floor(Math.random() * arr.length)];
};

// Entropy of a ca is undecidable:
// http://people.unipmn.it/manzini/papers/tcs03.pdf

var entropy = function(xs){
  var total = 0;
  var frequencies = {};
  for (var i=0; i < xs.length; i++){
    total += 1;
    if (xs[i] in frequencies){
      frequencies[xs[i]] += 1;
    } else {
      frequencies[xs[i]] = 1;
    }
  }
  var s = 0;
  for (var k in frequencies){
    if (frequencies.hasOwnProperty(k)){
      var freq = frequencies[k] / total;
      s += freq * (Math.log(freq) / Math.LN2);
    }

  }
  return (-1 * s);
};

// from http://pmav.eu/stuff/javascript-hashing-functions/source.html
var simpleHash = function(s, tableSize) {
  var hash = 0;
  for (var i = 0; i < s.length; i++) {
    hash += (s[i].charCodeAt() * (i+1));
  }
    return Math.abs(hash) % tableSize;
};

var array2binary = function(a){
  // Create a decimal number from an array.
  // Is this a bug?
  var n = 0;
  for (var i=0; i < a.length; i++){
    n = n << 1;
    n += a[i];
  }
};

var hammingDistance = function(xs, ys){
  var n = 0;
  for (var i=0; i < xs.length; i++){
    if (xs[i] !== ys[i]){
      n += 1;
    }
  }
  return n;
};

var hammingNeighbors = function(xs, states){
  // Strings similar to xs with a hamming distance of 1.

  var subNeighbors = function(xs, index, states){
    var b = [];
    var val = xs[index];
    for (var i=0; i < states; i++){
      if (i !== val){
        var tmp = xs.slice(0);
        tmp[index] = i;
        b.push(tmp);
      }
    }
    return b;
  };

  var a = [];
  for (var i=0; i < xs.length; i++){
    var ns = subNeighbors(xs, i, states);
    a = a.concat(ns);
  }
  return a;
};

<|endoftext|>


<commit_before>'use strict';

var chai = require('chai')
  , expect = chai.expect
  , resolver = require('../src/resolver')
  , helper = require('./helper')
  , sequelize = helper.sequelize
  , Sequelize = require('sequelize')
  , Promise = helper.Promise
  , attributeFields = require('../src/attributeFields');

import {
  GraphQLString,
  GraphQLInt,
  GraphQLFloat,
  GraphQLNonNull,
  GraphQLBoolean,
  GraphQLEnumType,
  GraphQLList,
  GraphQLObjectType,
  GraphQLSchema,
  graphql
} from 'graphql';

import {
  sequelizeNodeInterface
} from '../src/relay';

import {
  globalIdField,
  connectionDefinitions,
  connectionArgs,
  connectionFromArray
} from 'graphql-relay';

function generateTask(id) {
  return {
    id: id,
    name: Math.random().toString()
  }
}

describe('relay', function () {
  var User
    , Task
    , userType
    , taskType
    , taskConnection
    , nodeInterface
    , nodeField
    , schema;

  before(function () {
    sequelize.modelManager.models = [];
    sequelize.models = {};
    User = sequelize.define('user', {
      name: {
        type: Sequelize.STRING
      }
    }, {
      timestamps: false
    });

    Task = sequelize.define('task', {
      name: {
        type: Sequelize.STRING
      }
    }, {
      timestamps: false
    });

    User.Tasks = User.hasMany(Task, {as: 'tasks'});

    var node = sequelizeNodeInterface(sequelize, {User: userType, Task: taskType});
    nodeInterface = node.nodeInterface;
    nodeField = node.nodeField;

    taskType = new GraphQLObjectType({
      name: 'Task',
      fields: {
        id: globalIdField('Task'),
        name: {
          type: GraphQLString
        }
      },
      interfaces: [nodeInterface]
    });

    var connection = connectionDefinitions({name: 'Task', nodeType: taskType});

    taskConnection = connection.connectionType;

    userType = new GraphQLObjectType({
      name: 'User',
      fields: {
        id: globalIdField('User'),
        name: {
          type: GraphQLString
        },
        tasks: {
          type: taskConnection,
          args: connectionArgs,
          resolve: resolver(User.Tasks)
        }
      },
      interfaces: [nodeInterface]
    });

    schema = new GraphQLSchema({
      query: new GraphQLObjectType({
        name: 'RootQueryType',
        fields: {
          user: {
            type: userType,
            args: {
              id: {
                type: new GraphQLNonNull(GraphQLInt)
              },
              testV: {
                type: GraphQLBoolean
              }
            },
            resolve: resolver(User)
          },
          users: {
            type: new GraphQLList(userType),
            args: {
              limit: {
                type: GraphQLInt
              },
              order: {
                type: GraphQLString
              }
            },
            resolve: resolver(User)
          }
        }
      })
    });

  });

  before(function () {
    var userId = 1
      , taskId = 1;

    return this.sequelize.sync({force: true}).bind(this).then(function () {
      return Promise.join(
        User.create({
          id: userId++,
          name: 'b' + Math.random().toString(),
          tasks: [generateTask(taskId++), generateTask(taskId++), generateTask(taskId++)]
        }, {
          include: [User.Tasks]
        }),
        User.create({
          id: userId++,
          name: 'a' + Math.random().toString(),
          tasks: [generateTask(taskId++), generateTask(taskId++)]
        }, {
          include: [User.Tasks]
        })
      ).bind(this).spread(function (userA, userB) {
          this.userA = userA;
          this.userB = userB;
          this.users = [userA, userB];
        });
    });
  });

  it('should resolve a plain result with a single model', function () {
    var user = this.userB;

    return graphql(schema, `
      {
        user(id: ${user.id}, testV: true) {
          name
          tasks {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    `).then(function (result) {
      if (result.errors) throw new Error(result.errors[0].stack);

      expect(result.data).to.deep.equal({
        user: {
          name: user.name,
          tasks: {
            edges: [
              {
                node: {
                  name: user.tasks[0].name
                }
              },
              {
                node: {
                  name: user.tasks[1].name
                }
              }
            ]
          }
        }
      });
    });
  });

  it('should resolve a plain result with a single model', function () {
    var users = this.users;

    return graphql(schema, `
      {
        users {
          name
          tasks {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    `).then(function (result) {
      if (result.errors) throw new Error(result.errors[0].stack);

      expect(result.data.users.length).to.equal(users.length);
      result.data.users.forEach(function (user) {
        expect(user.tasks.edges).to.have.length.above(0);
      });

    });
  });

});
<commit_msg>removed custom graphQL testV values used for debugging.<commit_after>'use strict';

var chai = require('chai')
  , expect = chai.expect
  , resolver = require('../src/resolver')
  , helper = require('./helper')
  , sequelize = helper.sequelize
  , Sequelize = require('sequelize')
  , Promise = helper.Promise
  , attributeFields = require('../src/attributeFields');

import {
  GraphQLString,
  GraphQLInt,
  GraphQLFloat,
  GraphQLNonNull,
  GraphQLBoolean,
  GraphQLEnumType,
  GraphQLList,
  GraphQLObjectType,
  GraphQLSchema,
  graphql
} from 'graphql';

import {
  sequelizeNodeInterface
} from '../src/relay';

import {
  globalIdField,
  connectionDefinitions,
  connectionArgs,
  connectionFromArray
} from 'graphql-relay';

function generateTask(id) {
  return {
    id: id,
    name: Math.random().toString()
  }
}

describe('relay', function () {
  var User
    , Task
    , userType
    , taskType
    , taskConnection
    , nodeInterface
    , nodeField
    , schema;

  before(function () {
    sequelize.modelManager.models = [];
    sequelize.models = {};
    User = sequelize.define('user', {
      name: {
        type: Sequelize.STRING
      }
    }, {
      timestamps: false
    });

    Task = sequelize.define('task', {
      name: {
        type: Sequelize.STRING
      }
    }, {
      timestamps: false
    });

    User.Tasks = User.hasMany(Task, {as: 'tasks'});

    var node = sequelizeNodeInterface(sequelize, {User: userType, Task: taskType});
    nodeInterface = node.nodeInterface;
    nodeField = node.nodeField;

    taskType = new GraphQLObjectType({
      name: 'Task',
      fields: {
        id: globalIdField('Task'),
        name: {
          type: GraphQLString
        }
      },
      interfaces: [nodeInterface]
    });

    var connection = connectionDefinitions({name: 'Task', nodeType: taskType});

    taskConnection = connection.connectionType;

    userType = new GraphQLObjectType({
      name: 'User',
      fields: {
        id: globalIdField('User'),
        name: {
          type: GraphQLString
        },
        tasks: {
          type: taskConnection,
          args: connectionArgs,
          resolve: resolver(User.Tasks)
        }
      },
      interfaces: [nodeInterface]
    });

    schema = new GraphQLSchema({
      query: new GraphQLObjectType({
        name: 'RootQueryType',
        fields: {
          user: {
            type: userType,
            args: {
              id: {
                type: new GraphQLNonNull(GraphQLInt)
              }
            },
            resolve: resolver(User)
          },
          users: {
            type: new GraphQLList(userType),
            args: {
              limit: {
                type: GraphQLInt
              },
              order: {
                type: GraphQLString
              }
            },
            resolve: resolver(User)
          }
        }
      })
    });

  });

  before(function () {
    var userId = 1
      , taskId = 1;

    return this.sequelize.sync({force: true}).bind(this).then(function () {
      return Promise.join(
        User.create({
          id: userId++,
          name: 'b' + Math.random().toString(),
          tasks: [generateTask(taskId++), generateTask(taskId++), generateTask(taskId++)]
        }, {
          include: [User.Tasks]
        }),
        User.create({
          id: userId++,
          name: 'a' + Math.random().toString(),
          tasks: [generateTask(taskId++), generateTask(taskId++)]
        }, {
          include: [User.Tasks]
        })
      ).bind(this).spread(function (userA, userB) {
          this.userA = userA;
          this.userB = userB;
          this.users = [userA, userB];
        });
    });
  });

  it('should resolve a plain result with a single model', function () {
    var user = this.userB;

    return graphql(schema, `
      {
        user(id: ${user.id}) {
          name
          tasks {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    `).then(function (result) {
      if (result.errors) throw new Error(result.errors[0].stack);

      expect(result.data).to.deep.equal({
        user: {
          name: user.name,
          tasks: {
            edges: [
              {
                node: {
                  name: user.tasks[0].name
                }
              },
              {
                node: {
                  name: user.tasks[1].name
                }
              }
            ]
          }
        }
      });
    });
  });

  it('should resolve a plain result with a single model', function () {
    var users = this.users;

    return graphql(schema, `
      {
        users {
          name
          tasks {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    `).then(function (result) {
      if (result.errors) throw new Error(result.errors[0].stack);

      expect(result.data.users.length).to.equal(users.length);
      result.data.users.forEach(function (user) {
        expect(user.tasks.edges).to.have.length.above(0);
      });

    });
  });

});
<|endoftext|>


<commit_before>const assert = require('assert');

const Account     = require('../Contents/Scripts/account.js').Account;
const Repository  = require('../Contents/Scripts/repository.js').Repository;

describe('Repository', function() {
  let org     = new Account('rails');
  let forker  = new Account('spoon');
  let repo    = new Repository(org, 'rails', 'A Ruby web framework');
  let fork    = new Repository(forker, 'rails', 'A Ruby web framework', repo);

  describe('#nameWithOwner', function() {
    it('returns a formatted string of the account login and name', function() {
      assert.equal('rails/rails', repo.nameWithOwner);
    });
  });

  describe('#url', function() {
    it('returns the full URL of the repository', function() {
      assert.equal('https://github.com/rails/rails', repo.url);
    });
  });

  describe('#issuesURL', function() {
    it("returns the full URL of the repository's issues", function() {
      assert.equal('https://github.com/rails/rails/issues', repo.issuesURL);
    });
  });

  describe('#pullRequestsURL', function() {
    it("returns the full URL of the repository's pull requests", function() {
      assert.equal('https://github.com/rails/rails/pulls', repo.pullRequestsURL);
    });
  });

  describe('#toMenuItem()', function() {
    it("returns an object formatted to be displayed in LaunchBar", function() {
      assert.deepEqual({
        title: 'rails/rails',
        url: 'https://github.com/rails/rails',
        icon: 'repoTemplate.png',
        subtitle: 'A Ruby web framework',
        alwaysShowsSubtitle: true
      }, repo.toMenuItem());
    });
  });

  describe('isFork', function() {
    it("returns true if the repository is a fork", function() {
      assert.equal(true, fork.isFork);
    });

    it("returns false if the repository is not a fork", function() {
      assert.equal(false, repo.isFork);
    });
  });

  describe('#icon', function() {
    it("returns a repository icon if the repo is not a fork", function() {
      assert.equal('repoTemplate.png', repo.icon);
    });

    it("returns a fork icon if the repo is a fork", function() {
      assert.equal('forkTemplate.png', fork.icon);
    });
  });
});
<commit_msg>Update describe string to denote method<commit_after>const assert = require('assert');

const Account     = require('../Contents/Scripts/account.js').Account;
const Repository  = require('../Contents/Scripts/repository.js').Repository;

describe('Repository', function() {
  let org     = new Account('rails');
  let forker  = new Account('spoon');
  let repo    = new Repository(org, 'rails', 'A Ruby web framework');
  let fork    = new Repository(forker, 'rails', 'A Ruby web framework', repo);

  describe('#nameWithOwner', function() {
    it('returns a formatted string of the account login and name', function() {
      assert.equal('rails/rails', repo.nameWithOwner);
    });
  });

  describe('#url', function() {
    it('returns the full URL of the repository', function() {
      assert.equal('https://github.com/rails/rails', repo.url);
    });
  });

  describe('#issuesURL', function() {
    it("returns the full URL of the repository's issues", function() {
      assert.equal('https://github.com/rails/rails/issues', repo.issuesURL);
    });
  });

  describe('#pullRequestsURL', function() {
    it("returns the full URL of the repository's pull requests", function() {
      assert.equal('https://github.com/rails/rails/pulls', repo.pullRequestsURL);
    });
  });

  describe('#toMenuItem()', function() {
    it("returns an object formatted to be displayed in LaunchBar", function() {
      assert.deepEqual({
        title: 'rails/rails',
        url: 'https://github.com/rails/rails',
        icon: 'repoTemplate.png',
        subtitle: 'A Ruby web framework',
        alwaysShowsSubtitle: true
      }, repo.toMenuItem());
    });
  });

  describe('#isFork', function() {
    it("returns true if the repository is a fork", function() {
      assert.equal(true, fork.isFork);
    });

    it("returns false if the repository is not a fork", function() {
      assert.equal(false, repo.isFork);
    });
  });

  describe('#icon', function() {
    it("returns a repository icon if the repo is not a fork", function() {
      assert.equal('repoTemplate.png', repo.icon);
    });

    it("returns a fork icon if the repo is a fork", function() {
      assert.equal('forkTemplate.png', fork.icon);
    });
  });
});
<|endoftext|>


<commit_before>
var express = require('../')
  , request = require('./support/http');

describe('res', function(){
  describe('.cookie(name, object)', function(){
    it('should generate a JSON cookie', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('user', { name: 'tobi' }).end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['user=j%3A%7B%22name%22%3A%22tobi%22%7D; path=/'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })
  })

  describe('.cookie(name, string)', function(){
    it('should set a cookie', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('name', 'tobi').end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['name=tobi; path=/'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })

    // it('should default path to "root"', function(done){
    //   var app = express();
    //
    //   app.set('root', '/admin');
    //
    //   app.use(function(req, res){
    //     res.cookie('name', 'tobi').end();
    //   });
    //
    //   request(app)
    //   .get('/')
    //   .end(function(res){
    //     var val = ['name=tobi; path=/admin'];
    //     res.headers['set-cookie'].should.eql(val);
    //     done();
    //   })
    // })

    it('should allow multiple calls', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('name', 'tobi');
        res.cookie('age', 1);
        res.end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['name=tobi; path=/', 'age=1; path=/'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })
  })

  describe('.cookie(name, string, options)', function(){
    it('should set params', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('name', 'tobi', { httpOnly: true, secure: true });
        res.end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['name=tobi; path=/; httpOnly; secure'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })

    describe('maxAge', function(){
      it('should set relative expires', function(done){
        var app = express();

        app.use(function(req, res){
          res.cookie('name', 'tobi', { maxAge: 1000 });
          res.end();
        });

        request(app)
        .get('/')
        .end(function(res){
          res.headers['set-cookie'][0].should.not.include.string('Thu, 01 Jan 1970 00:00:01 GMT');
          done();
        })
      })
    })
  })
})
<commit_msg>removed the use of .include.string()<commit_after>
var express = require('../')
  , request = require('./support/http');

describe('res', function(){
  describe('.cookie(name, object)', function(){
    it('should generate a JSON cookie', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('user', { name: 'tobi' }).end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['user=j%3A%7B%22name%22%3A%22tobi%22%7D; path=/'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })
  })

  describe('.cookie(name, string)', function(){
    it('should set a cookie', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('name', 'tobi').end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['name=tobi; path=/'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })

    // it('should default path to "root"', function(done){
    //   var app = express();
    //
    //   app.set('root', '/admin');
    //
    //   app.use(function(req, res){
    //     res.cookie('name', 'tobi').end();
    //   });
    //
    //   request(app)
    //   .get('/')
    //   .end(function(res){
    //     var val = ['name=tobi; path=/admin'];
    //     res.headers['set-cookie'].should.eql(val);
    //     done();
    //   })
    // })

    it('should allow multiple calls', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('name', 'tobi');
        res.cookie('age', 1);
        res.end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['name=tobi; path=/', 'age=1; path=/'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })
  })

  describe('.cookie(name, string, options)', function(){
    it('should set params', function(done){
      var app = express();

      app.use(function(req, res){
        res.cookie('name', 'tobi', { httpOnly: true, secure: true });
        res.end();
      });

      request(app)
      .get('/')
      .end(function(res){
        var val = ['name=tobi; path=/; httpOnly; secure'];
        res.headers['set-cookie'].should.eql(val);
        done();
      })
    })

    describe('maxAge', function(){
      it('should set relative expires', function(done){
        var app = express();

        app.use(function(req, res){
          res.cookie('name', 'tobi', { maxAge: 1000 });
          res.end();
        });

        request(app)
        .get('/')
        .end(function(res){
          res.headers['set-cookie'][0].should.not.include('Thu, 01 Jan 1970 00:00:01 GMT');
          done();
        })
      })
    })
  })
})
<|endoftext|>


<commit_before>define(function(require, exports, module) {
    main.consumes = [
        "Plugin", "c9", "settings", "ui", "layout", "tooltip",
        "anims", "menus", "tabManager", "preferences", "save",
        "ace.stripws"
    ];
    main.provides = ["autosave"];
    return main;

    function main(options, imports, register) {
        var c9       = imports.c9;
        var Plugin   = imports.Plugin;
        var settings = imports.settings;
        var save     = imports.save;
        var tooltip  = imports.tooltip;
        var tabs     = imports.tabManager;
        var prefs    = imports.preferences;
        var stripws  = imports["ace.stripws"];

        /***** Initialization *****/

        var plugin = new Plugin("Ajax.org", main.consumes);
        // var emit   = plugin.getEmitter();

        var INTERVAL       = 60000;
        var CHANGE_TIMEOUT = 500;

        var docChangeTimeout   = null;
        var btnSave, autosave, saveInterval;

        var loaded = false;
        function load(){
            if (loaded) return false;
            loaded = true;

            prefs.add({
                "General" : {
                    "General" : {
                        "Enable Auto-Save" : {
                            type     : "checkbox",
                            position : 1000,
                            path     : "user/general/@autosave"
                        }
                    }
                }
            }, plugin);

            settings.on("read", function(e){
                settings.setDefaults("user/general", [["autosave", "false"]]);
                autosave = options.testing
                    || settings.getBool("user/general/@autosave");
                transformButton();
            }, plugin);

            settings.on("user/general", function(e) {
                autosave = settings.getBool("user/general/@autosave");
                transformButton();
            }, plugin);

            // when we're back online we'll trigger an autosave if enabled
            c9.on("stateChange", function(e) {
                if (e.state & c9.STORAGE && !(e.last & c9.STORAGE))
                    check();
            }, plugin);

            save.getElement("btnSave", function(btn){
                btnSave = btn;
                transformButton();
            });

            tabs.on("tabCreate", function(e){
                var tab = e.tab;
                tab.document.undoManager.on("change", function(e){
                    if (!autosave || !tab.path)
                        return;

                    clearTimeout(docChangeTimeout);
                    docChangeTimeout = setTimeout(function() {
                        stripws.disable();
                        saveTab(tab);
                    }, CHANGE_TIMEOUT);
                }, plugin);
            }, plugin);

            tabs.on("tabDestroy", function(e){
                if (!e.tab.path)
                    return;

                if (tabs.getTabs().length == 1)
                    btnSave.hide();

                saveTab(e.tab);
            }, plugin);

            save.on("beforeWarn", function(e){
                if (autosave && !e.tab.document.meta.newfile) {
                    saveTab(e.tab);
                    return false;
                }
            }, plugin);
        }

        function transformButton(){
            if (!btnSave) return;
            if (btnSave.autosave === autosave) return;

            if (autosave) {
                // Transform btnSave
                btnSave.setAttribute("caption", "");
                btnSave.setAttribute("margin", "0 20");
                btnSave.removeAttribute("tooltip");
                btnSave.removeAttribute("command");
                apf.setStyleClass(btnSave.$ext, "btnSave");

                tooltip.add(btnSave, {
                    message : "Changes to your file are automatically saved.
\
                        View all your changes through the Revision History pane. \
                        Rollback to a previous state, or make comparisons.",
                    width : "250px",
                    hideonclick : true
                }, plugin);
            }
            else {

            }

            btnSave.autosave = autosave;
        }

        /***** Helpers *****/

        function check() {
            if (!autosave) return;

            var pages = tabs.getTabs();
            for (var tab, i = 0, l = pages.length; i < l; i++) {
                if ((tab = pages[i]).document.changed && tab.path)
                    saveTab(tab)
            }
        }

        function saveTab(tab, force) {
            if (!autosave) return;

            if (!c9.has(c9.STORAGE)) {
                save.setSavingState(tab, "offline");
                return;
            }

            if (!force && (!tab.path
              || !tab.document.changed
              || tab.document.meta.newfile
              || tab.document.meta.error))
                return;

            save.save(tab, { silentsave: true, timeout: 1 }, function() {
                stripws.enable();
            });
        }

        /***** Lifecycle *****/

        plugin.on("load", function(){
            load();
        });
        plugin.on("enable", function(){
            autosave = settings.getBool("user/general/@autosave");
            transformButton();

        });
        plugin.on("disable", function(){
            autosave = false;
            transformButton();
        });
        plugin.on("unload", function(){
            if (saveInterval)
                clearInterval(saveInterval);

            loaded = false;
        });

        /***** Register and define API *****/

        /**
         * Implements auto save for Cloud9 IDE. When the user enables autosave
         * the contents of files are automatically saved about 500ms after the
         * change is made.
         * @singleton
         **/
        plugin.freezePublicAPI({ });

        register(null, {
            autosave: plugin
        });
    }
});<commit_msg>Partially addresses +1129. Good enough for now<commit_after>define(function(require, exports, module) {
    main.consumes = [
        "Plugin", "c9", "settings", "ui", "layout", "tooltip",
        "anims", "menus", "tabManager", "preferences", "save",
        "ace.stripws"
    ];
    main.provides = ["autosave"];
    return main;

    function main(options, imports, register) {
        var c9       = imports.c9;
        var Plugin   = imports.Plugin;
        var settings = imports.settings;
        var save     = imports.save;
        var tooltip  = imports.tooltip;
        var tabs     = imports.tabManager;
        var prefs    = imports.preferences;
        var stripws  = imports["ace.stripws"];

        /***** Initialization *****/

        var plugin = new Plugin("Ajax.org", main.consumes);
        // var emit   = plugin.getEmitter();

        var INTERVAL       = 60000;
        var CHANGE_TIMEOUT = 500;

        var docChangeTimeout   = null;
        var btnSave, autosave, saveInterval;

        var loaded = false;
        function load(){
            if (loaded) return false;
            loaded = true;

            prefs.add({
                "General" : {
                    "General" : {
                        "Enable Auto-Save" : {
                            type     : "checkbox",
                            position : 1000,
                            path     : "user/general/@autosave"
                        }
                    }
                }
            }, plugin);

            settings.on("read", function(e){
                settings.setDefaults("user/general", [["autosave", "false"]]);
                autosave = options.testing
                    || settings.getBool("user/general/@autosave");
                transformButton();
            }, plugin);

            settings.on("user/general", function(e) {
                autosave = settings.getBool("user/general/@autosave");
                transformButton();
            }, plugin);

            // when we're back online we'll trigger an autosave if enabled
            c9.on("stateChange", function(e) {
                if (e.state & c9.STORAGE && !(e.last & c9.STORAGE))
                    check();
            }, plugin);

            save.getElement("btnSave", function(btn){
                btnSave = btn;
                transformButton();
            });

            tabs.on("tabCreate", function(e){
                var tab = e.tab;
                tab.document.undoManager.on("change", function(e){
                    if (!autosave || !tab.path)
                        return;

                    clearTimeout(docChangeTimeout);
                    docChangeTimeout = setTimeout(function() {
                        stripws.disable();
                        saveTab(tab);
                    }, CHANGE_TIMEOUT);
                }, plugin);
            }, plugin);

            tabs.on("tabDestroy", function(e){
                if (!e.tab.path)
                    return;

                if (tabs.getTabs().length == 1)
                    btnSave.hide();

                saveTab(e.tab);
            }, plugin);

            save.on("beforeWarn", function(e){
                if (autosave && !e.tab.document.meta.newfile) {
                    saveTab(e.tab);
                    return false;
                }
            }, plugin);
        }

        function transformButton(){
            if (!btnSave) return;
            if (btnSave.autosave === autosave) return;

            if (autosave) {
                // Transform btnSave
                btnSave.setAttribute("caption", "");
                btnSave.setAttribute("margin", "0 20");
                btnSave.removeAttribute("tooltip");
                btnSave.removeAttribute("command");
                apf.setStyleClass(btnSave.$ext, "btnSave");

                tooltip.add(btnSave, {
                    message : "Changes to your file are automatically saved.
\
                        View all your changes through the Revision History pane. \
                        Rollback to a previous state, or make comparisons.",
                    width : "250px",
                    hideonclick : true
                }, plugin);
            }
            else {

            }

            btnSave.autosave = autosave;
        }

        /***** Helpers *****/

        function check() {
            if (!autosave) return;

            var pages = tabs.getTabs();
            for (var tab, i = 0, l = pages.length; i < l; i++) {
                if ((tab = pages[i]).document.changed && tab.path)
                    saveTab(tab)
            }
        }

        function saveTab(tab, force) {
            if (!autosave) return;

            if (!c9.has(c9.STORAGE)) {
                save.setSavingState(tab, "offline");
                return;
            }

            var doc;
            if (!force && (!tab.path
              || !(doc = tab.document).changed
              || doc.meta.newfile
              || doc.meta.error
              || doc.meta.$saving))
                return;

            save.save(tab, { silentsave: true, timeout: 1 }, function() {
                stripws.enable();
            });
        }

        /***** Lifecycle *****/

        plugin.on("load", function(){
            load();
        });
        plugin.on("enable", function(){
            autosave = settings.getBool("user/general/@autosave");
            transformButton();

        });
        plugin.on("disable", function(){
            autosave = false;
            transformButton();
        });
        plugin.on("unload", function(){
            if (saveInterval)
                clearInterval(saveInterval);

            loaded = false;
        });

        /***** Register and define API *****/

        /**
         * Implements auto save for Cloud9 IDE. When the user enables autosave
         * the contents of files are automatically saved about 500ms after the
         * change is made.
         * @singleton
         **/
        plugin.freezePublicAPI({ });

        register(null, {
            autosave: plugin
        });
    }
});<|endoftext|>


<commit_before>/**
 * Created with JetBrains PhpStorm.
 * User: fredericbonjour
 * Date: 24/05/13
 * Time: 14:59
 * To change this template use File | Settings | File Templates.
 */
(function ($) {

	"use strict";

	angular.module('RbsChange').directive('imageUploader', ['RbsChange.REST', '$q', function (REST, $q) {

		var	acceptedTypes = /image\/(gif|jpeg|png)/,
			MAX_PREVIEW_HEIGHT = 100;

		function updatePreview (scope, url) {
			var	img = new Image();
			img.onload = function () {
				scope.$apply(function () {
					scope.imageWidth  = img.width;
					scope.imageHeight = img.height;
					scope.previewHeight = Math.min(scope.imageHeight, MAX_PREVIEW_HEIGHT);
					scope.previewWidth = scope.previewHeight * (scope.imageWidth / scope.imageHeight);
					scope.imageSrc = url;
				});
			};
			img.src = url;
		}

		return {
			restrict    : 'EAC',
			require     : 'ngModel',
			templateUrl : 'Rbs/Admin/js/directives/image-uploader.twig',
			scope       : true,

			link : function (scope, elm, attrs, ngModel) {

				scope.previewWidth = MAX_PREVIEW_HEIGHT * (16/9.0);
				scope.previewHeight = MAX_PREVIEW_HEIGHT;

				ngModel.$render = function ngModelRenderFn () {
					if (angular.isObject(ngModel.$viewValue)) {
						REST.storage.info(ngModel.$viewValue.storageURI).then(function (info) {
							scope.fileSize = info.size;
							scope.fileName = info.fileName;
							updatePreview(scope, info.data);
						});
					}
				};

				var	inputFile = $(elm).find("input[type=file]"),
					reader = new FileReader();

				reader.onload = function imgOnloadFn (event) {
					scope.$apply(function () {
						scope.loading = false;
						scope.fileSize = event.total;
						scope.fileName = inputFile.get(0).files[0].name;
						// Load the image to get its dimensions.
						updatePreview(scope, event.target.result);
					});

					ngModel.$setViewValue("local:" + event.target.result);
				};

				inputFile.change(function inputChangedFn () {
					var file = inputFile.get(0).files[0];
					if (acceptedTypes.test(file.type)) {
						scope.$apply('loading=true');
						reader.readAsDataURL(file);
					} else {
						window.alert('Please select an image.');
					}
				});

				scope.choose = function chooseFn () {
					inputFile.click();
				};

				scope.upload = function uploadFn () {
					var	file = inputFile.get(0).files[0],
						q = $q.defer();

					if (ngModel.$pristine) {
						console.log("imageUploader: no changes (pristine) => q is resolved with '" + ngModel.$viewValue + "'");
						return null;
					} else if (acceptedTypes.test(file.type)) {
						console.log("imageUploader: has changes (dirty) => uploading...");
						REST.storage.upload(inputFile, attrs.storageName || 'images').then(
							function uploadSuccessFn (response) {
								ngModel.$setViewValue(response);
								ngModel.$render();
								console.log("imageUploader: uploading complete => q is resolved with '" + ngModel.$viewValue + "'");
								q.resolve(response);
							},
							function uploadErrorFn (data) {
								console.log("imageUploader: uploading failed => q is REJECTED with reason: ", data);
								q.reject(data);
							}
						);
					} else {
						console.log("imageUploader: invalid image file => q is REJECTED");
						q.reject('imageUploader: invalid image file.');
					}

					return q.promise;
				};

			}

		};
	}]);

})(window.jQuery);<commit_msg>Fixed Angular issue about a digest phase already running.<commit_after>(function ($) {

	"use strict";

	angular.module('RbsChange').directive('imageUploader', ['RbsChange.REST', '$q', '$timeout', function (REST, $q, $timeout) {

		var	acceptedTypes = /image\/(gif|jpeg|png)/,
			MAX_PREVIEW_HEIGHT = 100;

		function updatePreview (scope, url) {
			var	img = new Image();
			img.onload = function () {
				$timeout(function () {
					scope.imageWidth  = img.width;
					scope.imageHeight = img.height;
					scope.previewHeight = Math.min(scope.imageHeight, MAX_PREVIEW_HEIGHT);
					scope.previewWidth = scope.previewHeight * (scope.imageWidth / scope.imageHeight);
					scope.imageSrc = url;
				});
			};
			img.src = url;
		}

		return {
			restrict    : 'EAC',
			require     : 'ngModel',
			templateUrl : 'Rbs/Admin/js/directives/image-uploader.twig',
			scope       : true,

			link : function (scope, elm, attrs, ngModel) {

				scope.previewWidth = MAX_PREVIEW_HEIGHT * (16/9.0);
				scope.previewHeight = MAX_PREVIEW_HEIGHT;

				ngModel.$render = function ngModelRenderFn () {
					if (angular.isObject(ngModel.$viewValue)) {
						REST.storage.info(ngModel.$viewValue.storageURI).then(function (info) {
							scope.fileSize = info.size;
							scope.fileName = info.fileName;
							updatePreview(scope, info.data);
						});
					}
				};

				var	inputFile = $(elm).find("input[type=file]"),
					reader = new FileReader();

				reader.onload = function imgOnloadFn (event) {
					scope.$apply(function () {
						scope.loading = false;
						scope.fileSize = event.total;
						scope.fileName = inputFile.get(0).files[0].name;
						// Load the image to get its dimensions.
						updatePreview(scope, event.target.result);
					});

					ngModel.$setViewValue("local:" + event.target.result);
				};

				inputFile.change(function inputChangedFn () {
					var file = inputFile.get(0).files[0];
					if (acceptedTypes.test(file.type)) {
						scope.$apply('loading=true');
						reader.readAsDataURL(file);
					} else {
						window.alert('Please select an image.');
					}
				});

				scope.choose = function chooseFn () {
					inputFile.click();
				};

				scope.upload = function uploadFn () {
					var	file = inputFile.get(0).files[0],
						q = $q.defer();

					if (ngModel.$pristine) {
						console.log("imageUploader: no changes (pristine) => q is resolved with '" + ngModel.$viewValue + "'");
						return null;
					} else if (acceptedTypes.test(file.type)) {
						console.log("imageUploader: has changes (dirty) => uploading...");
						REST.storage.upload(inputFile, attrs.storageName || 'images').then(
							function uploadSuccessFn (response) {
								ngModel.$setViewValue(response);
								ngModel.$render();
								console.log("imageUploader: uploading complete => q is resolved with '" + ngModel.$viewValue + "'");
								q.resolve(response);
							},
							function uploadErrorFn (data) {
								console.log("imageUploader: uploading failed => q is REJECTED with reason: ", data);
								q.reject(data);
							}
						);
					} else {
						console.log("imageUploader: invalid image file => q is REJECTED");
						q.reject('imageUploader: invalid image file.');
					}

					return q.promise;
				};

			}

		};
	}]);

})(window.jQuery);<|endoftext|>


<commit_before>import { takeEvery } from 'redux-saga'
import { call, put } from 'redux-saga/effects'
import * as actions from './actions'
import 'isomorphic-fetch'

export default function* root() {
  yield takeEvery(actions.FETCH_QUEUE, fetchQueue)
}

export function fetchApi(url) {
  return fetch(url)
    .then(response => response.json())
}

export function* fetchQueue() {
  console.log('fetching')
  try {
    console.log('trying')
    const queue = yield call(fetchApi, 'donation/queue')
    console.log(queue)
    yield put(actions.fetchQueueDone(queue))
  } catch(err) {
    console.log(err)
    // Error handling
  }
}
<commit_msg>Remove some logging<commit_after>import { takeEvery } from 'redux-saga'
import { call, put } from 'redux-saga/effects'
import * as actions from './actions'
import 'isomorphic-fetch'

export default function* root() {
  yield takeEvery(actions.FETCH_QUEUE, fetchQueue)
}

export function fetchApi(url) {
  return fetch(url)
    .then(response => response.json())
}

export function* fetchQueue() {
  try {
    const queue = yield call(fetchApi, 'donation/queue')
    console.log(queue)
    yield put(actions.fetchQueueDone(queue))
  } catch(err) {
    console.log(err)
    // Error handling
  }
}
<|endoftext|>


<commit_before>var Between = require('./Between');
var FloatBetween = require('./FloatBetween');
var Class = require('../utils/Class');
var Percent = require('./Percent');
var Wrap = require('./Wrap');

//  A Helper Class that allows you to specify a range between min and max, and then
//  keep the value within those bounds, or get random ints or floats from the range.

var MinMax2 = new Class({

    initialize:

    function MinMax2 (min, max)
    {
        if (Array.isArray(min))
        {
            max = min[1];
            min = min[0];
        }
        else if (typeof min === 'object')
        {
            var obj = min;

            min = (obj.hasOwnProperty('x')) ? obj.x : obj.min;
            max = (obj.hasOwnProperty('y')) ? obj.y : obj.max;
        }

        if (min === undefined) { min = 0; }
        if (max === undefined) { max = min; }

        this.min = min;
        this.max = max;

        this._current = min;
    },

    set: function (min, max)
    {
        if (Array.isArray(min))
        {
            max = min[1];
            min = min[0];
        }
        else if (typeof min === 'object')
        {
            var obj = min;

            min = obj.min;
            max = obj.max;
        }

        if (min === undefined) { min = 0; }
        if (max === undefined) { max = min; }

        this.min = min;
        this.max = max;

        return this;
    },

    clone: function ()
    {
        return new MinMax2(this.min, this.max);
    },

    copy: function (dest)
    {
        dest.min = this.min;
        dest.max = this.max;

        return this;
    },

    copyXY: function (dest)
    {
        dest.x = this.min;
        dest.y = this.max;

        return this;
    },

    copyToMinMax: function (dest)
    {
        dest.min = this.min;
        dest.max = this.max;

        return this;
    },

    //  Given U (a value between 0 and 1) return the value in the range
    getU: function (u)
    {
        //  TODO
    },

    //  Returns a value between 0 and 1 based on value
    getPercent: function (value)
    {
        return Percent(value, this.min, this.max);
    },

    getRandom: function ()
    {
        return Between(this.min, this.max);
    },

    getRandomFloat: function ()
    {
        return FloatBetween(this.min, this.max);
    },

    current: {

        get: function ()
        {
            return this._current;
        },

        set: function (value)
        {
            this._current = Wrap(value, this.min, this.max);
        }

    },

    x: {

        get: function ()
        {
            return this.min;
        },

        set: function (value)
        {
            this.min = value;
        }

    },

    y: {

        get: function ()
        {
            return this.max;
        },

        set: function (value)
        {
            this.max = value;
        }

    }

});

module.exports = MinMax2;
<commit_msg>Made the index real-time<commit_after>var Between = require('./Between');
var FloatBetween = require('./FloatBetween');
var Class = require('../utils/Class');
var Percent = require('./Percent');
var Wrap = require('./Wrap');

//  A Helper Class that allows you to specify a range between min and max, and then
//  keep the value within those bounds, or get random ints or floats from the range.

var MinMax2 = new Class({

    initialize:

    function MinMax2 (min, max, steps)
    {
        this.min = 0;
        this.max = 0;
        this.steps = 0;

        this._current = 0;

        if (min !== undefined)
        {
            this.set(min, max, steps);
        }
    },

    set: function (min, max, steps)
    {
        if (Array.isArray(min))
        {
            steps = min[2];
            max = min[1];
            min = min[0];
        }
        else if (typeof min === 'object')
        {
            var obj = min;

            min = (obj.hasOwnProperty('x')) ? obj.x : obj.min;
            max = (obj.hasOwnProperty('y')) ? obj.y : obj.max;
            steps = obj.steps;
        }

        if (min === undefined) { min = 0; }
        if (max === undefined) { max = min; }
        if (steps === undefined) { steps = 0; }

        this.min = min;
        this.max = max;
        this.steps = steps;

        this._current = min;

        return this;
    },

    clone: function ()
    {
        return new MinMax2(this.min, this.max, this.steps);
    },

    copy: function (dest)
    {
        dest.min = this.min;
        dest.max = this.max;
        dest.steps = this.steps;

        return this;
    },

    copyXY: function (dest)
    {
        dest.x = this.min;
        dest.y = this.max;

        return this;
    },

    copyToMinMax: function (dest)
    {
        dest.min = this.min;
        dest.max = this.max;

        return this;
    },

    //  Given U (a value between 0 and 1) return the value in the range
    getU: function (u)
    {
        //  TODO
    },

    //  Returns a value between 0 and 1 based on value
    getPercent: function (value)
    {
        return Percent(value, this.min, this.max);
    },

    getRandom: function ()
    {
        return Between(this.min, this.max);
    },

    getRandomFloat: function ()
    {
        return FloatBetween(this.min, this.max);
    },

    getNext: function ()
    {
        var value;

        if (this.steps > 0)
        {
            value = this._current;

            var i = value + ((this.max - this.min) / this.steps);

            this._current = Wrap(i, this.min, this.max);
        }
        else
        {
            value = this.getRandom();
        }

        return value;
    },

    getNextFloat: function ()
    {
        var value;

        if (this.steps > 0)
        {
            value = this._current;

            var i = value + ((this.max - this.min) / this.steps);

            this._current = Wrap(i, this.min, this.max);
        }
        else
        {
            value = this.getRandomFloat();
        }

        return value;
    },

    current: {

        get: function ()
        {
            return this._current;
        },

        set: function (value)
        {
            this._current = Wrap(value, this.min, this.max);
        }

    },

    x: {

        get: function ()
        {
            return this.min;
        },

        set: function (value)
        {
            this.min = value;
        }

    },

    y: {

        get: function ()
        {
            return this.max;
        },

        set: function (value)
        {
            this.max = value;
        }

    }

});

module.exports = MinMax2;
<|endoftext|>


<commit_before>'use strict';

const
    Util = require('./util');

const
    eventBus    = require('./event-bus'),
    soundLoader = require('./sound-loader');

const
    ICON_TRANSPARENCY = 0.70,
    MUTE_KEY = '183461283-sound-mute',
    CRACKLE_TIME = 200;

class Sound {

    /**
     * TOOD: Clean this up by breaking into small objects.
     */
    constructor(parentGfx) {
        this.parentGfx = parentGfx;
        this._gfx = new PIXI.Container();
        this._gfx.x = 750;
        this._gfx.y = 550;
        this.parentGfx.addChild(this._gfx);

        let soundOnTexture = PIXI.Texture.fromFrame('sound-on.png');
        this._soundOnIcon = new PIXI.Sprite(soundOnTexture);
        this._soundOnIcon.alpha = ICON_TRANSPARENCY;
        this._soundOnIcon.interactive = true;
        this._soundOnIcon.on('mouseover', () => {
            this._soundOnIcon.alpha = 1.0;
        });
        this._soundOnIcon.on('mouseout', () => {
            this._soundOnIcon.alpha = ICON_TRANSPARENCY;
        });
        this._soundOnIcon.on('mousedown', () => {
            this._soundOnIcon.visible = false;
            this._soundOffIcon.visible = true;
            Howler.mute();
            sessionStorage.setItem(MUTE_KEY, 'on');
        });
        this._soundOnIcon.visible = false;
        this._gfx.addChild(this._soundOnIcon);

        let soundOffTexture = PIXI.Texture.fromFrame('sound-off.png');
        this._soundOffIcon = new PIXI.Sprite(soundOffTexture);
        this._soundOffIcon.interactive = true;
        this._soundOffIcon.on('mouseover', () => {
            this._soundOffIcon.alpha = 1.0;
        });
        this._soundOffIcon.on('mouseout', () => {
            this._soundOffIcon.alpha = ICON_TRANSPARENCY;
        });
        this._soundOffIcon.on('mousedown', () => {
            this._soundOffIcon.visible = false;
            this._soundOnIcon.visible = true;
            Howler.unmute();
            sessionStorage.setItem(MUTE_KEY, 'off');
        });
        this._soundOffIcon.alpha = ICON_TRANSPARENCY;
        this._soundOffIcon.visible = false;
        this._gfx.addChild(this._soundOffIcon);

        // Configure sound files

        this._punch = soundLoader.get('assets/punch.m4a');
        this._punch.volume(0.5);

        let wham1 = soundLoader.get('assets/wham1.m4a');
        let wham2 = soundLoader.get('assets/wham2.m4a');
        let wham3 = soundLoader.get('assets/wham3.m4a');
        this._whams = [ wham1, wham2, wham3 ];
        for (let wham of this._whams) {
            wham.volume(0.25);
        }

        this._energizer = soundLoader.get('assets/energizer.m4a');
        this._energizer.volume(0.5);

        let levelBackground1 = soundLoader.get('assets/cool-journey.m4a');
        let levelBackground2 = soundLoader.get('assets/happy-energy.m4a');
        this._levelBackgrounds = [ levelBackground1, levelBackground2 ];
        for (let levelBackground of this._levelBackgrounds) {
            levelBackground.volume(0.9);
            levelBackground.loop(true);
        }

        this._currentBackground = 0;

        this._levelEnd = soundLoader.get('assets/atari-st-beat-11.m4a');
        this._levelEnd.volume(0.4);
        this._levelEnd.loop(true);

        this._crackles = soundLoader.get('assets/crackles.m4a');
        this._crackles.volume(0.2);
        this._crackles.loop(true);

        this._cracklesTimeLeft = 0;

        Howler.volume(0.9);
    }

    step(elapsed) {
        if (this._cracklesTimeLeft > 0) {
            this._cracklesTimeLeft -= elapsed;
            if (this._cracklesTimeLeft <= 0) {
                this._cracklesTimeLeft = 0;
                this._crackles.pause();
            }
        }
    }

    start() {
        this._pauseBackgroundMusic = () => {
            this._levelBackgrounds[this._currentBackground].pause();
        };
        eventBus.register('event.pause.begin', this._pauseBackgroundMusic);

        this._playBackgroundMusic = () => {
            this._levelBackgrounds[this._currentBackground].play();
        };
        eventBus.register('event.pause.end', this._playBackgroundMusic);

        this._playLevelEndMusic = () => {
            this._stopAllMusic();
            this._levelEnd.play();
        };
        eventBus.register('event.level.end', this._playLevelEndMusic);

        this._stopLevelEndMusic = () => {
            this._levelEnd.stop();

            this._currentBackground += 1;
            if (this._currentBackground >= this._levelBackgrounds.length) {
                this._currentBackground = 0;
            }
        };
        eventBus.register('event.level.ending.readyfornext', this._stopLevelEndMusic);

        this._playWham = () => {
            let idx = Util.getRandomIntInclusive(0, this._whams.length - 1);
            this._whams[idx].play();
        };
        eventBus.register('event.action.death.pacman', this._playWham);

        this._playPunch = () => {
            this._punch.play();
        };
        eventBus.register('event.action.death.ghost', this._playPunch);

        this._playEnergizer = () => {
            this._energizer.play();
        };
        eventBus.register('event.action.energizer', this._playEnergizer);

        this._ensureCrackles = () => {
            if (this._cracklesTimeLeft > 0) {
                this._cracklesTimeLeft = CRACKLE_TIME;
            } else {
                this._cracklesTimeLeft = CRACKLE_TIME;
                this._crackles.play();
            }
        };
        eventBus.register('event.action.eatdot', this._ensureCrackles);

        // Determine if the user had muted during this session
        let mute = sessionStorage.getItem(MUTE_KEY);
        if (mute === 'on') {
            this._soundOffIcon.visible = true;
            Howler.mute();
        } else {
            this._soundOnIcon.visible = true;
            Howler.unmute();
        }
    }

    stop() {
        eventBus.unregister('event.action.death.ghost', this._playWham);
        eventBus.unregister('event.action.death.ghost', this._playPunch);
        eventBus.unregister('event.action.energizer', this._playEnergizer);
        // TODO: unregister the other stuff
    }

    _stopAllMusic() {
        for (let music of this._levelBackgrounds) {
            music.stop();
        }

        this._levelEnd.stop();
    }
}

module.exports = Sound;<commit_msg>Normalize sound volume a bit<commit_after>'use strict';

const
    Util = require('./util');

const
    eventBus    = require('./event-bus'),
    soundLoader = require('./sound-loader');

const
    ICON_TRANSPARENCY = 0.70,
    MUTE_KEY = '183461283-sound-mute',
    CRACKLE_TIME = 200;

class Sound {

    /**
     * TOOD: Clean this up by breaking into small objects.
     */
    constructor(parentGfx) {
        this.parentGfx = parentGfx;
        this._gfx = new PIXI.Container();
        this._gfx.x = 750;
        this._gfx.y = 550;
        this.parentGfx.addChild(this._gfx);

        let soundOnTexture = PIXI.Texture.fromFrame('sound-on.png');
        this._soundOnIcon = new PIXI.Sprite(soundOnTexture);
        this._soundOnIcon.alpha = ICON_TRANSPARENCY;
        this._soundOnIcon.interactive = true;
        this._soundOnIcon.on('mouseover', () => {
            this._soundOnIcon.alpha = 1.0;
        });
        this._soundOnIcon.on('mouseout', () => {
            this._soundOnIcon.alpha = ICON_TRANSPARENCY;
        });
        this._soundOnIcon.on('mousedown', () => {
            this._soundOnIcon.visible = false;
            this._soundOffIcon.visible = true;
            Howler.mute();
            sessionStorage.setItem(MUTE_KEY, 'on');
        });
        this._soundOnIcon.visible = false;
        this._gfx.addChild(this._soundOnIcon);

        let soundOffTexture = PIXI.Texture.fromFrame('sound-off.png');
        this._soundOffIcon = new PIXI.Sprite(soundOffTexture);
        this._soundOffIcon.interactive = true;
        this._soundOffIcon.on('mouseover', () => {
            this._soundOffIcon.alpha = 1.0;
        });
        this._soundOffIcon.on('mouseout', () => {
            this._soundOffIcon.alpha = ICON_TRANSPARENCY;
        });
        this._soundOffIcon.on('mousedown', () => {
            this._soundOffIcon.visible = false;
            this._soundOnIcon.visible = true;
            Howler.unmute();
            sessionStorage.setItem(MUTE_KEY, 'off');
        });
        this._soundOffIcon.alpha = ICON_TRANSPARENCY;
        this._soundOffIcon.visible = false;
        this._gfx.addChild(this._soundOffIcon);

        // Configure sound files

        this._punch = soundLoader.get('assets/punch.m4a');
        this._punch.volume(0.4);

        let wham1 = soundLoader.get('assets/wham1.m4a');
        let wham2 = soundLoader.get('assets/wham2.m4a');
        let wham3 = soundLoader.get('assets/wham3.m4a');
        this._whams = [ wham1, wham2, wham3 ];
        for (let wham of this._whams) {
            wham.volume(0.20);
        }

        this._energizer = soundLoader.get('assets/energizer.m4a');
        this._energizer.volume(0.5);

        let levelBackground1 = soundLoader.get('assets/cool-journey.m4a');
        let levelBackground2 = soundLoader.get('assets/happy-energy.m4a');
        this._levelBackgrounds = [ levelBackground1, levelBackground2 ];
        for (let levelBackground of this._levelBackgrounds) {
            levelBackground.volume(0.9);
            levelBackground.loop(true);
        }

        this._currentBackground = 0;

        this._levelEnd = soundLoader.get('assets/atari-st-beat-11.m4a');
        this._levelEnd.volume(0.35);
        this._levelEnd.loop(true);

        this._crackles = soundLoader.get('assets/crackles.m4a');
        this._crackles.volume(0.3);
        this._crackles.loop(true);

        this._cracklesTimeLeft = 0;

        Howler.volume(0.9);
    }

    step(elapsed) {
        if (this._cracklesTimeLeft > 0) {
            this._cracklesTimeLeft -= elapsed;
            if (this._cracklesTimeLeft <= 0) {
                this._cracklesTimeLeft = 0;
                this._crackles.pause();
            }
        }
    }

    start() {
        this._pauseBackgroundMusic = () => {
            this._levelBackgrounds[this._currentBackground].pause();
        };
        eventBus.register('event.pause.begin', this._pauseBackgroundMusic);

        this._playBackgroundMusic = () => {
            this._levelBackgrounds[this._currentBackground].play();
        };
        eventBus.register('event.pause.end', this._playBackgroundMusic);

        this._playLevelEndMusic = () => {
            this._stopAllMusic();
            this._levelEnd.play();
        };
        eventBus.register('event.level.end', this._playLevelEndMusic);

        this._stopLevelEndMusic = () => {
            this._levelEnd.stop();

            this._currentBackground += 1;
            if (this._currentBackground >= this._levelBackgrounds.length) {
                this._currentBackground = 0;
            }
        };
        eventBus.register('event.level.ending.readyfornext', this._stopLevelEndMusic);

        this._playWham = () => {
            let idx = Util.getRandomIntInclusive(0, this._whams.length - 1);
            this._whams[idx].play();
        };
        eventBus.register('event.action.death.pacman', this._playWham);

        this._playPunch = () => {
            this._punch.play();
        };
        eventBus.register('event.action.death.ghost', this._playPunch);

        this._playEnergizer = () => {
            this._energizer.play();
        };
        eventBus.register('event.action.energizer', this._playEnergizer);

        this._ensureCrackles = () => {
            if (this._cracklesTimeLeft > 0) {
                this._cracklesTimeLeft = CRACKLE_TIME;
            } else {
                this._cracklesTimeLeft = CRACKLE_TIME;
                this._crackles.play();
            }
        };
        eventBus.register('event.action.eatdot', this._ensureCrackles);

        // Determine if the user had muted during this session
        let mute = sessionStorage.getItem(MUTE_KEY);
        if (mute === 'on') {
            this._soundOffIcon.visible = true;
            Howler.mute();
        } else {
            this._soundOnIcon.visible = true;
            Howler.unmute();
        }
    }

    stop() {
        eventBus.unregister('event.action.death.ghost', this._playWham);
        eventBus.unregister('event.action.death.ghost', this._playPunch);
        eventBus.unregister('event.action.energizer', this._playEnergizer);
        // TODO: unregister the other stuff
    }

    _stopAllMusic() {
        for (let music of this._levelBackgrounds) {
            music.stop();
        }

        this._levelEnd.stop();
    }
}

module.exports = Sound;<|endoftext|>


<commit_before>var socket = io();

var articles = document.getElementsByClassName('articles')[0];
var pending = document.getElementsByClassName('pending')[0];

socket.on('connect', obj => {
  console.log('>> hello, you are connected on',socket.id);
})

socket.on('news', msg => {
  pending.classList.add('hidden');
  msg = JSON.parse(msg);
  console.log('got the result',msg)
  addToPage(msg);
});

function addToPage(msg) {

  var box = document.createElement('DIV');
  box.classList.add('box');

  var article = document.createElement('DIV');
  article.classList.add('internal-content');

  var h1 = document.createElement('H1');
  var a = document.createElement('A');
  a.setAttribute('href', msg.url)
  var textNode = document.createTextNode(msg.headline);
  a.classList.add('headline');
  a.appendChild(textNode);
  h1.appendChild(a);
  article.appendChild(h1);

  var h3 = document.createElement('H3');
  var textNode2 = document.createTextNode('Sentiment Value: ')
  h3.appendChild(textNode2);
  var span = document.createElement('SPAN');
  span.classList.add('sentiment-value')
  var textNode3 = document.createTextNode(msg.sentimentValue);
  span.appendChild(textNode3);
  h3.appendChild(span);
  article.appendChild(h3);

  var content = document.createElement('DIV');
  content.classList.add('content');
  article.appendChild(content);

  msg.content.forEach(paragraph => {
    var p = document.createElement('P');
    var textNode3 = document.createTextNode(paragraph);
    p.appendChild(textNode3);
    content.appendChild(p);
  });

  box.appendChild(article);
  articles.appendChild(box);
}
<commit_msg>Getting rid of console.log in browser<commit_after>var socket = io();

var articles = document.getElementsByClassName('articles')[0];
var pending = document.getElementsByClassName('pending')[0];

socket.on('connect', obj => {
  console.log([
    '\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\_',
    ' \\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/ ',
    ' /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\_',
    '/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/_',
    '\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\_',
    ' \\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/ ',
    ' /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\_',
    '/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/_',
    '\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\_',
    ' \\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/ ',
    ' /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\_',
    '/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/_',
    '\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\_',
    ' \\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/ ',
    ' /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\_',
    '/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/_',
    '\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\_',
    ' \\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/ ',
    ' /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\_',
    '/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/_',
    '\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\_',
    ' \\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/  \\_\\/__\\/_/ ',
    ' /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\__/ /\\__/\\ \\_'
  ].join('\n'));
})

socket.on('news', msg => {
  pending.classList.add('hidden');
  msg = JSON.parse(msg);
  addToPage(msg);
});

function addToPage(msg) {

  var box = document.createElement('DIV');
  box.classList.add('box');

  var article = document.createElement('DIV');
  article.classList.add('internal-content');

  var h1 = document.createElement('H1');
  var a = document.createElement('A');
  a.setAttribute('href', msg.url)
  var textNode = document.createTextNode(msg.headline);
  a.classList.add('headline');
  a.appendChild(textNode);
  h1.appendChild(a);
  article.appendChild(h1);

  var h3 = document.createElement('H3');
  var textNode2 = document.createTextNode('Sentiment Value: ')
  h3.appendChild(textNode2);
  var span = document.createElement('SPAN');
  span.classList.add('sentiment-value')
  var textNode3 = document.createTextNode(msg.sentimentValue);
  span.appendChild(textNode3);
  h3.appendChild(span);
  article.appendChild(h3);

  var content = document.createElement('DIV');
  content.classList.add('content');
  article.appendChild(content);

  msg.content.forEach(paragraph => {
    var p = document.createElement('P');
    var textNode3 = document.createTextNode(paragraph);
    p.appendChild(textNode3);
    content.appendChild(p);
  });

  box.appendChild(article);
  articles.appendChild(box);
}
<|endoftext|>


<commit_before>$(document).ready(function () {

  "use strict";

  module("Backbone.PageableCollection - setSorting");

  test("constructor", function () {
    var comparator = function () { return 0; };
    var Col = Backbone.PageableCollection.extend({
      comparator: function () { return 1; }
    });
    var col = new Col([], {
      mode: "client",
      comparator: comparator,
      full: true
    });

    ok(col.fullCollection.comparator === comparator);
    ok(!col.comparator);
  });

  test("_makeComparator", function () {
    var col, comparator;

    col = new Backbone.PageableCollection();
    comparator = col._makeComparator();
    strictEqual(comparator, undefined);

    col.state.sortKey = "name";
    col.state.order = 0;
    comparator = col._makeComparator();
    strictEqual(comparator, undefined);

    col.reset([{name: "b"}, {name: "c"}, {name: "A"}, {name: "a"}]);
    col.state.order = -1;
    col.comparator = col._makeComparator();
    col.sort();
    deepEqual(col.pluck("name"), ["A", "a", "b", "c"]);

    col.state.order = 1;
    col.comparator = col._makeComparator();
    col.sort();
    deepEqual(col.pluck("name"), ["c", "b", "a", "A"]);

    delete col.state.sortKey;
    delete col.state.order;
    col.comparator = col._makeComparator("name", -1);
    col.sort();
    deepEqual(col.pluck("name"), ["A", "a", "b", "c"]);

    delete col.state.sortKey;
    delete col.state.order;
    delete col.comparator;
    col.comparator = col._makeComparator("name", 1, function (model, attr) {
      return model.get(attr).toLowerCase();
    });
    col.sort();
    deepEqual(col.pluck("name"), ["c", "b", "A", "a"]);
  });

  test("setSorting", function () {

    var col = new (Backbone.PageableCollection.extend({
      comparator: function (l, r) {
        return 0;
      }
    }))([
      {id: 2},
      {id: 1},
      {id: 3}
    ], {
      pageSize: 3
    });

    col.setSorting("id");
    strictEqual(col.state.sortKey, "id");
    strictEqual(col.state.order, -1);
    ok(!col.state.comparator);
    deepEqual(col.toJSON(), [{id: 2}, {id: 1}, {id: 3}]);

    col.setSorting("id", 1);
    strictEqual(col.state.sortKey, "id");
    strictEqual(col.state.order, 1);
    ok(!col.state.comparator);
    deepEqual(col.toJSON(), [{id: 2}, {id: 1}, {id: 3}]);

    col.setSorting("id", -1, {full: false});
    col.sort();
    deepEqual(col.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);

    col = new Backbone.PageableCollection([
      {id: 2},
      {id: 1},
      {id: 3}
    ], {
      pageSize: 3,
      mode: "client"
    });

    col.setSorting("id", -1, {full: false});
    col.sort();
    deepEqual(col.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);
    ok(!col.fullCollection.comparator);

    col.setSorting(null);
    ok(!col.comparator);

    col.setSorting("id");
    col.fullCollection.sort();
    deepEqual(col.fullCollection.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);
    ok(!col.comparator);

    col.setSorting("id", 1);
    col.fullCollection.sort();
    deepEqual(col.fullCollection.toJSON(), [{id: 3}, {id: 2}, {id: 1}]);
    ok(!col.comparator);

    col.setSorting(null);
    ok(!col.comparator);
    ok(!col.fullCollection.comparator);

    col.setSorting("id", -1, {full: false, sortValue: function (model, sortKey) {
      return model.get(sortKey) / 3;
    }});
    col.sort();
    deepEqual(col.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);
    ok(!col.fullCollection.comparator);
  });

});
<commit_msg>Test case for #253<commit_after>$(document).ready(function () {

  "use strict";

  module("Backbone.PageableCollection - setSorting");

  test("constructor", function () {
    var comparator = function () { return 0; };
    var Col = Backbone.PageableCollection.extend({
      comparator: function () { return 1; }
    });
    var col = new Col([], {
      mode: "client",
      comparator: comparator,
      full: true
    });

    ok(col.fullCollection.comparator === comparator);
    ok(!col.comparator);
  });

  test("_makeComparator", function () {
    var col, comparator;

    col = new Backbone.PageableCollection();
    comparator = col._makeComparator();
    strictEqual(comparator, undefined);

    col.state.sortKey = "name";
    col.state.order = 0;
    comparator = col._makeComparator();
    strictEqual(comparator, undefined);

    col.reset([{name: "b"}, {name: "c"}, {name: "A"}, {name: "a"}]);
    col.state.order = -1;
    col.comparator = col._makeComparator();
    col.sort();
    deepEqual(col.pluck("name"), ["A", "a", "b", "c"]);

    col.state.order = 1;
    col.comparator = col._makeComparator();
    col.sort();
    deepEqual(col.pluck("name"), ["c", "b", "a", "A"]);

    delete col.state.sortKey;
    delete col.state.order;
    col.comparator = col._makeComparator("name", -1);
    col.sort();
    deepEqual(col.pluck("name"), ["A", "a", "b", "c"]);

    delete col.state.sortKey;
    delete col.state.order;
    delete col.comparator;
    col.comparator = col._makeComparator("name", 1, function (model, attr) {
      return model.get(attr).toLowerCase();
    });
    col.sort();
    deepEqual(col.pluck("name"), ["c", "b", "A", "a"]);
  });

  test("setSorting", function () {

    var col = new (Backbone.PageableCollection.extend({
      comparator: function (l, r) {
        return 0;
      }
    }))([
      {id: 2},
      {id: 1},
      {id: 3}
    ], {
      pageSize: 3
    });

    col.setSorting("id");
    strictEqual(col.state.sortKey, "id");
    strictEqual(col.state.order, -1);
    ok(!col.state.comparator);
    deepEqual(col.toJSON(), [{id: 2}, {id: 1}, {id: 3}]);

    col.setSorting("id", 1);
    strictEqual(col.state.sortKey, "id");
    strictEqual(col.state.order, 1);
    ok(!col.state.comparator);
    deepEqual(col.toJSON(), [{id: 2}, {id: 1}, {id: 3}]);

    col.setSorting("id", -1, {full: false});
    col.sort();
    deepEqual(col.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);

    col = new Backbone.PageableCollection([
      {id: 2},
      {id: 1},
      {id: 3}
    ], {
      pageSize: 3,
      mode: "client"
    });

    col.setSorting("id", -1, {full: false});
    col.sort();
    deepEqual(col.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);
    ok(!col.fullCollection.comparator);

    col.setSorting(null);
    ok(!col.comparator);

    col.setSorting("id");
    col.fullCollection.sort();
    deepEqual(col.fullCollection.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);
    ok(!col.comparator);

    col.setSorting("id", 1);
    col.fullCollection.sort();
    deepEqual(col.fullCollection.toJSON(), [{id: 3}, {id: 2}, {id: 1}]);
    ok(!col.comparator);

    col.setSorting(null);
    ok(!col.comparator);
    ok(!col.fullCollection.comparator);

    col.setSorting("id", -1, {full: false, sortValue: function (model, sortKey) {
      return model.get(sortKey) / 3;
    }});
    col.sort();
    deepEqual(col.toJSON(), [{id: 1}, {id: 2}, {id: 3}]);
    ok(!col.fullCollection.comparator);
  });

  test("Issue #253 Make sure the sorted result on the full collection is reflected on the current page", function () {
    var col = new Backbone.PageableCollection(
      [
        {"volume":8},
        {"volume":6},
        {"volume":6},
        {"volume":3},
        {"volume":2},
        {"volume":2},
        {"volume":2},
        {"volume":1},
        {"volume":1},
        {"volume":1},

        {"volume":112},
        {"volume":38},
        {"volume":24},
        {"volume":22},
        {"volume":19},
        {"volume":13},
        {"volume":13},
        {"volume":10},
        {"volume":9},
        {"volume":9},

        {"volume":1},
        {"volume":1},
        {"volume":1},
        {"volume":1},
        {"volume":1},
        {"volume":1}
      ], {
        state: {
          pageSize: 10
        },
        mode: "client"
      });
    col.setSorting("volume", 1, {full: true});
    col.fullCollection.sort();
    deepEqual(col.getFirstPage().pluck("volume"), [112,38,24,22,19,13,13,10,9,9]);
    deepEqual(col.getNextPage().pluck("volume"), [8,6,6,3,2,2,2,1,1,1]);
    deepEqual(col.getNextPage().pluck("volume"), [1,1,1,1,1,1]);
    deepEqual(col.fullCollection.pluck("volume"), [112,38,24,22,19,13,13,10,9,9,8,6,6,3,2,2,2,1,1,1,1,1,1,1,1,1]);
  });

});
<|endoftext|>


<commit_before>"use strict";

(function (K) {
    var db = require('pg');
    var config = {
        host : '/var/run/postgresql',
        database : 'kwarque'
    };
    //or native libpq bindings
    //var pg = require('pg').native

    //error handling omitted
    K.db = {
        getFragments : function(timestamp, area, fn) {
            db.connect(config, function(err, client) {
                client.query("SELECT location[0] AS lon, location[1] AS lat, title, text FROM fragment", function(err, result) {
                    console.log(err);
                    fn(result);
                });
            });
        },

        insertFragment : function(data, fn) {
            db.connect(config, function(err, client) {
                client.query({
                    name : 'insert fragment',
                    text : "INSERT INTO fragment (location, title, text) VALUES (POINT($1, $2), $3, $4)",
                    values : [data.lon, data.lat, data.title, data.text]
                }, fn);
            })
        },

        serve : function(client) {
            /**
             * watch an area on the map.
             */
            client.on("watch", function(select, fn) {
                K.db.getFragments(select.timestamp, select.area, function(result) {
                    fn(result);
                });
            });
            /**
             * ignore an area on the map
             */
            client.on("ignore", function(select, fn) {

            });

            client.on("insert", function(data, fn) {
                K.db.insertFragment(data, fn);
            });
        }
    }
})(process.KWARQUE);<commit_msg>remove useless error message<commit_after>"use strict";

(function (K) {
    var db = require('pg');
    var config = {
        host : '/var/run/postgresql',
        database : 'kwarque'
    };
    //or native libpq bindings
    //var pg = require('pg').native

    //error handling omitted
    K.db = {
        getFragments : function(timestamp, area, fn) {
            db.connect(config, function(err, client) {
                client.query("SELECT location[0] AS lon, location[1] AS lat, title, text FROM fragment", function(err, result) {
                    fn(result);
                });
            });
        },

        insertFragment : function(data, fn) {
            db.connect(config, function(err, client) {
                client.query({
                    name : 'insert fragment',
                    text : "INSERT INTO fragment (location, title, text) VALUES (POINT($1, $2), $3, $4)",
                    values : [data.lon, data.lat, data.title, data.text]
                }, fn);
            })
        },

        serve : function(client) {
            /**
             * watch an area on the map.
             */
            client.on("watch", function(select, fn) {
                K.db.getFragments(select.timestamp, select.area, function(result) {
                    fn(result);
                });
            });
            /**
             * ignore an area on the map
             */
            client.on("ignore", function(select, fn) {

            });

            client.on("insert", function(data, fn) {
                K.db.insertFragment(data, fn);
            });
        }
    }
})(process.KWARQUE);<|endoftext|>