<commit_before>var C = 10;
var colors = require('./colors.js');
var mapCX = 1000;
var mapCY = 710;

var u = require('./simplify.js').u;
var line = require('./simplify.js').line;
var createGem = require('./simplify.js').createGem;

module.exports = {
  levelObjects:{
    playerStart: {x: u(12)+C, y: u(8)},
    levelFinish:{x: u(23), y: u(16)}
  },
  size: { x: mapCX, y: mapCY },
  startColor: colors.yellow,
  gems: [].
concat(createGem( u(2),u(11), colors.red)).
concat(createGem( u(2),u(16), colors.purple)).
concat(createGem( u(18),u(11), colors.green)).
concat(createGem( u(22.5),u(3), colors.red)).
concat(createGem( u(8.5),u(3), colors.blue))
,
  walls: [].
concat(line(u(3),u(4),C,u(4),colors.green, 'g1')).
concat( line(u(6.5),u(8),u(4)-C,C,colors.red, 'r1')).
concat( line(u(2.5),u(14),u(2.5),C,colors.red, 'r2')).
concat( line(u(5)-C,u(11)+C,C,u(3),colors.blue, 'b1')).
concat( line(u(5)-C,u(16)-C,C,u(2),colors.purple, 'p1')).
concat( line(u(10),u(11)+C,C,u(3),colors.purple, 'p2')).
concat( line(u(13),u(14),u(3)-C,C,colors.green, 'g2')).
concat( line(u(14)+C,u(2),C,u(2),colors.purple, 'p3')).
concat( line(u(14)+C,u(9)-C/2,C,u(5)-C/2,colors.blue, 'b2')).
concat( line(u(16),u(16)-C,C,u(2),colors.green, 'g3')).
concat( line(u(23),u(14),u(2), C,colors.blue, 'b3')).
concat( line(u(16)+C/2,u(4),u(2)+C/2, C,colors.green, 'g4')).
concat( line(u(20)-C,u(7),u(1.5),C,colors.purple, 'p5')).
concat( line(u(18),u(5.5)+C,C,u(1.5),colors.red, 'r5')).
concat( line(u(21),u(11)-C,C,u(3.5),colors.red, 'r4')).
concat( line(u(21),u(16)-C,C,u(2),colors.purple, 'p6'))
};
<commit_msg>fixing some weird walls on the orig lev3<commit_after>var C = 10;
var colors = require('./colors.js');
var mapCX = 1000;
var mapCY = 710;

var u = require('./simplify.js').u;
var line = require('./simplify.js').line;
var createGem = require('./simplify.js').createGem;

module.exports = {
  levelObjects:{
    playerStart: {x: u(12)+C, y: u(8)},
    levelFinish:{x: u(23), y: u(16)}
  },
  size: { x: mapCX, y: mapCY },
  startColor: colors.yellow,
  gems: [].
concat(createGem( u(2),u(11), colors.red)).
concat(createGem( u(2),u(16), colors.purple)).
concat(createGem( u(18),u(11), colors.green)).
concat(createGem( u(22.5),u(3), colors.red)).
concat(createGem( u(8.5),u(3), colors.blue))
,
  walls: [].
concat(line(u(3),u(4),C,u(4),colors.green, 'g1')).
concat( line(u(6.5),u(8),u(4)-C,C,colors.red, 'r1')).
concat( line(u(2.5),u(14),u(2.5),C,colors.red, 'r2')).
concat( line(u(5)-C,u(11)+C,C,u(3),colors.blue, 'b1')).
concat( line(u(5)-C,u(16)-C,C,u(2),colors.purple, 'p1')).
concat( line(u(10),u(11)+C,C,u(3),colors.purple, 'p2')).
concat( line(u(12),u(14),u(2.25),C,colors.green, 'g2')).
concat( line(u(14)+C,u(2),C,u(2),colors.purple, 'p3')).
concat( line(u(14)+C,u(9)-C/2,C,u(5)-C/2,colors.blue, 'b2')).
concat( line(u(14)+C,u(16)-C,C,u(2),colors.green, 'g3')).
concat( line(u(23),u(14),u(2), C,colors.blue, 'b3')).
concat( line(u(16)+C/2,u(4),u(2)+C/2, C,colors.green, 'g4')).
concat( line(u(20)-C,u(7),u(1.5),C,colors.purple, 'p5')).
concat( line(u(18),u(5.5)+C,C,u(1.5),colors.red, 'r5')).
concat( line(u(21),u(11)-C,C,u(3.5),colors.red, 'r4')).
concat( line(u(21),u(16)-C,C,u(2),colors.purple, 'p6'))
};
<|endoftext|>


<commit_before>var w = 600;
var h = 400;

void setup() {
  size(w, h);
}

void draw() {
  //fill(255,0,0);
  //ellipse(200,200,10,10);
  //rect(200,205,10,10);
  //fill(255,255,255);
  //text('e',200,210);

  // face
  fill(player.skin[0],player.skin[1],player.skin[2]);
  ellipse(player.x,player.y-10,12+player.face*4,20);

  // arms
  rect(player.x-10,player.y+4,4,8);
  rect(player.x+6,player.y+4,4,8);

  // tshirt
  fill(player.tColor[0],player.tColor[1],player.tColor[2]);
  rect(player.x-6,player.y,12,10);
  rect(player.x-10,player.y,4,4);
  rect(player.x+6,player.y,4,4);

  /*
  // hat
  rect(player.x-player.face-6, player.y-25, player.face*2+12, 5);
  fill(0,0,100);
  rect(player.x-player.face-6-3, player.y-21, 3, 2);
  */

  // tshirt logo
  fill(255,255,255);
  text(player.tshirt,player.x-3,player.y+9);

  // eye whites
  fill(255,255,255);
  ellipse(player.x-3-player.face,player.y-11,4,5);
  ellipse(player.x+3+player.face,player.y-11,4,5);

  //pupils
  fill(0,0,0);
  ellipse(player.x-3-player.face,player.y-11,1,1);
  ellipse(player.x+3+player.face,player.y-11,1,1);

  // mouth
  //rect(player.x-3,payer.y-5,6,1);

  //pants
  fill(0,100,0);
  rect(player.x-4,player.y+10,8,4);
  rect(player.x-4,player.y+14,3,4);
  rect(player.x+2, player.y+14,3,4);

  //shoes
  fill(0,0,0);
  rect(player.x-5,player.y+19,5,2);
  rect(player.x+2,player.y+19,5,2);

}
<commit_msg>Update drawgame.js<commit_after>var w = 600;
var h = 400;

void setup() {
  size(w, h);
}

void draw() {
  //fill(255,0,0);
  //ellipse(200,200,10,10);
  //rect(200,205,10,10);
  //fill(255,255,255);
  //text('e',200,210);

  fill(player.skin[0],player.skin[1],player.skin[2]);
  //ears
  ellipse(player.x-6-player.face*2,player.y-12,4,4);
  ellipse(player.x+6+player.face*2,player.y-12,4,4);
   // head
  ellipse(player.x,player.y-10,12+player.face*4,20);

  // arms
  rect(player.x-10,player.y+8,4,4);
  rect(player.x+6,player.y+8,4,4);

  // tshirt
  fill(player.tColor[0],player.tColor[1],player.tColor[2]);
  rect(player.x-6,player.y,12,10);
  rect(player.x-10,player.y,4,8);
  rect(player.x+6,player.y,4,8);

  /*
  // hat
  rect(player.x-player.face-6, player.y-25, player.face*2+12, 5);
  fill(0,0,100);
  rect(player.x-player.face-6-3, player.y-21, 3, 2);
  */

  // tshirt logo
  fill(255,255,255);
  text(player.tshirt,player.x-3,player.y+9);

  // eye whites
  fill(255,255,255);
  ellipse(player.x-3-player.face,player.y-11,4,5);
  ellipse(player.x+3+player.face,player.y-11,4,5);

  //pupils
  fill(0,0,0);
  ellipse(player.x-3-player.face,player.y-11,1,1);
  ellipse(player.x+3+player.face,player.y-11,1,1);

  // mouth
  //rect(player.x-3,payer.y-5,6,1);

  //pants
  fill(0,100,0);
  rect(player.x-4,player.y+10,8,4);
  rect(player.x-4,player.y+14,3,4);
  rect(player.x+2, player.y+14,3,4);

  //shoes
  fill(0,0,0);
  rect(player.x-5,player.y+19,5,2);
  rect(player.x+2,player.y+19,5,2);

}
<|endoftext|>


<commit_before>var fs           =  require('fs');
var async        =  require('async');
var unshort      =  require('unshort');
var profanity    =  require('./profanity');
var Bitstamp     =  require('./Bitstamp');
var Blockchain   =  require('./Blockchain');

var Client       =  require('./Client');
var Lib          =  require('./Lib');
var Db           =  require('./Db');
var Config       =  require('./Config')();

var debug        =  require('debug')('shiba');

// Command syntax
var cmdReg = /^!([a-zA-z]*)\s*(.*)$/i;

function Shiba() {
  this.client = new Client(Config);

  this.setupUsernameScrape();
  this.setupConsoleLog();
  this.setupLossStreakComment();
  this.setupScamComment();
  this.setupBlockchain();
}

Shiba.prototype.setupUsernameScrape = function() {
  var self = this;
  self.client.on('player_bet', function(data) {
    Db.putUsername(data.username);
  });
  self.client.on('msg', function(msg) {
    if (msg.type != 'say') return;
    Db.putUsername(msg.username);
    Db.updateSeen(msg.username, msg);
    self.onSay(msg);
  });
};

Shiba.prototype.setupConsoleLog = function() {
  var self = this;
  self.client.on('game_starting', function(info) {
    var line =
        "Starting " + info.game_id +
        " " + info.hash.substring(0,8);
    process.stdout.write(line);
  });

  self.client.on('game_started', function(data) {
    process.stdout.write(".. ");
  });

  self.client.on('game_crash', function(data) {
    var gameInfo = self.client.getGameInfo();
    var crash = Lib.formatFactor(data.game_crash);
    process.stdout.write(" @" + crash + "x " + gameInfo.verified + "\n");
  });
};

Shiba.prototype.setupLossStreakComment = function() {
  var self = this;
  self.client.on('game_crash', function(data) {
    var gameHistory = self.client.gameHistory;

    // Determine loss streak
    var streak = gameHistory.length > 3;
    for (var i = 0; i < Math.min(gameHistory.length - 1, 4); ++i)
      streak = streak && gameHistory[i].game_crash <= 130;

    // Don't repeat yourself in a streak
    streak = streak && (gameHistory.length < 4 ||
                        gameHistory[i + 1].game_crash > 130);

    if (streak) self.client.doSay("wow. such rape. very butthurt");
  });
};

Shiba.prototype.setupScamComment = function() {
  var self = this;
  self.client.on('game_crash', function(data) {
    var gameInfo = self.client.getGameInfo();
    console.assert(gameInfo.hasOwnProperty('verified'));
    if (gameInfo.verified != 'ok') {
      self.client.doSay('wow. such scam. very hash failure.');
    }
  });
};

Shiba.prototype.setupBlockchain = function() {
  var bc = new Blockchain();

  bc.on('block', function(block) {
    Db.put('block', block);
  });
};

Shiba.prototype.getChatMessages = function(username, after) {
  var messages = [];
  var chatHistory = this.client.chatHistory;
  for (var i = 0; i < chatHistory.length; ++i) {
    then = new Date(chatHistory[i].time);
    if (then < after) break;

    if (chatHistory[i].type === 'say' &&
        chatHistory[i].username === username)
      messages.push(chatHistory[i]);
  }
  return messages;
};

