docs: function (Vue) {
    var ref = Vue.util;
    var isPlainObject = ref.isPlainObject;
  
    function getValue (options) {
      return this._elementable.getValue()
    }
  
    function checkModified () {
      return this._elementable.checkModified()
    }
  
    function willUpdateTouched (options) {
      if (!this.touched) {
        this.touched = true;
        toggleClasses(this.$el, this.classes.touched, addClass);
        toggleClasses(this.$el, this.classes.untouched, removeClass);
        this._fireEvent('touched');
      }
    }
  
    function willUpdateDirty () {
      if (!this.dirty && this.checkModified()) {
        this.dirty = true;
        toggleClasses(this.$el, this.classes.dirty, addClass);
        toggleClasses(this.$el, this.classes.pristine, removeClass);
        this._fireEvent('dirty');
      }
    }
  
    function willUpdateModified () {
      var modified = this.modified = this.checkModified();
      if (this._modified !== modified) {
        this._modified = modified;
        toggleClasses(this.$el, this.classes.modified, modified ? addClass : removeClass);
        this._fireEvent('modified', modified);
      }
    }
  
    function handleInputable (e) {
      this.willUpdateDirty();
      this.willUpdateModified();
    }
  
    function watchInputable (val) {
      this.willUpdateDirty();
      this.willUpdateModified();
    }
  
    function _initStates (keys, target, init) {
      if ( init === void 0 ) init = undefined;
  
      for (var i = 0; i < keys.length; i++) {
        var result = target[keys[i]];
        if (isPlainObject(result)) {
          var nestedKeys = Object.keys(result);
          _initStates(nestedKeys, result, init);
        } else {
          target[keys[i]] = init;
        }
      }
    }
  
    function reset () {
      this._unwatchValidationRawResults();
      var keys = this._keysCached(this._uid.toString(), this.results);
      _initStates(keys, this.results, undefined);
      _initStates(keys, this.progresses, '');
      toggleClasses(this.$el, this.classes.valid, removeClass);
      toggleClasses(this.$el, this.classes.invalid, removeClass);
      toggleClasses(this.$el, this.classes.touched, removeClass);
      toggleClasses(this.$el, this.classes.untouched, addClass);
      toggleClasses(this.$el, this.classes.dirty, removeClass);
      toggleClasses(this.$el, this.classes.pristine, addClass);
      toggleClasses(this.$el, this.classes.modified, removeClass);
      this.valid = true;
      this.dirty = false;
      this.touched = false;
      this.modified = false;
      this._modified = false;
      this._watchValidationRawResults();
    }
  
    function _walkValid (keys, target) {
      var valid = true;
      for (var i = 0; i < keys.length; i++) {
        var result = target[keys[i]];
        if (typeof result === 'boolean' && !result) {
          valid = false;
          break
        }
        if (typeof result === 'string' && result) {
          valid = false;
          break
        }
        if (isPlainObject(result)) {
          var nestedKeys = Object.keys(result);
          valid = _walkValid(nestedKeys, result);
          if (!valid) {
            break
          }
        }
      }
      return valid
    }
  
    function _watchValidationRawResults () {
      var this$1 = this;
  
      this._unwatchResults = this.$watch('results', function (val) {
        this$1.valid = _walkValid(
          this$1._keysCached(this$1._uid.toString(), this$1.results),
          this$1.results
        );
        if (this$1.valid) {
          toggleClasses(this$1.$el, this$1.classes.valid, addClass);
          toggleClasses(this$1.$el, this$1.classes.invalid, removeClass);
        } else {
          toggleClasses(this$1.$el, this$1.classes.valid, removeClass);
          toggleClasses(this$1.$el, this$1.classes.invalid, addClass);
        }
  
        this$1._fireEvent(this$1.valid ? 'valid' : 'invalid');
      }, { deep: true });
    }
  
    function _unwatchValidationRawResults () {
      this._unwatchResults();
      this._unwatchResults = undefined;
      delete this._unwatchResults;
    }
  
    function touch () {
      this.willUpdateTouched();
    }
  
    return {
      getValue: getValue,
      checkModified: checkModified,
      willUpdateTouched: willUpdateTouched,
      willUpdateDirty: willUpdateDirty,
      willUpdateModified: willUpdateModified,
      handleInputable: handleInputable,
      watchInputable: watchInputable,
      reset: reset,
      _walkValid: _walkValid,
      _watchValidationRawResults: _watchValidationRawResults,
      _unwatchValidationRawResults: _unwatchValidationRawResults,
      touch: touch
    }
  }