<commit_before>var assert = require('assert');
var paxos  = require('./paxos');

// Algorithm adapted from: "PaxosLease: Diskless Paxos for Leases",
// by Trencseni, Gazso, Reinhardt.
//
exports.lease_acquirer = function(lease_timeout, // In milliseconds.
                                  node_name, node_restarts,
                                  acceptors, comm, opts) {
  var timer = null;
  var is_owner = false; // Tri-state: true, false, 'timeout'.
  var lease_owner = null;

  opts = opts || {};
  opts.msg_preprocess = function(src, msg) {
    if (msg.kind == paxos.RES_PROPOSED) {
      if (msg.accepted_ballot != null ||
          msg.accepted_val != null) {
        msg.kind = paxos.RES_NACK;
      }
    }
    return msg;
  };
  opts.on_phase_complete = function(kind, err) {
    if (kind == paxos.RES_PROPOSED && !err) {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(function() {
                           is_owner = 'timeout';
                           lease_owner = null;
                         },
                         lease_timeout);
    }
  };
  opts.proposer_timeout = opts.proposer_timeout || opts.acquirer_timeout;

  var proposer = paxos.proposer(node_name, node_restarts,
                                0, acceptors, comm, opts);

  var acquirer = {};

  acquirer.acquire = function(cb) {
    var val = { "lease_owner"   : node_name,
                "lease_timeout" : lease_timeout };
    return proposer.propose(val,
                            function(err, info) {
                              is_owner = false;
                              lease_owner = null;
                              if (!err) {
                                is_owner = true;
                                if (info &&
                                    info.accepted_val) {
                                  lease_owner = info.accepted_val.lease_owner;
                                }
                                assert(lease_owner == node_name);
                              }
                              cb(err);
                            });
  };

  acquirer.is_owner = function() { return is_owner == true; };
  acquirer.lease_owner = function() { return lease_owner; };

  return acquirer;
};

exports.lease_voter = function(comm, opts) {
  var highest_proposed_ballot = null;
  var accepted_ballot         = null;
  var accepted_val            = null;
  var timer                   = null;

  opts = opts || {};
  opts.respond_preprocess = function(msg) {
    msg.accepted_ballot = accepted_ballot;
    msg.accepted_val    = accepted_val;
    return msg;
  }

  var lease_storage = {
    "slot_read": function(slot, cb) {
      assert(slot == 0);
      cb(false, { "highest_proposed_ballot": highest_proposed_ballot,
                  "accepted_ballot":         accepted_ballot,
                  "accepted_val":            accepted_val });
    },
    "slot_save_highest_proposed_ballot": function(slot, ballot, cb) {
      assert(slot == 0);
      highest_proposed_ballot = ballot;
      cb(false);
    },
    "slot_save_accepted": function(slot, ballot, val, cb) {
      assert(slot == 0);
      accepted_ballot = ballot;
      accepted_val    = null;

      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(function() {
                           accepted_ballot = null;
                           accepted_val    = null;
                         }, val.lease_timeout);
      cb(false);
    }
  };

  return paxos.acceptor(lease_storage, comm, opts);
};
<commit_msg>Expose stats for paxos lease acquirer.<commit_after>var assert = require('assert');
var paxos  = require('./paxos');

// Algorithm adapted from: "PaxosLease: Diskless Paxos for Leases",
// by Trencseni, Gazso, Reinhardt.
//
exports.lease_acquirer = function(lease_timeout, // In milliseconds.
                                  node_name, node_restarts,
                                  acceptors, comm, opts) {
  var timer = null;
  var is_owner = false; // Tri-state: true, false, 'timeout'.
  var lease_owner = null;

  opts = opts || {};
  opts.msg_preprocess = function(src, msg) {
    if (msg.kind == paxos.RES_PROPOSED) {
      if (msg.accepted_ballot != null ||
          msg.accepted_val != null) {
        msg.kind = paxos.RES_NACK;
      }
    }
    return msg;
  };
  opts.on_phase_complete = function(kind, err) {
    if (kind == paxos.RES_PROPOSED && !err) {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(function() {
                           is_owner = 'timeout';
                           lease_owner = null;
                         },
                         lease_timeout);
    }
  };
  opts.proposer_timeout = opts.proposer_timeout || opts.acquirer_timeout;

  var proposer = paxos.proposer(node_name, node_restarts,
                                0, acceptors, comm, opts);

  var acquirer = {};

  acquirer.acquire = function(cb) {
    var val = { "lease_owner"   : node_name,
                "lease_timeout" : lease_timeout };
    return proposer.propose(val,
                            function(err, info) {
                              is_owner = false;
                              lease_owner = null;
                              if (!err) {
                                is_owner = true;
                                if (info &&
                                    info.accepted_val) {
                                  lease_owner = info.accepted_val.lease_owner;
                                }
                                assert(lease_owner == node_name);
                              }
                              cb(err);
                            });
  };

  acquirer.is_owner    = function() { return is_owner == true; };
  acquirer.lease_owner = function() { return lease_owner; };
  acquirer.stats       = proposer.stats;

  return acquirer;
};

exports.lease_voter = function(comm, opts) {
  var highest_proposed_ballot = null;
  var accepted_ballot         = null;
  var accepted_val            = null;
  var timer                   = null;

  opts = opts || {};
  opts.respond_preprocess = function(msg) {
    msg.accepted_ballot = accepted_ballot;
    msg.accepted_val    = accepted_val;
    return msg;
  }

  var lease_storage = {
    "slot_read": function(slot, cb) {
      assert(slot == 0);
      cb(false, { "highest_proposed_ballot": highest_proposed_ballot,
                  "accepted_ballot":         accepted_ballot,
                  "accepted_val":            accepted_val });
    },
    "slot_save_highest_proposed_ballot": function(slot, ballot, cb) {
      assert(slot == 0);
      highest_proposed_ballot = ballot;
      cb(false);
    },
    "slot_save_accepted": function(slot, ballot, val, cb) {
      assert(slot == 0);
      accepted_ballot = ballot;
      accepted_val    = null;

      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(function() {
                           accepted_ballot = null;
                           accepted_val    = null;
                         }, val.lease_timeout);
      cb(false);
    }
  };

  return paxos.acceptor(lease_storage, comm, opts);
};
<|endoftext|>


<commit_before>'use strict';

var async = require('async');
var express = require('express');
var fs = require('fs');
var multiparty = require('multiparty');
var util = require('util');

/* Make an http server to receive the webhook. */
var server = express();
server.use(server.router);

server.head('/webhook', function (req, res) {
    console.log('Received head request from webhook.');
    res.send(200);
});

server.post('/webhook', function (req, res) {
    console.log('Receiving webhook.');

    /* Respond early to avoid timouting the mailin server. */
    // res.send(200);

    /* Parse the multipart form. The attachments are parsed into fields and can
     * be huge, so set the maxFieldsSize accordingly. */
    var form = new multiparty.Form({
        maxFieldsSize: 70000000
    });

    form.on('progress', function () {
        var start = Date.now();
        var lastDisplayedPercentage = -1;
        return function (bytesReceived, bytesExpected) {
            var elapsed = Date.now() - start;
            var percentage = Math.floor(bytesReceived / bytesExpected * 100);
            if (percentage % 20 === 0 && percentage !== lastDisplayedPercentage) {
                lastDisplayedPercentage = percentage;
                console.log('Form upload progress ' +
                    percentage + '% of ' + bytesExpected / 1000000 + 'Mb. ' + elapsed + 'ms');
            }
        };
    }());

    form.parse(req, function (err, fields) {
        console.log(util.inspect(fields.mailinMsg, {
            depth: 5
        }));

        console.log('Parsed fields: ' + Object.keys(fields));

        /* Write down the payload for ulterior inspection. */
        async.auto({
            writeParsedMessage: function (cbAuto) {
                fs.writeFile('payload.json', fields.mailinMsg, cbAuto);
            },
            writeAttachments: function (cbAuto) {
                var msg = JSON.parse(fields.mailinMsg);
                async.eachLimit(msg.attachments, 3, function (attachment, cbEach) {
                    fs.writeFile(attachment.generatedFileName, fields[attachment.generatedFileName], 'base64', cbEach);
                }, cbAuto);
            }
        }, function (err) {
            if (err) {
                console.log(err.stack);
                res.send(500, 'Unable to write payload');
            } else {
                console.log('Webhook payload written.');
                res.send(200);
            }
        });
    });
});

server.listen(3000, function (err) {
    if (err) {
        console.log(err);
    } else {
        console.log('Http server listening on port 3000');
    }
});

<commit_msg>Updated example server to properly support express 4.0<commit_after>'use strict';

var async = require('async');
var express = require('express');
var fs = require('fs');
var multiparty = require('multiparty');
var util = require('util');

/* Make an http server to receive the webhook. */
var server = express();

server.head('/webhook', function (req, res) {
    console.log('Received head request from webhook.');
    res.send(200);
});

server.post('/webhook', function (req, res) {
    console.log('Receiving webhook.');

    /* Respond early to avoid timouting the mailin server. */
    // res.send(200);

    /* Parse the multipart form. The attachments are parsed into fields and can
     * be huge, so set the maxFieldsSize accordingly. */
    var form = new multiparty.Form({
        maxFieldsSize: 70000000
    });

    form.on('progress', function () {
        var start = Date.now();
        var lastDisplayedPercentage = -1;
        return function (bytesReceived, bytesExpected) {
            var elapsed = Date.now() - start;
            var percentage = Math.floor(bytesReceived / bytesExpected * 100);
            if (percentage % 20 === 0 && percentage !== lastDisplayedPercentage) {
                lastDisplayedPercentage = percentage;
                console.log('Form upload progress ' +
                    percentage + '% of ' + bytesExpected / 1000000 + 'Mb. ' + elapsed + 'ms');
            }
        };
    }());

    form.parse(req, function (err, fields) {
        console.log(util.inspect(fields.mailinMsg, {
            depth: 5
        }));

        console.log('Parsed fields: ' + Object.keys(fields));

        /* Write down the payload for ulterior inspection. */
        async.auto({
            writeParsedMessage: function (cbAuto) {
                fs.writeFile('payload.json', fields.mailinMsg, cbAuto);
            },
            writeAttachments: function (cbAuto) {
                var msg = JSON.parse(fields.mailinMsg);
                async.eachLimit(msg.attachments, 3, function (attachment, cbEach) {
                    fs.writeFile(attachment.generatedFileName, fields[attachment.generatedFileName], 'base64', cbEach);
                }, cbAuto);
            }
        }, function (err) {
            if (err) {
                console.log(err.stack);
                res.send(500, 'Unable to write payload');
            } else {
                console.log('Webhook payload written.');
                res.send(200);
            }
        });
    });
});

