docs: function (Vue) {
    var ref = Vue.util;
    var extend = ref.extend;
  
    return {
      data: function data () {
        return {
          valid: true,
          dirty: false,
          touched: false,
          modified: false,
          results: {}
        }
      },
      computed: {
        invalid: function invalid () { return !this.valid },
        pristine: function pristine () { return !this.dirty },
        untouched: function untouched () { return !this.touched },
        result: function result () {
          var ret = {
            valid: this.valid,
            invalid: this.invalid,
            dirty: this.dirty,
            pristine: this.pristine,
            touched: this.touched,
            untouched: this.untouched,
            modified: this.modified
          };
          var results = this.results;
          this._validityKeys.forEach(function (key) {
            ret[key] = results[key];
            if (ret[key].errors) {
              var errors = ret.errors || [];
              ret[key].errors.forEach(function (error) {
                errors.push(error);
              });
              ret.errors = errors;
            }
          });
          return ret
        }
      },
      watch: {
        results: function results (val, old) {
          var keys = this._validityKeys;
          var results = this.results;
          this.valid = this.checkResults(keys, results, 'valid', true);
          this.dirty = this.checkResults(keys, results, 'dirty', false);
          this.touched = this.checkResults(keys, results, 'touched', false);
          this.modified = this.checkResults(keys, results, 'modified', false);
        }
      },
      created: function created () {
        this._validities = Object.create(null);
        this._validityWatchers = Object.create(null);
        this._validityKeys = [];
        this._committing = false;
      },
      destroyed: function destroyed () {
        var this$1 = this;
  
        this._validityKeys.forEach(function (key) {
          this$1._validityWatchers[key]();
          delete this$1._validityWatchers[key];
          delete this$1._validities[key];
        });
        delete this._validityWatchers;
        delete this._validities;
        delete this._validityKeys;
      },
      methods: {
        register: function register (name, validity) {
          var this$1 = this;
  
          this._validities[name] = validity;
          this._validityKeys = Object.keys(this._validities);
          this.setResults(name, {});
          this.withCommit(function () {
            this$1._validityWatchers[name] = validity.$watch('result', function (val, old) {
              this$1.setResults(name, val);
            }, { deep: true, immediate: true });
          });
        },
        unregister: function unregister (name) {
          var this$1 = this;
  
          this._validityWatchers[name]();
          delete this._validityWatchers[name];
          delete this._validities[name];
          this._validityKeys = Object.keys(this._validities);
          this.withCommit(function () {
            this$1.resetResults(name);
          });
        },
        validityCount: function validityCount () {
          return this._validityKeys.length
        },
        isRegistered: function isRegistered (name) {
          return name in this._validities
        },
        getValidityKeys: function getValidityKeys () {
          return this._validityKeys
        },
        checkResults: function checkResults (
          keys,
          results,
          prop,
          checking
        ) {
          var ret = checking;
          for (var i = 0; i < keys.length; i++) {
            var result = results[keys[i]];
            if (result[prop] !== checking) {
              ret = !checking;
              break
            }
          }
          return ret
        },
        setResults: function setResults (name, val) {
          var this$1 = this;
  
          var newVal = {};
          this._validityKeys.forEach(function (key) {
            newVal[key] = extend({}, this$1.results[key]);
          });
          newVal[name] = extend({}, val);
          this.results = newVal;
        },
        resetResults: function resetResults (ignore) {
          var this$1 = this;
  
          var newVal = {};
          this._validityKeys.forEach(function (key) {
            if (ignore && ignore !== key) {
              newVal[key] = extend({}, this$1.results[key]);
            }
          });
          this.results = newVal;
        },
        withCommit: function withCommit (fn) {
          var committing = this._committing;
          this._committing = true;
          fn();
          this._committing = committing;
        }
      }
    }
  }