Shiba.prototype.onSay = function(msg) {
  if (msg.username === this.client.username) return;

  var regexs  = [ /cloud.*mining.*vk\.cc\/[0-9a-z]/i,
                  /cur\.lv\/.*/i,
                  /minefield\.bitcoinlab\.org\/.*(\?|&)r=/i,
                  /strongbank\.biz\/\?.*ref=.*/i,
                  /satoshimines\.com\/a\/[^\s]+/i
                ];

  // Match entire message against the regular expressions.
  for (var r = 0; r < regexs.length; ++r)
    if (msg.message.match(regexs[r]))
      return this.client.doMute(msg.username, '6h');

  // Extract a list of URLs.
  // TODO: The regular expression could be made more intelligent.
  var urls = msg.message.match(/https?:\/\/[^\s]+/ig) || [];

  var urls2 = msg.message.match(/(\s|^)bit.ly\/[^s]+/ig);
  if (urls2) {
    for (var i = 0; i < urls2.length; ++i)
      urls2[i] = 'http://' + urls2[i].replace(/^\s+/g,'');
    urls = urls.concat(urls2);
  }
  var urls3 = msg.message.match(/(\s|^)goo.gl\/[^s]+/ig);
  if (urls3) {
    for (var i = 0; i < urls3.length; ++i)
      urls3[i] = 'http://' + urls3[i].replace(/^\s+/g,'');
    urls = urls.concat(urls3);
  }

  // Unshorten extracted URLs.
  var self = this;
  async.map(urls, unshort, function(err, urls2) {
    urls = urls.concat(urls2);
    for (var i = 0; i < urls.length; ++i) {
      var url    = urls[i];
      debug('Checking url: ' + url);

      // Run the regular expressions against the unshortened url.
      for (var r = 0; r < regexs.length; ++r)
        if (url.match(regexs[r])) {
          debug('URL matched ' + regexs[r]);
          return self.client.doMute(msg.username, '24h');
        }
    }

    var after, messages;
    // Rate limiter < 4 messages in 1s
    after    = new Date(Date.now() - 1000);
    messages = self.getChatMessages(msg.username, after);
    if (messages.length >= 4) return self.client.doMute(msg.username, '15m');

    // Rate limiter < 5 messages in 5s
    after    = new Date(Date.now() - 5000);
    messages = self.getChatMessages(msg.username, after);
    if (messages.length >= 5) return self.client.doMute(msg.username, '15m');

    // Rate limiter < 8 messages in 12s
    after    = new Date(Date.now() - 12000);
    messages = self.getChatMessages(msg.username, after);
    if (messages.length >= 8) return self.client.doMute(msg.username, '15m');

    // Everything checked out fine so far. Continue with the command
    // processing phase.
    var cmdMatch = msg.message.match(cmdReg);
    if (cmdMatch) self.onCmd(msg, cmdMatch[1], cmdMatch[2]);
  });
};

Shiba.prototype.onCmd = function(msg, cmd, rest) {
  // Cmd rate limiter
  var after    = new Date(Date.now() - 10000);
  var messages = this.getChatMessages(msg.username, after);
  var rate = 0;

  for (var i = 0; i < messages.length; ++i)
    if (messages[i].message.match(cmdReg)) ++rate;

  if (rate >= 4)
    return this.client.doMute(msg.username, '5m');
  else if (rate >= 3)
    return this.client.doSay('bites ' + msg.username);

  switch(cmd.toLowerCase()) {
  case 'custom': this.onCmdCustom(msg, rest); break;
  case 'lick': this.onCmdLick(msg, rest); break;
  case 'seen': this.onCmdSeen(msg, rest); break;
  case 'convert': this.onCmdConvert(msg, rest); break;
  case 'block': this.onCmdBlock(msg, rest); break;
  }
};

Shiba.prototype.onCmdCustom = function(msg, rest) {
  var self = this;
  if (msg.role != 'admin' &&
      msg.role != 'moderator') return;

  var customReg   = /^([A-Za-z0-9]*)\s*(.*)$/;
  var customMatch = rest.match(customReg);
  var customUser  = customMatch[1];
  var customMsg   = customMatch[2];
  Db.addCustomLickMessage(customUser, customMsg, function (err) {
    if (err) {
      console.log('onCmdCustom:', err);
      self.client.doSay('wow. such leveldb fail');
    } else {
      self.client.doSay('wow. so cool. very obedient');
    }
  });
};

Shiba.prototype.onCmdLick = function(msg, user) {
  var self = this;
  user = user.toLowerCase();
  user = user.replace(/^\s+|\s+$/g,'');

  // We're cultivated and don't lick ourselves.
  if (user === self.client.username.toLowerCase()) return;

  if (profanity[user]) {
    self.client.doSay('so trollol. very annoying. such mute');
    self.client.doMute(msg.username, '5m');
    return;
  }

  async.parallel(
    [ function(cb) { Db.getUsername(user, cb); },
      function(cb) { Db.getCustomLickMessages(user, cb); }
    ],
    function (err, val) {
      if (err) return;

      var username = val[0];
      var customs  = val[1];
      customs.push('licks ' + username);
      var r = Math.random() * (customs.length - 0.8);
      var m = customs[Math.floor(r)];
      self.client.doSay(m);
    });
};

Shiba.prototype.onCmdSeen = function(msg, user) {
  var self = this;
  user = user.toLowerCase();
  user = user.replace(/^\s+|\s+$/g,'');

  // Special treatment of block.
  if (user === 'block') return this.onCmdBlock();

  // Avoid this.
  if (user === self.client.username.toLowerCase()) return;

  if (profanity[user]) {
    self.client.doSay('so trollol. very annoying. such mute');
    self.client.doMute(msg.username, '5m');
    return;
  }

  async.parallel(
    [ function(cb) { Db.getUsername(user, cb); },
      function(cb) { Db.getSeen(user, cb); }
    ],
    function (err, val) {
      if (err) return;

      var username = val[0];
      var msg      = val[1];
      var time     = new Date(msg.time);
      var diff     = Date.now() - time;

      var line;
      if (diff < 1000) {
        line = 'Seen ' + username + ' just now.';
      } else {
        line = 'Seen ' + username + ' ';
        line += Lib.formatTimeDiff(diff);
        line += ' ago.';
      }

      self.client.doSay(line);
    });
};

Shiba.prototype.onCmdConvert = function(msg, conv) {
  var self = this;
  conv = conv.replace(/^\s+|\s+$/g,'');
  var convReg = /^((-|\+)?[0-9]*\.?[0-9]*)(k?)\s*(bits?|btc)$/i;
  var convMatch = conv.match(convReg);

  if (convMatch) {
    Bitstamp.getAveragePrice(function(err, price) {

      console.log(convMatch);
      var amount   = parseFloat(convMatch[1], 10);
      var modifier = convMatch[3];
      var currency = convMatch[4].toLowerCase();

      if (currency === 'btc') {
        usd    = amount * price;
        amount *= 1000000;
        if (modifier === 'k' || modifier === 'K') {
          amount *= 1000;
          usd *= 1000;
        }
        self.client.doSay(conv + ' is ' + amount + ' Bit ' + usd + ' USD');
      } else {
        usd = amount * price;
        if (modifier === 'k' || modifier === 'K') {
          amount /= 1000;
          usd /= 1000;
        }
        else {
          amount /= 1000000;
          usd /= 1000000;
        }
        amount = amount.toFixed(8);
        amount = amount.replace(/\.0*$|0*$/,'');
        self.client.doSay(conv + ' is ' + amount + ' BTC ' + usd + ' USD');
      }
    });
  } else {
    self.client.doSay('usage: !convert <number>k? (btc|bit[s])');
  }
};

Shiba.prototype.onCmdBlock = function() {
  var self = this;
  Db.get('block', function(err, block) {
    if (err) return self.client.doSay('wow. such leveldb fail');

    var time     = new Date(block.time * 1000);
    var diff     = Date.now() - time;

    var line = 'Seen block #' + block.height;
    if (diff < 1000) {
      line += ' just now.';
    } else {
      line += ' ';
      line += Lib.formatTimeDiff(diff);
      line += ' ago.';
    }
    self.client.doSay(line);
  });
};

var shiba = new Shiba();
<commit_msg>Block hashprofit referrals<commit_after>var fs           =  require('fs');
var async        =  require('async');
var unshort      =  require('unshort');
var profanity    =  require('./profanity');
var Bitstamp     =  require('./Bitstamp');
var Blockchain   =  require('./Blockchain');

var Client       =  require('./Client');
var Lib          =  require('./Lib');
var Db           =  require('./Db');
var Config       =  require('./Config')();

var debug        =  require('debug')('shiba');

// Command syntax
var cmdReg = /^!([a-zA-z]*)\s*(.*)$/i;

function Shiba() {
  this.client = new Client(Config);

  this.setupUsernameScrape();
  this.setupConsoleLog();
  this.setupLossStreakComment();
  this.setupScamComment();
  this.setupBlockchain();
}

Shiba.prototype.setupUsernameScrape = function() {
  var self = this;
  self.client.on('player_bet', function(data) {
    Db.putUsername(data.username);
  });
  self.client.on('msg', function(msg) {
    if (msg.type != 'say') return;
    Db.putUsername(msg.username);
    Db.updateSeen(msg.username, msg);
    self.onSay(msg);
  });
};

Shiba.prototype.setupConsoleLog = function() {
  var self = this;
  self.client.on('game_starting', function(info) {
    var line =
        "Starting " + info.game_id +
        " " + info.hash.substring(0,8);
    process.stdout.write(line);
  });

  self.client.on('game_started', function(data) {
    process.stdout.write(".. ");
  });

  self.client.on('game_crash', function(data) {
    var gameInfo = self.client.getGameInfo();
    var crash = Lib.formatFactor(data.game_crash);
    process.stdout.write(" @" + crash + "x " + gameInfo.verified + "\n");
  });
};

Shiba.prototype.setupLossStreakComment = function() {
  var self = this;
  self.client.on('game_crash', function(data) {
    var gameHistory = self.client.gameHistory;

    // Determine loss streak
    var streak = gameHistory.length > 3;
    for (var i = 0; i < Math.min(gameHistory.length - 1, 4); ++i)
      streak = streak && gameHistory[i].game_crash <= 130;

    // Don't repeat yourself in a streak
    streak = streak && (gameHistory.length < 4 ||
                        gameHistory[i + 1].game_crash > 130);

    if (streak) self.client.doSay("wow. such rape. very butthurt");
  });
};

Shiba.prototype.setupScamComment = function() {
  var self = this;
  self.client.on('game_crash', function(data) {
    var gameInfo = self.client.getGameInfo();
    console.assert(gameInfo.hasOwnProperty('verified'));
    if (gameInfo.verified != 'ok') {
      self.client.doSay('wow. such scam. very hash failure.');
    }
  });
};

Shiba.prototype.setupBlockchain = function() {
  var bc = new Blockchain();

  bc.on('block', function(block) {
    Db.put('block', block);
  });
};

Shiba.prototype.getChatMessages = function(username, after) {
  var messages = [];
  var chatHistory = this.client.chatHistory;
  for (var i = 0; i < chatHistory.length; ++i) {
    then = new Date(chatHistory[i].time);
    if (then < after) break;

    if (chatHistory[i].type === 'say' &&
        chatHistory[i].username === username)
      messages.push(chatHistory[i]);
  }
  return messages;
};