server.listen(3000, function (err) {
    if (err) {
        console.log(err);
    } else {
        console.log('Http server listening on port 3000');
    }
});

<|endoftext|>


<commit_before>MeteorApp = {};

MeteorApp.data = {
    playerId: null
};

MeteorApp.Card = new Mongo.Collection("Card");
MeteorApp.Action = new Mongo.Collection("Action");

MeteorApp.imageFileNames = [
    'adopt',
    'archer',
    'archerfemale',
    'blind',
    'blindfemale',
    'bodyguard',
    'burglar',
    'burglarfemale',
    'citizen',
    'citizenfemale',
    'farmer',
    'hunter',
    'hunterfemale',
    'master_archer',
    'master_archerfemale',
    'master_oracle',
    'medium',
    'mediumfemale',
    'ninja',
    'ninjafemale',
    'oracle',
    'oraclemale',
    'pickpocket',
    'pickpocketfemale',
    'rebel',
    'rogue',
    'roguefemale',
    'runaway',
    'shadow_walker',
    'shadow_walkerfemale',
    'thief',
    'thieffemale',
    'warden',
    'warrior',
    'witch'
];

Meteor.methods({
    moveCard: function(id, position) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.x = position.x;
        card.y = position.y;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardMoved',
            params: {
                id: id,
                position: position
            }
        });
    },

    removeCard: function(id) {
        MeteorApp.Card.remove(id);

        MeteorApp.Action.insert({
            type: 'Backend:cardRemoved',
            params: {
                id: id
            }
        });
    },

    tapCard: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.isTapped = true;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardTapped',
            params: {
                id: id
            }
        });
    },

    untapCard: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.isTapped = false;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardUntapped',
            params: {
                id: id
            }
        });
    },

    playAsMana: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        if (card.cardGroup == 'hand') {
            card.cardGroup = 'manaPool';
            MeteorApp.Card.update(id, card);

            MeteorApp.Action.insert({
                type: 'Backend:cardPlayedAsMana',
                params: {
                    id: id,
                    ownerId: card.ownerId
                }
            });
        }
    },

    drawCard: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        if (card.cardGroup == 'deck') {
            card.cardGroup = 'hand';
            MeteorApp.Card.update(id, card);

            MeteorApp.Action.insert({
                type: 'Backend:cardDrawn',
                params: {
                    id: id,
                    ownerId: card.ownerId
                }
            });
        }
    },

    playCard: function(id, position) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.cardGroup = 'table';
        card.x = position.x;
        card.y = position.y;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardPlayed',
            params: {
                id: id,
                position: position,
                ownerId: card.ownerId
            }
        });
    },

    addHealth: function(id, health) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.health = card.health + health;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardHealthChanged',
            params: {
                id: id,
                health: card.health
            }
        });

        if (card.health <= 0 && card.cardGroup == 'table') {
            card.cardGroup = 'graveyard';
            MeteorApp.Card.update(id, card);

            MeteorApp.Action.insert({
                type: 'Backend:cardDied',
                params: {
                    id: id,
                    ownerId: card.ownerId
                }
            });
        }
    },

    addCounter: function(id, counter) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.counter = card.counter + counter;
        if (card.counter < 0) {
            return;
        }

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardCounterChanged',
            params: {
                id: id,
                counter: card.counter
            }
        });
    }
});
<commit_msg>Добавил отмену действий с картой<commit_after>MeteorApp = {};

MeteorApp.data = {
    playerId: null
};

MeteorApp.Card = new Mongo.Collection("Card");
MeteorApp.Action = new Mongo.Collection("Action");

MeteorApp.imageFileNames = [
    'adopt',
    'archer',
    'archerfemale',
    'blind',
    'blindfemale',
    'bodyguard',
    'burglar',
    'burglarfemale',
    'citizen',
    'citizenfemale',
    'farmer',
    'hunter',
    'hunterfemale',
    'master_archer',
    'master_archerfemale',
    'master_oracle',
    'medium',
    'mediumfemale',
    'ninja',
    'ninjafemale',
    'oracle',
    'oraclemale',
    'pickpocket',
    'pickpocketfemale',
    'rebel',
    'rogue',
    'roguefemale',
    'runaway',
    'shadow_walker',
    'shadow_walkerfemale',
    'thief',
    'thieffemale',
    'warden',
    'warrior',
    'witch'
];

Meteor.methods({
    moveCard: function(id, position) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.x = position.x;
        card.y = position.y;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardMoved',
            params: {
                id: id,
                position: position
            }
        });
    },

    removeCard: function(id) {
        MeteorApp.Card.remove(id);

        MeteorApp.Action.insert({
            type: 'Backend:cardRemoved',
            params: {
                id: id
            }
        });
    },

    tapCard: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.isTapped = true;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardTapped',
            params: {
                id: id
            }
        });
    },

    untapCard: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.isTapped = false;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardUntapped',
            params: {
                id: id
            }
        });
    },

    playAsMana: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        if (card.cardGroup == 'hand') {
            card.cardGroup = 'manaPool';
            MeteorApp.Card.update(id, card);

            MeteorApp.Action.insert({
                type: 'Backend:cardPlayedAsMana',
                params: {
                    id: id,
                    ownerId: card.ownerId
                }
            });
        }
    },

    drawCard: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        if (card.cardGroup == 'deck') {
            card.cardGroup = 'hand';
            MeteorApp.Card.update(id, card);

            MeteorApp.Action.insert({
                type: 'Backend:cardDrawn',
                params: {
                    id: id,
                    ownerId: card.ownerId
                }
            });
        }
    },

    playCard: function(id, position) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.cardGroup = 'table';
        card.x = position.x;
        card.y = position.y;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardPlayed',
            params: {
                id: id,
                position: position,
                ownerId: card.ownerId
            }
        });
    },

    moveCardToPreviousGroup: function(id) {
        var card = MeteorApp.Card.findOne({_id: id});
        var group = card.cardGroup;

        if (group === 'table') {
            card.cardGroup = 'hand';
        } else if(group === 'hand') {
            card.cardGroup = 'deck';
        } else if(group === 'graveyard') {
            card.cardGroup = 'table';
        }

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardMovedToPreviousGroup',
            params: {
                id: id,
                oldCardGroup: group,
                newCardGroup: card.cardGroup,
                ownerId: card.ownerId
            }
        });
    },

    addHealth: function(id, health) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.health = card.health + health;

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardHealthChanged',
            params: {
                id: id,
                health: card.health
            }
        });

        if (card.health <= 0 && card.cardGroup == 'table') {
            card.cardGroup = 'graveyard';
            MeteorApp.Card.update(id, card);

            MeteorApp.Action.insert({
                type: 'Backend:cardDied',
                params: {
                    id: id,
                    ownerId: card.ownerId
                }
            });
        }
    },

    addCounter: function(id, counter) {
        var card = MeteorApp.Card.findOne({_id: id});
        card.counter = card.counter + counter;
        if (card.counter < 0) {
            return;
        }

        MeteorApp.Card.update(id, card);

        MeteorApp.Action.insert({
            type: 'Backend:cardCounterChanged',
            params: {
                id: id,
                counter: card.counter
            }
        });
    }
});
<|endoftext|>


<commit_before>import { _ }            from 'meteor/underscore';
import { Mongo }        from 'meteor/mongo';
import { Meteor }       from 'meteor/meteor';
import { Logger }       from 'meteor/ostrio:logger';
import { check, Match } from 'meteor/check';
const NOOP = () => {};

/*
 * @class LoggerMongo
 * @summary MongoDB adapter for ostrio:logger (Logger)
 */
class LoggerMongo {
  constructor(logger, options = {}) {
    check(logger, Match.OneOf(Logger, Object));
    check(options, {
      collectionName: Match.Optional(String),
      collection: Match.Optional(Match.OneOf(Mongo.Collection, Object)),
      format: Match.Optional(Function)
    });

    this.logger  = logger;
    this.options = options;

    if (!this.options.format) {
      this.options.format = (opts) => {
        return opts;
      };
    }

    if (Meteor.isServer) {
      if (this.options.collection) {
        this.collection = this.options.collection;
      } else {
        if (!this.options.collectionName) {
          this.options.collectionName = 'ostrioMongoLogger';
        }

        this.collection = new Meteor.Collection(this.options.collectionName);
        this.collection.deny({
          update() {
            return true;
          },
          remove() {
            return true;
          },
          insert() {
            return true;
          }
        });
      }
    }

    this.logger.add('Mongo', (level, message, data = null, userId) => {
      if (Meteor.isServer) {
        const time = new Date();
        if (data) {
          data = this.logger.antiCircular(data);
          if (_.isString(data.stackTrace)) {
            data.stackTrace = data.stackTrace.split(/\n|\\n|\r|\r\n/g);
          }
        }

        const record = this.options.format({
          userId: userId,
          date: time,
          timestamp: +time,
          level: level,
          message: message,
          additional: data,
        });

        if (!_.isObject(record)) {
          throw new Meteor.Error(400, '[ostrio:logger] [options.format]: Must return a plain Object!', record);
        }

        this.collection.insert(record, NOOP);
      }
    }, NOOP, false, false);
  }

  enable(rule = {}) {
    check(rule, {
      enable: Match.Optional(Boolean),
      client: Match.Optional(Boolean),
      server: Match.Optional(Boolean),
      filter: Match.Optional([String])
    });

    if (rule.enable == null) {
      rule.enable = true;
    }

    if (rule.client == null) {
      rule.client = true;
    }

    if (rule.server == null) {
      rule.server = true;
    }

    this.logger.rule('Mongo', rule);
    return this;
  }
}

export { LoggerMongo };
<commit_msg>🏗👷♂ Get rid of `underscore` package<commit_after>import { Mongo }        from 'meteor/mongo';
import { Meteor }       from 'meteor/meteor';
import { Logger }       from 'meteor/ostrio:logger';
import { check, Match } from 'meteor/check';
const NOOP = () => {};

