<commit_before>// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var users = [];

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

// Routing
app.use(express.static(__dirname + '/public'));

// Chatroom

// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;

io.on('connection', function (socket) {
  var addedUser = false;
  // when the client emits 'new message', this listens and executes
  socket.on('new message', function (data) {
    // we tell the client to execute 'new message'
    if (data.length <= 1000) {
      socket.broadcast.emit('new message', {
        username: socket.username,
        message: data
      });
    }
  }
);

  // when the client emits 'add user', this listens and executes
  socket.on('add user', function (username) {
    // we store the username in the socket session for this client

    var address = socket.request.connection.remoteAddress;
    console.log(address + " has connected");

    socket.username = username;
    // add the client's username to the global list

    users.push(username);
    currentUsers = users;

    socket.emit("fill roster", users);

    usernames[username] = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', function () {
    // remove the username from global usernames list
    var address = socket.request.connection.remoteAddress;
    console.log(address + " has disconnected");

    if (addedUser) {
      delete usernames[socket.username];
      --numUsers;

    users.splice(users.indexOf(socket.username), 1);

      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});
<commit_msg>Roster Feedback<commit_after>// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var users = [];

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

// Routing
app.use(express.static(__dirname + '/public'));

// Chatroom

// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;

io.on('connection', function (socket) {
  var addedUser = false;
  // when the client emits 'new message', this listens and executes
  socket.on('new message', function (data) {
    // we tell the client to execute 'new message'
    if (data.length <= 1000) {
      socket.broadcast.emit('new message', {
        username: socket.username,
        message: data
      });
    }
  }
);

  // when the client emits 'add user', this listens and executes
  socket.on('add user', function (username) {
    // we store the username in the socket session for this client

    var address = socket.request.connection.remoteAddress;
    console.log(address + " has connected");

    socket.username = username;
    // add the client's username to the global list

    users.push(username);
    currentUsers = users;

    socket.emit("fill roster", users);

    usernames[username] = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', function () {
    // remove the username from global usernames list
    var address = socket.request.connection.remoteAddress;
    console.log(address + " has disconnected");

    if (addedUser) {
      delete usernames[socket.username];
      --numUsers;

    users.splice(users.indexOf(socket.username), 1);
    console.log(users);
      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});
<|endoftext|>


<commit_before>/*
  Convert the contents of an HTML DOM element into a
  styled text document for an easier reading
  experience or to bring out certain features in the
  document. You can create your own README document.

  if (redistribute == true) {
    return credit;
  }

  --------------------------------------------------

  @DocTyp
  @author: Alexander Hovy
  @param:
    exports - Contains all the public variables and functions of the module.
    doc - The elements text that will be Docified.
    elements - An array of Elements.
  @credit:
    Prism, Highlight, SHJS, Rainbow, Prettify
*/
(function(exports) {
  /*============================================================
  ===========================Variables==========================
  ============================================================*/
  var prefix = 'doctyp-';
  var header = {
    'header4': {pattern: /\#{4,}/gm, regex: /\#{4,}.+/gm},
    'header3': {pattern: /\#{3}/gm, regex: /\#{3}.+/gm},
    'header2': {pattern: /\#{2}/gm, regex: /\#{2}.+/gm},
    'header1': {pattern: /\#{1}/gm, regex: /\#{1}.+/gm}
  };
  var style = {
    'bold': {pattern: /\*{2}/gm, regex: /\*{2}(.*?)\*{2}/gm},
    'italic': {pattern: /\*{1}/gm, regex: /\*{1}(.*?)\*{1}/gm},
    'underline': {pattern: /\.{2}/gm, regex: /\.{2}(?!\.)(.*?)\.{2}/gm},
    'strike': {pattern: /\~{1,}/gm, regex: /\~{1,}(.*?)\~{1,}/gm},
    'highlight': {pattern: /\={1,}/gm, regex: /\={1,}(?!\")(.*?)\={1,}/gm},
    'superscript': {pattern: /\^{2}/gm, regex: /\^{2}(.*?)\^{2}/gm},
    'subscript': {pattern: /\^{1}/gm, regex: /\^{1}(.*?)\^{1}/gm}
  };
  var rule = {
    'rule-solid': {pattern: /[]/gm, regex: /^\-{4,}/gm},
    'rule-dash': {pattern: /[]/gm, regex: /^\.{4,}/gm}
  };
  var block = {
    'pre-extra': {pattern: /[]/gm, regex: /^\[(.*?)\|(.*?)\]\`{3,}([\s\S]*?)\`{3,}/gm},
    'quote-extra': {pattern: /[]/gm, regex: /^\[(.*?)\]\`{2}([\s\S]*?)\`{2}/gm},
    'pre': {pattern: /\`{3,}/gm, regex: /^\`{3,}([\s\S]*?)\`{3,}/gm},
    'quote': {pattern: /\`{2}/gm, regex: /^\`{2}([\s\S]*?)\`{2}/gm},
    'code': {pattern: /\`{1}/gm, regex: /\`{1}(.*?)\`{1}/gm}
  };
  var list = {
    'unordered': {pattern: /\-{1}/gm, regex: /(^\-{1}(?!\-{3,}).+\n){1,}/gm},
    'ordered': {pattern: /\d{1,}\./gm, regex: /(^\d{1,}\..+\n){1,}/gm},
    'checklist': {pattern: /[]/gm, regex: /(^\[[Xx]?\].+\n){1,}/gm}
  };
  var link = {
    'url-extra': {pattern: /[]/gm, regex: /\[(.*?)\]\((.*?)(https?|ftp|file)\:\/{2}(.*?)\)/gm},
    'url': {pattern: /[]/gm, regex: /\b((https?|ftp|file)\:\/{2}([\w\d\.]+)([\/\?\&\w\d\=\,\.\+\:\;\@\$\%\#\!\_\-]+)?)\b/gm},
    'email': {pattern: /[]/gm, regex: /\b(([\w\d\.\_\%\+\-]+)\@([\w\d\.\-]+)(\.\w{2,}))\b/gm}
  };

  /*============================================================
  ============================Private===========================
  ============================================================*/

  /*============================================================
  ============================Header============================
  ============================================================*/
  exports.Header = function(doc) {
    for (key in header) {
      doc = doc.replace(header[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(header[key].pattern, '');
        return '' + exports.Trim(temp) + '';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Style=============================
  ============================================================*/
  exports.Style = function(doc) {
    for (key in style) {
      doc = doc.replace(style[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(style[key].pattern, '');
        return '' + exports.Trim(temp) + '';
      });
    }
    return doc;
  };

  /*============================================================
  =============================Rule=============================
  ============================================================*/
  exports.Rule = function(doc) {
    for (key in rule) {
      doc = doc.replace(rule[key].regex, function(match) {
        return '
';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Block=============================
  ============================================================*/
  exports.Block = function(doc) {
    for (key in block) {
      doc = doc.replace(block[key].regex, function(match) {
        if (key == 'pre-extra') {
          var extra = exports.Prepare(match).split(']```'),
            first = extra[0].split('[')[1].split('|'),
            second = extra[1].split('```')[0],
            language = exports.Trim(first[0]).toLowerCase(),
            service = exports.Trim(first[1]).toLowerCase(),
            classes = 'language-' + language + ' sh_' + language + ' prettyprint lang-' + language,
            dataClasses = 'data-language="' + language + '"';
          exports.LoadScript('Syntax/' + service + '/script.js');
          exports.LoadStyle('Syntax/' + service + '/' + exports.theme + '.css');
          return '
' + second + '
';
        } else if (key == 'quote-extra') {
          var extra = exports.Prepare(match).split(']``'),
            credit = extra[0].split('[')[1],
            quote = extra[1].split('``')[0];
          return '
"' + exports.Trim(quote) + '"' + exports.Trim(credit) + '
';
        } else {
          var temp = exports.Prepare(match).replace(block[key].pattern, ''),
            classes = 'nohighlight language-none';
          if (key == 'pre') {
            return '
' + temp + '
';
          } else if (key == 'quote') {
            return '
"' + exports.Trim(temp) + '"
';
          } else {
            return '' + exports.Trim(temp) + '';
          }
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================List=============================
  ============================================================*/
  exports.List = function(doc) {
    for (key in list) {
      doc = doc.replace(list[key].regex, function(match) {
        if (key == 'unordered' || key == 'ordered') {
          var tag = key == 'unordered' ? 'ul' : 'ol';
          return '<' + tag + ' class="' + prefix + key + '">' + match.replace(/.+/gm, function(line) {
            var temp = exports.Prepare(line).replace(list[key].pattern, '');
            return '
' + exports.Trim(temp) + '
';
          }) + '</' + tag + '>';
        } else {
          return '' + match.replace(/.+/gm, function(line) {
            var temp = exports.Prepare(line).replace(/\[[Xx]?\]/gm, ''),
              tag = (new RegExp(/\[\]/gm)).test(line) ? 'unchecked' : 'checked';
            return '' + exports.Trim(temp) + '';
          }) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================Link=============================
  ============================================================*/
  exports.Link = function(doc) {
    for (key in link) {
      doc = doc.replace(link[key].regex, function(match) {
        if (key == 'url-extra') {
          var extra = exports.Prepare(match).split(']('),
            title = extra[0].split('[')[1],
            url = extra[1].split(']')[0];
          return '' + exports.Trim(title) + '';
        } else {
          return '' + exports.Trim(match) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ===========================Cleaning===========================
  ============================================================*/
  exports.Prepare = function(doc) {
    return doc.replace(/\<(\/)?span(.*?)\>/gm, '');
  };
  exports.Trim = function(doc) {
    return doc.replace(/(^\s+|\s+$)/gm, '');
  };
  exports.Clean = function(doc) {
    return doc.replace(/\n/gm, '
');
  };

  /*============================================================
  ============================Syntax============================
  ============================================================*/
  exports.Syntax = function(elements) {
    for (var a = 0; a < elements.length; a++) {
      var element = elements[a],
        code = element.innerHTML,
        fixed = code.replace(/\
/gm, '\n');
      element.innerHTML = fixed;
    }
  };

  /*============================================================
  ============================Export============================
  ============================================================*/
  return exports;
})(DocTyp || {});
<commit_msg>Update extension.js<commit_after>/*
  Convert the contents of an HTML DOM element into a
  styled text document for an easier reading
  experience or to bring out certain features in the
  document. You can create your own README document.

  if (redistribute == true) {
    return credit;
  }

  --------------------------------------------------

  @DocTyp
  @author: Alexander Hovy
  @param:
    exports - Contains all the public variables and functions of the module.
    doc - The elements text that will be Docified.
    elements - An array of Elements.
  @credit:
    Prism, Highlight, SHJS, Rainbow, Prettify
*/
(function(exports) {
  /*============================================================
  ===========================Variables==========================
  ============================================================*/
  var prefix = 'doctyp-';
  var header = {
    'header4': {pattern: /\#{4,}/gm, regex: /\#{4,}.+/gm},
    'header3': {pattern: /\#{3}/gm, regex: /\#{3}.+/gm},
    'header2': {pattern: /\#{2}/gm, regex: /\#{2}.+/gm},
    'header1': {pattern: /\#{1}/gm, regex: /\#{1}.+/gm}
  };
  var style = {
    'bold': {pattern: /\*{2}/gm, regex: /\*{2}(.*?)\*{2}/gm},
    'italic': {pattern: /\*{1}/gm, regex: /\*{1}(.*?)\*{1}/gm},
    'underline': {pattern: /\.{2}/gm, regex: /\.{2}(?!\.)(.*?)\.{2}/gm},
    'strike': {pattern: /\~{1,}/gm, regex: /\~{1,}(.*?)\~{1,}/gm},
    'highlight': {pattern: /\={1,}/gm, regex: /\={1,}(?!\")(.*?)\={1,}/gm},
    'superscript': {pattern: /\^{2}/gm, regex: /\^{2}(.*?)\^{2}/gm},
    'subscript': {pattern: /\^{1}/gm, regex: /\^{1}(.*?)\^{1}/gm}
  };
  var rule = {
    'rule-solid': {pattern: /[]/gm, regex: /^\-{4,}/gm},
    'rule-dash': {pattern: /[]/gm, regex: /^\.{4,}/gm}
  };
  var block = {
    'pre-extra': {pattern: /[]/gm, regex: /^\[(.*?)\|(.*?)\]\`{3,}([\s\S]*?)\`{3,}/gm},
    'quote-extra': {pattern: /[]/gm, regex: /^\[(.*?)\]\`{2}([\s\S]*?)\`{2}/gm},
    'pre': {pattern: /\`{3,}/gm, regex: /^\`{3,}([\s\S]*?)\`{3,}/gm},
    'quote': {pattern: /\`{2}/gm, regex: /^\`{2}([\s\S]*?)\`{2}/gm},
    'code': {pattern: /\`{1}/gm, regex: /\`{1}(.*?)\`{1}/gm}
  };
  var list = {
    'unordered': {pattern: /\-{1}/gm, regex: /(^\-{1}(?!\-{3,}).+\n){1,}/gm},
    'ordered': {pattern: /\d{1,}\./gm, regex: /(^\d{1,}\..+\n){1,}/gm},
    'checklist': {pattern: /[]/gm, regex: /(^\[[Xx]?\].+\n){1,}/gm}
  };
  var link = {
    'url-extra': {pattern: /[]/gm, regex: /\[(.*?)\]\((.*?)(https?|ftp|file)\:\/{2}(.*?)\)/gm},
    'url': {pattern: /[]/gm, regex: /\b((https?|ftp|file)\:\/{2}([\w\d\.]+)([\/\?\&\w\d\=\,\.\+\:\;\@\$\%\#\!\_\-]+)?)\b/gm},
    'email': {pattern: /[]/gm, regex: /\b(([\w\d\.\_\%\+\-]+)\@([\w\d\.\-]+)(\.\w{2,}))\b/gm}
  };

  /*============================================================
  ============================Private===========================
  ============================================================*/

  /*============================================================
  ============================Header============================
  ============================================================*/
  exports.Header = function(doc) {
    for (key in header) {
      doc = doc.replace(header[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(header[key].pattern, '');
        return '' + exports.Trim(temp) + '';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Style=============================
  ============================================================*/
  exports.Style = function(doc) {
    for (key in style) {
      doc = doc.replace(style[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(style[key].pattern, '');
        return '' + exports.Trim(temp) + '';
      });
    }
    return doc;
  };

  /*============================================================
  =============================Rule=============================
  ============================================================*/
  exports.Rule = function(doc) {
    for (key in rule) {
      doc = doc.replace(rule[key].regex, function(match) {
        return '
';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Block=============================
  ============================================================*/
  exports.Block = function(doc) {
    for (key in block) {
      doc = doc.replace(block[key].regex, function(match) {
        if (key == 'pre-extra') {
          var extra = exports.Prepare(match).split(']```'),
            first = extra[0].split('[')[1].split('|'),
            second = extra[1].split('```')[0],
            language = exports.Trim(first[0]).toLowerCase(),
            service = exports.Trim(first[1]).toLowerCase(),
            classes = 'language-' + language + ' sh_' + language + ' prettyprint lang-' + language,
            dataClasses = 'data-language="' + language + '"';
          exports.LoadScript('Syntax/' + service + '/script.js');
          exports.LoadStyle('Syntax/' + service + '/' + exports.theme + '.css');
          return '
' + second + '
';
        } else if (key == 'quote-extra') {
          var extra = exports.Prepare(match).split(']``'),
            credit = extra[0].split('[')[1],
            quote = extra[1].split('``')[0];
          return '
"' + exports.Trim(quote) + '"
' + exports.Trim(credit) + '
';
        } else {
          var temp = exports.Prepare(match).replace(block[key].pattern, ''),
            classes = 'nohighlight language-none';
          if (key == 'pre') {
            return '
' + temp + '
';
          } else if (key == 'quote') {
            return '
"' + exports.Trim(temp) + '"
';
          } else {
            return '' + exports.Trim(temp) + '';
          }
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================List=============================
  ============================================================*/
  exports.List = function(doc) {
    for (key in list) {
      doc = doc.replace(list[key].regex, function(match) {
        if (key == 'unordered' || key == 'ordered') {
          var tag = key == 'unordered' ? 'ul' : 'ol';
          return '<' + tag + ' class="' + prefix + key + '">' + match.replace(/.+/gm, function(line) {
            var temp = exports.Prepare(line).replace(list[key].pattern, '');
            return '
' + exports.Trim(temp) + '
';
          }) + '</' + tag + '>';
        } else {
          return '' + match.replace(/.+/gm, function(line) {
            var temp = exports.Prepare(line).replace(/\[[Xx]?\]/gm, ''),
              tag = (new RegExp(/\[\]/gm)).test(line) ? 'unchecked' : 'checked';
            return '' + exports.Trim(temp) + '';
          }) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================Link=============================
  ============================================================*/
  exports.Link = function(doc) {
    for (key in link) {
      doc = doc.replace(link[key].regex, function(match) {
        if (key == 'url-extra') {
          var extra = exports.Prepare(match).split(']('),
            title = extra[0].split('[')[1],
            url = extra[1].split(']')[0];
          return '' + exports.Trim(title) + '';
        } else {
          return '' + exports.Trim(match) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ===========================Cleaning===========================
  ============================================================*/
  exports.Prepare = function(doc) {
    return doc.replace(/\<(\/)?span(.*?)\>/gm, '');
  };
  exports.Trim = function(doc) {
    return doc.replace(/(^\s+|\s+$)/gm, '');
  };
  exports.Clean = function(doc) {
    return doc.replace(/\n/gm, '
');
  };

  /*============================================================
  ============================Syntax============================
  ============================================================*/
  exports.Syntax = function(elements) {
    for (var a = 0; a < elements.length; a++) {
      var element = elements[a],
        code = element.innerHTML,
        fixed = code.replace(/\
/gm, '\n');
      element.innerHTML = fixed;
    }
  };

  /*============================================================
  ============================Export============================
  ============================================================*/
  return exports;
})(DocTyp || {});
<|endoftext|>


<commit_before>//======Define Memory Property======
Object.defineProperty(Structure.prototype, 'memory', {
    configurable: true,
    get: function() {
        if(_.isUndefined(Memory.structures)) {
            Memory.structures = {};
        }
        if(!_.isObject(Memory.structures)) {
            return undefined;
        }
        return Memory.structures[this.id] = Memory.structures[this.id] || {};
    },
    set: function(value) {
        if(_.isUndefined(Memory.structures)) {
            Memory.structures = {};
        }
        if(!_.isObject(Memory.structures)) {
            throw new Error('Could not set memory extension for structures');
        }
        Memory.structures[this.id] = value;
    }
});

Object.defineProperty(Source.prototype, 'memory', {
    configurable: true,
    get: function() {
        if(_.isUndefined(Memory.sources)) {
            Memory.sources = {};
        }
        if(!_.isObject(Memory.sources)) {
            return undefined;
        }
        return Memory.sources[this.id] = Memory.sources[this.id] || {};
    },
    set: function(value) {
        if(_.isUndefined(Memory.sources)) {
            Memory.sources = {};
        }
        if(!_.isObject(Memory.sources)) {
            throw new Error('Could not set memory extension for sources');
        }
        Memory.sources[this.id] = value;
    }
});
//======Define Other Property======
Object.defineProperties(Source.prototype, {
    'accessibleFields': {
        configurable: true,
        get: function() {
            if ( this.memory && !_.isUndefined(this.memory.accessibleFields) ) {
                return this.memory.accessibleFields;
            } else {
                const terrain = new Room.Terrain(this.room.name);
                const y = this.pos.y;
                const x = this.pos.x;
                var wallCnt = 0;
                for(let xi=x-1; xi<=x+1; xi++) {
                    for(let yi=y-1; yi<=y+1; yi++) {
                        //traverse fields nearby
                        if(xi===x && yi===y) continue;
                        if(TERRAIN_MASK_WALL === terrain.get(xi, yi)) {
                            wallCnt++;
                        }
                    }
                }
                var accessibleFields = 8-wallCnt;
                return (this.memory) ? this.memory.accessibleFields = accessibleFields : accessibleFields;
            }
        }
    },
    'container': {
        get: function() {
            if (!this._container) {
                if (!this.memory.containerId) {
                    const targets = this.pos.findInRange(this.room.cachedFind(FIND_STRUCTURES), 1, {
                        filter: o => o.structureType == STRUCTURE_CONTAINER || o.structureType == STRUCTURE_STORAGE
                    });
                    const closestTarget = targets[0]; //Same distance, so pick first one
                    if(closestTarget) {
                        this.memory.containerId = closestTarget.id;
                    } else {
                        return false;
                    }
                }
                const obj = Game.getObjectById(this.memory.containerId);
                if(!obj) {
                    //Then we need to reset containerId since it is invalid.
                    this.memory.containerId = false;
                    return false;
                }
                this._container = obj;
            }
            return this._container;
        },
        set: function(container) {
            this.memory.containerId = container.id;
            this._container = container;
        },
        enumerable: false,
        configurable: true
    },
});

Object.defineProperties(StructureController.prototype, {
    'container': {
        get: function() {
            if (!this._container) {
                if (!this.memory.containerId) {
                    const targets = this.pos.findInRange(this.room.cachedFind(FIND_STRUCTURES), 2, {
                        filter: o => o.structureType == STRUCTURE_CONTAINER || o.structureType == STRUCTURE_STORAGE
                    });
                    const closestTarget = this.pos.findClosestByRange(targets);
                    if(closestTarget) {
                        this.memory.containerId = closestTarget.id;
                    } else {
                        return false;
                    }
                }
                const obj = Game.getObjectById(this.memory.containerId);
                if(!obj) {
                    //Then we need to reset containerId since it is invalid.
                    this.memory.containerId = false;
                    return false;
                }
                this._container = obj;
            }
            return this._container;
        },
        set: function(container) {
            this.memory.containerId = container.id;
            this._container = container;
        },
        enumerable: false,
        configurable: true
    },
});

function genericGetter(self, name, internalName, initialFunc) {
    if (!self[internalName]) {
        if (self.memory[name]) {
            self[internalName] = self.memory[name];
        } else {
            self.memory[name] = initialFunc();
            self[internalName] = self.memory[name];
        }
    }
    return self[internalName];
}

function genericSetter(self, name, internalName, value) {
    self.memory[name] = value;
    self[internalName] = value;
}

Object.defineProperties(Room.prototype, {
    'layout': {
        get: function() {
            return genericGetter(this, 'layout', '_layout', () => {
                const value = {
                    'init': false,
                    [STRUCTURE_SPAWN]: [],
                    [STRUCTURE_EXTENSION]: [],
                    [STRUCTURE_ROAD]: [],
                    [STRUCTURE_WALL]: [],
                    [STRUCTURE_RAMPART]: [],
                    [STRUCTURE_LINK]: [],
                    [STRUCTURE_STORAGE]: [],
                    [STRUCTURE_TOWER]: [],
                    [STRUCTURE_OBSERVER]: [],
                    [STRUCTURE_POWER_SPAWN]: [],
                    [STRUCTURE_EXTRACTOR]: [],
                    [STRUCTURE_LAB]: [],
                    [STRUCTURE_TERMINAL]: [],
                    [STRUCTURE_CONTAINER]: [],
                    [STRUCTURE_NUKER]: []
                };
                return value;
            });
        },
        set: function(value) {
            return genericSetter(this, 'layout', '_layout');
        },
        enumerable: false,
        configurable: true
    },
    'queue': {
        get: function() {
            return genericGetter(this, 'queue', '_queue', () => {
                return {
                    urgent: [],
                    normal: [],
                    extern: [],
                    lastBalanceTick: 0,
                };
            });
        },
        set: function(queue) {
            return genericSetter(this, 'queue', '_queue');
        },
        enumerable: false,
        configurable: true
    },
    'spawnLink': {
        get: function() {
            if (!this._spawnLink) {
                if (this.memory.spawnLinkId) {
                    const obj = Game.getObjectById(this.memory.spawnLinkId);
                    if(!obj) {
                        this.memory.spawnLinkId = false;
                        return false;
                    }
                    this._spawnLink = obj;
                } else {
                    return false;
                }
            }
            return this._spawnLink;
        },
        set: function(spawnLink) {
            this.memory.spawnLinkId = spawnLink.id;
            this._spawnLink = spawnLink;
        },
        enumerable: false,
        configurable: true
    },
    'sourceLinks': {
        get: function() {
            if (!this._sourceLinks) {
                const sourceLinkIds = this.memory.sourceLinkIds;
                if (sourceLinkIds && sourceLinkIds.length > 0) {
                    this._sourceLinks = _.map(sourceLinkIds, id => Game.getObjectById(id));
                } else {
                    this._sourceLinks = [];
                }
            }
            return this._sourceLinks;
        },
        set: function(sourceLinks) {
            this.memory.sourceLinkIds = _.map(sourceLinks, link => link.id);
            this._sourceLinks = sourceLinks;
        },
        enumerable: false,
        configurable: true
    },
    'controllerLink': {
        get: function() {
            if (!this._controllerLink) {
                if (this.memory.controllerLinkId) {
                    const obj = Game.getObjectById(this.memory.controllerLinkId);
                    if(!obj) {
                        this.memory.controllerLinkId = false;
                        return false;
                    }
                    this._controllerLink = obj;
                } else {
                    return false;
                }
            }
            return this._controllerLink;
        },
        set: function(controllerLink) {
            this.memory.controllerLinkId = controllerLink.id;
            this._controllerLink = controllerLink;
        },
        enumerable: false,
        configurable: true
    },
    'spawns': {
        get: function() {
            if (!this._spawns) {
                const spawnIds = this.memory.spawnIds;
                //If array has no item, re-search and cache it
                if (spawnIds && spawnIds.length > 0) {
                    var spawns = _.map(spawnIds, id => Game.getObjectById(id));
                    this._spawns = spawns;
                } else {
                    const roomName = this.name;
                    const spawns = _.filter(Game.spawns, spawn => spawn.room.name===roomName);
                    this.memory.spawnIds = _.map(spawns, spawn => spawn.id);
                    this._spawns = spawns;
                }
            }
            return this._spawns;
        },
        set: function(spawns) {
            this.memory.spawnIds = _.map(spawns, spawn => spawn.id);
            this._spawns = spawns;
        },
        enumerable: false,
        configurable: true
    },
    'sources': {
        get: function() {
            if (!this._sources) {
                const sourceIds = this.memory.sourceIds;
                //If array has no item, re-search and cache it
                if (sourceIds && sourceIds.length > 0) {
                    let sources = _.map(sourceIds, id => Game.getObjectById(id));
                    this._sources = sources;
                } else {
                    const sources = this.cachedFind(FIND_SOURCES);
                    this.memory.sourceIds = _.map(sources, source => source.id);
                    this._sources = sources;
                }
            }
            return this._sources;
        },
        set: function(sources) {
            this.memory.sourceIds = _.map(sources, source => source.id);
            this._sources = sources;
        },
        enumerable: false,
        configurable: true
    },
});

Room.prototype.cachedRoleCount = function() {
    if(this.Cache === undefined) this.Cache = {};
    const internal = '$roleCount';
    if(this.Cache[internal]===undefined) {
        //=== Role count ===
        const self = this;
        const roomCreeps = _.filter(Game.creeps, function(creep) { return creep.memory.homeRoom == self.name; });
        let cnt = {
            existed: {},
            queue: {},
            total: {},
        };
        _.forEach(Role, o => {
            cnt.existed[o.roleName] = 0;
            cnt.queue[o.roleName] = 0;
            cnt.total[o.roleName] = 0;
        }); //Init cnt
        //Count role existed
        for(let creep of roomCreeps) {
            const role = creep.memory.role;
            cnt.existed[role]++;
            cnt.total[role]++;
        }
        //Count role in queue as well
        const queue = this.queue.urgent.concat(this.queue.normal);
        for(let setupName of queue) {
            const role = setupName;
            cnt.queue[role]++;
            cnt.total[role]++;
        }

        this.Cache[internal] = cnt;
    };
    return this.Cache[internal];
};

Room.prototype.cachedFind = function(type) {
    if(this.Cache === undefined) this.Cache = {};
    const internal = '_'+type;
    if(this.Cache[internal]===undefined) {
        this.Cache[internal] = this.find(type);
    }
    return this.Cache[internal];
};

Room.prototype.saveLinks = function() {
    if(this.sourceLink && this.spawnLink && this.controllerLink) return; //Only do search when links is not valid.
    const self = this;
    const links = _.filter(this.cachedFind(FIND_MY_STRUCTURES), { structureType: STRUCTURE_LINK });
    const controller = this.controller;
    const sources = this.cachedFind(FIND_SOURCES);
    const spawnsAndExtensions = _.filter(this.cachedFind(FIND_MY_STRUCTURES), o => o.structureType==STRUCTURE_SPAWN || o.structureType==STRUCTURE_EXTENSION);

    let sourceLinks = [];
    _.forEach(links, link => {
        if(link.pos.inRangeTo(controller, 3)) {
            self.controllerLink = link;
        } else if(link.pos.findInRange(sources, 2).length) {
            sourceLinks.push(link);
        } else if(link.pos.findInRange(spawnsAndExtensions, 3).length) {
            self.spawnLink = link;
        }
    });
    if(sourceLinks.length > 0) {
        this.sourceLinks = sourceLinks;
    }
};
<commit_msg>introduce bonzAI.blindMoveTo<commit_after>//======Define Memory Property======
Object.defineProperty(Structure.prototype, 'memory', {
    configurable: true,
    get: function() {
        if(_.isUndefined(Memory.structures)) {
            Memory.structures = {};
        }
        if(!_.isObject(Memory.structures)) {
            return undefined;
        }
        return Memory.structures[this.id] = Memory.structures[this.id] || {};
    },
    set: function(value) {
        if(_.isUndefined(Memory.structures)) {
            Memory.structures = {};
        }
        if(!_.isObject(Memory.structures)) {
            throw new Error('Could not set memory extension for structures');
        }
        Memory.structures[this.id] = value;
    }
});

Object.defineProperty(Source.prototype, 'memory', {
    configurable: true,
    get: function() {
        if(_.isUndefined(Memory.sources)) {
            Memory.sources = {};
        }
        if(!_.isObject(Memory.sources)) {
            return undefined;
        }
        return Memory.sources[this.id] = Memory.sources[this.id] || {};
    },
    set: function(value) {
        if(_.isUndefined(Memory.sources)) {
            Memory.sources = {};
        }
        if(!_.isObject(Memory.sources)) {
            throw new Error('Could not set memory extension for sources');
        }
        Memory.sources[this.id] = value;
    }
});
//======Define Other Property======
Object.defineProperties(Source.prototype, {
    'accessibleFields': {
        configurable: true,
        get: function() {
            if ( this.memory && !_.isUndefined(this.memory.accessibleFields) ) {
                return this.memory.accessibleFields;
            } else {
                const terrain = new Room.Terrain(this.room.name);
                const y = this.pos.y;
                const x = this.pos.x;
                var wallCnt = 0;
                for(let xi=x-1; xi<=x+1; xi++) {
                    for(let yi=y-1; yi<=y+1; yi++) {
                        //traverse fields nearby
                        if(xi===x && yi===y) continue;
                        if(TERRAIN_MASK_WALL === terrain.get(xi, yi)) {
                            wallCnt++;
                        }
                    }
                }
                var accessibleFields = 8-wallCnt;
                return (this.memory) ? this.memory.accessibleFields = accessibleFields : accessibleFields;
            }
        }
    },
    'container': {
        get: function() {
            if (!this._container) {
                if (!this.memory.containerId) {
                    const targets = this.pos.findInRange(this.room.cachedFind(FIND_STRUCTURES), 1, {
                        filter: o => o.structureType == STRUCTURE_CONTAINER || o.structureType == STRUCTURE_STORAGE
                    });
                    const closestTarget = targets[0]; //Same distance, so pick first one
                    if(closestTarget) {
                        this.memory.containerId = closestTarget.id;
                    } else {
                        return false;
                    }
                }
                const obj = Game.getObjectById(this.memory.containerId);
                if(!obj) {
                    //Then we need to reset containerId since it is invalid.
                    this.memory.containerId = false;
                    return false;
                }
                this._container = obj;
            }
            return this._container;
        },
        set: function(container) {
            this.memory.containerId = container.id;
            this._container = container;
        },
        enumerable: false,
        configurable: true
    },
});

Object.defineProperties(StructureController.prototype, {
    'container': {
        get: function() {
            if (!this._container) {
                if (!this.memory.containerId) {
                    const targets = this.pos.findInRange(this.room.cachedFind(FIND_STRUCTURES), 2, {
                        filter: o => o.structureType == STRUCTURE_CONTAINER || o.structureType == STRUCTURE_STORAGE
                    });
                    const closestTarget = this.pos.findClosestByRange(targets);
                    if(closestTarget) {
                        this.memory.containerId = closestTarget.id;
                    } else {
                        return false;
                    }
                }
                const obj = Game.getObjectById(this.memory.containerId);
                if(!obj) {
                    //Then we need to reset containerId since it is invalid.
                    this.memory.containerId = false;
                    return false;
                }
                this._container = obj;
            }
            return this._container;
        },
        set: function(container) {
            this.memory.containerId = container.id;
            this._container = container;
        },
        enumerable: false,
        configurable: true
    },
});

function genericGetter(self, name, internalName, initialFunc) {
    if (!self[internalName]) {
        if (self.memory[name]) {
            self[internalName] = self.memory[name];
        } else {
            self.memory[name] = initialFunc();
            self[internalName] = self.memory[name];
        }
    }
    return self[internalName];
}

function genericSetter(self, name, internalName, value) {
    self.memory[name] = value;
    self[internalName] = value;
}

Object.defineProperties(Room.prototype, {
    'layout': {
        get: function() {
            return genericGetter(this, 'layout', '_layout', () => {
                const value = {
                    'init': false,
                    [STRUCTURE_SPAWN]: [],
                    [STRUCTURE_EXTENSION]: [],
                    [STRUCTURE_ROAD]: [],
                    [STRUCTURE_WALL]: [],
                    [STRUCTURE_RAMPART]: [],
                    [STRUCTURE_LINK]: [],
                    [STRUCTURE_STORAGE]: [],
                    [STRUCTURE_TOWER]: [],
                    [STRUCTURE_OBSERVER]: [],
                    [STRUCTURE_POWER_SPAWN]: [],
                    [STRUCTURE_EXTRACTOR]: [],
                    [STRUCTURE_LAB]: [],
                    [STRUCTURE_TERMINAL]: [],
                    [STRUCTURE_CONTAINER]: [],
                    [STRUCTURE_NUKER]: []
                };
                return value;
            });
        },
        set: function(value) {
            return genericSetter(this, 'layout', '_layout');
        },
        enumerable: false,
        configurable: true
    },
    'queue': {
        get: function() {
            return genericGetter(this, 'queue', '_queue', () => {
                return {
                    urgent: [],
                    normal: [],
                    extern: [],
                    lastBalanceTick: 0,
                };
            });
        },
        set: function(queue) {
            return genericSetter(this, 'queue', '_queue');
        },
        enumerable: false,
        configurable: true
    },
    'spawnLink': {
        get: function() {
            if (!this._spawnLink) {
                if (this.memory.spawnLinkId) {
                    const obj = Game.getObjectById(this.memory.spawnLinkId);
                    if(!obj) {
                        this.memory.spawnLinkId = false;
                        return false;
                    }
                    this._spawnLink = obj;
                } else {
                    return false;
                }
            }
            return this._spawnLink;
        },
        set: function(spawnLink) {
            this.memory.spawnLinkId = spawnLink.id;
            this._spawnLink = spawnLink;
        },
        enumerable: false,
        configurable: true
    },
    'sourceLinks': {
        get: function() {
            if (!this._sourceLinks) {
                const sourceLinkIds = this.memory.sourceLinkIds;
                if (sourceLinkIds && sourceLinkIds.length > 0) {
                    this._sourceLinks = _.map(sourceLinkIds, id => Game.getObjectById(id));
                } else {
                    this._sourceLinks = [];
                }
            }
            return this._sourceLinks;
        },
        set: function(sourceLinks) {
            this.memory.sourceLinkIds = _.map(sourceLinks, link => link.id);
            this._sourceLinks = sourceLinks;
        },
        enumerable: false,
        configurable: true
    },
    'controllerLink': {
        get: function() {
            if (!this._controllerLink) {
                if (this.memory.controllerLinkId) {
                    const obj = Game.getObjectById(this.memory.controllerLinkId);
                    if(!obj) {
                        this.memory.controllerLinkId = false;
                        return false;
                    }
                    this._controllerLink = obj;
                } else {
                    return false;
                }
            }
            return this._controllerLink;
        },
        set: function(controllerLink) {
            this.memory.controllerLinkId = controllerLink.id;
            this._controllerLink = controllerLink;
        },
        enumerable: false,
        configurable: true
    },
    'spawns': {
        get: function() {
            if (!this._spawns) {
                const spawnIds = this.memory.spawnIds;
                //If array has no item, re-search and cache it
                if (spawnIds && spawnIds.length > 0) {
                    var spawns = _.map(spawnIds, id => Game.getObjectById(id));
                    this._spawns = spawns;
                } else {
                    const roomName = this.name;
                    const spawns = _.filter(Game.spawns, spawn => spawn.room.name===roomName);
                    this.memory.spawnIds = _.map(spawns, spawn => spawn.id);
                    this._spawns = spawns;
                }
            }
            return this._spawns;
        },
        set: function(spawns) {
            this.memory.spawnIds = _.map(spawns, spawn => spawn.id);
            this._spawns = spawns;
        },
        enumerable: false,
        configurable: true
    },
    'sources': {
        get: function() {
            if (!this._sources) {
                const sourceIds = this.memory.sourceIds;
                //If array has no item, re-search and cache it
                if (sourceIds && sourceIds.length > 0) {
                    let sources = _.map(sourceIds, id => Game.getObjectById(id));
                    this._sources = sources;
                } else {
                    const sources = this.cachedFind(FIND_SOURCES);
                    this.memory.sourceIds = _.map(sources, source => source.id);
                    this._sources = sources;
                }
            }
            return this._sources;
        },
        set: function(sources) {
            this.memory.sourceIds = _.map(sources, source => source.id);
            this._sources = sources;
        },
        enumerable: false,
        configurable: true
    },
});

Room.prototype.cachedRoleCount = function() {
    if(this.Cache === undefined) this.Cache = {};
    const internal = '$roleCount';
    if(this.Cache[internal]===undefined) {
        //=== Role count ===
        const self = this;
        const roomCreeps = _.filter(Game.creeps, function(creep) { return creep.memory.homeRoom == self.name; });
        let cnt = {
            existed: {},
            queue: {},
            total: {},
        };
        _.forEach(Role, o => {
            cnt.existed[o.roleName] = 0;
            cnt.queue[o.roleName] = 0;
            cnt.total[o.roleName] = 0;
        }); //Init cnt
        //Count role existed
        for(let creep of roomCreeps) {
            const role = creep.memory.role;
            cnt.existed[role]++;
            cnt.total[role]++;
        }
        //Count role in queue as well
        const queue = this.queue.urgent.concat(this.queue.normal);
        for(let setupName of queue) {
            const role = setupName;
            cnt.queue[role]++;
            cnt.total[role]++;
        }

        this.Cache[internal] = cnt;
    };
    return this.Cache[internal];
};

Room.prototype.cachedFind = function(type) {
    if(this.Cache === undefined) this.Cache = {};
    const internal = '_'+type;
    if(this.Cache[internal]===undefined) {
        this.Cache[internal] = this.find(type);
    }
    return this.Cache[internal];
};

Room.prototype.saveLinks = function() {
    if(this.sourceLink && this.spawnLink && this.controllerLink) return; //Only do search when links is not valid.
    const self = this;
    const links = _.filter(this.cachedFind(FIND_MY_STRUCTURES), { structureType: STRUCTURE_LINK });
    const controller = this.controller;
    const sources = this.cachedFind(FIND_SOURCES);
    const spawnsAndExtensions = _.filter(this.cachedFind(FIND_MY_STRUCTURES), o => o.structureType==STRUCTURE_SPAWN || o.structureType==STRUCTURE_EXTENSION);

    let sourceLinks = [];
    _.forEach(links, link => {
        if(link.pos.inRangeTo(controller, 3)) {
            self.controllerLink = link;
        } else if(link.pos.findInRange(sources, 2).length) {
            sourceLinks.push(link);
        } else if(link.pos.findInRange(spawnsAndExtensions, 3).length) {
            self.spawnLink = link;
        }
    });
    if(sourceLinks.length > 0) {
        this.sourceLinks = sourceLinks;
    }
};

Creep.prototype._moveTo = Creep.prototype.moveTo;

/**
 * [NOTE] Copied from https://github.com/bonzaiferroni/bonzAI/blob/master/src/prototypes/initPrototypes.ts
 * Forgive me for copy and use this function directly
 * General-purpose cpu-efficient movement function that uses ignoreCreeps: true, a high reusePath value and stuck-detection
 * @param destination
 * @param ops - pathfinding ops, ignoreCreeps and reusePath will be overwritten
 * @param dareDevil
 * @returns {number} - Error code
 */
Creep.prototype.moveTo = function(destination, ops, dareDevil = false) {

    if (this.spawning) {
        return 0;
    }

    if (this.fatigue > 0) {
        return ERR_TIRED;
    }

    if (!this.memory.position) {
        this.memory.position = this.pos;
    }

    if (!ops) {
        ops = {};
    }

    // check if trying to move last tick
    let movingLastTick = true;
    if (!this.memory.lastTickMoving) this.memory.lastTickMoving = 0;
    if (Game.time - this.memory.lastTickMoving > 1) {
        movingLastTick = false;
    }
    this.memory.lastTickMoving = Game.time;

    // check if stuck
    let stuck = this.pos.inRangeTo(this.memory.position.x, this.memory.position.y, 0);
    this.memory.position = this.pos;
    if (stuck && movingLastTick) {
        if (!this.memory.stuckCount) this.memory.stuckCount = 0;
        this.memory.stuckCount++;
        if (dareDevil && this.memory.stuckCount > 0) {
            this.memory.detourTicks = 5;
        }
        else if (this.memory.stuckCount >= 2) {
            this.memory.detourTicks = 5;
            // this.say("excuse me", true);
        }
        if (this.memory.stuckCount > 500 && !this.memory.stuckNoted) {
            console.log(this.name, "is stuck at", this.pos, "stuckCount:", this.memory.stuckCount);
            this.memory.stuckNoted = true;
        }
    }
    else {
        this.memory.stuckCount = 0;
    }

    if (this.memory.detourTicks > 0) {
        this.memory.detourTicks--;
        if (dareDevil) {
            ops.reusePath = 0;
        }
        else {
            ops.reusePath = 5;
        }
        return this._moveTo(destination, ops);
    }
    else {
        ops.reusePath = 50;
        ops.ignoreCreeps = true;
        return this._moveTo(destination, ops);
    }
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var fs = require("fs");
var path = require("path");
var through2       = require('through2');
var md5 = require('md5');
var JSONStore = require('./json-store');
var util = require('gulp-util');
var PluginError = util.PluginError;
// local version store
var db = JSONStore(process.cwd() + '/gulp-assets-version-replace-version.json');
// replace list
var reList = [];

var PLUGIN_NAME = 'gulp-assets-version-replace';

function scanTsFiles(replaceTemplateList, thisVersionsAmount) {
  return through2.obj(function(file, enc, cb) {
    if (file.isNull()) {
      return cb(null, file);
    }
    if (file.isStream()) {
      return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
    }

    // TODO: when gulp released 4, use `file.basename` instead of get basename by path
    var basename = path.basename(file.path);
    // TODO: when gulp released 4, use `file.stem` instead of replace file.relative append with extname
    var extname = path.extname(file.path);

    var fileVersions = db.get(basename);
    var thisVersion = md5(file.contents);
    var oldVersion;

    // Check file changed or not
    var fileChanged = false;

    // Alwways replace '__placeholder__' when thisVersionsAmount is 0
    if(thisVersionsAmount == 0
      // First time version
     || !fileVersions || fileVersions.length == 0) {
      oldVersion = '__placeholder__';
      fileVersions = [thisVersion];
      fileChanged = true;
    }
    else {
      // Use the last key to comparison as only the last version is using in template
      oldVersion = fileVersions[fileVersions.length - 1];
      if(oldVersion != thisVersion) {
        fileVersions.push(thisVersion);
        // Amount limit
        if(fileVersions.length > thisVersionsAmount) {
          fileVersions = fileVersions.slice(fileVersions.length - thisVersionsAmount, fileVersions.length)
        }
        fileChanged = true;
      }
    }

    db.set(basename, fileVersions)

    // Only pass modified files
    if(fileChanged) {
      var oldPath = basename.replace(extname, '.' + oldVersion + extname);
      var newRelativePath = basename.replace(extname, '.' + thisVersion + extname);
      reList.push({
        fileBasename: basename,
        oldPath: oldPath,
        newRelativePath: newRelativePath
      })
      // Output versioned file name
      var newPath = file.path.replace(extname, '.' + thisVersion + extname);
      file.path = newPath;
      this.push(file);
    }
    cb();

  }, function(cb) {
    // Keep to json file when limit is not 0
    // TODO: deal with saved bofore when limit is not 0, they can't be wiped now!
    if(thisVersionsAmount != 0) {
      // async save, and save only once
      db.save();
    }

    // Can only start after scaned ts files and finished collecting relist
    // Templates are always relative path of gulpfile.js
    if(replaceTemplateList && replaceTemplateList.length) {
      gulp.src(replaceTemplateList, { base: "./" })
        .pipe(replaceTemplate())
        .pipe(gulp.dest('.'));
    }

    cb();
  })
}

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function countOcurrences(str, value) {
  var regExp = new RegExp(value, "g");
  return (str.match(regExp) || []).length;
}

function replaceTemplate() {
  return through2.obj(function(file, enc, cb) {
    var content = file.contents.toString();
    for (var i = reList.length - 1; i >= 0; i--) {
      var reItem = reList[i];
      var count = countOcurrences(content, escapeRegExp(reItem.oldPath));
      if(count > 0) {
        util.log('Replaced ' + util.colors.magenta(count) + ' version string of ' + util.colors.gray(reItem.fileBasename) + ' in ' + file.relative + ':')
      }
      content = content.replace(reItem.oldPath, reItem.newRelativePath)
    }
    file.contents = new Buffer(content);
    cb(null, file)
  })
}

module.exports = function (options) {
  var replaceTemplateList = options.replaceTemplateList;
  // default amount of versions is 1
  var versionsAmount = options.versionsAmount;
  if(typeof versionsAmount === 'undefined')
    versionsAmount = 1;
  return scanTsFiles(replaceTemplateList, versionsAmount)
}<commit_msg>More readable log<commit_after>var gulp = require('gulp');
var fs = require("fs");
var path = require("path");
var through2       = require('through2');
var md5 = require('md5');
var JSONStore = require('./json-store');
var util = require('gulp-util');
var PluginError = util.PluginError;
// local version store
var db = JSONStore(process.cwd() + '/gulp-assets-version-replace-version.json');
// replace list
var reList = [];

var PLUGIN_NAME = 'gulp-assets-version-replace';

function scanTsFiles(replaceTemplateList, thisVersionsAmount) {
  return through2.obj(function(file, enc, cb) {
    if (file.isNull()) {
      return cb(null, file);
    }
    if (file.isStream()) {
      return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
    }

    // TODO: when gulp released 4, use `file.basename` instead of get basename by path
    var basename = path.basename(file.path);
    // TODO: when gulp released 4, use `file.stem` instead of replace file.relative append with extname
    var extname = path.extname(file.path);

    var fileVersions = db.get(basename);
    var thisVersion = md5(file.contents);
    var oldVersion;

    // Check file changed or not
    var fileChanged = false;

    // Alwways replace '__placeholder__' when thisVersionsAmount is 0
    if(thisVersionsAmount == 0
      // First time version
     || !fileVersions || fileVersions.length == 0) {
      oldVersion = '__placeholder__';
      fileVersions = [thisVersion];
      fileChanged = true;
    }
    else {
      // Use the last key to comparison as only the last version is using in template
      oldVersion = fileVersions[fileVersions.length - 1];
      if(oldVersion != thisVersion) {
        fileVersions.push(thisVersion);
        // Amount limit
        if(fileVersions.length > thisVersionsAmount) {
          fileVersions = fileVersions.slice(fileVersions.length - thisVersionsAmount, fileVersions.length)
        }
        fileChanged = true;
      }
    }

    db.set(basename, fileVersions)

    // Only pass modified files
    if(fileChanged) {
      var oldPath = basename.replace(extname, '.' + oldVersion + extname);
      var newRelativePath = basename.replace(extname, '.' + thisVersion + extname);
      reList.push({
        fileBasename: basename,
        oldPath: oldPath,
        newRelativePath: newRelativePath
      })
      // Output versioned file name
      var newPath = file.path.replace(extname, '.' + thisVersion + extname);
      file.path = newPath;
      this.push(file);
    }
    cb();

  }, function(cb) {
    // Keep to json file when limit is not 0
    // TODO: deal with saved bofore when limit is not 0, they can't be wiped now!
    if(thisVersionsAmount != 0) {
      // async save, and save only once
      db.save();
    }

    // Can only start after scaned ts files and finished collecting relist
    // Templates are always relative path of gulpfile.js
    if(replaceTemplateList && replaceTemplateList.length) {
      gulp.src(replaceTemplateList, { base: "./" })
        .pipe(replaceTemplate())
        .pipe(gulp.dest('.'));
    }

    cb();
  })
}

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
function countOcurrences(str, value) {
  var regExp = new RegExp(value, "g");
  return (str.match(regExp) || []).length;
}

function replaceTemplate() {
  return through2.obj(function(file, enc, cb) {
    var content = file.contents.toString();
    for (var i = reList.length - 1; i >= 0; i--) {
      var reItem = reList[i];
      var count = countOcurrences(content, escapeRegExp(reItem.oldPath));
      if(count > 0) {
        util.log(util.colors.cyan(PLUGIN_NAME), 'Replaced version(s) of ' + util.colors.magenta(reItem.fileBasename) + ' in ', util.colors.gray(file.relative))
      }
      content = content.replace(reItem.oldPath, reItem.newRelativePath)
    }
    file.contents = new Buffer(content);
    cb(null, file)
  })
}

module.exports = function (options) {
  var replaceTemplateList = options.replaceTemplateList;
  // default amount of versions is 1
  var versionsAmount = options.versionsAmount;
  if(typeof versionsAmount === 'undefined')
    versionsAmount = 1;
  return scanTsFiles(replaceTemplateList, versionsAmount)
}<|endoftext|>


<commit_before>import pagination from './pagination';

const RMP_URL = `https://www.ratemyprofessors.com/search.jsp?queryoption=HEADER&
queryBy=teacherName&schoolName=Portland+State+University&schoolID=&query={name}`;

let tableBody = document.querySelector('.datadisplaytable tbody');

function getTeacherNames () {
  let teacherNameList = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4) td:nth-child(18)'));

  return teacherNameList.map(name => {
    let isPrimaryTeacherIndex;
    let teacherName = name.innerText;
    isPrimaryTeacherIndex = teacherName.indexOf('(');
    if (isPrimaryTeacherIndex > -1) {
      return teacherName.slice(0, isPrimaryTeacherIndex - 1);
    }
    return teacherName;
  });
}

function updateHeaderColumn() {
  let rateMyProfessorColumn = document.createElement('th');
  let ratingText = document.createTextNode('Rate My Professor');
  rateMyProfessorColumn.appendChild(ratingText);
  rateMyProfessorColumn.classList.add('ddheader');
  let headers = tableBody.querySelector('tr:nth-child(3)');
  let teacherColumn = headers.querySelector('th:nth-child(20)');
  headers.insertBefore(rateMyProfessorColumn, teacherColumn);
}

function updateContentColumns() {
  let contentRows = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4)'));
  contentRows.forEach(row => {
    let column = document.createElement('td');
    column.setAttribute('style', 'font-size: .75em');
    column.classList.add('dddefault');
    let quality = insertIntoDiv(document.createTextNode('Quality: 4.0'));
    let difficulty = insertIntoDiv(document.createTextNode('Difficulty: 3.3'));
    let link = document.createElement('a');
    link.setAttribute('href', 'www.google.com');
    link.appendChild(document.createTextNode('More info...'));
    link = insertIntoDiv(link);
    addChildren(column, quality, difficulty, link);
    row.insertBefore(column, row.querySelector('td:nth-child(19)'));
  });
}

function insertIntoDiv(element) {
  let div = document.createElement('div');
  div.appendChild(element);
  return div;
}

function addChildren(parent, ...children) {
  children.forEach(child => {
    parent.appendChild(child);
  });
}
updateHeaderColumn();
updateContentColumns();
let name = 'Karla+Fant';
let prof = RMP_URL.replace('{name}', name);
console.log('PING');
pagination(prof, 0, 2).then(results => {
  results.forEach((body, index) => {
    console.log('&&&&&&&&&&&&&&&');
    console.log(index);
    console.log(body)
  })
}, error => {
  console.error('oops! There was an error: ' + error);
});<commit_msg>add pagination smoke tests<commit_after>import pagination from './pagination';

const RMP_URL = `https://www.ratemyprofessors.com/search.jsp?queryoption=HEADER&
queryBy=teacherName&schoolName=Portland+State+University&schoolID=&query={name}`;

let tableBody = document.querySelector('.datadisplaytable tbody');

function getTeacherNames () {
  let teacherNameList = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4) td:nth-child(18)'));

  return teacherNameList.map(name => {
    let isPrimaryTeacherIndex;
    let teacherName = name.innerText;
    isPrimaryTeacherIndex = teacherName.indexOf('(');
    if (isPrimaryTeacherIndex > -1) {
      return teacherName.slice(0, isPrimaryTeacherIndex - 1);
    }
    return teacherName;
  });
}

function updateHeaderColumn() {
  let rateMyProfessorColumn = document.createElement('th');
  let ratingText = document.createTextNode('Rate My Professor');
  rateMyProfessorColumn.appendChild(ratingText);
  rateMyProfessorColumn.classList.add('ddheader');
  let headers = tableBody.querySelector('tr:nth-child(3)');
  let teacherColumn = headers.querySelector('th:nth-child(20)');
  headers.insertBefore(rateMyProfessorColumn, teacherColumn);
}

function updateContentColumns() {
  let contentRows = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4)'));
  contentRows.forEach(row => {
    let column = document.createElement('td');
    column.setAttribute('style', 'font-size: .75em');
    column.classList.add('dddefault');
    let quality = insertIntoDiv(document.createTextNode('Quality: 4.0'));
    let difficulty = insertIntoDiv(document.createTextNode('Difficulty: 3.3'));
    let link = document.createElement('a');
    link.setAttribute('href', 'www.google.com');
    link.appendChild(document.createTextNode('More info...'));
    link = insertIntoDiv(link);
    addChildren(column, quality, difficulty, link);
    row.insertBefore(column, row.querySelector('td:nth-child(19)'));
  });
}

function insertIntoDiv(element) {
  let div = document.createElement('div');
  div.appendChild(element);
  return div;
}

function addChildren(parent, ...children) {
  children.forEach(child => {
    parent.appendChild(child);
  });
}
updateHeaderColumn();
updateContentColumns();
let name = 'Karla+Fant';
let prof = RMP_URL.replace('{name}', name);
pagination(prof).then(results => {
  results.forEach((body, index) => {
    console.log('&&&&&&&&&&&&&&&');
    console.log(index);
    console.log(body)
  })
}, error => {
  console.error('oops! There was an error: ' + error);
});<|endoftext|>


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

/* globals require, process */

'use strict';

const
    _ = require('lodash'),
    exec = require('child_process').exec,
    program = require('commander'),
    NO_COMMIT_MEANT = 'No commit-meant found.',
    messageRe = /^(MAJOR|MINOR|PATCH) - ([A-Z].+)\n\n((?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?)\n\n((?:[^\*+-].+(?:\n\n)*)*)((?:[\*]\s.+\n*)*)/g,
    noteRe = /[\*+-]\s/g,
    LOG_SEPARATOR = 'GJVX47gWz4@7m&*uYX%5qe24';

function message2cm(msg) {
    let json = msg
        .replace(messageRe, '{ "changeType": "$1", "title": "$2", "issue": "$3", "description": "$4", "notes": "$5" }')
        .replace(/\n/g, ''),
        cm;

    try {
        cm = JSON.parse(json);
        cm.changeType = cm.changeType.toLowerCase();
        cm.notes = _.filter(_.map(cm.notes.trim().split(noteRe), note => note.trim()), note => note);

        return cm;
    } catch (e) {
        return null;
    }
}

program
    .version('0.1.0')
    .usage('[options] [branchName]')
    .option('-t, --tip', 'only check the tip of the branch for a commit-meant')
    .option('-f, --field <name>', 'output the value of the commit-meant field with the specified name')
    .parse(process.argv);

function output(cm, dontExit) {
    if (!cm) {
        console.log(NO_COMMIT_MEANT);
    } else if (program.field) {
        console.log(cm[program.field]);
    } else {
        console.log(cm);
    }

    if (!dontExit) {
        process.exit(cm ? 0 : 1);
    }
}

let branch = program.args.length === 0 ? 'HEAD' : program.args[0];

exec(`git log master..${branch} --pretty=format:\'${LOG_SEPARATOR}%B\'`, (error, stdout) => {
    let cms = _.map(_.drop(stdout.split(LOG_SEPARATOR)), message2cm);

    if (program.tip) {
        output(cms.length === 0 ? null : cms[0]);
    } else {
        output(_.find(cms, cm => cm));
    }
});
<commit_msg>improve destination branch handling<commit_after>#! /usr/bin/env node

/* globals require, process */

'use strict';

const
    _ = require('lodash'),
    exec = require('child_process').exec,
    program = require('commander'),
    NO_COMMIT_MEANT = 'No commit-meant found.',
    messageRe = /^(MAJOR|MINOR|PATCH) - ([A-Z].+)\n\n((?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?)\n\n((?:[^\*+-].+(?:\n\n)*)*)((?:[\*]\s.+\n*)*)/g,
    noteRe = /[\*+-]\s/g,
    LOG_SEPARATOR = 'GJVX47gWz4@7m&*uYX%5qe24';

function message2cm(msg) {
    let json = msg
        .replace(messageRe, '{ "changeType": "$1", "title": "$2", "issue": "$3", "description": "$4", "notes": "$5" }')
        .replace(/\n/g, ''),
        cm;

    try {
        cm = JSON.parse(json);
        cm.changeType = cm.changeType.toLowerCase();
        cm.notes = _.filter(_.map(cm.notes.trim().split(noteRe), note => note.trim()), note => note);

        return cm;
    } catch (e) {
        return null;
    }
}

program
    .version('0.1.0')
    .usage('[options] [branchName]')
    .option('-d, --destination', 'the destination branch for merges, "origin/master" by default')
    .option('-t, --tip', 'only check the tip of the branch for a commit-meant')
    .option('-f, --field <name>', 'output the value of the commit-meant field with the specified name')
    .parse(process.argv);

function output(cm, dontExit) {
    if (!cm) {
        console.log(NO_COMMIT_MEANT);
    } else if (program.field) {
        console.log(cm[program.field]);
    } else {
        console.log(cm);
    }

    if (!dontExit) {
        process.exit(cm ? 0 : 1);
    }
}

let destination = program.destination || 'origin/master',
    branch = program.args.length === 0 ? 'HEAD' : program.args[0];

exec(`git log ${destination}..${branch} --pretty=format:\'${LOG_SEPARATOR}%B\'`, (error, stdout) => {
    let cms = _.map(_.drop(stdout.split(LOG_SEPARATOR)), message2cm);

    if (program.tip) {
        output(cms.length === 0 ? null : cms[0]);
    } else {
        output(_.find(cms, cm => cm));
    }
});
<|endoftext|>


<commit_before>import { getProfessorLink, getProfessorInfo } from './pagination';

function parseFirstAndLast (name) {
  name = name.split(' ');
  // Remove the (P) tag from the name
  let isPrimaryTeacherIndex = name.indexOf('(P)');
  if (isPrimaryTeacherIndex > -1) {
    name.pop();
  }
  // Returns only the first and last name - excluding the middle (if it
  // exists)
  return [name.shift(), name.pop()]
}

function updateHeaderColumns (tableBody) {
  let rateMyProfessorColumn = document.createElement('th');
  let tableHeaders = tableBody.querySelector('tr:nth-child(3)');
  let teacherColumn = tableHeaders.querySelector('th:nth-child(20)');
  rateMyProfessorColumn.appendChild(document.createTextNode('Rate My Professor'));
  rateMyProfessorColumn.classList.add('ddheader');
  tableHeaders.insertBefore(rateMyProfessorColumn, teacherColumn);
}

function populateRateMyProfessorCell (info, row) {
  let contentCell = document.createElement('td');
  contentCell.setAttribute('style', 'font-size: .75em');
  contentCell.classList.add('dddefault');
  if (!info) {
    let noInfo = insertIntoDiv(document.createTextNode('N/A'));
    contentCell = addChildren(contentCell, noInfo);
  } else {
    let quality = insertIntoDiv(document.createTextNode(`Quality: ${info.quality}`));
    let easiness = insertIntoDiv(document.createTextNode(`Easiness: ${info.easiness}`));
    let link = document.createElement('a');
    link.setAttribute('href', info.url);
    link.setAttribute('target', '_blank');
    link.appendChild(document.createTextNode('More info...'));
    link = insertIntoDiv(link);
    contentCell = addChildren(contentCell, quality, easiness, link);
  }
  row.insertBefore(contentCell, row.querySelector('td:nth-child(19)'));
}

function updateContentColumns (tableBody) {
  let contentRows = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4)'));

  contentRows.forEach(row => {
    let [first, last] = parseFirstAndLast(row.querySelector('td:nth-child(18)').innerText);
    let url = `http://www.ratemyprofessors.com/search.jsp?query=portland+state+university+${first}+${last}`;
    getProfessorLink(url).then(link => {
      return getProfessorInfo(link);
    }).then(info => {
      populateRateMyProfessorCell(info, row);
    });
  });
}

function insertIntoDiv (element) {
  let div = document.createElement('div');
  div.appendChild(element);
  return div;
}

function addChildren (parent, ...children) {
  children.forEach(child => {
    parent.appendChild(child);
  });
  return parent;
}

function onInit () {
  let table = document.querySelector('.datadisplaytable');
  if (table.getAttribute('summary').includes('sections')){
    let tableBody = table.querySelector('tbody');
    updateHeaderColumns(tableBody);
    updateContentColumns(tableBody);
  }

}

// fires when script is first loaded
// can't do onInit directly here, because the DOM hasn't been loaded yet
// we just set an event listener for document.DOMContentLoaded
document.addEventListener('DOMContentLoaded', onInit(), false);

<commit_msg>move main listener to the top page<commit_after>import { getProfessorLink, getProfessorInfo } from './pagination';

document.addEventListener('DOMContentLoaded', onInit(), false);

function parseFirstAndLast (name) {
  name = name.split(' ');
  // Remove the (P) tag from the name
  let isPrimaryTeacherIndex = name.indexOf('(P)');
  if (isPrimaryTeacherIndex > -1) {
    name.pop();
  }
  // Returns only the first and last name - excluding the middle (if it
  // exists)
  return [name.shift(), name.pop()]
}

function updateHeaderColumns (tableBody) {
  let rateMyProfessorColumn = document.createElement('th');
  let tableHeaders = tableBody.querySelector('tr:nth-child(3)');
  let teacherColumn = tableHeaders.querySelector('th:nth-child(20)');
  rateMyProfessorColumn.appendChild(document.createTextNode('Rate My Professor'));
  rateMyProfessorColumn.classList.add('ddheader');
  tableHeaders.insertBefore(rateMyProfessorColumn, teacherColumn);
}

function populateRateMyProfessorCell (info, row) {
  let contentCell = document.createElement('td');
  contentCell.setAttribute('style', 'font-size: .75em');
  contentCell.classList.add('dddefault');
  if (!info) {
    let noInfo = insertIntoDiv(document.createTextNode('N/A'));
    contentCell = addChildren(contentCell, noInfo);
  } else {
    let quality = insertIntoDiv(document.createTextNode(`Quality: ${info.quality}`));
    let easiness = insertIntoDiv(document.createTextNode(`Easiness: ${info.easiness}`));
    let link = document.createElement('a');
    link.setAttribute('href', info.url);
    link.setAttribute('target', '_blank');
    link.appendChild(document.createTextNode('More info...'));
    link = insertIntoDiv(link);
    contentCell = addChildren(contentCell, quality, easiness, link);
  }
  row.insertBefore(contentCell, row.querySelector('td:nth-child(19)'));
}

function updateContentColumns (tableBody) {
  let contentRows = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4)'));

  contentRows.forEach(row => {
    let [first, last] = parseFirstAndLast(row.querySelector('td:nth-child(18)').innerText);
    let url = `http://www.ratemyprofessors.com/search.jsp?query=portland+state+university+${first}+${last}`;
    getProfessorLink(url).then(link => {
      return getProfessorInfo(link);
    }).then(info => {
      populateRateMyProfessorCell(info, row);
    });
  });
}

function insertIntoDiv (element) {
  let div = document.createElement('div');
  div.appendChild(element);
  return div;
}

function addChildren (parent, ...children) {
  children.forEach(child => {
    parent.appendChild(child);
  });
  return parent;
}

function onInit () {
  let table = document.querySelector('.datadisplaytable');
  if (table.getAttribute('summary').includes('sections')){
    let tableBody = table.querySelector('tbody');
    updateHeaderColumns(tableBody);
    updateContentColumns(tableBody);
  }

}

<|endoftext|>


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

'use strict';
var spawn   = require('child_process').spawn;
var split   = require('split');
var trim    = require('trim');
var colors  = require('colors/safe');
var readline = require('readline');
var isArray = require('is-array');
var NumstatParser  = require('./NumstatParser');

var filesChanged = {};
var insertions   = 0;
var deletions    = 0;
//for some reason the stream is getting one line without a commit
var countCommits = 0;

var argsToInject = process.argv.slice(2);

var args = [
  'log',
  '--format=%n==_END_COMMIT_MESSAGE_HOW_MUCH_CODE_MODULE_',
  '--numstat'
];

argsToInject = argsToInject.filter(function(value){

  if(value.match(/--format|--pretty/)){
    console.log( colors.red('WARNING:'), 'Can\'t change log format' );
    return false;
  }

  if(value == '--yesterday'){

    var after = new Date();
    after.setDate(after.getDate() - 1);
    after.setHours(0, 0, 0, 0);

    var before = new Date();
    before.setDate(before.getDate() - 1);
    before.setHours(23, 59, 59, 999);

    args = args.concat(['--after', after.toString(), '--before', before.toString()]);

    return false;

  }

  if(value == '--today'){

    var today = new Date();
    today.setDate(today.getDate() - 1);
    today.setHours(0, 0, 0, 0);

    args = args.concat(['--after', today.toString()]);

    return false;

  }

  if(value == '--week'){

    var now = new Date();
    now.setDate(now.getDate() - 1);
    now.setHours(0, 0, 0, 0);

    var weekFirstDay = new Date( now.setDate( now.getDate() - now.getDay() ) );
    weekFirstDay.setHours(0, 0, 0, 0);
    var weekLastDay = new Date( now.setDate( now.getDate() - now.getDay() + 6) );
    weekLastDay.setHours(23, 59, 59, 999);

    args = args.concat(['--after', weekFirstDay.toString(), '--before', weekLastDay.toString()]);

    return false;

  }

  if(value == '--month'){

    var now = new Date();
    now.setDate(now.getDate() - 1);
    now.setHours(0, 0, 0, 0);

    var now = new Date();
    var firstDay = new Date(now.getFullYear(), now.getMonth(), 1);
    firstDay.setHours(0, 0, 0, 0);
    var lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
    lastDay.setHours(23, 59, 59, 999);

    args = args.concat(['--after', firstDay.toString(), '--before', lastDay.toString()]);

    return false;

  }

  return true;

});

args = args.concat(argsToInject);

function log(msg){

  console.log( colors.cyan('INFO:'), msg );

}

function pluralSingulaFilter(singularMessage, pluralMessage, number){
  var message = pluralMessage;

  if(number <= 1){
    message = singularMessage;
  }

  return number +' '+message;
}

spawn('git', args).stdout
.pipe(split('==_END_COMMIT_MESSAGE_HOW_MUCH_CODE_MODULE_'))
.on('data', function (line) {

  if(line.length <= 1) return;

  //check if there's a numstat log in the commit
  var parser = line.toString().match(/((?:\d+|\-))\t((?:\d+|\-))\t(.+)/g);

  if(isArray(parser)){

    var data = new NumstatParser(line.toString());

    for (var i = 0; i < data.files.length; i++) {

      if(typeof filesChanged[data.files[i].file] == 'undefined'){
        filesChanged[data.files[i].file] = 0;
      }

      filesChanged[data.files[i].file] += 1;

      insertions += data.files[i].insertions;
      deletions += data.files[i].deletions;
    };

  }

  //some commits doesn't have files changed, insertions or deletations
  countCommits++;

  readline.clearLine(process.stdout, 0);
  readline.cursorTo(process.stdout, 0);
  process.stdout.write(pluralSingulaFilter('Commit', 'Commits', countCommits));

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

  readline.clearLine(process.stdout, 0);

  var filesChangedCount = 0;

  for (var fileChanged in  filesChanged) {
    filesChangedCount++;
  }

  console.log('\n'+colors.cyan('----------------------------'));
  log( pluralSingulaFilter('Commit', 'Commits', countCommits) );
  log( pluralSingulaFilter('File changed', 'Files changed', filesChangedCount) );
  log( pluralSingulaFilter('Insertion', 'Insertions', insertions) + colors.green('(+)') );
  log( pluralSingulaFilter('Deletion', 'Deletions', deletions) + colors.red('(-)') );
  console.log(colors.cyan('----------------------------'));

});<commit_msg>[Fix] --today option returns info about the current day and not last day<commit_after>#!/usr/bin/env node

'use strict';
var spawn   = require('child_process').spawn;
var split   = require('split');
var trim    = require('trim');
var colors  = require('colors/safe');
var readline = require('readline');
var isArray = require('is-array');
var NumstatParser  = require('./NumstatParser');

var filesChanged = {};
var insertions   = 0;
var deletions    = 0;
//for some reason the stream is getting one line without a commit
var countCommits = 0;

var argsToInject = process.argv.slice(2);

var args = [
  'log',
  '--format=%n==_END_COMMIT_MESSAGE_HOW_MUCH_CODE_MODULE_',
  '--numstat'
];

argsToInject = argsToInject.filter(function(value){

  if(value.match(/--format|--pretty/)){
    console.log( colors.red('WARNING:'), 'Can\'t change log format' );
    return false;
  }

  if(value == '--yesterday'){

    var after = new Date();
    after.setDate(after.getDate() - 1);
    after.setHours(0, 0, 0, 0);

    var before = new Date();
    before.setDate(before.getDate() - 1);
    before.setHours(23, 59, 59, 999);

    args = args.concat(['--after', after.toString(), '--before', before.toString()]);

    return false;

  }

  if(value == '--today'){

    var today = new Date();
    today.setHours(0, 0, 0, 0);

    args = args.concat(['--since', today.toString()]);

    return false;

  }

  if(value == '--week'){

    var now = new Date();
    now.setDate(now.getDate() - 1);
    now.setHours(0, 0, 0, 0);

    var weekFirstDay = new Date( now.setDate( now.getDate() - now.getDay() ) );
    weekFirstDay.setHours(0, 0, 0, 0);
    var weekLastDay = new Date( now.setDate( now.getDate() - now.getDay() + 6) );
    weekLastDay.setHours(23, 59, 59, 999);

    args = args.concat(['--after', weekFirstDay.toString(), '--before', weekLastDay.toString()]);

    return false;

  }

  if(value == '--month'){

    var now = new Date();
    now.setDate(now.getDate() - 1);
    now.setHours(0, 0, 0, 0);

    var now = new Date();
    var firstDay = new Date(now.getFullYear(), now.getMonth(), 1);
    firstDay.setHours(0, 0, 0, 0);
    var lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
    lastDay.setHours(23, 59, 59, 999);

    args = args.concat(['--after', firstDay.toString(), '--before', lastDay.toString()]);

    return false;

  }

  return true;

});

args = args.concat(argsToInject);

function log(msg){

  console.log( colors.cyan('INFO:'), msg );

}

function pluralSingulaFilter(singularMessage, pluralMessage, number){
  var message = pluralMessage;

  if(number <= 1){
    message = singularMessage;
  }

  return number +' '+message;
}

spawn('git', args).stdout
.pipe(split('==_END_COMMIT_MESSAGE_HOW_MUCH_CODE_MODULE_'))
.on('data', function (line) {

  if(line.length <= 1) return;

  //check if there's a numstat log in the commit
  var parser = line.toString().match(/((?:\d+|\-))\t((?:\d+|\-))\t(.+)/g);

  if(isArray(parser)){

    var data = new NumstatParser(line.toString());

    for (var i = 0; i < data.files.length; i++) {

      if(typeof filesChanged[data.files[i].file] == 'undefined'){
        filesChanged[data.files[i].file] = 0;
      }

      filesChanged[data.files[i].file] += 1;

      insertions += data.files[i].insertions;
      deletions += data.files[i].deletions;
    };

  }

  //some commits doesn't have files changed, insertions or deletations
  countCommits++;

  readline.clearLine(process.stdout, 0);
  readline.cursorTo(process.stdout, 0);
  process.stdout.write(pluralSingulaFilter('Commit', 'Commits', countCommits));

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

  readline.clearLine(process.stdout, 0);

  var filesChangedCount = 0;

  for (var fileChanged in  filesChanged) {
    filesChangedCount++;
  }

  console.log('\n'+colors.cyan('----------------------------'));
  log( pluralSingulaFilter('Commit', 'Commits', countCommits) );
  log( pluralSingulaFilter('File changed', 'Files changed', filesChangedCount) );
  log( pluralSingulaFilter('Insertion', 'Insertions', insertions) + colors.green('(+)') );
  log( pluralSingulaFilter('Deletion', 'Deletions', deletions) + colors.red('(-)') );
  console.log(colors.cyan('----------------------------'));

});<|endoftext|>


<commit_before>const debug = require('debug')('screeps-webpack-plugin')
const path = require('path')
const fs = require('fs')

const ScreepsModules = require('screeps-modules')

// Events.
const COLLECT_MODULES = 'screeps-webpack-plugin-collect-modules'
const CONFIG_CLIENT = 'screeps-webpack-plugin-configure-client'
const BEFORE_COMMIT = 'screeps-webpack-plugin-before-commit'
const AFTER_COMMIT = 'screeps-webpack-plugin-after-commit'

class ScreepsWebpackPluginError extends Error {
  constructor (msg) {
    super(msg)
    this.name = 'ScreepsWebpackPluginError'
  }
}

class ScreepsWebpackPlugin {
  constructor (options = {}) {
    this.options = options
  }

  apply (compiler) {
    compiler.plugin('compilation', (compilation) => {
      if (compiler.options.target !== 'node') {
        const err = new ScreepsWebpackPluginError(`Can only support Node.js {target: 'node'}`)

        return compilation.errors.push(err)
      }

      this.registerHandlers(compilation)
    })

    compiler.plugin('after-emit', (compilation, cb) => {
      Promise.resolve()
        .then(() => {
          return new Promise((resolve, reject) => {
            const initial = {
              modules: {},
              plugin: this,
              compilation
            }

            compilation.applyPluginsAsyncWaterfall(COLLECT_MODULES, initial, (err, {modules}) => {
              if (err) {
                debug('Error while collecting modules', err.stack)

                return reject(err)
              } else {
                resolve(modules)
              }
            })
          })
        })
      .then((modules) => {
        const client = compilation.applyPluginsWaterfall(CONFIG_CLIENT, null, this)
        const {branch} = this.options

        compilation.applyPlugins(BEFORE_COMMIT, branch, modules)

        return client.commit(branch, modules)
          .then((body) => {
            compilation.applyPlugins(AFTER_COMMIT, body)
          })
          .catch((body) => {
            throw new Error(body)
          })
      })
      .then(cb)
      .catch((err) => {
        compilation.errors.push(new ScreepsWebpackPluginError(err.stack))

        cb()
      })
    })
  }

  registerHandlers (compilation) {
    compilation.plugin(COLLECT_MODULES, this.collectModules)
    compilation.plugin(CONFIG_CLIENT, this.configureClient)
  }

  collectModules ({modules: initial, plugin, compilation}, cb) {
    const chunks = compilation.getStats().toJson().chunks
    const outputPath = compilation.options.output.path
    const files = []

    for (const chunk of chunks) {
      for (const file of chunk.files) {
        files.push(path.resolve(outputPath, file))
      }
    }

    const outputFileSystem = (
      compilation.compiler.outputFileSystem.readFile
      ? compilation.compiler.outputFileSystem
      : fs
    )
    const promises = []

    for (const file of files) {
      promises.push(new Promise((resolve, reject) => {
        outputFileSystem.readFile(file, 'utf-8', (err, data) => {
          if (err) {
            return reject(err)
          }

          const moduleName = path.parse(file).name

          resolve({[moduleName]: data})
        })
      }))
    }

    Promise.all(promises)
      .then((files) => {
        const modules = files.reduce((modules, file) => {
          Object.assign(modules, file)

          return modules
        }, initial || {})

        cb(null, {modules, plugin, compilation})
      })
      .catch(cb)
  }

  configureClient (initial, plugin) {
    return new ScreepsModules(plugin.options)
  }
}

Object.assign(ScreepsWebpackPlugin, {
  COLLECT_MODULES,
  CONFIG_CLIENT,
  BEFORE_COMMIT,
  AFTER_COMMIT
})

module.exports = ScreepsWebpackPlugin
<commit_msg>Only ignore ext if file is .js file<commit_after>const debug = require('debug')('screeps-webpack-plugin')
const path = require('path')
const fs = require('fs')

const ScreepsModules = require('screeps-modules')

// Events.
const COLLECT_MODULES = 'screeps-webpack-plugin-collect-modules'
const CONFIG_CLIENT = 'screeps-webpack-plugin-configure-client'
const BEFORE_COMMIT = 'screeps-webpack-plugin-before-commit'
const AFTER_COMMIT = 'screeps-webpack-plugin-after-commit'

class ScreepsWebpackPluginError extends Error {
  constructor (msg) {
    super(msg)
    this.name = 'ScreepsWebpackPluginError'
  }
}

class ScreepsWebpackPlugin {
  constructor (options = {}) {
    this.options = options
  }

  apply (compiler) {
    compiler.plugin('compilation', (compilation) => {
      if (compiler.options.target !== 'node') {
        const err = new ScreepsWebpackPluginError(`Can only support Node.js {target: 'node'}`)

        return compilation.errors.push(err)
      }

      this.registerHandlers(compilation)
    })

    compiler.plugin('after-emit', (compilation, cb) => {
      Promise.resolve()
        .then(() => {
          return new Promise((resolve, reject) => {
            const initial = {
              modules: {},
              plugin: this,
              compilation
            }

            compilation.applyPluginsAsyncWaterfall(COLLECT_MODULES, initial, (err, {modules}) => {
              if (err) {
                debug('Error while collecting modules', err.stack)

                return reject(err)
              } else {
                resolve(modules)
              }
            })
          })
        })
      .then((modules) => {
        const client = compilation.applyPluginsWaterfall(CONFIG_CLIENT, null, this)
        const {branch} = this.options

        compilation.applyPlugins(BEFORE_COMMIT, branch, modules)

        return client.commit(branch, modules)
          .then((body) => {
            compilation.applyPlugins(AFTER_COMMIT, body)
          })
          .catch((body) => {
            throw new Error(body)
          })
      })
      .then(cb)
      .catch((err) => {
        compilation.errors.push(new ScreepsWebpackPluginError(err.stack))

        cb()
      })
    })
  }

  registerHandlers (compilation) {
    compilation.plugin(COLLECT_MODULES, this.collectModules)
    compilation.plugin(CONFIG_CLIENT, this.configureClient)
  }

  collectModules ({modules: initial, plugin, compilation}, cb) {
    const chunks = compilation.getStats().toJson().chunks
    const outputPath = compilation.options.output.path
    const files = []

    for (const chunk of chunks) {
      for (const file of chunk.files) {
        files.push(path.resolve(outputPath, file))
      }
    }

    const outputFileSystem = (
      compilation.compiler.outputFileSystem.readFile
      ? compilation.compiler.outputFileSystem
      : fs
    )
    const promises = []

    for (const file of files) {
      promises.push(new Promise((resolve, reject) => {
        outputFileSystem.readFile(file, 'utf-8', (err, data) => {
          if (err) {
            return reject(err)
          }

          const moduleName = path.basename(file, '.js')

          resolve({[moduleName]: data})
        })
      }))
    }

    Promise.all(promises)
      .then((files) => {
        const modules = files.reduce((modules, file) => {
          Object.assign(modules, file)

          return modules
        }, initial || {})

        cb(null, {modules, plugin, compilation})
      })
      .catch(cb)
  }

  configureClient (initial, plugin) {
    return new ScreepsModules(plugin.options)
  }
}

Object.assign(ScreepsWebpackPlugin, {
  COLLECT_MODULES,
  CONFIG_CLIENT,
  BEFORE_COMMIT,
  AFTER_COMMIT
})

module.exports = ScreepsWebpackPlugin
<|endoftext|>


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

const Github = require('github');
const eslint = require('eslint');
const exec = require('child-process-promise').exec;

const cli = new eslint.CLIEngine();

// Runs eslint on the array of file pathes and returns the lint results
const runEslint = files => cli.executeOnFiles(cli.resolveFileGlobPatterns(files));

// Get a promise of an array of the paths of *.js files that changed in the commit/PR
const getChangedFilePaths = () => exec(`git diff --name-only ${process.env.TRAVIS_COMMIT_RANGE} -- '*.js'`)
  .then((result) => {
    const files = result.stdout.split('\n');
    // Remove the extra "" caused by the last newline
    files.pop();
    return files;
  });

// Gets the sha of the commit/pull request
const getCommitTarget = (eventType) => {
  let sha;
  if (eventType === 'push') {
    sha = process.env.TRAVIS_COMMIT;
  } else if (eventType === 'pull_request') {
    const travisCommitRange = process.env.TRAVIS_COMMIT_RANGE;
    const parsed = travisCommitRange.split('...');
    if (parsed.length === 1) {
      sha = travisCommitRange;
    } else {
      sha = parsed[1];
    }
  } else {
    console.error('event type \'%s\' not supported', eventType);
    sha = null;
  }

  return sha;
};

// Add status with lint info to GitHub UI
const setGithubStatus = (eslintReport) => {
  const errors = eslintReport.errorCount;
  const gh = new Github();
  const parsedSlug = process.env.TRAVIS_REPO_SLUG.split('/');
  const sha = getCommitTarget(process.env.TRAVIS_EVENT_TYPE);
  const state = eslintReport.errorCount > 0 ? 'failure' : 'success';
  const warnings = eslintReport.warningCount;

  const description = `errors: ${errors} warnings: ${warnings}`;
  const repo = parsedSlug[1];
  const user = parsedSlug[0];
  const targetUrl = `https://travis-ci.com/${process.env.TRAVIS_REPO_SLUG}/jobs/${process.env.TRAVIS_JOB_ID}`;

  gh.authenticate({
    token: process.env.GITHUB_TOKEN,
    type: 'oauth',
  }, (err) => {
    if (err) console.error('Error authenticating GitHub', err);
  });

  gh.repos.createStatus({
    context: 'ESLint Changes',
    owner: user,
    target_url: targetUrl,
    description,
    repo,
    sha,
    state,
  }, (err) => {
    if (err) console.error('Error creating GitHub status', err);
  });
};

const logEslintResults = (eslintReport) => {
  const formatter = cli.getFormatter();
  console.log(formatter(eslintReport.results));
};

getChangedFilePaths()
  .then((files) => {
    const eslintReport = runEslint(files);
    setGithubStatus(eslintReport);
    logEslintResults(eslintReport);
  })
  .catch(err => console.error('Error: ', err));
<commit_msg>Added strict mode<commit_after>#!/usr/bin/env node
'use strict';

const Github = require('github');
const eslint = require('eslint');
const exec = require('child-process-promise').exec;

const cli = new eslint.CLIEngine();

// Runs eslint on the array of file pathes and returns the lint results
const runEslint = files => cli.executeOnFiles(cli.resolveFileGlobPatterns(files));

// Get a promise of an array of the paths of *.js files that changed in the commit/PR
const getChangedFilePaths = () => exec(`git diff --name-only ${process.env.TRAVIS_COMMIT_RANGE} -- '*.js'`)
  .then((result) => {
    const files = result.stdout.split('\n');
    // Remove the extra "" caused by the last newline
    files.pop();
    return files;
  });

// Gets the sha of the commit/pull request
const getCommitTarget = (eventType) => {
  let sha;
  if (eventType === 'push') {
    sha = process.env.TRAVIS_COMMIT;
  } else if (eventType === 'pull_request') {
    const travisCommitRange = process.env.TRAVIS_COMMIT_RANGE;
    const parsed = travisCommitRange.split('...');
    if (parsed.length === 1) {
      sha = travisCommitRange;
    } else {
      sha = parsed[1];
    }
  } else {
    console.error('event type \'%s\' not supported', eventType);
    sha = null;
  }

  return sha;
};

// Add status with lint info to GitHub UI
const setGithubStatus = (eslintReport) => {
  const errors = eslintReport.errorCount;
  const gh = new Github();
  const parsedSlug = process.env.TRAVIS_REPO_SLUG.split('/');
  const sha = getCommitTarget(process.env.TRAVIS_EVENT_TYPE);
  const state = eslintReport.errorCount > 0 ? 'failure' : 'success';
  const warnings = eslintReport.warningCount;

  const description = `errors: ${errors} warnings: ${warnings}`;
  const repo = parsedSlug[1];
  const user = parsedSlug[0];
  const targetUrl = `https://travis-ci.com/${process.env.TRAVIS_REPO_SLUG}/jobs/${process.env.TRAVIS_JOB_ID}`;

  gh.authenticate({
    token: process.env.GITHUB_TOKEN,
    type: 'oauth',
  }, (err) => {
    if (err) console.error('Error authenticating GitHub', err);
  });

  gh.repos.createStatus({
    context: 'ESLint Changes',
    owner: user,
    target_url: targetUrl,
    description,
    repo,
    sha,
    state,
  }, (err) => {
    if (err) console.error('Error creating GitHub status', err);
  });
};

const logEslintResults = (eslintReport) => {
  const formatter = cli.getFormatter();
  console.log(formatter(eslintReport.results));
};

getChangedFilePaths()
  .then((files) => {
    const eslintReport = runEslint(files);
    setGithubStatus(eslintReport);
    logEslintResults(eslintReport);
  })
  .catch(err => console.error('Error: ', err));
<|endoftext|>