Shiba.prototype.onSay = function(msg) {
  if (msg.username === this.client.username) return;

  var regexs  = [ /cloud.*mining.*vk\.cc\/[0-9a-z]/i,
                  /cur\.lv\/.*/i,
                  /minefield\.bitcoinlab\.org\/.*(\?|&)r=/i,
                  /strongbank\.biz\/\?.*ref=.*/i,
                  /satoshimines\.com\/a\/[^\s]+/i,
                  /hashprofit.com\/.*\?.*hp=[0-9]*/i
                ];

  // Match entire message against the regular expressions.
  for (var r = 0; r < regexs.length; ++r)
    if (msg.message.match(regexs[r]))
      return this.client.doMute(msg.username, '6h');

  // Extract a list of URLs.
  // TODO: The regular expression could be made more intelligent.
  var urls = msg.message.match(/https?:\/\/[^\s]+/ig) || [];

  var urls2 = msg.message.match(/(\s|^)bit.ly\/[^s]+/ig);
  if (urls2) {
    for (var i = 0; i < urls2.length; ++i)
      urls2[i] = 'http://' + urls2[i].replace(/^\s+/g,'');
    urls = urls.concat(urls2);
  }
  var urls3 = msg.message.match(/(\s|^)goo.gl\/[^s]+/ig);
  if (urls3) {
    for (var i = 0; i < urls3.length; ++i)
      urls3[i] = 'http://' + urls3[i].replace(/^\s+/g,'');
    urls = urls.concat(urls3);
  }

  // Unshorten extracted URLs.
  var self = this;
  async.map(urls, unshort, function(err, urls2) {
    urls = urls.concat(urls2);
    for (var i = 0; i < urls.length; ++i) {
      var url    = urls[i];
      debug('Checking url: ' + url);

      // Run the regular expressions against the unshortened url.
      for (var r = 0; r < regexs.length; ++r)
        if (url.match(regexs[r])) {
          debug('URL matched ' + regexs[r]);
          return self.client.doMute(msg.username, '24h');
        }
    }

    var after, messages;
    // Rate limiter < 4 messages in 1s
    after    = new Date(Date.now() - 1000);
    messages = self.getChatMessages(msg.username, after);
    if (messages.length >= 4) return self.client.doMute(msg.username, '15m');

    // Rate limiter < 5 messages in 5s
    after    = new Date(Date.now() - 5000);
    messages = self.getChatMessages(msg.username, after);
    if (messages.length >= 5) return self.client.doMute(msg.username, '15m');

    // Rate limiter < 8 messages in 12s
    after    = new Date(Date.now() - 12000);
    messages = self.getChatMessages(msg.username, after);
    if (messages.length >= 8) return self.client.doMute(msg.username, '15m');

    // Everything checked out fine so far. Continue with the command
    // processing phase.
    var cmdMatch = msg.message.match(cmdReg);
    if (cmdMatch) self.onCmd(msg, cmdMatch[1], cmdMatch[2]);
  });
};

Shiba.prototype.onCmd = function(msg, cmd, rest) {
  // Cmd rate limiter
  var after    = new Date(Date.now() - 10000);
  var messages = this.getChatMessages(msg.username, after);
  var rate = 0;

  for (var i = 0; i < messages.length; ++i)
    if (messages[i].message.match(cmdReg)) ++rate;

  if (rate >= 4)
    return this.client.doMute(msg.username, '5m');
  else if (rate >= 3)
    return this.client.doSay('bites ' + msg.username);

  switch(cmd.toLowerCase()) {
  case 'custom': this.onCmdCustom(msg, rest); break;
  case 'lick': this.onCmdLick(msg, rest); break;
  case 'seen': this.onCmdSeen(msg, rest); break;
  case 'convert': this.onCmdConvert(msg, rest); break;
  case 'block': this.onCmdBlock(msg, rest); break;
  }
};

Shiba.prototype.onCmdCustom = function(msg, rest) {
  var self = this;
  if (msg.role != 'admin' &&
      msg.role != 'moderator') return;

  var customReg   = /^([A-Za-z0-9]*)\s*(.*)$/;
  var customMatch = rest.match(customReg);
  var customUser  = customMatch[1];
  var customMsg   = customMatch[2];
  Db.addCustomLickMessage(customUser, customMsg, function (err) {
    if (err) {
      console.log('onCmdCustom:', err);
      self.client.doSay('wow. such leveldb fail');
    } else {
      self.client.doSay('wow. so cool. very obedient');
    }
  });
};

Shiba.prototype.onCmdLick = function(msg, user) {
  var self = this;
  user = user.toLowerCase();
  user = user.replace(/^\s+|\s+$/g,'');

  // We're cultivated and don't lick ourselves.
  if (user === self.client.username.toLowerCase()) return;

  if (profanity[user]) {
    self.client.doSay('so trollol. very annoying. such mute');
    self.client.doMute(msg.username, '5m');
    return;
  }

  async.parallel(
    [ function(cb) { Db.getUsername(user, cb); },
      function(cb) { Db.getCustomLickMessages(user, cb); }
    ],
    function (err, val) {
      if (err) return;

      var username = val[0];
      var customs  = val[1];
      customs.push('licks ' + username);
      var r = Math.random() * (customs.length - 0.8);
      var m = customs[Math.floor(r)];
      self.client.doSay(m);
    });
};

Shiba.prototype.onCmdSeen = function(msg, user) {
  var self = this;
  user = user.toLowerCase();
  user = user.replace(/^\s+|\s+$/g,'');

  // Special treatment of block.
  if (user === 'block') return this.onCmdBlock();

  // Avoid this.
  if (user === self.client.username.toLowerCase()) return;

  if (profanity[user]) {
    self.client.doSay('so trollol. very annoying. such mute');
    self.client.doMute(msg.username, '5m');
    return;
  }

  async.parallel(
    [ function(cb) { Db.getUsername(user, cb); },
      function(cb) { Db.getSeen(user, cb); }
    ],
    function (err, val) {
      if (err) return;

      var username = val[0];
      var msg      = val[1];
      var time     = new Date(msg.time);
      var diff     = Date.now() - time;

      var line;
      if (diff < 1000) {
        line = 'Seen ' + username + ' just now.';
      } else {
        line = 'Seen ' + username + ' ';
        line += Lib.formatTimeDiff(diff);
        line += ' ago.';
      }

      self.client.doSay(line);
    });
};

Shiba.prototype.onCmdConvert = function(msg, conv) {
  var self = this;
  conv = conv.replace(/^\s+|\s+$/g,'');
  var convReg = /^((-|\+)?[0-9]*\.?[0-9]*)(k?)\s*(bits?|btc)$/i;
  var convMatch = conv.match(convReg);

  if (convMatch) {
    Bitstamp.getAveragePrice(function(err, price) {

      console.log(convMatch);
      var amount   = parseFloat(convMatch[1], 10);
      var modifier = convMatch[3];
      var currency = convMatch[4].toLowerCase();

      if (currency === 'btc') {
        usd    = amount * price;
        amount *= 1000000;
        if (modifier === 'k' || modifier === 'K') {
          amount *= 1000;
          usd *= 1000;
        }
        self.client.doSay(conv + ' is ' + amount + ' Bit ' + usd + ' USD');
      } else {
        usd = amount * price;
        if (modifier === 'k' || modifier === 'K') {
          amount /= 1000;
          usd /= 1000;
        }
        else {
          amount /= 1000000;
          usd /= 1000000;
        }
        amount = amount.toFixed(8);
        amount = amount.replace(/\.0*$|0*$/,'');
        self.client.doSay(conv + ' is ' + amount + ' BTC ' + usd + ' USD');
      }
    });
  } else {
    self.client.doSay('usage: !convert <number>k? (btc|bit[s])');
  }
};

Shiba.prototype.onCmdBlock = function() {
  var self = this;
  Db.get('block', function(err, block) {
    if (err) return self.client.doSay('wow. such leveldb fail');

    var time     = new Date(block.time * 1000);
    var diff     = Date.now() - time;

    var line = 'Seen block #' + block.height;
    if (diff < 1000) {
      line += ' just now.';
    } else {
      line += ' ';
      line += Lib.formatTimeDiff(diff);
      line += ' ago.';
    }
    self.client.doSay(line);
  });
};

var shiba = new Shiba();
<|endoftext|>


<commit_before>var isMobile = false;
var snake = [[1, 0], [0, 0]]; // An array of [x, y] pairs. The head is at [0], tail is at [-1].
var board; // top left is 0, 0, bottom right is height-1, width-1
var food = [-10, -10];  // if there is no food, use this to avoid null pointers
var refreshRate = 250; // How quickly the snake moves. (ms)
var intervalId;
var gameIsStopped = true;
// high scores (both time- and food-based) for each level
var timeHighScores = [];
var pelletHighScores = [];
var currentTimeScore = 0;

document.cookie = null;
if (document.cookie !== null) {
  console.log(document.cookie);
  cookies = document.cookie.split(';');
  for (var c=0; c<cookies.length; c++) {
    var cookie = cookies[c].split('=');
    console.log(cookie);
    if (cookie[0] == 'speed') {
      var speed = parseInt(cookie[1]);
      var speedSlider = document.getElementById('speedSlider');
      speedSlider.value = speed;
      showValue(speedSlider);
    } else if (cookie[0] == 'highest') {
      maxLevel = cookie[1];
    }
  }
}

// Clears board & stops AI
function stopGame() {
  if ((snake.length - snake.level) > pelletHighScores[level]) {
    pelletHighScores[level] = snake.length - snake.level;
  }
  console.log("Game stopped");
  gameIsStopped = true;
  upLevel();
  board = [];
  board.length = width; // board[x][y]
  for (var i = 0; i < width; i++) {
    board[i] = [];
    board[i].length = height;
  }
  food = [-10, -10];
  snake = [];
  for (var i=0; i<level+3; i++) {
    snake.unshift([i, 0]);
  }
  dir = 'right';
  updateBoard();
}

// Snake collided with self, start next AI level
function startGame() {
  if (!gameIsStopped) {
    return;
  }
  document.cookie = 'speed='+refreshRate+'; highest='+maxLevel+';';
  console.log(document.cookie);
  document.cookie += '; highest=5';
  console.log(document.cookie);
  gameIsStopped = false;
  console.log("Game started");
  console.log("Round ended! Advancing to AI level", level);
  intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
  ai(level);
}

function changeSpeed(rate) {
  refreshRate = rate; // set to new value
  window.clearInterval(intervalId);
  if (!gameIsStopped) { // ensures only one interval going on at once
    intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
    ai(level);
  }
}

function debugSnake() {
  for (var s=0; s<snake.length; s++) {
    console.log(snake[s][0], snake[s][1]);
  }
}

function inSnakeTwice(string) {
  var count = 0;
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      count++;
    }
  }
  return count==2;
}

// String is of form x_y to allow compatibility with Board.js
function inSnake(string) {
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      return true;
    }
  }
  return false;
}

function moveHead(dir) {
  // move snake's head in given direction
  // 'right', 'left', 'up', and 'down'
  var newHead = snake[0].slice(0); // Clone so we don't move the head by accident.
  if (dir == 'right') {
    if (newHead[0] == width - 1) {
      throw 'cannot move right from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]+1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[0]++;
  } else if (dir == 'left') {
    if (newHead[0] === 0) {
      throw 'cannot move left from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]-1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[0]--;
  } else if (dir == 'up') {  // add new head above current one
    if (newHead[1] === 0) {
      throw 'cannot move up from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]-1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[1]--;  // changes y-coordinate by -1 (going UP)
  } else if (dir == 'down') {
    if (newHead[1] == height - 1) {
      throw 'cannot move down from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]+1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[1]++;
  }
  snake.unshift(newHead); // add newHead to the beginning of the list
  if (snake[0][0] == food[0] && snake[0][1] == food[1]) { // if snake's head is on the food
  food = [-10, -10];
} else {
  delTail();
}
updateBoard();
}

function delTail() {  // simple function to remove the tail
  snake.pop();
}

function placeFood(x, y) {
  startGame();
  if (inSnake(x+'_'+y)) {
    console.log('Invalid food placement: Food collides with snake');
  } else if (x >= width || y >= height || x < 0 || y < 0) { // off of board
    console.log('Invalid food placement: Food is off board');
  } else {
    food = [x, y];
    updateBoard();
  }
}
<commit_msg>Well it saves speed at least<commit_after>var isMobile = false;
var snake = [[1, 0], [0, 0]]; // An array of [x, y] pairs. The head is at [0], tail is at [-1].
var board; // top left is 0, 0, bottom right is height-1, width-1
var food = [-10, -10];  // if there is no food, use this to avoid null pointers
var refreshRate = 250; // How quickly the snake moves. (ms)
var intervalId;
var gameIsStopped = true;
// high scores (both time- and food-based) for each level
var timeHighScores = [];
var pelletHighScores = [];
var currentTimeScore = 0;

if (document.cookie !== null) {
  cookies = document.cookie.split(';');
  for (var c=0; c<cookies.length; c++) {
    var cookie = cookies[c].split('=');
    if (cookie[0] == 'speed') {
      var speed = parseInt(cookie[1]);
      var speedSlider = document.getElementById('speedSlider');
      speedSlider.value = speed;
      showValue(speedSlider);
    }
  }
}

// Clears board & stops AI
function stopGame() {
  if ((snake.length - snake.level) > pelletHighScores[level]) {
    pelletHighScores[level] = snake.length - snake.level;
  }
  console.log("Game stopped");
  gameIsStopped = true;
  upLevel();
  board = [];
  board.length = width; // board[x][y]
  for (var i = 0; i < width; i++) {
    board[i] = [];
    board[i].length = height;
  }
  food = [-10, -10];
  snake = [];
  for (var i=0; i<level+3; i++) {
    snake.unshift([i, 0]);
  }
  dir = 'right';
  updateBoard();
}

// Snake collided with self, start next AI level
function startGame() {
  if (!gameIsStopped) {
    return;
  }
  document.cookie = 'speed='+refreshRate;
  gameIsStopped = false;
  console.log("Game started");
  console.log("Round ended! Advancing to AI level", level);
  intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
  ai(level);
}

function changeSpeed(rate) {
  refreshRate = rate; // set to new value
  window.clearInterval(intervalId);
  if (!gameIsStopped) { // ensures only one interval going on at once
    intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
    ai(level);
  }
}

function debugSnake() {
  for (var s=0; s<snake.length; s++) {
    console.log(snake[s][0], snake[s][1]);
  }
}

function inSnakeTwice(string) {
  var count = 0;
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      count++;
    }
  }
  return count==2;
}

// String is of form x_y to allow compatibility with Board.js
function inSnake(string) {
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      return true;
    }
  }
  return false;
}