const helpers = {
  isObject(obj) {
    if (this.isArray(obj) || this.isFunction(obj)) {
      return false;
    }
    return obj === Object(obj);
  },
  isArray(obj) {
    return Array.isArray(obj);
  },
  isFunction(obj) {
    return typeof obj === 'function' || false;
  },
  isString(obj) {
    return Object.prototype.toString.call(obj) === '[object String]';
  }
};

/*
 * @class LoggerMongo
 * @summary MongoDB adapter for ostrio:logger (Logger)
 */
class LoggerMongo {
  constructor(logger, options = {}) {
    check(logger, Match.OneOf(Logger, Object));
    check(options, {
      collectionName: Match.Optional(String),
      collection: Match.Optional(Match.OneOf(Mongo.Collection, Object)),
      format: Match.Optional(Function)
    });

    this.logger  = logger;
    this.options = options;

    if (!this.options.format) {
      this.options.format = (opts) => {
        return opts;
      };
    }

    if (Meteor.isServer) {
      if (this.options.collection) {
        this.collection = this.options.collection;
      } else {
        if (!this.options.collectionName) {
          this.options.collectionName = 'ostrioMongoLogger';
        }

        this.collection = new Meteor.Collection(this.options.collectionName);
        this.collection.deny({
          update() {
            return true;
          },
          remove() {
            return true;
          },
          insert() {
            return true;
          }
        });
      }
    }

    this.logger.add('Mongo', (level, message, _data = null, userId) => {
      if (Meteor.isServer) {
        const time = new Date();
        let data   = _data;
        if (data) {
          data = this.logger.antiCircular(data);
          if (helpers.isString(data.stackTrace)) {
            data.stackTrace = data.stackTrace.split(/\n|\\n|\r|\r\n/g);
          }
        }

        const record = this.options.format({
          userId: userId,
          date: time,
          timestamp: +time,
          level: level,
          message: message,
          additional: data,
        });

        if (!helpers.isObject(record)) {
          throw new Meteor.Error(400, '[ostrio:logger] [options.format]: Must return a plain Object!', record);
        }

        this.collection.insert(record, NOOP);
      }
    }, NOOP, false, false);
  }

  enable(rule = {}) {
    check(rule, {
      enable: Match.Optional(Boolean),
      client: Match.Optional(Boolean),
      server: Match.Optional(Boolean),
      filter: Match.Optional([String])
    });

    if (rule.enable == null) {
      rule.enable = true;
    }

    if (rule.client == null) {
      rule.client = true;
    }

    if (rule.server == null) {
      rule.server = true;
    }

    this.logger.rule('Mongo', rule);
    return this;
  }
}

export { LoggerMongo };
<|endoftext|>


<commit_before>'use strict'
var path = require('path')
var express = require('express')
var app = express()
var http = require('http')
var https = require('https')
var fs = require('fs')
var options = {
  key: fs.readFileSync(path.join(__dirname, '/key.pem')),
  cert: fs.readFileSync(path.join(__dirname, '/key-cert.pem'))
}
var httpServer = http.createServer(app)
var httpsServer = https.createServer(options, app)
app.use('/files', express.static(path.join(__dirname, '/files')))
app.head('/fixed-size', (req, res) => res.status(403).send())
app.get('/fixed-size', (req, res) =>
  res.send('a quick brown fox jumps over the lazy dog')
)

const startServer = (app, port) =>
  new Promise(i => {
    // eslint-disable-line
    const onClose = () => new Promise(i => server.close(i)) // eslint-disable-line
    const onStart = () => i(onClose)
    const server = app.listen(port, onStart)
  })

exports.server = port =>
  Promise.all([
    startServer(httpServer, port),
    startServer(httpsServer, port + 1)
  ]).then(x => () => Promise.all(x.map(x => x())))
<commit_msg>chore(lint): eslint fixes<commit_after>'use strict'
var path = require('path')
var express = require('express')
var app = express()
var http = require('http')
var https = require('https')
var fs = require('fs')
var options = {
  key: fs.readFileSync(path.join(__dirname, '/key.pem')),
  cert: fs.readFileSync(path.join(__dirname, '/key-cert.pem'))
}
var httpServer = http.createServer(app)
var httpsServer = https.createServer(options, app)
app.use('/files', express.static(path.join(__dirname, '/files')))
app.head('/fixed-size', (req, res) => res.status(403).send())
app.get('/fixed-size', (req, res) =>
  res.send('a quick brown fox jumps over the lazy dog')
)

const startServer = (app, port) =>
  new Promise(resolve => {
    // eslint-disable-line
    const onClose = () => new Promise(i => server.close(i)) // eslint-disable-line
    const onStart = () => resolve(onClose)
    const server = app.listen(port, onStart)
  })

exports.server = port =>
  Promise.all([
    startServer(httpServer, port),
    startServer(httpsServer, port + 1)
  ]).then(x => () => Promise.all(x.map(x => x())))
<|endoftext|>


<commit_before>'use strict';

var EventEmitter = require('./EventEmitter');
var LeafSnapshot = require('./LeafSnapshot');
var ObjectSnapshot = require('./ObjectSnapshot');
var FlushQueue = require('./FlushQueue');
var utils = require('./utils');
var FakeRef = require('./FakeRef');

function TreeNode(ref, parent){
  this._parent = parent || null;
  if (parent) {
    this._rootQueue = parent._rootQueue;
    this._flushQueue = parent._flushQueue.childRegistration(this, '_flush');
  } else {
    this._rootQueue = new FlushQueue();
    this._flushQueue = this._rootQueue.childRegistration(this, '_flush');
  }
  this._events = new EventEmitter();
  this._children = {};
  this._valueChildren = {};
  this._valueSnap = null;
  this._value = null;
  this._priority = null;
  this._pendingValue = null;
  this._pendingPriority = null;
  this._changed = false;
  this._ref = ref;
  this._initialized = false;
  this._initializeNextFlush = false;
}

TreeNode.prototype.flushChanges = function() {
  this._rootQueue.flush();
};

TreeNode.prototype._flush = function(){
  var initializing = this._initializeNextFlush;
  if(initializing) {
    this._initializeNextFlush = false;
    this._initialized = true;
  }
  var changed = this._changed;
  if(changed || initializing){
    this._changed = false;
    this._value = this._pendingValue;
    this._priority = this._pendingPriority;
    var oldSnap = this._valueSnap;
    var newSnap = this._buildValueSnap();
    this._valueSnap = newSnap;
    if (newSnap.exists()) {
      if(!(oldSnap && oldSnap.exists())){
        this._registerValue();
        this._emitEventOnParent('child_added', newSnap);
      }
      else {
        this._emitEventOnParent('child_changed', newSnap);
      }
    } else {
      if(oldSnap && oldSnap.exists()){
        this._deregisterValue();
        this._emitEventOnParent('child_removed', oldSnap);
      }
    }
    this._events.emit('value', newSnap);
  }
};

TreeNode.prototype.on = function(eventType, callback, cancelCallback, context) {
  this._events.on.apply(this._events,arguments);
  if(this._initialized){
    switch (eventType){
      case 'value':
        callback(this._valueSnap);
        break;

      case 'child_added':
        this._valueSnap.forEach(function(snap){
          callback(snap);
        });
        break;
    }
  }
};

TreeNode.prototype.ref = function(){
  return this._ref;
};

TreeNode.prototype.key = function(){
  return this._ref.key();
};

TreeNode.prototype.initialized = function(){
  return this._initialized;
};

TreeNode.prototype.setValue = function(value){
  var initializeNextFlush = this._initializeNextFlush = !this._initialized;
  var changed = this._changed = this._setValue(value);
  if(changed || initializeNextFlush){
    this._flushQueue.schedule();
  }
  return changed;
};

TreeNode.prototype._setValue = function(value){
  if(typeof value === 'object' && value !== null){
    if(value.hasOwnProperty('.value')){
      return this._setLeafValue(value['.value'], value['.priority']);
    }
    return this._setObjectValue(value);
  }
  else {
    return this._setLeafValue(value, null);
  }
};

TreeNode.prototype._setObjectValue = function(value){
  var children = this._children;
  var changed = false;
  for(var i in children){
    /* istanbul ignore else */
    if(children.hasOwnProperty(i)){
      changed = children[i].setValue(value.hasOwnProperty(i) ? value[i] : null) || changed;
    }
  }
  for(var j in value){
    if(value.hasOwnProperty(j) && !children.hasOwnProperty(j) && j.charAt(0) !== '.'){
      var child = children[j] = new TreeNode(this.ref().child(j), this);
      changed = child.setValue(value[j]) || changed;
    }
  }
  if(value.hasOwnProperty('.priority')){
    var priority = value['.priority'];
    this._pendingPriority = priority;
    changed = priority !== this._priority || changed;
  }
  return changed;
};

TreeNode.prototype._setLeafValue = function(value, priority){
  var children = this._children;
  for(var i in children){
    if(children.hasOwnProperty(i)){
      children[i].setValue(null);
    }
  }
  this._pendingValue = value;
  this._pendingPriority = priority;
  return value !== this._value || priority !== this._priority;
};

TreeNode.prototype._registerValue = function(){
  if(this._parent) this._parent._registerValueChild(this);
};

TreeNode.prototype._deregisterValue = function(){
  if(this._parent) this._parent._deregisterValueChild(this);
};

TreeNode.prototype._registerValueChild = function(child){
  this._valueChildren[child.key()] = child;
};

TreeNode.prototype._deregisterValueChild = function(child){
  delete this._valueChildren[child.key()];
};

TreeNode.prototype._hasValueChildren = function(){
  return !!(Object.getOwnPropertyNames(this._valueChildren).length);
};

TreeNode.prototype._buildValueSnap = function(){
  if(this._hasValueChildren()){
    var children = [];
    for(var i in this._valueChildren){
      /* istanbul ignore else */
      if(this._valueChildren.hasOwnProperty(i)){
        children.push(this._valueChildren[i]._valueSnap);
      }
    }
    //TODO: Sort Children According To OrderByXXX
    //TODO: Create Meaningful Refs
    //TODO: Include priority
    return new ObjectSnapshot(this.ref(), children, this._priority);
  }
  else {
    return new LeafSnapshot(this.ref(), this._value, this._priority);
  }
};

