text: (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.tibaqend = f()}})(function(){var define,module,exports;return (function e(t,n,r){function o(i,u){if(!n[i]){if(!t[i]){var a=typeof require=="function"&&require;if(!u&&a)return a.length===2?a(i,!0):a(i);if(s&&s.length===2)return s(i,!0);if(s)return s(i);var f=new Error("Cannot find module '"+i+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[i]={exports:{}};t[i][0].call(l.exports,function(e){var n=t[i][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[i].exports}var i=Array.prototype.slice;Function.prototype.bind||Object.defineProperty(Function.prototype,"bind",{enumerable:!1,configurable:!0,writable:!0,value:function(e){function r(){return t.apply(this instanceof r&&e?this:e,n.concat(i.call(arguments)))}if(typeof this!="function")throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var t=this,n=i.call(arguments,1);return r.prototype=Object.create(t.prototype),r.prototype.contructor=r,r}});var s=typeof require=="function"&&require;for(var u=0;u<r.length;u++)o(r[u]);return o})({1:[function(require,module,exports){
  (function (clearTimeout,setTimeout){
  var message = require('./message');
  var error = require('./error');
  var binding = require('./binding');
  var util = require('./util');
  
  var EntityTransaction = require('./EntityTransaction');
  var Query = require('./Query');
  var Metadata = require('./util/Metadata');
  var Message = require('./connector/Message');
  var StatusCode = Message.StatusCode;
  
  /**
   * @class baqend.EntityManager
   * @extends baqend.util.Lockable
   *
   * @param {baqend.EntityManagerFactory} entityManagerFactory The factory which of this entityManager instance
   * @param {Boolean=} global <code>true</code> to use the global authorization mechanism via cookies,
   *                          <code>false</code> to use token base authorization
   */
  var EntityManager = Object.inherit(util.Lockable, /** @lends baqend.EntityManager.prototype */ {
  
    /**
     * Creates a new List collection
     * @function
     * @param {baqend.collection.Collection|Array=} collection The initial array or collection to initialize the new List
     * @return {baqend.collection.List} The new created List
     */
    List: require('./collection').List,
  
    /**
     * Creates a new Set collection
     * @function
     * @param {baqend.collection.Collection|Array=} collection The initial array or collection to initialize the new Set
     * @return {baqend.collection.Set} The new created Set
     */
    Set: require('./collection').Set,
  
    /**
     * Creates a new Map collection
     * @function
     * @param {baqend.collection.Collection|Array=} collection The initial array or collection to initialize the new Map
     * @return {baqend.collection.Map} The new created Map
     */
    Map: require('./collection').Map,
  
    /**
     * Creates a new GeoPoint
     * @function
     * @param {String|Number|Object|Array=} latitude A coordinate pair (latitude first), a GeoPoint like object or the GeoPoint's latitude
     * @param {Number=} longitude The GeoPoint's longitude
     * @return {baqend.collection.GeoPoint} The new created Map
     */
    GeoPoint: require('./GeoPoint'),
  
    /**
     * @type baqend.EntityManagerFactory
     */
    entityManagerFactory: null,
  
    /**
     * @type baqend.metamodel.Metamodel
     */
    metamodel: null,
  
    /**
     * @type baqend.util.Code
     */
    code: null,
  
    /**
     * @type baqend.util.Modules
     */
    modules: null,
  
    /**
     * The connector used for baqend requests
     * @type baqend.connector.Connector
     * @private
     */
    _connector: null,
  
    /**
     * All managed and cached entity instances
     * @type object<String,baqend.binding.Entity>
     * @private
     */
    _entities: null,
  
    /**
     * Determine whether the entity manager is open.
     * true until the entity manager has been closed
     * @type Boolean
     */
    get isOpen() {
      return !!this._connector;
    },
  
    /**
     * The authentication token if the user is logged in currently
     * @type String
     */
    token: null,
  
    /**
     * The current logged in user object
     * @type baqend.binding.User
     */
    me: null,
  
    /**
     * Returns true if the device token is already registered, otherwise false.
     * @type boolean
     */
    isDeviceRegistered: false,
  
    /**
     * Returns true if this EntityManager is the global one, otherwise false.
     * @returns {boolean} isGlobal
     */
    isGlobal: false,
  
    constructor: function EntityManager(entityManagerFactory, global) {
      this.entityManagerFactory = entityManagerFactory;
      this.metamodel = entityManagerFactory.metamodel;
      this.code = entityManagerFactory.code;
      this.isGlobal = !!global;
    },
  
    /**
     * Connects this entityManager, used for synchronous and asynchronous initialization
     * @param {baqend.connector.Connector} connector
     */
    connected: function(connector) {
      this._connector = connector;
      this._entities = {};
  
      this._createObjectFactory(this.metamodel.embeddables);
      this._createObjectFactory(this.metamodel.entities);
  
      this.transaction = new EntityTransaction(this);
      this.modules = new util.Modules(this, connector);
  
      if (this.isGlobal) {
        var msg = new message.Me();
        msg.withAuthorizationToken();
        return Promise.all([this.checkDeviceRegistration(), this._userRequest(msg, true)]);
      }
    },
  
    /**
     * @param {baqend.metamodel.ManagedType[]} types
     * @return {baqend.binding.ManagedFactory}
     * @private
     */
    _createObjectFactory: function(types) {
      Object.keys(types).forEach(function(ref) {
        var type = this.metamodel.managedType(ref);
        var name = type.name;
  
        if (this[name]) {
          type.typeConstructor = this[name];
          Object.defineProperty(this, name, {
            value: type.createObjectFactory(this)
          });
        } else {
          Object.defineProperty(this, name, {
            get: function() {
              Object.defineProperty(this, name, {
                value: type.createObjectFactory(this)
              });
  
              return this[name];
            },
            set: function(typeConstructor) {
              type.typeConstructor = typeConstructor;
            },
            configurable: true
          });
        }
      }, this);
    },
  
    _sendOverSocket : function(message) {
      message.token = this.token;
      this._connector.sendOverSocket(message);
    },
  
    _subscribe : function(topic, cb) {
      this._connector.subscribe(topic, cb);
    },
  
    _unsubscribe : function(topic, cb) {
      this._connector.unsubscribe(topic, cb);
    },
  
    _send: function(message) {
      message.withAuthorizationToken(this.isGlobal? null: this.token);
      return this._connector.send(message).then(function() {
        var token = message.getAuthorizationToken();
        if (token)
          this.token = token;
  
        return message;
      }.bind(this));
    },
  
    /**
     * Get an instance, whose state may be lazily fetched. If the requested instance does not exist
     * in the database, the EntityNotFoundError is thrown when the instance state is first accessed.
     * The application should not expect that the instance state will be available upon detachment,
     * unless it was accessed by the application while the entity manager was open.
     *
     * @param {(Function|String)} entityClass
     * @param {String=} key
     */
    getReference: function(entityClass, key) {
      var id, type;
      if (key) {
        type = this.metamodel.entity(entityClass);
        if (key.indexOf('/db/') == 0) {
          id = key;
        } else {
          id = type.ref + '/' + encodeURIComponent(key);
        }
      } else {
        id = entityClass;
        type = this.metamodel.entity(id.substring(0, id.indexOf('/', 4))); //skip /db/
      }
  
      var entity = this._entities[id];
      if (!entity) {
        entity = type.create();
        var metadata = Metadata.get(entity);
        metadata.id = id;
        metadata.setUnavailable();
  
        this._attach(entity);
      }
  
      return entity;
    },
  
    /**
     * Creates an instance of Query.Builder for query creation and execution. The Query results are instances of the
     * resultClass argument.
     * @param {Function=} resultClass - the type of the query result
     * @return {baqend.Query.Builder} A query builder to create one ore more queries for the specified class
     */
    createQueryBuilder: function(resultClass) {
      return new Query.Builder(this, resultClass);
    },
  
    /**
     * Clear the persistence context, causing all managed entities to become detached.
     * Changes made to entities that have not been flushed to the database will not be persisted.
     */
    clear: function() {
      this._entities = {};
    },
  
    /**
     * Close an application-managed entity manager. After the close method has been invoked,
     * all methods on the EntityManager instance and any Query and TypedQuery objects obtained from it
     * will throw the IllegalStateError except for transaction, and isOpen (which will return false).
     * If this method is called when the entity manager is associated with an active transaction,
     * the persistence context remains managed until the transaction completes.
     */
    close: function() {
      this._connector = null;
  
      return this.clear();
    },
  
    /**
     * Check if the instance is a managed entity instance belonging to the current persistence context.
     * @param {baqend.binding.Entity} entity - entity instance
     * @returns {Boolean} boolean indicating if entity is in persistence context
     */
    contains: function(entity) {
      return !!entity && this._entities[entity.id] === entity;
    },
  
    /**
     * Check if an object with the id from the given entity is already attached.
     * @param {baqend.binding.Entity} entity - entity instance
     * @returns {Boolean} boolean indicating if entity with same id is attached
     */
    containsById: function(entity) {
      return !!(entity && this._entities[entity.id]);
    },
  
    /**
     * Remove the given entity from the persistence context, causing a managed entity to become detached.
     * Unflushed changes made to the entity if any (including removal of the entity),
     * will not be synchronized to the database. Entities which previously referenced the detached entity will continue to reference it.
     * @param {baqend.binding.Entity} entity - entity instance
     */
    detach: function(entity) {
      var state = Metadata.get(entity);
      return state.withLock(function() {
        this.removeReference(entity);
        return Promise.resolve(entity);
      }.bind(this));
    },
  
    /**
     * Resolve the depth by loading the referenced objects of the given entity.
     *
     * @param {baqend.binding.Entity} entity - entity instance
     * @param {Object} [options] The load options
     * @return {Promise<baqend.binding.Entity>}
     */
    resolveDepth: function(entity, options) {
      if(!options || !options.depth)
        return Promise.resolve(entity);
  
      options.resolved = options.resolved || [];
      var promises = [];
      var subOptions = Object.extend({}, options);
      subOptions.depth = options.depth === true ? true : options.depth-1;
      this.getSubEntities(entity, 1).forEach(function(subEntity) {
        if(subEntity != null && !~options.resolved.indexOf(subEntity)) {
          options.resolved.push(subEntity);
          promises.push(this.load(subEntity.id, null, subOptions));
        }
      }.bind(this));
  
      return Promise.all(promises).then(function() {
        return entity;
      });
    },
  
    /**
     * Loads Object ID. Search for an entity of the specified oid.
     * If the entity instance is contained in the persistence context, it is returned from there.
     * @param {(Function|String)} entityClass - entity class
     * @param {String} oid - Object ID
     * @param {Object} [options] The load options
     * @return {Promise<baqend.binding.Entity>}
     */
    load: function(entityClass, oid, options) {
      options = options || {};
      var entity = this.getReference(entityClass, oid);
      var state = Metadata.get(entity);
  
      var tid = 0;
  
      //TODO: implement transactional changed case
      //if (this.transaction.isChanged(ref))
      //  tid = this.transaction.tid;
  
      var msg = new message.GetObject(state.bucket, state.key);
  
      //msg.setCacheControl('max-age=0,no-cache');
  
      if (state.version || options.refresh) {
        // force a refresh with a unused eTag
        msg.setIfNoneMatch(options.refresh? '': state.version);
      }
  
      return this._send(msg).then(function(msg) {
        if (msg.response.status != StatusCode.NOT_MODIFIED) {
          state.setJson(msg.response.entity);
        }
  
        state.setPersistent();
  
        return this.resolveDepth(entity, options);
      }.bind(this), function(e) {
        if (e.status == StatusCode.OBJECT_NOT_FOUND) {
          this.removeReference(entity);
          state.setRemoved();
          return null;
        } else {
          throw e;
        }
      }.bind(this));
    },
  
    /**
     * @param {baqend.binding.Entity} entity
     * @param {Object} options
     * @return {Promise<baqend.binding.Entity>}
     */
    insert: function(entity, options) {
      options = options || {};
      var isNew;
  
      return this._save(entity, options, function(state) {
        if (state.version)
          throw new error.PersistentError('Existing objects can\'t be inserted.');
  
        isNew = !state.id;
  
        return new message.CreateObject(state.bucket, state.getJson());
      }).then(function(val) {
        if (isNew)
          this._attach(entity);
  
        return val;
      }.bind(this));
    },
  
    /**
     * @param {baqend.binding.Entity} entity
     * @param {Object} options
     * @return {Promise<baqend.binding.Entity>}
     */
    update: function(entity, options) {
      options = options || {};
  
      return this._save(entity, options, function(state) {
        if(!state.version)
          throw new error.PersistentError("New objects can't be inserted.");
  
        if (options.force) {
          var msg = new message.ReplaceObject(state.bucket, state.key, state.getJson(true));
          msg.setIfMatch('*');
          return msg;
        } else {
          msg = new message.ReplaceObject(state.bucket, state.key, state.getJson(false));
          msg.setIfMatch(state.version);
          return msg;
        }
      });
    },
  
    /**
     * @param {baqend.binding.Entity} entity
     * @param {Object} options The save options
     * @return {Promise<baqend.binding.Entity>}
     */
    save: function(entity, options) {
      options = options || {};
  
      return this._save(entity, options, function(state) {
        if (options.force) {
          if (!state.id)
            throw new error.PersistentError("New special objects can't be forcedly saved.");
  
          return new message.ReplaceObject(state.bucket, state.key, state.getJson(true));
        } else if (state.version) {
          var msg = new message.ReplaceObject(state.bucket, state.key, state.getJson(false));
          msg.setIfMatch(state.version);
          return msg;
        } else {
          return new message.CreateObject(state.bucket, state.getJson());
        }
      });
    },
  
    /**
     * @param {baqend.binding.Entity} entity
     * @param {Function} cb pre-safe callback
     * @return {Promise<baqend.binding.Entity>}
     */
    optimisticSave: function(entity, cb) {
      var abort = false;
      var abortFn = function() {
        abort = true;
      };
      var promise = Promise.resolve(cb(entity, abortFn));
  
      if(abort)
        return Promise.resolve(entity);
  
      return promise.then(function() {
        return entity.save().catch(function(e) {
          if(e.status == 412) {
            return this.refresh(entity).then(function() {
              return this.optimisticSave(entity, cb);
            }.bind(this));
          } else {
            throw e;
          }
        }.bind(this));
      }.bind(this));
    },
  
    /**
     * Save the object state
     * @param {baqend.binding.Entity} entity
     * @param {Object} options
     * @param {Function} msgFactory
     * @return {Promise.<baqend.binding.Entity>}
     * @private
     */
    _save: function(entity, options, msgFactory) {
      this.attach(entity);
      var state = Metadata.get(entity);
      return state.withLock(function() {
        var refPromises;
        if (state.isDirty) {
          if(!options.refresh) {
            state.setPersistent();
          }
  
          var sendPromise = this._send(msgFactory(state)).then(function(msg) {
            if(options.refresh) {
              state.setJson(msg.response.entity);
              state.setPersistent();
            } else {
              state.setJsonMetadata(msg.response.entity);
            }
            return entity;
          }.bind(this), function(e) {
            if (e.status == StatusCode.OBJECT_NOT_FOUND) {
              this.removeReference(entity);
              state.setRemoved();
              return null;
            } else {
              state.setDirty();
              throw e;
            }
          }.bind(this));
  
          refPromises = [sendPromise];
        } else {
          refPromises = [Promise.resolve(entity)];
        }
  
        var subOptions = Object.extend({}, options);
        subOptions.depth = 0;
        this.getSubEntities(entity, options.depth).forEach(function(sub) {
          refPromises.push(this._save(sub, subOptions, msgFactory));
        }.bind(this));
  
        return Promise.all(refPromises).then(function() {
          return entity
        });
      }.bind(this));
    },
  
    /**
     * Returns all referenced sub entities for the given depth and root entity
     * @param {baqend.binding.Entity} entity
     * @param {Boolean|Number} depth
     * @param {baqend.binding.Entity[]} [resolved]
     * @param {baqend.binding.Entity=} initialEntity
     * @returns {baqend.binding.Entity[]}
     */
    getSubEntities: function(entity, depth, resolved, initialEntity) {
      resolved = resolved || [];
      if(!depth) {
        return resolved;
      }
      initialEntity = initialEntity || entity;
  
      var state = Metadata.get(entity);
      for (var iter = state.type.references(), item = iter.next(); !item.done; item = iter.next()) {
        this.getSubEntitiesByPath(entity, item.value.path).forEach(function(subEntity) {
          if(!~resolved.indexOf(subEntity) && subEntity != initialEntity) {
            resolved.push(subEntity);
            resolved = this.getSubEntities(subEntity, depth === true ? depth : depth-1, resolved, initialEntity);
          }
        }.bind(this));
      }
  
      return resolved;
    },
  
    /**
     * Returns all referenced one level sub entities for the given path
     * @param {baqend.binding.Entity} entity
     * @param {Array} path
     * @returns {baqend.binding.Entity[]}
     */
    getSubEntitiesByPath: function(entity, path) {
      var subEntities = [entity];
  
      path.forEach(function(attributeName) {
  
        var tmpSubEntities = [];
        subEntities.forEach(function(subEntity) {
          var curEntity = subEntity[attributeName];
          if(!curEntity)
            return;
  
          var attribute = this.metamodel.managedType(subEntity.constructor).getAttribute(attributeName);
          if(attribute.isCollection) {
            for (var colIter = curEntity.entries(), colItem; !(colItem = colIter.next()).done; ) {
              tmpSubEntities.push(colItem.value[1]);
              attribute.keyType && attribute.keyType.isEntity && tmpSubEntities.push(colItem.value[0]);
            }
          } else {
            tmpSubEntities.push(curEntity);
          }
        }.bind(this));
        subEntities = tmpSubEntities;
  
      }.bind(this));
  
      return subEntities;
    },
  
    /**
     * Delete the entity instance.
     * @param {baqend.binding.Entity} entity
     * @param {Object} options The delete options
     * @return {Promise<baqend.binding.Entity>}
     */
    delete: function(entity, options) {
      options = options || {};
  
      this.attach(entity);
      var state = Metadata.get(entity);
  
      return state.withLock(function() {
        if(!state.version && !options.force)
          throw new error.IllegalEntityError(entity);
  
        var msg = new message.DeleteObject(state.bucket, state.key);
  
        if (!options.force)
          msg.setIfMatch(state.version);
  
        var refPromises = [ this._send(msg).then(function() {
          this.removeReference(entity);
          state.setRemoved();
          return entity;
        }.bind(this)) ];
  
        var subOptions = Object.extend({}, options);
        subOptions.depth = 0;
        this.getSubEntities(entity, options.depth).forEach(function(sub) {
          refPromises.push(this.delete(sub, subOptions));
        }.bind(this));
  
        return Promise.all(refPromises).then(function() {
          return entity;
        });
      }.bind(this));
    },
  
    /**
     * Synchronize the persistence context to the underlying database.
     *
     * @returns {baqend.Promise}
     */
    flush: function(doneCallback, failCallback) {
      // TODO: implement this
    },
  
    /**
     * Make an instance managed and persistent.
     * @param {baqend.binding.Entity} entity - entity instance
     */
    persist: function(entity) {
      entity.attach(this);
    },
  
    /**
     * Refresh the state of the instance from the database, overwriting changes made to the entity, if any.
     * @param {baqend.binding.Entity} entity - entity instance
     * @param {Object} options The refresh options
     * @return {Promise<baqend.binding.Entity>}
     */
    refresh: function(entity, options) {
      options = options || {};
      options.refresh = true;
  
      return this.load(entity.id, null, options);
    },
  
    /**
     * Attach the instance to this database context, if it is not already attached
     * @param {baqend.binding.Entity} entity The entity to attach
     */
    attach: function(entity) {
      if (!this.contains(entity)) {
        var type = this.metamodel.entity(classOf(entity));
        if (!type)
          throw new error.IllegalEntityError(entity);
  
        if(this.containsById(entity))
          throw new error.EntityExistsError(entity);
  
        this._attach(entity);
      }
    },
  
    _attach: function(entity) {
      var metadata = Metadata.get(entity);
      if (metadata.isAttached) {
        if (metadata.db != this) {
          throw new error.EntityExistsError(entity);
        }
      } else {
        metadata.db = this;
      }
  
      if (!metadata.id) {
        if (metadata.type.name != 'User' && metadata.type.name != 'Role') {
          metadata.id = '/db/' + metadata.type.name + '/' + util.uuid();
        }
      }
  
      if (metadata.id) {
        this._entities[metadata.id] = entity;
      }
    },
  
    removeReference: function(entity) {
      var state = Metadata.get(entity);
      if (!state)
        throw new error.IllegalEntityError(entity);
  
      delete this._entities[state.id];
    },
  
    register: function(user, password, login) {
      if (this.me && login)
        throw new error.PersistentError('User is already logged in.');
  
      return this.withLock(function() {
        var msg = new message.Register({
          user: user,
          password: password,
          global: this.isGlobal,
          login: login
        });
  
        return this._userRequest(msg, login);
      }.bind(this));
    },
  
    login: function(username, password) {
      if (this.me)
        throw new error.PersistentError('User is already logged in.');
  
      return this.withLock(function() {
        var msg = new message.Login({
          username: username,
          password: password,
          global: this.isGlobal
        });
  
        return this._userRequest(msg, true);
      }.bind(this));
    },
  
    logout: function() {
      return this.withLock(function() {
        var logout = function() {
          this.me = null;
          this.token = null;
        }.bind(this);
        return this.isGlobal ? this._send(new message.Logout()).then(logout) : Promise.resolve(logout());
      }.bind(this));
    },
  
    loginWithOAuth: function(provider, clientID, options) {
      options = Object.extend({
        title: "Login with " + provider,
        timeout: 5 * 60 * 1000,
        state: {}
      }, options);
  
      var state = Object.extend(options.state, {
        isGlobal: this.isGlobal
      });
  
      var msg;
      if (Message[provider + 'OAuth']) {
        msg = new Message[provider + 'OAuth'](clientID, options.scope, JSON.stringify(state));
      } else {
        throw new Error("Provider not supported.")
      }
  
      var req = this._userRequest(msg, true);
      var w = open(msg.request.path, options.title, 'width=' + options.width + ',height=' + options.height);
  
      return new Promise(function(resolve, reject) {
        var timeout = setTimeout(function() {
          reject(new error.PersistentError('OAuth login timeout.'));
        }, options.timeout);
  
        req.then(function(result) {
          clearTimeout(timeout);
          resolve(result);
        }, function(e) {
          clearTimeout(timeout);
          reject(e);
        });
      }.bind(this));
    },
  
    renew: function() {
      return this.withLock(function() {
        var msg = new message.Me();
        msg.withAuthorizationToken(this.isGlobal? false: this.token);
        return this._userRequest(msg, true);
      }.bind(this));
    },
  
    newPassword: function(username, password, newPassword) {
      return this.withLock(function() {
        var msg = new message.NewPassword({
          username: username,
          password: password,
          newPassword: newPassword,
          global: this.isGlobal
        });
  
        return this._send(msg).then(function() {
          var user = this.getReference(msg.response.entity.id);
          var metadata = Metadata.get(user);
          metadata.setJson(msg.response.entity);
          metadata.setPersistent();
        }.bind(this));
      }.bind(this));
    },
  
    _userRequest: function(msg, updateMe) {
      return this._send(msg).then(function() {
        var user = this.getReference(msg.response.entity.id);
        var metadata = Metadata.get(user);
        metadata.setJson(msg.response.entity);
        metadata.setPersistent();
        if (updateMe)
          this.me = user;
  
        return user;
      }.bind(this), function(e) {
        if (e.status == StatusCode.OBJECT_NOT_FOUND) {
          return null;
        } else {
          throw e;
        }
      });
    },
  
    registerDevice: function(os, token, device) {
      var msg = new message.DeviceRegister({
        token: token,
        devicetype: os,
        device: device
      });
  
      return this._send(msg);
    },
  
    checkDeviceRegistration: function() {
      return this._send(new message.DeviceRegistered()).then(function() {
        return this.isDeviceRegistered = true;
      }.bind(this), function(e) {
        if (e.status == StatusCode.OBJECT_NOT_FOUND) {
          return this.isDeviceRegistered = false;
        } else {
          throw e;
        }
      }.bind(this));
    },
  
    pushDevice: function(pushMessage) {
      return this._send(new message.DevicePush(pushMessage));
    },
  
    /**
     * The given entity will be checked by the validation code of the entity type.
     *
     * @param {baqend.binding.Entity} entity
     * @returns {baqend.util.ValidationResult} result
     */
    validate: function(entity) {
      var type = Metadata.get(entity).type;
  
      var result = new util.ValidationResult();
      for (var iter = type.attributes(), item; !(item = iter.next()).done; ) {
        var validate = new util.Validator(item.value.name, entity);
        result.fields[validate.key] = validate;
      }
  
      var validationCode = type.validationCode;
      if(validationCode) {
        validationCode(result.fields);
      }
  
      return result;
    },
  
    /**
     * An User factory for user objects.
     * The User factory can be called to create new instances of users or can be used to register/login/logout users.
     * The created instances implements the {@link baqend.binding.User} interface
     * @type baqend.binding.UserFactory
     */
    User: null,
  
    /**
     * An Device factory for user objects.
     * The Device factory can be called to create new instances of devices or can be used to register, push to and
     * check registration status of devices.
     * @type baqend.binding.DeviceFactory
     */
    Device: null
  
    /**
     * An Object factory for embeddable objects,
     * that can be accessed by the type name of the embeddable type.
     * An object factory can be called to create new instances of the type.
     * The created instances implements the {@link baqend.binding.Managed} interface
     * @name &lt;<i>YourEmbeddableClass</i>&gt;
     * @memberOf baqend.EntityManager.prototype
     * @type {baqend.binding.ManagedFactory}
     */
  
    /**
     * An Object factory for entity objects,
     * that can be accessed by the type name of the entity type.
     * An object factory can be called to create new instances of the type.
     * The created instances implements the {@link baqend.binding.Entity} interface
     * @name &lt;<i>YourEntityClass</i>&gt;
     * @memberOf baqend.EntityManager.prototype
     * @type {baqend.binding.EntityFactory}
     */
  
    /**
     * An Role factory for role objects.
     * The Role factory can be called to create new instances of roles.
     * The created instances implements the {@link baqend.binding.Role} interface
     * @name Role
     * @memberOf baqend.EntityManager.prototype
     * @type baqend.binding.EntityFactory
     */
  });
  
  module.exports = EntityManager;
  }).call(this,require("--timers--").clearTimeout,require("--timers--").setTimeout)
  },{"--timers--":69,"./EntityTransaction":3,"./GeoPoint":4,"./Query":5,"./binding":16,"./collection":17,"./connector/Message":20,"./error":31,"./message":33,"./util":60,"./util/Metadata":54}],2:[function(require,module,exports){
  var message = require('./message');
  var metamodel = require('./metamodel');
  
  var Lockable = require('./util/Lockable');
  var Code = require('./util/Code');
  var Connector = require('./connector/Connector');
  var EntityManager = require('./EntityManager');
  
  /**
   * @class baqend.EntityManagerFactory
   * @extends baqend.util.Lockable
   *
   * Creates a new EntityManagerFactory connected to the given destination
   * @param {String|Object} [options] The baqend destination to connect with, or an options object
   * @param {String} [options.host] The baqend destination to connect with
   * @param {Number} [options.port=80|443] The optional baqend destination port to connect with
   * @param {Number} [options.secure=false] <code>true</code> To use a secure ssl encrypted connection
   * @param {Object} [options.schema=null] The serialized schema as json used to initialize the metamodel
   * @param {Boolean} [options.global=false] <code>true</code> To create the emf for the global DB
   */
  var EntityManagerFactory = Object.inherit(Lockable, /** @lends baqend.EntityManagerFactory.prototype */ {
  
    /**
     * @type baqend.connector.Connector
     * @private
     */
    _connector: null,
  
    /**
     * @type baqend.metamodel.Metamodel
     */
    metamodel: null,
  
    /**
     * @type baqend.util.Code
     */
    code: null,
  
    _connected: function() {},
  
    constructor: function EntityManagerFactory(options) {
      options = String.isInstance(options)? {host: options}: options || {};
  
      if (options.host) {
        this.connect(options.host, options.port, options.secure);
      } else {
        this.withLock(function() {
          return new Promise(function(success) {
            this._connected = success;
          }.bind(this));
        }.bind(this), true);
      }
  
      this.metamodel = this.createMetamodel(options.global);
      this.code = this.createCode();
  
      if (options.schema) {
        this.metamodel.init(options.schema);
      }
    },
  
    /**
     * Connects this EntityManager to the given destination
     * @param {String} host The host to connect with
     * @param {Number} [port] The port to connect to
     * @param {Boolean} [secure] <code>true</code> To use a secure connection
     */
    connect: function(host, port, secure) {
      if (this._connector)
        throw new Error('The EntityManagerFactory is already connected.');
  
      this._connector = Connector.create(host, port, secure);
      this._connected();
    },
  
    /**
     * Creates a new Metamodel instance, connected to the same destination as this EntityManagerFactory is connected to
     * @return {baqend.metamodel.Metamodel} A new Metamodel instance
     */
    createMetamodel: function(global) {
      var model = global? metamodel: new metamodel.Metamodel();
  
      if (this.isReady) {
        model.connected(this._connector);
      } else {
        model.withLock(function() {
          return this.ready().then(function() {
            model.connected(this._connector);
          }.bind(this));
        }.bind(this), true);
      }
  
      return model;
    },
  
    /**
     * Creates a new Code instance, connected to the same destination as this EntityManagerFactory is connected to
     * @return {baqend.util.Code} A new Code instance
     */
    createCode: function() {
      var code = new Code(this.metamodel);
      if (this.isReady) {
        code.connected(this._connector);
      } else {
        this.ready().then(function(emf) {
          code.connected(emf._connector);
        });
      }
      return code;
    },
  
    /**
     * Create a new application-managed EntityManager.
     *
     * @param {Boolean=} global <code>true</code> To use the global authorization
     *
     * @returns {baqend.EntityManagerFactory} a new entityManager
     */
    createEntityManager: function(global) {
      var em = new EntityManager(this, global);
  
      var promise;
      if (this.metamodel.isReady && this.metamodel.isInitialized) {
        promise = em.connected(this._connector);
      } else {
        promise = this.metamodel.ready().then(function() {
          return this.metamodel.init();
        }.bind(this)).then(function() {
          return em.connected(this._connector);
        }.bind(this));
      }
  
      if (promise) {
        em.withLock(function() {
          return promise;
        }, true);
      }
  
      return em;
    }
  });
  
  module.exports = EntityManagerFactory;
  },{"./EntityManager":1,"./connector/Connector":18,"./message":33,"./metamodel":49,"./util/Code":52,"./util/Lockable":53}],3:[function(require,module,exports){
  var message = require('./message');
  var error = require('./error');
  
  /**
   * @class baqend.EntityTransaction
   */
  var EntityTransaction = Object.inherit(/** @lends baqend.EntityTransaction.prototype */ {
  
  	/**
  	 * Indicate whether a resource transaction is in progress. 
  	 * @returns {Boolean} indicating whether transaction is in progress 
   	 */
  	get isActive() {
      return Boolean(this.tid);
  	},
  	
  	/**
  	 * @param {baqend.EntityManager} entityManager
  	 */
  	constructor: function EntityTransaction(entityManager) {
  		this._connector = entityManager.connector;
  		this.entityManager = entityManager;
  		
  		this.tid = null;
  		this.rollbackOnly = false;
  		
  		this.readSet = null;
  		this.changeSet = null;
  	},
  	
  	/**
  	 * Start a resource transaction.
  	 */
  	begin: function(doneCallback, failCallback) {
  		return this.yield().then(function() {
  			var result = this.send(new message.PostTransaction()).done(function(msg) {
  				this.tid = msg.tid;
  
  				this.rollbackOnly = false;
  				this.readSet = {};
  				this.changeSet = {};
  			});
  			
  			return this.wait(result);
  		}).then(doneCallback, failCallback);
  	},
  	
  	/**
  	 * Commit the current resource transaction, writing any unflushed changes to the database. 
  	 */
  	commit: function(doneCallback, failCallback) {
  		return this.yield().then(function() {
  			if (this.getRollbackOnly()) {
  				return this.rollback().then(function() {
  					throw new error.RollbackError();
  				});
  			} else {
  				return this.wait(this.entityManager.flush()).then(function() {
  					var readSet = [];
  					for (var ref in this.readSet) {
  						readSet.push({
  							"oid": ref,
  							"version": this.readSet[ref]
  						});
  					}
  					
  					var result = this.send(new message.PutTransactionCommitted(this.tid, readSet));
  					
  					return this.wait(result).then(function(msg) {
  						this.tid = null;
  						this.readSet = null;
  						this.changeSet = null;
  						
  						var oids = msg.oids;
  						for (var oid in oids) {
  							var version = oids[oid];
  							var entity = this.entityManager.entities[oid];
  							
  							if (entity) {
  								var state = util.Metadata.get(entity);
  								if (version == 'DELETED' || state.isDeleted) {
  									this.entityManager.removeReference(entity);
  								} else {								
  									state.setJsonValue(state.type.version, version);
  								}
  							}
  						}
  					});
  				});
  			}
  		}).then(doneCallback, failCallback);
  	},
  	
  	/**
  	 * Determine whether the current resource transaction has been marked for rollback. 
  	 * @returns {Boolean} indicating whether the transaction has been marked for rollback 
  	 */
  	getRollbackOnly: function() {
  		return this.rollbackOnly;
  	},
  	
  	/**
  	 * Roll back the current resource transaction. 
  	 */
  	rollback: function(doneCallback, failCallback) {
  		return this.yield().then(function() {
  			var result = this.send(new message.PutTransactionAborted(this.tid));
  			
  			this.wait(result).then(function() {
  				this.tid = null;
  				this.readSet = null;
  				this.changeSet = null;
  				return this.entityManager.clear();
  			}, function() {
  				return this.entityManager.clear();
  			});
  		}).then(doneCallback, failCallback);
  	},
  	
  	/**
  	 * Mark the current resource transaction so that the only possible outcome of the transaction is for the transaction to be rolled back. 
  	 */
  	setRollbackOnly: function(context, onSuccess) {
  		return this.yield().done(function() {
  			this.rollbackOnly = true;
  		});
  	},
  	
  	isRead: function(identifier) {
  		return this.isActive && identifier in this.readSet;
  	},
  	
  	setRead: function(identifier, version) {
  		if (this.isActive && !this.isChanged(identifier)) {
  			this.readSet[identifier] = version;
  		}
  	},
  	
  	isChanged: function(identifier) {
  		return this.isActive && identifier in this.changeSet;
  	},
  	
  	setChanged: function(identifier) {
  		if (this.isActive) {
  			delete this.readSet[identifier];
  			this.changeSet[identifier] = true;
  		}
  	}
  });
  
  module.exports = EntityTransaction;
  },{"./error":31,"./message":33}],4:[function(require,module,exports){
  var collection = require('./collection');
  
  /**
   * Creates a new GeoPoint instance
   * From latitude and longitude
   * From a json object
   * Or an tuple of latitude and longitude
   *
   * @class baqend.GeoPoint
   *
   * @param {String|Number|Object|Array=} latitude A coordinate pair (latitude first), a GeoPoint like object or the GeoPoint's latitude
   * @param {Number=} longitude The GeoPoint's longitude
   */
  var GeoPoint = Object.inherit(/** @lends baqend.GeoPoint.prototype */ {
  
    /** @lends baqend.GeoPoint */
    extend: {
      DEG_TO_RAD: Math.PI/180,
  
      /**
       * The Earth radius in kilometers used by {@link baqend.GeoPoint#kilometersTo}
       * @type {Number}
       */
      EARTH_RADIUS_IN_KILOMETERS: 6371,
  
      /**
       * The Earth radius in miles used by {@link baqend.GeoPoint#milesTo}
       * @type {Number}
       */
      EARTH_RADIUS_IN_MILES: 3956,
  
      /**
       * Creates a GeoPoint with the user's current location, if available.
       * @return {Promise<baqend.GeoPoint>} A promise that will be resolved with a GeoPoint
       */
      current: function() {
        return new Promise(function(resolve, reject) {
          navigator.geolocation.getCurrentPosition(function(location) {
            resolve(new GeoPoint(location.coords.latitude, location.coords.longitude));
          }, function(error) {
            reject(error);
          });
        });
      },
  
      conv: function(param) {
        return new this(param);
      }
    },
  
    latitude: 0,
    longitude: 0,
  
    /**
     * @private
     */
    constructor: function GeoPoint(latitude, longitude) {
      if (String.isInstance(latitude)) {
        var index = latitude.indexOf(';');
        this.latitude = latitude.substring(0, index);
        this.longitude = latitude.substring(index + 1);
      } else if (Number.isInstance(latitude)) {
        this.latitude = latitude;
        this.longitude = longitude;
      } else if (Array.isInstance(latitude)) {
        this.latitude = latitude[0];
        this.longitude = latitude[1];
      } else if (Object.isInstance(latitude)) {
        this.latitude = latitude.latitude;
        this.longitude = latitude.longitude;
      }
  
      if (this.latitude < -90 || this.latitude > 90) {
        throw new Error("Latitude " + this.latitude + " is not in bound of -90 <= latitude <= 90");
      }
  
      if (this.longitude < -180 || this.longitude > 180) {
        throw new Error("Longitude " + this.longitude + " is not in bound of -180 <= longitude <= 180");
      }
    },
  
    /**
     * Returns the distance from this GeoPoint to another in kilometers.
     * @param {baqend.GeoPoint} point another GeoPoint
     * @return {Number} The distance in kilometers
     *
     * @see baqend.GeoPoint#radiansTo
     */
    kilometersTo: function(point) {
      return Number((GeoPoint.EARTH_RADIUS_IN_KILOMETERS * this.radiansTo(point)).toFixed(3));
    },
  
    /**
     * Returns the distance from this GeoPoint to another in miles.
     * @param {baqend.GeoPoint} point another GeoPoint
     * @return {Number} The distance in miles
     *
     * @see baqend.GeoPoint#radiansTo
     */
    milesTo: function(point) {
      return Number((GeoPoint.EARTH_RADIUS_IN_MILES * this.radiansTo(point)).toFixed(3));
    },
  
    /**
     * Computes the arc, in radian, between two WGS-84 positions.
     *
     * The haversine formula implementation is taken from:
     * {@link http://www.movable-type.co.uk/scripts/latlong.html}
     *
     * Returns the distance from this GeoPoint to another in radians.
     * @param {baqend.GeoPoint} point another GeoPoint
     * @return {Number} the arc, in radian, between two WGS-84 positions
     *
     * @see http://en.wikipedia.org/wiki/Haversine_formula
     */
    radiansTo: function(point) {
      var from = this, to = point;
      var rad1 = from.latitude * GeoPoint.DEG_TO_RAD,
          rad2 = to.latitude * GeoPoint.DEG_TO_RAD,
          dLng = (to.longitude - from.longitude) * GeoPoint.DEG_TO_RAD;
  
      return Math.acos(Math.sin(rad1) * Math.sin(rad2) + Math.cos(rad1) * Math.cos(rad2) * Math.cos(dLng));
    },
  
    /**
     * A String representation in latitude, longitude format
     * @return {String} The string representation of this class
     */
    toString: function() {
      return this.latitude + ';' + this.longitude;
    },
  
    /**
     * Returns a JSON representation of the GeoPoint
     * @return {Object} A GeoJson object of this GeoPoint
     */
    toJSON: function() {
      return {latitude: this.latitude, longitude: this.longitude};
    }
  });
  
  module.exports = GeoPoint;
  
  },{"./collection":17}],5:[function(require,module,exports){
  var message = require('./message');
  var Metadata = require('./util/Metadata');
  var Entity = require('./binding/Entity');
  
  /**
   * @class baqend.Query
   */
  var Query = Trait.inherit(/** @lends baqend.Query.prototype */ {
  
    extend: {
      MAX_URI_SIZE: 2000
    },
  
    /**
     * The owning EntityManager of this query
     * @type baqend.EntityManager
     */
    entityManager: null,
  
    /**
     * The result class of this query
     * @type Function
     */
    resultClass: null,
  
  
    /**
     * Add an ascending sort for the specified field to this query
     * @param field The field to sort
     * @return {baqend.Query} The resulting Query
     */
    ascending: function(field) {
      return this._addOrder(field, 1);
    },
  
    /**
     * Add an decending sort for the specified field to this query
     * @param field The field to sort
     * @return {baqend.Query} The resulting Query
     */
    descending: function(field) {
      return this._addOrder(field, -1);
    },
  
    /**
     * Sets the sort of the query and discard all existing paramaters
     * @param {Object} sort The new sort of the query
     * @return {baqend.Query} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/method/cursor.sort/
     */
    sort: function(sort) {
      if (classOf(sort) != Object)
        throw new Error('sort must be an object.');
  
      return this._addOrder(sort);
    },
  
    /**
     * Sets the offset of the query, i.e. how many elements should be skipped
     * @param offset The offset of this query
     * @return {baqend.Query} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/method/cursor.skip/
     */
    offset: function(offset) {
      if (offset < 0)
        throw new Error("The offset can't be nagative.");
  
      return this._addOffset(offset);
    },
  
    /**
     * Sets the limit of this query, i.e hox many objects should be returnd
     * @param limit The limit of this query
     * @return {baqend.Query} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/method/cursor.limit/
     */
    limit: function(limit) {
      if (limit < 0)
        throw new Error("The limit can't be nagative.");
  
      return this._addLimit(limit);
    },
  
    /**
     * Execute the query and return the query results as a List.
     * Note: All local unsaved changes on matching objects, will be discarded.
     * @param {Object} [options] The query options
     * @param {Number|Boolean} [options.depth=0] The object depth which will be loaded. Depth 0 load only the found
     * objects, <code>true</code> loads the objects by reachability.
     * @param {Function=} doneCallback Called when the operation succeed.
     * @param {Function=} failCallback Called when the operation failed.
     * @return {Promise<Array<baqend.binding.Entity>>} A promise that will be resolved with the query result as a list
     */
    resultList: function(options, doneCallback, failCallback) {
    },
  
    /**
     * Execute the query that returns a single result.
     * Note: All local unsaved changes on the matched object, will be discarded.
     * @param {Object} [options] The query options
     * @param {Number|Boolean} [options.depth=0] The object depth which will be loaded. Depth 0 load only the found
     * object, <code>true</code> loads the objects by reachability.
     * @param {Function=} doneCallback Called when the operation succeed.
     * @param {Function=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A promise that will be resolved with the query result as a single result
     */
    singleResult: function(options, doneCallback, failCallback) {},
  
  
    stream: function(fetchQuery) {},
  
    /**
     * Execute the query that returns the matching objects count.
     * @return {Promise<Number>} The total number of matched objects
     */
    count: function(doneCallback, failCallback) {}
  });
  
  /**
   * @class baqend.Query.Condition
   * @extends baqend.Query
   */
  Query.Condition = Query.inherit(/** @lends baqend.Query.Condition.prototype */ {
  
    /**
     * An object, that contains filter rules which will be merged with the current filters of this query.
     * @param {Object} conditions - Additional filters for this query
     * @return {baqend.Query.Condition} The resulting Query
     */
    where: function(conditions) {
      return this._addFilter(null, null, conditions);
    },
  
    /**
     * Adds a equal filter to the field. All other other filters on the field will be discarded
     * @param {String} field The field to filter
     * @param {*} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     */
    equal: function(field, value) {
      return this._addFilter(field, null, value);
    },
  
    /**
     * Adds a not equal filter to the field.
     * @param {String} field The field to filter
     * @param {*} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/nin/
     */
    notEqual: function(field, value) {
      return this._addFilter(field, "$ne", value);
    },
  
    /**
     * Adds a greater than filter to the field.
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/gt/
     */
    greaterThan: function(field, value) {
      return this._addFilter(field, "$gt", value);
    },
  
    /**
     * Adds a greater than or equal to filter to the field.
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/gte/
     */
    greaterThanOrEqualTo: function(field, value) {
      return this._addFilter(field, "$gte", value);
    },
  
    /**
     * Adds a less than filter to the field.
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/lt/
     */
    lessThan: function(field, value) {
      return this._addFilter(field, "$lt", value);
    },
  
    /**
     * Adds a less than or equal to filter to the field.
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/lte/
     */
    lessThanOrEqualTo: function(field, value) {
      return this._addFilter(field, "$lte", value);
    },
  
    /**
     * Adds a between filter to the field. This is a shorthand for an less than and greater than filter.
     * @param {String} field The field to filter
     * @param {Number|String|Date} lessValue The field value must be greater than this value
     * @param {Number|String|Date} greaterValue The field value must be less than this value
     * @return {baqend.Query.Condition} The resulting Query
     */
    between: function(field, lessValue, greaterValue) {
      return this._addFilter(field, "$gt", lessValue)
          ._addFilter(field, "$lt", greaterValue);
    },
  
    /**
     * Adds a in filter to the field. The field value must be equal to one of the given values
     * @param {String} field The field to filter
     * @param {*|Array<*>} args... The field value or values to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/in/
     */
    'in': function(field, args) {
      return this._addFilter(field, "$in", classOf(args) == Array ? args : Array.prototype.slice.call(arguments, 1));
    },
  
    /**
     * Adds a not in filter to the field. The field value must not be equal to any of the given values
     * @param {String} field The field to filter
     * @param {*|Array<*>} args... The field value or values to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/nin/
     */
    notIn: function(field, args) {
      return this._addFilter(field, "$nin", classOf(args) == Array ? args : Array.prototype.slice.call(arguments, 1));
    },
  
    /**
     * Adds a null filter to the field. The field value must be null
     * @param {String} field The field to filter
     * @return {baqend.Query.Condition} The resulting Query
     */
    isNull: function(field) {
      return this.equal(field, null);
    },
  
    /**
     * Adds a not null filter to the field. The field value must not be null
     * @param {String} field The field to filter
     * @return {baqend.Query.Condition} The resulting Query
     */
    isNotNull: function(field) {
      return this._addFilter(field, "$exists", true)
          ._addFilter(field, "$ne", null);
    },
  
    /**
     * Adds a contains all filter to the collection field. The collection must contain all the given values.
     * @param {String} field The field to filter
     * @param {*|Array<*>} args... The field value or values to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/all/
     */
    containsAll: function(field, args) {
      return this._addFilter(field, "$all", classOf(args) == Array ? args : Array.prototype.slice.call(arguments, 1));
    },
  
    /**
     * Adds a modulo filter to the field. The field value divided by divisor must be equal to the remainder.
     * @param {String} field The field to filter
     * @param {Number} divisor The divisor of the modulo filter
     * @param {Number} remainder The remainder of the modulo filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/mod/
     */
    mod: function(field, divisor, remainder) {
      return this._addFilter(field, "$mod", [divisor, remainder]);
    },
  
    /**
     * Adds a regular expression filter to the field. The field value must matches the regular expression.
     * <p>Note: Only anchored expressions (Expressions that starts with an ^) and the multiline flag are supported.</p>
     * @param {String} field The field to filter
     * @param {String|RegExp} regExp The regular expression of the filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/regex/
     */
    matches: function(field, regExp) {
      if (!RegExp.isInstance(regExp)) {
        regExp = new RegExp(regExp);
      }
  
      if (regExp.ignoreCase) {
        throw new Error('RegExp.ignoreCase flag is not supported.');
      }
  
      if (regExp.global) {
        throw new Error('RegExp.global flag is not supported.');
      }
  
      if (regExp.source.indexOf('^') != 0) {
        throw new Error('regExp must be an anchored expression, i.e. it must be started with a ^.');
      }
  
      var result = this._addFilter(field, '$regex', regExp.source);
      if (regExp.multiline) {
        result._addFilter(field, '$options', 'm');
      }
  
      return result;
    },
  
    /**
     * Adds a size filter to the collection field. The collection must have exactly size members.
     * @param {String} field The field to filter
     * @param {Number} size The collections size to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/size/
     */
    size: function(field, size) {
      return this._addFilter(field, "$size", size);
    },
  
    /**
     * Adds a geopoint based near filter to the GeoPoint field. The GeoPoint must be within the maximum distance
     * to the given GeoPoint. Returns from nearest to farthest.
     * @param {String} field The field to filter
     * @param {baqend.GeoPoint} geoPoint The GeoPoint to filter
     * @param {Number} maxDistance Tha maximum distance to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/nearSphere/
     */
    near: function(field, geoPoint, maxDistance) {
      return this._addFilter(field, "$nearSphere", {
        $geometry: {
          type: "Point",
          coordinates: [geoPoint.longitude, geoPoint.latitude]
        },
        $maxDistance: maxDistance
      });
    },
  
    /**
     * Adds a GeoPoint based polygon filter to the GeoPoint field. The GeoPoint must be contained within the polygon.
     * @param {String} field The field to filter
     * @param {baqend.GeoPoint|Array<baqend.GeoPoint>} geoPoints... The geoPoints that describes the polygon of the filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/geoWithin/
     */
    withinPolygon: function(field, geoPoints) {
      geoPoints = classOf(geoPoints) == Array ? geoPoints : Array.prototype.slice.call(arguments, 1);
  
      return this._addFilter(field, "$geoWithin", {
        $geometry: {
          type: "Polygon",
          coordinates: [geoPoints.map(function(geoPoint) {
            return [geoPoint.longitude, geoPoint.latitude];
          })]
        }
      });
    }
  });
  
  // aliases
  var proto = Query.Condition.prototype;
  Object.extend(proto, /** @lends baqend.Query.Condition.prototype */ {
    /**
     * Adds a less than filter to the field. Shorthand for {@link baqend.Query.Condition#lessThan}.
     * @method
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/lt/
     */
    lt: proto.lessThan,
  
    /**
     * Adds a less than or equal to filter to the field. Shorthand for {@link baqend.Query.Condition#lessThanOrEqualTo}.
     * @method
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/lte/
     */
    le: proto.lessThanOrEqualTo,
  
    /**
     * Adds a greater than filter to the field. Shorthand for {@link baqend.Query.Condition#greaterThan}.
     * @method
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/gt/
     */
    gt: proto.greaterThan,
  
    /**
     * Adds a greater than or equal to filter to the field. Shorthand for {@link baqend.Query.Condition#greaterThanOrEqualTo}.
     * @method
     * @param {String} field The field to filter
     * @param {Number|String|Date} value The value used to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/gte/
     */
    ge: proto.greaterThanOrEqualTo,
  
    /**
     * Adds a contains any filter to the collection field. The collection must contains one the given values.
     * Alias for {@link baqend.Query.Condition#in}
     * @method
     * @param {String} field The field to filter
     * @param {*|Array<*>} args... The field value or values to filter
     * @return {baqend.Query.Condition} The resulting Query
     *
     * @see http://docs.mongodb.org/manual/reference/operator/query/in/
     */
    containsAny: proto.in
  });
  
  /**
   * @class baqend.Query.Node
   * @extends baqend.Query
   *
   * @param {baqend.EntityManager} entityManager The owning entity manager of this query
   * @param {Function} resultClass The query result class
   */
  Query.Node = Object.inherit(Query, /** @lends baqend.Query.Node.prototype */ {
  
    /**
     * The offset how many results should be skipped
     * @type Number
     */
    firstResult: 0,
  
    /**
     * The limit how many objects should be returned
     * @type Number
     */
    maxResults: -1,
  
    initialize: function(entityManager, resultClass) {
      this.entityManager = entityManager;
      this.resultClass = resultClass;
      this._sort = {};
    },
  
  
    /**
     * @inheritDoc
     */
    stream: function(fetchQuery) {
      var type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null;
      if (!type) {
        throw new Error('Only typed queries can be executed.');
      }
  
      if (fetchQuery === undefined)
        fetchQuery = true;
  
  
      var sort = this._serializeSort();
  
      return new Query.Stream(this.entityManager, type.name, this._serializeQuery(), fetchQuery, sort, this.maxResults);
    },
  
  
    /**
     * @inheritDoc
     */
    resultList: function(options, doneCallback, failCallback) {
      if(Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      var type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null;
  
      if (!type) {
        throw new Error('Only typed queries can be executed.');
      }
  
      var query = this._serializeQuery();
      var sort = this._serializeSort();
  
      var uriSize = this.entityManager._connector.host.length + query.length;
      var msg;
      if(uriSize > Query.MAX_URI_SIZE) {
        msg = new message.AdhocQueryPOST(type.name, this.firstResult, this.maxResults, sort, query);
      } else {
        msg = new message.AdhocQuery(type.name, query, this.firstResult, this.maxResults, sort);
      }
  
      return this.entityManager._send(msg).then(function() {
        return this._createResultList(msg.response.entity, options);
      }.bind(this)).then(doneCallback, failCallback);
    },
  
    /**
     * @inheritDoc
     */
    singleResult: function(options, doneCallback, failCallback) {
      if(Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      var type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null;
  
      if (!type) {
        throw new Error('Only typed queries can be executed.');
      }
  
      var query = this._serializeQuery();
      var sort = this._serializeSort();
  
      var uriSize = this.entityManager._connector.host.length + query.length;
      var msg;
      if(uriSize > Query.MAX_URI_SIZE) {
        msg = new message.AdhocQueryPOST(type.name, query, this.firstResult, 1, sort, query);
      } else {
        msg = new message.AdhocQuery(type.name, query, this.firstResult, 1, sort);
      }
  
      return this.entityManager._send(msg).then(function() {
        return this._createResultList(msg.response.entity, options);
      }.bind(this)).then(function(list) {
        return list.length ? list[0] : null;
      }).then(doneCallback, failCallback);
    },
  
    /**
     * @inheritDoc
     */
    count: function(doneCallback, failCallback) {
      var type = this.resultClass ? this.entityManager.metamodel.entity(this.resultClass) : null;
  
      if (!type) {
        throw new Error('Only typed queries can be executed.');
      }
  
      var query = this._serializeQuery();
  
      var uriSize = this.entityManager._connector.host.length + query.length;
      var msg;
      if(uriSize > Query.MAX_URI_SIZE) {
        msg = new message.AdhocCountQueryPOST(type.name, query);
      } else {
        msg = new message.AdhocCountQuery(type.name, query);
      }
  
      return this.entityManager._send(msg).then(function() {
        return msg.response.entity.count;
      }).then(doneCallback, failCallback);
    },
  
    _serializeQuery: function() {
      return JSON.stringify(this, function(k, v) {
        var typedValue = this[k];
        if (Date.isInstance(typedValue)) {
          return {$date: v};
        } else if (Entity.isInstance(typedValue)) {
          return typedValue.id;
        } else {
          return v;
        }
      });
    },
  
    _serializeSort: function() {
      return JSON.stringify(this._sort);
    },
  
    _createResultList: function(result, options) {
      if (result.length) {
        return Promise.all(result.map(function(el) {
          if (el.id) {
            var entity = this.entityManager.getReference(this.resultClass, el.id);
            var metadata = Metadata.get(entity);
            metadata.setJson(el);
            metadata.setPersistent();
            return this.entityManager.resolveDepth(entity, options);
          } else {
            return this.entityManager.load(Object.keys(el)[0]);
          }
        }, this)).then(function(result) {
          return result.filter(function(val) {
            return !!val;
          });
        });
      } else {
        return Promise.resolve([]);
      }
    },
  
    _addOrder: function(fieldOrSort, order) {
      if (order) {
        this._sort[fieldOrSort] = order;
      } else {
        this._sort = fieldOrSort;
      }
      return this;
    },
  
    _addOffset: function(offset) {
      this.firstResult = offset;
      return this;
    },
  
    _addLimit: function(limit) {
      this.maxResults = limit;
      return this;
    }
  });
  
  /**
   * @class baqend.Query.Builder
   * @extends baqend.Query.Condition
   *
   * @param {baqend.EntityManager} entityManager The owning entity manager of this query
   * @param {Function} resultClass The query result class
   */
  Query.Builder = Object.inherit(Query.Condition, /** @lends baqend.Query.Builder.prototype */ {
  
    initialize: function(entityManager, resultClass) {
      this.entityManager = entityManager;
      this.resultClass = resultClass;
    },
  
    /**
     * Joins the conditions by an logical AND
     * @param {baqend.Query} args... The query nodes to join
     * @return {baqend.Query} Returns a new query which joins the given queries by a logical AND
     */
    and: function(args) {
      return this._addOperator('$and', classOf(args) == Array ? args : Array.prototype.slice.call(arguments));
    },
  
    /**
     * Joins the conditions by an logical OR
     * @param {baqend.Query} args... The query nodes to join
     * @return {baqend.Query} Returns a new query which joins the given queries by a logical OR
     */
    or: function(args) {
      return this._addOperator('$or', classOf(args) == Array ? args : Array.prototype.slice.call(arguments));
    },
  
    /**
     * Joins the conditions by an logical NOR
     * @param {baqend.Query} args... The query nodes to join
     * @return {baqend.Query} Returns a new query which joins the given queries by a logical NOR
     */
    nor: function(args) {
      return this._addOperator('$nor', classOf(args) == Array ? args : Array.prototype.slice.call(arguments));
    },
  
    /**
     * @inheritDoc
     */
    stream: function(fetchQuery) {
      return this.where({}).stream(fetchQuery);
    },
  
    /**
     * @inheritDoc
     */
    resultList: function(options, doneCallback, failCallback) {
      return this.where({}).resultList(options, doneCallback, failCallback);
    },
  
    /**
     * @inheritDoc
     */
    singleResult: function(options, doneCallback, failCallback) {
      return this.where({}).singleResult(options, doneCallback, failCallback);
    },
  
    /**
     * @inheritDoc
     */
    count: function(doneCallback, failCallback) {
      return this.where({}).count(doneCallback, failCallback);
    },
  
    _addOperator: function(operator, args) {
      if (args.length < 2) {
        throw new Error('Only two or more queries can be joined with an ' + operator + ' operator.');
      }
  
      args.forEach(function(arg, index) {
        if (!Query.isInstance(arg)) {
          throw new Error('Argument at index ' + index + ' is not a Query.');
        }
      });
  
      return new Query.Operator(this.entityManager, this.resultClass, operator, args);
    },
  
    _addOrder: function(fieldOrSort, order) {
      return new Query.Filter(this.entityManager, this.resultClass)._addOrder(fieldOrSort, order);
    },
  
    _addFilter: function(field, filter, value) {
      return new Query.Filter(this.entityManager, this.resultClass)._addFilter(field, filter, value);
    },
  
    _addOffset: function(offset) {
      return new Query.Filter(this.entityManager, this.resultClass)._addOffset(offset);
    },
  
    _addLimit: function(limit) {
      return new Query.Filter(this.entityManager, this.resultClass)._addLimit(limit);
    }
  });
  
  /**
   * @class baqend.Query.Filter
   * @extends baqend.Query.Node
   * @extends baqend.Query.Condition
   *
   * @param {baqend.EntityManager} entityManager The owning entity manager of this query
   * @param {Function} resultClass The query result class
   */
  Query.Filter = Query.Node.inherit(Query.Condition, /** @lends baqend.Query.Filter.prototype */ {
    /**
     * The actual filters of this node
     * @type Object
     */
    _filter: null,
  
    initialize: function(entityManager, resultClass) {
      this.superCall(entityManager, resultClass);
      this._filter = {};
    },
  
    _addFilter: function(field, filter, value) {
      if (field !== null) {
        if (!String.isInstance(field))
          throw new Error('Field must be a string.');
  
        if (filter) {
          var fieldFilter = this._filter[field];
          if (classOf(fieldFilter) != Object) {
            this._filter[field] = fieldFilter = {};
          }
  
          fieldFilter[filter] = value;
        } else {
          this._filter[field] = value;
        }
      } else {
        Object.extend(this._filter, value);
      }
  
      return this;
    },
  
    toJSON: function() {
      return this._filter;
    }
  });
  
  /**
   * @class baqend.Query.Operator
   * @extends baqend.Query.Node
   *
   * @param {baqend.EntityManager} entityManager The owning entity manager of this query
   * @param {Function} resultClass The query result class
   * @param {String} operator The operator used to join the childs
   * @param {Array<baqend.Query.Node>} childs The childs to join
   */
  Query.Operator = Query.Node.inherit(/** @lends baqend.Query.Operator.prototype */ {
    /**
     * The operator used to join the child queries
     * @type String
     */
    _operator: null,
  
    /**
     * The child Node of this query, it is always one
     * @type Array<baqend.Query.Node>
     */
    _childs: null,
  
    initialize: function(entityManager, resultClass, operator, childs) {
      this.superCall(entityManager, resultClass);
      this._operator = operator;
      this._childs = childs;
    },
  
    toJSON: function() {
      var json = {};
      json[this._operator] = this._childs;
      return json;
    }
  });
  
  /**
   * @class baqend.Query.Stream
   *
   * @param {baqend.EntityManager} entityManager The owning entity manager of this query
   * @param {String} bucket The Bucket on which the streaming query is performed
   * @param {String} query The serialized query
   * @param {Boolean} fetchQuery true if the query result should be fetched
   */
  Query.Stream = Object.inherit(/** @lends baqend.Query.Stream.prototype */ {
    initialize: function(entityManager, bucket, query, fetchQuery, sort, limit) {
      this.entityManager = entityManager;
      this.bucket = bucket;
      this.fetchQuery = fetchQuery;
      this.sort = sort;
      this.limit = limit;
      this.query = query;
      this.callbacks = [];
    },
  
    on: function(matchType, callback) {
      var topic = [this.bucket, this.query, matchType, "any"].join("/");
      var wrappedCallback = this._wrapQueryCallback(callback);
      this.entityManager._subscribe(topic, wrappedCallback);
  
      var queryMessage = {
        register: true,
        topic: topic,
        query: {
          bucket: this.bucket,
          matchTypes: [matchType],
          operations: ["any"],
          query: this.query
        }
      };
  
      if (this.fetchQuery) {
        queryMessage.fromstart = true;
        queryMessage.limit = this.limit;
        queryMessage.sort = this.sort;
      }
  
      this.entityManager._sendOverSocket(queryMessage);
  
      this.callbacks.push({
        matchType: matchType,
        callback: callback,
        topic: topic,
        wrappedCallback: wrappedCallback,
        queryMessage: queryMessage
      });
    },
  
    off: function(matchType, callback) {
      this.callbacks = this.callbacks.reduce(function(keep, el) {
        if ((!callback || el.callback == callback) && (!matchType || el.matchType == matchType)) {
          this.entityManager._unsubscribe(el.topic, el.wrappedCallback);
          el.queryMessage.register = false;
          this.entityManager._sendOverSocket(el.queryMessage);
        } else {
          keep.push(el);
        }
        return keep;
      }.bind(this), []);
    },
  
    once: function(matchType, callback) {
      var wrapped = function(entity, operation, match) {
        this.off(matchType, wrapped);
        callback(entity, operation, match);
      }.bind(this);
      this.on(matchType, wrapped);
    },
  
    _wrapQueryCallback: function(cb) {
      var receivedResult = false;
      return function(msg) {
        var bucket = msg.query.bucket;
        if (msg.match) {
          //Single Match received
          var operation = msg.match.update.operation;
          //Hollow object for deletes
          var obj = msg.match.update.object ? msg.match.update.object : {id: msg.match.update.id};
          var entity = this._createObject(bucket, operation, obj);
          //Call wrapped callback
          cb({
            type: msg.match.matchtype,
            data: entity,
            operation: operation,
            date: new Date(msg.date),
            target: this,
            initial: false,
            query: this.query
          });
        } else {
          //Initial result received
          if (!receivedResult) {
            msg.result.forEach(function(obj) {
              var operation = 'insert';
              var entity = this._createObject(bucket, operation, obj, obj.id);
              cb({
                type: 'match',
                data: entity,
                operation: operation,
                date: new Date(msg.date),
                target: this,
                initial: true,
                query: this.query
              });
            }, this);
            receivedResult = true;
          }
        }
      }.bind(this);
    },
  
    _createObject: function(bucket, operation, object) {
      var entity = this.entityManager.getReference(bucket, object.id);
      var metadata = Metadata.get(entity);
      metadata.setJson(object);
      metadata.setPersistent();
      return entity;
    }
  });
  
  module.exports = Query;
  },{"./binding/Entity":9,"./message":33,"./util/Metadata":54}],6:[function(require,module,exports){
  /**
   * @class baqend.binding.Accessor
   */
  var Accessor = Object.inherit(/** @lends baqend.binding.Accessor.prototype */ {
  	/**
  	 * @param {Object} object
  	 * @param {baqend.metamodel.Attribute} attribute
  	 * @returns {*}
  	 */
  	getValue: function(object, attribute) {
  		return object[attribute.name];
  	},
  	 
  	/**
  	 * @param {Object} object
  	 * @param {baqend.metamodel.Attribute} attribute
  	 * @param {*} value
  	 */
  	setValue: function(object, attribute, value) {
  		object[attribute.name] = value;
  	}
  });
  
  module.exports = Accessor;
  },{}],7:[function(require,module,exports){
  var EntityFactory = require('./EntityFactory');
  
  /**
   * @class baqend.binding.DeviceFactory
   * @extends baqend.binding.EntityFactory
   */
  var DeviceFactory = {};
  Object.cloneOwnProperties(DeviceFactory, EntityFactory);
  Object.defineProperty(DeviceFactory, 'isRegistered', {
    /**
     * Returns true if the devices is already registered, otherwise false.
     * @returns {boolean} Status of the device registration
     */
    get: function() {
      return this._db.isDeviceRegistered;
    }
  });
  
  Object.extend(DeviceFactory, /** @lends baqend.binding.DeviceFactory */ {
  
    /** @lends baqend.binding.DeviceFactory */
    PushMessage: require('../util/PushMessage'),
  
    /**
     * Register a new device with the given device token and OS.
     * @param {String} os The OS of the device (IOS/Android)
     * @param {String} token The GCM or APNS device token
     * @param {baqend.binding.Entity=} device A optional device entity to set custom field values
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>} The created user object, for the new registered user.
     */
    register: function(os, token, device, doneCallback, failCallback) {
      if (Function.isInstance(device)) {
        failCallback = doneCallback;
        doneCallback = device;
        device = null;
      }
  
      return this._db.registerDevice(os, token, device).then(doneCallback, failCallback);
    },
  
    /**
     * Uses the info from the given {baqend.util.PushMessage} message to send an push notification.
     * @param {baqend.util.PushMessage} pushMessage to send an push notification.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise}
     */
    push: function(pushMessage, doneCallback, failCallback) {
      return this._db.pushDevice(pushMessage).then(doneCallback, failCallback);
    }
  });
  
  module.exports = DeviceFactory;
  },{"../util/PushMessage":57,"./EntityFactory":10}],8:[function(require,module,exports){
  var Metadata = require('../util/Metadata');
  var Lockable = require('../util/Lockable');
  
  /**
   * @class baqend.binding.Enhancer
   */
  var Enhancer = Object.inherit(/** @lends baqend.binding.Enhancer.prototype */ {
  
    /**
     * @param {Class<?>} superClass
     * @returns {Function} typeConstructor
     */
    createProxy: function(superClass) {
      function Proxy(properties) {
        superClass.apply(this, arguments);
      }
  
      Proxy.prototype = Object.create(superClass.prototype, {
        constructor: {
          value: Proxy,
          enumerable: false,
          configurable: true
        }
      });
  
      return Proxy;
    },
  
    /**
     * @param {Function} typeConstructor
     * @returns {String}
     */
    getIdentifier: function(typeConstructor) {
      return typeConstructor.__baqendId__;
    },
  
    /**
     * @param {Function} typeConstructor
     * @param {String} identifier
     */
    setIdentifier: function(typeConstructor, identifier) {
      typeConstructor.__baqendId__ = identifier;
    },
  
    /**
     * @param {baqend.metamodel.ManagedType} type
     * @param {Function} typeConstructor
     */
    enhance: function(type, typeConstructor) {
      this.setIdentifier(typeConstructor, type.ref);
      this.enhancePrototype(typeConstructor, type);
    },
  
    /**
     * Enhance the prototype of the type
     * @param {Function} typeConstructor
     * @param {baqend.metamodel.ManagedType} type
     */
    enhancePrototype: function(typeConstructor, type) {
      if (typeConstructor.prototype.toString === Object.prototype.toString) {
        // implements a better convenience toString method
        Object.defineProperty(typeConstructor.prototype, 'toString', {
          value: function toString() {
            return this._metadata.id || this._metadata.bucket;
          },
          enumerable: false
        });
      }
  
      // enhance all persistent object properties
      if (type.superType && type.superType.name == 'Object') {
        for (var i = 0, attr; attr = type.superType.declaredAttributes[i]; ++i) {
          if (!attr.isMetadata)
            this.enhanceProperty(typeConstructor, attr);
        }
      }
  
      // enhance all persistent properties
      for (var i = 0, attr; attr = type.declaredAttributes[i]; ++i) {
        this.enhanceProperty(typeConstructor, attr);
      }
    },
  
    /**
     * @param {Function} typeConstructor
     * @param {baqend.metamodel.Attribute} attribute
     */
    enhanceProperty: function(typeConstructor, attribute) {
      var name = '$' + attribute.name;
      Object.defineProperty(typeConstructor.prototype, attribute.name, {
        get: function() {
          Metadata.readAccess(this);
          return this._metadata[name];
        },
        set: function(value) {
          Metadata.writeAccess(this);
          this._metadata[name] = value;
        },
        configurable: true,
        enumerable: true
      });
    }
  });
  
  module.exports = Enhancer;
  
  
  
  },{"../util/Lockable":53,"../util/Metadata":54}],9:[function(require,module,exports){
  var Managed = require('./Managed');
  var Lockable = require('../util/Lockable');
  
  /**
   * @class baqend.binding.Entity
   * @extends baqend.binding.Managed
   *
   * The default constructor, copy all given properties to this object
   * @param {Object=} properties - The optional properties to copy
   */
  var Entity = Managed.inherit(/** @lends baqend.binding.Entity.prototype */ {
  
    extend: {
      extend: Managed.extend
    },
  
    constructor: function Entity() {
      Managed.apply(this, arguments);
    },
  
    /**
     * The unique id of this object
     * if the id is already set an error will be thrown
     * @type {string}
     */
    get id() {
      return this._metadata.id;
    },
  
    /**
     * @param {String} value
     */
    set id(value) {
      if (this._metadata.id)
        throw new Error('Id can\'t be set twice.');
  
      if (value.indexOf('/db/') != 0) {
        value = '/db/' + this._metadata.bucket + '/' + encodeURIComponent(value);
      }
  
      this._metadata.id = value;
    },
  
    /**
     * The version of this object
     * @type {*}
     */
    get version() {
      return this._metadata.version;
    },
  
    set version(value) {
      this._metadata.version = value;
    },
  
    /**
     * The object read/write permissions
     * @type baqend.Acl
     */
    get acl() {
      return this._metadata.acl;
    },
  
    /**
     * Waits on the previously requested operation and calls the doneCallback if the operation is fulfilled
     * @param {baqend.util.Lockable~callback=} doneCallback The callback which will be invoked when the previously
     * operations on this object is completed.
     * @return {Promise<baqend.binding.Entity>} A promise which completes successfully, when the previously requested
     * operation completes
     */
    ready: function(doneCallback) {
      return this._metadata.ready(doneCallback);
    },
  
    /**
     * Attach this object to the given db
     * @param {baqend.EntityManager} db The db which will be used for future crud operations
     */
    attach: function(db) {
      db.attach(this);
    },
  
    /**
     * Saves the object. Inserts the object if it doesn't exists and updates the object if the object exist.
     * @param {Object} [options] The save options
     * @param {Boolean} [options.force=false] Force the save operation, the version will not be validated.
     * @param {Number|Boolean} [options.depth=0] The object depth which will be saved. Depth 0 save this object only,
     * <code>true</code> saves the objects by reachability.
     * @param {Boolean} [options.refresh=false] Refresh the local object state from remote.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    save: function(options, doneCallback, failCallback) {
      if (Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      return this._metadata.db.save(this, options).then(doneCallback, failCallback);
    },
  
    /**
     * Inserts a new object. Inserts the object if it doesn't exists and raise an error if the object already exist.
     * @param {Object} [options] The insertion options
     * @param {Number|Boolean} [options.depth=0] The object depth which will be inserted. Depth 0 insert this object only,
     * <code>true</code> inserts objects by reachability.
     * @param {Boolean} [options.refresh=false] Refresh the local object state from remote.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    insert: function(options, doneCallback, failCallback) {
      if (Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      return this._metadata.db.insert(this, options).then(doneCallback, failCallback);
    },
  
    /**
     * Updates an existing object.
     * Updates the object if it exists and raise an error if the object doesn't exist.
     * @param {Object} [options] The update options
     * @param {Boolean} [options.force=false] Force the update operation, the version will not be validated, only existence will be checked.
     * @param {Number|Boolean} [options.depth=0] The object depth which will be updated. Depth 0 updates this object only,
     * <code>true</code> updates objects by reachability.
     * @param {Boolean} [options.refresh=false] Refresh the local object state from remote.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    update: function(options, doneCallback, failCallback) {
      if (Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      return this._metadata.db.update(this, options).then(doneCallback, failCallback);;
    },
  
    /**
     * Loads the referenced objects
     * Removed objects will be marked as removed.
     * @param {Object} [options] The load options
     * @param {Number|Boolean} [options.depth=1] The object depth which will be loaded. Depth set to <code>true</code>
     * loads objects by reachability.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    load: function(options, doneCallback, failCallback) {
      if (Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {
          depth: 1
        };
      }
  
      return this._metadata.db.load(this.id, null , options).then(doneCallback, failCallback);
    },
  
    /**
     * Delete an existing object.
     * @param {Object} [options] The remove options
     * @param {Boolean} [options.force=false] Force the remove operation, the version will not be validated.
     * @param {Number|Boolean} [options.depth=0] The object depth which will be removed. Depth 0 removes this object only,
     * <code>true</code> removes objects by reachability.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    delete: function(options, doneCallback, failCallback) {
      if (Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      return this._metadata.db.delete(this, options).then(doneCallback, failCallback);
    },
  
    /**
     * Saves the object and repeats the operation if the object is out of date.
     * In each pass the callback will be called. Ths first parameter of the callback is the entity and the second one
     * is a function to abort the process.
     *
     * @param {Function} cb Will be called in each pass
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    optimisticSave: function(cb, doneCallback, failCallback) {
      return this._metadata.db.optimisticSave(this, cb).then(doneCallback, failCallback);
    },
  
    attr: function() {
      throw new Error("Attr is not yet implemented.");
    },
  
    /**
     * Validates the entity by using the validation code of the entity type
     *
     * @returns {baqend.util.ValidationResult} Contains the result of the Validation
     */
    validate: function() {
      return this._metadata.db.validate(this);
    },
  
    /**
     * Converts the entity to an JSON-Object.
     * @param {Boolean} excludeMetadata
     * @return {Object} JSON-Object
     */
    toJSON: function(excludeMetadata) {
      return this._metadata.getJson(excludeMetadata, excludeMetadata);
    }
  });
  
  module.exports = Entity;
  
  /**
   * The done callback is called, when the asynchronous operation completes successfully
   * @callback baqend.binding.Entity~doneCallback
   * @param {baqend.binding.Entity} entity This entity
   * @return {Promise<*>|*|undefined} A Promise, result or undefined
   */
  
  /**
   * The fail callback is called, when the asynchronous operation is rejected by an error
   * @callback baqend.binding.Entity~failCallback
   * @param {baqend.error.PersistentError} error The error which reject the operation
   * @return {Promise<*>|*|undefined} A Promise, result or undefined
   */
  
  
  },{"../util/Lockable":53,"./Managed":11}],10:[function(require,module,exports){
  var ManagedFactory = require('./ManagedFactory');
  
  /**
   * @class baqend.binding.EntityFactory
   * @extends baqend.binding.ManagedFactory
   */
  var EntityFactory = {};
  Object.cloneOwnProperties(EntityFactory, ManagedFactory);
  Object.extend(EntityFactory, /** @lends baqend.binding.EntityFactory */ {
  
    /**
     * Loads the instance for the given id, or null if the id does not exists.
     * @param {String} id The id to query
     * @param {Object} [options] The load options
     * @param {Number|Boolean} [options.depth=0] The object depth which will be saved. Depth 0 saves only this object,
     * <code>true</code> saves the objects by reachability.
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.Entity>} A Promise that will be fulfilled when the asynchronous operation completes.
     */
    load: function(id, options, doneCallback, failCallback) {
      if(Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      return this._db.load(this._managedType.typeConstructor, id, options).then(doneCallback, failCallback);
    },
  
    /**
     * Creates a new instance and sets the DatabaseObject to the given json
     * @param {Object} json
     * @returns {baqend.binding.Entity} instance
     */
    fromJSON: function(json) {
      var instance = json.id? this._db.getReference(this._managedType.typeConstructor, json.id): this.newInstance();
      var metadata = instance._metadata;
      metadata.setJson(json);
      metadata.setDirty();
      return instance;
    },
  
    /**
     * Creates a new query for this class
     * @return {baqend.Query.Builder} The query builder
     */
    find: function() {
      return this._db.createQueryBuilder(this._managedType.typeConstructor);
    },
  
    partialUpdate: function() {
      throw new Error("partialUpdate is not yet implemented.");
    }
  });
  
  module.exports = EntityFactory;
  },{"./ManagedFactory":12}],11:[function(require,module,exports){
  var util = require('../util');
  
  /**
   * @class baqend.binding.Managed
   *
   * The default constructor, copy all given properties to this object
   * @param {Object=} properties - The optional properties to copy
   */
  var Managed = Object.inherit(/** @lends baqend.binding.Managed.prototype */ {
  
    extend: {
      /**
       * Creates a subclass of this class
       * @param {Class<*>} childClass
       * @return {Class<*>} The extended child class
       */
      extend: function(childClass) {
        childClass.prototype = Object.create(this.prototype, {
          constructor: {
            value: childClass,
            enumerable: false,
            configurable: true,
            writable: true
          }
        });
        childClass.extend = Managed.extend;
        return childClass;
      }
    },
  
    constructor: function Managed(properties) {
      if (properties)
        Object.extend(this, properties);
    }
  
  });
  
  module.exports = Managed;
  },{"../util":60}],12:[function(require,module,exports){
  /**
   * @class baqend.binding.ManagedFactory
   */
  var ManagedFactory = {};
  Object.defineProperty(ManagedFactory, 'methods', {
    /**
     * Methods that are added to object instances
     * This property is an alias for this factories type prototype
     * @type object
     */
    get: function() {
      return this.prototype;
    }
  });
  
  Object.extend(ManagedFactory, /** @lends baqend.binding.ManagedFactory */ {
    /**
     * Creates a new ManagedFactory for the given type
     * @param {baqend.metamodel.ManagedType} managedType The metadata of type T
     * @param {baqend.EntityManager} db
     * @return {baqend.binding.ManagedFactory} A new object factory to created instances of T
     */
    create: function(managedType, db) {
      var self = this;
      var factory = function Factory() {
        return factory.newInstance.apply(factory, arguments);
      };
  
      Object.cloneOwnProperties(factory, self);
  
      //lets instanceof work properly
      factory.prototype = managedType.typeConstructor.prototype;
      factory._managedType = managedType;
      factory._db = db;
  
      return factory;
    },
  
    /**
     * Creates a new instance of the factory type
     * @param {Object<*>} properties A hash of initial properties
     * @param {...*} arguments Constructor arguments used for instantiation
     * @return {baqend.binding.Managed} A new created instance of T
     */
    newInstance: function(properties) {
      var typeInstance = this._managedType.create();
      this.prototype.constructor.apply(typeInstance, arguments);
      typeInstance._metadata.db = this._db;
      return typeInstance;
    },
  
    /**
     * Adds methods to instances of this factories type
     * @param {object} methods The methods to add
     */
    addMethods: function(methods) {
      Object.extend(this.methods, methods);
    },
  
    /**
     * Add a method to instances of this factories type
     * @param {string} name The method name to add
     * @param {function} fn The Method to add
     */
    addMethod: function(name, fn) {
      this.methods[name] = fn;
    }
  });
  
  module.exports = ManagedFactory;
  },{}],13:[function(require,module,exports){
  var Entity = require('./Entity');
  var User = require('./User');
  var Set = require('../collection').Set;
  
  /**
   * @class baqend.binding.Role
   * @extends baqend.binding.Entity
   */
  var Role = Entity.inherit(/** @lends baqend.binding.Role.prototype */ {
  
    extend: {
      extend: Entity.extend
    },
  
    /**
     * A set of users which have this role
     * @type baqend.Set
     */
    users: null,
  
    /**
     * The name of the role
     * @type String
     */
    name: null,
  
    constructor: function Role() {
      Entity.apply(this, arguments);
    },
  
    /**
     * Test if the given user has this role
     * @return {Boolean} <code>true</code> if the given user has this role,
     * otherwise <code>false</code>
     */
    hasUser: function(user) {
      return this.users && this.users.has(user);
    },
  
    /**
     * Add the given user to this role
     * @param {baqend.binding.User} user The user to add
     */
    addUser: function(user) {
      if (user instanceof User) {
        if (!this.users)
          this.users = new Set();
  
        this.users.add(user);
      } else {
        throw new Error('Only user instances can be added to a role.');
      }
    },
  
    /**
     * Remove the given user from this role
     * @param {baqend.binding.User} user The user to remove
     */
    removeUser: function(user) {
      if (user instanceof User) {
        if (this.users)
          this.users.delete(user);
      } else {
        throw new Error('Only user instances can be removed from a role.');
      }
    }
  
  });
  
  module.exports = Role;
  
  
  
  },{"../collection":17,"./Entity":9,"./User":14}],14:[function(require,module,exports){
  var Entity = require('./Entity');
  
  /**
   * @class baqend.binding.User
   * @extends baqend.binding.Entity
   */
  var User = Entity.inherit(/** @lends baqend.binding.User.prototype */ {
  
    extend: {
      extend: Entity.extend
    },
  
    constructor: function User() {
      Entity.apply(this, arguments);
    },
  
    /**
     * The name of the user
     * @type String
     */
    username: null,
  
    /**
     * Change the password of the given user
     *
     * @param {String} password Current password of the user
     * @param {String} newPassword New password of the user
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     */
    newPassword: function(password, newPassword, doneCallback, failCallback) {
      return this._metadata.db.newPassword(this.username, password, newPassword).then(doneCallback, failCallback);
    }
  });
  
  module.exports = User;
  
  
  
  },{"./Entity":9}],15:[function(require,module,exports){
  var EntityFactory = require('./EntityFactory');
  
  /**
   * @class baqend.binding.UserFactory
   * @extends baqend.binding.EntityFactory
   */
  var UserFactory = {};
  Object.cloneOwnProperties(UserFactory, EntityFactory);
  
  Object.defineProperty(UserFactory, 'me', {
    /**
     * The current logged in user, or <code>null</code> if the user is not logged in
     * @type baqend.binding.User
     */
    get: function() {
      return this._db.me;
    }
  });
  
  Object.extend(UserFactory, /** @lends baqend.binding.UserFactory */ {
    defaultOptions: {
      google: {
        width: 585,
        height: 545,
        scope: 'email'
      },
      facebook:{
        width: 1140,
        height: 640,
        scope: 'email'
      },
      github: {
        width: 1040,
        height: 580,
        scope: 'user:email'
      },
      twitter: {
        width: 740,
        height: 730
      },
      linkedin: {
        width: 630,
        height: 530,
        scope: ''
      }
    },
  
    /**
     * Register a new user with the given username and password, if the username is not used by an another user.
     * @param {String|baqend.binding.User} user The username as a string or a <baqend.binding.User> Object, which must contain the username.
     * @param {String} password The password for the given user
     * @param {Boolean} [login=true] <code>true</code> to login after a successful registration
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>} The created user object, for the new registered user.
     */
    register: function(user, password, login, doneCallback, failCallback) {
      if (!Boolean.isInstance(login)) {
        failCallback = doneCallback;
        doneCallback = login;
        login = true;
      }
  
      user = String.isInstance(user)? this.fromJSON({username: user}): user;
      return this._db.register(user, password, login).then(doneCallback, failCallback);
    },
  
    /**
     * Log in the user with the given username and password and starts a user session
     * @param {String} username The username of the user
     * @param {String} password The password of the user
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     */
    login: function(username, password, doneCallback, failCallback) {
      return this._db.login(username, password).then(doneCallback, failCallback);
    },
  
    /**
     * Log out the current logged in user and ends the active user session
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<null>}
     */
    logout: function(doneCallback, failCallback) {
      return this._db.logout().then(doneCallback, failCallback);
    },
  
    /**
     * Change the password of the given user
     *
     * @param {String} username Username to identify the user
     * @param {String} password Current password of the user
     * @param {String} newPassword New password of the user
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     */
    newPassword: function(username, password, newPassword, doneCallback, failCallback) {
      return this._db.newPassword(username, password, newPassword).then(doneCallback, failCallback);
    }
  
    /**
     * Prompts the user for the Google login in a new window. Before using OAuth you need to setup your application
     * on the provider website, add the redirect uri: <code>https://example.net/db/User/OAuth/google</code> and copy the client id
     * and the client secret to your Baqend dashboard settings. When the returned promise succeeds the user is logged in.
     *
     * @param {String} clientID
     * @param {Object=} options
     * @param {String} [options.title="Login"] sets the title of the popup window
     * @param {Number} [options.width=585] defines the width of the popup window
     * @param {Number} [options.height=545] defines the height of the popup window
     * @param {String} [options.scope="email"] the range of rights requested from the user
     * @param {Object} [options.state={}]
     * @param {Number} [options.timeout=5 * 60 * 1000]
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     *
     * @function
     * @name loginWithGoogle
     * @memberOf baqend.binding.UserFactory.prototype
     */
  
    /**
     * Prompts the user for the Facebook login in a new window. Before using OAuth you need to setup your application
     * on the provider website, add the redirect uri: https://example.net/db/User/OAuth/facebook and copy the client id
     * and the client secret to your Baqend dashboard settings. When the returned promise succeeds the user is logged in.
     *
     * @param {String} clientID
     * @param {Object=} options
     * @param {String} [options.title="Login"] sets the title of the popup window
     * @param {Number} [options.width=1140] defines the width of the popup window
     * @param {Number} [options.height=640] defines the height of the popup window
     * @param {String} [options.scope="email"] the range of rights requested from the user
     * @param {Object} [options.state={}]
     * @param {Number} [options.timeout=5 * 60 * 1000]
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     *
     * @function
     * @name loginWithFacebook
     * @memberOf baqend.binding.UserFactory.prototype
     */
  
    /**
     * Prompts the user for the GitHub login in a new window. Before using OAuth you need to setup your application
     * on the provider website, add the redirect uri: https://example.net/db/User/OAuth/github and copy the client id
     * and the client secret to your Baqend dashboard settings. When the returned promise succeeds the user is logged in.
     *
     * @param {String} clientID
     * @param {Object=} options
     * @param {String} [options.title="Login"] sets the title of the popup window
     * @param {Number} [options.width=1040] defines the width of the popup window
     * @param {Number} [options.height=580] defines the height of the popup window
     * @param {String} [options.scope="user:email"] the range of rights requested from the user
     * @param {Object} [options.state={}]
     * @param {Number} [options.timeout=5 * 60 * 1000]
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     *
     * @function
     * @name loginWithGitHub
     * @memberOf baqend.binding.UserFactory.prototype
     */
  
    /**
     * Prompts the user for the Twitter login in a new window. Before using OAuth you need to setup your application
     * on the provider website, add the redirect uri: https://example.net/db/User/OAuth/twitter and copy the client id
     * and the client secret to your Baqend dashboard settings. When the returned promise succeeds the user is logged in.
     *
     * @param {String} clientID
     * @param {Object=} options
     * @param {String} [options.title="Login"] sets the title of the popup window
     * @param {Number} [options.width=740] defines the width of the popup window
     * @param {Number} [options.height=730] defines the height of the popup window
     * @param {Number} [options.timeout=5 * 60 * 1000]
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     *
     * @function
     * @name loginWithTwitter
     * @memberOf baqend.binding.UserFactory.prototype
     */
  
    /**
     * Prompts the user for the LinkedIn login in a new window. Before using OAuth you need to setup your application
     * on the provider website, add the redirect uri: https://example.net/db/User/OAuth/linkedin and copy the client id
     * and the client secret to your Baqend dashboard settings. When the returned promise succeeds the user is logged in.
     *
     * @param {String} clientID
     * @param {Object=} options
     * @param {String} [options.title="Login"] sets the title of the popup window
     * @param {Number} [options.width=630] defines the width of the popup window
     * @param {Number} [options.height=530] defines the height of the popup window
     * @param {String} [options.scope=""] the range of rights requested from the user
     * @param {Object} [options.state={}]
     * @param {Number} [options.timeout=5 * 60 * 1000]
     * @param {baqend.binding.Entity~doneCallback=} doneCallback Called when the operation succeed.
     * @param {baqend.binding.Entity~failCallback=} failCallback Called when the operation failed.
     * @return {Promise<baqend.binding.User>}
     *
     * @function
     * @name loginWithLinkedIn
     * @memberOf baqend.binding.UserFactory.prototype
     */
  });
  
  ["Google", "Facebook", "GitHub", "Twitter", "LinkedIn"].forEach(function(name) {
    UserFactory["loginWith" + name] = function(clientID, options, doneCallback, failCallback) {
      //noinspection JSPotentiallyInvalidUsageOfThis
      if (Function.isInstance(options)) {
        failCallback = doneCallback;
        doneCallback = options;
        options = {};
      }
  
      options = Object.extend(Object.extend({}, UserFactory.defaultOptions[name.toLowerCase()]), options || {});
  
      return this._db.loginWithOAuth(name, clientID, options).then(doneCallback, failCallback);
    }
  });
  
  module.exports = UserFactory;
  
  },{"./EntityFactory":10}],16:[function(require,module,exports){
  /**
   * @namespace baqend.binding
   */
  
  exports.Accessor = require('./Accessor');
  exports.Enhancer = require('./Enhancer');
  exports.ManagedFactory = require('./ManagedFactory');
  exports.EntityFactory = require('./EntityFactory');
  exports.UserFactory = require('./UserFactory');
  exports.DeviceFactory = require('./DeviceFactory');
  exports.Managed = require('./Managed');
  exports.Entity = require('./Entity');
  exports.Role = require('./Role');
  exports.User = require('./User');
  },{"./Accessor":6,"./DeviceFactory":7,"./Enhancer":8,"./Entity":9,"./EntityFactory":10,"./Managed":11,"./ManagedFactory":12,"./Role":13,"./User":14,"./UserFactory":15}],17:[function(require,module,exports){
  /**
   * @namespace baqend.collection
   */
  
  var Metadata = require('./util/Metadata');
  var Iterator, IndexIterator, PropertyIterator, Iterable, Collection, List, Set, Map;
  var ITERATOR = '@@iterator';
  
  /**
   * @typedef {Object} baqend.collection.Iterator.Item
   * @property {Boolean} done Indicates if the iterator has no more elements
   * @property {*} value Tha actual iterated element
   */
  
  /**
   * @class baqend.collection.Iterator
   */
  exports.Iterator = Iterator = Trait.inherit( /** @lends baqend.collection.Iterator.prototype */ {
    /** @lends baqend.collection.Iterator */
    extend: {
      /**
       * @type baqend.collection.Iterator.Item
       */
      DONE: {done: true}
    },
  
    constructor: function Iterator(obj) {
      if (obj) {
        if (obj[ITERATOR] && Function.isInstance(obj[ITERATOR])) {
          return obj[ITERATOR]();
        } else if (Array.isInstance(obj)) {
          return new IndexIterator(obj.length, function(index) {
            return obj[index];
          });
        } else {
          return new PropertyIterator(obj);
        }
      }
    },
  
    /**
     * Gets the next item
     * @return {Object} item The next iterating item
     * @return {Boolean} item.done <code>true</code> if there are no more elements to iterate
     * @return {*} item.value The current iterating value
     */
    next: function() {
      return Iterator.DONE;
    }
  });
  
  /**
   * @class baqend.collection.IndexIterator
   * @extends baqend.collection.Iterator
   */
  exports.IndexIterator = IndexIterator = Object.inherit(Iterator, /** @lends baqend.collection.IndexIterator.prototype */ {
    length: 0,
    index: 0,
  
    constructor: function collection(length, accessor) {
      this.length = length;
  
      if (accessor)
        this.accessor = accessor;
    },
  
    /**
     * Returns the element for an index
     * @param {Number} index
     */
    accessor: function(index) {
      return index;
    },
  
    /**
     * @inheritDoc
     */
    next: function() {
      if (this.index < this.length) {
        var result = { done: false, value: this.accessor(this.index) };
        this.index++;
        return result;
      } else {
        return Iterator.DONE;
      }
    }
  });
  
  /**
   * @class baqend.collection.PropertyIterator
   * @extends baqend.collection.Iterator
   */
  exports.PropertyIterator = PropertyIterator = Iterator.inherit(/** baqend.collection.PropertyIterator.prototype */ {
    index: 0,
  
    constructor: function PropertyIterator(object) {
      this.object = object;
      this.names = Object.getOwnPropertyNames(object);
    },
  
    next: function() {
      if (this.names.length < this.index) {
        var name = this.names[this.index++];
        return {done: false, value: [name, this.object[name]]};
      } else {
        return Iterator.DONE;
      }
    }
  });
  
  /**
   * @class baqend.collection.Iterable
   */
  exports.Iterable = Iterable = Trait.inherit( /** @lends baqend.collection.Iterable.prototype */ {
    /**
     * Returns an iterator over the entries of this collection
     * @return {Iterator<Array<*>>} An iterator where each entry is a key - value pair
     */
    entries: function() {
      return null;
    },
  
    /**
     * Executes a provided function once per array element.
     * @param {Function} callback Function to execute for each element.
     * @param {*} thisArg Value to use as this when executing callback.
     */
    forEach: function(callback, thisArg) {
      if (!callback || !Function.isInstance(callback)) {
        throw new TypeError(callback + ' is not a function');
      }
  
      for (var iter = this.entries(), item; !(item = iter.next()).done; ) {
        callback.call(thisArg, item.value[1], item.value[0], this);
      }
    },
  
    /**
     * Tests whether all elements in the array pass the test implemented by the provided function.
     * @param {Function} callback Function to test for each element.
     * @param {*} thisArg Value to use as this when executing callback.
     * @returns {boolean} true if all elements in the array pass the test
     */
    every: function(callback, thisArg) {
      if (!callback || !Function.isInstance(callback)) {
        throw new TypeError(callback + ' is not a function');
      }
  
      for (var iter = this.entries(), item; !(item = iter.next()).done; ) {
        if (!callback.call(thisArg, item.value[1], item.value[0], this))
          return false;
      }
  
      return true;
    },
  
    /**
     * Tests whether some element in the array passes the test implemented by the provided function.
     * @param {Function} callback Function to test for each element.
     * @param {*} thisArg Value to use as this when executing callback.
     * @returns {boolean} true if some element in the array passes the test
     */
    some: function(callback, thisArg) {
      if (!Function.isInstance(callback)) {
        throw new TypeError(callback + ' is not a function');
      }
  
      for (var iter = this.entries(), item; !(item = iter.next()).done; ) {
        if (callback.call(thisArg, item.value[1], item.value[0], this))
          return true;
      }
  
      return false;
    },
  
    /**
     * Creates a new instance of this object with all elements that pass the test implemented by the provided function.
     * @param {Function} callback Function to test each element of the array.
     * @param {*} thisArg Value to use as this when executing callback.
     * @returns {*} A new instance of this object with all elements that pass the test
     */
    filter: function(callback, thisArg) {
      if (!Function.isInstance(callback)) {
        throw new TypeError(callback + ' is not a function');
      }
  
      var result = new this.constructor();
      for (var iter = this.entries(), item; !(item = iter.next()).done; ) {
        if (callback.call(thisArg, item.value[1], item.value[0], this)) {
          if (result.set) {
            result.set(item.value[0], item.value[1]);
          } else {
            result.add(item.value[1]);
          }
        }
      }
  
      return result;
    },
  
    /**
     * Creates a new instance of this object with the results of calling a provided function on every element in this array.
     * @param {Function} callback Function that produces an element of the new object
     * @param {*} thisArg Value to use as this when executing callback.
     * @returns {*} A new instance of this object with the results
     */
    map: function(callback, thisArg) {
      if (!Function.isInstance(callback)) {
        throw new TypeError(callback + ' is not a function');
      }
  
      var result = new this.constructor();
      for (var iter = this.entries(), item; !(item = iter.next()).done; ) {
        var value = callback.call(thisArg, item.value[1], item.value[0], this);
        if (result.set) {
          result.set(item.value[0], value);
        } else {
          result.add(value);
        }
      }
  
      return result;
    },
  
    /**
     * Applies a function against an accumulator and each element
     * (from left-to-right) has to reduce it to a single value.
     * @param {Function} callback Function to execute on each element
     * @param {*} previousValue Object to use as the first argument to the first call of the callback.
     * @returns {*}
     */
    reduce: function(callback, previousValue) {
      if (!Function.isInstance(callback)) {
        throw new TypeError(callback + ' is not a function');
      }
  
      var iter = this.entries();
      if (arguments.length == 1) {
        previousValue = iter.next().value;
      }
  
      var item;
      while (!(item = iter.next()).done) {
        previousValue = callback.call(null, previousValue, item.value[1], item.value[0], this);
      }
  
      return previousValue;
    }
  });
  
  /**
   * @class baqend.collection.Collection
   * @extends baqend.collection.Iterable
   *
   * @param {Array|baqend.collection.Collection=} collection
   */
  exports.Collection = Collection = Object.inherit(Iterable, /** @lends baqend.collection.Collection.prototype */ {
  
    /**
     * The collection backed array
     * @type Array.<*>
     */
    array: null,
  
    get size() {
      return this.array.length;
    },
  
    constructor: function Collection(iterable) {
      this.array = [];
  
      var iter = Iterator(iterable);
      if (iter) {
        var item;
        while(!(item = iter.next()).done) {
          this.add(item.value);
        }
      }
    },
  
    /**
     * Indicates if this collection contains the element
     * @param element The element to test
     * @returns {boolean} true if the collection contains the element
     */
    has: function(element) {
      return this.array.indexOf(element) != -1;
    },
  
    /**
     * Clears the collection by removing all elements
     */
    clear: function() {
      Metadata.writeAccess(this);
      this.array = [];
    },
  
    /**
     * Add a alement to the collection
     * @param element The element to add
     */
    add: function(element) {
      Metadata.writeAccess(this);
      this.array.push(element);
    },
  
    /**
     * Removes teh element form the collection
     * @param element The element to remove
     */
    'delete': function(element) {
      Metadata.writeAccess(this);
      var index = this.array.indexOf(element);
      if (index > -1) {
        this.array.splice(index, 1);
      }
    },
  
    /**
     * Gets an iterator over the entries of the collection
     * @returns {baqend.collection.Iterator.<Array<*>>} An iterator over the entries of the collection
     */
    entries: function() {
      var array = this.array;
      return new IndexIterator(this.size, function(index) {
        return [index, array[index]];
      });
    },
  
    /**
     * Gets an iterator over the keys of the collection
     * @returns {baqend.collection.Iterator.<Number>} An iterator over the keys of the collection
     */
    keys: function() {
      return new IndexIterator(this.size);
    },
  
    /**
     * Gets an iterator over the values of the collection
     * @returns {baqend.collection.Iterator.<*>} An iterator over the values of the collection
     */
    values: function() {
      var array = this.array;
      return new IndexIterator(this.size, function(index) {
        return array[index];
      });
    },
  
    toString: function() {
      return this.array.toString();
    },
  
    toJSON: function() {
      return this.array;
    }
  });
  
  var Arr = Array.prototype;
  
  /**
   * Creates a new List instance
   * @class baqend.collection.List
   * @extends baqend.collection.Collection
   *
   * @param {Array|baqend.collection.Collection=} collection
   */
  exports.List = List = Collection.inherit(/** @lends baqend.collection.List.prototype */ {
  
    constructor: function List(iterable) {
      Collection.call(this, iterable);
    },
  
    /**
     * Get the value by index
     * @param index The index
     * @returns {*} The value of the index
     */
    get: function(index) {
      if (index < 0) {
        index = this.size + index;
      }
  
      if (index >= 0 && index < this.size) {
        return this.array[index];
      }
    },
  
    /**
     * @inheritDoc
     */
    add: function(element) {
      Metadata.writeAccess(this);
      this.array.push(element);
    },
  
    /**
     * Sets the value at index
     * @param index The index
     * @param value The new value
     */
    set: function(index, value) {
      Metadata.writeAccess(this);
      if (index < 0) {
        index = this.size + index;
      }
  
      if (index < 0) {
        this.array.unshift(value);
      } else if (index >= this.size) {
        this.array.push(value);
      } else {
        this.array[index] = value;
      }
    },
  
    concat: function() {
      var args = Arr.map.call(arguments, function(arg) {
        if (List.isInstance(arg)) {
          return arg.array;
        } else {
          return arg;
        }
      });
  
      return new List(Arr.concat.apply(this.array, args));
    },
  
    /**
     * Gets the index of an value
     * @param value The value to search
     * @returns {*} The index of the value, or -1 if the value was not found
     */
    indexOf: function(value) {
      return this.seq.indexOf(value);
    },
  
    /**
     * Gets the last index of the value
     * @param value The value to search
     * @returns {*} The last index of the value, or -1 if teh value was not found
     */
    lastIndexOf: function(value) {
      return this.seq.lastIndexOf(value);
    },
  
    join: function(seperator) {
      return this.array.join(seperator);
    },
  
    pop: function() {
      Metadata.writeAccess(this);
      return this.array.pop();
    },
  
    push: function() {
      Metadata.writeAccess(this);
      return Arr.push.apply(this.array, arguments);
    },
  
    reverse: function() {
      Metadata.writeAccess(this);
      this.array.reverse();
    },
  
    shift: function() {
      Metadata.writeAccess(this);
      return this.array.shift();
    },
  
    slice: function(begin, end) {
      return new List(this.array.slice(begin, end));
    },
  
    sort: function(compareFunction) {
      Metadata.writeAccess(this);
      this.array.sort(compareFunction);
    },
  
    splice: function() {
      Metadata.writeAccess(this);
      return Arr.splice.apply(this.array, arguments);
    },
  
    unshift: function() {
      Metadata.writeAccess(this);
      return Arr.unshift.apply(this.array, arguments);
    }
  });
  
  List.prototype[ITERATOR] = List.prototype.values;
  
  /**
   * @class baqend.collection.Set
   * @extends baqend.collection.Collection
   *
   * @param {Array|baqend.collection.Collection=} collection
   */
  exports.Set = Set = Collection.inherit(/** @lends baqend.collection.Set.prototype */ {
  
    constructor: function Set(iterable) {
      Collection.call(this, iterable);
    },
  
    /**
     * Adds the element ot the collection, if the collection doesn't contain the element
     * @param value The value to add
     */
    add: function(value) {
      var index = this.array.indexOf(value);
      if (index < 0) {
        this.array.push(value);
        Metadata.writeAccess(this);
      }
    },
  
    /**
     * @inheritDoc
     */
    entries: function() {
      var array = this.array;
      return new IndexIterator(this.size, function(index) {
        return [array[index], array[index]];
      });
    }
  });
  
  Set.prototype.keys = Set.prototype.values;
  Set.prototype[ITERATOR] = Set.prototype.values;
  
  /**
   * @class baqend.collection.Map
   * @extends baqend.collection.Collection
   *
   * @param {Array|baqend.collection.Collection=} collection
   */
  exports.Map = Map = Collection.inherit(/** @lends baqend.collection.Map.prototype */ {
  
    constructor: function Map(iterable) {
      this.array = [];
      this.vals = [];
  
      var iter = Iterator(iterable);
      if (iter) {
        var item;
        while (!(item = iter.next()).done) {
          if (!Array.isInstance(item.value) || item.value.length != 2) {
            throw new Error('No key value pair in entry ' + item.value);
          }
  
          this.set(item.value[0], item.value[1]);
        }
      }
    },
  
    /**
     * @inheritDoc
     */
    clear: function() {
      Metadata.writeAccess(this);
      this.array = [];
      this.vals = [];
    },
  
    /**
     * Gets the associated value of the key
     * @param key The key
     * @returns {*} The associated value
     */
    get: function(key) {
      var index = this.array.indexOf(key);
      if (index > -1) {
        return this.vals[index];
      }
    },
  
    /**
     * Adds the given key, without an value
     * @param key The key to add
     */
    add: function(key) {
      Metadata.writeAccess(this);
      this.set(key, key);
    },
  
    /**
     * Sets the value of an key
     * @param key The key
     * @param value The new value
     */
    set: function(key, value) {
      Metadata.writeAccess(this);
      var index = this.array.indexOf(key);
      if (index == -1) {
        index = this.array.length;
        this.array[index] = key;
      }
  
      this.vals[index] = value;
    },
  
    /**
     * Removes the key and the associated value
     * @param key The key to remove
     */
    remove: function(key) {
      Metadata.writeAccess(this);
      var index = this.array.indexOf(key);
      if (index > -1) {
        this.array.splice(index, 1);
        this.vals.splice(index, 1);
      }
    },
  
    /**
     * Gets an iterator over the entries of the map
     * @returns {baqend.collection.Iterator.<Array<*>>} An iterator over the key value pairs of the map
     */
    entries: function() {
      var keys = this.array;
      var vals = this.vals;
      return new IndexIterator(this.size, function(index) {
        return [keys[index], vals[index]];
      });
    },
  
    /**
     * Gets a iterator over the keys
     * @returns {baqend.collection.Iterator.<*>} A key iterator
     */
    keys: function() {
      var keys = this.array;
      return new IndexIterator(this.size, function(index) {
        return keys[index];
      });
    },
  
    /**
     * Gets a iterator over the values
     * @returns {baqend.collection.Iterator.<*>} A value iterator
     */
    values: function() {
      var vals = this.vals;
      return new IndexIterator(this.size, function(index) {
        return vals[index];
      });
    },
  
    toString: function() {
      var str = '';
      for (var i = 0, len = this.size; i < len; ++i) {
        if (str != '')
          str += ', ';
  
        str += this.array[i];
        str += ': ';
        str += this.vals[i];
      }
      return '[' + str + ']';
    },
  
    toJSON: function() {
      var map = [];
      for (var i = 0, len = this.size; i < len; ++i) {
        map.push({
          key: this.array[i],
          value: this.vals[i]
        });
      }
      return map;
    }
  });
  
  Map.prototype[ITERATOR] = Map.prototype.entries;
  
  },{"./util/Metadata":54}],18:[function(require,module,exports){
  var PersistentError = require('../error/PersistentError');
  
  /**
   * @class baqend.connector.Connector
   *
   * @param {String} host
   * @param {number} port
   * @param {boolean} secure
   */
  var Connector = Object.inherit(/** @lends baqend.connector.Connector.prototype */{
    /** @lends baqend.connector.Connector */
    extend: {
      /**
       * An array of all exposed response headers
       * @type String[]
       */
      RESPONSE_HEADERS: [
        'Baqend-Authorization-Token',
        'Content-Type'
      ],
  
      /**
       * Array of all available connector implementations
       * @type baqend.connector.Connector[]
       */
      connectors: [],
  
      /**
       * Array of all created connections
       * @type Object<string,baqend.connector.Connector>
       */
      connections: {},
  
      /**
       * @param {String} host or location
       * @param {number=} port
       * @param {boolean=} secure <code>true</code> for an secure connection
       * @return {baqend.connector.Connector}
       */
      create: function(host, port, secure) {
        if (!host && typeof window !== 'undefined') {
          host = window.location.hostname;
          port = Number(window.location.port);
          secure = window.location.protocol == 'https:';
        }
  
        if (host.indexOf('/') != -1) {
          var matches = /^(https?):\/\/([^\/:]+|\[[^\]]+])(:(\d*))?\/?$/.exec(host);
          if (matches) {
            secure = matches[1] == 'https';
            host = matches[2].replace(/(\[|])/g, '');
            port = matches[4];
          } else {
            throw new Error('The connection uri host ' + host + ' seems not to be valid');
          }
        }
  
        if (!port)
          port = secure ? 443 : 80;
  
        var url = Connector.toUri(host, port, secure);
        var connection = this.connections[url];
  
        if (!connection) {
          for (var name in this.connectors) {
            var connector = this.connectors[name];
            if (connector.isUsable && connector.isUsable(host, port, secure)) {
              connection = new connector(host, port, secure);
              break;
            }
          }
  
          if (!connection)
            throw new Error('No connector is usable for the requested connection.');
  
          this.connections[url] = connection;
        }
  
        return connection;
      },
  
      toUri: function(host, port, secure) {
        var uri = (secure ? 'https://' : 'http://') + (host.indexOf(':') != -1? '[' + host + ']': host);
        uri += (secure && port != 443 || !secure && port != 80) ? ':' + port : '';
        return uri;
      }
    },
  
    constructor: function Connector(host, port, secure) {
      this.host = host;
      this.port = port;
      this.secure = secure;
      this.socket = null;
      this.listeners = {};
  
      this.origin = Connector.toUri(host, port, secure);
    },
  
    /**
     * @param {baqend.connector.Message} message
     * @returns {Promise<baqend.connector.Message>}
     */
    send: function(message) {
      if (message.request.method == 'OAUTH') {
        message.addRedirectOrigin(this.origin);
      }
  
      return new Promise(function(resolve, reject) {
        this.prepareRequestEntity(message);
        this.doSend(message.request, this.receive.bind(this, message, resolve, reject));
      }.bind(this)).catch(function(e) {
        throw PersistentError.of(e);
      });
    },
  
    /**
     * @param {baqend.connector.Message} message
     * @param {Function} resolve
     * @param {Function} reject
     * @param {Object} response
     */
    receive: function(message, resolve, reject, response) {
      message.response = response;
      try {
        // IE9 returns status code 1223 instead of 204
        message.response.status = message.response.status == 1223 ? 204 : message.response.status;
  
        this.prepareResponseEntity(message);
        message.doReceive();
        resolve(message);
      } catch (e) {
        e = PersistentError.of(e);
        message.response.entity = null;
        reject(e);
      }
    },
  
    /**
     * Handle the actual message send
     * @param {baqend.connector.Message} message
     * @param {Function} receive
     * @abstract
     */
    doSend: function(message, receive) {
    },
  
    /**
     * Registers a handler for a topic.
     * @param {String|Object} topic
     * @param {Function} cb
     */
    subscribe: function(topic, cb) {
      topic = String.isInstance(topic) ? topic : JSON.stringify(topic);
      if (!this.listeners[topic]) {
        this.listeners[topic] = [cb]
      } else if (this.listeners[topic].indexOf(cb) == -1) {
        this.listeners[topic].push(cb);
      }
    },
  
    /**
     * Deregisters a handler.
     * @param {String|Object}  topic
     * @param {Function} cb
     */
    unsubscribe: function(topic, cb) {
      topic = String.isInstance(topic) ? topic : JSON.stringify(topic);
      if (this.listeners[topic]) {
        var index = this.listeners[topic].indexOf(cb)
        if (index != -1) {
          this.listeners[topic].splice(index, 1);
        }
      }
    },
  
    socketListener: function(event) {
      var message = JSON.parse(event.data);
      var topic = message.topic;
      topic = String.isInstance(topic) ? topic : JSON.stringify(topic);
      if(this.listeners[topic]) {
        this.listeners[topic].forEach(function(listener) {
          listener(message);
        });
      }
    },
  
    socketOpen: null,
  
    /**
     * Sends a websocket message over a lazily initialized websocket connection.
     * @param {Object} message
     * @param {String} message.topic
     * @param {String} message.token
     */
    sendOverSocket: function(message) {
      //Lazy socket initialization
      if (this.socket === null) {
        this.socket = this.createSocket();
        this.socket.onmessage = this.socketListener.bind(this);
  
        //Resolve Promise on connect
        this.socketOpen = new Promise(function(resolve, reject) {
          this.socket.onopen = resolve;
          this.socket.onerror = reject;
        }.bind(this));
  
        //Reset socket on close
        this.socket.onclose = function() {
          this.socket = null;
          this.socketOpen = null;
        }.bind(this);
      }
  
      var jsonMessage = JSON.stringify(message);
      this.socketOpen.then(function() {
        this.socket.send(jsonMessage);
      }.bind(this));
    },
  
    /**
     * Handle the actual message send
     * @param {baqend.connector.Message} message
     * @param {Function} receive
     * @abstract
     */
    createSocket: function(message, receive) {
    },
  
    /**
     * @param {baqend.connector.Message} message
     */
    prepareRequestEntity: function(message) {
      if (message.request.entity) {
        if (String.isInstance(message.request.entity)) {
          message.request.headers['Content-Type'] = 'text/plain;charset=utf-8';
        } else {
          message.request.headers['Content-Type'] = 'application/json;charset=utf-8';
          message.request.entity = JSON.stringify(message.request.entity);
        }
      }
    },
  
    /**
     * @param {baqend.connector.Message} message
     * @param {Object} data
     */
    prepareResponseEntity: function(message) {
      var entity = message.response.entity;
      if (entity && entity.length > 0) {
        var contentType = message.response.headers['Content-Type'] || message.response.headers['content-type'];
        if (contentType && contentType.indexOf("application/json") > -1) {
          entity = JSON.parse(entity);
        }
      } else {
        entity = null;
      }
      message.response.entity = entity;
    }
  });
  
  module.exports = Connector;
  },{"../error/PersistentError":29}],19:[function(require,module,exports){
  var Connector = require('./Connector');
  
  /**
   * @class baqend.connector.IFrameConnector
   * @extends baqend.connector.Connector
   */
  var IFrameConnector = Connector.inherit(/** @lends baqend.connector.IFrameConnector.prototype */ {
    /** @lends baqend.connector.IFrameConnector */
    extend: {
      loadedAttr: 'data-loaded',
      style: 'width:1px;height:1px;position:absolute;top:-10px;left:-10px;',
  
      initialize: function() {
        Connector.connectors.push(this);
      },
  
      /**
       * Indicates if this connector implementation is usable for the given host and port
       * @param {String} host
       * @param {number} port
       * @param {boolean} secure
       * @returns {boolean}
       */
      isUsable: function(host, port, secure) {
        return typeof window != 'undefined' &&
            (window.location.hostname != host || window.location.port != port);
      }
    },
  
    queue: null,
    origin: null,
    iframe: null,
    messages: null,
    mid: 0,
  
    constructor: function IFrameConnector(host, port, secure) {
      Connector.call(this, host, port, secure);
  
      this.messages = {};
      var src = this.origin + '/connect';
  
      this.iframe = document.querySelector('iframe[src="'+ src + '"]');
      if (!this.iframe || this.iframe.src != src) {
        this.iframe = document.createElement('iframe');
        this.iframe.src = src;
        this.iframe.setAttribute("style", IFrameConnector.style);
        document.body.appendChild(this.iframe);
      }
  
      if(!this.isLoaded()) {
        this.queue = [];
        this.iframe.addEventListener('load', this.onLoad.bind(this), false);
      }
  
      window.addEventListener('message', this.doReceive.bind(this), false);
    },
  
    onLoad: function() {
      var queue = this.queue;
  
      for (var i = 0; i < queue.length; ++i) {
        this.iframe.contentWindow.postMessage(queue[i], this.origin);
      }
  
      this.queue = null;
      this.setLoaded();
    },
  
    setLoaded: function() {
      this.iframe.setAttribute(IFrameConnector.loadedAttr, true);
    },
  
    isLoaded: function() {
      return !!this.iframe.getAttribute(IFrameConnector.loadedAttr);
    },
  
    /**
     * @inheritDoc
     */
    doSend: function(request, receive) {
      var msg = {
        mid: ++this.mid,
        method: request.method,
        path: request.path,
        headers: request.headers,
        entity: request.entity,
        responseHeaders: Connector.RESPONSE_HEADERS
      };
  
      this.messages[msg.mid] = {
        request: request,
        receive: receive
      };
  
      msg = JSON.stringify(msg);
      if (this.queue) {
        this.queue.push(msg);
      } else {
        this.iframe.contentWindow.postMessage(msg, this.origin);
      }
    },
  
    createSocket: function() {
      return new WebSocket((this.secure ? 'wss://' : 'ws://') + this.host + ':' + this.port + '/events/');
    },
  
    doReceive: function(event) {
      if(event.origin !== this.origin || event.data[0] != '{') {
        return;
      }
  
      var msg = JSON.parse(event.data);
  
      var message = this.messages[msg.mid];
      delete this.messages[msg.mid];
  
      message.receive({
        status: msg.status,
        headers: msg.headers,
        entity: msg.entity
      });
    }
  });
  
  module.exports = IFrameConnector;
  },{"./Connector":18}],20:[function(require,module,exports){
  var CommunicationError = require('../error/CommunicationError');
  
  /**
   * @class baqend.connector.Message
   *
   * @param {String} arguments... The path arguments
   */
  var Message = Object.inherit(/** @lends baqend.connector.Message.prototype */ {
  
    /** @lends baqend.connector.Message */
    extend: {
      /**
       * @enum {number}
       */
      StatusCode: {
        NOT_MODIFIED: 304,
        BAD_CREDENTIALS: 460,
        BUCKET_NOT_FOUND: 461,
        INVALID_PERMISSION_MODIFICATION: 462,
        INVALID_TYPE_VALUE: 463,
        OBJECT_NOT_FOUND: 404,
        OBJECT_OUT_OF_DATE: 412,
        PERMISSION_DENIED: 466,
        QUERY_DISPOSED: 467,
        QUERY_NOT_SUPPORTED: 468,
        SCHEMA_NOT_COMPATIBLE: 469,
        SCHEMA_STILL_EXISTS: 470,
        SYNTAX_ERROR: 471,
        TRANSACTION_INACTIVE: 472,
        TYPE_ALREADY_EXISTS: 473,
        TYPE_STILL_REFERENCED: 474,
        SCRIPT_ABORTION: 475
      },
  
      /**
       * Creates a new message class with the given message specification
       * @param {object} spec
       * @return {Function}
       */
      create: function(spec) {
        var parts = spec.path.split('?');
        var path = parts[0].split(/:\w*/);
        var query = [];
        if (parts[1]) {
          parts[1].split('&').forEach(function(arg) {
            var part = arg.split('=');
            query.push(part[0]);
          });
        }
  
        spec.path = path;
        spec.query = query;
  
        return Message.inherit({
          spec: spec
        });
      },
  
        /**
         * Creates a new message class with the given message specification and a full path
         * @param {object} spec
         * @return {Function}
         */
        createExternal: function(spec, query) {
          spec.path = [spec.path];
  
          return Message.inherit({
            spec: spec
          });
        }
    },
  
  
    /**
     * Message specification
     * @type object
     */
    spec: null,
  
    /**
     * @type {boolean}
     */
    withCredentials: false,
  
    initialize: function() {
      var args = arguments;
      var index = 0;
      var path = this.spec.path;
      if (!String.isInstance(path)) {
        path = this.spec.path[0];
        for (var i = 1; i < this.spec.path.length; ++i) {
          path += encodeURIComponent(args[index++]) + this.spec.path[i];
        }
      }
  
      var query = "";
      for (var i = 0; i < this.spec.query.length; ++i) {
        var arg = args[index++];
        if (arg !== undefined && arg !== null) {
          query += (query || ~path.indexOf("?"))? "&": "?";
          query += this.spec.query[i] + '=' + encodeURIComponent(arg);
        }
      }
  
      this.request = {
        method: this.spec.method,
        path: path + query,
        headers: {
          'accept': 'application/json, text/*;q=0.1'
        },
        entity: args[index] || null
      };
  
      this.response = {
        status: 0,
        headers: {},
        entity: null
      };
    },
  
    setIfMatch: function(value) {
      if (value != '*')
        value = '"' + value + '"';
  
      this.request.headers['If-Match'] = value;
    },
  
    setIfNoneMatch: function(value) {
      if (value != '*')
        value = '"' + value + '"';
  
      this.request.headers['If-None-Match'] = value;
    },
  
    setCacheControl: function(value) {
      this.request.headers['Cache-Control'] = value;
    },
  
    getAuthorizationToken: function() {
      return this.response.headers['Baqend-Authorization-Token'] || this.response.headers['baqend-authorization-token'];
    },
  
    setAuthorizationToken: function(value) {
      this.request.headers['Authorization'] = 'BAT ' + value;
    },
  
    /**
     * @param {String=} value
     */
    withAuthorizationToken: function(value) {
      if(value) {
        this.setAuthorizationToken(value);
      } else {
        this.request.withCredentials = true;
      }
    },
  
    /**
     * Adds the given String to the request path.
     * If the parameter is an object the query string will be created.
     *
     * @param {String|Object} query which will added to the request path
     */
    addQueryString: function(query) {
      if(String.isInstance(query)) {
        this.request.path += query;
      } else if(query) {
        var sep = ~this.request.path.indexOf("?")? "&": "?";
        Object.keys(query).forEach(function(key, i) {
          this.request.path += sep + key + "=" + encodeURIComponent(query[key]);
          if(i == 0) {
            sep = "&";
          }
        }.bind(this));
      }
    },
  
    /**
     * Handle the receive
     */
    doReceive: function() {
      if (this.spec.status.indexOf(this.response.status) == -1) {
        throw new CommunicationError(this);
      }
    }
  });
  
  Message.GoogleOAuth = Message.createExternal({
    method: 'OAUTH',
    path: 'https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=online',
    query: ["client_id", "scope", "state"],
    status: [200]
  });
  
  Message.GoogleOAuth.prototype.addRedirectOrigin = function(origin) {
    this.addQueryString({
      redirect_uri: origin + '/db/User/OAuth/google'
    });
  };
  
  Message.FacebookOAuth = Message.createExternal({
    method: 'OAUTH',
    path: 'https://www.facebook.com/dialog/oauth?response_type=code',
    query: ["client_id", "scope", "state"],
    status: [200]
  });
  
  Message.FacebookOAuth.prototype.addRedirectOrigin = function(origin) {
    this.addQueryString({
      redirect_uri: origin + '/db/User/OAuth/facebook'
    });
  };
  
  Message.GitHubOAuth = Message.createExternal({
    method: 'OAUTH',
    path: 'https://github.com/login/oauth/authorize?response_type=code&access_type=online',
    query: ["client_id", "scope", "state"],
    status: [200]
  });
  
  Message.GitHubOAuth.prototype.addRedirectOrigin = function(origin) {
    this.addQueryString({
      redirect_uri: origin + '/db/User/OAuth/github'
    });
  };
  
  Message.LinkedInOAuth = Message.createExternal({
    method: 'OAUTH',
    path: 'https://www.linkedin.com/uas/oauth2/authorization?response_type=code&access_type=online',
    query: ["client_id", "scope", "state"],
    status: [200]
  });
  
  Message.LinkedInOAuth.prototype.addRedirectOrigin = function(origin) {
    this.addQueryString({
      redirect_uri: origin + '/db/User/OAuth/linkedin'
    });
  };
  
  Message.TwitterOAuth = Message.createExternal({
    method: 'OAUTH',
    path: '',
    query: [],
    status: [200]
  });
  
  Message.TwitterOAuth.prototype.addRedirectOrigin = function(origin) {
    this.request.path = origin + '/db/User/OAuth1/twitter';
  };
  
  module.exports = Message;
  },{"../error/CommunicationError":25}],21:[function(require,module,exports){
  var Connector = require('./Connector');
  
  /**
   * @class baqend.connector.NodeConnector
   * @extends baqend.connector.Connector
   */
  var NodeConnector = Connector.inherit(/** @lends baqend.connector.NodeConnector.prototype */ {
    /** @lends baqend.connector.NodeConnector */
    extend: {
      initialize: function() {
        Connector.connectors.push(this);
      },
  
      isUsable: function(host, port, secure) {
        if (!this.prototype.http) {
          try {
            var http;
            if (secure) {
              http = require('https');
            } else {
              http = require('http');
            }
  
            if (http.request && http.Server) {
              this.prototype.http = http;
            }
          } catch (e) {
          }
        }
        return Boolean(this.prototype.http);
      }
    },
  
    constructor: function NodeConnector() {
      Connector.apply(this, arguments);
    },
  
    cookie: null,
  
    /**
     * @inheritDoc
     */
    doSend: function(request, receive) {
      request.host = this.host;
      request.port = this.port;
  
      var self = this;
      var entity = request.entity;
  
      if (this.cookie && this.secure && request.withCredentials)
        request.headers['Cookie'] = this.cookie;
  
      var req = this.http.request(request, function(res) {
        var data = '';
  
        res.setEncoding('utf-8');
        res.on('data', function(chunk) {
          data += chunk;
        });
        res.on('end', function() {
          var cookie = res.headers['set-cookie'];
          if (cookie) {
            // cookie may be an array, convert it to a string
            self.cookie = self.parseCookie(cookie + '');
          }
  
          receive({
            status: res.statusCode,
            headers: res.headers,
            entity: data
          });
        });
      });
  
      req.on('error', function(e) {
        receive({
          status: 0,
          error: e
        });
      });
  
      if (entity)
        req.end(entity, 'utf8');
      else
        req.end();
    },
  
    /**
     * @inheritDoc
     */
    createSocket : function() {
      var WebSocket = require('websocket').w3cwebsocket;
      return new WebSocket((this.secure ? 'wss://' : 'ws://') + this.host + ':' + this.port + '/events/');
    },
  
    /**
     * Parse the cookie header
     * @param {String} header
     */
    parseCookie: function(header) {
      var parts = header.split(';');
  
      for (var i = 0, part; part = parts[i]; ++i) {
        if (part.indexOf('Expires=') == 0) {
          var date = Date.parse(part.substring(8));
          if (date < Date.now()) {
            return null;
          }
        }
      }
  
      return parts[0];
    }
  });
  
  module.exports = NodeConnector;
  },{"./Connector":18,"http":103,"https":78,"websocket":64}],22:[function(require,module,exports){
  var Connector = require('./Connector');
  
  /**
   * @class baqend.connector.TitaniumConnector
   * @extends baqend.connector.Connector
   */
  var TitaniumConnector = Connector.inherit(/** @lends baqend.connector.TitaniumConnector.prototype */ {
    /** @lends baqend.connector.TitaniumConnector */
  	extend: {
      initialize: function() {
        Connector.connectors.push(this);
      },
  
      /**
       * Indicates if this connector implementation is usable for the given host and port
       * @param {String} host
       * @param {number} port
       * @param {boolean} secure
       * @returns {boolean}
       */
  		isUsable: function(host, port, secure) {
        return typeof Ti != 'undefined' && Ti.Network;
  		}
  	},
  
    constructor: function TitaniumConnector() {
      Connector.apply(this, arguments);
    },
  	
  	/**
  	 * @inheritDoc
  	 */
  	doSend: function(request, receive) {
  		var xhr = Ti.Network.createHTTPClient();
  		var url = this.origin + request.path;
  
  	  xhr.onreadystatechange = function() {
  			if (xhr.readyState == 4) {
  				var response = {
  					headers: {},
  					statusCode: xhr.status,
  					entity:  xhr.responseText
  				};
  
  				Connector.RESPONSE_HEADERS.forEach(function(name) {
  					response.headers[name] = xhr.getResponseHeader(name);
  				});
  
  				receive(response);
  			}
  		};
  
  		xhr.open(request.method, url, true);
  
  		var entity = request.entity;
  		var headers = request.headers;
  		for (var name in headers)
  			xhr.setRequestHeader(name, headers[name]);
  
      xhr.withCredentials = request.withCredentials;
  
  		xhr.send(entity);
  	}
  });
  
  module.exports = TitaniumConnector;
  },{"./Connector":18}],23:[function(require,module,exports){
  var Connector = require('./Connector');
  
  /**
   * @class baqend.connector.XMLHttpConnector
   * @extends baqend.connector.Connector
   */
  var XMLHttpConnector = Connector.inherit(/** @lends baqend.connector.XMLHttpConnector.prototype */ {
    /** @lends baqend.connector.XMLHttpConnector */
    extend: {
      initialize: function() {
        Connector.connectors.push(this);
      },
  
      /**
       * Indicates if this connector implementation is usable for the given host and port
       * @param {String} host
       * @param {number} port
       * @param {boolean} secure
       * @returns {boolean}
       */
      isUsable: function(host, port, secure) {
        return (
            window != 'undefined' &&
            window.location.hostname == host &&
            window.location.port == port &&
            window.location.protocol == (secure ? 'https:' : 'http:') &&
            typeof XMLHttpRequest != 'undefined'
        );
      }
    },
  
    constructor: function XMLHttpConnector() {
      Connector.apply(this, arguments);
    },
  
    /**
     * @inheritDoc
     */
    doSend: function(request, receive) {
      if (request.method == 'OAUTH') {
        addEventListener("storage", function handle(event) {
          if (event.key == 'oauth-response') {
            receive(JSON.parse(event.newValue));
            localStorage.removeItem('oauth-response');
            removeEventListener("storage", handle, false);
          }
        }, false);
        return;
      }
  
      var xhr = new XMLHttpRequest();
  
      var url = this.origin + request.path;
  
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
          var response = {
            headers: {},
            status: xhr.status,
            entity: xhr.response || xhr.responseText
          };
  
          Connector.RESPONSE_HEADERS.forEach(function(name) {
            response.headers[name] = xhr.getResponseHeader(name);
          });
  
          receive(response);
        }
      };
  
      xhr.open(request.method, url, true);
  
      var entity = request.entity;
      var headers = request.headers;
      for (var name in headers)
        xhr.setRequestHeader(name, headers[name]);
  
      xhr.withCredentials = request.withCredentials;
  
      xhr.send(entity);
    },
  
    createSocket: function() {
      return new WebSocket((this.secure ? 'wss://' : 'ws://') + this.host + ':' + this.port + '/events/');
    }
  });
  
  module.exports = XMLHttpConnector;
  },{"./Connector":18}],24:[function(require,module,exports){
  /**
   * @namespace baqend.connector
   */
  
  exports.Message = require('./Message');
  exports.Connector = require('./Connector');
  exports.NodeConnector = require('./NodeConnector');
  exports.TitaniumConnector = require('./TitaniumConnector');
  exports.XMLHttpConnector = require('./XMLHttpConnector');
  exports.IFrameConnector = require('./IFrameConnector');
  
  },{"./Connector":18,"./IFrameConnector":19,"./Message":20,"./NodeConnector":21,"./TitaniumConnector":22,"./XMLHttpConnector":23}],25:[function(require,module,exports){
  var PersistentError = require('./PersistentError');
  
  /**
   * @class baqend.error.CommunicationError
   * @extends baqend.error.PersistentError
   *
   * @param {baqend.connector.Message} httpMessage
   */
  var CommunicationError = PersistentError.inherit(/** @lends baqend.error.CommunicationError */ {
  
    status: 0,
  
  	constructor: function CommunicationError(httpMessage) {
  		var response = httpMessage.response.entity || {};
  		var state = (httpMessage.response.status == 0? 'Request': 'Response');
  		var message = response.message || 'Handling the ' + state + ' for ' + httpMessage.request.method + ' ' + httpMessage.request.path;
  
  		PersistentError.call(this, message, response);
  
  		this.name = response.className || 'CommunicationError';
  		this.reason = response.reason || 'Communication failed';
      this.status = httpMessage.response.status;
  
      if(response.data)
        this.data = response.data;
  
  		var cause = response;
  		while (cause && cause.stackTrace) {
  			this.stack += '\nServerside Caused by: ' + cause.className + ' ' + cause.message;
  
  			var stackTrace = cause.stackTrace;
  			for (var i = 0; i < stackTrace.length; ++i) {
  				var el = stackTrace[i];
  
  				this.stack += '\n    at ' + el.className + '.' + el.methodName;
  				this.stack += ' (' + el.fileName + ':' + el.lineNumber + ')';
  			}
  			
  			cause = cause.cause;
  		}
  	}
  });
  
  module.exports = CommunicationError;
  },{"./PersistentError":29}],26:[function(require,module,exports){
  var PersistentError = require('./PersistentError');
  
  /**
   * @class baqend.error.EntityExistsError
   * @extends baqend.error.PersistentError
   *
   * @param {String} entity
   */
  var EntityExistsError = PersistentError.inherit(/** @lends baqend.error.EntityExistsError.prototype */{
    constructor: function EntityExistsError(entity) {
      PersistentError.call(this, 'The entity ' + entity + ' is managed by a different db.');
  
      this.entity = entity;
    }
  });
  
  module.exports = EntityExistsError;
  },{"./PersistentError":29}],27:[function(require,module,exports){
  var PersistentError = require('./PersistentError');
  
  /**
   * @class baqend.error.EntityNotFoundError
   * @extends baqend.error.PersistentError
   *
   * @param {String} identity
   */
  var EntityNotFoundError = PersistentError.inherit(/** @lends baqend.error.EntityNotFoundError.prototype */ {
    constructor: function EntityNotFoundError(identity) {
      PersistentError.call(this, 'Entity ' + identity + ' is not found');
  
      this.identity = identity;
    }
  });
  
  module.exports = EntityNotFoundError;
  },{"./PersistentError":29}],28:[function(require,module,exports){
  var PersistentError = require('./PersistentError');
  
  /**
   * @class baqend.error.IllegalEntityError
   * @extends baqend.error.PersistentError
   *
   * @param {*} entity
   */
  var IllegalEntityError = PersistentError.inherit({
    constructor: function IllegalEntityError(entity) {
  		PersistentError.call(this, 'Entity ' + entity + ' is not a valid entity');
  		
  		this.entity = entity;
  	}
  });
  
  module.exports = IllegalEntityError;
  },{"./PersistentError":29}],29:[function(require,module,exports){
  /**
   * @class baqend.error.PersistentError
   * @extends Error
   *
   * @param {String} message
   * @param {Error=} cause
   */
  var PersistentError = Error.inherit(/* @lends baqend.error.PersistentError.prototype */ {
    cause: null,
  
    /**
     * @lends baqend.error.PersistentError
     */
    extend: {
      of: function(error) {
        if (error instanceof PersistentError) {
          return error;
        } else {
          return new PersistentError(null, error);
        }
      }
    },
  
    constructor: function PersistentError(message, cause) {
      message = (message ? message : 'An unexpected persistent error occured. ') +
          (cause ? ': ' + cause.message : '');
  
      if (Error.hasOwnProperty('captureStackTrace')) {
        Error.captureStackTrace(this, this.constructor);
      } else {
        this.stack = (new Error()).stack;
      }
  
      this.message = message;
      this.name = this.constructor.name;
  
      if (cause) {
        this.cause = cause;
        if (cause.stack) {
          this.stack += '\nCaused By: ' + cause.stack;
        }
      }
    }
  });
  
  module.exports = PersistentError;
  },{}],30:[function(require,module,exports){
  var PersistentError = require('./PersistentError');
  
  /**
   * @class baqend.error.RollbackError
   * @extends baqend.error.PersistentError
   *
   * @param {Error} cause
   */
  var RollbackError = PersistentError.inherit(/* @lends baqend.error.RollbackError */ {
    constructor: function RollbackError(cause) {
      PersistentError.call(this, 'The transaction has been rollbacked', cause);
    }
  });
  
  module.exports = RollbackError;
  
  },{"./PersistentError":29}],31:[function(require,module,exports){
  /**
   * @namespace baqend.error
   */
  
  exports.CommunicationError = require('./CommunicationError');
  exports.EntityExistsError = require('./EntityExistsError');
  exports.EntityNotFoundError = require('./EntityNotFoundError');
  exports.IllegalEntityError = require('./IllegalEntityError');
  exports.PersistentError = require('./PersistentError');
  exports.RollbackError = require('./RollbackError');
  },{"./CommunicationError":25,"./EntityExistsError":26,"./EntityNotFoundError":27,"./IllegalEntityError":28,"./PersistentError":29,"./RollbackError":30}],32:[function(require,module,exports){
  /**
   * @namespace baqend
   *
   * @borrows baqend.EntityManager#User
   * @borrows baqend.EntityManager#Role
   * @borrows baqend.EntityManager#run
   * @borrows baqend.EntityManager#getReference
   * @borrows baqend.EntityManager#contains
   * @borrows baqend.EntityManager#&lt;<i>YourEmbeddableClass</i>&gt;
   * @borrows baqend.EntityManager#&lt;<i>YourEntityClass</i>&gt;
   */
  
  require('jahcode');
  require('lie/dist/lie.polyfill');
  require('./polyfills');
  
  var EntityManagerFactory = require('./EntityManagerFactory');
  var EntityManager = require('./EntityManager');
  
  var emf = new EntityManagerFactory({global: true});
  
  exports = module.exports = emf.createEntityManager(true);
  
  EntityManager.prototype.collection = require('./collection');
  EntityManager.prototype.binding = require('./binding');
  EntityManager.prototype.connector = require('./connector');
  EntityManager.prototype.error = require('./error');
  EntityManager.prototype.message = require('./message');
  EntityManager.prototype.metamodel = require('./metamodel');
  EntityManager.prototype.util = require('./util');
  
  EntityManager.prototype.EntityManager = require('./EntityManager');
  EntityManager.prototype.EntityManagerFactory = require('./EntityManagerFactory');
  EntityManager.prototype.EntityTransaction = require('./EntityTransaction');
  EntityManager.prototype.Query = require('./Query');
  
  /**
   * Connects the DB with the baqend server and calls the callback on success
   * @param {String=} location The url to connect to
   * @param {function=} callback The callback, called when a connection is established
   * @function
   * @alias baqend#connect
   */
  exports.connect = function(location, callback) {
    emf.connect(location);
    return this.ready(callback);
  };
  
  },{"./EntityManager":1,"./EntityManagerFactory":2,"./EntityTransaction":3,"./Query":5,"./binding":16,"./collection":17,"./connector":24,"./error":31,"./message":33,"./metamodel":49,"./polyfills":50,"./util":60,"jahcode":61,"lie/dist/lie.polyfill":62}],33:[function(require,module,exports){
  var Message = require('./connector/Message');
  
  /**
   * Get the list of all available subresources
   * 
   * @class baqend.message.ListAllResources
   * @extends baqend.connector.Message
   *
   */
  exports.ListAllResources = Message.create({
      method: 'GET',
      path: '/',
      status: [200]
  });
  
  /**
   * Get the API version of the Orestes-Server
   * 
   * @class baqend.message.ApiVersion
   * @extends baqend.connector.Message
   *
   */
  exports.ApiVersion = Message.create({
      method: 'GET',
      path: '/version',
      status: [200]
  });
  
  /**
   * The Swagger specification of the Orestes-Server
   * 
   * @class baqend.message.Specification
   * @extends baqend.connector.Message
   *
   */
  exports.Specification = Message.create({
      method: 'GET',
      path: '/spec',
      status: [200]
  });
  
  /**
   * Returns all changed objects
   * 
   * @class baqend.message.GetBloomFilter
   * @extends baqend.connector.Message
   *
   */
  exports.GetBloomFilter = Message.create({
      method: 'GET',
      path: '/replication',
      status: [200]
  });
  
  /**
   * Get the current Orestes config
   * 
   * @class baqend.message.GetOrestesConfig
   * @extends baqend.connector.Message
   *
   */
  exports.GetOrestesConfig = Message.create({
      method: 'GET',
      path: '/config',
      status: [200]
  });
  
  /**
   * Updates the current Orestes config
   * 
   * @class baqend.message.UpdateOrestesConfig
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.UpdateOrestesConfig = Message.create({
      method: 'PUT',
      path: '/config',
      status: [200, 202]
  });
  
  /**
   * Initialize the database and creates predefined objects
   * 
   * @class baqend.message.Create
   * @extends baqend.connector.Message
   *
   */
  exports.Create = Message.create({
      method: 'POST',
      path: '/create',
      status: [201]
  });
  
  /**
   * Connects a browser to this server
   * 
   * @class baqend.message.Connect
   * @extends baqend.connector.Message
   *
   */
  exports.Connect = Message.create({
      method: 'GET',
      path: '/connect',
      status: [200]
  });
  
  /**
   * List all available bucket names
   * List all bucket
   * 
   * @class baqend.message.GetBucketNames
   * @extends baqend.connector.Message
   *
   */
  exports.GetBucketNames = Message.create({
      method: 'GET',
      path: '/db',
      status: [200]
  });
  
  /**
   * List all bucket objects
   * List all object ids of the bucket
   * 
   * @class baqend.message.GetBucketIds
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param start {Object} The offset to skip
   * @param count {Object} The upper limit to return
   */
  exports.GetBucketIds = Message.create({
      method: 'GET',
      path: '/db/:bucket/ids?start=0&count=-1',
      status: [200]
  });
  
  /**
   * Dumps all objects of the bucket
   * Exports the complete Bucket content
   * 
   * @class baqend.message.ExportBucket
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param bat {Object} The baqend authorization token
   */
  exports.ExportBucket = Message.create({
      method: 'GET',
      path: '/db/:bucket?bat=',
      status: [200]
  });
  
  /**
   * Upload all objects to the bucket
   * Imports the complete Bucket content
   * 
   * @class baqend.message.ImportBucket
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param bat {Object} The baqend authorization token
   * @param body {object} The massage Content
   */
  exports.ImportBucket = Message.create({
      method: 'PUT',
      path: '/db/:bucket?bat=',
      status: [200]
  });
  
  /**
   * Deletes all objects of the bucket
   * Deletes all objects of the bucket
   * 
   * @class baqend.message.TruncateBucket
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param bat {Object} The baqend authorization token
   */
  exports.TruncateBucket = Message.create({
      method: 'DELETE',
      path: '/db/:bucket?bat=',
      status: [200]
  });
  
  /**
   * Create object
   * Create the given Object.
   * The object will be created and gets a unique oid.
   * 
   * @class baqend.message.CreateObject
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param body {object} The massage Content
   */
  exports.CreateObject = Message.create({
      method: 'POST',
      path: '/db/:bucket',
      status: [201, 202]
  });
  
  /**
   * Get object
   * Returns the specified object. Each object has one unique identifier and therefore only one location.
   * 
   * @class baqend.message.GetObject
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   */
  exports.GetObject = Message.create({
      method: 'GET',
      path: '/db/:bucket/:oid',
      status: [200, 304]
  });
  
  /**
   * Replace object
   * Replace the current object with the updated one.
   * To update a specific version of the object a version Number can be provided in the If-Match header.
   * The update will only be accepted, if the current version matches the provided one, otherwise the update
   * will be rejected.
   * You can use the * wildcard to match any existing object, but prevents a insertion if the object doesn't exists.
   * 
   * @class baqend.message.ReplaceObject
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   * @param body {object} The massage Content
   */
  exports.ReplaceObject = Message.create({
      method: 'PUT',
      path: '/db/:bucket/:oid',
      status: [200, 202]
  });
  
  /**
   * Deletes the object
   * Deletes the object. The If-Match Header can be used to specify an expected version. The object will
   * only be deleted if the version matches the provided one. The * wildcard can be used to match any existing
   * version but results in an error if the object doesn't exists.
   * 
   * @class baqend.message.DeleteObject
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   */
  exports.DeleteObject = Message.create({
      method: 'DELETE',
      path: '/db/:bucket/:oid',
      status: [202, 204]
  });
  
  /**
   * Get all available class schemas
   * Gets the complete schema
   * 
   * @class baqend.message.GetAllSchemas
   * @extends baqend.connector.Message
   *
   */
  exports.GetAllSchemas = Message.create({
      method: 'GET',
      path: '/schema',
      status: [200]
  });
  
  /**
   * Create new class schemas and update existing class schemas
   * Updates the complete schema, merge all changes, reject the schema update if the schema changes aren't compatible
   * 
   * @class baqend.message.UpdateAllSchemas
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.UpdateAllSchemas = Message.create({
      method: 'POST',
      path: '/schema',
      status: [200]
  });
  
  /**
   * Replace all currently created schemas with the new ones
   * Replace the complete schema, with the new one.
   * 
   * @class baqend.message.ReplaceAllSchemas
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.ReplaceAllSchemas = Message.create({
      method: 'PUT',
      path: '/schema',
      status: [200]
  });
  
  /**
   * Get the class schema
   * Returns the schema definition of the class
   * The class definition contains a link to its parent class and all persistable fields with there types of the class
   * 
   * @class baqend.message.GetSchema
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.GetSchema = Message.create({
      method: 'GET',
      path: '/schema/:bucket',
      status: [200]
  });
  
  /**
   * Update the class schema
   * Modify the schema definition of the class by adding all missing fields
   * 
   * @class baqend.message.UpdateSchema
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param body {object} The massage Content
   */
  exports.UpdateSchema = Message.create({
      method: 'POST',
      path: '/schema/:bucket',
      status: [200]
  });
  
  /**
   * Replace the class schema
   * Replace the schema definition of the class
   * 
   * @class baqend.message.ReplaceSchema
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param body {object} The massage Content
   */
  exports.ReplaceSchema = Message.create({
      method: 'PUT',
      path: '/schema/:bucket',
      status: [200]
  });
  
  /**
   * Delete the class schema
   * Delete the schema definition of the class
   * 
   * @class baqend.message.DeleteSchema
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.DeleteSchema = Message.create({
      method: 'DELETE',
      path: '/schema/:bucket',
      status: [204]
  });
  
  /**
   * Executes a basic ad-hoc query
   * Executes the given query and returns a list of matching objects.
   * 
   * @class baqend.message.AdhocQuery
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param q {Object} The query
   * @param eager {Object} indicates if the query result should be send back as ids or as objects
   * @param start {Object} The offset to start from
   * @param count {Object} The number of objects to list
   * @param sort {Object} The sort object
   */
  exports.AdhocQuery = Message.create({
      method: 'GET',
      path: '/db/:bucket/query?q&start=0&count=-1&sort=&eager=',
      status: [200]
  });
  
  /**
   * Executes a basic ad-hoc query
   * Executes the given query and returns a list of matching objects.
   * 
   * @class baqend.message.AdhocQueryPOST
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param start {Object} The offset to start from
   * @param count {Object} The number of objects to list
   * @param sort {Object} The sort object
   * @param body {object} The massage Content
   */
  exports.AdhocQueryPOST = Message.create({
      method: 'POST',
      path: '/db/:bucket/query?start=0&count=-1&sort=',
      status: [200]
  });
  
  /**
   * Executes a count query
   * Executes the given query and returns the number of objects that match the query
   * 
   * @class baqend.message.AdhocCountQuery
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param q {Object} The query
   */
  exports.AdhocCountQuery = Message.create({
      method: 'GET',
      path: '/db/:bucket/count?q',
      status: [200]
  });
  
  /**
   * Executes a count query
   * Executes the given query and returns the number of objects that match the query
   * 
   * @class baqend.message.AdhocCountQueryPOST
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param body {object} The massage Content
   */
  exports.AdhocCountQueryPOST = Message.create({
      method: 'POST',
      path: '/db/:bucket/count',
      status: [200]
  });
  
  /**
   * List all Query subresources
   * 
   * @class baqend.message.ListQueryResources
   * @extends baqend.connector.Message
   *
   */
  exports.ListQueryResources = Message.create({
      method: 'GET',
      path: '/query',
      status: [200]
  });
  
  /**
   * Creates a prepared query
   * 
   * @class baqend.message.CreateQuery
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.CreateQuery = Message.create({
      method: 'POST',
      path: '/query',
      status: [201]
  });
  
  /**
   * List all subresources of a query
   * 
   * @class baqend.message.ListThisQueryResources
   * @extends baqend.connector.Message
   *
   * @param qid {Object} The query id
   */
  exports.ListThisQueryResources = Message.create({
      method: 'GET',
      path: '/query/:qid',
      status: [200]
  });
  
  /**
   * Get the query string
   * 
   * @class baqend.message.GetQueryCode
   * @extends baqend.connector.Message
   *
   * @param qid {Object} The query id
   */
  exports.GetQueryCode = Message.create({
      method: 'GET',
      path: '/query/:qid/source',
      status: [200]
  });
  
  /**
   * Executes a prepared query
   * 
   * @class baqend.message.RunQuery
   * @extends baqend.connector.Message
   *
   * @param start {Object} The offset from where to start from
   * @param count {Object} The number of objects to enlist
   * @param qid {Object} The query id
   */
  exports.RunQuery = Message.create({
      method: 'GET',
      path: '/query/:qid/result?start=0&count=-1',
      status: [200]
  });
  
  /**
   * Get the declared query parameters
   * 
   * @class baqend.message.GetQueryParameters
   * @extends baqend.connector.Message
   *
   * @param qid {Object} The query id
   */
  exports.GetQueryParameters = Message.create({
      method: 'GET',
      path: '/query/:qid/parameters',
      status: [200]
  });
  
  /**
   * List all active transactions
   * 
   * @class baqend.message.GetActiveTransactions
   * @extends baqend.connector.Message
   *
   */
  exports.GetActiveTransactions = Message.create({
      method: 'GET',
      path: '/transaction',
      status: [200]
  });
  
  /**
   * Starts a new Transaction
   * 
   * @class baqend.message.NewTransaction
   * @extends baqend.connector.Message
   *
   */
  exports.NewTransaction = Message.create({
      method: 'POST',
      path: '/transaction',
      status: [201]
  });
  
  /**
   * List all subresources
   * 
   * @class baqend.message.ListTransactionalSubresurces
   * @extends baqend.connector.Message
   *
   * @param tid {Object} The transaction id
   */
  exports.ListTransactionalSubresurces = Message.create({
      method: 'GET',
      path: '/transaction/:tid',
      status: [200]
  });
  
  /**
   * Aborts a active transaction
   * 
   * @class baqend.message.AbortTransaction
   * @extends baqend.connector.Message
   *
   * @param tid {Object} The transaction id
   */
  exports.AbortTransaction = Message.create({
      method: 'PUT',
      path: '/transaction/:tid/aborted',
      status: [204]
  });
  
  /**
   * List all transactional changed objects
   * 
   * @class baqend.message.GetTransactionChangeset
   * @extends baqend.connector.Message
   *
   * @param tid {Object} The transaction id
   */
  exports.GetTransactionChangeset = Message.create({
      method: 'GET',
      path: '/transaction/:tid/changeset',
      status: [200]
  });
  
  /**
   * Commits the transaction
   * If the transaction can be completed a list of all changed objects with their updated versions are returned.
   * 
   * @class baqend.message.CommitTransaction
   * @extends baqend.connector.Message
   *
   * @param tid {Object} The transaction id
   * @param body {object} The massage Content
   */
  exports.CommitTransaction = Message.create({
      method: 'PUT',
      path: '/transaction/:tid/committed',
      status: [200]
  });
  
  /**
   * List all subresources
   * 
   * @class baqend.message.ListTransactionResources
   * @extends baqend.connector.Message
   *
   * @param tid {Object} The transaction id
   */
  exports.ListTransactionResources = Message.create({
      method: 'GET',
      path: '/transaction/:tid/dbview',
      status: [200]
  });
  
  /**
   * List all subresources
   * 
   * @class baqend.message.ListTransactionBucketResources
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param tid {Object} The transaction id
   */
  exports.ListTransactionBucketResources = Message.create({
      method: 'GET',
      path: '/transaction/:tid/dbview/:bucket',
      status: [200]
  });
  
  /**
   * Get the transactional modified version of the object
   * 
   * @class baqend.message.GetTransactionStateObject
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   * @param tid {Object} The transaction id
   */
  exports.GetTransactionStateObject = Message.create({
      method: 'GET',
      path: '/transaction/:tid/dbview/:bucket/:oid',
      status: [200]
  });
  
  /**
   * Executes an transactional adhoc query
   * Executes an adhoc query and returns a list of matched object identifiers
   * 
   * @class baqend.message.QueryTransactional
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param query {Object} The query
   * @param start {Object} The offset to start from
   * @param count {Object} The number of objects to list
   * @param tid {Object} The transaction id
   */
  exports.QueryTransactional = Message.create({
      method: 'GET',
      path: '/transaction/:tid/dbview/:bucket?query&start=0&count=-1',
      status: [200]
  });
  
  /**
   * Executes a transactional prepared query
   * 
   * @class baqend.message.RunQueryTransactional
   * @extends baqend.connector.Message
   *
   * @param start {Object} The offset which will be skipped
   * @param count {Object} The number of objects to enlist
   * @param qid {Object} The query id
   * @param tid {Object} The transaction id
   */
  exports.RunQueryTransactional = Message.create({
      method: 'GET',
      path: '/transaction/:tid/queryview/:qid/result?start=0&count=-1',
      status: [200]
  });
  
  /**
   * Update the object
   * Executes the partial updates on the object.
   * To update an object an explicit version must be provided in the If-Match header.
   * If the version is not equal to the current object version the update will be aborted.
   * The version identifier Any (*) can be used to skip the version validation and therefore
   * the update will always be applied.
   * 
   * @class baqend.message.UpdatePartially
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   * @param body {object} The massage Content
   */
  exports.UpdatePartially = Message.create({
      method: 'POST',
      path: '/db/:bucket/:oid',
      status: [204]
  });
  
  /**
   * Update the object field
   * Executes the partial update on a object field.
   * To update an object an explicit version must be provided in the If-Match header.
   * If the version is not equal to the current object version the update will be aborted.
   * The version identifier Any (*) can be used to skip the version validation and therefore
   * the update will always be applied.
   * 
   * @class baqend.message.UpdateField
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param field {Object} The field name
   * @param oid {Object} The unique object identifier
   * @param body {object} The massage Content
   */
  exports.UpdateField = Message.create({
      method: 'POST',
      path: '/db/:bucket/:oid/:field',
      status: [204]
  });
  
  /**
   * Method to login a user
   * Log in a user by it's credentials
   * 
   * @class baqend.message.Login
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.Login = Message.create({
      method: 'POST',
      path: '/db/User/login',
      status: [200]
  });
  
  /**
   * Method to register a user
   * Register and creates a new user
   * 
   * @class baqend.message.Register
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.Register = Message.create({
      method: 'POST',
      path: '/db/User/register',
      status: [200]
  });
  
  /**
   * Method to load the current user object
   * Gets the user object of the currently logged in user
   * 
   * @class baqend.message.Me
   * @extends baqend.connector.Message
   *
   */
  exports.Me = Message.create({
      method: 'GET',
      path: '/db/User/me',
      status: [200]
  });
  
  /**
   * Method to validate a user token
   * Validates if a given token is still valid
   * 
   * @class baqend.message.ValidateUser
   * @extends baqend.connector.Message
   *
   */
  exports.ValidateUser = Message.create({
      method: 'GET',
      path: '/db/User/validate',
      status: [200]
  });
  
  /**
   * Method to remove token cookie
   * Log out a user by removing the cookie token
   * 
   * @class baqend.message.Logout
   * @extends baqend.connector.Message
   *
   */
  exports.Logout = Message.create({
      method: 'GET',
      path: '/db/User/logout',
      status: [204]
  });
  
  /**
   * Method to change the password
   * 
   * @class baqend.message.NewPassword
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.NewPassword = Message.create({
      method: 'POST',
      path: '/db/User/password',
      status: [200]
  });
  
  /**
   * Method to register or login using an OAuth provider.
   * This resource is invoked by the provider with a redirect after the user granted permission.
   * 
   * @class baqend.message.OAuth2
   * @extends baqend.connector.Message
   *
   * @param oauth_verifier {Object} OAuth 1.0 code
   * @param code {Object} The code written by the provider
   * @param provider {Object} The OAuth provider
   * @param oauth_token {Object} OAuth 1.0 identifier
   * @param state {Object} On true a token will be returned
   */
  exports.OAuth2 = Message.create({
      method: 'GET',
      path: '/db/User/OAuth/:provider?state=&code=&oauth_verifier=&oauth_token=',
      status: [200]
  });
  
  /**
   * Method to invoke a OAuth-1.0 login/register
   * The resource requests a request-token and redirects the user to the provider page to log-in and grant permission for
   * your application.
   * 
   * @class baqend.message.OAuth1
   * @extends baqend.connector.Message
   *
   * @param provider {Object} The OAuth provider
   */
  exports.OAuth1 = Message.create({
      method: 'GET',
      path: '/db/User/OAuth1/:provider',
      status: [200]
  });
  
  /**
   * Gets the code of the the given bucket and type
   * 
   * @class baqend.message.GetBaqendCode
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param type {Object} The type of the script
   */
  exports.GetBaqendCode = Message.create({
      method: 'GET',
      path: '/code/:bucket/:type',
      status: [200]
  });
  
  /**
   * Sets the code of the bucket and type
   * 
   * @class baqend.message.SetBaqendCode
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param type {Object} The type of the script
   * @param body {object} The massage Content
   */
  exports.SetBaqendCode = Message.create({
      method: 'PUT',
      path: '/code/:bucket/:type',
      status: [200]
  });
  
  /**
   * Delete the code of the given bucket and type
   * 
   * @class baqend.message.DeleteBaqendCode
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param type {Object} The type of the script
   */
  exports.DeleteBaqendCode = Message.create({
      method: 'DELETE',
      path: '/code/:bucket/:type',
      status: [204]
  });
  
  /**
   * Calls the module of the specific bucket
   * 
   * @class baqend.message.PostBaqendModule
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The method name
   */
  exports.PostBaqendModule = Message.create({
      method: 'POST',
      path: '/code/:bucket',
      status: [200, 204]
  });
  
  /**
   * Calls the module of the specific bucket
   * 
   * @class baqend.message.GetBaqendModule
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The module name
   */
  exports.GetBaqendModule = Message.create({
      method: 'GET',
      path: '/code/:bucket',
      status: [200, 204]
  });
  
  /**
   * List all available modules
   * 
   * @class baqend.message.GetAllModules
   * @extends baqend.connector.Message
   *
   */
  exports.GetAllModules = Message.create({
      method: 'GET',
      path: '/code',
      status: [200]
  });
  
  /**
   * Get all file ID's   File-Bucket
   * retrieve meta-information about all accessible Files in a specific Bucket.
   * 
   * @class baqend.message.ListFiles
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param start {Object} The unique object identifier
   * @param count {Object} The upper limit to return.
   */
  exports.ListFiles = Message.create({
      method: 'GET',
      path: '/file/:bucket/ids?start=&count=-1',
      status: [200]
  });
  
  /**
   * Retrieves the bucket ACL's
   * The bucket metadata object contains the bucketAcl
   * 
   * @class baqend.message.GetFileBucketAcls
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.GetFileBucketAcls = Message.create({
      method: 'GET',
      path: '/file/:bucket',
      status: [200]
  });
  
  /**
   * Sets the Bucket ACL
   * Creates or replaces the bucket ACL's to control permission access to all included Files.
   * 
   * @class baqend.message.SetFileBucketAcls
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param body {object} The massage Content
   */
  exports.SetFileBucketAcls = Message.create({
      method: 'PUT',
      path: '/file/:bucket',
      status: [204]
  });
  
  /**
   * deletes all files of a file Bucket
   * Deletes the bucket and all its content
   * 
   * @class baqend.message.DeleteFileBucket
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.DeleteFileBucket = Message.create({
      method: 'DELETE',
      path: '/file/:bucket',
      status: [204]
  });
  
  /**
   * Creates a new file with a UUID
   * Creates a File with a random ID, only Insert permissions are required
   * 
   * @class baqend.message.CreateFile
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.CreateFile = Message.create({
      method: 'POST',
      path: '/file/:bucket',
      status: [200]
  });
  
  /**
   * Download a file  File-Bucket-OID
   * Download a chunk of Data.
   * 
   * @class baqend.message.GetFile
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   */
  exports.GetFile = Message.create({
      method: 'GET',
      path: '/file/:bucket/:oid',
      status: [200, 304]
  });
  
  /**
   * replaces File ACL
   * replaces File Access control listing  Files.
   * 
   * @class baqend.message.SetFileAcl
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   * @param body {object} The massage Content
   */
  exports.SetFileAcl = Message.create({
      method: 'POST',
      path: '/file/:bucket/:oid',
      status: [204]
  });
  
  /**
   * Replace a file
   * Replace an File with some other file.
   * Like objects, you can specify an explicit version in the
   * If-Match Header or use * to replace any version but error if the File dose not exist.
   * 
   * @class baqend.message.ReplaceFile
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   */
  exports.ReplaceFile = Message.create({
      method: 'PUT',
      path: '/file/:bucket/:oid',
      status: [200]
  });
  
  /**
   * Delete a file
   * Deletes a file.
   * Like objects, you can specify an explicit version in the
   * If-Match Header or use * to replace any version but error if the File dose not exist.
   * 
   * @class baqend.message.DeleteFile
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param oid {Object} The unique object identifier
   */
  exports.DeleteFile = Message.create({
      method: 'DELETE',
      path: '/file/:bucket/:oid',
      status: [203]
  });
  
  /**
   * List bucket indexes
   * List all indexes of the given bucket
   * 
   * @class baqend.message.ListIndexes
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.ListIndexes = Message.create({
      method: 'GET',
      path: '/index/:bucket',
      status: [200]
  });
  
  /**
   * Create or drop bucket index
   * Create or drop a index for the given bucket
   * 
   * @class baqend.message.CreateDropIndex
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   * @param body {object} The massage Content
   */
  exports.CreateDropIndex = Message.create({
      method: 'POST',
      path: '/index/:bucket',
      status: [202]
  });
  
  /**
   * Drop all indexes
   * Drop all indexes on the given bucket
   * 
   * @class baqend.message.DropAllIndexes
   * @extends baqend.connector.Message
   *
   * @param bucket {Object} The bucket name
   */
  exports.DropAllIndexes = Message.create({
      method: 'DELETE',
      path: '/index/:bucket',
      status: [202]
  });
  
  /**
   * Method to register a new device
   * Registers a new devices
   * 
   * @class baqend.message.DeviceRegister
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.DeviceRegister = Message.create({
      method: 'POST',
      path: '/db/Device/register',
      status: [204]
  });
  
  /**
   * Method to push a message to devices
   * Pushes a message to devices
   * 
   * @class baqend.message.DevicePush
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.DevicePush = Message.create({
      method: 'POST',
      path: '/db/Device/push',
      status: [204]
  });
  
  /**
   * Check if device is registered
   * Checks if the device is already registered
   * 
   * @class baqend.message.DeviceRegistered
   * @extends baqend.connector.Message
   *
   */
  exports.DeviceRegistered = Message.create({
      method: 'GET',
      path: '/db/Device/registered',
      status: [200]
  });
  
  /**
   * Upload APNS certificate
   * Upload APNS certificate
   * 
   * @class baqend.message.UploadAPNSCertificate
   * @extends baqend.connector.Message
   *
   */
  exports.UploadAPNSCertificate = Message.create({
      method: 'POST',
      path: '/config/APNSCert',
      status: [204]
  });
  
  /**
   * Set GCM-API-Key
   * Sets the GCM-API-Key
   * 
   * @class baqend.message.GCMAKey
   * @extends baqend.connector.Message
   *
   * @param body {object} The massage Content
   */
  exports.GCMAKey = Message.create({
      method: 'POST',
      path: '/config/GCMKey',
      status: [204]
  });
  
  
  },{"./connector/Message":20}],34:[function(require,module,exports){
  var Accessor = require('../binding/Accessor');
  
  /**
   * @class baqend.metamodel.Attribute
   */
  var Attribute = Object.inherit(/** @lends baqend.metamodel.Attribute.prototype */ {
    /**
     * @lends baqend.metamodel.Attribute
     */
    extend: {
      /**
       * @enum {number}
       */
      PersistentAttributeType: {
        BASIC: 0,
        ELEMENT_COLLECTION: 1,
        EMBEDDED: 2,
        MANY_TO_MANY: 3,
        MANY_TO_ONE: 4,
        ONE_TO_MANY: 5,
        ONE_TO_ONE: 6
      }
    },
  
    /**
     * @type Boolean
     */
    get isAssociation() {
      return this.persistentAttributeType > Attribute.PersistentAttributeType.EMBEDDED;
    },
  
    /**
     * @type Boolean
     */
    get isCollection() {
      return this.persistentAttributeType == Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
    },
  
    /**
     * @type Boolean
     */
    isId: false,
  
    /**
     * @type Boolean
     */
    isVersion: false,
  
    /**
     * @type Boolean
     */
    isAcl: false,
  
    /**
     * @type Boolean
     */
    isMetadata: false,
  
    /**
     * @type baqend.binding.Accessor
     */
    accessor: null,
  
    /**
     * @type Number
     */
    persistentAttributeType: -1,
  
    /**
     * @type baqend.metamodel.ManagedType
     */
    declaringType: null,
  
    /**
     * @type String
     */
    name: null,
  
    /**
     * @type Number
     */
    order: null,
  
    /**
     * @param {String} name The attribute name
     * @param {Boolean=} isMetadata <code>true</code> if the attribute is an metadata attribute
     */
    constructor: function Attribute(name, isMetadata) {
      this.name = name;
      this.isMetadata = !!isMetadata;
    },
  
    /**
     * @param {baqend.metamodel.ManagedType} declaringType The type that owns this attribute
     * @param {Number} order Position of the attribute
     */
    init: function(declaringType, order) {
      if (this.declaringType)
        throw new Error('The attribute is already initialized.');
  
      this.order = order;
      this.accessor = new Accessor();
      this.declaringType = declaringType;
    },
  
    /**
     * @param {Object} entity
     * @returns {*}
     */
    getValue: function (entity) {
      return this.accessor.getValue(entity, this);
    },
  
    /**
     * @param {Object} entity
     * @param {*} value
     */
    setValue: function (entity, value) {
      this.accessor.setValue(entity, this, value);
    },
  
    /**
     * Gets this attribute value form the object as json
     * @param {baqend.util.Metadata} state The root object state
     * @param {*} object The object which contains the value of this attribute
     * @return {*} The converted json value
     * @abstract
     */
    getJsonValue: function (state, object) {},
  
    /**
     * Sets this attribute value from json to the object
     * @param {baqend.util.Metadata} state The root state
     * @param {*} object The object which contains the attribute
     * @param {*} jsonValue The json value to convert an set
     * @abstract
     */
    setJsonValue: function (state, object, jsonValue) {},
  
    /**
     * Converts this attribute field to json
     * @abstract
     * @returns {Object} The attribute description as json
     */
    toJSON: function() {}
  });
  
  module.exports = Attribute;
  },{"../binding/Accessor":6}],35:[function(require,module,exports){
  var Type = require('./Type');
  var GeoPoint = require('../GeoPoint');
  
  /**
   * @class baqend.metamodel.BasicType
   * @extends baqend.metamodel.Type
   */
  var BasicType = Type.inherit(/** @lends baqend.metamodel.BasicType.prototype */ {
  
    /**
     * The persistent type of this type
     * @type Number
     */
    persistenceType: Type.PersistenceType.BASIC,
  
    /**
     * Indicates if this type is not the main type of the constructor
     * @type {Boolean}
     */
    noResolving: false,
  
    /**
     * Creates a new instance of a native db type
     * @param {String} ref The db ref of this type
     * @param {Function} typeConstructor The javascript class of this type
     * @param {Boolean} noResolving Indicates if this type is not the main type of the constructor
     */
    constructor: function BasicType(ref, typeConstructor, noResolving) {
      if (ref.indexOf('/db/') != 0)
        ref = '/db/' + ref;
  
      Type.call(this, ref, typeConstructor);
  
      this.noResolving = noResolving;
    },
  
    /**
     * @inheritDoc
     */
    toJsonValue: function (state, currentValue) {
      if (currentValue === null || currentValue === undefined) {
        return null;
      }
  
      return this.typeConstructor.asInstance(currentValue);
    },
  
    /**
     * @inheritDoc
     */
    fromJsonValue: function (state, jsonValue, currentValue) {
      if (jsonValue === null || jsonValue === undefined) {
        return null;
      }
  
      return this.typeConstructor.asInstance(jsonValue);
    },
  
    toString: function() {
      return "BasicType(" + this.ref + ")";
    }
  });
  
  BasicType.extend( /** @lends baqend.metamodel.BasicType */ {
    Boolean: new BasicType('Boolean', Boolean),
    Double: new BasicType('Double', Number),
    Integer: new BasicType('Integer', Number),
    String: new BasicType('String', String),
    DateTime: new (BasicType.inherit({
      constructor: function DateTimeType() {
        BasicType.call(this, 'DateTime', Date);
      },
  
      toJsonValue: function(state, currentValue) {
        var value = this.superCall(state, currentValue);
        if (value) {
          value = value.toISOString();
        }
        return value;
      }
    })),
  
    Date: new (BasicType.inherit({
      constructor: function DateType() {
        BasicType.call(this, 'Date', Date);
      },
  
      toJsonValue: function (state, currentValue) {
        var value = this.superCall(state, currentValue);
        if (value) {
          value = value.toISOString();
          value = value.substring(0, value.indexOf('T'));
        }
        return value;
      },
  
      fromJsonValue: function (state, json) {
        return this.superCall(state, String.isInstance(json) ? json + 'T00:00Z' : json);
      }
    })),
  
    Time: new (BasicType.inherit({
      constructor: function TimeType() {
        BasicType.call(this, 'Time', Date);
      },
  
      toJsonValue: function (state, currentValue) {
        var value = this.superCall(state, currentValue);
        if (value) {
          value = value.toISOString();
          value = value.substring(value.indexOf('T') + 1);
        }
        return value;
      },
  
      fromJsonValue: function (state, json) {
        return this.superCall(state, String.isInstance(json) ? '1970-01-01T' + json : json);
      }
    })),
  
    GeoPoint: new BasicType('GeoPoint', GeoPoint),
  
    JsonArray: new (BasicType.inherit({
      constructor: function JsonArrayType() {
        BasicType.call(this, 'JsonArray', Array);
      },
  
      init: function(classFactory) {
        this._enhancer = classFactory;
      },
  
      toJsonValue: function (state, value) {
        if (value && value.constructor == Array) {
          return value;
        }
  
        return null;
      }
    })),
  
    JsonObject: new (BasicType.inherit({
      constructor: function JsonObjectType() {
        BasicType.call(this, 'JsonObject', Object);
      },
  
      init: function(classFactory) {
        this._enhancer = classFactory;
      },
  
      toJsonValue: function (state, value) {
        if (value && value.constructor == Object) {
          return value;
        }
  
        return null;
      }
    }))
  });
  
  module.exports = BasicType;
  },{"../GeoPoint":4,"./Type":48}],36:[function(require,module,exports){
  var PluralAttribute = require('./PluralAttribute');
  var collection = require('../collection');
  
  /**
   * @class baqend.metamodel.CollectionAttribute
   * @extends baqend.metamodel.PluralAttribute
   */
  var CollectionAttribute = PluralAttribute.inherit(/** @lends baqend.metamodel.CollectionAttribute.prototype */ {
  
    collectionType: PluralAttribute.CollectionType.COLLECTION,
  
    /**
     * @param {String} name
     * @param {baqend.metamodel.Type} elementType
     */
    constructor: function CollectionAttribute(name, elementType) {
      PluralAttribute.call(this, name, elementType);
      this.typeConstructor = collection.Collection;
    }
  });
  
  module.exports = CollectionAttribute;
  },{"../collection":17,"./PluralAttribute":45}],37:[function(require,module,exports){
  /**
   * Creates a new index instance which is needed to create an
   * database index.
   *
   * @class baqend.metamodel.DbIndex
   *
   * @param {String|Object|Array} keys The name of the field which will be used for the index,
   * an object of an field and index type combination or
   * an array of objects to create an compound index
   * @param {Boolean=} unique Indicates if the index will be unique
   */
  var DbIndex = Object.inherit(/** @lends baqend.metamodel.DbIndex.prototype */ {
  
    /** @lends baqend.metamodel.DbIndex */
    extend: {
      /**
       * @type String
       */
      ASC: 'asc',
      /**
       * @type String
       */
      DESC: 'desc',
      /**
       * @type String
       */
      GEO: 'geo',
  
      /**
       * Returns DbIndex Object created from the given JSON
       */
      fromJSON: function(json) {
        return new DbIndex(json.keys, json.unique);
      }
    },
  
    /**
     * @type Boolean
     */
    drop: false,
  
    constructor: function DbIndex(keys, unique) {
  
      if(String.isInstance(keys)) {
        var key = {};
        key[keys] = DbIndex.ASC;
        this.keys = [key];
      } else if(Array.isInstance(keys)) {
        this.keys = keys;
      } else if(Object.isInstance(keys)) {
        this.keys = [keys];
      } else {
        throw new Error("The keys parameter must be an String, Object or Array.");
      }
  
      this.unique = unique === true;
    },
  
    hasKey: function(name) {
      for(var i = 0; i < this.keys.length; i++) {
        if(this.keys[i][name]) {
          return true;
        }
      }
      return false;
    },
  
    get isCompound() {
      return this.keys.length > 1;
    },
  
    get isUnique() {
      return this.unique;
    },
  
    /**
     * Returns a JSON representation of the Index object
     *
     * @return {Object} A Json of this Index object
     */
    toJSON: function() {
      return {
        unique: this.unique,
        keys: this.keys,
        drop: this.drop
      };
    }
  });
  
  module.exports = DbIndex;
  
  },{}],38:[function(require,module,exports){
  var ManagedType = require('./ManagedType');
  var Type = require('./Type');
  var binding = require('../binding');
  
  /**
   * @class baqend.metamodel.EmbeddableType
   * @extends baqend.metamodel.ManagedType
   */
  var EmbeddableType = ManagedType.inherit(/** @lends baqend.metamodel.EmbeddableType.prototype */ {
    persistenceType: Type.PersistenceType.EMBEDDABLE,
  
    constructor: function EmbeddableType(name, typeConstructor) {
      ManagedType.call(this, name, typeConstructor);
    },
  
    /**
     * {@inheritDoc}
     */
    createProxyClass: function() {
      return this._enhancer.createProxy(binding.Managed);
    },
  
    /**
     * {@inheritDoc}
     * @param {baqend.EntityManager} db {@inheritDoc}
     * @return {baqend.binding.ManagedFactory} A factory which creates embeddable objects
     */
    createObjectFactory: function(db) {
      return binding.ManagedFactory.create(this, db);
    },
  
    /**
     * @inheritDoc
     */
    toJsonValue: function (state, object) {
      if (this.typeConstructor.isInstance(object) && !object.hasOwnProperty('__metadata')) {
        object._metadata = {
          _root: state._root
        };
      }
  
      return this.superCall(state, object);
    },
  
    /**
     * @inheritDoc
     */
    fromJsonValue: function (state, jsonObject, currentObject) {
      if (!currentObject && jsonObject) {
        currentObject = this.create();
        currentObject._metadata._root = state._root;
      }
  
      return this.superCall(state, jsonObject, currentObject);
    },
  
    toString: function() {
      return "EmbeddableType(" + this.ref + ")";
    }
  });
  
  module.exports = EmbeddableType;
  },{"../binding":16,"./ManagedType":41,"./Type":48}],39:[function(require,module,exports){
  var binding = require('../binding');
  
  var SingularAttribute = require('./SingularAttribute');
  var BasicType = require('./BasicType');
  var Type = require('./Type');
  var ManagedType = require('./ManagedType');
  var Metadata = require('../util/Metadata');
  var Permission = require('../util/Permission');
  
  /**
   * @class baqend.metamodel.EntityType
   * @extends baqend.metamodel.ManagedType
   *
   * @param {String} ref
   * @param {baqend.metamodel.EntityType} superType
   * @param {Function} typeConstructor
   */
  var EntityType = ManagedType.inherit( /** @lends baqend.metamodel.EntityType.prototype */ {
    persistenceType: Type.PersistenceType.ENTITY,
  
    /**
     * @type baqend.metamodel.SingularAttribute
     */
    declaredId: null,
  
    /**
     * @type baqend.metamodel.SingularAttribute
     */
    declaredVersion: null,
  
    /**
     * @type baqend.metamodel.SingularAttribute
     */
    declaredAcl: null,
  
    /**
     * @type baqend.metamodel.EntityType
     */
    superType: null,
  
    /**
     * @type baqend.metamodel.SingularAttribute
     */
    get id() {
      return this.declaredId || this.superType.id;
    },
  
    /**
     * @type baqend.metamodel.SingularAttribute
     */
    get version() {
      return this.declaredVersion || this.superType.version;
    },
  
    /**
     * @type baqend.metamodel.SingularAttribute
     */
    get acl() {
      return this.declaredAcl || this.superType.acl;
    },
  
    /**
     * @type baqend.util.Permission
     */
    updatePermission: null,
  
    /**
     * @type baqend.util.Permission
     */
    insertPermission: null,
  
    /**
     * @type baqend.util.Permission
     */
    deletePermission: null,
  
    /**
     * @type baqend.util.Permission
     */
    queryPermission: null,
  
    /**
     * @type baqend.util.Permission
     */
    schemaSubclassPermission: null,
  
    constructor: function EntityType(ref, superType, typeConstructor) {
      ManagedType.call(this, ref, typeConstructor);
  
      this.superType = superType;
      this.insertPermission = new Permission();
      this.updatePermission = new Permission();
      this.deletePermission = new Permission();
      this.queryPermission = new Permission();
      this.schemaSubclassPermission = new Permission();
    },
  
    /**
     * {@inheritDoc}
     */
    createProxyClass: function() {
      var Class = this.superType.typeConstructor;
      if (Class === Object) {
        switch (this.name) {
          case 'User':
            Class = binding.User;
            break;
          case 'Role':
            Class = binding.Role;
            break;
          default:
            Class = binding.Entity;
            break;
        }
      }
  
      return this._enhancer.createProxy(Class);
    },
  
    /**
     * {@inheritDoc}
     * Creates an ObjectFactory for this type and the given EntityManager
     * @return {baqend.binding.EntityFactory} A factory which creates entity objects
     */
    createObjectFactory: function(db) {
      switch (this.name) {
        case 'User':
          return binding.UserFactory.create(this, db);
        case 'Device':
          return binding.DeviceFactory.create(this, db);
        case 'Object':
          return undefined;
      }
  
      return binding.EntityFactory.create(this, db);
    },
  
    /**
     * @inheritDoc
     */
    fromJsonValue: function (state, jsonObject, currentObject, isRoot) {
      if (isRoot) {
        return this.superCall(state, jsonObject, currentObject);
      } else if (jsonObject) {
        return state.db.getReference(jsonObject);
      } else {
        return null;
      }
    },
  
    /**
     * @inheritDoc
     */
    toJsonValue: function(state, object, isRoot) {
      if (isRoot) {
        return this.superCall(state, object);
      } else if (this.typeConstructor.isInstance(object)) {
        object.attach(state.db);
        return object.id;
      } else {
        return null;
      }
    },
  
    toString: function() {
      return "EntityType(" + this.ref + ")";
    },
  
    toJSON: function() {
      var json = this.superCall();
  
      json.acl.schemaSubclass = this.schemaSubclassPermission;
      json.acl.insert = this.insertPermission;
      json.acl.update = this.updatePermission;
      json.acl.delete = this.deletePermission;
      json.acl.query = this.queryPermission;
  
      return json;
    }
  });
  
  EntityType.extend(/** @lends baqend.metamodel.EntityType */ {
  
    /**
     * @class baqend.metamodel.EntityType.Object
     * @extends baqend.metamodel.EntityType
     */
    Object: EntityType.inherit(/** @lends baqend.metamodel.EntityType.Object.prototype */{
      /** @lends baqend.metamodel.EntityType.Object */
      extend: {
        ref: '/db/Object'
      },
  
      constructor: function ObjectType() {
        EntityType.call(this, EntityType.Object.ref, null, Object);
  
        this.declaredId = new SingularAttribute('id', BasicType.String, true);
        this.declaredId.init(this, 0);
        this.declaredId.isId = true;
        this.declaredVersion = new SingularAttribute('version', BasicType.Double, true);
        this.declaredVersion.init(this, 1);
        this.declaredVersion.isVersion = true;
        this.declaredAcl = new SingularAttribute('acl', BasicType.JsonObject, true);
        this.declaredAcl.init(this, 2);
        this.declaredAcl.isAcl = true;
  
        this.declaredAttributes = [this.declaredId, this.declaredVersion, this.declaredAcl];
      }
    })
  });
  
  module.exports = EntityType;
  },{"../binding":16,"../util/Metadata":54,"../util/Permission":56,"./BasicType":35,"./ManagedType":41,"./SingularAttribute":47,"./Type":48}],40:[function(require,module,exports){
  var PluralAttribute = require('./PluralAttribute');
  var collection = require('../collection');
  
  /**
   * @class baqend.metamodel.ListAttribute
   * @extends baqend.metamodel.PluralAttribute
   *
   * @param {String} name
   * @param {baqend.metamodel.Type} elementType
   */
  var ListAttribute = PluralAttribute.inherit(/** @lends baqend.metamodel.ListAttribute.prototype */ {
  
    extend: {
      ref: '/db/collection.List'
    },
  
    collectionType: PluralAttribute.CollectionType.LIST,
  
    constructor: function ListAttribute(name, elementType) {
      PluralAttribute.call(this, name, elementType);
      this.typeConstructor = collection.List;
    },
  
    /**
     * {@inheritDoc}
     * @returns {Object} {@inheritDoc}
     */
    toJSON: function() {
      return {
        name: this.name,
        type: ListAttribute.ref + '[' + this.elementType.ref + ']',
        order: this.order
      };
    }
  });
  
  module.exports = ListAttribute;
  },{"../collection":17,"./PluralAttribute":45}],41:[function(require,module,exports){
  var binding = require('../binding');
  var util = require('../util');
  
  var Type = require('./Type');
  var Permission = require('../util/Permission');
  var Iterator = require('../collection').Iterator;
  var Validator = require('../util/Validator');
  
  /**
   * @class baqend.metamodel.ManagedType
   * @extends baqend.metamodel.Type
   */
  var ManagedType = Type.inherit(/** @lends baqend.metamodel.ManagedType.prototype */ {
  
    /**
     * @class baqend.Metamodel.prototype.AttributeIterator
     * @extends baqend.collection.Iterator
     */
    AttributeIterator: Object.inherit(Iterator, /* @lends baqend.Metamodel.prototype.AttributeIterator.prototype */ {
      index: 0,
  
      constructor: function AttributeIterator(type) {
        this.types = [];
  
        do {
          this.types.push(type);
        } while (type = type.superType);
      },
  
      /**
       * @return {Object} item
       * @return {Boolean} item.done
       * @return {baqend.metamodel.Attribute} item.value
       */
      next: function() {
        var type = this.types.pop();
  
        while (type && type.declaredAttributes.length == this.index) {
          type = this.types.pop();
          this.index = 0;
        }
  
        if (type) {
          this.types.push(type);
          return {done: false, value: type.declaredAttributes[this.index++]};
        } else {
          return Iterator.DONE;
        }
      }
    }),
  
    /**
     * @type baqend.binding.Enhancer
     */
    _enhancer: null,
  
    /**
     * @type {baqend.metamodel.Attribute[]}
     */
    declaredAttributes: null,
  
    /**
     * @type {baqend.metamodel.EntityType}
     */
    superType: null,
  
    /**
     * @type baqend.util.Permission
     */
    loadPermission: null,
  
    /**
     * @type baqend.util.Permission
     */
    schemaAddPermission: null,
  
    /**
     * @type baqend.util.Permission
     */
    schemaReplacePermission: null,
  
    /**
     * @type Function
     * @param {String|Function} code
     */
    set validationCode(code) {
      if(!code) {
        this._validationCode = null;
      } else {
        this._validationCode = Validator.compile(this, code);
      }
    },
  
    /**
     * @type Function
     */
    get validationCode() {
      return this._validationCode;
    },
  
    /**
     * @type Function
     * @private
     */
    _validationCode: null,
  
    /**
     * @type {Function}
     */
    get typeConstructor() {
      if (!this._typeConstructor) {
        this.typeConstructor = this.createProxyClass();
      }
      return this._typeConstructor;
    },
  
    /**
     * @param {Function} typeConstructor
     */
    set typeConstructor(typeConstructor) {
      if (this._typeConstructor) {
        throw new Error("Type constructor has already been set.");
      }
  
      var isEntity = typeConstructor.prototype instanceof binding.Entity;
      if (this.isEntity) {
        if (!isEntity)
          throw new TypeError("Entity classes must extends the Entity class.");
      } else {
        if (!(typeConstructor.prototype instanceof binding.Managed) || isEntity)
          throw new TypeError("Embeddable classes must extends the Managed class.");
      }
  
      this._enhancer.enhance(this, typeConstructor);
      this._typeConstructor = typeConstructor;
    },
  
    /**
     * @param {String} ref or full class name
     * @param {Function} typeConstructor
     */
    constructor: function ManagedType(ref, typeConstructor) {
      Type.call(this, ref.indexOf('/db/') != 0 ? '/db/' + ref : ref, typeConstructor);
      this.declaredAttributes = [];
      this.loadPermission = new Permission();
      this.schemaAddPermission = new Permission();
      this.schemaReplacePermission = new Permission();
    },
  
    /**
     * Initialize this type
     * @param {baqend.binding.Enhancer} enhancer The class enhancer
     * used to enhance and instantiate instance of this managed class
     */
    init: function(enhancer) {
      this._enhancer = enhancer;
  
      if (this._typeConstructor && !this._enhancer.getIdentifier(this._typeConstructor))
        this._enhancer.setIdentifier(this._typeConstructor, this.ref);
    },
  
    /**
     * Creates an ProxyClass for this type
     * @return {Class<baqend.binding.Managed>} the crated proxy class for this type
     * @abstract
     */
    createProxyClass: function() {},
  
    /**
     * Creates an ObjectFactory for this type and the given EntityManager
     * @param {baqend.EntityManager} db The created instances will be attached to this EntityManager
     * @return {baqend.binding.ManagedFactory} the crated object factory for the given EntityManager
     * @abstract
     */
    createObjectFactory: function(db) {},
  
    /**
     * Creates a new instance of the managed type, without invoking any constructors
     * This method is used to create object instances which are loaded form the backend
     * @returns {Object}
     */
    create: function() {
      var instance = Object.create(this.typeConstructor.prototype);
  
      Object.defineProperty(instance, '_metadata', {
        value: new util.Metadata(instance, this),
        writable: false,
        enumerable: false,
        configurable: true
      });
  
      return instance;
    },
  
    /**
     * @return {baqend.metamodel.ManagedType.AttributeIterator}
     */
    attributes: function() {
      return new this.AttributeIterator(this);
    },
  
    /**
     * Adds an attribute to this type
     * @param {baqend.metamodel.Attribute} attr The attribute to add
     * @param {Number=} order Position of the attribute
     */
    addAttribute: function(attr, order) {
      if (this.getAttribute(attr.name))
        throw new Error("An attribute with the name " + attr.name + " is already declared.");
  
      if(attr.order == null) {
        order = typeof order == 'undefined'? this.declaredAttributes.length: order;
      } else {
        order = attr.order;
      }
      attr.init(this, order);
  
      this.declaredAttributes.push(attr);
      if (this._typeConstructor && this.name != 'Object')
        this._enhancer.enhanceProperty(this._typeConstructor, attr);
    },
  
    /**
     * Removes an attribute from this type
     * @param {String} name The Name of the attribute which will be removed
     */
    removeAttribute: function(name) {
      var length = this.declaredAttributes.length;
      this.declaredAttributes = this.declaredAttributes.filter(function(val) {
        return val.name != name;
      });
  
      if (length == this.declaredAttributes.length)
        throw new Error("An Attribute with the name " + name + " is not declared.");
    },
  
    /**
     * @param {!String} name
     * @returns {baqend.metamodel.Attribute}
     */
    getAttribute: function(name) {
      var attr = this.getDeclaredAttribute(name);
  
      if (!attr && this.superType) {
        attr = this.superType.getAttribute(name);
      }
  
      return attr;
    },
  
    /**
     * @param {String|Number} val Name or order of the attribute
     * @returns {baqend.metamodel.Attribute}
     */
    getDeclaredAttribute: function(val) {
      for (var i = 0, attr; attr = this.declaredAttributes[i]; ++i) {
        if (attr.name === val || attr.order === val) {
          return attr;
        }
      }
  
      return null;
    },
  
    /**
     * @inheritDoc
     */
    fromJsonValue: function(state, jsonObject, currentObject) {
      if (jsonObject) {
        for (var iter = this.attributes(), item; !(item = iter.next()).done; ) {
          var attribute = item.value;
          if (!attribute.isMetadata)
            attribute.setJsonValue(state, currentObject, jsonObject[attribute.name]);
        }
      } else {
        currentObject = null;
      }
  
      return currentObject;
    },
  
    /**
     * @inheritDoc
     */
    toJsonValue: function(state, object) {
      var value = null;
  
      if (this.typeConstructor.isInstance(object)) {
        value = {};
        for (var iter = this.attributes(), item; !(item = iter.next()).done; ) {
          var attribute = item.value;
          if (!attribute.isMetadata)
            value[attribute.name] = attribute.getJsonValue(state, object);
        }
      }
  
      return value;
    },
  
    /**
     * Converts ths type schema to json
     * @returns {Object}
     */
    toJSON: function() {
      var json = {};
      json['class'] = this.ref;
  
      if (this.superType)
        json['superClass'] = this.superType.ref;
  
      if (this.isEmbeddable)
        json['embedded'] = true;
  
      json['acl'] = {
        load: this.loadPermission,
        schemaAdd: this.schemaAddPermission,
        schemaReplace: this.schemaReplacePermission
      };
  
      var fields = json['fields'] = {};
      for (var i = 0, attribute; attribute = this.declaredAttributes[i]; i++) {
        if (!attribute.isMetadata)
          fields[attribute.name] = attribute;
      }
  
      return json;
    },
  
    /**
     * Returns iterator to get all referenced entities
     * @return {baqend.metamodel.ManagedType.ReferenceIterator}
     */
    references: function() {
      return new this.ReferenceIterator(this);
    },
  
    ReferenceIterator: Object.inherit({
  
      constructor: function ReferenceIterator(type) {
        this.type = type;
        this.attributes = this.type.attributes();
        this.embedded = [];
      },
  
      /**
       * @return {baqend.metamodel.Attribute}
       */
      next: function() {
        for (var iter = this.attributes, item; !(item = iter.next()).done; ) {
          var attribute = item.value;
          var type = attribute.isCollection ? attribute.elementType : attribute.type;
          if(type.isEntity) {
            return {done: false, value: {path: [attribute.name]}};
          } else if(type.isEmbeddable) {
            for (var emIter = type.references(), emItem; !(emItem = emIter.next()).done; ) {
              this.embedded.push({done: false, value: {path: [attribute.name].concat(emItem.value.path)}});
            }
          }
        }
  
        return this.embedded.length ? this.embedded.pop() : {done: true};
      }
    })
  });
  
  module.exports = ManagedType;
  },{"../binding":16,"../collection":17,"../util":60,"../util/Permission":56,"../util/Validator":59,"./Type":48}],42:[function(require,module,exports){
  var PluralAttribute = require('./PluralAttribute');
  var collection = require('../collection');
  var PersistentError = require('../error/PersistentError');
  
  /**
   * @class baqend.metamodel.MapAttribute
   * @extends baqend.metamodel.PluralAttribute
   */
  var MapAttribute = PluralAttribute.inherit(/** @lends baqend.metamodel.MapAttribute.prototype */ {
  
    extend: {
      ref: '/db/collection.Map'
    },
  
    collectionType: PluralAttribute.CollectionType.MAP,
  
    /**
     * @type baqend.metamodel.Type
     */
    keyType: null,
  
    /**
     * @param {String} name
     * @param {baqend.metamodel.Type} keyType
     * @param {baqend.metamodel.Type} elementType
     */
    constructor: function MapAttribute(name, keyType, elementType) {
      PluralAttribute.call(this, name, elementType);
  
      this.keyType = keyType;
      this.typeConstructor = collection.Map;
    },
  
    /**
     * @inheritDoc
     */
    getJsonValue: function (state, object) {
      var value = this.getValue(object);
  
      if (value) {
        if (!value._metadata) {
          Object.defineProperty(value, '_metadata', {
            value: {_root: state._root}
          });
        }
  
        var json = {};
        for (var iter = value.entries(), item; !(item = iter.next()).done; ) {
          if (item.value[0] === null || item.value[1] === undefined)
            throw new PersistentError('Map keys can\'t be null nor undefined.');
  
          json[this.keyType.toJsonValue(state, item.value[0])] =
            this.elementType.toJsonValue(state, item.value[1]);
        }
  
        return json;
      } else {
        return null;
      }
    },
  
    /**
     * @inheritDoc
     */
    setJsonValue: function (state, obj, json) {
      var value = null;
      if (json) {
        value = this.getValue(obj);
  
        if (!this.typeConstructor.isInstance(value)) {
          value = new this.typeConstructor();
          Object.defineProperty(value, '_metadata', {
            value: {_root: state._root}
          });
        }
  
        var keys = value.array;
        var vals = value.vals;
  
        value.array = [];
        value.vals = [];
  
        for (var key in json) {
          key = this.keyType.fromJsonValue(state, key);
          var index = keys.indexOf(key);
          var val = this.elementType.fromJsonValue(state, json[key], index != -1? vals[index]: null);
  
          value.set(key, val);
        }
      }
  
      this.setValue(obj, value);
    },
  
    /**
     * {@inheritDoc}
     * @returns {Object} {@inheritDoc}
     */
    toJSON: function() {
      return {
        name: this.name,
        type: MapAttribute.ref + '[' + this.keyType.ref + ',' + this.elementType.ref + ']',
        order: this.order
      };
    }
  });
  
  module.exports = MapAttribute;
  },{"../collection":17,"../error/PersistentError":29,"./PluralAttribute":45}],43:[function(require,module,exports){
  var BasicType = require('./BasicType');
  var ManagedType = require('./ManagedType');
  var EntityType = require('./EntityType');
  var Enhancer = require('../binding/Enhancer');
  var ModelBuilder = require('./ModelBuilder');
  var DbIndex = require('./DbIndex');
  var Lockable = require('../util/Lockable');
  var StatusCode = require('../connector/Message').StatusCode;
  
  var message = require('../message');
  
  /**
   * @class baqend.metamodel.Metamodel
   * @extends baqend.util.Lockable
   */
  var Metamodel = Object.inherit(Lockable, /** @lends baqend.metamodel.Metamodel.prototype */ {
  
    /**
     * Defines if the Metamodel has been finalized
     * @type Boolean
     */
    isInitialized: false,
  
    /**
     * @type baqend.connector.Connector
     * @private
     */
    _connector: null,
  
    /**
     * @type Array.<baqend.metamodel.EntityType>
     */
    entities: null,
  
    /**
     * @type Array.<baqend.metamodel.EmbeddableType>
     */
    embeddables: null,
  
    /**
     * @type Array.<baqend.metamodel.BasicType>
     */
    baseTypes: null,
  
    constructor: function Metamodel() {
      this._enhancer = new Enhancer();
    },
  
    /**
     * Connects this instance with the given connector
     * @param {baqend.connector.Connector} connector
     */
    connected: function(connector) {
      this._connector = connector;
    },
  
    /**
     * Prepare the Metamodel for custom schema creation
     * @param {Object=} jsonMetamodel initialize the metamodel with the serialized json schema
     * @return {Promise<*>} A promise which will be resolved, if the metamodel is initialized
     */
    init: function(jsonMetamodel) {
      if (jsonMetamodel) {
        if (this.isInitialized) {
          throw new Error('Metamodel is already initialized.');
        }
  
        this.fromJSON(jsonMetamodel || []);
        this.isInitialized = true;
      } else if (!this.isInitialized) {
        return this.load();
      }
  
      return this.ready();
    },
  
    /**
     * @param {(Function|String)} arg
     * @return {String}
     */
    _getRef: function(arg) {
      var ref;
      if (String.isInstance(arg)) {
        ref = arg;
  
        if (ref.indexOf('/db/') != 0) {
          ref = '/db/' + arg;
        }
      } else {
        ref = this._enhancer.getIdentifier(arg);
      }
  
      return ref;
    },
  
    /**
     * Return the metamodel entity type representing the entity.
     *
     * @param {(Function|String)} typeConstructor - the type of the represented entity
     * @returns {baqend.metamodel.EntityType} the metamodel entity type
     */
    entity: function(typeConstructor) {
      var ref = this._getRef(typeConstructor);
      return ref ? this.entities[ref] : null;
    },
  
    /**
     * Return the metamodel basic type representing the native class.
     * @param {(Function|String)} typeConstructor - the type of the represented native class
     * @returns {baqend.metamodel.BasicType} the metamodel basic type
     */
    baseType: function(typeConstructor) {
      var ref = null;
      if (String.isInstance(typeConstructor)) {
        ref = this._getRef(typeConstructor);
      } else {
        for (var name in this.baseTypes) {
          var type = this.baseTypes[name];
          if (!type.noResolving && type.typeConstructor == typeConstructor) {
            ref = name;
            break;
          }
        }
      }
  
      return ref ? this.baseTypes[ref] : null;
    },
  
    /**
     * Return the metamodel embeddable type representing the embeddable class.
     * @param {(Function|String)} typeConstructor - the type of the represented embeddable class
     * @returns {baqend.metamodel.EmbeddableType} the metamodel embeddable type
     */
    embeddable: function(typeConstructor) {
      var ref = this._getRef(typeConstructor);
      return ref ? this.embeddables[ref] : null;
    },
  
    /**
     * Return the metamodel managed type representing the entity, mapped superclass, or embeddable class.
     *
     * @param {(Function|String)} typeConstructor - the type of the represented managed class
     * @returns {baqend.metamodel.Type} the metamodel managed type
     */
    managedType: function(typeConstructor) {
      return this.baseType(typeConstructor) || this.entity(typeConstructor) || this.embeddable(typeConstructor);
    },
  
    /**
     * @param {baqend.metamodel.Type} type
     * @return the added type
     */
    addType: function(type) {
      var types;
  
      if (type.isBasic) {
        types = this.baseTypes;
      } else if (type.isEmbeddable) {
        type.init(this._enhancer);
        types = this.embeddables;
      } else if (type.isEntity) {
        type.init(this._enhancer);
        types = this.entities;
  
        if (type.superType == null && type.ref != EntityType.Object.ref) {
          type.superType = this.entity(EntityType.Object.ref);
        }
      }
  
      if (types[type.ref]) {
        throw new Error("The type " + type.ref + " is already declared.");
      }
  
      return types[type.ref] = type;
    },
  
    /**
     * Load all schema data from the server
     * @returns {Promise<baqend.metamodel.Metamodel>}
     */
    load: function() {
      if(!this.isInitialized) {
        return this.withLock(function() {
          this.isInitialized = true;
          var msg = new message.GetAllSchemas();
  
          return this._connector.send(msg).then(function(message) {
            this.fromJSON(message.response.entity);
            return this;
          }.bind(this));
        }.bind(this));
      } else {
        throw new Error("Metamodel is already initialized.");
      }
    },
  
    /**
     * Store all local schema data on the server, or the provided one
     *
     * Note: The schema must be initialized, by init or load
     *
     * @param {baqend.metamodel.ManagedType=} managedType The specific type to persist, if omitted the complete schema will be updated
     * @param {String=} token The authorization token to use, otherwise the global credentials will be used
     * @returns {Promise<baqend.metamodel.Metamodel>}
     */
    save: function(managedType, token) {
      if (!ManagedType.isInstance(managedType)) {
        token = managedType;
        managedType = null;
      }
  
      return this._send(managedType || this.toJSON(), token).then(function() {
        return this;
      }.bind(this));
    },
  
    /**
     * The provided options object will be forwarded to the UpdateAllSchemas resource.
     * The underlying schema of this Metamodel object will be replaced by the result.
     *
     * @param {Object} data The JSON which will be send to the UpdateAllSchemas resource.
     * @param {String=} token The authorization token to use, otherwise the global credentials will be used
     * @returns {Promise<baqend.metamodel.Metamodel>}
     */
    update: function(data, token) {
      return this._send(data, token).then(function(message) {
        this.fromJSON(message.response.entity);
        return this;
      }.bind(this))
    },
  
    _send: function(data, token) {
      if (!this.isInitialized)
        throw new Error("Metamodel is not initialized.");
  
      return this.withLock(function() {
        var msg;
        if(ManagedType.isInstance(data)) {
          msg = new message.UpdateSchema(data.name, data.toJSON());
        } else {
          msg = new message.UpdateAllSchemas(data);
        }
  
        msg.withAuthorizationToken(token);
  
        return this._connector.send(msg);
      }.bind(this));
    },
  
    /**
     * Get the current schema types as json
     * @returns {object} the json data
     */
    toJSON: function() {
      var json = [];
  
      for (var ref in this.entities) {
        json.push(this.entities[ref]);
      }
  
      for (ref in this.embeddables) {
        json.push(this.embeddables[ref]);
      }
  
      return json;
    },
  
    /**
     * Replace the current schema by the provided one in json
     * @param json The json schema data
     */
    fromJSON: function(json) {
      var builder = new ModelBuilder();
      var models = builder.buildModels(json);
  
      this.baseTypes = {};
      this.embeddables = {};
      this.entities = {};
  
      for (var ref in models) {
        var type = models[ref];
        this.addType(type);
      }
    },
  
    /**
     * Creates an index
     *
     * @param {String} bucket Name of the Bucket
     * @param {baqend.metamodel.DbIndex} index Will be applied for the given bucket
     * @param {String=} token The authorization token to use, otherwise the global credentials will be used
     * @return {Promise}
     */
    createIndex: function(bucket, index, token) {
      index.drop = false;
      var msg = new message.CreateDropIndex(bucket, index.toJSON());
      msg.withAuthorizationToken(token);
      return this._connector.send(msg);
    },
  
    /**
     * Drops an index
     *
     * @param {String} bucket Name of the Bucket
     * @param {baqend.metamodel.DbIndex} index Will be dropped for the given bucket
     * @param {String=} token The authorization token to use, otherwise the global credentials will be used
     * @return {Promise}
     */
    dropIndex: function(bucket, index, token) {
      index.drop = true;
      var msg = new message.CreateDropIndex(bucket, index.toJSON());
      msg.withAuthorizationToken(token);
      return this._connector.send(msg);
    },
  
    /**
     * Drops all indexes
     *
     * @param bucket Indexes will be dropped for the given bucket
     * @param {String=} token The authorization token to use, otherwise the global credentials will be used
     * @returns {Promise}
     */
    dropAllIndexes: function(bucket, token) {
      var msg = new message.DropAllIndexes(bucket);
      msg.withAuthorizationToken(token);
      return this._connector.send(msg);
    },
  
    /**
     * Loads all indexes for the given bucket
     *
     * @param bucket Current indexes will be loaded for the given bucket
     * @param {String=} token The authorization token to use, otherwise the global credentials will be used
     * @returns {Promise<Array<baqend.metamodel.DbIndex>>}
     */
    getIndexes: function(bucket, token) {
      var msg = new message.ListIndexes(bucket);
      msg.withAuthorizationToken(token);
      return this._connector.send(msg).then(function(data) {
        return data.response.entity.map(function(el) {
          return new DbIndex(el.keys, el.unique);
        });
      }, function(e) {
        if (e.status == StatusCode.BUCKET_NOT_FOUND || e.status == StatusCode.OBJECT_NOT_FOUND) {
          return null;
        } else {
          throw e;
        }
      });
    }
  });
  
  module.exports = Metamodel;
  },{"../binding/Enhancer":8,"../connector/Message":20,"../message":33,"../util/Lockable":53,"./BasicType":35,"./DbIndex":37,"./EntityType":39,"./ManagedType":41,"./ModelBuilder":44}],44:[function(require,module,exports){
  var BasicType = require('./BasicType');
  var EntityType = require('./EntityType');
  var EmbeddableType = require('./EmbeddableType');
  
  var ListAttribute = require('./ListAttribute');
  var MapAttribute = require('./MapAttribute');
  var SetAttribute = require('./SetAttribute');
  var SingularAttribute = require('./SingularAttribute');
  
  var PersistentError = require('../error/PersistentError');
  
  /**
   * @class baqend.metamodel.ModelBuilder
   */
  var ModelBuilder = Object.inherit( /** @lends baqend.metamodel.ModelBuilder.prototype */ {
  
    /**
     * @type Object<string,baqend.metamodel.ManagedType>
     */
    models: null,
  
    /**
     * @type Object<string,Object>
     */
    modelDescriptors: null,
  
    /**
     * @param {baqend.metamodel.Metamodel} metamodel
     */
    constructor: function ModelBuilder() {
      this.models = {};
  
      for (var typeName in BasicType) {
        if (BasicType.hasOwnProperty(typeName)) {
          var basicType = BasicType[typeName];
          if (basicType instanceof BasicType) {
            this.models[basicType.ref] = basicType;
          }
        }
      }
    },
  
    /**
     * @param {String} ref
     * @returns {baqend.metamodel.ManagedType}
     */
    getModel: function (ref) {
      if (ref in this.models) {
        return this.models[ref];
      } else {
        return this.models[ref] = this.buildModel(ref);
      }
    },
  
    /**
     * @param {Object} modelDescriptors
     * @returns {Object<string,baqend.metamodel.ManagedType>}
     */
    buildModels: function (modelDescriptors) {
      this.modelDescriptors = {};
      for (var i = 0, modelDescriptor; modelDescriptor = modelDescriptors[i]; ++i) {
        this.modelDescriptors[modelDescriptor['class']] = modelDescriptor;
      }
  
      for (var ref in this.modelDescriptors) {
        try {
          var model = this.getModel(ref);
          this.buildAttributes(model);
        } catch (e) {
          throw new PersistentError('Can\'t create model for entity class ' + ref, e);
        }
      }
  
      //ensure at least an object entity
      this.getModel(EntityType.Object.ref);
  
      return this.models;
    },
  
    /**
     * @param {String} ref
     * @returns {baqend.metamodel.ManagedType}
     */
    buildModel: function (ref) {
      var modelDescriptor = this.modelDescriptors[ref];
      var type;
      if (ref == EntityType.Object.ref) {
        type = new EntityType.Object();
      } else if (modelDescriptor) {
        if (modelDescriptor.embedded) {
          type = new EmbeddableType(ref)
        } else {
          var superTypeIdentifier = modelDescriptor['superClass'] || EntityType.Object.ref;
          type = new EntityType(ref, this.getModel(superTypeIdentifier));
        }
      } else {
        throw new TypeError('No model available for ' + ref);
      }
  
      if (modelDescriptor) {
        var permissions = modelDescriptor['acl'];
        for (var permission in permissions) {
          type[permission + 'Permission'].fromJSON(permissions[permission]);
        }
      }
  
      return type;
    },
  
    /**
     * @param {baqend.metamodel.EntityType} model
     */
    buildAttributes: function (model) {
      var modelDescriptor = this.modelDescriptors[model.ref];
      var fields = modelDescriptor['fields'];
  
      for (var name in fields) {
        var field = fields[name];
        if (!model.getAttribute(name)) //skip predefined attributes
          model.addAttribute(this.buildAttribute(field.name, field.type), field.order);
      }
  
      if(modelDescriptor.validationCode) {
        model.validationCode = modelDescriptor.validationCode;
      }
    },
  
    /**
     * @param {baqend.metamodel.EntityType} model
     * @param {String} name
     * @param {String} ref
     * @returns {baqend.metamodel.Attribute}
     */
    buildAttribute: function(name, ref) {
      if (ref.indexOf('/db/collection.') == 0) {
        var collectionType = ref.substring(0, ref.indexOf('['));
  
        var elementType = ref.substring(ref.indexOf('[') + 1, ref.indexOf(']')).trim();
        switch (collectionType) {
          case ListAttribute.ref:
            return new ListAttribute(name, this.getModel(elementType));
          case SetAttribute.ref:
            return new SetAttribute(name, this.getModel(elementType));
          case MapAttribute.ref:
            var keyType = elementType.substring(0, elementType.indexOf(',')).trim();
            elementType = elementType.substring(elementType.indexOf(',') + 1).trim();
  
            return new MapAttribute(name, this.getModel(keyType), this.getModel(elementType));
          default:
            throw new TypeError('No collection available for ' + ref);
        }
      } else {
        return new SingularAttribute(name, this.getModel(ref));
      }
    }
  });
  
  module.exports = ModelBuilder;
  },{"../error/PersistentError":29,"./BasicType":35,"./EmbeddableType":38,"./EntityType":39,"./ListAttribute":40,"./MapAttribute":42,"./SetAttribute":46,"./SingularAttribute":47}],45:[function(require,module,exports){
  var Attribute = require('./Attribute');
  
  /**
   * @class baqend.metamodel.PluralAttribute
   * @extends baqend.metamodel.Attribute
   */
  var PluralAttribute = Attribute.inherit(/** @lends baqend.metamodel.PluralAttribute.prototype */{
    /**
     * @lends baqend.metamodel.PluralAttribute
     */
    extend: {
      /**
       * @enum {number}
       */
      CollectionType: {
        COLLECTION: 0,
        LIST: 1,
        MAP: 2,
        SET: 3
      }
    },
  
    /**
     * @type Function
     */
    typeConstructor: null,
  
    persistentAttributeType: Attribute.PersistentAttributeType.ELEMENT_COLLECTION,
  
    /**
     * @type baqend.metamodel.Type
     */
    elementType: null,
  
    /**
     * @param {String} name
     * @param {baqend.metamodel.Type} elementType
     */
    constructor: function PluralAttribute(name, elementType) {
      Attribute.call(this, name);
      this.elementType = elementType;
    },
  
    /**
     * @inheritDoc
     */
    getJsonValue: function (state, object) {
      var value = this.getValue(object);
  
      if (this.typeConstructor.isInstance(value)) {
        // convert normal collections to tracked collections
        if (!value._metadata) {
          Object.defineProperty(value, '_metadata', {
            value: {_root: state._root}
          });
        }
  
        var json = [];
        for (var iter = value.values(), item; !(item = iter.next()).done; ) {
          json.push(this.elementType.toJsonValue(state, item.value));
        }
  
        return json;
      } else {
        return null;
      }
    },
  
    /**
     * @inheritDoc
     */
    setJsonValue: function (state, obj, json) {
      var value = null;
  
      if (json) {
        value = this.getValue(obj);
  
        if (!this.typeConstructor.isInstance(value)) {
          value = new this.typeConstructor();
  
          Object.defineProperty(value, '_metadata', {
            value: {_root: state._root}
          });
        }
  
        var items = value.array;
        value.array = [];
  
        for (var i = 0, len = json.length; i < len; ++i) {
          value.add(this.elementType.fromJsonValue(state, json[i], items[i]));
        }
      }
  
      this.setValue(obj, value);
    }
  });
  
  module.exports = PluralAttribute;
  },{"./Attribute":34}],46:[function(require,module,exports){
  var PluralAttribute = require('./PluralAttribute');
  var collection = require('../collection');
  var SetAttribute;
  
  /**
   * @class baqend.metamodel.SetAttribute
   * @extends baqend.metamodel.PluralAttribute
   */
  var SetAttribute = PluralAttribute.inherit(/** @lends baqend.metamodel.SetAttribute.prototype */ {
  
    extend: {
      ref: '/db/collection.Set'
    },
  
    collectionType: PluralAttribute.CollectionType.SET,
  
    /**
     * @param {String} name
     * @param {baqend.metamodel.Type} elementType
     */
    constructor: function SetAttribute(name, elementType) {
      PluralAttribute.call(this, name, elementType);
  
      this.typeConstructor = collection.Set;
    },
  
    /**
     * {@inheritDoc}
     * @returns {Object} {@inheritDoc}
     */
    toJSON: function() {
      return {
        name: this.name,
        type: SetAttribute.ref + '[' + this.elementType.ref + ']',
        order: this.order
      };
    }
  });
  
  module.exports = SetAttribute;
  },{"../collection":17,"./PluralAttribute":45}],47:[function(require,module,exports){
  var Attribute = require('./Attribute');
  var Type = require('./Type');
  
  /**
   * @class baqend.metamodel.SingularAttribute
   * @extends baqend.metamodel.Attribute
   */
  var SingularAttribute = Attribute.inherit(/** @lends baqend.metamodel.SingularAttribute.prototype */ {
  
    get typeConstructor() {
      return this.type.typeConstructor;
    },
  
    /**
     * @type baqend.metamodel.Type
     */
    type: null,
  
    /**
     * @param {String} name
     * @param {baqend.metamodel.Type} type
     * @param {Boolean=} isMetadata
     */
    constructor: function SingularAttribute(name, type, isMetadata) {
      Attribute.call(this, name, isMetadata);
  
      this.type = type;
  
      switch (type.persistenceType) {
        case Type.PersistenceType.BASIC:
          this.persistentAttributeType = Attribute.PersistentAttributeType.BASIC;
          break;
        case Type.PersistenceType.EMBEDDABLE:
          this.persistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
          break;
        case Type.PersistenceType.ENTITY:
          this.persistentAttributeType = Attribute.PersistentAttributeType.ONE_TO_MANY;
          break;
      }
    },
  
    /**
     * @inheritDoc
     */
    getJsonValue: function(state, object) {
      return this.type.toJsonValue(state, this.getValue(object));
    },
  
    /**
     * @inheritDoc
     */
    setJsonValue: function(state, object, jsonValue) {
      this.setValue(object, this.type.fromJsonValue(state, jsonValue, this.getValue(object)));
    },
  
    /**
     * @inheritDoc
     */
    toJSON: function() {
      return {
        name: this.name,
        type: this.type.ref,
        order: this.order
      }
    }
  });
  
  module.exports = SingularAttribute;
  },{"./Attribute":34,"./Type":48}],48:[function(require,module,exports){
  /**
   * @class baqend.metamodel.Type
   */
  var Type = Object.inherit(/** @lends baqend.metamodel.Type.prototype */ {
    /**
     * @lends baqend.metamodel.Type
     */
    extend: {
      /**
       * @enum {number}
       */
      PersistenceType: {
        BASIC: 0,
        EMBEDDABLE: 1,
        ENTITY: 2,
        MAPPED_SUPERCLASS: 3
      }
    },
  
    /**
     * @type Boolean
     */
    get isBasic() {
      return this.persistenceType == Type.PersistenceType.BASIC;
    },
  
    /**
     * @type Boolean
     */
    get isEmbeddable() {
      return this.persistenceType == Type.PersistenceType.EMBEDDABLE;
    },
  
    /**
     * @type Boolean
     */
    get isEntity() {
      return this.persistenceType == Type.PersistenceType.ENTITY;
    },
  
    /**
     * @type Boolean
     */
    get isMappedSuperclass() {
      return this.persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS;
    },
  
    /**
     * @type Number
     */
    persistenceType: -1,
  
    /**
     * @type Function
     */
    get typeConstructor() {
      return this._typeConstructor;
    },
  
    /**
     * @param {Function} typeConstructor
     */
    set typeConstructor(typeConstructor) {
      if(this._typeConstructor) {
        throw new Error("typeConstructor has already been set.")
      }
      this._typeConstructor = typeConstructor;
    },
  
    /**
     * @type String
     */
    ref: null,
  
    /**
     * @type String
     */
    name: null,
  
    /**
     * @param {String} ref
     * @param {Function} typeConstructor
     */
    constructor: function Type(ref, typeConstructor) {
      if (ref.indexOf("/db/") != 0) {
        throw new SyntaxError("Type ref " + ref + " is invalid.");
      }
  
      this.ref = ref;
      this.name = ref.substring(4);
      this._typeConstructor = typeConstructor;
    },
  
    /**
     * Merge the json data into the current object instance and returns the merged object
     * @param {baqend.util.Metadata} state The root object state
     * @param {Object} jsonValue The json data to merge
     * @param {*=} currentValue The object where the jsonObject will be merged into, if the current object is null,
     *  a new instance will be created
     * @return {*} The merged object instance
     * @abstract
     */
    fromJsonValue: function(state, jsonValue, currentValue) {},
  
    /**
     * Converts the given object to json
     * @param {baqend.util.Metadata} state The root object state
     * @param {*} object The object to convert
     * @return {Object} The converted object as json
     * @abstract
     */
    toJsonValue: function(state, object) {}
  });
  
  module.exports = Type;
  },{}],49:[function(require,module,exports){
  /**
   * @namespace baqend.metamodel
   */
  
  var Metamodel = require('./Metamodel');
  
  exports = module.exports = new Metamodel();
  
  exports.Attribute = require('./Attribute');
  exports.BasicType = require('./BasicType');
  exports.CollectionAttribute = require('./CollectionAttribute');
  exports.EmbeddableType = require('./EmbeddableType');
  exports.EntityType = require('./EntityType');
  exports.ListAttribute = require('./ListAttribute');
  exports.ManagedType = require('./ManagedType');
  exports.MapAttribute = require('./MapAttribute');
  exports.Metamodel = require('./Metamodel');
  exports.ModelBuilder = require('./ModelBuilder');
  exports.PluralAttribute = require('./PluralAttribute');
  exports.SetAttribute = require('./SetAttribute');
  exports.SingularAttribute = require('./SingularAttribute');
  exports.Type = require('./Type');
  exports.DbIndex = require('./DbIndex');
  
  },{"./Attribute":34,"./BasicType":35,"./CollectionAttribute":36,"./DbIndex":37,"./EmbeddableType":38,"./EntityType":39,"./ListAttribute":40,"./ManagedType":41,"./MapAttribute":42,"./Metamodel":43,"./ModelBuilder":44,"./PluralAttribute":45,"./SetAttribute":46,"./SingularAttribute":47,"./Type":48}],50:[function(require,module,exports){
  /******
   * START - BIND POLYFILL
   *****/
  Function.prototype.bind = Function.prototype.bind || function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
  
    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                  ? this
                  : oThis,
              aArgs.concat(Array.prototype.slice.call(arguments)));
        };
  
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
  
    return fBound;
  };
  /******
   * END - BIND POLYFILL
   *****/
  },{}],51:[function(require,module,exports){
  var Permission = require('./Permission');
  
  /**
   * @class baqend.Acl
   *
   * @classdesc Creates a new Acl object, with an empty rule set for an object
   * @param {baqend.util.Metadata} metadata the metadata of the object
   */
  var Acl = Object.inherit(/** @lends baqend.Acl.prototype */ {
  
    /**
     * The read permission of the object
     * @type baqend.util.Permission
     */
    read: null,
  
    /**
     * The write permission of the object
     * @type baqend.util.Permission
     */
    write: null,
  
    constructor: function Acl(metadata) {
      this.read = new Permission(metadata);
      this.write = new Permission(metadata);
    },
  
    /**
     * Removes all acl rules, read and write access is public afterwards
     */
    clear: function() {
      this.read.clear();
      this.write.clear();
    },
  
    /**
     * Gets whenever all users and roles have the permission to read the object
     * @return {boolean} <code>true</code> If public access is allowed
     */
    isPublicReadAllowed: function() {
      return this.read.isPublicAllowed();
    },
  
    /**
     * Sets whenever all users and roles should have the permission to read the object.
     * Note: All other allow read rules will be removed.
     */
    setPublicReadAllowed: function() {
      return this.read.setPublicAllowed();
    },
  
    /**
     * Checks whenever the user or role is explicit allowed to read the object.
     *
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to check for
     */
    isReadAllowed: function(userOrRole) {
      return this.read.isAllowed(userOrRole);
    },
  
    /**
     * Checks whenever the user or role is explicit denied to read the object
     *
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to check for
     */
    isReadDenied: function(userOrRole) {
      return this.read.isDenied(userOrRole);
    },
  
    /**
     * Allows the given user or rule to read the object
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to allow
     * @return {baqend.Acl} this acl object
     */
    allowReadAccess: function(userOrRole) {
      this.read.allowAccess(userOrRole);
      return this;
    },
  
    /**
     * Denies the given user or rule to read the object
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to deny
     * @return {baqend.Acl} this acl object
     */
    denyReadAccess: function(userOrRole) {
      this.read.denyAccess(userOrRole);
      return this;
    },
  
    /**
     * Deletes any read allow/deny rule for the given user or role
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role
     * @return {baqend.Acl} this acl object
     */
    deleteReadAccess: function(userOrRole) {
      this.read.deleteAccess(userOrRole);
      return this;
    },
  
    /**
     * Gets whenever all users and roles have the permission to write the object
     * @return {boolean} <code>true</code> If public access is allowed
     */
    isPublicWriteAllowed: function() {
      return this.write.isPublicAllowed();
    },
  
    /**
     * Sets whenever all users and roles should have the permission to write the object.
     * Note: All other allow write rules will be removed.
     */
    setPublicWriteAllowed: function() {
      return this.write.setPublicAllowed();
    },
  
    /**
     * Checks whenever the user or role is explicit allowed to write the object.
     *
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to check for
     */
    isWriteAllowed: function(userOrRole) {
      return this.write.isAllowed(userOrRole);
    },
  
    /**
     * Checks whenever the user or role is explicit denied to write the object
     *
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to check for
     */
    isWriteDenied: function(userOrRole) {
      return this.write.isDenied(userOrRole);
    },
  
    /**
     * Allows the given user or rule to write the object
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to allow
     * @return {baqend.Acl} this acl object
     */
    allowWriteAccess: function(userOrRole) {
      this.write.allowAccess(userOrRole);
      return this;
    },
  
    /**
     * Denies the given user or rule to write the object
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role to deny
     * @return {baqend.Acl} this acl object
     */
    denyWriteAccess: function(userOrRole) {
      this.write.denyAccess(userOrRole);
      return this;
    },
  
    /**
     * Deletes any write allow/deny rule for the given user or role
     * @param {baqend.binding.User|baqend.binding.Role|String} userOrRole The user or role
     * @return {baqend.Acl} this acl object
     */
    deleteWriteAccess: function(userOrRole) {
      this.write.deleteAccess(userOrRole);
      return this;
    },
  
    /**
     * A Json representation of the set of rules
     * @return {object}
     */
    toJSON: function() {
      return {
        read: this.read,
        write: this.write
      };
    },
  
    /**
     * Sets the acl rules form json
     * @param {object} json The json encoded acls
     */
    fromJSON: function(json) {
      this.read.fromJSON(json.read || {});
      this.write.fromJSON(json.write || {});
    }
  
  });
  
  module.exports = Acl;
  },{"./Permission":56}],52:[function(require,module,exports){
  var message = require('../message');
  var StatusCode = require('../connector/Message').StatusCode;
  
  /**
   * @class baqend.util.Code
   * @param {baqend.metamodel.Metamodel} metamodel
   */
  var Code = Object.inherit(/** @lends baqend.util.Code.prototype */ {
  
    /**
     * @type baqend.connector.Connector
     * @private
     */
    _connector: null,
  
    /**
     * @type baqend.metamodel.Metamodel
     * @private
     */
    _metamodel: null,
  
    constructor: function Code(metamodel) {
      this._metamodel = metamodel;
    },
  
    /**
     * Connects this instance with the given connector
     * @param {baqend.connector.Connector} connector The connector
     */
    connected: function(connector) {
      this._connector = connector;
    },
  
    /**
     * Converts the given function to a string
     * @param {Function} fn The JavaScript function to serialize
     * @return {String} The serialized function
     */
    functionToString: function(fn) {
      if(!fn)
        return "";
  
      var str = fn.toString();
      str = str.substring(str.indexOf("{") + 1, str.lastIndexOf("}"));
      if (str.charAt(0) == '\n')
        str = str.substring(1);
  
      if (str.charAt(str.length - 1) == '\n')
        str = str.substring(0, str.length - 1);
  
      return str;
    },
  
    /**
     * Converts the given string to a module wrapper function
     * @param {Array<String>} signature The expected parameters of the function
     * @param {String} code The JavaScript function to deserialize
     * @return {Function} The deserialized function
     */
    stringToFunction: function(signature, code) {
      return new Function(signature, code);
    },
  
    /**
     * Loads a list of all available baqend modules
     * Does not include handlers
     *
     * @param {String} token to authenticate the user
     * @returns {Promise<Array<String>>}
     */
    loadModules: function(token) {
      var msg = new message.GetAllModules();
      msg.withAuthorizationToken(token);
      return this._connector.send(msg).then(function(data) {
        return data.response.entity;
      });
    },
  
    /**
     * Loads Baqend code which will be identified by the given bucket and code codeType
     *
     * @param {baqend.metamodel.ManagedType|String} type The entity type for the baqend handler or the Name of the
     * Baqend code
     * @param {String} codeType The type of the code
     * @param {String} token to authenticate the user
     * @param {boolean} [asFunction=false] set it to <code>true</code>, to parse the code as a function and return it
     * instead of a string
     * @returns {Promise<Function|String>} The baqend code as string or as a parsed function
     */
    loadCode: function(type, codeType, token, asFunction) {
      var bucket = String.isInstance(type)? type: type.name;
      var msg = new message.GetBaqendCode(bucket, codeType);
      msg.withAuthorizationToken(token);
  
      return this._connector.send(msg).then(function(msg) {
        return this._parseCode(bucket, codeType, asFunction, msg.response.entity);
      }.bind(this), function(e) {
        if (e.status == StatusCode.OBJECT_NOT_FOUND)
          return null;
  
        throw e;
      });
    },
  
    /**
     * Saves Baqend code which will be identified by the given bucket and code type
     *
     * @param {baqend.metamodel.ManagedType|String} type The entity type for the baqend handler or the Name of the
     * Baqend code
     * @param {String} codeType The type of the code
     * @param {String|Function} fn Baqend code as a string or function
     * @param {String} token to authenticate the user
     * @returns {Promise<Function|String>} The stored baqend code as a string or as a parsed function
     */
    saveCode: function(type, codeType, fn, token) {
      var bucket = String.isInstance(type)? type: type.name;
      var asFunction = Function.isInstance(fn);
  
      var msg = new message.SetBaqendCode(bucket, codeType, asFunction? this.functionToString(fn): fn);
      msg.withAuthorizationToken(token);
  
      return this._connector.send(msg).then(function(msg) {
        return this._parseCode(bucket, codeType, asFunction, msg.response.entity);
      }.bind(this));
    },
  
    /**
     * Deletes Baqend code identified by the given bucket and code type
     *
     * @param {baqend.metamodel.ManagedType|String} type The entity type for the baqend handler or the Name of the
     * Baqend code
     * @param {String} codeType The type of the code
     * @param {String} token to authenticate the user
     * @returns {Promise<void>} succeed if the code was deleted
     */
    deleteCode: function(type, codeType, token) {
      var bucket = String.isInstance(type)? type: type.name;
      var msg = new message.DeleteBaqendCode(bucket, codeType);
      msg.withAuthorizationToken(token);
      return this._connector.send(msg).then(function() {
        return this._parseCode(bucket, codeType, false, null);
      }.bind(this));
    },
  
    _parseCode: function(bucket, codeType, asFunction, code) {
      if (codeType == 'validate') {
        var type = this._metamodel.entity(bucket);
        type.validationCode = code;
        return asFunction? type.validationCode: code;
      } else {
        return asFunction? this.stringToFunction(['module', 'exports'], code): code;
      }
    }
  });
  
  module.exports = Code;
  
  },{"../connector/Message":20,"../message":33}],53:[function(require,module,exports){
  /**
   * This mixin provides an lock interface to execute exclusive operations
   *
   * @class baqend.util.Lockable
   */
  var Lockable = Trait.inherit(/** @lends baqend.util.Lockable.prototype */{
  
    /**
     * Indicates if there is currently an onging exclusive operation
     * @type Boolean
     * @private
     */
    _isLocked: false,
  
    /**
     * A promise which represents the state of the least exclusive operation
     * @type Promise
     * @private
     */
    _readyPromise: Promise.resolve(null),
  
    /**
     * A deferred used to explicit lock and unlock this instance
     * @private
     */
    _deferred: null,
  
    /**
     * Indicates if there is currently no exclusive operation executed
     * <code>true</code> If no exclusive lock is hold
     * @type {Boolean}
     */
    get isReady() {
      return !this._isLocked;
    },
  
    /**
     * Waits on the previously requested operation and calls the doneCallback if the operation is fulfilled
     * @param {baqend.util.Lockable~callback=} doneCallback The callback which will be invoked when the previously
     * operations on this object is completed.
     * @param {baqend.util.Lockable~callback=} errorCallback When the lock can't be released caused by a none
     * recoverable error
     * @return {Promise<baqend.util.Lockable>} A promise which completes successfully, when the previously requested
     * operation completes
     */
    ready: function(doneCallback, failCallback) {
      var self = this;
      return this._readyPromise.then(function() {
        return self;
      }, function(e) {
        // the error was critical, the lock wasn't released
        if (self._isLocked)
          throw e;
  
        return self;
      }).then(doneCallback, failCallback);
    },
  
    /**
     * Try to aquire an exclusive lock and executes the given callback.
     * @param {baqend.util.Lockable~callback} callback The exclusive operation to execute
     * @param {Boolean} [critical=false] Indicates if the operation is critical. If the operation is critical and the
     * operation fails, then the lock will not be released
     * @return {Promise<baqend.util.Lockable>} A promise
     * @throws {Error} If the lock can't be aquired
     * @protected
     */
    withLock: function(callback, critical) {
      if(this._isLocked)
        throw new Error('Current operation has not been finished.');
  
      try {
        this._isLocked = true;
        return this._readyPromise = callback().then(function(result) {
          this._isLocked = false;
          return result;
        }.bind(this), function(e) {
          if (!critical)
            this._isLocked = false;
          throw e;
        }.bind(this));
      } catch (e) {
        if (!critical)
          this._isLocked = false;
        throw e;
      }
    }
  });
  
  module.exports = Lockable;
  
  /**
   * The operation callback is used by the {@link baqend.util.Lockable#withLock} method,
   * to perform an exclusive operation on the entity.
   * @callback baqend.util.Lockable~callback
   * @return {Promise<*>} A Promise, which reflects the result of the operation
   */
  },{}],54:[function(require,module,exports){
  //var binding = require('../binding');
  var PersistentError = require('../error/PersistentError');
  var Acl = require('./Acl');
  var Lockable = require('./Lockable');
  
  /**
   * @class baqend.util.Metadata
   */
  var Metadata = Object.inherit(Lockable, /** @lends baqend.util.Metadata.prototype */ {
    /** @lends baqend.util.Metadata */
    extend: {
      /**
       * @enum {number}
       */
      Type: {
        UNAVAILABLE: -1,
        PERSISTENT: 0,
        DIRTY: 1
      },
  
      /**
       * @param {baqend.binding.Entity} entity
       * @return {baqend.util.Metadata}
       */
      get: function(entity) {
        //if (!(entity instanceof binding.Entity))
        //  throw new error.IllegalEntityError(entity);
  
        return entity._metadata;
      },
  
      /**
       * @param {baqend.binding.Entity|baqend.Collection} object
       * @return {baqend.util.Metadata}
       */
      getRoot: function(object) {
        var metadata = object && object._metadata;
  
        if (metadata && metadata._root != object)
          metadata = metadata._root && metadata._root._metadata;
  
        return metadata;
      },
  
      /**
       * @param {baqend.binding.Entity|baqend.Collection} object
       */
      readAccess: function(object) {
        var metadata = Metadata.getRoot(object);
        if (metadata)
          metadata.readAccess();
      },
  
      /**
       * @param {baqend.binding.Entity|baqend.Collection} object
       */
      writeAccess: function(object) {
        var metadata = Metadata.getRoot(object);
        if (metadata)
          metadata.writeAccess();
      }
    },
  
    /**
     * @return {baqend.EntityManager}
     */
    get db() {
      if(this._db)
        return this._db;
  
      return this._db = require('../');
    },
  
    set db(db) {
      if(!this._db) {
        this._db = db;
      } else {
        throw new Error("DB has already been set.")
      }
    },
  
    /**
     * @return {String}
     */
    get bucket() {
      return this.type && this.type.name
    },
  
    /**
     * @return {String}
     */
    get key() {
      if (!this._key && this.id) {
        var index = this.id.lastIndexOf('/');
        this._key = decodeURIComponent(this.id.substring(index + 1));
      }
      return this._key;
    },
  
    /**
     * @return {Boolean}
     */
    get isAttached() {
      return !!this._db;
    },
  
    /**
     * @return {Boolean}
     */
    get isAvailable() {
      return this._state > Metadata.Type.UNAVAILABLE;
    },
  
    /**
     * @return {Boolean}
     */
    get isPersistent() {
      return this._state == Metadata.Type.PERSISTENT;
    },
  
    /**
     * @return {Boolean}
     */
    get isDirty() {
      return this._state == Metadata.Type.DIRTY;
    },
  
    /**
     * @type baqend.binding.Entity
     * @private
     */
    _root: null,
  
    _db: null,
  
    /**
     * @type String
     */
    id: null,
  
    /**
     * @type Number
     */
    version: null,
  
    /**
     * @type baqend.util.Acl
     */
    acl: null,
  
    /**
     * @return {baqend.metamodel.ManagedType}
     */
    type: null,
  
    /**
     * @param {baqend.binding.Entity} entity
     * @param {baqend.binding.ManagedType} type
     */
    constructor: function Metadata(entity, type) {
      this._root = entity;
      this.type = type;
      this._state = Metadata.Type.DIRTY;
      this._enabled = true;
      this.acl = new Acl(this);
    },
  
    readAccess: function() {
      if (this._enabled) {
        if (!this.isAvailable) {
          throw new PersistentError('This object ' + this.bucket + '/' + this.id + ' is not available.');
        }
      }
    },
  
    writeAccess: function() {
      if (this._enabled) {
        if (!this.isAvailable) {
          throw new PersistentError('This object ' + this.bucket + '/' + this.id + ' is not available.');
        }
  
        this.setDirty();
      }
    },
  
    /**
     * Indicates that the associated object isn't available
     */
    setUnavailable: function() {
      this._state = Metadata.Type.UNAVAILABLE;
    },
  
    /**
     * Indicates that the associated object isn't stale, i.e.
     * the object correlate the database state and is not modified by the user
     */
    setPersistent: function() {
      this._state = Metadata.Type.PERSISTENT;
    },
  
    /**
     * Indicates the the object is modified by the user
     */
    setDirty: function() {
      this._state = Metadata.Type.DIRTY;
    },
  
    /**
     * Indicates the the object is removed
     */
    setRemoved: function() {
      this.setDirty();
      this.version = null;
    },
  
    getJsonMetadata: function(excludeVersion) {
      var info = {};
  
      if (this.id) {
        info.id = this.id;
      }
  
      if (!excludeVersion && this.version) {
        info.version = this.version;
      }
  
      info.acl = this.acl;
  
      return info;
    },
  
    /**
     * Sets the object metadata from the object
     * @param {Object} json
     */
    setJsonMetadata: function(json) {
      if (!this.id) {
        this.id = json.id;
      }
  
      if(json.version)
        this.version = json.version;
  
      this.acl.fromJSON(json.acl || {});
    },
  
    /**
     * Converts the object to an JSON-Object
     * @param {Boolean} [excludeVersion=false]
     * @param {Boolean} [excludeMetadata=false]
     * @returns {Object} JSON-Object
     */
    getJson: function(excludeVersion, excludeMetadata) {
      this._enabled = false;
      var json = this.type.toJsonValue(this, this._root, true);
      this._enabled = true;
  
      if (this.isAttached && !excludeMetadata) {
        Object.extend(json, this.getJsonMetadata(excludeVersion));
      }
  
      return json;
    },
  
    setJson: function(json) {
      if (json.id || json.version || json.acl) {
        this.setJsonMetadata(json);
      }
  
      this._enabled = false;
      this.type.fromJsonValue(this, json, this._root, true);
      this._enabled = true;
    }
  });
  
  module.exports = Metadata;
  },{"../":32,"../error/PersistentError":29,"./Acl":51,"./Lockable":53}],55:[function(require,module,exports){
  var message = require('../message');
  
  /**
   * @class baqend.util.Modules
   */
  var Modules = Object.inherit(/** @lends baqend.util.Modules.prototype */ {
  
    /**
     * @type baqend.EntityManager
     * @private
     */
    _entityManager: null,
  
    /**
     * The connector used for baqend requests
     * @type baqend.connector.Connector
     * @private
     */
    _connector: null,
  
    /**
     * @param {baqend.EntityManager} entityManager
     * @param {baqend.connector.Connector} connector
     */
    constructor: function Modules(entityManager, connector) {
      this._entityManager = entityManager;
      this._connector = connector;
    },
  
    /**
     * Calls the baqend module, which is identified by the given bucket.
     * The optional query parameter will be attached as GET-parameters.
     *
     * @param {String} bucket Name of the baqend module
     * @param {Object|String=} query GET-Parameter as key-value-pairs or query string
     * @param {Function=} doneCallback
     * @param {Function=} failCallback
     * @returns {Promise<Object>}
     */
    get: function(bucket, query, doneCallback, failCallback) {
      if(Function.isInstance(query)) {
        failCallback = doneCallback;
        doneCallback = query;
        query = null;
      }
  
      var msg = new message.GetBaqendModule(bucket);
      msg.addQueryString(query);
  
      return this._send(msg, doneCallback, failCallback);
    },
  
    /**
     * Calls the baqend module, which is identified by the given bucket.
     *
     * @param {String} bucket Name of the baqend module
     * @param {Object|String} body Body of the POST-request
     * @param {Function=} doneCallback
     * @param {Function=} failCallback
     * @returns {Promise<Object>}
     */
    post: function(bucket, body, doneCallback, failCallback) {
      var msg = new message.PostBaqendModule(bucket, body);
  
      return this._send(msg, doneCallback, failCallback);
    },
  
    _send: function(msg, doneCallback, failCallback) {
      return this._entityManager._send(msg).then(function(code) {
        return code.response.entity;
      }).then(doneCallback, failCallback);
    }
  });
  
  module.exports = Modules;
  
  },{"../message":33}],56:[function(require,module,exports){
  /**
   * @class baqend.util.Permission
   */
  var Permission = Object.inherit(/** @lends baqend.util.Permission.prototype */ {
  
    /**
     * @type baqend.util.Metadata
     * @private
     */
    _metadata: null,
  
    /**
     * The set of rules
     * @type object
     * @private
     */
    _rules: null,
  
    /**
     * Creates a new Permission object, with an empty rule set
     * @param {baqend.util.Metadata} metadata The metadata of the object
     */
    constructor: function Permission(metadata) {
      this._rules = {};
      this._metadata = metadata;
    },
  
    /**
     * Returns a list of user and role references of all rules
     * @return {String[]} a list of references
     */
    allRules: function() {
      return Object.keys(this._rules);
    },
  
    /**
     * Removes all rules from this permission object
     */
    clear: function() {
      this._metadata && this._metadata.writeAccess();
      this._rules = {};
    },
  
    /**
     * Gets whenever all users and roles have the permission to perform the operation
     * @return {boolean} <code>true</code> If public access is allowed
     */
    isPublicAllowed: function() {
      for (var ref in this._rules) {
        if (this._rules[ref] == 'allow') {
          return false;
        }
      }
  
      return true;
    },
  
    /**
     * Sets whenever all users and roles should have the permission to perform the operation.
     * Note: All other allow rules will be removed.
     */
    setPublicAllowed: function() {
      this._metadata && this._metadata.writeAccess();
      for (var ref in this._rules) {
        if (this._rules[ref] == 'allow') {
          delete this._rules[ref];
        }
      }
    },
  
    /**
     * Returns the actual rule of the given user or role.
     * @param userOrRole The user or role to check for
     * @return {String|undefined} The actual access rule
     */
    getRule: function(userOrRole) {
      return this._rules[this._getRef(userOrRole)];
    },
  
    /**
     * Checks whenever the user or role is explicit allowed to perform the operation.
     *
     * @param userOrRole The user or role to check for
     */
    isAllowed: function(userOrRole) {
      return this._rules[this._getRef(userOrRole)] == 'allow';
    },
  
    /**
     * Checks whenever the user or role is explicit denied to perform the operation.
     *
     * @param userOrRole The user or role to check for
     */
    isDenied: function(userOrRole) {
      return this._rules[this._getRef(userOrRole)] == 'deny';
    },
  
    /**
     * Allows the given user or rule to perform the operation
     * @param userOrRole The user or role to allow
     * @return {baqend.util.Permission} this permission object
     */
    allowAccess: function(userOrRole) {
      this._metadata && this._metadata.writeAccess();
      this._rules[this._getRef(userOrRole)] = 'allow';
      return this;
    },
  
    /**
     * Denies the given user or rule to perform the operation
     * @param userOrRole The user or role to deny
     * @return {baqend.util.Permission} this permission object
     */
    denyAccess: function(userOrRole) {
      this._metadata && this._metadata.writeAccess();
      this._rules[this._getRef(userOrRole)] = 'deny';
      return this;
    },
  
    /**
     * Deletes any allow/deny rule for the given user or role
     * @param userOrRole The user or role
     * @return {baqend.util.Permission} this permission object
     */
    deleteAccess: function(userOrRole) {
      this._metadata && this._metadata.writeAccess();
      delete this._rules[this._getRef(userOrRole)];
      return this;
    },
  
    /**
     * A Json representation of the set of rules
     * @return {object}
     */
    toJSON: function() {
      return this._rules;
    },
  
    /**
     * Sets the permission rules from json
     * @param {object} json The permission json representation
     */
    fromJSON: function(json) {
      this._rules = json;
    },
  
    /**
     * Resolves user and role references and validate given references
     * @param userOrRole The user, role or reference
     * @return {String} The resolved and validated reference
     * @private
     */
    _getRef: function(userOrRole) {
      if (!String.isInstance(userOrRole)) {
        userOrRole = userOrRole._metadata.id;
      }
  
      if (userOrRole.indexOf('/db/User/') == 0 || userOrRole.indexOf('/db/Role/') == 0) {
        return userOrRole;
      }
  
      throw new TypeError('The given object isn\'t a user, role or a valid reference.');
    }
  
  });
  
  module.exports = Permission;
  },{}],57:[function(require,module,exports){
  var Set = require('../collection').Set;
  var List = require('../collection').List;
  var Metadata = require('./Metadata');
  var Entity = require('../binding/Entity');
  
  
  /**
   * @class baqend.util.PushMessage
   */
  var PushMessage = Object.inherit(/** @lends baqend.util.PushMessage.prototype */ {
  
    /**
     * Set of devices
     * @type Set<baqend.binding.Entity>
     */
    devices: null,
  
    /**
     * push notification message
     * @type String
     */
    message: null,
  
    /**
     * push notification subject
     * @type String
     */
    subject: null,
  
    /**
     * push notification sound
     * @type String
     */
    sound: null,
  
    /**
     * badge count
     * @type Number
     */
    badge: 0,
  
    /**
     * data object
     * @type Object
     */
    data: null,
  
    /**
     * Push message will be used to send a push notification to a set of devices
     *
     * @param {Set<baqend.binding.Entity>|List<baqend.binding.Entity>|Array=} devices The Set of device references which
     * will receive this push notification.
     * @param {String=} message The message of the push notification.
     * @param {String=} subject The subject of the push notification.
     * @param {String=} sound The file reference of the sound file as a string. The device uses this file as the
     * notification sound.
     * @param {Number=} badge The badge count.
     * @param {Object=} data The data object which can contain additional information.
     * @constructor
     */
    constructor: function PushMessage(devices, message, subject, sound, badge, data) {
      if(Array.isInstance(devices) || List.isInstance(devices) || !devices) {
        this.devices = new Set(devices);
      } else if(Entity.isInstance(devices)) {
        this.devices = new Set();
        this.devices.add(devices);
      } else if(!Set.isInstance(devices)) {
        throw new Error("Only Sets, Lists and Arrays can be used as devices.")
      }
  
      this.message = message;
      this.subject = subject;
      this.sound = sound;
      this.badge = badge;
      this.data = data;
    },
  
  
    /**
     * Adds a new object to the set of devices
     *
     * @param {baqend.binding.Entity} device will be added to the device set to receive the push notification
     */
    addDevice: function(device) {
      if(!this.devices) {
        this.devices = new Set();
      } else if(Array.isInstance(this.devices)) {
        this.devices = new Set(this.devices);
      }
  
      this.devices.add(device);
    },
  
    toJSON: function() {
      if(Array.isInstance(this.devices) || List.isInstance(this.devices))
        this.devices = new Set(this.devices);
  
      if(!this.devices || !this.devices.size)
        throw new Error("Set of devices is empty.");
  
      return Object.extend(Object.extend({}, this), {
        devices: this.devices.map(function(device) {
          return device.id;
        })
      });
    }
  });
  
  module.exports = PushMessage;
  },{"../binding/Entity":9,"../collection":17,"./Metadata":54}],58:[function(require,module,exports){
  /**
   * @class baqend.util.ValidationResult
   */
  var ValidationResult = Object.inherit(/** @lends baqend.util.ValidationResult.prototype */ {
  
    fields: null,
  
    get isValid() {
      for (var key in this.fields) {
        if(!this.fields[key].isValid) {
          return false;
        }
      }
      return true;
    },
  
    constructor: function ValidationResult() {
      this.fields = {};
    },
  
    toJSON: function() {
      var json = {};
      for(var key in this.fields) {
        json[key] = this.fields[key].toJSON();
      }
      return json;
    }
  });
  
  module.exports = ValidationResult;
  },{}],59:[function(require,module,exports){
  var valLib = require('validator');
  var ValidationResult = require('./ValidationResult');
  
  /**
   * @class baqend.util.Validator
   */
  var Validator = Object.inherit(/** @lends baqend.util.Validator.prototype */ {
  
    extend: {
      initialize: function() {
        Object.keys(valLib).forEach(function(name) {
          if (typeof valLib[name] == 'function' && name !== 'toString' &&
              name !== 'toDate' && name !== 'extend' && name !== 'init') {
  
            this.prototype[name] = function(error) {
              //noinspection JSPotentiallyInvalidUsageOfThis
              return this._callMethod(name, error || name, Array.prototype.slice.call(arguments, error? 1: 0));
            }
  
          }
        }.bind(this));
      },
  
      /**
       * Compiles the given validation code for the managedType
       * @param {baqend.metamodel.ManagedType} managedType The managedType of the code
       * @param {String} validationCode The validation code
       */
      compile: function(managedType, validationCode) {
        var keys = [];
        for (var iter = managedType.attributes(), item; !(item = iter.next()).done; ) {
          keys.push(item.value.name);
        }
  
        var fn = new Function(keys, validationCode);
        return function onValidate(argObj) {
          var args = keys.map(function(name) {
            return argObj[name];
          });
  
          return fn.apply({}, args);
        }
      }
    },
  
    /**
     * Name of the attribute
     * @type String
     */
    key: null,
  
    /**
     * Result of the validation
     * @type Array
     */
    errors: null,
  
    /**
     * Entity to get the value of the attribute
     * @type {baqend.binding.Entity}
     * @private
     */
    _entity: null,
  
    /**
     * Gets the value of the attribute
     * @return {*} Value
     */
    get value() {
      return this._entity[this.key];
    },
  
    /**
     * Checks if the attribute is valid
     * @return {Boolean}
     */
    get isValid() {
      return this.errors.length == 0;
    },
  
    /**
     * Executes the given validation function to validate the value.
     *
     * The value will be passed as the first parameter to the validation function and
     * the library {@link https://github.com/chriso/validator.js} as the second one.
     * If the function returns true the value is valid, otherwise it's invalid.
     *
     * @param {String=} error The error message which will be used if the value is invalid
     * @param {Function} fn will be used to validate the value
     * @returns {baqend.util.Validator}
     */
    is: function(error, fn) {
      if(Function.isInstance(error)) {
        fn = error;
        error = 'is';
      }
      if(fn(this.value, valLib) === false) {
        this.errors.push(error);
      }
      return this;
    },
  
    constructor: function Validator(key, entity) {
      this.key = key;
      this._entity = entity;
      this.errors = [];
    },
  
    _callMethod: function(method, error, args) {
      args = args || [];
      args.unshift(this.value);
      if(valLib[method].apply(this, args) === false) {
        this.errors.push(error);
      }
      return this;
    },
  
    toString: function() {
      return this.value;
    },
  
    toJSON: function() {
      return {
        isValid: this.isValid,
        errors: this.errors
      }
    }
  });
  
  module.exports = Validator;
  },{"./ValidationResult":58,"validator":63}],60:[function(require,module,exports){
  /**
   * @namespace baqend.util
   */
  
  exports.Metadata = require('./Metadata');
  exports.Permission = require('./Permission');
  exports.Acl = require('./Acl');
  exports.Validator = require('./Validator');
  exports.ValidationResult = require('./ValidationResult');
  exports.Code = require('./Code');
  exports.Modules = require('./Modules');
  exports.Lockable = require('./Lockable');
  //exports.uuid = require('./ti-uuid').v4;
  exports.uuid = Ti.Platform.getId();
  
  exports.PushMessage = require('./PushMessage');
  },{"./Acl":51,"./Code":52,"./Lockable":53,"./Metadata":54,"./Modules":55,"./Permission":56,"./PushMessage":57,"./ValidationResult":58,"./Validator":59}],61:[function(require,module,exports){
  (function (global){
  /*! Jahcode v1.1.6 | jahcode.com | Copyright 2011-2014 by Florian Buecklers | MIT license */
  
  (function(global) {
      var fakePrototype = Object.getPrototypeOf({
              constructor : String
          }) == String.prototype;
  
      if (!Function.prototype.extend) {
          /**
           * Extends the target with the properties of props and return target
           * @param {*=} target The target to extends or thisArg, if it is not set
           * @param {Object} props The properties to extend
           * @returns {*} The extended target
           */
          Function.prototype.extend = function(target, props) {
              if (!props) {
                  props = target;
                  target = this;
              }
  
              for (var name in props) {
                  if (props.hasOwnProperty(name)) {
                      target[name] = props[name];
                  }
              }
  
              return target;
          };
      }
  
      Object.extend(Function.prototype, /** @lends Function.prototype */ {
          /**
           * The linearized type hierarchy of this class
           * @type Function[]
           */
          linearizedTypes : [Object],
  
          /**
           * Inherits this constructor and extends it by additional properties and methods. Optional there can be mixined
           * additional Traits
           * @param {Trait...} traits Additional traits to mixin
           * @param {Object} classDescriptor The descriptor of the class properties and methods
           * @returns {Function} The new created child class
           */
          inherit : function() {
              var objectDescriptor = arguments[arguments.length - 1];
              var klass = objectDescriptor.constructor !== Object? objectDescriptor.constructor: function Class(toCast) {
                  if (!(this instanceof klass)) {
                      return klass.asInstance(toCast);
                  }
  
                  if (this.initialize)
                      arguments.length ? this.initialize.apply(this, arguments) : this.initialize();
              };
  
              var proto = Object.createPrototypeChain(klass, this, Array.prototype.slice.call(arguments, 0, arguments.length - 1));
  
              var names = Object.getOwnPropertyNames(objectDescriptor);
              for ( var i = 0; i < names.length; ++i) {
                  var name = names[i];
                  var result = false;
                  if (Object.properties.hasOwnProperty(name)) {
                      result = Object.properties[name](proto, objectDescriptor, name);
                  }
  
                  if (!result) {
                      var d = Object.getOwnPropertyDescriptor(objectDescriptor, name);
  
                      if (d.value) {
                          var val = d.value;
                          if (val instanceof Function) {
                              if (/this\.superCall/.test(val.toString())) {
                                  d.value = Object.createSuperCallWrapper(klass, name, val);
                              }
                          } else if (val && (val.hasOwnProperty('get') || val.hasOwnProperty('value'))) {
                              d = val;
                          }
                      }
  
                      Object.defineProperty(proto, name, d);
                  }
              }
  
              if (klass.initialize) {
                  klass.initialize();
              }
  
              return klass;
          },
  
          /**
           * Indicates if this class is a subclass of the given class or mixin the given trait.
           * @param {Function} cls The parent class or trait to check
           * @returns {boolean} <code>true</code> if this class is a subclass or mixin the trait
           */
          isA: function(cls) {
              return this.prototype instanceof cls || this.linearizedTypes.lastIndexOf(cls) != -1;
          },
  
          /**
           * Indicates if the object is an instance of this class
           * @param obj The object to check for
           * @returns {boolean} <code>true</code> if the object is defined and
           */
          isInstance : function(obj) {
              if (obj === null || obj === void 0)
                  return false;
  
              return Object(obj) instanceof this || classOf(obj).linearizedTypes.lastIndexOf(this) != -1;
          },
  
          /**
           * Checks if the object is an instance of this class and returns the object or try to convert the
           * object to an instance of this class by calling {@link #conv}
           * @param obj The object to check
           * @returns {*} The typed object or null, if the object can't be typed to an instance of this class
           */
          asInstance : function(obj) {
              if (this.isInstance(obj)) {
                  return obj;
              } else {
                  return this.conv(obj);
              }
          },
  
          /**
           * Converts the given value to an instance of this class, or returns null, if the value can't be converted
           * @param {*} value The value to convert
           * @returns {null} The converted value or null
           */
          conv : function() {
              return null;
          }
      });
  
      Object.extend( /** @lends Object **/ {
          properties : {},
          cloneOwnProperties : function(target, src) {
              var names = Object.getOwnPropertyNames(src);
              for ( var i = 0; i < names.length; ++i) {
                  var name = names[i];
                  if (name != '__proto__') {
                      var descr = Object.getOwnPropertyDescriptor(src, name);
  
                      Object.defineProperty(target, name, descr);
                  }
              }
          },
          createPrototypeChain : function(cls, parentClass, traits) {
              var proto = parentClass.prototype;
              var linearizedTypes = parentClass.linearizedTypes.slice();
              var prototypeChain = parentClass.prototypeChain ? parentClass.prototypeChain.slice() : [proto];
  
              for ( var i = 0, trait; trait = traits[i]; ++i) {
                  if (!(trait.prototype instanceof Trait)) {
                      throw new TypeError("Only traits can be mixed in.");
                  }
  
                  var linearizedTraitTypes = trait.linearizedTypes;
                  for ( var j = 0, type; type = linearizedTraitTypes[j]; ++j) {
                      if (linearizedTypes.indexOf(type) == -1 && type != Trait) {
                          proto = Object.create(proto);
                          Object.cloneOwnProperties(proto, type.wrappedPrototype ? type.wrappedPrototype : type.prototype);
  
                          proto.constructor = type;
  
                          linearizedTypes.push(type);
                          prototypeChain.push(proto);
                      }
                  }
              }
  
              proto = Object.create(proto);
              proto.constructor = cls;
  
              linearizedTypes.push(cls);
              prototypeChain.push(proto);
  
              if (fakePrototype) {
                  cls.wrappedPrototype = proto;
                  cls.prototype = Object.create(proto);
              } else {
                  cls.prototype = proto;
              }
  
              cls.linearizedTypes = linearizedTypes;
              cls.prototypeChain = prototypeChain;
  
              return proto;
          },
          createSuperCallWrapper : function(declaringClass, methodName, method) {
              var superCall = function() {
                  var cls = classOf(this);
                  var index = cls.linearizedTypes.lastIndexOf(declaringClass);
                  if (index == -1) {
                      throw new ReferenceError("superCall can't determine any super method");
                  }
  
                  var proto = cls.prototypeChain[index - 1];
  
                  if (methodName != 'initialize' || proto[methodName])
                      return arguments.length ? proto[methodName].apply(this, arguments) : proto[methodName].call(this);
              };
  
              return function() {
                  var current = this.superCall;
                  this.superCall = superCall;
  
                  try {
                      return arguments.length ? method.apply(this, arguments) : method.call(this);
                  } finally {
                      if (current) {
                          this.superCall = current;
                      } else {
                          // made the property invisible again
                          delete this.superCall;
                      }
                  }
              };
          }
      });
  
      Object.extend(Object.properties, {
          initialize : function(proto, objectDescriptor) {
              var init = objectDescriptor.initialize;
              var test = /this\.superCall/.test(init.toString());
              if (proto instanceof Trait) {
                  if (test) {
                      throw new TypeError('Trait constructors can not call super constructors directly.');
                  }
  
                  objectDescriptor.initialize = function() {
                      arguments.length ? this.superCall.apply(this, arguments) : this.superCall.call(this);
                      init.call(this);
                  };
              } else if (!test && classOf(proto) != Object) {
                  objectDescriptor.initialize = function() {
                      this.superCall.call(this);
                      arguments.length ? init.apply(this, arguments) : init.call(this);
                  };
              }
          },
          extend : function(proto, objectDescriptor) {
              Object.extend(proto.constructor, objectDescriptor.extend);
              return true;
          }
      });
  
      /**
       * Returns the constructor of the given object, works for objects and primitive types
       * @param {*} object The constructor to return for
       * @returns {Function} The constructor of the object
       * @global
       */
      var classOf = function(object) {
          if (object === null || object === void 0)
              return object;
  
          return Object.getPrototypeOf(Object(object)).constructor;
      };
  
      /**
       * @mixin Trait
       * @global
       */
      var Trait = Object.inherit({});
  
      /**
       * @extends Trait
       * @mixin Bind
       * @global
       */
      var Bind = Trait.inherit({
          /** @lends Bind */
          extend : {
              initialize : function() {
                  try {
                      Object.defineProperty(this.prototype, 'bind', {
                          get : function() {
                              return this.bind = Bind.create(this);
                          },
                          set : function(val) {
                              Object.defineProperty(this, 'bind', {
                                  value : val
                              });
                          },
                          configurable : true
                      });
  
                      this.Object = Object.inherit({
                          initialize : function(self) {
                              this.self = self;
                          }
                      });
                  } catch (e) {
                      this.Object = Object.inherit({
                          initialize : function(self) {
                              this.self = self;
  
                              var bind = this;
                              Bind.each(self, function(name, method) {
                                  bind[name] = method.bind(bind.self);
                              });
                          }
                      });
                  }
              },
  
              /**
               * Creates a bind proxy for the given object
               * Each method of the given object is reflected on the proxy and
               * bound to the object context
               * @param {*} obj The object which will be bound
               * @returns {Bind} The bound proxy
               */
              create : function(obj) {
                  if (!obj.constructor.Bind) {
                      try {
                          var descr = {};
                          Bind.each(obj, function(name, method) {
                              descr[name] = {
                                  get : function() {
                                      return this[name] = method.bind(this.self);
                                  },
                                  set : function(val) {
                                      Object.defineProperty(this, name, {
                                          value : val
                                      });
                                  },
                                  configurable : true
                              };
                          });
                          obj.constructor.Bind = Bind.Object.inherit(descr);
                      } catch (e) {
                          obj.constructor.Bind = Bind.Object.inherit({});
                      }
                  }
  
                  return new obj.constructor.Bind(obj);
              },
              each : function(obj, callback) {
                  var proto = Object.getPrototypeOf(obj);
  
                  for ( var name in proto) {
                      var method = proto[name];
                      if (name != 'initialize' && name != 'constructor' && method instanceof Function) {
                          callback(name, method);
                      }
                  }
              }
          },
  
          initialize : function() {
              if (!('bind' in this)) {
                  this.bind = Bind.create(this);
              }
          }
  
          /**
           * @type Bind
           * @name Bind.prototype.bind
           */
      });
  
      var nativeClasses = [Boolean, Number, String, Function, RegExp, Error];
      for ( var i = 0, cls; cls = nativeClasses[i]; ++i) {
          cls.conv = cls;
      }
  
      Date.conv = function(object) {
          return new Date(object);
      };
  
      Array.conv = function(object) {
          return Array.prototype.slice.call(object);
      };
  
      Array.prototype.initialize = function() {
          for ( var i = 0; i < arguments.length; ++i) {
              this[i] = arguments[i];
          }
  
          this.length = arguments.length;
      };
  
      Error.prototype.initialize = function(message) {
          var stack = new Error().stack || 'Error';
          stack = stack.substring(stack.indexOf('\n') + 1);
  
          this.stack = message + '\n' + stack;
          this.message = message;
      };
  
      if (TypeError instanceof Error) { // ie8 uses error instances for subtype constructors
          Error.prototype.isInstance = Error.isInstance;
          Error.prototype.asInstance = Error.asInstance;
          Error.prototype.conv = Error.conv;
      }
  
      Object.extend(global, {
          classOf : classOf,
          Trait : Trait,
          Bind : Bind
      });
  })(typeof window != 'undefined' ? window : global);
  }).call(this,require("--global--"))
  },{"--global--":67}],62:[function(require,module,exports){
  (function (global,setTimeout){
  (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(_dereq_,module,exports){
  (function (global){
  'use strict';
  if (typeof global.Promise !== 'function') {
    global.Promise = _dereq_('./index');
  }
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"./index":5}],2:[function(_dereq_,module,exports){
  'use strict';
  
  module.exports = INTERNAL;
  
  function INTERNAL() {}
  },{}],3:[function(_dereq_,module,exports){
  'use strict';
  var Promise = _dereq_('./promise');
  var reject = _dereq_('./reject');
  var resolve = _dereq_('./resolve');
  var INTERNAL = _dereq_('./INTERNAL');
  var handlers = _dereq_('./handlers');
  module.exports = all;
  function all(iterable) {
    if (Object.prototype.toString.call(iterable) !== '[object Array]') {
      return reject(new TypeError('must be an array'));
    }
  
    var len = iterable.length;
    var called = false;
    if (!len) {
      return resolve([]);
    }
  
    var values = new Array(len);
    var resolved = 0;
    var i = -1;
    var promise = new Promise(INTERNAL);
    
    while (++i < len) {
      allResolver(iterable[i], i);
    }
    return promise;
    function allResolver(value, i) {
      resolve(value).then(resolveFromAll, function (error) {
        if (!called) {
          called = true;
          handlers.reject(promise, error);
        }
      });
      function resolveFromAll(outValue) {
        values[i] = outValue;
        if (++resolved === len & !called) {
          called = true;
          handlers.resolve(promise, values);
        }
      }
    }
  }
  },{"./INTERNAL":2,"./handlers":4,"./promise":6,"./reject":9,"./resolve":10}],4:[function(_dereq_,module,exports){
  'use strict';
  var tryCatch = _dereq_('./tryCatch');
  var resolveThenable = _dereq_('./resolveThenable');
  var states = _dereq_('./states');
  
  exports.resolve = function (self, value) {
    var result = tryCatch(getThen, value);
    if (result.status === 'error') {
      return exports.reject(self, result.value);
    }
    var thenable = result.value;
  
    if (thenable) {
      resolveThenable.safely(self, thenable);
    } else {
      self.state = states.FULFILLED;
      self.outcome = value;
      var i = -1;
      var len = self.queue.length;
      while (++i < len) {
        self.queue[i].callFulfilled(value);
      }
    }
    return self;
  };
  exports.reject = function (self, error) {
    self.state = states.REJECTED;
    self.outcome = error;
    var i = -1;
    var len = self.queue.length;
    while (++i < len) {
      self.queue[i].callRejected(error);
    }
    return self;
  };
  
  function getThen(obj) {
    // Make sure we only access the accessor once as required by the spec
    var then = obj && obj.then;
    if (obj && typeof obj === 'object' && typeof then === 'function') {
      return function appyThen() {
        then.apply(obj, arguments);
      };
    }
  }
  
  },{"./resolveThenable":11,"./states":12,"./tryCatch":13}],5:[function(_dereq_,module,exports){
  module.exports = exports = _dereq_('./promise');
  
  exports.resolve = _dereq_('./resolve');
  exports.reject = _dereq_('./reject');
  exports.all = _dereq_('./all');
  exports.race = _dereq_('./race');
  
  },{"./all":3,"./promise":6,"./race":8,"./reject":9,"./resolve":10}],6:[function(_dereq_,module,exports){
  'use strict';
  
  var unwrap = _dereq_('./unwrap');
  var INTERNAL = _dereq_('./INTERNAL');
  var resolveThenable = _dereq_('./resolveThenable');
  var states = _dereq_('./states');
  var QueueItem = _dereq_('./queueItem');
  
  module.exports = Promise;
  function Promise(resolver) {
    if (!(this instanceof Promise)) {
      return new Promise(resolver);
    }
    if (typeof resolver !== 'function') {
      throw new TypeError('resolver must be a function');
    }
    this.state = states.PENDING;
    this.queue = [];
    this.outcome = void 0;
    if (resolver !== INTERNAL) {
      resolveThenable.safely(this, resolver);
    }
  }
  
  Promise.prototype['catch'] = function (onRejected) {
    return this.then(null, onRejected);
  };
  Promise.prototype.then = function (onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function' && this.state === states.FULFILLED ||
      typeof onRejected !== 'function' && this.state === states.REJECTED) {
      return this;
    }
    var promise = new Promise(INTERNAL);
    if (this.state !== states.PENDING) {
      var resolver = this.state === states.FULFILLED ? onFulfilled : onRejected;
      unwrap(promise, resolver, this.outcome);
    } else {
      this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
    }
  
    return promise;
  };
  
  },{"./INTERNAL":2,"./queueItem":7,"./resolveThenable":11,"./states":12,"./unwrap":14}],7:[function(_dereq_,module,exports){
  'use strict';
  var handlers = _dereq_('./handlers');
  var unwrap = _dereq_('./unwrap');
  
  module.exports = QueueItem;
  function QueueItem(promise, onFulfilled, onRejected) {
    this.promise = promise;
    if (typeof onFulfilled === 'function') {
      this.onFulfilled = onFulfilled;
      this.callFulfilled = this.otherCallFulfilled;
    }
    if (typeof onRejected === 'function') {
      this.onRejected = onRejected;
      this.callRejected = this.otherCallRejected;
    }
  }
  QueueItem.prototype.callFulfilled = function (value) {
    handlers.resolve(this.promise, value);
  };
  QueueItem.prototype.otherCallFulfilled = function (value) {
    unwrap(this.promise, this.onFulfilled, value);
  };
  QueueItem.prototype.callRejected = function (value) {
    handlers.reject(this.promise, value);
  };
  QueueItem.prototype.otherCallRejected = function (value) {
    unwrap(this.promise, this.onRejected, value);
  };
  
  },{"./handlers":4,"./unwrap":14}],8:[function(_dereq_,module,exports){
  'use strict';
  var Promise = _dereq_('./promise');
  var reject = _dereq_('./reject');
  var resolve = _dereq_('./resolve');
  var INTERNAL = _dereq_('./INTERNAL');
  var handlers = _dereq_('./handlers');
  module.exports = race;
  function race(iterable) {
    if (Object.prototype.toString.call(iterable) !== '[object Array]') {
      return reject(new TypeError('must be an array'));
    }
  
    var len = iterable.length;
    var called = false;
    if (!len) {
      return resolve([]);
    }
  
    var i = -1;
    var promise = new Promise(INTERNAL);
  
    while (++i < len) {
      resolver(iterable[i]);
    }
    return promise;
    function resolver(value) {
      resolve(value).then(function (response) {
        if (!called) {
          called = true;
          handlers.resolve(promise, response);
        }
      }, function (error) {
        if (!called) {
          called = true;
          handlers.reject(promise, error);
        }
      });
    }
  }
  
  },{"./INTERNAL":2,"./handlers":4,"./promise":6,"./reject":9,"./resolve":10}],9:[function(_dereq_,module,exports){
  'use strict';
  
  var Promise = _dereq_('./promise');
  var INTERNAL = _dereq_('./INTERNAL');
  var handlers = _dereq_('./handlers');
  module.exports = reject;
  
  function reject(reason) {
  	var promise = new Promise(INTERNAL);
  	return handlers.reject(promise, reason);
  }
  },{"./INTERNAL":2,"./handlers":4,"./promise":6}],10:[function(_dereq_,module,exports){
  'use strict';
  
  var Promise = _dereq_('./promise');
  var INTERNAL = _dereq_('./INTERNAL');
  var handlers = _dereq_('./handlers');
  module.exports = resolve;
  
  var FALSE = handlers.resolve(new Promise(INTERNAL), false);
  var NULL = handlers.resolve(new Promise(INTERNAL), null);
  var UNDEFINED = handlers.resolve(new Promise(INTERNAL), void 0);
  var ZERO = handlers.resolve(new Promise(INTERNAL), 0);
  var EMPTYSTRING = handlers.resolve(new Promise(INTERNAL), '');
  
  function resolve(value) {
    if (value) {
      if (value instanceof Promise) {
        return value;
      }
      return handlers.resolve(new Promise(INTERNAL), value);
    }
    var valueType = typeof value;
    switch (valueType) {
      case 'boolean':
        return FALSE;
      case 'undefined':
        return UNDEFINED;
      case 'object':
        return NULL;
      case 'number':
        return ZERO;
      case 'string':
        return EMPTYSTRING;
    }
  }
  },{"./INTERNAL":2,"./handlers":4,"./promise":6}],11:[function(_dereq_,module,exports){
  'use strict';
  var handlers = _dereq_('./handlers');
  var tryCatch = _dereq_('./tryCatch');
  function safelyResolveThenable(self, thenable) {
    // Either fulfill, reject or reject with error
    var called = false;
    function onError(value) {
      if (called) {
        return;
      }
      called = true;
      handlers.reject(self, value);
    }
  
    function onSuccess(value) {
      if (called) {
        return;
      }
      called = true;
      handlers.resolve(self, value);
    }
  
    function tryToUnwrap() {
      thenable(onSuccess, onError);
    }
    
    var result = tryCatch(tryToUnwrap);
    if (result.status === 'error') {
      onError(result.value);
    }
  }
  exports.safely = safelyResolveThenable;
  },{"./handlers":4,"./tryCatch":13}],12:[function(_dereq_,module,exports){
  // Lazy man's symbols for states
  
  exports.REJECTED = ['REJECTED'];
  exports.FULFILLED = ['FULFILLED'];
  exports.PENDING = ['PENDING'];
  
  },{}],13:[function(_dereq_,module,exports){
  'use strict';
  
  module.exports = tryCatch;
  
  function tryCatch(func, value) {
    var out = {};
    try {
      out.value = func(value);
      out.status = 'success';
    } catch (e) {
      out.status = 'error';
      out.value = e;
    }
    return out;
  }
  },{}],14:[function(_dereq_,module,exports){
  'use strict';
  
  var immediate = _dereq_('immediate');
  var handlers = _dereq_('./handlers');
  module.exports = unwrap;
  
  function unwrap(promise, func, value) {
    immediate(function () {
      var returnValue;
      try {
        returnValue = func(value);
      } catch (e) {
        return handlers.reject(promise, e);
      }
      if (returnValue === promise) {
        handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
      } else {
        handlers.resolve(promise, returnValue);
      }
    });
  }
  },{"./handlers":4,"immediate":16}],15:[function(_dereq_,module,exports){
  
  },{}],16:[function(_dereq_,module,exports){
  'use strict';
  var types = [
    _dereq_('./nextTick'),
    _dereq_('./mutation.js'),
    _dereq_('./messageChannel'),
    _dereq_('./stateChange'),
    _dereq_('./timeout')
  ];
  var draining;
  var queue = [];
  //named nextTick for less confusing stack traces
  function nextTick() {
    draining = true;
    var i, oldQueue;
    var len = queue.length;
    while (len) {
      oldQueue = queue;
      queue = [];
      i = -1;
      while (++i < len) {
        oldQueue[i]();
      }
      len = queue.length;
    }
    draining = false;
  }
  var scheduleDrain;
  var i = -1;
  var len = types.length;
  while (++ i < len) {
    if (types[i] && types[i].test && types[i].test()) {
      scheduleDrain = types[i].install(nextTick);
      break;
    }
  }
  module.exports = immediate;
  function immediate(task) {
    if (queue.push(task) === 1 && !draining) {
      scheduleDrain();
    }
  }
  },{"./messageChannel":17,"./mutation.js":18,"./nextTick":15,"./stateChange":19,"./timeout":20}],17:[function(_dereq_,module,exports){
  (function (global){
  'use strict';
  
  exports.test = function () {
    if (global.setImmediate) {
      // we can only get here in IE10
      // which doesn't handel postMessage well
      return false;
    }
    return typeof global.MessageChannel !== 'undefined';
  };
  
  exports.install = function (func) {
    var channel = new global.MessageChannel();
    channel.port1.onmessage = func;
    return function () {
      channel.port2.postMessage(0);
    };
  };
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{}],18:[function(_dereq_,module,exports){
  (function (global){
  'use strict';
  //based off rsvp https://github.com/tildeio/rsvp.js
  //license https://github.com/tildeio/rsvp.js/blob/master/LICENSE
  //https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js
  
  var Mutation = global.MutationObserver || global.WebKitMutationObserver;
  
  exports.test = function () {
    return Mutation;
  };
  
  exports.install = function (handle) {
    var called = 0;
    var observer = new Mutation(handle);
    var element = global.document.createTextNode('');
    observer.observe(element, {
      characterData: true
    });
    return function () {
      element.data = (called = ++called % 2);
    };
  };
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{}],19:[function(_dereq_,module,exports){
  (function (global){
  'use strict';
  
  exports.test = function () {
    return 'document' in global && 'onreadystatechange' in global.document.createElement('script');
  };
  
  exports.install = function (handle) {
    return function () {
  
      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
      var scriptEl = global.document.createElement('script');
      scriptEl.onreadystatechange = function () {
        handle();
  
        scriptEl.onreadystatechange = null;
        scriptEl.parentNode.removeChild(scriptEl);
        scriptEl = null;
      };
      global.document.documentElement.appendChild(scriptEl);
  
      return handle;
    };
  };
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{}],20:[function(_dereq_,module,exports){
  'use strict';
  exports.test = function () {
    return true;
  };
  
  exports.install = function (t) {
    return function () {
      setTimeout(t, 0);
    };
  };
  },{}]},{},[1]);
  
  
  }).call(this,require("--global--"),require("--timers--").setTimeout)
  },{"--global--":67,"--timers--":69}],63:[function(require,module,exports){
  /*!
   * Copyright (c) 2015 Chris O'Hara <cohara87@gmail.com>
   *
   * 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 (name, definition) {
      if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
          module.exports = definition();
      } else if (typeof define === 'function' && typeof define.amd === 'object') {
          define(definition);
      } else {
          this[name] = definition();
      }
  })('validator', function (validator) {
  
      'use strict';
  
      validator = { version: '3.43.0' };
  
      var emailUser = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e])|(\\[\x01-\x09\x0b\x0c\x0d-\x7f])))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))$/i;
  
      var emailUserUtf8 = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))$/i;
  
      var displayName = /^(?:[a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~\.]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(?:[a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~\.]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\s)*<(.+)>$/i;
  
      var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;
  
      var isin = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;
  
      var isbn10Maybe = /^(?:[0-9]{9}X|[0-9]{10})$/
        , isbn13Maybe = /^(?:[0-9]{13})$/;
  
      var ipv4Maybe = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
        , ipv6Block = /^[0-9A-F]{1,4}$/i;
  
      var uuid = {
          '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i
        , '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
        , '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
        , all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
      };
  
      var alpha = /^[A-Z]+$/i
        , alphanumeric = /^[0-9A-Z]+$/i
        , numeric = /^[-+]?[0-9]+$/
        , int = /^(?:[-+]?(?:0|[1-9][0-9]*))$/
        , float = /^(?:[-+]?(?:[0-9]+))?(?:\.[0-9]*)?(?:[eE][\+\-]?(?:[0-9]+))?$/
        , hexadecimal = /^[0-9A-F]+$/i
        , decimal = /^[-+]?[0-9]*(\.[0-9]+)?$/
        , hexcolor = /^#?([0-9A-F]{3}|[0-9A-F]{6})$/i;
  
      var ascii = /^[\x00-\x7F]+$/
        , multibyte = /[^\x00-\x7F]/
        , fullWidth = /[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/
        , halfWidth = /[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;
  
      var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
  
      var base64 = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
  
      var phones = {
        'zh-CN': /^(\+?0?86\-?)?1[345789]\d{9}$/,
        'en-ZA': /^(\+?27|0)\d{9}$/,
        'en-AU': /^(\+?61|0)4\d{8}$/,
        'en-HK': /^(\+?852\-?)?[569]\d{3}\-?\d{4}$/,
        'fr-FR': /^(\+?33|0)[67]\d{8}$/,
        'pt-PT': /^(\+351)?9[1236]\d{7}$/,
        'el-GR': /^(\+30)?((2\d{9})|(69\d{8}))$/,
        'en-GB': /^(\+?44|0)7\d{9}$/,
        'en-US': /^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$/,
        'en-ZM': /^(\+26)?09[567]\d{7}$/,
        'ru-RU': /^(\+?7|8)?9\d{9}$/
      };
  
      validator.extend = function (name, fn) {
          validator[name] = function () {
              var args = Array.prototype.slice.call(arguments);
              args[0] = validator.toString(args[0]);
              return fn.apply(validator, args);
          };
      };
  
      //Right before exporting the validator object, pass each of the builtins
      //through extend() so that their first argument is coerced to a string
      validator.init = function () {
          for (var name in validator) {
              if (typeof validator[name] !== 'function' || name === 'toString' ||
                      name === 'toDate' || name === 'extend' || name === 'init') {
                  continue;
              }
              validator.extend(name, validator[name]);
          }
      };
  
      validator.toString = function (input) {
          if (typeof input === 'object' && input !== null && input.toString) {
              input = input.toString();
          } else if (input === null || typeof input === 'undefined' || (isNaN(input) && !input.length)) {
              input = '';
          } else if (typeof input !== 'string') {
              input += '';
          }
          return input;
      };
  
      validator.toDate = function (date) {
          if (Object.prototype.toString.call(date) === '[object Date]') {
              return date;
          }
          date = Date.parse(date);
          return !isNaN(date) ? new Date(date) : null;
      };
  
      validator.toFloat = function (str) {
          return parseFloat(str);
      };
  
      validator.toInt = function (str, radix) {
          return parseInt(str, radix || 10);
      };
  
      validator.toBoolean = function (str, strict) {
          if (strict) {
              return str === '1' || str === 'true';
          }
          return str !== '0' && str !== 'false' && str !== '';
      };
  
      validator.equals = function (str, comparison) {
          return str === validator.toString(comparison);
      };
  
      validator.contains = function (str, elem) {
          return str.indexOf(validator.toString(elem)) >= 0;
      };
  
      validator.matches = function (str, pattern, modifiers) {
          if (Object.prototype.toString.call(pattern) !== '[object RegExp]') {
              pattern = new RegExp(pattern, modifiers);
          }
          return pattern.test(str);
      };
  
      var default_email_options = {
          allow_display_name: false,
          allow_utf8_local_part: true,
          require_tld: true
      };
  
      validator.isEmail = function (str, options) {
          options = merge(options, default_email_options);
  
          if (options.allow_display_name) {
              var display_email = str.match(displayName);
              if (display_email) {
                  str = display_email[1];
              }
          } else if (/\s/.test(str)) {
              return false;
          }
  
          var parts = str.split('@')
            , domain = parts.pop()
            , user = parts.join('@');
  
          var lower_domain = domain.toLowerCase();
          if (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com') {
              user = user.replace(/\./g, '').toLowerCase();
          }
  
          if (!validator.isFQDN(domain, {require_tld: options.require_tld})) {
              return false;
          }
  
          return options.allow_utf8_local_part ?
              emailUserUtf8.test(user) :
              emailUser.test(user);
      };
  
      var default_url_options = {
          protocols: [ 'http', 'https', 'ftp' ]
        , require_tld: true
        , require_protocol: false
        , require_valid_protocol: true
        , allow_underscores: false
        , allow_trailing_dot: false
        , allow_protocol_relative_urls: false
      };
  
      validator.isURL = function (url, options) {
          if (!url || url.length >= 2083 || /\s/.test(url)) {
              return false;
          }
          if (url.indexOf('mailto:') === 0) {
              return false;
          }
          options = merge(options, default_url_options);
          var protocol, auth, host, hostname, port,
              port_str, split;
          split = url.split('://');
          if (split.length > 1) {
              protocol = split.shift();
              if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
                  return false;
              }
          } else if (options.require_protocol) {
              return false;
          }  else if (options.allow_protocol_relative_urls && url.substr(0, 2) === '//') {
              split[0] = url.substr(2);
          }
          url = split.join('://');
          split = url.split('#');
          url = split.shift();
  
          split = url.split('?');
          url = split.shift();
  
          split = url.split('/');
          url = split.shift();
          split = url.split('@');
          if (split.length > 1) {
              auth = split.shift();
              if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
                  return false;
              }
          }
          hostname = split.join('@');
          split = hostname.split(':');
          host = split.shift();
          if (split.length) {
              port_str = split.join(':');
              port = parseInt(port_str, 10);
              if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
                  return false;
              }
          }
          if (!validator.isIP(host) && !validator.isFQDN(host, options) &&
                  host !== 'localhost') {
              return false;
          }
          if (options.host_whitelist &&
                  options.host_whitelist.indexOf(host) === -1) {
              return false;
          }
          if (options.host_blacklist &&
                  options.host_blacklist.indexOf(host) !== -1) {
              return false;
          }
          return true;
      };
  
      validator.isIP = function (str, version) {
          version = validator.toString(version);
          if (!version) {
              return validator.isIP(str, 4) || validator.isIP(str, 6);
          } else if (version === '4') {
              if (!ipv4Maybe.test(str)) {
                  return false;
              }
              var parts = str.split('.').sort(function (a, b) {
                  return a - b;
              });
              return parts[3] <= 255;
          } else if (version === '6') {
              var blocks = str.split(':');
              var foundOmissionBlock = false; // marker to indicate ::
  
              // At least some OS accept the last 32 bits of an IPv6 address
              // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says
              // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses,
              // and '::a.b.c.d' is deprecated, but also valid.
              var foundIPv4TransitionBlock = validator.isIP(blocks[blocks.length - 1], 4);
              var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8;
  
              if (blocks.length > expectedNumberOfBlocks)
                  return false;
  
              // initial or final ::
              if (str === '::') {
                  return true;
              } else if (str.substr(0, 2) === '::') {
                  blocks.shift();
                  blocks.shift();
                  foundOmissionBlock = true;
              } else if (str.substr(str.length - 2) === '::') {
                  blocks.pop();
                  blocks.pop();
                  foundOmissionBlock = true;
              }
  
              for (var i = 0; i < blocks.length; ++i) {
                  // test for a :: which can not be at the string start/end
                  // since those cases have been handled above
                  if (blocks[i] === '' && i > 0 && i < blocks.length -1) {
                      if (foundOmissionBlock)
                          return false; // multiple :: in address
                      foundOmissionBlock = true;
                  } else if (foundIPv4TransitionBlock && i == blocks.length - 1) {
                      // it has been checked before that the last
                      // block is a valid IPv4 address
                  } else if (!ipv6Block.test(blocks[i])) {
                      return false;
                  }
              }
  
              if (foundOmissionBlock) {
                  return blocks.length >= 1;
              } else {
                  return blocks.length === expectedNumberOfBlocks;
              }
          }
          return false;
      };
  
      var default_fqdn_options = {
          require_tld: true
        , allow_underscores: false
        , allow_trailing_dot: false
      };
  
      validator.isFQDN = function (str, options) {
          options = merge(options, default_fqdn_options);
  
          /* Remove the optional trailing dot before checking validity */
          if (options.allow_trailing_dot && str[str.length - 1] === '.') {
              str = str.substring(0, str.length - 1);
          }
          var parts = str.split('.');
          if (options.require_tld) {
              var tld = parts.pop();
              if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) {
                  return false;
              }
          }
          for (var part, i = 0; i < parts.length; i++) {
              part = parts[i];
              if (options.allow_underscores) {
                  if (part.indexOf('__') >= 0) {
                      return false;
                  }
                  part = part.replace(/_/g, '');
              }
              if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) {
                  return false;
              }
              if (part[0] === '-' || part[part.length - 1] === '-' ||
                      part.indexOf('---') >= 0) {
                  return false;
              }
          }
          return true;
      };
  
      validator.isBoolean = function(str) {
          return (['true', 'false', '1', '0'].indexOf(str) >= 0);
      };
  
      validator.isAlpha = function (str) {
          return alpha.test(str);
      };
  
      validator.isAlphanumeric = function (str) {
          return alphanumeric.test(str);
      };
  
      validator.isNumeric = function (str) {
          return numeric.test(str);
      };
      
      validator.isDecimal = function (str) {
          return decimal.test(str);
      };
  
      validator.isHexadecimal = function (str) {
          return hexadecimal.test(str);
      };
  
      validator.isHexColor = function (str) {
          return hexcolor.test(str);
      };
  
      validator.isLowercase = function (str) {
          return str === str.toLowerCase();
      };
  
      validator.isUppercase = function (str) {
          return str === str.toUpperCase();
      };
  
      validator.isInt = function (str, options) {
          options = options || {};
          return int.test(str) && (!options.hasOwnProperty('min') || str >= options.min) && (!options.hasOwnProperty('max') || str <= options.max);
      };
  
      validator.isFloat = function (str, options) {
          options = options || {};
          return str !== '' && float.test(str) && (!options.hasOwnProperty('min') || str >= options.min) && (!options.hasOwnProperty('max') || str <= options.max);
      };
  
      validator.isDivisibleBy = function (str, num) {
          return validator.toFloat(str) % validator.toInt(num) === 0;
      };
  
      validator.isNull = function (str) {
          return str.length === 0;
      };
  
      validator.isLength = function (str, min, max) {
          var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
          var len = str.length - surrogatePairs.length;
          return len >= min && (typeof max === 'undefined' || len <= max);
      };
  
      validator.isByteLength = function (str, min, max) {
          return str.length >= min && (typeof max === 'undefined' || str.length <= max);
      };
  
      validator.isUUID = function (str, version) {
          var pattern = uuid[version ? version : 'all'];
          return pattern && pattern.test(str);
      };
  
      validator.isDate = function (str) {
          return !isNaN(Date.parse(str));
      };
  
      validator.isAfter = function (str, date) {
          var comparison = validator.toDate(date || new Date())
            , original = validator.toDate(str);
          return !!(original && comparison && original > comparison);
      };
  
      validator.isBefore = function (str, date) {
          var comparison = validator.toDate(date || new Date())
            , original = validator.toDate(str);
          return original && comparison && original < comparison;
      };
  
      validator.isIn = function (str, options) {
          var i;
          if (Object.prototype.toString.call(options) === '[object Array]') {
              var array = [];
              for (i in options) {
                  array[i] = validator.toString(options[i]);
              }
              return array.indexOf(str) >= 0;
          } else if (typeof options === 'object') {
              return options.hasOwnProperty(str);
          } else if (options && typeof options.indexOf === 'function') {
              return options.indexOf(str) >= 0;
          }
          return false;
      };
  
      validator.isCreditCard = function (str) {
          var sanitized = str.replace(/[^0-9]+/g, '');
          if (!creditCard.test(sanitized)) {
              return false;
          }
          var sum = 0, digit, tmpNum, shouldDouble;
          for (var i = sanitized.length - 1; i >= 0; i--) {
              digit = sanitized.substring(i, (i + 1));
              tmpNum = parseInt(digit, 10);
              if (shouldDouble) {
                  tmpNum *= 2;
                  if (tmpNum >= 10) {
                      sum += ((tmpNum % 10) + 1);
                  } else {
                      sum += tmpNum;
                  }
              } else {
                  sum += tmpNum;
              }
              shouldDouble = !shouldDouble;
          }
          return !!((sum % 10) === 0 ? sanitized : false);
      };
  
      validator.isISIN = function (str) {
          if (!isin.test(str)) {
              return false;
          }
  
          var checksumStr = str.replace(/[A-Z]/g, function(character) {
              return parseInt(character, 36);
          });
  
          var sum = 0, digit, tmpNum, shouldDouble = true;
          for (var i = checksumStr.length - 2; i >= 0; i--) {
              digit = checksumStr.substring(i, (i + 1));
              tmpNum = parseInt(digit, 10);
              if (shouldDouble) {
                  tmpNum *= 2;
                  if (tmpNum >= 10) {
                      sum += tmpNum + 1;
                  } else {
                      sum += tmpNum;
                  }
              } else {
                  sum += tmpNum;
              }
              shouldDouble = !shouldDouble;
          }
  
          return parseInt(str.substr(str.length - 1), 10) === (10000 - sum) % 10;
      };
  
      validator.isISBN = function (str, version) {
          version = validator.toString(version);
          if (!version) {
              return validator.isISBN(str, 10) || validator.isISBN(str, 13);
          }
          var sanitized = str.replace(/[\s-]+/g, '')
            , checksum = 0, i;
          if (version === '10') {
              if (!isbn10Maybe.test(sanitized)) {
                  return false;
              }
              for (i = 0; i < 9; i++) {
                  checksum += (i + 1) * sanitized.charAt(i);
              }
              if (sanitized.charAt(9) === 'X') {
                  checksum += 10 * 10;
              } else {
                  checksum += 10 * sanitized.charAt(9);
              }
              if ((checksum % 11) === 0) {
                  return !!sanitized;
              }
          } else  if (version === '13') {
              if (!isbn13Maybe.test(sanitized)) {
                  return false;
              }
              var factor = [ 1, 3 ];
              for (i = 0; i < 12; i++) {
                  checksum += factor[i % 2] * sanitized.charAt(i);
              }
              if (sanitized.charAt(12) - ((10 - (checksum % 10)) % 10) === 0) {
                  return !!sanitized;
              }
          }
          return false;
      };
  
      validator.isMobilePhone = function(str, locale) {
          if (locale in phones) {
              return phones[locale].test(str);
          }
          return false;
      };
  
      var default_currency_options = {
          symbol: '$'
        , require_symbol: false
        , allow_space_after_symbol: false
        , symbol_after_digits: false
        , allow_negatives: true
        , parens_for_negatives: false
        , negative_sign_before_digits: false
        , negative_sign_after_digits: false
        , allow_negative_sign_placeholder: false
        , thousands_separator: ','
        , decimal_separator: '.'
        , allow_space_after_digits: false
      };
  
      validator.isCurrency = function (str, options) {
          options = merge(options, default_currency_options);
  
          return currencyRegex(options).test(str);
      };
  
      validator.isJSON = function (str) {
          try {
              var obj = JSON.parse(str);
              return !!obj && typeof obj === 'object';
          } catch (e) {}
          return false;
      };
  
      validator.isMultibyte = function (str) {
          return multibyte.test(str);
      };
  
      validator.isAscii = function (str) {
          return ascii.test(str);
      };
  
      validator.isFullWidth = function (str) {
          return fullWidth.test(str);
      };
  
      validator.isHalfWidth = function (str) {
          return halfWidth.test(str);
      };
  
      validator.isVariableWidth = function (str) {
          return fullWidth.test(str) && halfWidth.test(str);
      };
  
      validator.isSurrogatePair = function (str) {
          return surrogatePair.test(str);
      };
  
      validator.isBase64 = function (str) {
          return base64.test(str);
      };
  
      validator.isMongoId = function (str) {
          return validator.isHexadecimal(str) && str.length === 24;
      };
  
      validator.ltrim = function (str, chars) {
          var pattern = chars ? new RegExp('^[' + chars + ']+', 'g') : /^\s+/g;
          return str.replace(pattern, '');
      };
  
      validator.rtrim = function (str, chars) {
          var pattern = chars ? new RegExp('[' + chars + ']+$', 'g') : /\s+$/g;
          return str.replace(pattern, '');
      };
  
      validator.trim = function (str, chars) {
          var pattern = chars ? new RegExp('^[' + chars + ']+|[' + chars + ']+$', 'g') : /^\s+|\s+$/g;
          return str.replace(pattern, '');
      };
  
      validator.escape = function (str) {
          return (str.replace(/&/g, '&amp;')
              .replace(/"/g, '&quot;')
              .replace(/'/g, '&#x27;')
              .replace(/</g, '&lt;')
              .replace(/>/g, '&gt;')
              .replace(/\//g, '&#x2F;')
              .replace(/\`/g, '&#96;'));
      };
  
      validator.stripLow = function (str, keep_new_lines) {
          var chars = keep_new_lines ? '\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F' : '\\x00-\\x1F\\x7F';
          return validator.blacklist(str, chars);
      };
  
      validator.whitelist = function (str, chars) {
          return str.replace(new RegExp('[^' + chars + ']+', 'g'), '');
      };
  
      validator.blacklist = function (str, chars) {
          return str.replace(new RegExp('[' + chars + ']+', 'g'), '');
      };
  
      var default_normalize_email_options = {
          lowercase: true
      };
  
      validator.normalizeEmail = function (email, options) {
          options = merge(options, default_normalize_email_options);
          if (!validator.isEmail(email)) {
              return false;
          }
          var parts = email.split('@', 2);
          parts[1] = parts[1].toLowerCase();
          if (parts[1] === 'gmail.com' || parts[1] === 'googlemail.com') {
              parts[0] = parts[0].toLowerCase().replace(/\./g, '');
              if (parts[0][0] === '+') {
                  return false;
              }
              parts[0] = parts[0].split('+')[0];
              parts[1] = 'gmail.com';
          } else if (options.lowercase) {
              parts[0] = parts[0].toLowerCase();
          }
          return parts.join('@');
      };
  
      function merge(obj, defaults) {
          obj = obj || {};
          for (var key in defaults) {
              if (typeof obj[key] === 'undefined') {
                  obj[key] = defaults[key];
              }
          }
          return obj;
      }
  
      function currencyRegex(options) {
          var symbol = '(\\' + options.symbol.replace(/\./g, '\\.') + ')' + (options.require_symbol ? '' : '?')
              , negative = '-?'
              , whole_dollar_amount_without_sep = '[1-9]\\d*'
              , whole_dollar_amount_with_sep = '[1-9]\\d{0,2}(\\' + options.thousands_separator + '\\d{3})*'
              , valid_whole_dollar_amounts = ['0', whole_dollar_amount_without_sep, whole_dollar_amount_with_sep]
              , whole_dollar_amount = '(' + valid_whole_dollar_amounts.join('|') + ')?'
              , decimal_amount = '(\\' + options.decimal_separator + '\\d{2})?';
          var pattern = whole_dollar_amount + decimal_amount;
          // default is negative sign before symbol, but there are two other options (besides parens)
          if (options.allow_negatives && !options.parens_for_negatives) {
              if (options.negative_sign_after_digits) {
                  pattern += negative;
              }
              else if (options.negative_sign_before_digits) {
                  pattern = negative + pattern;
              }
          }
          // South African Rand, for example, uses R 123 (space) and R-123 (no space)
          if (options.allow_negative_sign_placeholder) {
              pattern = '( (?!\\-))?' + pattern;
          }
          else if (options.allow_space_after_symbol) {
              pattern = ' ?' + pattern;
          }
          else if (options.allow_space_after_digits) {
              pattern += '( (?!$))?';
          }
          if (options.symbol_after_digits) {
              pattern += symbol;
          } else {
              pattern = symbol + pattern;
          }
          if (options.allow_negatives) {
              if (options.parens_for_negatives) {
                  pattern = '(\\(' + pattern + '\\)|' + pattern + ')';
              }
              else if (!(options.negative_sign_before_digits || options.negative_sign_after_digits)) {
                  pattern = negative + pattern;
              }
          }
          return new RegExp(
              '^' +
              // ensure there's a dollar and/or decimal amount, and that it doesn't start with a space or a negative sign followed by a space
              '(?!-? )(?=.*\\d)' +
              pattern +
              '$'
          );
      }
  
      validator.init();
  
      return validator;
  
  });
  
  },{}],64:[function(require,module,exports){
  var _global = (function() { return this; })();
  var nativeWebSocket = _global.WebSocket || _global.MozWebSocket;
  var websocket_version = require('./version');
  
  
  /**
   * Expose a W3C WebSocket class with just one or two arguments.
   */
  function W3CWebSocket(uri, protocols) {
  	var native_instance;
  
  	if (protocols) {
  		native_instance = new nativeWebSocket(uri, protocols);
  	}
  	else {
  		native_instance = new nativeWebSocket(uri);
  	}
  
  	/**
  	 * 'native_instance' is an instance of nativeWebSocket (the browser's WebSocket
  	 * class). Since it is an Object it will be returned as it is when creating an
  	 * instance of W3CWebSocket via 'new W3CWebSocket()'.
  	 *
  	 * ECMAScript 5: http://bclary.com/2004/11/07/#a-13.2.2
  	 */
  	return native_instance;
  }
  
  
  /**
   * Module exports.
   */
  module.exports = {
      'w3cwebsocket' : nativeWebSocket ? W3CWebSocket : null,
      'version'      : websocket_version
  };
  
  },{"./version":65}],65:[function(require,module,exports){
  module.exports = require('../package.json').version;
  
  },{"../package.json":66}],66:[function(require,module,exports){
  module.exports={
    "_args": [
      [
        "websocket@^1.0.18",
        "/Users/fuerst/Documents/APPC_WORKSPACE/TiBaqend"
      ]
    ],
    "_from": "websocket@>=1.0.18 <2.0.0",
    "_id": "websocket@1.0.22",
    "_inCache": true,
    "_installable": true,
    "_location": "/websocket",
    "_nodeVersion": "3.3.1",
    "_npmUser": {
      "email": "brian@worlize.com",
      "name": "theturtle32"
    },
    "_npmVersion": "2.14.3",
    "_phantomChildren": {},
    "_requested": {
      "name": "websocket",
      "raw": "websocket@^1.0.18",
      "rawSpec": "^1.0.18",
      "scope": null,
      "spec": ">=1.0.18 <2.0.0",
      "type": "range"
    },
    "_requiredBy": [
      "/"
    ],
    "_resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.22.tgz",
    "_shasum": "8c33e3449f879aaf518297c9744cebf812b9e3d8",
    "_shrinkwrap": null,
    "_spec": "websocket@^1.0.18",
    "_where": "/Users/fuerst/Documents/APPC_WORKSPACE/TiBaqend",
    "author": {
      "email": "brian@worlize.com",
      "name": "Brian McKelvey",
      "url": "https://www.worlize.com/"
    },
    "browser": "lib/browser.js",
    "bugs": {
      "url": "https://github.com/theturtle32/WebSocket-Node/issues"
    },
    "config": {
      "verbose": false
    },
    "contributors": [
      {
        "name": "Iñaki Baz Castillo",
        "email": "ibc@aliax.net",
        "url": "http://dev.sipdoc.net"
      }
    ],
    "dependencies": {
      "debug": "~2.2.0",
      "nan": "~2.0.5",
      "typedarray-to-buffer": "~3.0.3",
      "yaeti": "~0.0.4"
    },
    "description": "Websocket Client & Server Library implementing the WebSocket protocol as specified in RFC 6455.",
    "devDependencies": {
      "buffer-equal": "^0.0.1",
      "faucet": "^0.0.1",
      "gulp": "git+https://github.com/gulpjs/gulp.git#4.0",
      "gulp-jshint": "^1.11.2",
      "jshint-stylish": "^1.0.2",
      "tape": "^4.0.1"
    },
    "directories": {
      "lib": "./lib"
    },
    "dist": {
      "shasum": "8c33e3449f879aaf518297c9744cebf812b9e3d8",
      "tarball": "http://registry.npmjs.org/websocket/-/websocket-1.0.22.tgz"
    },
    "engines": {
      "node": ">=0.8.0"
    },
    "gitHead": "19108bbfd7d94a5cd02dbff3495eafee9e901ca4",
    "homepage": "https://github.com/theturtle32/WebSocket-Node",
    "keywords": [
      "RFC-6455",
      "client",
      "comet",
      "networking",
      "push",
      "realtime",
      "server",
      "socket",
      "websocket",
      "websockets"
    ],
    "license": "Apache-2.0",
    "main": "index",
    "maintainers": [
      {
        "name": "theturtle32",
        "email": "brian@worlize.com"
      }
    ],
    "name": "websocket",
    "optionalDependencies": {},
    "readme": "ERROR: No README data found!",
    "repository": {
      "type": "git",
      "url": "git+https://github.com/theturtle32/WebSocket-Node.git"
    },
    "scripts": {
      "gulp": "gulp",
      "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)",
      "test": "faucet test/unit"
    },
    "version": "1.0.22"
  }
  
  },{}],67:[function(require,module,exports){
  
  module.exports = (function () { return this; })();
  
  module.exports.location = {};
  
  },{}],68:[function(require,module,exports){
  (function (setTimeout){
  /* global Ti:true, Titanium:true */
  
  var process = module.exports = {};
  
  process.nextTick = function nextTick(fn) {
    setTimeout(fn, 0);
  };
  
  process.title = 'titanium';
  process.titanium = true;
  process.env = {};
  process.argv = [];
  
  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.stdout = {};
  process.stderr = {};
  
  process.stdout.write = function (msg) {
    Ti.API.info(msg);
  };
  
  process.stderr.write = function (msg) {
    Ti.API.error(msg);
  };
  
  'addEventListener removeEventListener removeListener hasEventListener fireEvent emit on off'.split(' ').forEach(function (name) {
    process[ name ] = noop;
  });
  
  function noop() {}
  
  }).call(this,require("--timers--").setTimeout)
  },{"--timers--":69}],69:[function(require,module,exports){
  (function (global){
  
  module.exports.clearInterval = clearInterval;
  module.exports.clearTimeout = clearTimeout;
  module.exports.setInterval = setInterval;
  module.exports.setTimeout = setTimeout;
  
  // See https://html.spec.whatwg.org/multipage/webappapis.html#dom-windowtimers-cleartimeout
  
  function clearInterval(intervalId) {
    try {
      return global.clearInterval(intervalId);
    }
    catch (e) {
      // Do nothing
      return undefined;
    }
  }
  
  function clearTimeout(timeoutId) {
    try {
      return global.clearTimeout(timeoutId);
    }
    catch (e) {
      // Do nothing
      return undefined;
    }
  }
  
  function setInterval(func, delay) {
    var args = [];
    for (var i = 2, l = arguments.length; i < l; ++i) {
      args[ i - 2 ] = arguments[ i ];
    }
  
    return global.setInterval(function () {
      func.apply(this, args);
    }, +delay);
  }
  
  function setTimeout(func, delay) {
    var args = [];
    for (var i = 2, l = arguments.length; i < l; ++i) {
      args[ i - 2 ] = arguments[ i ];
    }
  
    return global.setTimeout(function () {
      func.apply(this, args);
    }, +delay);
  }
  
  }).call(this,require("--global--"))
  },{"--global--":67}],70:[function(require,module,exports){
  // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
  //
  // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
  //
  // Originally from narwhal.js (http://narwhaljs.org)
  // Copyright (c) 2009 Thomas Robinson <280north.com>
  //
  // 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 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.
  
  // when used in node, this will actually load the util module we depend on
  // versus loading the builtin util module as happens otherwise
  // this is a bug in node module loading as far as I am concerned
  var util = require('util/');
  
  var pSlice = Array.prototype.slice;
  var hasOwn = Object.prototype.hasOwnProperty;
  
  // 1. The assert module provides functions that throw
  // AssertionError's when particular conditions are not met. The
  // assert module must conform to the following interface.
  
  var assert = module.exports = ok;
  
  // 2. The AssertionError is defined in assert.
  // new assert.AssertionError({ message: message,
  //                             actual: actual,
  //                             expected: expected })
  
  assert.AssertionError = function AssertionError(options) {
    this.name = 'AssertionError';
    this.actual = options.actual;
    this.expected = options.expected;
    this.operator = options.operator;
    if (options.message) {
      this.message = options.message;
      this.generatedMessage = false;
    } else {
      this.message = getMessage(this);
      this.generatedMessage = true;
    }
    var stackStartFunction = options.stackStartFunction || fail;
  
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, stackStartFunction);
    }
    else {
      // non v8 browsers so we can have a stacktrace
      var err = new Error();
      if (err.stack) {
        var out = err.stack;
  
        // try to strip useless frames
        var fn_name = stackStartFunction.name;
        var idx = out.indexOf('\n' + fn_name);
        if (idx >= 0) {
          // once we have located the function frame
          // we need to strip out everything before it (and its line)
          var next_line = out.indexOf('\n', idx + 1);
          out = out.substring(next_line + 1);
        }
  
        this.stack = out;
      }
    }
  };
  
  // assert.AssertionError instanceof Error
  util.inherits(assert.AssertionError, Error);
  
  function replacer(key, value) {
    if (util.isUndefined(value)) {
      return '' + value;
    }
    if (util.isNumber(value) && !isFinite(value)) {
      return value.toString();
    }
    if (util.isFunction(value) || util.isRegExp(value)) {
      return value.toString();
    }
    return value;
  }
  
  function truncate(s, n) {
    if (util.isString(s)) {
      return s.length < n ? s : s.slice(0, n);
    } else {
      return s;
    }
  }
  
  function getMessage(self) {
    return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
           self.operator + ' ' +
           truncate(JSON.stringify(self.expected, replacer), 128);
  }
  
  // At present only the three keys mentioned above are used and
  // understood by the spec. Implementations or sub modules can pass
  // other keys to the AssertionError's constructor - they will be
  // ignored.
  
  // 3. All of the following functions must throw an AssertionError
  // when a corresponding condition is not met, with a message that
  // may be undefined if not provided.  All assertion methods provide
  // both the actual and expected values to the assertion error for
  // display purposes.
  
  function fail(actual, expected, message, operator, stackStartFunction) {
    throw new assert.AssertionError({
      message: message,
      actual: actual,
      expected: expected,
      operator: operator,
      stackStartFunction: stackStartFunction
    });
  }
  
  // EXTENSION! allows for well behaved errors defined elsewhere.
  assert.fail = fail;
  
  // 4. Pure assertion tests whether a value is truthy, as determined
  // by !!guard.
  // assert.ok(guard, message_opt);
  // This statement is equivalent to assert.equal(true, !!guard,
  // message_opt);. To test strictly for the value true, use
  // assert.strictEqual(true, guard, message_opt);.
  
  function ok(value, message) {
    if (!value) fail(value, true, message, '==', assert.ok);
  }
  assert.ok = ok;
  
  // 5. The equality assertion tests shallow, coercive equality with
  // ==.
  // assert.equal(actual, expected, message_opt);
  
  assert.equal = function equal(actual, expected, message) {
    if (actual != expected) fail(actual, expected, message, '==', assert.equal);
  };
  
  // 6. The non-equality assertion tests for whether two objects are not equal
  // with != assert.notEqual(actual, expected, message_opt);
  
  assert.notEqual = function notEqual(actual, expected, message) {
    if (actual == expected) {
      fail(actual, expected, message, '!=', assert.notEqual);
    }
  };
  
  // 7. The equivalence assertion tests a deep equality relation.
  // assert.deepEqual(actual, expected, message_opt);
  
  assert.deepEqual = function deepEqual(actual, expected, message) {
    if (!_deepEqual(actual, expected)) {
      fail(actual, expected, message, 'deepEqual', assert.deepEqual);
    }
  };
  
  function _deepEqual(actual, expected) {
    // 7.1. All identical values are equivalent, as determined by ===.
    if (actual === expected) {
      return true;
  
    } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
      if (actual.length != expected.length) return false;
  
      for (var i = 0; i < actual.length; i++) {
        if (actual[i] !== expected[i]) return false;
      }
  
      return true;
  
    // 7.2. If the expected value is a Date object, the actual value is
    // equivalent if it is also a Date object that refers to the same time.
    } else if (util.isDate(actual) && util.isDate(expected)) {
      return actual.getTime() === expected.getTime();
  
    // 7.3 If the expected value is a RegExp object, the actual value is
    // equivalent if it is also a RegExp object with the same source and
    // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
    } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
      return actual.source === expected.source &&
             actual.global === expected.global &&
             actual.multiline === expected.multiline &&
             actual.lastIndex === expected.lastIndex &&
             actual.ignoreCase === expected.ignoreCase;
  
    // 7.4. Other pairs that do not both pass typeof value == 'object',
    // equivalence is determined by ==.
    } else if (!util.isObject(actual) && !util.isObject(expected)) {
      return actual == expected;
  
    // 7.5 For all other Object pairs, including Array objects, equivalence is
    // determined by having the same number of owned properties (as verified
    // with Object.prototype.hasOwnProperty.call), the same set of keys
    // (although not necessarily the same order), equivalent values for every
    // corresponding key, and an identical 'prototype' property. Note: this
    // accounts for both named and indexed properties on Arrays.
    } else {
      return objEquiv(actual, expected);
    }
  }
  
  function isArguments(object) {
    return Object.prototype.toString.call(object) == '[object Arguments]';
  }
  
  function objEquiv(a, b) {
    if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
      return false;
    // an identical 'prototype' property.
    if (a.prototype !== b.prototype) return false;
    // if one is a primitive, the other must be same
    if (util.isPrimitive(a) || util.isPrimitive(b)) {
      return a === b;
    }
    var aIsArgs = isArguments(a),
        bIsArgs = isArguments(b);
    if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
      return false;
    if (aIsArgs) {
      a = pSlice.call(a);
      b = pSlice.call(b);
      return _deepEqual(a, b);
    }
    var ka = objectKeys(a),
        kb = objectKeys(b),
        key, i;
    // having the same number of owned properties (keys incorporates
    // hasOwnProperty)
    if (ka.length != kb.length)
      return false;
    //the same set of keys (although not necessarily the same order),
    ka.sort();
    kb.sort();
    //~~~cheap key test
    for (i = ka.length - 1; i >= 0; i--) {
      if (ka[i] != kb[i])
        return false;
    }
    //equivalent values for every corresponding key, and
    //~~~possibly expensive deep test
    for (i = ka.length - 1; i >= 0; i--) {
      key = ka[i];
      if (!_deepEqual(a[key], b[key])) return false;
    }
    return true;
  }
  
  // 8. The non-equivalence assertion tests for any deep inequality.
  // assert.notDeepEqual(actual, expected, message_opt);
  
  assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
    if (_deepEqual(actual, expected)) {
      fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
    }
  };
  
  // 9. The strict equality assertion tests strict equality, as determined by ===.
  // assert.strictEqual(actual, expected, message_opt);
  
  assert.strictEqual = function strictEqual(actual, expected, message) {
    if (actual !== expected) {
      fail(actual, expected, message, '===', assert.strictEqual);
    }
  };
  
  // 10. The strict non-equality assertion tests for strict inequality, as
  // determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
  
  assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
    if (actual === expected) {
      fail(actual, expected, message, '!==', assert.notStrictEqual);
    }
  };
  
  function expectedException(actual, expected) {
    if (!actual || !expected) {
      return false;
    }
  
    if (Object.prototype.toString.call(expected) == '[object RegExp]') {
      return expected.test(actual);
    } else if (actual instanceof expected) {
      return true;
    } else if (expected.call({}, actual) === true) {
      return true;
    }
  
    return false;
  }
  
  function _throws(shouldThrow, block, expected, message) {
    var actual;
  
    if (util.isString(expected)) {
      message = expected;
      expected = null;
    }
  
    try {
      block();
    } catch (e) {
      actual = e;
    }
  
    message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
              (message ? ' ' + message : '.');
  
    if (shouldThrow && !actual) {
      fail(actual, expected, 'Missing expected exception' + message);
    }
  
    if (!shouldThrow && expectedException(actual, expected)) {
      fail(actual, expected, 'Got unwanted exception' + message);
    }
  
    if ((shouldThrow && actual && expected &&
        !expectedException(actual, expected)) || (!shouldThrow && actual)) {
      throw actual;
    }
  }
  
  // 11. Expected to throw an error:
  // assert.throws(block, Error_opt, message_opt);
  
  assert.throws = function(block, /*optional*/error, /*optional*/message) {
    _throws.apply(this, [true].concat(pSlice.call(arguments)));
  };
  
  // EXTENSION! This is annoying to write outside this module.
  assert.doesNotThrow = function(block, /*optional*/message) {
    _throws.apply(this, [false].concat(pSlice.call(arguments)));
  };
  
  assert.ifError = function(err) { if (err) {throw err;}};
  
  var objectKeys = Object.keys || function (obj) {
    var keys = [];
    for (var key in obj) {
      if (hasOwn.call(obj, key)) keys.push(key);
    }
    return keys;
  };
  
  },{"util/":113}],71:[function(require,module,exports){
  var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  
  ;(function (exports) {
  	'use strict';
  
    var Arr = (typeof Uint8Array !== 'undefined')
      ? Uint8Array
      : Array
  
  	var PLUS   = '+'.charCodeAt(0)
  	var SLASH  = '/'.charCodeAt(0)
  	var NUMBER = '0'.charCodeAt(0)
  	var LOWER  = 'a'.charCodeAt(0)
  	var UPPER  = 'A'.charCodeAt(0)
  	var PLUS_URL_SAFE = '-'.charCodeAt(0)
  	var SLASH_URL_SAFE = '_'.charCodeAt(0)
  
  	function decode (elt) {
  		var code = elt.charCodeAt(0)
  		if (code === PLUS ||
  		    code === PLUS_URL_SAFE)
  			return 62 // '+'
  		if (code === SLASH ||
  		    code === SLASH_URL_SAFE)
  			return 63 // '/'
  		if (code < NUMBER)
  			return -1 //no match
  		if (code < NUMBER + 10)
  			return code - NUMBER + 26 + 26
  		if (code < UPPER + 26)
  			return code - UPPER
  		if (code < LOWER + 26)
  			return code - LOWER + 26
  	}
  
  	function b64ToByteArray (b64) {
  		var i, j, l, tmp, placeHolders, arr
  
  		if (b64.length % 4 > 0) {
  			throw new Error('Invalid string. Length must be a multiple of 4')
  		}
  
  		// the number of equal signs (place holders)
  		// if there are two placeholders, than the two characters before it
  		// represent one byte
  		// if there is only one, then the three characters before it represent 2 bytes
  		// this is just a cheap hack to not do indexOf twice
  		var len = b64.length
  		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
  
  		// base64 is 4/3 + up to two characters of the original data
  		arr = new Arr(b64.length * 3 / 4 - placeHolders)
  
  		// if there are placeholders, only get up to the last complete 4 chars
  		l = placeHolders > 0 ? b64.length - 4 : b64.length
  
  		var L = 0
  
  		function push (v) {
  			arr[L++] = v
  		}
  
  		for (i = 0, j = 0; i < l; i += 4, j += 3) {
  			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
  			push((tmp & 0xFF0000) >> 16)
  			push((tmp & 0xFF00) >> 8)
  			push(tmp & 0xFF)
  		}
  
  		if (placeHolders === 2) {
  			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
  			push(tmp & 0xFF)
  		} else if (placeHolders === 1) {
  			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
  			push((tmp >> 8) & 0xFF)
  			push(tmp & 0xFF)
  		}
  
  		return arr
  	}
  
  	function uint8ToBase64 (uint8) {
  		var i,
  			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
  			output = "",
  			temp, length
  
  		function encode (num) {
  			return lookup.charAt(num)
  		}
  
  		function tripletToBase64 (num) {
  			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
  		}
  
  		// go through the array every three bytes, we'll deal with trailing stuff later
  		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
  			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
  			output += tripletToBase64(temp)
  		}
  
  		// pad the end with zeros, but make sure to not forget the extra bytes
  		switch (extraBytes) {
  			case 1:
  				temp = uint8[uint8.length - 1]
  				output += encode(temp >> 2)
  				output += encode((temp << 4) & 0x3F)
  				output += '=='
  				break
  			case 2:
  				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
  				output += encode(temp >> 10)
  				output += encode((temp >> 4) & 0x3F)
  				output += encode((temp << 2) & 0x3F)
  				output += '='
  				break
  		}
  
  		return output
  	}
  
  	exports.toByteArray = b64ToByteArray
  	exports.fromByteArray = uint8ToBase64
  }(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
  
  },{}],72:[function(require,module,exports){
  (function (global,console){
  /*!
   * The buffer module from node.js, for the browser.
   *
   * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
   * @license  MIT
   */
  /* eslint-disable no-proto */
  
  var base64 = require('base64-js')
  var ieee754 = require('ieee754')
  var isArray = require('is-array')
  
  exports.Buffer = Buffer
  exports.SlowBuffer = SlowBuffer
  exports.INSPECT_MAX_BYTES = 50
  Buffer.poolSize = 8192 // not used by this implementation
  
  var rootParent = {}
  
  /**
   * If `Buffer.TYPED_ARRAY_SUPPORT`:
   *   === true    Use Uint8Array implementation (fastest)
   *   === false   Use Object implementation (most compatible, even IE6)
   *
   * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
   * Opera 11.6+, iOS 4.2+.
   *
   * Due to various browser bugs, sometimes the Object implementation will be used even
   * when the browser supports typed arrays.
   *
   * Note:
   *
   *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
   *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
   *
   *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
   *     on objects.
   *
   *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
   *
   *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
   *     incorrect length in some situations.
  
   * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
   * get the Object implementation, which is slower but behaves correctly.
   */
  Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
    ? global.TYPED_ARRAY_SUPPORT
    : typedArraySupport()
  
  function typedArraySupport () {
    function Bar () {}
    try {
      var arr = new Uint8Array(1)
      arr.foo = function () { return 42 }
      arr.constructor = Bar
      return arr.foo() === 42 && // typed array instances can be augmented
          arr.constructor === Bar && // constructor can be set
          typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
          arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
    } catch (e) {
      return false
    }
  }
  
  function kMaxLength () {
    return Buffer.TYPED_ARRAY_SUPPORT
      ? 0x7fffffff
      : 0x3fffffff
  }
  
  /**
   * Class: Buffer
   * =============
   *
   * The Buffer constructor returns instances of `Uint8Array` that are augmented
   * with function properties for all the node `Buffer` API functions. We use
   * `Uint8Array` so that square bracket notation works as expected -- it returns
   * a single octet.
   *
   * By augmenting the instances, we can avoid modifying the `Uint8Array`
   * prototype.
   */
  function Buffer (arg) {
    if (!(this instanceof Buffer)) {
      // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
      if (arguments.length > 1) return new Buffer(arg, arguments[1])
      return new Buffer(arg)
    }
  
    this.length = 0
    this.parent = undefined
  
    // Common case.
    if (typeof arg === 'number') {
      return fromNumber(this, arg)
    }
  
    // Slightly less common case.
    if (typeof arg === 'string') {
      return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
    }
  
    // Unusual.
    return fromObject(this, arg)
  }
  
  function fromNumber (that, length) {
    that = allocate(that, length < 0 ? 0 : checked(length) | 0)
    if (!Buffer.TYPED_ARRAY_SUPPORT) {
      for (var i = 0; i < length; i++) {
        that[i] = 0
      }
    }
    return that
  }
  
  function fromString (that, string, encoding) {
    if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
  
    // Assumption: byteLength() return value is always < kMaxLength.
    var length = byteLength(string, encoding) | 0
    that = allocate(that, length)
  
    that.write(string, encoding)
    return that
  }
  
  function fromObject (that, object) {
    if (Buffer.isBuffer(object)) return fromBuffer(that, object)
  
    if (isArray(object)) return fromArray(that, object)
  
    if (object == null) {
      throw new TypeError('must start with number, buffer, array or string')
    }
  
    if (typeof ArrayBuffer !== 'undefined') {
      if (object.buffer instanceof ArrayBuffer) {
        return fromTypedArray(that, object)
      }
      if (object instanceof ArrayBuffer) {
        return fromArrayBuffer(that, object)
      }
    }
  
    if (object.length) return fromArrayLike(that, object)
  
    return fromJsonObject(that, object)
  }
  
  function fromBuffer (that, buffer) {
    var length = checked(buffer.length) | 0
    that = allocate(that, length)
    buffer.copy(that, 0, 0, length)
    return that
  }
  
  function fromArray (that, array) {
    var length = checked(array.length) | 0
    that = allocate(that, length)
    for (var i = 0; i < length; i += 1) {
      that[i] = array[i] & 255
    }
    return that
  }
  
  // Duplicate of fromArray() to keep fromArray() monomorphic.
  function fromTypedArray (that, array) {
    var length = checked(array.length) | 0
    that = allocate(that, length)
    // Truncating the elements is probably not what people expect from typed
    // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
    // of the old Buffer constructor.
    for (var i = 0; i < length; i += 1) {
      that[i] = array[i] & 255
    }
    return that
  }
  
  function fromArrayBuffer (that, array) {
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      // Return an augmented `Uint8Array` instance, for best performance
      array.byteLength
      that = Buffer._augment(new Uint8Array(array))
    } else {
      // Fallback: Return an object instance of the Buffer class
      that = fromTypedArray(that, new Uint8Array(array))
    }
    return that
  }
  
  function fromArrayLike (that, array) {
    var length = checked(array.length) | 0
    that = allocate(that, length)
    for (var i = 0; i < length; i += 1) {
      that[i] = array[i] & 255
    }
    return that
  }
  
  // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
  // Returns a zero-length buffer for inputs that don't conform to the spec.
  function fromJsonObject (that, object) {
    var array
    var length = 0
  
    if (object.type === 'Buffer' && isArray(object.data)) {
      array = object.data
      length = checked(array.length) | 0
    }
    that = allocate(that, length)
  
    for (var i = 0; i < length; i += 1) {
      that[i] = array[i] & 255
    }
    return that
  }
  
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    Buffer.prototype.__proto__ = Uint8Array.prototype
    Buffer.__proto__ = Uint8Array
  }
  
  function allocate (that, length) {
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      // Return an augmented `Uint8Array` instance, for best performance
      that = Buffer._augment(new Uint8Array(length))
      that.__proto__ = Buffer.prototype
    } else {
      // Fallback: Return an object instance of the Buffer class
      that.length = length
      that._isBuffer = true
    }
  
    var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
    if (fromPool) that.parent = rootParent
  
    return that
  }
  
  function checked (length) {
    // Note: cannot use `length < kMaxLength` here because that fails when
    // length is NaN (which is otherwise coerced to zero.)
    if (length >= kMaxLength()) {
      throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                           'size: 0x' + kMaxLength().toString(16) + ' bytes')
    }
    return length | 0
  }
  
  function SlowBuffer (subject, encoding) {
    if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
  
    var buf = new Buffer(subject, encoding)
    delete buf.parent
    return buf
  }
  
  Buffer.isBuffer = function isBuffer (b) {
    return !!(b != null && b._isBuffer)
  }
  
  Buffer.compare = function compare (a, b) {
    if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
      throw new TypeError('Arguments must be Buffers')
    }
  
    if (a === b) return 0
  
    var x = a.length
    var y = b.length
  
    var i = 0
    var len = Math.min(x, y)
    while (i < len) {
      if (a[i] !== b[i]) break
  
      ++i
    }
  
    if (i !== len) {
      x = a[i]
      y = b[i]
    }
  
    if (x < y) return -1
    if (y < x) return 1
    return 0
  }
  
  Buffer.isEncoding = function isEncoding (encoding) {
    switch (String(encoding).toLowerCase()) {
      case 'hex':
      case 'utf8':
      case 'utf-8':
      case 'ascii':
      case 'binary':
      case 'base64':
      case 'raw':
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return true
      default:
        return false
    }
  }
  
  Buffer.concat = function concat (list, length) {
    if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
  
    if (list.length === 0) {
      return new Buffer(0)
    }
  
    var i
    if (length === undefined) {
      length = 0
      for (i = 0; i < list.length; i++) {
        length += list[i].length
      }
    }
  
    var buf = new Buffer(length)
    var pos = 0
    for (i = 0; i < list.length; i++) {
      var item = list[i]
      item.copy(buf, pos)
      pos += item.length
    }
    return buf
  }
  
  function byteLength (string, encoding) {
    if (typeof string !== 'string') string = '' + string
  
    var len = string.length
    if (len === 0) return 0
  
    // Use a for loop to avoid recursion
    var loweredCase = false
    for (;;) {
      switch (encoding) {
        case 'ascii':
        case 'binary':
        // Deprecated
        case 'raw':
        case 'raws':
          return len
        case 'utf8':
        case 'utf-8':
          return utf8ToBytes(string).length
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return len * 2
        case 'hex':
          return len >>> 1
        case 'base64':
          return base64ToBytes(string).length
        default:
          if (loweredCase) return utf8ToBytes(string).length // assume utf8
          encoding = ('' + encoding).toLowerCase()
          loweredCase = true
      }
    }
  }
  Buffer.byteLength = byteLength
  
  // pre-set for values that may exist in the future
  Buffer.prototype.length = undefined
  Buffer.prototype.parent = undefined
  
  function slowToString (encoding, start, end) {
    var loweredCase = false
  
    start = start | 0
    end = end === undefined || end === Infinity ? this.length : end | 0
  
    if (!encoding) encoding = 'utf8'
    if (start < 0) start = 0
    if (end > this.length) end = this.length
    if (end <= start) return ''
  
    while (true) {
      switch (encoding) {
        case 'hex':
          return hexSlice(this, start, end)
  
        case 'utf8':
        case 'utf-8':
          return utf8Slice(this, start, end)
  
        case 'ascii':
          return asciiSlice(this, start, end)
  
        case 'binary':
          return binarySlice(this, start, end)
  
        case 'base64':
          return base64Slice(this, start, end)
  
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return utf16leSlice(this, start, end)
  
        default:
          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
          encoding = (encoding + '').toLowerCase()
          loweredCase = true
      }
    }
  }
  
  Buffer.prototype.toString = function toString () {
    var length = this.length | 0
    if (length === 0) return ''
    if (arguments.length === 0) return utf8Slice(this, 0, length)
    return slowToString.apply(this, arguments)
  }
  
  Buffer.prototype.equals = function equals (b) {
    if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
    if (this === b) return true
    return Buffer.compare(this, b) === 0
  }
  
  Buffer.prototype.inspect = function inspect () {
    var str = ''
    var max = exports.INSPECT_MAX_BYTES
    if (this.length > 0) {
      str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
      if (this.length > max) str += ' ... '
    }
    return '<Buffer ' + str + '>'
  }
  
  Buffer.prototype.compare = function compare (b) {
    if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
    if (this === b) return 0
    return Buffer.compare(this, b)
  }
  
  Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
    if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
    else if (byteOffset < -0x80000000) byteOffset = -0x80000000
    byteOffset >>= 0
  
    if (this.length === 0) return -1
    if (byteOffset >= this.length) return -1
  
    // Negative offsets start from the end of the buffer
    if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
  
    if (typeof val === 'string') {
      if (val.length === 0) return -1 // special case: looking for empty string always fails
      return String.prototype.indexOf.call(this, val, byteOffset)
    }
    if (Buffer.isBuffer(val)) {
      return arrayIndexOf(this, val, byteOffset)
    }
    if (typeof val === 'number') {
      if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
        return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
      }
      return arrayIndexOf(this, [ val ], byteOffset)
    }
  
    function arrayIndexOf (arr, val, byteOffset) {
      var foundIndex = -1
      for (var i = 0; byteOffset + i < arr.length; i++) {
        if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
          if (foundIndex === -1) foundIndex = i
          if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
        } else {
          foundIndex = -1
        }
      }
      return -1
    }
  
    throw new TypeError('val must be string, number or Buffer')
  }
  
  // `get` is deprecated
  Buffer.prototype.get = function get (offset) {
    console.log('.get() is deprecated. Access using array indexes instead.')
    return this.readUInt8(offset)
  }
  
  // `set` is deprecated
  Buffer.prototype.set = function set (v, offset) {
    console.log('.set() is deprecated. Access using array indexes instead.')
    return this.writeUInt8(v, offset)
  }
  
  function hexWrite (buf, string, offset, length) {
    offset = Number(offset) || 0
    var remaining = buf.length - offset
    if (!length) {
      length = remaining
    } else {
      length = Number(length)
      if (length > remaining) {
        length = remaining
      }
    }
  
    // must be an even number of digits
    var strLen = string.length
    if (strLen % 2 !== 0) throw new Error('Invalid hex string')
  
    if (length > strLen / 2) {
      length = strLen / 2
    }
    for (var i = 0; i < length; i++) {
      var parsed = parseInt(string.substr(i * 2, 2), 16)
      if (isNaN(parsed)) throw new Error('Invalid hex string')
      buf[offset + i] = parsed
    }
    return i
  }
  
  function utf8Write (buf, string, offset, length) {
    return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  }
  
  function asciiWrite (buf, string, offset, length) {
    return blitBuffer(asciiToBytes(string), buf, offset, length)
  }
  
  function binaryWrite (buf, string, offset, length) {
    return asciiWrite(buf, string, offset, length)
  }
  
  function base64Write (buf, string, offset, length) {
    return blitBuffer(base64ToBytes(string), buf, offset, length)
  }
  
  function ucs2Write (buf, string, offset, length) {
    return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
  }
  
  Buffer.prototype.write = function write (string, offset, length, encoding) {
    // Buffer#write(string)
    if (offset === undefined) {
      encoding = 'utf8'
      length = this.length
      offset = 0
    // Buffer#write(string, encoding)
    } else if (length === undefined && typeof offset === 'string') {
      encoding = offset
      length = this.length
      offset = 0
    // Buffer#write(string, offset[, length][, encoding])
    } else if (isFinite(offset)) {
      offset = offset | 0
      if (isFinite(length)) {
        length = length | 0
        if (encoding === undefined) encoding = 'utf8'
      } else {
        encoding = length
        length = undefined
      }
    // legacy write(string, encoding, offset, length) - remove in v0.13
    } else {
      var swap = encoding
      encoding = offset
      offset = length | 0
      length = swap
    }
  
    var remaining = this.length - offset
    if (length === undefined || length > remaining) length = remaining
  
    if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
      throw new RangeError('attempt to write outside buffer bounds')
    }
  
    if (!encoding) encoding = 'utf8'
  
    var loweredCase = false
    for (;;) {
      switch (encoding) {
        case 'hex':
          return hexWrite(this, string, offset, length)
  
        case 'utf8':
        case 'utf-8':
          return utf8Write(this, string, offset, length)
  
        case 'ascii':
          return asciiWrite(this, string, offset, length)
  
        case 'binary':
          return binaryWrite(this, string, offset, length)
  
        case 'base64':
          // Warning: maxLength not taken into account in base64Write
          return base64Write(this, string, offset, length)
  
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return ucs2Write(this, string, offset, length)
  
        default:
          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
          encoding = ('' + encoding).toLowerCase()
          loweredCase = true
      }
    }
  }
  
  Buffer.prototype.toJSON = function toJSON () {
    return {
      type: 'Buffer',
      data: Array.prototype.slice.call(this._arr || this, 0)
    }
  }
  
  function base64Slice (buf, start, end) {
    if (start === 0 && end === buf.length) {
      return base64.fromByteArray(buf)
    } else {
      return base64.fromByteArray(buf.slice(start, end))
    }
  }
  
  function utf8Slice (buf, start, end) {
    end = Math.min(buf.length, end)
    var res = []
  
    var i = start
    while (i < end) {
      var firstByte = buf[i]
      var codePoint = null
      var bytesPerSequence = (firstByte > 0xEF) ? 4
        : (firstByte > 0xDF) ? 3
        : (firstByte > 0xBF) ? 2
        : 1
  
      if (i + bytesPerSequence <= end) {
        var secondByte, thirdByte, fourthByte, tempCodePoint
  
        switch (bytesPerSequence) {
          case 1:
            if (firstByte < 0x80) {
              codePoint = firstByte
            }
            break
          case 2:
            secondByte = buf[i + 1]
            if ((secondByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
              if (tempCodePoint > 0x7F) {
                codePoint = tempCodePoint
              }
            }
            break
          case 3:
            secondByte = buf[i + 1]
            thirdByte = buf[i + 2]
            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
              if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
                codePoint = tempCodePoint
              }
            }
            break
          case 4:
            secondByte = buf[i + 1]
            thirdByte = buf[i + 2]
            fourthByte = buf[i + 3]
            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
              if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
                codePoint = tempCodePoint
              }
            }
        }
      }
  
      if (codePoint === null) {
        // we did not generate a valid codePoint so insert a
        // replacement char (U+FFFD) and advance only 1 byte
        codePoint = 0xFFFD
        bytesPerSequence = 1
      } else if (codePoint > 0xFFFF) {
        // encode to utf16 (surrogate pair dance)
        codePoint -= 0x10000
        res.push(codePoint >>> 10 & 0x3FF | 0xD800)
        codePoint = 0xDC00 | codePoint & 0x3FF
      }
  
      res.push(codePoint)
      i += bytesPerSequence
    }
  
    return decodeCodePointsArray(res)
  }
  
  // Based on http://stackoverflow.com/a/22747272/680742, the browser with
  // the lowest limit is Chrome, with 0x10000 args.
  // We go 1 magnitude less, for safety
  var MAX_ARGUMENTS_LENGTH = 0x1000
  
  function decodeCodePointsArray (codePoints) {
    var len = codePoints.length
    if (len <= MAX_ARGUMENTS_LENGTH) {
      return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
    }
  
    // Decode in chunks to avoid "call stack size exceeded".
    var res = ''
    var i = 0
    while (i < len) {
      res += String.fromCharCode.apply(
        String,
        codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
      )
    }
    return res
  }
  
  function asciiSlice (buf, start, end) {
    var ret = ''
    end = Math.min(buf.length, end)
  
    for (var i = start; i < end; i++) {
      ret += String.fromCharCode(buf[i] & 0x7F)
    }
    return ret
  }
  
  function binarySlice (buf, start, end) {
    var ret = ''
    end = Math.min(buf.length, end)
  
    for (var i = start; i < end; i++) {
      ret += String.fromCharCode(buf[i])
    }
    return ret
  }
  
  function hexSlice (buf, start, end) {
    var len = buf.length
  
    if (!start || start < 0) start = 0
    if (!end || end < 0 || end > len) end = len
  
    var out = ''
    for (var i = start; i < end; i++) {
      out += toHex(buf[i])
    }
    return out
  }
  
  function utf16leSlice (buf, start, end) {
    var bytes = buf.slice(start, end)
    var res = ''
    for (var i = 0; i < bytes.length; i += 2) {
      res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
    }
    return res
  }
  
  Buffer.prototype.slice = function slice (start, end) {
    var len = this.length
    start = ~~start
    end = end === undefined ? len : ~~end
  
    if (start < 0) {
      start += len
      if (start < 0) start = 0
    } else if (start > len) {
      start = len
    }
  
    if (end < 0) {
      end += len
      if (end < 0) end = 0
    } else if (end > len) {
      end = len
    }
  
    if (end < start) end = start
  
    var newBuf
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      newBuf = Buffer._augment(this.subarray(start, end))
    } else {
      var sliceLen = end - start
      newBuf = new Buffer(sliceLen, undefined)
      for (var i = 0; i < sliceLen; i++) {
        newBuf[i] = this[i + start]
      }
    }
  
    if (newBuf.length) newBuf.parent = this.parent || this
  
    return newBuf
  }
  
  /*
   * Need to make sure that buffer isn't trying to write out of bounds.
   */
  function checkOffset (offset, ext, length) {
    if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
    if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
  }
  
  Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkOffset(offset, byteLength, this.length)
  
    var val = this[offset]
    var mul = 1
    var i = 0
    while (++i < byteLength && (mul *= 0x100)) {
      val += this[offset + i] * mul
    }
  
    return val
  }
  
  Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) {
      checkOffset(offset, byteLength, this.length)
    }
  
    var val = this[offset + --byteLength]
    var mul = 1
    while (byteLength > 0 && (mul *= 0x100)) {
      val += this[offset + --byteLength] * mul
    }
  
    return val
  }
  
  Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 1, this.length)
    return this[offset]
  }
  
  Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    return this[offset] | (this[offset + 1] << 8)
  }
  
  Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    return (this[offset] << 8) | this[offset + 1]
  }
  
  Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return ((this[offset]) |
        (this[offset + 1] << 8) |
        (this[offset + 2] << 16)) +
        (this[offset + 3] * 0x1000000)
  }
  
  Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return (this[offset] * 0x1000000) +
      ((this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      this[offset + 3])
  }
  
  Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkOffset(offset, byteLength, this.length)
  
    var val = this[offset]
    var mul = 1
    var i = 0
    while (++i < byteLength && (mul *= 0x100)) {
      val += this[offset + i] * mul
    }
    mul *= 0x80
  
    if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  
    return val
  }
  
  Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkOffset(offset, byteLength, this.length)
  
    var i = byteLength
    var mul = 1
    var val = this[offset + --i]
    while (i > 0 && (mul *= 0x100)) {
      val += this[offset + --i] * mul
    }
    mul *= 0x80
  
    if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  
    return val
  }
  
  Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 1, this.length)
    if (!(this[offset] & 0x80)) return (this[offset])
    return ((0xff - this[offset] + 1) * -1)
  }
  
  Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    var val = this[offset] | (this[offset + 1] << 8)
    return (val & 0x8000) ? val | 0xFFFF0000 : val
  }
  
  Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    var val = this[offset + 1] | (this[offset] << 8)
    return (val & 0x8000) ? val | 0xFFFF0000 : val
  }
  
  Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return (this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16) |
      (this[offset + 3] << 24)
  }
  
  Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return (this[offset] << 24) |
      (this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      (this[offset + 3])
  }
  
  Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
    return ieee754.read(this, offset, true, 23, 4)
  }
  
  Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
    return ieee754.read(this, offset, false, 23, 4)
  }
  
  Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 8, this.length)
    return ieee754.read(this, offset, true, 52, 8)
  }
  
  Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 8, this.length)
    return ieee754.read(this, offset, false, 52, 8)
  }
  
  function checkInt (buf, value, offset, ext, max, min) {
    if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
    if (value > max || value < min) throw new RangeError('value is out of bounds')
    if (offset + ext > buf.length) throw new RangeError('index out of range')
  }
  
  Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
  
    var mul = 1
    var i = 0
    this[offset] = value & 0xFF
    while (++i < byteLength && (mul *= 0x100)) {
      this[offset + i] = (value / mul) & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
  
    var i = byteLength - 1
    var mul = 1
    this[offset + i] = value & 0xFF
    while (--i >= 0 && (mul *= 0x100)) {
      this[offset + i] = (value / mul) & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
    this[offset] = (value & 0xff)
    return offset + 1
  }
  
  function objectWriteUInt16 (buf, value, offset, littleEndian) {
    if (value < 0) value = 0xffff + value + 1
    for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
      buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
        (littleEndian ? i : 1 - i) * 8
    }
  }
  
  Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
    } else {
      objectWriteUInt16(this, value, offset, true)
    }
    return offset + 2
  }
  
  Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
    } else {
      objectWriteUInt16(this, value, offset, false)
    }
    return offset + 2
  }
  
  function objectWriteUInt32 (buf, value, offset, littleEndian) {
    if (value < 0) value = 0xffffffff + value + 1
    for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
      buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
    }
  }
  
  Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset + 3] = (value >>> 24)
      this[offset + 2] = (value >>> 16)
      this[offset + 1] = (value >>> 8)
      this[offset] = (value & 0xff)
    } else {
      objectWriteUInt32(this, value, offset, true)
    }
    return offset + 4
  }
  
  Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
    } else {
      objectWriteUInt32(this, value, offset, false)
    }
    return offset + 4
  }
  
  Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) {
      var limit = Math.pow(2, 8 * byteLength - 1)
  
      checkInt(this, value, offset, byteLength, limit - 1, -limit)
    }
  
    var i = 0
    var mul = 1
    var sub = value < 0 ? 1 : 0
    this[offset] = value & 0xFF
    while (++i < byteLength && (mul *= 0x100)) {
      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) {
      var limit = Math.pow(2, 8 * byteLength - 1)
  
      checkInt(this, value, offset, byteLength, limit - 1, -limit)
    }
  
    var i = byteLength - 1
    var mul = 1
    var sub = value < 0 ? 1 : 0
    this[offset + i] = value & 0xFF
    while (--i >= 0 && (mul *= 0x100)) {
      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
    if (value < 0) value = 0xff + value + 1
    this[offset] = (value & 0xff)
    return offset + 1
  }
  
  Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
    } else {
      objectWriteUInt16(this, value, offset, true)
    }
    return offset + 2
  }
  
  Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
    } else {
      objectWriteUInt16(this, value, offset, false)
    }
    return offset + 2
  }
  
  Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      this[offset + 2] = (value >>> 16)
      this[offset + 3] = (value >>> 24)
    } else {
      objectWriteUInt32(this, value, offset, true)
    }
    return offset + 4
  }
  
  Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
    if (value < 0) value = 0xffffffff + value + 1
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
    } else {
      objectWriteUInt32(this, value, offset, false)
    }
    return offset + 4
  }
  
  function checkIEEE754 (buf, value, offset, ext, max, min) {
    if (value > max || value < min) throw new RangeError('value is out of bounds')
    if (offset + ext > buf.length) throw new RangeError('index out of range')
    if (offset < 0) throw new RangeError('index out of range')
  }
  
  function writeFloat (buf, value, offset, littleEndian, noAssert) {
    if (!noAssert) {
      checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
    }
    ieee754.write(buf, value, offset, littleEndian, 23, 4)
    return offset + 4
  }
  
  Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
    return writeFloat(this, value, offset, true, noAssert)
  }
  
  Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
    return writeFloat(this, value, offset, false, noAssert)
  }
  
  function writeDouble (buf, value, offset, littleEndian, noAssert) {
    if (!noAssert) {
      checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
    }
    ieee754.write(buf, value, offset, littleEndian, 52, 8)
    return offset + 8
  }
  
  Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
    return writeDouble(this, value, offset, true, noAssert)
  }
  
  Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
    return writeDouble(this, value, offset, false, noAssert)
  }
  
  // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
  Buffer.prototype.copy = function copy (target, targetStart, start, end) {
    if (!start) start = 0
    if (!end && end !== 0) end = this.length
    if (targetStart >= target.length) targetStart = target.length
    if (!targetStart) targetStart = 0
    if (end > 0 && end < start) end = start
  
    // Copy 0 bytes; we're done
    if (end === start) return 0
    if (target.length === 0 || this.length === 0) return 0
  
    // Fatal error conditions
    if (targetStart < 0) {
      throw new RangeError('targetStart out of bounds')
    }
    if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
    if (end < 0) throw new RangeError('sourceEnd out of bounds')
  
    // Are we oob?
    if (end > this.length) end = this.length
    if (target.length - targetStart < end - start) {
      end = target.length - targetStart + start
    }
  
    var len = end - start
    var i
  
    if (this === target && start < targetStart && targetStart < end) {
      // descending copy from end
      for (i = len - 1; i >= 0; i--) {
        target[i + targetStart] = this[i + start]
      }
    } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
      // ascending copy from start
      for (i = 0; i < len; i++) {
        target[i + targetStart] = this[i + start]
      }
    } else {
      target._set(this.subarray(start, start + len), targetStart)
    }
  
    return len
  }
  
  // fill(value, start=0, end=buffer.length)
  Buffer.prototype.fill = function fill (value, start, end) {
    if (!value) value = 0
    if (!start) start = 0
    if (!end) end = this.length
  
    if (end < start) throw new RangeError('end < start')
  
    // Fill 0 bytes; we're done
    if (end === start) return
    if (this.length === 0) return
  
    if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
    if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
  
    var i
    if (typeof value === 'number') {
      for (i = start; i < end; i++) {
        this[i] = value
      }
    } else {
      var bytes = utf8ToBytes(value.toString())
      var len = bytes.length
      for (i = start; i < end; i++) {
        this[i] = bytes[i % len]
      }
    }
  
    return this
  }
  
  /**
   * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
   * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
   */
  Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
    if (typeof Uint8Array !== 'undefined') {
      if (Buffer.TYPED_ARRAY_SUPPORT) {
        return (new Buffer(this)).buffer
      } else {
        var buf = new Uint8Array(this.length)
        for (var i = 0, len = buf.length; i < len; i += 1) {
          buf[i] = this[i]
        }
        return buf.buffer
      }
    } else {
      throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
    }
  }
  
  // HELPER FUNCTIONS
  // ================
  
  var BP = Buffer.prototype
  
  /**
   * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
   */
  Buffer._augment = function _augment (arr) {
    arr.constructor = Buffer
    arr._isBuffer = true
  
    // save reference to original Uint8Array set method before overwriting
    arr._set = arr.set
  
    // deprecated
    arr.get = BP.get
    arr.set = BP.set
  
    arr.write = BP.write
    arr.toString = BP.toString
    arr.toLocaleString = BP.toString
    arr.toJSON = BP.toJSON
    arr.equals = BP.equals
    arr.compare = BP.compare
    arr.indexOf = BP.indexOf
    arr.copy = BP.copy
    arr.slice = BP.slice
    arr.readUIntLE = BP.readUIntLE
    arr.readUIntBE = BP.readUIntBE
    arr.readUInt8 = BP.readUInt8
    arr.readUInt16LE = BP.readUInt16LE
    arr.readUInt16BE = BP.readUInt16BE
    arr.readUInt32LE = BP.readUInt32LE
    arr.readUInt32BE = BP.readUInt32BE
    arr.readIntLE = BP.readIntLE
    arr.readIntBE = BP.readIntBE
    arr.readInt8 = BP.readInt8
    arr.readInt16LE = BP.readInt16LE
    arr.readInt16BE = BP.readInt16BE
    arr.readInt32LE = BP.readInt32LE
    arr.readInt32BE = BP.readInt32BE
    arr.readFloatLE = BP.readFloatLE
    arr.readFloatBE = BP.readFloatBE
    arr.readDoubleLE = BP.readDoubleLE
    arr.readDoubleBE = BP.readDoubleBE
    arr.writeUInt8 = BP.writeUInt8
    arr.writeUIntLE = BP.writeUIntLE
    arr.writeUIntBE = BP.writeUIntBE
    arr.writeUInt16LE = BP.writeUInt16LE
    arr.writeUInt16BE = BP.writeUInt16BE
    arr.writeUInt32LE = BP.writeUInt32LE
    arr.writeUInt32BE = BP.writeUInt32BE
    arr.writeIntLE = BP.writeIntLE
    arr.writeIntBE = BP.writeIntBE
    arr.writeInt8 = BP.writeInt8
    arr.writeInt16LE = BP.writeInt16LE
    arr.writeInt16BE = BP.writeInt16BE
    arr.writeInt32LE = BP.writeInt32LE
    arr.writeInt32BE = BP.writeInt32BE
    arr.writeFloatLE = BP.writeFloatLE
    arr.writeFloatBE = BP.writeFloatBE
    arr.writeDoubleLE = BP.writeDoubleLE
    arr.writeDoubleBE = BP.writeDoubleBE
    arr.fill = BP.fill
    arr.inspect = BP.inspect
    arr.toArrayBuffer = BP.toArrayBuffer
  
    return arr
  }
  
  var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
  
  function base64clean (str) {
    // Node strips out invalid characters like \n and \t from the string, base64-js does not
    str = stringtrim(str).replace(INVALID_BASE64_RE, '')
    // Node converts strings with length < 2 to ''
    if (str.length < 2) return ''
    // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
    while (str.length % 4 !== 0) {
      str = str + '='
    }
    return str
  }
  
  function stringtrim (str) {
    if (str.trim) return str.trim()
    return str.replace(/^\s+|\s+$/g, '')
  }
  
  function toHex (n) {
    if (n < 16) return '0' + n.toString(16)
    return n.toString(16)
  }
  
  function utf8ToBytes (string, units) {
    units = units || Infinity
    var codePoint
    var length = string.length
    var leadSurrogate = null
    var bytes = []
  
    for (var i = 0; i < length; i++) {
      codePoint = string.charCodeAt(i)
  
      // is surrogate component
      if (codePoint > 0xD7FF && codePoint < 0xE000) {
        // last char was a lead
        if (!leadSurrogate) {
          // no lead yet
          if (codePoint > 0xDBFF) {
            // unexpected trail
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
            continue
          } else if (i + 1 === length) {
            // unpaired lead
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
            continue
          }
  
          // valid lead
          leadSurrogate = codePoint
  
          continue
        }
  
        // 2 leads in a row
        if (codePoint < 0xDC00) {
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          leadSurrogate = codePoint
          continue
        }
  
        // valid surrogate pair
        codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
      } else if (leadSurrogate) {
        // valid bmp char, but last char was a lead
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
      }
  
      leadSurrogate = null
  
      // encode utf8
      if (codePoint < 0x80) {
        if ((units -= 1) < 0) break
        bytes.push(codePoint)
      } else if (codePoint < 0x800) {
        if ((units -= 2) < 0) break
        bytes.push(
          codePoint >> 0x6 | 0xC0,
          codePoint & 0x3F | 0x80
        )
      } else if (codePoint < 0x10000) {
        if ((units -= 3) < 0) break
        bytes.push(
          codePoint >> 0xC | 0xE0,
          codePoint >> 0x6 & 0x3F | 0x80,
          codePoint & 0x3F | 0x80
        )
      } else if (codePoint < 0x110000) {
        if ((units -= 4) < 0) break
        bytes.push(
          codePoint >> 0x12 | 0xF0,
          codePoint >> 0xC & 0x3F | 0x80,
          codePoint >> 0x6 & 0x3F | 0x80,
          codePoint & 0x3F | 0x80
        )
      } else {
        throw new Error('Invalid code point')
      }
    }
  
    return bytes
  }
  
  function asciiToBytes (str) {
    var byteArray = []
    for (var i = 0; i < str.length; i++) {
      // Node's code seems to be doing this and not & 0x7F..
      byteArray.push(str.charCodeAt(i) & 0xFF)
    }
    return byteArray
  }
  
  function utf16leToBytes (str, units) {
    var c, hi, lo
    var byteArray = []
    for (var i = 0; i < str.length; i++) {
      if ((units -= 2) < 0) break
  
      c = str.charCodeAt(i)
      hi = c >> 8
      lo = c % 256
      byteArray.push(lo)
      byteArray.push(hi)
    }
  
    return byteArray
  }
  
  function base64ToBytes (str) {
    return base64.toByteArray(base64clean(str))
  }
  
  function blitBuffer (src, dst, offset, length) {
    for (var i = 0; i < length; i++) {
      if ((i + offset >= dst.length) || (i >= src.length)) break
      dst[i + offset] = src[i]
    }
    return i
  }
  
  }).call(this,require("--global--"),require("--console--"))
  },{"--console--":108,"--global--":67,"base64-js":71,"ieee754":79,"is-array":82}],73:[function(require,module,exports){
  module.exports = {
    "100": "Continue",
    "101": "Switching Protocols",
    "102": "Processing",
    "200": "OK",
    "201": "Created",
    "202": "Accepted",
    "203": "Non-Authoritative Information",
    "204": "No Content",
    "205": "Reset Content",
    "206": "Partial Content",
    "207": "Multi-Status",
    "300": "Multiple Choices",
    "301": "Moved Permanently",
    "302": "Moved Temporarily",
    "303": "See Other",
    "304": "Not Modified",
    "305": "Use Proxy",
    "307": "Temporary Redirect",
    "308": "Permanent Redirect",
    "400": "Bad Request",
    "401": "Unauthorized",
    "402": "Payment Required",
    "403": "Forbidden",
    "404": "Not Found",
    "405": "Method Not Allowed",
    "406": "Not Acceptable",
    "407": "Proxy Authentication Required",
    "408": "Request Time-out",
    "409": "Conflict",
    "410": "Gone",
    "411": "Length Required",
    "412": "Precondition Failed",
    "413": "Request Entity Too Large",
    "414": "Request-URI Too Large",
    "415": "Unsupported Media Type",
    "416": "Requested Range Not Satisfiable",
    "417": "Expectation Failed",
    "418": "I'm a teapot",
    "422": "Unprocessable Entity",
    "423": "Locked",
    "424": "Failed Dependency",
    "425": "Unordered Collection",
    "426": "Upgrade Required",
    "428": "Precondition Required",
    "429": "Too Many Requests",
    "431": "Request Header Fields Too Large",
    "500": "Internal Server Error",
    "501": "Not Implemented",
    "502": "Bad Gateway",
    "503": "Service Unavailable",
    "504": "Gateway Time-out",
    "505": "HTTP Version Not Supported",
    "506": "Variant Also Negotiates",
    "507": "Insufficient Storage",
    "509": "Bandwidth Limit Exceeded",
    "510": "Not Extended",
    "511": "Network Authentication Required"
  }
  
  },{}],74:[function(require,module,exports){
  (function (Buffer){
  // 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.
  
  // NOTE: These type checking functions intentionally don't use `instanceof`
  // because it is fragile and can be easily faked with `Object.create()`.
  
  function isArray(arg) {
    if (Array.isArray) {
      return Array.isArray(arg);
    }
    return objectToString(arg) === '[object Array]';
  }
  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 objectToString(re) === '[object RegExp]';
  }
  exports.isRegExp = isRegExp;
  
  function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
  }
  exports.isObject = isObject;
  
  function isDate(d) {
    return objectToString(d) === '[object Date]';
  }
  exports.isDate = isDate;
  
  function isError(e) {
    return (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 = Buffer.isBuffer;
  
  function objectToString(o) {
    return Object.prototype.toString.call(o);
  }
  
  }).call(this,{"isBuffer":require("../../is-buffer/index.js")})
  },{"../../is-buffer/index.js":83}],75:[function(require,module,exports){
  module.exports = now
  
  function now() {
      return new Date().getTime()
  }
  
  },{}],76:[function(require,module,exports){
  (function (console){
  // 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;
  }
  
  }).call(this,require("--console--"))
  },{"--console--":108}],77:[function(require,module,exports){
  
  var hasOwn = Object.prototype.hasOwnProperty;
  var toString = Object.prototype.toString;
  
  module.exports = function forEach (obj, fn, ctx) {
      if (toString.call(fn) !== '[object Function]') {
          throw new TypeError('iterator must be a function');
      }
      var l = obj.length;
      if (l === +l) {
          for (var i = 0; i < l; i++) {
              fn.call(ctx, obj[i], i, obj);
          }
      } else {
          for (var k in obj) {
              if (hasOwn.call(obj, k)) {
                  fn.call(ctx, obj[k], k, obj);
              }
          }
      }
  };
  
  
  },{}],78:[function(require,module,exports){
  var http = require('http');
  
  var https = module.exports;
  
  for (var key in http) {
      if (http.hasOwnProperty(key)) https[key] = http[key];
  };
  
  https.request = function (params, cb) {
      if (!params) params = {};
      params.scheme = 'https';
      params.protocol = 'https:';
      return http.request.call(this, params, cb);
  }
  
  },{"http":103}],79:[function(require,module,exports){
  exports.read = function (buffer, offset, isLE, mLen, nBytes) {
    var e, m
    var eLen = nBytes * 8 - mLen - 1
    var eMax = (1 << eLen) - 1
    var eBias = eMax >> 1
    var nBits = -7
    var i = isLE ? (nBytes - 1) : 0
    var d = isLE ? -1 : 1
    var s = buffer[offset + i]
  
    i += d
  
    e = s & ((1 << (-nBits)) - 1)
    s >>= (-nBits)
    nBits += eLen
    for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  
    m = e & ((1 << (-nBits)) - 1)
    e >>= (-nBits)
    nBits += mLen
    for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  
    if (e === 0) {
      e = 1 - eBias
    } else if (e === eMax) {
      return m ? NaN : ((s ? -1 : 1) * Infinity)
    } else {
      m = m + Math.pow(2, mLen)
      e = e - eBias
    }
    return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
  }
  
  exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
    var e, m, c
    var eLen = nBytes * 8 - mLen - 1
    var eMax = (1 << eLen) - 1
    var eBias = eMax >> 1
    var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
    var i = isLE ? 0 : (nBytes - 1)
    var d = isLE ? 1 : -1
    var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
  
    value = Math.abs(value)
  
    if (isNaN(value) || value === Infinity) {
      m = isNaN(value) ? 1 : 0
      e = eMax
    } else {
      e = Math.floor(Math.log(value) / Math.LN2)
      if (value * (c = Math.pow(2, -e)) < 1) {
        e--
        c *= 2
      }
      if (e + eBias >= 1) {
        value += rt / c
      } else {
        value += rt * Math.pow(2, 1 - eBias)
      }
      if (value * c >= 2) {
        e++
        c /= 2
      }
  
      if (e + eBias >= eMax) {
        m = 0
        e = eMax
      } else if (e + eBias >= 1) {
        m = (value * c - 1) * Math.pow(2, mLen)
        e = e + eBias
      } else {
        m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
        e = 0
      }
    }
  
    for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  
    e = (e << mLen) | m
    eLen += mLen
    for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  
    buffer[offset + i - d] |= s * 128
  }
  
  },{}],80:[function(require,module,exports){
  
  var indexOf = [].indexOf;
  
  module.exports = function(arr, obj){
    if (indexOf) return arr.indexOf(obj);
    for (var i = 0; i < arr.length; ++i) {
      if (arr[i] === obj) return i;
    }
    return -1;
  };
  },{}],81:[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
    }
  }
  
  },{}],82:[function(require,module,exports){
  
  /**
   * isArray
   */
  
  var isArray = Array.isArray;
  
  /**
   * toString
   */
  
  var str = Object.prototype.toString;
  
  /**
   * Whether or not the given `val`
   * is an array.
   *
   * example:
   *
   *        isArray([]);
   *        // > true
   *        isArray(arguments);
   *        // > false
   *        isArray('');
   *        // > false
   *
   * @param {mixed} val
   * @return {bool}
   */
  
  module.exports = isArray || function (val) {
    return !! val && '[object Array]' == str.call(val);
  };
  
  },{}],83:[function(require,module,exports){
  /**
   * Determine if an object is Buffer
   *
   * Author:   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
   * License:  MIT
   *
   * `npm install is-buffer`
   */
  
  module.exports = function (obj) {
    return !!(obj != null &&
      (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
        (obj.constructor &&
        typeof obj.constructor.isBuffer === 'function' &&
        obj.constructor.isBuffer(obj))
      ))
  }
  
  },{}],84:[function(require,module,exports){
  module.exports = Array.isArray || function (arr) {
    return Object.prototype.toString.call(arr) == '[object Array]';
  };
  
  },{}],85:[function(require,module,exports){
  'use strict';
  
  // modified from https://github.com/es-shims/es5-shim
  var has = Object.prototype.hasOwnProperty;
  var toStr = Object.prototype.toString;
  var slice = Array.prototype.slice;
  var isArgs = require('./isArguments');
  var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
  var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
  var dontEnums = [
  	'toString',
  	'toLocaleString',
  	'valueOf',
  	'hasOwnProperty',
  	'isPrototypeOf',
  	'propertyIsEnumerable',
  	'constructor'
  ];
  var equalsConstructorPrototype = function (o) {
  	var ctor = o.constructor;
  	return ctor && ctor.prototype === o;
  };
  var blacklistedKeys = {
  	$console: true,
  	$frame: true,
  	$frameElement: true,
  	$frames: true,
  	$parent: true,
  	$self: true,
  	$webkitIndexedDB: true,
  	$webkitStorageInfo: true,
  	$window: true
  };
  var hasAutomationEqualityBug = (function () {
  	/* global window */
  	if (typeof window === 'undefined') { return false; }
  	for (var k in window) {
  		try {
  			if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
  				try {
  					equalsConstructorPrototype(window[k]);
  				} catch (e) {
  					return true;
  				}
  			}
  		} catch (e) {
  			return true;
  		}
  	}
  	return false;
  }());
  var equalsConstructorPrototypeIfNotBuggy = function (o) {
  	/* global window */
  	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
  		return equalsConstructorPrototype(o);
  	}
  	try {
  		return equalsConstructorPrototype(o);
  	} catch (e) {
  		return false;
  	}
  };
  
  var keysShim = function keys(object) {
  	var isObject = object !== null && typeof object === 'object';
  	var isFunction = toStr.call(object) === '[object Function]';
  	var isArguments = isArgs(object);
  	var isString = isObject && toStr.call(object) === '[object String]';
  	var theKeys = [];
  
  	if (!isObject && !isFunction && !isArguments) {
  		throw new TypeError('Object.keys called on a non-object');
  	}
  
  	var skipProto = hasProtoEnumBug && isFunction;
  	if (isString && object.length > 0 && !has.call(object, 0)) {
  		for (var i = 0; i < object.length; ++i) {
  			theKeys.push(String(i));
  		}
  	}
  
  	if (isArguments && object.length > 0) {
  		for (var j = 0; j < object.length; ++j) {
  			theKeys.push(String(j));
  		}
  	} else {
  		for (var name in object) {
  			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
  				theKeys.push(String(name));
  			}
  		}
  	}
  
  	if (hasDontEnumBug) {
  		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
  
  		for (var k = 0; k < dontEnums.length; ++k) {
  			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
  				theKeys.push(dontEnums[k]);
  			}
  		}
  	}
  	return theKeys;
  };
  
  keysShim.shim = function shimObjectKeys() {
  	if (Object.keys) {
  		var keysWorksWithArguments = (function () {
  			// Safari 5.0 bug
  			return (Object.keys(arguments) || '').length === 2;
  		}(1, 2));
  		if (!keysWorksWithArguments) {
  			var originalKeys = Object.keys;
  			Object.keys = function keys(object) {
  				if (isArgs(object)) {
  					return originalKeys(slice.call(object));
  				} else {
  					return originalKeys(object);
  				}
  			};
  		}
  	} else {
  		Object.keys = keysShim;
  	}
  	return Object.keys || keysShim;
  };
  
  module.exports = keysShim;
  
  },{"./isArguments":86}],86:[function(require,module,exports){
  'use strict';
  
  var toStr = Object.prototype.toString;
  
  module.exports = function isArguments(value) {
  	var str = toStr.call(value);
  	var isArgs = str === '[object Arguments]';
  	if (!isArgs) {
  		isArgs = str !== '[object Array]' &&
  			value !== null &&
  			typeof value === 'object' &&
  			typeof value.length === 'number' &&
  			value.length >= 0 &&
  			toStr.call(value.callee) === '[object Function]';
  	}
  	return isArgs;
  };
  
  },{}],87:[function(require,module,exports){
  (function (process){
  'use strict';
  module.exports = nextTick;
  
  function nextTick(fn) {
    var args = new Array(arguments.length - 1);
    var i = 0;
    while (i < args.length) {
      args[i++] = arguments[i];
    }
    process.nextTick(function afterTick() {
      fn.apply(null, args);
    });
  }
  
  }).call(this,require("--process--"))
  },{"--process--":68}],88:[function(require,module,exports){
  (function (global){
  /*! https://mths.be/punycode v1.3.2 by @mathias */
  ;(function(root) {
  
  	/** Detect free variables */
  	var freeExports = typeof exports == 'object' && exports &&
  		!exports.nodeType && exports;
  	var freeModule = typeof module == 'object' && module &&
  		!module.nodeType && module;
  	var freeGlobal = typeof global == 'object' && global;
  	if (
  		freeGlobal.global === freeGlobal ||
  		freeGlobal.window === freeGlobal ||
  		freeGlobal.self === freeGlobal
  	) {
  		root = freeGlobal;
  	}
  
  	/**
  	 * The `punycode` object.
  	 * @name punycode
  	 * @type Object
  	 */
  	var punycode,
  
  	/** Highest positive signed 32-bit float value */
  	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
  
  	/** Bootstring parameters */
  	base = 36,
  	tMin = 1,
  	tMax = 26,
  	skew = 38,
  	damp = 700,
  	initialBias = 72,
  	initialN = 128, // 0x80
  	delimiter = '-', // '\x2D'
  
  	/** Regular expressions */
  	regexPunycode = /^xn--/,
  	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
  	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
  
  	/** Error messages */
  	errors = {
  		'overflow': 'Overflow: input needs wider integers to process',
  		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
  		'invalid-input': 'Invalid input'
  	},
  
  	/** Convenience shortcuts */
  	baseMinusTMin = base - tMin,
  	floor = Math.floor,
  	stringFromCharCode = String.fromCharCode,
  
  	/** Temporary variable */
  	key;
  
  	/*--------------------------------------------------------------------------*/
  
  	/**
  	 * A generic error utility function.
  	 * @private
  	 * @param {String} type The error type.
  	 * @returns {Error} Throws a `RangeError` with the applicable error message.
  	 */
  	function error(type) {
  		throw RangeError(errors[type]);
  	}
  
  	/**
  	 * A generic `Array#map` utility function.
  	 * @private
  	 * @param {Array} array The array to iterate over.
  	 * @param {Function} callback The function that gets called for every array
  	 * item.
  	 * @returns {Array} A new array of values returned by the callback function.
  	 */
  	function map(array, fn) {
  		var length = array.length;
  		var result = [];
  		while (length--) {
  			result[length] = fn(array[length]);
  		}
  		return result;
  	}
  
  	/**
  	 * A simple `Array#map`-like wrapper to work with domain name strings or email
  	 * addresses.
  	 * @private
  	 * @param {String} domain The domain name or email address.
  	 * @param {Function} callback The function that gets called for every
  	 * character.
  	 * @returns {Array} A new string of characters returned by the callback
  	 * function.
  	 */
  	function mapDomain(string, fn) {
  		var parts = string.split('@');
  		var result = '';
  		if (parts.length > 1) {
  			// In email addresses, only the domain name should be punycoded. Leave
  			// the local part (i.e. everything up to `@`) intact.
  			result = parts[0] + '@';
  			string = parts[1];
  		}
  		// Avoid `split(regex)` for IE8 compatibility. See #17.
  		string = string.replace(regexSeparators, '\x2E');
  		var labels = string.split('.');
  		var encoded = map(labels, fn).join('.');
  		return result + encoded;
  	}
  
  	/**
  	 * Creates an array containing the numeric code points of each Unicode
  	 * character in the string. While JavaScript uses UCS-2 internally,
  	 * this function will convert a pair of surrogate halves (each of which
  	 * UCS-2 exposes as separate characters) into a single code point,
  	 * matching UTF-16.
  	 * @see `punycode.ucs2.encode`
  	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
  	 * @memberOf punycode.ucs2
  	 * @name decode
  	 * @param {String} string The Unicode input string (UCS-2).
  	 * @returns {Array} The new array of code points.
  	 */
  	function ucs2decode(string) {
  		var output = [],
  		    counter = 0,
  		    length = string.length,
  		    value,
  		    extra;
  		while (counter < length) {
  			value = string.charCodeAt(counter++);
  			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
  				// high surrogate, and there is a next character
  				extra = string.charCodeAt(counter++);
  				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
  					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
  				} else {
  					// unmatched surrogate; only append this code unit, in case the next
  					// code unit is the high surrogate of a surrogate pair
  					output.push(value);
  					counter--;
  				}
  			} else {
  				output.push(value);
  			}
  		}
  		return output;
  	}
  
  	/**
  	 * Creates a string based on an array of numeric code points.
  	 * @see `punycode.ucs2.decode`
  	 * @memberOf punycode.ucs2
  	 * @name encode
  	 * @param {Array} codePoints The array of numeric code points.
  	 * @returns {String} The new Unicode string (UCS-2).
  	 */
  	function ucs2encode(array) {
  		return map(array, function(value) {
  			var output = '';
  			if (value > 0xFFFF) {
  				value -= 0x10000;
  				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
  				value = 0xDC00 | value & 0x3FF;
  			}
  			output += stringFromCharCode(value);
  			return output;
  		}).join('');
  	}
  
  	/**
  	 * Converts a basic code point into a digit/integer.
  	 * @see `digitToBasic()`
  	 * @private
  	 * @param {Number} codePoint The basic numeric code point value.
  	 * @returns {Number} The numeric value of a basic code point (for use in
  	 * representing integers) in the range `0` to `base - 1`, or `base` if
  	 * the code point does not represent a value.
  	 */
  	function basicToDigit(codePoint) {
  		if (codePoint - 48 < 10) {
  			return codePoint - 22;
  		}
  		if (codePoint - 65 < 26) {
  			return codePoint - 65;
  		}
  		if (codePoint - 97 < 26) {
  			return codePoint - 97;
  		}
  		return base;
  	}
  
  	/**
  	 * Converts a digit/integer into a basic code point.
  	 * @see `basicToDigit()`
  	 * @private
  	 * @param {Number} digit The numeric value of a basic code point.
  	 * @returns {Number} The basic code point whose value (when used for
  	 * representing integers) is `digit`, which needs to be in the range
  	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
  	 * used; else, the lowercase form is used. The behavior is undefined
  	 * if `flag` is non-zero and `digit` has no uppercase form.
  	 */
  	function digitToBasic(digit, flag) {
  		//  0..25 map to ASCII a..z or A..Z
  		// 26..35 map to ASCII 0..9
  		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
  	}
  
  	/**
  	 * Bias adaptation function as per section 3.4 of RFC 3492.
  	 * http://tools.ietf.org/html/rfc3492#section-3.4
  	 * @private
  	 */
  	function adapt(delta, numPoints, firstTime) {
  		var k = 0;
  		delta = firstTime ? floor(delta / damp) : delta >> 1;
  		delta += floor(delta / numPoints);
  		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
  			delta = floor(delta / baseMinusTMin);
  		}
  		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
  	}
  
  	/**
  	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
  	 * symbols.
  	 * @memberOf punycode
  	 * @param {String} input The Punycode string of ASCII-only symbols.
  	 * @returns {String} The resulting string of Unicode symbols.
  	 */
  	function decode(input) {
  		// Don't use UCS-2
  		var output = [],
  		    inputLength = input.length,
  		    out,
  		    i = 0,
  		    n = initialN,
  		    bias = initialBias,
  		    basic,
  		    j,
  		    index,
  		    oldi,
  		    w,
  		    k,
  		    digit,
  		    t,
  		    /** Cached calculation results */
  		    baseMinusT;
  
  		// Handle the basic code points: let `basic` be the number of input code
  		// points before the last delimiter, or `0` if there is none, then copy
  		// the first basic code points to the output.
  
  		basic = input.lastIndexOf(delimiter);
  		if (basic < 0) {
  			basic = 0;
  		}
  
  		for (j = 0; j < basic; ++j) {
  			// if it's not a basic code point
  			if (input.charCodeAt(j) >= 0x80) {
  				error('not-basic');
  			}
  			output.push(input.charCodeAt(j));
  		}
  
  		// Main decoding loop: start just after the last delimiter if any basic code
  		// points were copied; start at the beginning otherwise.
  
  		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
  
  			// `index` is the index of the next character to be consumed.
  			// Decode a generalized variable-length integer into `delta`,
  			// which gets added to `i`. The overflow checking is easier
  			// if we increase `i` as we go, then subtract off its starting
  			// value at the end to obtain `delta`.
  			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
  
  				if (index >= inputLength) {
  					error('invalid-input');
  				}
  
  				digit = basicToDigit(input.charCodeAt(index++));
  
  				if (digit >= base || digit > floor((maxInt - i) / w)) {
  					error('overflow');
  				}
  
  				i += digit * w;
  				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
  
  				if (digit < t) {
  					break;
  				}
  
  				baseMinusT = base - t;
  				if (w > floor(maxInt / baseMinusT)) {
  					error('overflow');
  				}
  
  				w *= baseMinusT;
  
  			}
  
  			out = output.length + 1;
  			bias = adapt(i - oldi, out, oldi == 0);
  
  			// `i` was supposed to wrap around from `out` to `0`,
  			// incrementing `n` each time, so we'll fix that now:
  			if (floor(i / out) > maxInt - n) {
  				error('overflow');
  			}
  
  			n += floor(i / out);
  			i %= out;
  
  			// Insert `n` at position `i` of the output
  			output.splice(i++, 0, n);
  
  		}
  
  		return ucs2encode(output);
  	}
  
  	/**
  	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
  	 * Punycode string of ASCII-only symbols.
  	 * @memberOf punycode
  	 * @param {String} input The string of Unicode symbols.
  	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
  	 */
  	function encode(input) {
  		var n,
  		    delta,
  		    handledCPCount,
  		    basicLength,
  		    bias,
  		    j,
  		    m,
  		    q,
  		    k,
  		    t,
  		    currentValue,
  		    output = [],
  		    /** `inputLength` will hold the number of code points in `input`. */
  		    inputLength,
  		    /** Cached calculation results */
  		    handledCPCountPlusOne,
  		    baseMinusT,
  		    qMinusT;
  
  		// Convert the input in UCS-2 to Unicode
  		input = ucs2decode(input);
  
  		// Cache the length
  		inputLength = input.length;
  
  		// Initialize the state
  		n = initialN;
  		delta = 0;
  		bias = initialBias;
  
  		// Handle the basic code points
  		for (j = 0; j < inputLength; ++j) {
  			currentValue = input[j];
  			if (currentValue < 0x80) {
  				output.push(stringFromCharCode(currentValue));
  			}
  		}
  
  		handledCPCount = basicLength = output.length;
  
  		// `handledCPCount` is the number of code points that have been handled;
  		// `basicLength` is the number of basic code points.
  
  		// Finish the basic string - if it is not empty - with a delimiter
  		if (basicLength) {
  			output.push(delimiter);
  		}
  
  		// Main encoding loop:
  		while (handledCPCount < inputLength) {
  
  			// All non-basic code points < n have been handled already. Find the next
  			// larger one:
  			for (m = maxInt, j = 0; j < inputLength; ++j) {
  				currentValue = input[j];
  				if (currentValue >= n && currentValue < m) {
  					m = currentValue;
  				}
  			}
  
  			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
  			// but guard against overflow
  			handledCPCountPlusOne = handledCPCount + 1;
  			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
  				error('overflow');
  			}
  
  			delta += (m - n) * handledCPCountPlusOne;
  			n = m;
  
  			for (j = 0; j < inputLength; ++j) {
  				currentValue = input[j];
  
  				if (currentValue < n && ++delta > maxInt) {
  					error('overflow');
  				}
  
  				if (currentValue == n) {
  					// Represent delta as a generalized variable-length integer
  					for (q = delta, k = base; /* no condition */; k += base) {
  						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
  						if (q < t) {
  							break;
  						}
  						qMinusT = q - t;
  						baseMinusT = base - t;
  						output.push(
  							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
  						);
  						q = floor(qMinusT / baseMinusT);
  					}
  
  					output.push(stringFromCharCode(digitToBasic(q, 0)));
  					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
  					delta = 0;
  					++handledCPCount;
  				}
  			}
  
  			++delta;
  			++n;
  
  		}
  		return output.join('');
  	}
  
  	/**
  	 * Converts a Punycode string representing a domain name or an email address
  	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
  	 * it doesn't matter if you call it on a string that has already been
  	 * converted to Unicode.
  	 * @memberOf punycode
  	 * @param {String} input The Punycoded domain name or email address to
  	 * convert to Unicode.
  	 * @returns {String} The Unicode representation of the given Punycode
  	 * string.
  	 */
  	function toUnicode(input) {
  		return mapDomain(input, function(string) {
  			return regexPunycode.test(string)
  				? decode(string.slice(4).toLowerCase())
  				: string;
  		});
  	}
  
  	/**
  	 * Converts a Unicode string representing a domain name or an email address to
  	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
  	 * i.e. it doesn't matter if you call it with a domain that's already in
  	 * ASCII.
  	 * @memberOf punycode
  	 * @param {String} input The domain name or email address to convert, as a
  	 * Unicode string.
  	 * @returns {String} The Punycode representation of the given domain name or
  	 * email address.
  	 */
  	function toASCII(input) {
  		return mapDomain(input, function(string) {
  			return regexNonASCII.test(string)
  				? 'xn--' + encode(string)
  				: string;
  		});
  	}
  
  	/*--------------------------------------------------------------------------*/
  
  	/** Define the public API */
  	punycode = {
  		/**
  		 * A string representing the current Punycode.js version number.
  		 * @memberOf punycode
  		 * @type String
  		 */
  		'version': '1.3.2',
  		/**
  		 * An object of methods to convert from JavaScript's internal character
  		 * representation (UCS-2) to Unicode code points, and back.
  		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
  		 * @memberOf punycode
  		 * @type Object
  		 */
  		'ucs2': {
  			'decode': ucs2decode,
  			'encode': ucs2encode
  		},
  		'decode': decode,
  		'encode': encode,
  		'toASCII': toASCII,
  		'toUnicode': toUnicode
  	};
  
  	/** Expose `punycode` */
  	// Some AMD build optimizers, like r.js, check for specific condition patterns
  	// like the following:
  	if (
  		typeof define == 'function' &&
  		typeof define.amd == 'object' &&
  		define.amd
  	) {
  		define('punycode', function() {
  			return punycode;
  		});
  	} else if (freeExports && freeModule) {
  		if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
  			freeModule.exports = punycode;
  		} else { // in Narwhal or RingoJS v0.7.0-
  			for (key in punycode) {
  				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
  			}
  		}
  	} else { // in Rhino or a web browser
  		root.punycode = punycode;
  	}
  
  }(this));
  
  }).call(this,require("--global--"))
  },{"--global--":67}],89:[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.
  
  'use strict';
  
  // If obj.hasOwnProperty has been overridden, then calling
  // obj.hasOwnProperty(prop) will break.
  // See: https://github.com/joyent/node/issues/1707
  function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }
  
  module.exports = function(qs, sep, eq, options) {
    sep = sep || '&';
    eq = eq || '=';
    var obj = {};
  
    if (typeof qs !== 'string' || qs.length === 0) {
      return obj;
    }
  
    var regexp = /\+/g;
    qs = qs.split(sep);
  
    var maxKeys = 1000;
    if (options && typeof options.maxKeys === 'number') {
      maxKeys = options.maxKeys;
    }
  
    var len = qs.length;
    // maxKeys <= 0 means that we should not limit keys count
    if (maxKeys > 0 && len > maxKeys) {
      len = maxKeys;
    }
  
    for (var i = 0; i < len; ++i) {
      var x = qs[i].replace(regexp, '%20'),
          idx = x.indexOf(eq),
          kstr, vstr, k, v;
  
      if (idx >= 0) {
        kstr = x.substr(0, idx);
        vstr = x.substr(idx + 1);
      } else {
        kstr = x;
        vstr = '';
      }
  
      k = decodeURIComponent(kstr);
      v = decodeURIComponent(vstr);
  
      if (!hasOwnProperty(obj, k)) {
        obj[k] = v;
      } else if (isArray(obj[k])) {
        obj[k].push(v);
      } else {
        obj[k] = [obj[k], v];
      }
    }
  
    return obj;
  };
  
  var isArray = Array.isArray || function (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
  };
  
  },{}],90:[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.
  
  'use strict';
  
  var stringifyPrimitive = function(v) {
    switch (typeof v) {
      case 'string':
        return v;
  
      case 'boolean':
        return v ? 'true' : 'false';
  
      case 'number':
        return isFinite(v) ? v : '';
  
      default:
        return '';
    }
  };
  
  module.exports = function(obj, sep, eq, name) {
    sep = sep || '&';
    eq = eq || '=';
    if (obj === null) {
      obj = undefined;
    }
  
    if (typeof obj === 'object') {
      return map(objectKeys(obj), function(k) {
        var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
        if (isArray(obj[k])) {
          return map(obj[k], function(v) {
            return ks + encodeURIComponent(stringifyPrimitive(v));
          }).join(sep);
        } else {
          return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
        }
      }).join(sep);
  
    }
  
    if (!name) return '';
    return encodeURIComponent(stringifyPrimitive(name)) + eq +
           encodeURIComponent(stringifyPrimitive(obj));
  };
  
  var isArray = Array.isArray || function (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
  };
  
  function map (xs, f) {
    if (xs.map) return xs.map(f);
    var res = [];
    for (var i = 0; i < xs.length; i++) {
      res.push(f(xs[i], i));
    }
    return res;
  }
  
  var objectKeys = Object.keys || function (obj) {
    var res = [];
    for (var key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
    }
    return res;
  };
  
  },{}],91:[function(require,module,exports){
  'use strict';
  
  exports.decode = exports.parse = require('./decode');
  exports.encode = exports.stringify = require('./encode');
  
  },{"./decode":89,"./encode":90}],92:[function(require,module,exports){
  module.exports = require("./lib/_stream_duplex.js")
  
  },{"./lib/_stream_duplex.js":93}],93:[function(require,module,exports){
  // a duplex stream is just a stream that is both readable and writable.
  // Since JS doesn't have multiple prototypal inheritance, this class
  // prototypally inherits from Readable, and then parasitically from
  // Writable.
  
  'use strict';
  
  /*<replacement>*/
  var objectKeys = Object.keys || function (obj) {
    var keys = [];
    for (var key in obj) keys.push(key);
    return keys;
  }
  /*</replacement>*/
  
  
  module.exports = Duplex;
  
  /*<replacement>*/
  var processNextTick = require('process-nextick-args');
  /*</replacement>*/
  
  
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  var Readable = require('./_stream_readable');
  var Writable = require('./_stream_writable');
  
  util.inherits(Duplex, Readable);
  
  var keys = objectKeys(Writable.prototype);
  for (var v = 0; v < keys.length; v++) {
    var method = keys[v];
    if (!Duplex.prototype[method])
      Duplex.prototype[method] = Writable.prototype[method];
  }
  
  function Duplex(options) {
    if (!(this instanceof Duplex))
      return new Duplex(options);
  
    Readable.call(this, options);
    Writable.call(this, options);
  
    if (options && options.readable === false)
      this.readable = false;
  
    if (options && options.writable === false)
      this.writable = false;
  
    this.allowHalfOpen = true;
    if (options && options.allowHalfOpen === false)
      this.allowHalfOpen = false;
  
    this.once('end', onend);
  }
  
  // the no-half-open enforcer
  function onend() {
    // if we allow half-open state, or if the writable side ended,
    // then we're ok.
    if (this.allowHalfOpen || this._writableState.ended)
      return;
  
    // no more data can be written.
    // But allow more writes to happen in this tick.
    processNextTick(onEndNT, this);
  }
  
  function onEndNT(self) {
    self.end();
  }
  
  function forEach (xs, f) {
    for (var i = 0, l = xs.length; i < l; i++) {
      f(xs[i], i);
    }
  }
  
  },{"./_stream_readable":95,"./_stream_writable":97,"core-util-is":74,"inherits":81,"process-nextick-args":87}],94:[function(require,module,exports){
  // a passthrough stream.
  // basically just the most minimal sort of Transform stream.
  // Every written chunk gets output as-is.
  
  'use strict';
  
  module.exports = PassThrough;
  
  var Transform = require('./_stream_transform');
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  util.inherits(PassThrough, Transform);
  
  function PassThrough(options) {
    if (!(this instanceof PassThrough))
      return new PassThrough(options);
  
    Transform.call(this, options);
  }
  
  PassThrough.prototype._transform = function(chunk, encoding, cb) {
    cb(null, chunk);
  };
  
  },{"./_stream_transform":96,"core-util-is":74,"inherits":81}],95:[function(require,module,exports){
  (function (process){
  'use strict';
  
  module.exports = Readable;
  
  /*<replacement>*/
  var processNextTick = require('process-nextick-args');
  /*</replacement>*/
  
  
  /*<replacement>*/
  var isArray = require('isarray');
  /*</replacement>*/
  
  
  /*<replacement>*/
  var Buffer = require('buffer').Buffer;
  /*</replacement>*/
  
  Readable.ReadableState = ReadableState;
  
  var EE = require('events');
  
  /*<replacement>*/
  var EElistenerCount = function(emitter, type) {
    return emitter.listeners(type).length;
  };
  /*</replacement>*/
  
  
  
  /*<replacement>*/
  var Stream;
  (function (){try{
    Stream = require('st' + 'ream');
  }catch(_){}finally{
    if (!Stream)
      Stream = require('events').EventEmitter;
  }}())
  /*</replacement>*/
  
  var Buffer = require('buffer').Buffer;
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  
  
  /*<replacement>*/
  var debugUtil = require('util');
  var debug;
  if (debugUtil && debugUtil.debuglog) {
    debug = debugUtil.debuglog('stream');
  } else {
    debug = function () {};
  }
  /*</replacement>*/
  
  var StringDecoder;
  
  util.inherits(Readable, Stream);
  
  function ReadableState(options, stream) {
    var Duplex = require('./_stream_duplex');
  
    options = options || {};
  
    // object stream flag. Used to make read(n) ignore n and to
    // make all the buffer merging and length checks go away
    this.objectMode = !!options.objectMode;
  
    if (stream instanceof Duplex)
      this.objectMode = this.objectMode || !!options.readableObjectMode;
  
    // the point at which it stops calling _read() to fill the buffer
    // Note: 0 is a valid value, means "don't call _read preemptively ever"
    var hwm = options.highWaterMark;
    var defaultHwm = this.objectMode ? 16 : 16 * 1024;
    this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
  
    // cast to ints.
    this.highWaterMark = ~~this.highWaterMark;
  
    this.buffer = [];
    this.length = 0;
    this.pipes = null;
    this.pipesCount = 0;
    this.flowing = null;
    this.ended = false;
    this.endEmitted = false;
    this.reading = false;
  
    // a flag to be able to tell if the onwrite cb is called immediately,
    // or on a later tick.  We set this to true at first, because any
    // actions that shouldn't happen until "later" should generally also
    // not happen before the first write call.
    this.sync = true;
  
    // whenever we return null, then we set a flag to say
    // that we're awaiting a 'readable' event emission.
    this.needReadable = false;
    this.emittedReadable = false;
    this.readableListening = false;
  
    // Crypto is kind of old and crusty.  Historically, its default string
    // encoding is 'binary' so we have to make this configurable.
    // Everything else in the universe uses 'utf8', though.
    this.defaultEncoding = options.defaultEncoding || 'utf8';
  
    // when piping, we only care about 'readable' events that happen
    // after read()ing all the bytes and not getting any pushback.
    this.ranOut = false;
  
    // the number of writers that are awaiting a drain event in .pipe()s
    this.awaitDrain = 0;
  
    // if true, a maybeReadMore has been scheduled
    this.readingMore = false;
  
    this.decoder = null;
    this.encoding = null;
    if (options.encoding) {
      if (!StringDecoder)
        StringDecoder = require('string_decoder/').StringDecoder;
      this.decoder = new StringDecoder(options.encoding);
      this.encoding = options.encoding;
    }
  }
  
  function Readable(options) {
    var Duplex = require('./_stream_duplex');
  
    if (!(this instanceof Readable))
      return new Readable(options);
  
    this._readableState = new ReadableState(options, this);
  
    // legacy
    this.readable = true;
  
    if (options && typeof options.read === 'function')
      this._read = options.read;
  
    Stream.call(this);
  }
  
  // Manually shove something into the read() buffer.
  // This returns true if the highWaterMark has not been hit yet,
  // similar to how Writable.write() returns true if you should
  // write() some more.
  Readable.prototype.push = function(chunk, encoding) {
    var state = this._readableState;
  
    if (!state.objectMode && typeof chunk === 'string') {
      encoding = encoding || state.defaultEncoding;
      if (encoding !== state.encoding) {
        chunk = new Buffer(chunk, encoding);
        encoding = '';
      }
    }
  
    return readableAddChunk(this, state, chunk, encoding, false);
  };
  
  // Unshift should *always* be something directly out of read()
  Readable.prototype.unshift = function(chunk) {
    var state = this._readableState;
    return readableAddChunk(this, state, chunk, '', true);
  };
  
  Readable.prototype.isPaused = function() {
    return this._readableState.flowing === false;
  };
  
  function readableAddChunk(stream, state, chunk, encoding, addToFront) {
    var er = chunkInvalid(state, chunk);
    if (er) {
      stream.emit('error', er);
    } else if (chunk === null) {
      state.reading = false;
      onEofChunk(stream, state);
    } else if (state.objectMode || chunk && chunk.length > 0) {
      if (state.ended && !addToFront) {
        var e = new Error('stream.push() after EOF');
        stream.emit('error', e);
      } else if (state.endEmitted && addToFront) {
        var e = new Error('stream.unshift() after end event');
        stream.emit('error', e);
      } else {
        if (state.decoder && !addToFront && !encoding)
          chunk = state.decoder.write(chunk);
  
        if (!addToFront)
          state.reading = false;
  
        // if we want the data now, just emit it.
        if (state.flowing && state.length === 0 && !state.sync) {
          stream.emit('data', chunk);
          stream.read(0);
        } else {
          // update the buffer info.
          state.length += state.objectMode ? 1 : chunk.length;
          if (addToFront)
            state.buffer.unshift(chunk);
          else
            state.buffer.push(chunk);
  
          if (state.needReadable)
            emitReadable(stream);
        }
  
        maybeReadMore(stream, state);
      }
    } else if (!addToFront) {
      state.reading = false;
    }
  
    return needMoreData(state);
  }
  
  
  // if it's past the high water mark, we can push in some more.
  // Also, if we have no data yet, we can stand some
  // more bytes.  This is to work around cases where hwm=0,
  // such as the repl.  Also, if the push() triggered a
  // readable event, and the user called read(largeNumber) such that
  // needReadable was set, then we ought to push more, so that another
  // 'readable' event will be triggered.
  function needMoreData(state) {
    return !state.ended &&
           (state.needReadable ||
            state.length < state.highWaterMark ||
            state.length === 0);
  }
  
  // backwards compatibility.
  Readable.prototype.setEncoding = function(enc) {
    if (!StringDecoder)
      StringDecoder = require('string_decoder/').StringDecoder;
    this._readableState.decoder = new StringDecoder(enc);
    this._readableState.encoding = enc;
    return this;
  };
  
  // Don't raise the hwm > 8MB
  var MAX_HWM = 0x800000;
  function computeNewHighWaterMark(n) {
    if (n >= MAX_HWM) {
      n = MAX_HWM;
    } else {
      // Get the next highest power of 2
      n--;
      n |= n >>> 1;
      n |= n >>> 2;
      n |= n >>> 4;
      n |= n >>> 8;
      n |= n >>> 16;
      n++;
    }
    return n;
  }
  
  function howMuchToRead(n, state) {
    if (state.length === 0 && state.ended)
      return 0;
  
    if (state.objectMode)
      return n === 0 ? 0 : 1;
  
    if (n === null || isNaN(n)) {
      // only flow one buffer at a time
      if (state.flowing && state.buffer.length)
        return state.buffer[0].length;
      else
        return state.length;
    }
  
    if (n <= 0)
      return 0;
  
    // If we're asking for more than the target buffer level,
    // then raise the water mark.  Bump up to the next highest
    // power of 2, to prevent increasing it excessively in tiny
    // amounts.
    if (n > state.highWaterMark)
      state.highWaterMark = computeNewHighWaterMark(n);
  
    // don't have that much.  return null, unless we've ended.
    if (n > state.length) {
      if (!state.ended) {
        state.needReadable = true;
        return 0;
      } else {
        return state.length;
      }
    }
  
    return n;
  }
  
  // you can override either this method, or the async _read(n) below.
  Readable.prototype.read = function(n) {
    debug('read', n);
    var state = this._readableState;
    var nOrig = n;
  
    if (typeof n !== 'number' || n > 0)
      state.emittedReadable = false;
  
    // if we're doing read(0) to trigger a readable event, but we
    // already have a bunch of data in the buffer, then just trigger
    // the 'readable' event and move on.
    if (n === 0 &&
        state.needReadable &&
        (state.length >= state.highWaterMark || state.ended)) {
      debug('read: emitReadable', state.length, state.ended);
      if (state.length === 0 && state.ended)
        endReadable(this);
      else
        emitReadable(this);
      return null;
    }
  
    n = howMuchToRead(n, state);
  
    // if we've ended, and we're now clear, then finish it up.
    if (n === 0 && state.ended) {
      if (state.length === 0)
        endReadable(this);
      return null;
    }
  
    // All the actual chunk generation logic needs to be
    // *below* the call to _read.  The reason is that in certain
    // synthetic stream cases, such as passthrough streams, _read
    // may be a completely synchronous operation which may change
    // the state of the read buffer, providing enough data when
    // before there was *not* enough.
    //
    // So, the steps are:
    // 1. Figure out what the state of things will be after we do
    // a read from the buffer.
    //
    // 2. If that resulting state will trigger a _read, then call _read.
    // Note that this may be asynchronous, or synchronous.  Yes, it is
    // deeply ugly to write APIs this way, but that still doesn't mean
    // that the Readable class should behave improperly, as streams are
    // designed to be sync/async agnostic.
    // Take note if the _read call is sync or async (ie, if the read call
    // has returned yet), so that we know whether or not it's safe to emit
    // 'readable' etc.
    //
    // 3. Actually pull the requested chunks out of the buffer and return.
  
    // if we need a readable event, then we need to do some reading.
    var doRead = state.needReadable;
    debug('need readable', doRead);
  
    // if we currently have less than the highWaterMark, then also read some
    if (state.length === 0 || state.length - n < state.highWaterMark) {
      doRead = true;
      debug('length less than watermark', doRead);
    }
  
    // however, if we've ended, then there's no point, and if we're already
    // reading, then it's unnecessary.
    if (state.ended || state.reading) {
      doRead = false;
      debug('reading or ended', doRead);
    }
  
    if (doRead) {
      debug('do read');
      state.reading = true;
      state.sync = true;
      // if the length is currently zero, then we *need* a readable event.
      if (state.length === 0)
        state.needReadable = true;
      // call internal read method
      this._read(state.highWaterMark);
      state.sync = false;
    }
  
    // If _read pushed data synchronously, then `reading` will be false,
    // and we need to re-evaluate how much data we can return to the user.
    if (doRead && !state.reading)
      n = howMuchToRead(nOrig, state);
  
    var ret;
    if (n > 0)
      ret = fromList(n, state);
    else
      ret = null;
  
    if (ret === null) {
      state.needReadable = true;
      n = 0;
    }
  
    state.length -= n;
  
    // If we have nothing in the buffer, then we want to know
    // as soon as we *do* get something into the buffer.
    if (state.length === 0 && !state.ended)
      state.needReadable = true;
  
    // If we tried to read() past the EOF, then emit end on the next tick.
    if (nOrig !== n && state.ended && state.length === 0)
      endReadable(this);
  
    if (ret !== null)
      this.emit('data', ret);
  
    return ret;
  };
  
  function chunkInvalid(state, chunk) {
    var er = null;
    if (!(Buffer.isBuffer(chunk)) &&
        typeof chunk !== 'string' &&
        chunk !== null &&
        chunk !== undefined &&
        !state.objectMode) {
      er = new TypeError('Invalid non-string/buffer chunk');
    }
    return er;
  }
  
  
  function onEofChunk(stream, state) {
    if (state.ended) return;
    if (state.decoder) {
      var chunk = state.decoder.end();
      if (chunk && chunk.length) {
        state.buffer.push(chunk);
        state.length += state.objectMode ? 1 : chunk.length;
      }
    }
    state.ended = true;
  
    // emit 'readable' now to make sure it gets picked up.
    emitReadable(stream);
  }
  
  // Don't emit readable right away in sync mode, because this can trigger
  // another read() call => stack overflow.  This way, it might trigger
  // a nextTick recursion warning, but that's not so bad.
  function emitReadable(stream) {
    var state = stream._readableState;
    state.needReadable = false;
    if (!state.emittedReadable) {
      debug('emitReadable', state.flowing);
      state.emittedReadable = true;
      if (state.sync)
        processNextTick(emitReadable_, stream);
      else
        emitReadable_(stream);
    }
  }
  
  function emitReadable_(stream) {
    debug('emit readable');
    stream.emit('readable');
    flow(stream);
  }
  
  
  // at this point, the user has presumably seen the 'readable' event,
  // and called read() to consume some data.  that may have triggered
  // in turn another _read(n) call, in which case reading = true if
  // it's in progress.
  // However, if we're not ended, or reading, and the length < hwm,
  // then go ahead and try to read some more preemptively.
  function maybeReadMore(stream, state) {
    if (!state.readingMore) {
      state.readingMore = true;
      processNextTick(maybeReadMore_, stream, state);
    }
  }
  
  function maybeReadMore_(stream, state) {
    var len = state.length;
    while (!state.reading && !state.flowing && !state.ended &&
           state.length < state.highWaterMark) {
      debug('maybeReadMore read 0');
      stream.read(0);
      if (len === state.length)
        // didn't get any data, stop spinning.
        break;
      else
        len = state.length;
    }
    state.readingMore = false;
  }
  
  // abstract method.  to be overridden in specific implementation classes.
  // call cb(er, data) where data is <= n in length.
  // for virtual (non-string, non-buffer) streams, "length" is somewhat
  // arbitrary, and perhaps not very meaningful.
  Readable.prototype._read = function(n) {
    this.emit('error', new Error('not implemented'));
  };
  
  Readable.prototype.pipe = function(dest, pipeOpts) {
    var src = this;
    var state = this._readableState;
  
    switch (state.pipesCount) {
      case 0:
        state.pipes = dest;
        break;
      case 1:
        state.pipes = [state.pipes, dest];
        break;
      default:
        state.pipes.push(dest);
        break;
    }
    state.pipesCount += 1;
    debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
  
    var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
                dest !== process.stdout &&
                dest !== process.stderr;
  
    var endFn = doEnd ? onend : cleanup;
    if (state.endEmitted)
      processNextTick(endFn);
    else
      src.once('end', endFn);
  
    dest.on('unpipe', onunpipe);
    function onunpipe(readable) {
      debug('onunpipe');
      if (readable === src) {
        cleanup();
      }
    }
  
    function onend() {
      debug('onend');
      dest.end();
    }
  
    // when the dest drains, it reduces the awaitDrain counter
    // on the source.  This would be more elegant with a .once()
    // handler in flow(), but adding and removing repeatedly is
    // too slow.
    var ondrain = pipeOnDrain(src);
    dest.on('drain', ondrain);
  
    var cleanedUp = false;
    function cleanup() {
      debug('cleanup');
      // cleanup event handlers once the pipe is broken
      dest.removeListener('close', onclose);
      dest.removeListener('finish', onfinish);
      dest.removeListener('drain', ondrain);
      dest.removeListener('error', onerror);
      dest.removeListener('unpipe', onunpipe);
      src.removeListener('end', onend);
      src.removeListener('end', cleanup);
      src.removeListener('data', ondata);
  
      cleanedUp = true;
  
      // if the reader is waiting for a drain event from this
      // specific writer, then it would cause it to never start
      // flowing again.
      // So, if this is awaiting a drain, then we just call it now.
      // If we don't know, then assume that we are waiting for one.
      if (state.awaitDrain &&
          (!dest._writableState || dest._writableState.needDrain))
        ondrain();
    }
  
    src.on('data', ondata);
    function ondata(chunk) {
      debug('ondata');
      var ret = dest.write(chunk);
      if (false === ret) {
        // If the user unpiped during `dest.write()`, it is possible
        // to get stuck in a permanently paused state if that write
        // also returned false.
        if (state.pipesCount === 1 &&
            state.pipes[0] === dest &&
            src.listenerCount('data') === 1 &&
            !cleanedUp) {
          debug('false write response, pause', src._readableState.awaitDrain);
          src._readableState.awaitDrain++;
        }
        src.pause();
      }
    }
  
    // if the dest has an error, then stop piping into it.
    // however, don't suppress the throwing behavior for this.
    function onerror(er) {
      debug('onerror', er);
      unpipe();
      dest.removeListener('error', onerror);
      if (EElistenerCount(dest, 'error') === 0)
        dest.emit('error', er);
    }
    // This is a brutally ugly hack to make sure that our error handler
    // is attached before any userland ones.  NEVER DO THIS.
    if (!dest._events || !dest._events.error)
      dest.on('error', onerror);
    else if (isArray(dest._events.error))
      dest._events.error.unshift(onerror);
    else
      dest._events.error = [onerror, dest._events.error];
  
  
    // Both close and finish should trigger unpipe, but only once.
    function onclose() {
      dest.removeListener('finish', onfinish);
      unpipe();
    }
    dest.once('close', onclose);
    function onfinish() {
      debug('onfinish');
      dest.removeListener('close', onclose);
      unpipe();
    }
    dest.once('finish', onfinish);
  
    function unpipe() {
      debug('unpipe');
      src.unpipe(dest);
    }
  
    // tell the dest that it's being piped to
    dest.emit('pipe', src);
  
    // start the flow if it hasn't been started already.
    if (!state.flowing) {
      debug('pipe resume');
      src.resume();
    }
  
    return dest;
  };
  
  function pipeOnDrain(src) {
    return function() {
      var state = src._readableState;
      debug('pipeOnDrain', state.awaitDrain);
      if (state.awaitDrain)
        state.awaitDrain--;
      if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
        state.flowing = true;
        flow(src);
      }
    };
  }
  
  
  Readable.prototype.unpipe = function(dest) {
    var state = this._readableState;
  
    // if we're not piping anywhere, then do nothing.
    if (state.pipesCount === 0)
      return this;
  
    // just one destination.  most common case.
    if (state.pipesCount === 1) {
      // passed in one, but it's not the right one.
      if (dest && dest !== state.pipes)
        return this;
  
      if (!dest)
        dest = state.pipes;
  
      // got a match.
      state.pipes = null;
      state.pipesCount = 0;
      state.flowing = false;
      if (dest)
        dest.emit('unpipe', this);
      return this;
    }
  
    // slow case. multiple pipe destinations.
  
    if (!dest) {
      // remove all.
      var dests = state.pipes;
      var len = state.pipesCount;
      state.pipes = null;
      state.pipesCount = 0;
      state.flowing = false;
  
      for (var i = 0; i < len; i++)
        dests[i].emit('unpipe', this);
      return this;
    }
  
    // try to find the right one.
    var i = indexOf(state.pipes, dest);
    if (i === -1)
      return this;
  
    state.pipes.splice(i, 1);
    state.pipesCount -= 1;
    if (state.pipesCount === 1)
      state.pipes = state.pipes[0];
  
    dest.emit('unpipe', this);
  
    return this;
  };
  
  // set up data events if they are asked for
  // Ensure readable listeners eventually get something
  Readable.prototype.on = function(ev, fn) {
    var res = Stream.prototype.on.call(this, ev, fn);
  
    // If listening to data, and it has not explicitly been paused,
    // then call resume to start the flow of data on the next tick.
    if (ev === 'data' && false !== this._readableState.flowing) {
      this.resume();
    }
  
    if (ev === 'readable' && this.readable) {
      var state = this._readableState;
      if (!state.readableListening) {
        state.readableListening = true;
        state.emittedReadable = false;
        state.needReadable = true;
        if (!state.reading) {
          processNextTick(nReadingNextTick, this);
        } else if (state.length) {
          emitReadable(this, state);
        }
      }
    }
  
    return res;
  };
  Readable.prototype.addListener = Readable.prototype.on;
  
  function nReadingNextTick(self) {
    debug('readable nexttick read 0');
    self.read(0);
  }
  
  // pause() and resume() are remnants of the legacy readable stream API
  // If the user uses them, then switch into old mode.
  Readable.prototype.resume = function() {
    var state = this._readableState;
    if (!state.flowing) {
      debug('resume');
      state.flowing = true;
      resume(this, state);
    }
    return this;
  };
  
  function resume(stream, state) {
    if (!state.resumeScheduled) {
      state.resumeScheduled = true;
      processNextTick(resume_, stream, state);
    }
  }
  
  function resume_(stream, state) {
    if (!state.reading) {
      debug('resume read 0');
      stream.read(0);
    }
  
    state.resumeScheduled = false;
    stream.emit('resume');
    flow(stream);
    if (state.flowing && !state.reading)
      stream.read(0);
  }
  
  Readable.prototype.pause = function() {
    debug('call pause flowing=%j', this._readableState.flowing);
    if (false !== this._readableState.flowing) {
      debug('pause');
      this._readableState.flowing = false;
      this.emit('pause');
    }
    return this;
  };
  
  function flow(stream) {
    var state = stream._readableState;
    debug('flow', state.flowing);
    if (state.flowing) {
      do {
        var chunk = stream.read();
      } while (null !== chunk && state.flowing);
    }
  }
  
  // wrap an old-style stream as the async data source.
  // This is *not* part of the readable stream interface.
  // It is an ugly unfortunate mess of history.
  Readable.prototype.wrap = function(stream) {
    var state = this._readableState;
    var paused = false;
  
    var self = this;
    stream.on('end', function() {
      debug('wrapped end');
      if (state.decoder && !state.ended) {
        var chunk = state.decoder.end();
        if (chunk && chunk.length)
          self.push(chunk);
      }
  
      self.push(null);
    });
  
    stream.on('data', function(chunk) {
      debug('wrapped data');
      if (state.decoder)
        chunk = state.decoder.write(chunk);
  
      // don't skip over falsy values in objectMode
      if (state.objectMode && (chunk === null || chunk === undefined))
        return;
      else if (!state.objectMode && (!chunk || !chunk.length))
        return;
  
      var ret = self.push(chunk);
      if (!ret) {
        paused = true;
        stream.pause();
      }
    });
  
    // proxy all the other methods.
    // important when wrapping filters and duplexes.
    for (var i in stream) {
      if (this[i] === undefined && typeof stream[i] === 'function') {
        this[i] = function(method) { return function() {
          return stream[method].apply(stream, arguments);
        }; }(i);
      }
    }
  
    // proxy certain important events.
    var events = ['error', 'close', 'destroy', 'pause', 'resume'];
    forEach(events, function(ev) {
      stream.on(ev, self.emit.bind(self, ev));
    });
  
    // when we try to consume some more bytes, simply unpause the
    // underlying stream.
    self._read = function(n) {
      debug('wrapped _read', n);
      if (paused) {
        paused = false;
        stream.resume();
      }
    };
  
    return self;
  };
  
  
  // exposed for testing purposes only.
  Readable._fromList = fromList;
  
  // Pluck off n bytes from an array of buffers.
  // Length is the combined lengths of all the buffers in the list.
  function fromList(n, state) {
    var list = state.buffer;
    var length = state.length;
    var stringMode = !!state.decoder;
    var objectMode = !!state.objectMode;
    var ret;
  
    // nothing in the list, definitely empty.
    if (list.length === 0)
      return null;
  
    if (length === 0)
      ret = null;
    else if (objectMode)
      ret = list.shift();
    else if (!n || n >= length) {
      // read it all, truncate the array.
      if (stringMode)
        ret = list.join('');
      else if (list.length === 1)
        ret = list[0];
      else
        ret = Buffer.concat(list, length);
      list.length = 0;
    } else {
      // read just some of it.
      if (n < list[0].length) {
        // just take a part of the first list item.
        // slice is the same for buffers and strings.
        var buf = list[0];
        ret = buf.slice(0, n);
        list[0] = buf.slice(n);
      } else if (n === list[0].length) {
        // first list is a perfect match
        ret = list.shift();
      } else {
        // complex case.
        // we have enough to cover it, but it spans past the first buffer.
        if (stringMode)
          ret = '';
        else
          ret = new Buffer(n);
  
        var c = 0;
        for (var i = 0, l = list.length; i < l && c < n; i++) {
          var buf = list[0];
          var cpy = Math.min(n - c, buf.length);
  
          if (stringMode)
            ret += buf.slice(0, cpy);
          else
            buf.copy(ret, c, 0, cpy);
  
          if (cpy < buf.length)
            list[0] = buf.slice(cpy);
          else
            list.shift();
  
          c += cpy;
        }
      }
    }
  
    return ret;
  }
  
  function endReadable(stream) {
    var state = stream._readableState;
  
    // If we get here before consuming all the bytes, then that is a
    // bug in node.  Should never happen.
    if (state.length > 0)
      throw new Error('endReadable called on non-empty stream');
  
    if (!state.endEmitted) {
      state.ended = true;
      processNextTick(endReadableNT, state, stream);
    }
  }
  
  function endReadableNT(state, stream) {
    // Check that we didn't get one last unshift.
    if (!state.endEmitted && state.length === 0) {
      state.endEmitted = true;
      stream.readable = false;
      stream.emit('end');
    }
  }
  
  function forEach (xs, f) {
    for (var i = 0, l = xs.length; i < l; i++) {
      f(xs[i], i);
    }
  }
  
  function indexOf (xs, x) {
    for (var i = 0, l = xs.length; i < l; i++) {
      if (xs[i] === x) return i;
    }
    return -1;
  }
  
  }).call(this,require("--process--"))
  },{"--process--":68,"./_stream_duplex":93,"buffer":72,"core-util-is":74,"events":76,"inherits":81,"isarray":84,"process-nextick-args":87,"string_decoder/":107,"util":109}],96:[function(require,module,exports){
  // a transform stream is a readable/writable stream where you do
  // something with the data.  Sometimes it's called a "filter",
  // but that's not a great name for it, since that implies a thing where
  // some bits pass through, and others are simply ignored.  (That would
  // be a valid example of a transform, of course.)
  //
  // While the output is causally related to the input, it's not a
  // necessarily symmetric or synchronous transformation.  For example,
  // a zlib stream might take multiple plain-text writes(), and then
  // emit a single compressed chunk some time in the future.
  //
  // Here's how this works:
  //
  // The Transform stream has all the aspects of the readable and writable
  // stream classes.  When you write(chunk), that calls _write(chunk,cb)
  // internally, and returns false if there's a lot of pending writes
  // buffered up.  When you call read(), that calls _read(n) until
  // there's enough pending readable data buffered up.
  //
  // In a transform stream, the written data is placed in a buffer.  When
  // _read(n) is called, it transforms the queued up data, calling the
  // buffered _write cb's as it consumes chunks.  If consuming a single
  // written chunk would result in multiple output chunks, then the first
  // outputted bit calls the readcb, and subsequent chunks just go into
  // the read buffer, and will cause it to emit 'readable' if necessary.
  //
  // This way, back-pressure is actually determined by the reading side,
  // since _read has to be called to start processing a new chunk.  However,
  // a pathological inflate type of transform can cause excessive buffering
  // here.  For example, imagine a stream where every byte of input is
  // interpreted as an integer from 0-255, and then results in that many
  // bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
  // 1kb of data being output.  In this case, you could write a very small
  // amount of input, and end up with a very large amount of output.  In
  // such a pathological inflating mechanism, there'd be no way to tell
  // the system to stop doing the transform.  A single 4MB write could
  // cause the system to run out of memory.
  //
  // However, even in such a pathological case, only a single written chunk
  // would be consumed, and then the rest would wait (un-transformed) until
  // the results of the previous transformed chunk were consumed.
  
  'use strict';
  
  module.exports = Transform;
  
  var Duplex = require('./_stream_duplex');
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  util.inherits(Transform, Duplex);
  
  
  function TransformState(stream) {
    this.afterTransform = function(er, data) {
      return afterTransform(stream, er, data);
    };
  
    this.needTransform = false;
    this.transforming = false;
    this.writecb = null;
    this.writechunk = null;
  }
  
  function afterTransform(stream, er, data) {
    var ts = stream._transformState;
    ts.transforming = false;
  
    var cb = ts.writecb;
  
    if (!cb)
      return stream.emit('error', new Error('no writecb in Transform class'));
  
    ts.writechunk = null;
    ts.writecb = null;
  
    if (data !== null && data !== undefined)
      stream.push(data);
  
    if (cb)
      cb(er);
  
    var rs = stream._readableState;
    rs.reading = false;
    if (rs.needReadable || rs.length < rs.highWaterMark) {
      stream._read(rs.highWaterMark);
    }
  }
  
  
  function Transform(options) {
    if (!(this instanceof Transform))
      return new Transform(options);
  
    Duplex.call(this, options);
  
    this._transformState = new TransformState(this);
  
    // when the writable side finishes, then flush out anything remaining.
    var stream = this;
  
    // start out asking for a readable event once data is transformed.
    this._readableState.needReadable = true;
  
    // we have implemented the _read method, and done the other things
    // that Readable wants before the first _read call, so unset the
    // sync guard flag.
    this._readableState.sync = false;
  
    if (options) {
      if (typeof options.transform === 'function')
        this._transform = options.transform;
  
      if (typeof options.flush === 'function')
        this._flush = options.flush;
    }
  
    this.once('prefinish', function() {
      if (typeof this._flush === 'function')
        this._flush(function(er) {
          done(stream, er);
        });
      else
        done(stream);
    });
  }
  
  Transform.prototype.push = function(chunk, encoding) {
    this._transformState.needTransform = false;
    return Duplex.prototype.push.call(this, chunk, encoding);
  };
  
  // This is the part where you do stuff!
  // override this function in implementation classes.
  // 'chunk' is an input chunk.
  //
  // Call `push(newChunk)` to pass along transformed output
  // to the readable side.  You may call 'push' zero or more times.
  //
  // Call `cb(err)` when you are done with this chunk.  If you pass
  // an error, then that'll put the hurt on the whole operation.  If you
  // never call cb(), then you'll never get another chunk.
  Transform.prototype._transform = function(chunk, encoding, cb) {
    throw new Error('not implemented');
  };
  
  Transform.prototype._write = function(chunk, encoding, cb) {
    var ts = this._transformState;
    ts.writecb = cb;
    ts.writechunk = chunk;
    ts.writeencoding = encoding;
    if (!ts.transforming) {
      var rs = this._readableState;
      if (ts.needTransform ||
          rs.needReadable ||
          rs.length < rs.highWaterMark)
        this._read(rs.highWaterMark);
    }
  };
  
  // Doesn't matter what the args are here.
  // _transform does all the work.
  // That we got here means that the readable side wants more data.
  Transform.prototype._read = function(n) {
    var ts = this._transformState;
  
    if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
      ts.transforming = true;
      this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
    } else {
      // mark that we need a transform, so that any data that comes in
      // will get processed, now that we've asked for it.
      ts.needTransform = true;
    }
  };
  
  
  function done(stream, er) {
    if (er)
      return stream.emit('error', er);
  
    // if there's nothing in the write buffer, then that means
    // that nothing more will ever be provided
    var ws = stream._writableState;
    var ts = stream._transformState;
  
    if (ws.length)
      throw new Error('calling transform done when ws.length != 0');
  
    if (ts.transforming)
      throw new Error('calling transform done when still transforming');
  
    return stream.push(null);
  }
  
  },{"./_stream_duplex":93,"core-util-is":74,"inherits":81}],97:[function(require,module,exports){
  // A bit simpler than readable streams.
  // Implement an async ._write(chunk, encoding, cb), and it'll handle all
  // the drain event emission and buffering.
  
  'use strict';
  
  module.exports = Writable;
  
  /*<replacement>*/
  var processNextTick = require('process-nextick-args');
  /*</replacement>*/
  
  
  /*<replacement>*/
  var Buffer = require('buffer').Buffer;
  /*</replacement>*/
  
  Writable.WritableState = WritableState;
  
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  
  /*<replacement>*/
  var internalUtil = {
    deprecate: require('util-deprecate')
  };
  /*</replacement>*/
  
  
  
  /*<replacement>*/
  var Stream;
  (function (){try{
    Stream = require('st' + 'ream');
  }catch(_){}finally{
    if (!Stream)
      Stream = require('events').EventEmitter;
  }}())
  /*</replacement>*/
  
  var Buffer = require('buffer').Buffer;
  
  util.inherits(Writable, Stream);
  
  function nop() {}
  
  function WriteReq(chunk, encoding, cb) {
    this.chunk = chunk;
    this.encoding = encoding;
    this.callback = cb;
    this.next = null;
  }
  
  function WritableState(options, stream) {
    var Duplex = require('./_stream_duplex');
  
    options = options || {};
  
    // object stream flag to indicate whether or not this stream
    // contains buffers or objects.
    this.objectMode = !!options.objectMode;
  
    if (stream instanceof Duplex)
      this.objectMode = this.objectMode || !!options.writableObjectMode;
  
    // the point at which write() starts returning false
    // Note: 0 is a valid value, means that we always return false if
    // the entire buffer is not flushed immediately on write()
    var hwm = options.highWaterMark;
    var defaultHwm = this.objectMode ? 16 : 16 * 1024;
    this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
  
    // cast to ints.
    this.highWaterMark = ~~this.highWaterMark;
  
    this.needDrain = false;
    // at the start of calling end()
    this.ending = false;
    // when end() has been called, and returned
    this.ended = false;
    // when 'finish' is emitted
    this.finished = false;
  
    // should we decode strings into buffers before passing to _write?
    // this is here so that some node-core streams can optimize string
    // handling at a lower level.
    var noDecode = options.decodeStrings === false;
    this.decodeStrings = !noDecode;
  
    // Crypto is kind of old and crusty.  Historically, its default string
    // encoding is 'binary' so we have to make this configurable.
    // Everything else in the universe uses 'utf8', though.
    this.defaultEncoding = options.defaultEncoding || 'utf8';
  
    // not an actual buffer we keep track of, but a measurement
    // of how much we're waiting to get pushed to some underlying
    // socket or file.
    this.length = 0;
  
    // a flag to see when we're in the middle of a write.
    this.writing = false;
  
    // when true all writes will be buffered until .uncork() call
    this.corked = 0;
  
    // a flag to be able to tell if the onwrite cb is called immediately,
    // or on a later tick.  We set this to true at first, because any
    // actions that shouldn't happen until "later" should generally also
    // not happen before the first write call.
    this.sync = true;
  
    // a flag to know if we're processing previously buffered items, which
    // may call the _write() callback in the same tick, so that we don't
    // end up in an overlapped onwrite situation.
    this.bufferProcessing = false;
  
    // the callback that's passed to _write(chunk,cb)
    this.onwrite = function(er) {
      onwrite(stream, er);
    };
  
    // the callback that the user supplies to write(chunk,encoding,cb)
    this.writecb = null;
  
    // the amount that is being written when _write is called.
    this.writelen = 0;
  
    this.bufferedRequest = null;
    this.lastBufferedRequest = null;
  
    // number of pending user-supplied write callbacks
    // this must be 0 before 'finish' can be emitted
    this.pendingcb = 0;
  
    // emit prefinish if the only thing we're waiting for is _write cbs
    // This is relevant for synchronous Transform streams
    this.prefinished = false;
  
    // True if the error was already emitted and should not be thrown again
    this.errorEmitted = false;
  }
  
  WritableState.prototype.getBuffer = function writableStateGetBuffer() {
    var current = this.bufferedRequest;
    var out = [];
    while (current) {
      out.push(current);
      current = current.next;
    }
    return out;
  };
  
  (function (){try {
  Object.defineProperty(WritableState.prototype, 'buffer', {
    get: internalUtil.deprecate(function() {
      return this.getBuffer();
    }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' +
       'instead.')
  });
  }catch(_){}}());
  
  
  function Writable(options) {
    var Duplex = require('./_stream_duplex');
  
    // Writable ctor is applied to Duplexes, though they're not
    // instanceof Writable, they're instanceof Readable.
    if (!(this instanceof Writable) && !(this instanceof Duplex))
      return new Writable(options);
  
    this._writableState = new WritableState(options, this);
  
    // legacy.
    this.writable = true;
  
    if (options) {
      if (typeof options.write === 'function')
        this._write = options.write;
  
      if (typeof options.writev === 'function')
        this._writev = options.writev;
    }
  
    Stream.call(this);
  }
  
  // Otherwise people can pipe Writable streams, which is just wrong.
  Writable.prototype.pipe = function() {
    this.emit('error', new Error('Cannot pipe. Not readable.'));
  };
  
  
  function writeAfterEnd(stream, cb) {
    var er = new Error('write after end');
    // TODO: defer error events consistently everywhere, not just the cb
    stream.emit('error', er);
    processNextTick(cb, er);
  }
  
  // If we get something that is not a buffer, string, null, or undefined,
  // and we're not in objectMode, then that's an error.
  // Otherwise stream chunks are all considered to be of length=1, and the
  // watermarks determine how many objects to keep in the buffer, rather than
  // how many bytes or characters.
  function validChunk(stream, state, chunk, cb) {
    var valid = true;
  
    if (!(Buffer.isBuffer(chunk)) &&
        typeof chunk !== 'string' &&
        chunk !== null &&
        chunk !== undefined &&
        !state.objectMode) {
      var er = new TypeError('Invalid non-string/buffer chunk');
      stream.emit('error', er);
      processNextTick(cb, er);
      valid = false;
    }
    return valid;
  }
  
  Writable.prototype.write = function(chunk, encoding, cb) {
    var state = this._writableState;
    var ret = false;
  
    if (typeof encoding === 'function') {
      cb = encoding;
      encoding = null;
    }
  
    if (Buffer.isBuffer(chunk))
      encoding = 'buffer';
    else if (!encoding)
      encoding = state.defaultEncoding;
  
    if (typeof cb !== 'function')
      cb = nop;
  
    if (state.ended)
      writeAfterEnd(this, cb);
    else if (validChunk(this, state, chunk, cb)) {
      state.pendingcb++;
      ret = writeOrBuffer(this, state, chunk, encoding, cb);
    }
  
    return ret;
  };
  
  Writable.prototype.cork = function() {
    var state = this._writableState;
  
    state.corked++;
  };
  
  Writable.prototype.uncork = function() {
    var state = this._writableState;
  
    if (state.corked) {
      state.corked--;
  
      if (!state.writing &&
          !state.corked &&
          !state.finished &&
          !state.bufferProcessing &&
          state.bufferedRequest)
        clearBuffer(this, state);
    }
  };
  
  Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
    // node::ParseEncoding() requires lower case.
    if (typeof encoding === 'string')
      encoding = encoding.toLowerCase();
    if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64',
  'ucs2', 'ucs-2','utf16le', 'utf-16le', 'raw']
  .indexOf((encoding + '').toLowerCase()) > -1))
      throw new TypeError('Unknown encoding: ' + encoding);
    this._writableState.defaultEncoding = encoding;
  };
  
  function decodeChunk(state, chunk, encoding) {
    if (!state.objectMode &&
        state.decodeStrings !== false &&
        typeof chunk === 'string') {
      chunk = new Buffer(chunk, encoding);
    }
    return chunk;
  }
  
  // if we're already writing something, then just put this
  // in the queue, and wait our turn.  Otherwise, call _write
  // If we return false, then we need a drain event, so set that flag.
  function writeOrBuffer(stream, state, chunk, encoding, cb) {
    chunk = decodeChunk(state, chunk, encoding);
  
    if (Buffer.isBuffer(chunk))
      encoding = 'buffer';
    var len = state.objectMode ? 1 : chunk.length;
  
    state.length += len;
  
    var ret = state.length < state.highWaterMark;
    // we must ensure that previous needDrain will not be reset to false.
    if (!ret)
      state.needDrain = true;
  
    if (state.writing || state.corked) {
      var last = state.lastBufferedRequest;
      state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
      if (last) {
        last.next = state.lastBufferedRequest;
      } else {
        state.bufferedRequest = state.lastBufferedRequest;
      }
    } else {
      doWrite(stream, state, false, len, chunk, encoding, cb);
    }
  
    return ret;
  }
  
  function doWrite(stream, state, writev, len, chunk, encoding, cb) {
    state.writelen = len;
    state.writecb = cb;
    state.writing = true;
    state.sync = true;
    if (writev)
      stream._writev(chunk, state.onwrite);
    else
      stream._write(chunk, encoding, state.onwrite);
    state.sync = false;
  }
  
  function onwriteError(stream, state, sync, er, cb) {
    --state.pendingcb;
    if (sync)
      processNextTick(cb, er);
    else
      cb(er);
  
    stream._writableState.errorEmitted = true;
    stream.emit('error', er);
  }
  
  function onwriteStateUpdate(state) {
    state.writing = false;
    state.writecb = null;
    state.length -= state.writelen;
    state.writelen = 0;
  }
  
  function onwrite(stream, er) {
    var state = stream._writableState;
    var sync = state.sync;
    var cb = state.writecb;
  
    onwriteStateUpdate(state);
  
    if (er)
      onwriteError(stream, state, sync, er, cb);
    else {
      // Check if we're actually ready to finish, but don't emit yet
      var finished = needFinish(state);
  
      if (!finished &&
          !state.corked &&
          !state.bufferProcessing &&
          state.bufferedRequest) {
        clearBuffer(stream, state);
      }
  
      if (sync) {
        processNextTick(afterWrite, stream, state, finished, cb);
      } else {
        afterWrite(stream, state, finished, cb);
      }
    }
  }
  
  function afterWrite(stream, state, finished, cb) {
    if (!finished)
      onwriteDrain(stream, state);
    state.pendingcb--;
    cb();
    finishMaybe(stream, state);
  }
  
  // Must force callback to be called on nextTick, so that we don't
  // emit 'drain' before the write() consumer gets the 'false' return
  // value, and has a chance to attach a 'drain' listener.
  function onwriteDrain(stream, state) {
    if (state.length === 0 && state.needDrain) {
      state.needDrain = false;
      stream.emit('drain');
    }
  }
  
  
  // if there's something in the buffer waiting, then process it
  function clearBuffer(stream, state) {
    state.bufferProcessing = true;
    var entry = state.bufferedRequest;
  
    if (stream._writev && entry && entry.next) {
      // Fast case, write everything using _writev()
      var buffer = [];
      var cbs = [];
      while (entry) {
        cbs.push(entry.callback);
        buffer.push(entry);
        entry = entry.next;
      }
  
      // count the one we are adding, as well.
      // TODO(isaacs) clean this up
      state.pendingcb++;
      state.lastBufferedRequest = null;
      doWrite(stream, state, true, state.length, buffer, '', function(err) {
        for (var i = 0; i < cbs.length; i++) {
          state.pendingcb--;
          cbs[i](err);
        }
      });
  
      // Clear buffer
    } else {
      // Slow case, write chunks one-by-one
      while (entry) {
        var chunk = entry.chunk;
        var encoding = entry.encoding;
        var cb = entry.callback;
        var len = state.objectMode ? 1 : chunk.length;
  
        doWrite(stream, state, false, len, chunk, encoding, cb);
        entry = entry.next;
        // if we didn't call the onwrite immediately, then
        // it means that we need to wait until it does.
        // also, that means that the chunk and cb are currently
        // being processed, so move the buffer counter past them.
        if (state.writing) {
          break;
        }
      }
  
      if (entry === null)
        state.lastBufferedRequest = null;
    }
    state.bufferedRequest = entry;
    state.bufferProcessing = false;
  }
  
  Writable.prototype._write = function(chunk, encoding, cb) {
    cb(new Error('not implemented'));
  };
  
  Writable.prototype._writev = null;
  
  Writable.prototype.end = function(chunk, encoding, cb) {
    var state = this._writableState;
  
    if (typeof chunk === 'function') {
      cb = chunk;
      chunk = null;
      encoding = null;
    } else if (typeof encoding === 'function') {
      cb = encoding;
      encoding = null;
    }
  
    if (chunk !== null && chunk !== undefined)
      this.write(chunk, encoding);
  
    // .end() fully uncorks
    if (state.corked) {
      state.corked = 1;
      this.uncork();
    }
  
    // ignore unnecessary end() calls.
    if (!state.ending && !state.finished)
      endWritable(this, state, cb);
  };
  
  
  function needFinish(state) {
    return (state.ending &&
            state.length === 0 &&
            state.bufferedRequest === null &&
            !state.finished &&
            !state.writing);
  }
  
  function prefinish(stream, state) {
    if (!state.prefinished) {
      state.prefinished = true;
      stream.emit('prefinish');
    }
  }
  
  function finishMaybe(stream, state) {
    var need = needFinish(state);
    if (need) {
      if (state.pendingcb === 0) {
        prefinish(stream, state);
        state.finished = true;
        stream.emit('finish');
      } else {
        prefinish(stream, state);
      }
    }
    return need;
  }
  
  function endWritable(stream, state, cb) {
    state.ending = true;
    finishMaybe(stream, state);
    if (cb) {
      if (state.finished)
        processNextTick(cb);
      else
        stream.once('finish', cb);
    }
    state.ended = true;
  }
  
  },{"./_stream_duplex":93,"buffer":72,"core-util-is":74,"events":76,"inherits":81,"process-nextick-args":87,"util-deprecate":111}],98:[function(require,module,exports){
  module.exports = require("./lib/_stream_passthrough.js")
  
  },{"./lib/_stream_passthrough.js":94}],99:[function(require,module,exports){
  var Stream = (function (){
    try {
      return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
    } catch(_){}
  }());
  exports = module.exports = require('./lib/_stream_readable.js');
  exports.Stream = Stream || exports;
  exports.Readable = exports;
  exports.Writable = require('./lib/_stream_writable.js');
  exports.Duplex = require('./lib/_stream_duplex.js');
  exports.Transform = require('./lib/_stream_transform.js');
  exports.PassThrough = require('./lib/_stream_passthrough.js');
  
  },{"./lib/_stream_duplex.js":93,"./lib/_stream_passthrough.js":94,"./lib/_stream_readable.js":95,"./lib/_stream_transform.js":96,"./lib/_stream_writable.js":97}],100:[function(require,module,exports){
  module.exports = require("./lib/_stream_transform.js")
  
  },{"./lib/_stream_transform.js":96}],101:[function(require,module,exports){
  module.exports = require("./lib/_stream_writable.js")
  
  },{"./lib/_stream_writable.js":97}],102:[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.
  
  module.exports = Stream;
  
  var EE = require('events').EventEmitter;
  var inherits = require('inherits');
  
  inherits(Stream, EE);
  Stream.Readable = require('readable-stream/readable.js');
  Stream.Writable = require('readable-stream/writable.js');
  Stream.Duplex = require('readable-stream/duplex.js');
  Stream.Transform = require('readable-stream/transform.js');
  Stream.PassThrough = require('readable-stream/passthrough.js');
  
  // Backwards-compat with node 0.4.x
  Stream.Stream = Stream;
  
  
  
  // old-style streams.  Note that the pipe method (the only relevant
  // part of this class) is overridden in the Readable class.
  
  function Stream() {
    EE.call(this);
  }
  
  Stream.prototype.pipe = function(dest, options) {
    var source = this;
  
    function ondata(chunk) {
      if (dest.writable) {
        if (false === dest.write(chunk) && source.pause) {
          source.pause();
        }
      }
    }
  
    source.on('data', ondata);
  
    function ondrain() {
      if (source.readable && source.resume) {
        source.resume();
      }
    }
  
    dest.on('drain', ondrain);
  
    // If the 'end' option is not supplied, dest.end() will be called when
    // source gets the 'end' or 'close' events.  Only dest.end() once.
    if (!dest._isStdio && (!options || options.end !== false)) {
      source.on('end', onend);
      source.on('close', onclose);
    }
  
    var didOnEnd = false;
    function onend() {
      if (didOnEnd) return;
      didOnEnd = true;
  
      dest.end();
    }
  
  
    function onclose() {
      if (didOnEnd) return;
      didOnEnd = true;
  
      if (typeof dest.destroy === 'function') dest.destroy();
    }
  
    // don't leave dangling pipes when there are errors.
    function onerror(er) {
      cleanup();
      if (EE.listenerCount(this, 'error') === 0) {
        throw er; // Unhandled stream error in pipe.
      }
    }
  
    source.on('error', onerror);
    dest.on('error', onerror);
  
    // remove all the event listeners that were added.
    function cleanup() {
      source.removeListener('data', ondata);
      dest.removeListener('drain', ondrain);
  
      source.removeListener('end', onend);
      source.removeListener('close', onclose);
  
      source.removeListener('error', onerror);
      dest.removeListener('error', onerror);
  
      source.removeListener('end', cleanup);
      source.removeListener('close', cleanup);
  
      dest.removeListener('close', cleanup);
    }
  
    source.on('end', cleanup);
    source.on('close', cleanup);
  
    dest.on('close', cleanup);
  
    dest.emit('pipe', source);
  
    // Allow for unix-like usage: A.pipe(B).pipe(C)
    return dest;
  };
  
  },{"events":76,"inherits":81,"readable-stream/duplex.js":92,"readable-stream/passthrough.js":98,"readable-stream/readable.js":99,"readable-stream/transform.js":100,"readable-stream/writable.js":101}],103:[function(require,module,exports){
  var ClientRequest = require('./lib/request')
  var extend = require('xtend')
  var statusCodes = require('builtin-status-codes')
  var url = require('url')
  
  var http = exports
  
  http.request = function (opts, cb) {
  	if (typeof opts === 'string')
  		opts = url.parse(opts)
  	else
  		opts = extend(opts)
  
  	var protocol = opts.protocol || ''
  	var host = opts.hostname || opts.host
  	var port = opts.port
  	var path = opts.path || '/'
  
  	// Necessary for IPv6 addresses
  	if (host && host.indexOf(':') !== -1)
  		host = '[' + host + ']'
  
  	// This may be a relative url. The browser should always be able to interpret it correctly.
  	opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path
  	opts.method = (opts.method || 'GET').toUpperCase()
  	opts.headers = opts.headers || {}
  
  	// Also valid opts.auth, opts.mode
  
  	var req = new ClientRequest(opts)
  	if (cb)
  		req.on('response', cb)
  	return req
  }
  
  http.get = function get (opts, cb) {
  	var req = http.request(opts, cb)
  	req.end()
  	return req
  }
  
  http.Agent = function () {}
  http.Agent.defaultMaxSockets = 4
  
  http.STATUS_CODES = statusCodes
  
  http.METHODS = [
  	'CHECKOUT',
  	'CONNECT',
  	'COPY',
  	'DELETE',
  	'GET',
  	'HEAD',
  	'LOCK',
  	'M-SEARCH',
  	'MERGE',
  	'MKACTIVITY',
  	'MKCOL',
  	'MOVE',
  	'NOTIFY',
  	'OPTIONS',
  	'PATCH',
  	'POST',
  	'PROPFIND',
  	'PROPPATCH',
  	'PURGE',
  	'PUT',
  	'REPORT',
  	'SEARCH',
  	'SUBSCRIBE',
  	'TRACE',
  	'UNLOCK',
  	'UNSUBSCRIBE'
  ]
  },{"./lib/request":105,"builtin-status-codes":73,"url":110,"xtend":114}],104:[function(require,module,exports){
  (function (global){
  exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableByteStream)
  
  exports.blobConstructor = false
  try {
  	new Blob([new ArrayBuffer(1)])
  	exports.blobConstructor = true
  } catch (e) {}
  
  var xhr = new global.XMLHttpRequest()
  // If location.host is empty, e.g. if this page/worker was loaded
  // from a Blob, then use example.com to avoid an error
  xhr.open('GET', global.location.host ? '/' : 'https://example.com')
  
  function checkTypeSupport (type) {
  	try {
  		xhr.responseType = type
  		return xhr.responseType === type
  	} catch (e) {}
  	return false
  }
  
  // For some strange reason, Safari 7.0 reports typeof global.ArrayBuffer === 'object'.
  // Safari 7.1 appears to have fixed this bug.
  var haveArrayBuffer = typeof global.ArrayBuffer !== 'undefined'
  var haveSlice = haveArrayBuffer && isFunction(global.ArrayBuffer.prototype.slice)
  
  exports.arraybuffer = haveArrayBuffer && checkTypeSupport('arraybuffer')
  // These next two tests unavoidably show warnings in Chrome. Since fetch will always
  // be used if it's available, just return false for these to avoid the warnings.
  exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream')
  exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer &&
  	checkTypeSupport('moz-chunked-arraybuffer')
  exports.overrideMimeType = isFunction(xhr.overrideMimeType)
  exports.vbArray = isFunction(global.VBArray)
  
  function isFunction (value) {
    return typeof value === 'function'
  }
  
  xhr = null // Help gc
  
  }).call(this,require("--global--"))
  },{"--global--":67}],105:[function(require,module,exports){
  (function (process,global,Buffer){
  // var Base64 = require('Base64')
  var capability = require('./capability')
  var foreach = require('foreach')
  var indexOf = require('indexof')
  var inherits = require('inherits')
  var keys = require('object-keys')
  var response = require('./response')
  var stream = require('stream')
  
  var IncomingMessage = response.IncomingMessage
  var rStates = response.readyStates
  
  function decideMode (preferBinary) {
  	if (capability.fetch) {
  		return 'fetch'
  	} else if (capability.mozchunkedarraybuffer) {
  		return 'moz-chunked-arraybuffer'
  	} else if (capability.msstream) {
  		return 'ms-stream'
  	} else if (capability.arraybuffer && preferBinary) {
  		return 'arraybuffer'
  	} else if (capability.vbArray && preferBinary) {
  		return 'text:vbarray'
  	} else {
  		return 'text'
  	}
  }
  
  var ClientRequest = module.exports = function (opts) {
  	var self = this
  	stream.Writable.call(self)
  
  	self._opts = opts
  	self._body = []
  	self._headers = {}
  	if (opts.auth)
  		self.setHeader('Authorization', 'Basic ' + new Buffer(opts.auth).toString('base64'))
  	foreach(keys(opts.headers), function (name) {
  		self.setHeader(name, opts.headers[name])
  	})
  
  	var preferBinary
  	if (opts.mode === 'prefer-streaming') {
  		// If streaming is a high priority but binary compatibility and
  		// the accuracy of the 'content-type' header aren't
  		preferBinary = false
  	} else if (opts.mode === 'allow-wrong-content-type') {
  		// If streaming is more important than preserving the 'content-type' header
  		preferBinary = !capability.overrideMimeType
  	} else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') {
  		// Use binary if text streaming may corrupt data or the content-type header, or for speed
  		preferBinary = true
  	} else {
  		throw new Error('Invalid value for opts.mode')
  	}
  	self._mode = decideMode(preferBinary)
  
  	self.on('finish', function () {
  		self._onFinish()
  	})
  }
  
  inherits(ClientRequest, stream.Writable)
  
  ClientRequest.prototype.setHeader = function (name, value) {
  	var self = this
  	var lowerName = name.toLowerCase()
  	// This check is not necessary, but it prevents warnings from browsers about setting unsafe
  	// headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but
  	// http-browserify did it, so I will too.
  	if (indexOf(unsafeHeaders, lowerName) !== -1)
  		return
  
  	self._headers[lowerName] = {
  		name: name,
  		value: value
  	}
  }
  
  ClientRequest.prototype.getHeader = function (name) {
  	var self = this
  	return self._headers[name.toLowerCase()].value
  }
  
  ClientRequest.prototype.removeHeader = function (name) {
  	var self = this
  	delete self._headers[name.toLowerCase()]
  }
  
  ClientRequest.prototype._onFinish = function () {
  	var self = this
  
  	if (self._destroyed)
  		return
  	var opts = self._opts
  
  	var headersObj = self._headers
  	var body
  	if (opts.method === 'POST' || opts.method === 'PUT') {
  		if (capability.blobConstructor) {
  			body = new global.Blob(self._body.map(function (buffer) {
  				return buffer.toArrayBuffer()
  			}), {
  				type: (headersObj['content-type'] || {}).value || ''
  			})
  		} else {
  			// get utf8 string
  			body = Buffer.concat(self._body).toString()
  		}
  	}
  
  	if (self._mode === 'fetch') {
  		var headers = keys(headersObj).map(function (name) {
  			return [headersObj[name].name, headersObj[name].value]
  		})
  
  		global.fetch(self._opts.url, {
  			method: self._opts.method,
  			headers: headers,
  			body: body,
  			mode: 'cors',
  			credentials: opts.withCredentials ? 'include' : 'same-origin'
  		}).then(function (response) {
  			self._fetchResponse = response
  			self._connect()
  		}).then(undefined, function (reason) {
  			self.emit('error', reason)
  		})
  	} else {
  		var xhr = self._xhr = new global.XMLHttpRequest()
  		try {
  			xhr.open(self._opts.method, self._opts.url, true)
  		} catch (err) {
  			process.nextTick(function () {
  				self.emit('error', err)
  			})
  			return
  		}
  
  		// Can't set responseType on really old browsers
  		if ('responseType' in xhr)
  			xhr.responseType = self._mode.split(':')[0]
  
  		if ('withCredentials' in xhr)
  			xhr.withCredentials = !!opts.withCredentials
  
  		if (self._mode === 'text' && 'overrideMimeType' in xhr)
  			xhr.overrideMimeType('text/plain; charset=x-user-defined')
  
  		foreach(keys(headersObj), function (name) {
  			xhr.setRequestHeader(headersObj[name].name, headersObj[name].value)
  		})
  
  		self._response = null
  		xhr.onreadystatechange = function () {
  			switch (xhr.readyState) {
  				case rStates.LOADING:
  				case rStates.DONE:
  					self._onXHRProgress()
  					break
  			}
  		}
  		// Necessary for streaming in Firefox, since xhr.response is ONLY defined
  		// in onprogress, not in onreadystatechange with xhr.readyState = 3
  		if (self._mode === 'moz-chunked-arraybuffer') {
  			xhr.onprogress = function () {
  				self._onXHRProgress()
  			}
  		}
  
  		xhr.onerror = function () {
  			if (self._destroyed)
  				return
  			self.emit('error', new Error('XHR error'))
  		}
  
  		try {
  			xhr.send(body)
  		} catch (err) {
  			process.nextTick(function () {
  				self.emit('error', err)
  			})
  			return
  		}
  	}
  }
  
  /**
   * Checks if xhr.status is readable. Even though the spec says it should
   * be available in readyState 3, accessing it throws an exception in IE8
   */
  function statusValid (xhr) {
  	try {
  		return (xhr.status !== null)
  	} catch (e) {
  		return false
  	}
  }
  
  ClientRequest.prototype._onXHRProgress = function () {
  	var self = this
  
  	if (!statusValid(self._xhr) || self._destroyed)
  		return
  
  	if (!self._response)
  		self._connect()
  
  	self._response._onXHRProgress()
  }
  
  ClientRequest.prototype._connect = function () {
  	var self = this
  
  	if (self._destroyed)
  		return
  
  	self._response = new IncomingMessage(self._xhr, self._fetchResponse, self._mode)
  	self.emit('response', self._response)
  }
  
  ClientRequest.prototype._write = function (chunk, encoding, cb) {
  	var self = this
  
  	self._body.push(chunk)
  	cb()
  }
  
  ClientRequest.prototype.abort = ClientRequest.prototype.destroy = function () {
  	var self = this
  	self._destroyed = true
  	if (self._response)
  		self._response._destroyed = true
  	if (self._xhr)
  		self._xhr.abort()
  	// Currently, there isn't a way to truly abort a fetch.
  	// If you like bikeshedding, see https://github.com/whatwg/fetch/issues/27
  }
  
  ClientRequest.prototype.end = function (data, encoding, cb) {
  	var self = this
  	if (typeof data === 'function') {
  		cb = data
  		data = undefined
  	}
  
  	stream.Writable.prototype.end.call(self, data, encoding, cb)
  }
  
  ClientRequest.prototype.flushHeaders = function () {}
  ClientRequest.prototype.setTimeout = function () {}
  ClientRequest.prototype.setNoDelay = function () {}
  ClientRequest.prototype.setSocketKeepAlive = function () {}
  
  // Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method
  var unsafeHeaders = [
  	'accept-charset',
  	'accept-encoding',
  	'access-control-request-headers',
  	'access-control-request-method',
  	'connection',
  	'content-length',
  	'cookie',
  	'cookie2',
  	'date',
  	'dnt',
  	'expect',
  	'host',
  	'keep-alive',
  	'origin',
  	'referer',
  	'te',
  	'trailer',
  	'transfer-encoding',
  	'upgrade',
  	'user-agent',
  	'via'
  ]
  
  }).call(this,require("--process--"),require("--global--"),require("buffer").Buffer)
  },{"--global--":67,"--process--":68,"./capability":104,"./response":106,"buffer":72,"foreach":77,"indexof":80,"inherits":81,"object-keys":85,"stream":102}],106:[function(require,module,exports){
  (function (process,global,Buffer){
  var capability = require('./capability')
  var foreach = require('foreach')
  var inherits = require('inherits')
  var stream = require('stream')
  
  var rStates = exports.readyStates = {
  	UNSENT: 0,
  	OPENED: 1,
  	HEADERS_RECEIVED: 2,
  	LOADING: 3,
  	DONE: 4
  }
  
  var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode) {
  	var self = this
  	stream.Readable.call(self)
  
  	self._mode = mode
  	self.headers = {}
  	self.rawHeaders = []
  	self.trailers = {}
  	self.rawTrailers = []
  
  	// Fake the 'close' event, but only once 'end' fires
  	self.on('end', function () {
  		// The nextTick is necessary to prevent the 'request' module from causing an infinite loop
  		process.nextTick(function () {
  			self.emit('close')
  		})
  	})
  
  	if (mode === 'fetch') {
  		self._fetchResponse = response
  
  		self.statusCode = response.status
  		self.statusMessage = response.statusText
  		// backwards compatible version of for (<item> of <iterable>):
  		// for (var <item>,_i,_it = <iterable>[Symbol.iterator](); <item> = (_i = _it.next()).value,!_i.done;)
  		for (var header, _i, _it = response.headers[Symbol.iterator](); header = (_i = _it.next()).value, !_i.done;) {
  			self.headers[header[0].toLowerCase()] = header[1]
  			self.rawHeaders.push(header[0], header[1])
  		}
  
  		// TODO: this doesn't respect backpressure. Once WritableStream is available, this can be fixed
  		var reader = response.body.getReader()
  		function read () {
  			reader.read().then(function (result) {
  				if (self._destroyed)
  					return
  				if (result.done) {
  					self.push(null)
  					return
  				}
  				self.push(new Buffer(result.value))
  				read()
  			})
  		}
  		read()
  
  	} else {
  		self._xhr = xhr
  		self._pos = 0
  
  		self.statusCode = xhr.status
  		self.statusMessage = xhr.statusText
  		var headers = xhr.getAllResponseHeaders().split(/\r?\n/)
  		foreach(headers, function (header) {
  			var matches = header.match(/^([^:]+):\s*(.*)/)
  			if (matches) {
  				var key = matches[1].toLowerCase()
  				if (self.headers[key] !== undefined)
  					self.headers[key] += ', ' + matches[2]
  				else
  					self.headers[key] = matches[2]
  				self.rawHeaders.push(matches[1], matches[2])
  			}
  		})
  
  		self._charset = 'x-user-defined'
  		if (!capability.overrideMimeType) {
  			var mimeType = self.rawHeaders['mime-type']
  			if (mimeType) {
  				var charsetMatch = mimeType.match(/;\s*charset=([^;])(;|$)/)
  				if (charsetMatch) {
  					self._charset = charsetMatch[1].toLowerCase()
  				}
  			}
  			if (!self._charset)
  				self._charset = 'utf-8' // best guess
  		}
  	}
  }
  
  inherits(IncomingMessage, stream.Readable)
  
  IncomingMessage.prototype._read = function () {}
  
  IncomingMessage.prototype._onXHRProgress = function () {
  	var self = this
  
  	var xhr = self._xhr
  
  	var response = null
  	switch (self._mode) {
  		case 'text:vbarray': // For IE9
  			if (xhr.readyState !== rStates.DONE)
  				break
  			try {
  				// This fails in IE8
  				response = new global.VBArray(xhr.responseBody).toArray()
  			} catch (e) {}
  			if (response !== null) {
  				self.push(new Buffer(response))
  				break
  			}
  			// Falls through in IE8	
  		case 'text':
  			try { // This will fail when readyState = 3 in IE9. Switch mode and wait for readyState = 4
  				response = xhr.responseText
  			} catch (e) {
  				self._mode = 'text:vbarray'
  				break
  			}
  			if (response.length > self._pos) {
  				var newData = response.substr(self._pos)
  				if (self._charset === 'x-user-defined') {
  					var buffer = new Buffer(newData.length)
  					for (var i = 0; i < newData.length; i++)
  						buffer[i] = newData.charCodeAt(i) & 0xff
  
  					self.push(buffer)
  				} else {
  					self.push(newData, self._charset)
  				}
  				self._pos = response.length
  			}
  			break
  		case 'arraybuffer':
  			if (xhr.readyState !== rStates.DONE)
  				break
  			response = xhr.response
  			self.push(new Buffer(new Uint8Array(response)))
  			break
  		case 'moz-chunked-arraybuffer': // take whole
  			response = xhr.response
  			if (xhr.readyState !== rStates.LOADING || !response)
  				break
  			self.push(new Buffer(new Uint8Array(response)))
  			break
  		case 'ms-stream':
  			response = xhr.response
  			if (xhr.readyState !== rStates.LOADING)
  				break
  			var reader = new global.MSStreamReader()
  			reader.onprogress = function () {
  				if (reader.result.byteLength > self._pos) {
  					self.push(new Buffer(new Uint8Array(reader.result.slice(self._pos))))
  					self._pos = reader.result.byteLength
  				}
  			}
  			reader.onload = function () {
  				self.push(null)
  			}
  			// reader.onerror = ??? // TODO: this
  			reader.readAsArrayBuffer(response)
  			break
  	}
  
  	// The ms-stream case handles end separately in reader.onload()
  	if (self._xhr.readyState === rStates.DONE && self._mode !== 'ms-stream') {
  		self.push(null)
  	}
  }
  
  }).call(this,require("--process--"),require("--global--"),require("buffer").Buffer)
  },{"--global--":67,"--process--":68,"./capability":104,"buffer":72,"foreach":77,"inherits":81,"stream":102}],107:[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.
  
  var Buffer = require('buffer').Buffer;
  
  var isBufferEncoding = Buffer.isEncoding
    || function(encoding) {
         switch (encoding && encoding.toLowerCase()) {
           case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
           default: return false;
         }
       }
  
  
  function assertEncoding(encoding) {
    if (encoding && !isBufferEncoding(encoding)) {
      throw new Error('Unknown encoding: ' + encoding);
    }
  }
  
  // StringDecoder provides an interface for efficiently splitting a series of
  // buffers into a series of JS strings without breaking apart multi-byte
  // characters. CESU-8 is handled as part of the UTF-8 encoding.
  //
  // @TODO Handling all encodings inside a single object makes it very difficult
  // to reason about this code, so it should be split up in the future.
  // @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
  // points as used by CESU-8.
  var StringDecoder = exports.StringDecoder = function(encoding) {
    this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
    assertEncoding(encoding);
    switch (this.encoding) {
      case 'utf8':
        // CESU-8 represents each of Surrogate Pair by 3-bytes
        this.surrogateSize = 3;
        break;
      case 'ucs2':
      case 'utf16le':
        // UTF-16 represents each of Surrogate Pair by 2-bytes
        this.surrogateSize = 2;
        this.detectIncompleteChar = utf16DetectIncompleteChar;
        break;
      case 'base64':
        // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
        this.surrogateSize = 3;
        this.detectIncompleteChar = base64DetectIncompleteChar;
        break;
      default:
        this.write = passThroughWrite;
        return;
    }
  
    // Enough space to store all bytes of a single character. UTF-8 needs 4
    // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
    this.charBuffer = new Buffer(6);
    // Number of bytes received for the current incomplete multi-byte character.
    this.charReceived = 0;
    // Number of bytes expected for the current incomplete multi-byte character.
    this.charLength = 0;
  };
  
  
  // write decodes the given buffer and returns it as JS string that is
  // guaranteed to not contain any partial multi-byte characters. Any partial
  // character found at the end of the buffer is buffered up, and will be
  // returned when calling write again with the remaining bytes.
  //
  // Note: Converting a Buffer containing an orphan surrogate to a String
  // currently works, but converting a String to a Buffer (via `new Buffer`, or
  // Buffer#write) will replace incomplete surrogates with the unicode
  // replacement character. See https://codereview.chromium.org/121173009/ .
  StringDecoder.prototype.write = function(buffer) {
    var charStr = '';
    // if our last write ended with an incomplete multibyte character
    while (this.charLength) {
      // determine how many remaining bytes this buffer has to offer for this char
      var available = (buffer.length >= this.charLength - this.charReceived) ?
          this.charLength - this.charReceived :
          buffer.length;
  
      // add the new bytes to the char buffer
      buffer.copy(this.charBuffer, this.charReceived, 0, available);
      this.charReceived += available;
  
      if (this.charReceived < this.charLength) {
        // still not enough chars in this buffer? wait for more ...
        return '';
      }
  
      // remove bytes belonging to the current character from the buffer
      buffer = buffer.slice(available, buffer.length);
  
      // get the character that was split
      charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
  
      // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
      var charCode = charStr.charCodeAt(charStr.length - 1);
      if (charCode >= 0xD800 && charCode <= 0xDBFF) {
        this.charLength += this.surrogateSize;
        charStr = '';
        continue;
      }
      this.charReceived = this.charLength = 0;
  
      // if there are no more bytes in this buffer, just emit our char
      if (buffer.length === 0) {
        return charStr;
      }
      break;
    }
  
    // determine and set charLength / charReceived
    this.detectIncompleteChar(buffer);
  
    var end = buffer.length;
    if (this.charLength) {
      // buffer the incomplete character bytes we got
      buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
      end -= this.charReceived;
    }
  
    charStr += buffer.toString(this.encoding, 0, end);
  
    var end = charStr.length - 1;
    var charCode = charStr.charCodeAt(end);
    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
      var size = this.surrogateSize;
      this.charLength += size;
      this.charReceived += size;
      this.charBuffer.copy(this.charBuffer, size, 0, size);
      buffer.copy(this.charBuffer, 0, 0, size);
      return charStr.substring(0, end);
    }
  
    // or just emit the charStr
    return charStr;
  };
  
  // detectIncompleteChar determines if there is an incomplete UTF-8 character at
  // the end of the given buffer. If so, it sets this.charLength to the byte
  // length that character, and sets this.charReceived to the number of bytes
  // that are available for this character.
  StringDecoder.prototype.detectIncompleteChar = function(buffer) {
    // determine how many bytes we have to check at the end of this buffer
    var i = (buffer.length >= 3) ? 3 : buffer.length;
  
    // Figure out if one of the last i bytes of our buffer announces an
    // incomplete char.
    for (; i > 0; i--) {
      var c = buffer[buffer.length - i];
  
      // See http://en.wikipedia.org/wiki/UTF-8#Description
  
      // 110XXXXX
      if (i == 1 && c >> 5 == 0x06) {
        this.charLength = 2;
        break;
      }
  
      // 1110XXXX
      if (i <= 2 && c >> 4 == 0x0E) {
        this.charLength = 3;
        break;
      }
  
      // 11110XXX
      if (i <= 3 && c >> 3 == 0x1E) {
        this.charLength = 4;
        break;
      }
    }
    this.charReceived = i;
  };
  
  StringDecoder.prototype.end = function(buffer) {
    var res = '';
    if (buffer && buffer.length)
      res = this.write(buffer);
  
    if (this.charReceived) {
      var cr = this.charReceived;
      var buf = this.charBuffer;
      var enc = this.encoding;
      res += buf.slice(0, cr).toString(enc);
    }
  
    return res;
  };
  
  function passThroughWrite(buffer) {
    return buffer.toString(this.encoding);
  }
  
  function utf16DetectIncompleteChar(buffer) {
    this.charReceived = buffer.length % 2;
    this.charLength = this.charReceived ? 2 : 0;
  }
  
  function base64DetectIncompleteChar(buffer) {
    this.charReceived = buffer.length % 3;
    this.charLength = this.charReceived ? 3 : 0;
  }
  
  },{"buffer":72}],108:[function(require,module,exports){
  var util = require("util");
  var now = require("date-now");
  
  var _console = {};
  var times = {};
  
  var functions = [
  	['log','info'],
  	['info','info'],
  	['warn','warn'],
  	['error','error']
  ];
  
  functions.forEach(function(tuple) {
  	_console[tuple[0]] = function() {
  		Ti.API[tuple[1]](util.format.apply(util, arguments));
  	};
  });
  
  _console.time = function(label) {
  	times[label] = now();
  };
  
  _console.timeEnd = function(label) {
  	var time = times[label];
  	if (!time) {
  		throw new Error("No such label: " + label);
  	}
  
  	var duration = now() - time;
  	_console.log(label + ": " + duration + "ms");
  };
  
  _console.trace = function() {
  	var err = new Error();
  	err.name = "Trace";
  	err.message = util.format.apply(null, arguments);
  	_console.error(err.stack);
  };
  
  _console.dir = function(object) {
  	_console.log(util.inspect(object) + "\n");
  };
  
  _console.assert = function(expression) {
  	if (!expression) {
  		var arr = Array.prototype.slice.call(arguments, 1);
  		require("assert").ok(false, util.format.apply(null, arr));
  	}
  };
  
  module.exports = _console;
  
  },{"assert":70,"date-now":75,"util":113}],109:[function(require,module,exports){
  
  },{}],110:[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.
  
  var punycode = require('punycode');
  
  exports.parse = urlParse;
  exports.resolve = urlResolve;
  exports.resolveObject = urlResolveObject;
  exports.format = urlFormat;
  
  exports.Url = Url;
  
  function Url() {
    this.protocol = null;
    this.slashes = null;
    this.auth = null;
    this.host = null;
    this.port = null;
    this.hostname = null;
    this.hash = null;
    this.search = null;
    this.query = null;
    this.pathname = null;
    this.path = null;
    this.href = null;
  }
  
  // Reference: RFC 3986, RFC 1808, RFC 2396
  
  // define these here so at least they only have to be
  // compiled once on the first module load.
  var protocolPattern = /^([a-z0-9.+-]+:)/i,
      portPattern = /:[0-9]*$/,
  
      // RFC 2396: characters reserved for delimiting URLs.
      // We actually just auto-escape these.
      delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
  
      // RFC 2396: characters not allowed for various reasons.
      unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
  
      // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
      autoEscape = ['\''].concat(unwise),
      // Characters that are never ever allowed in a hostname.
      // Note that any invalid chars are also handled, but these
      // are the ones that are *expected* to be seen, so we fast-path
      // them.
      nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
      hostEndingChars = ['/', '?', '#'],
      hostnameMaxLen = 255,
      hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
      hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
      // protocols that can allow "unsafe" and "unwise" chars.
      unsafeProtocol = {
        'javascript': true,
        'javascript:': true
      },
      // protocols that never have a hostname.
      hostlessProtocol = {
        'javascript': true,
        'javascript:': true
      },
      // protocols that always contain a // bit.
      slashedProtocol = {
        'http': true,
        'https': true,
        'ftp': true,
        'gopher': true,
        'file': true,
        'http:': true,
        'https:': true,
        'ftp:': true,
        'gopher:': true,
        'file:': true
      },
      querystring = require('querystring');
  
  function urlParse(url, parseQueryString, slashesDenoteHost) {
    if (url && isObject(url) && url instanceof Url) return url;
  
    var u = new Url;
    u.parse(url, parseQueryString, slashesDenoteHost);
    return u;
  }
  
  Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
    if (!isString(url)) {
      throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
    }
  
    var rest = url;
  
    // trim before proceeding.
    // This is to support parse stuff like "  http://foo.com  \n"
    rest = rest.trim();
  
    var proto = protocolPattern.exec(rest);
    if (proto) {
      proto = proto[0];
      var lowerProto = proto.toLowerCase();
      this.protocol = lowerProto;
      rest = rest.substr(proto.length);
    }
  
    // figure out if it's got a host
    // user@server is *always* interpreted as a hostname, and url
    // resolution will treat //foo/bar as host=foo,path=bar because that's
    // how the browser resolves relative URLs.
    if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
      var slashes = rest.substr(0, 2) === '//';
      if (slashes && !(proto && hostlessProtocol[proto])) {
        rest = rest.substr(2);
        this.slashes = true;
      }
    }
  
    if (!hostlessProtocol[proto] &&
        (slashes || (proto && !slashedProtocol[proto]))) {
  
      // there's a hostname.
      // the first instance of /, ?, ;, or # ends the host.
      //
      // If there is an @ in the hostname, then non-host chars *are* allowed
      // to the left of the last @ sign, unless some host-ending character
      // comes *before* the @-sign.
      // URLs are obnoxious.
      //
      // ex:
      // http://a@b@c/ => user:a@b host:c
      // http://a@b?@c => user:a host:c path:/?@c
  
      // v0.12 TODO(isaacs): This is not quite how Chrome does things.
      // Review our test case against browsers more comprehensively.
  
      // find the first instance of any hostEndingChars
      var hostEnd = -1;
      for (var i = 0; i < hostEndingChars.length; i++) {
        var hec = rest.indexOf(hostEndingChars[i]);
        if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
          hostEnd = hec;
      }
  
      // at this point, either we have an explicit point where the
      // auth portion cannot go past, or the last @ char is the decider.
      var auth, atSign;
      if (hostEnd === -1) {
        // atSign can be anywhere.
        atSign = rest.lastIndexOf('@');
      } else {
        // atSign must be in auth portion.
        // http://a@b/c@d => host:b auth:a path:/c@d
        atSign = rest.lastIndexOf('@', hostEnd);
      }
  
      // Now we have a portion which is definitely the auth.
      // Pull that off.
      if (atSign !== -1) {
        auth = rest.slice(0, atSign);
        rest = rest.slice(atSign + 1);
        this.auth = decodeURIComponent(auth);
      }
  
      // the host is the remaining to the left of the first non-host char
      hostEnd = -1;
      for (var i = 0; i < nonHostChars.length; i++) {
        var hec = rest.indexOf(nonHostChars[i]);
        if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
          hostEnd = hec;
      }
      // if we still have not hit it, then the entire thing is a host.
      if (hostEnd === -1)
        hostEnd = rest.length;
  
      this.host = rest.slice(0, hostEnd);
      rest = rest.slice(hostEnd);
  
      // pull out port.
      this.parseHost();
  
      // we've indicated that there is a hostname,
      // so even if it's empty, it has to be present.
      this.hostname = this.hostname || '';
  
      // if hostname begins with [ and ends with ]
      // assume that it's an IPv6 address.
      var ipv6Hostname = this.hostname[0] === '[' &&
          this.hostname[this.hostname.length - 1] === ']';
  
      // validate a little.
      if (!ipv6Hostname) {
        var hostparts = this.hostname.split(/\./);
        for (var i = 0, l = hostparts.length; i < l; i++) {
          var part = hostparts[i];
          if (!part) continue;
          if (!part.match(hostnamePartPattern)) {
            var newpart = '';
            for (var j = 0, k = part.length; j < k; j++) {
              if (part.charCodeAt(j) > 127) {
                // we replace non-ASCII char with a temporary placeholder
                // we need this to make sure size of hostname is not
                // broken by replacing non-ASCII by nothing
                newpart += 'x';
              } else {
                newpart += part[j];
              }
            }
            // we test again with ASCII char only
            if (!newpart.match(hostnamePartPattern)) {
              var validParts = hostparts.slice(0, i);
              var notHost = hostparts.slice(i + 1);
              var bit = part.match(hostnamePartStart);
              if (bit) {
                validParts.push(bit[1]);
                notHost.unshift(bit[2]);
              }
              if (notHost.length) {
                rest = '/' + notHost.join('.') + rest;
              }
              this.hostname = validParts.join('.');
              break;
            }
          }
        }
      }
  
      if (this.hostname.length > hostnameMaxLen) {
        this.hostname = '';
      } else {
        // hostnames are always lower case.
        this.hostname = this.hostname.toLowerCase();
      }
  
      if (!ipv6Hostname) {
        // IDNA Support: Returns a puny coded representation of "domain".
        // It only converts the part of the domain name that
        // has non ASCII characters. I.e. it dosent matter if
        // you call it with a domain that already is in ASCII.
        var domainArray = this.hostname.split('.');
        var newOut = [];
        for (var i = 0; i < domainArray.length; ++i) {
          var s = domainArray[i];
          newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
              'xn--' + punycode.encode(s) : s);
        }
        this.hostname = newOut.join('.');
      }
  
      var p = this.port ? ':' + this.port : '';
      var h = this.hostname || '';
      this.host = h + p;
      this.href += this.host;
  
      // strip [ and ] from the hostname
      // the host field still retains them, though
      if (ipv6Hostname) {
        this.hostname = this.hostname.substr(1, this.hostname.length - 2);
        if (rest[0] !== '/') {
          rest = '/' + rest;
        }
      }
    }
  
    // now rest is set to the post-host stuff.
    // chop off any delim chars.
    if (!unsafeProtocol[lowerProto]) {
  
      // First, make 100% sure that any "autoEscape" chars get
      // escaped, even if encodeURIComponent doesn't think they
      // need to be.
      for (var i = 0, l = autoEscape.length; i < l; i++) {
        var ae = autoEscape[i];
        var esc = encodeURIComponent(ae);
        if (esc === ae) {
          esc = escape(ae);
        }
        rest = rest.split(ae).join(esc);
      }
    }
  
  
    // chop off from the tail first.
    var hash = rest.indexOf('#');
    if (hash !== -1) {
      // got a fragment string.
      this.hash = rest.substr(hash);
      rest = rest.slice(0, hash);
    }
    var qm = rest.indexOf('?');
    if (qm !== -1) {
      this.search = rest.substr(qm);
      this.query = rest.substr(qm + 1);
      if (parseQueryString) {
        this.query = querystring.parse(this.query);
      }
      rest = rest.slice(0, qm);
    } else if (parseQueryString) {
      // no query string, but parseQueryString still requested
      this.search = '';
      this.query = {};
    }
    if (rest) this.pathname = rest;
    if (slashedProtocol[lowerProto] &&
        this.hostname && !this.pathname) {
      this.pathname = '/';
    }
  
    //to support http.request
    if (this.pathname || this.search) {
      var p = this.pathname || '';
      var s = this.search || '';
      this.path = p + s;
    }
  
    // finally, reconstruct the href based on what has been validated.
    this.href = this.format();
    return this;
  };
  
  // format a parsed object into a url string
  function urlFormat(obj) {
    // ensure it's an object, and not a string url.
    // If it's an obj, this is a no-op.
    // this way, you can call url_format() on strings
    // to clean up potentially wonky urls.
    if (isString(obj)) obj = urlParse(obj);
    if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
    return obj.format();
  }
  
  Url.prototype.format = function() {
    var auth = this.auth || '';
    if (auth) {
      auth = encodeURIComponent(auth);
      auth = auth.replace(/%3A/i, ':');
      auth += '@';
    }
  
    var protocol = this.protocol || '',
        pathname = this.pathname || '',
        hash = this.hash || '',
        host = false,
        query = '';
  
    if (this.host) {
      host = auth + this.host;
    } else if (this.hostname) {
      host = auth + (this.hostname.indexOf(':') === -1 ?
          this.hostname :
          '[' + this.hostname + ']');
      if (this.port) {
        host += ':' + this.port;
      }
    }
  
    if (this.query &&
        isObject(this.query) &&
        Object.keys(this.query).length) {
      query = querystring.stringify(this.query);
    }
  
    var search = this.search || (query && ('?' + query)) || '';
  
    if (protocol && protocol.substr(-1) !== ':') protocol += ':';
  
    // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
    // unless they had them to begin with.
    if (this.slashes ||
        (!protocol || slashedProtocol[protocol]) && host !== false) {
      host = '//' + (host || '');
      if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
    } else if (!host) {
      host = '';
    }
  
    if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
    if (search && search.charAt(0) !== '?') search = '?' + search;
  
    pathname = pathname.replace(/[?#]/g, function(match) {
      return encodeURIComponent(match);
    });
    search = search.replace('#', '%23');
  
    return protocol + host + pathname + search + hash;
  };
  
  function urlResolve(source, relative) {
    return urlParse(source, false, true).resolve(relative);
  }
  
  Url.prototype.resolve = function(relative) {
    return this.resolveObject(urlParse(relative, false, true)).format();
  };
  
  function urlResolveObject(source, relative) {
    if (!source) return relative;
    return urlParse(source, false, true).resolveObject(relative);
  }
  
  Url.prototype.resolveObject = function(relative) {
    if (isString(relative)) {
      var rel = new Url();
      rel.parse(relative, false, true);
      relative = rel;
    }
  
    var result = new Url();
    Object.keys(this).forEach(function(k) {
      result[k] = this[k];
    }, this);
  
    // hash is always overridden, no matter what.
    // even href="" will remove it.
    result.hash = relative.hash;
  
    // if the relative url is empty, then there's nothing left to do here.
    if (relative.href === '') {
      result.href = result.format();
      return result;
    }
  
    // hrefs like //foo/bar always cut to the protocol.
    if (relative.slashes && !relative.protocol) {
      // take everything except the protocol from relative
      Object.keys(relative).forEach(function(k) {
        if (k !== 'protocol')
          result[k] = relative[k];
      });
  
      //urlParse appends trailing / to urls like http://www.example.com
      if (slashedProtocol[result.protocol] &&
          result.hostname && !result.pathname) {
        result.path = result.pathname = '/';
      }
  
      result.href = result.format();
      return result;
    }
  
    if (relative.protocol && relative.protocol !== result.protocol) {
      // if it's a known url protocol, then changing
      // the protocol does weird things
      // first, if it's not file:, then we MUST have a host,
      // and if there was a path
      // to begin with, then we MUST have a path.
      // if it is file:, then the host is dropped,
      // because that's known to be hostless.
      // anything else is assumed to be absolute.
      if (!slashedProtocol[relative.protocol]) {
        Object.keys(relative).forEach(function(k) {
          result[k] = relative[k];
        });
        result.href = result.format();
        return result;
      }
  
      result.protocol = relative.protocol;
      if (!relative.host && !hostlessProtocol[relative.protocol]) {
        var relPath = (relative.pathname || '').split('/');
        while (relPath.length && !(relative.host = relPath.shift()));
        if (!relative.host) relative.host = '';
        if (!relative.hostname) relative.hostname = '';
        if (relPath[0] !== '') relPath.unshift('');
        if (relPath.length < 2) relPath.unshift('');
        result.pathname = relPath.join('/');
      } else {
        result.pathname = relative.pathname;
      }
      result.search = relative.search;
      result.query = relative.query;
      result.host = relative.host || '';
      result.auth = relative.auth;
      result.hostname = relative.hostname || relative.host;
      result.port = relative.port;
      // to support http.request
      if (result.pathname || result.search) {
        var p = result.pathname || '';
        var s = result.search || '';
        result.path = p + s;
      }
      result.slashes = result.slashes || relative.slashes;
      result.href = result.format();
      return result;
    }
  
    var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
        isRelAbs = (
            relative.host ||
            relative.pathname && relative.pathname.charAt(0) === '/'
        ),
        mustEndAbs = (isRelAbs || isSourceAbs ||
                      (result.host && relative.pathname)),
        removeAllDots = mustEndAbs,
        srcPath = result.pathname && result.pathname.split('/') || [],
        relPath = relative.pathname && relative.pathname.split('/') || [],
        psychotic = result.protocol && !slashedProtocol[result.protocol];
  
    // if the url is a non-slashed url, then relative
    // links like ../.. should be able
    // to crawl up to the hostname, as well.  This is strange.
    // result.protocol has already been set by now.
    // Later on, put the first path part into the host field.
    if (psychotic) {
      result.hostname = '';
      result.port = null;
      if (result.host) {
        if (srcPath[0] === '') srcPath[0] = result.host;
        else srcPath.unshift(result.host);
      }
      result.host = '';
      if (relative.protocol) {
        relative.hostname = null;
        relative.port = null;
        if (relative.host) {
          if (relPath[0] === '') relPath[0] = relative.host;
          else relPath.unshift(relative.host);
        }
        relative.host = null;
      }
      mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
    }
  
    if (isRelAbs) {
      // it's absolute.
      result.host = (relative.host || relative.host === '') ?
                    relative.host : result.host;
      result.hostname = (relative.hostname || relative.hostname === '') ?
                        relative.hostname : result.hostname;
      result.search = relative.search;
      result.query = relative.query;
      srcPath = relPath;
      // fall through to the dot-handling below.
    } else if (relPath.length) {
      // it's relative
      // throw away the existing file, and take the new path instead.
      if (!srcPath) srcPath = [];
      srcPath.pop();
      srcPath = srcPath.concat(relPath);
      result.search = relative.search;
      result.query = relative.query;
    } else if (!isNullOrUndefined(relative.search)) {
      // just pull out the search.
      // like href='?foo'.
      // Put this after the other two cases because it simplifies the booleans
      if (psychotic) {
        result.hostname = result.host = srcPath.shift();
        //occationaly the auth can get stuck only in host
        //this especialy happens in cases like
        //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
        var authInHost = result.host && result.host.indexOf('@') > 0 ?
                         result.host.split('@') : false;
        if (authInHost) {
          result.auth = authInHost.shift();
          result.host = result.hostname = authInHost.shift();
        }
      }
      result.search = relative.search;
      result.query = relative.query;
      //to support http.request
      if (!isNull(result.pathname) || !isNull(result.search)) {
        result.path = (result.pathname ? result.pathname : '') +
                      (result.search ? result.search : '');
      }
      result.href = result.format();
      return result;
    }
  
    if (!srcPath.length) {
      // no path at all.  easy.
      // we've already handled the other stuff above.
      result.pathname = null;
      //to support http.request
      if (result.search) {
        result.path = '/' + result.search;
      } else {
        result.path = null;
      }
      result.href = result.format();
      return result;
    }
  
    // if a url ENDs in . or .., then it must get a trailing slash.
    // however, if it ends in anything else non-slashy,
    // then it must NOT get a trailing slash.
    var last = srcPath.slice(-1)[0];
    var hasTrailingSlash = (
        (result.host || relative.host) && (last === '.' || last === '..') ||
        last === '');
  
    // strip single dots, resolve double dots to parent dir
    // if the path tries to go above the root, `up` ends up > 0
    var up = 0;
    for (var i = srcPath.length; i >= 0; i--) {
      last = srcPath[i];
      if (last == '.') {
        srcPath.splice(i, 1);
      } else if (last === '..') {
        srcPath.splice(i, 1);
        up++;
      } else if (up) {
        srcPath.splice(i, 1);
        up--;
      }
    }
  
    // if the path is allowed to go above the root, restore leading ..s
    if (!mustEndAbs && !removeAllDots) {
      for (; up--; up) {
        srcPath.unshift('..');
      }
    }
  
    if (mustEndAbs && srcPath[0] !== '' &&
        (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
      srcPath.unshift('');
    }
  
    if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
      srcPath.push('');
    }
  
    var isAbsolute = srcPath[0] === '' ||
        (srcPath[0] && srcPath[0].charAt(0) === '/');
  
    // put the host back
    if (psychotic) {
      result.hostname = result.host = isAbsolute ? '' :
                                      srcPath.length ? srcPath.shift() : '';
      //occationaly the auth can get stuck only in host
      //this especialy happens in cases like
      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
      var authInHost = result.host && result.host.indexOf('@') > 0 ?
                       result.host.split('@') : false;
      if (authInHost) {
        result.auth = authInHost.shift();
        result.host = result.hostname = authInHost.shift();
      }
    }
  
    mustEndAbs = mustEndAbs || (result.host && srcPath.length);
  
    if (mustEndAbs && !isAbsolute) {
      srcPath.unshift('');
    }
  
    if (!srcPath.length) {
      result.pathname = null;
      result.path = null;
    } else {
      result.pathname = srcPath.join('/');
    }
  
    //to support request.http
    if (!isNull(result.pathname) || !isNull(result.search)) {
      result.path = (result.pathname ? result.pathname : '') +
                    (result.search ? result.search : '');
    }
    result.auth = relative.auth || result.auth;
    result.slashes = result.slashes || relative.slashes;
    result.href = result.format();
    return result;
  };
  
  Url.prototype.parseHost = function() {
    var host = this.host;
    var port = portPattern.exec(host);
    if (port) {
      port = port[0];
      if (port !== ':') {
        this.port = port.substr(1);
      }
      host = host.substr(0, host.length - port.length);
    }
    if (host) this.hostname = host;
  };
  
  function isString(arg) {
    return typeof arg === "string";
  }
  
  function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
  }
  
  function isNull(arg) {
    return arg === null;
  }
  function isNullOrUndefined(arg) {
    return  arg == null;
  }
  
  },{"punycode":88,"querystring":91}],111:[function(require,module,exports){
  (function (global,console){
  
  /**
   * Module exports.
   */
  
  module.exports = deprecate;
  
  /**
   * Mark that a method should not be used.
   * Returns a modified function which warns once by default.
   *
   * If `localStorage.noDeprecation = true` is set, then it is a no-op.
   *
   * If `localStorage.throwDeprecation = true` is set, then deprecated functions
   * will throw an Error when invoked.
   *
   * If `localStorage.traceDeprecation = true` is set, then deprecated functions
   * will invoke `console.trace()` instead of `console.error()`.
   *
   * @param {Function} fn - the function to deprecate
   * @param {String} msg - the string to print to the console when `fn` is invoked
   * @returns {Function} a new "deprecated" version of `fn`
   * @api public
   */
  
  function deprecate (fn, msg) {
    if (config('noDeprecation')) {
      return fn;
    }
  
    var warned = false;
    function deprecated() {
      if (!warned) {
        if (config('throwDeprecation')) {
          throw new Error(msg);
        } else if (config('traceDeprecation')) {
          console.trace(msg);
        } else {
          console.warn(msg);
        }
        warned = true;
      }
      return fn.apply(this, arguments);
    }
  
    return deprecated;
  }
  
  /**
   * Checks `localStorage` for boolean values for the given `name`.
   *
   * @param {String} name
   * @returns {Boolean}
   * @api private
   */
  
  function config (name) {
    // accessing global.localStorage can trigger a DOMException in sandboxed iframes
    try {
      if (!global.localStorage) return false;
    } catch (_) {
      return false;
    }
    var val = global.localStorage[name];
    if (null == val) return false;
    return String(val).toLowerCase() === 'true';
  }
  
  }).call(this,require("--global--"),require("--console--"))
  },{"--console--":108,"--global--":67}],112:[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';
  }
  },{}],113:[function(require,module,exports){
  (function (process,global,console){
  // 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--"),require("--global--"),require("--console--"))
  },{"--console--":108,"--global--":67,"--process--":68,"./support/isBuffer":112,"inherits":81}],114:[function(require,module,exports){
  module.exports = extend
  
  var hasOwnProperty = Object.prototype.hasOwnProperty;
  
  function extend() {
      var target = {}
  
      for (var i = 0; i < arguments.length; i++) {
          var source = arguments[i]
  
          for (var key in source) {
              if (hasOwnProperty.call(source, key)) {
                  target[key] = source[key]
              }
          }
      }
  
      return target
  }
  
  },{}]},{},[32])(32)
  });