(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

function EventEmitter() {
  this._events = this._events || {};
  this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;

EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
  if (!isNumber(n) || n < 0 || isNaN(n))
    throw TypeError('n must be a positive number');
  this._maxListeners = n;
  return this;
};

EventEmitter.prototype.emit = function(type) {
  var er, handler, len, args, i, listeners;

  if (!this._events)
    this._events = {};

  // If there is no 'error' event listener then throw.
  if (type === 'error') {
    if (!this._events.error ||
        (isObject(this._events.error) && !this._events.error.length)) {
      er = arguments[1];
      if (er instanceof Error) {
        throw er; // Unhandled 'error' event
      }
      throw TypeError('Uncaught, unspecified "error" event.');
    }
  }

  handler = this._events[type];

  if (isUndefined(handler))
    return false;

  if (isFunction(handler)) {
    switch (arguments.length) {
      // fast cases
      case 1:
        handler.call(this);
        break;
      case 2:
        handler.call(this, arguments[1]);
        break;
      case 3:
        handler.call(this, arguments[1], arguments[2]);
        break;
      // slower
      default:
        len = arguments.length;
        args = new Array(len - 1);
        for (i = 1; i < len; i++)
          args[i - 1] = arguments[i];
        handler.apply(this, args);
    }
  } else if (isObject(handler)) {
    len = arguments.length;
    args = new Array(len - 1);
    for (i = 1; i < len; i++)
      args[i - 1] = arguments[i];

    listeners = handler.slice();
    len = listeners.length;
    for (i = 0; i < len; i++)
      listeners[i].apply(this, args);
  }

  return true;
};

EventEmitter.prototype.addListener = function(type, listener) {
  var m;

  if (!isFunction(listener))
    throw TypeError('listener must be a function');

  if (!this._events)
    this._events = {};

  // To avoid recursion in the case that type === "newListener"! Before
  // adding it to the listeners, first emit "newListener".
  if (this._events.newListener)
    this.emit('newListener', type,
              isFunction(listener.listener) ?
              listener.listener : listener);

  if (!this._events[type])
    // Optimize the case of one listener. Don't need the extra array object.
    this._events[type] = listener;
  else if (isObject(this._events[type]))
    // If we've already got an array, just append.
    this._events[type].push(listener);
  else
    // Adding the second element, need to change to array.
    this._events[type] = [this._events[type], listener];

  // Check for listener leak
  if (isObject(this._events[type]) && !this._events[type].warned) {
    var m;
    if (!isUndefined(this._maxListeners)) {
      m = this._maxListeners;
    } else {
      m = EventEmitter.defaultMaxListeners;
    }

    if (m && m > 0 && this._events[type].length > m) {
      this._events[type].warned = true;
      console.error('(node) warning: possible EventEmitter memory ' +
                    'leak detected. %d listeners added. ' +
                    'Use emitter.setMaxListeners() to increase limit.',
                    this._events[type].length);
      if (typeof console.trace === 'function') {
        // not supported in IE 10
        console.trace();
      }
    }
  }

  return this;
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.once = function(type, listener) {
  if (!isFunction(listener))
    throw TypeError('listener must be a function');

  var fired = false;

  function g() {
    this.removeListener(type, g);

    if (!fired) {
      fired = true;
      listener.apply(this, arguments);
    }
  }

  g.listener = listener;
  this.on(type, g);

  return this;
};

// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
  var list, position, length, i;

  if (!isFunction(listener))
    throw TypeError('listener must be a function');

  if (!this._events || !this._events[type])
    return this;

  list = this._events[type];
  length = list.length;
  position = -1;

  if (list === listener ||
      (isFunction(list.listener) && list.listener === listener)) {
    delete this._events[type];
    if (this._events.removeListener)
      this.emit('removeListener', type, listener);

  } else if (isObject(list)) {
    for (i = length; i-- > 0;) {
      if (list[i] === listener ||
          (list[i].listener && list[i].listener === listener)) {
        position = i;
        break;
      }
    }

    if (position < 0)
      return this;

    if (list.length === 1) {
      list.length = 0;
      delete this._events[type];
    } else {
      list.splice(position, 1);
    }

    if (this._events.removeListener)
      this.emit('removeListener', type, listener);
  }

  return this;
};

EventEmitter.prototype.removeAllListeners = function(type) {
  var key, listeners;

  if (!this._events)
    return this;

  // not listening for removeListener, no need to emit
  if (!this._events.removeListener) {
    if (arguments.length === 0)
      this._events = {};
    else if (this._events[type])
      delete this._events[type];
    return this;
  }

  // emit removeListener for all listeners on all events
  if (arguments.length === 0) {
    for (key in this._events) {
      if (key === 'removeListener') continue;
      this.removeAllListeners(key);
    }
    this.removeAllListeners('removeListener');
    this._events = {};
    return this;
  }

  listeners = this._events[type];

  if (isFunction(listeners)) {
    this.removeListener(type, listeners);
  } else {
    // LIFO order
    while (listeners.length)
      this.removeListener(type, listeners[listeners.length - 1]);
  }
  delete this._events[type];

  return this;
};

EventEmitter.prototype.listeners = function(type) {
  var ret;
  if (!this._events || !this._events[type])
    ret = [];
  else if (isFunction(this._events[type]))
    ret = [this._events[type]];
  else
    ret = this._events[type].slice();
  return ret;
};

EventEmitter.listenerCount = function(emitter, type) {
  var ret;
  if (!emitter._events || !emitter._events[type])
    ret = 0;
  else if (isFunction(emitter._events[type]))
    ret = 1;
  else
    ret = emitter._events[type].length;
  return ret;
};

function isFunction(arg) {
  return typeof arg === 'function';
}

function isNumber(arg) {
  return typeof arg === 'number';
}

function isObject(arg) {
  return typeof arg === 'object' && arg !== null;
}

function isUndefined(arg) {
  return arg === void 0;
}

},{}],2:[function(require,module,exports){
if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  };
} else {
  // old school shim for old browsers
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    var TempCtor = function () {}
    TempCtor.prototype = superCtor.prototype
    ctor.prototype = new TempCtor()
    ctor.prototype.constructor = ctor
  }
}

},{}],3:[function(require,module,exports){
// shim for using process in browser

var process = module.exports = {};
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = setTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    clearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        setTimeout(drainQueue, 0);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };

},{}],4:[function(require,module,exports){
module.exports = function isBuffer(arg) {
  return arg && typeof arg === 'object'
    && typeof arg.copy === 'function'
    && typeof arg.fill === 'function'
    && typeof arg.readUInt8 === 'function';
}
},{}],5:[function(require,module,exports){
(function (process,global){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
  if (!isString(f)) {
    var objects = [];
    for (var i = 0; i < arguments.length; i++) {
      objects.push(inspect(arguments[i]));
    }
    return objects.join(' ');
  }

  var i = 1;
  var args = arguments;
  var len = args.length;
  var str = String(f).replace(formatRegExp, function(x) {
    if (x === '%%') return '%';
    if (i >= len) return x;
    switch (x) {
      case '%s': return String(args[i++]);
      case '%d': return Number(args[i++]);
      case '%j':
        try {
          return JSON.stringify(args[i++]);
        } catch (_) {
          return '[Circular]';
        }
      default:
        return x;
    }
  });
  for (var x = args[i]; i < len; x = args[++i]) {
    if (isNull(x) || !isObject(x)) {
      str += ' ' + x;
    } else {
      str += ' ' + inspect(x);
    }
  }
  return str;
};


// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
  // Allow for deprecating things in the process of starting up.
  if (isUndefined(global.process)) {
    return function() {
      return exports.deprecate(fn, msg).apply(this, arguments);
    };
  }

  if (process.noDeprecation === true) {
    return fn;
  }

  var warned = false;
  function deprecated() {
    if (!warned) {
      if (process.throwDeprecation) {
        throw new Error(msg);
      } else if (process.traceDeprecation) {
        console.trace(msg);
      } else {
        console.error(msg);
      }
      warned = true;
    }
    return fn.apply(this, arguments);
  }

  return deprecated;
};


var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
  if (isUndefined(debugEnviron))
    debugEnviron = process.env.NODE_DEBUG || '';
  set = set.toUpperCase();
  if (!debugs[set]) {
    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
      var pid = process.pid;
      debugs[set] = function() {
        var msg = exports.format.apply(exports, arguments);
        console.error('%s %d: %s', set, pid, msg);
      };
    } else {
      debugs[set] = function() {};
    }
  }
  return debugs[set];
};