TreeNode.prototype.child = function(path,create){
  path = path.split('/');
  var child = this;
  var i,len;
  if (create) {
    for (i = 0, len = path.length; i < len; i++) {
      child = child._getOrCreateChild(path[i]);
    }
  } else {
    for (i = 0, len = path.length; child && i < len; i++) {
      child = child._getChild(path[i]);
    }
  }
  return child;
};

TreeNode.prototype._emitChildEvent = function (eventType, snap){
  this._events.emit(eventType,snap);
  this._changed = true;
};

TreeNode.prototype._emitEventOnParent = function(eventType, snap){
  if(this._parent) this._parent._emitChildEvent(eventType,snap);
};

TreeNode.prototype._getChild = function(key){
  return this._children[key] || null;
};

TreeNode.prototype._getOrCreateChild = function(key){
  var children = this._children;
  var child = children[key];
  if(!child){
    child = children[key] = new TreeNode(this.ref().child(key),this);
    if(this._initialized){
      child._initEmpty();
    }
  }
  return child;
};

/**
 * Called if we know this child to currently be empty.
 * @private
 */
TreeNode.prototype._initEmpty = function(){
  this._initialized = true;
  this._valueSnap = this._buildValueSnap();
};

module.exports = TreeNode;<commit_msg>spiked code in comments I'm leaving it there while I work on something else<commit_after>'use strict';

var EventEmitter = require('./EventEmitter');
var LeafSnapshot = require('./LeafSnapshot');
var ObjectSnapshot = require('./ObjectSnapshot');
var FlushQueue = require('./FlushQueue');
var utils = require('./utils');
var FakeRef = require('./FakeRef');

function TreeNode(ref, parent){
  this._parent = parent || null;
  if (parent) {
    //this._root = parent._root;
    this._rootQueue = parent._rootQueue;
    this._flushQueue = parent._flushQueue.childRegistration(this, '_flush');
  } else {
    //this._root = this;
    this._rootQueue = new FlushQueue();
    this._flushQueue = this._rootQueue.childRegistration(this, '_flush');
  }
  this._events = new EventEmitter();
  this._children = {};
  this._valueChildren = {};
  //this._listeningChildren = {};
  //this._forgettableChildren = {};
  this._valueSnap = null;
  this._value = null;
  this._priority = null;
  this._pendingValue = null;
  this._pendingPriority = null;
  this._changed = false;
  this._ref = ref;
  this._initialized = false;
  this._initializeNextFlush = false;
}

TreeNode.prototype.flushChanges = function() {
  this._rootQueue.flush();
};

TreeNode.prototype._flush = function(){
  var initializing = this._initializeNextFlush;
  if(initializing) {
    this._initializeNextFlush = false;
    this._initialized = true;
  }
  var changed = this._changed;
  if(changed || initializing){
    this._changed = false;
    this._value = this._pendingValue;
    this._priority = this._pendingPriority;
    var oldSnap = this._valueSnap;
    var newSnap = this._buildValueSnap();
    this._valueSnap = newSnap;
    if (newSnap.exists()) {
      if(!(oldSnap && oldSnap.exists())){
        this._registerValue();
        this._emitEventOnParent('child_added', newSnap);
      }
      else {
        this._emitEventOnParent('child_changed', newSnap);
      }
    } else {
      if(oldSnap && oldSnap.exists()){
        this._deregisterValue();
        this._emitEventOnParent('child_removed', oldSnap);
      }
    }
    this._events.emit('value', newSnap);
  }
};

TreeNode.prototype.on = function(eventType, callback, cancelCallback, context) {
  this._events.on.apply(this._events,arguments);
  if(this._initialized){
    switch (eventType){
      case 'value':
        callback(this._valueSnap);
        break;

      case 'child_added':
        this._valueSnap.forEach(function(snap){
          callback(snap);
        });
        break;
    }
  }
};

TreeNode.prototype.ref = function(){
  return this._ref;
};

TreeNode.prototype.key = function(){
  return this._ref.key();
};

TreeNode.prototype.initialized = function(){
  return this._initialized;
};

TreeNode.prototype.setValue = function(value){
  var initializeNextFlush = this._initializeNextFlush = !this._initialized;
  var changed = this._changed = this._setValue(value);
  if(changed || initializeNextFlush){
    this._flushQueue.schedule();
  }
  return changed;
};

TreeNode.prototype._setValue = function(value){
  if(typeof value === 'object' && value !== null){
    if(value.hasOwnProperty('.value')){
      return this._setLeafValue(value['.value'], value['.priority']);
    }
    return this._setObjectValue(value);
  }
  else {
    return this._setLeafValue(value, null);
  }
};

TreeNode.prototype._setObjectValue = function(value){
  var children = this._children;
  var changed = false;
  for(var i in children){
    /* istanbul ignore else */
    if(children.hasOwnProperty(i)){
      changed = children[i].setValue(value.hasOwnProperty(i) ? value[i] : null) || changed;
    }
  }
  for(var j in value){
    if(value.hasOwnProperty(j) && !children.hasOwnProperty(j) && j.charAt(0) !== '.'){
      var child = children[j] = new TreeNode(this.ref().child(j), this);
      changed = child.setValue(value[j]) || changed;
    }
  }
  if(value.hasOwnProperty('.priority')){
    var priority = value['.priority'];
    this._pendingPriority = priority;
    changed = priority !== this._priority || changed;
  }
  return changed;
};

TreeNode.prototype._setLeafValue = function(value, priority){
  var children = this._children;
  for(var i in children){
    if(children.hasOwnProperty(i)){
      children[i].setValue(null);
    }
  }
  this._pendingValue = value;
  this._pendingPriority = priority;
  return value !== this._value || priority !== this._priority;
};

TreeNode.prototype._registerValue = function(){
  if(this._parent) this._parent._registerValueChild(this);
};

TreeNode.prototype._deregisterValue = function(){
  if(this._parent) this._parent._deregisterValueChild(this);
};

TreeNode.prototype._registerValueChild = function(child){
  this._valueChildren[child.key()] = child;
};

TreeNode.prototype._deregisterValueChild = function(child){
  delete this._valueChildren[child.key()];
};

TreeNode.prototype._hasValueChildren = function(){
  return !!(Object.getOwnPropertyNames(this._valueChildren).length);
};

TreeNode.prototype._buildValueSnap = function(){
  if(this._hasValueChildren()){
    var children = [];
    for(var i in this._valueChildren){
      /* istanbul ignore else */
      if(this._valueChildren.hasOwnProperty(i)){
        children.push(this._valueChildren[i]._valueSnap);
      }
    }
    //TODO: Sort Children According To OrderByXXX
    //TODO: Create Meaningful Refs
    //TODO: Include priority
    return new ObjectSnapshot(this.ref(), children, this._priority);
  }
  else {
    return new LeafSnapshot(this.ref(), this._value, this._priority);
  }
};

TreeNode.prototype.child = function(path,create){
  path = path.split('/');
  var child = this;
  var i,len;
  if (create) {
    for (i = 0, len = path.length; i < len; i++) {
      child = child._getOrCreateChild(path[i]);
    }
  } else {
    for (i = 0, len = path.length; child && i < len; i++) {
      child = child._getChild(path[i]);
    }
  }
  return child;
};

TreeNode.prototype._emitChildEvent = function (eventType, snap){
  this._events.emit(eventType,snap);
  this._changed = true;
};

TreeNode.prototype._emitEventOnParent = function(eventType, snap){
  if(this._parent) this._parent._emitChildEvent(eventType,snap);
};

TreeNode.prototype._getChild = function(key){
  return this._children[key] || null;
};

TreeNode.prototype._getOrCreateChild = function(key){
  var children = this._children;
  var child = children[key];
  if(!child){
    child = children[key] = new TreeNode(this.ref().child(key),this);
    if(this._initialized){
      child._initEmpty();
    }
  }
  return child;
};

/*TreeNode.prototype._hasLocalListeners = function(){
  return this._events.hasListeners();
};

TreeNode.prototype._hasChildren = function(){
  return !!(Object.getOwnPropertyNames(this._children).length);
};

TreeNode.prototype._registerAsForgettable = function(){
  var parent = this._parent;
  if(parent) parent._registerChildAsForgettable(this);
};

TreeNode.prototype._registerChildAsForgettable = function(child){
  this._forgettableChildren[child.key()] = child;
  if(!this._hasLocalListeners()) {
    this._registerAsForgettable();
  }
};

TreeNode.prototype._hasForgettableChildren = function(){
  return !!(Object.getOwnPropertyNames(this._forgettableChildren).length);
};

TreeNode.prototype._deregisterAsForgettable = function(){
  var parent = this._parent;
  if(parent) parent._deregisterChildAsForgettable(this);
};

TreeNode.prototype._deregisterChildAsForgettable = function(child){
  delete this._forgettableChildren[child.key()];
  if(!this._hasForgettableChildren()){
    this._deregisterAsForgettable();
  }
};

TreeNode.prototype.forget = function(){
  this._root._forget();
};

TreeNode.prototype._forget = function(){
  if(this._hasLocalListeners()) return;
  var forgettable = this._forgettableChildren;
  for(var i in forgettable){
    if(forgettable.hasOwnProperty(i)){
      forgettable[i]._forget();
    }
  }
};

TreeNode.prototype._destroy = function(){
  var parent = this._parent;
  if(parent) parent._forgetChild(this);
};

TreeNode.prototype._forgetChild = function(child){
  var key = child.key();
  delete this._children[key];
  delete this._valueChildren[key];
  delete this._forgettableChildren[key];
};
 */
/*

TreeNode.prototype._listening = function(){
  return !(this._hasListeners() || Object.getOwnPropertyNames(this._listeningChildren).length);
};

TreeNode.prototype._registerAsListening = function(){
  var parent = this._parent;
  if(parent) parent._registerChildAsListening(this);
};

TreeNode.prototype._registerChildAsListening = function(child){
  this._listeningChildren[child.key()] = child;
  this._registerAsListening();
};

TreeNode.prototype._deregisterAsListening = function(){
  var parent = this._parent;
  if(parent) parent._deregisterChildAsListening(this);
};

TreeNode.prototype._deregisterChildAsListening = function(child){
  delete this._listeningChildren[child.key()];
  if(this._listening()){
    this._deregisterAsListening();
  }
};
    */