function moveHead(dir) {
  // move snake's head in given direction
  // 'right', 'left', 'up', and 'down'
  var newHead = snake[0].slice(0); // Clone so we don't move the head by accident.
  if (dir == 'right') {
    if (newHead[0] == width - 1) {
      throw 'cannot move right from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]+1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[0]++;
  } else if (dir == 'left') {
    if (newHead[0] === 0) {
      throw 'cannot move left from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]-1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[0]--;
  } else if (dir == 'up') {  // add new head above current one
    if (newHead[1] === 0) {
      throw 'cannot move up from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]-1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[1]--;  // changes y-coordinate by -1 (going UP)
  } else if (dir == 'down') {
    if (newHead[1] == height - 1) {
      throw 'cannot move down from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]+1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 10*refreshRate
);
    }
    newHead[1]++;
  }
  snake.unshift(newHead); // add newHead to the beginning of the list
  if (snake[0][0] == food[0] && snake[0][1] == food[1]) { // if snake's head is on the food
  food = [-10, -10];
} else {
  delTail();
}
updateBoard();
}

function delTail() {  // simple function to remove the tail
  snake.pop();
}

function placeFood(x, y) {
  startGame();
  if (inSnake(x+'_'+y)) {
    console.log('Invalid food placement: Food collides with snake');
  } else if (x >= width || y >= height || x < 0 || y < 0) { // off of board
    console.log('Invalid food placement: Food is off board');
  } else {
    food = [x, y];
    updateBoard();
  }
}
<|endoftext|>


<commit_before>// Variables
var snake = [[2, 0], [1, 0], [0, 0]]; // An array of [x, y] pairs. The head is at [0], tail is at [-1].
// At level 0, the snake has 3 elements. Each level, it gains 1 starting element.
var board; // top left is 0, 0, bottom right is height-1, width-1
var food = [-10, -10];  // if there is no food, use this to avoid null pointers
// Settings
var level = 0;
var maxLevel = 4; // Starting max level

function debugSnake() {
  for (var s=0; s<snake.length; s++) {
    console.log(snake[s][0], snake[s][1]);
  }
}

// String is of form x_y to allow compatibility with Board.js
function inSnakeTwice(string) {
  var count = 0;
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      count++;
    }
  }
  return count==2;
}

// String is of form x_y to allow compatibility with Board.js
function inSnake(string) {
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      return true;
    }
  }
  return false;
}

// String is of form x_y to allow compatibility with Board.js
function getSnakeIndex(string) {
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      return s;
    }
  }
  return -1;  // not in snake
}

function moveHead(dir) {
  //pelletHighScores[level] = snake.length - snake.level - 2;
  // move snake's head in given direction
  // 'right', 'left', 'up', and 'down'
  var newHead = snake[0].slice(0); // Clone so we don't move the head by accident.
  if (dir == 'right') {
    if (newHead[0] == width - 1) {
      throw 'cannot move right from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]+1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 20*refreshRate);
    }
    newHead[0]++;
  } else if (dir == 'left') {
    if (newHead[0] === 0) {
      throw 'cannot move left from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]-1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 20*refreshRate);
    }
    newHead[0]--;
  } else if (dir == 'up') {  // add new head above current one
    if (newHead[1] === 0) {
      throw 'cannot move up from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]-1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 20*refreshRate);
    }
    newHead[1]--;  // changes y-coordinate by -1 (going UP)
  } else if (dir == 'down') {
    if (newHead[1] == height - 1) {
      throw 'cannot move down from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]+1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 20*refreshRate);
    }
    newHead[1]++;
  }
  snake.unshift(newHead); // add newHead to the beginning of the list
  if (snake[0][0] == food[0] && snake[0][1] == food[1]) { // if snake's head is on the food
  food = [-10, -10];
} else {
  snake.pop(); // Remove the tail
}
updateBoard();
}

function placeFood(x, y) {
  startGame();
  if (inSnake(x+'_'+y)) {
    console.log('Invalid food placement: Food collides with snake');
  } else if (x >= width || y >= height || x < 0 || y < 0) {
    console.log('Invalid food placement: Food is off board');
  } else {
    food = [x, y];
    updateBoard();
  }
}
<commit_msg>Change to constant timeout<commit_after>// Variables
var snake = [[2, 0], [1, 0], [0, 0]]; // An array of [x, y] pairs. The head is at [0], tail is at [-1].
// At level 0, the snake has 3 elements. Each level, it gains 1 starting element.
var board; // top left is 0, 0, bottom right is height-1, width-1
var food = [-10, -10];  // if there is no food, use this to avoid null pointers
// Settings
var level = 0;
var maxLevel = 4; // Starting max level

function debugSnake() {
  for (var s=0; s<snake.length; s++) {
    console.log(snake[s][0], snake[s][1]);
  }
}

// String is of form x_y to allow compatibility with Board.js
function inSnakeTwice(string) {
  var count = 0;
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      count++;
    }
  }
  return count==2;
}

// String is of form x_y to allow compatibility with Board.js
function inSnake(string) {
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      return true;
    }
  }
  return false;
}

// String is of form x_y to allow compatibility with Board.js
function getSnakeIndex(string) {
  for (var s=0; s<snake.length; s++) {
    if (string == snake[s][0]+'_'+snake[s][1]) {
      return s;
    }
  }
  return -1;  // not in snake
}

function moveHead(dir) {
  //pelletHighScores[level] = snake.length - snake.level - 2;
  // move snake's head in given direction
  // 'right', 'left', 'up', and 'down'
  var newHead = snake[0].slice(0); // Clone so we don't move the head by accident.
  if (dir == 'right') {
    if (newHead[0] == width - 1) {
      throw 'cannot move right from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]+1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 5000);
    }
    newHead[0]++;
  } else if (dir == 'left') {
    if (newHead[0] === 0) {
      throw 'cannot move left from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake((newHead[0]-1)+'_'+newHead[1])) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 5000);
    }
    newHead[0]--;
  } else if (dir == 'up') {  // add new head above current one
    if (newHead[1] === 0) {
      throw 'cannot move up from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]-1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 5000);
    }
    newHead[1]--;  // changes y-coordinate by -1 (going UP)
  } else if (dir == 'down') {
    if (newHead[1] == height - 1) {
      throw 'cannot move down from ' + newHead[0] + ', ' + newHead[1];
    } else if (inSnake(newHead[0]+'_'+(newHead[1]+1))) {
      window.clearInterval(intervalId);
      window.setTimeout(stopGame, 5000);
    }
    newHead[1]++;
  }
  snake.unshift(newHead); // add newHead to the beginning of the list
  if (snake[0][0] == food[0] && snake[0][1] == food[1]) { // if snake's head is on the food
  food = [-10, -10];
} else {
  snake.pop(); // Remove the tail
}
updateBoard();
}

function placeFood(x, y) {
  startGame();
  if (inSnake(x+'_'+y)) {
    console.log('Invalid food placement: Food collides with snake');
  } else if (x >= width || y >= height || x < 0 || y < 0) {
    console.log('Invalid food placement: Food is off board');
  } else {
    food = [x, y];
    updateBoard();
  }
}
<|endoftext|>


<commit_before>// board is double array
// snake is a list w/head and tail

snake = [[0, 0]]; // x, y
dir = 'right';
var board = [];     // top left is 0, 0, bottom right is height-1, width-1
var food = [-1, -1];

// initialize board and snake, and start snake movement
function initSnake() {
  board.length = width; // board[x][y]
  for (var i = 0; i < width; i++) {
    board[i] = [];
    board[i].length = height;
  }
  window.setInterval(aiLevel0, 500);
  aiLevel0();
}

function aiLevel0() {
  moveHead(dir);
  if (dir == 'right' || dir == 'left') {
    if (snake[0][0] == food[0]) {   // is the snake above or below the food?
      if (snake[0][1] < food[1]) {
        dir = 'down';
      } else {
        dir = 'up';
      }
    } else if ((snake[0][0] == width - 1) && dir == 'right') { // is the snake at the right wall
		dir = 'down';
	} else if ((snake[0][0] === 0) && dir == 'left') {  // is the snake at the left wall?
		dir = 'up';
	}
  } else if (dir == 'up' || dir == 'down') {
    if (snake[0][1] == food[1]) {   // is the snake to the right or left of the food?
      if (snake[0][0] < food[0]) {
        dir = 'right';
      } else {
        dir = 'left';
      }
    } else if ((snake[0][1] === 0) && dir == 'up') { // is the snake at the top wall
		dir = 'right';
  } else if (snake[0][1] == height - 1 && dir == 'down') {  // is the snake at the bottom wall?
		dir = 'left';
	} // else dir is unchanged
  }
}

function moveHead(dir) {
  // move snake's head in given direction
  // 'right', 'left', 'up', and 'down'
  var newHead = snake[0];
  if (dir == 'up') {  // add new head above current one
    newHead[1]--;  // changes y-coordinate by -1 (going UP)
  } else if (dir == 'down') {
    newHead[1]++;
  } else if (dir == 'right') {
    newHead[0]++;
  } else if (dir == 'left') {
    newHead[0]--;
  }
//  if (newHead[0] < 0 || newHead[0] >= width || newHead[1] < 0 || newHead[1] >= height) {

//  }
  snake.unshift(newHead); // add newHead to the beginning of the list
  console.log(snake);
  updateBoard(snake);
  if (snake[0] == food) { // if snake's head is on the food
    food = [-1, -1];
  } else {
    delTail();
  }
}

function delTail() {  // simple function to remove the tail
  console.log(snake.pop());
  updateBoard(snake);
}

function placeFood(x, y) {
  for (var s=0; s<snake.length; s++) {
		if (x == snake[s][0] && y == snake[s][1]) {
			isSnakeCell = true;
			break;
		}
	if (food != [-1, -1]) { // already food
		console.log("Invalid food placement: There is already food");
		return false;
	} else if (x >= width || y >= height || x < 0 || y < 0) { // off of board
		console.log("Invalid food placement: Food is off board");
		return false;
	} else if (snake.includes([x, y])) {	 // new food collides with snake
		console.log("Invalid food placement: Food collides with snake");
		return false;
	} else {
		food = [x, y];
		console.log("Food placed at "+x+" "+y);
		return true;
	}
}
<commit_msg>Missed a }<commit_after>// board is double array
// snake is a list w/head and tail