/**
 * Echos the value of a value. Trys to print the value out
 * in the best way possible given the different types.
 *
 * @param {Object} obj The object to print out.
 * @param {Object} opts Optional options object that alters the output.
 */
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
  // default options
  var ctx = {
    seen: [],
    stylize: stylizeNoColor
  };
  // legacy...
  if (arguments.length >= 3) ctx.depth = arguments[2];
  if (arguments.length >= 4) ctx.colors = arguments[3];
  if (isBoolean(opts)) {
    // legacy...
    ctx.showHidden = opts;
  } else if (opts) {
    // got an "options" object
    exports._extend(ctx, opts);
  }
  // set default options
  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
  if (isUndefined(ctx.depth)) ctx.depth = 2;
  if (isUndefined(ctx.colors)) ctx.colors = false;
  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
  if (ctx.colors) ctx.stylize = stylizeWithColor;
  return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;


// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
  'bold' : [1, 22],
  'italic' : [3, 23],
  'underline' : [4, 24],
  'inverse' : [7, 27],
  'white' : [37, 39],
  'grey' : [90, 39],
  'black' : [30, 39],
  'blue' : [34, 39],
  'cyan' : [36, 39],
  'green' : [32, 39],
  'magenta' : [35, 39],
  'red' : [31, 39],
  'yellow' : [33, 39]
};

// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
  'special': 'cyan',
  'number': 'yellow',
  'boolean': 'yellow',
  'undefined': 'grey',
  'null': 'bold',
  'string': 'green',
  'date': 'magenta',
  // "name": intentionally not styling
  'regexp': 'red'
};


function stylizeWithColor(str, styleType) {
  var style = inspect.styles[styleType];

  if (style) {
    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
           '\u001b[' + inspect.colors[style][1] + 'm';
  } else {
    return str;
  }
}


function stylizeNoColor(str, styleType) {
  return str;
}


function arrayToHash(array) {
  var hash = {};

  array.forEach(function(val, idx) {
    hash[val] = true;
  });

  return hash;
}