/**
 * Called if we know this child to currently be empty.
 * @private
 */
TreeNode.prototype._initEmpty = function(){
  this._initialized = true;
  this._valueSnap = this._buildValueSnap();
};

module.exports = TreeNode;<|endoftext|>


<commit_before>'use strict';

goog.require('task_queue');

describe('task_queue', function() {
	var queue;
	var orderCalled;
	var clock = sinon.useFakeTimers();
	var assert = testUtils.unplanned();
	beforeEach(function() {
		queue = task_queue();
		orderCalled = [];
		queue(function(next) {
			setTimeout(function() {
				orderCalled.push(0);
				next();
			}, 10);
		});
		assert(orderCalled[0] === undefined, 'Has not yet called function');
	});

	it('should queue a function and call it', function(done) {
		assert.equal(orderCalled[0] === undefined, 'Function not yet called');
		clock.tick(15);
		assert.equal(orderCalled[0], 0, 'Function called');
		done();
	});

	it('should enqueue two functions, and call them in order', function(done) {
		queue(function(next) {
			setTimeout(function() {
				orderCalled.push(1);
				next();
			}, 10);
		});
		clock.tick(15);
		assert.equal(orderCalled[0], 0, 'Called first function');
		assert(orderCalled[1] === undefined, 'Has not yet called second function');
		clock.tick(15);
		assert.equal(orderCalled[1], 1, 'Called second function');
		done();
	});
});
<commit_msg>remove useless assertion<commit_after>'use strict';

goog.require('task_queue');

describe('task_queue', function() {
	var queue;
	var orderCalled;
	var clock = sinon.useFakeTimers();
	var assert = testUtils.unplanned();
	beforeEach(function() {
		queue = task_queue();
		orderCalled = [];
		queue(function(next) {
			setTimeout(function() {
				orderCalled.push(0);
				next();
			}, 10);
		});
		assert(orderCalled[0] === undefined, 'Has not yet called function');
	});

	it('should queue a function and call it', function(done) {
		clock.tick(15);
		assert.equal(orderCalled[0], 0, 'Function called');
		done();
	});

	it('should enqueue two functions, and call them in order', function(done) {
		queue(function(next) {
			setTimeout(function() {
				orderCalled.push(1);
				next();
			}, 10);
		});
		clock.tick(15);
		assert.equal(orderCalled[0], 0, 'Called first function');
		assert(orderCalled[1] === undefined, 'Has not yet called second function');
		clock.tick(15);
		assert.equal(orderCalled[1], 1, 'Called second function');
		done();
	});
});
<|endoftext|>


<commit_before>var GrovePi = require('node-grovepi').GrovePi;

var STATE_UNINITIALISED = 0;
var STATE_INITIALISED   = 1;

 var GrovePiBoard = function() {
   console.log('GrovePiBoard.js: Constructor');
   this.state = this.state || STATE_UNINITIALISED;
   if(this.state == STATE_UNINITIALISED){
     this.board = this.init.apply(this);
     this.commands = GrovePi.commands;
     this.state = STATE_INITIALISED;
   }
   console.log('GrovePiBoard.js: Init Complete');
   console.log(this.board);

 };

 GrovePiBoard.prototype.init = function() {
   console.log('GrovePiBoard.js: Init Function');
   var board = new GrovePi.board({
     debug: true,
     onError: function(err){
       console.error('GrovePiBoard.js: Something went wrong');
       console.error(err)
     },
     onInit: function(res) {
       console.log('GrovePiBoard.js: GrovePi onInit');
       if(res){
         console.log('GrovePiBoard.js: GrovePi Version :: ' + board.version());
       }
     }
   });
   board.init();
   return board;
 };

 GrovePiBoard.prototype.registerSensor = function(sensorType, pin, repeat, callback){
   if(sensorType == 'analog'){
   var self = this;
   var interval =  setInterval( function(){
       var value = self.readAnalogSensor.apply(self,[pin] );
       callback(value);
     }, repeat * 1000);

     return function(callback){
       clearInterval(interval);
       calllback();
     }
   } else if(sensorType == 'digital'){
     var self = this;
     var interval = setInterval(function(){
       var value = self.readDHTSensor.apply(self, [pin]);
       callback(value);
     }, repeat *1000);
     return function(callback){
       clearInterval(interval);
       calllback();
     }

   }
 };

 GrovePiBoard.prototype.readDHTSensor = function(pin){
   var dhtSensor = new GrovePi.sensors.DHTDigital(pin);
   var reading = dhtSensor.read();
   return reading;
 };

 GrovePiBoard.prototype.input = function(pin, state){
   this.board.writeBytes(this.commands.dWrite.concat([pin, state, this.commands.unused]));
 };

 GrovePiBoard.prototype.readAnalogSensor = function(pin, length){
   if(typeof length == 'undefined'){
     length - this.board.BYTESLEN;
   }
   var writeRet = this.board.writeBytes(this.commands.aRead.concat([pin, this.commands.unused, this.commands.unused]));
   if(writeRet){
     this.board.readByte();
     var bytes = this.board.readBytes(length);
     if(bytes instanceof Buffer) {
       return bytes[1] * 256 + bytes[2]
     } else {
       return false;
     }
   } else {
     return false;
   }
 };

module.exports = GrovePiBoard;
<commit_msg>Returning DHT reading as object instead of array<commit_after>var GrovePi = require('node-grovepi').GrovePi;

var STATE_UNINITIALISED = 0;
var STATE_INITIALISED   = 1;

 var GrovePiBoard = function() {
   console.log('GrovePiBoard.js: Constructor');
   this.state = this.state || STATE_UNINITIALISED;
   if(this.state == STATE_UNINITIALISED){
     this.board = this.init.apply(this);
     this.commands = GrovePi.commands;
     this.state = STATE_INITIALISED;
   }
   console.log('GrovePiBoard.js: Init Complete');
   console.log(this.board);

 };

 GrovePiBoard.prototype.init = function() {
   console.log('GrovePiBoard.js: Init Function');
   var board = new GrovePi.board({
     debug: true,
     onError: function(err){
       console.error('GrovePiBoard.js: Something went wrong');
       console.error(err)
     },
     onInit: function(res) {
       console.log('GrovePiBoard.js: GrovePi onInit');
       if(res){
         console.log('GrovePiBoard.js: GrovePi Version :: ' + board.version());
       }
     }
   });
   board.init();
   return board;
 };

 GrovePiBoard.prototype.registerSensor = function(sensorType, pin, repeat, callback){
   if(sensorType == 'analog'){
   var self = this;
   var interval =  setInterval( function(){
       var value = self.readAnalogSensor.apply(self,[pin] );
       callback(value);
     }, repeat * 1000);

     return function(callback){
       clearInterval(interval);
       calllback();
     }
   } else if(sensorType == 'digital'){
     var self = this;
     var interval = setInterval(function(){
       var value = self.readDHTSensor.apply(self, [pin]);
       callback(value);
     }, repeat *1000);
     return function(callback){
       clearInterval(interval);
       calllback();
     }

   }
 };

 GrovePiBoard.prototype.readDHTSensor = function(pin){
   var dhtSensor = new GrovePi.sensors.DHTDigital(pin);
   var reading = dhtSensor.read();
   var formatted = {};
   formatted.temperature = reading[0];
   formatted.humdity = reading[1];
   formatted.heatIndex = reading[3];
   return formatted;
 };

 GrovePiBoard.prototype.input = function(pin, state){
   this.board.writeBytes(this.commands.dWrite.concat([pin, state, this.commands.unused]));
 };

 GrovePiBoard.prototype.readAnalogSensor = function(pin, length){
   if(typeof length == 'undefined'){
     length - this.board.BYTESLEN;
   }
   var writeRet = this.board.writeBytes(this.commands.aRead.concat([pin, this.commands.unused, this.commands.unused]));
   if(writeRet){
     this.board.readByte();
     var bytes = this.board.readBytes(length);
     if(bytes instanceof Buffer) {
       return bytes[1] * 256 + bytes[2]
     } else {
       return false;
     }
   } else {
     return false;
   }
 };

module.exports = GrovePiBoard;
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

define(['./virtualsocket'], function(VirtualSocket) {
  /**
   * @typedef {Object} GameClient~Options
   * @property {string?} gameId id of game. This is how games and
   *           controller rendezvous.
   * @property {string?} url url of websocket server.
   */

  /**
   * GameClient is what a controller uses to talk with a
   * game's GameServer.
   *
   * Messages sent with `sendCmd` get sent to the game. Messages
   * from the game are delivered to callbacks registerd with
   * `addEventListener`.
   *
   * @constructor
   * @alias GameClient
   * @param {GameClient~Options} options options.
   */
  var GameClient = function(options) {
    options = options || {};
    var g_socket;
    var g_sendQueue = [];
    var eventListeners = {};

    if (!options.gameId) {
      var m = /games\/([^\/]+)\//.exec(window.location.href);
      if (m) {
        options.gameId = m[1];
      } else {
        throw new Error("can't derive gameId");
      }
    }

    /**
     * returns the game's gameId
     * @returns {String} the game's gameId
     */
    this.getGameId = function() {
      return options.gameId;
    };

    /**
     * @callback GameClient~Listener
     * @param {Object} data data from sender.
     */

    /**
     * Adds an event listener for the given event type.
     * event types are made up by you. Sending a command
     * from the game with
     *
     *     someNetPlayer.sendCmd('foo', {data: "bar"});
     *
     * Will arrive at the event listener registered for 'foo' here
     * and given an object `{data: "bar"}`.
     *
     * Note: Currently only 1 listener is allowed per eventType.
     * Adding a second listener for an specific eventType replaces
     * the previous listener for that type.
     *
     * @param {string} eventType name of event
     * @param {GameClient~Listener} listener callback to call for
     *        event.
     */
    this.addEventListener = function(eventType, listener) {
      eventListeners[eventType] = listener;
    };

    /**
     * Removes an eventListener
     * @param {string} eventType name of event
     */
    this.removeEventListener = function(eventType) {
      eventListeners[eventType] = undefined;
    };

    var sendEvent_ = function(eventType, args) {
      var fn = eventListeners[eventType];
      if (fn) {
        fn.apply(this, args);
      }
    }.bind(this);

    var connected_ = function() {
      for (var ii = 0; ii < g_sendQueue.length; ++ii) {
        g_socket.send(g_sendQueue[ii]);
      }
      g_sendQueue = [];
      console.log("connected");
      sendEvent_('connect');
    }.bind(this);

    var disconnected_ = function() {
      console.log("disconnected");
      sendEvent_('disconnect');
      eventListeners = {};
    }.bind(this);

    var processMessage_ = function(msg) {
      sendEvent_(msg.cmd, [msg.data]); // FIX: no need for this array?
    }.bind(this);

    var connect_ = function() {
      g_sendQueue = [];
      g_socket = new VirtualSocket(options);
      g_socket.on('connect', connected_.bind(this));
      g_socket.on('message', processMessage_.bind(this));
      g_socket.on('disconnect', disconnected_.bind(this));
    }.bind(this);

    var sendCmdLowLevel = function(cmd, data) {
      var msg = {
        cmd: cmd,
        data: data,
      };
      if (g_socket.readyState == WebSocket.CONNECTING) {
        g_sendQueue.push(msg);
      } else {
        g_socket.send(msg);
      }
    }.bind(this);

    /**
     * Sends a command to the game
     * @param {string} cmd name of command
     * @param {Object=} data any jsonifyable object.
     */
    this.sendCmd = function(cmd, data) {
      sendCmdLowLevel('update', {
        cmd: cmd,
        data: data,
      });
    };

    connect_();
    sendCmdLowLevel('join', options);
  };
  return GameClient;
});

