docs: function(file, settings) {
  
      if (!file instanceof Blob) {
          return;
      }
  
      if (settings.name == null) {
          settings.filename = file.name;
      }
  
      this.events = [];
  
      var _self = this;
  
      this.setSettings(settings);
      var BYTE_SIZE = this.settings.maxChunkSize;
      this.paused = !this.settings.autoStart;
      this.bytesLoaded = 0;
      this.bytesTotal = file.size;
      this.file = file;
      this.startTime = null;
      this.endTime = null;
      this.chunk = 0;
      this.chunks = Math.ceil(_self.bytesTotal / BYTE_SIZE);
  
      var upload = function() {
        var _self = this;
          if (!_self.settings.url) {
              return;
          }
  
          if (!_self.paused) {
              if (_self.bytesLoaded < _self.bytesTotal) {
                  ++_self.chunk;
                  
                  var xhr = new XMLHttpRequest();
                  xhr.open(_self.settings.method, _self.settings.url);
  
                  xhr.addEventListener('error', function(e) {
                      _self.dispatchEvent(new FileUploadEvent('error', {
                          bytesLoaded: _self.bytesLoaded,
                          bytesTotal: _self.bytesTotal,
                          filename: _self.settings.filename,
                          file: _self.file,
                          data: typeof e.response === 'string' ? JSON.parse(e.response) : e.response,
                          header: e.responseHeaders
                      }));
                  });
                  
                  xhr.addEventListener('loadstart', function(e) {
                    if (!!e.currentTarget.upload && !!e.currentTarget.upload.addEventListener) {
                      e.currentTarget.upload.addEventListener('progress', function(ue) {
                        var p = ue.loaded / ue.total;
                        _self.bytesLoaded = ((BYTE_SIZE * _self.chunk) * p);
                        if (_self.bytesLoaded > _self.bytesTotal) {
                          _self.bytesLoaded = _self.bytesTotal;
                        }
                        _self.dispatchEvent(new FileUploadEvent('progress', {
                          bytesLoaded: _self.bytesLoaded,
                          bytesTotal: _self.bytesTotal,
                          filename: _self.settings.filename,
                          file: _self.file
                          }));
                        });
                    }
                    });
  
                  xhr.addEventListener('load', function (e) {
                      var xhr = e.currentTarget;
                      
                      if (xhr.status < 200 || xhr.status >= 400) {
                        _self.dispatchEvent(new FileUploadEvent('error', {
                              bytesLoaded: _self.bytesLoaded,
                              bytesTotal: _self.bytesTotal,
                              filename: _self.settings.filename,
                              file: _self.file,
                              data: typeof e.response === 'string' ? JSON.parse(e.response) : e.response,
                              header: e.responseHeaders
                          }));
                        return;
                      }
                      
                      _self.bytesLoaded = BYTE_SIZE * _self.chunk;
                      if (_self.bytesLoaded > _self.bytesTotal) {
                        _self.bytesLoaded = _self.bytesTotal;
                      }
                      
                      _self.dispatchEvent(new FileUploadEvent('progress', {
                          bytesLoaded: _self.bytesLoaded,
                          bytesTotal: _self.bytesTotal,
                          filename: _self.settings.filename,
                          file: _self.file,
                          duration: new Date().getTime() - _self.startTime
                      }));
  
                      if (_self.chunk < _self.chunks) {
                        if (!_self.paused) {
                          upload.apply(_self);
                        }
                      }
                      else {
                          _self.endTime = new Date().getTime();
                          _self.dispatchEvent(new FileUploadEvent('complete', {
                            bytesLoaded: _self.bytesLoaded,
                            bytesTotal: _self.bytesTotal,
                            filename: _self.settings.filename,
                            file: _self.file,
                            duration: _self.endTime - _self.startTime,
                            data: xhr.getResponseHeader('Content-Type').indexOf('json') > -1 && typeof xhr.response === 'string' ? JSON.parse(xhr.response) : xhr.response,
                            header: xhr.responseHeaders
                        }));
                      }
                  });
  
                  var fd = new FormData();
                  fd.append('filename', _self.settings.filename);
                  fd.append(_self.settings.chunkParameter, _self.chunk);
                  fd.append(_self.settings.chunksParameter, _self.chunks);
                  fd.append(_self.settings.formFileField, _self.file.slice(_self.bytesLoaded, _self.bytesLoaded + BYTE_SIZE), _self.settings.filename);
  
                  xhr.send(fd);
              }
          }
      };
  
      this.start = function() {
          this.paused = false;
          var now = new Date().getTime();
          if (this.startTime === null) {
              this.startTime = now;
          }
          else {
              this.startTime = now - (this.endTime - this.startTime);
          }
  
          this.dispatchEvent(new FileUploadEvent('start', {
              bytesLoaded: this.bytesLoaded,
              bytesTotal: this.bytesTotal,
              filename: this.settings.filename,
              file: this.file
          }));
          
          upload.apply(this);
  
          return this;
      };
  
      this.pause = function() {
          this.paused = true;
          this.endTime = new Date().getTime();
  
          this.dispatchEvent(new FileUploadEvent('pause', {
              bytesLoaded: this.bytesLoaded,
              bytesTotal: this.bytesTotal,
              filename: this.settings.filename,
              file: this.file
          }));
  
          return this;
      };
  
      this.reset = function() {
          var paused = this.paused;
          this.pause();
          this.chunk = 0;
          this.bytesLoaded = 0;
          this.startTime = new Date().getTime();
  
          if (!paused) {
              this.start();
          }
  
          return this;
      }
  
      this.uuid = uuid();
  
      if (!this.paused) {
          this.start();
      }
  }