snake = [[0, 0]]; // x, y
dir = 'right';
var board = [];     // top left is 0, 0, bottom right is height-1, width-1
var food = [-1, -1];

// initialize board and snake, and start snake movement
function initSnake() {
  board.length = width; // board[x][y]
  for (var i = 0; i < width; i++) {
    board[i] = [];
    board[i].length = height;
  }
  window.setInterval(aiLevel0, 500);
  aiLevel0();
}

function aiLevel0() {
  moveHead(dir);
  if (dir == 'right' || dir == 'left') {
    if (snake[0][0] == food[0]) {   // is the snake above or below the food?
      if (snake[0][1] < food[1]) {
        dir = 'down';
      } else {
        dir = 'up';
      }
    } else if ((snake[0][0] == width - 1) && dir == 'right') { // is the snake at the right wall
		dir = 'down';
	} else if ((snake[0][0] === 0) && dir == 'left') {  // is the snake at the left wall?
		dir = 'up';
	}
  } else if (dir == 'up' || dir == 'down') {
    if (snake[0][1] == food[1]) {   // is the snake to the right or left of the food?
      if (snake[0][0] < food[0]) {
        dir = 'right';
      } else {
        dir = 'left';
      }
    } else if ((snake[0][1] === 0) && dir == 'up') { // is the snake at the top wall
		dir = 'right';
  } else if (snake[0][1] == height - 1 && dir == 'down') {  // is the snake at the bottom wall?
		dir = 'left';
	} // else dir is unchanged
  }
}

function moveHead(dir) {
  // move snake's head in given direction
  // 'right', 'left', 'up', and 'down'
  var newHead = snake[0];
  if (dir == 'up') {  // add new head above current one
    newHead[1]--;  // changes y-coordinate by -1 (going UP)
  } else if (dir == 'down') {
    newHead[1]++;
  } else if (dir == 'right') {
    newHead[0]++;
  } else if (dir == 'left') {
    newHead[0]--;
  }
//  if (newHead[0] < 0 || newHead[0] >= width || newHead[1] < 0 || newHead[1] >= height) {

//  }
  snake.unshift(newHead); // add newHead to the beginning of the list
  console.log(snake);
  updateBoard(snake);
  if (snake[0] == food) { // if snake's head is on the food
    food = [-1, -1];
  } else {
    delTail();
  }
}

function delTail() {  // simple function to remove the tail
  console.log(snake.pop());
  updateBoard(snake);
}