<commit_msg>make gameclient print error for unhandled events<commit_after>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

define(['./virtualsocket'], function(VirtualSocket) {
  /**
   * @typedef {Object} GameClient~Options
   * @property {string?} gameId id of game. This is how games and
   *           controller rendezvous.
   * @property {string?} url url of websocket server.
   */

  /**
   * GameClient is what a controller uses to talk with a
   * game's GameServer.
   *
   * Messages sent with `sendCmd` get sent to the game. Messages
   * from the game are delivered to callbacks registerd with
   * `addEventListener`.
   *
   * @constructor
   * @alias GameClient
   * @param {GameClient~Options} options options.
   */
  var GameClient = function(options) {
    options = options || {};
    var g_socket;
    var g_sendQueue = [];
    var eventListeners = {};

    if (!options.gameId) {
      var m = /games\/([^\/]+)\//.exec(window.location.href);
      if (m) {
        options.gameId = m[1];
      } else {
        throw new Error("can't derive gameId");
      }
    }

    /**
     * returns the game's gameId
     * @returns {String} the game's gameId
     */
    this.getGameId = function() {
      return options.gameId;
    };

    /**
     * @callback GameClient~Listener
     * @param {Object} data data from sender.
     */

    /**
     * Adds an event listener for the given event type.
     * event types are made up by you. Sending a command
     * from the game with
     *
     *     someNetPlayer.sendCmd('foo', {data: "bar"});
     *
     * Will arrive at the event listener registered for 'foo' here
     * and given an object `{data: "bar"}`.
     *
     * Note: Currently only 1 listener is allowed per eventType.
     * Adding a second listener for an specific eventType replaces
     * the previous listener for that type.
     *
     * @param {string} eventType name of event
     * @param {GameClient~Listener} listener callback to call for
     *        event.
     */
    this.addEventListener = function(eventType, listener) {
      eventListeners[eventType] = listener;
    };

    /**
     * Removes an eventListener
     * @param {string} eventType name of event
     */
    this.removeEventListener = function(eventType) {
      eventListeners[eventType] = undefined;
    };

    var sendEvent_ = function(eventType, args) {
      var fn = eventListeners[eventType];
      if (fn) {
        fn.apply(this, args);
      } else {
        console.error("unknown event: " + eventType);
      }
    }.bind(this);

    var connected_ = function() {
      for (var ii = 0; ii < g_sendQueue.length; ++ii) {
        g_socket.send(g_sendQueue[ii]);
      }
      g_sendQueue = [];
      console.log("connected");
      sendEvent_('connect');
    }.bind(this);

    var disconnected_ = function() {
      console.log("disconnected");
      sendEvent_('disconnect');
      eventListeners = {};
    }.bind(this);

    var processMessage_ = function(msg) {
      sendEvent_(msg.cmd, [msg.data]); // FIX: no need for this array?
    }.bind(this);

    var connect_ = function() {
      g_sendQueue = [];
      g_socket = new VirtualSocket(options);
      g_socket.on('connect', connected_.bind(this));
      g_socket.on('message', processMessage_.bind(this));
      g_socket.on('disconnect', disconnected_.bind(this));
    }.bind(this);

    var sendCmdLowLevel = function(cmd, data) {
      var msg = {
        cmd: cmd,
        data: data,
      };
      if (g_socket.readyState == WebSocket.CONNECTING) {
        g_sendQueue.push(msg);
      } else {
        g_socket.send(msg);
      }
    }.bind(this);

    /**
     * Sends a command to the game
     * @param {string} cmd name of command
     * @param {Object=} data any jsonifyable object.
     */
    this.sendCmd = function(cmd, data) {
      sendCmdLowLevel('update', {
        cmd: cmd,
        data: data,
      });
    };

    connect_();
    sendCmdLowLevel('join', options);
  };
  return GameClient;
});

<|endoftext|>


<commit_before>/**
 * Unit Tests for maps and map cells.
 *
 */

var chai = require("chai");
var expect = chai.expect;
var RG = require("../roguelike.js");

var Actor = RG.RogueActor;
var Action = RG.RogueAction;
var Level = RG.RogueLevel;
var Element = RG.RogueElement;
var Cell = RG.MapCell;

//---------------------------------------------------------------------------
// MAP CELL
//---------------------------------------------------------------------------

describe('Basic properties of map cell', function() {
    it('Holds elements and actors', function() {
        var actor = new Actor(true);
        var cell = new Cell(0, 0, new Element("wall"));
        expect(cell.isFree()).to.equal(false);
        expect(cell.hasPropType("wall")).to.equal(true);
        expect(cell.hasPropType("actors")).to.equal(false);
        expect(cell.lightPasses()).to.equal(false);

        // Setting an element property of the cell
        var floorElem = new Element("floor");
        cell.setProp("elements", floorElem);
        expect(cell.hasPropType("floor")).to.equal(true);
        expect(cell.hasProp("elements")).to.equal(true);

        // Removing a property
        expect(cell.removeProp("elements", floorElem)).to.equal(true);
        expect(cell.hasPropType("floor")).to.equal(false);
        expect(cell.hasProp("elements")).to.equal(false);

        // Retrieving a property
        var propNull = cell.getProp("xxx");
        expect(propNull).to.equal(null);

        // Actors in cell, cell with actor is not free
        var floor = new Element("floor");
        var fCell = new Cell(1, 1, floor);
        expect(fCell.isFree()).to.equal(true);
        fCell.setProp("actors", actor);
        expect(fCell.isFree()).to.equal(false);
        expect(fCell.lightPasses()).to.equal(true);
        expect(fCell.hasProp("actors")).to.equal(true);
        expect(fCell.hasProp("items")).to.equal(false);
    });
});

describe('Retrieving styling classes for cells', function() {
    it('description', function() {
        var cell = new Cell(0, 0, new Element("wall"));
        expect(RG.getStyleClassForCell(cell)).to.equal("cell-element-wall");

        var floorCell = new Cell(0, 0, new Element("floor"));
        var actor = new Actor(true);
        floorCell.setProp("actors", actor);
        expect(RG.getStyleClassForCell(floorCell)).to.equal("cell-actors");
    });
});

//---------------------------------------------------------------------------
// MAP UNIT TESTS
//---------------------------------------------------------------------------

describe('Tests to check that basic operations for map work', function() {
    var mapgen = new RG.RogueMapGen();
    mapgen.setGen("arena", 10, 10);
    var actor = new Actor(true);
    var level1 = new Level(10, 10);
    var level2 = new Level(20, 20);

    it('Is initialized as empty and having floors', function() {
        var map = mapgen.getMap();
        var map2 = mapgen.getMap();
        level1.setMap(map);
        level2.setMap(map);

        expect(map.hasXY(0,0)).to.equal(true);
        expect(map.hasXY(9,9)).to.equal(true);
        expect(map.hasXY(10,10)).to.equal(false);

        var freeCells = map.getFree();
        expect(freeCells.length).to.equal(8*8);
        for (var i = 0; i < freeCells.length; i++) {
            expect(freeCells[i].isFree()).to.equal(true);
            expect(freeCells[i].lightPasses()).to.equal(true);
        }

        var actorNotInLevel = new Actor(false);
        actor.getFOVRange = function() {return 1;}; // Override default
        level1.addActor(actor, 4, 4);
        var cells = map.getVisibleCells(actor);
        expect(cells.length).to.equal(9);
        var zeroCells = map.getVisibleCells(actorNotInLevel);
        expect(zeroCells.length).to.equal(0);

        // After setting x,y try again
        actorNotInLevel.setXY(4,4);
        actorNotInLevel.getFOVRange = function() {return 5;}; // Override default
        zeroCells = map.getVisibleCells(actorNotInLevel);
        expect(zeroCells.length).to.equal(0);

        expect(level1.getMap().getCell(4,4).isExplored()).to.equal(false);
        level1.exploreCells(actor);
        expect(level1.getMap().getCell(4,4).isExplored()).to.equal(true);

    });
});

//---------------------------------------------------------------------------
// LEVEL UNIT TESTS
//---------------------------------------------------------------------------

describe('Moving actors around in the game', function() {
    it('Moves but is blocked by walls.', function() {
        var actor = new Actor(true);
        var level = new Level(10, 10);
        var mapgen = new RG.RogueMapGen();
        mapgen.setGen("arena", 10, 10);
        var map = mapgen.getMap();
        level.setMap(map);
        level.addActor(actor, 1, 2);
        expect(actor.getX()).to.equal(1);
        expect(actor.getY()).to.equal(2);

        // Actors x,y changes due to move
        expect(level.moveActorTo(actor, 2, 3)).to.equal(true);
        expect(actor.getX()).to.equal(2);
        expect(actor.getY()).to.equal(3);

        // Create a wall to block the passage
        var wall = new Element("wall");
        level.getMap().setBaseElemXY(4, 4, wall);
        expect(level.moveActorTo(actor, 4, 4)).to.equal(false);
        expect(actor.getX(), "X didn't change due to wall").to.equal(2);
        expect(actor.getY()).to.equal(3);

    });
});

