github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/dist/vue.common.js (about)

     1  /*!
     2   * Vue.js v1.0.24
     3   * (c) 2016 Evan You
     4   * Released under the MIT License.
     5   */
     6  'use strict';
     7  
     8  function set(obj, key, val) {
     9    if (hasOwn(obj, key)) {
    10      obj[key] = val;
    11      return;
    12    }
    13    if (obj._isVue) {
    14      set(obj._data, key, val);
    15      return;
    16    }
    17    var ob = obj.__ob__;
    18    if (!ob) {
    19      obj[key] = val;
    20      return;
    21    }
    22    ob.convert(key, val);
    23    ob.dep.notify();
    24    if (ob.vms) {
    25      var i = ob.vms.length;
    26      while (i--) {
    27        var vm = ob.vms[i];
    28        vm._proxy(key);
    29        vm._digest();
    30      }
    31    }
    32    return val;
    33  }
    34  
    35  /**
    36   * Delete a property and trigger change if necessary.
    37   *
    38   * @param {Object} obj
    39   * @param {String} key
    40   */
    41  
    42  function del(obj, key) {
    43    if (!hasOwn(obj, key)) {
    44      return;
    45    }
    46    delete obj[key];
    47    var ob = obj.__ob__;
    48    if (!ob) {
    49      if (obj._isVue) {
    50        delete obj._data[key];
    51        obj._digest();
    52      }
    53      return;
    54    }
    55    ob.dep.notify();
    56    if (ob.vms) {
    57      var i = ob.vms.length;
    58      while (i--) {
    59        var vm = ob.vms[i];
    60        vm._unproxy(key);
    61        vm._digest();
    62      }
    63    }
    64  }
    65  
    66  var hasOwnProperty = Object.prototype.hasOwnProperty;
    67  /**
    68   * Check whether the object has the property.
    69   *
    70   * @param {Object} obj
    71   * @param {String} key
    72   * @return {Boolean}
    73   */
    74  
    75  function hasOwn(obj, key) {
    76    return hasOwnProperty.call(obj, key);
    77  }
    78  
    79  /**
    80   * Check if an expression is a literal value.
    81   *
    82   * @param {String} exp
    83   * @return {Boolean}
    84   */
    85  
    86  var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;
    87  
    88  function isLiteral(exp) {
    89    return literalValueRE.test(exp);
    90  }
    91  
    92  /**
    93   * Check if a string starts with $ or _
    94   *
    95   * @param {String} str
    96   * @return {Boolean}
    97   */
    98  
    99  function isReserved(str) {
   100    var c = (str + '').charCodeAt(0);
   101    return c === 0x24 || c === 0x5F;
   102  }
   103  
   104  /**
   105   * Guard text output, make sure undefined outputs
   106   * empty string
   107   *
   108   * @param {*} value
   109   * @return {String}
   110   */
   111  
   112  function _toString(value) {
   113    return value == null ? '' : value.toString();
   114  }
   115  
   116  /**
   117   * Check and convert possible numeric strings to numbers
   118   * before setting back to data
   119   *
   120   * @param {*} value
   121   * @return {*|Number}
   122   */
   123  
   124  function toNumber(value) {
   125    if (typeof value !== 'string') {
   126      return value;
   127    } else {
   128      var parsed = Number(value);
   129      return isNaN(parsed) ? value : parsed;
   130    }
   131  }
   132  
   133  /**
   134   * Convert string boolean literals into real booleans.
   135   *
   136   * @param {*} value
   137   * @return {*|Boolean}
   138   */
   139  
   140  function toBoolean(value) {
   141    return value === 'true' ? true : value === 'false' ? false : value;
   142  }
   143  
   144  /**
   145   * Strip quotes from a string
   146   *
   147   * @param {String} str
   148   * @return {String | false}
   149   */
   150  
   151  function stripQuotes(str) {
   152    var a = str.charCodeAt(0);
   153    var b = str.charCodeAt(str.length - 1);
   154    return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
   155  }
   156  
   157  /**
   158   * Camelize a hyphen-delmited string.
   159   *
   160   * @param {String} str
   161   * @return {String}
   162   */
   163  
   164  var camelizeRE = /-(\w)/g;
   165  
   166  function camelize(str) {
   167    return str.replace(camelizeRE, toUpper);
   168  }
   169  
   170  function toUpper(_, c) {
   171    return c ? c.toUpperCase() : '';
   172  }
   173  
   174  /**
   175   * Hyphenate a camelCase string.
   176   *
   177   * @param {String} str
   178   * @return {String}
   179   */
   180  
   181  var hyphenateRE = /([a-z\d])([A-Z])/g;
   182  
   183  function hyphenate(str) {
   184    return str.replace(hyphenateRE, '$1-$2').toLowerCase();
   185  }
   186  
   187  /**
   188   * Converts hyphen/underscore/slash delimitered names into
   189   * camelized classNames.
   190   *
   191   * e.g. my-component => MyComponent
   192   *      some_else    => SomeElse
   193   *      some/comp    => SomeComp
   194   *
   195   * @param {String} str
   196   * @return {String}
   197   */
   198  
   199  var classifyRE = /(?:^|[-_\/])(\w)/g;
   200  
   201  function classify(str) {
   202    return str.replace(classifyRE, toUpper);
   203  }
   204  
   205  /**
   206   * Simple bind, faster than native
   207   *
   208   * @param {Function} fn
   209   * @param {Object} ctx
   210   * @return {Function}
   211   */
   212  
   213  function bind(fn, ctx) {
   214    return function (a) {
   215      var l = arguments.length;
   216      return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
   217    };
   218  }
   219  
   220  /**
   221   * Convert an Array-like object to a real Array.
   222   *
   223   * @param {Array-like} list
   224   * @param {Number} [start] - start index
   225   * @return {Array}
   226   */
   227  
   228  function toArray(list, start) {
   229    start = start || 0;
   230    var i = list.length - start;
   231    var ret = new Array(i);
   232    while (i--) {
   233      ret[i] = list[i + start];
   234    }
   235    return ret;
   236  }
   237  
   238  /**
   239   * Mix properties into target object.
   240   *
   241   * @param {Object} to
   242   * @param {Object} from
   243   */
   244  
   245  function extend(to, from) {
   246    var keys = Object.keys(from);
   247    var i = keys.length;
   248    while (i--) {
   249      to[keys[i]] = from[keys[i]];
   250    }
   251    return to;
   252  }
   253  
   254  /**
   255   * Quick object check - this is primarily used to tell
   256   * Objects from primitive values when we know the value
   257   * is a JSON-compliant type.
   258   *
   259   * @param {*} obj
   260   * @return {Boolean}
   261   */
   262  
   263  function isObject(obj) {
   264    return obj !== null && typeof obj === 'object';
   265  }
   266  
   267  /**
   268   * Strict object type check. Only returns true
   269   * for plain JavaScript objects.
   270   *
   271   * @param {*} obj
   272   * @return {Boolean}
   273   */
   274  
   275  var toString = Object.prototype.toString;
   276  var OBJECT_STRING = '[object Object]';
   277  
   278  function isPlainObject(obj) {
   279    return toString.call(obj) === OBJECT_STRING;
   280  }
   281  
   282  /**
   283   * Array type check.
   284   *
   285   * @param {*} obj
   286   * @return {Boolean}
   287   */
   288  
   289  var isArray = Array.isArray;
   290  
   291  /**
   292   * Define a property.
   293   *
   294   * @param {Object} obj
   295   * @param {String} key
   296   * @param {*} val
   297   * @param {Boolean} [enumerable]
   298   */
   299  
   300  function def(obj, key, val, enumerable) {
   301    Object.defineProperty(obj, key, {
   302      value: val,
   303      enumerable: !!enumerable,
   304      writable: true,
   305      configurable: true
   306    });
   307  }
   308  
   309  /**
   310   * Debounce a function so it only gets called after the
   311   * input stops arriving after the given wait period.
   312   *
   313   * @param {Function} func
   314   * @param {Number} wait
   315   * @return {Function} - the debounced function
   316   */
   317  
   318  function _debounce(func, wait) {
   319    var timeout, args, context, timestamp, result;
   320    var later = function later() {
   321      var last = Date.now() - timestamp;
   322      if (last < wait && last >= 0) {
   323        timeout = setTimeout(later, wait - last);
   324      } else {
   325        timeout = null;
   326        result = func.apply(context, args);
   327        if (!timeout) context = args = null;
   328      }
   329    };
   330    return function () {
   331      context = this;
   332      args = arguments;
   333      timestamp = Date.now();
   334      if (!timeout) {
   335        timeout = setTimeout(later, wait);
   336      }
   337      return result;
   338    };
   339  }
   340  
   341  /**
   342   * Manual indexOf because it's slightly faster than
   343   * native.
   344   *
   345   * @param {Array} arr
   346   * @param {*} obj
   347   */
   348  
   349  function indexOf(arr, obj) {
   350    var i = arr.length;
   351    while (i--) {
   352      if (arr[i] === obj) return i;
   353    }
   354    return -1;
   355  }
   356  
   357  /**
   358   * Make a cancellable version of an async callback.
   359   *
   360   * @param {Function} fn
   361   * @return {Function}
   362   */
   363  
   364  function cancellable(fn) {
   365    var cb = function cb() {
   366      if (!cb.cancelled) {
   367        return fn.apply(this, arguments);
   368      }
   369    };
   370    cb.cancel = function () {
   371      cb.cancelled = true;
   372    };
   373    return cb;
   374  }
   375  
   376  /**
   377   * Check if two values are loosely equal - that is,
   378   * if they are plain objects, do they have the same shape?
   379   *
   380   * @param {*} a
   381   * @param {*} b
   382   * @return {Boolean}
   383   */
   384  
   385  function looseEqual(a, b) {
   386    /* eslint-disable eqeqeq */
   387    return a == b || (isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false);
   388    /* eslint-enable eqeqeq */
   389  }
   390  
   391  var hasProto = ('__proto__' in {});
   392  
   393  // Browser environment sniffing
   394  var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
   395  
   396  // detect devtools
   397  var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
   398  
   399  // UA sniffing for working around browser-specific quirks
   400  var UA = inBrowser && window.navigator.userAgent.toLowerCase();
   401  var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
   402  var isAndroid = UA && UA.indexOf('android') > 0;
   403  var isIos = UA && /(iphone|ipad|ipod|ios)/i.test(UA);
   404  var isWechat = UA && UA.indexOf('micromessenger') > 0;
   405  
   406  var transitionProp = undefined;
   407  var transitionEndEvent = undefined;
   408  var animationProp = undefined;
   409  var animationEndEvent = undefined;
   410  
   411  // Transition property/event sniffing
   412  if (inBrowser && !isIE9) {
   413    var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
   414    var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
   415    transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
   416    transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
   417    animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
   418    animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
   419  }
   420  
   421  /**
   422   * Defer a task to execute it asynchronously. Ideally this
   423   * should be executed as a microtask, so we leverage
   424   * MutationObserver if it's available, and fallback to
   425   * setTimeout(0).
   426   *
   427   * @param {Function} cb
   428   * @param {Object} ctx
   429   */
   430  
   431  var nextTick = (function () {
   432    var callbacks = [];
   433    var pending = false;
   434    var timerFunc;
   435    function nextTickHandler() {
   436      pending = false;
   437      var copies = callbacks.slice(0);
   438      callbacks = [];
   439      for (var i = 0; i < copies.length; i++) {
   440        copies[i]();
   441      }
   442    }
   443  
   444    /* istanbul ignore if */
   445    if (typeof MutationObserver !== 'undefined' && !(isWechat && isIos)) {
   446      var counter = 1;
   447      var observer = new MutationObserver(nextTickHandler);
   448      var textNode = document.createTextNode(counter);
   449      observer.observe(textNode, {
   450        characterData: true
   451      });
   452      timerFunc = function () {
   453        counter = (counter + 1) % 2;
   454        textNode.data = counter;
   455      };
   456    } else {
   457      // webpack attempts to inject a shim for setImmediate
   458      // if it is used as a global, so we have to work around that to
   459      // avoid bundling unnecessary code.
   460      var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
   461      timerFunc = context.setImmediate || setTimeout;
   462    }
   463    return function (cb, ctx) {
   464      var func = ctx ? function () {
   465        cb.call(ctx);
   466      } : cb;
   467      callbacks.push(func);
   468      if (pending) return;
   469      pending = true;
   470      timerFunc(nextTickHandler, 0);
   471    };
   472  })();
   473  
   474  var _Set = undefined;
   475  /* istanbul ignore if */
   476  if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
   477    // use native Set when available.
   478    _Set = Set;
   479  } else {
   480    // a non-standard Set polyfill that only works with primitive keys.
   481    _Set = function () {
   482      this.set = Object.create(null);
   483    };
   484    _Set.prototype.has = function (key) {
   485      return this.set[key] !== undefined;
   486    };
   487    _Set.prototype.add = function (key) {
   488      this.set[key] = 1;
   489    };
   490    _Set.prototype.clear = function () {
   491      this.set = Object.create(null);
   492    };
   493  }
   494  
   495  function Cache(limit) {
   496    this.size = 0;
   497    this.limit = limit;
   498    this.head = this.tail = undefined;
   499    this._keymap = Object.create(null);
   500  }
   501  
   502  var p = Cache.prototype;
   503  
   504  /**
   505   * Put <value> into the cache associated with <key>.
   506   * Returns the entry which was removed to make room for
   507   * the new entry. Otherwise undefined is returned.
   508   * (i.e. if there was enough room already).
   509   *
   510   * @param {String} key
   511   * @param {*} value
   512   * @return {Entry|undefined}
   513   */
   514  
   515  p.put = function (key, value) {
   516    var removed;
   517    if (this.size === this.limit) {
   518      removed = this.shift();
   519    }
   520  
   521    var entry = this.get(key, true);
   522    if (!entry) {
   523      entry = {
   524        key: key
   525      };
   526      this._keymap[key] = entry;
   527      if (this.tail) {
   528        this.tail.newer = entry;
   529        entry.older = this.tail;
   530      } else {
   531        this.head = entry;
   532      }
   533      this.tail = entry;
   534      this.size++;
   535    }
   536    entry.value = value;
   537  
   538    return removed;
   539  };
   540  
   541  /**
   542   * Purge the least recently used (oldest) entry from the
   543   * cache. Returns the removed entry or undefined if the
   544   * cache was empty.
   545   */
   546  
   547  p.shift = function () {
   548    var entry = this.head;
   549    if (entry) {
   550      this.head = this.head.newer;
   551      this.head.older = undefined;
   552      entry.newer = entry.older = undefined;
   553      this._keymap[entry.key] = undefined;
   554      this.size--;
   555    }
   556    return entry;
   557  };
   558  
   559  /**
   560   * Get and register recent use of <key>. Returns the value
   561   * associated with <key> or undefined if not in cache.
   562   *
   563   * @param {String} key
   564   * @param {Boolean} returnEntry
   565   * @return {Entry|*}
   566   */
   567  
   568  p.get = function (key, returnEntry) {
   569    var entry = this._keymap[key];
   570    if (entry === undefined) return;
   571    if (entry === this.tail) {
   572      return returnEntry ? entry : entry.value;
   573    }
   574    // HEAD--------------TAIL
   575    //   <.older   .newer>
   576    //  <--- add direction --
   577    //   A  B  C  <D>  E
   578    if (entry.newer) {
   579      if (entry === this.head) {
   580        this.head = entry.newer;
   581      }
   582      entry.newer.older = entry.older; // C <-- E.
   583    }
   584    if (entry.older) {
   585      entry.older.newer = entry.newer; // C. --> E
   586    }
   587    entry.newer = undefined; // D --x
   588    entry.older = this.tail; // D. --> E
   589    if (this.tail) {
   590      this.tail.newer = entry; // E. <-- D
   591    }
   592    this.tail = entry;
   593    return returnEntry ? entry : entry.value;
   594  };
   595  
   596  var cache$1 = new Cache(1000);
   597  var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
   598  var reservedArgRE = /^in$|^-?\d+/;
   599  
   600  /**
   601   * Parser state
   602   */
   603  
   604  var str;
   605  var dir;
   606  var c;
   607  var prev;
   608  var i;
   609  var l;
   610  var lastFilterIndex;
   611  var inSingle;
   612  var inDouble;
   613  var curly;
   614  var square;
   615  var paren;
   616  /**
   617   * Push a filter to the current directive object
   618   */
   619  
   620  function pushFilter() {
   621    var exp = str.slice(lastFilterIndex, i).trim();
   622    var filter;
   623    if (exp) {
   624      filter = {};
   625      var tokens = exp.match(filterTokenRE);
   626      filter.name = tokens[0];
   627      if (tokens.length > 1) {
   628        filter.args = tokens.slice(1).map(processFilterArg);
   629      }
   630    }
   631    if (filter) {
   632      (dir.filters = dir.filters || []).push(filter);
   633    }
   634    lastFilterIndex = i + 1;
   635  }
   636  
   637  /**
   638   * Check if an argument is dynamic and strip quotes.
   639   *
   640   * @param {String} arg
   641   * @return {Object}
   642   */
   643  
   644  function processFilterArg(arg) {
   645    if (reservedArgRE.test(arg)) {
   646      return {
   647        value: toNumber(arg),
   648        dynamic: false
   649      };
   650    } else {
   651      var stripped = stripQuotes(arg);
   652      var dynamic = stripped === arg;
   653      return {
   654        value: dynamic ? arg : stripped,
   655        dynamic: dynamic
   656      };
   657    }
   658  }
   659  
   660  /**
   661   * Parse a directive value and extract the expression
   662   * and its filters into a descriptor.
   663   *
   664   * Example:
   665   *
   666   * "a + 1 | uppercase" will yield:
   667   * {
   668   *   expression: 'a + 1',
   669   *   filters: [
   670   *     { name: 'uppercase', args: null }
   671   *   ]
   672   * }
   673   *
   674   * @param {String} s
   675   * @return {Object}
   676   */
   677  
   678  function parseDirective(s) {
   679    var hit = cache$1.get(s);
   680    if (hit) {
   681      return hit;
   682    }
   683  
   684    // reset parser state
   685    str = s;
   686    inSingle = inDouble = false;
   687    curly = square = paren = 0;
   688    lastFilterIndex = 0;
   689    dir = {};
   690  
   691    for (i = 0, l = str.length; i < l; i++) {
   692      prev = c;
   693      c = str.charCodeAt(i);
   694      if (inSingle) {
   695        // check single quote
   696        if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
   697      } else if (inDouble) {
   698        // check double quote
   699        if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
   700      } else if (c === 0x7C && // pipe
   701      str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
   702        if (dir.expression == null) {
   703          // first filter, end of expression
   704          lastFilterIndex = i + 1;
   705          dir.expression = str.slice(0, i).trim();
   706        } else {
   707          // already has filter
   708          pushFilter();
   709        }
   710      } else {
   711        switch (c) {
   712          case 0x22:
   713            inDouble = true;break; // "
   714          case 0x27:
   715            inSingle = true;break; // '
   716          case 0x28:
   717            paren++;break; // (
   718          case 0x29:
   719            paren--;break; // )
   720          case 0x5B:
   721            square++;break; // [
   722          case 0x5D:
   723            square--;break; // ]
   724          case 0x7B:
   725            curly++;break; // {
   726          case 0x7D:
   727            curly--;break; // }
   728        }
   729      }
   730    }
   731  
   732    if (dir.expression == null) {
   733      dir.expression = str.slice(0, i).trim();
   734    } else if (lastFilterIndex !== 0) {
   735      pushFilter();
   736    }
   737  
   738    cache$1.put(s, dir);
   739    return dir;
   740  }
   741  
   742  var directive = Object.freeze({
   743    parseDirective: parseDirective
   744  });
   745  
   746  var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
   747  var cache = undefined;
   748  var tagRE = undefined;
   749  var htmlRE = undefined;
   750  /**
   751   * Escape a string so it can be used in a RegExp
   752   * constructor.
   753   *
   754   * @param {String} str
   755   */
   756  
   757  function escapeRegex(str) {
   758    return str.replace(regexEscapeRE, '\\$&');
   759  }
   760  
   761  function compileRegex() {
   762    var open = escapeRegex(config.delimiters[0]);
   763    var close = escapeRegex(config.delimiters[1]);
   764    var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
   765    var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
   766    tagRE = new RegExp(unsafeOpen + '((?:.|\\n)+?)' + unsafeClose + '|' + open + '((?:.|\\n)+?)' + close, 'g');
   767    htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
   768    // reset cache
   769    cache = new Cache(1000);
   770  }
   771  
   772  /**
   773   * Parse a template text string into an array of tokens.
   774   *
   775   * @param {String} text
   776   * @return {Array<Object> | null}
   777   *               - {String} type
   778   *               - {String} value
   779   *               - {Boolean} [html]
   780   *               - {Boolean} [oneTime]
   781   */
   782  
   783  function parseText(text) {
   784    if (!cache) {
   785      compileRegex();
   786    }
   787    var hit = cache.get(text);
   788    if (hit) {
   789      return hit;
   790    }
   791    if (!tagRE.test(text)) {
   792      return null;
   793    }
   794    var tokens = [];
   795    var lastIndex = tagRE.lastIndex = 0;
   796    var match, index, html, value, first, oneTime;
   797    /* eslint-disable no-cond-assign */
   798    while (match = tagRE.exec(text)) {
   799      /* eslint-enable no-cond-assign */
   800      index = match.index;
   801      // push text token
   802      if (index > lastIndex) {
   803        tokens.push({
   804          value: text.slice(lastIndex, index)
   805        });
   806      }
   807      // tag token
   808      html = htmlRE.test(match[0]);
   809      value = html ? match[1] : match[2];
   810      first = value.charCodeAt(0);
   811      oneTime = first === 42; // *
   812      value = oneTime ? value.slice(1) : value;
   813      tokens.push({
   814        tag: true,
   815        value: value.trim(),
   816        html: html,
   817        oneTime: oneTime
   818      });
   819      lastIndex = index + match[0].length;
   820    }
   821    if (lastIndex < text.length) {
   822      tokens.push({
   823        value: text.slice(lastIndex)
   824      });
   825    }
   826    cache.put(text, tokens);
   827    return tokens;
   828  }
   829  
   830  /**
   831   * Format a list of tokens into an expression.
   832   * e.g. tokens parsed from 'a {{b}} c' can be serialized
   833   * into one single expression as '"a " + b + " c"'.
   834   *
   835   * @param {Array} tokens
   836   * @param {Vue} [vm]
   837   * @return {String}
   838   */
   839  
   840  function tokensToExp(tokens, vm) {
   841    if (tokens.length > 1) {
   842      return tokens.map(function (token) {
   843        return formatToken(token, vm);
   844      }).join('+');
   845    } else {
   846      return formatToken(tokens[0], vm, true);
   847    }
   848  }
   849  
   850  /**
   851   * Format a single token.
   852   *
   853   * @param {Object} token
   854   * @param {Vue} [vm]
   855   * @param {Boolean} [single]
   856   * @return {String}
   857   */
   858  
   859  function formatToken(token, vm, single) {
   860    return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
   861  }
   862  
   863  /**
   864   * For an attribute with multiple interpolation tags,
   865   * e.g. attr="some-{{thing | filter}}", in order to combine
   866   * the whole thing into a single watchable expression, we
   867   * have to inline those filters. This function does exactly
   868   * that. This is a bit hacky but it avoids heavy changes
   869   * to directive parser and watcher mechanism.
   870   *
   871   * @param {String} exp
   872   * @param {Boolean} single
   873   * @return {String}
   874   */
   875  
   876  var filterRE = /[^|]\|[^|]/;
   877  function inlineFilters(exp, single) {
   878    if (!filterRE.test(exp)) {
   879      return single ? exp : '(' + exp + ')';
   880    } else {
   881      var dir = parseDirective(exp);
   882      if (!dir.filters) {
   883        return '(' + exp + ')';
   884      } else {
   885        return 'this._applyFilters(' + dir.expression + // value
   886        ',null,' + // oldValue (null for read)
   887        JSON.stringify(dir.filters) + // filter descriptors
   888        ',false)'; // write?
   889      }
   890    }
   891  }
   892  
   893  var text = Object.freeze({
   894    compileRegex: compileRegex,
   895    parseText: parseText,
   896    tokensToExp: tokensToExp
   897  });
   898  
   899  var delimiters = ['{{', '}}'];
   900  var unsafeDelimiters = ['{{{', '}}}'];
   901  
   902  var config = Object.defineProperties({
   903  
   904    /**
   905     * Whether to print debug messages.
   906     * Also enables stack trace for warnings.
   907     *
   908     * @type {Boolean}
   909     */
   910  
   911    debug: false,
   912  
   913    /**
   914     * Whether to suppress warnings.
   915     *
   916     * @type {Boolean}
   917     */
   918  
   919    silent: false,
   920  
   921    /**
   922     * Whether to use async rendering.
   923     */
   924  
   925    async: true,
   926  
   927    /**
   928     * Whether to warn against errors caught when evaluating
   929     * expressions.
   930     */
   931  
   932    warnExpressionErrors: true,
   933  
   934    /**
   935     * Whether to allow devtools inspection.
   936     * Disabled by default in production builds.
   937     */
   938  
   939    devtools: process.env.NODE_ENV !== 'production',
   940  
   941    /**
   942     * Internal flag to indicate the delimiters have been
   943     * changed.
   944     *
   945     * @type {Boolean}
   946     */
   947  
   948    _delimitersChanged: true,
   949  
   950    /**
   951     * List of asset types that a component can own.
   952     *
   953     * @type {Array}
   954     */
   955  
   956    _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
   957  
   958    /**
   959     * prop binding modes
   960     */
   961  
   962    _propBindingModes: {
   963      ONE_WAY: 0,
   964      TWO_WAY: 1,
   965      ONE_TIME: 2
   966    },
   967  
   968    /**
   969     * Max circular updates allowed in a batcher flush cycle.
   970     */
   971  
   972    _maxUpdateCount: 100
   973  
   974  }, {
   975    delimiters: { /**
   976                   * Interpolation delimiters. Changing these would trigger
   977                   * the text parser to re-compile the regular expressions.
   978                   *
   979                   * @type {Array<String>}
   980                   */
   981  
   982      get: function get() {
   983        return delimiters;
   984      },
   985      set: function set(val) {
   986        delimiters = val;
   987        compileRegex();
   988      },
   989      configurable: true,
   990      enumerable: true
   991    },
   992    unsafeDelimiters: {
   993      get: function get() {
   994        return unsafeDelimiters;
   995      },
   996      set: function set(val) {
   997        unsafeDelimiters = val;
   998        compileRegex();
   999      },
  1000      configurable: true,
  1001      enumerable: true
  1002    }
  1003  });
  1004  
  1005  var warn = undefined;
  1006  var formatComponentName = undefined;
  1007  
  1008  if (process.env.NODE_ENV !== 'production') {
  1009    (function () {
  1010      var hasConsole = typeof console !== 'undefined';
  1011  
  1012      warn = function (msg, vm) {
  1013        if (hasConsole && !config.silent) {
  1014          console.error('[Vue warn]: ' + msg + (vm ? formatComponentName(vm) : ''));
  1015        }
  1016      };
  1017  
  1018      formatComponentName = function (vm) {
  1019        var name = vm._isVue ? vm.$options.name : vm.name;
  1020        return name ? ' (found in component: <' + hyphenate(name) + '>)' : '';
  1021      };
  1022    })();
  1023  }
  1024  
  1025  /**
  1026   * Append with transition.
  1027   *
  1028   * @param {Element} el
  1029   * @param {Element} target
  1030   * @param {Vue} vm
  1031   * @param {Function} [cb]
  1032   */
  1033  
  1034  function appendWithTransition(el, target, vm, cb) {
  1035    applyTransition(el, 1, function () {
  1036      target.appendChild(el);
  1037    }, vm, cb);
  1038  }
  1039  
  1040  /**
  1041   * InsertBefore with transition.
  1042   *
  1043   * @param {Element} el
  1044   * @param {Element} target
  1045   * @param {Vue} vm
  1046   * @param {Function} [cb]
  1047   */
  1048  
  1049  function beforeWithTransition(el, target, vm, cb) {
  1050    applyTransition(el, 1, function () {
  1051      before(el, target);
  1052    }, vm, cb);
  1053  }
  1054  
  1055  /**
  1056   * Remove with transition.
  1057   *
  1058   * @param {Element} el
  1059   * @param {Vue} vm
  1060   * @param {Function} [cb]
  1061   */
  1062  
  1063  function removeWithTransition(el, vm, cb) {
  1064    applyTransition(el, -1, function () {
  1065      remove(el);
  1066    }, vm, cb);
  1067  }
  1068  
  1069  /**
  1070   * Apply transitions with an operation callback.
  1071   *
  1072   * @param {Element} el
  1073   * @param {Number} direction
  1074   *                  1: enter
  1075   *                 -1: leave
  1076   * @param {Function} op - the actual DOM operation
  1077   * @param {Vue} vm
  1078   * @param {Function} [cb]
  1079   */
  1080  
  1081  function applyTransition(el, direction, op, vm, cb) {
  1082    var transition = el.__v_trans;
  1083    if (!transition ||
  1084    // skip if there are no js hooks and CSS transition is
  1085    // not supported
  1086    !transition.hooks && !transitionEndEvent ||
  1087    // skip transitions for initial compile
  1088    !vm._isCompiled ||
  1089    // if the vm is being manipulated by a parent directive
  1090    // during the parent's compilation phase, skip the
  1091    // animation.
  1092    vm.$parent && !vm.$parent._isCompiled) {
  1093      op();
  1094      if (cb) cb();
  1095      return;
  1096    }
  1097    var action = direction > 0 ? 'enter' : 'leave';
  1098    transition[action](op, cb);
  1099  }
  1100  
  1101  var transition = Object.freeze({
  1102    appendWithTransition: appendWithTransition,
  1103    beforeWithTransition: beforeWithTransition,
  1104    removeWithTransition: removeWithTransition,
  1105    applyTransition: applyTransition
  1106  });
  1107  
  1108  /**
  1109   * Query an element selector if it's not an element already.
  1110   *
  1111   * @param {String|Element} el
  1112   * @return {Element}
  1113   */
  1114  
  1115  function query(el) {
  1116    if (typeof el === 'string') {
  1117      var selector = el;
  1118      el = document.querySelector(el);
  1119      if (!el) {
  1120        process.env.NODE_ENV !== 'production' && warn('Cannot find element: ' + selector);
  1121      }
  1122    }
  1123    return el;
  1124  }
  1125  
  1126  /**
  1127   * Check if a node is in the document.
  1128   * Note: document.documentElement.contains should work here
  1129   * but always returns false for comment nodes in phantomjs,
  1130   * making unit tests difficult. This is fixed by doing the
  1131   * contains() check on the node's parentNode instead of
  1132   * the node itself.
  1133   *
  1134   * @param {Node} node
  1135   * @return {Boolean}
  1136   */
  1137  
  1138  function inDoc(node) {
  1139    if (!node) return false;
  1140    var doc = node.ownerDocument.documentElement;
  1141    var parent = node.parentNode;
  1142    return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
  1143  }
  1144  
  1145  /**
  1146   * Get and remove an attribute from a node.
  1147   *
  1148   * @param {Node} node
  1149   * @param {String} _attr
  1150   */
  1151  
  1152  function getAttr(node, _attr) {
  1153    var val = node.getAttribute(_attr);
  1154    if (val !== null) {
  1155      node.removeAttribute(_attr);
  1156    }
  1157    return val;
  1158  }
  1159  
  1160  /**
  1161   * Get an attribute with colon or v-bind: prefix.
  1162   *
  1163   * @param {Node} node
  1164   * @param {String} name
  1165   * @return {String|null}
  1166   */
  1167  
  1168  function getBindAttr(node, name) {
  1169    var val = getAttr(node, ':' + name);
  1170    if (val === null) {
  1171      val = getAttr(node, 'v-bind:' + name);
  1172    }
  1173    return val;
  1174  }
  1175  
  1176  /**
  1177   * Check the presence of a bind attribute.
  1178   *
  1179   * @param {Node} node
  1180   * @param {String} name
  1181   * @return {Boolean}
  1182   */
  1183  
  1184  function hasBindAttr(node, name) {
  1185    return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
  1186  }
  1187  
  1188  /**
  1189   * Insert el before target
  1190   *
  1191   * @param {Element} el
  1192   * @param {Element} target
  1193   */
  1194  
  1195  function before(el, target) {
  1196    target.parentNode.insertBefore(el, target);
  1197  }
  1198  
  1199  /**
  1200   * Insert el after target
  1201   *
  1202   * @param {Element} el
  1203   * @param {Element} target
  1204   */
  1205  
  1206  function after(el, target) {
  1207    if (target.nextSibling) {
  1208      before(el, target.nextSibling);
  1209    } else {
  1210      target.parentNode.appendChild(el);
  1211    }
  1212  }
  1213  
  1214  /**
  1215   * Remove el from DOM
  1216   *
  1217   * @param {Element} el
  1218   */
  1219  
  1220  function remove(el) {
  1221    el.parentNode.removeChild(el);
  1222  }
  1223  
  1224  /**
  1225   * Prepend el to target
  1226   *
  1227   * @param {Element} el
  1228   * @param {Element} target
  1229   */
  1230  
  1231  function prepend(el, target) {
  1232    if (target.firstChild) {
  1233      before(el, target.firstChild);
  1234    } else {
  1235      target.appendChild(el);
  1236    }
  1237  }
  1238  
  1239  /**
  1240   * Replace target with el
  1241   *
  1242   * @param {Element} target
  1243   * @param {Element} el
  1244   */
  1245  
  1246  function replace(target, el) {
  1247    var parent = target.parentNode;
  1248    if (parent) {
  1249      parent.replaceChild(el, target);
  1250    }
  1251  }
  1252  
  1253  /**
  1254   * Add event listener shorthand.
  1255   *
  1256   * @param {Element} el
  1257   * @param {String} event
  1258   * @param {Function} cb
  1259   * @param {Boolean} [useCapture]
  1260   */
  1261  
  1262  function on(el, event, cb, useCapture) {
  1263    el.addEventListener(event, cb, useCapture);
  1264  }
  1265  
  1266  /**
  1267   * Remove event listener shorthand.
  1268   *
  1269   * @param {Element} el
  1270   * @param {String} event
  1271   * @param {Function} cb
  1272   */
  1273  
  1274  function off(el, event, cb) {
  1275    el.removeEventListener(event, cb);
  1276  }
  1277  
  1278  /**
  1279   * For IE9 compat: when both class and :class are present
  1280   * getAttribute('class') returns wrong value...
  1281   *
  1282   * @param {Element} el
  1283   * @return {String}
  1284   */
  1285  
  1286  function getClass(el) {
  1287    var classname = el.className;
  1288    if (typeof classname === 'object') {
  1289      classname = classname.baseVal || '';
  1290    }
  1291    return classname;
  1292  }
  1293  
  1294  /**
  1295   * In IE9, setAttribute('class') will result in empty class
  1296   * if the element also has the :class attribute; However in
  1297   * PhantomJS, setting `className` does not work on SVG elements...
  1298   * So we have to do a conditional check here.
  1299   *
  1300   * @param {Element} el
  1301   * @param {String} cls
  1302   */
  1303  
  1304  function setClass(el, cls) {
  1305    /* istanbul ignore if */
  1306    if (isIE9 && !/svg$/.test(el.namespaceURI)) {
  1307      el.className = cls;
  1308    } else {
  1309      el.setAttribute('class', cls);
  1310    }
  1311  }
  1312  
  1313  /**
  1314   * Add class with compatibility for IE & SVG
  1315   *
  1316   * @param {Element} el
  1317   * @param {String} cls
  1318   */
  1319  
  1320  function addClass(el, cls) {
  1321    if (el.classList) {
  1322      el.classList.add(cls);
  1323    } else {
  1324      var cur = ' ' + getClass(el) + ' ';
  1325      if (cur.indexOf(' ' + cls + ' ') < 0) {
  1326        setClass(el, (cur + cls).trim());
  1327      }
  1328    }
  1329  }
  1330  
  1331  /**
  1332   * Remove class with compatibility for IE & SVG
  1333   *
  1334   * @param {Element} el
  1335   * @param {String} cls
  1336   */
  1337  
  1338  function removeClass(el, cls) {
  1339    if (el.classList) {
  1340      el.classList.remove(cls);
  1341    } else {
  1342      var cur = ' ' + getClass(el) + ' ';
  1343      var tar = ' ' + cls + ' ';
  1344      while (cur.indexOf(tar) >= 0) {
  1345        cur = cur.replace(tar, ' ');
  1346      }
  1347      setClass(el, cur.trim());
  1348    }
  1349    if (!el.className) {
  1350      el.removeAttribute('class');
  1351    }
  1352  }
  1353  
  1354  /**
  1355   * Extract raw content inside an element into a temporary
  1356   * container div
  1357   *
  1358   * @param {Element} el
  1359   * @param {Boolean} asFragment
  1360   * @return {Element|DocumentFragment}
  1361   */
  1362  
  1363  function extractContent(el, asFragment) {
  1364    var child;
  1365    var rawContent;
  1366    /* istanbul ignore if */
  1367    if (isTemplate(el) && isFragment(el.content)) {
  1368      el = el.content;
  1369    }
  1370    if (el.hasChildNodes()) {
  1371      trimNode(el);
  1372      rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
  1373      /* eslint-disable no-cond-assign */
  1374      while (child = el.firstChild) {
  1375        /* eslint-enable no-cond-assign */
  1376        rawContent.appendChild(child);
  1377      }
  1378    }
  1379    return rawContent;
  1380  }
  1381  
  1382  /**
  1383   * Trim possible empty head/tail text and comment
  1384   * nodes inside a parent.
  1385   *
  1386   * @param {Node} node
  1387   */
  1388  
  1389  function trimNode(node) {
  1390    var child;
  1391    /* eslint-disable no-sequences */
  1392    while ((child = node.firstChild, isTrimmable(child))) {
  1393      node.removeChild(child);
  1394    }
  1395    while ((child = node.lastChild, isTrimmable(child))) {
  1396      node.removeChild(child);
  1397    }
  1398    /* eslint-enable no-sequences */
  1399  }
  1400  
  1401  function isTrimmable(node) {
  1402    return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
  1403  }
  1404  
  1405  /**
  1406   * Check if an element is a template tag.
  1407   * Note if the template appears inside an SVG its tagName
  1408   * will be in lowercase.
  1409   *
  1410   * @param {Element} el
  1411   */
  1412  
  1413  function isTemplate(el) {
  1414    return el.tagName && el.tagName.toLowerCase() === 'template';
  1415  }
  1416  
  1417  /**
  1418   * Create an "anchor" for performing dom insertion/removals.
  1419   * This is used in a number of scenarios:
  1420   * - fragment instance
  1421   * - v-html
  1422   * - v-if
  1423   * - v-for
  1424   * - component
  1425   *
  1426   * @param {String} content
  1427   * @param {Boolean} persist - IE trashes empty textNodes on
  1428   *                            cloneNode(true), so in certain
  1429   *                            cases the anchor needs to be
  1430   *                            non-empty to be persisted in
  1431   *                            templates.
  1432   * @return {Comment|Text}
  1433   */
  1434  
  1435  function createAnchor(content, persist) {
  1436    var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
  1437    anchor.__v_anchor = true;
  1438    return anchor;
  1439  }
  1440  
  1441  /**
  1442   * Find a component ref attribute that starts with $.
  1443   *
  1444   * @param {Element} node
  1445   * @return {String|undefined}
  1446   */
  1447  
  1448  var refRE = /^v-ref:/;
  1449  
  1450  function findRef(node) {
  1451    if (node.hasAttributes()) {
  1452      var attrs = node.attributes;
  1453      for (var i = 0, l = attrs.length; i < l; i++) {
  1454        var name = attrs[i].name;
  1455        if (refRE.test(name)) {
  1456          return camelize(name.replace(refRE, ''));
  1457        }
  1458      }
  1459    }
  1460  }
  1461  
  1462  /**
  1463   * Map a function to a range of nodes .
  1464   *
  1465   * @param {Node} node
  1466   * @param {Node} end
  1467   * @param {Function} op
  1468   */
  1469  
  1470  function mapNodeRange(node, end, op) {
  1471    var next;
  1472    while (node !== end) {
  1473      next = node.nextSibling;
  1474      op(node);
  1475      node = next;
  1476    }
  1477    op(end);
  1478  }
  1479  
  1480  /**
  1481   * Remove a range of nodes with transition, store
  1482   * the nodes in a fragment with correct ordering,
  1483   * and call callback when done.
  1484   *
  1485   * @param {Node} start
  1486   * @param {Node} end
  1487   * @param {Vue} vm
  1488   * @param {DocumentFragment} frag
  1489   * @param {Function} cb
  1490   */
  1491  
  1492  function removeNodeRange(start, end, vm, frag, cb) {
  1493    var done = false;
  1494    var removed = 0;
  1495    var nodes = [];
  1496    mapNodeRange(start, end, function (node) {
  1497      if (node === end) done = true;
  1498      nodes.push(node);
  1499      removeWithTransition(node, vm, onRemoved);
  1500    });
  1501    function onRemoved() {
  1502      removed++;
  1503      if (done && removed >= nodes.length) {
  1504        for (var i = 0; i < nodes.length; i++) {
  1505          frag.appendChild(nodes[i]);
  1506        }
  1507        cb && cb();
  1508      }
  1509    }
  1510  }
  1511  
  1512  /**
  1513   * Check if a node is a DocumentFragment.
  1514   *
  1515   * @param {Node} node
  1516   * @return {Boolean}
  1517   */
  1518  
  1519  function isFragment(node) {
  1520    return node && node.nodeType === 11;
  1521  }
  1522  
  1523  /**
  1524   * Get outerHTML of elements, taking care
  1525   * of SVG elements in IE as well.
  1526   *
  1527   * @param {Element} el
  1528   * @return {String}
  1529   */
  1530  
  1531  function getOuterHTML(el) {
  1532    if (el.outerHTML) {
  1533      return el.outerHTML;
  1534    } else {
  1535      var container = document.createElement('div');
  1536      container.appendChild(el.cloneNode(true));
  1537      return container.innerHTML;
  1538    }
  1539  }
  1540  
  1541  var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i;
  1542  var reservedTagRE = /^(slot|partial|component)$/i;
  1543  
  1544  var isUnknownElement = undefined;
  1545  if (process.env.NODE_ENV !== 'production') {
  1546    isUnknownElement = function (el, tag) {
  1547      if (tag.indexOf('-') > -1) {
  1548        // http://stackoverflow.com/a/28210364/1070244
  1549        return el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement;
  1550      } else {
  1551        return (/HTMLUnknownElement/.test(el.toString()) &&
  1552          // Chrome returns unknown for several HTML5 elements.
  1553          // https://code.google.com/p/chromium/issues/detail?id=540526
  1554          !/^(data|time|rtc|rb)$/.test(tag)
  1555        );
  1556      }
  1557    };
  1558  }
  1559  
  1560  /**
  1561   * Check if an element is a component, if yes return its
  1562   * component id.
  1563   *
  1564   * @param {Element} el
  1565   * @param {Object} options
  1566   * @return {Object|undefined}
  1567   */
  1568  
  1569  function checkComponentAttr(el, options) {
  1570    var tag = el.tagName.toLowerCase();
  1571    var hasAttrs = el.hasAttributes();
  1572    if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
  1573      if (resolveAsset(options, 'components', tag)) {
  1574        return { id: tag };
  1575      } else {
  1576        var is = hasAttrs && getIsBinding(el, options);
  1577        if (is) {
  1578          return is;
  1579        } else if (process.env.NODE_ENV !== 'production') {
  1580          var expectedTag = options._componentNameMap && options._componentNameMap[tag];
  1581          if (expectedTag) {
  1582            warn('Unknown custom element: <' + tag + '> - ' + 'did you mean <' + expectedTag + '>? ' + 'HTML is case-insensitive, remember to use kebab-case in templates.');
  1583          } else if (isUnknownElement(el, tag)) {
  1584            warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
  1585          }
  1586        }
  1587      }
  1588    } else if (hasAttrs) {
  1589      return getIsBinding(el, options);
  1590    }
  1591  }
  1592  
  1593  /**
  1594   * Get "is" binding from an element.
  1595   *
  1596   * @param {Element} el
  1597   * @param {Object} options
  1598   * @return {Object|undefined}
  1599   */
  1600  
  1601  function getIsBinding(el, options) {
  1602    // dynamic syntax
  1603    var exp = el.getAttribute('is');
  1604    if (exp != null) {
  1605      if (resolveAsset(options, 'components', exp)) {
  1606        el.removeAttribute('is');
  1607        return { id: exp };
  1608      }
  1609    } else {
  1610      exp = getBindAttr(el, 'is');
  1611      if (exp != null) {
  1612        return { id: exp, dynamic: true };
  1613      }
  1614    }
  1615  }
  1616  
  1617  /**
  1618   * Option overwriting strategies are functions that handle
  1619   * how to merge a parent option value and a child option
  1620   * value into the final value.
  1621   *
  1622   * All strategy functions follow the same signature:
  1623   *
  1624   * @param {*} parentVal
  1625   * @param {*} childVal
  1626   * @param {Vue} [vm]
  1627   */
  1628  
  1629  var strats = config.optionMergeStrategies = Object.create(null);
  1630  
  1631  /**
  1632   * Helper that recursively merges two data objects together.
  1633   */
  1634  
  1635  function mergeData(to, from) {
  1636    var key, toVal, fromVal;
  1637    for (key in from) {
  1638      toVal = to[key];
  1639      fromVal = from[key];
  1640      if (!hasOwn(to, key)) {
  1641        set(to, key, fromVal);
  1642      } else if (isObject(toVal) && isObject(fromVal)) {
  1643        mergeData(toVal, fromVal);
  1644      }
  1645    }
  1646    return to;
  1647  }
  1648  
  1649  /**
  1650   * Data
  1651   */
  1652  
  1653  strats.data = function (parentVal, childVal, vm) {
  1654    if (!vm) {
  1655      // in a Vue.extend merge, both should be functions
  1656      if (!childVal) {
  1657        return parentVal;
  1658      }
  1659      if (typeof childVal !== 'function') {
  1660        process.env.NODE_ENV !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
  1661        return parentVal;
  1662      }
  1663      if (!parentVal) {
  1664        return childVal;
  1665      }
  1666      // when parentVal & childVal are both present,
  1667      // we need to return a function that returns the
  1668      // merged result of both functions... no need to
  1669      // check if parentVal is a function here because
  1670      // it has to be a function to pass previous merges.
  1671      return function mergedDataFn() {
  1672        return mergeData(childVal.call(this), parentVal.call(this));
  1673      };
  1674    } else if (parentVal || childVal) {
  1675      return function mergedInstanceDataFn() {
  1676        // instance merge
  1677        var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal;
  1678        var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined;
  1679        if (instanceData) {
  1680          return mergeData(instanceData, defaultData);
  1681        } else {
  1682          return defaultData;
  1683        }
  1684      };
  1685    }
  1686  };
  1687  
  1688  /**
  1689   * El
  1690   */
  1691  
  1692  strats.el = function (parentVal, childVal, vm) {
  1693    if (!vm && childVal && typeof childVal !== 'function') {
  1694      process.env.NODE_ENV !== 'production' && warn('The "el" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
  1695      return;
  1696    }
  1697    var ret = childVal || parentVal;
  1698    // invoke the element factory if this is instance merge
  1699    return vm && typeof ret === 'function' ? ret.call(vm) : ret;
  1700  };
  1701  
  1702  /**
  1703   * Hooks and param attributes are merged as arrays.
  1704   */
  1705  
  1706  strats.init = strats.created = strats.ready = strats.attached = strats.detached = strats.beforeCompile = strats.compiled = strats.beforeDestroy = strats.destroyed = strats.activate = function (parentVal, childVal) {
  1707    return childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
  1708  };
  1709  
  1710  /**
  1711   * Assets
  1712   *
  1713   * When a vm is present (instance creation), we need to do
  1714   * a three-way merge between constructor options, instance
  1715   * options and parent options.
  1716   */
  1717  
  1718  function mergeAssets(parentVal, childVal) {
  1719    var res = Object.create(parentVal || null);
  1720    return childVal ? extend(res, guardArrayAssets(childVal)) : res;
  1721  }
  1722  
  1723  config._assetTypes.forEach(function (type) {
  1724    strats[type + 's'] = mergeAssets;
  1725  });
  1726  
  1727  /**
  1728   * Events & Watchers.
  1729   *
  1730   * Events & watchers hashes should not overwrite one
  1731   * another, so we merge them as arrays.
  1732   */
  1733  
  1734  strats.watch = strats.events = function (parentVal, childVal) {
  1735    if (!childVal) return parentVal;
  1736    if (!parentVal) return childVal;
  1737    var ret = {};
  1738    extend(ret, parentVal);
  1739    for (var key in childVal) {
  1740      var parent = ret[key];
  1741      var child = childVal[key];
  1742      if (parent && !isArray(parent)) {
  1743        parent = [parent];
  1744      }
  1745      ret[key] = parent ? parent.concat(child) : [child];
  1746    }
  1747    return ret;
  1748  };
  1749  
  1750  /**
  1751   * Other object hashes.
  1752   */
  1753  
  1754  strats.props = strats.methods = strats.computed = function (parentVal, childVal) {
  1755    if (!childVal) return parentVal;
  1756    if (!parentVal) return childVal;
  1757    var ret = Object.create(null);
  1758    extend(ret, parentVal);
  1759    extend(ret, childVal);
  1760    return ret;
  1761  };
  1762  
  1763  /**
  1764   * Default strategy.
  1765   */
  1766  
  1767  var defaultStrat = function defaultStrat(parentVal, childVal) {
  1768    return childVal === undefined ? parentVal : childVal;
  1769  };
  1770  
  1771  /**
  1772   * Make sure component options get converted to actual
  1773   * constructors.
  1774   *
  1775   * @param {Object} options
  1776   */
  1777  
  1778  function guardComponents(options) {
  1779    if (options.components) {
  1780      var components = options.components = guardArrayAssets(options.components);
  1781      var ids = Object.keys(components);
  1782      var def;
  1783      if (process.env.NODE_ENV !== 'production') {
  1784        var map = options._componentNameMap = {};
  1785      }
  1786      for (var i = 0, l = ids.length; i < l; i++) {
  1787        var key = ids[i];
  1788        if (commonTagRE.test(key) || reservedTagRE.test(key)) {
  1789          process.env.NODE_ENV !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
  1790          continue;
  1791        }
  1792        // record a all lowercase <-> kebab-case mapping for
  1793        // possible custom element case error warning
  1794        if (process.env.NODE_ENV !== 'production') {
  1795          map[key.replace(/-/g, '').toLowerCase()] = hyphenate(key);
  1796        }
  1797        def = components[key];
  1798        if (isPlainObject(def)) {
  1799          components[key] = Vue.extend(def);
  1800        }
  1801      }
  1802    }
  1803  }
  1804  
  1805  /**
  1806   * Ensure all props option syntax are normalized into the
  1807   * Object-based format.
  1808   *
  1809   * @param {Object} options
  1810   */
  1811  
  1812  function guardProps(options) {
  1813    var props = options.props;
  1814    var i, val;
  1815    if (isArray(props)) {
  1816      options.props = {};
  1817      i = props.length;
  1818      while (i--) {
  1819        val = props[i];
  1820        if (typeof val === 'string') {
  1821          options.props[val] = null;
  1822        } else if (val.name) {
  1823          options.props[val.name] = val;
  1824        }
  1825      }
  1826    } else if (isPlainObject(props)) {
  1827      var keys = Object.keys(props);
  1828      i = keys.length;
  1829      while (i--) {
  1830        val = props[keys[i]];
  1831        if (typeof val === 'function') {
  1832          props[keys[i]] = { type: val };
  1833        }
  1834      }
  1835    }
  1836  }
  1837  
  1838  /**
  1839   * Guard an Array-format assets option and converted it
  1840   * into the key-value Object format.
  1841   *
  1842   * @param {Object|Array} assets
  1843   * @return {Object}
  1844   */
  1845  
  1846  function guardArrayAssets(assets) {
  1847    if (isArray(assets)) {
  1848      var res = {};
  1849      var i = assets.length;
  1850      var asset;
  1851      while (i--) {
  1852        asset = assets[i];
  1853        var id = typeof asset === 'function' ? asset.options && asset.options.name || asset.id : asset.name || asset.id;
  1854        if (!id) {
  1855          process.env.NODE_ENV !== 'production' && warn('Array-syntax assets must provide a "name" or "id" field.');
  1856        } else {
  1857          res[id] = asset;
  1858        }
  1859      }
  1860      return res;
  1861    }
  1862    return assets;
  1863  }
  1864  
  1865  /**
  1866   * Merge two option objects into a new one.
  1867   * Core utility used in both instantiation and inheritance.
  1868   *
  1869   * @param {Object} parent
  1870   * @param {Object} child
  1871   * @param {Vue} [vm] - if vm is present, indicates this is
  1872   *                     an instantiation merge.
  1873   */
  1874  
  1875  function mergeOptions(parent, child, vm) {
  1876    guardComponents(child);
  1877    guardProps(child);
  1878    if (process.env.NODE_ENV !== 'production') {
  1879      if (child.propsData && !vm) {
  1880        warn('propsData can only be used as an instantiation option.');
  1881      }
  1882    }
  1883    var options = {};
  1884    var key;
  1885    if (child['extends']) {
  1886      parent = typeof child['extends'] === 'function' ? mergeOptions(parent, child['extends'].options, vm) : mergeOptions(parent, child['extends'], vm);
  1887    }
  1888    if (child.mixins) {
  1889      for (var i = 0, l = child.mixins.length; i < l; i++) {
  1890        parent = mergeOptions(parent, child.mixins[i], vm);
  1891      }
  1892    }
  1893    for (key in parent) {
  1894      mergeField(key);
  1895    }
  1896    for (key in child) {
  1897      if (!hasOwn(parent, key)) {
  1898        mergeField(key);
  1899      }
  1900    }
  1901    function mergeField(key) {
  1902      var strat = strats[key] || defaultStrat;
  1903      options[key] = strat(parent[key], child[key], vm, key);
  1904    }
  1905    return options;
  1906  }
  1907  
  1908  /**
  1909   * Resolve an asset.
  1910   * This function is used because child instances need access
  1911   * to assets defined in its ancestor chain.
  1912   *
  1913   * @param {Object} options
  1914   * @param {String} type
  1915   * @param {String} id
  1916   * @param {Boolean} warnMissing
  1917   * @return {Object|Function}
  1918   */
  1919  
  1920  function resolveAsset(options, type, id, warnMissing) {
  1921    /* istanbul ignore if */
  1922    if (typeof id !== 'string') {
  1923      return;
  1924    }
  1925    var assets = options[type];
  1926    var camelizedId;
  1927    var res = assets[id] ||
  1928    // camelCase ID
  1929    assets[camelizedId = camelize(id)] ||
  1930    // Pascal Case ID
  1931    assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)];
  1932    if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {
  1933      warn('Failed to resolve ' + type.slice(0, -1) + ': ' + id, options);
  1934    }
  1935    return res;
  1936  }
  1937  
  1938  var uid$1 = 0;
  1939  
  1940  /**
  1941   * A dep is an observable that can have multiple
  1942   * directives subscribing to it.
  1943   *
  1944   * @constructor
  1945   */
  1946  function Dep() {
  1947    this.id = uid$1++;
  1948    this.subs = [];
  1949  }
  1950  
  1951  // the current target watcher being evaluated.
  1952  // this is globally unique because there could be only one
  1953  // watcher being evaluated at any time.
  1954  Dep.target = null;
  1955  
  1956  /**
  1957   * Add a directive subscriber.
  1958   *
  1959   * @param {Directive} sub
  1960   */
  1961  
  1962  Dep.prototype.addSub = function (sub) {
  1963    this.subs.push(sub);
  1964  };
  1965  
  1966  /**
  1967   * Remove a directive subscriber.
  1968   *
  1969   * @param {Directive} sub
  1970   */
  1971  
  1972  Dep.prototype.removeSub = function (sub) {
  1973    this.subs.$remove(sub);
  1974  };
  1975  
  1976  /**
  1977   * Add self as a dependency to the target watcher.
  1978   */
  1979  
  1980  Dep.prototype.depend = function () {
  1981    Dep.target.addDep(this);
  1982  };
  1983  
  1984  /**
  1985   * Notify all subscribers of a new value.
  1986   */
  1987  
  1988  Dep.prototype.notify = function () {
  1989    // stablize the subscriber list first
  1990    var subs = toArray(this.subs);
  1991    for (var i = 0, l = subs.length; i < l; i++) {
  1992      subs[i].update();
  1993    }
  1994  };
  1995  
  1996  var arrayProto = Array.prototype;
  1997  var arrayMethods = Object.create(arrayProto)
  1998  
  1999  /**
  2000   * Intercept mutating methods and emit events
  2001   */
  2002  
  2003  ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
  2004    // cache original method
  2005    var original = arrayProto[method];
  2006    def(arrayMethods, method, function mutator() {
  2007      // avoid leaking arguments:
  2008      // http://jsperf.com/closure-with-arguments
  2009      var i = arguments.length;
  2010      var args = new Array(i);
  2011      while (i--) {
  2012        args[i] = arguments[i];
  2013      }
  2014      var result = original.apply(this, args);
  2015      var ob = this.__ob__;
  2016      var inserted;
  2017      switch (method) {
  2018        case 'push':
  2019          inserted = args;
  2020          break;
  2021        case 'unshift':
  2022          inserted = args;
  2023          break;
  2024        case 'splice':
  2025          inserted = args.slice(2);
  2026          break;
  2027      }
  2028      if (inserted) ob.observeArray(inserted);
  2029      // notify change
  2030      ob.dep.notify();
  2031      return result;
  2032    });
  2033  });
  2034  
  2035  /**
  2036   * Swap the element at the given index with a new value
  2037   * and emits corresponding event.
  2038   *
  2039   * @param {Number} index
  2040   * @param {*} val
  2041   * @return {*} - replaced element
  2042   */
  2043  
  2044  def(arrayProto, '$set', function $set(index, val) {
  2045    if (index >= this.length) {
  2046      this.length = Number(index) + 1;
  2047    }
  2048    return this.splice(index, 1, val)[0];
  2049  });
  2050  
  2051  /**
  2052   * Convenience method to remove the element at given index or target element reference.
  2053   *
  2054   * @param {*} item
  2055   */
  2056  
  2057  def(arrayProto, '$remove', function $remove(item) {
  2058    /* istanbul ignore if */
  2059    if (!this.length) return;
  2060    var index = indexOf(this, item);
  2061    if (index > -1) {
  2062      return this.splice(index, 1);
  2063    }
  2064  });
  2065  
  2066  var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
  2067  
  2068  /**
  2069   * By default, when a reactive property is set, the new value is
  2070   * also converted to become reactive. However in certain cases, e.g.
  2071   * v-for scope alias and props, we don't want to force conversion
  2072   * because the value may be a nested value under a frozen data structure.
  2073   *
  2074   * So whenever we want to set a reactive property without forcing
  2075   * conversion on the new value, we wrap that call inside this function.
  2076   */
  2077  
  2078  var shouldConvert = true;
  2079  
  2080  function withoutConversion(fn) {
  2081    shouldConvert = false;
  2082    fn();
  2083    shouldConvert = true;
  2084  }
  2085  
  2086  /**
  2087   * Observer class that are attached to each observed
  2088   * object. Once attached, the observer converts target
  2089   * object's property keys into getter/setters that
  2090   * collect dependencies and dispatches updates.
  2091   *
  2092   * @param {Array|Object} value
  2093   * @constructor
  2094   */
  2095  
  2096  function Observer(value) {
  2097    this.value = value;
  2098    this.dep = new Dep();
  2099    def(value, '__ob__', this);
  2100    if (isArray(value)) {
  2101      var augment = hasProto ? protoAugment : copyAugment;
  2102      augment(value, arrayMethods, arrayKeys);
  2103      this.observeArray(value);
  2104    } else {
  2105      this.walk(value);
  2106    }
  2107  }
  2108  
  2109  // Instance methods
  2110  
  2111  /**
  2112   * Walk through each property and convert them into
  2113   * getter/setters. This method should only be called when
  2114   * value type is Object.
  2115   *
  2116   * @param {Object} obj
  2117   */
  2118  
  2119  Observer.prototype.walk = function (obj) {
  2120    var keys = Object.keys(obj);
  2121    for (var i = 0, l = keys.length; i < l; i++) {
  2122      this.convert(keys[i], obj[keys[i]]);
  2123    }
  2124  };
  2125  
  2126  /**
  2127   * Observe a list of Array items.
  2128   *
  2129   * @param {Array} items
  2130   */
  2131  
  2132  Observer.prototype.observeArray = function (items) {
  2133    for (var i = 0, l = items.length; i < l; i++) {
  2134      observe(items[i]);
  2135    }
  2136  };
  2137  
  2138  /**
  2139   * Convert a property into getter/setter so we can emit
  2140   * the events when the property is accessed/changed.
  2141   *
  2142   * @param {String} key
  2143   * @param {*} val
  2144   */
  2145  
  2146  Observer.prototype.convert = function (key, val) {
  2147    defineReactive(this.value, key, val);
  2148  };
  2149  
  2150  /**
  2151   * Add an owner vm, so that when $set/$delete mutations
  2152   * happen we can notify owner vms to proxy the keys and
  2153   * digest the watchers. This is only called when the object
  2154   * is observed as an instance's root $data.
  2155   *
  2156   * @param {Vue} vm
  2157   */
  2158  
  2159  Observer.prototype.addVm = function (vm) {
  2160    (this.vms || (this.vms = [])).push(vm);
  2161  };
  2162  
  2163  /**
  2164   * Remove an owner vm. This is called when the object is
  2165   * swapped out as an instance's $data object.
  2166   *
  2167   * @param {Vue} vm
  2168   */
  2169  
  2170  Observer.prototype.removeVm = function (vm) {
  2171    this.vms.$remove(vm);
  2172  };
  2173  
  2174  // helpers
  2175  
  2176  /**
  2177   * Augment an target Object or Array by intercepting
  2178   * the prototype chain using __proto__
  2179   *
  2180   * @param {Object|Array} target
  2181   * @param {Object} src
  2182   */
  2183  
  2184  function protoAugment(target, src) {
  2185    /* eslint-disable no-proto */
  2186    target.__proto__ = src;
  2187    /* eslint-enable no-proto */
  2188  }
  2189  
  2190  /**
  2191   * Augment an target Object or Array by defining
  2192   * hidden properties.
  2193   *
  2194   * @param {Object|Array} target
  2195   * @param {Object} proto
  2196   */
  2197  
  2198  function copyAugment(target, src, keys) {
  2199    for (var i = 0, l = keys.length; i < l; i++) {
  2200      var key = keys[i];
  2201      def(target, key, src[key]);
  2202    }
  2203  }
  2204  
  2205  /**
  2206   * Attempt to create an observer instance for a value,
  2207   * returns the new observer if successfully observed,
  2208   * or the existing observer if the value already has one.
  2209   *
  2210   * @param {*} value
  2211   * @param {Vue} [vm]
  2212   * @return {Observer|undefined}
  2213   * @static
  2214   */
  2215  
  2216  function observe(value, vm) {
  2217    if (!value || typeof value !== 'object') {
  2218      return;
  2219    }
  2220    var ob;
  2221    if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
  2222      ob = value.__ob__;
  2223    } else if (shouldConvert && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
  2224      ob = new Observer(value);
  2225    }
  2226    if (ob && vm) {
  2227      ob.addVm(vm);
  2228    }
  2229    return ob;
  2230  }
  2231  
  2232  /**
  2233   * Define a reactive property on an Object.
  2234   *
  2235   * @param {Object} obj
  2236   * @param {String} key
  2237   * @param {*} val
  2238   */
  2239  
  2240  function defineReactive(obj, key, val) {
  2241    var dep = new Dep();
  2242  
  2243    var property = Object.getOwnPropertyDescriptor(obj, key);
  2244    if (property && property.configurable === false) {
  2245      return;
  2246    }
  2247  
  2248    // cater for pre-defined getter/setters
  2249    var getter = property && property.get;
  2250    var setter = property && property.set;
  2251  
  2252    var childOb = observe(val);
  2253    Object.defineProperty(obj, key, {
  2254      enumerable: true,
  2255      configurable: true,
  2256      get: function reactiveGetter() {
  2257        var value = getter ? getter.call(obj) : val;
  2258        if (Dep.target) {
  2259          dep.depend();
  2260          if (childOb) {
  2261            childOb.dep.depend();
  2262          }
  2263          if (isArray(value)) {
  2264            for (var e, i = 0, l = value.length; i < l; i++) {
  2265              e = value[i];
  2266              e && e.__ob__ && e.__ob__.dep.depend();
  2267            }
  2268          }
  2269        }
  2270        return value;
  2271      },
  2272      set: function reactiveSetter(newVal) {
  2273        var value = getter ? getter.call(obj) : val;
  2274        if (newVal === value) {
  2275          return;
  2276        }
  2277        if (setter) {
  2278          setter.call(obj, newVal);
  2279        } else {
  2280          val = newVal;
  2281        }
  2282        childOb = observe(newVal);
  2283        dep.notify();
  2284      }
  2285    });
  2286  }
  2287  
  2288  
  2289  
  2290  var util = Object.freeze({
  2291  	defineReactive: defineReactive,
  2292  	set: set,
  2293  	del: del,
  2294  	hasOwn: hasOwn,
  2295  	isLiteral: isLiteral,
  2296  	isReserved: isReserved,
  2297  	_toString: _toString,
  2298  	toNumber: toNumber,
  2299  	toBoolean: toBoolean,
  2300  	stripQuotes: stripQuotes,
  2301  	camelize: camelize,
  2302  	hyphenate: hyphenate,
  2303  	classify: classify,
  2304  	bind: bind,
  2305  	toArray: toArray,
  2306  	extend: extend,
  2307  	isObject: isObject,
  2308  	isPlainObject: isPlainObject,
  2309  	def: def,
  2310  	debounce: _debounce,
  2311  	indexOf: indexOf,
  2312  	cancellable: cancellable,
  2313  	looseEqual: looseEqual,
  2314  	isArray: isArray,
  2315  	hasProto: hasProto,
  2316  	inBrowser: inBrowser,
  2317  	devtools: devtools,
  2318  	isIE9: isIE9,
  2319  	isAndroid: isAndroid,
  2320  	isIos: isIos,
  2321  	isWechat: isWechat,
  2322  	get transitionProp () { return transitionProp; },
  2323  	get transitionEndEvent () { return transitionEndEvent; },
  2324  	get animationProp () { return animationProp; },
  2325  	get animationEndEvent () { return animationEndEvent; },
  2326  	nextTick: nextTick,
  2327  	get _Set () { return _Set; },
  2328  	query: query,
  2329  	inDoc: inDoc,
  2330  	getAttr: getAttr,
  2331  	getBindAttr: getBindAttr,
  2332  	hasBindAttr: hasBindAttr,
  2333  	before: before,
  2334  	after: after,
  2335  	remove: remove,
  2336  	prepend: prepend,
  2337  	replace: replace,
  2338  	on: on,
  2339  	off: off,
  2340  	setClass: setClass,
  2341  	addClass: addClass,
  2342  	removeClass: removeClass,
  2343  	extractContent: extractContent,
  2344  	trimNode: trimNode,
  2345  	isTemplate: isTemplate,
  2346  	createAnchor: createAnchor,
  2347  	findRef: findRef,
  2348  	mapNodeRange: mapNodeRange,
  2349  	removeNodeRange: removeNodeRange,
  2350  	isFragment: isFragment,
  2351  	getOuterHTML: getOuterHTML,
  2352  	mergeOptions: mergeOptions,
  2353  	resolveAsset: resolveAsset,
  2354  	checkComponentAttr: checkComponentAttr,
  2355  	commonTagRE: commonTagRE,
  2356  	reservedTagRE: reservedTagRE,
  2357  	get warn () { return warn; }
  2358  });
  2359  
  2360  var uid = 0;
  2361  
  2362  function initMixin (Vue) {
  2363    /**
  2364     * The main init sequence. This is called for every
  2365     * instance, including ones that are created from extended
  2366     * constructors.
  2367     *
  2368     * @param {Object} options - this options object should be
  2369     *                           the result of merging class
  2370     *                           options and the options passed
  2371     *                           in to the constructor.
  2372     */
  2373  
  2374    Vue.prototype._init = function (options) {
  2375      options = options || {};
  2376  
  2377      this.$el = null;
  2378      this.$parent = options.parent;
  2379      this.$root = this.$parent ? this.$parent.$root : this;
  2380      this.$children = [];
  2381      this.$refs = {}; // child vm references
  2382      this.$els = {}; // element references
  2383      this._watchers = []; // all watchers as an array
  2384      this._directives = []; // all directives
  2385  
  2386      // a uid
  2387      this._uid = uid++;
  2388  
  2389      // a flag to avoid this being observed
  2390      this._isVue = true;
  2391  
  2392      // events bookkeeping
  2393      this._events = {}; // registered callbacks
  2394      this._eventsCount = {}; // for $broadcast optimization
  2395  
  2396      // fragment instance properties
  2397      this._isFragment = false;
  2398      this._fragment = // @type {DocumentFragment}
  2399      this._fragmentStart = // @type {Text|Comment}
  2400      this._fragmentEnd = null; // @type {Text|Comment}
  2401  
  2402      // lifecycle state
  2403      this._isCompiled = this._isDestroyed = this._isReady = this._isAttached = this._isBeingDestroyed = this._vForRemoving = false;
  2404      this._unlinkFn = null;
  2405  
  2406      // context:
  2407      // if this is a transcluded component, context
  2408      // will be the common parent vm of this instance
  2409      // and its host.
  2410      this._context = options._context || this.$parent;
  2411  
  2412      // scope:
  2413      // if this is inside an inline v-for, the scope
  2414      // will be the intermediate scope created for this
  2415      // repeat fragment. this is used for linking props
  2416      // and container directives.
  2417      this._scope = options._scope;
  2418  
  2419      // fragment:
  2420      // if this instance is compiled inside a Fragment, it
  2421      // needs to reigster itself as a child of that fragment
  2422      // for attach/detach to work properly.
  2423      this._frag = options._frag;
  2424      if (this._frag) {
  2425        this._frag.children.push(this);
  2426      }
  2427  
  2428      // push self into parent / transclusion host
  2429      if (this.$parent) {
  2430        this.$parent.$children.push(this);
  2431      }
  2432  
  2433      // merge options.
  2434      options = this.$options = mergeOptions(this.constructor.options, options, this);
  2435  
  2436      // set ref
  2437      this._updateRef();
  2438  
  2439      // initialize data as empty object.
  2440      // it will be filled up in _initData().
  2441      this._data = {};
  2442  
  2443      // call init hook
  2444      this._callHook('init');
  2445  
  2446      // initialize data observation and scope inheritance.
  2447      this._initState();
  2448  
  2449      // setup event system and option events.
  2450      this._initEvents();
  2451  
  2452      // call created hook
  2453      this._callHook('created');
  2454  
  2455      // if `el` option is passed, start compilation.
  2456      if (options.el) {
  2457        this.$mount(options.el);
  2458      }
  2459    };
  2460  }
  2461  
  2462  var pathCache = new Cache(1000);
  2463  
  2464  // actions
  2465  var APPEND = 0;
  2466  var PUSH = 1;
  2467  var INC_SUB_PATH_DEPTH = 2;
  2468  var PUSH_SUB_PATH = 3;
  2469  
  2470  // states
  2471  var BEFORE_PATH = 0;
  2472  var IN_PATH = 1;
  2473  var BEFORE_IDENT = 2;
  2474  var IN_IDENT = 3;
  2475  var IN_SUB_PATH = 4;
  2476  var IN_SINGLE_QUOTE = 5;
  2477  var IN_DOUBLE_QUOTE = 6;
  2478  var AFTER_PATH = 7;
  2479  var ERROR = 8;
  2480  
  2481  var pathStateMachine = [];
  2482  
  2483  pathStateMachine[BEFORE_PATH] = {
  2484    'ws': [BEFORE_PATH],
  2485    'ident': [IN_IDENT, APPEND],
  2486    '[': [IN_SUB_PATH],
  2487    'eof': [AFTER_PATH]
  2488  };
  2489  
  2490  pathStateMachine[IN_PATH] = {
  2491    'ws': [IN_PATH],
  2492    '.': [BEFORE_IDENT],
  2493    '[': [IN_SUB_PATH],
  2494    'eof': [AFTER_PATH]
  2495  };
  2496  
  2497  pathStateMachine[BEFORE_IDENT] = {
  2498    'ws': [BEFORE_IDENT],
  2499    'ident': [IN_IDENT, APPEND]
  2500  };
  2501  
  2502  pathStateMachine[IN_IDENT] = {
  2503    'ident': [IN_IDENT, APPEND],
  2504    '0': [IN_IDENT, APPEND],
  2505    'number': [IN_IDENT, APPEND],
  2506    'ws': [IN_PATH, PUSH],
  2507    '.': [BEFORE_IDENT, PUSH],
  2508    '[': [IN_SUB_PATH, PUSH],
  2509    'eof': [AFTER_PATH, PUSH]
  2510  };
  2511  
  2512  pathStateMachine[IN_SUB_PATH] = {
  2513    "'": [IN_SINGLE_QUOTE, APPEND],
  2514    '"': [IN_DOUBLE_QUOTE, APPEND],
  2515    '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
  2516    ']': [IN_PATH, PUSH_SUB_PATH],
  2517    'eof': ERROR,
  2518    'else': [IN_SUB_PATH, APPEND]
  2519  };
  2520  
  2521  pathStateMachine[IN_SINGLE_QUOTE] = {
  2522    "'": [IN_SUB_PATH, APPEND],
  2523    'eof': ERROR,
  2524    'else': [IN_SINGLE_QUOTE, APPEND]
  2525  };
  2526  
  2527  pathStateMachine[IN_DOUBLE_QUOTE] = {
  2528    '"': [IN_SUB_PATH, APPEND],
  2529    'eof': ERROR,
  2530    'else': [IN_DOUBLE_QUOTE, APPEND]
  2531  };
  2532  
  2533  /**
  2534   * Determine the type of a character in a keypath.
  2535   *
  2536   * @param {Char} ch
  2537   * @return {String} type
  2538   */
  2539  
  2540  function getPathCharType(ch) {
  2541    if (ch === undefined) {
  2542      return 'eof';
  2543    }
  2544  
  2545    var code = ch.charCodeAt(0);
  2546  
  2547    switch (code) {
  2548      case 0x5B: // [
  2549      case 0x5D: // ]
  2550      case 0x2E: // .
  2551      case 0x22: // "
  2552      case 0x27: // '
  2553      case 0x30:
  2554        // 0
  2555        return ch;
  2556  
  2557      case 0x5F: // _
  2558      case 0x24:
  2559        // $
  2560        return 'ident';
  2561  
  2562      case 0x20: // Space
  2563      case 0x09: // Tab
  2564      case 0x0A: // Newline
  2565      case 0x0D: // Return
  2566      case 0xA0: // No-break space
  2567      case 0xFEFF: // Byte Order Mark
  2568      case 0x2028: // Line Separator
  2569      case 0x2029:
  2570        // Paragraph Separator
  2571        return 'ws';
  2572    }
  2573  
  2574    // a-z, A-Z
  2575    if (code >= 0x61 && code <= 0x7A || code >= 0x41 && code <= 0x5A) {
  2576      return 'ident';
  2577    }
  2578  
  2579    // 1-9
  2580    if (code >= 0x31 && code <= 0x39) {
  2581      return 'number';
  2582    }
  2583  
  2584    return 'else';
  2585  }
  2586  
  2587  /**
  2588   * Format a subPath, return its plain form if it is
  2589   * a literal string or number. Otherwise prepend the
  2590   * dynamic indicator (*).
  2591   *
  2592   * @param {String} path
  2593   * @return {String}
  2594   */
  2595  
  2596  function formatSubPath(path) {
  2597    var trimmed = path.trim();
  2598    // invalid leading 0
  2599    if (path.charAt(0) === '0' && isNaN(path)) {
  2600      return false;
  2601    }
  2602    return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed;
  2603  }
  2604  
  2605  /**
  2606   * Parse a string path into an array of segments
  2607   *
  2608   * @param {String} path
  2609   * @return {Array|undefined}
  2610   */
  2611  
  2612  function parse(path) {
  2613    var keys = [];
  2614    var index = -1;
  2615    var mode = BEFORE_PATH;
  2616    var subPathDepth = 0;
  2617    var c, newChar, key, type, transition, action, typeMap;
  2618  
  2619    var actions = [];
  2620  
  2621    actions[PUSH] = function () {
  2622      if (key !== undefined) {
  2623        keys.push(key);
  2624        key = undefined;
  2625      }
  2626    };
  2627  
  2628    actions[APPEND] = function () {
  2629      if (key === undefined) {
  2630        key = newChar;
  2631      } else {
  2632        key += newChar;
  2633      }
  2634    };
  2635  
  2636    actions[INC_SUB_PATH_DEPTH] = function () {
  2637      actions[APPEND]();
  2638      subPathDepth++;
  2639    };
  2640  
  2641    actions[PUSH_SUB_PATH] = function () {
  2642      if (subPathDepth > 0) {
  2643        subPathDepth--;
  2644        mode = IN_SUB_PATH;
  2645        actions[APPEND]();
  2646      } else {
  2647        subPathDepth = 0;
  2648        key = formatSubPath(key);
  2649        if (key === false) {
  2650          return false;
  2651        } else {
  2652          actions[PUSH]();
  2653        }
  2654      }
  2655    };
  2656  
  2657    function maybeUnescapeQuote() {
  2658      var nextChar = path[index + 1];
  2659      if (mode === IN_SINGLE_QUOTE && nextChar === "'" || mode === IN_DOUBLE_QUOTE && nextChar === '"') {
  2660        index++;
  2661        newChar = '\\' + nextChar;
  2662        actions[APPEND]();
  2663        return true;
  2664      }
  2665    }
  2666  
  2667    while (mode != null) {
  2668      index++;
  2669      c = path[index];
  2670  
  2671      if (c === '\\' && maybeUnescapeQuote()) {
  2672        continue;
  2673      }
  2674  
  2675      type = getPathCharType(c);
  2676      typeMap = pathStateMachine[mode];
  2677      transition = typeMap[type] || typeMap['else'] || ERROR;
  2678  
  2679      if (transition === ERROR) {
  2680        return; // parse error
  2681      }
  2682  
  2683      mode = transition[0];
  2684      action = actions[transition[1]];
  2685      if (action) {
  2686        newChar = transition[2];
  2687        newChar = newChar === undefined ? c : newChar;
  2688        if (action() === false) {
  2689          return;
  2690        }
  2691      }
  2692  
  2693      if (mode === AFTER_PATH) {
  2694        keys.raw = path;
  2695        return keys;
  2696      }
  2697    }
  2698  }
  2699  
  2700  /**
  2701   * External parse that check for a cache hit first
  2702   *
  2703   * @param {String} path
  2704   * @return {Array|undefined}
  2705   */
  2706  
  2707  function parsePath(path) {
  2708    var hit = pathCache.get(path);
  2709    if (!hit) {
  2710      hit = parse(path);
  2711      if (hit) {
  2712        pathCache.put(path, hit);
  2713      }
  2714    }
  2715    return hit;
  2716  }
  2717  
  2718  /**
  2719   * Get from an object from a path string
  2720   *
  2721   * @param {Object} obj
  2722   * @param {String} path
  2723   */
  2724  
  2725  function getPath(obj, path) {
  2726    return parseExpression(path).get(obj);
  2727  }
  2728  
  2729  /**
  2730   * Warn against setting non-existent root path on a vm.
  2731   */
  2732  
  2733  var warnNonExistent;
  2734  if (process.env.NODE_ENV !== 'production') {
  2735    warnNonExistent = function (path, vm) {
  2736      warn('You are setting a non-existent path "' + path.raw + '" ' + 'on a vm instance. Consider pre-initializing the property ' + 'with the "data" option for more reliable reactivity ' + 'and better performance.', vm);
  2737    };
  2738  }
  2739  
  2740  /**
  2741   * Set on an object from a path
  2742   *
  2743   * @param {Object} obj
  2744   * @param {String | Array} path
  2745   * @param {*} val
  2746   */
  2747  
  2748  function setPath(obj, path, val) {
  2749    var original = obj;
  2750    if (typeof path === 'string') {
  2751      path = parse(path);
  2752    }
  2753    if (!path || !isObject(obj)) {
  2754      return false;
  2755    }
  2756    var last, key;
  2757    for (var i = 0, l = path.length; i < l; i++) {
  2758      last = obj;
  2759      key = path[i];
  2760      if (key.charAt(0) === '*') {
  2761        key = parseExpression(key.slice(1)).get.call(original, original);
  2762      }
  2763      if (i < l - 1) {
  2764        obj = obj[key];
  2765        if (!isObject(obj)) {
  2766          obj = {};
  2767          if (process.env.NODE_ENV !== 'production' && last._isVue) {
  2768            warnNonExistent(path, last);
  2769          }
  2770          set(last, key, obj);
  2771        }
  2772      } else {
  2773        if (isArray(obj)) {
  2774          obj.$set(key, val);
  2775        } else if (key in obj) {
  2776          obj[key] = val;
  2777        } else {
  2778          if (process.env.NODE_ENV !== 'production' && obj._isVue) {
  2779            warnNonExistent(path, obj);
  2780          }
  2781          set(obj, key, val);
  2782        }
  2783      }
  2784    }
  2785    return true;
  2786  }
  2787  
  2788  var path = Object.freeze({
  2789    parsePath: parsePath,
  2790    getPath: getPath,
  2791    setPath: setPath
  2792  });
  2793  
  2794  var expressionCache = new Cache(1000);
  2795  
  2796  var allowedKeywords = 'Math,Date,this,true,false,null,undefined,Infinity,NaN,' + 'isNaN,isFinite,decodeURI,decodeURIComponent,encodeURI,' + 'encodeURIComponent,parseInt,parseFloat';
  2797  var allowedKeywordsRE = new RegExp('^(' + allowedKeywords.replace(/,/g, '\\b|') + '\\b)');
  2798  
  2799  // keywords that don't make sense inside expressions
  2800  var improperKeywords = 'break,case,class,catch,const,continue,debugger,default,' + 'delete,do,else,export,extends,finally,for,function,if,' + 'import,in,instanceof,let,return,super,switch,throw,try,' + 'var,while,with,yield,enum,await,implements,package,' + 'protected,static,interface,private,public';
  2801  var improperKeywordsRE = new RegExp('^(' + improperKeywords.replace(/,/g, '\\b|') + '\\b)');
  2802  
  2803  var wsRE = /\s/g;
  2804  var newlineRE = /\n/g;
  2805  var saveRE = /[\{,]\s*[\w\$_]+\s*:|('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`)|new |typeof |void /g;
  2806  var restoreRE = /"(\d+)"/g;
  2807  var pathTestRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/;
  2808  var identRE = /[^\w$\.](?:[A-Za-z_$][\w$]*)/g;
  2809  var booleanLiteralRE = /^(?:true|false)$/;
  2810  
  2811  /**
  2812   * Save / Rewrite / Restore
  2813   *
  2814   * When rewriting paths found in an expression, it is
  2815   * possible for the same letter sequences to be found in
  2816   * strings and Object literal property keys. Therefore we
  2817   * remove and store these parts in a temporary array, and
  2818   * restore them after the path rewrite.
  2819   */
  2820  
  2821  var saved = [];
  2822  
  2823  /**
  2824   * Save replacer
  2825   *
  2826   * The save regex can match two possible cases:
  2827   * 1. An opening object literal
  2828   * 2. A string
  2829   * If matched as a plain string, we need to escape its
  2830   * newlines, since the string needs to be preserved when
  2831   * generating the function body.
  2832   *
  2833   * @param {String} str
  2834   * @param {String} isString - str if matched as a string
  2835   * @return {String} - placeholder with index
  2836   */
  2837  
  2838  function save(str, isString) {
  2839    var i = saved.length;
  2840    saved[i] = isString ? str.replace(newlineRE, '\\n') : str;
  2841    return '"' + i + '"';
  2842  }
  2843  
  2844  /**
  2845   * Path rewrite replacer
  2846   *
  2847   * @param {String} raw
  2848   * @return {String}
  2849   */
  2850  
  2851  function rewrite(raw) {
  2852    var c = raw.charAt(0);
  2853    var path = raw.slice(1);
  2854    if (allowedKeywordsRE.test(path)) {
  2855      return raw;
  2856    } else {
  2857      path = path.indexOf('"') > -1 ? path.replace(restoreRE, restore) : path;
  2858      return c + 'scope.' + path;
  2859    }
  2860  }
  2861  
  2862  /**
  2863   * Restore replacer
  2864   *
  2865   * @param {String} str
  2866   * @param {String} i - matched save index
  2867   * @return {String}
  2868   */
  2869  
  2870  function restore(str, i) {
  2871    return saved[i];
  2872  }
  2873  
  2874  /**
  2875   * Rewrite an expression, prefixing all path accessors with
  2876   * `scope.` and generate getter/setter functions.
  2877   *
  2878   * @param {String} exp
  2879   * @return {Function}
  2880   */
  2881  
  2882  function compileGetter(exp) {
  2883    if (improperKeywordsRE.test(exp)) {
  2884      process.env.NODE_ENV !== 'production' && warn('Avoid using reserved keywords in expression: ' + exp);
  2885    }
  2886    // reset state
  2887    saved.length = 0;
  2888    // save strings and object literal keys
  2889    var body = exp.replace(saveRE, save).replace(wsRE, '');
  2890    // rewrite all paths
  2891    // pad 1 space here becaue the regex matches 1 extra char
  2892    body = (' ' + body).replace(identRE, rewrite).replace(restoreRE, restore);
  2893    return makeGetterFn(body);
  2894  }
  2895  
  2896  /**
  2897   * Build a getter function. Requires eval.
  2898   *
  2899   * We isolate the try/catch so it doesn't affect the
  2900   * optimization of the parse function when it is not called.
  2901   *
  2902   * @param {String} body
  2903   * @return {Function|undefined}
  2904   */
  2905  
  2906  function makeGetterFn(body) {
  2907    try {
  2908      /* eslint-disable no-new-func */
  2909      return new Function('scope', 'return ' + body + ';');
  2910      /* eslint-enable no-new-func */
  2911    } catch (e) {
  2912      process.env.NODE_ENV !== 'production' && warn('Invalid expression. ' + 'Generated function body: ' + body);
  2913    }
  2914  }
  2915  
  2916  /**
  2917   * Compile a setter function for the expression.
  2918   *
  2919   * @param {String} exp
  2920   * @return {Function|undefined}
  2921   */
  2922  
  2923  function compileSetter(exp) {
  2924    var path = parsePath(exp);
  2925    if (path) {
  2926      return function (scope, val) {
  2927        setPath(scope, path, val);
  2928      };
  2929    } else {
  2930      process.env.NODE_ENV !== 'production' && warn('Invalid setter expression: ' + exp);
  2931    }
  2932  }
  2933  
  2934  /**
  2935   * Parse an expression into re-written getter/setters.
  2936   *
  2937   * @param {String} exp
  2938   * @param {Boolean} needSet
  2939   * @return {Function}
  2940   */
  2941  
  2942  function parseExpression(exp, needSet) {
  2943    exp = exp.trim();
  2944    // try cache
  2945    var hit = expressionCache.get(exp);
  2946    if (hit) {
  2947      if (needSet && !hit.set) {
  2948        hit.set = compileSetter(hit.exp);
  2949      }
  2950      return hit;
  2951    }
  2952    var res = { exp: exp };
  2953    res.get = isSimplePath(exp) && exp.indexOf('[') < 0
  2954    // optimized super simple getter
  2955    ? makeGetterFn('scope.' + exp)
  2956    // dynamic getter
  2957    : compileGetter(exp);
  2958    if (needSet) {
  2959      res.set = compileSetter(exp);
  2960    }
  2961    expressionCache.put(exp, res);
  2962    return res;
  2963  }
  2964  
  2965  /**
  2966   * Check if an expression is a simple path.
  2967   *
  2968   * @param {String} exp
  2969   * @return {Boolean}
  2970   */
  2971  
  2972  function isSimplePath(exp) {
  2973    return pathTestRE.test(exp) &&
  2974    // don't treat true/false as paths
  2975    !booleanLiteralRE.test(exp) &&
  2976    // Math constants e.g. Math.PI, Math.E etc.
  2977    exp.slice(0, 5) !== 'Math.';
  2978  }
  2979  
  2980  var expression = Object.freeze({
  2981    parseExpression: parseExpression,
  2982    isSimplePath: isSimplePath
  2983  });
  2984  
  2985  // we have two separate queues: one for directive updates
  2986  // and one for user watcher registered via $watch().
  2987  // we want to guarantee directive updates to be called
  2988  // before user watchers so that when user watchers are
  2989  // triggered, the DOM would have already been in updated
  2990  // state.
  2991  
  2992  var queue = [];
  2993  var userQueue = [];
  2994  var has = {};
  2995  var circular = {};
  2996  var waiting = false;
  2997  
  2998  /**
  2999   * Reset the batcher's state.
  3000   */
  3001  
  3002  function resetBatcherState() {
  3003    queue.length = 0;
  3004    userQueue.length = 0;
  3005    has = {};
  3006    circular = {};
  3007    waiting = false;
  3008  }
  3009  
  3010  /**
  3011   * Flush both queues and run the watchers.
  3012   */
  3013  
  3014  function flushBatcherQueue() {
  3015    var _again = true;
  3016  
  3017    _function: while (_again) {
  3018      _again = false;
  3019  
  3020      runBatcherQueue(queue);
  3021      runBatcherQueue(userQueue);
  3022      // user watchers triggered more watchers,
  3023      // keep flushing until it depletes
  3024      if (queue.length) {
  3025        _again = true;
  3026        continue _function;
  3027      }
  3028      // dev tool hook
  3029      /* istanbul ignore if */
  3030      if (devtools && config.devtools) {
  3031        devtools.emit('flush');
  3032      }
  3033      resetBatcherState();
  3034    }
  3035  }
  3036  
  3037  /**
  3038   * Run the watchers in a single queue.
  3039   *
  3040   * @param {Array} queue
  3041   */
  3042  
  3043  function runBatcherQueue(queue) {
  3044    // do not cache length because more watchers might be pushed
  3045    // as we run existing watchers
  3046    for (var i = 0; i < queue.length; i++) {
  3047      var watcher = queue[i];
  3048      var id = watcher.id;
  3049      has[id] = null;
  3050      watcher.run();
  3051      // in dev build, check and stop circular updates.
  3052      if (process.env.NODE_ENV !== 'production' && has[id] != null) {
  3053        circular[id] = (circular[id] || 0) + 1;
  3054        if (circular[id] > config._maxUpdateCount) {
  3055          warn('You may have an infinite update loop for watcher ' + 'with expression "' + watcher.expression + '"', watcher.vm);
  3056          break;
  3057        }
  3058      }
  3059    }
  3060    queue.length = 0;
  3061  }
  3062  
  3063  /**
  3064   * Push a watcher into the watcher queue.
  3065   * Jobs with duplicate IDs will be skipped unless it's
  3066   * pushed when the queue is being flushed.
  3067   *
  3068   * @param {Watcher} watcher
  3069   *   properties:
  3070   *   - {Number} id
  3071   *   - {Function} run
  3072   */
  3073  
  3074  function pushWatcher(watcher) {
  3075    var id = watcher.id;
  3076    if (has[id] == null) {
  3077      // push watcher into appropriate queue
  3078      var q = watcher.user ? userQueue : queue;
  3079      has[id] = q.length;
  3080      q.push(watcher);
  3081      // queue the flush
  3082      if (!waiting) {
  3083        waiting = true;
  3084        nextTick(flushBatcherQueue);
  3085      }
  3086    }
  3087  }
  3088  
  3089  var uid$2 = 0;
  3090  
  3091  /**
  3092   * A watcher parses an expression, collects dependencies,
  3093   * and fires callback when the expression value changes.
  3094   * This is used for both the $watch() api and directives.
  3095   *
  3096   * @param {Vue} vm
  3097   * @param {String|Function} expOrFn
  3098   * @param {Function} cb
  3099   * @param {Object} options
  3100   *                 - {Array} filters
  3101   *                 - {Boolean} twoWay
  3102   *                 - {Boolean} deep
  3103   *                 - {Boolean} user
  3104   *                 - {Boolean} sync
  3105   *                 - {Boolean} lazy
  3106   *                 - {Function} [preProcess]
  3107   *                 - {Function} [postProcess]
  3108   * @constructor
  3109   */
  3110  function Watcher(vm, expOrFn, cb, options) {
  3111    // mix in options
  3112    if (options) {
  3113      extend(this, options);
  3114    }
  3115    var isFn = typeof expOrFn === 'function';
  3116    this.vm = vm;
  3117    vm._watchers.push(this);
  3118    this.expression = expOrFn;
  3119    this.cb = cb;
  3120    this.id = ++uid$2; // uid for batching
  3121    this.active = true;
  3122    this.dirty = this.lazy; // for lazy watchers
  3123    this.deps = [];
  3124    this.newDeps = [];
  3125    this.depIds = new _Set();
  3126    this.newDepIds = new _Set();
  3127    this.prevError = null; // for async error stacks
  3128    // parse expression for getter/setter
  3129    if (isFn) {
  3130      this.getter = expOrFn;
  3131      this.setter = undefined;
  3132    } else {
  3133      var res = parseExpression(expOrFn, this.twoWay);
  3134      this.getter = res.get;
  3135      this.setter = res.set;
  3136    }
  3137    this.value = this.lazy ? undefined : this.get();
  3138    // state for avoiding false triggers for deep and Array
  3139    // watchers during vm._digest()
  3140    this.queued = this.shallow = false;
  3141  }
  3142  
  3143  /**
  3144   * Evaluate the getter, and re-collect dependencies.
  3145   */
  3146  
  3147  Watcher.prototype.get = function () {
  3148    this.beforeGet();
  3149    var scope = this.scope || this.vm;
  3150    var value;
  3151    try {
  3152      value = this.getter.call(scope, scope);
  3153    } catch (e) {
  3154      if (process.env.NODE_ENV !== 'production' && config.warnExpressionErrors) {
  3155        warn('Error when evaluating expression ' + '"' + this.expression + '": ' + e.toString(), this.vm);
  3156      }
  3157    }
  3158    // "touch" every property so they are all tracked as
  3159    // dependencies for deep watching
  3160    if (this.deep) {
  3161      traverse(value);
  3162    }
  3163    if (this.preProcess) {
  3164      value = this.preProcess(value);
  3165    }
  3166    if (this.filters) {
  3167      value = scope._applyFilters(value, null, this.filters, false);
  3168    }
  3169    if (this.postProcess) {
  3170      value = this.postProcess(value);
  3171    }
  3172    this.afterGet();
  3173    return value;
  3174  };
  3175  
  3176  /**
  3177   * Set the corresponding value with the setter.
  3178   *
  3179   * @param {*} value
  3180   */
  3181  
  3182  Watcher.prototype.set = function (value) {
  3183    var scope = this.scope || this.vm;
  3184    if (this.filters) {
  3185      value = scope._applyFilters(value, this.value, this.filters, true);
  3186    }
  3187    try {
  3188      this.setter.call(scope, scope, value);
  3189    } catch (e) {
  3190      if (process.env.NODE_ENV !== 'production' && config.warnExpressionErrors) {
  3191        warn('Error when evaluating setter ' + '"' + this.expression + '": ' + e.toString(), this.vm);
  3192      }
  3193    }
  3194    // two-way sync for v-for alias
  3195    var forContext = scope.$forContext;
  3196    if (forContext && forContext.alias === this.expression) {
  3197      if (forContext.filters) {
  3198        process.env.NODE_ENV !== 'production' && warn('It seems you are using two-way binding on ' + 'a v-for alias (' + this.expression + '), and the ' + 'v-for has filters. This will not work properly. ' + 'Either remove the filters or use an array of ' + 'objects and bind to object properties instead.', this.vm);
  3199        return;
  3200      }
  3201      forContext._withLock(function () {
  3202        if (scope.$key) {
  3203          // original is an object
  3204          forContext.rawValue[scope.$key] = value;
  3205        } else {
  3206          forContext.rawValue.$set(scope.$index, value);
  3207        }
  3208      });
  3209    }
  3210  };
  3211  
  3212  /**
  3213   * Prepare for dependency collection.
  3214   */
  3215  
  3216  Watcher.prototype.beforeGet = function () {
  3217    Dep.target = this;
  3218  };
  3219  
  3220  /**
  3221   * Add a dependency to this directive.
  3222   *
  3223   * @param {Dep} dep
  3224   */
  3225  
  3226  Watcher.prototype.addDep = function (dep) {
  3227    var id = dep.id;
  3228    if (!this.newDepIds.has(id)) {
  3229      this.newDepIds.add(id);
  3230      this.newDeps.push(dep);
  3231      if (!this.depIds.has(id)) {
  3232        dep.addSub(this);
  3233      }
  3234    }
  3235  };
  3236  
  3237  /**
  3238   * Clean up for dependency collection.
  3239   */
  3240  
  3241  Watcher.prototype.afterGet = function () {
  3242    Dep.target = null;
  3243    var i = this.deps.length;
  3244    while (i--) {
  3245      var dep = this.deps[i];
  3246      if (!this.newDepIds.has(dep.id)) {
  3247        dep.removeSub(this);
  3248      }
  3249    }
  3250    var tmp = this.depIds;
  3251    this.depIds = this.newDepIds;
  3252    this.newDepIds = tmp;
  3253    this.newDepIds.clear();
  3254    tmp = this.deps;
  3255    this.deps = this.newDeps;
  3256    this.newDeps = tmp;
  3257    this.newDeps.length = 0;
  3258  };
  3259  
  3260  /**
  3261   * Subscriber interface.
  3262   * Will be called when a dependency changes.
  3263   *
  3264   * @param {Boolean} shallow
  3265   */
  3266  
  3267  Watcher.prototype.update = function (shallow) {
  3268    if (this.lazy) {
  3269      this.dirty = true;
  3270    } else if (this.sync || !config.async) {
  3271      this.run();
  3272    } else {
  3273      // if queued, only overwrite shallow with non-shallow,
  3274      // but not the other way around.
  3275      this.shallow = this.queued ? shallow ? this.shallow : false : !!shallow;
  3276      this.queued = true;
  3277      // record before-push error stack in debug mode
  3278      /* istanbul ignore if */
  3279      if (process.env.NODE_ENV !== 'production' && config.debug) {
  3280        this.prevError = new Error('[vue] async stack trace');
  3281      }
  3282      pushWatcher(this);
  3283    }
  3284  };
  3285  
  3286  /**
  3287   * Batcher job interface.
  3288   * Will be called by the batcher.
  3289   */
  3290  
  3291  Watcher.prototype.run = function () {
  3292    if (this.active) {
  3293      var value = this.get();
  3294      if (value !== this.value ||
  3295      // Deep watchers and watchers on Object/Arrays should fire even
  3296      // when the value is the same, because the value may
  3297      // have mutated; but only do so if this is a
  3298      // non-shallow update (caused by a vm digest).
  3299      (isObject(value) || this.deep) && !this.shallow) {
  3300        // set new value
  3301        var oldValue = this.value;
  3302        this.value = value;
  3303        // in debug + async mode, when a watcher callbacks
  3304        // throws, we also throw the saved before-push error
  3305        // so the full cross-tick stack trace is available.
  3306        var prevError = this.prevError;
  3307        /* istanbul ignore if */
  3308        if (process.env.NODE_ENV !== 'production' && config.debug && prevError) {
  3309          this.prevError = null;
  3310          try {
  3311            this.cb.call(this.vm, value, oldValue);
  3312          } catch (e) {
  3313            nextTick(function () {
  3314              throw prevError;
  3315            }, 0);
  3316            throw e;
  3317          }
  3318        } else {
  3319          this.cb.call(this.vm, value, oldValue);
  3320        }
  3321      }
  3322      this.queued = this.shallow = false;
  3323    }
  3324  };
  3325  
  3326  /**
  3327   * Evaluate the value of the watcher.
  3328   * This only gets called for lazy watchers.
  3329   */
  3330  
  3331  Watcher.prototype.evaluate = function () {
  3332    // avoid overwriting another watcher that is being
  3333    // collected.
  3334    var current = Dep.target;
  3335    this.value = this.get();
  3336    this.dirty = false;
  3337    Dep.target = current;
  3338  };
  3339  
  3340  /**
  3341   * Depend on all deps collected by this watcher.
  3342   */
  3343  
  3344  Watcher.prototype.depend = function () {
  3345    var i = this.deps.length;
  3346    while (i--) {
  3347      this.deps[i].depend();
  3348    }
  3349  };
  3350  
  3351  /**
  3352   * Remove self from all dependencies' subcriber list.
  3353   */
  3354  
  3355  Watcher.prototype.teardown = function () {
  3356    if (this.active) {
  3357      // remove self from vm's watcher list
  3358      // this is a somewhat expensive operation so we skip it
  3359      // if the vm is being destroyed or is performing a v-for
  3360      // re-render (the watcher list is then filtered by v-for).
  3361      if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
  3362        this.vm._watchers.$remove(this);
  3363      }
  3364      var i = this.deps.length;
  3365      while (i--) {
  3366        this.deps[i].removeSub(this);
  3367      }
  3368      this.active = false;
  3369      this.vm = this.cb = this.value = null;
  3370    }
  3371  };
  3372  
  3373  /**
  3374   * Recrusively traverse an object to evoke all converted
  3375   * getters, so that every nested property inside the object
  3376   * is collected as a "deep" dependency.
  3377   *
  3378   * @param {*} val
  3379   */
  3380  
  3381  var seenObjects = new _Set();
  3382  function traverse(val, seen) {
  3383    var i = undefined,
  3384        keys = undefined;
  3385    if (!seen) {
  3386      seen = seenObjects;
  3387      seen.clear();
  3388    }
  3389    var isA = isArray(val);
  3390    var isO = isObject(val);
  3391    if (isA || isO) {
  3392      if (val.__ob__) {
  3393        var depId = val.__ob__.dep.id;
  3394        if (seen.has(depId)) {
  3395          return;
  3396        } else {
  3397          seen.add(depId);
  3398        }
  3399      }
  3400      if (isA) {
  3401        i = val.length;
  3402        while (i--) traverse(val[i], seen);
  3403      } else if (isO) {
  3404        keys = Object.keys(val);
  3405        i = keys.length;
  3406        while (i--) traverse(val[keys[i]], seen);
  3407      }
  3408    }
  3409  }
  3410  
  3411  var text$1 = {
  3412  
  3413    bind: function bind() {
  3414      this.attr = this.el.nodeType === 3 ? 'data' : 'textContent';
  3415    },
  3416  
  3417    update: function update(value) {
  3418      this.el[this.attr] = _toString(value);
  3419    }
  3420  };
  3421  
  3422  var templateCache = new Cache(1000);
  3423  var idSelectorCache = new Cache(1000);
  3424  
  3425  var map = {
  3426    efault: [0, '', ''],
  3427    legend: [1, '<fieldset>', '</fieldset>'],
  3428    tr: [2, '<table><tbody>', '</tbody></table>'],
  3429    col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>']
  3430  };
  3431  
  3432  map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
  3433  
  3434  map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
  3435  
  3436  map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
  3437  
  3438  map.g = map.defs = map.symbol = map.use = map.image = map.text = map.circle = map.ellipse = map.line = map.path = map.polygon = map.polyline = map.rect = [1, '<svg ' + 'xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'xmlns:ev="http://www.w3.org/2001/xml-events"' + 'version="1.1">', '</svg>'];
  3439  
  3440  /**
  3441   * Check if a node is a supported template node with a
  3442   * DocumentFragment content.
  3443   *
  3444   * @param {Node} node
  3445   * @return {Boolean}
  3446   */
  3447  
  3448  function isRealTemplate(node) {
  3449    return isTemplate(node) && isFragment(node.content);
  3450  }
  3451  
  3452  var tagRE$1 = /<([\w:-]+)/;
  3453  var entityRE = /&#?\w+?;/;
  3454  
  3455  /**
  3456   * Convert a string template to a DocumentFragment.
  3457   * Determines correct wrapping by tag types. Wrapping
  3458   * strategy found in jQuery & component/domify.
  3459   *
  3460   * @param {String} templateString
  3461   * @param {Boolean} raw
  3462   * @return {DocumentFragment}
  3463   */
  3464  
  3465  function stringToFragment(templateString, raw) {
  3466    // try a cache hit first
  3467    var cacheKey = raw ? templateString : templateString.trim();
  3468    var hit = templateCache.get(cacheKey);
  3469    if (hit) {
  3470      return hit;
  3471    }
  3472  
  3473    var frag = document.createDocumentFragment();
  3474    var tagMatch = templateString.match(tagRE$1);
  3475    var entityMatch = entityRE.test(templateString);
  3476  
  3477    if (!tagMatch && !entityMatch) {
  3478      // text only, return a single text node.
  3479      frag.appendChild(document.createTextNode(templateString));
  3480    } else {
  3481      var tag = tagMatch && tagMatch[1];
  3482      var wrap = map[tag] || map.efault;
  3483      var depth = wrap[0];
  3484      var prefix = wrap[1];
  3485      var suffix = wrap[2];
  3486      var node = document.createElement('div');
  3487  
  3488      node.innerHTML = prefix + templateString + suffix;
  3489      while (depth--) {
  3490        node = node.lastChild;
  3491      }
  3492  
  3493      var child;
  3494      /* eslint-disable no-cond-assign */
  3495      while (child = node.firstChild) {
  3496        /* eslint-enable no-cond-assign */
  3497        frag.appendChild(child);
  3498      }
  3499    }
  3500    if (!raw) {
  3501      trimNode(frag);
  3502    }
  3503    templateCache.put(cacheKey, frag);
  3504    return frag;
  3505  }
  3506  
  3507  /**
  3508   * Convert a template node to a DocumentFragment.
  3509   *
  3510   * @param {Node} node
  3511   * @return {DocumentFragment}
  3512   */
  3513  
  3514  function nodeToFragment(node) {
  3515    // if its a template tag and the browser supports it,
  3516    // its content is already a document fragment. However, iOS Safari has
  3517    // bug when using directly cloned template content with touch
  3518    // events and can cause crashes when the nodes are removed from DOM, so we
  3519    // have to treat template elements as string templates. (#2805)
  3520    /* istanbul ignore if */
  3521    if (isRealTemplate(node)) {
  3522      return stringToFragment(node.innerHTML);
  3523    }
  3524    // script template
  3525    if (node.tagName === 'SCRIPT') {
  3526      return stringToFragment(node.textContent);
  3527    }
  3528    // normal node, clone it to avoid mutating the original
  3529    var clonedNode = cloneNode(node);
  3530    var frag = document.createDocumentFragment();
  3531    var child;
  3532    /* eslint-disable no-cond-assign */
  3533    while (child = clonedNode.firstChild) {
  3534      /* eslint-enable no-cond-assign */
  3535      frag.appendChild(child);
  3536    }
  3537    trimNode(frag);
  3538    return frag;
  3539  }
  3540  
  3541  // Test for the presence of the Safari template cloning bug
  3542  // https://bugs.webkit.org/showug.cgi?id=137755
  3543  var hasBrokenTemplate = (function () {
  3544    /* istanbul ignore else */
  3545    if (inBrowser) {
  3546      var a = document.createElement('div');
  3547      a.innerHTML = '<template>1</template>';
  3548      return !a.cloneNode(true).firstChild.innerHTML;
  3549    } else {
  3550      return false;
  3551    }
  3552  })();
  3553  
  3554  // Test for IE10/11 textarea placeholder clone bug
  3555  var hasTextareaCloneBug = (function () {
  3556    /* istanbul ignore else */
  3557    if (inBrowser) {
  3558      var t = document.createElement('textarea');
  3559      t.placeholder = 't';
  3560      return t.cloneNode(true).value === 't';
  3561    } else {
  3562      return false;
  3563    }
  3564  })();
  3565  
  3566  /**
  3567   * 1. Deal with Safari cloning nested <template> bug by
  3568   *    manually cloning all template instances.
  3569   * 2. Deal with IE10/11 textarea placeholder bug by setting
  3570   *    the correct value after cloning.
  3571   *
  3572   * @param {Element|DocumentFragment} node
  3573   * @return {Element|DocumentFragment}
  3574   */
  3575  
  3576  function cloneNode(node) {
  3577    /* istanbul ignore if */
  3578    if (!node.querySelectorAll) {
  3579      return node.cloneNode();
  3580    }
  3581    var res = node.cloneNode(true);
  3582    var i, original, cloned;
  3583    /* istanbul ignore if */
  3584    if (hasBrokenTemplate) {
  3585      var tempClone = res;
  3586      if (isRealTemplate(node)) {
  3587        node = node.content;
  3588        tempClone = res.content;
  3589      }
  3590      original = node.querySelectorAll('template');
  3591      if (original.length) {
  3592        cloned = tempClone.querySelectorAll('template');
  3593        i = cloned.length;
  3594        while (i--) {
  3595          cloned[i].parentNode.replaceChild(cloneNode(original[i]), cloned[i]);
  3596        }
  3597      }
  3598    }
  3599    /* istanbul ignore if */
  3600    if (hasTextareaCloneBug) {
  3601      if (node.tagName === 'TEXTAREA') {
  3602        res.value = node.value;
  3603      } else {
  3604        original = node.querySelectorAll('textarea');
  3605        if (original.length) {
  3606          cloned = res.querySelectorAll('textarea');
  3607          i = cloned.length;
  3608          while (i--) {
  3609            cloned[i].value = original[i].value;
  3610          }
  3611        }
  3612      }
  3613    }
  3614    return res;
  3615  }
  3616  
  3617  /**
  3618   * Process the template option and normalizes it into a
  3619   * a DocumentFragment that can be used as a partial or a
  3620   * instance template.
  3621   *
  3622   * @param {*} template
  3623   *        Possible values include:
  3624   *        - DocumentFragment object
  3625   *        - Node object of type Template
  3626   *        - id selector: '#some-template-id'
  3627   *        - template string: '<div><span>{{msg}}</span></div>'
  3628   * @param {Boolean} shouldClone
  3629   * @param {Boolean} raw
  3630   *        inline HTML interpolation. Do not check for id
  3631   *        selector and keep whitespace in the string.
  3632   * @return {DocumentFragment|undefined}
  3633   */
  3634  
  3635  function parseTemplate(template, shouldClone, raw) {
  3636    var node, frag;
  3637  
  3638    // if the template is already a document fragment,
  3639    // do nothing
  3640    if (isFragment(template)) {
  3641      trimNode(template);
  3642      return shouldClone ? cloneNode(template) : template;
  3643    }
  3644  
  3645    if (typeof template === 'string') {
  3646      // id selector
  3647      if (!raw && template.charAt(0) === '#') {
  3648        // id selector can be cached too
  3649        frag = idSelectorCache.get(template);
  3650        if (!frag) {
  3651          node = document.getElementById(template.slice(1));
  3652          if (node) {
  3653            frag = nodeToFragment(node);
  3654            // save selector to cache
  3655            idSelectorCache.put(template, frag);
  3656          }
  3657        }
  3658      } else {
  3659        // normal string template
  3660        frag = stringToFragment(template, raw);
  3661      }
  3662    } else if (template.nodeType) {
  3663      // a direct node
  3664      frag = nodeToFragment(template);
  3665    }
  3666  
  3667    return frag && shouldClone ? cloneNode(frag) : frag;
  3668  }
  3669  
  3670  var template = Object.freeze({
  3671    cloneNode: cloneNode,
  3672    parseTemplate: parseTemplate
  3673  });
  3674  
  3675  var html = {
  3676  
  3677    bind: function bind() {
  3678      // a comment node means this is a binding for
  3679      // {{{ inline unescaped html }}}
  3680      if (this.el.nodeType === 8) {
  3681        // hold nodes
  3682        this.nodes = [];
  3683        // replace the placeholder with proper anchor
  3684        this.anchor = createAnchor('v-html');
  3685        replace(this.el, this.anchor);
  3686      }
  3687    },
  3688  
  3689    update: function update(value) {
  3690      value = _toString(value);
  3691      if (this.nodes) {
  3692        this.swap(value);
  3693      } else {
  3694        this.el.innerHTML = value;
  3695      }
  3696    },
  3697  
  3698    swap: function swap(value) {
  3699      // remove old nodes
  3700      var i = this.nodes.length;
  3701      while (i--) {
  3702        remove(this.nodes[i]);
  3703      }
  3704      // convert new value to a fragment
  3705      // do not attempt to retrieve from id selector
  3706      var frag = parseTemplate(value, true, true);
  3707      // save a reference to these nodes so we can remove later
  3708      this.nodes = toArray(frag.childNodes);
  3709      before(frag, this.anchor);
  3710    }
  3711  };
  3712  
  3713  /**
  3714   * Abstraction for a partially-compiled fragment.
  3715   * Can optionally compile content with a child scope.
  3716   *
  3717   * @param {Function} linker
  3718   * @param {Vue} vm
  3719   * @param {DocumentFragment} frag
  3720   * @param {Vue} [host]
  3721   * @param {Object} [scope]
  3722   * @param {Fragment} [parentFrag]
  3723   */
  3724  function Fragment(linker, vm, frag, host, scope, parentFrag) {
  3725    this.children = [];
  3726    this.childFrags = [];
  3727    this.vm = vm;
  3728    this.scope = scope;
  3729    this.inserted = false;
  3730    this.parentFrag = parentFrag;
  3731    if (parentFrag) {
  3732      parentFrag.childFrags.push(this);
  3733    }
  3734    this.unlink = linker(vm, frag, host, scope, this);
  3735    var single = this.single = frag.childNodes.length === 1 &&
  3736    // do not go single mode if the only node is an anchor
  3737    !frag.childNodes[0].__v_anchor;
  3738    if (single) {
  3739      this.node = frag.childNodes[0];
  3740      this.before = singleBefore;
  3741      this.remove = singleRemove;
  3742    } else {
  3743      this.node = createAnchor('fragment-start');
  3744      this.end = createAnchor('fragment-end');
  3745      this.frag = frag;
  3746      prepend(this.node, frag);
  3747      frag.appendChild(this.end);
  3748      this.before = multiBefore;
  3749      this.remove = multiRemove;
  3750    }
  3751    this.node.__v_frag = this;
  3752  }
  3753  
  3754  /**
  3755   * Call attach/detach for all components contained within
  3756   * this fragment. Also do so recursively for all child
  3757   * fragments.
  3758   *
  3759   * @param {Function} hook
  3760   */
  3761  
  3762  Fragment.prototype.callHook = function (hook) {
  3763    var i, l;
  3764    for (i = 0, l = this.childFrags.length; i < l; i++) {
  3765      this.childFrags[i].callHook(hook);
  3766    }
  3767    for (i = 0, l = this.children.length; i < l; i++) {
  3768      hook(this.children[i]);
  3769    }
  3770  };
  3771  
  3772  /**
  3773   * Insert fragment before target, single node version
  3774   *
  3775   * @param {Node} target
  3776   * @param {Boolean} withTransition
  3777   */
  3778  
  3779  function singleBefore(target, withTransition) {
  3780    this.inserted = true;
  3781    var method = withTransition !== false ? beforeWithTransition : before;
  3782    method(this.node, target, this.vm);
  3783    if (inDoc(this.node)) {
  3784      this.callHook(attach);
  3785    }
  3786  }
  3787  
  3788  /**
  3789   * Remove fragment, single node version
  3790   */
  3791  
  3792  function singleRemove() {
  3793    this.inserted = false;
  3794    var shouldCallRemove = inDoc(this.node);
  3795    var self = this;
  3796    this.beforeRemove();
  3797    removeWithTransition(this.node, this.vm, function () {
  3798      if (shouldCallRemove) {
  3799        self.callHook(detach);
  3800      }
  3801      self.destroy();
  3802    });
  3803  }
  3804  
  3805  /**
  3806   * Insert fragment before target, multi-nodes version
  3807   *
  3808   * @param {Node} target
  3809   * @param {Boolean} withTransition
  3810   */
  3811  
  3812  function multiBefore(target, withTransition) {
  3813    this.inserted = true;
  3814    var vm = this.vm;
  3815    var method = withTransition !== false ? beforeWithTransition : before;
  3816    mapNodeRange(this.node, this.end, function (node) {
  3817      method(node, target, vm);
  3818    });
  3819    if (inDoc(this.node)) {
  3820      this.callHook(attach);
  3821    }
  3822  }
  3823  
  3824  /**
  3825   * Remove fragment, multi-nodes version
  3826   */
  3827  
  3828  function multiRemove() {
  3829    this.inserted = false;
  3830    var self = this;
  3831    var shouldCallRemove = inDoc(this.node);
  3832    this.beforeRemove();
  3833    removeNodeRange(this.node, this.end, this.vm, this.frag, function () {
  3834      if (shouldCallRemove) {
  3835        self.callHook(detach);
  3836      }
  3837      self.destroy();
  3838    });
  3839  }
  3840  
  3841  /**
  3842   * Prepare the fragment for removal.
  3843   */
  3844  
  3845  Fragment.prototype.beforeRemove = function () {
  3846    var i, l;
  3847    for (i = 0, l = this.childFrags.length; i < l; i++) {
  3848      // call the same method recursively on child
  3849      // fragments, depth-first
  3850      this.childFrags[i].beforeRemove(false);
  3851    }
  3852    for (i = 0, l = this.children.length; i < l; i++) {
  3853      // Call destroy for all contained instances,
  3854      // with remove:false and defer:true.
  3855      // Defer is necessary because we need to
  3856      // keep the children to call detach hooks
  3857      // on them.
  3858      this.children[i].$destroy(false, true);
  3859    }
  3860    var dirs = this.unlink.dirs;
  3861    for (i = 0, l = dirs.length; i < l; i++) {
  3862      // disable the watchers on all the directives
  3863      // so that the rendered content stays the same
  3864      // during removal.
  3865      dirs[i]._watcher && dirs[i]._watcher.teardown();
  3866    }
  3867  };
  3868  
  3869  /**
  3870   * Destroy the fragment.
  3871   */
  3872  
  3873  Fragment.prototype.destroy = function () {
  3874    if (this.parentFrag) {
  3875      this.parentFrag.childFrags.$remove(this);
  3876    }
  3877    this.node.__v_frag = null;
  3878    this.unlink();
  3879  };
  3880  
  3881  /**
  3882   * Call attach hook for a Vue instance.
  3883   *
  3884   * @param {Vue} child
  3885   */
  3886  
  3887  function attach(child) {
  3888    if (!child._isAttached && inDoc(child.$el)) {
  3889      child._callHook('attached');
  3890    }
  3891  }
  3892  
  3893  /**
  3894   * Call detach hook for a Vue instance.
  3895   *
  3896   * @param {Vue} child
  3897   */
  3898  
  3899  function detach(child) {
  3900    if (child._isAttached && !inDoc(child.$el)) {
  3901      child._callHook('detached');
  3902    }
  3903  }
  3904  
  3905  var linkerCache = new Cache(5000);
  3906  
  3907  /**
  3908   * A factory that can be used to create instances of a
  3909   * fragment. Caches the compiled linker if possible.
  3910   *
  3911   * @param {Vue} vm
  3912   * @param {Element|String} el
  3913   */
  3914  function FragmentFactory(vm, el) {
  3915    this.vm = vm;
  3916    var template;
  3917    var isString = typeof el === 'string';
  3918    if (isString || isTemplate(el) && !el.hasAttribute('v-if')) {
  3919      template = parseTemplate(el, true);
  3920    } else {
  3921      template = document.createDocumentFragment();
  3922      template.appendChild(el);
  3923    }
  3924    this.template = template;
  3925    // linker can be cached, but only for components
  3926    var linker;
  3927    var cid = vm.constructor.cid;
  3928    if (cid > 0) {
  3929      var cacheId = cid + (isString ? el : getOuterHTML(el));
  3930      linker = linkerCache.get(cacheId);
  3931      if (!linker) {
  3932        linker = compile(template, vm.$options, true);
  3933        linkerCache.put(cacheId, linker);
  3934      }
  3935    } else {
  3936      linker = compile(template, vm.$options, true);
  3937    }
  3938    this.linker = linker;
  3939  }
  3940  
  3941  /**
  3942   * Create a fragment instance with given host and scope.
  3943   *
  3944   * @param {Vue} host
  3945   * @param {Object} scope
  3946   * @param {Fragment} parentFrag
  3947   */
  3948  
  3949  FragmentFactory.prototype.create = function (host, scope, parentFrag) {
  3950    var frag = cloneNode(this.template);
  3951    return new Fragment(this.linker, this.vm, frag, host, scope, parentFrag);
  3952  };
  3953  
  3954  var ON = 700;
  3955  var MODEL = 800;
  3956  var BIND = 850;
  3957  var TRANSITION = 1100;
  3958  var EL = 1500;
  3959  var COMPONENT = 1500;
  3960  var PARTIAL = 1750;
  3961  var IF = 2100;
  3962  var FOR = 2200;
  3963  var SLOT = 2300;
  3964  
  3965  var uid$3 = 0;
  3966  
  3967  var vFor = {
  3968  
  3969    priority: FOR,
  3970    terminal: true,
  3971  
  3972    params: ['track-by', 'stagger', 'enter-stagger', 'leave-stagger'],
  3973  
  3974    bind: function bind() {
  3975      // support "item in/of items" syntax
  3976      var inMatch = this.expression.match(/(.*) (?:in|of) (.*)/);
  3977      if (inMatch) {
  3978        var itMatch = inMatch[1].match(/\((.*),(.*)\)/);
  3979        if (itMatch) {
  3980          this.iterator = itMatch[1].trim();
  3981          this.alias = itMatch[2].trim();
  3982        } else {
  3983          this.alias = inMatch[1].trim();
  3984        }
  3985        this.expression = inMatch[2];
  3986      }
  3987  
  3988      if (!this.alias) {
  3989        process.env.NODE_ENV !== 'production' && warn('Invalid v-for expression "' + this.descriptor.raw + '": ' + 'alias is required.', this.vm);
  3990        return;
  3991      }
  3992  
  3993      // uid as a cache identifier
  3994      this.id = '__v-for__' + ++uid$3;
  3995  
  3996      // check if this is an option list,
  3997      // so that we know if we need to update the <select>'s
  3998      // v-model when the option list has changed.
  3999      // because v-model has a lower priority than v-for,
  4000      // the v-model is not bound here yet, so we have to
  4001      // retrive it in the actual updateModel() function.
  4002      var tag = this.el.tagName;
  4003      this.isOption = (tag === 'OPTION' || tag === 'OPTGROUP') && this.el.parentNode.tagName === 'SELECT';
  4004  
  4005      // setup anchor nodes
  4006      this.start = createAnchor('v-for-start');
  4007      this.end = createAnchor('v-for-end');
  4008      replace(this.el, this.end);
  4009      before(this.start, this.end);
  4010  
  4011      // cache
  4012      this.cache = Object.create(null);
  4013  
  4014      // fragment factory
  4015      this.factory = new FragmentFactory(this.vm, this.el);
  4016    },
  4017  
  4018    update: function update(data) {
  4019      this.diff(data);
  4020      this.updateRef();
  4021      this.updateModel();
  4022    },
  4023  
  4024    /**
  4025     * Diff, based on new data and old data, determine the
  4026     * minimum amount of DOM manipulations needed to make the
  4027     * DOM reflect the new data Array.
  4028     *
  4029     * The algorithm diffs the new data Array by storing a
  4030     * hidden reference to an owner vm instance on previously
  4031     * seen data. This allows us to achieve O(n) which is
  4032     * better than a levenshtein distance based algorithm,
  4033     * which is O(m * n).
  4034     *
  4035     * @param {Array} data
  4036     */
  4037  
  4038    diff: function diff(data) {
  4039      // check if the Array was converted from an Object
  4040      var item = data[0];
  4041      var convertedFromObject = this.fromObject = isObject(item) && hasOwn(item, '$key') && hasOwn(item, '$value');
  4042  
  4043      var trackByKey = this.params.trackBy;
  4044      var oldFrags = this.frags;
  4045      var frags = this.frags = new Array(data.length);
  4046      var alias = this.alias;
  4047      var iterator = this.iterator;
  4048      var start = this.start;
  4049      var end = this.end;
  4050      var inDocument = inDoc(start);
  4051      var init = !oldFrags;
  4052      var i, l, frag, key, value, primitive;
  4053  
  4054      // First pass, go through the new Array and fill up
  4055      // the new frags array. If a piece of data has a cached
  4056      // instance for it, we reuse it. Otherwise build a new
  4057      // instance.
  4058      for (i = 0, l = data.length; i < l; i++) {
  4059        item = data[i];
  4060        key = convertedFromObject ? item.$key : null;
  4061        value = convertedFromObject ? item.$value : item;
  4062        primitive = !isObject(value);
  4063        frag = !init && this.getCachedFrag(value, i, key);
  4064        if (frag) {
  4065          // reusable fragment
  4066          frag.reused = true;
  4067          // update $index
  4068          frag.scope.$index = i;
  4069          // update $key
  4070          if (key) {
  4071            frag.scope.$key = key;
  4072          }
  4073          // update iterator
  4074          if (iterator) {
  4075            frag.scope[iterator] = key !== null ? key : i;
  4076          }
  4077          // update data for track-by, object repeat &
  4078          // primitive values.
  4079          if (trackByKey || convertedFromObject || primitive) {
  4080            withoutConversion(function () {
  4081              frag.scope[alias] = value;
  4082            });
  4083          }
  4084        } else {
  4085          // new isntance
  4086          frag = this.create(value, alias, i, key);
  4087          frag.fresh = !init;
  4088        }
  4089        frags[i] = frag;
  4090        if (init) {
  4091          frag.before(end);
  4092        }
  4093      }
  4094  
  4095      // we're done for the initial render.
  4096      if (init) {
  4097        return;
  4098      }
  4099  
  4100      // Second pass, go through the old fragments and
  4101      // destroy those who are not reused (and remove them
  4102      // from cache)
  4103      var removalIndex = 0;
  4104      var totalRemoved = oldFrags.length - frags.length;
  4105      // when removing a large number of fragments, watcher removal
  4106      // turns out to be a perf bottleneck, so we batch the watcher
  4107      // removals into a single filter call!
  4108      this.vm._vForRemoving = true;
  4109      for (i = 0, l = oldFrags.length; i < l; i++) {
  4110        frag = oldFrags[i];
  4111        if (!frag.reused) {
  4112          this.deleteCachedFrag(frag);
  4113          this.remove(frag, removalIndex++, totalRemoved, inDocument);
  4114        }
  4115      }
  4116      this.vm._vForRemoving = false;
  4117      if (removalIndex) {
  4118        this.vm._watchers = this.vm._watchers.filter(function (w) {
  4119          return w.active;
  4120        });
  4121      }
  4122  
  4123      // Final pass, move/insert new fragments into the
  4124      // right place.
  4125      var targetPrev, prevEl, currentPrev;
  4126      var insertionIndex = 0;
  4127      for (i = 0, l = frags.length; i < l; i++) {
  4128        frag = frags[i];
  4129        // this is the frag that we should be after
  4130        targetPrev = frags[i - 1];
  4131        prevEl = targetPrev ? targetPrev.staggerCb ? targetPrev.staggerAnchor : targetPrev.end || targetPrev.node : start;
  4132        if (frag.reused && !frag.staggerCb) {
  4133          currentPrev = findPrevFrag(frag, start, this.id);
  4134          if (currentPrev !== targetPrev && (!currentPrev ||
  4135          // optimization for moving a single item.
  4136          // thanks to suggestions by @livoras in #1807
  4137          findPrevFrag(currentPrev, start, this.id) !== targetPrev)) {
  4138            this.move(frag, prevEl);
  4139          }
  4140        } else {
  4141          // new instance, or still in stagger.
  4142          // insert with updated stagger index.
  4143          this.insert(frag, insertionIndex++, prevEl, inDocument);
  4144        }
  4145        frag.reused = frag.fresh = false;
  4146      }
  4147    },
  4148  
  4149    /**
  4150     * Create a new fragment instance.
  4151     *
  4152     * @param {*} value
  4153     * @param {String} alias
  4154     * @param {Number} index
  4155     * @param {String} [key]
  4156     * @return {Fragment}
  4157     */
  4158  
  4159    create: function create(value, alias, index, key) {
  4160      var host = this._host;
  4161      // create iteration scope
  4162      var parentScope = this._scope || this.vm;
  4163      var scope = Object.create(parentScope);
  4164      // ref holder for the scope
  4165      scope.$refs = Object.create(parentScope.$refs);
  4166      scope.$els = Object.create(parentScope.$els);
  4167      // make sure point $parent to parent scope
  4168      scope.$parent = parentScope;
  4169      // for two-way binding on alias
  4170      scope.$forContext = this;
  4171      // define scope properties
  4172      // important: define the scope alias without forced conversion
  4173      // so that frozen data structures remain non-reactive.
  4174      withoutConversion(function () {
  4175        defineReactive(scope, alias, value);
  4176      });
  4177      defineReactive(scope, '$index', index);
  4178      if (key) {
  4179        defineReactive(scope, '$key', key);
  4180      } else if (scope.$key) {
  4181        // avoid accidental fallback
  4182        def(scope, '$key', null);
  4183      }
  4184      if (this.iterator) {
  4185        defineReactive(scope, this.iterator, key !== null ? key : index);
  4186      }
  4187      var frag = this.factory.create(host, scope, this._frag);
  4188      frag.forId = this.id;
  4189      this.cacheFrag(value, frag, index, key);
  4190      return frag;
  4191    },
  4192  
  4193    /**
  4194     * Update the v-ref on owner vm.
  4195     */
  4196  
  4197    updateRef: function updateRef() {
  4198      var ref = this.descriptor.ref;
  4199      if (!ref) return;
  4200      var hash = (this._scope || this.vm).$refs;
  4201      var refs;
  4202      if (!this.fromObject) {
  4203        refs = this.frags.map(findVmFromFrag);
  4204      } else {
  4205        refs = {};
  4206        this.frags.forEach(function (frag) {
  4207          refs[frag.scope.$key] = findVmFromFrag(frag);
  4208        });
  4209      }
  4210      hash[ref] = refs;
  4211    },
  4212  
  4213    /**
  4214     * For option lists, update the containing v-model on
  4215     * parent <select>.
  4216     */
  4217  
  4218    updateModel: function updateModel() {
  4219      if (this.isOption) {
  4220        var parent = this.start.parentNode;
  4221        var model = parent && parent.__v_model;
  4222        if (model) {
  4223          model.forceUpdate();
  4224        }
  4225      }
  4226    },
  4227  
  4228    /**
  4229     * Insert a fragment. Handles staggering.
  4230     *
  4231     * @param {Fragment} frag
  4232     * @param {Number} index
  4233     * @param {Node} prevEl
  4234     * @param {Boolean} inDocument
  4235     */
  4236  
  4237    insert: function insert(frag, index, prevEl, inDocument) {
  4238      if (frag.staggerCb) {
  4239        frag.staggerCb.cancel();
  4240        frag.staggerCb = null;
  4241      }
  4242      var staggerAmount = this.getStagger(frag, index, null, 'enter');
  4243      if (inDocument && staggerAmount) {
  4244        // create an anchor and insert it synchronously,
  4245        // so that we can resolve the correct order without
  4246        // worrying about some elements not inserted yet
  4247        var anchor = frag.staggerAnchor;
  4248        if (!anchor) {
  4249          anchor = frag.staggerAnchor = createAnchor('stagger-anchor');
  4250          anchor.__v_frag = frag;
  4251        }
  4252        after(anchor, prevEl);
  4253        var op = frag.staggerCb = cancellable(function () {
  4254          frag.staggerCb = null;
  4255          frag.before(anchor);
  4256          remove(anchor);
  4257        });
  4258        setTimeout(op, staggerAmount);
  4259      } else {
  4260        var target = prevEl.nextSibling;
  4261        /* istanbul ignore if */
  4262        if (!target) {
  4263          // reset end anchor position in case the position was messed up
  4264          // by an external drag-n-drop library.
  4265          after(this.end, prevEl);
  4266          target = this.end;
  4267        }
  4268        frag.before(target);
  4269      }
  4270    },
  4271  
  4272    /**
  4273     * Remove a fragment. Handles staggering.
  4274     *
  4275     * @param {Fragment} frag
  4276     * @param {Number} index
  4277     * @param {Number} total
  4278     * @param {Boolean} inDocument
  4279     */
  4280  
  4281    remove: function remove(frag, index, total, inDocument) {
  4282      if (frag.staggerCb) {
  4283        frag.staggerCb.cancel();
  4284        frag.staggerCb = null;
  4285        // it's not possible for the same frag to be removed
  4286        // twice, so if we have a pending stagger callback,
  4287        // it means this frag is queued for enter but removed
  4288        // before its transition started. Since it is already
  4289        // destroyed, we can just leave it in detached state.
  4290        return;
  4291      }
  4292      var staggerAmount = this.getStagger(frag, index, total, 'leave');
  4293      if (inDocument && staggerAmount) {
  4294        var op = frag.staggerCb = cancellable(function () {
  4295          frag.staggerCb = null;
  4296          frag.remove();
  4297        });
  4298        setTimeout(op, staggerAmount);
  4299      } else {
  4300        frag.remove();
  4301      }
  4302    },
  4303  
  4304    /**
  4305     * Move a fragment to a new position.
  4306     * Force no transition.
  4307     *
  4308     * @param {Fragment} frag
  4309     * @param {Node} prevEl
  4310     */
  4311  
  4312    move: function move(frag, prevEl) {
  4313      // fix a common issue with Sortable:
  4314      // if prevEl doesn't have nextSibling, this means it's
  4315      // been dragged after the end anchor. Just re-position
  4316      // the end anchor to the end of the container.
  4317      /* istanbul ignore if */
  4318      if (!prevEl.nextSibling) {
  4319        this.end.parentNode.appendChild(this.end);
  4320      }
  4321      frag.before(prevEl.nextSibling, false);
  4322    },
  4323  
  4324    /**
  4325     * Cache a fragment using track-by or the object key.
  4326     *
  4327     * @param {*} value
  4328     * @param {Fragment} frag
  4329     * @param {Number} index
  4330     * @param {String} [key]
  4331     */
  4332  
  4333    cacheFrag: function cacheFrag(value, frag, index, key) {
  4334      var trackByKey = this.params.trackBy;
  4335      var cache = this.cache;
  4336      var primitive = !isObject(value);
  4337      var id;
  4338      if (key || trackByKey || primitive) {
  4339        id = getTrackByKey(index, key, value, trackByKey);
  4340        if (!cache[id]) {
  4341          cache[id] = frag;
  4342        } else if (trackByKey !== '$index') {
  4343          process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
  4344        }
  4345      } else {
  4346        id = this.id;
  4347        if (hasOwn(value, id)) {
  4348          if (value[id] === null) {
  4349            value[id] = frag;
  4350          } else {
  4351            process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
  4352          }
  4353        } else if (Object.isExtensible(value)) {
  4354          def(value, id, frag);
  4355        } else if (process.env.NODE_ENV !== 'production') {
  4356          warn('Frozen v-for objects cannot be automatically tracked, make sure to ' + 'provide a track-by key.');
  4357        }
  4358      }
  4359      frag.raw = value;
  4360    },
  4361  
  4362    /**
  4363     * Get a cached fragment from the value/index/key
  4364     *
  4365     * @param {*} value
  4366     * @param {Number} index
  4367     * @param {String} key
  4368     * @return {Fragment}
  4369     */
  4370  
  4371    getCachedFrag: function getCachedFrag(value, index, key) {
  4372      var trackByKey = this.params.trackBy;
  4373      var primitive = !isObject(value);
  4374      var frag;
  4375      if (key || trackByKey || primitive) {
  4376        var id = getTrackByKey(index, key, value, trackByKey);
  4377        frag = this.cache[id];
  4378      } else {
  4379        frag = value[this.id];
  4380      }
  4381      if (frag && (frag.reused || frag.fresh)) {
  4382        process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
  4383      }
  4384      return frag;
  4385    },
  4386  
  4387    /**
  4388     * Delete a fragment from cache.
  4389     *
  4390     * @param {Fragment} frag
  4391     */
  4392  
  4393    deleteCachedFrag: function deleteCachedFrag(frag) {
  4394      var value = frag.raw;
  4395      var trackByKey = this.params.trackBy;
  4396      var scope = frag.scope;
  4397      var index = scope.$index;
  4398      // fix #948: avoid accidentally fall through to
  4399      // a parent repeater which happens to have $key.
  4400      var key = hasOwn(scope, '$key') && scope.$key;
  4401      var primitive = !isObject(value);
  4402      if (trackByKey || key || primitive) {
  4403        var id = getTrackByKey(index, key, value, trackByKey);
  4404        this.cache[id] = null;
  4405      } else {
  4406        value[this.id] = null;
  4407        frag.raw = null;
  4408      }
  4409    },
  4410  
  4411    /**
  4412     * Get the stagger amount for an insertion/removal.
  4413     *
  4414     * @param {Fragment} frag
  4415     * @param {Number} index
  4416     * @param {Number} total
  4417     * @param {String} type
  4418     */
  4419  
  4420    getStagger: function getStagger(frag, index, total, type) {
  4421      type = type + 'Stagger';
  4422      var trans = frag.node.__v_trans;
  4423      var hooks = trans && trans.hooks;
  4424      var hook = hooks && (hooks[type] || hooks.stagger);
  4425      return hook ? hook.call(frag, index, total) : index * parseInt(this.params[type] || this.params.stagger, 10);
  4426    },
  4427  
  4428    /**
  4429     * Pre-process the value before piping it through the
  4430     * filters. This is passed to and called by the watcher.
  4431     */
  4432  
  4433    _preProcess: function _preProcess(value) {
  4434      // regardless of type, store the un-filtered raw value.
  4435      this.rawValue = value;
  4436      return value;
  4437    },
  4438  
  4439    /**
  4440     * Post-process the value after it has been piped through
  4441     * the filters. This is passed to and called by the watcher.
  4442     *
  4443     * It is necessary for this to be called during the
  4444     * wathcer's dependency collection phase because we want
  4445     * the v-for to update when the source Object is mutated.
  4446     */
  4447  
  4448    _postProcess: function _postProcess(value) {
  4449      if (isArray(value)) {
  4450        return value;
  4451      } else if (isPlainObject(value)) {
  4452        // convert plain object to array.
  4453        var keys = Object.keys(value);
  4454        var i = keys.length;
  4455        var res = new Array(i);
  4456        var key;
  4457        while (i--) {
  4458          key = keys[i];
  4459          res[i] = {
  4460            $key: key,
  4461            $value: value[key]
  4462          };
  4463        }
  4464        return res;
  4465      } else {
  4466        if (typeof value === 'number' && !isNaN(value)) {
  4467          value = range(value);
  4468        }
  4469        return value || [];
  4470      }
  4471    },
  4472  
  4473    unbind: function unbind() {
  4474      if (this.descriptor.ref) {
  4475        (this._scope || this.vm).$refs[this.descriptor.ref] = null;
  4476      }
  4477      if (this.frags) {
  4478        var i = this.frags.length;
  4479        var frag;
  4480        while (i--) {
  4481          frag = this.frags[i];
  4482          this.deleteCachedFrag(frag);
  4483          frag.destroy();
  4484        }
  4485      }
  4486    }
  4487  };
  4488  
  4489  /**
  4490   * Helper to find the previous element that is a fragment
  4491   * anchor. This is necessary because a destroyed frag's
  4492   * element could still be lingering in the DOM before its
  4493   * leaving transition finishes, but its inserted flag
  4494   * should have been set to false so we can skip them.
  4495   *
  4496   * If this is a block repeat, we want to make sure we only
  4497   * return frag that is bound to this v-for. (see #929)
  4498   *
  4499   * @param {Fragment} frag
  4500   * @param {Comment|Text} anchor
  4501   * @param {String} id
  4502   * @return {Fragment}
  4503   */
  4504  
  4505  function findPrevFrag(frag, anchor, id) {
  4506    var el = frag.node.previousSibling;
  4507    /* istanbul ignore if */
  4508    if (!el) return;
  4509    frag = el.__v_frag;
  4510    while ((!frag || frag.forId !== id || !frag.inserted) && el !== anchor) {
  4511      el = el.previousSibling;
  4512      /* istanbul ignore if */
  4513      if (!el) return;
  4514      frag = el.__v_frag;
  4515    }
  4516    return frag;
  4517  }
  4518  
  4519  /**
  4520   * Find a vm from a fragment.
  4521   *
  4522   * @param {Fragment} frag
  4523   * @return {Vue|undefined}
  4524   */
  4525  
  4526  function findVmFromFrag(frag) {
  4527    var node = frag.node;
  4528    // handle multi-node frag
  4529    if (frag.end) {
  4530      while (!node.__vue__ && node !== frag.end && node.nextSibling) {
  4531        node = node.nextSibling;
  4532      }
  4533    }
  4534    return node.__vue__;
  4535  }
  4536  
  4537  /**
  4538   * Create a range array from given number.
  4539   *
  4540   * @param {Number} n
  4541   * @return {Array}
  4542   */
  4543  
  4544  function range(n) {
  4545    var i = -1;
  4546    var ret = new Array(Math.floor(n));
  4547    while (++i < n) {
  4548      ret[i] = i;
  4549    }
  4550    return ret;
  4551  }
  4552  
  4553  /**
  4554   * Get the track by key for an item.
  4555   *
  4556   * @param {Number} index
  4557   * @param {String} key
  4558   * @param {*} value
  4559   * @param {String} [trackByKey]
  4560   */
  4561  
  4562  function getTrackByKey(index, key, value, trackByKey) {
  4563    return trackByKey ? trackByKey === '$index' ? index : trackByKey.charAt(0).match(/\w/) ? getPath(value, trackByKey) : value[trackByKey] : key || value;
  4564  }
  4565  
  4566  if (process.env.NODE_ENV !== 'production') {
  4567    vFor.warnDuplicate = function (value) {
  4568      warn('Duplicate value found in v-for="' + this.descriptor.raw + '": ' + JSON.stringify(value) + '. Use track-by="$index" if ' + 'you are expecting duplicate values.', this.vm);
  4569    };
  4570  }
  4571  
  4572  var vIf = {
  4573  
  4574    priority: IF,
  4575    terminal: true,
  4576  
  4577    bind: function bind() {
  4578      var el = this.el;
  4579      if (!el.__vue__) {
  4580        // check else block
  4581        var next = el.nextElementSibling;
  4582        if (next && getAttr(next, 'v-else') !== null) {
  4583          remove(next);
  4584          this.elseEl = next;
  4585        }
  4586        // check main block
  4587        this.anchor = createAnchor('v-if');
  4588        replace(el, this.anchor);
  4589      } else {
  4590        process.env.NODE_ENV !== 'production' && warn('v-if="' + this.expression + '" cannot be ' + 'used on an instance root element.', this.vm);
  4591        this.invalid = true;
  4592      }
  4593    },
  4594  
  4595    update: function update(value) {
  4596      if (this.invalid) return;
  4597      if (value) {
  4598        if (!this.frag) {
  4599          this.insert();
  4600        }
  4601      } else {
  4602        this.remove();
  4603      }
  4604    },
  4605  
  4606    insert: function insert() {
  4607      if (this.elseFrag) {
  4608        this.elseFrag.remove();
  4609        this.elseFrag = null;
  4610      }
  4611      // lazy init factory
  4612      if (!this.factory) {
  4613        this.factory = new FragmentFactory(this.vm, this.el);
  4614      }
  4615      this.frag = this.factory.create(this._host, this._scope, this._frag);
  4616      this.frag.before(this.anchor);
  4617    },
  4618  
  4619    remove: function remove() {
  4620      if (this.frag) {
  4621        this.frag.remove();
  4622        this.frag = null;
  4623      }
  4624      if (this.elseEl && !this.elseFrag) {
  4625        if (!this.elseFactory) {
  4626          this.elseFactory = new FragmentFactory(this.elseEl._context || this.vm, this.elseEl);
  4627        }
  4628        this.elseFrag = this.elseFactory.create(this._host, this._scope, this._frag);
  4629        this.elseFrag.before(this.anchor);
  4630      }
  4631    },
  4632  
  4633    unbind: function unbind() {
  4634      if (this.frag) {
  4635        this.frag.destroy();
  4636      }
  4637      if (this.elseFrag) {
  4638        this.elseFrag.destroy();
  4639      }
  4640    }
  4641  };
  4642  
  4643  var show = {
  4644  
  4645    bind: function bind() {
  4646      // check else block
  4647      var next = this.el.nextElementSibling;
  4648      if (next && getAttr(next, 'v-else') !== null) {
  4649        this.elseEl = next;
  4650      }
  4651    },
  4652  
  4653    update: function update(value) {
  4654      this.apply(this.el, value);
  4655      if (this.elseEl) {
  4656        this.apply(this.elseEl, !value);
  4657      }
  4658    },
  4659  
  4660    apply: function apply(el, value) {
  4661      if (inDoc(el)) {
  4662        applyTransition(el, value ? 1 : -1, toggle, this.vm);
  4663      } else {
  4664        toggle();
  4665      }
  4666      function toggle() {
  4667        el.style.display = value ? '' : 'none';
  4668      }
  4669    }
  4670  };
  4671  
  4672  var text$2 = {
  4673  
  4674    bind: function bind() {
  4675      var self = this;
  4676      var el = this.el;
  4677      var isRange = el.type === 'range';
  4678      var lazy = this.params.lazy;
  4679      var number = this.params.number;
  4680      var debounce = this.params.debounce;
  4681  
  4682      // handle composition events.
  4683      //   http://blog.evanyou.me/2014/01/03/composition-event/
  4684      // skip this for Android because it handles composition
  4685      // events quite differently. Android doesn't trigger
  4686      // composition events for language input methods e.g.
  4687      // Chinese, but instead triggers them for spelling
  4688      // suggestions... (see Discussion/#162)
  4689      var composing = false;
  4690      if (!isAndroid && !isRange) {
  4691        this.on('compositionstart', function () {
  4692          composing = true;
  4693        });
  4694        this.on('compositionend', function () {
  4695          composing = false;
  4696          // in IE11 the "compositionend" event fires AFTER
  4697          // the "input" event, so the input handler is blocked
  4698          // at the end... have to call it here.
  4699          //
  4700          // #1327: in lazy mode this is unecessary.
  4701          if (!lazy) {
  4702            self.listener();
  4703          }
  4704        });
  4705      }
  4706  
  4707      // prevent messing with the input when user is typing,
  4708      // and force update on blur.
  4709      this.focused = false;
  4710      if (!isRange && !lazy) {
  4711        this.on('focus', function () {
  4712          self.focused = true;
  4713        });
  4714        this.on('blur', function () {
  4715          self.focused = false;
  4716          // do not sync value after fragment removal (#2017)
  4717          if (!self._frag || self._frag.inserted) {
  4718            self.rawListener();
  4719          }
  4720        });
  4721      }
  4722  
  4723      // Now attach the main listener
  4724      this.listener = this.rawListener = function () {
  4725        if (composing || !self._bound) {
  4726          return;
  4727        }
  4728        var val = number || isRange ? toNumber(el.value) : el.value;
  4729        self.set(val);
  4730        // force update on next tick to avoid lock & same value
  4731        // also only update when user is not typing
  4732        nextTick(function () {
  4733          if (self._bound && !self.focused) {
  4734            self.update(self._watcher.value);
  4735          }
  4736        });
  4737      };
  4738  
  4739      // apply debounce
  4740      if (debounce) {
  4741        this.listener = _debounce(this.listener, debounce);
  4742      }
  4743  
  4744      // Support jQuery events, since jQuery.trigger() doesn't
  4745      // trigger native events in some cases and some plugins
  4746      // rely on $.trigger()
  4747      //
  4748      // We want to make sure if a listener is attached using
  4749      // jQuery, it is also removed with jQuery, that's why
  4750      // we do the check for each directive instance and
  4751      // store that check result on itself. This also allows
  4752      // easier test coverage control by unsetting the global
  4753      // jQuery variable in tests.
  4754      this.hasjQuery = typeof jQuery === 'function';
  4755      if (this.hasjQuery) {
  4756        var method = jQuery.fn.on ? 'on' : 'bind';
  4757        jQuery(el)[method]('change', this.rawListener);
  4758        if (!lazy) {
  4759          jQuery(el)[method]('input', this.listener);
  4760        }
  4761      } else {
  4762        this.on('change', this.rawListener);
  4763        if (!lazy) {
  4764          this.on('input', this.listener);
  4765        }
  4766      }
  4767  
  4768      // IE9 doesn't fire input event on backspace/del/cut
  4769      if (!lazy && isIE9) {
  4770        this.on('cut', function () {
  4771          nextTick(self.listener);
  4772        });
  4773        this.on('keyup', function (e) {
  4774          if (e.keyCode === 46 || e.keyCode === 8) {
  4775            self.listener();
  4776          }
  4777        });
  4778      }
  4779  
  4780      // set initial value if present
  4781      if (el.hasAttribute('value') || el.tagName === 'TEXTAREA' && el.value.trim()) {
  4782        this.afterBind = this.listener;
  4783      }
  4784    },
  4785  
  4786    update: function update(value) {
  4787      this.el.value = _toString(value);
  4788    },
  4789  
  4790    unbind: function unbind() {
  4791      var el = this.el;
  4792      if (this.hasjQuery) {
  4793        var method = jQuery.fn.off ? 'off' : 'unbind';
  4794        jQuery(el)[method]('change', this.listener);
  4795        jQuery(el)[method]('input', this.listener);
  4796      }
  4797    }
  4798  };
  4799  
  4800  var radio = {
  4801  
  4802    bind: function bind() {
  4803      var self = this;
  4804      var el = this.el;
  4805  
  4806      this.getValue = function () {
  4807        // value overwrite via v-bind:value
  4808        if (el.hasOwnProperty('_value')) {
  4809          return el._value;
  4810        }
  4811        var val = el.value;
  4812        if (self.params.number) {
  4813          val = toNumber(val);
  4814        }
  4815        return val;
  4816      };
  4817  
  4818      this.listener = function () {
  4819        self.set(self.getValue());
  4820      };
  4821      this.on('change', this.listener);
  4822  
  4823      if (el.hasAttribute('checked')) {
  4824        this.afterBind = this.listener;
  4825      }
  4826    },
  4827  
  4828    update: function update(value) {
  4829      this.el.checked = looseEqual(value, this.getValue());
  4830    }
  4831  };
  4832  
  4833  var select = {
  4834  
  4835    bind: function bind() {
  4836      var self = this;
  4837      var el = this.el;
  4838  
  4839      // method to force update DOM using latest value.
  4840      this.forceUpdate = function () {
  4841        if (self._watcher) {
  4842          self.update(self._watcher.get());
  4843        }
  4844      };
  4845  
  4846      // check if this is a multiple select
  4847      var multiple = this.multiple = el.hasAttribute('multiple');
  4848  
  4849      // attach listener
  4850      this.listener = function () {
  4851        var value = getValue(el, multiple);
  4852        value = self.params.number ? isArray(value) ? value.map(toNumber) : toNumber(value) : value;
  4853        self.set(value);
  4854      };
  4855      this.on('change', this.listener);
  4856  
  4857      // if has initial value, set afterBind
  4858      var initValue = getValue(el, multiple, true);
  4859      if (multiple && initValue.length || !multiple && initValue !== null) {
  4860        this.afterBind = this.listener;
  4861      }
  4862  
  4863      // All major browsers except Firefox resets
  4864      // selectedIndex with value -1 to 0 when the element
  4865      // is appended to a new parent, therefore we have to
  4866      // force a DOM update whenever that happens...
  4867      this.vm.$on('hook:attached', this.forceUpdate);
  4868    },
  4869  
  4870    update: function update(value) {
  4871      var el = this.el;
  4872      el.selectedIndex = -1;
  4873      var multi = this.multiple && isArray(value);
  4874      var options = el.options;
  4875      var i = options.length;
  4876      var op, val;
  4877      while (i--) {
  4878        op = options[i];
  4879        val = op.hasOwnProperty('_value') ? op._value : op.value;
  4880        /* eslint-disable eqeqeq */
  4881        op.selected = multi ? indexOf$1(value, val) > -1 : looseEqual(value, val);
  4882        /* eslint-enable eqeqeq */
  4883      }
  4884    },
  4885  
  4886    unbind: function unbind() {
  4887      /* istanbul ignore next */
  4888      this.vm.$off('hook:attached', this.forceUpdate);
  4889    }
  4890  };
  4891  
  4892  /**
  4893   * Get select value
  4894   *
  4895   * @param {SelectElement} el
  4896   * @param {Boolean} multi
  4897   * @param {Boolean} init
  4898   * @return {Array|*}
  4899   */
  4900  
  4901  function getValue(el, multi, init) {
  4902    var res = multi ? [] : null;
  4903    var op, val, selected;
  4904    for (var i = 0, l = el.options.length; i < l; i++) {
  4905      op = el.options[i];
  4906      selected = init ? op.hasAttribute('selected') : op.selected;
  4907      if (selected) {
  4908        val = op.hasOwnProperty('_value') ? op._value : op.value;
  4909        if (multi) {
  4910          res.push(val);
  4911        } else {
  4912          return val;
  4913        }
  4914      }
  4915    }
  4916    return res;
  4917  }
  4918  
  4919  /**
  4920   * Native Array.indexOf uses strict equal, but in this
  4921   * case we need to match string/numbers with custom equal.
  4922   *
  4923   * @param {Array} arr
  4924   * @param {*} val
  4925   */
  4926  
  4927  function indexOf$1(arr, val) {
  4928    var i = arr.length;
  4929    while (i--) {
  4930      if (looseEqual(arr[i], val)) {
  4931        return i;
  4932      }
  4933    }
  4934    return -1;
  4935  }
  4936  
  4937  var checkbox = {
  4938  
  4939    bind: function bind() {
  4940      var self = this;
  4941      var el = this.el;
  4942  
  4943      this.getValue = function () {
  4944        return el.hasOwnProperty('_value') ? el._value : self.params.number ? toNumber(el.value) : el.value;
  4945      };
  4946  
  4947      function getBooleanValue() {
  4948        var val = el.checked;
  4949        if (val && el.hasOwnProperty('_trueValue')) {
  4950          return el._trueValue;
  4951        }
  4952        if (!val && el.hasOwnProperty('_falseValue')) {
  4953          return el._falseValue;
  4954        }
  4955        return val;
  4956      }
  4957  
  4958      this.listener = function () {
  4959        var model = self._watcher.value;
  4960        if (isArray(model)) {
  4961          var val = self.getValue();
  4962          if (el.checked) {
  4963            if (indexOf(model, val) < 0) {
  4964              model.push(val);
  4965            }
  4966          } else {
  4967            model.$remove(val);
  4968          }
  4969        } else {
  4970          self.set(getBooleanValue());
  4971        }
  4972      };
  4973  
  4974      this.on('change', this.listener);
  4975      if (el.hasAttribute('checked')) {
  4976        this.afterBind = this.listener;
  4977      }
  4978    },
  4979  
  4980    update: function update(value) {
  4981      var el = this.el;
  4982      if (isArray(value)) {
  4983        el.checked = indexOf(value, this.getValue()) > -1;
  4984      } else {
  4985        if (el.hasOwnProperty('_trueValue')) {
  4986          el.checked = looseEqual(value, el._trueValue);
  4987        } else {
  4988          el.checked = !!value;
  4989        }
  4990      }
  4991    }
  4992  };
  4993  
  4994  var handlers = {
  4995    text: text$2,
  4996    radio: radio,
  4997    select: select,
  4998    checkbox: checkbox
  4999  };
  5000  
  5001  var model = {
  5002  
  5003    priority: MODEL,
  5004    twoWay: true,
  5005    handlers: handlers,
  5006    params: ['lazy', 'number', 'debounce'],
  5007  
  5008    /**
  5009     * Possible elements:
  5010     *   <select>
  5011     *   <textarea>
  5012     *   <input type="*">
  5013     *     - text
  5014     *     - checkbox
  5015     *     - radio
  5016     *     - number
  5017     */
  5018  
  5019    bind: function bind() {
  5020      // friendly warning...
  5021      this.checkFilters();
  5022      if (this.hasRead && !this.hasWrite) {
  5023        process.env.NODE_ENV !== 'production' && warn('It seems you are using a read-only filter with ' + 'v-model="' + this.descriptor.raw + '". ' + 'You might want to use a two-way filter to ensure correct behavior.', this.vm);
  5024      }
  5025      var el = this.el;
  5026      var tag = el.tagName;
  5027      var handler;
  5028      if (tag === 'INPUT') {
  5029        handler = handlers[el.type] || handlers.text;
  5030      } else if (tag === 'SELECT') {
  5031        handler = handlers.select;
  5032      } else if (tag === 'TEXTAREA') {
  5033        handler = handlers.text;
  5034      } else {
  5035        process.env.NODE_ENV !== 'production' && warn('v-model does not support element type: ' + tag, this.vm);
  5036        return;
  5037      }
  5038      el.__v_model = this;
  5039      handler.bind.call(this);
  5040      this.update = handler.update;
  5041      this._unbind = handler.unbind;
  5042    },
  5043  
  5044    /**
  5045     * Check read/write filter stats.
  5046     */
  5047  
  5048    checkFilters: function checkFilters() {
  5049      var filters = this.filters;
  5050      if (!filters) return;
  5051      var i = filters.length;
  5052      while (i--) {
  5053        var filter = resolveAsset(this.vm.$options, 'filters', filters[i].name);
  5054        if (typeof filter === 'function' || filter.read) {
  5055          this.hasRead = true;
  5056        }
  5057        if (filter.write) {
  5058          this.hasWrite = true;
  5059        }
  5060      }
  5061    },
  5062  
  5063    unbind: function unbind() {
  5064      this.el.__v_model = null;
  5065      this._unbind && this._unbind();
  5066    }
  5067  };
  5068  
  5069  // keyCode aliases
  5070  var keyCodes = {
  5071    esc: 27,
  5072    tab: 9,
  5073    enter: 13,
  5074    space: 32,
  5075    'delete': [8, 46],
  5076    up: 38,
  5077    left: 37,
  5078    right: 39,
  5079    down: 40
  5080  };
  5081  
  5082  function keyFilter(handler, keys) {
  5083    var codes = keys.map(function (key) {
  5084      var charCode = key.charCodeAt(0);
  5085      if (charCode > 47 && charCode < 58) {
  5086        return parseInt(key, 10);
  5087      }
  5088      if (key.length === 1) {
  5089        charCode = key.toUpperCase().charCodeAt(0);
  5090        if (charCode > 64 && charCode < 91) {
  5091          return charCode;
  5092        }
  5093      }
  5094      return keyCodes[key];
  5095    });
  5096    codes = [].concat.apply([], codes);
  5097    return function keyHandler(e) {
  5098      if (codes.indexOf(e.keyCode) > -1) {
  5099        return handler.call(this, e);
  5100      }
  5101    };
  5102  }
  5103  
  5104  function stopFilter(handler) {
  5105    return function stopHandler(e) {
  5106      e.stopPropagation();
  5107      return handler.call(this, e);
  5108    };
  5109  }
  5110  
  5111  function preventFilter(handler) {
  5112    return function preventHandler(e) {
  5113      e.preventDefault();
  5114      return handler.call(this, e);
  5115    };
  5116  }
  5117  
  5118  function selfFilter(handler) {
  5119    return function selfHandler(e) {
  5120      if (e.target === e.currentTarget) {
  5121        return handler.call(this, e);
  5122      }
  5123    };
  5124  }
  5125  
  5126  var on$1 = {
  5127  
  5128    priority: ON,
  5129    acceptStatement: true,
  5130    keyCodes: keyCodes,
  5131  
  5132    bind: function bind() {
  5133      // deal with iframes
  5134      if (this.el.tagName === 'IFRAME' && this.arg !== 'load') {
  5135        var self = this;
  5136        this.iframeBind = function () {
  5137          on(self.el.contentWindow, self.arg, self.handler, self.modifiers.capture);
  5138        };
  5139        this.on('load', this.iframeBind);
  5140      }
  5141    },
  5142  
  5143    update: function update(handler) {
  5144      // stub a noop for v-on with no value,
  5145      // e.g. @mousedown.prevent
  5146      if (!this.descriptor.raw) {
  5147        handler = function () {};
  5148      }
  5149  
  5150      if (typeof handler !== 'function') {
  5151        process.env.NODE_ENV !== 'production' && warn('v-on:' + this.arg + '="' + this.expression + '" expects a function value, ' + 'got ' + handler, this.vm);
  5152        return;
  5153      }
  5154  
  5155      // apply modifiers
  5156      if (this.modifiers.stop) {
  5157        handler = stopFilter(handler);
  5158      }
  5159      if (this.modifiers.prevent) {
  5160        handler = preventFilter(handler);
  5161      }
  5162      if (this.modifiers.self) {
  5163        handler = selfFilter(handler);
  5164      }
  5165      // key filter
  5166      var keys = Object.keys(this.modifiers).filter(function (key) {
  5167        return key !== 'stop' && key !== 'prevent' && key !== 'self' && key !== 'capture';
  5168      });
  5169      if (keys.length) {
  5170        handler = keyFilter(handler, keys);
  5171      }
  5172  
  5173      this.reset();
  5174      this.handler = handler;
  5175  
  5176      if (this.iframeBind) {
  5177        this.iframeBind();
  5178      } else {
  5179        on(this.el, this.arg, this.handler, this.modifiers.capture);
  5180      }
  5181    },
  5182  
  5183    reset: function reset() {
  5184      var el = this.iframeBind ? this.el.contentWindow : this.el;
  5185      if (this.handler) {
  5186        off(el, this.arg, this.handler);
  5187      }
  5188    },
  5189  
  5190    unbind: function unbind() {
  5191      this.reset();
  5192    }
  5193  };
  5194  
  5195  var prefixes = ['-webkit-', '-moz-', '-ms-'];
  5196  var camelPrefixes = ['Webkit', 'Moz', 'ms'];
  5197  var importantRE = /!important;?$/;
  5198  var propCache = Object.create(null);
  5199  
  5200  var testEl = null;
  5201  
  5202  var style = {
  5203  
  5204    deep: true,
  5205  
  5206    update: function update(value) {
  5207      if (typeof value === 'string') {
  5208        this.el.style.cssText = value;
  5209      } else if (isArray(value)) {
  5210        this.handleObject(value.reduce(extend, {}));
  5211      } else {
  5212        this.handleObject(value || {});
  5213      }
  5214    },
  5215  
  5216    handleObject: function handleObject(value) {
  5217      // cache object styles so that only changed props
  5218      // are actually updated.
  5219      var cache = this.cache || (this.cache = {});
  5220      var name, val;
  5221      for (name in cache) {
  5222        if (!(name in value)) {
  5223          this.handleSingle(name, null);
  5224          delete cache[name];
  5225        }
  5226      }
  5227      for (name in value) {
  5228        val = value[name];
  5229        if (val !== cache[name]) {
  5230          cache[name] = val;
  5231          this.handleSingle(name, val);
  5232        }
  5233      }
  5234    },
  5235  
  5236    handleSingle: function handleSingle(prop, value) {
  5237      prop = normalize(prop);
  5238      if (!prop) return; // unsupported prop
  5239      // cast possible numbers/booleans into strings
  5240      if (value != null) value += '';
  5241      if (value) {
  5242        var isImportant = importantRE.test(value) ? 'important' : '';
  5243        if (isImportant) {
  5244          /* istanbul ignore if */
  5245          if (process.env.NODE_ENV !== 'production') {
  5246            warn('It\'s probably a bad idea to use !important with inline rules. ' + 'This feature will be deprecated in a future version of Vue.');
  5247          }
  5248          value = value.replace(importantRE, '').trim();
  5249          this.el.style.setProperty(prop.kebab, value, isImportant);
  5250        } else {
  5251          this.el.style[prop.camel] = value;
  5252        }
  5253      } else {
  5254        this.el.style[prop.camel] = '';
  5255      }
  5256    }
  5257  
  5258  };
  5259  
  5260  /**
  5261   * Normalize a CSS property name.
  5262   * - cache result
  5263   * - auto prefix
  5264   * - camelCase -> dash-case
  5265   *
  5266   * @param {String} prop
  5267   * @return {String}
  5268   */
  5269  
  5270  function normalize(prop) {
  5271    if (propCache[prop]) {
  5272      return propCache[prop];
  5273    }
  5274    var res = prefix(prop);
  5275    propCache[prop] = propCache[res] = res;
  5276    return res;
  5277  }
  5278  
  5279  /**
  5280   * Auto detect the appropriate prefix for a CSS property.
  5281   * https://gist.github.com/paulirish/523692
  5282   *
  5283   * @param {String} prop
  5284   * @return {String}
  5285   */
  5286  
  5287  function prefix(prop) {
  5288    prop = hyphenate(prop);
  5289    var camel = camelize(prop);
  5290    var upper = camel.charAt(0).toUpperCase() + camel.slice(1);
  5291    if (!testEl) {
  5292      testEl = document.createElement('div');
  5293    }
  5294    var i = prefixes.length;
  5295    var prefixed;
  5296    if (camel !== 'filter' && camel in testEl.style) {
  5297      return {
  5298        kebab: prop,
  5299        camel: camel
  5300      };
  5301    }
  5302    while (i--) {
  5303      prefixed = camelPrefixes[i] + upper;
  5304      if (prefixed in testEl.style) {
  5305        return {
  5306          kebab: prefixes[i] + prop,
  5307          camel: prefixed
  5308        };
  5309      }
  5310    }
  5311  }
  5312  
  5313  // xlink
  5314  var xlinkNS = 'http://www.w3.org/1999/xlink';
  5315  var xlinkRE = /^xlink:/;
  5316  
  5317  // check for attributes that prohibit interpolations
  5318  var disallowedInterpAttrRE = /^v-|^:|^@|^(?:is|transition|transition-mode|debounce|track-by|stagger|enter-stagger|leave-stagger)$/;
  5319  // these attributes should also set their corresponding properties
  5320  // because they only affect the initial state of the element
  5321  var attrWithPropsRE = /^(?:value|checked|selected|muted)$/;
  5322  // these attributes expect enumrated values of "true" or "false"
  5323  // but are not boolean attributes
  5324  var enumeratedAttrRE = /^(?:draggable|contenteditable|spellcheck)$/;
  5325  
  5326  // these attributes should set a hidden property for
  5327  // binding v-model to object values
  5328  var modelProps = {
  5329    value: '_value',
  5330    'true-value': '_trueValue',
  5331    'false-value': '_falseValue'
  5332  };
  5333  
  5334  var bind$1 = {
  5335  
  5336    priority: BIND,
  5337  
  5338    bind: function bind() {
  5339      var attr = this.arg;
  5340      var tag = this.el.tagName;
  5341      // should be deep watch on object mode
  5342      if (!attr) {
  5343        this.deep = true;
  5344      }
  5345      // handle interpolation bindings
  5346      var descriptor = this.descriptor;
  5347      var tokens = descriptor.interp;
  5348      if (tokens) {
  5349        // handle interpolations with one-time tokens
  5350        if (descriptor.hasOneTime) {
  5351          this.expression = tokensToExp(tokens, this._scope || this.vm);
  5352        }
  5353  
  5354        // only allow binding on native attributes
  5355        if (disallowedInterpAttrRE.test(attr) || attr === 'name' && (tag === 'PARTIAL' || tag === 'SLOT')) {
  5356          process.env.NODE_ENV !== 'production' && warn(attr + '="' + descriptor.raw + '": ' + 'attribute interpolation is not allowed in Vue.js ' + 'directives and special attributes.', this.vm);
  5357          this.el.removeAttribute(attr);
  5358          this.invalid = true;
  5359        }
  5360  
  5361        /* istanbul ignore if */
  5362        if (process.env.NODE_ENV !== 'production') {
  5363          var raw = attr + '="' + descriptor.raw + '": ';
  5364          // warn src
  5365          if (attr === 'src') {
  5366            warn(raw + 'interpolation in "src" attribute will cause ' + 'a 404 request. Use v-bind:src instead.', this.vm);
  5367          }
  5368  
  5369          // warn style
  5370          if (attr === 'style') {
  5371            warn(raw + 'interpolation in "style" attribute will cause ' + 'the attribute to be discarded in Internet Explorer. ' + 'Use v-bind:style instead.', this.vm);
  5372          }
  5373        }
  5374      }
  5375    },
  5376  
  5377    update: function update(value) {
  5378      if (this.invalid) {
  5379        return;
  5380      }
  5381      var attr = this.arg;
  5382      if (this.arg) {
  5383        this.handleSingle(attr, value);
  5384      } else {
  5385        this.handleObject(value || {});
  5386      }
  5387    },
  5388  
  5389    // share object handler with v-bind:class
  5390    handleObject: style.handleObject,
  5391  
  5392    handleSingle: function handleSingle(attr, value) {
  5393      var el = this.el;
  5394      var interp = this.descriptor.interp;
  5395      if (this.modifiers.camel) {
  5396        attr = camelize(attr);
  5397      }
  5398      if (!interp && attrWithPropsRE.test(attr) && attr in el) {
  5399        var attrValue = attr === 'value' ? value == null // IE9 will set input.value to "null" for null...
  5400        ? '' : value : value;
  5401  
  5402        if (el[attr] !== attrValue) {
  5403          el[attr] = attrValue;
  5404        }
  5405      }
  5406      // set model props
  5407      var modelProp = modelProps[attr];
  5408      if (!interp && modelProp) {
  5409        el[modelProp] = value;
  5410        // update v-model if present
  5411        var model = el.__v_model;
  5412        if (model) {
  5413          model.listener();
  5414        }
  5415      }
  5416      // do not set value attribute for textarea
  5417      if (attr === 'value' && el.tagName === 'TEXTAREA') {
  5418        el.removeAttribute(attr);
  5419        return;
  5420      }
  5421      // update attribute
  5422      if (enumeratedAttrRE.test(attr)) {
  5423        el.setAttribute(attr, value ? 'true' : 'false');
  5424      } else if (value != null && value !== false) {
  5425        if (attr === 'class') {
  5426          // handle edge case #1960:
  5427          // class interpolation should not overwrite Vue transition class
  5428          if (el.__v_trans) {
  5429            value += ' ' + el.__v_trans.id + '-transition';
  5430          }
  5431          setClass(el, value);
  5432        } else if (xlinkRE.test(attr)) {
  5433          el.setAttributeNS(xlinkNS, attr, value === true ? '' : value);
  5434        } else {
  5435          el.setAttribute(attr, value === true ? '' : value);
  5436        }
  5437      } else {
  5438        el.removeAttribute(attr);
  5439      }
  5440    }
  5441  };
  5442  
  5443  var el = {
  5444  
  5445    priority: EL,
  5446  
  5447    bind: function bind() {
  5448      /* istanbul ignore if */
  5449      if (!this.arg) {
  5450        return;
  5451      }
  5452      var id = this.id = camelize(this.arg);
  5453      var refs = (this._scope || this.vm).$els;
  5454      if (hasOwn(refs, id)) {
  5455        refs[id] = this.el;
  5456      } else {
  5457        defineReactive(refs, id, this.el);
  5458      }
  5459    },
  5460  
  5461    unbind: function unbind() {
  5462      var refs = (this._scope || this.vm).$els;
  5463      if (refs[this.id] === this.el) {
  5464        refs[this.id] = null;
  5465      }
  5466    }
  5467  };
  5468  
  5469  var ref = {
  5470    bind: function bind() {
  5471      process.env.NODE_ENV !== 'production' && warn('v-ref:' + this.arg + ' must be used on a child ' + 'component. Found on <' + this.el.tagName.toLowerCase() + '>.', this.vm);
  5472    }
  5473  };
  5474  
  5475  var cloak = {
  5476    bind: function bind() {
  5477      var el = this.el;
  5478      this.vm.$once('pre-hook:compiled', function () {
  5479        el.removeAttribute('v-cloak');
  5480      });
  5481    }
  5482  };
  5483  
  5484  // must export plain object
  5485  var directives = {
  5486    text: text$1,
  5487    html: html,
  5488    'for': vFor,
  5489    'if': vIf,
  5490    show: show,
  5491    model: model,
  5492    on: on$1,
  5493    bind: bind$1,
  5494    el: el,
  5495    ref: ref,
  5496    cloak: cloak
  5497  };
  5498  
  5499  var vClass = {
  5500  
  5501    deep: true,
  5502  
  5503    update: function update(value) {
  5504      if (!value) {
  5505        this.cleanup();
  5506      } else if (typeof value === 'string') {
  5507        this.setClass(value.trim().split(/\s+/));
  5508      } else {
  5509        this.setClass(normalize$1(value));
  5510      }
  5511    },
  5512  
  5513    setClass: function setClass(value) {
  5514      this.cleanup(value);
  5515      for (var i = 0, l = value.length; i < l; i++) {
  5516        var val = value[i];
  5517        if (val) {
  5518          apply(this.el, val, addClass);
  5519        }
  5520      }
  5521      this.prevKeys = value;
  5522    },
  5523  
  5524    cleanup: function cleanup(value) {
  5525      var prevKeys = this.prevKeys;
  5526      if (!prevKeys) return;
  5527      var i = prevKeys.length;
  5528      while (i--) {
  5529        var key = prevKeys[i];
  5530        if (!value || value.indexOf(key) < 0) {
  5531          apply(this.el, key, removeClass);
  5532        }
  5533      }
  5534    }
  5535  };
  5536  
  5537  /**
  5538   * Normalize objects and arrays (potentially containing objects)
  5539   * into array of strings.
  5540   *
  5541   * @param {Object|Array<String|Object>} value
  5542   * @return {Array<String>}
  5543   */
  5544  
  5545  function normalize$1(value) {
  5546    var res = [];
  5547    if (isArray(value)) {
  5548      for (var i = 0, l = value.length; i < l; i++) {
  5549        var _key = value[i];
  5550        if (_key) {
  5551          if (typeof _key === 'string') {
  5552            res.push(_key);
  5553          } else {
  5554            for (var k in _key) {
  5555              if (_key[k]) res.push(k);
  5556            }
  5557          }
  5558        }
  5559      }
  5560    } else if (isObject(value)) {
  5561      for (var key in value) {
  5562        if (value[key]) res.push(key);
  5563      }
  5564    }
  5565    return res;
  5566  }
  5567  
  5568  /**
  5569   * Add or remove a class/classes on an element
  5570   *
  5571   * @param {Element} el
  5572   * @param {String} key The class name. This may or may not
  5573   *                     contain a space character, in such a
  5574   *                     case we'll deal with multiple class
  5575   *                     names at once.
  5576   * @param {Function} fn
  5577   */
  5578  
  5579  function apply(el, key, fn) {
  5580    key = key.trim();
  5581    if (key.indexOf(' ') === -1) {
  5582      fn(el, key);
  5583      return;
  5584    }
  5585    // The key contains one or more space characters.
  5586    // Since a class name doesn't accept such characters, we
  5587    // treat it as multiple classes.
  5588    var keys = key.split(/\s+/);
  5589    for (var i = 0, l = keys.length; i < l; i++) {
  5590      fn(el, keys[i]);
  5591    }
  5592  }
  5593  
  5594  var component = {
  5595  
  5596    priority: COMPONENT,
  5597  
  5598    params: ['keep-alive', 'transition-mode', 'inline-template'],
  5599  
  5600    /**
  5601     * Setup. Two possible usages:
  5602     *
  5603     * - static:
  5604     *   <comp> or <div v-component="comp">
  5605     *
  5606     * - dynamic:
  5607     *   <component :is="view">
  5608     */
  5609  
  5610    bind: function bind() {
  5611      if (!this.el.__vue__) {
  5612        // keep-alive cache
  5613        this.keepAlive = this.params.keepAlive;
  5614        if (this.keepAlive) {
  5615          this.cache = {};
  5616        }
  5617        // check inline-template
  5618        if (this.params.inlineTemplate) {
  5619          // extract inline template as a DocumentFragment
  5620          this.inlineTemplate = extractContent(this.el, true);
  5621        }
  5622        // component resolution related state
  5623        this.pendingComponentCb = this.Component = null;
  5624        // transition related state
  5625        this.pendingRemovals = 0;
  5626        this.pendingRemovalCb = null;
  5627        // create a ref anchor
  5628        this.anchor = createAnchor('v-component');
  5629        replace(this.el, this.anchor);
  5630        // remove is attribute.
  5631        // this is removed during compilation, but because compilation is
  5632        // cached, when the component is used elsewhere this attribute
  5633        // will remain at link time.
  5634        this.el.removeAttribute('is');
  5635        this.el.removeAttribute(':is');
  5636        // remove ref, same as above
  5637        if (this.descriptor.ref) {
  5638          this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref));
  5639        }
  5640        // if static, build right now.
  5641        if (this.literal) {
  5642          this.setComponent(this.expression);
  5643        }
  5644      } else {
  5645        process.env.NODE_ENV !== 'production' && warn('cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el);
  5646      }
  5647    },
  5648  
  5649    /**
  5650     * Public update, called by the watcher in the dynamic
  5651     * literal scenario, e.g. <component :is="view">
  5652     */
  5653  
  5654    update: function update(value) {
  5655      if (!this.literal) {
  5656        this.setComponent(value);
  5657      }
  5658    },
  5659  
  5660    /**
  5661     * Switch dynamic components. May resolve the component
  5662     * asynchronously, and perform transition based on
  5663     * specified transition mode. Accepts a few additional
  5664     * arguments specifically for vue-router.
  5665     *
  5666     * The callback is called when the full transition is
  5667     * finished.
  5668     *
  5669     * @param {String} value
  5670     * @param {Function} [cb]
  5671     */
  5672  
  5673    setComponent: function setComponent(value, cb) {
  5674      this.invalidatePending();
  5675      if (!value) {
  5676        // just remove current
  5677        this.unbuild(true);
  5678        this.remove(this.childVM, cb);
  5679        this.childVM = null;
  5680      } else {
  5681        var self = this;
  5682        this.resolveComponent(value, function () {
  5683          self.mountComponent(cb);
  5684        });
  5685      }
  5686    },
  5687  
  5688    /**
  5689     * Resolve the component constructor to use when creating
  5690     * the child vm.
  5691     *
  5692     * @param {String|Function} value
  5693     * @param {Function} cb
  5694     */
  5695  
  5696    resolveComponent: function resolveComponent(value, cb) {
  5697      var self = this;
  5698      this.pendingComponentCb = cancellable(function (Component) {
  5699        self.ComponentName = Component.options.name || (typeof value === 'string' ? value : null);
  5700        self.Component = Component;
  5701        cb();
  5702      });
  5703      this.vm._resolveComponent(value, this.pendingComponentCb);
  5704    },
  5705  
  5706    /**
  5707     * Create a new instance using the current constructor and
  5708     * replace the existing instance. This method doesn't care
  5709     * whether the new component and the old one are actually
  5710     * the same.
  5711     *
  5712     * @param {Function} [cb]
  5713     */
  5714  
  5715    mountComponent: function mountComponent(cb) {
  5716      // actual mount
  5717      this.unbuild(true);
  5718      var self = this;
  5719      var activateHooks = this.Component.options.activate;
  5720      var cached = this.getCached();
  5721      var newComponent = this.build();
  5722      if (activateHooks && !cached) {
  5723        this.waitingFor = newComponent;
  5724        callActivateHooks(activateHooks, newComponent, function () {
  5725          if (self.waitingFor !== newComponent) {
  5726            return;
  5727          }
  5728          self.waitingFor = null;
  5729          self.transition(newComponent, cb);
  5730        });
  5731      } else {
  5732        // update ref for kept-alive component
  5733        if (cached) {
  5734          newComponent._updateRef();
  5735        }
  5736        this.transition(newComponent, cb);
  5737      }
  5738    },
  5739  
  5740    /**
  5741     * When the component changes or unbinds before an async
  5742     * constructor is resolved, we need to invalidate its
  5743     * pending callback.
  5744     */
  5745  
  5746    invalidatePending: function invalidatePending() {
  5747      if (this.pendingComponentCb) {
  5748        this.pendingComponentCb.cancel();
  5749        this.pendingComponentCb = null;
  5750      }
  5751    },
  5752  
  5753    /**
  5754     * Instantiate/insert a new child vm.
  5755     * If keep alive and has cached instance, insert that
  5756     * instance; otherwise build a new one and cache it.
  5757     *
  5758     * @param {Object} [extraOptions]
  5759     * @return {Vue} - the created instance
  5760     */
  5761  
  5762    build: function build(extraOptions) {
  5763      var cached = this.getCached();
  5764      if (cached) {
  5765        return cached;
  5766      }
  5767      if (this.Component) {
  5768        // default options
  5769        var options = {
  5770          name: this.ComponentName,
  5771          el: cloneNode(this.el),
  5772          template: this.inlineTemplate,
  5773          // make sure to add the child with correct parent
  5774          // if this is a transcluded component, its parent
  5775          // should be the transclusion host.
  5776          parent: this._host || this.vm,
  5777          // if no inline-template, then the compiled
  5778          // linker can be cached for better performance.
  5779          _linkerCachable: !this.inlineTemplate,
  5780          _ref: this.descriptor.ref,
  5781          _asComponent: true,
  5782          _isRouterView: this._isRouterView,
  5783          // if this is a transcluded component, context
  5784          // will be the common parent vm of this instance
  5785          // and its host.
  5786          _context: this.vm,
  5787          // if this is inside an inline v-for, the scope
  5788          // will be the intermediate scope created for this
  5789          // repeat fragment. this is used for linking props
  5790          // and container directives.
  5791          _scope: this._scope,
  5792          // pass in the owner fragment of this component.
  5793          // this is necessary so that the fragment can keep
  5794          // track of its contained components in order to
  5795          // call attach/detach hooks for them.
  5796          _frag: this._frag
  5797        };
  5798        // extra options
  5799        // in 1.0.0 this is used by vue-router only
  5800        /* istanbul ignore if */
  5801        if (extraOptions) {
  5802          extend(options, extraOptions);
  5803        }
  5804        var child = new this.Component(options);
  5805        if (this.keepAlive) {
  5806          this.cache[this.Component.cid] = child;
  5807        }
  5808        /* istanbul ignore if */
  5809        if (process.env.NODE_ENV !== 'production' && this.el.hasAttribute('transition') && child._isFragment) {
  5810          warn('Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template, child);
  5811        }
  5812        return child;
  5813      }
  5814    },
  5815  
  5816    /**
  5817     * Try to get a cached instance of the current component.
  5818     *
  5819     * @return {Vue|undefined}
  5820     */
  5821  
  5822    getCached: function getCached() {
  5823      return this.keepAlive && this.cache[this.Component.cid];
  5824    },
  5825  
  5826    /**
  5827     * Teardown the current child, but defers cleanup so
  5828     * that we can separate the destroy and removal steps.
  5829     *
  5830     * @param {Boolean} defer
  5831     */
  5832  
  5833    unbuild: function unbuild(defer) {
  5834      if (this.waitingFor) {
  5835        if (!this.keepAlive) {
  5836          this.waitingFor.$destroy();
  5837        }
  5838        this.waitingFor = null;
  5839      }
  5840      var child = this.childVM;
  5841      if (!child || this.keepAlive) {
  5842        if (child) {
  5843          // remove ref
  5844          child._inactive = true;
  5845          child._updateRef(true);
  5846        }
  5847        return;
  5848      }
  5849      // the sole purpose of `deferCleanup` is so that we can
  5850      // "deactivate" the vm right now and perform DOM removal
  5851      // later.
  5852      child.$destroy(false, defer);
  5853    },
  5854  
  5855    /**
  5856     * Remove current destroyed child and manually do
  5857     * the cleanup after removal.
  5858     *
  5859     * @param {Function} cb
  5860     */
  5861  
  5862    remove: function remove(child, cb) {
  5863      var keepAlive = this.keepAlive;
  5864      if (child) {
  5865        // we may have a component switch when a previous
  5866        // component is still being transitioned out.
  5867        // we want to trigger only one lastest insertion cb
  5868        // when the existing transition finishes. (#1119)
  5869        this.pendingRemovals++;
  5870        this.pendingRemovalCb = cb;
  5871        var self = this;
  5872        child.$remove(function () {
  5873          self.pendingRemovals--;
  5874          if (!keepAlive) child._cleanup();
  5875          if (!self.pendingRemovals && self.pendingRemovalCb) {
  5876            self.pendingRemovalCb();
  5877            self.pendingRemovalCb = null;
  5878          }
  5879        });
  5880      } else if (cb) {
  5881        cb();
  5882      }
  5883    },
  5884  
  5885    /**
  5886     * Actually swap the components, depending on the
  5887     * transition mode. Defaults to simultaneous.
  5888     *
  5889     * @param {Vue} target
  5890     * @param {Function} [cb]
  5891     */
  5892  
  5893    transition: function transition(target, cb) {
  5894      var self = this;
  5895      var current = this.childVM;
  5896      // for devtool inspection
  5897      if (current) current._inactive = true;
  5898      target._inactive = false;
  5899      this.childVM = target;
  5900      switch (self.params.transitionMode) {
  5901        case 'in-out':
  5902          target.$before(self.anchor, function () {
  5903            self.remove(current, cb);
  5904          });
  5905          break;
  5906        case 'out-in':
  5907          self.remove(current, function () {
  5908            target.$before(self.anchor, cb);
  5909          });
  5910          break;
  5911        default:
  5912          self.remove(current);
  5913          target.$before(self.anchor, cb);
  5914      }
  5915    },
  5916  
  5917    /**
  5918     * Unbind.
  5919     */
  5920  
  5921    unbind: function unbind() {
  5922      this.invalidatePending();
  5923      // Do not defer cleanup when unbinding
  5924      this.unbuild();
  5925      // destroy all keep-alive cached instances
  5926      if (this.cache) {
  5927        for (var key in this.cache) {
  5928          this.cache[key].$destroy();
  5929        }
  5930        this.cache = null;
  5931      }
  5932    }
  5933  };
  5934  
  5935  /**
  5936   * Call activate hooks in order (asynchronous)
  5937   *
  5938   * @param {Array} hooks
  5939   * @param {Vue} vm
  5940   * @param {Function} cb
  5941   */
  5942  
  5943  function callActivateHooks(hooks, vm, cb) {
  5944    var total = hooks.length;
  5945    var called = 0;
  5946    hooks[0].call(vm, next);
  5947    function next() {
  5948      if (++called >= total) {
  5949        cb();
  5950      } else {
  5951        hooks[called].call(vm, next);
  5952      }
  5953    }
  5954  }
  5955  
  5956  var propBindingModes = config._propBindingModes;
  5957  var empty = {};
  5958  
  5959  // regexes
  5960  var identRE$1 = /^[$_a-zA-Z]+[\w$]*$/;
  5961  var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/;
  5962  
  5963  /**
  5964   * Compile props on a root element and return
  5965   * a props link function.
  5966   *
  5967   * @param {Element|DocumentFragment} el
  5968   * @param {Array} propOptions
  5969   * @param {Vue} vm
  5970   * @return {Function} propsLinkFn
  5971   */
  5972  
  5973  function compileProps(el, propOptions, vm) {
  5974    var props = [];
  5975    var names = Object.keys(propOptions);
  5976    var i = names.length;
  5977    var options, name, attr, value, path, parsed, prop;
  5978    while (i--) {
  5979      name = names[i];
  5980      options = propOptions[name] || empty;
  5981  
  5982      if (process.env.NODE_ENV !== 'production' && name === '$data') {
  5983        warn('Do not use $data as prop.', vm);
  5984        continue;
  5985      }
  5986  
  5987      // props could contain dashes, which will be
  5988      // interpreted as minus calculations by the parser
  5989      // so we need to camelize the path here
  5990      path = camelize(name);
  5991      if (!identRE$1.test(path)) {
  5992        process.env.NODE_ENV !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.', vm);
  5993        continue;
  5994      }
  5995  
  5996      prop = {
  5997        name: name,
  5998        path: path,
  5999        options: options,
  6000        mode: propBindingModes.ONE_WAY,
  6001        raw: null
  6002      };
  6003  
  6004      attr = hyphenate(name);
  6005      // first check dynamic version
  6006      if ((value = getBindAttr(el, attr)) === null) {
  6007        if ((value = getBindAttr(el, attr + '.sync')) !== null) {
  6008          prop.mode = propBindingModes.TWO_WAY;
  6009        } else if ((value = getBindAttr(el, attr + '.once')) !== null) {
  6010          prop.mode = propBindingModes.ONE_TIME;
  6011        }
  6012      }
  6013      if (value !== null) {
  6014        // has dynamic binding!
  6015        prop.raw = value;
  6016        parsed = parseDirective(value);
  6017        value = parsed.expression;
  6018        prop.filters = parsed.filters;
  6019        // check binding type
  6020        if (isLiteral(value) && !parsed.filters) {
  6021          // for expressions containing literal numbers and
  6022          // booleans, there's no need to setup a prop binding,
  6023          // so we can optimize them as a one-time set.
  6024          prop.optimizedLiteral = true;
  6025        } else {
  6026          prop.dynamic = true;
  6027          // check non-settable path for two-way bindings
  6028          if (process.env.NODE_ENV !== 'production' && prop.mode === propBindingModes.TWO_WAY && !settablePathRE.test(value)) {
  6029            prop.mode = propBindingModes.ONE_WAY;
  6030            warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value, vm);
  6031          }
  6032        }
  6033        prop.parentPath = value;
  6034  
  6035        // warn required two-way
  6036        if (process.env.NODE_ENV !== 'production' && options.twoWay && prop.mode !== propBindingModes.TWO_WAY) {
  6037          warn('Prop "' + name + '" expects a two-way binding type.', vm);
  6038        }
  6039      } else if ((value = getAttr(el, attr)) !== null) {
  6040        // has literal binding!
  6041        prop.raw = value;
  6042      } else if (process.env.NODE_ENV !== 'production') {
  6043        // check possible camelCase prop usage
  6044        var lowerCaseName = path.toLowerCase();
  6045        value = /[A-Z\-]/.test(name) && (el.getAttribute(lowerCaseName) || el.getAttribute(':' + lowerCaseName) || el.getAttribute('v-bind:' + lowerCaseName) || el.getAttribute(':' + lowerCaseName + '.once') || el.getAttribute('v-bind:' + lowerCaseName + '.once') || el.getAttribute(':' + lowerCaseName + '.sync') || el.getAttribute('v-bind:' + lowerCaseName + '.sync'));
  6046        if (value) {
  6047          warn('Possible usage error for prop `' + lowerCaseName + '` - ' + 'did you mean `' + attr + '`? HTML is case-insensitive, remember to use ' + 'kebab-case for props in templates.', vm);
  6048        } else if (options.required) {
  6049          // warn missing required
  6050          warn('Missing required prop: ' + name, vm);
  6051        }
  6052      }
  6053      // push prop
  6054      props.push(prop);
  6055    }
  6056    return makePropsLinkFn(props);
  6057  }
  6058  
  6059  /**
  6060   * Build a function that applies props to a vm.
  6061   *
  6062   * @param {Array} props
  6063   * @return {Function} propsLinkFn
  6064   */
  6065  
  6066  function makePropsLinkFn(props) {
  6067    return function propsLinkFn(vm, scope) {
  6068      // store resolved props info
  6069      vm._props = {};
  6070      var inlineProps = vm.$options.propsData;
  6071      var i = props.length;
  6072      var prop, path, options, value, raw;
  6073      while (i--) {
  6074        prop = props[i];
  6075        raw = prop.raw;
  6076        path = prop.path;
  6077        options = prop.options;
  6078        vm._props[path] = prop;
  6079        if (inlineProps && hasOwn(inlineProps, path)) {
  6080          initProp(vm, prop, inlineProps[path]);
  6081        }if (raw === null) {
  6082          // initialize absent prop
  6083          initProp(vm, prop, undefined);
  6084        } else if (prop.dynamic) {
  6085          // dynamic prop
  6086          if (prop.mode === propBindingModes.ONE_TIME) {
  6087            // one time binding
  6088            value = (scope || vm._context || vm).$get(prop.parentPath);
  6089            initProp(vm, prop, value);
  6090          } else {
  6091            if (vm._context) {
  6092              // dynamic binding
  6093              vm._bindDir({
  6094                name: 'prop',
  6095                def: propDef,
  6096                prop: prop
  6097              }, null, null, scope); // el, host, scope
  6098            } else {
  6099                // root instance
  6100                initProp(vm, prop, vm.$get(prop.parentPath));
  6101              }
  6102          }
  6103        } else if (prop.optimizedLiteral) {
  6104          // optimized literal, cast it and just set once
  6105          var stripped = stripQuotes(raw);
  6106          value = stripped === raw ? toBoolean(toNumber(raw)) : stripped;
  6107          initProp(vm, prop, value);
  6108        } else {
  6109          // string literal, but we need to cater for
  6110          // Boolean props with no value, or with same
  6111          // literal value (e.g. disabled="disabled")
  6112          // see https://github.com/vuejs/vue-loader/issues/182
  6113          value = options.type === Boolean && (raw === '' || raw === hyphenate(prop.name)) ? true : raw;
  6114          initProp(vm, prop, value);
  6115        }
  6116      }
  6117    };
  6118  }
  6119  
  6120  /**
  6121   * Process a prop with a rawValue, applying necessary coersions,
  6122   * default values & assertions and call the given callback with
  6123   * processed value.
  6124   *
  6125   * @param {Vue} vm
  6126   * @param {Object} prop
  6127   * @param {*} rawValue
  6128   * @param {Function} fn
  6129   */
  6130  
  6131  function processPropValue(vm, prop, rawValue, fn) {
  6132    var isSimple = prop.dynamic && isSimplePath(prop.parentPath);
  6133    var value = rawValue;
  6134    if (value === undefined) {
  6135      value = getPropDefaultValue(vm, prop);
  6136    }
  6137    value = coerceProp(prop, value);
  6138    var coerced = value !== rawValue;
  6139    if (!assertProp(prop, value, vm)) {
  6140      value = undefined;
  6141    }
  6142    if (isSimple && !coerced) {
  6143      withoutConversion(function () {
  6144        fn(value);
  6145      });
  6146    } else {
  6147      fn(value);
  6148    }
  6149  }
  6150  
  6151  /**
  6152   * Set a prop's initial value on a vm and its data object.
  6153   *
  6154   * @param {Vue} vm
  6155   * @param {Object} prop
  6156   * @param {*} value
  6157   */
  6158  
  6159  function initProp(vm, prop, value) {
  6160    processPropValue(vm, prop, value, function (value) {
  6161      defineReactive(vm, prop.path, value);
  6162    });
  6163  }
  6164  
  6165  /**
  6166   * Update a prop's value on a vm.
  6167   *
  6168   * @param {Vue} vm
  6169   * @param {Object} prop
  6170   * @param {*} value
  6171   */
  6172  
  6173  function updateProp(vm, prop, value) {
  6174    processPropValue(vm, prop, value, function (value) {
  6175      vm[prop.path] = value;
  6176    });
  6177  }
  6178  
  6179  /**
  6180   * Get the default value of a prop.
  6181   *
  6182   * @param {Vue} vm
  6183   * @param {Object} prop
  6184   * @return {*}
  6185   */
  6186  
  6187  function getPropDefaultValue(vm, prop) {
  6188    // no default, return undefined
  6189    var options = prop.options;
  6190    if (!hasOwn(options, 'default')) {
  6191      // absent boolean value defaults to false
  6192      return options.type === Boolean ? false : undefined;
  6193    }
  6194    var def = options['default'];
  6195    // warn against non-factory defaults for Object & Array
  6196    if (isObject(def)) {
  6197      process.env.NODE_ENV !== 'production' && warn('Invalid default value for prop "' + prop.name + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm);
  6198    }
  6199    // call factory function for non-Function types
  6200    return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
  6201  }
  6202  
  6203  /**
  6204   * Assert whether a prop is valid.
  6205   *
  6206   * @param {Object} prop
  6207   * @param {*} value
  6208   * @param {Vue} vm
  6209   */
  6210  
  6211  function assertProp(prop, value, vm) {
  6212    if (!prop.options.required && ( // non-required
  6213    prop.raw === null || // abscent
  6214    value == null) // null or undefined
  6215    ) {
  6216        return true;
  6217      }
  6218    var options = prop.options;
  6219    var type = options.type;
  6220    var valid = !type;
  6221    var expectedTypes = [];
  6222    if (type) {
  6223      if (!isArray(type)) {
  6224        type = [type];
  6225      }
  6226      for (var i = 0; i < type.length && !valid; i++) {
  6227        var assertedType = assertType(value, type[i]);
  6228        expectedTypes.push(assertedType.expectedType);
  6229        valid = assertedType.valid;
  6230      }
  6231    }
  6232    if (!valid) {
  6233      if (process.env.NODE_ENV !== 'production') {
  6234        warn('Invalid prop: type check failed for prop "' + prop.name + '".' + ' Expected ' + expectedTypes.map(formatType).join(', ') + ', got ' + formatValue(value) + '.', vm);
  6235      }
  6236      return false;
  6237    }
  6238    var validator = options.validator;
  6239    if (validator) {
  6240      if (!validator(value)) {
  6241        process.env.NODE_ENV !== 'production' && warn('Invalid prop: custom validator check failed for prop "' + prop.name + '".', vm);
  6242        return false;
  6243      }
  6244    }
  6245    return true;
  6246  }
  6247  
  6248  /**
  6249   * Force parsing value with coerce option.
  6250   *
  6251   * @param {*} value
  6252   * @param {Object} options
  6253   * @return {*}
  6254   */
  6255  
  6256  function coerceProp(prop, value) {
  6257    var coerce = prop.options.coerce;
  6258    if (!coerce) {
  6259      return value;
  6260    }
  6261    // coerce is a function
  6262    return coerce(value);
  6263  }
  6264  
  6265  /**
  6266   * Assert the type of a value
  6267   *
  6268   * @param {*} value
  6269   * @param {Function} type
  6270   * @return {Object}
  6271   */
  6272  
  6273  function assertType(value, type) {
  6274    var valid;
  6275    var expectedType;
  6276    if (type === String) {
  6277      expectedType = 'string';
  6278      valid = typeof value === expectedType;
  6279    } else if (type === Number) {
  6280      expectedType = 'number';
  6281      valid = typeof value === expectedType;
  6282    } else if (type === Boolean) {
  6283      expectedType = 'boolean';
  6284      valid = typeof value === expectedType;
  6285    } else if (type === Function) {
  6286      expectedType = 'function';
  6287      valid = typeof value === expectedType;
  6288    } else if (type === Object) {
  6289      expectedType = 'object';
  6290      valid = isPlainObject(value);
  6291    } else if (type === Array) {
  6292      expectedType = 'array';
  6293      valid = isArray(value);
  6294    } else {
  6295      valid = value instanceof type;
  6296    }
  6297    return {
  6298      valid: valid,
  6299      expectedType: expectedType
  6300    };
  6301  }
  6302  
  6303  /**
  6304   * Format type for output
  6305   *
  6306   * @param {String} type
  6307   * @return {String}
  6308   */
  6309  
  6310  function formatType(type) {
  6311    return type ? type.charAt(0).toUpperCase() + type.slice(1) : 'custom type';
  6312  }
  6313  
  6314  /**
  6315   * Format value
  6316   *
  6317   * @param {*} value
  6318   * @return {String}
  6319   */
  6320  
  6321  function formatValue(val) {
  6322    return Object.prototype.toString.call(val).slice(8, -1);
  6323  }
  6324  
  6325  var bindingModes = config._propBindingModes;
  6326  
  6327  var propDef = {
  6328  
  6329    bind: function bind() {
  6330      var child = this.vm;
  6331      var parent = child._context;
  6332      // passed in from compiler directly
  6333      var prop = this.descriptor.prop;
  6334      var childKey = prop.path;
  6335      var parentKey = prop.parentPath;
  6336      var twoWay = prop.mode === bindingModes.TWO_WAY;
  6337  
  6338      var parentWatcher = this.parentWatcher = new Watcher(parent, parentKey, function (val) {
  6339        updateProp(child, prop, val);
  6340      }, {
  6341        twoWay: twoWay,
  6342        filters: prop.filters,
  6343        // important: props need to be observed on the
  6344        // v-for scope if present
  6345        scope: this._scope
  6346      });
  6347  
  6348      // set the child initial value.
  6349      initProp(child, prop, parentWatcher.value);
  6350  
  6351      // setup two-way binding
  6352      if (twoWay) {
  6353        // important: defer the child watcher creation until
  6354        // the created hook (after data observation)
  6355        var self = this;
  6356        child.$once('pre-hook:created', function () {
  6357          self.childWatcher = new Watcher(child, childKey, function (val) {
  6358            parentWatcher.set(val);
  6359          }, {
  6360            // ensure sync upward before parent sync down.
  6361            // this is necessary in cases e.g. the child
  6362            // mutates a prop array, then replaces it. (#1683)
  6363            sync: true
  6364          });
  6365        });
  6366      }
  6367    },
  6368  
  6369    unbind: function unbind() {
  6370      this.parentWatcher.teardown();
  6371      if (this.childWatcher) {
  6372        this.childWatcher.teardown();
  6373      }
  6374    }
  6375  };
  6376  
  6377  var queue$1 = [];
  6378  var queued = false;
  6379  
  6380  /**
  6381   * Push a job into the queue.
  6382   *
  6383   * @param {Function} job
  6384   */
  6385  
  6386  function pushJob(job) {
  6387    queue$1.push(job);
  6388    if (!queued) {
  6389      queued = true;
  6390      nextTick(flush);
  6391    }
  6392  }
  6393  
  6394  /**
  6395   * Flush the queue, and do one forced reflow before
  6396   * triggering transitions.
  6397   */
  6398  
  6399  function flush() {
  6400    // Force layout
  6401    var f = document.documentElement.offsetHeight;
  6402    for (var i = 0; i < queue$1.length; i++) {
  6403      queue$1[i]();
  6404    }
  6405    queue$1 = [];
  6406    queued = false;
  6407    // dummy return, so js linters don't complain about
  6408    // unused variable f
  6409    return f;
  6410  }
  6411  
  6412  var TYPE_TRANSITION = 'transition';
  6413  var TYPE_ANIMATION = 'animation';
  6414  var transDurationProp = transitionProp + 'Duration';
  6415  var animDurationProp = animationProp + 'Duration';
  6416  
  6417  /**
  6418   * If a just-entered element is applied the
  6419   * leave class while its enter transition hasn't started yet,
  6420   * and the transitioned property has the same value for both
  6421   * enter/leave, then the leave transition will be skipped and
  6422   * the transitionend event never fires. This function ensures
  6423   * its callback to be called after a transition has started
  6424   * by waiting for double raf.
  6425   *
  6426   * It falls back to setTimeout on devices that support CSS
  6427   * transitions but not raf (e.g. Android 4.2 browser) - since
  6428   * these environments are usually slow, we are giving it a
  6429   * relatively large timeout.
  6430   */
  6431  
  6432  var raf = inBrowser && window.requestAnimationFrame;
  6433  var waitForTransitionStart = raf
  6434  /* istanbul ignore next */
  6435  ? function (fn) {
  6436    raf(function () {
  6437      raf(fn);
  6438    });
  6439  } : function (fn) {
  6440    setTimeout(fn, 50);
  6441  };
  6442  
  6443  /**
  6444   * A Transition object that encapsulates the state and logic
  6445   * of the transition.
  6446   *
  6447   * @param {Element} el
  6448   * @param {String} id
  6449   * @param {Object} hooks
  6450   * @param {Vue} vm
  6451   */
  6452  function Transition(el, id, hooks, vm) {
  6453    this.id = id;
  6454    this.el = el;
  6455    this.enterClass = hooks && hooks.enterClass || id + '-enter';
  6456    this.leaveClass = hooks && hooks.leaveClass || id + '-leave';
  6457    this.hooks = hooks;
  6458    this.vm = vm;
  6459    // async state
  6460    this.pendingCssEvent = this.pendingCssCb = this.cancel = this.pendingJsCb = this.op = this.cb = null;
  6461    this.justEntered = false;
  6462    this.entered = this.left = false;
  6463    this.typeCache = {};
  6464    // check css transition type
  6465    this.type = hooks && hooks.type;
  6466    /* istanbul ignore if */
  6467    if (process.env.NODE_ENV !== 'production') {
  6468      if (this.type && this.type !== TYPE_TRANSITION && this.type !== TYPE_ANIMATION) {
  6469        warn('invalid CSS transition type for transition="' + this.id + '": ' + this.type, vm);
  6470      }
  6471    }
  6472    // bind
  6473    var self = this;['enterNextTick', 'enterDone', 'leaveNextTick', 'leaveDone'].forEach(function (m) {
  6474      self[m] = bind(self[m], self);
  6475    });
  6476  }
  6477  
  6478  var p$1 = Transition.prototype;
  6479  
  6480  /**
  6481   * Start an entering transition.
  6482   *
  6483   * 1. enter transition triggered
  6484   * 2. call beforeEnter hook
  6485   * 3. add enter class
  6486   * 4. insert/show element
  6487   * 5. call enter hook (with possible explicit js callback)
  6488   * 6. reflow
  6489   * 7. based on transition type:
  6490   *    - transition:
  6491   *        remove class now, wait for transitionend,
  6492   *        then done if there's no explicit js callback.
  6493   *    - animation:
  6494   *        wait for animationend, remove class,
  6495   *        then done if there's no explicit js callback.
  6496   *    - no css transition:
  6497   *        done now if there's no explicit js callback.
  6498   * 8. wait for either done or js callback, then call
  6499   *    afterEnter hook.
  6500   *
  6501   * @param {Function} op - insert/show the element
  6502   * @param {Function} [cb]
  6503   */
  6504  
  6505  p$1.enter = function (op, cb) {
  6506    this.cancelPending();
  6507    this.callHook('beforeEnter');
  6508    this.cb = cb;
  6509    addClass(this.el, this.enterClass);
  6510    op();
  6511    this.entered = false;
  6512    this.callHookWithCb('enter');
  6513    if (this.entered) {
  6514      return; // user called done synchronously.
  6515    }
  6516    this.cancel = this.hooks && this.hooks.enterCancelled;
  6517    pushJob(this.enterNextTick);
  6518  };
  6519  
  6520  /**
  6521   * The "nextTick" phase of an entering transition, which is
  6522   * to be pushed into a queue and executed after a reflow so
  6523   * that removing the class can trigger a CSS transition.
  6524   */
  6525  
  6526  p$1.enterNextTick = function () {
  6527    var _this = this;
  6528  
  6529    // prevent transition skipping
  6530    this.justEntered = true;
  6531    waitForTransitionStart(function () {
  6532      _this.justEntered = false;
  6533    });
  6534    var enterDone = this.enterDone;
  6535    var type = this.getCssTransitionType(this.enterClass);
  6536    if (!this.pendingJsCb) {
  6537      if (type === TYPE_TRANSITION) {
  6538        // trigger transition by removing enter class now
  6539        removeClass(this.el, this.enterClass);
  6540        this.setupCssCb(transitionEndEvent, enterDone);
  6541      } else if (type === TYPE_ANIMATION) {
  6542        this.setupCssCb(animationEndEvent, enterDone);
  6543      } else {
  6544        enterDone();
  6545      }
  6546    } else if (type === TYPE_TRANSITION) {
  6547      removeClass(this.el, this.enterClass);
  6548    }
  6549  };
  6550  
  6551  /**
  6552   * The "cleanup" phase of an entering transition.
  6553   */
  6554  
  6555  p$1.enterDone = function () {
  6556    this.entered = true;
  6557    this.cancel = this.pendingJsCb = null;
  6558    removeClass(this.el, this.enterClass);
  6559    this.callHook('afterEnter');
  6560    if (this.cb) this.cb();
  6561  };
  6562  
  6563  /**
  6564   * Start a leaving transition.
  6565   *
  6566   * 1. leave transition triggered.
  6567   * 2. call beforeLeave hook
  6568   * 3. add leave class (trigger css transition)
  6569   * 4. call leave hook (with possible explicit js callback)
  6570   * 5. reflow if no explicit js callback is provided
  6571   * 6. based on transition type:
  6572   *    - transition or animation:
  6573   *        wait for end event, remove class, then done if
  6574   *        there's no explicit js callback.
  6575   *    - no css transition:
  6576   *        done if there's no explicit js callback.
  6577   * 7. wait for either done or js callback, then call
  6578   *    afterLeave hook.
  6579   *
  6580   * @param {Function} op - remove/hide the element
  6581   * @param {Function} [cb]
  6582   */
  6583  
  6584  p$1.leave = function (op, cb) {
  6585    this.cancelPending();
  6586    this.callHook('beforeLeave');
  6587    this.op = op;
  6588    this.cb = cb;
  6589    addClass(this.el, this.leaveClass);
  6590    this.left = false;
  6591    this.callHookWithCb('leave');
  6592    if (this.left) {
  6593      return; // user called done synchronously.
  6594    }
  6595    this.cancel = this.hooks && this.hooks.leaveCancelled;
  6596    // only need to handle leaveDone if
  6597    // 1. the transition is already done (synchronously called
  6598    //    by the user, which causes this.op set to null)
  6599    // 2. there's no explicit js callback
  6600    if (this.op && !this.pendingJsCb) {
  6601      // if a CSS transition leaves immediately after enter,
  6602      // the transitionend event never fires. therefore we
  6603      // detect such cases and end the leave immediately.
  6604      if (this.justEntered) {
  6605        this.leaveDone();
  6606      } else {
  6607        pushJob(this.leaveNextTick);
  6608      }
  6609    }
  6610  };
  6611  
  6612  /**
  6613   * The "nextTick" phase of a leaving transition.
  6614   */
  6615  
  6616  p$1.leaveNextTick = function () {
  6617    var type = this.getCssTransitionType(this.leaveClass);
  6618    if (type) {
  6619      var event = type === TYPE_TRANSITION ? transitionEndEvent : animationEndEvent;
  6620      this.setupCssCb(event, this.leaveDone);
  6621    } else {
  6622      this.leaveDone();
  6623    }
  6624  };
  6625  
  6626  /**
  6627   * The "cleanup" phase of a leaving transition.
  6628   */
  6629  
  6630  p$1.leaveDone = function () {
  6631    this.left = true;
  6632    this.cancel = this.pendingJsCb = null;
  6633    this.op();
  6634    removeClass(this.el, this.leaveClass);
  6635    this.callHook('afterLeave');
  6636    if (this.cb) this.cb();
  6637    this.op = null;
  6638  };
  6639  
  6640  /**
  6641   * Cancel any pending callbacks from a previously running
  6642   * but not finished transition.
  6643   */
  6644  
  6645  p$1.cancelPending = function () {
  6646    this.op = this.cb = null;
  6647    var hasPending = false;
  6648    if (this.pendingCssCb) {
  6649      hasPending = true;
  6650      off(this.el, this.pendingCssEvent, this.pendingCssCb);
  6651      this.pendingCssEvent = this.pendingCssCb = null;
  6652    }
  6653    if (this.pendingJsCb) {
  6654      hasPending = true;
  6655      this.pendingJsCb.cancel();
  6656      this.pendingJsCb = null;
  6657    }
  6658    if (hasPending) {
  6659      removeClass(this.el, this.enterClass);
  6660      removeClass(this.el, this.leaveClass);
  6661    }
  6662    if (this.cancel) {
  6663      this.cancel.call(this.vm, this.el);
  6664      this.cancel = null;
  6665    }
  6666  };
  6667  
  6668  /**
  6669   * Call a user-provided synchronous hook function.
  6670   *
  6671   * @param {String} type
  6672   */
  6673  
  6674  p$1.callHook = function (type) {
  6675    if (this.hooks && this.hooks[type]) {
  6676      this.hooks[type].call(this.vm, this.el);
  6677    }
  6678  };
  6679  
  6680  /**
  6681   * Call a user-provided, potentially-async hook function.
  6682   * We check for the length of arguments to see if the hook
  6683   * expects a `done` callback. If true, the transition's end
  6684   * will be determined by when the user calls that callback;
  6685   * otherwise, the end is determined by the CSS transition or
  6686   * animation.
  6687   *
  6688   * @param {String} type
  6689   */
  6690  
  6691  p$1.callHookWithCb = function (type) {
  6692    var hook = this.hooks && this.hooks[type];
  6693    if (hook) {
  6694      if (hook.length > 1) {
  6695        this.pendingJsCb = cancellable(this[type + 'Done']);
  6696      }
  6697      hook.call(this.vm, this.el, this.pendingJsCb);
  6698    }
  6699  };
  6700  
  6701  /**
  6702   * Get an element's transition type based on the
  6703   * calculated styles.
  6704   *
  6705   * @param {String} className
  6706   * @return {Number}
  6707   */
  6708  
  6709  p$1.getCssTransitionType = function (className) {
  6710    /* istanbul ignore if */
  6711    if (!transitionEndEvent ||
  6712    // skip CSS transitions if page is not visible -
  6713    // this solves the issue of transitionend events not
  6714    // firing until the page is visible again.
  6715    // pageVisibility API is supported in IE10+, same as
  6716    // CSS transitions.
  6717    document.hidden ||
  6718    // explicit js-only transition
  6719    this.hooks && this.hooks.css === false ||
  6720    // element is hidden
  6721    isHidden(this.el)) {
  6722      return;
  6723    }
  6724    var type = this.type || this.typeCache[className];
  6725    if (type) return type;
  6726    var inlineStyles = this.el.style;
  6727    var computedStyles = window.getComputedStyle(this.el);
  6728    var transDuration = inlineStyles[transDurationProp] || computedStyles[transDurationProp];
  6729    if (transDuration && transDuration !== '0s') {
  6730      type = TYPE_TRANSITION;
  6731    } else {
  6732      var animDuration = inlineStyles[animDurationProp] || computedStyles[animDurationProp];
  6733      if (animDuration && animDuration !== '0s') {
  6734        type = TYPE_ANIMATION;
  6735      }
  6736    }
  6737    if (type) {
  6738      this.typeCache[className] = type;
  6739    }
  6740    return type;
  6741  };
  6742  
  6743  /**
  6744   * Setup a CSS transitionend/animationend callback.
  6745   *
  6746   * @param {String} event
  6747   * @param {Function} cb
  6748   */
  6749  
  6750  p$1.setupCssCb = function (event, cb) {
  6751    this.pendingCssEvent = event;
  6752    var self = this;
  6753    var el = this.el;
  6754    var onEnd = this.pendingCssCb = function (e) {
  6755      if (e.target === el) {
  6756        off(el, event, onEnd);
  6757        self.pendingCssEvent = self.pendingCssCb = null;
  6758        if (!self.pendingJsCb && cb) {
  6759          cb();
  6760        }
  6761      }
  6762    };
  6763    on(el, event, onEnd);
  6764  };
  6765  
  6766  /**
  6767   * Check if an element is hidden - in that case we can just
  6768   * skip the transition alltogether.
  6769   *
  6770   * @param {Element} el
  6771   * @return {Boolean}
  6772   */
  6773  
  6774  function isHidden(el) {
  6775    if (/svg$/.test(el.namespaceURI)) {
  6776      // SVG elements do not have offset(Width|Height)
  6777      // so we need to check the client rect
  6778      var rect = el.getBoundingClientRect();
  6779      return !(rect.width || rect.height);
  6780    } else {
  6781      return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
  6782    }
  6783  }
  6784  
  6785  var transition$1 = {
  6786  
  6787    priority: TRANSITION,
  6788  
  6789    update: function update(id, oldId) {
  6790      var el = this.el;
  6791      // resolve on owner vm
  6792      var hooks = resolveAsset(this.vm.$options, 'transitions', id);
  6793      id = id || 'v';
  6794      el.__v_trans = new Transition(el, id, hooks, this.vm);
  6795      if (oldId) {
  6796        removeClass(el, oldId + '-transition');
  6797      }
  6798      addClass(el, id + '-transition');
  6799    }
  6800  };
  6801  
  6802  var internalDirectives = {
  6803    style: style,
  6804    'class': vClass,
  6805    component: component,
  6806    prop: propDef,
  6807    transition: transition$1
  6808  };
  6809  
  6810  // special binding prefixes
  6811  var bindRE = /^v-bind:|^:/;
  6812  var onRE = /^v-on:|^@/;
  6813  var dirAttrRE = /^v-([^:]+)(?:$|:(.*)$)/;
  6814  var modifierRE = /\.[^\.]+/g;
  6815  var transitionRE = /^(v-bind:|:)?transition$/;
  6816  
  6817  // default directive priority
  6818  var DEFAULT_PRIORITY = 1000;
  6819  var DEFAULT_TERMINAL_PRIORITY = 2000;
  6820  
  6821  /**
  6822   * Compile a template and return a reusable composite link
  6823   * function, which recursively contains more link functions
  6824   * inside. This top level compile function would normally
  6825   * be called on instance root nodes, but can also be used
  6826   * for partial compilation if the partial argument is true.
  6827   *
  6828   * The returned composite link function, when called, will
  6829   * return an unlink function that tearsdown all directives
  6830   * created during the linking phase.
  6831   *
  6832   * @param {Element|DocumentFragment} el
  6833   * @param {Object} options
  6834   * @param {Boolean} partial
  6835   * @return {Function}
  6836   */
  6837  
  6838  function compile(el, options, partial) {
  6839    // link function for the node itself.
  6840    var nodeLinkFn = partial || !options._asComponent ? compileNode(el, options) : null;
  6841    // link function for the childNodes
  6842    var childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && !isScript(el) && el.hasChildNodes() ? compileNodeList(el.childNodes, options) : null;
  6843  
  6844    /**
  6845     * A composite linker function to be called on a already
  6846     * compiled piece of DOM, which instantiates all directive
  6847     * instances.
  6848     *
  6849     * @param {Vue} vm
  6850     * @param {Element|DocumentFragment} el
  6851     * @param {Vue} [host] - host vm of transcluded content
  6852     * @param {Object} [scope] - v-for scope
  6853     * @param {Fragment} [frag] - link context fragment
  6854     * @return {Function|undefined}
  6855     */
  6856  
  6857    return function compositeLinkFn(vm, el, host, scope, frag) {
  6858      // cache childNodes before linking parent, fix #657
  6859      var childNodes = toArray(el.childNodes);
  6860      // link
  6861      var dirs = linkAndCapture(function compositeLinkCapturer() {
  6862        if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag);
  6863        if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag);
  6864      }, vm);
  6865      return makeUnlinkFn(vm, dirs);
  6866    };
  6867  }
  6868  
  6869  /**
  6870   * Apply a linker to a vm/element pair and capture the
  6871   * directives created during the process.
  6872   *
  6873   * @param {Function} linker
  6874   * @param {Vue} vm
  6875   */
  6876  
  6877  function linkAndCapture(linker, vm) {
  6878    /* istanbul ignore if */
  6879    if (process.env.NODE_ENV === 'production') {
  6880      // reset directives before every capture in production
  6881      // mode, so that when unlinking we don't need to splice
  6882      // them out (which turns out to be a perf hit).
  6883      // they are kept in development mode because they are
  6884      // useful for Vue's own tests.
  6885      vm._directives = [];
  6886    }
  6887    var originalDirCount = vm._directives.length;
  6888    linker();
  6889    var dirs = vm._directives.slice(originalDirCount);
  6890    dirs.sort(directiveComparator);
  6891    for (var i = 0, l = dirs.length; i < l; i++) {
  6892      dirs[i]._bind();
  6893    }
  6894    return dirs;
  6895  }
  6896  
  6897  /**
  6898   * Directive priority sort comparator
  6899   *
  6900   * @param {Object} a
  6901   * @param {Object} b
  6902   */
  6903  
  6904  function directiveComparator(a, b) {
  6905    a = a.descriptor.def.priority || DEFAULT_PRIORITY;
  6906    b = b.descriptor.def.priority || DEFAULT_PRIORITY;
  6907    return a > b ? -1 : a === b ? 0 : 1;
  6908  }
  6909  
  6910  /**
  6911   * Linker functions return an unlink function that
  6912   * tearsdown all directives instances generated during
  6913   * the process.
  6914   *
  6915   * We create unlink functions with only the necessary
  6916   * information to avoid retaining additional closures.
  6917   *
  6918   * @param {Vue} vm
  6919   * @param {Array} dirs
  6920   * @param {Vue} [context]
  6921   * @param {Array} [contextDirs]
  6922   * @return {Function}
  6923   */
  6924  
  6925  function makeUnlinkFn(vm, dirs, context, contextDirs) {
  6926    function unlink(destroying) {
  6927      teardownDirs(vm, dirs, destroying);
  6928      if (context && contextDirs) {
  6929        teardownDirs(context, contextDirs);
  6930      }
  6931    }
  6932    // expose linked directives
  6933    unlink.dirs = dirs;
  6934    return unlink;
  6935  }
  6936  
  6937  /**
  6938   * Teardown partial linked directives.
  6939   *
  6940   * @param {Vue} vm
  6941   * @param {Array} dirs
  6942   * @param {Boolean} destroying
  6943   */
  6944  
  6945  function teardownDirs(vm, dirs, destroying) {
  6946    var i = dirs.length;
  6947    while (i--) {
  6948      dirs[i]._teardown();
  6949      if (process.env.NODE_ENV !== 'production' && !destroying) {
  6950        vm._directives.$remove(dirs[i]);
  6951      }
  6952    }
  6953  }
  6954  
  6955  /**
  6956   * Compile link props on an instance.
  6957   *
  6958   * @param {Vue} vm
  6959   * @param {Element} el
  6960   * @param {Object} props
  6961   * @param {Object} [scope]
  6962   * @return {Function}
  6963   */
  6964  
  6965  function compileAndLinkProps(vm, el, props, scope) {
  6966    var propsLinkFn = compileProps(el, props, vm);
  6967    var propDirs = linkAndCapture(function () {
  6968      propsLinkFn(vm, scope);
  6969    }, vm);
  6970    return makeUnlinkFn(vm, propDirs);
  6971  }
  6972  
  6973  /**
  6974   * Compile the root element of an instance.
  6975   *
  6976   * 1. attrs on context container (context scope)
  6977   * 2. attrs on the component template root node, if
  6978   *    replace:true (child scope)
  6979   *
  6980   * If this is a fragment instance, we only need to compile 1.
  6981   *
  6982   * @param {Element} el
  6983   * @param {Object} options
  6984   * @param {Object} contextOptions
  6985   * @return {Function}
  6986   */
  6987  
  6988  function compileRoot(el, options, contextOptions) {
  6989    var containerAttrs = options._containerAttrs;
  6990    var replacerAttrs = options._replacerAttrs;
  6991    var contextLinkFn, replacerLinkFn;
  6992  
  6993    // only need to compile other attributes for
  6994    // non-fragment instances
  6995    if (el.nodeType !== 11) {
  6996      // for components, container and replacer need to be
  6997      // compiled separately and linked in different scopes.
  6998      if (options._asComponent) {
  6999        // 2. container attributes
  7000        if (containerAttrs && contextOptions) {
  7001          contextLinkFn = compileDirectives(containerAttrs, contextOptions);
  7002        }
  7003        if (replacerAttrs) {
  7004          // 3. replacer attributes
  7005          replacerLinkFn = compileDirectives(replacerAttrs, options);
  7006        }
  7007      } else {
  7008        // non-component, just compile as a normal element.
  7009        replacerLinkFn = compileDirectives(el.attributes, options);
  7010      }
  7011    } else if (process.env.NODE_ENV !== 'production' && containerAttrs) {
  7012      // warn container directives for fragment instances
  7013      var names = containerAttrs.filter(function (attr) {
  7014        // allow vue-loader/vueify scoped css attributes
  7015        return attr.name.indexOf('_v-') < 0 &&
  7016        // allow event listeners
  7017        !onRE.test(attr.name) &&
  7018        // allow slots
  7019        attr.name !== 'slot';
  7020      }).map(function (attr) {
  7021        return '"' + attr.name + '"';
  7022      });
  7023      if (names.length) {
  7024        var plural = names.length > 1;
  7025        warn('Attribute' + (plural ? 's ' : ' ') + names.join(', ') + (plural ? ' are' : ' is') + ' ignored on component ' + '<' + options.el.tagName.toLowerCase() + '> because ' + 'the component is a fragment instance: ' + 'http://vuejs.org/guide/components.html#Fragment-Instance');
  7026      }
  7027    }
  7028  
  7029    options._containerAttrs = options._replacerAttrs = null;
  7030    return function rootLinkFn(vm, el, scope) {
  7031      // link context scope dirs
  7032      var context = vm._context;
  7033      var contextDirs;
  7034      if (context && contextLinkFn) {
  7035        contextDirs = linkAndCapture(function () {
  7036          contextLinkFn(context, el, null, scope);
  7037        }, context);
  7038      }
  7039  
  7040      // link self
  7041      var selfDirs = linkAndCapture(function () {
  7042        if (replacerLinkFn) replacerLinkFn(vm, el);
  7043      }, vm);
  7044  
  7045      // return the unlink function that tearsdown context
  7046      // container directives.
  7047      return makeUnlinkFn(vm, selfDirs, context, contextDirs);
  7048    };
  7049  }
  7050  
  7051  /**
  7052   * Compile a node and return a nodeLinkFn based on the
  7053   * node type.
  7054   *
  7055   * @param {Node} node
  7056   * @param {Object} options
  7057   * @return {Function|null}
  7058   */
  7059  
  7060  function compileNode(node, options) {
  7061    var type = node.nodeType;
  7062    if (type === 1 && !isScript(node)) {
  7063      return compileElement(node, options);
  7064    } else if (type === 3 && node.data.trim()) {
  7065      return compileTextNode(node, options);
  7066    } else {
  7067      return null;
  7068    }
  7069  }
  7070  
  7071  /**
  7072   * Compile an element and return a nodeLinkFn.
  7073   *
  7074   * @param {Element} el
  7075   * @param {Object} options
  7076   * @return {Function|null}
  7077   */
  7078  
  7079  function compileElement(el, options) {
  7080    // preprocess textareas.
  7081    // textarea treats its text content as the initial value.
  7082    // just bind it as an attr directive for value.
  7083    if (el.tagName === 'TEXTAREA') {
  7084      var tokens = parseText(el.value);
  7085      if (tokens) {
  7086        el.setAttribute(':value', tokensToExp(tokens));
  7087        el.value = '';
  7088      }
  7089    }
  7090    var linkFn;
  7091    var hasAttrs = el.hasAttributes();
  7092    var attrs = hasAttrs && toArray(el.attributes);
  7093    // check terminal directives (for & if)
  7094    if (hasAttrs) {
  7095      linkFn = checkTerminalDirectives(el, attrs, options);
  7096    }
  7097    // check element directives
  7098    if (!linkFn) {
  7099      linkFn = checkElementDirectives(el, options);
  7100    }
  7101    // check component
  7102    if (!linkFn) {
  7103      linkFn = checkComponent(el, options);
  7104    }
  7105    // normal directives
  7106    if (!linkFn && hasAttrs) {
  7107      linkFn = compileDirectives(attrs, options);
  7108    }
  7109    return linkFn;
  7110  }
  7111  
  7112  /**
  7113   * Compile a textNode and return a nodeLinkFn.
  7114   *
  7115   * @param {TextNode} node
  7116   * @param {Object} options
  7117   * @return {Function|null} textNodeLinkFn
  7118   */
  7119  
  7120  function compileTextNode(node, options) {
  7121    // skip marked text nodes
  7122    if (node._skip) {
  7123      return removeText;
  7124    }
  7125  
  7126    var tokens = parseText(node.wholeText);
  7127    if (!tokens) {
  7128      return null;
  7129    }
  7130  
  7131    // mark adjacent text nodes as skipped,
  7132    // because we are using node.wholeText to compile
  7133    // all adjacent text nodes together. This fixes
  7134    // issues in IE where sometimes it splits up a single
  7135    // text node into multiple ones.
  7136    var next = node.nextSibling;
  7137    while (next && next.nodeType === 3) {
  7138      next._skip = true;
  7139      next = next.nextSibling;
  7140    }
  7141  
  7142    var frag = document.createDocumentFragment();
  7143    var el, token;
  7144    for (var i = 0, l = tokens.length; i < l; i++) {
  7145      token = tokens[i];
  7146      el = token.tag ? processTextToken(token, options) : document.createTextNode(token.value);
  7147      frag.appendChild(el);
  7148    }
  7149    return makeTextNodeLinkFn(tokens, frag, options);
  7150  }
  7151  
  7152  /**
  7153   * Linker for an skipped text node.
  7154   *
  7155   * @param {Vue} vm
  7156   * @param {Text} node
  7157   */
  7158  
  7159  function removeText(vm, node) {
  7160    remove(node);
  7161  }
  7162  
  7163  /**
  7164   * Process a single text token.
  7165   *
  7166   * @param {Object} token
  7167   * @param {Object} options
  7168   * @return {Node}
  7169   */
  7170  
  7171  function processTextToken(token, options) {
  7172    var el;
  7173    if (token.oneTime) {
  7174      el = document.createTextNode(token.value);
  7175    } else {
  7176      if (token.html) {
  7177        el = document.createComment('v-html');
  7178        setTokenType('html');
  7179      } else {
  7180        // IE will clean up empty textNodes during
  7181        // frag.cloneNode(true), so we have to give it
  7182        // something here...
  7183        el = document.createTextNode(' ');
  7184        setTokenType('text');
  7185      }
  7186    }
  7187    function setTokenType(type) {
  7188      if (token.descriptor) return;
  7189      var parsed = parseDirective(token.value);
  7190      token.descriptor = {
  7191        name: type,
  7192        def: directives[type],
  7193        expression: parsed.expression,
  7194        filters: parsed.filters
  7195      };
  7196    }
  7197    return el;
  7198  }
  7199  
  7200  /**
  7201   * Build a function that processes a textNode.
  7202   *
  7203   * @param {Array<Object>} tokens
  7204   * @param {DocumentFragment} frag
  7205   */
  7206  
  7207  function makeTextNodeLinkFn(tokens, frag) {
  7208    return function textNodeLinkFn(vm, el, host, scope) {
  7209      var fragClone = frag.cloneNode(true);
  7210      var childNodes = toArray(fragClone.childNodes);
  7211      var token, value, node;
  7212      for (var i = 0, l = tokens.length; i < l; i++) {
  7213        token = tokens[i];
  7214        value = token.value;
  7215        if (token.tag) {
  7216          node = childNodes[i];
  7217          if (token.oneTime) {
  7218            value = (scope || vm).$eval(value);
  7219            if (token.html) {
  7220              replace(node, parseTemplate(value, true));
  7221            } else {
  7222              node.data = value;
  7223            }
  7224          } else {
  7225            vm._bindDir(token.descriptor, node, host, scope);
  7226          }
  7227        }
  7228      }
  7229      replace(el, fragClone);
  7230    };
  7231  }
  7232  
  7233  /**
  7234   * Compile a node list and return a childLinkFn.
  7235   *
  7236   * @param {NodeList} nodeList
  7237   * @param {Object} options
  7238   * @return {Function|undefined}
  7239   */
  7240  
  7241  function compileNodeList(nodeList, options) {
  7242    var linkFns = [];
  7243    var nodeLinkFn, childLinkFn, node;
  7244    for (var i = 0, l = nodeList.length; i < l; i++) {
  7245      node = nodeList[i];
  7246      nodeLinkFn = compileNode(node, options);
  7247      childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && node.tagName !== 'SCRIPT' && node.hasChildNodes() ? compileNodeList(node.childNodes, options) : null;
  7248      linkFns.push(nodeLinkFn, childLinkFn);
  7249    }
  7250    return linkFns.length ? makeChildLinkFn(linkFns) : null;
  7251  }
  7252  
  7253  /**
  7254   * Make a child link function for a node's childNodes.
  7255   *
  7256   * @param {Array<Function>} linkFns
  7257   * @return {Function} childLinkFn
  7258   */
  7259  
  7260  function makeChildLinkFn(linkFns) {
  7261    return function childLinkFn(vm, nodes, host, scope, frag) {
  7262      var node, nodeLinkFn, childrenLinkFn;
  7263      for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
  7264        node = nodes[n];
  7265        nodeLinkFn = linkFns[i++];
  7266        childrenLinkFn = linkFns[i++];
  7267        // cache childNodes before linking parent, fix #657
  7268        var childNodes = toArray(node.childNodes);
  7269        if (nodeLinkFn) {
  7270          nodeLinkFn(vm, node, host, scope, frag);
  7271        }
  7272        if (childrenLinkFn) {
  7273          childrenLinkFn(vm, childNodes, host, scope, frag);
  7274        }
  7275      }
  7276    };
  7277  }
  7278  
  7279  /**
  7280   * Check for element directives (custom elements that should
  7281   * be resovled as terminal directives).
  7282   *
  7283   * @param {Element} el
  7284   * @param {Object} options
  7285   */
  7286  
  7287  function checkElementDirectives(el, options) {
  7288    var tag = el.tagName.toLowerCase();
  7289    if (commonTagRE.test(tag)) {
  7290      return;
  7291    }
  7292    var def = resolveAsset(options, 'elementDirectives', tag);
  7293    if (def) {
  7294      return makeTerminalNodeLinkFn(el, tag, '', options, def);
  7295    }
  7296  }
  7297  
  7298  /**
  7299   * Check if an element is a component. If yes, return
  7300   * a component link function.
  7301   *
  7302   * @param {Element} el
  7303   * @param {Object} options
  7304   * @return {Function|undefined}
  7305   */
  7306  
  7307  function checkComponent(el, options) {
  7308    var component = checkComponentAttr(el, options);
  7309    if (component) {
  7310      var ref = findRef(el);
  7311      var descriptor = {
  7312        name: 'component',
  7313        ref: ref,
  7314        expression: component.id,
  7315        def: internalDirectives.component,
  7316        modifiers: {
  7317          literal: !component.dynamic
  7318        }
  7319      };
  7320      var componentLinkFn = function componentLinkFn(vm, el, host, scope, frag) {
  7321        if (ref) {
  7322          defineReactive((scope || vm).$refs, ref, null);
  7323        }
  7324        vm._bindDir(descriptor, el, host, scope, frag);
  7325      };
  7326      componentLinkFn.terminal = true;
  7327      return componentLinkFn;
  7328    }
  7329  }
  7330  
  7331  /**
  7332   * Check an element for terminal directives in fixed order.
  7333   * If it finds one, return a terminal link function.
  7334   *
  7335   * @param {Element} el
  7336   * @param {Array} attrs
  7337   * @param {Object} options
  7338   * @return {Function} terminalLinkFn
  7339   */
  7340  
  7341  function checkTerminalDirectives(el, attrs, options) {
  7342    // skip v-pre
  7343    if (getAttr(el, 'v-pre') !== null) {
  7344      return skip;
  7345    }
  7346    // skip v-else block, but only if following v-if
  7347    if (el.hasAttribute('v-else')) {
  7348      var prev = el.previousElementSibling;
  7349      if (prev && prev.hasAttribute('v-if')) {
  7350        return skip;
  7351      }
  7352    }
  7353  
  7354    var attr, name, value, modifiers, matched, dirName, rawName, arg, def, termDef;
  7355    for (var i = 0, j = attrs.length; i < j; i++) {
  7356      attr = attrs[i];
  7357      name = attr.name.replace(modifierRE, '');
  7358      if (matched = name.match(dirAttrRE)) {
  7359        def = resolveAsset(options, 'directives', matched[1]);
  7360        if (def && def.terminal) {
  7361          if (!termDef || (def.priority || DEFAULT_TERMINAL_PRIORITY) > termDef.priority) {
  7362            termDef = def;
  7363            rawName = attr.name;
  7364            modifiers = parseModifiers(attr.name);
  7365            value = attr.value;
  7366            dirName = matched[1];
  7367            arg = matched[2];
  7368          }
  7369        }
  7370      }
  7371    }
  7372  
  7373    if (termDef) {
  7374      return makeTerminalNodeLinkFn(el, dirName, value, options, termDef, rawName, arg, modifiers);
  7375    }
  7376  }
  7377  
  7378  function skip() {}
  7379  skip.terminal = true;
  7380  
  7381  /**
  7382   * Build a node link function for a terminal directive.
  7383   * A terminal link function terminates the current
  7384   * compilation recursion and handles compilation of the
  7385   * subtree in the directive.
  7386   *
  7387   * @param {Element} el
  7388   * @param {String} dirName
  7389   * @param {String} value
  7390   * @param {Object} options
  7391   * @param {Object} def
  7392   * @param {String} [rawName]
  7393   * @param {String} [arg]
  7394   * @param {Object} [modifiers]
  7395   * @return {Function} terminalLinkFn
  7396   */
  7397  
  7398  function makeTerminalNodeLinkFn(el, dirName, value, options, def, rawName, arg, modifiers) {
  7399    var parsed = parseDirective(value);
  7400    var descriptor = {
  7401      name: dirName,
  7402      arg: arg,
  7403      expression: parsed.expression,
  7404      filters: parsed.filters,
  7405      raw: value,
  7406      attr: rawName,
  7407      modifiers: modifiers,
  7408      def: def
  7409    };
  7410    // check ref for v-for and router-view
  7411    if (dirName === 'for' || dirName === 'router-view') {
  7412      descriptor.ref = findRef(el);
  7413    }
  7414    var fn = function terminalNodeLinkFn(vm, el, host, scope, frag) {
  7415      if (descriptor.ref) {
  7416        defineReactive((scope || vm).$refs, descriptor.ref, null);
  7417      }
  7418      vm._bindDir(descriptor, el, host, scope, frag);
  7419    };
  7420    fn.terminal = true;
  7421    return fn;
  7422  }
  7423  
  7424  /**
  7425   * Compile the directives on an element and return a linker.
  7426   *
  7427   * @param {Array|NamedNodeMap} attrs
  7428   * @param {Object} options
  7429   * @return {Function}
  7430   */
  7431  
  7432  function compileDirectives(attrs, options) {
  7433    var i = attrs.length;
  7434    var dirs = [];
  7435    var attr, name, value, rawName, rawValue, dirName, arg, modifiers, dirDef, tokens, matched;
  7436    while (i--) {
  7437      attr = attrs[i];
  7438      name = rawName = attr.name;
  7439      value = rawValue = attr.value;
  7440      tokens = parseText(value);
  7441      // reset arg
  7442      arg = null;
  7443      // check modifiers
  7444      modifiers = parseModifiers(name);
  7445      name = name.replace(modifierRE, '');
  7446  
  7447      // attribute interpolations
  7448      if (tokens) {
  7449        value = tokensToExp(tokens);
  7450        arg = name;
  7451        pushDir('bind', directives.bind, tokens);
  7452        // warn against mixing mustaches with v-bind
  7453        if (process.env.NODE_ENV !== 'production') {
  7454          if (name === 'class' && Array.prototype.some.call(attrs, function (attr) {
  7455            return attr.name === ':class' || attr.name === 'v-bind:class';
  7456          })) {
  7457            warn('class="' + rawValue + '": Do not mix mustache interpolation ' + 'and v-bind for "class" on the same element. Use one or the other.', options);
  7458          }
  7459        }
  7460      } else
  7461  
  7462        // special attribute: transition
  7463        if (transitionRE.test(name)) {
  7464          modifiers.literal = !bindRE.test(name);
  7465          pushDir('transition', internalDirectives.transition);
  7466        } else
  7467  
  7468          // event handlers
  7469          if (onRE.test(name)) {
  7470            arg = name.replace(onRE, '');
  7471            pushDir('on', directives.on);
  7472          } else
  7473  
  7474            // attribute bindings
  7475            if (bindRE.test(name)) {
  7476              dirName = name.replace(bindRE, '');
  7477              if (dirName === 'style' || dirName === 'class') {
  7478                pushDir(dirName, internalDirectives[dirName]);
  7479              } else {
  7480                arg = dirName;
  7481                pushDir('bind', directives.bind);
  7482              }
  7483            } else
  7484  
  7485              // normal directives
  7486              if (matched = name.match(dirAttrRE)) {
  7487                dirName = matched[1];
  7488                arg = matched[2];
  7489  
  7490                // skip v-else (when used with v-show)
  7491                if (dirName === 'else') {
  7492                  continue;
  7493                }
  7494  
  7495                dirDef = resolveAsset(options, 'directives', dirName, true);
  7496                if (dirDef) {
  7497                  pushDir(dirName, dirDef);
  7498                }
  7499              }
  7500    }
  7501  
  7502    /**
  7503     * Push a directive.
  7504     *
  7505     * @param {String} dirName
  7506     * @param {Object|Function} def
  7507     * @param {Array} [interpTokens]
  7508     */
  7509  
  7510    function pushDir(dirName, def, interpTokens) {
  7511      var hasOneTimeToken = interpTokens && hasOneTime(interpTokens);
  7512      var parsed = !hasOneTimeToken && parseDirective(value);
  7513      dirs.push({
  7514        name: dirName,
  7515        attr: rawName,
  7516        raw: rawValue,
  7517        def: def,
  7518        arg: arg,
  7519        modifiers: modifiers,
  7520        // conversion from interpolation strings with one-time token
  7521        // to expression is differed until directive bind time so that we
  7522        // have access to the actual vm context for one-time bindings.
  7523        expression: parsed && parsed.expression,
  7524        filters: parsed && parsed.filters,
  7525        interp: interpTokens,
  7526        hasOneTime: hasOneTimeToken
  7527      });
  7528    }
  7529  
  7530    if (dirs.length) {
  7531      return makeNodeLinkFn(dirs);
  7532    }
  7533  }
  7534  
  7535  /**
  7536   * Parse modifiers from directive attribute name.
  7537   *
  7538   * @param {String} name
  7539   * @return {Object}
  7540   */
  7541  
  7542  function parseModifiers(name) {
  7543    var res = Object.create(null);
  7544    var match = name.match(modifierRE);
  7545    if (match) {
  7546      var i = match.length;
  7547      while (i--) {
  7548        res[match[i].slice(1)] = true;
  7549      }
  7550    }
  7551    return res;
  7552  }
  7553  
  7554  /**
  7555   * Build a link function for all directives on a single node.
  7556   *
  7557   * @param {Array} directives
  7558   * @return {Function} directivesLinkFn
  7559   */
  7560  
  7561  function makeNodeLinkFn(directives) {
  7562    return function nodeLinkFn(vm, el, host, scope, frag) {
  7563      // reverse apply because it's sorted low to high
  7564      var i = directives.length;
  7565      while (i--) {
  7566        vm._bindDir(directives[i], el, host, scope, frag);
  7567      }
  7568    };
  7569  }
  7570  
  7571  /**
  7572   * Check if an interpolation string contains one-time tokens.
  7573   *
  7574   * @param {Array} tokens
  7575   * @return {Boolean}
  7576   */
  7577  
  7578  function hasOneTime(tokens) {
  7579    var i = tokens.length;
  7580    while (i--) {
  7581      if (tokens[i].oneTime) return true;
  7582    }
  7583  }
  7584  
  7585  function isScript(el) {
  7586    return el.tagName === 'SCRIPT' && (!el.hasAttribute('type') || el.getAttribute('type') === 'text/javascript');
  7587  }
  7588  
  7589  var specialCharRE = /[^\w\-:\.]/;
  7590  
  7591  /**
  7592   * Process an element or a DocumentFragment based on a
  7593   * instance option object. This allows us to transclude
  7594   * a template node/fragment before the instance is created,
  7595   * so the processed fragment can then be cloned and reused
  7596   * in v-for.
  7597   *
  7598   * @param {Element} el
  7599   * @param {Object} options
  7600   * @return {Element|DocumentFragment}
  7601   */
  7602  
  7603  function transclude(el, options) {
  7604    // extract container attributes to pass them down
  7605    // to compiler, because they need to be compiled in
  7606    // parent scope. we are mutating the options object here
  7607    // assuming the same object will be used for compile
  7608    // right after this.
  7609    if (options) {
  7610      options._containerAttrs = extractAttrs(el);
  7611    }
  7612    // for template tags, what we want is its content as
  7613    // a documentFragment (for fragment instances)
  7614    if (isTemplate(el)) {
  7615      el = parseTemplate(el);
  7616    }
  7617    if (options) {
  7618      if (options._asComponent && !options.template) {
  7619        options.template = '<slot></slot>';
  7620      }
  7621      if (options.template) {
  7622        options._content = extractContent(el);
  7623        el = transcludeTemplate(el, options);
  7624      }
  7625    }
  7626    if (isFragment(el)) {
  7627      // anchors for fragment instance
  7628      // passing in `persist: true` to avoid them being
  7629      // discarded by IE during template cloning
  7630      prepend(createAnchor('v-start', true), el);
  7631      el.appendChild(createAnchor('v-end', true));
  7632    }
  7633    return el;
  7634  }
  7635  
  7636  /**
  7637   * Process the template option.
  7638   * If the replace option is true this will swap the $el.
  7639   *
  7640   * @param {Element} el
  7641   * @param {Object} options
  7642   * @return {Element|DocumentFragment}
  7643   */
  7644  
  7645  function transcludeTemplate(el, options) {
  7646    var template = options.template;
  7647    var frag = parseTemplate(template, true);
  7648    if (frag) {
  7649      var replacer = frag.firstChild;
  7650      var tag = replacer.tagName && replacer.tagName.toLowerCase();
  7651      if (options.replace) {
  7652        /* istanbul ignore if */
  7653        if (el === document.body) {
  7654          process.env.NODE_ENV !== 'production' && warn('You are mounting an instance with a template to ' + '<body>. This will replace <body> entirely. You ' + 'should probably use `replace: false` here.');
  7655        }
  7656        // there are many cases where the instance must
  7657        // become a fragment instance: basically anything that
  7658        // can create more than 1 root nodes.
  7659        if (
  7660        // multi-children template
  7661        frag.childNodes.length > 1 ||
  7662        // non-element template
  7663        replacer.nodeType !== 1 ||
  7664        // single nested component
  7665        tag === 'component' || resolveAsset(options, 'components', tag) || hasBindAttr(replacer, 'is') ||
  7666        // element directive
  7667        resolveAsset(options, 'elementDirectives', tag) ||
  7668        // for block
  7669        replacer.hasAttribute('v-for') ||
  7670        // if block
  7671        replacer.hasAttribute('v-if')) {
  7672          return frag;
  7673        } else {
  7674          options._replacerAttrs = extractAttrs(replacer);
  7675          mergeAttrs(el, replacer);
  7676          return replacer;
  7677        }
  7678      } else {
  7679        el.appendChild(frag);
  7680        return el;
  7681      }
  7682    } else {
  7683      process.env.NODE_ENV !== 'production' && warn('Invalid template option: ' + template);
  7684    }
  7685  }
  7686  
  7687  /**
  7688   * Helper to extract a component container's attributes
  7689   * into a plain object array.
  7690   *
  7691   * @param {Element} el
  7692   * @return {Array}
  7693   */
  7694  
  7695  function extractAttrs(el) {
  7696    if (el.nodeType === 1 && el.hasAttributes()) {
  7697      return toArray(el.attributes);
  7698    }
  7699  }
  7700  
  7701  /**
  7702   * Merge the attributes of two elements, and make sure
  7703   * the class names are merged properly.
  7704   *
  7705   * @param {Element} from
  7706   * @param {Element} to
  7707   */
  7708  
  7709  function mergeAttrs(from, to) {
  7710    var attrs = from.attributes;
  7711    var i = attrs.length;
  7712    var name, value;
  7713    while (i--) {
  7714      name = attrs[i].name;
  7715      value = attrs[i].value;
  7716      if (!to.hasAttribute(name) && !specialCharRE.test(name)) {
  7717        to.setAttribute(name, value);
  7718      } else if (name === 'class' && !parseText(value) && (value = value.trim())) {
  7719        value.split(/\s+/).forEach(function (cls) {
  7720          addClass(to, cls);
  7721        });
  7722      }
  7723    }
  7724  }
  7725  
  7726  /**
  7727   * Scan and determine slot content distribution.
  7728   * We do this during transclusion instead at compile time so that
  7729   * the distribution is decoupled from the compilation order of
  7730   * the slots.
  7731   *
  7732   * @param {Element|DocumentFragment} template
  7733   * @param {Element} content
  7734   * @param {Vue} vm
  7735   */
  7736  
  7737  function resolveSlots(vm, content) {
  7738    if (!content) {
  7739      return;
  7740    }
  7741    var contents = vm._slotContents = Object.create(null);
  7742    var el, name;
  7743    for (var i = 0, l = content.children.length; i < l; i++) {
  7744      el = content.children[i];
  7745      /* eslint-disable no-cond-assign */
  7746      if (name = el.getAttribute('slot')) {
  7747        (contents[name] || (contents[name] = [])).push(el);
  7748      }
  7749      /* eslint-enable no-cond-assign */
  7750      if (process.env.NODE_ENV !== 'production' && getBindAttr(el, 'slot')) {
  7751        warn('The "slot" attribute must be static.', vm.$parent);
  7752      }
  7753    }
  7754    for (name in contents) {
  7755      contents[name] = extractFragment(contents[name], content);
  7756    }
  7757    if (content.hasChildNodes()) {
  7758      var nodes = content.childNodes;
  7759      if (nodes.length === 1 && nodes[0].nodeType === 3 && !nodes[0].data.trim()) {
  7760        return;
  7761      }
  7762      contents['default'] = extractFragment(content.childNodes, content);
  7763    }
  7764  }
  7765  
  7766  /**
  7767   * Extract qualified content nodes from a node list.
  7768   *
  7769   * @param {NodeList} nodes
  7770   * @return {DocumentFragment}
  7771   */
  7772  
  7773  function extractFragment(nodes, parent) {
  7774    var frag = document.createDocumentFragment();
  7775    nodes = toArray(nodes);
  7776    for (var i = 0, l = nodes.length; i < l; i++) {
  7777      var node = nodes[i];
  7778      if (isTemplate(node) && !node.hasAttribute('v-if') && !node.hasAttribute('v-for')) {
  7779        parent.removeChild(node);
  7780        node = parseTemplate(node, true);
  7781      }
  7782      frag.appendChild(node);
  7783    }
  7784    return frag;
  7785  }
  7786  
  7787  
  7788  
  7789  var compiler = Object.freeze({
  7790  	compile: compile,
  7791  	compileAndLinkProps: compileAndLinkProps,
  7792  	compileRoot: compileRoot,
  7793  	transclude: transclude,
  7794  	resolveSlots: resolveSlots
  7795  });
  7796  
  7797  function stateMixin (Vue) {
  7798    /**
  7799     * Accessor for `$data` property, since setting $data
  7800     * requires observing the new object and updating
  7801     * proxied properties.
  7802     */
  7803  
  7804    Object.defineProperty(Vue.prototype, '$data', {
  7805      get: function get() {
  7806        return this._data;
  7807      },
  7808      set: function set(newData) {
  7809        if (newData !== this._data) {
  7810          this._setData(newData);
  7811        }
  7812      }
  7813    });
  7814  
  7815    /**
  7816     * Setup the scope of an instance, which contains:
  7817     * - observed data
  7818     * - computed properties
  7819     * - user methods
  7820     * - meta properties
  7821     */
  7822  
  7823    Vue.prototype._initState = function () {
  7824      this._initProps();
  7825      this._initMeta();
  7826      this._initMethods();
  7827      this._initData();
  7828      this._initComputed();
  7829    };
  7830  
  7831    /**
  7832     * Initialize props.
  7833     */
  7834  
  7835    Vue.prototype._initProps = function () {
  7836      var options = this.$options;
  7837      var el = options.el;
  7838      var props = options.props;
  7839      if (props && !el) {
  7840        process.env.NODE_ENV !== 'production' && warn('Props will not be compiled if no `el` option is ' + 'provided at instantiation.', this);
  7841      }
  7842      // make sure to convert string selectors into element now
  7843      el = options.el = query(el);
  7844      this._propsUnlinkFn = el && el.nodeType === 1 && props
  7845      // props must be linked in proper scope if inside v-for
  7846      ? compileAndLinkProps(this, el, props, this._scope) : null;
  7847    };
  7848  
  7849    /**
  7850     * Initialize the data.
  7851     */
  7852  
  7853    Vue.prototype._initData = function () {
  7854      var dataFn = this.$options.data;
  7855      var data = this._data = dataFn ? dataFn() : {};
  7856      if (!isPlainObject(data)) {
  7857        data = {};
  7858        process.env.NODE_ENV !== 'production' && warn('data functions should return an object.', this);
  7859      }
  7860      var props = this._props;
  7861      // proxy data on instance
  7862      var keys = Object.keys(data);
  7863      var i, key;
  7864      i = keys.length;
  7865      while (i--) {
  7866        key = keys[i];
  7867        // there are two scenarios where we can proxy a data key:
  7868        // 1. it's not already defined as a prop
  7869        // 2. it's provided via a instantiation option AND there are no
  7870        //    template prop present
  7871        if (!props || !hasOwn(props, key)) {
  7872          this._proxy(key);
  7873        } else if (process.env.NODE_ENV !== 'production') {
  7874          warn('Data field "' + key + '" is already defined ' + 'as a prop. To provide default value for a prop, use the "default" ' + 'prop option; if you want to pass prop values to an instantiation ' + 'call, use the "propsData" option.', this);
  7875        }
  7876      }
  7877      // observe data
  7878      observe(data, this);
  7879    };
  7880  
  7881    /**
  7882     * Swap the instance's $data. Called in $data's setter.
  7883     *
  7884     * @param {Object} newData
  7885     */
  7886  
  7887    Vue.prototype._setData = function (newData) {
  7888      newData = newData || {};
  7889      var oldData = this._data;
  7890      this._data = newData;
  7891      var keys, key, i;
  7892      // unproxy keys not present in new data
  7893      keys = Object.keys(oldData);
  7894      i = keys.length;
  7895      while (i--) {
  7896        key = keys[i];
  7897        if (!(key in newData)) {
  7898          this._unproxy(key);
  7899        }
  7900      }
  7901      // proxy keys not already proxied,
  7902      // and trigger change for changed values
  7903      keys = Object.keys(newData);
  7904      i = keys.length;
  7905      while (i--) {
  7906        key = keys[i];
  7907        if (!hasOwn(this, key)) {
  7908          // new property
  7909          this._proxy(key);
  7910        }
  7911      }
  7912      oldData.__ob__.removeVm(this);
  7913      observe(newData, this);
  7914      this._digest();
  7915    };
  7916  
  7917    /**
  7918     * Proxy a property, so that
  7919     * vm.prop === vm._data.prop
  7920     *
  7921     * @param {String} key
  7922     */
  7923  
  7924    Vue.prototype._proxy = function (key) {
  7925      if (!isReserved(key)) {
  7926        // need to store ref to self here
  7927        // because these getter/setters might
  7928        // be called by child scopes via
  7929        // prototype inheritance.
  7930        var self = this;
  7931        Object.defineProperty(self, key, {
  7932          configurable: true,
  7933          enumerable: true,
  7934          get: function proxyGetter() {
  7935            return self._data[key];
  7936          },
  7937          set: function proxySetter(val) {
  7938            self._data[key] = val;
  7939          }
  7940        });
  7941      }
  7942    };
  7943  
  7944    /**
  7945     * Unproxy a property.
  7946     *
  7947     * @param {String} key
  7948     */
  7949  
  7950    Vue.prototype._unproxy = function (key) {
  7951      if (!isReserved(key)) {
  7952        delete this[key];
  7953      }
  7954    };
  7955  
  7956    /**
  7957     * Force update on every watcher in scope.
  7958     */
  7959  
  7960    Vue.prototype._digest = function () {
  7961      for (var i = 0, l = this._watchers.length; i < l; i++) {
  7962        this._watchers[i].update(true); // shallow updates
  7963      }
  7964    };
  7965  
  7966    /**
  7967     * Setup computed properties. They are essentially
  7968     * special getter/setters
  7969     */
  7970  
  7971    function noop() {}
  7972    Vue.prototype._initComputed = function () {
  7973      var computed = this.$options.computed;
  7974      if (computed) {
  7975        for (var key in computed) {
  7976          var userDef = computed[key];
  7977          var def = {
  7978            enumerable: true,
  7979            configurable: true
  7980          };
  7981          if (typeof userDef === 'function') {
  7982            def.get = makeComputedGetter(userDef, this);
  7983            def.set = noop;
  7984          } else {
  7985            def.get = userDef.get ? userDef.cache !== false ? makeComputedGetter(userDef.get, this) : bind(userDef.get, this) : noop;
  7986            def.set = userDef.set ? bind(userDef.set, this) : noop;
  7987          }
  7988          Object.defineProperty(this, key, def);
  7989        }
  7990      }
  7991    };
  7992  
  7993    function makeComputedGetter(getter, owner) {
  7994      var watcher = new Watcher(owner, getter, null, {
  7995        lazy: true
  7996      });
  7997      return function computedGetter() {
  7998        if (watcher.dirty) {
  7999          watcher.evaluate();
  8000        }
  8001        if (Dep.target) {
  8002          watcher.depend();
  8003        }
  8004        return watcher.value;
  8005      };
  8006    }
  8007  
  8008    /**
  8009     * Setup instance methods. Methods must be bound to the
  8010     * instance since they might be passed down as a prop to
  8011     * child components.
  8012     */
  8013  
  8014    Vue.prototype._initMethods = function () {
  8015      var methods = this.$options.methods;
  8016      if (methods) {
  8017        for (var key in methods) {
  8018          this[key] = bind(methods[key], this);
  8019        }
  8020      }
  8021    };
  8022  
  8023    /**
  8024     * Initialize meta information like $index, $key & $value.
  8025     */
  8026  
  8027    Vue.prototype._initMeta = function () {
  8028      var metas = this.$options._meta;
  8029      if (metas) {
  8030        for (var key in metas) {
  8031          defineReactive(this, key, metas[key]);
  8032        }
  8033      }
  8034    };
  8035  }
  8036  
  8037  var eventRE = /^v-on:|^@/;
  8038  
  8039  function eventsMixin (Vue) {
  8040    /**
  8041     * Setup the instance's option events & watchers.
  8042     * If the value is a string, we pull it from the
  8043     * instance's methods by name.
  8044     */
  8045  
  8046    Vue.prototype._initEvents = function () {
  8047      var options = this.$options;
  8048      if (options._asComponent) {
  8049        registerComponentEvents(this, options.el);
  8050      }
  8051      registerCallbacks(this, '$on', options.events);
  8052      registerCallbacks(this, '$watch', options.watch);
  8053    };
  8054  
  8055    /**
  8056     * Register v-on events on a child component
  8057     *
  8058     * @param {Vue} vm
  8059     * @param {Element} el
  8060     */
  8061  
  8062    function registerComponentEvents(vm, el) {
  8063      var attrs = el.attributes;
  8064      var name, value, handler;
  8065      for (var i = 0, l = attrs.length; i < l; i++) {
  8066        name = attrs[i].name;
  8067        if (eventRE.test(name)) {
  8068          name = name.replace(eventRE, '');
  8069          // force the expression into a statement so that
  8070          // it always dynamically resolves the method to call (#2670)
  8071          // kinda ugly hack, but does the job.
  8072          value = attrs[i].value;
  8073          if (isSimplePath(value)) {
  8074            value += '.apply(this, $arguments)';
  8075          }
  8076          handler = (vm._scope || vm._context).$eval(value, true);
  8077          handler._fromParent = true;
  8078          vm.$on(name.replace(eventRE), handler);
  8079        }
  8080      }
  8081    }
  8082  
  8083    /**
  8084     * Register callbacks for option events and watchers.
  8085     *
  8086     * @param {Vue} vm
  8087     * @param {String} action
  8088     * @param {Object} hash
  8089     */
  8090  
  8091    function registerCallbacks(vm, action, hash) {
  8092      if (!hash) return;
  8093      var handlers, key, i, j;
  8094      for (key in hash) {
  8095        handlers = hash[key];
  8096        if (isArray(handlers)) {
  8097          for (i = 0, j = handlers.length; i < j; i++) {
  8098            register(vm, action, key, handlers[i]);
  8099          }
  8100        } else {
  8101          register(vm, action, key, handlers);
  8102        }
  8103      }
  8104    }
  8105  
  8106    /**
  8107     * Helper to register an event/watch callback.
  8108     *
  8109     * @param {Vue} vm
  8110     * @param {String} action
  8111     * @param {String} key
  8112     * @param {Function|String|Object} handler
  8113     * @param {Object} [options]
  8114     */
  8115  
  8116    function register(vm, action, key, handler, options) {
  8117      var type = typeof handler;
  8118      if (type === 'function') {
  8119        vm[action](key, handler, options);
  8120      } else if (type === 'string') {
  8121        var methods = vm.$options.methods;
  8122        var method = methods && methods[handler];
  8123        if (method) {
  8124          vm[action](key, method, options);
  8125        } else {
  8126          process.env.NODE_ENV !== 'production' && warn('Unknown method: "' + handler + '" when ' + 'registering callback for ' + action + ': "' + key + '".', vm);
  8127        }
  8128      } else if (handler && type === 'object') {
  8129        register(vm, action, key, handler.handler, handler);
  8130      }
  8131    }
  8132  
  8133    /**
  8134     * Setup recursive attached/detached calls
  8135     */
  8136  
  8137    Vue.prototype._initDOMHooks = function () {
  8138      this.$on('hook:attached', onAttached);
  8139      this.$on('hook:detached', onDetached);
  8140    };
  8141  
  8142    /**
  8143     * Callback to recursively call attached hook on children
  8144     */
  8145  
  8146    function onAttached() {
  8147      if (!this._isAttached) {
  8148        this._isAttached = true;
  8149        this.$children.forEach(callAttach);
  8150      }
  8151    }
  8152  
  8153    /**
  8154     * Iterator to call attached hook
  8155     *
  8156     * @param {Vue} child
  8157     */
  8158  
  8159    function callAttach(child) {
  8160      if (!child._isAttached && inDoc(child.$el)) {
  8161        child._callHook('attached');
  8162      }
  8163    }
  8164  
  8165    /**
  8166     * Callback to recursively call detached hook on children
  8167     */
  8168  
  8169    function onDetached() {
  8170      if (this._isAttached) {
  8171        this._isAttached = false;
  8172        this.$children.forEach(callDetach);
  8173      }
  8174    }
  8175  
  8176    /**
  8177     * Iterator to call detached hook
  8178     *
  8179     * @param {Vue} child
  8180     */
  8181  
  8182    function callDetach(child) {
  8183      if (child._isAttached && !inDoc(child.$el)) {
  8184        child._callHook('detached');
  8185      }
  8186    }
  8187  
  8188    /**
  8189     * Trigger all handlers for a hook
  8190     *
  8191     * @param {String} hook
  8192     */
  8193  
  8194    Vue.prototype._callHook = function (hook) {
  8195      this.$emit('pre-hook:' + hook);
  8196      var handlers = this.$options[hook];
  8197      if (handlers) {
  8198        for (var i = 0, j = handlers.length; i < j; i++) {
  8199          handlers[i].call(this);
  8200        }
  8201      }
  8202      this.$emit('hook:' + hook);
  8203    };
  8204  }
  8205  
  8206  function noop() {}
  8207  
  8208  /**
  8209   * A directive links a DOM element with a piece of data,
  8210   * which is the result of evaluating an expression.
  8211   * It registers a watcher with the expression and calls
  8212   * the DOM update function when a change is triggered.
  8213   *
  8214   * @param {Object} descriptor
  8215   *                 - {String} name
  8216   *                 - {Object} def
  8217   *                 - {String} expression
  8218   *                 - {Array<Object>} [filters]
  8219   *                 - {Object} [modifiers]
  8220   *                 - {Boolean} literal
  8221   *                 - {String} attr
  8222   *                 - {String} arg
  8223   *                 - {String} raw
  8224   *                 - {String} [ref]
  8225   *                 - {Array<Object>} [interp]
  8226   *                 - {Boolean} [hasOneTime]
  8227   * @param {Vue} vm
  8228   * @param {Node} el
  8229   * @param {Vue} [host] - transclusion host component
  8230   * @param {Object} [scope] - v-for scope
  8231   * @param {Fragment} [frag] - owner fragment
  8232   * @constructor
  8233   */
  8234  function Directive(descriptor, vm, el, host, scope, frag) {
  8235    this.vm = vm;
  8236    this.el = el;
  8237    // copy descriptor properties
  8238    this.descriptor = descriptor;
  8239    this.name = descriptor.name;
  8240    this.expression = descriptor.expression;
  8241    this.arg = descriptor.arg;
  8242    this.modifiers = descriptor.modifiers;
  8243    this.filters = descriptor.filters;
  8244    this.literal = this.modifiers && this.modifiers.literal;
  8245    // private
  8246    this._locked = false;
  8247    this._bound = false;
  8248    this._listeners = null;
  8249    // link context
  8250    this._host = host;
  8251    this._scope = scope;
  8252    this._frag = frag;
  8253    // store directives on node in dev mode
  8254    if (process.env.NODE_ENV !== 'production' && this.el) {
  8255      this.el._vue_directives = this.el._vue_directives || [];
  8256      this.el._vue_directives.push(this);
  8257    }
  8258  }
  8259  
  8260  /**
  8261   * Initialize the directive, mixin definition properties,
  8262   * setup the watcher, call definition bind() and update()
  8263   * if present.
  8264   */
  8265  
  8266  Directive.prototype._bind = function () {
  8267    var name = this.name;
  8268    var descriptor = this.descriptor;
  8269  
  8270    // remove attribute
  8271    if ((name !== 'cloak' || this.vm._isCompiled) && this.el && this.el.removeAttribute) {
  8272      var attr = descriptor.attr || 'v-' + name;
  8273      this.el.removeAttribute(attr);
  8274    }
  8275  
  8276    // copy def properties
  8277    var def = descriptor.def;
  8278    if (typeof def === 'function') {
  8279      this.update = def;
  8280    } else {
  8281      extend(this, def);
  8282    }
  8283  
  8284    // setup directive params
  8285    this._setupParams();
  8286  
  8287    // initial bind
  8288    if (this.bind) {
  8289      this.bind();
  8290    }
  8291    this._bound = true;
  8292  
  8293    if (this.literal) {
  8294      this.update && this.update(descriptor.raw);
  8295    } else if ((this.expression || this.modifiers) && (this.update || this.twoWay) && !this._checkStatement()) {
  8296      // wrapped updater for context
  8297      var dir = this;
  8298      if (this.update) {
  8299        this._update = function (val, oldVal) {
  8300          if (!dir._locked) {
  8301            dir.update(val, oldVal);
  8302          }
  8303        };
  8304      } else {
  8305        this._update = noop;
  8306      }
  8307      var preProcess = this._preProcess ? bind(this._preProcess, this) : null;
  8308      var postProcess = this._postProcess ? bind(this._postProcess, this) : null;
  8309      var watcher = this._watcher = new Watcher(this.vm, this.expression, this._update, // callback
  8310      {
  8311        filters: this.filters,
  8312        twoWay: this.twoWay,
  8313        deep: this.deep,
  8314        preProcess: preProcess,
  8315        postProcess: postProcess,
  8316        scope: this._scope
  8317      });
  8318      // v-model with inital inline value need to sync back to
  8319      // model instead of update to DOM on init. They would
  8320      // set the afterBind hook to indicate that.
  8321      if (this.afterBind) {
  8322        this.afterBind();
  8323      } else if (this.update) {
  8324        this.update(watcher.value);
  8325      }
  8326    }
  8327  };
  8328  
  8329  /**
  8330   * Setup all param attributes, e.g. track-by,
  8331   * transition-mode, etc...
  8332   */
  8333  
  8334  Directive.prototype._setupParams = function () {
  8335    if (!this.params) {
  8336      return;
  8337    }
  8338    var params = this.params;
  8339    // swap the params array with a fresh object.
  8340    this.params = Object.create(null);
  8341    var i = params.length;
  8342    var key, val, mappedKey;
  8343    while (i--) {
  8344      key = hyphenate(params[i]);
  8345      mappedKey = camelize(key);
  8346      val = getBindAttr(this.el, key);
  8347      if (val != null) {
  8348        // dynamic
  8349        this._setupParamWatcher(mappedKey, val);
  8350      } else {
  8351        // static
  8352        val = getAttr(this.el, key);
  8353        if (val != null) {
  8354          this.params[mappedKey] = val === '' ? true : val;
  8355        }
  8356      }
  8357    }
  8358  };
  8359  
  8360  /**
  8361   * Setup a watcher for a dynamic param.
  8362   *
  8363   * @param {String} key
  8364   * @param {String} expression
  8365   */
  8366  
  8367  Directive.prototype._setupParamWatcher = function (key, expression) {
  8368    var self = this;
  8369    var called = false;
  8370    var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
  8371      self.params[key] = val;
  8372      // since we are in immediate mode,
  8373      // only call the param change callbacks if this is not the first update.
  8374      if (called) {
  8375        var cb = self.paramWatchers && self.paramWatchers[key];
  8376        if (cb) {
  8377          cb.call(self, val, oldVal);
  8378        }
  8379      } else {
  8380        called = true;
  8381      }
  8382    }, {
  8383      immediate: true,
  8384      user: false
  8385    });(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
  8386  };
  8387  
  8388  /**
  8389   * Check if the directive is a function caller
  8390   * and if the expression is a callable one. If both true,
  8391   * we wrap up the expression and use it as the event
  8392   * handler.
  8393   *
  8394   * e.g. on-click="a++"
  8395   *
  8396   * @return {Boolean}
  8397   */
  8398  
  8399  Directive.prototype._checkStatement = function () {
  8400    var expression = this.expression;
  8401    if (expression && this.acceptStatement && !isSimplePath(expression)) {
  8402      var fn = parseExpression(expression).get;
  8403      var scope = this._scope || this.vm;
  8404      var handler = function handler(e) {
  8405        scope.$event = e;
  8406        fn.call(scope, scope);
  8407        scope.$event = null;
  8408      };
  8409      if (this.filters) {
  8410        handler = scope._applyFilters(handler, null, this.filters);
  8411      }
  8412      this.update(handler);
  8413      return true;
  8414    }
  8415  };
  8416  
  8417  /**
  8418   * Set the corresponding value with the setter.
  8419   * This should only be used in two-way directives
  8420   * e.g. v-model.
  8421   *
  8422   * @param {*} value
  8423   * @public
  8424   */
  8425  
  8426  Directive.prototype.set = function (value) {
  8427    /* istanbul ignore else */
  8428    if (this.twoWay) {
  8429      this._withLock(function () {
  8430        this._watcher.set(value);
  8431      });
  8432    } else if (process.env.NODE_ENV !== 'production') {
  8433      warn('Directive.set() can only be used inside twoWay' + 'directives.');
  8434    }
  8435  };
  8436  
  8437  /**
  8438   * Execute a function while preventing that function from
  8439   * triggering updates on this directive instance.
  8440   *
  8441   * @param {Function} fn
  8442   */
  8443  
  8444  Directive.prototype._withLock = function (fn) {
  8445    var self = this;
  8446    self._locked = true;
  8447    fn.call(self);
  8448    nextTick(function () {
  8449      self._locked = false;
  8450    });
  8451  };
  8452  
  8453  /**
  8454   * Convenience method that attaches a DOM event listener
  8455   * to the directive element and autometically tears it down
  8456   * during unbind.
  8457   *
  8458   * @param {String} event
  8459   * @param {Function} handler
  8460   * @param {Boolean} [useCapture]
  8461   */
  8462  
  8463  Directive.prototype.on = function (event, handler, useCapture) {
  8464    on(this.el, event, handler, useCapture);(this._listeners || (this._listeners = [])).push([event, handler]);
  8465  };
  8466  
  8467  /**
  8468   * Teardown the watcher and call unbind.
  8469   */
  8470  
  8471  Directive.prototype._teardown = function () {
  8472    if (this._bound) {
  8473      this._bound = false;
  8474      if (this.unbind) {
  8475        this.unbind();
  8476      }
  8477      if (this._watcher) {
  8478        this._watcher.teardown();
  8479      }
  8480      var listeners = this._listeners;
  8481      var i;
  8482      if (listeners) {
  8483        i = listeners.length;
  8484        while (i--) {
  8485          off(this.el, listeners[i][0], listeners[i][1]);
  8486        }
  8487      }
  8488      var unwatchFns = this._paramUnwatchFns;
  8489      if (unwatchFns) {
  8490        i = unwatchFns.length;
  8491        while (i--) {
  8492          unwatchFns[i]();
  8493        }
  8494      }
  8495      if (process.env.NODE_ENV !== 'production' && this.el) {
  8496        this.el._vue_directives.$remove(this);
  8497      }
  8498      this.vm = this.el = this._watcher = this._listeners = null;
  8499    }
  8500  };
  8501  
  8502  function lifecycleMixin (Vue) {
  8503    /**
  8504     * Update v-ref for component.
  8505     *
  8506     * @param {Boolean} remove
  8507     */
  8508  
  8509    Vue.prototype._updateRef = function (remove) {
  8510      var ref = this.$options._ref;
  8511      if (ref) {
  8512        var refs = (this._scope || this._context).$refs;
  8513        if (remove) {
  8514          if (refs[ref] === this) {
  8515            refs[ref] = null;
  8516          }
  8517        } else {
  8518          refs[ref] = this;
  8519        }
  8520      }
  8521    };
  8522  
  8523    /**
  8524     * Transclude, compile and link element.
  8525     *
  8526     * If a pre-compiled linker is available, that means the
  8527     * passed in element will be pre-transcluded and compiled
  8528     * as well - all we need to do is to call the linker.
  8529     *
  8530     * Otherwise we need to call transclude/compile/link here.
  8531     *
  8532     * @param {Element} el
  8533     */
  8534  
  8535    Vue.prototype._compile = function (el) {
  8536      var options = this.$options;
  8537  
  8538      // transclude and init element
  8539      // transclude can potentially replace original
  8540      // so we need to keep reference; this step also injects
  8541      // the template and caches the original attributes
  8542      // on the container node and replacer node.
  8543      var original = el;
  8544      el = transclude(el, options);
  8545      this._initElement(el);
  8546  
  8547      // handle v-pre on root node (#2026)
  8548      if (el.nodeType === 1 && getAttr(el, 'v-pre') !== null) {
  8549        return;
  8550      }
  8551  
  8552      // root is always compiled per-instance, because
  8553      // container attrs and props can be different every time.
  8554      var contextOptions = this._context && this._context.$options;
  8555      var rootLinker = compileRoot(el, options, contextOptions);
  8556  
  8557      // resolve slot distribution
  8558      resolveSlots(this, options._content);
  8559  
  8560      // compile and link the rest
  8561      var contentLinkFn;
  8562      var ctor = this.constructor;
  8563      // component compilation can be cached
  8564      // as long as it's not using inline-template
  8565      if (options._linkerCachable) {
  8566        contentLinkFn = ctor.linker;
  8567        if (!contentLinkFn) {
  8568          contentLinkFn = ctor.linker = compile(el, options);
  8569        }
  8570      }
  8571  
  8572      // link phase
  8573      // make sure to link root with prop scope!
  8574      var rootUnlinkFn = rootLinker(this, el, this._scope);
  8575      var contentUnlinkFn = contentLinkFn ? contentLinkFn(this, el) : compile(el, options)(this, el);
  8576  
  8577      // register composite unlink function
  8578      // to be called during instance destruction
  8579      this._unlinkFn = function () {
  8580        rootUnlinkFn();
  8581        // passing destroying: true to avoid searching and
  8582        // splicing the directives
  8583        contentUnlinkFn(true);
  8584      };
  8585  
  8586      // finally replace original
  8587      if (options.replace) {
  8588        replace(original, el);
  8589      }
  8590  
  8591      this._isCompiled = true;
  8592      this._callHook('compiled');
  8593    };
  8594  
  8595    /**
  8596     * Initialize instance element. Called in the public
  8597     * $mount() method.
  8598     *
  8599     * @param {Element} el
  8600     */
  8601  
  8602    Vue.prototype._initElement = function (el) {
  8603      if (isFragment(el)) {
  8604        this._isFragment = true;
  8605        this.$el = this._fragmentStart = el.firstChild;
  8606        this._fragmentEnd = el.lastChild;
  8607        // set persisted text anchors to empty
  8608        if (this._fragmentStart.nodeType === 3) {
  8609          this._fragmentStart.data = this._fragmentEnd.data = '';
  8610        }
  8611        this._fragment = el;
  8612      } else {
  8613        this.$el = el;
  8614      }
  8615      this.$el.__vue__ = this;
  8616      this._callHook('beforeCompile');
  8617    };
  8618  
  8619    /**
  8620     * Create and bind a directive to an element.
  8621     *
  8622     * @param {Object} descriptor - parsed directive descriptor
  8623     * @param {Node} node   - target node
  8624     * @param {Vue} [host] - transclusion host component
  8625     * @param {Object} [scope] - v-for scope
  8626     * @param {Fragment} [frag] - owner fragment
  8627     */
  8628  
  8629    Vue.prototype._bindDir = function (descriptor, node, host, scope, frag) {
  8630      this._directives.push(new Directive(descriptor, this, node, host, scope, frag));
  8631    };
  8632  
  8633    /**
  8634     * Teardown an instance, unobserves the data, unbind all the
  8635     * directives, turn off all the event listeners, etc.
  8636     *
  8637     * @param {Boolean} remove - whether to remove the DOM node.
  8638     * @param {Boolean} deferCleanup - if true, defer cleanup to
  8639     *                                 be called later
  8640     */
  8641  
  8642    Vue.prototype._destroy = function (remove, deferCleanup) {
  8643      if (this._isBeingDestroyed) {
  8644        if (!deferCleanup) {
  8645          this._cleanup();
  8646        }
  8647        return;
  8648      }
  8649  
  8650      var destroyReady;
  8651      var pendingRemoval;
  8652  
  8653      var self = this;
  8654      // Cleanup should be called either synchronously or asynchronoysly as
  8655      // callback of this.$remove(), or if remove and deferCleanup are false.
  8656      // In any case it should be called after all other removing, unbinding and
  8657      // turning of is done
  8658      var cleanupIfPossible = function cleanupIfPossible() {
  8659        if (destroyReady && !pendingRemoval && !deferCleanup) {
  8660          self._cleanup();
  8661        }
  8662      };
  8663  
  8664      // remove DOM element
  8665      if (remove && this.$el) {
  8666        pendingRemoval = true;
  8667        this.$remove(function () {
  8668          pendingRemoval = false;
  8669          cleanupIfPossible();
  8670        });
  8671      }
  8672  
  8673      this._callHook('beforeDestroy');
  8674      this._isBeingDestroyed = true;
  8675      var i;
  8676      // remove self from parent. only necessary
  8677      // if parent is not being destroyed as well.
  8678      var parent = this.$parent;
  8679      if (parent && !parent._isBeingDestroyed) {
  8680        parent.$children.$remove(this);
  8681        // unregister ref (remove: true)
  8682        this._updateRef(true);
  8683      }
  8684      // destroy all children.
  8685      i = this.$children.length;
  8686      while (i--) {
  8687        this.$children[i].$destroy();
  8688      }
  8689      // teardown props
  8690      if (this._propsUnlinkFn) {
  8691        this._propsUnlinkFn();
  8692      }
  8693      // teardown all directives. this also tearsdown all
  8694      // directive-owned watchers.
  8695      if (this._unlinkFn) {
  8696        this._unlinkFn();
  8697      }
  8698      i = this._watchers.length;
  8699      while (i--) {
  8700        this._watchers[i].teardown();
  8701      }
  8702      // remove reference to self on $el
  8703      if (this.$el) {
  8704        this.$el.__vue__ = null;
  8705      }
  8706  
  8707      destroyReady = true;
  8708      cleanupIfPossible();
  8709    };
  8710  
  8711    /**
  8712     * Clean up to ensure garbage collection.
  8713     * This is called after the leave transition if there
  8714     * is any.
  8715     */
  8716  
  8717    Vue.prototype._cleanup = function () {
  8718      if (this._isDestroyed) {
  8719        return;
  8720      }
  8721      // remove self from owner fragment
  8722      // do it in cleanup so that we can call $destroy with
  8723      // defer right when a fragment is about to be removed.
  8724      if (this._frag) {
  8725        this._frag.children.$remove(this);
  8726      }
  8727      // remove reference from data ob
  8728      // frozen object may not have observer.
  8729      if (this._data && this._data.__ob__) {
  8730        this._data.__ob__.removeVm(this);
  8731      }
  8732      // Clean up references to private properties and other
  8733      // instances. preserve reference to _data so that proxy
  8734      // accessors still work. The only potential side effect
  8735      // here is that mutating the instance after it's destroyed
  8736      // may affect the state of other components that are still
  8737      // observing the same object, but that seems to be a
  8738      // reasonable responsibility for the user rather than
  8739      // always throwing an error on them.
  8740      this.$el = this.$parent = this.$root = this.$children = this._watchers = this._context = this._scope = this._directives = null;
  8741      // call the last hook...
  8742      this._isDestroyed = true;
  8743      this._callHook('destroyed');
  8744      // turn off all instance listeners.
  8745      this.$off();
  8746    };
  8747  }
  8748  
  8749  function miscMixin (Vue) {
  8750    /**
  8751     * Apply a list of filter (descriptors) to a value.
  8752     * Using plain for loops here because this will be called in
  8753     * the getter of any watcher with filters so it is very
  8754     * performance sensitive.
  8755     *
  8756     * @param {*} value
  8757     * @param {*} [oldValue]
  8758     * @param {Array} filters
  8759     * @param {Boolean} write
  8760     * @return {*}
  8761     */
  8762  
  8763    Vue.prototype._applyFilters = function (value, oldValue, filters, write) {
  8764      var filter, fn, args, arg, offset, i, l, j, k;
  8765      for (i = 0, l = filters.length; i < l; i++) {
  8766        filter = filters[write ? l - i - 1 : i];
  8767        fn = resolveAsset(this.$options, 'filters', filter.name, true);
  8768        if (!fn) continue;
  8769        fn = write ? fn.write : fn.read || fn;
  8770        if (typeof fn !== 'function') continue;
  8771        args = write ? [value, oldValue] : [value];
  8772        offset = write ? 2 : 1;
  8773        if (filter.args) {
  8774          for (j = 0, k = filter.args.length; j < k; j++) {
  8775            arg = filter.args[j];
  8776            args[j + offset] = arg.dynamic ? this.$get(arg.value) : arg.value;
  8777          }
  8778        }
  8779        value = fn.apply(this, args);
  8780      }
  8781      return value;
  8782    };
  8783  
  8784    /**
  8785     * Resolve a component, depending on whether the component
  8786     * is defined normally or using an async factory function.
  8787     * Resolves synchronously if already resolved, otherwise
  8788     * resolves asynchronously and caches the resolved
  8789     * constructor on the factory.
  8790     *
  8791     * @param {String|Function} value
  8792     * @param {Function} cb
  8793     */
  8794  
  8795    Vue.prototype._resolveComponent = function (value, cb) {
  8796      var factory;
  8797      if (typeof value === 'function') {
  8798        factory = value;
  8799      } else {
  8800        factory = resolveAsset(this.$options, 'components', value, true);
  8801      }
  8802      /* istanbul ignore if */
  8803      if (!factory) {
  8804        return;
  8805      }
  8806      // async component factory
  8807      if (!factory.options) {
  8808        if (factory.resolved) {
  8809          // cached
  8810          cb(factory.resolved);
  8811        } else if (factory.requested) {
  8812          // pool callbacks
  8813          factory.pendingCallbacks.push(cb);
  8814        } else {
  8815          factory.requested = true;
  8816          var cbs = factory.pendingCallbacks = [cb];
  8817          factory.call(this, function resolve(res) {
  8818            if (isPlainObject(res)) {
  8819              res = Vue.extend(res);
  8820            }
  8821            // cache resolved
  8822            factory.resolved = res;
  8823            // invoke callbacks
  8824            for (var i = 0, l = cbs.length; i < l; i++) {
  8825              cbs[i](res);
  8826            }
  8827          }, function reject(reason) {
  8828            process.env.NODE_ENV !== 'production' && warn('Failed to resolve async component' + (typeof value === 'string' ? ': ' + value : '') + '. ' + (reason ? '\nReason: ' + reason : ''));
  8829          });
  8830        }
  8831      } else {
  8832        // normal component
  8833        cb(factory);
  8834      }
  8835    };
  8836  }
  8837  
  8838  var filterRE$1 = /[^|]\|[^|]/;
  8839  
  8840  function dataAPI (Vue) {
  8841    /**
  8842     * Get the value from an expression on this vm.
  8843     *
  8844     * @param {String} exp
  8845     * @param {Boolean} [asStatement]
  8846     * @return {*}
  8847     */
  8848  
  8849    Vue.prototype.$get = function (exp, asStatement) {
  8850      var res = parseExpression(exp);
  8851      if (res) {
  8852        if (asStatement) {
  8853          var self = this;
  8854          return function statementHandler() {
  8855            self.$arguments = toArray(arguments);
  8856            var result = res.get.call(self, self);
  8857            self.$arguments = null;
  8858            return result;
  8859          };
  8860        } else {
  8861          try {
  8862            return res.get.call(this, this);
  8863          } catch (e) {}
  8864        }
  8865      }
  8866    };
  8867  
  8868    /**
  8869     * Set the value from an expression on this vm.
  8870     * The expression must be a valid left-hand
  8871     * expression in an assignment.
  8872     *
  8873     * @param {String} exp
  8874     * @param {*} val
  8875     */
  8876  
  8877    Vue.prototype.$set = function (exp, val) {
  8878      var res = parseExpression(exp, true);
  8879      if (res && res.set) {
  8880        res.set.call(this, this, val);
  8881      }
  8882    };
  8883  
  8884    /**
  8885     * Delete a property on the VM
  8886     *
  8887     * @param {String} key
  8888     */
  8889  
  8890    Vue.prototype.$delete = function (key) {
  8891      del(this._data, key);
  8892    };
  8893  
  8894    /**
  8895     * Watch an expression, trigger callback when its
  8896     * value changes.
  8897     *
  8898     * @param {String|Function} expOrFn
  8899     * @param {Function} cb
  8900     * @param {Object} [options]
  8901     *                 - {Boolean} deep
  8902     *                 - {Boolean} immediate
  8903     * @return {Function} - unwatchFn
  8904     */
  8905  
  8906    Vue.prototype.$watch = function (expOrFn, cb, options) {
  8907      var vm = this;
  8908      var parsed;
  8909      if (typeof expOrFn === 'string') {
  8910        parsed = parseDirective(expOrFn);
  8911        expOrFn = parsed.expression;
  8912      }
  8913      var watcher = new Watcher(vm, expOrFn, cb, {
  8914        deep: options && options.deep,
  8915        sync: options && options.sync,
  8916        filters: parsed && parsed.filters,
  8917        user: !options || options.user !== false
  8918      });
  8919      if (options && options.immediate) {
  8920        cb.call(vm, watcher.value);
  8921      }
  8922      return function unwatchFn() {
  8923        watcher.teardown();
  8924      };
  8925    };
  8926  
  8927    /**
  8928     * Evaluate a text directive, including filters.
  8929     *
  8930     * @param {String} text
  8931     * @param {Boolean} [asStatement]
  8932     * @return {String}
  8933     */
  8934  
  8935    Vue.prototype.$eval = function (text, asStatement) {
  8936      // check for filters.
  8937      if (filterRE$1.test(text)) {
  8938        var dir = parseDirective(text);
  8939        // the filter regex check might give false positive
  8940        // for pipes inside strings, so it's possible that
  8941        // we don't get any filters here
  8942        var val = this.$get(dir.expression, asStatement);
  8943        return dir.filters ? this._applyFilters(val, null, dir.filters) : val;
  8944      } else {
  8945        // no filter
  8946        return this.$get(text, asStatement);
  8947      }
  8948    };
  8949  
  8950    /**
  8951     * Interpolate a piece of template text.
  8952     *
  8953     * @param {String} text
  8954     * @return {String}
  8955     */
  8956  
  8957    Vue.prototype.$interpolate = function (text) {
  8958      var tokens = parseText(text);
  8959      var vm = this;
  8960      if (tokens) {
  8961        if (tokens.length === 1) {
  8962          return vm.$eval(tokens[0].value) + '';
  8963        } else {
  8964          return tokens.map(function (token) {
  8965            return token.tag ? vm.$eval(token.value) : token.value;
  8966          }).join('');
  8967        }
  8968      } else {
  8969        return text;
  8970      }
  8971    };
  8972  
  8973    /**
  8974     * Log instance data as a plain JS object
  8975     * so that it is easier to inspect in console.
  8976     * This method assumes console is available.
  8977     *
  8978     * @param {String} [path]
  8979     */
  8980  
  8981    Vue.prototype.$log = function (path) {
  8982      var data = path ? getPath(this._data, path) : this._data;
  8983      if (data) {
  8984        data = clean(data);
  8985      }
  8986      // include computed fields
  8987      if (!path) {
  8988        var key;
  8989        for (key in this.$options.computed) {
  8990          data[key] = clean(this[key]);
  8991        }
  8992        if (this._props) {
  8993          for (key in this._props) {
  8994            data[key] = clean(this[key]);
  8995          }
  8996        }
  8997      }
  8998      console.log(data);
  8999    };
  9000  
  9001    /**
  9002     * "clean" a getter/setter converted object into a plain
  9003     * object copy.
  9004     *
  9005     * @param {Object} - obj
  9006     * @return {Object}
  9007     */
  9008  
  9009    function clean(obj) {
  9010      return JSON.parse(JSON.stringify(obj));
  9011    }
  9012  }
  9013  
  9014  function domAPI (Vue) {
  9015    /**
  9016     * Convenience on-instance nextTick. The callback is
  9017     * auto-bound to the instance, and this avoids component
  9018     * modules having to rely on the global Vue.
  9019     *
  9020     * @param {Function} fn
  9021     */
  9022  
  9023    Vue.prototype.$nextTick = function (fn) {
  9024      nextTick(fn, this);
  9025    };
  9026  
  9027    /**
  9028     * Append instance to target
  9029     *
  9030     * @param {Node} target
  9031     * @param {Function} [cb]
  9032     * @param {Boolean} [withTransition] - defaults to true
  9033     */
  9034  
  9035    Vue.prototype.$appendTo = function (target, cb, withTransition) {
  9036      return insert(this, target, cb, withTransition, append, appendWithTransition);
  9037    };
  9038  
  9039    /**
  9040     * Prepend instance to target
  9041     *
  9042     * @param {Node} target
  9043     * @param {Function} [cb]
  9044     * @param {Boolean} [withTransition] - defaults to true
  9045     */
  9046  
  9047    Vue.prototype.$prependTo = function (target, cb, withTransition) {
  9048      target = query(target);
  9049      if (target.hasChildNodes()) {
  9050        this.$before(target.firstChild, cb, withTransition);
  9051      } else {
  9052        this.$appendTo(target, cb, withTransition);
  9053      }
  9054      return this;
  9055    };
  9056  
  9057    /**
  9058     * Insert instance before target
  9059     *
  9060     * @param {Node} target
  9061     * @param {Function} [cb]
  9062     * @param {Boolean} [withTransition] - defaults to true
  9063     */
  9064  
  9065    Vue.prototype.$before = function (target, cb, withTransition) {
  9066      return insert(this, target, cb, withTransition, beforeWithCb, beforeWithTransition);
  9067    };
  9068  
  9069    /**
  9070     * Insert instance after target
  9071     *
  9072     * @param {Node} target
  9073     * @param {Function} [cb]
  9074     * @param {Boolean} [withTransition] - defaults to true
  9075     */
  9076  
  9077    Vue.prototype.$after = function (target, cb, withTransition) {
  9078      target = query(target);
  9079      if (target.nextSibling) {
  9080        this.$before(target.nextSibling, cb, withTransition);
  9081      } else {
  9082        this.$appendTo(target.parentNode, cb, withTransition);
  9083      }
  9084      return this;
  9085    };
  9086  
  9087    /**
  9088     * Remove instance from DOM
  9089     *
  9090     * @param {Function} [cb]
  9091     * @param {Boolean} [withTransition] - defaults to true
  9092     */
  9093  
  9094    Vue.prototype.$remove = function (cb, withTransition) {
  9095      if (!this.$el.parentNode) {
  9096        return cb && cb();
  9097      }
  9098      var inDocument = this._isAttached && inDoc(this.$el);
  9099      // if we are not in document, no need to check
  9100      // for transitions
  9101      if (!inDocument) withTransition = false;
  9102      var self = this;
  9103      var realCb = function realCb() {
  9104        if (inDocument) self._callHook('detached');
  9105        if (cb) cb();
  9106      };
  9107      if (this._isFragment) {
  9108        removeNodeRange(this._fragmentStart, this._fragmentEnd, this, this._fragment, realCb);
  9109      } else {
  9110        var op = withTransition === false ? removeWithCb : removeWithTransition;
  9111        op(this.$el, this, realCb);
  9112      }
  9113      return this;
  9114    };
  9115  
  9116    /**
  9117     * Shared DOM insertion function.
  9118     *
  9119     * @param {Vue} vm
  9120     * @param {Element} target
  9121     * @param {Function} [cb]
  9122     * @param {Boolean} [withTransition]
  9123     * @param {Function} op1 - op for non-transition insert
  9124     * @param {Function} op2 - op for transition insert
  9125     * @return vm
  9126     */
  9127  
  9128    function insert(vm, target, cb, withTransition, op1, op2) {
  9129      target = query(target);
  9130      var targetIsDetached = !inDoc(target);
  9131      var op = withTransition === false || targetIsDetached ? op1 : op2;
  9132      var shouldCallHook = !targetIsDetached && !vm._isAttached && !inDoc(vm.$el);
  9133      if (vm._isFragment) {
  9134        mapNodeRange(vm._fragmentStart, vm._fragmentEnd, function (node) {
  9135          op(node, target, vm);
  9136        });
  9137        cb && cb();
  9138      } else {
  9139        op(vm.$el, target, vm, cb);
  9140      }
  9141      if (shouldCallHook) {
  9142        vm._callHook('attached');
  9143      }
  9144      return vm;
  9145    }
  9146  
  9147    /**
  9148     * Check for selectors
  9149     *
  9150     * @param {String|Element} el
  9151     */
  9152  
  9153    function query(el) {
  9154      return typeof el === 'string' ? document.querySelector(el) : el;
  9155    }
  9156  
  9157    /**
  9158     * Append operation that takes a callback.
  9159     *
  9160     * @param {Node} el
  9161     * @param {Node} target
  9162     * @param {Vue} vm - unused
  9163     * @param {Function} [cb]
  9164     */
  9165  
  9166    function append(el, target, vm, cb) {
  9167      target.appendChild(el);
  9168      if (cb) cb();
  9169    }
  9170  
  9171    /**
  9172     * InsertBefore operation that takes a callback.
  9173     *
  9174     * @param {Node} el
  9175     * @param {Node} target
  9176     * @param {Vue} vm - unused
  9177     * @param {Function} [cb]
  9178     */
  9179  
  9180    function beforeWithCb(el, target, vm, cb) {
  9181      before(el, target);
  9182      if (cb) cb();
  9183    }
  9184  
  9185    /**
  9186     * Remove operation that takes a callback.
  9187     *
  9188     * @param {Node} el
  9189     * @param {Vue} vm - unused
  9190     * @param {Function} [cb]
  9191     */
  9192  
  9193    function removeWithCb(el, vm, cb) {
  9194      remove(el);
  9195      if (cb) cb();
  9196    }
  9197  }
  9198  
  9199  function eventsAPI (Vue) {
  9200    /**
  9201     * Listen on the given `event` with `fn`.
  9202     *
  9203     * @param {String} event
  9204     * @param {Function} fn
  9205     */
  9206  
  9207    Vue.prototype.$on = function (event, fn) {
  9208      (this._events[event] || (this._events[event] = [])).push(fn);
  9209      modifyListenerCount(this, event, 1);
  9210      return this;
  9211    };
  9212  
  9213    /**
  9214     * Adds an `event` listener that will be invoked a single
  9215     * time then automatically removed.
  9216     *
  9217     * @param {String} event
  9218     * @param {Function} fn
  9219     */
  9220  
  9221    Vue.prototype.$once = function (event, fn) {
  9222      var self = this;
  9223      function on() {
  9224        self.$off(event, on);
  9225        fn.apply(this, arguments);
  9226      }
  9227      on.fn = fn;
  9228      this.$on(event, on);
  9229      return this;
  9230    };
  9231  
  9232    /**
  9233     * Remove the given callback for `event` or all
  9234     * registered callbacks.
  9235     *
  9236     * @param {String} event
  9237     * @param {Function} fn
  9238     */
  9239  
  9240    Vue.prototype.$off = function (event, fn) {
  9241      var cbs;
  9242      // all
  9243      if (!arguments.length) {
  9244        if (this.$parent) {
  9245          for (event in this._events) {
  9246            cbs = this._events[event];
  9247            if (cbs) {
  9248              modifyListenerCount(this, event, -cbs.length);
  9249            }
  9250          }
  9251        }
  9252        this._events = {};
  9253        return this;
  9254      }
  9255      // specific event
  9256      cbs = this._events[event];
  9257      if (!cbs) {
  9258        return this;
  9259      }
  9260      if (arguments.length === 1) {
  9261        modifyListenerCount(this, event, -cbs.length);
  9262        this._events[event] = null;
  9263        return this;
  9264      }
  9265      // specific handler
  9266      var cb;
  9267      var i = cbs.length;
  9268      while (i--) {
  9269        cb = cbs[i];
  9270        if (cb === fn || cb.fn === fn) {
  9271          modifyListenerCount(this, event, -1);
  9272          cbs.splice(i, 1);
  9273          break;
  9274        }
  9275      }
  9276      return this;
  9277    };
  9278  
  9279    /**
  9280     * Trigger an event on self.
  9281     *
  9282     * @param {String|Object} event
  9283     * @return {Boolean} shouldPropagate
  9284     */
  9285  
  9286    Vue.prototype.$emit = function (event) {
  9287      var isSource = typeof event === 'string';
  9288      event = isSource ? event : event.name;
  9289      var cbs = this._events[event];
  9290      var shouldPropagate = isSource || !cbs;
  9291      if (cbs) {
  9292        cbs = cbs.length > 1 ? toArray(cbs) : cbs;
  9293        // this is a somewhat hacky solution to the question raised
  9294        // in #2102: for an inline component listener like <comp @test="doThis">,
  9295        // the propagation handling is somewhat broken. Therefore we
  9296        // need to treat these inline callbacks differently.
  9297        var hasParentCbs = isSource && cbs.some(function (cb) {
  9298          return cb._fromParent;
  9299        });
  9300        if (hasParentCbs) {
  9301          shouldPropagate = false;
  9302        }
  9303        var args = toArray(arguments, 1);
  9304        for (var i = 0, l = cbs.length; i < l; i++) {
  9305          var cb = cbs[i];
  9306          var res = cb.apply(this, args);
  9307          if (res === true && (!hasParentCbs || cb._fromParent)) {
  9308            shouldPropagate = true;
  9309          }
  9310        }
  9311      }
  9312      return shouldPropagate;
  9313    };
  9314  
  9315    /**
  9316     * Recursively broadcast an event to all children instances.
  9317     *
  9318     * @param {String|Object} event
  9319     * @param {...*} additional arguments
  9320     */
  9321  
  9322    Vue.prototype.$broadcast = function (event) {
  9323      var isSource = typeof event === 'string';
  9324      event = isSource ? event : event.name;
  9325      // if no child has registered for this event,
  9326      // then there's no need to broadcast.
  9327      if (!this._eventsCount[event]) return;
  9328      var children = this.$children;
  9329      var args = toArray(arguments);
  9330      if (isSource) {
  9331        // use object event to indicate non-source emit
  9332        // on children
  9333        args[0] = { name: event, source: this };
  9334      }
  9335      for (var i = 0, l = children.length; i < l; i++) {
  9336        var child = children[i];
  9337        var shouldPropagate = child.$emit.apply(child, args);
  9338        if (shouldPropagate) {
  9339          child.$broadcast.apply(child, args);
  9340        }
  9341      }
  9342      return this;
  9343    };
  9344  
  9345    /**
  9346     * Recursively propagate an event up the parent chain.
  9347     *
  9348     * @param {String} event
  9349     * @param {...*} additional arguments
  9350     */
  9351  
  9352    Vue.prototype.$dispatch = function (event) {
  9353      var shouldPropagate = this.$emit.apply(this, arguments);
  9354      if (!shouldPropagate) return;
  9355      var parent = this.$parent;
  9356      var args = toArray(arguments);
  9357      // use object event to indicate non-source emit
  9358      // on parents
  9359      args[0] = { name: event, source: this };
  9360      while (parent) {
  9361        shouldPropagate = parent.$emit.apply(parent, args);
  9362        parent = shouldPropagate ? parent.$parent : null;
  9363      }
  9364      return this;
  9365    };
  9366  
  9367    /**
  9368     * Modify the listener counts on all parents.
  9369     * This bookkeeping allows $broadcast to return early when
  9370     * no child has listened to a certain event.
  9371     *
  9372     * @param {Vue} vm
  9373     * @param {String} event
  9374     * @param {Number} count
  9375     */
  9376  
  9377    var hookRE = /^hook:/;
  9378    function modifyListenerCount(vm, event, count) {
  9379      var parent = vm.$parent;
  9380      // hooks do not get broadcasted so no need
  9381      // to do bookkeeping for them
  9382      if (!parent || !count || hookRE.test(event)) return;
  9383      while (parent) {
  9384        parent._eventsCount[event] = (parent._eventsCount[event] || 0) + count;
  9385        parent = parent.$parent;
  9386      }
  9387    }
  9388  }
  9389  
  9390  function lifecycleAPI (Vue) {
  9391    /**
  9392     * Set instance target element and kick off the compilation
  9393     * process. The passed in `el` can be a selector string, an
  9394     * existing Element, or a DocumentFragment (for block
  9395     * instances).
  9396     *
  9397     * @param {Element|DocumentFragment|string} el
  9398     * @public
  9399     */
  9400  
  9401    Vue.prototype.$mount = function (el) {
  9402      if (this._isCompiled) {
  9403        process.env.NODE_ENV !== 'production' && warn('$mount() should be called only once.', this);
  9404        return;
  9405      }
  9406      el = query(el);
  9407      if (!el) {
  9408        el = document.createElement('div');
  9409      }
  9410      this._compile(el);
  9411      this._initDOMHooks();
  9412      if (inDoc(this.$el)) {
  9413        this._callHook('attached');
  9414        ready.call(this);
  9415      } else {
  9416        this.$once('hook:attached', ready);
  9417      }
  9418      return this;
  9419    };
  9420  
  9421    /**
  9422     * Mark an instance as ready.
  9423     */
  9424  
  9425    function ready() {
  9426      this._isAttached = true;
  9427      this._isReady = true;
  9428      this._callHook('ready');
  9429    }
  9430  
  9431    /**
  9432     * Teardown the instance, simply delegate to the internal
  9433     * _destroy.
  9434     *
  9435     * @param {Boolean} remove
  9436     * @param {Boolean} deferCleanup
  9437     */
  9438  
  9439    Vue.prototype.$destroy = function (remove, deferCleanup) {
  9440      this._destroy(remove, deferCleanup);
  9441    };
  9442  
  9443    /**
  9444     * Partially compile a piece of DOM and return a
  9445     * decompile function.
  9446     *
  9447     * @param {Element|DocumentFragment} el
  9448     * @param {Vue} [host]
  9449     * @param {Object} [scope]
  9450     * @param {Fragment} [frag]
  9451     * @return {Function}
  9452     */
  9453  
  9454    Vue.prototype.$compile = function (el, host, scope, frag) {
  9455      return compile(el, this.$options, true)(this, el, host, scope, frag);
  9456    };
  9457  }
  9458  
  9459  /**
  9460   * The exposed Vue constructor.
  9461   *
  9462   * API conventions:
  9463   * - public API methods/properties are prefixed with `$`
  9464   * - internal methods/properties are prefixed with `_`
  9465   * - non-prefixed properties are assumed to be proxied user
  9466   *   data.
  9467   *
  9468   * @constructor
  9469   * @param {Object} [options]
  9470   * @public
  9471   */
  9472  
  9473  function Vue(options) {
  9474    this._init(options);
  9475  }
  9476  
  9477  // install internals
  9478  initMixin(Vue);
  9479  stateMixin(Vue);
  9480  eventsMixin(Vue);
  9481  lifecycleMixin(Vue);
  9482  miscMixin(Vue);
  9483  
  9484  // install instance APIs
  9485  dataAPI(Vue);
  9486  domAPI(Vue);
  9487  eventsAPI(Vue);
  9488  lifecycleAPI(Vue);
  9489  
  9490  var slot = {
  9491  
  9492    priority: SLOT,
  9493    params: ['name'],
  9494  
  9495    bind: function bind() {
  9496      // this was resolved during component transclusion
  9497      var name = this.params.name || 'default';
  9498      var content = this.vm._slotContents && this.vm._slotContents[name];
  9499      if (!content || !content.hasChildNodes()) {
  9500        this.fallback();
  9501      } else {
  9502        this.compile(content.cloneNode(true), this.vm._context, this.vm);
  9503      }
  9504    },
  9505  
  9506    compile: function compile(content, context, host) {
  9507      if (content && context) {
  9508        if (this.el.hasChildNodes() && content.childNodes.length === 1 && content.childNodes[0].nodeType === 1 && content.childNodes[0].hasAttribute('v-if')) {
  9509          // if the inserted slot has v-if
  9510          // inject fallback content as the v-else
  9511          var elseBlock = document.createElement('template');
  9512          elseBlock.setAttribute('v-else', '');
  9513          elseBlock.innerHTML = this.el.innerHTML;
  9514          // the else block should be compiled in child scope
  9515          elseBlock._context = this.vm;
  9516          content.appendChild(elseBlock);
  9517        }
  9518        var scope = host ? host._scope : this._scope;
  9519        this.unlink = context.$compile(content, host, scope, this._frag);
  9520      }
  9521      if (content) {
  9522        replace(this.el, content);
  9523      } else {
  9524        remove(this.el);
  9525      }
  9526    },
  9527  
  9528    fallback: function fallback() {
  9529      this.compile(extractContent(this.el, true), this.vm);
  9530    },
  9531  
  9532    unbind: function unbind() {
  9533      if (this.unlink) {
  9534        this.unlink();
  9535      }
  9536    }
  9537  };
  9538  
  9539  var partial = {
  9540  
  9541    priority: PARTIAL,
  9542  
  9543    params: ['name'],
  9544  
  9545    // watch changes to name for dynamic partials
  9546    paramWatchers: {
  9547      name: function name(value) {
  9548        vIf.remove.call(this);
  9549        if (value) {
  9550          this.insert(value);
  9551        }
  9552      }
  9553    },
  9554  
  9555    bind: function bind() {
  9556      this.anchor = createAnchor('v-partial');
  9557      replace(this.el, this.anchor);
  9558      this.insert(this.params.name);
  9559    },
  9560  
  9561    insert: function insert(id) {
  9562      var partial = resolveAsset(this.vm.$options, 'partials', id, true);
  9563      if (partial) {
  9564        this.factory = new FragmentFactory(this.vm, partial);
  9565        vIf.insert.call(this);
  9566      }
  9567    },
  9568  
  9569    unbind: function unbind() {
  9570      if (this.frag) {
  9571        this.frag.destroy();
  9572      }
  9573    }
  9574  };
  9575  
  9576  var elementDirectives = {
  9577    slot: slot,
  9578    partial: partial
  9579  };
  9580  
  9581  var convertArray = vFor._postProcess;
  9582  
  9583  /**
  9584   * Limit filter for arrays
  9585   *
  9586   * @param {Number} n
  9587   * @param {Number} offset (Decimal expected)
  9588   */
  9589  
  9590  function limitBy(arr, n, offset) {
  9591    offset = offset ? parseInt(offset, 10) : 0;
  9592    n = toNumber(n);
  9593    return typeof n === 'number' ? arr.slice(offset, offset + n) : arr;
  9594  }
  9595  
  9596  /**
  9597   * Filter filter for arrays
  9598   *
  9599   * @param {String} search
  9600   * @param {String} [delimiter]
  9601   * @param {String} ...dataKeys
  9602   */
  9603  
  9604  function filterBy(arr, search, delimiter) {
  9605    arr = convertArray(arr);
  9606    if (search == null) {
  9607      return arr;
  9608    }
  9609    if (typeof search === 'function') {
  9610      return arr.filter(search);
  9611    }
  9612    // cast to lowercase string
  9613    search = ('' + search).toLowerCase();
  9614    // allow optional `in` delimiter
  9615    // because why not
  9616    var n = delimiter === 'in' ? 3 : 2;
  9617    // extract and flatten keys
  9618    var keys = Array.prototype.concat.apply([], toArray(arguments, n));
  9619    var res = [];
  9620    var item, key, val, j;
  9621    for (var i = 0, l = arr.length; i < l; i++) {
  9622      item = arr[i];
  9623      val = item && item.$value || item;
  9624      j = keys.length;
  9625      if (j) {
  9626        while (j--) {
  9627          key = keys[j];
  9628          if (key === '$key' && contains(item.$key, search) || contains(getPath(val, key), search)) {
  9629            res.push(item);
  9630            break;
  9631          }
  9632        }
  9633      } else if (contains(item, search)) {
  9634        res.push(item);
  9635      }
  9636    }
  9637    return res;
  9638  }
  9639  
  9640  /**
  9641   * Filter filter for arrays
  9642   *
  9643   * @param {String|Array<String>|Function} ...sortKeys
  9644   * @param {Number} [order]
  9645   */
  9646  
  9647  function orderBy(arr) {
  9648    var comparator = null;
  9649    var sortKeys = undefined;
  9650    arr = convertArray(arr);
  9651  
  9652    // determine order (last argument)
  9653    var args = toArray(arguments, 1);
  9654    var order = args[args.length - 1];
  9655    if (typeof order === 'number') {
  9656      order = order < 0 ? -1 : 1;
  9657      args = args.length > 1 ? args.slice(0, -1) : args;
  9658    } else {
  9659      order = 1;
  9660    }
  9661  
  9662    // determine sortKeys & comparator
  9663    var firstArg = args[0];
  9664    if (!firstArg) {
  9665      return arr;
  9666    } else if (typeof firstArg === 'function') {
  9667      // custom comparator
  9668      comparator = function (a, b) {
  9669        return firstArg(a, b) * order;
  9670      };
  9671    } else {
  9672      // string keys. flatten first
  9673      sortKeys = Array.prototype.concat.apply([], args);
  9674      comparator = function (a, b, i) {
  9675        i = i || 0;
  9676        return i >= sortKeys.length - 1 ? baseCompare(a, b, i) : baseCompare(a, b, i) || comparator(a, b, i + 1);
  9677      };
  9678    }
  9679  
  9680    function baseCompare(a, b, sortKeyIndex) {
  9681      var sortKey = sortKeys[sortKeyIndex];
  9682      if (sortKey) {
  9683        if (sortKey !== '$key') {
  9684          if (isObject(a) && '$value' in a) a = a.$value;
  9685          if (isObject(b) && '$value' in b) b = b.$value;
  9686        }
  9687        a = isObject(a) ? getPath(a, sortKey) : a;
  9688        b = isObject(b) ? getPath(b, sortKey) : b;
  9689      }
  9690      return a === b ? 0 : a > b ? order : -order;
  9691    }
  9692  
  9693    // sort on a copy to avoid mutating original array
  9694    return arr.slice().sort(comparator);
  9695  }
  9696  
  9697  /**
  9698   * String contain helper
  9699   *
  9700   * @param {*} val
  9701   * @param {String} search
  9702   */
  9703  
  9704  function contains(val, search) {
  9705    var i;
  9706    if (isPlainObject(val)) {
  9707      var keys = Object.keys(val);
  9708      i = keys.length;
  9709      while (i--) {
  9710        if (contains(val[keys[i]], search)) {
  9711          return true;
  9712        }
  9713      }
  9714    } else if (isArray(val)) {
  9715      i = val.length;
  9716      while (i--) {
  9717        if (contains(val[i], search)) {
  9718          return true;
  9719        }
  9720      }
  9721    } else if (val != null) {
  9722      return val.toString().toLowerCase().indexOf(search) > -1;
  9723    }
  9724  }
  9725  
  9726  var digitsRE = /(\d{3})(?=\d)/g;
  9727  
  9728  // asset collections must be a plain object.
  9729  var filters = {
  9730  
  9731    orderBy: orderBy,
  9732    filterBy: filterBy,
  9733    limitBy: limitBy,
  9734  
  9735    /**
  9736     * Stringify value.
  9737     *
  9738     * @param {Number} indent
  9739     */
  9740  
  9741    json: {
  9742      read: function read(value, indent) {
  9743        return typeof value === 'string' ? value : JSON.stringify(value, null, Number(indent) || 2);
  9744      },
  9745      write: function write(value) {
  9746        try {
  9747          return JSON.parse(value);
  9748        } catch (e) {
  9749          return value;
  9750        }
  9751      }
  9752    },
  9753  
  9754    /**
  9755     * 'abc' => 'Abc'
  9756     */
  9757  
  9758    capitalize: function capitalize(value) {
  9759      if (!value && value !== 0) return '';
  9760      value = value.toString();
  9761      return value.charAt(0).toUpperCase() + value.slice(1);
  9762    },
  9763  
  9764    /**
  9765     * 'abc' => 'ABC'
  9766     */
  9767  
  9768    uppercase: function uppercase(value) {
  9769      return value || value === 0 ? value.toString().toUpperCase() : '';
  9770    },
  9771  
  9772    /**
  9773     * 'AbC' => 'abc'
  9774     */
  9775  
  9776    lowercase: function lowercase(value) {
  9777      return value || value === 0 ? value.toString().toLowerCase() : '';
  9778    },
  9779  
  9780    /**
  9781     * 12345 => $12,345.00
  9782     *
  9783     * @param {String} sign
  9784     * @param {Number} decimals Decimal places
  9785     */
  9786  
  9787    currency: function currency(value, _currency, decimals) {
  9788      value = parseFloat(value);
  9789      if (!isFinite(value) || !value && value !== 0) return '';
  9790      _currency = _currency != null ? _currency : '$';
  9791      decimals = decimals != null ? decimals : 2;
  9792      var stringified = Math.abs(value).toFixed(decimals);
  9793      var _int = decimals ? stringified.slice(0, -1 - decimals) : stringified;
  9794      var i = _int.length % 3;
  9795      var head = i > 0 ? _int.slice(0, i) + (_int.length > 3 ? ',' : '') : '';
  9796      var _float = decimals ? stringified.slice(-1 - decimals) : '';
  9797      var sign = value < 0 ? '-' : '';
  9798      return sign + _currency + head + _int.slice(i).replace(digitsRE, '$1,') + _float;
  9799    },
  9800  
  9801    /**
  9802     * 'item' => 'items'
  9803     *
  9804     * @params
  9805     *  an array of strings corresponding to
  9806     *  the single, double, triple ... forms of the word to
  9807     *  be pluralized. When the number to be pluralized
  9808     *  exceeds the length of the args, it will use the last
  9809     *  entry in the array.
  9810     *
  9811     *  e.g. ['single', 'double', 'triple', 'multiple']
  9812     */
  9813  
  9814    pluralize: function pluralize(value) {
  9815      var args = toArray(arguments, 1);
  9816      return args.length > 1 ? args[value % 10 - 1] || args[args.length - 1] : args[0] + (value === 1 ? '' : 's');
  9817    },
  9818  
  9819    /**
  9820     * Debounce a handler function.
  9821     *
  9822     * @param {Function} handler
  9823     * @param {Number} delay = 300
  9824     * @return {Function}
  9825     */
  9826  
  9827    debounce: function debounce(handler, delay) {
  9828      if (!handler) return;
  9829      if (!delay) {
  9830        delay = 300;
  9831      }
  9832      return _debounce(handler, delay);
  9833    }
  9834  };
  9835  
  9836  function installGlobalAPI (Vue) {
  9837    /**
  9838     * Vue and every constructor that extends Vue has an
  9839     * associated options object, which can be accessed during
  9840     * compilation steps as `this.constructor.options`.
  9841     *
  9842     * These can be seen as the default options of every
  9843     * Vue instance.
  9844     */
  9845  
  9846    Vue.options = {
  9847      directives: directives,
  9848      elementDirectives: elementDirectives,
  9849      filters: filters,
  9850      transitions: {},
  9851      components: {},
  9852      partials: {},
  9853      replace: true
  9854    };
  9855  
  9856    /**
  9857     * Expose useful internals
  9858     */
  9859  
  9860    Vue.util = util;
  9861    Vue.config = config;
  9862    Vue.set = set;
  9863    Vue['delete'] = del;
  9864    Vue.nextTick = nextTick;
  9865  
  9866    /**
  9867     * The following are exposed for advanced usage / plugins
  9868     */
  9869  
  9870    Vue.compiler = compiler;
  9871    Vue.FragmentFactory = FragmentFactory;
  9872    Vue.internalDirectives = internalDirectives;
  9873    Vue.parsers = {
  9874      path: path,
  9875      text: text,
  9876      template: template,
  9877      directive: directive,
  9878      expression: expression
  9879    };
  9880  
  9881    /**
  9882     * Each instance constructor, including Vue, has a unique
  9883     * cid. This enables us to create wrapped "child
  9884     * constructors" for prototypal inheritance and cache them.
  9885     */
  9886  
  9887    Vue.cid = 0;
  9888    var cid = 1;
  9889  
  9890    /**
  9891     * Class inheritance
  9892     *
  9893     * @param {Object} extendOptions
  9894     */
  9895  
  9896    Vue.extend = function (extendOptions) {
  9897      extendOptions = extendOptions || {};
  9898      var Super = this;
  9899      var isFirstExtend = Super.cid === 0;
  9900      if (isFirstExtend && extendOptions._Ctor) {
  9901        return extendOptions._Ctor;
  9902      }
  9903      var name = extendOptions.name || Super.options.name;
  9904      if (process.env.NODE_ENV !== 'production') {
  9905        if (!/^[a-zA-Z][\w-]*$/.test(name)) {
  9906          warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
  9907          name = null;
  9908        }
  9909      }
  9910      var Sub = createClass(name || 'VueComponent');
  9911      Sub.prototype = Object.create(Super.prototype);
  9912      Sub.prototype.constructor = Sub;
  9913      Sub.cid = cid++;
  9914      Sub.options = mergeOptions(Super.options, extendOptions);
  9915      Sub['super'] = Super;
  9916      // allow further extension
  9917      Sub.extend = Super.extend;
  9918      // create asset registers, so extended classes
  9919      // can have their private assets too.
  9920      config._assetTypes.forEach(function (type) {
  9921        Sub[type] = Super[type];
  9922      });
  9923      // enable recursive self-lookup
  9924      if (name) {
  9925        Sub.options.components[name] = Sub;
  9926      }
  9927      // cache constructor
  9928      if (isFirstExtend) {
  9929        extendOptions._Ctor = Sub;
  9930      }
  9931      return Sub;
  9932    };
  9933  
  9934    /**
  9935     * A function that returns a sub-class constructor with the
  9936     * given name. This gives us much nicer output when
  9937     * logging instances in the console.
  9938     *
  9939     * @param {String} name
  9940     * @return {Function}
  9941     */
  9942  
  9943    function createClass(name) {
  9944      /* eslint-disable no-new-func */
  9945      return new Function('return function ' + classify(name) + ' (options) { this._init(options) }')();
  9946      /* eslint-enable no-new-func */
  9947    }
  9948  
  9949    /**
  9950     * Plugin system
  9951     *
  9952     * @param {Object} plugin
  9953     */
  9954  
  9955    Vue.use = function (plugin) {
  9956      /* istanbul ignore if */
  9957      if (plugin.installed) {
  9958        return;
  9959      }
  9960      // additional parameters
  9961      var args = toArray(arguments, 1);
  9962      args.unshift(this);
  9963      if (typeof plugin.install === 'function') {
  9964        plugin.install.apply(plugin, args);
  9965      } else {
  9966        plugin.apply(null, args);
  9967      }
  9968      plugin.installed = true;
  9969      return this;
  9970    };
  9971  
  9972    /**
  9973     * Apply a global mixin by merging it into the default
  9974     * options.
  9975     */
  9976  
  9977    Vue.mixin = function (mixin) {
  9978      Vue.options = mergeOptions(Vue.options, mixin);
  9979    };
  9980  
  9981    /**
  9982     * Create asset registration methods with the following
  9983     * signature:
  9984     *
  9985     * @param {String} id
  9986     * @param {*} definition
  9987     */
  9988  
  9989    config._assetTypes.forEach(function (type) {
  9990      Vue[type] = function (id, definition) {
  9991        if (!definition) {
  9992          return this.options[type + 's'][id];
  9993        } else {
  9994          /* istanbul ignore if */
  9995          if (process.env.NODE_ENV !== 'production') {
  9996            if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {
  9997              warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
  9998            }
  9999          }
 10000          if (type === 'component' && isPlainObject(definition)) {
 10001            definition.name = id;
 10002            definition = Vue.extend(definition);
 10003          }
 10004          this.options[type + 's'][id] = definition;
 10005          return definition;
 10006        }
 10007      };
 10008    });
 10009  
 10010    // expose internal transition API
 10011    extend(Vue.transition, transition);
 10012  }
 10013  
 10014  installGlobalAPI(Vue);
 10015  
 10016  Vue.version = '1.0.24';
 10017  
 10018  // devtools global hook
 10019  /* istanbul ignore next */
 10020  setTimeout(function () {
 10021    if (config.devtools) {
 10022      if (devtools) {
 10023        devtools.emit('init', Vue);
 10024      } else if (process.env.NODE_ENV !== 'production' && inBrowser && /Chrome\/\d+/.test(window.navigator.userAgent)) {
 10025        console.log('Download the Vue Devtools for a better development experience:\n' + 'https://github.com/vuejs/vue-devtools');
 10026      }
 10027    }
 10028  }, 0);
 10029  
 10030  module.exports = Vue;