function formatValue(ctx, value, recurseTimes) {
  // Provide a hook for user-specified inspect functions.
  // Check that value is an object with an inspect function on it
  if (ctx.customInspect &&
      value &&
      isFunction(value.inspect) &&
      // Filter out the util module, it's inspect function is special
      value.inspect !== exports.inspect &&
      // Also filter out any prototype objects using the circular check.
      !(value.constructor && value.constructor.prototype === value)) {
    var ret = value.inspect(recurseTimes, ctx);
    if (!isString(ret)) {
      ret = formatValue(ctx, ret, recurseTimes);
    }
    return ret;
  }

  // Primitive types cannot have properties
  var primitive = formatPrimitive(ctx, value);
  if (primitive) {
    return primitive;
  }

  // Look up the keys of the object.
  var keys = Object.keys(value);
  var visibleKeys = arrayToHash(keys);

  if (ctx.showHidden) {
    keys = Object.getOwnPropertyNames(value);
  }

  // IE doesn't make error fields non-enumerable
  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
  if (isError(value)
      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
    return formatError(value);
  }

  // Some type of object without properties can be shortcutted.
  if (keys.length === 0) {
    if (isFunction(value)) {
      var name = value.name ? ': ' + value.name : '';
      return ctx.stylize('[Function' + name + ']', 'special');
    }
    if (isRegExp(value)) {
      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
    }
    if (isDate(value)) {
      return ctx.stylize(Date.prototype.toString.call(value), 'date');
    }
    if (isError(value)) {
      return formatError(value);
    }
  }

  var base = '', array = false, braces = ['{', '}'];

  // Make Array say that they are Array
  if (isArray(value)) {
    array = true;
    braces = ['[', ']'];
  }

  // Make functions say that they are functions
  if (isFunction(value)) {
    var n = value.name ? ': ' + value.name : '';
    base = ' [Function' + n + ']';
  }

  // Make RegExps say that they are RegExps
  if (isRegExp(value)) {
    base = ' ' + RegExp.prototype.toString.call(value);
  }

  // Make dates with properties first say the date
  if (isDate(value)) {
    base = ' ' + Date.prototype.toUTCString.call(value);
  }

  // Make error with message first say the error
  if (isError(value)) {
    base = ' ' + formatError(value);
  }

  if (keys.length === 0 && (!array || value.length == 0)) {
    return braces[0] + base + braces[1];
  }

  if (recurseTimes < 0) {
    if (isRegExp(value)) {
      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
    } else {
      return ctx.stylize('[Object]', 'special');
    }
  }

  ctx.seen.push(value);

  var output;
  if (array) {
    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
  } else {
    output = keys.map(function(key) {
      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
    });
  }

  ctx.seen.pop();

  return reduceToSingleString(output, base, braces);
}


function formatPrimitive(ctx, value) {
  if (isUndefined(value))
    return ctx.stylize('undefined', 'undefined');
  if (isString(value)) {
    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                             .replace(/'/g, "\\'")
                                             .replace(/\\"/g, '"') + '\'';
    return ctx.stylize(simple, 'string');
  }
  if (isNumber(value))
    return ctx.stylize('' + value, 'number');
  if (isBoolean(value))
    return ctx.stylize('' + value, 'boolean');
  // For some reason typeof null is "object", so special case here.
  if (isNull(value))
    return ctx.stylize('null', 'null');
}


function formatError(value) {
  return '[' + Error.prototype.toString.call(value) + ']';
}


function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
  var output = [];
  for (var i = 0, l = value.length; i < l; ++i) {
    if (hasOwnProperty(value, String(i))) {
      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
          String(i), true));
    } else {
      output.push('');
    }
  }
  keys.forEach(function(key) {
    if (!key.match(/^\d+$/)) {
      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
          key, true));
    }
  });
  return output;
}


function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
  var name, str, desc;
  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
  if (desc.get) {
    if (desc.set) {
      str = ctx.stylize('[Getter/Setter]', 'special');
    } else {
      str = ctx.stylize('[Getter]', 'special');
    }
  } else {
    if (desc.set) {
      str = ctx.stylize('[Setter]', 'special');
    }
  }
  if (!hasOwnProperty(visibleKeys, key)) {
    name = '[' + key + ']';
  }
  if (!str) {
    if (ctx.seen.indexOf(desc.value) < 0) {
      if (isNull(recurseTimes)) {
        str = formatValue(ctx, desc.value, null);
      } else {
        str = formatValue(ctx, desc.value, recurseTimes - 1);
      }
      if (str.indexOf('\n') > -1) {
        if (array) {
          str = str.split('\n').map(function(line) {
            return '  ' + line;
          }).join('\n').substr(2);
        } else {
          str = '\n' + str.split('\n').map(function(line) {
            return '   ' + line;
          }).join('\n');
        }
      }
    } else {
      str = ctx.stylize('[Circular]', 'special');
    }
  }
  if (isUndefined(name)) {
    if (array && key.match(/^\d+$/)) {
      return str;
    }
    name = JSON.stringify('' + key);
    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
      name = name.substr(1, name.length - 2);
      name = ctx.stylize(name, 'name');
    } else {
      name = name.replace(/'/g, "\\'")
                 .replace(/\\"/g, '"')
                 .replace(/(^"|"$)/g, "'");
      name = ctx.stylize(name, 'string');
    }
  }

  return name + ': ' + str;
}


function reduceToSingleString(output, base, braces) {
  var numLinesEst = 0;
  var length = output.reduce(function(prev, cur) {
    numLinesEst++;
    if (cur.indexOf('\n') >= 0) numLinesEst++;
    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
  }, 0);

  if (length > 60) {
    return braces[0] +
           (base === '' ? '' : base + '\n ') +
           ' ' +
           output.join(',\n  ') +
           ' ' +
           braces[1];
  }

  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}


// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
  return Array.isArray(ar);
}
exports.isArray = isArray;