<commit_msg>Added unit tests for the item in a map cell.<commit_after>/**
 * Unit Tests for maps and map cells.
 *
 */

var chai = require("chai");
var expect = chai.expect;
var RG = require("../roguelike.js");

var Actor = RG.RogueActor;
var Action = RG.RogueAction;
var Level = RG.RogueLevel;
var Element = RG.RogueElement;
var Cell = RG.MapCell;
var Item = RG.RogueItem;

//---------------------------------------------------------------------------
// MAP CELL
//---------------------------------------------------------------------------

describe('Basic properties of map cell', function() {
    it('Holds elements and actors', function() {
        var actor = new Actor(true);
        var cell = new Cell(0, 0, new Element("wall"));
        expect(cell.isFree()).to.equal(false);
        expect(cell.hasPropType("wall")).to.equal(true);
        expect(cell.hasPropType("actors")).to.equal(false);
        expect(cell.lightPasses()).to.equal(false);

        // Setting an element property of the cell
        var floorElem = new Element("floor");
        cell.setProp("elements", floorElem);
        expect(cell.hasPropType("floor")).to.equal(true);
        expect(cell.hasProp("elements")).to.equal(true);

        // Removing a property
        expect(cell.removeProp("elements", floorElem)).to.equal(true);
        expect(cell.hasPropType("floor")).to.equal(false);
        expect(cell.hasProp("elements")).to.equal(false);

        // Retrieving a property
        var propNull = cell.getProp("xxx");
        expect(propNull).to.equal(null);

        // Actors in cell, cell with actor is not free
        var floor = new Element("floor");
        var fCell = new Cell(1, 1, floor);
        expect(fCell.isFree()).to.equal(true);
        fCell.setProp("actors", actor);
        expect(fCell.isFree()).to.equal(false);
        expect(fCell.lightPasses()).to.equal(true);
        expect(fCell.hasProp("actors")).to.equal(true);
        expect(fCell.hasProp("items")).to.equal(false);
    });
});

describe('Retrieving styling classes for cells', function() {
    it('description', function() {
        var cell = new Cell(0, 0, new Element("wall"));
        cell.setExplored();
        expect(RG.getStyleClassForCell(cell)).to.equal("cell-element-wall");

        var floorCell = new Cell(0, 0, new Element("floor"));
        var actor = new Actor(true);
        floorCell.setProp("actors", actor);
        floorCell.setExplored();
        expect(RG.getStyleClassForCell(floorCell)).to.equal("cell-actors");
    });
});

describe('Items in map cells', function() {
    it('description', function() {
        var cell = new Cell(0, 0, new Element("floor"));
        cell.setExplored();
        var item = new Item("food");
        cell.setProp("items", item);
        expect(cell.hasProp("items")).to.equal(true);

        var items = cell.getProp("items");
        expect(items.length).to.equal(1);

        expect(RG.getStyleClassForCell(cell)).to.equal("cell-items");

    });
});

//---------------------------------------------------------------------------
// MAP UNIT TESTS
//---------------------------------------------------------------------------

describe('Tests to check that basic operations for map work', function() {
    var mapgen = new RG.RogueMapGen();
    mapgen.setGen("arena", 10, 10);
    var actor = new Actor(true);
    var level1 = new Level(10, 10);
    var level2 = new Level(20, 20);

    it('Is initialized as empty and having floors', function() {
        var map = mapgen.getMap();
        var map2 = mapgen.getMap();
        level1.setMap(map);
        level2.setMap(map);

        expect(map.hasXY(0,0)).to.equal(true);
        expect(map.hasXY(9,9)).to.equal(true);
        expect(map.hasXY(10,10)).to.equal(false);

        var freeCells = map.getFree();
        expect(freeCells.length).to.equal(8*8);
        for (var i = 0; i < freeCells.length; i++) {
            expect(freeCells[i].isFree()).to.equal(true);
            expect(freeCells[i].lightPasses()).to.equal(true);
        }

        var actorNotInLevel = new Actor(false);
        actor.getFOVRange = function() {return 1;}; // Override default
        level1.addActor(actor, 4, 4);
        var cells = map.getVisibleCells(actor);
        expect(cells.length).to.equal(9);
        var zeroCells = map.getVisibleCells(actorNotInLevel);
        expect(zeroCells.length).to.equal(0);

        // After setting x,y try again
        actorNotInLevel.setXY(4,4);
        actorNotInLevel.getFOVRange = function() {return 5;}; // Override default
        zeroCells = map.getVisibleCells(actorNotInLevel);
        expect(zeroCells.length).to.equal(0);

        expect(level1.getMap().getCell(4,4).isExplored()).to.equal(false);
        level1.exploreCells(actor);
        expect(level1.getMap().getCell(4,4).isExplored()).to.equal(true);

    });
});

//---------------------------------------------------------------------------
// LEVEL UNIT TESTS
//---------------------------------------------------------------------------

describe('Moving actors around in the game', function() {
    it('Moves but is blocked by walls.', function() {
        var actor = new Actor(true);
        var level = new Level(10, 10);
        var mapgen = new RG.RogueMapGen();
        mapgen.setGen("arena", 10, 10);
        var map = mapgen.getMap();
        level.setMap(map);
        level.addActor(actor, 1, 2);
        expect(actor.getX()).to.equal(1);
        expect(actor.getY()).to.equal(2);

        // Actors x,y changes due to move
        expect(level.moveActorTo(actor, 2, 3)).to.equal(true);
        expect(actor.getX()).to.equal(2);
        expect(actor.getY()).to.equal(3);

        // Create a wall to block the passage
        var wall = new Element("wall");
        level.getMap().setBaseElemXY(4, 4, wall);
        expect(level.moveActorTo(actor, 4, 4)).to.equal(false);
        expect(actor.getX(), "X didn't change due to wall").to.equal(2);
        expect(actor.getY()).to.equal(3);

    });
});

<|endoftext|>


<commit_before>const Joi = require('joi');

module.exports = {
  query: {
    q: Joi.string().allow(''),
    'page[number]': Joi.number().integer().min(0).max(300),
    'page[size]': Joi.number().integer().min(1).max(10),
    'page[type]': Joi.string().valid('search', 'results-list'),
    'ajax': Joi.boolean().truthy('true').falsy('false'),
    'random': Joi.number().integer().min(1).max(50)
  }
};
<commit_msg>reduce paginatin to 10 pages<commit_after>const Joi = require('joi');

module.exports = {
  query: {
    q: Joi.string().allow(''),
    'page[number]': Joi.number().integer().min(0).max(10),
    'page[size]': Joi.number().integer().min(1).max(100),
    'page[type]': Joi.string().valid('search', 'results-list'),
    'ajax': Joi.boolean().truthy('true').falsy('false'),
    'random': Joi.number().integer().min(1).max(50)
  }
};
<|endoftext|>


<commit_before>var _ = require('underscore'),
    ES = require('./es');

// STILL TO BE DONE: filter by time range, filter by elapsed millis

var Histogram = React.createClass({

  dims: function(){
    var margin = {top: 5, right: 10, bottom: 20, left: 10},
        full = {width:this.props.width,height:this.props.height},
        inner = {
          width:(full.width - margin.left - margin.right),
          height:(full.height - margin.top - margin.bottom)
        };

    return { margin:margin,full:full,inner:inner };
  },

  scales: function(){
    var dims = this.dims();
    var props = this.props;
    var countBuckets = props.data;
    var buckets = _.map(_.keys(countBuckets),parseFloat);

    var x = d3.scale.ordinal()
      .domain(buckets)
      .rangeRoundBands([dims.margin.left, dims.inner.width]);

    var xAxis = d3.scale.linear()
      .domain([ _.min(buckets), _.max(buckets) ])
      .range([dims.margin.left, dims.inner.width]);

    var y = d3.scale.linear()
      .domain([0, _.max(countBuckets)])
        .range([dims.inner.height,dims.margin.top]);

    return {x:x,xAxis:xAxis,y:y};
  },

  generateXAxis: function(){
    var xAxis = d3.svg.axis()
      .scale(this.scales().xAxis)
      .ticks(10)
      .tickFormat(function(d){ return ""+d+"ms"; })
      .orient("bottom");

    xAxis(d3.select(this.getDOMNode()).select('.x.axis'));
  },

  componentDidMount: function(){
    this.generateXAxis();
  },

  render: function(){
    var dims = this.dims();
    var props = this.props;
    var countBuckets = props.data;
    var scales = this.scales();

    var bars = _.map( props.data, function(count,bucket){
      var transform = "translate("+scales.x(+bucket)+","+scales.y(count)+")";
      return <g className="bar" transform={transform} data-bucket={bucket} data-count={count}>
        <rect
          x="1"
          width={scales.x.rangeBand()}
          height={dims.inner.height-scales.y(count)}
        >
         </rect>
      </g>;
    });

    // x axis part is filled out by componentDidUpdate
    return <svg width={dims.full.width} height={dims.full.height}>
      <g className="x axis" transform={"translate(0,"+dims.inner.height+")"}></g>
      {bars}
    </svg>;

  }
});

var AppComponent = React.createClass({
  render: function(){
    var traces = _.map(this.props.traceRoots,function(traceRoot){
      var millis = ""+traceRoot.elapsedMillis+"ms";
      var timestamp = traceRoot['@timestamp'];
      var url = "trace.html?"+traceRoot.Correlation_ID;
      return

          {timestamp}
          [{millis}]

;
    });

    return

traces starting with {this.props.serviceName}

        <Histogram width={500} height={200} data={this.props.histogram}/>

{traces}

;
  }
});

var serviceName = window.location.search.substr(1);

ES.getRootTracesForService(serviceName).then(function(result){
  React.render(
      <AppComponent serviceName={serviceName} traceRoots={result.spans} histogram={result.histogram}/>,
      document.getElementById('appContainer')
  );
});
<commit_msg>WIP adding selection highlighting<commit_after>var _ = require('underscore'),
    ES = require('./es');

function translationTransform(x,y){
  return "translate("+x+","+y+")";
}