function placeFood(x, y) {
  for (var s=0; s<snake.length; s++) {
		if (x == snake[s][0] && y == snake[s][1]) {
			isSnakeCell = true;
			break;
		}
	}
	if (food != [-1, -1]) { // already food
		console.log("Invalid food placement: There is already food");
		return false;
	} else if (x >= width || y >= height || x < 0 || y < 0) { // off of board
		console.log("Invalid food placement: Food is off board");
		return false;
	} else if (snake.includes([x, y])) {	 // new food collides with snake
		console.log("Invalid food placement: Food collides with snake");
		return false;
	} else {
		food = [x, y];
		console.log("Food placed at "+x+" "+y);
		return true;
	}
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const commander     = require('commander');
const path          = require('path');
const fs            = require('fs');
const jsonfile      = require('jsonfile');
const gulp          = require('gulp');
const decache       = require('decache');
const logger        = require('../modules/logger')(gulp);
const $             = require('gulp-load-plugins')();
const runSequence   = require('run-sequence');
const pipeErrorStop = require('pipe-error-stop');
const del           = require('del');
const requireDir    = require('require-dir');
const hbsLayouts    = require('handlebars-layouts');
const notifier      = require('node-notifier');
const iconizer      = require('../modules/gulp-iconizer');
const browserSync   = require('browser-sync').create();
const pkg           = require('../package.json');
const terminal      = require('terminal-logger')('marmelad');
const chalk         = require('chalk');

let settings = require('../assets/marmelad.settings');
let database = {};

/**
 * фдаг финальная сборка
 */
let isRelease = false;

/**
 * данные для шаблонов
 */
let db = {
    pageTitle : 'Marmelad project'
};

/**
 * обработчик ошибок для plumber
 */
let onError = function(err) {

    $.util.log(err.message);

    notifier.notify({
        'title': 'Error',
        'message': err.message
    });

    this.emit('end');
};

/**
 * регистрация хелперов расширения шаблонов handlebars-layouts
 * https://www.npmjs.com/package/handlebars-layouts
 */
$.compileHandlebars.Handlebars.registerHelper(hbsLayouts($.compileHandlebars.Handlebars));

/**
 * Получение списка директорий Блоков для их подключения в шаблоны
 *
 * @author Yunus Gaziev <yunus.gaziev@gmail.com>
 * @param dest {String} путь до папки в которой лежат блоки
 * @returns {Array} массив путей до шаблонов handlebars
 */
let getPartialsPaths = (dest) => {

    let folders = fs.readdirSync(dest); // массив папок-блоков
    let partials = []; // массив путей до шаблонов handlebars

    folders.forEach(function (el) {
        partials.push(dest + '/' + el);
    });

    return partials;
};

/**
 * обновление данных для шаблонов
 */
gulp.task('get:data', (done) => {

    let dataPath = path.join(process.cwd(), settings.paths.assets, 'marmelad.data.js');

    decache(dataPath);

    database = require(dataPath);

    Object.assign(database.app, {
        package  : pkg,
        settings : settings
    });

    terminal
        .write()
        .tick(`database for handlebars templates ${chalk.bold.yellow('refreshed')}\n`);

    done();

});

/**
 * обновление данных для шаблонов
 * пересборка шаблонов с новыми данными
 */
gulp.task('refresh:data', (cb) => {
    runSequence('get:data', 'handlebars', cb);
});

/**
 * сборка шаблонов handlebars
 * https://www.npmjs.com/package/gulp-compile-handlebars
 */
gulp.task('handlebars', function(done) {

    let stream = gulp.src(settings.paths.pages + '/**/*.{hbs,handlebars}')
        .pipe($.plumber())
        .pipe(
            $.compileHandlebars(database, {
                ignorePartials: false,
                batch: getPartialsPaths(settings.paths.blocks)
            })
        )
        .pipe(pipeErrorStop()) // на случай если handlebars сломается, иначе таск останавливается
        .pipe($.beml(settings.app.beml))
        .pipe(iconizer({path: settings.paths.iconizer.src + '/sprite.svg'}))
        .pipe($.rename({extname: '.html'}))
        .pipe(gulp.dest(settings.paths.dist));

    stream.on('end', function() {
        browserSync.reload();
        done();
    });

    stream.on('error', function(err) {
        done(err);
    });
});

/**
 * генерация svg спрайта
 */
gulp.task('build:iconizer', () => {

    return gulp.src(settings.paths.iconizer.icons + '/*.svg')
        .pipe($.svgSprite(settings.app.svgSprite))
        .pipe(gulp.dest('.'));
});

/**
 * обновляет svg спрайт
 * пересборка шаблонов
 */
gulp.task('build:iconizer:refresh', (cb) => {
    runSequence('build:iconizer', 'handlebars', cb);
});

/**
 * сборка стилей блоков, для каждого отдельный css
 */
gulp.task('stylus:main', function() {

    return gulp.src([
            path.join(settings.paths.stylus, '**', '_*.styl'),
            path.join(settings.paths.stylus, 'app.styl'),
            path.join(settings.paths.blocks, '**', '*.styl')
        ])
        .pipe($.plumber())
        .pipe($.concat('app.styl'))
        .pipe($.stylus())
        .pipe($.autoprefixer())
        .pipe($.groupCssMediaQueries())
        .pipe(gulp.dest(path.join(settings.paths.storage, 'css')));

});

/**
 * СТИЛИ ПАГИНОВ
 */
gulp.task('stylus:plugins', () => {
    return gulp.src(path.join(settings.paths.js.plugins, '**', '*.{styl,css}'))
        .pipe($.plumber())
        .pipe(
            $.stylus({
                'include css': true
            })
        )
        .pipe($.concat('plugins.min.css'))
        .pipe($.autoprefixer())
        .pipe($.csso())
        .pipe(gulp.dest(path.join(settings.paths.storage, 'css')))
});

/**
 * СКРИПТЫ ВЕНДОРНЫЕ
 */
gulp.task('scripts:vendors', (done) => {

    let vendorsDist = path.join(settings.paths.storage,  settings.folders.js.src, settings.folders.js.vendors);

    let stream = gulp.src(settings.paths.js.vendors + '/**/*.js')
        .pipe($.plumber())
        .pipe($.changed(vendorsDist))
        .pipe(gulp.dest(vendorsDist));

    stream.on('end', function () {
        browserSync.reload();
        done();
    });

    stream.on('error', function (err) {
        done(err);
    });

});

/**
 * СКРИПТЫ ПЛАГИНОВ
 */
gulp.task('scripts:plugins', (done) => {

    let stream = gulp.src(settings.paths.js.vendors + '/**/*.js')
        .pipe($.plumber())
        .pipe($.concat('plugins.min.js'))
        .pipe($.uglify())
        .pipe(gulp.dest(path.join(settings.paths.storage,  settings.folders.js.src)));

    stream.on('end', function () {
        browserSync.reload();
        done();
    });

    stream.on('error', function (err) {
        done(err);
    });

});

/**
 * СКРИПТЫ ОСНОВНЫЕ
 */
gulp.task('scripts:app', (done) => {

    let stream = gulp.src([
            settings.paths.js.src + '/app.js',
            settings.paths.blocks + '/**/*.js',
        ])
        .pipe($.plumber())
        .pipe($.concat('app.js'))
        .pipe($.wrap("$(function () {\n\n    'use strict';\n\n<%= contents %>\n});"))
        .pipe(gulp.dest(path.join(settings.paths.storage,  settings.folders.js.src)));

    stream.on('end', () => {
        browserSync.reload();
        done();
    });

    stream.on('error', (err) => {
        done(err);
    });
});

/**
 * перекладываем картинки блоков
 */
gulp.task('blocks:images', (done) => {

    let stream = gulp.src(settings.paths.blocks + '/**/*.{jpg,png,gif,svg,bmp}')
        .pipe($.plumber({errorHandler: onError}))
        .pipe($.rename({dirname: ''}))
        .pipe(gulp.dest(settings.paths.dist));

    stream.on('end', () => {
        browserSync.reload();
        done();
    });

    stream.on('error', (err) => {
        done(err);
    });
});

gulp.task('watch', () => {

    /* СТАТИКА */
    $.watch([
        settings.paths.static + '/**/*.*',
        '!' + settings.paths.static + '/**/Thumbs.db',
        '!' + settings.paths.static + '/**/*tmp*'
    ], $.batch((events, done) => {
        gulp.start('build:static', done);
    }));

    /* ICONIZER */
    $.watch(settings.paths.iconizer.icons + '/*.svg', $.batch(function (events, done) {
        gulp.start('build:iconizer:refresh', done);
    }));

    /* СТИЛИ */
    $.watch([
        path.join(settings.paths.stylus, '**', '*.styl'),
        path.join(settings.paths.blocks, '**', '*.styl')
    ], $.batch((events, done) => {
        gulp.start('stylus:main', done);
    }));
    $.watch(path.join(settings.paths.js.plugins, '**', '*.css'), $.batch((events, done) => {
        gulp.start('stylus:plugins', done);
    }));
    // $.watch(settings.paths.blocks + '/**/*.{styl,css}', $.batch((events, done) => {
    //     gulp.start('styles:main', done);
    // }));

    /* СКРИПТЫ */
    $.watch(path.join(settings.paths.js.vendors, '**' + '*.js'), $.batch((events, done) => {
        gulp.start('scripts:vendors', done);
    }));
    $.watch(path.join(settings.paths.js.plugins, '**' + '*.js'), $.batch((events, done) => {
        gulp.start('scripts:plugins', done);
    }));
    $.watch([
            settings.paths.js.src + '/app.js',
            settings.paths.blocks + '/**/*.js',
        ], $.batch((events, done) => {
            gulp.start('scripts:app', done);
        }));

    /* ДАННЫЕ ДЛЯ ШАБЛОНОВ */
    $.watch(path.join(settings.paths.assets, 'marmelad.data.js'), $.batch((events, done) => {
        gulp.start('refresh:data', done);
    }));

    /* ШАБЛОНЫ */
    $.watch(settings.paths.pages + '/**/*.{hbs,handlebars}', $.batch((events, done) => {
        gulp.start('handlebars', done);
    }));
    $.watch(settings.paths.blocks + '/**/*.{hbs,handlebars}', $.batch((events, done) => {
        gulp.start('handlebars', done);
    }));

    /* КАРТИНКИ БЛОКОВ*/
    // $.watch(settings.paths.blocks + '/**/*.{jpg,png,gif,svg,bmp}', $.batch((events, done) => {
    //     gulp.start('blocks:images', done);
    // }));

});

/**
 * СТАТИКА
 */
gulp.task('build:static', function(done) {

    let stream = gulp.src([
            settings.paths.static + '/**/*.*',
            '!' + settings.paths.static + '/**/Thumbs.db',
            '!' + settings.paths.static + '/**/*tmp*'
        ])
        .pipe($.plumber())
        .pipe($.changed(settings.paths.dist))
        .pipe(gulp.dest(settings.paths.dist));

    stream.on('end', function () {
        browserSync.reload();
        done();
    });

    stream.on('error', function (err) {
        done(err);
    });
});

/**
 * очищаем папку сборки перед сборкой Ж)
 */
gulp.task('build:clean', (done) => {
    del.sync(settings.paths.dist);
    done();
});

gulp.task('build:server', (done) => {
    browserSync.init(settings.app.browserSync, done);
});

gulp.task('registerHbsHelpers', function(done) {

    /**
     * Регистрация кастомных хелперов для Handlebars
     */
    const hbsHelpers = requireDir(process.cwd() + '/assets/helpers');

    Object.keys(hbsHelpers).forEach(function(name) {
        $.compileHandlebars.Handlebars.registerHelper(name, hbsHelpers[name]);
    });

    done();
});

/**
 * инициализация нового проекта
 */
gulp.task('marmelad:init', (done) => {

    let stream = gulp.src(path.join(__dirname.replace('bin', ''), 'assets', '**', '*.*'))
        .pipe($.plumber())
        .pipe($.logger({
            before     : '[MARMELAD:INIT] STARTING',
            after      : '[MARMELAD:INIT] COMPLETE',
            showChange : true,
            display    : 'name'
        }))
        .pipe(gulp.dest(path.join(process.cwd(), 'assets')));

    stream.on('end', function () {

        terminal
            .write()
            .tick(`All good, just type ${chalk.bold.yellow('marmelad')} and start build`);

        done();
    });

    stream.on('error', function (err) {
        done(err);
    });

});

gulp.task('marmelad:start', function(done) {

    runSequence(
        'build:clean',
        'build:server',
        'build:static',
        'build:iconizer',
        'get:data',
        'handlebars',
        'stylus:main',
        'stylus:plugins',
        'scripts:vendors',
        'scripts:plugins',
        'scripts:app',
        // 'blocks:images',
        'watch',
        done);
});

let init = () => {

    fs.exists('assets/marmelad.settings.js', (exist) => {

        if (exist) {

            settings = require(path.join(process.cwd(), 'assets', 'marmelad.settings'));

            settings.app.package = pkg;

            gulp.start('marmelad:start');

        } else {
            gulp.start('marmelad:init');
        }

    });
};

init();
<commit_msg>Доработки новой сборки<commit_after>#!/usr/bin/env node

'use strict';

const commander     = require('commander');
const path          = require('path');
const fs            = require('fs');
const jsonfile      = require('jsonfile');
const gulp          = require('gulp');
const decache       = require('decache');
const logger        = require('../modules/logger')(gulp);
const $             = require('gulp-load-plugins')();
const runSequence   = require('run-sequence');
const pipeErrorStop = require('pipe-error-stop');
const del           = require('del');
const requireDir    = require('require-dir');
const hbsLayouts    = require('handlebars-layouts');
const notifier      = require('node-notifier');
const iconizer      = require('../modules/gulp-iconizer');
const browserSync   = require('browser-sync').create();
const pkg           = require('../package.json');
const terminal      = require('terminal-logger')('marmelad');
const chalk         = require('chalk');

let settings = require('../assets/marmelad.settings');
let database = {};

/**
 * фдаг финальная сборка
 */
let isRelease = false;

/**
 * данные для шаблонов
 */
let db = {
    pageTitle : 'Marmelad project'
};

/**
 * обработчик ошибок для plumber
 */
let onError = function(err) {

    $.util.log(err.message);

    notifier.notify({
        'title': 'Error',
        'message': err.message
    });

    this.emit('end');
};

/**
 * регистрация хелперов расширения шаблонов handlebars-layouts
 * https://www.npmjs.com/package/handlebars-layouts
 */
$.compileHandlebars.Handlebars.registerHelper(hbsLayouts($.compileHandlebars.Handlebars));

/**
 * Получение списка директорий Блоков для их подключения в шаблоны
 *
 * @author Yunus Gaziev <yunus.gaziev@gmail.com>
 * @param dest {String} путь до папки в которой лежат блоки
 * @returns {Array} массив путей до шаблонов handlebars
 */
let getPartialsPaths = (dest) => {

    let folders = fs.readdirSync(dest); // массив папок-блоков
    let partials = []; // массив путей до шаблонов handlebars

    folders.forEach(function (el) {
        partials.push(dest + '/' + el);
    });

    return partials;
};

/**
 * обновление данных для шаблонов
 */
gulp.task('get:data', (done) => {

    let dataPath = path.join(process.cwd(), settings.paths.assets, 'marmelad.data.js');

    decache(dataPath);

    database = require(dataPath);

    Object.assign(database.app, {
        package  : pkg,
        settings : settings
    });

    terminal
        .write()
        .tick(`database for handlebars templates ${chalk.bold.yellow('refreshed')}\n`);

    done();

});

/**
 * обновление данных для шаблонов
 * пересборка шаблонов с новыми данными
 */
gulp.task('refresh:data', (cb) => {
    runSequence('get:data', 'handlebars', cb);
});

/**
 * сборка шаблонов handlebars
 * https://www.npmjs.com/package/gulp-compile-handlebars
 */
gulp.task('handlebars', function(done) {

    let stream = gulp.src(settings.paths.pages + '/**/*.{hbs,handlebars}')
        .pipe($.plumber())
        .pipe(
            $.compileHandlebars(database, {
                ignorePartials: false,
                batch: getPartialsPaths(settings.paths.blocks)
            })
        )
        .pipe(pipeErrorStop()) // на случай если handlebars сломается, иначе таск останавливается
        .pipe($.beml(settings.app.beml))
        .pipe(iconizer({path: settings.paths.iconizer.src + '/sprite.svg'}))
        .pipe($.rename({extname: '.html'}))
        .pipe(gulp.dest(settings.paths.dist));

    stream.on('end', function() {
        browserSync.reload();
        done();
    });

    stream.on('error', function(err) {
        done(err);
    });
});

/**
 * генерация svg спрайта
 */
gulp.task('build:iconizer', () => {

    return gulp.src(settings.paths.iconizer.icons + '/*.svg')
        .pipe($.svgSprite(settings.app.svgSprite))
        .pipe(gulp.dest('.'));
});

/**
 * обновляет svg спрайт
 * пересборка шаблонов
 */
gulp.task('build:iconizer:refresh', (cb) => {
    runSequence('build:iconizer', 'handlebars', cb);
});

/**
 * сборка стилей блоков, для каждого отдельный css
 */
gulp.task('stylus:main', function() {

    return gulp.src([
            path.join(settings.paths.stylus, '**', '_*.styl'),
            path.join(settings.paths.stylus, 'app.styl'),
            path.join(settings.paths.blocks, '**', '*.styl')
        ])
        .pipe($.plumber())
        .pipe($.concat('app.styl'))
        .pipe($.stylus())
        .pipe($.autoprefixer())
        .pipe($.groupCssMediaQueries())
        .pipe(gulp.dest(path.join(settings.paths.storage, 'css')))
        .pipe(browserSync.stream());

});

/**
 * СТИЛИ ПАГИНОВ
 */
gulp.task('stylus:plugins', () => {
    return gulp.src(path.join(settings.paths.js.plugins, '**', '*.{styl,css}'))
        .pipe($.plumber())
        .pipe(
            $.stylus({
                'include css': true
            })
        )
        .pipe($.concat('plugins.min.css'))
        .pipe($.autoprefixer())
        .pipe($.csso())
        .pipe(gulp.dest(path.join(settings.paths.storage, 'css')))
        .pipe(browserSync.stream());
});

/**
 * СКРИПТЫ ВЕНДОРНЫЕ
 */
gulp.task('scripts:vendors', (done) => {

    let vendorsDist = path.join(settings.paths.storage,  settings.folders.js.src, settings.folders.js.vendors);

    let stream = gulp.src(settings.paths.js.vendors + '/**/*.js')
        .pipe($.plumber())
        .pipe($.changed(vendorsDist))
        .pipe(gulp.dest(vendorsDist));

    stream.on('end', function () {
        browserSync.reload();
        done();
    });

    stream.on('error', function (err) {
        done(err);
    });

});

/**
 * СКРИПТЫ ПЛАГИНОВ
 */
gulp.task('scripts:plugins', (done) => {

    let stream = gulp.src(settings.paths.js.plugins + '/**/*.js')
        .pipe($.plumber())
        .pipe($.concat('plugins.min.js'))
        .pipe($.uglify())
        .pipe(gulp.dest(path.join(settings.paths.storage,  settings.folders.js.src)));

    stream.on('end', function () {
        browserSync.reload();
        done();
    });

    stream.on('error', function (err) {
        done(err);
    });

});

/**
 * СКРИПТЫ ОСНОВНЫЕ
 */
gulp.task('scripts:app', (done) => {

    let stream = gulp.src([
            settings.paths.js.src + '/app.js',
            settings.paths.blocks + '/**/*.js',
        ])
        .pipe($.plumber())
        .pipe($.concat('app.js'))
        .pipe($.wrap("$(function () {\n\n    'use strict';\n\n<%= contents %>\n});"))
        .pipe(gulp.dest(path.join(settings.paths.storage,  settings.folders.js.src)));

    stream.on('end', () => {
        browserSync.reload();
        done();
    });

    stream.on('error', (err) => {
        done(err);
    });
});

/**
 * перекладываем картинки блоков
 */
gulp.task('blocks:images', (done) => {

    let stream = gulp.src(settings.paths.blocks + '/**/*.{jpg,png,gif,svg,bmp}')
        .pipe($.plumber({errorHandler: onError}))
        .pipe($.rename({dirname: ''}))
        .pipe(gulp.dest(settings.paths.dist));

    stream.on('end', () => {
        browserSync.reload();
        done();
    });

    stream.on('error', (err) => {
        done(err);
    });
});

gulp.task('watch', () => {

    /* СТАТИКА */
    $.watch([
        settings.paths.static + '/**/*.*',
        '!' + settings.paths.static + '/**/Thumbs.db',
        '!' + settings.paths.static + '/**/*tmp*'
    ], $.batch((events, done) => {
        gulp.start('build:static', done);
    }));

    /* ICONIZER */
    $.watch(settings.paths.iconizer.icons + '/*.svg', $.batch(function (events, done) {
        gulp.start('build:iconizer:refresh', done);
    }));

    /* СТИЛИ */
    $.watch([
        path.join(settings.paths.stylus, '**', '*.styl'),
        path.join(settings.paths.blocks, '**', '*.styl')
    ], $.batch((events, done) => {
        gulp.start('stylus:main', done);
    }));

    $.watch([
        path.join(settings.paths.stylus, '**', '*.styl'),
        path.join(settings.paths.blocks, '**', '*.styl')
    ], $.batch((events, done) => {
        gulp.start('stylus:main', done);
    }));

    $.watch(path.join(settings.paths.js.plugins, '**', '*.css'), $.batch((events, done) => {
        gulp.start('stylus:plugins', done);
    }));
    // $.watch(settings.paths.blocks + '/**/*.{styl,css}', $.batch((events, done) => {
    //     gulp.start('styles:main', done);
    // }));

    /* СКРИПТЫ */
    $.watch(path.join(settings.paths.js.vendors, '**', '*.js'), $.batch((events, done) => {
        gulp.start('scripts:vendors', done);
    }));
    $.watch(path.join(settings.paths.js.plugins, '**', '*.js'), $.batch((events, done) => {
        gulp.start('scripts:plugins', done);
    }));
    $.watch([
            settings.paths.js.src + '/app.js',
            settings.paths.blocks + '/**/*.js',
        ], $.batch((events, done) => {
            gulp.start('scripts:app', done);
        }));

    /* ДАННЫЕ ДЛЯ ШАБЛОНОВ */
    $.watch(path.join(settings.paths.assets, 'marmelad.data.js'), $.batch((events, done) => {
        gulp.start('refresh:data', done);
    }));

    /* ШАБЛОНЫ */
    $.watch(settings.paths.pages + '/**/*.{hbs,handlebars}', $.batch((events, done) => {
        gulp.start('handlebars', done);
    }));
    $.watch(settings.paths.blocks + '/**/*.{hbs,handlebars}', $.batch((events, done) => {
        gulp.start('handlebars', done);
    }));

    /* КАРТИНКИ БЛОКОВ*/
    // $.watch(settings.paths.blocks + '/**/*.{jpg,png,gif,svg,bmp}', $.batch((events, done) => {
    //     gulp.start('blocks:images', done);
    // }));

});

/**
 * СТАТИКА
 */
gulp.task('build:static', function(done) {

    let stream = gulp.src([
            settings.paths.static + '/**/*.*',
            '!' + settings.paths.static + '/**/Thumbs.db',
            '!' + settings.paths.static + '/**/*tmp*'
        ])
        .pipe($.plumber())
        .pipe($.changed(settings.paths.dist))
        .pipe(gulp.dest(settings.paths.dist));

    stream.on('end', function () {
        browserSync.reload();
        done();
    });

    stream.on('error', function (err) {
        done(err);
    });
});

/**
 * очищаем папку сборки перед сборкой Ж)
 */
gulp.task('build:clean', (done) => {
    del.sync(settings.paths.dist);
    done();
});

gulp.task('build:server', (done) => {
    browserSync.init(settings.app.browserSync, done);
});

gulp.task('handlebars:registerHelpers', function(done) {

    /**
     * Регистрация кастомных хелперов для Handlebars
     */
    const hbsHelpers = requireDir(path.join(process.cwd(), settings.paths.helpers));

    Object.keys(hbsHelpers).forEach(function(name) {
        $.compileHandlebars.Handlebars.registerHelper(name, hbsHelpers[name]);
    });

    done();
});

/**
 * инициализация нового проекта
 */
gulp.task('marmelad:init', (done) => {

    let stream = gulp.src(path.join(__dirname.replace('bin', ''), 'assets', '**', '*.*'))
        .pipe($.plumber())
        .pipe($.logger({
            before     : '[MARMELAD:INIT] STARTING',
            after      : '[MARMELAD:INIT] COMPLETE',
            showChange : true,
            display    : 'name'
        }))
        .pipe(gulp.dest(path.join(process.cwd(), 'assets')));

    stream.on('end', function () {

        terminal
            .write()
            .tick(`All good, just type ${chalk.bold.yellow('marmelad')} and start build`);

        done();
    });

    stream.on('error', function (err) {
        done(err);
    });

});

gulp.task('marmelad:start', function(done) {

    runSequence(
        'build:clean',
        'build:server',
        'build:static',
        'build:iconizer',
        'get:data',
        'handlebars:registerHelpers',
        'handlebars',
        'stylus:main',
        'stylus:plugins',
        'scripts:vendors',
        'scripts:plugins',
        'scripts:app',
        // 'blocks:images',
        'watch',
        done);
});

let init = () => {

    fs.exists('assets/marmelad.settings.js', (exist) => {

        if (exist) {

            settings = require(path.join(process.cwd(), 'assets', 'marmelad.settings'));

            settings.app.package = pkg;

            gulp.start('marmelad:start');

        } else {
            gulp.start('marmelad:init');
        }

    });
};

init();
<|endoftext|>


<commit_before>'use strict';

var emojiArray = ['alien.png','cat.png','dancer.png','dog.png','poop.png','unicorn.png'];
var currentEmojis = [];
var playButton = document.getElementById('playButton');
var userNameSpan = document.getElementById('userName'); // Is this id name okay?

// get data and name
if (Data.loadCurrentUser() === null) {
  //TODO - get persistance
  // load settings page
  window.location.href = 'options.html';
  // Render username on page
  renderUserName();
} else {
  var currentUser = Data.loadCurrentUser(); //TODO - get persistance
  renderUserName();
}

// when play button is clicked
playButton.addEventListener('click', function(event){
  // Start animation
  imageArray[i].setAttribute('id', 'animationGo');
  // picks a random img from emojiArray
  currentEmojis = getRandomEmojis();
  // update rounds in currentUser
  currentUser.rounds++;
  // update rendered image to DOM
  renderEmojis();
  // Finish animation
  imageArray[i].setAttribute('id', 'finished');
  // if three img are same
  updateWins();
  // update localStorage with new currentUser
  Data.saveUser(currentUser); //TODO - get persistance
  // get new data from localStorage
  Data.loadCurrentUser(); //TODO - get persistance
});

// Function to get three random emoji images.
function getRandomEmojis(){
  var threeEmojis = [];
  for (var i = 0; i < 3; i++) {
    var random = Math.floor(Math.random() * emojiArray.length);
    threeEmojis.push(emojiArray[random]);
  }
  return threeEmojis;
}

function renderEmojis(){
  for (var i = 0; i < currentEmojis.length; i++) {
    imageArray[i].setAttribute('src', 'img/' + currentEmojis[i]);
    imageArray[i].setAttribute('alt', currentEmojis[i]);
  }
}

function updateWins(){
  var response = document.getElementById('response');
  if (currentEmojis[0] === currentEmojis[1] && currentEmojis[0] === currentEmojis[2]) {
    // update jackpots and response in currentUser
    currentUser.jackpots++;
    response.textContent = 'You hit the Jackpot!';
  } else if (currentEmojis[0] === currentEmojis[1] ||
          currentEmojis[1] === currentEmojis[2] ||
          currentEmojis[0] === currentEmojis[2] ) {
    currentUser.pairs++;
    response.textContent = 'You got a pair!';
  } else {
    response.textContent = ' ';
  }
}

function renderUserName(){
  // update text content of the span
  userNameSpan.textContent = currentUser.userName;
}
<commit_msg>Fixed merge conflict - added back in click animation<commit_after>'use strict';

/*********** VARIABLE ***********/
var emojiArray = ['alien.png','cat.png','dancer.png','dog.png','poop.png','unicorn.png'];
var currentEmojis = [];
var playButton = document.getElementById('playButton');
var userNameSpan = document.getElementById('userName'); // Is this id name okay?

/*********** MAIN FLOW ***********/
// get data and name
if (Data.loadCurrentUser() === null) {
  //TODO - get persistance
  // load settings page
  window.location.href = 'options.html';
  // Render username on page
  renderUserName();
} else {
  var currentUser = Data.loadCurrentUser(); //TODO - get persistance
  renderUserName();
}

/*********** EVENT HANDLING ***********/
// when play button is clicked
playButton.addEventListener('click', function(event){
  // picks a random img from emojiArray
  currentEmojis = getRandomEmojis();
  // update rounds in currentUser
  currentUser.rounds++;
  // update rendered image to DOM
  renderEmojis();
  // if three img are same
  updateWins();
  // update localStorage with new currentUser
  Data.saveUser(currentUser); //TODO - get persistance
  // get new data from localStorage
  Data.loadCurrentUser(); //TODO - get persistance
});

/*********** FUNCTION ***********/
// Function to get three random emoji images.
function getRandomEmojis(){
  var threeEmojis = [];
  for (var i = 0; i < 3; i++) {
    var random = Math.floor(Math.random() * emojiArray.length);
    threeEmojis.push(emojiArray[random]);
  }
  return threeEmojis;
}

function renderEmojis(){
  var divs = document.getElementsByClassName('slotWindow');
  for (var i = 0; i < currentEmojis.length; i++) {
    divs[i].removeChild(divs[i].lastChild);
    var img = document.createElement('img');
    img.setAttribute('src', 'img/' + currentEmojis[i]);
    img.setAttribute('alt', currentEmojis[i]);
    img.setAttribute('class','animation');
    divs[i].append(img);
  }
}

function updateWins(){
  var response = document.getElementById('response');
  if (currentEmojis[0] === currentEmojis[1] && currentEmojis[0] === currentEmojis[2]) {
    // update jackpots and response in currentUser
    currentUser.jackpots++;
    response.textContent = 'You hit the Jackpot!';
  } else if (currentEmojis[0] === currentEmojis[1] ||
          currentEmojis[1] === currentEmojis[2] ||
          currentEmojis[0] === currentEmojis[2] ) {
    currentUser.pairs++;
    response.textContent = 'You got a pair!';
  } else {
    response.textContent = ' ';
  }
}

function renderUserName(){
  // update text content of the span
  userNameSpan.textContent = currentUser.userName;
}
<|endoftext|>


<commit_before>/**
 *
 * @module messages
 * @description modules used for messages cli firekyll
 * @author Wilson Flores
 *
 */

function messages(plugins){
  this.output = '';
  this.plugins = plugins;
}

messages.prototype.server = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('server ready - port : '+ 4000);
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.build = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('build jekyll');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.commandNotFound = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('command not found');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.successCreatePost = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('post created');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.postExists = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('post name already exists');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.projectExists = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('project name already exists');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.directoryPostNotExist = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('directory does not exist _posts');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.successCreateProject = function(){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('project created jekyll');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.errorProjectNew = function(error){
  this.output='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.error+' '+this.plugins.chalk.red(' '+error)+'\n\n';
  this.output+=' '+this.plugins.chalk.red(' '+'Please install : npm install firekyll-generator-gulp-webapp -g')+'\n\n';
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.listPosts = function(a,b,wrapper,length){
  wrapper.push(
    [this.plugins.chalk.magenta(b+' bytes'),this.plugins.chalk.bold(a)]
  );
  if(wrapper.length == length){
    console.log(wrapper.toString());
  }
}

module.exports = messages;
<commit_msg>feat(messages):sangria de los mensajes<commit_after>/**
 *
 * @module messages
 * @description modules used for messages cli firekyll
 * @author Wilson Flores
 *
 */

function messages(plugins){
  this.output  = '';
  this.plugins = plugins;
}

messages.prototype.server = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('server ready - port : '+ 4000);
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.build = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('build jekyll');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.commandNotFound = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('command not found');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.successCreatePost = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('post created');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.postExists = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('post name already exists');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.projectExists = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('project name already exists');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.directoryPostNotExist = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.warning+' '+this.plugins.chalk.yellow('directory does not exist _posts');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.successCreateProject = function(){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.success+' '+this.plugins.chalk.green('project created jekyll');
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.errorProjectNew = function(error){
  this.output ='';
  this.output+='\n';
  this.output+=' '+this.plugins.symbols.error+' '+this.plugins.chalk.red(' '+error)+'\n\n';
  this.output+=' '+this.plugins.chalk.red(' '+'Please install : npm install firekyll-generator-gulp-webapp -g')+'\n\n';
  this.output+='\n';
  console.log(this.output);
}

messages.prototype.listPosts = function(a,b,wrapper,length){
  wrapper.push(
    [this.plugins.chalk.magenta(b+' bytes'),this.plugins.chalk.bold(a)]
  );
  if(wrapper.length == length){
    console.log(wrapper.toString());
  }
}

module.exports = messages;
<|endoftext|>


<commit_before>/**
 * Setup Script
 *  - Creates setting.json file (given user input)
 *  - Creates blank atReaction, and txtReaction.json files
 */

const readline = require('readline');
const chalk = require('chalk');
const fs = require('fs');

const json = JSON.parse(fs.readFileSync('settings.template.json', 'utf8'));
const regToken = /[\w\d]{24}\.[\w\d]{6}\.[\w\d-_]{27}/;
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const writeFiles = (settingsObj, reactionsObj) => {
  console.log('\n');
  // Write `settings.json`
  fs.writeFile('settings.json', JSON.stringify(settingsObj, null, 2), (err) => {
    if (err) {
      console.log(chalk.bgRed.black('FAILED'), ' Writing settings.json', `\n${err}`);
    } else {
      // SUCCESS settings.json
      console.log(chalk.bgGreen.black('SUCCESS'), ' Writing settings.json');
      // create backup file
      fs.writeFile('settings.backup.json', JSON.stringify(settingsObj, null, 2), (errOnBackup) => {
        if (errOnBackup) {
          console.log(chalk.bgRed.black('FAILED'), ' Writing settings.backup.json', `\n${errOnBackup}`);
        } else {
          console.log(chalk.bgGreen.black('SUCCESS'), ' Writing settings.backup.json');
        }
      });
    }

    /** Write `atReactions.json` */
    fs.writeFile('./config/atReactions.json', JSON.stringify(reactionsObj), (errAtReactions) => {
      if (errAtReactions) {
        console.log(chalk.bgRed.black('FAILED'), ' Writing /config/atReactions.json', `\n${err}`);
      } else {
        console.log(chalk.bgGreen.black('SUCCESS'), ' Writing /config/atReactions.json');
      }

      /** Write `txtReactions.json` */
      fs.writeFile('./config/txtReactions.json', JSON.stringify(reactionsObj), (errTxtReactions) => {
        if (errTxtReactions) {
          console.log(chalk.bgRed.black('FAILED'), ' Writing /config/txtReactions.json', `\n${err}`);
        } else {
          console.log(chalk.bgGreen.black('SUCCESS'), ' Writing /config/txtReactions.json');
          console.log('\nSetup complete!\nRun "npm start" to start up your bot. :)');
          rl.close();
        }
      });
    });
  });
};

console.log('Generating configuration files for you. Just need some info first...' +
  '\n\nA (*) means that the setting is required. Otherwise, you can leave the setting blank.' +
  '\n[Refer to the README for more information on this setup script.]\n');

/** Define questions to ask */

const askForToken = () =>
  new Promise((resolve, reject) => {
    try {
      /* eslint-disable */
      let notDone = true;

      rl.question('* Token: [Discord bot token] ', (token) => {
        token = token.trim();
        if (token.match(regToken)) {
          resolve(token);
          notDone = false;
        } else {
          // if token doesn't match expectations, ask again
          console.log('Woops, looks like that wasn\'t a valid token format... Please enter your Discord bot token again: ');
          askForToken().then(recursiveToken => {
            resolve(recursiveToken);
          });
        }
      });
      /* eslint-enable */
    } catch (err) {
      reject(err);
    }
  });

const askForBotName = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question(`* Your bot's name: (${json.botNameProper}) `, (name) => {
        resolve(name.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const ridWhiteSpace = name => name.replace(/\s/g, '');

const getCode = name => ridWhiteSpace(name).toLowerCase();

const askForPrefix = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question(`* Command prefix: (${json.prefix}) `, (prefix) => {
        resolve(ridWhiteSpace(prefix));
      });
    } catch (err) {
      reject(err);
    }
  });

const askForMasterID = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('* Your Discord User ID: ( ) [right click, Copy ID] ', (masterID) => {
        resolve(masterID.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const askForMainGuild = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('* Your Discord Server ID: ( ) [right click, Copy ID] ', (mainGuild) => {
        resolve(mainGuild.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const askForTestGuild = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('  Test Guild Server ID: ( ) [needed only for ExtendedEmoji] ', (testGuild) => {
        resolve(testGuild.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const askForImgurToken = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('  Imgur API Token: ( ) [needed only for `reloadfortunes`] ', (imgurToken) => {
        resolve(imgurToken.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

/** Start asking questions */
(async function exec() {
  try {
    json.token = await askForToken();

    const name = await askForBotName();
    if (name !== '') {
      json.botNameProper = name;
      json.botName = getCode(name);
    }

    const prefix = await askForPrefix();
    if (prefix !== '') {
      json.prefix = prefix;
    }

    const masterID = await askForMasterID();
    if (masterID !== '') {
      json.masterID = masterID;
    }

    const mainGuild = await askForMainGuild();
    if (mainGuild !== '') {
      json.mainGuild = mainGuild;
    }

    const testGuild = await askForTestGuild();
    if (testGuild !== '') {
      json.testGuild = testGuild;
    }

    const imgurToken = await askForImgurToken();
    if (imgurToken !== '') {
      json.fortune.token = imgurToken;
    }

    /* Write and close */
    writeFiles(json, { reactions: [] });
    rl.close();
  } catch (err) {
    console.error(err);
  }
}());
<commit_msg>[Scripts] Add indents to generated json files<commit_after>/**
 * Setup Script
 *  - Creates setting.json file (given user input)
 *  - Creates blank atReaction, and txtReaction.json files
 */

const readline = require('readline');
const chalk = require('chalk');
const fs = require('fs');

const json = JSON.parse(fs.readFileSync('settings.template.json', 'utf8'));
const regToken = /[\w\d]{24}\.[\w\d]{6}\.[\w\d-_]{27}/;
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const writeFiles = (settingsObj, reactionsObj) => {
  console.log('\n');
  // Write `settings.json`
  fs.writeFile('settings.json', JSON.stringify(settingsObj, null, 2), (err) => {
    if (err) {
      console.log(chalk.bgRed.black('FAILED'), ' Writing settings.json', `\n${err}`);
    } else {
      // SUCCESS settings.json
      console.log(chalk.bgGreen.black('SUCCESS'), ' Writing settings.json');
      // create backup file
      fs.writeFile('settings.backup.json', JSON.stringify(settingsObj, null, 2), (errOnBackup) => {
        if (errOnBackup) {
          console.log(chalk.bgRed.black('FAILED'), ' Writing settings.backup.json', `\n${errOnBackup}`);
        } else {
          console.log(chalk.bgGreen.black('SUCCESS'), ' Writing settings.backup.json');
        }
      });
    }

    /** Write `atReactions.json` */
    fs.writeFile('./config/atReactions.json', JSON.stringify(reactionsObj, null, 2), (errAtReactions) => {
      if (errAtReactions) {
        console.log(chalk.bgRed.black('FAILED'), ' Writing /config/atReactions.json', `\n${err}`);
      } else {
        console.log(chalk.bgGreen.black('SUCCESS'), ' Writing /config/atReactions.json');
      }

      /** Write `txtReactions.json` */
      fs.writeFile('./config/txtReactions.json', JSON.stringify(reactionsObj, null, 2), (errTxtReactions) => {
        if (errTxtReactions) {
          console.log(chalk.bgRed.black('FAILED'), ' Writing /config/txtReactions.json', `\n${err}`);
        } else {
          console.log(chalk.bgGreen.black('SUCCESS'), ' Writing /config/txtReactions.json');
          console.log('\nSetup complete!\nRun "npm start" to start up your bot. :)');
          rl.close();
        }
      });
    });
  });
};

console.log('Generating configuration files for you. Just need some info first...' +
  '\n\nA (*) means that the setting is required. Otherwise, you can leave the setting blank.' +
  '\n[Refer to the README for more information on this setup script.]\n');

/** Define questions to ask */

const askForToken = () =>
  new Promise((resolve, reject) => {
    try {
      /* eslint-disable */
      let notDone = true;

      rl.question('* Token: [Discord bot token] ', (token) => {
        token = token.trim();
        if (token.match(regToken)) {
          resolve(token);
          notDone = false;
        } else {
          // if token doesn't match expectations, ask again
          console.log('Woops, looks like that wasn\'t a valid token format... Please enter your Discord bot token again: ');
          askForToken().then(recursiveToken => {
            resolve(recursiveToken);
          });
        }
      });
      /* eslint-enable */
    } catch (err) {
      reject(err);
    }
  });

const askForBotName = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question(`* Your bot's name: (${json.botNameProper}) `, (name) => {
        resolve(name.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const ridWhiteSpace = name => name.replace(/\s/g, '');

const getCode = name => ridWhiteSpace(name).toLowerCase();

const askForPrefix = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question(`* Command prefix: (${json.prefix}) `, (prefix) => {
        resolve(ridWhiteSpace(prefix));
      });
    } catch (err) {
      reject(err);
    }
  });

const askForMasterID = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('* Your Discord User ID: ( ) [right click, Copy ID] ', (masterID) => {
        resolve(masterID.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const askForMainGuild = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('* Your Discord Server ID: ( ) [right click, Copy ID] ', (mainGuild) => {
        resolve(mainGuild.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const askForTestGuild = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('  Test Guild Server ID: ( ) [needed only for ExtendedEmoji] ', (testGuild) => {
        resolve(testGuild.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

const askForImgurToken = () =>
  new Promise((resolve, reject) => {
    try {
      rl.question('  Imgur API Token: ( ) [needed only for `reloadfortunes`] ', (imgurToken) => {
        resolve(imgurToken.trim());
      });
    } catch (err) {
      reject(err);
    }
  });

/** Start asking questions */
(async function exec() {
  try {
    json.token = await askForToken();

    const name = await askForBotName();
    if (name !== '') {
      json.botNameProper = name;
      json.botName = getCode(name);
    }

    const prefix = await askForPrefix();
    if (prefix !== '') {
      json.prefix = prefix;
    }

    const masterID = await askForMasterID();
    if (masterID !== '') {
      json.masterID = masterID;
    }

    const mainGuild = await askForMainGuild();
    if (mainGuild !== '') {
      json.mainGuild = mainGuild;
    }

    const testGuild = await askForTestGuild();
    if (testGuild !== '') {
      json.testGuild = testGuild;
    }

    const imgurToken = await askForImgurToken();
    if (imgurToken !== '') {
      json.fortune.token = imgurToken;
    }

    /* Write and close */
    writeFiles(json, { reactions: [] });
    rl.close();
  } catch (err) {
    console.error(err);
  }
}());
<|endoftext|>


<commit_before>/**
 * Created by ATILLA on 27/11/2015.
 */
(function () {
    'use strict';

    angular
        .module('oobj-filters')
        .filter('cnpj', cnpj);

    /** @ngInject */
    function cnpj() {

        var cnpj = function (value) {
            return angular.isUndefined(value) ? value : formattedCNPJ(value);
        };

        return cnpj;

        function formattedCNPJ(value) {
            var str = value + '';

            str = str.replace(/\D/g, '');
            str = str.replace(/^(\d{2})(\d)/, '$1.$2');
            str = str.replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3');
            str = str.replace(/\.(\d{3})(\d)/, '.$1/$2');
            str = str.replace(/(\d{4})(\d)/, '$1-$2');

            return str;
        }
    }
})();
<commit_msg>Melhorando legibilidade do filtro de CNPJ<commit_after>/**
 * Created by ATILLA on 27/11/2015.
 */
(function () {
    'use strict';

    angular
        .module('oobj-filters')
        .filter('cnpj', cnpj);

    /** @ngInject */
    function cnpj() {

        var cnpj = function (value) {
            return angular.isUndefined(value) ? value : formattedCNPJ(value);
        };

        return cnpj;

        function formattedCNPJ(value) {
            var formatted = value + '';

            formatted = formatted.replace(/\D/g, '');
            formatted = formatted.replace(/^(\d{2})(\d)/, '$1.$2');
            formatted = formatted.replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3');
            formatted = formatted.replace(/\.(\d{3})(\d)/, '.$1/$2');
            formatted = formatted.replace(/(\d{4})(\d)/, '$1-$2');

            return formatted;
        }
    }
})();
<|endoftext|>