function isBoolean(arg) {
  return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;

function isNull(arg) {
  return arg === null;
}
exports.isNull = isNull;

function isNullOrUndefined(arg) {
  return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;

function isNumber(arg) {
  return typeof arg === 'number';
}
exports.isNumber = isNumber;

function isString(arg) {
  return typeof arg === 'string';
}
exports.isString = isString;

function isSymbol(arg) {
  return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;

function isUndefined(arg) {
  return arg === void 0;
}
exports.isUndefined = isUndefined;

function isRegExp(re) {
  return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;

function isObject(arg) {
  return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;

function isDate(d) {
  return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;

function isError(e) {
  return isObject(e) &&
      (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;

function isFunction(arg) {
  return typeof arg === 'function';
}
exports.isFunction = isFunction;

function isPrimitive(arg) {
  return arg === null ||
         typeof arg === 'boolean' ||
         typeof arg === 'number' ||
         typeof arg === 'string' ||
         typeof arg === 'symbol' ||  // ES6 symbol
         typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;

exports.isBuffer = require('./support/isBuffer');

function objectToString(o) {
  return Object.prototype.toString.call(o);
}


function pad(n) {
  return n < 10 ? '0' + n.toString(10) : n.toString(10);
}


var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
              'Oct', 'Nov', 'Dec'];

// 26 Feb 16:19:34
function timestamp() {
  var d = new Date();
  var time = [pad(d.getHours()),
              pad(d.getMinutes()),
              pad(d.getSeconds())].join(':');
  return [d.getDate(), months[d.getMonth()], time].join(' ');
}


// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};


/**
 * Inherit the prototype methods from one constructor into another.
 *
 * The Function.prototype.inherits from lang.js rewritten as a standalone
 * function (not on Function.prototype). NOTE: If this file is to be loaded
 * during bootstrapping this function needs to be rewritten using some native
 * functions as prototype setup using normal JavaScript does not work as
 * expected during bootstrapping (see mirror.js in r114903).
 *
 * @param {function} ctor Constructor function which needs to inherit the
 *     prototype.
 * @param {function} superCtor Constructor function to inherit prototype from.
 */
exports.inherits = require('inherits');

exports._extend = function(origin, add) {
  // Don't do anything if add isn't an object
  if (!add || !isObject(add)) return origin;

  var keys = Object.keys(add);
  var i = keys.length;
  while (i--) {
    origin[keys[i]] = add[keys[i]];
  }
  return origin;
};

function hasOwnProperty(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}

}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./support/isBuffer":4,"_process":3,"inherits":2}],6:[function(require,module,exports){


var util = require('util');

// Constraints computations on event streams to a simple functional contract
function AggregateFunction() {
  var self = this;
  // function type can be one of
  // - simple (default)
  // - ordered - will require window to store elements in arrival and sorted order
  //
  self.type = "simple";
  // invoked when a window opens - should 'reset' or 'zero' a windows internal state
  self.init = function() { throw "Must subclass"; };
  // invoked when an event is enqueued into a window
  self.accumulate = function(value) { throw "Must subclass"; };
  // invoked to compensate sliding window overwrite
  self.compensate = function(value) { throw "Must subclass"; };
  // invoked when a window closes
  self.emit = function() { throw "Must subclass"; };
  // used by window implementations variously to preallocate function instances - makes things 'fast', basically
  self.make = function(win) { throw "Must subclass"; };
}

// Conveniance. Computations on a set of (independant) aggregate functions. Use wisely.
function CompositeFunction(fxs) {
  var self = this, fx = fxs;

  // if any fn has ordered property, force all to be (not ideal w.r.t. perf, find a better way)
  self.type="simple";
  for (var f in fxs) {
    if (f.type === "ordered") {
      self.type = "ordered";
    }
  }

  self.init = function() { for(var i in fxs) { fx[i] = fxs[i].make(fxs[i].win); fx[i].init(); } };
  self.accumulate = function(value) { for (var i in fx) { fx[i].accumulate(value); } };
  self.compensate = function(value) { for (var i in fx) { fx[i].compensate(value); } };
  self.emit = function() { var a = []; for (var i in fx) { a.push(fx[i].emit()); }; return a; };
  self.make = function() { return new CompositeFunction(fx); };
}
util.inherits(CompositeFunction, AggregateFunction);

// Exports
module.exports.AggregateFunction = AggregateFunction;
module.exports.CompositeFunction = CompositeFunction;

},{"util":5}],7:[function(require,module,exports){


// Clocks tick and they tock, but not all clocks are equal
function ClockSource(params) {
  var self = this;
  // every clock deserves a name, eg: (wall clock, logical clock, vector clock, ...)
  self.name = 'crock';
  // returns the current time according to this type of clock
  self.at = function() { throw "Must subclass"; }
  // initializes a clock
  self.init = function() { throw "Must subclass"; }
  // increments the current clocks time by a single moment
  self.inc  = function() { throw "Must subclass"; }
  // stream operators call tick when they want to know if the clock has advanced since last checked
  self.tick = function() { throw "Must subclass"; }
  // stream operators call tock with a time x. if x happened now or before, returns true
  self.tock = function(x) { throw "Must subclass"; }
}

// Exports
module.exports.ClockSource = ClockSource;

},{}],8:[function(require,module,exports){


var util = require('util');
var ClockSource = require('./eep.clock').ClockSource;

// Simple monotonic clock. Ticks and tocks like the count on Sesame St. Mwa ha ha. Monotonic, basically.
function CountingClock() {
  var self = this, at, mark = null;

  self.at = function() {
    return at;
  };

  self.init = function() {
    at = mark = 0;
    return at;
  };

  self.inc = function() {
    at += 1;
  };

  self.tick = function() {
    if (mark === null) {
      mark = at + 1;
    }

    return ((at - mark) >= 1);
  };

  self.tock = function(elapsed) {
    var d = at - elapsed;
    if ( d >= 1) {
      mark += 1;
      return true;
    }
    return false;
  };
}
util.inherits(CountingClock, ClockSource);

// Exports
module.exports.CountingClock = CountingClock;

},{"./eep.clock":7,"util":5}],9:[function(require,module,exports){


var util = require('util');
var ClockSource = require('./eep.clock').ClockSource;

// Wall clock. Watch out for NTP/PTP shenanigans
function WallClock(interval) {
  var self = this, at, mark = null;

  self.at = function() {
    return at;
  };

  self.init = function() {
    at = new Date().getTime();
    mark = at + interval;
    return at;
  };

  self.inc = function() {
    at = new Date().getTime();
  };

  self.tick = function() {
    if (mark === null) {
      throw "clock was not initialized";
    }
    self.inc();

    return ((at - mark) >= 0);
  };

  self.tock = function(elapsed) {
    var d = at - elapsed;
    if ( d >= interval) {
      mark += interval;
      return true;
    }
    return false;
  };
}
util.inherits(WallClock, ClockSource);

// Exports
module.exports.WallClock = WallClock;

},{"./eep.clock":7,"util":5}],10:[function(require,module,exports){


var util = require('util');
var events = require('events');

// Monotemporal value wrapper. Tracks origin time of an event.
// Value can be updated. 
// Updating a value does not update the origin.
var Temporal = function (initialValue, instant) {
  var self = this; var v = initialValue; var at = instant;

  self.value = function() {
    return v;
  };

  self.at = function() {
    return instant;
  };

  self.update = function(newValue) {
    self.v = newValue;
    return self;
  };
};

// Factory function turns regular data into temporal data
Temporal.make = function(initialValue, instant) {
  return new Temporal(initialValue, instant);
};

// A (degenerated) temporal aggregate function. Useful for temporal stream operators
var TemporalFunction = function(aggFn,instant) {
  var self = this; var inner = aggFn.make(); var t;
  self.init =  function() { inner.init(); t = Temporal.make(inner.emit(), instant); };
  self.accumulate =  function(value) { t = t.update(inner.accumulate(value.value())); };
  self.emit = function()  { return Temporal.make(inner.emit()); };
  self.at = function() { return t.at(); };
}; 

// Factory function for turning regular aggregate functions into temporal ones
TemporalFunction.make = function(aggFn, at) {
  return new TemporalFunction(aggFn, at);
};

// Exports
module.exports.Temporal = Temporal;
module.exports.TemporalFunction = TemporalFunction;

},{"events":1,"util":5}],11:[function(require,module,exports){


var util = require('util');
var events = require('events');
var WindowFactory = require('./eep.windowfactory').WindowFactory;

// EventWorld. The root of all event processing evilry. Not evil yet.
//
var EventWorld = function() {
  var self = this, ctx = WindowFactory.make();

  self.windows = function() {
    return ctx;
  };
};

// Factory that creates event worlds
EventWorld.make = function() {
    return new EventWorld();
};

// Exports
module.exports.EventWorld = EventWorld;

},{"./eep.windowfactory":20,"events":1,"util":5}],12:[function(require,module,exports){


var util = require('util');
var AggregateFunction = require('./eep.aggregate_function').AggregateFunction;

// Do nothing with all the things.
//
// Useful when you simply want to exploit window 'emit' events
// to perform some action
//
var NoopFunction = function(win) {
  var self = this;
  self.name = 'noop';
  self.type = "simple";
  self.init = function() { };
  self.accumulate = function(value) { };
  self.compensate = function(value) { };
  self.emit = function()  { return null; };
  self.make = function(win) { return new NoopFunction(win); };
};
util.inherits(NoopFunction, AggregateFunction);

// eep.js Noop package
var Noop = function() {};

// Register Noop package aggregate functions
Noop.noop = new NoopFunction(undefined);

// Export the Noop package
module.exports.Noop = Noop;

},{"./eep.aggregate_function":6,"util":5}],13:[function(require,module,exports){


var util = require('util');
var AggregateFunction = require('./eep.aggregate_function').AggregateFunction;

// Count all the things
function CountFunction(win) {
  var self = this, n;
  self.name = "count";
  self.type = "simple";
  self.init = function() { n = 0; };
  self.accumulate = function(ignored) { n += 1; };
  self.compensate = function(ignored) { n -= 1; };
  self.emit = function()  { return n; };
  self.make = function(win) { return new CountFunction(win); };
}
util.inherits(CountFunction, AggregateFunction);

// Sum all the things
function SumFunction(win) {
  var self = this, s;
  self.name = "sum";
  self.type = "simple";
  self.init = function() { s = 0; };
  self.accumulate = function(v) { s += v; };
  self.compensate = function(v) { s -= v; };
  self.emit = function()  { return s; };
  self.make = function(win) { return new SumFunction(win); };
}
util.inherits(SumFunction, AggregateFunction);

// Get the smallest of all the things
function MinFunction(win) { 
  var self = this, r;
  self.win = win;
  self.name = "min";
  self.type = "ordered_reverse";
  self.init = function() { r = null; };
  self.accumulate = function(v) { if (v == null) { return; } if (r == null) { r = v; return; } r = (v < r) ? v : r; };
  self.compensate = function(v) { r = self.win.min(); };
  self.emit = function()  { return r; };
  self.make = function(win) { return new MinFunction(win); };
}
util.inherits(MinFunction, AggregateFunction);

// Get the biggest of all the things
function MaxFunction(win) { 
  var self = this, r;
  self.win = win;
  self.name = "max";
  self.type = "ordered_reverse";
  self.init = function() { r = null; };
  self.accumulate = function(v) { if (v == null) { return; } if (r == null) { r = v; return; } r = (v > r) ? v : r; };
  self.compensate = function(v) { r = self.win.max(); };
  self.emit = function()  { return r; };
  self.make = function(win) { return new MaxFunction(win); };
}
util.inherits(MaxFunction, AggregateFunction);

// Get the average of all the things
function MeanFunction(win) {
  var self = this, m, d, n;
  self.name = "mean";
  self.type = "simple";
  self.init = function() { m = 0; d = 0; n = 0; };
  self.accumulate = function(v) { n+=1; d = v - m; m = d/n + m; };
  self.compensate = function(v) { n-=1; d = m - v; m = m + d/n; };
  self.emit = function()  { return m; };
  self.make = function(win) { return new MeanFunction(win); };
}
util.inherits(MeanFunction, AggregateFunction);

// Get the sample variance of all the things
function VarianceFunction(win) {
  var self = this, m, m2, d, n;
  self.name = "vars";
  self.type = "simple";
  self.init = function() { m = 0; m2 = 0; d = 0; n = 0; };
  self.accumulate = function(v) { n+=1; d = v - m; m = d/n + m; m2 = m2 + d*(v - m); };
  self.compensate = function(v) { n-=1; d = m - v; m = m + d/n; m2 = d*(v - m) + m2; };
  self.emit = function()  { return m2/(n-1); };
  self.make = function(win) { return new VarianceFunction(win); };
}
util.inherits(VarianceFunction, AggregateFunction);

// Get the standard deviation of all the things
function StdevFunction(win) {
  var self = this, m, m2, d, n;
  self.name = "stdevs";
  self.type = "simple";
  self.init = function() { m = 0, m2 = 0, d = 0, n = 0; };
  self.accumulate = function(v) {
    n+=1; 
    d = v - m;
    m = m + d/n;
    m2 = m2 + d*(v-m);
  };
  self.compensate = function(v) {
    n-=1;
    d = m - v;
    m = d/n + m;
    m2 = d*(v-m) + m2;
  };
  self.emit = function()  { return Math.sqrt(m2/(n-1)); };
  self.make = function(win) { return new StdevFunction(win); };
}
util.inherits(StdevFunction, AggregateFunction);

function AllStatsFunction(win) {
  var self = this, m, m4, m3, m3, d, n, s, min, max;
  self.name = "all";
  self.win = win;
  self.type = "ordered";
  self.init = function() { 
    m = 0, m2 = 0, d = 0, n = 0, s = 0, min = null, max = null;
  };
  self.accumulate = function(v) {
    if (v == null) return;
    var o = n;
    s+=v;
    if (v != null) { if (min == null) { min = v; } else { min = (v < min) ? v : min; } };
    if (v != null) { if (max == null) { max = v; } else { max = (v > max) ? v : max; } };
    n+=1;
    d = v - m;
    var dn = d / n, t1 = d * dn *  o;
    m = m + dn;
    m2 = m2 + t1;
  };
  self.compensate = function(v) {
    if (v == null) return;
    var o = n;
    s-=v;
    min = self.win.min();
    max = self.win.max();
    n-=1;
    d = m - v;
    var dn = d / n, t1 = d * dn * o;
    m = dn;
    m2 = m2 - t1;
  };
  self.emit = function()  { 
    var variance = m2/(n-1);
    return results = {
      count: n,
      sum: s,
      min: min,
      max: max,
      mean: m,
      vars: variance,
      stdevs:  Math.sqrt(variance)
    };
  };
  self.make = function(win) { return new AllStatsFunction(win); };
}
util.inherits(AllStatsFunction, AggregateFunction);

// eep.js Statistics package
var Stats = function() {};

// Register statistics aggregate functions
Stats.count = new CountFunction();
Stats.sum = new SumFunction();
Stats.min = new MinFunction();
Stats.max = new MaxFunction();
Stats.mean = new MeanFunction();
Stats.vars = new VarianceFunction();
Stats.stdevs = new StdevFunction();
Stats.all = new AllStatsFunction();

// Export the Statistics package
module.exports.Stats = Stats;

},{"./eep.aggregate_function":6,"util":5}],14:[function(require,module,exports){


//
// eep.js Embedded Event Processing core
//

// A namespace to package all eep.js core facilities
var eep = {};

// Register eep.js core facilities
eep.WindowFactory = require('./eep.windowfactory').WindowFactory;
eep.EventWorld = require('./eep.eventworld').EventWorld;
eep.AggregateFunction = require('./eep.aggregate_function').AggregateFunction;
eep.CompositeFunction = require('./eep.aggregate_function').CompositeFunction;
eep.ClockSource = require('./eep.clock').ClockSource;
eep.WallClock = require('./eep.clock_wall').WallClock;
eep.CountingClock = require('./eep.clock_counting').CountingClock;
eep.TumblingWindow = require('./eep.window_tumbling').TumblingWindow;
eep.SlidingWindow = require('./eep.window_sliding').SlidingWindow;
eep.Periodicwindow = require('./eep.window_periodic').PeriodicWindow;
eep.MonotonicWindow = require('./eep.window_monotonic').MonotonicWindow;
eep.OrderedWindow = require('./eep.window_ordered').OrderedWindow;

// Register optional packages
eep.Noop = require('./eep.fn.noop').Noop;
eep.Stats = require('./eep.fn.stats').Stats;

// Export the eep package to window
window.eep = eep;
},{"./eep.aggregate_function":6,"./eep.clock":7,"./eep.clock_counting":8,"./eep.clock_wall":9,"./eep.eventworld":11,"./eep.fn.noop":12,"./eep.fn.stats":13,"./eep.window_monotonic":15,"./eep.window_ordered":16,"./eep.window_periodic":17,"./eep.window_sliding":18,"./eep.window_tumbling":19,"./eep.windowfactory":20}],15:[function(require,module,exports){


var util = require('util');
var events = require('events');
var Temporal = require('./eep.core').Temporal;
var TemporalFunction = require('./eep.core').TemporalFunction;

// A monotonic window. Client should call tick monotonically and use with a monotonic clock implementation.
var MonotonicWindow = function(aggFn, clock) {
  events.EventEmitter.call(this);
  var self = this;
  self.fn = TemporalFunction.make(aggFn,clock.init());
  var idx = 0;

  self.fn.init();

  self.enqueue = function(v) {
    self.fn.accumulate(Temporal.make(v, clock.inc()));
  };

  self.tick = function() {
    // If time hasn't passed, we're done
    if (!clock.tick()) return;

    // Otherwise, emit
    if (clock.tock(self.fn.at())) {
      self.emit('emit', self.fn.emit().value());
      // for ordering, send a 'drop all' event
      self.emit('clear');
      // 'close' current window and 'open' a new one
      self.fn.init();
    }
  };
};
util.inherits(MonotonicWindow, events.EventEmitter);

// Exports
module.exports.MonotonicWindow = MonotonicWindow;

},{"./eep.core":10,"events":1,"util":5}],16:[function(require,module,exports){


var util = require('util');
var events = require('events');

var indexOf = function(data,candidate) {
  var min = 0;
  var max = data.length - 1;
  var pivot;
  var value;

  while (min <= max) {
    pivot = (min + max) / 2 | 0;
    value = data[pivot];
    if (value < candidate) {
      min = pivot + 1;
    } else if (value > candidate) {
      max = pivot - 1;
    } else {
      return pivot;
    }
  }

  return -1;
};

var remove = function(data,value) {
   var idx = indexOf(data,value);
   if (idx >= 0) {
    data.splice(idx, 1);
   }
};

var insert = function(data,value) {
  var hi = n = data.length, lo = 0;
  var pivot = Math.floor(n/2);

  do {
    if (value > data[pivot]) {
      lo = pivot + 1;
    } else if (value < data[pivot]) {
      hi = pivot;
    } else break;

    pivot = Math.floor(lo + ((hi - lo) / 2));
  } while (lo < hi);

  data.splice(pivot,0, value);
};

// A window decorator that supports ordering. Leverages an insertion sort.
// Use wisely. Order is not a requirement for most algorithms and has a
// significant performance cost associated with it.
//
var OrderedWindow = function(win) {
  events.EventEmitter.call(this);
  var self = this; var s = new Array();

  self.min = function() { return s[0]; };
  self.max = function() { return s[s.length-1]; };
  self.size = function() { return s.length; };

  // override
  win.min = self.min;
  win.max = self.max;
  win.size = self.size;

  if (win.tick) self.tick = win.tick;

  win.on('drop', function(x) { remove(s, x);  });
  win.on('clear', function() { 
    for (var i = 0; i < s.length; i++) { 
      // emit drop event for each collected event
      self.emit('drop', s[i]); 
    }
    // clear array 'cheaply'
    s.length = 0;
  });
  win.on('emit', function(x) { self.emit('emit',x); });
  self.enqueue = function(x) { insert(s, x); win.enqueue(x); };
};
util.inherits(OrderedWindow, events.EventEmitter);


// Exports
module.exports.OrderedWindow = OrderedWindow;

// For testing
module.exports.OrderedWindow.indexOf = indexOf;
module.exports.OrderedWindow.remove = remove;
module.exports.OrderedWindow.insert = insert;

},{"events":1,"util":5}],17:[function(require,module,exports){


var util = require('util');
var events = require('events');
var WallClock = require('./eep.clock_wall').WallClock;
var Temporal = require('./eep.core').Temporal;
var TemporalFunction = require('./eep.core').TemporalFunction;

// A periodic window. Lowest granularity, or a moment of time, is milliseconds.
// As wall clock time is used, this window is not monotonic. 
// Here be dragons like NTP, PTP, basically.
//
var PeriodicWindow = function(aggFn, intervalMillis) {
  events.EventEmitter.call(this);
  var self = this, clock = new WallClock(intervalMillis), fn = TemporalFunction.make(aggFn,clock.init());
  var idx = 0;

  fn.init();

  self.enqueue = function(v) {
    fn.accumulate(Temporal.make(v, clock.inc()));
  }; 

  self.tick = function() {
    // If time hasn't passed, we're done
    if (!clock.tick()) return;

    // Otherwise, emit
    if (clock.tock(fn.at())) {
      self.emit('emit', fn.emit().value());
      // 'close' current time window and 'open' a fresh one
      fn.init();
    };
  };
};

util.inherits(PeriodicWindow, events.EventEmitter);

module.exports.PeriodicWindow = PeriodicWindow;

},{"./eep.clock_wall":9,"./eep.core":10,"events":1,"util":5}],18:[function(require,module,exports){


var util = require('util');
var events = require('events');

// A sliding window. Sliding windows (here) have a fixed a-priori known size.
// Example: Sliding window of size 2 computing sum of values.
//
// <pre>
//
//     t0     t1      (emit)   t2             (emit)       tN
//   +---+  +---+---+          -...-...-
//   | 1 |  | 2 | 1 |   <3>    : x : x :
//   +---+  +---+---+          _...+---+---+               ...
//              | 2 |              | 2 | 3 |    <5>
//              +---+              +---+---+
//                                     | 4 |
//                                     +---+
// </pre>
//
// Logically, we only ever need N active elements to emit a result for every input event once
// all windows are open. Previous versions, used a ring buffer and preallocated the slots but
// performance was exponentially degrading with the size of the window. This version enhances
// aggregate functions with the notion of compensation. In this version the first accumulation
// occuring on closing of a window is effectively reversed when the next value is added
// effectively removing the influence of the now evicted element, but without incurring the
// overhead of cascading values for all open elements in the window. This cost is now constant
// and the resulting performance is linear w.r.t the size of the window.
//
//

var SlidingWindow = function(aggFn, n) {
  events.EventEmitter.call(this);
  var self = this;
  self.fn = aggFn.make(self);
  var size = n, idx = 0; var p = new Array(size);

  self.fn.init();

  self.min = function() { throw "Unordered sliding window"; };
  self.max = function() { throw "Unordered sliding window"; };
  self.size = function() { return win.size; };

  self.enqueue = function(v) {
    self.fn.accumulate(v);
    if (idx >= (size - 1)) {
      var po = (idx+1) % size;
      self.emit('emit', self.fn.emit());
      var evictee = p[po];
      self.fn.compensate(p[po]);
      p[(idx) % size]=v;
      self.emit('drop', evictee); // required for correctness when using ordering
    } else {
      p[idx] = v;
    }
    idx+=1;
  };
};
util.inherits(SlidingWindow, events.EventEmitter);


// Exports
module.exports.SlidingWindow = SlidingWindow;

},{"events":1,"util":5}],19:[function(require,module,exports){


var util = require('util');
var events = require('events');

// A tumbling window. Tumbling windows (here) have a fixed a-priori known size.
// Example: Tumbling window of size 2 computing sum of values.
//
// <pre>
//
//     t0     t1      (emit)    t2            t3         (emit)    t4
//   +---+  +---+---+         -...-...-
//   | 1 |  | 2 | 1 |   <3>   : x : x :
//   +---+  +---+---+         -...+---+---+   +---+---+            ...
//                                    | 3 |   | 4 | 3 |    <7>
//                                    +---+   +---+---+
//                                         
// </pre>
//
// So, we only ever need 1 active window to emit a result for every set of N input events.
//
// This is the only window implementation that actually needs a queue (ring buffer)
// in this simple embedded event processing engine.
//
var TumblingWindow = function(aggFn, n) {
  events.EventEmitter.call(this);

  var self = this, size = n, mark = size - 1, idx = 0; var p = new Array();
  self.fn = aggFn.make(self);

  self.fn.init();

  self.min = function() { throw "Unordered sliding window"; };
  self.max = function() { throw "Unordered sliding window"; };
  self.size = function() { return n; }

  self.enqueue = function(v) {
    self.fn.accumulate(v);
    p.push(v);
    idx+=1;
    if (idx == size) {
      var r = self.fn.emit();
      self.emit('emit',r);
      var i = 0;
      if (self.fn.type === "ordered") {
        // has a high perf cost so only run if fn requires ordering
        while(p.length > 0) {
          self.emit('drop', p.shift());
        };
      }
      self.fn.init();
      idx = 0;
    }
  };  
};
util.inherits(TumblingWindow, events.EventEmitter);

// Exports
module.exports.TumblingWindow = TumblingWindow;

},{"events":1,"util":5}],20:[function(require,module,exports){


var TumblingWindow = require('./eep.window_tumbling').TumblingWindow;
var SlidingWindow = require('./eep.window_sliding').SlidingWindow;
var PeriodicWindow = require('./eep.window_periodic').PeriodicWindow;
var MonotonicWindow = require('./eep.window_monotonic').MonotonicWindow;
var OrderedWindow = require('./eep.window_ordered').OrderedWindow;

//
// A factory class for creating instances of windowed stream operations
//
var WindowFactory = function() {
  var self = this;

  // Given an aggregate function and a size, create a tumbling event stream window
  self.tumbling = function(aggFn, n) {
    return new TumblingWindow(aggFn, n);
  }

  // Given an aggregate function and a size, create a sliding event stream window
  self.sliding = function(aggFn, n) {
    return new SlidingWindow(aggFn, n);
  }

  // Given an aggregate function and an interval in milliseconds, create a periodic
  // (wall clock driven) event stream window
  self.periodic = function(aggFn, intervalMillis) {
    return new PeriodicWindow(aggFn, intervalMillis);
  }

  // Given an aggregate function and an interval in milliseconds, create a monotonic
  // event stream window - with a custom monotonic clock (eg: eep.CountingClock)
  self.monotonic = function(aggFn, clock) {
    return new MonotonicWindow(aggFn, clock); 
  }

  // Given a simple window, return a window that orders data
  self.ordered = function(win) {
    return new OrderedWindow(win);
  }
};

// A factory factory
WindowFactory.make = function() {
    return new WindowFactory();
};

// Exports
module.exports.WindowFactory = WindowFactory;

},{"./eep.window_monotonic":15,"./eep.window_ordered":16,"./eep.window_periodic":17,"./eep.window_sliding":18,"./eep.window_tumbling":19}]},{},[14]);