// STILL TO BE DONE: filter by time range, filter by elapsed millis

var Histogram = React.createClass({

  dims: function(){
    var margin = {top: 5, right: 10, bottom: 20, left: 10},
        full = {width:this.props.width,height:this.props.height},
        inner = {
          width:(full.width - margin.left - margin.right),
          height:(full.height - margin.top - margin.bottom)
        };

    return { margin:margin,full:full,inner:inner };
  },

  scales: function(){
    var dims = this.dims();
    var props = this.props;
    var countBuckets = props.data;
    var buckets = _.map(_.keys(countBuckets),parseFloat);

    var x = d3.scale.ordinal()
      .domain(buckets)
      .rangeRoundBands([dims.margin.left, dims.inner.width]);

    var xLinear = d3.scale.linear()
      .domain([ _.min(buckets), _.max(buckets) ])
      .range([dims.margin.left, dims.inner.width]);

    var y = d3.scale.linear()
      .domain([0, _.max(countBuckets)])
        .range([dims.inner.height,dims.margin.top]);

    return {x:x,xLinear:xLinear,y:y};
  },

  generateXAxis: function(){
    var xAxis = d3.svg.axis()
      .scale(this.scales().xLinear)
      .ticks(10)
      .tickFormat(function(d){ return ""+d+"ms"; })
      .orient("bottom");

    xAxis(d3.select(this.getDOMNode()).select('.x.axis'));
  },

  componentDidMount: function(){
    this.generateXAxis();
  },

  render: function(){
    var dims = this.dims();
    var props = this.props;
    var countBuckets = props.data;
    var scales = this.scales();

    var selectionRange = [1000,2350];

    var x = scales.xLinear(selectionRange[1])-scales.xLinear(selectionRange[0])
    var selection = <rect x={scales.xLinear(selectionRange[0])}
        y={2}
        width={x}
        height={dims.inner.height-2}
        className="bar"
      >
        <foo></foo>
      </rect>;

    var bars = _.map( props.data, function(count,bucket){
      return <g
          className="bar"
          transform={translationTransform(scales.x(+bucket),scales.y(count))}
          data-bucket={bucket}
          data-count={count}
        >
          <rect
            x="1"
            width={scales.x.rangeBand()}
            height={dims.inner.height-scales.y(count)}
          >
         </rect>
      </g>;
    });

    // x axis part is filled out by componentDidUpdate
    return <svg width={dims.full.width} height={dims.full.height}>
      {selection}
      <g className="x axis" transform={translationTransform(0,dims.inner.height)}></g>
      {bars}
    </svg>;

  }
});

var AppComponent = React.createClass({
  render: function(){
    var traces = _.map(this.props.traceRoots,function(traceRoot){
      var millis = ""+traceRoot.elapsedMillis+"ms";
      var timestamp = traceRoot['@timestamp'];
      var url = "trace.html?"+traceRoot.Correlation_ID;
      return

          {timestamp}
          [{millis}]

;
    });

    return

traces starting with {this.props.serviceName}

        <Histogram width={500} height={200} data={this.props.histogram}/>

{traces}

;
  }
});

var serviceName = window.location.search.substr(1);

ES.getRootTracesForService(serviceName).then(function(result){
  React.render(
      <AppComponent serviceName={serviceName} traceRoots={result.spans} histogram={result.histogram}/>,
      document.getElementById('appContainer')
  );
});
<|endoftext|>


<commit_before>const webpack = require('webpack');
const path = require('path');
const qs = require('qs');
const autoprefixer = require('autoprefixer');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const imageminMozjpeg = require('imagemin-mozjpeg');

const mergeWithConcat = require('./util/mergeWithConcat');
const addHotMiddleware = require('./util/addHotMiddleware');
const webpackConfigProduction = require('./webpack.config.production');
const webpackConfigWatch = require('./webpack.config.watch');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

const jsLoader = {
  test: /\.js$/,
  exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
  loaders: [{
    loader: 'babel',
    query: {
      presets: [[path.resolve('./node_modules/babel-preset-es2015'), { modules: false }]],
      cacheDirectory: true,
    },
  }],
};

if (config.enabled.watcher) {
  jsLoader.loaders.unshift('monkey-hot?sourceType=module');
}

const webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  module: {
    preLoaders: [
      {
        test: /\.js?$/,
        include: config.paths.assets,
        loader: 'eslint',
      },
    ],
    loaders: [
      jsLoader,
      {
        test: /\.css$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss',
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss',
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        include: config.paths.assets,
        loaders: [
          `file?${qs.stringify({
            name: '[path][name].[ext]',
          })}`,
        ],
      },
      {
        test: /\.(ttf|eot)$/,
        include: config.paths.assets,
        loader: `file?${qs.stringify({
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.woff2?$/,
        include: config.paths.assets,
        loader: `url?${qs.stringify({
          limit: 10000,
          mimetype: 'application/font-woff',
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules|bower_components/,
        loader: 'file',
        query: {
          name: `vendor/${config.cacheBusting}.[ext]`,
        },
      },
    ],
  },
  modules: [
    config.paths.assets,
    'node_modules',
    'bower_components',
  ],
  enforceExtensions: false,
  externals: {
    jquery: 'jQuery',
  },
  plugins: [
    new CleanPlugin([config.paths.dist], config.paths.root),
    new ImageminPlugin({
      optipng: {
        optimizationLevel: 7,
      },
      gifsicle: {
        optimizationLevel: 3,
      },
      pngquant: {
        quality: '65-90',
        speed: 4,
      },
      svgo: {
        removeUnknownsAndDefaults: false,
        cleanupIDs: false,
      },
      jpegtran: null,
      plugins: [imageminMozjpeg({
        quality: 75,
      })],
      disable: (config.enabled.watcher),
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: true,
      disable: (config.enabled.watcher),
    }),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      Tether: 'tether',
      'window.Tether': 'tether',
    }),
    new webpack.DefinePlugin({
      WEBPACK_PUBLIC_PATH: (config.enabled.watcher)
        ? JSON.stringify(config.publicPath)
        : false,
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.minify,
      debug: config.enabled.watcher,
      stats: { colors: true },
      postcss: [
        autoprefixer({
          browsers: [
            'last 2 versions',
            'android 4',
            'opera 12',
          ],
        }),
      ],
      eslint: {
        failOnWarning: false,
        failOnError: true,
      },
    }),
  ],
};

module.exports = webpackConfig;

if (config.env.production) {
  module.exports = mergeWithConcat(webpackConfig, webpackConfigProduction);
}

if (config.enabled.watcher) {
  module.exports = mergeWithConcat(webpackConfig, webpackConfigWatch, {
    entry: addHotMiddleware(webpackConfig.entry),
  });
}

if (config.enabled.uglifyJs) {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: config.enabled.sourceMaps,
    })
  );
}
<commit_msg>Add support for .ico files (#1740)<commit_after>const webpack = require('webpack');
const path = require('path');
const qs = require('qs');
const autoprefixer = require('autoprefixer');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const imageminMozjpeg = require('imagemin-mozjpeg');

const mergeWithConcat = require('./util/mergeWithConcat');
const addHotMiddleware = require('./util/addHotMiddleware');
const webpackConfigProduction = require('./webpack.config.production');
const webpackConfigWatch = require('./webpack.config.watch');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

const jsLoader = {
  test: /\.js$/,
  exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
  loaders: [{
    loader: 'babel',
    query: {
      presets: [[path.resolve('./node_modules/babel-preset-es2015'), { modules: false }]],
      cacheDirectory: true,
    },
  }],
};

if (config.enabled.watcher) {
  jsLoader.loaders.unshift('monkey-hot?sourceType=module');
}

const webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  module: {
    preLoaders: [
      {
        test: /\.js?$/,
        include: config.paths.assets,
        loader: 'eslint',
      },
    ],
    loaders: [
      jsLoader,
      {
        test: /\.css$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss',
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss',
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        loaders: [
          `file?${qs.stringify({
            name: '[path][name].[ext]',
          })}`,
        ],
      },
      {
        test: /\.(ttf|eot)$/,
        include: config.paths.assets,
        loader: `file?${qs.stringify({
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.woff2?$/,
        include: config.paths.assets,
        loader: `url?${qs.stringify({
          limit: 10000,
          mimetype: 'application/font-woff',
          name: `[path]${assetsFilenames}.[ext]`,
        })}`,
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules|bower_components/,
        loader: 'file',
        query: {
          name: `vendor/${config.cacheBusting}.[ext]`,
        },
      },
    ],
  },
  modules: [
    config.paths.assets,
    'node_modules',
    'bower_components',
  ],
  enforceExtensions: false,
  externals: {
    jquery: 'jQuery',
  },
  plugins: [
    new CleanPlugin([config.paths.dist], config.paths.root),
    new ImageminPlugin({
      optipng: {
        optimizationLevel: 7,
      },
      gifsicle: {
        optimizationLevel: 3,
      },
      pngquant: {
        quality: '65-90',
        speed: 4,
      },
      svgo: {
        removeUnknownsAndDefaults: false,
        cleanupIDs: false,
      },
      jpegtran: null,
      plugins: [imageminMozjpeg({
        quality: 75,
      })],
      disable: (config.enabled.watcher),
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: true,
      disable: (config.enabled.watcher),
    }),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      Tether: 'tether',
      'window.Tether': 'tether',
    }),
    new webpack.DefinePlugin({
      WEBPACK_PUBLIC_PATH: (config.enabled.watcher)
        ? JSON.stringify(config.publicPath)
        : false,
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.minify,
      debug: config.enabled.watcher,
      stats: { colors: true },
      postcss: [
        autoprefixer({
          browsers: [
            'last 2 versions',
            'android 4',
            'opera 12',
          ],
        }),
      ],
      eslint: {
        failOnWarning: false,
        failOnError: true,
      },
    }),
  ],
};

module.exports = webpackConfig;

if (config.env.production) {
  module.exports = mergeWithConcat(webpackConfig, webpackConfigProduction);
}

if (config.enabled.watcher) {
  module.exports = mergeWithConcat(webpackConfig, webpackConfigWatch, {
    entry: addHotMiddleware(webpackConfig.entry),
  });
}

if (config.enabled.uglifyJs) {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: config.enabled.sourceMaps,
    })
  );
}
<|endoftext|>