UNPKG

314 kBJavaScriptView Raw
1/*!
2 * Vue.js v2.6.8
3 * (c) 2014-2019 Evan You
4 * Released under the MIT License.
5 */
6/* */
7
8const emptyObject = Object.freeze({});
9
10// These helpers produce better VM code in JS engines due to their
11// explicitness and function inlining.
12function isUndef (v) {
13 return v === undefined || v === null
14}
15
16function isDef (v) {
17 return v !== undefined && v !== null
18}
19
20function isTrue (v) {
21 return v === true
22}
23
24function isFalse (v) {
25 return v === false
26}
27
28/**
29 * Check if value is primitive.
30 */
31function isPrimitive (value) {
32 return (
33 typeof value === 'string' ||
34 typeof value === 'number' ||
35 // $flow-disable-line
36 typeof value === 'symbol' ||
37 typeof value === 'boolean'
38 )
39}
40
41/**
42 * Quick object check - this is primarily used to tell
43 * Objects from primitive values when we know the value
44 * is a JSON-compliant type.
45 */
46function isObject (obj) {
47 return obj !== null && typeof obj === 'object'
48}
49
50/**
51 * Get the raw type string of a value, e.g., [object Object].
52 */
53const _toString = Object.prototype.toString;
54
55function toRawType (value) {
56 return _toString.call(value).slice(8, -1)
57}
58
59/**
60 * Strict object type check. Only returns true
61 * for plain JavaScript objects.
62 */
63function isPlainObject (obj) {
64 return _toString.call(obj) === '[object Object]'
65}
66
67function isRegExp (v) {
68 return _toString.call(v) === '[object RegExp]'
69}
70
71/**
72 * Check if val is a valid array index.
73 */
74function isValidArrayIndex (val) {
75 const n = parseFloat(String(val));
76 return n >= 0 && Math.floor(n) === n && isFinite(val)
77}
78
79function isPromise (val) {
80 return (
81 isDef(val) &&
82 typeof val.then === 'function' &&
83 typeof val.catch === 'function'
84 )
85}
86
87/**
88 * Convert a value to a string that is actually rendered.
89 */
90function toString (val) {
91 return val == null
92 ? ''
93 : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
94 ? JSON.stringify(val, null, 2)
95 : String(val)
96}
97
98/**
99 * Convert an input value to a number for persistence.
100 * If the conversion fails, return original string.
101 */
102function toNumber (val) {
103 const n = parseFloat(val);
104 return isNaN(n) ? val : n
105}
106
107/**
108 * Make a map and return a function for checking if a key
109 * is in that map.
110 */
111function makeMap (
112 str,
113 expectsLowerCase
114) {
115 const map = Object.create(null);
116 const list = str.split(',');
117 for (let i = 0; i < list.length; i++) {
118 map[list[i]] = true;
119 }
120 return expectsLowerCase
121 ? val => map[val.toLowerCase()]
122 : val => map[val]
123}
124
125/**
126 * Check if a tag is a built-in tag.
127 */
128const isBuiltInTag = makeMap('slot,component', true);
129
130/**
131 * Check if an attribute is a reserved attribute.
132 */
133const isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');
134
135/**
136 * Remove an item from an array.
137 */
138function remove (arr, item) {
139 if (arr.length) {
140 const index = arr.indexOf(item);
141 if (index > -1) {
142 return arr.splice(index, 1)
143 }
144 }
145}
146
147/**
148 * Check whether an object has the property.
149 */
150const hasOwnProperty = Object.prototype.hasOwnProperty;
151function hasOwn (obj, key) {
152 return hasOwnProperty.call(obj, key)
153}
154
155/**
156 * Create a cached version of a pure function.
157 */
158function cached (fn) {
159 const cache = Object.create(null);
160 return (function cachedFn (str) {
161 const hit = cache[str];
162 return hit || (cache[str] = fn(str))
163 })
164}
165
166/**
167 * Camelize a hyphen-delimited string.
168 */
169const camelizeRE = /-(\w)/g;
170const camelize = cached((str) => {
171 return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
172});
173
174/**
175 * Capitalize a string.
176 */
177const capitalize = cached((str) => {
178 return str.charAt(0).toUpperCase() + str.slice(1)
179});
180
181/**
182 * Hyphenate a camelCase string.
183 */
184const hyphenateRE = /\B([A-Z])/g;
185const hyphenate = cached((str) => {
186 return str.replace(hyphenateRE, '-$1').toLowerCase()
187});
188
189/**
190 * Simple bind polyfill for environments that do not support it,
191 * e.g., PhantomJS 1.x. Technically, we don't need this anymore
192 * since native bind is now performant enough in most browsers.
193 * But removing it would mean breaking code that was able to run in
194 * PhantomJS 1.x, so this must be kept for backward compatibility.
195 */
196
197/* istanbul ignore next */
198function polyfillBind (fn, ctx) {
199 function boundFn (a) {
200 const l = arguments.length;
201 return l
202 ? l > 1
203 ? fn.apply(ctx, arguments)
204 : fn.call(ctx, a)
205 : fn.call(ctx)
206 }
207
208 boundFn._length = fn.length;
209 return boundFn
210}
211
212function nativeBind (fn, ctx) {
213 return fn.bind(ctx)
214}
215
216const bind = Function.prototype.bind
217 ? nativeBind
218 : polyfillBind;
219
220/**
221 * Convert an Array-like object to a real Array.
222 */
223function toArray (list, start) {
224 start = start || 0;
225 let i = list.length - start;
226 const ret = new Array(i);
227 while (i--) {
228 ret[i] = list[i + start];
229 }
230 return ret
231}
232
233/**
234 * Mix properties into target object.
235 */
236function extend (to, _from) {
237 for (const key in _from) {
238 to[key] = _from[key];
239 }
240 return to
241}
242
243/**
244 * Merge an Array of Objects into a single Object.
245 */
246function toObject (arr) {
247 const res = {};
248 for (let i = 0; i < arr.length; i++) {
249 if (arr[i]) {
250 extend(res, arr[i]);
251 }
252 }
253 return res
254}
255
256/* eslint-disable no-unused-vars */
257
258/**
259 * Perform no operation.
260 * Stubbing args to make Flow happy without leaving useless transpiled code
261 * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/).
262 */
263function noop (a, b, c) {}
264
265/**
266 * Always return false.
267 */
268const no = (a, b, c) => false;
269
270/* eslint-enable no-unused-vars */
271
272/**
273 * Return the same value.
274 */
275const identity = (_) => _;
276
277/**
278 * Generate a string containing static keys from compiler modules.
279 */
280function genStaticKeys (modules) {
281 return modules.reduce((keys, m) => {
282 return keys.concat(m.staticKeys || [])
283 }, []).join(',')
284}
285
286/**
287 * Check if two values are loosely equal - that is,
288 * if they are plain objects, do they have the same shape?
289 */
290function looseEqual (a, b) {
291 if (a === b) return true
292 const isObjectA = isObject(a);
293 const isObjectB = isObject(b);
294 if (isObjectA && isObjectB) {
295 try {
296 const isArrayA = Array.isArray(a);
297 const isArrayB = Array.isArray(b);
298 if (isArrayA && isArrayB) {
299 return a.length === b.length && a.every((e, i) => {
300 return looseEqual(e, b[i])
301 })
302 } else if (a instanceof Date && b instanceof Date) {
303 return a.getTime() === b.getTime()
304 } else if (!isArrayA && !isArrayB) {
305 const keysA = Object.keys(a);
306 const keysB = Object.keys(b);
307 return keysA.length === keysB.length && keysA.every(key => {
308 return looseEqual(a[key], b[key])
309 })
310 } else {
311 /* istanbul ignore next */
312 return false
313 }
314 } catch (e) {
315 /* istanbul ignore next */
316 return false
317 }
318 } else if (!isObjectA && !isObjectB) {
319 return String(a) === String(b)
320 } else {
321 return false
322 }
323}
324
325/**
326 * Return the first index at which a loosely equal value can be
327 * found in the array (if value is a plain object, the array must
328 * contain an object of the same shape), or -1 if it is not present.
329 */
330function looseIndexOf (arr, val) {
331 for (let i = 0; i < arr.length; i++) {
332 if (looseEqual(arr[i], val)) return i
333 }
334 return -1
335}
336
337/**
338 * Ensure a function is called only once.
339 */
340function once (fn) {
341 let called = false;
342 return function () {
343 if (!called) {
344 called = true;
345 fn.apply(this, arguments);
346 }
347 }
348}
349
350const SSR_ATTR = 'data-server-rendered';
351
352const ASSET_TYPES = [
353 'component',
354 'directive',
355 'filter'
356];
357
358const LIFECYCLE_HOOKS = [
359 'beforeCreate',
360 'created',
361 'beforeMount',
362 'mounted',
363 'beforeUpdate',
364 'updated',
365 'beforeDestroy',
366 'destroyed',
367 'activated',
368 'deactivated',
369 'errorCaptured',
370 'serverPrefetch'
371];
372
373/* */
374
375
376
377var config = ({
378 /**
379 * Option merge strategies (used in core/util/options)
380 */
381 // $flow-disable-line
382 optionMergeStrategies: Object.create(null),
383
384 /**
385 * Whether to suppress warnings.
386 */
387 silent: false,
388
389 /**
390 * Show production mode tip message on boot?
391 */
392 productionTip: "development" !== 'production',
393
394 /**
395 * Whether to enable devtools
396 */
397 devtools: "development" !== 'production',
398
399 /**
400 * Whether to record perf
401 */
402 performance: false,
403
404 /**
405 * Error handler for watcher errors
406 */
407 errorHandler: null,
408
409 /**
410 * Warn handler for watcher warns
411 */
412 warnHandler: null,
413
414 /**
415 * Ignore certain custom elements
416 */
417 ignoredElements: [],
418
419 /**
420 * Custom user key aliases for v-on
421 */
422 // $flow-disable-line
423 keyCodes: Object.create(null),
424
425 /**
426 * Check if a tag is reserved so that it cannot be registered as a
427 * component. This is platform-dependent and may be overwritten.
428 */
429 isReservedTag: no,
430
431 /**
432 * Check if an attribute is reserved so that it cannot be used as a component
433 * prop. This is platform-dependent and may be overwritten.
434 */
435 isReservedAttr: no,
436
437 /**
438 * Check if a tag is an unknown element.
439 * Platform-dependent.
440 */
441 isUnknownElement: no,
442
443 /**
444 * Get the namespace of an element
445 */
446 getTagNamespace: noop,
447
448 /**
449 * Parse the real tag name for the specific platform.
450 */
451 parsePlatformTagName: identity,
452
453 /**
454 * Check if an attribute must be bound using property, e.g. value
455 * Platform-dependent.
456 */
457 mustUseProp: no,
458
459 /**
460 * Perform updates asynchronously. Intended to be used by Vue Test Utils
461 * This will significantly reduce performance if set to false.
462 */
463 async: true,
464
465 /**
466 * Exposed for legacy reasons
467 */
468 _lifecycleHooks: LIFECYCLE_HOOKS
469});
470
471/* */
472
473/**
474 * unicode letters used for parsing html tags, component names and property paths.
475 * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
476 * skipping \u10000-\uEFFFF due to it freezing up PhantomJS
477 */
478const unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/;
479
480/**
481 * Check if a string starts with $ or _
482 */
483function isReserved (str) {
484 const c = (str + '').charCodeAt(0);
485 return c === 0x24 || c === 0x5F
486}
487
488/**
489 * Define a property.
490 */
491function def (obj, key, val, enumerable) {
492 Object.defineProperty(obj, key, {
493 value: val,
494 enumerable: !!enumerable,
495 writable: true,
496 configurable: true
497 });
498}
499
500/**
501 * Parse simple path.
502 */
503const bailRE = new RegExp(`[^${unicodeRegExp.source}.$_\\d]`);
504function parsePath (path) {
505 if (bailRE.test(path)) {
506 return
507 }
508 const segments = path.split('.');
509 return function (obj) {
510 for (let i = 0; i < segments.length; i++) {
511 if (!obj) return
512 obj = obj[segments[i]];
513 }
514 return obj
515 }
516}
517
518/* */
519
520// can we use __proto__?
521const hasProto = '__proto__' in {};
522
523// Browser environment sniffing
524const inBrowser = typeof window !== 'undefined';
525const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
526const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
527const UA = inBrowser && window.navigator.userAgent.toLowerCase();
528const isIE = UA && /msie|trident/.test(UA);
529const isIE9 = UA && UA.indexOf('msie 9.0') > 0;
530const isEdge = UA && UA.indexOf('edge/') > 0;
531const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
532const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
533const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
534const isPhantomJS = UA && /phantomjs/.test(UA);
535const isFF = UA && UA.match(/firefox\/(\d+)/);
536
537// Firefox has a "watch" function on Object.prototype...
538const nativeWatch = ({}).watch;
539
540let supportsPassive = false;
541if (inBrowser) {
542 try {
543 const opts = {};
544 Object.defineProperty(opts, 'passive', ({
545 get () {
546 /* istanbul ignore next */
547 supportsPassive = true;
548 }
549 })); // https://github.com/facebook/flow/issues/285
550 window.addEventListener('test-passive', null, opts);
551 } catch (e) {}
552}
553
554// this needs to be lazy-evaled because vue may be required before
555// vue-server-renderer can set VUE_ENV
556let _isServer;
557const isServerRendering = () => {
558 if (_isServer === undefined) {
559 /* istanbul ignore if */
560 if (!inBrowser && !inWeex && typeof global !== 'undefined') {
561 // detect presence of vue-server-renderer and avoid
562 // Webpack shimming the process
563 _isServer = global['process'] && global['process'].env.VUE_ENV === 'server';
564 } else {
565 _isServer = false;
566 }
567 }
568 return _isServer
569};
570
571// detect devtools
572const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
573
574/* istanbul ignore next */
575function isNative (Ctor) {
576 return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
577}
578
579const hasSymbol =
580 typeof Symbol !== 'undefined' && isNative(Symbol) &&
581 typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);
582
583let _Set;
584/* istanbul ignore if */ // $flow-disable-line
585if (typeof Set !== 'undefined' && isNative(Set)) {
586 // use native Set when available.
587 _Set = Set;
588} else {
589 // a non-standard Set polyfill that only works with primitive keys.
590 _Set = class Set {
591
592 constructor () {
593 this.set = Object.create(null);
594 }
595 has (key) {
596 return this.set[key] === true
597 }
598 add (key) {
599 this.set[key] = true;
600 }
601 clear () {
602 this.set = Object.create(null);
603 }
604 };
605}
606
607/* */
608
609let warn = noop;
610let tip = noop;
611let generateComponentTrace = (noop); // work around flow check
612let formatComponentName = (noop);
613
614{
615 const hasConsole = typeof console !== 'undefined';
616 const classifyRE = /(?:^|[-_])(\w)/g;
617 const classify = str => str
618 .replace(classifyRE, c => c.toUpperCase())
619 .replace(/[-_]/g, '');
620
621 warn = (msg, vm) => {
622 const trace = vm ? generateComponentTrace(vm) : '';
623
624 if (config.warnHandler) {
625 config.warnHandler.call(null, msg, vm, trace);
626 } else if (hasConsole && (!config.silent)) {
627 console.error(`[Vue warn]: ${msg}${trace}`);
628 }
629 };
630
631 tip = (msg, vm) => {
632 if (hasConsole && (!config.silent)) {
633 console.warn(`[Vue tip]: ${msg}` + (
634 vm ? generateComponentTrace(vm) : ''
635 ));
636 }
637 };
638
639 formatComponentName = (vm, includeFile) => {
640 if (vm.$root === vm) {
641 return '<Root>'
642 }
643 const options = typeof vm === 'function' && vm.cid != null
644 ? vm.options
645 : vm._isVue
646 ? vm.$options || vm.constructor.options
647 : vm;
648 let name = options.name || options._componentTag;
649 const file = options.__file;
650 if (!name && file) {
651 const match = file.match(/([^/\\]+)\.vue$/);
652 name = match && match[1];
653 }
654
655 return (
656 (name ? `<${classify(name)}>` : `<Anonymous>`) +
657 (file && includeFile !== false ? ` at ${file}` : '')
658 )
659 };
660
661 const repeat = (str, n) => {
662 let res = '';
663 while (n) {
664 if (n % 2 === 1) res += str;
665 if (n > 1) str += str;
666 n >>= 1;
667 }
668 return res
669 };
670
671 generateComponentTrace = vm => {
672 if (vm._isVue && vm.$parent) {
673 const tree = [];
674 let currentRecursiveSequence = 0;
675 while (vm) {
676 if (tree.length > 0) {
677 const last = tree[tree.length - 1];
678 if (last.constructor === vm.constructor) {
679 currentRecursiveSequence++;
680 vm = vm.$parent;
681 continue
682 } else if (currentRecursiveSequence > 0) {
683 tree[tree.length - 1] = [last, currentRecursiveSequence];
684 currentRecursiveSequence = 0;
685 }
686 }
687 tree.push(vm);
688 vm = vm.$parent;
689 }
690 return '\n\nfound in\n\n' + tree
691 .map((vm, i) => `${
692 i === 0 ? '---> ' : repeat(' ', 5 + i * 2)
693 }${
694 Array.isArray(vm)
695 ? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)`
696 : formatComponentName(vm)
697 }`)
698 .join('\n')
699 } else {
700 return `\n\n(found in ${formatComponentName(vm)})`
701 }
702 };
703}
704
705/* */
706
707let uid = 0;
708
709/**
710 * A dep is an observable that can have multiple
711 * directives subscribing to it.
712 */
713class Dep {
714
715
716
717
718 constructor () {
719 this.id = uid++;
720 this.subs = [];
721 }
722
723 addSub (sub) {
724 this.subs.push(sub);
725 }
726
727 removeSub (sub) {
728 remove(this.subs, sub);
729 }
730
731 depend () {
732 if (Dep.target) {
733 Dep.target.addDep(this);
734 }
735 }
736
737 notify () {
738 // stabilize the subscriber list first
739 const subs = this.subs.slice();
740 if (!config.async) {
741 // subs aren't sorted in scheduler if not running async
742 // we need to sort them now to make sure they fire in correct
743 // order
744 subs.sort((a, b) => a.id - b.id);
745 }
746 for (let i = 0, l = subs.length; i < l; i++) {
747 subs[i].update();
748 }
749 }
750}
751
752// The current target watcher being evaluated.
753// This is globally unique because only one watcher
754// can be evaluated at a time.
755Dep.target = null;
756const targetStack = [];
757
758function pushTarget (target) {
759 targetStack.push(target);
760 Dep.target = target;
761}
762
763function popTarget () {
764 targetStack.pop();
765 Dep.target = targetStack[targetStack.length - 1];
766}
767
768/* */
769
770class VNode {
771
772
773
774
775
776
777 // rendered in this component's scope
778
779
780 // component instance
781 // component placeholder node
782
783 // strictly internal
784 // contains raw HTML? (server only)
785 // hoisted static node
786 // necessary for enter transition check
787 // empty comment placeholder?
788 // is a cloned node?
789 // is a v-once node?
790 // async component factory function
791
792
793
794 // real context vm for functional nodes
795 // for SSR caching
796 // used to store functional render context for devtools
797 // functional scope id support
798
799 constructor (
800 tag,
801 data,
802 children,
803 text,
804 elm,
805 context,
806 componentOptions,
807 asyncFactory
808 ) {
809 this.tag = tag;
810 this.data = data;
811 this.children = children;
812 this.text = text;
813 this.elm = elm;
814 this.ns = undefined;
815 this.context = context;
816 this.fnContext = undefined;
817 this.fnOptions = undefined;
818 this.fnScopeId = undefined;
819 this.key = data && data.key;
820 this.componentOptions = componentOptions;
821 this.componentInstance = undefined;
822 this.parent = undefined;
823 this.raw = false;
824 this.isStatic = false;
825 this.isRootInsert = true;
826 this.isComment = false;
827 this.isCloned = false;
828 this.isOnce = false;
829 this.asyncFactory = asyncFactory;
830 this.asyncMeta = undefined;
831 this.isAsyncPlaceholder = false;
832 }
833
834 // DEPRECATED: alias for componentInstance for backwards compat.
835 /* istanbul ignore next */
836 get child () {
837 return this.componentInstance
838 }
839}
840
841const createEmptyVNode = (text = '') => {
842 const node = new VNode();
843 node.text = text;
844 node.isComment = true;
845 return node
846};
847
848function createTextVNode (val) {
849 return new VNode(undefined, undefined, undefined, String(val))
850}
851
852// optimized shallow clone
853// used for static nodes and slot nodes because they may be reused across
854// multiple renders, cloning them avoids errors when DOM manipulations rely
855// on their elm reference.
856function cloneVNode (vnode) {
857 const cloned = new VNode(
858 vnode.tag,
859 vnode.data,
860 // #7975
861 // clone children array to avoid mutating original in case of cloning
862 // a child.
863 vnode.children && vnode.children.slice(),
864 vnode.text,
865 vnode.elm,
866 vnode.context,
867 vnode.componentOptions,
868 vnode.asyncFactory
869 );
870 cloned.ns = vnode.ns;
871 cloned.isStatic = vnode.isStatic;
872 cloned.key = vnode.key;
873 cloned.isComment = vnode.isComment;
874 cloned.fnContext = vnode.fnContext;
875 cloned.fnOptions = vnode.fnOptions;
876 cloned.fnScopeId = vnode.fnScopeId;
877 cloned.asyncMeta = vnode.asyncMeta;
878 cloned.isCloned = true;
879 return cloned
880}
881
882/*
883 * not type checking this file because flow doesn't play well with
884 * dynamically accessing methods on Array prototype
885 */
886
887const arrayProto = Array.prototype;
888const arrayMethods = Object.create(arrayProto);
889
890const methodsToPatch = [
891 'push',
892 'pop',
893 'shift',
894 'unshift',
895 'splice',
896 'sort',
897 'reverse'
898];
899
900/**
901 * Intercept mutating methods and emit events
902 */
903methodsToPatch.forEach(function (method) {
904 // cache original method
905 const original = arrayProto[method];
906 def(arrayMethods, method, function mutator (...args) {
907 const result = original.apply(this, args);
908 const ob = this.__ob__;
909 let inserted;
910 switch (method) {
911 case 'push':
912 case 'unshift':
913 inserted = args;
914 break
915 case 'splice':
916 inserted = args.slice(2);
917 break
918 }
919 if (inserted) ob.observeArray(inserted);
920 // notify change
921 ob.dep.notify();
922 return result
923 });
924});
925
926/* */
927
928const arrayKeys = Object.getOwnPropertyNames(arrayMethods);
929
930/**
931 * In some cases we may want to disable observation inside a component's
932 * update computation.
933 */
934let shouldObserve = true;
935
936function toggleObserving (value) {
937 shouldObserve = value;
938}
939
940/**
941 * Observer class that is attached to each observed
942 * object. Once attached, the observer converts the target
943 * object's property keys into getter/setters that
944 * collect dependencies and dispatch updates.
945 */
946class Observer {
947
948
949 // number of vms that have this object as root $data
950
951 constructor (value) {
952 this.value = value;
953 this.dep = new Dep();
954 this.vmCount = 0;
955 def(value, '__ob__', this);
956 if (Array.isArray(value)) {
957 if (hasProto) {
958 protoAugment(value, arrayMethods);
959 } else {
960 copyAugment(value, arrayMethods, arrayKeys);
961 }
962 this.observeArray(value);
963 } else {
964 this.walk(value);
965 }
966 }
967
968 /**
969 * Walk through all properties and convert them into
970 * getter/setters. This method should only be called when
971 * value type is Object.
972 */
973 walk (obj) {
974 const keys = Object.keys(obj);
975 for (let i = 0; i < keys.length; i++) {
976 defineReactive$$1(obj, keys[i]);
977 }
978 }
979
980 /**
981 * Observe a list of Array items.
982 */
983 observeArray (items) {
984 for (let i = 0, l = items.length; i < l; i++) {
985 observe(items[i]);
986 }
987 }
988}
989
990// helpers
991
992/**
993 * Augment a target Object or Array by intercepting
994 * the prototype chain using __proto__
995 */
996function protoAugment (target, src) {
997 /* eslint-disable no-proto */
998 target.__proto__ = src;
999 /* eslint-enable no-proto */
1000}
1001
1002/**
1003 * Augment a target Object or Array by defining
1004 * hidden properties.
1005 */
1006/* istanbul ignore next */
1007function copyAugment (target, src, keys) {
1008 for (let i = 0, l = keys.length; i < l; i++) {
1009 const key = keys[i];
1010 def(target, key, src[key]);
1011 }
1012}
1013
1014/**
1015 * Attempt to create an observer instance for a value,
1016 * returns the new observer if successfully observed,
1017 * or the existing observer if the value already has one.
1018 */
1019function observe (value, asRootData) {
1020 if (!isObject(value) || value instanceof VNode) {
1021 return
1022 }
1023 let ob;
1024 if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
1025 ob = value.__ob__;
1026 } else if (
1027 shouldObserve &&
1028 !isServerRendering() &&
1029 (Array.isArray(value) || isPlainObject(value)) &&
1030 Object.isExtensible(value) &&
1031 !value._isVue
1032 ) {
1033 ob = new Observer(value);
1034 }
1035 if (asRootData && ob) {
1036 ob.vmCount++;
1037 }
1038 return ob
1039}
1040
1041/**
1042 * Define a reactive property on an Object.
1043 */
1044function defineReactive$$1 (
1045 obj,
1046 key,
1047 val,
1048 customSetter,
1049 shallow
1050) {
1051 const dep = new Dep();
1052
1053 const property = Object.getOwnPropertyDescriptor(obj, key);
1054 if (property && property.configurable === false) {
1055 return
1056 }
1057
1058 // cater for pre-defined getter/setters
1059 const getter = property && property.get;
1060 const setter = property && property.set;
1061 if ((!getter || setter) && arguments.length === 2) {
1062 val = obj[key];
1063 }
1064
1065 let childOb = !shallow && observe(val);
1066 Object.defineProperty(obj, key, {
1067 enumerable: true,
1068 configurable: true,
1069 get: function reactiveGetter () {
1070 const value = getter ? getter.call(obj) : val;
1071 if (Dep.target) {
1072 dep.depend();
1073 if (childOb) {
1074 childOb.dep.depend();
1075 if (Array.isArray(value)) {
1076 dependArray(value);
1077 }
1078 }
1079 }
1080 return value
1081 },
1082 set: function reactiveSetter (newVal) {
1083 const value = getter ? getter.call(obj) : val;
1084 /* eslint-disable no-self-compare */
1085 if (newVal === value || (newVal !== newVal && value !== value)) {
1086 return
1087 }
1088 /* eslint-enable no-self-compare */
1089 if (customSetter) {
1090 customSetter();
1091 }
1092 // #7981: for accessor properties without setter
1093 if (getter && !setter) return
1094 if (setter) {
1095 setter.call(obj, newVal);
1096 } else {
1097 val = newVal;
1098 }
1099 childOb = !shallow && observe(newVal);
1100 dep.notify();
1101 }
1102 });
1103}
1104
1105/**
1106 * Set a property on an object. Adds the new property and
1107 * triggers change notification if the property doesn't
1108 * already exist.
1109 */
1110function set (target, key, val) {
1111 if (isUndef(target) || isPrimitive(target)
1112 ) {
1113 warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target)}`);
1114 }
1115 if (Array.isArray(target) && isValidArrayIndex(key)) {
1116 target.length = Math.max(target.length, key);
1117 target.splice(key, 1, val);
1118 return val
1119 }
1120 if (key in target && !(key in Object.prototype)) {
1121 target[key] = val;
1122 return val
1123 }
1124 const ob = (target).__ob__;
1125 if (target._isVue || (ob && ob.vmCount)) {
1126 warn(
1127 'Avoid adding reactive properties to a Vue instance or its root $data ' +
1128 'at runtime - declare it upfront in the data option.'
1129 );
1130 return val
1131 }
1132 if (!ob) {
1133 target[key] = val;
1134 return val
1135 }
1136 defineReactive$$1(ob.value, key, val);
1137 ob.dep.notify();
1138 return val
1139}
1140
1141/**
1142 * Delete a property and trigger change if necessary.
1143 */
1144function del (target, key) {
1145 if (isUndef(target) || isPrimitive(target)
1146 ) {
1147 warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target)}`);
1148 }
1149 if (Array.isArray(target) && isValidArrayIndex(key)) {
1150 target.splice(key, 1);
1151 return
1152 }
1153 const ob = (target).__ob__;
1154 if (target._isVue || (ob && ob.vmCount)) {
1155 warn(
1156 'Avoid deleting properties on a Vue instance or its root $data ' +
1157 '- just set it to null.'
1158 );
1159 return
1160 }
1161 if (!hasOwn(target, key)) {
1162 return
1163 }
1164 delete target[key];
1165 if (!ob) {
1166 return
1167 }
1168 ob.dep.notify();
1169}
1170
1171/**
1172 * Collect dependencies on array elements when the array is touched, since
1173 * we cannot intercept array element access like property getters.
1174 */
1175function dependArray (value) {
1176 for (let e, i = 0, l = value.length; i < l; i++) {
1177 e = value[i];
1178 e && e.__ob__ && e.__ob__.dep.depend();
1179 if (Array.isArray(e)) {
1180 dependArray(e);
1181 }
1182 }
1183}
1184
1185/* */
1186
1187/**
1188 * Option overwriting strategies are functions that handle
1189 * how to merge a parent option value and a child option
1190 * value into the final value.
1191 */
1192const strats = config.optionMergeStrategies;
1193
1194/**
1195 * Options with restrictions
1196 */
1197{
1198 strats.el = strats.propsData = function (parent, child, vm, key) {
1199 if (!vm) {
1200 warn(
1201 `option "${key}" can only be used during instance ` +
1202 'creation with the `new` keyword.'
1203 );
1204 }
1205 return defaultStrat(parent, child)
1206 };
1207}
1208
1209/**
1210 * Helper that recursively merges two data objects together.
1211 */
1212function mergeData (to, from) {
1213 if (!from) return to
1214 let key, toVal, fromVal;
1215
1216 const keys = hasSymbol
1217 ? Reflect.ownKeys(from)
1218 : Object.keys(from);
1219
1220 for (let i = 0; i < keys.length; i++) {
1221 key = keys[i];
1222 // in case the object is already observed...
1223 if (key === '__ob__') continue
1224 toVal = to[key];
1225 fromVal = from[key];
1226 if (!hasOwn(to, key)) {
1227 set(to, key, fromVal);
1228 } else if (
1229 toVal !== fromVal &&
1230 isPlainObject(toVal) &&
1231 isPlainObject(fromVal)
1232 ) {
1233 mergeData(toVal, fromVal);
1234 }
1235 }
1236 return to
1237}
1238
1239/**
1240 * Data
1241 */
1242function mergeDataOrFn (
1243 parentVal,
1244 childVal,
1245 vm
1246) {
1247 if (!vm) {
1248 // in a Vue.extend merge, both should be functions
1249 if (!childVal) {
1250 return parentVal
1251 }
1252 if (!parentVal) {
1253 return childVal
1254 }
1255 // when parentVal & childVal are both present,
1256 // we need to return a function that returns the
1257 // merged result of both functions... no need to
1258 // check if parentVal is a function here because
1259 // it has to be a function to pass previous merges.
1260 return function mergedDataFn () {
1261 return mergeData(
1262 typeof childVal === 'function' ? childVal.call(this, this) : childVal,
1263 typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
1264 )
1265 }
1266 } else {
1267 return function mergedInstanceDataFn () {
1268 // instance merge
1269 const instanceData = typeof childVal === 'function'
1270 ? childVal.call(vm, vm)
1271 : childVal;
1272 const defaultData = typeof parentVal === 'function'
1273 ? parentVal.call(vm, vm)
1274 : parentVal;
1275 if (instanceData) {
1276 return mergeData(instanceData, defaultData)
1277 } else {
1278 return defaultData
1279 }
1280 }
1281 }
1282}
1283
1284strats.data = function (
1285 parentVal,
1286 childVal,
1287 vm
1288) {
1289 if (!vm) {
1290 if (childVal && typeof childVal !== 'function') {
1291 warn(
1292 'The "data" option should be a function ' +
1293 'that returns a per-instance value in component ' +
1294 'definitions.',
1295 vm
1296 );
1297
1298 return parentVal
1299 }
1300 return mergeDataOrFn(parentVal, childVal)
1301 }
1302
1303 return mergeDataOrFn(parentVal, childVal, vm)
1304};
1305
1306/**
1307 * Hooks and props are merged as arrays.
1308 */
1309function mergeHook (
1310 parentVal,
1311 childVal
1312) {
1313 const res = childVal
1314 ? parentVal
1315 ? parentVal.concat(childVal)
1316 : Array.isArray(childVal)
1317 ? childVal
1318 : [childVal]
1319 : parentVal;
1320 return res
1321 ? dedupeHooks(res)
1322 : res
1323}
1324
1325function dedupeHooks (hooks) {
1326 const res = [];
1327 for (let i = 0; i < hooks.length; i++) {
1328 if (res.indexOf(hooks[i]) === -1) {
1329 res.push(hooks[i]);
1330 }
1331 }
1332 return res
1333}
1334
1335LIFECYCLE_HOOKS.forEach(hook => {
1336 strats[hook] = mergeHook;
1337});
1338
1339/**
1340 * Assets
1341 *
1342 * When a vm is present (instance creation), we need to do
1343 * a three-way merge between constructor options, instance
1344 * options and parent options.
1345 */
1346function mergeAssets (
1347 parentVal,
1348 childVal,
1349 vm,
1350 key
1351) {
1352 const res = Object.create(parentVal || null);
1353 if (childVal) {
1354 assertObjectType(key, childVal, vm);
1355 return extend(res, childVal)
1356 } else {
1357 return res
1358 }
1359}
1360
1361ASSET_TYPES.forEach(function (type) {
1362 strats[type + 's'] = mergeAssets;
1363});
1364
1365/**
1366 * Watchers.
1367 *
1368 * Watchers hashes should not overwrite one
1369 * another, so we merge them as arrays.
1370 */
1371strats.watch = function (
1372 parentVal,
1373 childVal,
1374 vm,
1375 key
1376) {
1377 // work around Firefox's Object.prototype.watch...
1378 if (parentVal === nativeWatch) parentVal = undefined;
1379 if (childVal === nativeWatch) childVal = undefined;
1380 /* istanbul ignore if */
1381 if (!childVal) return Object.create(parentVal || null)
1382 {
1383 assertObjectType(key, childVal, vm);
1384 }
1385 if (!parentVal) return childVal
1386 const ret = {};
1387 extend(ret, parentVal);
1388 for (const key in childVal) {
1389 let parent = ret[key];
1390 const child = childVal[key];
1391 if (parent && !Array.isArray(parent)) {
1392 parent = [parent];
1393 }
1394 ret[key] = parent
1395 ? parent.concat(child)
1396 : Array.isArray(child) ? child : [child];
1397 }
1398 return ret
1399};
1400
1401/**
1402 * Other object hashes.
1403 */
1404strats.props =
1405strats.methods =
1406strats.inject =
1407strats.computed = function (
1408 parentVal,
1409 childVal,
1410 vm,
1411 key
1412) {
1413 if (childVal && "development" !== 'production') {
1414 assertObjectType(key, childVal, vm);
1415 }
1416 if (!parentVal) return childVal
1417 const ret = Object.create(null);
1418 extend(ret, parentVal);
1419 if (childVal) extend(ret, childVal);
1420 return ret
1421};
1422strats.provide = mergeDataOrFn;
1423
1424/**
1425 * Default strategy.
1426 */
1427const defaultStrat = function (parentVal, childVal) {
1428 return childVal === undefined
1429 ? parentVal
1430 : childVal
1431};
1432
1433/**
1434 * Validate component names
1435 */
1436function checkComponents (options) {
1437 for (const key in options.components) {
1438 validateComponentName(key);
1439 }
1440}
1441
1442function validateComponentName (name) {
1443 if (!new RegExp(`^[a-zA-Z][\\-\\.0-9_${unicodeRegExp.source}]*$`).test(name)) {
1444 warn(
1445 'Invalid component name: "' + name + '". Component names ' +
1446 'should conform to valid custom element name in html5 specification.'
1447 );
1448 }
1449 if (isBuiltInTag(name) || config.isReservedTag(name)) {
1450 warn(
1451 'Do not use built-in or reserved HTML elements as component ' +
1452 'id: ' + name
1453 );
1454 }
1455}
1456
1457/**
1458 * Ensure all props option syntax are normalized into the
1459 * Object-based format.
1460 */
1461function normalizeProps (options, vm) {
1462 const props = options.props;
1463 if (!props) return
1464 const res = {};
1465 let i, val, name;
1466 if (Array.isArray(props)) {
1467 i = props.length;
1468 while (i--) {
1469 val = props[i];
1470 if (typeof val === 'string') {
1471 name = camelize(val);
1472 res[name] = { type: null };
1473 } else {
1474 warn('props must be strings when using array syntax.');
1475 }
1476 }
1477 } else if (isPlainObject(props)) {
1478 for (const key in props) {
1479 val = props[key];
1480 name = camelize(key);
1481 res[name] = isPlainObject(val)
1482 ? val
1483 : { type: val };
1484 }
1485 } else {
1486 warn(
1487 `Invalid value for option "props": expected an Array or an Object, ` +
1488 `but got ${toRawType(props)}.`,
1489 vm
1490 );
1491 }
1492 options.props = res;
1493}
1494
1495/**
1496 * Normalize all injections into Object-based format
1497 */
1498function normalizeInject (options, vm) {
1499 const inject = options.inject;
1500 if (!inject) return
1501 const normalized = options.inject = {};
1502 if (Array.isArray(inject)) {
1503 for (let i = 0; i < inject.length; i++) {
1504 normalized[inject[i]] = { from: inject[i] };
1505 }
1506 } else if (isPlainObject(inject)) {
1507 for (const key in inject) {
1508 const val = inject[key];
1509 normalized[key] = isPlainObject(val)
1510 ? extend({ from: key }, val)
1511 : { from: val };
1512 }
1513 } else {
1514 warn(
1515 `Invalid value for option "inject": expected an Array or an Object, ` +
1516 `but got ${toRawType(inject)}.`,
1517 vm
1518 );
1519 }
1520}
1521
1522/**
1523 * Normalize raw function directives into object format.
1524 */
1525function normalizeDirectives (options) {
1526 const dirs = options.directives;
1527 if (dirs) {
1528 for (const key in dirs) {
1529 const def$$1 = dirs[key];
1530 if (typeof def$$1 === 'function') {
1531 dirs[key] = { bind: def$$1, update: def$$1 };
1532 }
1533 }
1534 }
1535}
1536
1537function assertObjectType (name, value, vm) {
1538 if (!isPlainObject(value)) {
1539 warn(
1540 `Invalid value for option "${name}": expected an Object, ` +
1541 `but got ${toRawType(value)}.`,
1542 vm
1543 );
1544 }
1545}
1546
1547/**
1548 * Merge two option objects into a new one.
1549 * Core utility used in both instantiation and inheritance.
1550 */
1551function mergeOptions (
1552 parent,
1553 child,
1554 vm
1555) {
1556 {
1557 checkComponents(child);
1558 }
1559
1560 if (typeof child === 'function') {
1561 child = child.options;
1562 }
1563
1564 normalizeProps(child, vm);
1565 normalizeInject(child, vm);
1566 normalizeDirectives(child);
1567
1568 // Apply extends and mixins on the child options,
1569 // but only if it is a raw options object that isn't
1570 // the result of another mergeOptions call.
1571 // Only merged options has the _base property.
1572 if (!child._base) {
1573 if (child.extends) {
1574 parent = mergeOptions(parent, child.extends, vm);
1575 }
1576 if (child.mixins) {
1577 for (let i = 0, l = child.mixins.length; i < l; i++) {
1578 parent = mergeOptions(parent, child.mixins[i], vm);
1579 }
1580 }
1581 }
1582
1583 const options = {};
1584 let key;
1585 for (key in parent) {
1586 mergeField(key);
1587 }
1588 for (key in child) {
1589 if (!hasOwn(parent, key)) {
1590 mergeField(key);
1591 }
1592 }
1593 function mergeField (key) {
1594 const strat = strats[key] || defaultStrat;
1595 options[key] = strat(parent[key], child[key], vm, key);
1596 }
1597 return options
1598}
1599
1600/**
1601 * Resolve an asset.
1602 * This function is used because child instances need access
1603 * to assets defined in its ancestor chain.
1604 */
1605function resolveAsset (
1606 options,
1607 type,
1608 id,
1609 warnMissing
1610) {
1611 /* istanbul ignore if */
1612 if (typeof id !== 'string') {
1613 return
1614 }
1615 const assets = options[type];
1616 // check local registration variations first
1617 if (hasOwn(assets, id)) return assets[id]
1618 const camelizedId = camelize(id);
1619 if (hasOwn(assets, camelizedId)) return assets[camelizedId]
1620 const PascalCaseId = capitalize(camelizedId);
1621 if (hasOwn(assets, PascalCaseId)) return assets[PascalCaseId]
1622 // fallback to prototype chain
1623 const res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
1624 if (warnMissing && !res) {
1625 warn(
1626 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
1627 options
1628 );
1629 }
1630 return res
1631}
1632
1633/* */
1634
1635
1636
1637function validateProp (
1638 key,
1639 propOptions,
1640 propsData,
1641 vm
1642) {
1643 const prop = propOptions[key];
1644 const absent = !hasOwn(propsData, key);
1645 let value = propsData[key];
1646 // boolean casting
1647 const booleanIndex = getTypeIndex(Boolean, prop.type);
1648 if (booleanIndex > -1) {
1649 if (absent && !hasOwn(prop, 'default')) {
1650 value = false;
1651 } else if (value === '' || value === hyphenate(key)) {
1652 // only cast empty string / same name to boolean if
1653 // boolean has higher priority
1654 const stringIndex = getTypeIndex(String, prop.type);
1655 if (stringIndex < 0 || booleanIndex < stringIndex) {
1656 value = true;
1657 }
1658 }
1659 }
1660 // check default value
1661 if (value === undefined) {
1662 value = getPropDefaultValue(vm, prop, key);
1663 // since the default value is a fresh copy,
1664 // make sure to observe it.
1665 const prevShouldObserve = shouldObserve;
1666 toggleObserving(true);
1667 observe(value);
1668 toggleObserving(prevShouldObserve);
1669 }
1670 {
1671 assertProp(prop, key, value, vm, absent);
1672 }
1673 return value
1674}
1675
1676/**
1677 * Get the default value of a prop.
1678 */
1679function getPropDefaultValue (vm, prop, key) {
1680 // no default, return undefined
1681 if (!hasOwn(prop, 'default')) {
1682 return undefined
1683 }
1684 const def = prop.default;
1685 // warn against non-factory defaults for Object & Array
1686 if (isObject(def)) {
1687 warn(
1688 'Invalid default value for prop "' + key + '": ' +
1689 'Props with type Object/Array must use a factory function ' +
1690 'to return the default value.',
1691 vm
1692 );
1693 }
1694 // the raw prop value was also undefined from previous render,
1695 // return previous default value to avoid unnecessary watcher trigger
1696 if (vm && vm.$options.propsData &&
1697 vm.$options.propsData[key] === undefined &&
1698 vm._props[key] !== undefined
1699 ) {
1700 return vm._props[key]
1701 }
1702 // call factory function for non-Function types
1703 // a value is Function if its prototype is function even across different execution context
1704 return typeof def === 'function' && getType(prop.type) !== 'Function'
1705 ? def.call(vm)
1706 : def
1707}
1708
1709/**
1710 * Assert whether a prop is valid.
1711 */
1712function assertProp (
1713 prop,
1714 name,
1715 value,
1716 vm,
1717 absent
1718) {
1719 if (prop.required && absent) {
1720 warn(
1721 'Missing required prop: "' + name + '"',
1722 vm
1723 );
1724 return
1725 }
1726 if (value == null && !prop.required) {
1727 return
1728 }
1729 let type = prop.type;
1730 let valid = !type || type === true;
1731 const expectedTypes = [];
1732 if (type) {
1733 if (!Array.isArray(type)) {
1734 type = [type];
1735 }
1736 for (let i = 0; i < type.length && !valid; i++) {
1737 const assertedType = assertType(value, type[i]);
1738 expectedTypes.push(assertedType.expectedType || '');
1739 valid = assertedType.valid;
1740 }
1741 }
1742
1743 if (!valid) {
1744 warn(
1745 getInvalidTypeMessage(name, value, expectedTypes),
1746 vm
1747 );
1748 return
1749 }
1750 const validator = prop.validator;
1751 if (validator) {
1752 if (!validator(value)) {
1753 warn(
1754 'Invalid prop: custom validator check failed for prop "' + name + '".',
1755 vm
1756 );
1757 }
1758 }
1759}
1760
1761const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;
1762
1763function assertType (value, type) {
1764 let valid;
1765 const expectedType = getType(type);
1766 if (simpleCheckRE.test(expectedType)) {
1767 const t = typeof value;
1768 valid = t === expectedType.toLowerCase();
1769 // for primitive wrapper objects
1770 if (!valid && t === 'object') {
1771 valid = value instanceof type;
1772 }
1773 } else if (expectedType === 'Object') {
1774 valid = isPlainObject(value);
1775 } else if (expectedType === 'Array') {
1776 valid = Array.isArray(value);
1777 } else {
1778 valid = value instanceof type;
1779 }
1780 return {
1781 valid,
1782 expectedType
1783 }
1784}
1785
1786/**
1787 * Use function string name to check built-in types,
1788 * because a simple equality check will fail when running
1789 * across different vms / iframes.
1790 */
1791function getType (fn) {
1792 const match = fn && fn.toString().match(/^\s*function (\w+)/);
1793 return match ? match[1] : ''
1794}
1795
1796function isSameType (a, b) {
1797 return getType(a) === getType(b)
1798}
1799
1800function getTypeIndex (type, expectedTypes) {
1801 if (!Array.isArray(expectedTypes)) {
1802 return isSameType(expectedTypes, type) ? 0 : -1
1803 }
1804 for (let i = 0, len = expectedTypes.length; i < len; i++) {
1805 if (isSameType(expectedTypes[i], type)) {
1806 return i
1807 }
1808 }
1809 return -1
1810}
1811
1812function getInvalidTypeMessage (name, value, expectedTypes) {
1813 let message = `Invalid prop: type check failed for prop "${name}".` +
1814 ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
1815 const expectedType = expectedTypes[0];
1816 const receivedType = toRawType(value);
1817 const expectedValue = styleValue(value, expectedType);
1818 const receivedValue = styleValue(value, receivedType);
1819 // check if we need to specify expected value
1820 if (expectedTypes.length === 1 &&
1821 isExplicable(expectedType) &&
1822 !isBoolean(expectedType, receivedType)) {
1823 message += ` with value ${expectedValue}`;
1824 }
1825 message += `, got ${receivedType} `;
1826 // check if we need to specify received value
1827 if (isExplicable(receivedType)) {
1828 message += `with value ${receivedValue}.`;
1829 }
1830 return message
1831}
1832
1833function styleValue (value, type) {
1834 if (type === 'String') {
1835 return `"${value}"`
1836 } else if (type === 'Number') {
1837 return `${Number(value)}`
1838 } else {
1839 return `${value}`
1840 }
1841}
1842
1843function isExplicable (value) {
1844 const explicitTypes = ['string', 'number', 'boolean'];
1845 return explicitTypes.some(elem => value.toLowerCase() === elem)
1846}
1847
1848function isBoolean (...args) {
1849 return args.some(elem => elem.toLowerCase() === 'boolean')
1850}
1851
1852/* */
1853
1854function handleError (err, vm, info) {
1855 // Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
1856 // See: https://github.com/vuejs/vuex/issues/1505
1857 pushTarget();
1858 try {
1859 if (vm) {
1860 let cur = vm;
1861 while ((cur = cur.$parent)) {
1862 const hooks = cur.$options.errorCaptured;
1863 if (hooks) {
1864 for (let i = 0; i < hooks.length; i++) {
1865 try {
1866 const capture = hooks[i].call(cur, err, vm, info) === false;
1867 if (capture) return
1868 } catch (e) {
1869 globalHandleError(e, cur, 'errorCaptured hook');
1870 }
1871 }
1872 }
1873 }
1874 }
1875 globalHandleError(err, vm, info);
1876 } finally {
1877 popTarget();
1878 }
1879}
1880
1881function invokeWithErrorHandling (
1882 handler,
1883 context,
1884 args,
1885 vm,
1886 info
1887) {
1888 let res;
1889 try {
1890 res = args ? handler.apply(context, args) : handler.call(context);
1891 if (res && !res._isVue && isPromise(res)) {
1892 // issue #9511
1893 // reassign to res to avoid catch triggering multiple times when nested calls
1894 res = res.catch(e => handleError(e, vm, info + ` (Promise/async)`));
1895 }
1896 } catch (e) {
1897 handleError(e, vm, info);
1898 }
1899 return res
1900}
1901
1902function globalHandleError (err, vm, info) {
1903 if (config.errorHandler) {
1904 try {
1905 return config.errorHandler.call(null, err, vm, info)
1906 } catch (e) {
1907 // if the user intentionally throws the original error in the handler,
1908 // do not log it twice
1909 if (e !== err) {
1910 logError(e, null, 'config.errorHandler');
1911 }
1912 }
1913 }
1914 logError(err, vm, info);
1915}
1916
1917function logError (err, vm, info) {
1918 {
1919 warn(`Error in ${info}: "${err.toString()}"`, vm);
1920 }
1921 /* istanbul ignore else */
1922 if ((inBrowser || inWeex) && typeof console !== 'undefined') {
1923 console.error(err);
1924 } else {
1925 throw err
1926 }
1927}
1928
1929/* */
1930
1931let isUsingMicroTask = false;
1932
1933const callbacks = [];
1934let pending = false;
1935
1936function flushCallbacks () {
1937 pending = false;
1938 const copies = callbacks.slice(0);
1939 callbacks.length = 0;
1940 for (let i = 0; i < copies.length; i++) {
1941 copies[i]();
1942 }
1943}
1944
1945// Here we have async deferring wrappers using microtasks.
1946// In 2.5 we used (macro) tasks (in combination with microtasks).
1947// However, it has subtle problems when state is changed right before repaint
1948// (e.g. #6813, out-in transitions).
1949// Also, using (macro) tasks in event handler would cause some weird behaviors
1950// that cannot be circumvented (e.g. #7109, #7153, #7546, #7834, #8109).
1951// So we now use microtasks everywhere, again.
1952// A major drawback of this tradeoff is that there are some scenarios
1953// where microtasks have too high a priority and fire in between supposedly
1954// sequential events (e.g. #4521, #6690, which have workarounds)
1955// or even between bubbling of the same event (#6566).
1956let timerFunc;
1957
1958// The nextTick behavior leverages the microtask queue, which can be accessed
1959// via either native Promise.then or MutationObserver.
1960// MutationObserver has wider support, however it is seriously bugged in
1961// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
1962// completely stops working after triggering a few times... so, if native
1963// Promise is available, we will use it:
1964/* istanbul ignore next, $flow-disable-line */
1965if (typeof Promise !== 'undefined' && isNative(Promise)) {
1966 const p = Promise.resolve();
1967 timerFunc = () => {
1968 p.then(flushCallbacks);
1969 // In problematic UIWebViews, Promise.then doesn't completely break, but
1970 // it can get stuck in a weird state where callbacks are pushed into the
1971 // microtask queue but the queue isn't being flushed, until the browser
1972 // needs to do some other work, e.g. handle a timer. Therefore we can
1973 // "force" the microtask queue to be flushed by adding an empty timer.
1974 if (isIOS) setTimeout(noop);
1975 };
1976 isUsingMicroTask = true;
1977} else if (!isIE && typeof MutationObserver !== 'undefined' && (
1978 isNative(MutationObserver) ||
1979 // PhantomJS and iOS 7.x
1980 MutationObserver.toString() === '[object MutationObserverConstructor]'
1981)) {
1982 // Use MutationObserver where native Promise is not available,
1983 // e.g. PhantomJS, iOS7, Android 4.4
1984 // (#6466 MutationObserver is unreliable in IE11)
1985 let counter = 1;
1986 const observer = new MutationObserver(flushCallbacks);
1987 const textNode = document.createTextNode(String(counter));
1988 observer.observe(textNode, {
1989 characterData: true
1990 });
1991 timerFunc = () => {
1992 counter = (counter + 1) % 2;
1993 textNode.data = String(counter);
1994 };
1995 isUsingMicroTask = true;
1996} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
1997 // Fallback to setImmediate.
1998 // Techinically it leverages the (macro) task queue,
1999 // but it is still a better choice than setTimeout.
2000 timerFunc = () => {
2001 setImmediate(flushCallbacks);
2002 };
2003} else {
2004 // Fallback to setTimeout.
2005 timerFunc = () => {
2006 setTimeout(flushCallbacks, 0);
2007 };
2008}
2009
2010function nextTick (cb, ctx) {
2011 let _resolve;
2012 callbacks.push(() => {
2013 if (cb) {
2014 try {
2015 cb.call(ctx);
2016 } catch (e) {
2017 handleError(e, ctx, 'nextTick');
2018 }
2019 } else if (_resolve) {
2020 _resolve(ctx);
2021 }
2022 });
2023 if (!pending) {
2024 pending = true;
2025 timerFunc();
2026 }
2027 // $flow-disable-line
2028 if (!cb && typeof Promise !== 'undefined') {
2029 return new Promise(resolve => {
2030 _resolve = resolve;
2031 })
2032 }
2033}
2034
2035/* */
2036
2037let mark;
2038let measure;
2039
2040{
2041 const perf = inBrowser && window.performance;
2042 /* istanbul ignore if */
2043 if (
2044 perf &&
2045 perf.mark &&
2046 perf.measure &&
2047 perf.clearMarks &&
2048 perf.clearMeasures
2049 ) {
2050 mark = tag => perf.mark(tag);
2051 measure = (name, startTag, endTag) => {
2052 perf.measure(name, startTag, endTag);
2053 perf.clearMarks(startTag);
2054 perf.clearMarks(endTag);
2055 // perf.clearMeasures(name)
2056 };
2057 }
2058}
2059
2060/* not type checking this file because flow doesn't play well with Proxy */
2061
2062let initProxy;
2063
2064{
2065 const allowedGlobals = makeMap(
2066 'Infinity,undefined,NaN,isFinite,isNaN,' +
2067 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
2068 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
2069 'require' // for Webpack/Browserify
2070 );
2071
2072 const warnNonPresent = (target, key) => {
2073 warn(
2074 `Property or method "${key}" is not defined on the instance but ` +
2075 'referenced during render. Make sure that this property is reactive, ' +
2076 'either in the data option, or for class-based components, by ' +
2077 'initializing the property. ' +
2078 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
2079 target
2080 );
2081 };
2082
2083 const warnReservedPrefix = (target, key) => {
2084 warn(
2085 `Property "${key}" must be accessed with "$data.${key}" because ` +
2086 'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
2087 'prevent conflicts with Vue internals' +
2088 'See: https://vuejs.org/v2/api/#data',
2089 target
2090 );
2091 };
2092
2093 const hasProxy =
2094 typeof Proxy !== 'undefined' && isNative(Proxy);
2095
2096 if (hasProxy) {
2097 const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact');
2098 config.keyCodes = new Proxy(config.keyCodes, {
2099 set (target, key, value) {
2100 if (isBuiltInModifier(key)) {
2101 warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`);
2102 return false
2103 } else {
2104 target[key] = value;
2105 return true
2106 }
2107 }
2108 });
2109 }
2110
2111 const hasHandler = {
2112 has (target, key) {
2113 const has = key in target;
2114 const isAllowed = allowedGlobals(key) ||
2115 (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data));
2116 if (!has && !isAllowed) {
2117 if (key in target.$data) warnReservedPrefix(target, key);
2118 else warnNonPresent(target, key);
2119 }
2120 return has || !isAllowed
2121 }
2122 };
2123
2124 const getHandler = {
2125 get (target, key) {
2126 if (typeof key === 'string' && !(key in target)) {
2127 if (key in target.$data) warnReservedPrefix(target, key);
2128 else warnNonPresent(target, key);
2129 }
2130 return target[key]
2131 }
2132 };
2133
2134 initProxy = function initProxy (vm) {
2135 if (hasProxy) {
2136 // determine which proxy handler to use
2137 const options = vm.$options;
2138 const handlers = options.render && options.render._withStripped
2139 ? getHandler
2140 : hasHandler;
2141 vm._renderProxy = new Proxy(vm, handlers);
2142 } else {
2143 vm._renderProxy = vm;
2144 }
2145 };
2146}
2147
2148/* */
2149
2150const seenObjects = new _Set();
2151
2152/**
2153 * Recursively traverse an object to evoke all converted
2154 * getters, so that every nested property inside the object
2155 * is collected as a "deep" dependency.
2156 */
2157function traverse (val) {
2158 _traverse(val, seenObjects);
2159 seenObjects.clear();
2160}
2161
2162function _traverse (val, seen) {
2163 let i, keys;
2164 const isA = Array.isArray(val);
2165 if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
2166 return
2167 }
2168 if (val.__ob__) {
2169 const depId = val.__ob__.dep.id;
2170 if (seen.has(depId)) {
2171 return
2172 }
2173 seen.add(depId);
2174 }
2175 if (isA) {
2176 i = val.length;
2177 while (i--) _traverse(val[i], seen);
2178 } else {
2179 keys = Object.keys(val);
2180 i = keys.length;
2181 while (i--) _traverse(val[keys[i]], seen);
2182 }
2183}
2184
2185/* */
2186
2187const normalizeEvent = cached((name) => {
2188 const passive = name.charAt(0) === '&';
2189 name = passive ? name.slice(1) : name;
2190 const once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first
2191 name = once$$1 ? name.slice(1) : name;
2192 const capture = name.charAt(0) === '!';
2193 name = capture ? name.slice(1) : name;
2194 return {
2195 name,
2196 once: once$$1,
2197 capture,
2198 passive
2199 }
2200});
2201
2202function createFnInvoker (fns, vm) {
2203 function invoker () {
2204 const fns = invoker.fns;
2205 if (Array.isArray(fns)) {
2206 const cloned = fns.slice();
2207 for (let i = 0; i < cloned.length; i++) {
2208 invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`);
2209 }
2210 } else {
2211 // return handler return value for single handlers
2212 return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)
2213 }
2214 }
2215 invoker.fns = fns;
2216 return invoker
2217}
2218
2219function updateListeners (
2220 on,
2221 oldOn,
2222 add,
2223 remove$$1,
2224 createOnceHandler,
2225 vm
2226) {
2227 let name, def$$1, cur, old, event;
2228 for (name in on) {
2229 def$$1 = cur = on[name];
2230 old = oldOn[name];
2231 event = normalizeEvent(name);
2232 if (isUndef(cur)) {
2233 warn(
2234 `Invalid handler for event "${event.name}": got ` + String(cur),
2235 vm
2236 );
2237 } else if (isUndef(old)) {
2238 if (isUndef(cur.fns)) {
2239 cur = on[name] = createFnInvoker(cur, vm);
2240 }
2241 if (isTrue(event.once)) {
2242 cur = on[name] = createOnceHandler(event.name, cur, event.capture);
2243 }
2244 add(event.name, cur, event.capture, event.passive, event.params);
2245 } else if (cur !== old) {
2246 old.fns = cur;
2247 on[name] = old;
2248 }
2249 }
2250 for (name in oldOn) {
2251 if (isUndef(on[name])) {
2252 event = normalizeEvent(name);
2253 remove$$1(event.name, oldOn[name], event.capture);
2254 }
2255 }
2256}
2257
2258/* */
2259
2260function mergeVNodeHook (def, hookKey, hook) {
2261 if (def instanceof VNode) {
2262 def = def.data.hook || (def.data.hook = {});
2263 }
2264 let invoker;
2265 const oldHook = def[hookKey];
2266
2267 function wrappedHook () {
2268 hook.apply(this, arguments);
2269 // important: remove merged hook to ensure it's called only once
2270 // and prevent memory leak
2271 remove(invoker.fns, wrappedHook);
2272 }
2273
2274 if (isUndef(oldHook)) {
2275 // no existing hook
2276 invoker = createFnInvoker([wrappedHook]);
2277 } else {
2278 /* istanbul ignore if */
2279 if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
2280 // already a merged invoker
2281 invoker = oldHook;
2282 invoker.fns.push(wrappedHook);
2283 } else {
2284 // existing plain hook
2285 invoker = createFnInvoker([oldHook, wrappedHook]);
2286 }
2287 }
2288
2289 invoker.merged = true;
2290 def[hookKey] = invoker;
2291}
2292
2293/* */
2294
2295function extractPropsFromVNodeData (
2296 data,
2297 Ctor,
2298 tag
2299) {
2300 // we are only extracting raw values here.
2301 // validation and default values are handled in the child
2302 // component itself.
2303 const propOptions = Ctor.options.props;
2304 if (isUndef(propOptions)) {
2305 return
2306 }
2307 const res = {};
2308 const { attrs, props } = data;
2309 if (isDef(attrs) || isDef(props)) {
2310 for (const key in propOptions) {
2311 const altKey = hyphenate(key);
2312 {
2313 const keyInLowerCase = key.toLowerCase();
2314 if (
2315 key !== keyInLowerCase &&
2316 attrs && hasOwn(attrs, keyInLowerCase)
2317 ) {
2318 tip(
2319 `Prop "${keyInLowerCase}" is passed to component ` +
2320 `${formatComponentName(tag || Ctor)}, but the declared prop name is` +
2321 ` "${key}". ` +
2322 `Note that HTML attributes are case-insensitive and camelCased ` +
2323 `props need to use their kebab-case equivalents when using in-DOM ` +
2324 `templates. You should probably use "${altKey}" instead of "${key}".`
2325 );
2326 }
2327 }
2328 checkProp(res, props, key, altKey, true) ||
2329 checkProp(res, attrs, key, altKey, false);
2330 }
2331 }
2332 return res
2333}
2334
2335function checkProp (
2336 res,
2337 hash,
2338 key,
2339 altKey,
2340 preserve
2341) {
2342 if (isDef(hash)) {
2343 if (hasOwn(hash, key)) {
2344 res[key] = hash[key];
2345 if (!preserve) {
2346 delete hash[key];
2347 }
2348 return true
2349 } else if (hasOwn(hash, altKey)) {
2350 res[key] = hash[altKey];
2351 if (!preserve) {
2352 delete hash[altKey];
2353 }
2354 return true
2355 }
2356 }
2357 return false
2358}
2359
2360/* */
2361
2362// The template compiler attempts to minimize the need for normalization by
2363// statically analyzing the template at compile time.
2364//
2365// For plain HTML markup, normalization can be completely skipped because the
2366// generated render function is guaranteed to return Array<VNode>. There are
2367// two cases where extra normalization is needed:
2368
2369// 1. When the children contains components - because a functional component
2370// may return an Array instead of a single root. In this case, just a simple
2371// normalization is needed - if any child is an Array, we flatten the whole
2372// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
2373// because functional components already normalize their own children.
2374function simpleNormalizeChildren (children) {
2375 for (let i = 0; i < children.length; i++) {
2376 if (Array.isArray(children[i])) {
2377 return Array.prototype.concat.apply([], children)
2378 }
2379 }
2380 return children
2381}
2382
2383// 2. When the children contains constructs that always generated nested Arrays,
2384// e.g. <template>, <slot>, v-for, or when the children is provided by user
2385// with hand-written render functions / JSX. In such cases a full normalization
2386// is needed to cater to all possible types of children values.
2387function normalizeChildren (children) {
2388 return isPrimitive(children)
2389 ? [createTextVNode(children)]
2390 : Array.isArray(children)
2391 ? normalizeArrayChildren(children)
2392 : undefined
2393}
2394
2395function isTextNode (node) {
2396 return isDef(node) && isDef(node.text) && isFalse(node.isComment)
2397}
2398
2399function normalizeArrayChildren (children, nestedIndex) {
2400 const res = [];
2401 let i, c, lastIndex, last;
2402 for (i = 0; i < children.length; i++) {
2403 c = children[i];
2404 if (isUndef(c) || typeof c === 'boolean') continue
2405 lastIndex = res.length - 1;
2406 last = res[lastIndex];
2407 // nested
2408 if (Array.isArray(c)) {
2409 if (c.length > 0) {
2410 c = normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`);
2411 // merge adjacent text nodes
2412 if (isTextNode(c[0]) && isTextNode(last)) {
2413 res[lastIndex] = createTextVNode(last.text + (c[0]).text);
2414 c.shift();
2415 }
2416 res.push.apply(res, c);
2417 }
2418 } else if (isPrimitive(c)) {
2419 if (isTextNode(last)) {
2420 // merge adjacent text nodes
2421 // this is necessary for SSR hydration because text nodes are
2422 // essentially merged when rendered to HTML strings
2423 res[lastIndex] = createTextVNode(last.text + c);
2424 } else if (c !== '') {
2425 // convert primitive to vnode
2426 res.push(createTextVNode(c));
2427 }
2428 } else {
2429 if (isTextNode(c) && isTextNode(last)) {
2430 // merge adjacent text nodes
2431 res[lastIndex] = createTextVNode(last.text + c.text);
2432 } else {
2433 // default key for nested array children (likely generated by v-for)
2434 if (isTrue(children._isVList) &&
2435 isDef(c.tag) &&
2436 isUndef(c.key) &&
2437 isDef(nestedIndex)) {
2438 c.key = `__vlist${nestedIndex}_${i}__`;
2439 }
2440 res.push(c);
2441 }
2442 }
2443 }
2444 return res
2445}
2446
2447/* */
2448
2449function initProvide (vm) {
2450 const provide = vm.$options.provide;
2451 if (provide) {
2452 vm._provided = typeof provide === 'function'
2453 ? provide.call(vm)
2454 : provide;
2455 }
2456}
2457
2458function initInjections (vm) {
2459 const result = resolveInject(vm.$options.inject, vm);
2460 if (result) {
2461 toggleObserving(false);
2462 Object.keys(result).forEach(key => {
2463 /* istanbul ignore else */
2464 {
2465 defineReactive$$1(vm, key, result[key], () => {
2466 warn(
2467 `Avoid mutating an injected value directly since the changes will be ` +
2468 `overwritten whenever the provided component re-renders. ` +
2469 `injection being mutated: "${key}"`,
2470 vm
2471 );
2472 });
2473 }
2474 });
2475 toggleObserving(true);
2476 }
2477}
2478
2479function resolveInject (inject, vm) {
2480 if (inject) {
2481 // inject is :any because flow is not smart enough to figure out cached
2482 const result = Object.create(null);
2483 const keys = hasSymbol
2484 ? Reflect.ownKeys(inject)
2485 : Object.keys(inject);
2486
2487 for (let i = 0; i < keys.length; i++) {
2488 const key = keys[i];
2489 // #6574 in case the inject object is observed...
2490 if (key === '__ob__') continue
2491 const provideKey = inject[key].from;
2492 let source = vm;
2493 while (source) {
2494 if (source._provided && hasOwn(source._provided, provideKey)) {
2495 result[key] = source._provided[provideKey];
2496 break
2497 }
2498 source = source.$parent;
2499 }
2500 if (!source) {
2501 if ('default' in inject[key]) {
2502 const provideDefault = inject[key].default;
2503 result[key] = typeof provideDefault === 'function'
2504 ? provideDefault.call(vm)
2505 : provideDefault;
2506 } else {
2507 warn(`Injection "${key}" not found`, vm);
2508 }
2509 }
2510 }
2511 return result
2512 }
2513}
2514
2515/* */
2516
2517
2518
2519/**
2520 * Runtime helper for resolving raw children VNodes into a slot object.
2521 */
2522function resolveSlots (
2523 children,
2524 context
2525) {
2526 if (!children || !children.length) {
2527 return {}
2528 }
2529 const slots = {};
2530 for (let i = 0, l = children.length; i < l; i++) {
2531 const child = children[i];
2532 const data = child.data;
2533 // remove slot attribute if the node is resolved as a Vue slot node
2534 if (data && data.attrs && data.attrs.slot) {
2535 delete data.attrs.slot;
2536 }
2537 // named slots should only be respected if the vnode was rendered in the
2538 // same context.
2539 if ((child.context === context || child.fnContext === context) &&
2540 data && data.slot != null
2541 ) {
2542 const name = data.slot;
2543 const slot = (slots[name] || (slots[name] = []));
2544 if (child.tag === 'template') {
2545 slot.push.apply(slot, child.children || []);
2546 } else {
2547 slot.push(child);
2548 }
2549 } else {
2550 (slots.default || (slots.default = [])).push(child);
2551 }
2552 }
2553 // ignore slots that contains only whitespace
2554 for (const name in slots) {
2555 if (slots[name].every(isWhitespace)) {
2556 delete slots[name];
2557 }
2558 }
2559 return slots
2560}
2561
2562function isWhitespace (node) {
2563 return (node.isComment && !node.asyncFactory) || node.text === ' '
2564}
2565
2566/* */
2567
2568function normalizeScopedSlots (
2569 slots,
2570 normalSlots,
2571 prevSlots
2572) {
2573 let res;
2574 const isStable = slots ? !!slots.$stable : true;
2575 const key = slots && slots.$key;
2576 if (!slots) {
2577 res = {};
2578 } else if (slots._normalized) {
2579 // fast path 1: child component re-render only, parent did not change
2580 return slots._normalized
2581 } else if (
2582 isStable &&
2583 prevSlots &&
2584 prevSlots !== emptyObject &&
2585 key === prevSlots.$key &&
2586 Object.keys(normalSlots).length === 0
2587 ) {
2588 // fast path 2: stable scoped slots w/ no normal slots to proxy,
2589 // only need to normalize once
2590 return prevSlots
2591 } else {
2592 res = {};
2593 for (const key in slots) {
2594 if (slots[key] && key[0] !== '$') {
2595 res[key] = normalizeScopedSlot(normalSlots, key, slots[key]);
2596 }
2597 }
2598 }
2599 // expose normal slots on scopedSlots
2600 for (const key in normalSlots) {
2601 if (!(key in res)) {
2602 res[key] = proxyNormalSlot(normalSlots, key);
2603 }
2604 }
2605 // avoriaz seems to mock a non-extensible $scopedSlots object
2606 // and when that is passed down this would cause an error
2607 if (slots && Object.isExtensible(slots)) {
2608 (slots)._normalized = res;
2609 }
2610 def(res, '$stable', isStable);
2611 def(res, '$key', key);
2612 return res
2613}
2614
2615function normalizeScopedSlot(normalSlots, key, fn) {
2616 const normalized = function () {
2617 let res = arguments.length ? fn.apply(null, arguments) : fn({});
2618 res = res && typeof res === 'object' && !Array.isArray(res)
2619 ? [res] // single vnode
2620 : normalizeChildren(res);
2621 return res && res.length === 0
2622 ? undefined
2623 : res
2624 };
2625 // this is a slot using the new v-slot syntax without scope. although it is
2626 // compiled as a scoped slot, render fn users would expect it to be present
2627 // on this.$slots because the usage is semantically a normal slot.
2628 if (fn.proxy) {
2629 Object.defineProperty(normalSlots, key, {
2630 get: normalized,
2631 enumerable: true,
2632 configurable: true
2633 });
2634 }
2635 return normalized
2636}
2637
2638function proxyNormalSlot(slots, key) {
2639 return () => slots[key]
2640}
2641
2642/* */
2643
2644/**
2645 * Runtime helper for rendering v-for lists.
2646 */
2647function renderList (
2648 val,
2649 render
2650) {
2651 let ret, i, l, keys, key;
2652 if (Array.isArray(val) || typeof val === 'string') {
2653 ret = new Array(val.length);
2654 for (i = 0, l = val.length; i < l; i++) {
2655 ret[i] = render(val[i], i);
2656 }
2657 } else if (typeof val === 'number') {
2658 ret = new Array(val);
2659 for (i = 0; i < val; i++) {
2660 ret[i] = render(i + 1, i);
2661 }
2662 } else if (isObject(val)) {
2663 if (hasSymbol && val[Symbol.iterator]) {
2664 ret = [];
2665 const iterator = val[Symbol.iterator]();
2666 let result = iterator.next();
2667 while (!result.done) {
2668 ret.push(render(result.value, ret.length));
2669 result = iterator.next();
2670 }
2671 } else {
2672 keys = Object.keys(val);
2673 ret = new Array(keys.length);
2674 for (i = 0, l = keys.length; i < l; i++) {
2675 key = keys[i];
2676 ret[i] = render(val[key], key, i);
2677 }
2678 }
2679 }
2680 if (!isDef(ret)) {
2681 ret = [];
2682 }
2683 (ret)._isVList = true;
2684 return ret
2685}
2686
2687/* */
2688
2689/**
2690 * Runtime helper for rendering <slot>
2691 */
2692function renderSlot (
2693 name,
2694 fallback,
2695 props,
2696 bindObject
2697) {
2698 const scopedSlotFn = this.$scopedSlots[name];
2699 let nodes;
2700 if (scopedSlotFn) { // scoped slot
2701 props = props || {};
2702 if (bindObject) {
2703 if (!isObject(bindObject)) {
2704 warn(
2705 'slot v-bind without argument expects an Object',
2706 this
2707 );
2708 }
2709 props = extend(extend({}, bindObject), props);
2710 }
2711 nodes = scopedSlotFn(props) || fallback;
2712 } else {
2713 nodes = this.$slots[name] || fallback;
2714 }
2715
2716 const target = props && props.slot;
2717 if (target) {
2718 return this.$createElement('template', { slot: target }, nodes)
2719 } else {
2720 return nodes
2721 }
2722}
2723
2724/* */
2725
2726/**
2727 * Runtime helper for resolving filters
2728 */
2729function resolveFilter (id) {
2730 return resolveAsset(this.$options, 'filters', id, true) || identity
2731}
2732
2733/* */
2734
2735function isKeyNotMatch (expect, actual) {
2736 if (Array.isArray(expect)) {
2737 return expect.indexOf(actual) === -1
2738 } else {
2739 return expect !== actual
2740 }
2741}
2742
2743/**
2744 * Runtime helper for checking keyCodes from config.
2745 * exposed as Vue.prototype._k
2746 * passing in eventKeyName as last argument separately for backwards compat
2747 */
2748function checkKeyCodes (
2749 eventKeyCode,
2750 key,
2751 builtInKeyCode,
2752 eventKeyName,
2753 builtInKeyName
2754) {
2755 const mappedKeyCode = config.keyCodes[key] || builtInKeyCode;
2756 if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
2757 return isKeyNotMatch(builtInKeyName, eventKeyName)
2758 } else if (mappedKeyCode) {
2759 return isKeyNotMatch(mappedKeyCode, eventKeyCode)
2760 } else if (eventKeyName) {
2761 return hyphenate(eventKeyName) !== key
2762 }
2763}
2764
2765/* */
2766
2767/**
2768 * Runtime helper for merging v-bind="object" into a VNode's data.
2769 */
2770function bindObjectProps (
2771 data,
2772 tag,
2773 value,
2774 asProp,
2775 isSync
2776) {
2777 if (value) {
2778 if (!isObject(value)) {
2779 warn(
2780 'v-bind without argument expects an Object or Array value',
2781 this
2782 );
2783 } else {
2784 if (Array.isArray(value)) {
2785 value = toObject(value);
2786 }
2787 let hash;
2788 for (const key in value) {
2789 if (
2790 key === 'class' ||
2791 key === 'style' ||
2792 isReservedAttribute(key)
2793 ) {
2794 hash = data;
2795 } else {
2796 const type = data.attrs && data.attrs.type;
2797 hash = asProp || config.mustUseProp(tag, type, key)
2798 ? data.domProps || (data.domProps = {})
2799 : data.attrs || (data.attrs = {});
2800 }
2801 const camelizedKey = camelize(key);
2802 if (!(key in hash) && !(camelizedKey in hash)) {
2803 hash[key] = value[key];
2804
2805 if (isSync) {
2806 const on = data.on || (data.on = {});
2807 on[`update:${camelizedKey}`] = function ($event) {
2808 value[key] = $event;
2809 };
2810 }
2811 }
2812 }
2813 }
2814 }
2815 return data
2816}
2817
2818/* */
2819
2820/**
2821 * Runtime helper for rendering static trees.
2822 */
2823function renderStatic (
2824 index,
2825 isInFor
2826) {
2827 const cached = this._staticTrees || (this._staticTrees = []);
2828 let tree = cached[index];
2829 // if has already-rendered static tree and not inside v-for,
2830 // we can reuse the same tree.
2831 if (tree && !isInFor) {
2832 return tree
2833 }
2834 // otherwise, render a fresh tree.
2835 tree = cached[index] = this.$options.staticRenderFns[index].call(
2836 this._renderProxy,
2837 null,
2838 this // for render fns generated for functional component templates
2839 );
2840 markStatic(tree, `__static__${index}`, false);
2841 return tree
2842}
2843
2844/**
2845 * Runtime helper for v-once.
2846 * Effectively it means marking the node as static with a unique key.
2847 */
2848function markOnce (
2849 tree,
2850 index,
2851 key
2852) {
2853 markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true);
2854 return tree
2855}
2856
2857function markStatic (
2858 tree,
2859 key,
2860 isOnce
2861) {
2862 if (Array.isArray(tree)) {
2863 for (let i = 0; i < tree.length; i++) {
2864 if (tree[i] && typeof tree[i] !== 'string') {
2865 markStaticNode(tree[i], `${key}_${i}`, isOnce);
2866 }
2867 }
2868 } else {
2869 markStaticNode(tree, key, isOnce);
2870 }
2871}
2872
2873function markStaticNode (node, key, isOnce) {
2874 node.isStatic = true;
2875 node.key = key;
2876 node.isOnce = isOnce;
2877}
2878
2879/* */
2880
2881function bindObjectListeners (data, value) {
2882 if (value) {
2883 if (!isPlainObject(value)) {
2884 warn(
2885 'v-on without argument expects an Object value',
2886 this
2887 );
2888 } else {
2889 const on = data.on = data.on ? extend({}, data.on) : {};
2890 for (const key in value) {
2891 const existing = on[key];
2892 const ours = value[key];
2893 on[key] = existing ? [].concat(existing, ours) : ours;
2894 }
2895 }
2896 }
2897 return data
2898}
2899
2900/* */
2901
2902function resolveScopedSlots (
2903 fns, // see flow/vnode
2904 res,
2905 // the following are added in 2.6
2906 hasDynamicKeys,
2907 contentHashKey
2908) {
2909 res = res || { $stable: !hasDynamicKeys };
2910 for (let i = 0; i < fns.length; i++) {
2911 const slot = fns[i];
2912 if (Array.isArray(slot)) {
2913 resolveScopedSlots(slot, res, hasDynamicKeys);
2914 } else if (slot) {
2915 // marker for reverse proxying v-slot without scope on this.$slots
2916 if (slot.proxy) {
2917 slot.fn.proxy = true;
2918 }
2919 res[slot.key] = slot.fn;
2920 }
2921 }
2922 if (contentHashKey) {
2923 (res).$key = contentHashKey;
2924 }
2925 return res
2926}
2927
2928/* */
2929
2930function bindDynamicKeys (baseObj, values) {
2931 for (let i = 0; i < values.length; i += 2) {
2932 const key = values[i];
2933 if (typeof key === 'string' && key) {
2934 baseObj[values[i]] = values[i + 1];
2935 } else if (key !== '' && key !== null) {
2936 // null is a speical value for explicitly removing a binding
2937 warn(
2938 `Invalid value for dynamic directive argument (expected string or null): ${key}`,
2939 this
2940 );
2941 }
2942 }
2943 return baseObj
2944}
2945
2946// helper to dynamically append modifier runtime markers to event names.
2947// ensure only append when value is already string, otherwise it will be cast
2948// to string and cause the type check to miss.
2949function prependModifier (value, symbol) {
2950 return typeof value === 'string' ? symbol + value : value
2951}
2952
2953/* */
2954
2955function installRenderHelpers (target) {
2956 target._o = markOnce;
2957 target._n = toNumber;
2958 target._s = toString;
2959 target._l = renderList;
2960 target._t = renderSlot;
2961 target._q = looseEqual;
2962 target._i = looseIndexOf;
2963 target._m = renderStatic;
2964 target._f = resolveFilter;
2965 target._k = checkKeyCodes;
2966 target._b = bindObjectProps;
2967 target._v = createTextVNode;
2968 target._e = createEmptyVNode;
2969 target._u = resolveScopedSlots;
2970 target._g = bindObjectListeners;
2971 target._d = bindDynamicKeys;
2972 target._p = prependModifier;
2973}
2974
2975/* */
2976
2977function FunctionalRenderContext (
2978 data,
2979 props,
2980 children,
2981 parent,
2982 Ctor
2983) {
2984 const options = Ctor.options;
2985 // ensure the createElement function in functional components
2986 // gets a unique context - this is necessary for correct named slot check
2987 let contextVm;
2988 if (hasOwn(parent, '_uid')) {
2989 contextVm = Object.create(parent);
2990 // $flow-disable-line
2991 contextVm._original = parent;
2992 } else {
2993 // the context vm passed in is a functional context as well.
2994 // in this case we want to make sure we are able to get a hold to the
2995 // real context instance.
2996 contextVm = parent;
2997 // $flow-disable-line
2998 parent = parent._original;
2999 }
3000 const isCompiled = isTrue(options._compiled);
3001 const needNormalization = !isCompiled;
3002
3003 this.data = data;
3004 this.props = props;
3005 this.children = children;
3006 this.parent = parent;
3007 this.listeners = data.on || emptyObject;
3008 this.injections = resolveInject(options.inject, parent);
3009 this.slots = () => {
3010 if (!this.$slots) {
3011 normalizeScopedSlots(
3012 data.scopedSlots,
3013 this.$slots = resolveSlots(children, parent)
3014 );
3015 }
3016 return this.$slots
3017 };
3018
3019 Object.defineProperty(this, 'scopedSlots', ({
3020 enumerable: true,
3021 get () {
3022 return normalizeScopedSlots(data.scopedSlots, this.slots())
3023 }
3024 }));
3025
3026 // support for compiled functional template
3027 if (isCompiled) {
3028 // exposing $options for renderStatic()
3029 this.$options = options;
3030 // pre-resolve slots for renderSlot()
3031 this.$slots = this.slots();
3032 this.$scopedSlots = normalizeScopedSlots(data.scopedSlots, this.$slots);
3033 }
3034
3035 if (options._scopeId) {
3036 this._c = (a, b, c, d) => {
3037 const vnode = createElement(contextVm, a, b, c, d, needNormalization);
3038 if (vnode && !Array.isArray(vnode)) {
3039 vnode.fnScopeId = options._scopeId;
3040 vnode.fnContext = parent;
3041 }
3042 return vnode
3043 };
3044 } else {
3045 this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization);
3046 }
3047}
3048
3049installRenderHelpers(FunctionalRenderContext.prototype);
3050
3051function createFunctionalComponent (
3052 Ctor,
3053 propsData,
3054 data,
3055 contextVm,
3056 children
3057) {
3058 const options = Ctor.options;
3059 const props = {};
3060 const propOptions = options.props;
3061 if (isDef(propOptions)) {
3062 for (const key in propOptions) {
3063 props[key] = validateProp(key, propOptions, propsData || emptyObject);
3064 }
3065 } else {
3066 if (isDef(data.attrs)) mergeProps(props, data.attrs);
3067 if (isDef(data.props)) mergeProps(props, data.props);
3068 }
3069
3070 const renderContext = new FunctionalRenderContext(
3071 data,
3072 props,
3073 children,
3074 contextVm,
3075 Ctor
3076 );
3077
3078 const vnode = options.render.call(null, renderContext._c, renderContext);
3079
3080 if (vnode instanceof VNode) {
3081 return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options, renderContext)
3082 } else if (Array.isArray(vnode)) {
3083 const vnodes = normalizeChildren(vnode) || [];
3084 const res = new Array(vnodes.length);
3085 for (let i = 0; i < vnodes.length; i++) {
3086 res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options, renderContext);
3087 }
3088 return res
3089 }
3090}
3091
3092function cloneAndMarkFunctionalResult (vnode, data, contextVm, options, renderContext) {
3093 // #7817 clone node before setting fnContext, otherwise if the node is reused
3094 // (e.g. it was from a cached normal slot) the fnContext causes named slots
3095 // that should not be matched to match.
3096 const clone = cloneVNode(vnode);
3097 clone.fnContext = contextVm;
3098 clone.fnOptions = options;
3099 {
3100 (clone.devtoolsMeta = clone.devtoolsMeta || {}).renderContext = renderContext;
3101 }
3102 if (data.slot) {
3103 (clone.data || (clone.data = {})).slot = data.slot;
3104 }
3105 return clone
3106}
3107
3108function mergeProps (to, from) {
3109 for (const key in from) {
3110 to[camelize(key)] = from[key];
3111 }
3112}
3113
3114/* */
3115
3116/* */
3117
3118/* */
3119
3120/* */
3121
3122// inline hooks to be invoked on component VNodes during patch
3123const componentVNodeHooks = {
3124 init (vnode, hydrating) {
3125 if (
3126 vnode.componentInstance &&
3127 !vnode.componentInstance._isDestroyed &&
3128 vnode.data.keepAlive
3129 ) {
3130 // kept-alive components, treat as a patch
3131 const mountedNode = vnode; // work around flow
3132 componentVNodeHooks.prepatch(mountedNode, mountedNode);
3133 } else {
3134 const child = vnode.componentInstance = createComponentInstanceForVnode(
3135 vnode,
3136 activeInstance
3137 );
3138 child.$mount(hydrating ? vnode.elm : undefined, hydrating);
3139 }
3140 },
3141
3142 prepatch (oldVnode, vnode) {
3143 const options = vnode.componentOptions;
3144 const child = vnode.componentInstance = oldVnode.componentInstance;
3145 updateChildComponent(
3146 child,
3147 options.propsData, // updated props
3148 options.listeners, // updated listeners
3149 vnode, // new parent vnode
3150 options.children // new children
3151 );
3152 },
3153
3154 insert (vnode) {
3155 const { context, componentInstance } = vnode;
3156 if (!componentInstance._isMounted) {
3157 componentInstance._isMounted = true;
3158 callHook(componentInstance, 'mounted');
3159 }
3160 if (vnode.data.keepAlive) {
3161 if (context._isMounted) {
3162 // vue-router#1212
3163 // During updates, a kept-alive component's child components may
3164 // change, so directly walking the tree here may call activated hooks
3165 // on incorrect children. Instead we push them into a queue which will
3166 // be processed after the whole patch process ended.
3167 queueActivatedComponent(componentInstance);
3168 } else {
3169 activateChildComponent(componentInstance, true /* direct */);
3170 }
3171 }
3172 },
3173
3174 destroy (vnode) {
3175 const { componentInstance } = vnode;
3176 if (!componentInstance._isDestroyed) {
3177 if (!vnode.data.keepAlive) {
3178 componentInstance.$destroy();
3179 } else {
3180 deactivateChildComponent(componentInstance, true /* direct */);
3181 }
3182 }
3183 }
3184};
3185
3186const hooksToMerge = Object.keys(componentVNodeHooks);
3187
3188function createComponent (
3189 Ctor,
3190 data,
3191 context,
3192 children,
3193 tag
3194) {
3195 if (isUndef(Ctor)) {
3196 return
3197 }
3198
3199 const baseCtor = context.$options._base;
3200
3201 // plain options object: turn it into a constructor
3202 if (isObject(Ctor)) {
3203 Ctor = baseCtor.extend(Ctor);
3204 }
3205
3206 // if at this stage it's not a constructor or an async component factory,
3207 // reject.
3208 if (typeof Ctor !== 'function') {
3209 {
3210 warn(`Invalid Component definition: ${String(Ctor)}`, context);
3211 }
3212 return
3213 }
3214
3215 // async component
3216 let asyncFactory;
3217 if (isUndef(Ctor.cid)) {
3218 asyncFactory = Ctor;
3219 Ctor = resolveAsyncComponent(asyncFactory, baseCtor);
3220 if (Ctor === undefined) {
3221 // return a placeholder node for async component, which is rendered
3222 // as a comment node but preserves all the raw information for the node.
3223 // the information will be used for async server-rendering and hydration.
3224 return createAsyncPlaceholder(
3225 asyncFactory,
3226 data,
3227 context,
3228 children,
3229 tag
3230 )
3231 }
3232 }
3233
3234 data = data || {};
3235
3236 // resolve constructor options in case global mixins are applied after
3237 // component constructor creation
3238 resolveConstructorOptions(Ctor);
3239
3240 // transform component v-model data into props & events
3241 if (isDef(data.model)) {
3242 transformModel(Ctor.options, data);
3243 }
3244
3245 // extract props
3246 const propsData = extractPropsFromVNodeData(data, Ctor, tag);
3247
3248 // functional component
3249 if (isTrue(Ctor.options.functional)) {
3250 return createFunctionalComponent(Ctor, propsData, data, context, children)
3251 }
3252
3253 // extract listeners, since these needs to be treated as
3254 // child component listeners instead of DOM listeners
3255 const listeners = data.on;
3256 // replace with listeners with .native modifier
3257 // so it gets processed during parent component patch.
3258 data.on = data.nativeOn;
3259
3260 if (isTrue(Ctor.options.abstract)) {
3261 // abstract components do not keep anything
3262 // other than props & listeners & slot
3263
3264 // work around flow
3265 const slot = data.slot;
3266 data = {};
3267 if (slot) {
3268 data.slot = slot;
3269 }
3270 }
3271
3272 // install component management hooks onto the placeholder node
3273 installComponentHooks(data);
3274
3275 // return a placeholder vnode
3276 const name = Ctor.options.name || tag;
3277 const vnode = new VNode(
3278 `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
3279 data, undefined, undefined, undefined, context,
3280 { Ctor, propsData, listeners, tag, children },
3281 asyncFactory
3282 );
3283
3284 return vnode
3285}
3286
3287function createComponentInstanceForVnode (
3288 vnode, // we know it's MountedComponentVNode but flow doesn't
3289 parent, // activeInstance in lifecycle state
3290) {
3291 const options = {
3292 _isComponent: true,
3293 _parentVnode: vnode,
3294 parent
3295 };
3296 // check inline-template render functions
3297 const inlineTemplate = vnode.data.inlineTemplate;
3298 if (isDef(inlineTemplate)) {
3299 options.render = inlineTemplate.render;
3300 options.staticRenderFns = inlineTemplate.staticRenderFns;
3301 }
3302 return new vnode.componentOptions.Ctor(options)
3303}
3304
3305function installComponentHooks (data) {
3306 const hooks = data.hook || (data.hook = {});
3307 for (let i = 0; i < hooksToMerge.length; i++) {
3308 const key = hooksToMerge[i];
3309 const existing = hooks[key];
3310 const toMerge = componentVNodeHooks[key];
3311 if (existing !== toMerge && !(existing && existing._merged)) {
3312 hooks[key] = existing ? mergeHook$1(toMerge, existing) : toMerge;
3313 }
3314 }
3315}
3316
3317function mergeHook$1 (f1, f2) {
3318 const merged = (a, b) => {
3319 // flow complains about extra args which is why we use any
3320 f1(a, b);
3321 f2(a, b);
3322 };
3323 merged._merged = true;
3324 return merged
3325}
3326
3327// transform component v-model info (value and callback) into
3328// prop and event handler respectively.
3329function transformModel (options, data) {
3330 const prop = (options.model && options.model.prop) || 'value';
3331 const event = (options.model && options.model.event) || 'input'
3332 ;(data.attrs || (data.attrs = {}))[prop] = data.model.value;
3333 const on = data.on || (data.on = {});
3334 const existing = on[event];
3335 const callback = data.model.callback;
3336 if (isDef(existing)) {
3337 if (
3338 Array.isArray(existing)
3339 ? existing.indexOf(callback) === -1
3340 : existing !== callback
3341 ) {
3342 on[event] = [callback].concat(existing);
3343 }
3344 } else {
3345 on[event] = callback;
3346 }
3347}
3348
3349/* */
3350
3351const SIMPLE_NORMALIZE = 1;
3352const ALWAYS_NORMALIZE = 2;
3353
3354// wrapper function for providing a more flexible interface
3355// without getting yelled at by flow
3356function createElement (
3357 context,
3358 tag,
3359 data,
3360 children,
3361 normalizationType,
3362 alwaysNormalize
3363) {
3364 if (Array.isArray(data) || isPrimitive(data)) {
3365 normalizationType = children;
3366 children = data;
3367 data = undefined;
3368 }
3369 if (isTrue(alwaysNormalize)) {
3370 normalizationType = ALWAYS_NORMALIZE;
3371 }
3372 return _createElement(context, tag, data, children, normalizationType)
3373}
3374
3375function _createElement (
3376 context,
3377 tag,
3378 data,
3379 children,
3380 normalizationType
3381) {
3382 if (isDef(data) && isDef((data).__ob__)) {
3383 warn(
3384 `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
3385 'Always create fresh vnode data objects in each render!',
3386 context
3387 );
3388 return createEmptyVNode()
3389 }
3390 // object syntax in v-bind
3391 if (isDef(data) && isDef(data.is)) {
3392 tag = data.is;
3393 }
3394 if (!tag) {
3395 // in case of component :is set to falsy value
3396 return createEmptyVNode()
3397 }
3398 // warn against non-primitive key
3399 if (isDef(data) && isDef(data.key) && !isPrimitive(data.key)
3400 ) {
3401 {
3402 warn(
3403 'Avoid using non-primitive value as key, ' +
3404 'use string/number value instead.',
3405 context
3406 );
3407 }
3408 }
3409 // support single function children as default scoped slot
3410 if (Array.isArray(children) &&
3411 typeof children[0] === 'function'
3412 ) {
3413 data = data || {};
3414 data.scopedSlots = { default: children[0] };
3415 children.length = 0;
3416 }
3417 if (normalizationType === ALWAYS_NORMALIZE) {
3418 children = normalizeChildren(children);
3419 } else if (normalizationType === SIMPLE_NORMALIZE) {
3420 children = simpleNormalizeChildren(children);
3421 }
3422 let vnode, ns;
3423 if (typeof tag === 'string') {
3424 let Ctor;
3425 ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
3426 if (config.isReservedTag(tag)) {
3427 // platform built-in elements
3428 vnode = new VNode(
3429 config.parsePlatformTagName(tag), data, children,
3430 undefined, undefined, context
3431 );
3432 } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
3433 // component
3434 vnode = createComponent(Ctor, data, context, children, tag);
3435 } else {
3436 // unknown or unlisted namespaced elements
3437 // check at runtime because it may get assigned a namespace when its
3438 // parent normalizes children
3439 vnode = new VNode(
3440 tag, data, children,
3441 undefined, undefined, context
3442 );
3443 }
3444 } else {
3445 // direct component options / constructor
3446 vnode = createComponent(tag, data, context, children);
3447 }
3448 if (Array.isArray(vnode)) {
3449 return vnode
3450 } else if (isDef(vnode)) {
3451 if (isDef(ns)) applyNS(vnode, ns);
3452 if (isDef(data)) registerDeepBindings(data);
3453 return vnode
3454 } else {
3455 return createEmptyVNode()
3456 }
3457}
3458
3459function applyNS (vnode, ns, force) {
3460 vnode.ns = ns;
3461 if (vnode.tag === 'foreignObject') {
3462 // use default namespace inside foreignObject
3463 ns = undefined;
3464 force = true;
3465 }
3466 if (isDef(vnode.children)) {
3467 for (let i = 0, l = vnode.children.length; i < l; i++) {
3468 const child = vnode.children[i];
3469 if (isDef(child.tag) && (
3470 isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) {
3471 applyNS(child, ns, force);
3472 }
3473 }
3474 }
3475}
3476
3477// ref #5318
3478// necessary to ensure parent re-render when deep bindings like :style and
3479// :class are used on slot nodes
3480function registerDeepBindings (data) {
3481 if (isObject(data.style)) {
3482 traverse(data.style);
3483 }
3484 if (isObject(data.class)) {
3485 traverse(data.class);
3486 }
3487}
3488
3489/* */
3490
3491function initRender (vm) {
3492 vm._vnode = null; // the root of the child tree
3493 vm._staticTrees = null; // v-once cached trees
3494 const options = vm.$options;
3495 const parentVnode = vm.$vnode = options._parentVnode; // the placeholder node in parent tree
3496 const renderContext = parentVnode && parentVnode.context;
3497 vm.$slots = resolveSlots(options._renderChildren, renderContext);
3498 vm.$scopedSlots = emptyObject;
3499 // bind the createElement fn to this instance
3500 // so that we get proper render context inside it.
3501 // args order: tag, data, children, normalizationType, alwaysNormalize
3502 // internal version is used by render functions compiled from templates
3503 vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false);
3504 // normalization is always applied for the public version, used in
3505 // user-written render functions.
3506 vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true);
3507
3508 // $attrs & $listeners are exposed for easier HOC creation.
3509 // they need to be reactive so that HOCs using them are always updated
3510 const parentData = parentVnode && parentVnode.data;
3511
3512 /* istanbul ignore else */
3513 {
3514 defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
3515 !isUpdatingChildComponent && warn(`$attrs is readonly.`, vm);
3516 }, true);
3517 defineReactive$$1(vm, '$listeners', options._parentListeners || emptyObject, () => {
3518 !isUpdatingChildComponent && warn(`$listeners is readonly.`, vm);
3519 }, true);
3520 }
3521}
3522
3523let currentRenderingInstance = null;
3524
3525function renderMixin (Vue) {
3526 // install runtime convenience helpers
3527 installRenderHelpers(Vue.prototype);
3528
3529 Vue.prototype.$nextTick = function (fn) {
3530 return nextTick(fn, this)
3531 };
3532
3533 Vue.prototype._render = function () {
3534 const vm = this;
3535 const { render, _parentVnode } = vm.$options;
3536
3537 if (_parentVnode) {
3538 vm.$scopedSlots = normalizeScopedSlots(
3539 _parentVnode.data.scopedSlots,
3540 vm.$slots,
3541 vm.$scopedSlots
3542 );
3543 }
3544
3545 // set parent vnode. this allows render functions to have access
3546 // to the data on the placeholder node.
3547 vm.$vnode = _parentVnode;
3548 // render self
3549 let vnode;
3550 try {
3551 // There's no need to maintain a stack becaues all render fns are called
3552 // separately from one another. Nested component's render fns are called
3553 // when parent component is patched.
3554 currentRenderingInstance = vm;
3555 vnode = render.call(vm._renderProxy, vm.$createElement);
3556 } catch (e) {
3557 handleError(e, vm, `render`);
3558 // return error render result,
3559 // or previous vnode to prevent render error causing blank component
3560 /* istanbul ignore else */
3561 if (vm.$options.renderError) {
3562 try {
3563 vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e);
3564 } catch (e) {
3565 handleError(e, vm, `renderError`);
3566 vnode = vm._vnode;
3567 }
3568 } else {
3569 vnode = vm._vnode;
3570 }
3571 } finally {
3572 currentRenderingInstance = null;
3573 }
3574 // if the returned array contains only a single node, allow it
3575 if (Array.isArray(vnode) && vnode.length === 1) {
3576 vnode = vnode[0];
3577 }
3578 // return empty vnode in case the render function errored out
3579 if (!(vnode instanceof VNode)) {
3580 if (Array.isArray(vnode)) {
3581 warn(
3582 'Multiple root nodes returned from render function. Render function ' +
3583 'should return a single root node.',
3584 vm
3585 );
3586 }
3587 vnode = createEmptyVNode();
3588 }
3589 // set parent
3590 vnode.parent = _parentVnode;
3591 return vnode
3592 };
3593}
3594
3595/* */
3596
3597function ensureCtor (comp, base) {
3598 if (
3599 comp.__esModule ||
3600 (hasSymbol && comp[Symbol.toStringTag] === 'Module')
3601 ) {
3602 comp = comp.default;
3603 }
3604 return isObject(comp)
3605 ? base.extend(comp)
3606 : comp
3607}
3608
3609function createAsyncPlaceholder (
3610 factory,
3611 data,
3612 context,
3613 children,
3614 tag
3615) {
3616 const node = createEmptyVNode();
3617 node.asyncFactory = factory;
3618 node.asyncMeta = { data, context, children, tag };
3619 return node
3620}
3621
3622function resolveAsyncComponent (
3623 factory,
3624 baseCtor
3625) {
3626 if (isTrue(factory.error) && isDef(factory.errorComp)) {
3627 return factory.errorComp
3628 }
3629
3630 if (isDef(factory.resolved)) {
3631 return factory.resolved
3632 }
3633
3634 const owner = currentRenderingInstance;
3635 if (isDef(factory.owners) && factory.owners.indexOf(owner) === -1) {
3636 // already pending
3637 factory.owners.push(owner);
3638 }
3639
3640 if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
3641 return factory.loadingComp
3642 }
3643
3644 if (!isDef(factory.owners)) {
3645 const owners = factory.owners = [owner];
3646 let sync = true
3647
3648 ;(owner).$on('hook:destroyed', () => remove(owners, owner));
3649
3650 const forceRender = (renderCompleted) => {
3651 for (let i = 0, l = owners.length; i < l; i++) {
3652 (owners[i]).$forceUpdate();
3653 }
3654
3655 if (renderCompleted) {
3656 owners.length = 0;
3657 }
3658 };
3659
3660 const resolve = once((res) => {
3661 // cache resolved
3662 factory.resolved = ensureCtor(res, baseCtor);
3663 // invoke callbacks only if this is not a synchronous resolve
3664 // (async resolves are shimmed as synchronous during SSR)
3665 if (!sync) {
3666 forceRender(true);
3667 } else {
3668 owners.length = 0;
3669 }
3670 });
3671
3672 const reject = once(reason => {
3673 warn(
3674 `Failed to resolve async component: ${String(factory)}` +
3675 (reason ? `\nReason: ${reason}` : '')
3676 );
3677 if (isDef(factory.errorComp)) {
3678 factory.error = true;
3679 forceRender(true);
3680 }
3681 });
3682
3683 const res = factory(resolve, reject);
3684
3685 if (isObject(res)) {
3686 if (isPromise(res)) {
3687 // () => Promise
3688 if (isUndef(factory.resolved)) {
3689 res.then(resolve, reject);
3690 }
3691 } else if (isPromise(res.component)) {
3692 res.component.then(resolve, reject);
3693
3694 if (isDef(res.error)) {
3695 factory.errorComp = ensureCtor(res.error, baseCtor);
3696 }
3697
3698 if (isDef(res.loading)) {
3699 factory.loadingComp = ensureCtor(res.loading, baseCtor);
3700 if (res.delay === 0) {
3701 factory.loading = true;
3702 } else {
3703 setTimeout(() => {
3704 if (isUndef(factory.resolved) && isUndef(factory.error)) {
3705 factory.loading = true;
3706 forceRender(false);
3707 }
3708 }, res.delay || 200);
3709 }
3710 }
3711
3712 if (isDef(res.timeout)) {
3713 setTimeout(() => {
3714 if (isUndef(factory.resolved)) {
3715 reject(
3716 `timeout (${res.timeout}ms)`
3717 );
3718 }
3719 }, res.timeout);
3720 }
3721 }
3722 }
3723
3724 sync = false;
3725 // return in case resolved synchronously
3726 return factory.loading
3727 ? factory.loadingComp
3728 : factory.resolved
3729 }
3730}
3731
3732/* */
3733
3734function isAsyncPlaceholder (node) {
3735 return node.isComment && node.asyncFactory
3736}
3737
3738/* */
3739
3740function getFirstComponentChild (children) {
3741 if (Array.isArray(children)) {
3742 for (let i = 0; i < children.length; i++) {
3743 const c = children[i];
3744 if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
3745 return c
3746 }
3747 }
3748 }
3749}
3750
3751/* */
3752
3753/* */
3754
3755function initEvents (vm) {
3756 vm._events = Object.create(null);
3757 vm._hasHookEvent = false;
3758 // init parent attached events
3759 const listeners = vm.$options._parentListeners;
3760 if (listeners) {
3761 updateComponentListeners(vm, listeners);
3762 }
3763}
3764
3765let target;
3766
3767function add (event, fn) {
3768 target.$on(event, fn);
3769}
3770
3771function remove$1 (event, fn) {
3772 target.$off(event, fn);
3773}
3774
3775function createOnceHandler (event, fn) {
3776 const _target = target;
3777 return function onceHandler () {
3778 const res = fn.apply(null, arguments);
3779 if (res !== null) {
3780 _target.$off(event, onceHandler);
3781 }
3782 }
3783}
3784
3785function updateComponentListeners (
3786 vm,
3787 listeners,
3788 oldListeners
3789) {
3790 target = vm;
3791 updateListeners(listeners, oldListeners || {}, add, remove$1, createOnceHandler, vm);
3792 target = undefined;
3793}
3794
3795function eventsMixin (Vue) {
3796 const hookRE = /^hook:/;
3797 Vue.prototype.$on = function (event, fn) {
3798 const vm = this;
3799 if (Array.isArray(event)) {
3800 for (let i = 0, l = event.length; i < l; i++) {
3801 vm.$on(event[i], fn);
3802 }
3803 } else {
3804 (vm._events[event] || (vm._events[event] = [])).push(fn);
3805 // optimize hook:event cost by using a boolean flag marked at registration
3806 // instead of a hash lookup
3807 if (hookRE.test(event)) {
3808 vm._hasHookEvent = true;
3809 }
3810 }
3811 return vm
3812 };
3813
3814 Vue.prototype.$once = function (event, fn) {
3815 const vm = this;
3816 function on () {
3817 vm.$off(event, on);
3818 fn.apply(vm, arguments);
3819 }
3820 on.fn = fn;
3821 vm.$on(event, on);
3822 return vm
3823 };
3824
3825 Vue.prototype.$off = function (event, fn) {
3826 const vm = this;
3827 // all
3828 if (!arguments.length) {
3829 vm._events = Object.create(null);
3830 return vm
3831 }
3832 // array of events
3833 if (Array.isArray(event)) {
3834 for (let i = 0, l = event.length; i < l; i++) {
3835 vm.$off(event[i], fn);
3836 }
3837 return vm
3838 }
3839 // specific event
3840 const cbs = vm._events[event];
3841 if (!cbs) {
3842 return vm
3843 }
3844 if (!fn) {
3845 vm._events[event] = null;
3846 return vm
3847 }
3848 // specific handler
3849 let cb;
3850 let i = cbs.length;
3851 while (i--) {
3852 cb = cbs[i];
3853 if (cb === fn || cb.fn === fn) {
3854 cbs.splice(i, 1);
3855 break
3856 }
3857 }
3858 return vm
3859 };
3860
3861 Vue.prototype.$emit = function (event) {
3862 const vm = this;
3863 {
3864 const lowerCaseEvent = event.toLowerCase();
3865 if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
3866 tip(
3867 `Event "${lowerCaseEvent}" is emitted in component ` +
3868 `${formatComponentName(vm)} but the handler is registered for "${event}". ` +
3869 `Note that HTML attributes are case-insensitive and you cannot use ` +
3870 `v-on to listen to camelCase events when using in-DOM templates. ` +
3871 `You should probably use "${hyphenate(event)}" instead of "${event}".`
3872 );
3873 }
3874 }
3875 let cbs = vm._events[event];
3876 if (cbs) {
3877 cbs = cbs.length > 1 ? toArray(cbs) : cbs;
3878 const args = toArray(arguments, 1);
3879 const info = `event handler for "${event}"`;
3880 for (let i = 0, l = cbs.length; i < l; i++) {
3881 invokeWithErrorHandling(cbs[i], vm, args, vm, info);
3882 }
3883 }
3884 return vm
3885 };
3886}
3887
3888/* */
3889
3890let activeInstance = null;
3891let isUpdatingChildComponent = false;
3892
3893function setActiveInstance(vm) {
3894 const prevActiveInstance = activeInstance;
3895 activeInstance = vm;
3896 return () => {
3897 activeInstance = prevActiveInstance;
3898 }
3899}
3900
3901function initLifecycle (vm) {
3902 const options = vm.$options;
3903
3904 // locate first non-abstract parent
3905 let parent = options.parent;
3906 if (parent && !options.abstract) {
3907 while (parent.$options.abstract && parent.$parent) {
3908 parent = parent.$parent;
3909 }
3910 parent.$children.push(vm);
3911 }
3912
3913 vm.$parent = parent;
3914 vm.$root = parent ? parent.$root : vm;
3915
3916 vm.$children = [];
3917 vm.$refs = {};
3918
3919 vm._watcher = null;
3920 vm._inactive = null;
3921 vm._directInactive = false;
3922 vm._isMounted = false;
3923 vm._isDestroyed = false;
3924 vm._isBeingDestroyed = false;
3925}
3926
3927function lifecycleMixin (Vue) {
3928 Vue.prototype._update = function (vnode, hydrating) {
3929 const vm = this;
3930 const prevEl = vm.$el;
3931 const prevVnode = vm._vnode;
3932 const restoreActiveInstance = setActiveInstance(vm);
3933 vm._vnode = vnode;
3934 // Vue.prototype.__patch__ is injected in entry points
3935 // based on the rendering backend used.
3936 if (!prevVnode) {
3937 // initial render
3938 vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
3939 } else {
3940 // updates
3941 vm.$el = vm.__patch__(prevVnode, vnode);
3942 }
3943 restoreActiveInstance();
3944 // update __vue__ reference
3945 if (prevEl) {
3946 prevEl.__vue__ = null;
3947 }
3948 if (vm.$el) {
3949 vm.$el.__vue__ = vm;
3950 }
3951 // if parent is an HOC, update its $el as well
3952 if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
3953 vm.$parent.$el = vm.$el;
3954 }
3955 // updated hook is called by the scheduler to ensure that children are
3956 // updated in a parent's updated hook.
3957 };
3958
3959 Vue.prototype.$forceUpdate = function () {
3960 const vm = this;
3961 if (vm._watcher) {
3962 vm._watcher.update();
3963 }
3964 };
3965
3966 Vue.prototype.$destroy = function () {
3967 const vm = this;
3968 if (vm._isBeingDestroyed) {
3969 return
3970 }
3971 callHook(vm, 'beforeDestroy');
3972 vm._isBeingDestroyed = true;
3973 // remove self from parent
3974 const parent = vm.$parent;
3975 if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
3976 remove(parent.$children, vm);
3977 }
3978 // teardown watchers
3979 if (vm._watcher) {
3980 vm._watcher.teardown();
3981 }
3982 let i = vm._watchers.length;
3983 while (i--) {
3984 vm._watchers[i].teardown();
3985 }
3986 // remove reference from data ob
3987 // frozen object may not have observer.
3988 if (vm._data.__ob__) {
3989 vm._data.__ob__.vmCount--;
3990 }
3991 // call the last hook...
3992 vm._isDestroyed = true;
3993 // invoke destroy hooks on current rendered tree
3994 vm.__patch__(vm._vnode, null);
3995 // fire destroyed hook
3996 callHook(vm, 'destroyed');
3997 // turn off all instance listeners.
3998 vm.$off();
3999 // remove __vue__ reference
4000 if (vm.$el) {
4001 vm.$el.__vue__ = null;
4002 }
4003 // release circular reference (#6759)
4004 if (vm.$vnode) {
4005 vm.$vnode.parent = null;
4006 }
4007 };
4008}
4009
4010function mountComponent (
4011 vm,
4012 el,
4013 hydrating
4014) {
4015 vm.$el = el;
4016 if (!vm.$options.render) {
4017 vm.$options.render = createEmptyVNode;
4018 {
4019 /* istanbul ignore if */
4020 if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
4021 vm.$options.el || el) {
4022 warn(
4023 'You are using the runtime-only build of Vue where the template ' +
4024 'compiler is not available. Either pre-compile the templates into ' +
4025 'render functions, or use the compiler-included build.',
4026 vm
4027 );
4028 } else {
4029 warn(
4030 'Failed to mount component: template or render function not defined.',
4031 vm
4032 );
4033 }
4034 }
4035 }
4036 callHook(vm, 'beforeMount');
4037
4038 let updateComponent;
4039 /* istanbul ignore if */
4040 if (config.performance && mark) {
4041 updateComponent = () => {
4042 const name = vm._name;
4043 const id = vm._uid;
4044 const startTag = `vue-perf-start:${id}`;
4045 const endTag = `vue-perf-end:${id}`;
4046
4047 mark(startTag);
4048 const vnode = vm._render();
4049 mark(endTag);
4050 measure(`vue ${name} render`, startTag, endTag);
4051
4052 mark(startTag);
4053 vm._update(vnode, hydrating);
4054 mark(endTag);
4055 measure(`vue ${name} patch`, startTag, endTag);
4056 };
4057 } else {
4058 updateComponent = () => {
4059 vm._update(vm._render(), hydrating);
4060 };
4061 }
4062
4063 // we set this to vm._watcher inside the watcher's constructor
4064 // since the watcher's initial patch may call $forceUpdate (e.g. inside child
4065 // component's mounted hook), which relies on vm._watcher being already defined
4066 new Watcher(vm, updateComponent, noop, {
4067 before () {
4068 if (vm._isMounted && !vm._isDestroyed) {
4069 callHook(vm, 'beforeUpdate');
4070 }
4071 }
4072 }, true /* isRenderWatcher */);
4073 hydrating = false;
4074
4075 // manually mounted instance, call mounted on self
4076 // mounted is called for render-created child components in its inserted hook
4077 if (vm.$vnode == null) {
4078 vm._isMounted = true;
4079 callHook(vm, 'mounted');
4080 }
4081 return vm
4082}
4083
4084function updateChildComponent (
4085 vm,
4086 propsData,
4087 listeners,
4088 parentVnode,
4089 renderChildren
4090) {
4091 {
4092 isUpdatingChildComponent = true;
4093 }
4094
4095 // determine whether component has slot children
4096 // we need to do this before overwriting $options._renderChildren.
4097
4098 // check if there are dynamic scopedSlots (hand-written or compiled but with
4099 // dynamic slot names). Static scoped slots compiled from template has the
4100 // "$stable" marker.
4101 const newScopedSlots = parentVnode.data.scopedSlots;
4102 const oldScopedSlots = vm.$scopedSlots;
4103 const hasDynamicScopedSlot = !!(
4104 (newScopedSlots && !newScopedSlots.$stable) ||
4105 (oldScopedSlots !== emptyObject && !oldScopedSlots.$stable) ||
4106 (newScopedSlots && vm.$scopedSlots.$key !== newScopedSlots.$key)
4107 );
4108
4109 // Any static slot children from the parent may have changed during parent's
4110 // update. Dynamic scoped slots may also have changed. In such cases, a forced
4111 // update is necessary to ensure correctness.
4112 const needsForceUpdate = !!(
4113 renderChildren || // has new static slots
4114 vm.$options._renderChildren || // has old static slots
4115 hasDynamicScopedSlot
4116 );
4117
4118 vm.$options._parentVnode = parentVnode;
4119 vm.$vnode = parentVnode; // update vm's placeholder node without re-render
4120
4121 if (vm._vnode) { // update child tree's parent
4122 vm._vnode.parent = parentVnode;
4123 }
4124 vm.$options._renderChildren = renderChildren;
4125
4126 // update $attrs and $listeners hash
4127 // these are also reactive so they may trigger child update if the child
4128 // used them during render
4129 vm.$attrs = parentVnode.data.attrs || emptyObject;
4130 vm.$listeners = listeners || emptyObject;
4131
4132 // update props
4133 if (propsData && vm.$options.props) {
4134 toggleObserving(false);
4135 const props = vm._props;
4136 const propKeys = vm.$options._propKeys || [];
4137 for (let i = 0; i < propKeys.length; i++) {
4138 const key = propKeys[i];
4139 const propOptions = vm.$options.props; // wtf flow?
4140 props[key] = validateProp(key, propOptions, propsData, vm);
4141 }
4142 toggleObserving(true);
4143 // keep a copy of raw propsData
4144 vm.$options.propsData = propsData;
4145 }
4146
4147 // update listeners
4148 listeners = listeners || emptyObject;
4149 const oldListeners = vm.$options._parentListeners;
4150 vm.$options._parentListeners = listeners;
4151 updateComponentListeners(vm, listeners, oldListeners);
4152
4153 // resolve slots + force update if has children
4154 if (needsForceUpdate) {
4155 vm.$slots = resolveSlots(renderChildren, parentVnode.context);
4156 vm.$forceUpdate();
4157 }
4158
4159 {
4160 isUpdatingChildComponent = false;
4161 }
4162}
4163
4164function isInInactiveTree (vm) {
4165 while (vm && (vm = vm.$parent)) {
4166 if (vm._inactive) return true
4167 }
4168 return false
4169}
4170
4171function activateChildComponent (vm, direct) {
4172 if (direct) {
4173 vm._directInactive = false;
4174 if (isInInactiveTree(vm)) {
4175 return
4176 }
4177 } else if (vm._directInactive) {
4178 return
4179 }
4180 if (vm._inactive || vm._inactive === null) {
4181 vm._inactive = false;
4182 for (let i = 0; i < vm.$children.length; i++) {
4183 activateChildComponent(vm.$children[i]);
4184 }
4185 callHook(vm, 'activated');
4186 }
4187}
4188
4189function deactivateChildComponent (vm, direct) {
4190 if (direct) {
4191 vm._directInactive = true;
4192 if (isInInactiveTree(vm)) {
4193 return
4194 }
4195 }
4196 if (!vm._inactive) {
4197 vm._inactive = true;
4198 for (let i = 0; i < vm.$children.length; i++) {
4199 deactivateChildComponent(vm.$children[i]);
4200 }
4201 callHook(vm, 'deactivated');
4202 }
4203}
4204
4205function callHook (vm, hook) {
4206 // #7573 disable dep collection when invoking lifecycle hooks
4207 pushTarget();
4208 const handlers = vm.$options[hook];
4209 const info = `${hook} hook`;
4210 if (handlers) {
4211 for (let i = 0, j = handlers.length; i < j; i++) {
4212 invokeWithErrorHandling(handlers[i], vm, null, vm, info);
4213 }
4214 }
4215 if (vm._hasHookEvent) {
4216 vm.$emit('hook:' + hook);
4217 }
4218 popTarget();
4219}
4220
4221/* */
4222
4223const MAX_UPDATE_COUNT = 100;
4224
4225const queue = [];
4226const activatedChildren = [];
4227let has = {};
4228let circular = {};
4229let waiting = false;
4230let flushing = false;
4231let index = 0;
4232
4233/**
4234 * Reset the scheduler's state.
4235 */
4236function resetSchedulerState () {
4237 index = queue.length = activatedChildren.length = 0;
4238 has = {};
4239 {
4240 circular = {};
4241 }
4242 waiting = flushing = false;
4243}
4244
4245// Async edge case #6566 requires saving the timestamp when event listeners are
4246// attached. However, calling performance.now() has a perf overhead especially
4247// if the page has thousands of event listeners. Instead, we take a timestamp
4248// every time the scheduler flushes and use that for all event listeners
4249// attached during that flush.
4250let currentFlushTimestamp = 0;
4251
4252// Async edge case fix requires storing an event listener's attach timestamp.
4253let getNow = Date.now;
4254
4255// Determine what event timestamp the browser is using. Annoyingly, the
4256// timestamp can either be hi-res (relative to page load) or low-res
4257// (relative to UNIX epoch), so in order to compare time we have to use the
4258// same timestamp type when saving the flush timestamp.
4259if (inBrowser && getNow() > document.createEvent('Event').timeStamp) {
4260 // if the low-res timestamp which is bigger than the event timestamp
4261 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
4262 // and we need to use the hi-res version for event listeners as well.
4263 getNow = () => performance.now();
4264}
4265
4266/**
4267 * Flush both queues and run the watchers.
4268 */
4269function flushSchedulerQueue () {
4270 currentFlushTimestamp = getNow();
4271 flushing = true;
4272 let watcher, id;
4273
4274 // Sort queue before flush.
4275 // This ensures that:
4276 // 1. Components are updated from parent to child. (because parent is always
4277 // created before the child)
4278 // 2. A component's user watchers are run before its render watcher (because
4279 // user watchers are created before the render watcher)
4280 // 3. If a component is destroyed during a parent component's watcher run,
4281 // its watchers can be skipped.
4282 queue.sort((a, b) => a.id - b.id);
4283
4284 // do not cache length because more watchers might be pushed
4285 // as we run existing watchers
4286 for (index = 0; index < queue.length; index++) {
4287 watcher = queue[index];
4288 if (watcher.before) {
4289 watcher.before();
4290 }
4291 id = watcher.id;
4292 has[id] = null;
4293 watcher.run();
4294 // in dev build, check and stop circular updates.
4295 if (has[id] != null) {
4296 circular[id] = (circular[id] || 0) + 1;
4297 if (circular[id] > MAX_UPDATE_COUNT) {
4298 warn(
4299 'You may have an infinite update loop ' + (
4300 watcher.user
4301 ? `in watcher with expression "${watcher.expression}"`
4302 : `in a component render function.`
4303 ),
4304 watcher.vm
4305 );
4306 break
4307 }
4308 }
4309 }
4310
4311 // keep copies of post queues before resetting state
4312 const activatedQueue = activatedChildren.slice();
4313 const updatedQueue = queue.slice();
4314
4315 resetSchedulerState();
4316
4317 // call component updated and activated hooks
4318 callActivatedHooks(activatedQueue);
4319 callUpdatedHooks(updatedQueue);
4320
4321 // devtool hook
4322 /* istanbul ignore if */
4323 if (devtools && config.devtools) {
4324 devtools.emit('flush');
4325 }
4326}
4327
4328function callUpdatedHooks (queue) {
4329 let i = queue.length;
4330 while (i--) {
4331 const watcher = queue[i];
4332 const vm = watcher.vm;
4333 if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) {
4334 callHook(vm, 'updated');
4335 }
4336 }
4337}
4338
4339/**
4340 * Queue a kept-alive component that was activated during patch.
4341 * The queue will be processed after the entire tree has been patched.
4342 */
4343function queueActivatedComponent (vm) {
4344 // setting _inactive to false here so that a render function can
4345 // rely on checking whether it's in an inactive tree (e.g. router-view)
4346 vm._inactive = false;
4347 activatedChildren.push(vm);
4348}
4349
4350function callActivatedHooks (queue) {
4351 for (let i = 0; i < queue.length; i++) {
4352 queue[i]._inactive = true;
4353 activateChildComponent(queue[i], true /* true */);
4354 }
4355}
4356
4357/**
4358 * Push a watcher into the watcher queue.
4359 * Jobs with duplicate IDs will be skipped unless it's
4360 * pushed when the queue is being flushed.
4361 */
4362function queueWatcher (watcher) {
4363 const id = watcher.id;
4364 if (has[id] == null) {
4365 has[id] = true;
4366 if (!flushing) {
4367 queue.push(watcher);
4368 } else {
4369 // if already flushing, splice the watcher based on its id
4370 // if already past its id, it will be run next immediately.
4371 let i = queue.length - 1;
4372 while (i > index && queue[i].id > watcher.id) {
4373 i--;
4374 }
4375 queue.splice(i + 1, 0, watcher);
4376 }
4377 // queue the flush
4378 if (!waiting) {
4379 waiting = true;
4380
4381 if (!config.async) {
4382 flushSchedulerQueue();
4383 return
4384 }
4385 nextTick(flushSchedulerQueue);
4386 }
4387 }
4388}
4389
4390/* */
4391
4392
4393
4394let uid$2 = 0;
4395
4396/**
4397 * A watcher parses an expression, collects dependencies,
4398 * and fires callback when the expression value changes.
4399 * This is used for both the $watch() api and directives.
4400 */
4401class Watcher {
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420 constructor (
4421 vm,
4422 expOrFn,
4423 cb,
4424 options,
4425 isRenderWatcher
4426 ) {
4427 this.vm = vm;
4428 if (isRenderWatcher) {
4429 vm._watcher = this;
4430 }
4431 vm._watchers.push(this);
4432 // options
4433 if (options) {
4434 this.deep = !!options.deep;
4435 this.user = !!options.user;
4436 this.lazy = !!options.lazy;
4437 this.sync = !!options.sync;
4438 this.before = options.before;
4439 } else {
4440 this.deep = this.user = this.lazy = this.sync = false;
4441 }
4442 this.cb = cb;
4443 this.id = ++uid$2; // uid for batching
4444 this.active = true;
4445 this.dirty = this.lazy; // for lazy watchers
4446 this.deps = [];
4447 this.newDeps = [];
4448 this.depIds = new _Set();
4449 this.newDepIds = new _Set();
4450 this.expression = expOrFn.toString();
4451 // parse expression for getter
4452 if (typeof expOrFn === 'function') {
4453 this.getter = expOrFn;
4454 } else {
4455 this.getter = parsePath(expOrFn);
4456 if (!this.getter) {
4457 this.getter = noop;
4458 warn(
4459 `Failed watching path: "${expOrFn}" ` +
4460 'Watcher only accepts simple dot-delimited paths. ' +
4461 'For full control, use a function instead.',
4462 vm
4463 );
4464 }
4465 }
4466 this.value = this.lazy
4467 ? undefined
4468 : this.get();
4469 }
4470
4471 /**
4472 * Evaluate the getter, and re-collect dependencies.
4473 */
4474 get () {
4475 pushTarget(this);
4476 let value;
4477 const vm = this.vm;
4478 try {
4479 value = this.getter.call(vm, vm);
4480 } catch (e) {
4481 if (this.user) {
4482 handleError(e, vm, `getter for watcher "${this.expression}"`);
4483 } else {
4484 throw e
4485 }
4486 } finally {
4487 // "touch" every property so they are all tracked as
4488 // dependencies for deep watching
4489 if (this.deep) {
4490 traverse(value);
4491 }
4492 popTarget();
4493 this.cleanupDeps();
4494 }
4495 return value
4496 }
4497
4498 /**
4499 * Add a dependency to this directive.
4500 */
4501 addDep (dep) {
4502 const id = dep.id;
4503 if (!this.newDepIds.has(id)) {
4504 this.newDepIds.add(id);
4505 this.newDeps.push(dep);
4506 if (!this.depIds.has(id)) {
4507 dep.addSub(this);
4508 }
4509 }
4510 }
4511
4512 /**
4513 * Clean up for dependency collection.
4514 */
4515 cleanupDeps () {
4516 let i = this.deps.length;
4517 while (i--) {
4518 const dep = this.deps[i];
4519 if (!this.newDepIds.has(dep.id)) {
4520 dep.removeSub(this);
4521 }
4522 }
4523 let tmp = this.depIds;
4524 this.depIds = this.newDepIds;
4525 this.newDepIds = tmp;
4526 this.newDepIds.clear();
4527 tmp = this.deps;
4528 this.deps = this.newDeps;
4529 this.newDeps = tmp;
4530 this.newDeps.length = 0;
4531 }
4532
4533 /**
4534 * Subscriber interface.
4535 * Will be called when a dependency changes.
4536 */
4537 update () {
4538 /* istanbul ignore else */
4539 if (this.lazy) {
4540 this.dirty = true;
4541 } else if (this.sync) {
4542 this.run();
4543 } else {
4544 queueWatcher(this);
4545 }
4546 }
4547
4548 /**
4549 * Scheduler job interface.
4550 * Will be called by the scheduler.
4551 */
4552 run () {
4553 if (this.active) {
4554 const value = this.get();
4555 if (
4556 value !== this.value ||
4557 // Deep watchers and watchers on Object/Arrays should fire even
4558 // when the value is the same, because the value may
4559 // have mutated.
4560 isObject(value) ||
4561 this.deep
4562 ) {
4563 // set new value
4564 const oldValue = this.value;
4565 this.value = value;
4566 if (this.user) {
4567 try {
4568 this.cb.call(this.vm, value, oldValue);
4569 } catch (e) {
4570 handleError(e, this.vm, `callback for watcher "${this.expression}"`);
4571 }
4572 } else {
4573 this.cb.call(this.vm, value, oldValue);
4574 }
4575 }
4576 }
4577 }
4578
4579 /**
4580 * Evaluate the value of the watcher.
4581 * This only gets called for lazy watchers.
4582 */
4583 evaluate () {
4584 this.value = this.get();
4585 this.dirty = false;
4586 }
4587
4588 /**
4589 * Depend on all deps collected by this watcher.
4590 */
4591 depend () {
4592 let i = this.deps.length;
4593 while (i--) {
4594 this.deps[i].depend();
4595 }
4596 }
4597
4598 /**
4599 * Remove self from all dependencies' subscriber list.
4600 */
4601 teardown () {
4602 if (this.active) {
4603 // remove self from vm's watcher list
4604 // this is a somewhat expensive operation so we skip it
4605 // if the vm is being destroyed.
4606 if (!this.vm._isBeingDestroyed) {
4607 remove(this.vm._watchers, this);
4608 }
4609 let i = this.deps.length;
4610 while (i--) {
4611 this.deps[i].removeSub(this);
4612 }
4613 this.active = false;
4614 }
4615 }
4616}
4617
4618/* */
4619
4620const sharedPropertyDefinition = {
4621 enumerable: true,
4622 configurable: true,
4623 get: noop,
4624 set: noop
4625};
4626
4627function proxy (target, sourceKey, key) {
4628 sharedPropertyDefinition.get = function proxyGetter () {
4629 return this[sourceKey][key]
4630 };
4631 sharedPropertyDefinition.set = function proxySetter (val) {
4632 this[sourceKey][key] = val;
4633 };
4634 Object.defineProperty(target, key, sharedPropertyDefinition);
4635}
4636
4637function initState (vm) {
4638 vm._watchers = [];
4639 const opts = vm.$options;
4640 if (opts.props) initProps(vm, opts.props);
4641 if (opts.methods) initMethods(vm, opts.methods);
4642 if (opts.data) {
4643 initData(vm);
4644 } else {
4645 observe(vm._data = {}, true /* asRootData */);
4646 }
4647 if (opts.computed) initComputed(vm, opts.computed);
4648 if (opts.watch && opts.watch !== nativeWatch) {
4649 initWatch(vm, opts.watch);
4650 }
4651}
4652
4653function initProps (vm, propsOptions) {
4654 const propsData = vm.$options.propsData || {};
4655 const props = vm._props = {};
4656 // cache prop keys so that future props updates can iterate using Array
4657 // instead of dynamic object key enumeration.
4658 const keys = vm.$options._propKeys = [];
4659 const isRoot = !vm.$parent;
4660 // root instance props should be converted
4661 if (!isRoot) {
4662 toggleObserving(false);
4663 }
4664 for (const key in propsOptions) {
4665 keys.push(key);
4666 const value = validateProp(key, propsOptions, propsData, vm);
4667 /* istanbul ignore else */
4668 {
4669 const hyphenatedKey = hyphenate(key);
4670 if (isReservedAttribute(hyphenatedKey) ||
4671 config.isReservedAttr(hyphenatedKey)) {
4672 warn(
4673 `"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,
4674 vm
4675 );
4676 }
4677 defineReactive$$1(props, key, value, () => {
4678 if (!isRoot && !isUpdatingChildComponent) {
4679 warn(
4680 `Avoid mutating a prop directly since the value will be ` +
4681 `overwritten whenever the parent component re-renders. ` +
4682 `Instead, use a data or computed property based on the prop's ` +
4683 `value. Prop being mutated: "${key}"`,
4684 vm
4685 );
4686 }
4687 });
4688 }
4689 // static props are already proxied on the component's prototype
4690 // during Vue.extend(). We only need to proxy props defined at
4691 // instantiation here.
4692 if (!(key in vm)) {
4693 proxy(vm, `_props`, key);
4694 }
4695 }
4696 toggleObserving(true);
4697}
4698
4699function initData (vm) {
4700 let data = vm.$options.data;
4701 data = vm._data = typeof data === 'function'
4702 ? getData(data, vm)
4703 : data || {};
4704 if (!isPlainObject(data)) {
4705 data = {};
4706 warn(
4707 'data functions should return an object:\n' +
4708 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
4709 vm
4710 );
4711 }
4712 // proxy data on instance
4713 const keys = Object.keys(data);
4714 const props = vm.$options.props;
4715 const methods = vm.$options.methods;
4716 let i = keys.length;
4717 while (i--) {
4718 const key = keys[i];
4719 {
4720 if (methods && hasOwn(methods, key)) {
4721 warn(
4722 `Method "${key}" has already been defined as a data property.`,
4723 vm
4724 );
4725 }
4726 }
4727 if (props && hasOwn(props, key)) {
4728 warn(
4729 `The data property "${key}" is already declared as a prop. ` +
4730 `Use prop default value instead.`,
4731 vm
4732 );
4733 } else if (!isReserved(key)) {
4734 proxy(vm, `_data`, key);
4735 }
4736 }
4737 // observe data
4738 observe(data, true /* asRootData */);
4739}
4740
4741function getData (data, vm) {
4742 // #7573 disable dep collection when invoking data getters
4743 pushTarget();
4744 try {
4745 return data.call(vm, vm)
4746 } catch (e) {
4747 handleError(e, vm, `data()`);
4748 return {}
4749 } finally {
4750 popTarget();
4751 }
4752}
4753
4754const computedWatcherOptions = { lazy: true };
4755
4756function initComputed (vm, computed) {
4757 // $flow-disable-line
4758 const watchers = vm._computedWatchers = Object.create(null);
4759 // computed properties are just getters during SSR
4760 const isSSR = isServerRendering();
4761
4762 for (const key in computed) {
4763 const userDef = computed[key];
4764 const getter = typeof userDef === 'function' ? userDef : userDef.get;
4765 if (getter == null) {
4766 warn(
4767 `Getter is missing for computed property "${key}".`,
4768 vm
4769 );
4770 }
4771
4772 if (!isSSR) {
4773 // create internal watcher for the computed property.
4774 watchers[key] = new Watcher(
4775 vm,
4776 getter || noop,
4777 noop,
4778 computedWatcherOptions
4779 );
4780 }
4781
4782 // component-defined computed properties are already defined on the
4783 // component prototype. We only need to define computed properties defined
4784 // at instantiation here.
4785 if (!(key in vm)) {
4786 defineComputed(vm, key, userDef);
4787 } else {
4788 if (key in vm.$data) {
4789 warn(`The computed property "${key}" is already defined in data.`, vm);
4790 } else if (vm.$options.props && key in vm.$options.props) {
4791 warn(`The computed property "${key}" is already defined as a prop.`, vm);
4792 }
4793 }
4794 }
4795}
4796
4797function defineComputed (
4798 target,
4799 key,
4800 userDef
4801) {
4802 const shouldCache = !isServerRendering();
4803 if (typeof userDef === 'function') {
4804 sharedPropertyDefinition.get = shouldCache
4805 ? createComputedGetter(key)
4806 : createGetterInvoker(userDef);
4807 sharedPropertyDefinition.set = noop;
4808 } else {
4809 sharedPropertyDefinition.get = userDef.get
4810 ? shouldCache && userDef.cache !== false
4811 ? createComputedGetter(key)
4812 : createGetterInvoker(userDef.get)
4813 : noop;
4814 sharedPropertyDefinition.set = userDef.set || noop;
4815 }
4816 if (sharedPropertyDefinition.set === noop) {
4817 sharedPropertyDefinition.set = function () {
4818 warn(
4819 `Computed property "${key}" was assigned to but it has no setter.`,
4820 this
4821 );
4822 };
4823 }
4824 Object.defineProperty(target, key, sharedPropertyDefinition);
4825}
4826
4827function createComputedGetter (key) {
4828 return function computedGetter () {
4829 const watcher = this._computedWatchers && this._computedWatchers[key];
4830 if (watcher) {
4831 if (watcher.dirty) {
4832 watcher.evaluate();
4833 }
4834 if (Dep.target) {
4835 watcher.depend();
4836 }
4837 return watcher.value
4838 }
4839 }
4840}
4841
4842function createGetterInvoker(fn) {
4843 return function computedGetter () {
4844 return fn.call(this, this)
4845 }
4846}
4847
4848function initMethods (vm, methods) {
4849 const props = vm.$options.props;
4850 for (const key in methods) {
4851 {
4852 if (typeof methods[key] !== 'function') {
4853 warn(
4854 `Method "${key}" has type "${typeof methods[key]}" in the component definition. ` +
4855 `Did you reference the function correctly?`,
4856 vm
4857 );
4858 }
4859 if (props && hasOwn(props, key)) {
4860 warn(
4861 `Method "${key}" has already been defined as a prop.`,
4862 vm
4863 );
4864 }
4865 if ((key in vm) && isReserved(key)) {
4866 warn(
4867 `Method "${key}" conflicts with an existing Vue instance method. ` +
4868 `Avoid defining component methods that start with _ or $.`
4869 );
4870 }
4871 }
4872 vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm);
4873 }
4874}
4875
4876function initWatch (vm, watch) {
4877 for (const key in watch) {
4878 const handler = watch[key];
4879 if (Array.isArray(handler)) {
4880 for (let i = 0; i < handler.length; i++) {
4881 createWatcher(vm, key, handler[i]);
4882 }
4883 } else {
4884 createWatcher(vm, key, handler);
4885 }
4886 }
4887}
4888
4889function createWatcher (
4890 vm,
4891 expOrFn,
4892 handler,
4893 options
4894) {
4895 if (isPlainObject(handler)) {
4896 options = handler;
4897 handler = handler.handler;
4898 }
4899 if (typeof handler === 'string') {
4900 handler = vm[handler];
4901 }
4902 return vm.$watch(expOrFn, handler, options)
4903}
4904
4905function stateMixin (Vue) {
4906 // flow somehow has problems with directly declared definition object
4907 // when using Object.defineProperty, so we have to procedurally build up
4908 // the object here.
4909 const dataDef = {};
4910 dataDef.get = function () { return this._data };
4911 const propsDef = {};
4912 propsDef.get = function () { return this._props };
4913 {
4914 dataDef.set = function () {
4915 warn(
4916 'Avoid replacing instance root $data. ' +
4917 'Use nested data properties instead.',
4918 this
4919 );
4920 };
4921 propsDef.set = function () {
4922 warn(`$props is readonly.`, this);
4923 };
4924 }
4925 Object.defineProperty(Vue.prototype, '$data', dataDef);
4926 Object.defineProperty(Vue.prototype, '$props', propsDef);
4927
4928 Vue.prototype.$set = set;
4929 Vue.prototype.$delete = del;
4930
4931 Vue.prototype.$watch = function (
4932 expOrFn,
4933 cb,
4934 options
4935 ) {
4936 const vm = this;
4937 if (isPlainObject(cb)) {
4938 return createWatcher(vm, expOrFn, cb, options)
4939 }
4940 options = options || {};
4941 options.user = true;
4942 const watcher = new Watcher(vm, expOrFn, cb, options);
4943 if (options.immediate) {
4944 try {
4945 cb.call(vm, watcher.value);
4946 } catch (error) {
4947 handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`);
4948 }
4949 }
4950 return function unwatchFn () {
4951 watcher.teardown();
4952 }
4953 };
4954}
4955
4956/* */
4957
4958let uid$3 = 0;
4959
4960function initMixin (Vue) {
4961 Vue.prototype._init = function (options) {
4962 const vm = this;
4963 // a uid
4964 vm._uid = uid$3++;
4965
4966 let startTag, endTag;
4967 /* istanbul ignore if */
4968 if (config.performance && mark) {
4969 startTag = `vue-perf-start:${vm._uid}`;
4970 endTag = `vue-perf-end:${vm._uid}`;
4971 mark(startTag);
4972 }
4973
4974 // a flag to avoid this being observed
4975 vm._isVue = true;
4976 // merge options
4977 if (options && options._isComponent) {
4978 // optimize internal component instantiation
4979 // since dynamic options merging is pretty slow, and none of the
4980 // internal component options needs special treatment.
4981 initInternalComponent(vm, options);
4982 } else {
4983 vm.$options = mergeOptions(
4984 resolveConstructorOptions(vm.constructor),
4985 options || {},
4986 vm
4987 );
4988 }
4989 /* istanbul ignore else */
4990 {
4991 initProxy(vm);
4992 }
4993 // expose real self
4994 vm._self = vm;
4995 initLifecycle(vm);
4996 initEvents(vm);
4997 initRender(vm);
4998 callHook(vm, 'beforeCreate');
4999 initInjections(vm); // resolve injections before data/props
5000 initState(vm);
5001 initProvide(vm); // resolve provide after data/props
5002 callHook(vm, 'created');
5003
5004 /* istanbul ignore if */
5005 if (config.performance && mark) {
5006 vm._name = formatComponentName(vm, false);
5007 mark(endTag);
5008 measure(`vue ${vm._name} init`, startTag, endTag);
5009 }
5010
5011 if (vm.$options.el) {
5012 vm.$mount(vm.$options.el);
5013 }
5014 };
5015}
5016
5017function initInternalComponent (vm, options) {
5018 const opts = vm.$options = Object.create(vm.constructor.options);
5019 // doing this because it's faster than dynamic enumeration.
5020 const parentVnode = options._parentVnode;
5021 opts.parent = options.parent;
5022 opts._parentVnode = parentVnode;
5023
5024 const vnodeComponentOptions = parentVnode.componentOptions;
5025 opts.propsData = vnodeComponentOptions.propsData;
5026 opts._parentListeners = vnodeComponentOptions.listeners;
5027 opts._renderChildren = vnodeComponentOptions.children;
5028 opts._componentTag = vnodeComponentOptions.tag;
5029
5030 if (options.render) {
5031 opts.render = options.render;
5032 opts.staticRenderFns = options.staticRenderFns;
5033 }
5034}
5035
5036function resolveConstructorOptions (Ctor) {
5037 let options = Ctor.options;
5038 if (Ctor.super) {
5039 const superOptions = resolveConstructorOptions(Ctor.super);
5040 const cachedSuperOptions = Ctor.superOptions;
5041 if (superOptions !== cachedSuperOptions) {
5042 // super option changed,
5043 // need to resolve new options.
5044 Ctor.superOptions = superOptions;
5045 // check if there are any late-modified/attached options (#4976)
5046 const modifiedOptions = resolveModifiedOptions(Ctor);
5047 // update base extend options
5048 if (modifiedOptions) {
5049 extend(Ctor.extendOptions, modifiedOptions);
5050 }
5051 options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);
5052 if (options.name) {
5053 options.components[options.name] = Ctor;
5054 }
5055 }
5056 }
5057 return options
5058}
5059
5060function resolveModifiedOptions (Ctor) {
5061 let modified;
5062 const latest = Ctor.options;
5063 const sealed = Ctor.sealedOptions;
5064 for (const key in latest) {
5065 if (latest[key] !== sealed[key]) {
5066 if (!modified) modified = {};
5067 modified[key] = latest[key];
5068 }
5069 }
5070 return modified
5071}
5072
5073function Vue (options) {
5074 if (!(this instanceof Vue)
5075 ) {
5076 warn('Vue is a constructor and should be called with the `new` keyword');
5077 }
5078 this._init(options);
5079}
5080
5081initMixin(Vue);
5082stateMixin(Vue);
5083eventsMixin(Vue);
5084lifecycleMixin(Vue);
5085renderMixin(Vue);
5086
5087/* */
5088
5089function initUse (Vue) {
5090 Vue.use = function (plugin) {
5091 const installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
5092 if (installedPlugins.indexOf(plugin) > -1) {
5093 return this
5094 }
5095
5096 // additional parameters
5097 const args = toArray(arguments, 1);
5098 args.unshift(this);
5099 if (typeof plugin.install === 'function') {
5100 plugin.install.apply(plugin, args);
5101 } else if (typeof plugin === 'function') {
5102 plugin.apply(null, args);
5103 }
5104 installedPlugins.push(plugin);
5105 return this
5106 };
5107}
5108
5109/* */
5110
5111function initMixin$1 (Vue) {
5112 Vue.mixin = function (mixin) {
5113 this.options = mergeOptions(this.options, mixin);
5114 return this
5115 };
5116}
5117
5118/* */
5119
5120function initExtend (Vue) {
5121 /**
5122 * Each instance constructor, including Vue, has a unique
5123 * cid. This enables us to create wrapped "child
5124 * constructors" for prototypal inheritance and cache them.
5125 */
5126 Vue.cid = 0;
5127 let cid = 1;
5128
5129 /**
5130 * Class inheritance
5131 */
5132 Vue.extend = function (extendOptions) {
5133 extendOptions = extendOptions || {};
5134 const Super = this;
5135 const SuperId = Super.cid;
5136 const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
5137 if (cachedCtors[SuperId]) {
5138 return cachedCtors[SuperId]
5139 }
5140
5141 const name = extendOptions.name || Super.options.name;
5142 if (name) {
5143 validateComponentName(name);
5144 }
5145
5146 const Sub = function VueComponent (options) {
5147 this._init(options);
5148 };
5149 Sub.prototype = Object.create(Super.prototype);
5150 Sub.prototype.constructor = Sub;
5151 Sub.cid = cid++;
5152 Sub.options = mergeOptions(
5153 Super.options,
5154 extendOptions
5155 );
5156 Sub['super'] = Super;
5157
5158 // For props and computed properties, we define the proxy getters on
5159 // the Vue instances at extension time, on the extended prototype. This
5160 // avoids Object.defineProperty calls for each instance created.
5161 if (Sub.options.props) {
5162 initProps$1(Sub);
5163 }
5164 if (Sub.options.computed) {
5165 initComputed$1(Sub);
5166 }
5167
5168 // allow further extension/mixin/plugin usage
5169 Sub.extend = Super.extend;
5170 Sub.mixin = Super.mixin;
5171 Sub.use = Super.use;
5172
5173 // create asset registers, so extended classes
5174 // can have their private assets too.
5175 ASSET_TYPES.forEach(function (type) {
5176 Sub[type] = Super[type];
5177 });
5178 // enable recursive self-lookup
5179 if (name) {
5180 Sub.options.components[name] = Sub;
5181 }
5182
5183 // keep a reference to the super options at extension time.
5184 // later at instantiation we can check if Super's options have
5185 // been updated.
5186 Sub.superOptions = Super.options;
5187 Sub.extendOptions = extendOptions;
5188 Sub.sealedOptions = extend({}, Sub.options);
5189
5190 // cache constructor
5191 cachedCtors[SuperId] = Sub;
5192 return Sub
5193 };
5194}
5195
5196function initProps$1 (Comp) {
5197 const props = Comp.options.props;
5198 for (const key in props) {
5199 proxy(Comp.prototype, `_props`, key);
5200 }
5201}
5202
5203function initComputed$1 (Comp) {
5204 const computed = Comp.options.computed;
5205 for (const key in computed) {
5206 defineComputed(Comp.prototype, key, computed[key]);
5207 }
5208}
5209
5210/* */
5211
5212function initAssetRegisters (Vue) {
5213 /**
5214 * Create asset registration methods.
5215 */
5216 ASSET_TYPES.forEach(type => {
5217 Vue[type] = function (
5218 id,
5219 definition
5220 ) {
5221 if (!definition) {
5222 return this.options[type + 's'][id]
5223 } else {
5224 /* istanbul ignore if */
5225 if (type === 'component') {
5226 validateComponentName(id);
5227 }
5228 if (type === 'component' && isPlainObject(definition)) {
5229 definition.name = definition.name || id;
5230 definition = this.options._base.extend(definition);
5231 }
5232 if (type === 'directive' && typeof definition === 'function') {
5233 definition = { bind: definition, update: definition };
5234 }
5235 this.options[type + 's'][id] = definition;
5236 return definition
5237 }
5238 };
5239 });
5240}
5241
5242/* */
5243
5244
5245
5246function getComponentName (opts) {
5247 return opts && (opts.Ctor.options.name || opts.tag)
5248}
5249
5250function matches (pattern, name) {
5251 if (Array.isArray(pattern)) {
5252 return pattern.indexOf(name) > -1
5253 } else if (typeof pattern === 'string') {
5254 return pattern.split(',').indexOf(name) > -1
5255 } else if (isRegExp(pattern)) {
5256 return pattern.test(name)
5257 }
5258 /* istanbul ignore next */
5259 return false
5260}
5261
5262function pruneCache (keepAliveInstance, filter) {
5263 const { cache, keys, _vnode } = keepAliveInstance;
5264 for (const key in cache) {
5265 const cachedNode = cache[key];
5266 if (cachedNode) {
5267 const name = getComponentName(cachedNode.componentOptions);
5268 if (name && !filter(name)) {
5269 pruneCacheEntry(cache, key, keys, _vnode);
5270 }
5271 }
5272 }
5273}
5274
5275function pruneCacheEntry (
5276 cache,
5277 key,
5278 keys,
5279 current
5280) {
5281 const cached$$1 = cache[key];
5282 if (cached$$1 && (!current || cached$$1.tag !== current.tag)) {
5283 cached$$1.componentInstance.$destroy();
5284 }
5285 cache[key] = null;
5286 remove(keys, key);
5287}
5288
5289const patternTypes = [String, RegExp, Array];
5290
5291var KeepAlive = {
5292 name: 'keep-alive',
5293 abstract: true,
5294
5295 props: {
5296 include: patternTypes,
5297 exclude: patternTypes,
5298 max: [String, Number]
5299 },
5300
5301 created () {
5302 this.cache = Object.create(null);
5303 this.keys = [];
5304 },
5305
5306 destroyed () {
5307 for (const key in this.cache) {
5308 pruneCacheEntry(this.cache, key, this.keys);
5309 }
5310 },
5311
5312 mounted () {
5313 this.$watch('include', val => {
5314 pruneCache(this, name => matches(val, name));
5315 });
5316 this.$watch('exclude', val => {
5317 pruneCache(this, name => !matches(val, name));
5318 });
5319 },
5320
5321 render () {
5322 const slot = this.$slots.default;
5323 const vnode = getFirstComponentChild(slot);
5324 const componentOptions = vnode && vnode.componentOptions;
5325 if (componentOptions) {
5326 // check pattern
5327 const name = getComponentName(componentOptions);
5328 const { include, exclude } = this;
5329 if (
5330 // not included
5331 (include && (!name || !matches(include, name))) ||
5332 // excluded
5333 (exclude && name && matches(exclude, name))
5334 ) {
5335 return vnode
5336 }
5337
5338 const { cache, keys } = this;
5339 const key = vnode.key == null
5340 // same constructor may get registered as different local components
5341 // so cid alone is not enough (#3269)
5342 ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
5343 : vnode.key;
5344 if (cache[key]) {
5345 vnode.componentInstance = cache[key].componentInstance;
5346 // make current key freshest
5347 remove(keys, key);
5348 keys.push(key);
5349 } else {
5350 cache[key] = vnode;
5351 keys.push(key);
5352 // prune oldest entry
5353 if (this.max && keys.length > parseInt(this.max)) {
5354 pruneCacheEntry(cache, keys[0], keys, this._vnode);
5355 }
5356 }
5357
5358 vnode.data.keepAlive = true;
5359 }
5360 return vnode || (slot && slot[0])
5361 }
5362};
5363
5364var builtInComponents = {
5365 KeepAlive
5366};
5367
5368/* */
5369
5370function initGlobalAPI (Vue) {
5371 // config
5372 const configDef = {};
5373 configDef.get = () => config;
5374 {
5375 configDef.set = () => {
5376 warn(
5377 'Do not replace the Vue.config object, set individual fields instead.'
5378 );
5379 };
5380 }
5381 Object.defineProperty(Vue, 'config', configDef);
5382
5383 // exposed util methods.
5384 // NOTE: these are not considered part of the public API - avoid relying on
5385 // them unless you are aware of the risk.
5386 Vue.util = {
5387 warn,
5388 extend,
5389 mergeOptions,
5390 defineReactive: defineReactive$$1
5391 };
5392
5393 Vue.set = set;
5394 Vue.delete = del;
5395 Vue.nextTick = nextTick;
5396
5397 // 2.6 explicit observable API
5398 Vue.observable = (obj) => {
5399 observe(obj);
5400 return obj
5401 };
5402
5403 Vue.options = Object.create(null);
5404 ASSET_TYPES.forEach(type => {
5405 Vue.options[type + 's'] = Object.create(null);
5406 });
5407
5408 // this is used to identify the "base" constructor to extend all plain-object
5409 // components with in Weex's multi-instance scenarios.
5410 Vue.options._base = Vue;
5411
5412 extend(Vue.options.components, builtInComponents);
5413
5414 initUse(Vue);
5415 initMixin$1(Vue);
5416 initExtend(Vue);
5417 initAssetRegisters(Vue);
5418}
5419
5420initGlobalAPI(Vue);
5421
5422Object.defineProperty(Vue.prototype, '$isServer', {
5423 get: isServerRendering
5424});
5425
5426Object.defineProperty(Vue.prototype, '$ssrContext', {
5427 get () {
5428 /* istanbul ignore next */
5429 return this.$vnode && this.$vnode.ssrContext
5430 }
5431});
5432
5433// expose FunctionalRenderContext for ssr runtime helper installation
5434Object.defineProperty(Vue, 'FunctionalRenderContext', {
5435 value: FunctionalRenderContext
5436});
5437
5438Vue.version = '2.6.8';
5439
5440/* */
5441
5442// these are reserved for web because they are directly compiled away
5443// during template compilation
5444const isReservedAttr = makeMap('style,class');
5445
5446// attributes that should be using props for binding
5447const acceptValue = makeMap('input,textarea,option,select,progress');
5448const mustUseProp = (tag, type, attr) => {
5449 return (
5450 (attr === 'value' && acceptValue(tag)) && type !== 'button' ||
5451 (attr === 'selected' && tag === 'option') ||
5452 (attr === 'checked' && tag === 'input') ||
5453 (attr === 'muted' && tag === 'video')
5454 )
5455};
5456
5457const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck');
5458
5459const isValidContentEditableValue = makeMap('events,caret,typing,plaintext-only');
5460
5461const convertEnumeratedValue = (key, value) => {
5462 return isFalsyAttrValue(value) || value === 'false'
5463 ? 'false'
5464 // allow arbitrary string value for contenteditable
5465 : key === 'contenteditable' && isValidContentEditableValue(value)
5466 ? value
5467 : 'true'
5468};
5469
5470const isBooleanAttr = makeMap(
5471 'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
5472 'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
5473 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
5474 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
5475 'required,reversed,scoped,seamless,selected,sortable,translate,' +
5476 'truespeed,typemustmatch,visible'
5477);
5478
5479const xlinkNS = 'http://www.w3.org/1999/xlink';
5480
5481const isXlink = (name) => {
5482 return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'
5483};
5484
5485const getXlinkProp = (name) => {
5486 return isXlink(name) ? name.slice(6, name.length) : ''
5487};
5488
5489const isFalsyAttrValue = (val) => {
5490 return val == null || val === false
5491};
5492
5493/* */
5494
5495function genClassForVnode (vnode) {
5496 let data = vnode.data;
5497 let parentNode = vnode;
5498 let childNode = vnode;
5499 while (isDef(childNode.componentInstance)) {
5500 childNode = childNode.componentInstance._vnode;
5501 if (childNode && childNode.data) {
5502 data = mergeClassData(childNode.data, data);
5503 }
5504 }
5505 while (isDef(parentNode = parentNode.parent)) {
5506 if (parentNode && parentNode.data) {
5507 data = mergeClassData(data, parentNode.data);
5508 }
5509 }
5510 return renderClass(data.staticClass, data.class)
5511}
5512
5513function mergeClassData (child, parent) {
5514 return {
5515 staticClass: concat(child.staticClass, parent.staticClass),
5516 class: isDef(child.class)
5517 ? [child.class, parent.class]
5518 : parent.class
5519 }
5520}
5521
5522function renderClass (
5523 staticClass,
5524 dynamicClass
5525) {
5526 if (isDef(staticClass) || isDef(dynamicClass)) {
5527 return concat(staticClass, stringifyClass(dynamicClass))
5528 }
5529 /* istanbul ignore next */
5530 return ''
5531}
5532
5533function concat (a, b) {
5534 return a ? b ? (a + ' ' + b) : a : (b || '')
5535}
5536
5537function stringifyClass (value) {
5538 if (Array.isArray(value)) {
5539 return stringifyArray(value)
5540 }
5541 if (isObject(value)) {
5542 return stringifyObject(value)
5543 }
5544 if (typeof value === 'string') {
5545 return value
5546 }
5547 /* istanbul ignore next */
5548 return ''
5549}
5550
5551function stringifyArray (value) {
5552 let res = '';
5553 let stringified;
5554 for (let i = 0, l = value.length; i < l; i++) {
5555 if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') {
5556 if (res) res += ' ';
5557 res += stringified;
5558 }
5559 }
5560 return res
5561}
5562
5563function stringifyObject (value) {
5564 let res = '';
5565 for (const key in value) {
5566 if (value[key]) {
5567 if (res) res += ' ';
5568 res += key;
5569 }
5570 }
5571 return res
5572}
5573
5574/* */
5575
5576const namespaceMap = {
5577 svg: 'http://www.w3.org/2000/svg',
5578 math: 'http://www.w3.org/1998/Math/MathML'
5579};
5580
5581const isHTMLTag = makeMap(
5582 'html,body,base,head,link,meta,style,title,' +
5583 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
5584 'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
5585 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
5586 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
5587 'embed,object,param,source,canvas,script,noscript,del,ins,' +
5588 'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
5589 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
5590 'output,progress,select,textarea,' +
5591 'details,dialog,menu,menuitem,summary,' +
5592 'content,element,shadow,template,blockquote,iframe,tfoot'
5593);
5594
5595// this map is intentionally selective, only covering SVG elements that may
5596// contain child elements.
5597const isSVG = makeMap(
5598 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
5599 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
5600 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
5601 true
5602);
5603
5604const isPreTag = (tag) => tag === 'pre';
5605
5606const isReservedTag = (tag) => {
5607 return isHTMLTag(tag) || isSVG(tag)
5608};
5609
5610function getTagNamespace (tag) {
5611 if (isSVG(tag)) {
5612 return 'svg'
5613 }
5614 // basic support for MathML
5615 // note it doesn't support other MathML elements being component roots
5616 if (tag === 'math') {
5617 return 'math'
5618 }
5619}
5620
5621const unknownElementCache = Object.create(null);
5622function isUnknownElement (tag) {
5623 /* istanbul ignore if */
5624 if (!inBrowser) {
5625 return true
5626 }
5627 if (isReservedTag(tag)) {
5628 return false
5629 }
5630 tag = tag.toLowerCase();
5631 /* istanbul ignore if */
5632 if (unknownElementCache[tag] != null) {
5633 return unknownElementCache[tag]
5634 }
5635 const el = document.createElement(tag);
5636 if (tag.indexOf('-') > -1) {
5637 // http://stackoverflow.com/a/28210364/1070244
5638 return (unknownElementCache[tag] = (
5639 el.constructor === window.HTMLUnknownElement ||
5640 el.constructor === window.HTMLElement
5641 ))
5642 } else {
5643 return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString()))
5644 }
5645}
5646
5647const isTextInputType = makeMap('text,number,password,search,email,tel,url');
5648
5649/* */
5650
5651/**
5652 * Query an element selector if it's not an element already.
5653 */
5654function query (el) {
5655 if (typeof el === 'string') {
5656 const selected = document.querySelector(el);
5657 if (!selected) {
5658 warn(
5659 'Cannot find element: ' + el
5660 );
5661 return document.createElement('div')
5662 }
5663 return selected
5664 } else {
5665 return el
5666 }
5667}
5668
5669/* */
5670
5671function createElement$1 (tagName, vnode) {
5672 const elm = document.createElement(tagName);
5673 if (tagName !== 'select') {
5674 return elm
5675 }
5676 // false or null will remove the attribute but undefined will not
5677 if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) {
5678 elm.setAttribute('multiple', 'multiple');
5679 }
5680 return elm
5681}
5682
5683function createElementNS (namespace, tagName) {
5684 return document.createElementNS(namespaceMap[namespace], tagName)
5685}
5686
5687function createTextNode (text) {
5688 return document.createTextNode(text)
5689}
5690
5691function createComment (text) {
5692 return document.createComment(text)
5693}
5694
5695function insertBefore (parentNode, newNode, referenceNode) {
5696 parentNode.insertBefore(newNode, referenceNode);
5697}
5698
5699function removeChild (node, child) {
5700 node.removeChild(child);
5701}
5702
5703function appendChild (node, child) {
5704 node.appendChild(child);
5705}
5706
5707function parentNode (node) {
5708 return node.parentNode
5709}
5710
5711function nextSibling (node) {
5712 return node.nextSibling
5713}
5714
5715function tagName (node) {
5716 return node.tagName
5717}
5718
5719function setTextContent (node, text) {
5720 node.textContent = text;
5721}
5722
5723function setStyleScope (node, scopeId) {
5724 node.setAttribute(scopeId, '');
5725}
5726
5727var nodeOps = /*#__PURE__*/Object.freeze({
5728 createElement: createElement$1,
5729 createElementNS: createElementNS,
5730 createTextNode: createTextNode,
5731 createComment: createComment,
5732 insertBefore: insertBefore,
5733 removeChild: removeChild,
5734 appendChild: appendChild,
5735 parentNode: parentNode,
5736 nextSibling: nextSibling,
5737 tagName: tagName,
5738 setTextContent: setTextContent,
5739 setStyleScope: setStyleScope
5740});
5741
5742/* */
5743
5744var ref = {
5745 create (_, vnode) {
5746 registerRef(vnode);
5747 },
5748 update (oldVnode, vnode) {
5749 if (oldVnode.data.ref !== vnode.data.ref) {
5750 registerRef(oldVnode, true);
5751 registerRef(vnode);
5752 }
5753 },
5754 destroy (vnode) {
5755 registerRef(vnode, true);
5756 }
5757};
5758
5759function registerRef (vnode, isRemoval) {
5760 const key = vnode.data.ref;
5761 if (!isDef(key)) return
5762
5763 const vm = vnode.context;
5764 const ref = vnode.componentInstance || vnode.elm;
5765 const refs = vm.$refs;
5766 if (isRemoval) {
5767 if (Array.isArray(refs[key])) {
5768 remove(refs[key], ref);
5769 } else if (refs[key] === ref) {
5770 refs[key] = undefined;
5771 }
5772 } else {
5773 if (vnode.data.refInFor) {
5774 if (!Array.isArray(refs[key])) {
5775 refs[key] = [ref];
5776 } else if (refs[key].indexOf(ref) < 0) {
5777 // $flow-disable-line
5778 refs[key].push(ref);
5779 }
5780 } else {
5781 refs[key] = ref;
5782 }
5783 }
5784}
5785
5786/**
5787 * Virtual DOM patching algorithm based on Snabbdom by
5788 * Simon Friis Vindum (@paldepind)
5789 * Licensed under the MIT License
5790 * https://github.com/paldepind/snabbdom/blob/master/LICENSE
5791 *
5792 * modified by Evan You (@yyx990803)
5793 *
5794 * Not type-checking this because this file is perf-critical and the cost
5795 * of making flow understand it is not worth it.
5796 */
5797
5798const emptyNode = new VNode('', {}, []);
5799
5800const hooks = ['create', 'activate', 'update', 'remove', 'destroy'];
5801
5802function sameVnode (a, b) {
5803 return (
5804 a.key === b.key && (
5805 (
5806 a.tag === b.tag &&
5807 a.isComment === b.isComment &&
5808 isDef(a.data) === isDef(b.data) &&
5809 sameInputType(a, b)
5810 ) || (
5811 isTrue(a.isAsyncPlaceholder) &&
5812 a.asyncFactory === b.asyncFactory &&
5813 isUndef(b.asyncFactory.error)
5814 )
5815 )
5816 )
5817}
5818
5819function sameInputType (a, b) {
5820 if (a.tag !== 'input') return true
5821 let i;
5822 const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type;
5823 const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type;
5824 return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
5825}
5826
5827function createKeyToOldIdx (children, beginIdx, endIdx) {
5828 let i, key;
5829 const map = {};
5830 for (i = beginIdx; i <= endIdx; ++i) {
5831 key = children[i].key;
5832 if (isDef(key)) map[key] = i;
5833 }
5834 return map
5835}
5836
5837function createPatchFunction (backend) {
5838 let i, j;
5839 const cbs = {};
5840
5841 const { modules, nodeOps } = backend;
5842
5843 for (i = 0; i < hooks.length; ++i) {
5844 cbs[hooks[i]] = [];
5845 for (j = 0; j < modules.length; ++j) {
5846 if (isDef(modules[j][hooks[i]])) {
5847 cbs[hooks[i]].push(modules[j][hooks[i]]);
5848 }
5849 }
5850 }
5851
5852 function emptyNodeAt (elm) {
5853 return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
5854 }
5855
5856 function createRmCb (childElm, listeners) {
5857 function remove$$1 () {
5858 if (--remove$$1.listeners === 0) {
5859 removeNode(childElm);
5860 }
5861 }
5862 remove$$1.listeners = listeners;
5863 return remove$$1
5864 }
5865
5866 function removeNode (el) {
5867 const parent = nodeOps.parentNode(el);
5868 // element may have already been removed due to v-html / v-text
5869 if (isDef(parent)) {
5870 nodeOps.removeChild(parent, el);
5871 }
5872 }
5873
5874 function isUnknownElement$$1 (vnode, inVPre) {
5875 return (
5876 !inVPre &&
5877 !vnode.ns &&
5878 !(
5879 config.ignoredElements.length &&
5880 config.ignoredElements.some(ignore => {
5881 return isRegExp(ignore)
5882 ? ignore.test(vnode.tag)
5883 : ignore === vnode.tag
5884 })
5885 ) &&
5886 config.isUnknownElement(vnode.tag)
5887 )
5888 }
5889
5890 let creatingElmInVPre = 0;
5891
5892 function createElm (
5893 vnode,
5894 insertedVnodeQueue,
5895 parentElm,
5896 refElm,
5897 nested,
5898 ownerArray,
5899 index
5900 ) {
5901 if (isDef(vnode.elm) && isDef(ownerArray)) {
5902 // This vnode was used in a previous render!
5903 // now it's used as a new node, overwriting its elm would cause
5904 // potential patch errors down the road when it's used as an insertion
5905 // reference node. Instead, we clone the node on-demand before creating
5906 // associated DOM element for it.
5907 vnode = ownerArray[index] = cloneVNode(vnode);
5908 }
5909
5910 vnode.isRootInsert = !nested; // for transition enter check
5911 if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
5912 return
5913 }
5914
5915 const data = vnode.data;
5916 const children = vnode.children;
5917 const tag = vnode.tag;
5918 if (isDef(tag)) {
5919 {
5920 if (data && data.pre) {
5921 creatingElmInVPre++;
5922 }
5923 if (isUnknownElement$$1(vnode, creatingElmInVPre)) {
5924 warn(
5925 'Unknown custom element: <' + tag + '> - did you ' +
5926 'register the component correctly? For recursive components, ' +
5927 'make sure to provide the "name" option.',
5928 vnode.context
5929 );
5930 }
5931 }
5932
5933 vnode.elm = vnode.ns
5934 ? nodeOps.createElementNS(vnode.ns, tag)
5935 : nodeOps.createElement(tag, vnode);
5936 setScope(vnode);
5937
5938 /* istanbul ignore if */
5939 {
5940 createChildren(vnode, children, insertedVnodeQueue);
5941 if (isDef(data)) {
5942 invokeCreateHooks(vnode, insertedVnodeQueue);
5943 }
5944 insert(parentElm, vnode.elm, refElm);
5945 }
5946
5947 if (data && data.pre) {
5948 creatingElmInVPre--;
5949 }
5950 } else if (isTrue(vnode.isComment)) {
5951 vnode.elm = nodeOps.createComment(vnode.text);
5952 insert(parentElm, vnode.elm, refElm);
5953 } else {
5954 vnode.elm = nodeOps.createTextNode(vnode.text);
5955 insert(parentElm, vnode.elm, refElm);
5956 }
5957 }
5958
5959 function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
5960 let i = vnode.data;
5961 if (isDef(i)) {
5962 const isReactivated = isDef(vnode.componentInstance) && i.keepAlive;
5963 if (isDef(i = i.hook) && isDef(i = i.init)) {
5964 i(vnode, false /* hydrating */);
5965 }
5966 // after calling the init hook, if the vnode is a child component
5967 // it should've created a child instance and mounted it. the child
5968 // component also has set the placeholder vnode's elm.
5969 // in that case we can just return the element and be done.
5970 if (isDef(vnode.componentInstance)) {
5971 initComponent(vnode, insertedVnodeQueue);
5972 insert(parentElm, vnode.elm, refElm);
5973 if (isTrue(isReactivated)) {
5974 reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);
5975 }
5976 return true
5977 }
5978 }
5979 }
5980
5981 function initComponent (vnode, insertedVnodeQueue) {
5982 if (isDef(vnode.data.pendingInsert)) {
5983 insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);
5984 vnode.data.pendingInsert = null;
5985 }
5986 vnode.elm = vnode.componentInstance.$el;
5987 if (isPatchable(vnode)) {
5988 invokeCreateHooks(vnode, insertedVnodeQueue);
5989 setScope(vnode);
5990 } else {
5991 // empty component root.
5992 // skip all element-related modules except for ref (#3455)
5993 registerRef(vnode);
5994 // make sure to invoke the insert hook
5995 insertedVnodeQueue.push(vnode);
5996 }
5997 }
5998
5999 function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
6000 let i;
6001 // hack for #4339: a reactivated component with inner transition
6002 // does not trigger because the inner node's created hooks are not called
6003 // again. It's not ideal to involve module-specific logic in here but
6004 // there doesn't seem to be a better way to do it.
6005 let innerNode = vnode;
6006 while (innerNode.componentInstance) {
6007 innerNode = innerNode.componentInstance._vnode;
6008 if (isDef(i = innerNode.data) && isDef(i = i.transition)) {
6009 for (i = 0; i < cbs.activate.length; ++i) {
6010 cbs.activate[i](emptyNode, innerNode);
6011 }
6012 insertedVnodeQueue.push(innerNode);
6013 break
6014 }
6015 }
6016 // unlike a newly created component,
6017 // a reactivated keep-alive component doesn't insert itself
6018 insert(parentElm, vnode.elm, refElm);
6019 }
6020
6021 function insert (parent, elm, ref$$1) {
6022 if (isDef(parent)) {
6023 if (isDef(ref$$1)) {
6024 if (nodeOps.parentNode(ref$$1) === parent) {
6025 nodeOps.insertBefore(parent, elm, ref$$1);
6026 }
6027 } else {
6028 nodeOps.appendChild(parent, elm);
6029 }
6030 }
6031 }
6032
6033 function createChildren (vnode, children, insertedVnodeQueue) {
6034 if (Array.isArray(children)) {
6035 {
6036 checkDuplicateKeys(children);
6037 }
6038 for (let i = 0; i < children.length; ++i) {
6039 createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i);
6040 }
6041 } else if (isPrimitive(vnode.text)) {
6042 nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)));
6043 }
6044 }
6045
6046 function isPatchable (vnode) {
6047 while (vnode.componentInstance) {
6048 vnode = vnode.componentInstance._vnode;
6049 }
6050 return isDef(vnode.tag)
6051 }
6052
6053 function invokeCreateHooks (vnode, insertedVnodeQueue) {
6054 for (let i = 0; i < cbs.create.length; ++i) {
6055 cbs.create[i](emptyNode, vnode);
6056 }
6057 i = vnode.data.hook; // Reuse variable
6058 if (isDef(i)) {
6059 if (isDef(i.create)) i.create(emptyNode, vnode);
6060 if (isDef(i.insert)) insertedVnodeQueue.push(vnode);
6061 }
6062 }
6063
6064 // set scope id attribute for scoped CSS.
6065 // this is implemented as a special case to avoid the overhead
6066 // of going through the normal attribute patching process.
6067 function setScope (vnode) {
6068 let i;
6069 if (isDef(i = vnode.fnScopeId)) {
6070 nodeOps.setStyleScope(vnode.elm, i);
6071 } else {
6072 let ancestor = vnode;
6073 while (ancestor) {
6074 if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {
6075 nodeOps.setStyleScope(vnode.elm, i);
6076 }
6077 ancestor = ancestor.parent;
6078 }
6079 }
6080 // for slot content they should also get the scopeId from the host instance.
6081 if (isDef(i = activeInstance) &&
6082 i !== vnode.context &&
6083 i !== vnode.fnContext &&
6084 isDef(i = i.$options._scopeId)
6085 ) {
6086 nodeOps.setStyleScope(vnode.elm, i);
6087 }
6088 }
6089
6090 function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {
6091 for (; startIdx <= endIdx; ++startIdx) {
6092 createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx);
6093 }
6094 }
6095
6096 function invokeDestroyHook (vnode) {
6097 let i, j;
6098 const data = vnode.data;
6099 if (isDef(data)) {
6100 if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode);
6101 for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode);
6102 }
6103 if (isDef(i = vnode.children)) {
6104 for (j = 0; j < vnode.children.length; ++j) {
6105 invokeDestroyHook(vnode.children[j]);
6106 }
6107 }
6108 }
6109
6110 function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
6111 for (; startIdx <= endIdx; ++startIdx) {
6112 const ch = vnodes[startIdx];
6113 if (isDef(ch)) {
6114 if (isDef(ch.tag)) {
6115 removeAndInvokeRemoveHook(ch);
6116 invokeDestroyHook(ch);
6117 } else { // Text node
6118 removeNode(ch.elm);
6119 }
6120 }
6121 }
6122 }
6123
6124 function removeAndInvokeRemoveHook (vnode, rm) {
6125 if (isDef(rm) || isDef(vnode.data)) {
6126 let i;
6127 const listeners = cbs.remove.length + 1;
6128 if (isDef(rm)) {
6129 // we have a recursively passed down rm callback
6130 // increase the listeners count
6131 rm.listeners += listeners;
6132 } else {
6133 // directly removing
6134 rm = createRmCb(vnode.elm, listeners);
6135 }
6136 // recursively invoke hooks on child component root node
6137 if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {
6138 removeAndInvokeRemoveHook(i, rm);
6139 }
6140 for (i = 0; i < cbs.remove.length; ++i) {
6141 cbs.remove[i](vnode, rm);
6142 }
6143 if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {
6144 i(vnode, rm);
6145 } else {
6146 rm();
6147 }
6148 } else {
6149 removeNode(vnode.elm);
6150 }
6151 }
6152
6153 function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
6154 let oldStartIdx = 0;
6155 let newStartIdx = 0;
6156 let oldEndIdx = oldCh.length - 1;
6157 let oldStartVnode = oldCh[0];
6158 let oldEndVnode = oldCh[oldEndIdx];
6159 let newEndIdx = newCh.length - 1;
6160 let newStartVnode = newCh[0];
6161 let newEndVnode = newCh[newEndIdx];
6162 let oldKeyToIdx, idxInOld, vnodeToMove, refElm;
6163
6164 // removeOnly is a special flag used only by <transition-group>
6165 // to ensure removed elements stay in correct relative positions
6166 // during leaving transitions
6167 const canMove = !removeOnly;
6168
6169 {
6170 checkDuplicateKeys(newCh);
6171 }
6172
6173 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
6174 if (isUndef(oldStartVnode)) {
6175 oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left
6176 } else if (isUndef(oldEndVnode)) {
6177 oldEndVnode = oldCh[--oldEndIdx];
6178 } else if (sameVnode(oldStartVnode, newStartVnode)) {
6179 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
6180 oldStartVnode = oldCh[++oldStartIdx];
6181 newStartVnode = newCh[++newStartIdx];
6182 } else if (sameVnode(oldEndVnode, newEndVnode)) {
6183 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx);
6184 oldEndVnode = oldCh[--oldEndIdx];
6185 newEndVnode = newCh[--newEndIdx];
6186 } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
6187 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx);
6188 canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));
6189 oldStartVnode = oldCh[++oldStartIdx];
6190 newEndVnode = newCh[--newEndIdx];
6191 } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
6192 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
6193 canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
6194 oldEndVnode = oldCh[--oldEndIdx];
6195 newStartVnode = newCh[++newStartIdx];
6196 } else {
6197 if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
6198 idxInOld = isDef(newStartVnode.key)
6199 ? oldKeyToIdx[newStartVnode.key]
6200 : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);
6201 if (isUndef(idxInOld)) { // New element
6202 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx);
6203 } else {
6204 vnodeToMove = oldCh[idxInOld];
6205 if (sameVnode(vnodeToMove, newStartVnode)) {
6206 patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
6207 oldCh[idxInOld] = undefined;
6208 canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm);
6209 } else {
6210 // same key but different element. treat as new element
6211 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx);
6212 }
6213 }
6214 newStartVnode = newCh[++newStartIdx];
6215 }
6216 }
6217 if (oldStartIdx > oldEndIdx) {
6218 refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;
6219 addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
6220 } else if (newStartIdx > newEndIdx) {
6221 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
6222 }
6223 }
6224
6225 function checkDuplicateKeys (children) {
6226 const seenKeys = {};
6227 for (let i = 0; i < children.length; i++) {
6228 const vnode = children[i];
6229 const key = vnode.key;
6230 if (isDef(key)) {
6231 if (seenKeys[key]) {
6232 warn(
6233 `Duplicate keys detected: '${key}'. This may cause an update error.`,
6234 vnode.context
6235 );
6236 } else {
6237 seenKeys[key] = true;
6238 }
6239 }
6240 }
6241 }
6242
6243 function findIdxInOld (node, oldCh, start, end) {
6244 for (let i = start; i < end; i++) {
6245 const c = oldCh[i];
6246 if (isDef(c) && sameVnode(node, c)) return i
6247 }
6248 }
6249
6250 function patchVnode (
6251 oldVnode,
6252 vnode,
6253 insertedVnodeQueue,
6254 ownerArray,
6255 index,
6256 removeOnly
6257 ) {
6258 if (oldVnode === vnode) {
6259 return
6260 }
6261
6262 if (isDef(vnode.elm) && isDef(ownerArray)) {
6263 // clone reused vnode
6264 vnode = ownerArray[index] = cloneVNode(vnode);
6265 }
6266
6267 const elm = vnode.elm = oldVnode.elm;
6268
6269 if (isTrue(oldVnode.isAsyncPlaceholder)) {
6270 if (isDef(vnode.asyncFactory.resolved)) {
6271 hydrate(oldVnode.elm, vnode, insertedVnodeQueue);
6272 } else {
6273 vnode.isAsyncPlaceholder = true;
6274 }
6275 return
6276 }
6277
6278 // reuse element for static trees.
6279 // note we only do this if the vnode is cloned -
6280 // if the new node is not cloned it means the render functions have been
6281 // reset by the hot-reload-api and we need to do a proper re-render.
6282 if (isTrue(vnode.isStatic) &&
6283 isTrue(oldVnode.isStatic) &&
6284 vnode.key === oldVnode.key &&
6285 (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
6286 ) {
6287 vnode.componentInstance = oldVnode.componentInstance;
6288 return
6289 }
6290
6291 let i;
6292 const data = vnode.data;
6293 if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
6294 i(oldVnode, vnode);
6295 }
6296
6297 const oldCh = oldVnode.children;
6298 const ch = vnode.children;
6299 if (isDef(data) && isPatchable(vnode)) {
6300 for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode);
6301 if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode);
6302 }
6303 if (isUndef(vnode.text)) {
6304 if (isDef(oldCh) && isDef(ch)) {
6305 if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly);
6306 } else if (isDef(ch)) {
6307 {
6308 checkDuplicateKeys(ch);
6309 }
6310 if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '');
6311 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
6312 } else if (isDef(oldCh)) {
6313 removeVnodes(elm, oldCh, 0, oldCh.length - 1);
6314 } else if (isDef(oldVnode.text)) {
6315 nodeOps.setTextContent(elm, '');
6316 }
6317 } else if (oldVnode.text !== vnode.text) {
6318 nodeOps.setTextContent(elm, vnode.text);
6319 }
6320 if (isDef(data)) {
6321 if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode);
6322 }
6323 }
6324
6325 function invokeInsertHook (vnode, queue, initial) {
6326 // delay insert hooks for component root nodes, invoke them after the
6327 // element is really inserted
6328 if (isTrue(initial) && isDef(vnode.parent)) {
6329 vnode.parent.data.pendingInsert = queue;
6330 } else {
6331 for (let i = 0; i < queue.length; ++i) {
6332 queue[i].data.hook.insert(queue[i]);
6333 }
6334 }
6335 }
6336
6337 let hydrationBailed = false;
6338 // list of modules that can skip create hook during hydration because they
6339 // are already rendered on the client or has no need for initialization
6340 // Note: style is excluded because it relies on initial clone for future
6341 // deep updates (#7063).
6342 const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key');
6343
6344 // Note: this is a browser-only function so we can assume elms are DOM nodes.
6345 function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
6346 let i;
6347 const { tag, data, children } = vnode;
6348 inVPre = inVPre || (data && data.pre);
6349 vnode.elm = elm;
6350
6351 if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
6352 vnode.isAsyncPlaceholder = true;
6353 return true
6354 }
6355 // assert node match
6356 {
6357 if (!assertNodeMatch(elm, vnode, inVPre)) {
6358 return false
6359 }
6360 }
6361 if (isDef(data)) {
6362 if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */);
6363 if (isDef(i = vnode.componentInstance)) {
6364 // child component. it should have hydrated its own tree.
6365 initComponent(vnode, insertedVnodeQueue);
6366 return true
6367 }
6368 }
6369 if (isDef(tag)) {
6370 if (isDef(children)) {
6371 // empty element, allow client to pick up and populate children
6372 if (!elm.hasChildNodes()) {
6373 createChildren(vnode, children, insertedVnodeQueue);
6374 } else {
6375 // v-html and domProps: innerHTML
6376 if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
6377 if (i !== elm.innerHTML) {
6378 /* istanbul ignore if */
6379 if (typeof console !== 'undefined' &&
6380 !hydrationBailed
6381 ) {
6382 hydrationBailed = true;
6383 console.warn('Parent: ', elm);
6384 console.warn('server innerHTML: ', i);
6385 console.warn('client innerHTML: ', elm.innerHTML);
6386 }
6387 return false
6388 }
6389 } else {
6390 // iterate and compare children lists
6391 let childrenMatch = true;
6392 let childNode = elm.firstChild;
6393 for (let i = 0; i < children.length; i++) {
6394 if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {
6395 childrenMatch = false;
6396 break
6397 }
6398 childNode = childNode.nextSibling;
6399 }
6400 // if childNode is not null, it means the actual childNodes list is
6401 // longer than the virtual children list.
6402 if (!childrenMatch || childNode) {
6403 /* istanbul ignore if */
6404 if (typeof console !== 'undefined' &&
6405 !hydrationBailed
6406 ) {
6407 hydrationBailed = true;
6408 console.warn('Parent: ', elm);
6409 console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);
6410 }
6411 return false
6412 }
6413 }
6414 }
6415 }
6416 if (isDef(data)) {
6417 let fullInvoke = false;
6418 for (const key in data) {
6419 if (!isRenderedModule(key)) {
6420 fullInvoke = true;
6421 invokeCreateHooks(vnode, insertedVnodeQueue);
6422 break
6423 }
6424 }
6425 if (!fullInvoke && data['class']) {
6426 // ensure collecting deps for deep class bindings for future updates
6427 traverse(data['class']);
6428 }
6429 }
6430 } else if (elm.data !== vnode.text) {
6431 elm.data = vnode.text;
6432 }
6433 return true
6434 }
6435
6436 function assertNodeMatch (node, vnode, inVPre) {
6437 if (isDef(vnode.tag)) {
6438 return vnode.tag.indexOf('vue-component') === 0 || (
6439 !isUnknownElement$$1(vnode, inVPre) &&
6440 vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())
6441 )
6442 } else {
6443 return node.nodeType === (vnode.isComment ? 8 : 3)
6444 }
6445 }
6446
6447 return function patch (oldVnode, vnode, hydrating, removeOnly) {
6448 if (isUndef(vnode)) {
6449 if (isDef(oldVnode)) invokeDestroyHook(oldVnode);
6450 return
6451 }
6452
6453 let isInitialPatch = false;
6454 const insertedVnodeQueue = [];
6455
6456 if (isUndef(oldVnode)) {
6457 // empty mount (likely as component), create new root element
6458 isInitialPatch = true;
6459 createElm(vnode, insertedVnodeQueue);
6460 } else {
6461 const isRealElement = isDef(oldVnode.nodeType);
6462 if (!isRealElement && sameVnode(oldVnode, vnode)) {
6463 // patch existing root node
6464 patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly);
6465 } else {
6466 if (isRealElement) {
6467 // mounting to a real element
6468 // check if this is server-rendered content and if we can perform
6469 // a successful hydration.
6470 if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
6471 oldVnode.removeAttribute(SSR_ATTR);
6472 hydrating = true;
6473 }
6474 if (isTrue(hydrating)) {
6475 if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
6476 invokeInsertHook(vnode, insertedVnodeQueue, true);
6477 return oldVnode
6478 } else {
6479 warn(
6480 'The client-side rendered virtual DOM tree is not matching ' +
6481 'server-rendered content. This is likely caused by incorrect ' +
6482 'HTML markup, for example nesting block-level elements inside ' +
6483 '<p>, or missing <tbody>. Bailing hydration and performing ' +
6484 'full client-side render.'
6485 );
6486 }
6487 }
6488 // either not server-rendered, or hydration failed.
6489 // create an empty node and replace it
6490 oldVnode = emptyNodeAt(oldVnode);
6491 }
6492
6493 // replacing existing element
6494 const oldElm = oldVnode.elm;
6495 const parentElm = nodeOps.parentNode(oldElm);
6496
6497 // create new node
6498 createElm(
6499 vnode,
6500 insertedVnodeQueue,
6501 // extremely rare edge case: do not insert if old element is in a
6502 // leaving transition. Only happens when combining transition +
6503 // keep-alive + HOCs. (#4590)
6504 oldElm._leaveCb ? null : parentElm,
6505 nodeOps.nextSibling(oldElm)
6506 );
6507
6508 // update parent placeholder node element, recursively
6509 if (isDef(vnode.parent)) {
6510 let ancestor = vnode.parent;
6511 const patchable = isPatchable(vnode);
6512 while (ancestor) {
6513 for (let i = 0; i < cbs.destroy.length; ++i) {
6514 cbs.destroy[i](ancestor);
6515 }
6516 ancestor.elm = vnode.elm;
6517 if (patchable) {
6518 for (let i = 0; i < cbs.create.length; ++i) {
6519 cbs.create[i](emptyNode, ancestor);
6520 }
6521 // #6513
6522 // invoke insert hooks that may have been merged by create hooks.
6523 // e.g. for directives that uses the "inserted" hook.
6524 const insert = ancestor.data.hook.insert;
6525 if (insert.merged) {
6526 // start at index 1 to avoid re-invoking component mounted hook
6527 for (let i = 1; i < insert.fns.length; i++) {
6528 insert.fns[i]();
6529 }
6530 }
6531 } else {
6532 registerRef(ancestor);
6533 }
6534 ancestor = ancestor.parent;
6535 }
6536 }
6537
6538 // destroy old node
6539 if (isDef(parentElm)) {
6540 removeVnodes(parentElm, [oldVnode], 0, 0);
6541 } else if (isDef(oldVnode.tag)) {
6542 invokeDestroyHook(oldVnode);
6543 }
6544 }
6545 }
6546
6547 invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
6548 return vnode.elm
6549 }
6550}
6551
6552/* */
6553
6554var directives = {
6555 create: updateDirectives,
6556 update: updateDirectives,
6557 destroy: function unbindDirectives (vnode) {
6558 updateDirectives(vnode, emptyNode);
6559 }
6560};
6561
6562function updateDirectives (oldVnode, vnode) {
6563 if (oldVnode.data.directives || vnode.data.directives) {
6564 _update(oldVnode, vnode);
6565 }
6566}
6567
6568function _update (oldVnode, vnode) {
6569 const isCreate = oldVnode === emptyNode;
6570 const isDestroy = vnode === emptyNode;
6571 const oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);
6572 const newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);
6573
6574 const dirsWithInsert = [];
6575 const dirsWithPostpatch = [];
6576
6577 let key, oldDir, dir;
6578 for (key in newDirs) {
6579 oldDir = oldDirs[key];
6580 dir = newDirs[key];
6581 if (!oldDir) {
6582 // new directive, bind
6583 callHook$1(dir, 'bind', vnode, oldVnode);
6584 if (dir.def && dir.def.inserted) {
6585 dirsWithInsert.push(dir);
6586 }
6587 } else {
6588 // existing directive, update
6589 dir.oldValue = oldDir.value;
6590 dir.oldArg = oldDir.arg;
6591 callHook$1(dir, 'update', vnode, oldVnode);
6592 if (dir.def && dir.def.componentUpdated) {
6593 dirsWithPostpatch.push(dir);
6594 }
6595 }
6596 }
6597
6598 if (dirsWithInsert.length) {
6599 const callInsert = () => {
6600 for (let i = 0; i < dirsWithInsert.length; i++) {
6601 callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode);
6602 }
6603 };
6604 if (isCreate) {
6605 mergeVNodeHook(vnode, 'insert', callInsert);
6606 } else {
6607 callInsert();
6608 }
6609 }
6610
6611 if (dirsWithPostpatch.length) {
6612 mergeVNodeHook(vnode, 'postpatch', () => {
6613 for (let i = 0; i < dirsWithPostpatch.length; i++) {
6614 callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode);
6615 }
6616 });
6617 }
6618
6619 if (!isCreate) {
6620 for (key in oldDirs) {
6621 if (!newDirs[key]) {
6622 // no longer present, unbind
6623 callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy);
6624 }
6625 }
6626 }
6627}
6628
6629const emptyModifiers = Object.create(null);
6630
6631function normalizeDirectives$1 (
6632 dirs,
6633 vm
6634) {
6635 const res = Object.create(null);
6636 if (!dirs) {
6637 // $flow-disable-line
6638 return res
6639 }
6640 let i, dir;
6641 for (i = 0; i < dirs.length; i++) {
6642 dir = dirs[i];
6643 if (!dir.modifiers) {
6644 // $flow-disable-line
6645 dir.modifiers = emptyModifiers;
6646 }
6647 res[getRawDirName(dir)] = dir;
6648 dir.def = resolveAsset(vm.$options, 'directives', dir.name, true);
6649 }
6650 // $flow-disable-line
6651 return res
6652}
6653
6654function getRawDirName (dir) {
6655 return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}`
6656}
6657
6658function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) {
6659 const fn = dir.def && dir.def[hook];
6660 if (fn) {
6661 try {
6662 fn(vnode.elm, dir, vnode, oldVnode, isDestroy);
6663 } catch (e) {
6664 handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`);
6665 }
6666 }
6667}
6668
6669var baseModules = [
6670 ref,
6671 directives
6672];
6673
6674/* */
6675
6676function updateAttrs (oldVnode, vnode) {
6677 const opts = vnode.componentOptions;
6678 if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) {
6679 return
6680 }
6681 if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) {
6682 return
6683 }
6684 let key, cur, old;
6685 const elm = vnode.elm;
6686 const oldAttrs = oldVnode.data.attrs || {};
6687 let attrs = vnode.data.attrs || {};
6688 // clone observed objects, as the user probably wants to mutate it
6689 if (isDef(attrs.__ob__)) {
6690 attrs = vnode.data.attrs = extend({}, attrs);
6691 }
6692
6693 for (key in attrs) {
6694 cur = attrs[key];
6695 old = oldAttrs[key];
6696 if (old !== cur) {
6697 setAttr(elm, key, cur);
6698 }
6699 }
6700 // #4391: in IE9, setting type can reset value for input[type=radio]
6701 // #6666: IE/Edge forces progress value down to 1 before setting a max
6702 /* istanbul ignore if */
6703 if ((isIE || isEdge) && attrs.value !== oldAttrs.value) {
6704 setAttr(elm, 'value', attrs.value);
6705 }
6706 for (key in oldAttrs) {
6707 if (isUndef(attrs[key])) {
6708 if (isXlink(key)) {
6709 elm.removeAttributeNS(xlinkNS, getXlinkProp(key));
6710 } else if (!isEnumeratedAttr(key)) {
6711 elm.removeAttribute(key);
6712 }
6713 }
6714 }
6715}
6716
6717function setAttr (el, key, value) {
6718 if (el.tagName.indexOf('-') > -1) {
6719 baseSetAttr(el, key, value);
6720 } else if (isBooleanAttr(key)) {
6721 // set attribute for blank value
6722 // e.g. <option disabled>Select one</option>
6723 if (isFalsyAttrValue(value)) {
6724 el.removeAttribute(key);
6725 } else {
6726 // technically allowfullscreen is a boolean attribute for <iframe>,
6727 // but Flash expects a value of "true" when used on <embed> tag
6728 value = key === 'allowfullscreen' && el.tagName === 'EMBED'
6729 ? 'true'
6730 : key;
6731 el.setAttribute(key, value);
6732 }
6733 } else if (isEnumeratedAttr(key)) {
6734 el.setAttribute(key, convertEnumeratedValue(key, value));
6735 } else if (isXlink(key)) {
6736 if (isFalsyAttrValue(value)) {
6737 el.removeAttributeNS(xlinkNS, getXlinkProp(key));
6738 } else {
6739 el.setAttributeNS(xlinkNS, key, value);
6740 }
6741 } else {
6742 baseSetAttr(el, key, value);
6743 }
6744}
6745
6746function baseSetAttr (el, key, value) {
6747 if (isFalsyAttrValue(value)) {
6748 el.removeAttribute(key);
6749 } else {
6750 // #7138: IE10 & 11 fires input event when setting placeholder on
6751 // <textarea>... block the first input event and remove the blocker
6752 // immediately.
6753 /* istanbul ignore if */
6754 if (
6755 isIE && !isIE9 &&
6756 el.tagName === 'TEXTAREA' &&
6757 key === 'placeholder' && value !== '' && !el.__ieph
6758 ) {
6759 const blocker = e => {
6760 e.stopImmediatePropagation();
6761 el.removeEventListener('input', blocker);
6762 };
6763 el.addEventListener('input', blocker);
6764 // $flow-disable-line
6765 el.__ieph = true; /* IE placeholder patched */
6766 }
6767 el.setAttribute(key, value);
6768 }
6769}
6770
6771var attrs = {
6772 create: updateAttrs,
6773 update: updateAttrs
6774};
6775
6776/* */
6777
6778function updateClass (oldVnode, vnode) {
6779 const el = vnode.elm;
6780 const data = vnode.data;
6781 const oldData = oldVnode.data;
6782 if (
6783 isUndef(data.staticClass) &&
6784 isUndef(data.class) && (
6785 isUndef(oldData) || (
6786 isUndef(oldData.staticClass) &&
6787 isUndef(oldData.class)
6788 )
6789 )
6790 ) {
6791 return
6792 }
6793
6794 let cls = genClassForVnode(vnode);
6795
6796 // handle transition classes
6797 const transitionClass = el._transitionClasses;
6798 if (isDef(transitionClass)) {
6799 cls = concat(cls, stringifyClass(transitionClass));
6800 }
6801
6802 // set the class
6803 if (cls !== el._prevClass) {
6804 el.setAttribute('class', cls);
6805 el._prevClass = cls;
6806 }
6807}
6808
6809var klass = {
6810 create: updateClass,
6811 update: updateClass
6812};
6813
6814/* */
6815
6816const validDivisionCharRE = /[\w).+\-_$\]]/;
6817
6818function parseFilters (exp) {
6819 let inSingle = false;
6820 let inDouble = false;
6821 let inTemplateString = false;
6822 let inRegex = false;
6823 let curly = 0;
6824 let square = 0;
6825 let paren = 0;
6826 let lastFilterIndex = 0;
6827 let c, prev, i, expression, filters;
6828
6829 for (i = 0; i < exp.length; i++) {
6830 prev = c;
6831 c = exp.charCodeAt(i);
6832 if (inSingle) {
6833 if (c === 0x27 && prev !== 0x5C) inSingle = false;
6834 } else if (inDouble) {
6835 if (c === 0x22 && prev !== 0x5C) inDouble = false;
6836 } else if (inTemplateString) {
6837 if (c === 0x60 && prev !== 0x5C) inTemplateString = false;
6838 } else if (inRegex) {
6839 if (c === 0x2f && prev !== 0x5C) inRegex = false;
6840 } else if (
6841 c === 0x7C && // pipe
6842 exp.charCodeAt(i + 1) !== 0x7C &&
6843 exp.charCodeAt(i - 1) !== 0x7C &&
6844 !curly && !square && !paren
6845 ) {
6846 if (expression === undefined) {
6847 // first filter, end of expression
6848 lastFilterIndex = i + 1;
6849 expression = exp.slice(0, i).trim();
6850 } else {
6851 pushFilter();
6852 }
6853 } else {
6854 switch (c) {
6855 case 0x22: inDouble = true; break // "
6856 case 0x27: inSingle = true; break // '
6857 case 0x60: inTemplateString = true; break // `
6858 case 0x28: paren++; break // (
6859 case 0x29: paren--; break // )
6860 case 0x5B: square++; break // [
6861 case 0x5D: square--; break // ]
6862 case 0x7B: curly++; break // {
6863 case 0x7D: curly--; break // }
6864 }
6865 if (c === 0x2f) { // /
6866 let j = i - 1;
6867 let p;
6868 // find first non-whitespace prev char
6869 for (; j >= 0; j--) {
6870 p = exp.charAt(j);
6871 if (p !== ' ') break
6872 }
6873 if (!p || !validDivisionCharRE.test(p)) {
6874 inRegex = true;
6875 }
6876 }
6877 }
6878 }
6879
6880 if (expression === undefined) {
6881 expression = exp.slice(0, i).trim();
6882 } else if (lastFilterIndex !== 0) {
6883 pushFilter();
6884 }
6885
6886 function pushFilter () {
6887 (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim());
6888 lastFilterIndex = i + 1;
6889 }
6890
6891 if (filters) {
6892 for (i = 0; i < filters.length; i++) {
6893 expression = wrapFilter(expression, filters[i]);
6894 }
6895 }
6896
6897 return expression
6898}
6899
6900function wrapFilter (exp, filter) {
6901 const i = filter.indexOf('(');
6902 if (i < 0) {
6903 // _f: resolveFilter
6904 return `_f("${filter}")(${exp})`
6905 } else {
6906 const name = filter.slice(0, i);
6907 const args = filter.slice(i + 1);
6908 return `_f("${name}")(${exp}${args !== ')' ? ',' + args : args}`
6909 }
6910}
6911
6912/* */
6913
6914
6915
6916/* eslint-disable no-unused-vars */
6917function baseWarn (msg, range) {
6918 console.error(`[Vue compiler]: ${msg}`);
6919}
6920/* eslint-enable no-unused-vars */
6921
6922function pluckModuleFunction (
6923 modules,
6924 key
6925) {
6926 return modules
6927 ? modules.map(m => m[key]).filter(_ => _)
6928 : []
6929}
6930
6931function addProp (el, name, value, range, dynamic) {
6932 (el.props || (el.props = [])).push(rangeSetItem({ name, value, dynamic }, range));
6933 el.plain = false;
6934}
6935
6936function addAttr (el, name, value, range, dynamic) {
6937 const attrs = dynamic
6938 ? (el.dynamicAttrs || (el.dynamicAttrs = []))
6939 : (el.attrs || (el.attrs = []));
6940 attrs.push(rangeSetItem({ name, value, dynamic }, range));
6941 el.plain = false;
6942}
6943
6944// add a raw attr (use this in preTransforms)
6945function addRawAttr (el, name, value, range) {
6946 el.attrsMap[name] = value;
6947 el.attrsList.push(rangeSetItem({ name, value }, range));
6948}
6949
6950function addDirective (
6951 el,
6952 name,
6953 rawName,
6954 value,
6955 arg,
6956 isDynamicArg,
6957 modifiers,
6958 range
6959) {
6960 (el.directives || (el.directives = [])).push(rangeSetItem({
6961 name,
6962 rawName,
6963 value,
6964 arg,
6965 isDynamicArg,
6966 modifiers
6967 }, range));
6968 el.plain = false;
6969}
6970
6971function prependModifierMarker (symbol, name, dynamic) {
6972 return dynamic
6973 ? `_p(${name},"${symbol}")`
6974 : symbol + name // mark the event as captured
6975}
6976
6977function addHandler (
6978 el,
6979 name,
6980 value,
6981 modifiers,
6982 important,
6983 warn,
6984 range,
6985 dynamic
6986) {
6987 modifiers = modifiers || emptyObject;
6988 // warn prevent and passive modifier
6989 /* istanbul ignore if */
6990 if (
6991 warn &&
6992 modifiers.prevent && modifiers.passive
6993 ) {
6994 warn(
6995 'passive and prevent can\'t be used together. ' +
6996 'Passive handler can\'t prevent default event.',
6997 range
6998 );
6999 }
7000
7001 // normalize click.right and click.middle since they don't actually fire
7002 // this is technically browser-specific, but at least for now browsers are
7003 // the only target envs that have right/middle clicks.
7004 if (modifiers.right) {
7005 if (dynamic) {
7006 name = `(${name})==='click'?'contextmenu':(${name})`;
7007 } else if (name === 'click') {
7008 name = 'contextmenu';
7009 delete modifiers.right;
7010 }
7011 } else if (modifiers.middle) {
7012 if (dynamic) {
7013 name = `(${name})==='click'?'mouseup':(${name})`;
7014 } else if (name === 'click') {
7015 name = 'mouseup';
7016 }
7017 }
7018
7019 // check capture modifier
7020 if (modifiers.capture) {
7021 delete modifiers.capture;
7022 name = prependModifierMarker('!', name, dynamic);
7023 }
7024 if (modifiers.once) {
7025 delete modifiers.once;
7026 name = prependModifierMarker('~', name, dynamic);
7027 }
7028 /* istanbul ignore if */
7029 if (modifiers.passive) {
7030 delete modifiers.passive;
7031 name = prependModifierMarker('&', name, dynamic);
7032 }
7033
7034 let events;
7035 if (modifiers.native) {
7036 delete modifiers.native;
7037 events = el.nativeEvents || (el.nativeEvents = {});
7038 } else {
7039 events = el.events || (el.events = {});
7040 }
7041
7042 const newHandler = rangeSetItem({ value: value.trim(), dynamic }, range);
7043 if (modifiers !== emptyObject) {
7044 newHandler.modifiers = modifiers;
7045 }
7046
7047 const handlers = events[name];
7048 /* istanbul ignore if */
7049 if (Array.isArray(handlers)) {
7050 important ? handlers.unshift(newHandler) : handlers.push(newHandler);
7051 } else if (handlers) {
7052 events[name] = important ? [newHandler, handlers] : [handlers, newHandler];
7053 } else {
7054 events[name] = newHandler;
7055 }
7056
7057 el.plain = false;
7058}
7059
7060function getRawBindingAttr (
7061 el,
7062 name
7063) {
7064 return el.rawAttrsMap[':' + name] ||
7065 el.rawAttrsMap['v-bind:' + name] ||
7066 el.rawAttrsMap[name]
7067}
7068
7069function getBindingAttr (
7070 el,
7071 name,
7072 getStatic
7073) {
7074 const dynamicValue =
7075 getAndRemoveAttr(el, ':' + name) ||
7076 getAndRemoveAttr(el, 'v-bind:' + name);
7077 if (dynamicValue != null) {
7078 return parseFilters(dynamicValue)
7079 } else if (getStatic !== false) {
7080 const staticValue = getAndRemoveAttr(el, name);
7081 if (staticValue != null) {
7082 return JSON.stringify(staticValue)
7083 }
7084 }
7085}
7086
7087// note: this only removes the attr from the Array (attrsList) so that it
7088// doesn't get processed by processAttrs.
7089// By default it does NOT remove it from the map (attrsMap) because the map is
7090// needed during codegen.
7091function getAndRemoveAttr (
7092 el,
7093 name,
7094 removeFromMap
7095) {
7096 let val;
7097 if ((val = el.attrsMap[name]) != null) {
7098 const list = el.attrsList;
7099 for (let i = 0, l = list.length; i < l; i++) {
7100 if (list[i].name === name) {
7101 list.splice(i, 1);
7102 break
7103 }
7104 }
7105 }
7106 if (removeFromMap) {
7107 delete el.attrsMap[name];
7108 }
7109 return val
7110}
7111
7112function getAndRemoveAttrByRegex (
7113 el,
7114 name
7115) {
7116 const list = el.attrsList;
7117 for (let i = 0, l = list.length; i < l; i++) {
7118 const attr = list[i];
7119 if (name.test(attr.name)) {
7120 list.splice(i, 1);
7121 return attr
7122 }
7123 }
7124}
7125
7126function rangeSetItem (
7127 item,
7128 range
7129) {
7130 if (range) {
7131 if (range.start != null) {
7132 item.start = range.start;
7133 }
7134 if (range.end != null) {
7135 item.end = range.end;
7136 }
7137 }
7138 return item
7139}
7140
7141/* */
7142
7143/**
7144 * Cross-platform code generation for component v-model
7145 */
7146function genComponentModel (
7147 el,
7148 value,
7149 modifiers
7150) {
7151 const { number, trim } = modifiers || {};
7152
7153 const baseValueExpression = '$$v';
7154 let valueExpression = baseValueExpression;
7155 if (trim) {
7156 valueExpression =
7157 `(typeof ${baseValueExpression} === 'string'` +
7158 `? ${baseValueExpression}.trim()` +
7159 `: ${baseValueExpression})`;
7160 }
7161 if (number) {
7162 valueExpression = `_n(${valueExpression})`;
7163 }
7164 const assignment = genAssignmentCode(value, valueExpression);
7165
7166 el.model = {
7167 value: `(${value})`,
7168 expression: JSON.stringify(value),
7169 callback: `function (${baseValueExpression}) {${assignment}}`
7170 };
7171}
7172
7173/**
7174 * Cross-platform codegen helper for generating v-model value assignment code.
7175 */
7176function genAssignmentCode (
7177 value,
7178 assignment
7179) {
7180 const res = parseModel(value);
7181 if (res.key === null) {
7182 return `${value}=${assignment}`
7183 } else {
7184 return `$set(${res.exp}, ${res.key}, ${assignment})`
7185 }
7186}
7187
7188/**
7189 * Parse a v-model expression into a base path and a final key segment.
7190 * Handles both dot-path and possible square brackets.
7191 *
7192 * Possible cases:
7193 *
7194 * - test
7195 * - test[key]
7196 * - test[test1[key]]
7197 * - test["a"][key]
7198 * - xxx.test[a[a].test1[key]]
7199 * - test.xxx.a["asa"][test1[key]]
7200 *
7201 */
7202
7203let len, str, chr, index$1, expressionPos, expressionEndPos;
7204
7205
7206
7207function parseModel (val) {
7208 // Fix https://github.com/vuejs/vue/pull/7730
7209 // allow v-model="obj.val " (trailing whitespace)
7210 val = val.trim();
7211 len = val.length;
7212
7213 if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
7214 index$1 = val.lastIndexOf('.');
7215 if (index$1 > -1) {
7216 return {
7217 exp: val.slice(0, index$1),
7218 key: '"' + val.slice(index$1 + 1) + '"'
7219 }
7220 } else {
7221 return {
7222 exp: val,
7223 key: null
7224 }
7225 }
7226 }
7227
7228 str = val;
7229 index$1 = expressionPos = expressionEndPos = 0;
7230
7231 while (!eof()) {
7232 chr = next();
7233 /* istanbul ignore if */
7234 if (isStringStart(chr)) {
7235 parseString(chr);
7236 } else if (chr === 0x5B) {
7237 parseBracket(chr);
7238 }
7239 }
7240
7241 return {
7242 exp: val.slice(0, expressionPos),
7243 key: val.slice(expressionPos + 1, expressionEndPos)
7244 }
7245}
7246
7247function next () {
7248 return str.charCodeAt(++index$1)
7249}
7250
7251function eof () {
7252 return index$1 >= len
7253}
7254
7255function isStringStart (chr) {
7256 return chr === 0x22 || chr === 0x27
7257}
7258
7259function parseBracket (chr) {
7260 let inBracket = 1;
7261 expressionPos = index$1;
7262 while (!eof()) {
7263 chr = next();
7264 if (isStringStart(chr)) {
7265 parseString(chr);
7266 continue
7267 }
7268 if (chr === 0x5B) inBracket++;
7269 if (chr === 0x5D) inBracket--;
7270 if (inBracket === 0) {
7271 expressionEndPos = index$1;
7272 break
7273 }
7274 }
7275}
7276
7277function parseString (chr) {
7278 const stringQuote = chr;
7279 while (!eof()) {
7280 chr = next();
7281 if (chr === stringQuote) {
7282 break
7283 }
7284 }
7285}
7286
7287/* */
7288
7289let warn$1;
7290
7291// in some cases, the event used has to be determined at runtime
7292// so we used some reserved tokens during compile.
7293const RANGE_TOKEN = '__r';
7294const CHECKBOX_RADIO_TOKEN = '__c';
7295
7296function model (
7297 el,
7298 dir,
7299 _warn
7300) {
7301 warn$1 = _warn;
7302 const value = dir.value;
7303 const modifiers = dir.modifiers;
7304 const tag = el.tag;
7305 const type = el.attrsMap.type;
7306
7307 {
7308 // inputs with type="file" are read only and setting the input's
7309 // value will throw an error.
7310 if (tag === 'input' && type === 'file') {
7311 warn$1(
7312 `<${el.tag} v-model="${value}" type="file">:\n` +
7313 `File inputs are read only. Use a v-on:change listener instead.`,
7314 el.rawAttrsMap['v-model']
7315 );
7316 }
7317 }
7318
7319 if (el.component) {
7320 genComponentModel(el, value, modifiers);
7321 // component v-model doesn't need extra runtime
7322 return false
7323 } else if (tag === 'select') {
7324 genSelect(el, value, modifiers);
7325 } else if (tag === 'input' && type === 'checkbox') {
7326 genCheckboxModel(el, value, modifiers);
7327 } else if (tag === 'input' && type === 'radio') {
7328 genRadioModel(el, value, modifiers);
7329 } else if (tag === 'input' || tag === 'textarea') {
7330 genDefaultModel(el, value, modifiers);
7331 } else if (!config.isReservedTag(tag)) {
7332 genComponentModel(el, value, modifiers);
7333 // component v-model doesn't need extra runtime
7334 return false
7335 } else {
7336 warn$1(
7337 `<${el.tag} v-model="${value}">: ` +
7338 `v-model is not supported on this element type. ` +
7339 'If you are working with contenteditable, it\'s recommended to ' +
7340 'wrap a library dedicated for that purpose inside a custom component.',
7341 el.rawAttrsMap['v-model']
7342 );
7343 }
7344
7345 // ensure runtime directive metadata
7346 return true
7347}
7348
7349function genCheckboxModel (
7350 el,
7351 value,
7352 modifiers
7353) {
7354 const number = modifiers && modifiers.number;
7355 const valueBinding = getBindingAttr(el, 'value') || 'null';
7356 const trueValueBinding = getBindingAttr(el, 'true-value') || 'true';
7357 const falseValueBinding = getBindingAttr(el, 'false-value') || 'false';
7358 addProp(el, 'checked',
7359 `Array.isArray(${value})` +
7360 `?_i(${value},${valueBinding})>-1` + (
7361 trueValueBinding === 'true'
7362 ? `:(${value})`
7363 : `:_q(${value},${trueValueBinding})`
7364 )
7365 );
7366 addHandler(el, 'change',
7367 `var $$a=${value},` +
7368 '$$el=$event.target,' +
7369 `$$c=$$el.checked?(${trueValueBinding}):(${falseValueBinding});` +
7370 'if(Array.isArray($$a)){' +
7371 `var $$v=${number ? '_n(' + valueBinding + ')' : valueBinding},` +
7372 '$$i=_i($$a,$$v);' +
7373 `if($$el.checked){$$i<0&&(${genAssignmentCode(value, '$$a.concat([$$v])')})}` +
7374 `else{$$i>-1&&(${genAssignmentCode(value, '$$a.slice(0,$$i).concat($$a.slice($$i+1))')})}` +
7375 `}else{${genAssignmentCode(value, '$$c')}}`,
7376 null, true
7377 );
7378}
7379
7380function genRadioModel (
7381 el,
7382 value,
7383 modifiers
7384) {
7385 const number = modifiers && modifiers.number;
7386 let valueBinding = getBindingAttr(el, 'value') || 'null';
7387 valueBinding = number ? `_n(${valueBinding})` : valueBinding;
7388 addProp(el, 'checked', `_q(${value},${valueBinding})`);
7389 addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true);
7390}
7391
7392function genSelect (
7393 el,
7394 value,
7395 modifiers
7396) {
7397 const number = modifiers && modifiers.number;
7398 const selectedVal = `Array.prototype.filter` +
7399 `.call($event.target.options,function(o){return o.selected})` +
7400 `.map(function(o){var val = "_value" in o ? o._value : o.value;` +
7401 `return ${number ? '_n(val)' : 'val'}})`;
7402
7403 const assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';
7404 let code = `var $$selectedVal = ${selectedVal};`;
7405 code = `${code} ${genAssignmentCode(value, assignment)}`;
7406 addHandler(el, 'change', code, null, true);
7407}
7408
7409function genDefaultModel (
7410 el,
7411 value,
7412 modifiers
7413) {
7414 const type = el.attrsMap.type;
7415
7416 // warn if v-bind:value conflicts with v-model
7417 // except for inputs with v-bind:type
7418 {
7419 const value = el.attrsMap['v-bind:value'] || el.attrsMap[':value'];
7420 const typeBinding = el.attrsMap['v-bind:type'] || el.attrsMap[':type'];
7421 if (value && !typeBinding) {
7422 const binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value';
7423 warn$1(
7424 `${binding}="${value}" conflicts with v-model on the same element ` +
7425 'because the latter already expands to a value binding internally',
7426 el.rawAttrsMap[binding]
7427 );
7428 }
7429 }
7430
7431 const { lazy, number, trim } = modifiers || {};
7432 const needCompositionGuard = !lazy && type !== 'range';
7433 const event = lazy
7434 ? 'change'
7435 : type === 'range'
7436 ? RANGE_TOKEN
7437 : 'input';
7438
7439 let valueExpression = '$event.target.value';
7440 if (trim) {
7441 valueExpression = `$event.target.value.trim()`;
7442 }
7443 if (number) {
7444 valueExpression = `_n(${valueExpression})`;
7445 }
7446
7447 let code = genAssignmentCode(value, valueExpression);
7448 if (needCompositionGuard) {
7449 code = `if($event.target.composing)return;${code}`;
7450 }
7451
7452 addProp(el, 'value', `(${value})`);
7453 addHandler(el, event, code, null, true);
7454 if (trim || number) {
7455 addHandler(el, 'blur', '$forceUpdate()');
7456 }
7457}
7458
7459/* */
7460
7461// normalize v-model event tokens that can only be determined at runtime.
7462// it's important to place the event as the first in the array because
7463// the whole point is ensuring the v-model callback gets called before
7464// user-attached handlers.
7465function normalizeEvents (on) {
7466 /* istanbul ignore if */
7467 if (isDef(on[RANGE_TOKEN])) {
7468 // IE input[type=range] only supports `change` event
7469 const event = isIE ? 'change' : 'input';
7470 on[event] = [].concat(on[RANGE_TOKEN], on[event] || []);
7471 delete on[RANGE_TOKEN];
7472 }
7473 // This was originally intended to fix #4521 but no longer necessary
7474 // after 2.5. Keeping it for backwards compat with generated code from < 2.4
7475 /* istanbul ignore if */
7476 if (isDef(on[CHECKBOX_RADIO_TOKEN])) {
7477 on.change = [].concat(on[CHECKBOX_RADIO_TOKEN], on.change || []);
7478 delete on[CHECKBOX_RADIO_TOKEN];
7479 }
7480}
7481
7482let target$1;
7483
7484function createOnceHandler$1 (event, handler, capture) {
7485 const _target = target$1; // save current target element in closure
7486 return function onceHandler () {
7487 const res = handler.apply(null, arguments);
7488 if (res !== null) {
7489 remove$2(event, onceHandler, capture, _target);
7490 }
7491 }
7492}
7493
7494// #9446: Firefox <= 53 (in particular, ESR 52) has incorrect Event.timeStamp
7495// implementation and does not fire microtasks in between event propagation, so
7496// safe to exclude.
7497const useMicrotaskFix = isUsingMicroTask && !(isFF && Number(isFF[1]) <= 53);
7498
7499function add$1 (
7500 name,
7501 handler,
7502 capture,
7503 passive
7504) {
7505 // async edge case #6566: inner click event triggers patch, event handler
7506 // attached to outer element during patch, and triggered again. This
7507 // happens because browsers fire microtask ticks between event propagation.
7508 // the solution is simple: we save the timestamp when a handler is attached,
7509 // and the handler would only fire if the event passed to it was fired
7510 // AFTER it was attached.
7511 if (useMicrotaskFix) {
7512 const attachedTimestamp = currentFlushTimestamp;
7513 const original = handler;
7514 handler = original._wrapper = function (e) {
7515 if (
7516 // no bubbling, should always fire.
7517 // this is just a safety net in case event.timeStamp is unreliable in
7518 // certain weird environments...
7519 e.target === e.currentTarget ||
7520 // event is fired after handler attachment
7521 e.timeStamp >= attachedTimestamp ||
7522 // #9462 bail for iOS 9 bug: event.timeStamp is 0 after history.pushState
7523 e.timeStamp === 0 ||
7524 // #9448 bail if event is fired in another document in a multi-page
7525 // electron/nw.js app, since event.timeStamp will be using a different
7526 // starting reference
7527 e.target.ownerDocument !== document
7528 ) {
7529 return original.apply(this, arguments)
7530 }
7531 };
7532 }
7533 target$1.addEventListener(
7534 name,
7535 handler,
7536 supportsPassive
7537 ? { capture, passive }
7538 : capture
7539 );
7540}
7541
7542function remove$2 (
7543 name,
7544 handler,
7545 capture,
7546 _target
7547) {
7548 (_target || target$1).removeEventListener(
7549 name,
7550 handler._wrapper || handler,
7551 capture
7552 );
7553}
7554
7555function updateDOMListeners (oldVnode, vnode) {
7556 if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {
7557 return
7558 }
7559 const on = vnode.data.on || {};
7560 const oldOn = oldVnode.data.on || {};
7561 target$1 = vnode.elm;
7562 normalizeEvents(on);
7563 updateListeners(on, oldOn, add$1, remove$2, createOnceHandler$1, vnode.context);
7564 target$1 = undefined;
7565}
7566
7567var events = {
7568 create: updateDOMListeners,
7569 update: updateDOMListeners
7570};
7571
7572/* */
7573
7574let svgContainer;
7575
7576function updateDOMProps (oldVnode, vnode) {
7577 if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) {
7578 return
7579 }
7580 let key, cur;
7581 const elm = vnode.elm;
7582 const oldProps = oldVnode.data.domProps || {};
7583 let props = vnode.data.domProps || {};
7584 // clone observed objects, as the user probably wants to mutate it
7585 if (isDef(props.__ob__)) {
7586 props = vnode.data.domProps = extend({}, props);
7587 }
7588
7589 for (key in oldProps) {
7590 if (isUndef(props[key])) {
7591 elm[key] = '';
7592 }
7593 }
7594 for (key in props) {
7595 cur = props[key];
7596 // ignore children if the node has textContent or innerHTML,
7597 // as these will throw away existing DOM nodes and cause removal errors
7598 // on subsequent patches (#3360)
7599 if (key === 'textContent' || key === 'innerHTML') {
7600 if (vnode.children) vnode.children.length = 0;
7601 if (cur === oldProps[key]) continue
7602 // #6601 work around Chrome version <= 55 bug where single textNode
7603 // replaced by innerHTML/textContent retains its parentNode property
7604 if (elm.childNodes.length === 1) {
7605 elm.removeChild(elm.childNodes[0]);
7606 }
7607 }
7608
7609 if (key === 'value' && elm.tagName !== 'PROGRESS') {
7610 // store value as _value as well since
7611 // non-string values will be stringified
7612 elm._value = cur;
7613 // avoid resetting cursor position when value is the same
7614 const strCur = isUndef(cur) ? '' : String(cur);
7615 if (shouldUpdateValue(elm, strCur)) {
7616 elm.value = strCur;
7617 }
7618 } else if (key === 'innerHTML' && isSVG(elm.tagName) && isUndef(elm.innerHTML)) {
7619 // IE doesn't support innerHTML for SVG elements
7620 svgContainer = svgContainer || document.createElement('div');
7621 svgContainer.innerHTML = `<svg>${cur}</svg>`;
7622 const svg = svgContainer.firstChild;
7623 while (elm.firstChild) {
7624 elm.removeChild(elm.firstChild);
7625 }
7626 while (svg.firstChild) {
7627 elm.appendChild(svg.firstChild);
7628 }
7629 } else if (
7630 // skip the update if old and new VDOM state is the same.
7631 // `value` is handled separately because the DOM value may be temporarily
7632 // out of sync with VDOM state due to focus, composition and modifiers.
7633 // This #4521 by skipping the unnecesarry `checked` update.
7634 cur !== oldProps[key]
7635 ) {
7636 // some property updates can throw
7637 // e.g. `value` on <progress> w/ non-finite value
7638 try {
7639 elm[key] = cur;
7640 } catch (e) {}
7641 }
7642 }
7643}
7644
7645// check platforms/web/util/attrs.js acceptValue
7646
7647
7648function shouldUpdateValue (elm, checkVal) {
7649 return (!elm.composing && (
7650 elm.tagName === 'OPTION' ||
7651 isNotInFocusAndDirty(elm, checkVal) ||
7652 isDirtyWithModifiers(elm, checkVal)
7653 ))
7654}
7655
7656function isNotInFocusAndDirty (elm, checkVal) {
7657 // return true when textbox (.number and .trim) loses focus and its value is
7658 // not equal to the updated value
7659 let notInFocus = true;
7660 // #6157
7661 // work around IE bug when accessing document.activeElement in an iframe
7662 try { notInFocus = document.activeElement !== elm; } catch (e) {}
7663 return notInFocus && elm.value !== checkVal
7664}
7665
7666function isDirtyWithModifiers (elm, newVal) {
7667 const value = elm.value;
7668 const modifiers = elm._vModifiers; // injected by v-model runtime
7669 if (isDef(modifiers)) {
7670 if (modifiers.number) {
7671 return toNumber(value) !== toNumber(newVal)
7672 }
7673 if (modifiers.trim) {
7674 return value.trim() !== newVal.trim()
7675 }
7676 }
7677 return value !== newVal
7678}
7679
7680var domProps = {
7681 create: updateDOMProps,
7682 update: updateDOMProps
7683};
7684
7685/* */
7686
7687const parseStyleText = cached(function (cssText) {
7688 const res = {};
7689 const listDelimiter = /;(?![^(]*\))/g;
7690 const propertyDelimiter = /:(.+)/;
7691 cssText.split(listDelimiter).forEach(function (item) {
7692 if (item) {
7693 const tmp = item.split(propertyDelimiter);
7694 tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim());
7695 }
7696 });
7697 return res
7698});
7699
7700// merge static and dynamic style data on the same vnode
7701function normalizeStyleData (data) {
7702 const style = normalizeStyleBinding(data.style);
7703 // static style is pre-processed into an object during compilation
7704 // and is always a fresh object, so it's safe to merge into it
7705 return data.staticStyle
7706 ? extend(data.staticStyle, style)
7707 : style
7708}
7709
7710// normalize possible array / string values into Object
7711function normalizeStyleBinding (bindingStyle) {
7712 if (Array.isArray(bindingStyle)) {
7713 return toObject(bindingStyle)
7714 }
7715 if (typeof bindingStyle === 'string') {
7716 return parseStyleText(bindingStyle)
7717 }
7718 return bindingStyle
7719}
7720
7721/**
7722 * parent component style should be after child's
7723 * so that parent component's style could override it
7724 */
7725function getStyle (vnode, checkChild) {
7726 const res = {};
7727 let styleData;
7728
7729 if (checkChild) {
7730 let childNode = vnode;
7731 while (childNode.componentInstance) {
7732 childNode = childNode.componentInstance._vnode;
7733 if (
7734 childNode && childNode.data &&
7735 (styleData = normalizeStyleData(childNode.data))
7736 ) {
7737 extend(res, styleData);
7738 }
7739 }
7740 }
7741
7742 if ((styleData = normalizeStyleData(vnode.data))) {
7743 extend(res, styleData);
7744 }
7745
7746 let parentNode = vnode;
7747 while ((parentNode = parentNode.parent)) {
7748 if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {
7749 extend(res, styleData);
7750 }
7751 }
7752 return res
7753}
7754
7755/* */
7756
7757const cssVarRE = /^--/;
7758const importantRE = /\s*!important$/;
7759const setProp = (el, name, val) => {
7760 /* istanbul ignore if */
7761 if (cssVarRE.test(name)) {
7762 el.style.setProperty(name, val);
7763 } else if (importantRE.test(val)) {
7764 el.style.setProperty(hyphenate(name), val.replace(importantRE, ''), 'important');
7765 } else {
7766 const normalizedName = normalize(name);
7767 if (Array.isArray(val)) {
7768 // Support values array created by autoprefixer, e.g.
7769 // {display: ["-webkit-box", "-ms-flexbox", "flex"]}
7770 // Set them one by one, and the browser will only set those it can recognize
7771 for (let i = 0, len = val.length; i < len; i++) {
7772 el.style[normalizedName] = val[i];
7773 }
7774 } else {
7775 el.style[normalizedName] = val;
7776 }
7777 }
7778};
7779
7780const vendorNames = ['Webkit', 'Moz', 'ms'];
7781
7782let emptyStyle;
7783const normalize = cached(function (prop) {
7784 emptyStyle = emptyStyle || document.createElement('div').style;
7785 prop = camelize(prop);
7786 if (prop !== 'filter' && (prop in emptyStyle)) {
7787 return prop
7788 }
7789 const capName = prop.charAt(0).toUpperCase() + prop.slice(1);
7790 for (let i = 0; i < vendorNames.length; i++) {
7791 const name = vendorNames[i] + capName;
7792 if (name in emptyStyle) {
7793 return name
7794 }
7795 }
7796});
7797
7798function updateStyle (oldVnode, vnode) {
7799 const data = vnode.data;
7800 const oldData = oldVnode.data;
7801
7802 if (isUndef(data.staticStyle) && isUndef(data.style) &&
7803 isUndef(oldData.staticStyle) && isUndef(oldData.style)
7804 ) {
7805 return
7806 }
7807
7808 let cur, name;
7809 const el = vnode.elm;
7810 const oldStaticStyle = oldData.staticStyle;
7811 const oldStyleBinding = oldData.normalizedStyle || oldData.style || {};
7812
7813 // if static style exists, stylebinding already merged into it when doing normalizeStyleData
7814 const oldStyle = oldStaticStyle || oldStyleBinding;
7815
7816 const style = normalizeStyleBinding(vnode.data.style) || {};
7817
7818 // store normalized style under a different key for next diff
7819 // make sure to clone it if it's reactive, since the user likely wants
7820 // to mutate it.
7821 vnode.data.normalizedStyle = isDef(style.__ob__)
7822 ? extend({}, style)
7823 : style;
7824
7825 const newStyle = getStyle(vnode, true);
7826
7827 for (name in oldStyle) {
7828 if (isUndef(newStyle[name])) {
7829 setProp(el, name, '');
7830 }
7831 }
7832 for (name in newStyle) {
7833 cur = newStyle[name];
7834 if (cur !== oldStyle[name]) {
7835 // ie9 setting to null has no effect, must use empty string
7836 setProp(el, name, cur == null ? '' : cur);
7837 }
7838 }
7839}
7840
7841var style = {
7842 create: updateStyle,
7843 update: updateStyle
7844};
7845
7846/* */
7847
7848const whitespaceRE = /\s+/;
7849
7850/**
7851 * Add class with compatibility for SVG since classList is not supported on
7852 * SVG elements in IE
7853 */
7854function addClass (el, cls) {
7855 /* istanbul ignore if */
7856 if (!cls || !(cls = cls.trim())) {
7857 return
7858 }
7859
7860 /* istanbul ignore else */
7861 if (el.classList) {
7862 if (cls.indexOf(' ') > -1) {
7863 cls.split(whitespaceRE).forEach(c => el.classList.add(c));
7864 } else {
7865 el.classList.add(cls);
7866 }
7867 } else {
7868 const cur = ` ${el.getAttribute('class') || ''} `;
7869 if (cur.indexOf(' ' + cls + ' ') < 0) {
7870 el.setAttribute('class', (cur + cls).trim());
7871 }
7872 }
7873}
7874
7875/**
7876 * Remove class with compatibility for SVG since classList is not supported on
7877 * SVG elements in IE
7878 */
7879function removeClass (el, cls) {
7880 /* istanbul ignore if */
7881 if (!cls || !(cls = cls.trim())) {
7882 return
7883 }
7884
7885 /* istanbul ignore else */
7886 if (el.classList) {
7887 if (cls.indexOf(' ') > -1) {
7888 cls.split(whitespaceRE).forEach(c => el.classList.remove(c));
7889 } else {
7890 el.classList.remove(cls);
7891 }
7892 if (!el.classList.length) {
7893 el.removeAttribute('class');
7894 }
7895 } else {
7896 let cur = ` ${el.getAttribute('class') || ''} `;
7897 const tar = ' ' + cls + ' ';
7898 while (cur.indexOf(tar) >= 0) {
7899 cur = cur.replace(tar, ' ');
7900 }
7901 cur = cur.trim();
7902 if (cur) {
7903 el.setAttribute('class', cur);
7904 } else {
7905 el.removeAttribute('class');
7906 }
7907 }
7908}
7909
7910/* */
7911
7912function resolveTransition (def$$1) {
7913 if (!def$$1) {
7914 return
7915 }
7916 /* istanbul ignore else */
7917 if (typeof def$$1 === 'object') {
7918 const res = {};
7919 if (def$$1.css !== false) {
7920 extend(res, autoCssTransition(def$$1.name || 'v'));
7921 }
7922 extend(res, def$$1);
7923 return res
7924 } else if (typeof def$$1 === 'string') {
7925 return autoCssTransition(def$$1)
7926 }
7927}
7928
7929const autoCssTransition = cached(name => {
7930 return {
7931 enterClass: `${name}-enter`,
7932 enterToClass: `${name}-enter-to`,
7933 enterActiveClass: `${name}-enter-active`,
7934 leaveClass: `${name}-leave`,
7935 leaveToClass: `${name}-leave-to`,
7936 leaveActiveClass: `${name}-leave-active`
7937 }
7938});
7939
7940const hasTransition = inBrowser && !isIE9;
7941const TRANSITION = 'transition';
7942const ANIMATION = 'animation';
7943
7944// Transition property/event sniffing
7945let transitionProp = 'transition';
7946let transitionEndEvent = 'transitionend';
7947let animationProp = 'animation';
7948let animationEndEvent = 'animationend';
7949if (hasTransition) {
7950 /* istanbul ignore if */
7951 if (window.ontransitionend === undefined &&
7952 window.onwebkittransitionend !== undefined
7953 ) {
7954 transitionProp = 'WebkitTransition';
7955 transitionEndEvent = 'webkitTransitionEnd';
7956 }
7957 if (window.onanimationend === undefined &&
7958 window.onwebkitanimationend !== undefined
7959 ) {
7960 animationProp = 'WebkitAnimation';
7961 animationEndEvent = 'webkitAnimationEnd';
7962 }
7963}
7964
7965// binding to window is necessary to make hot reload work in IE in strict mode
7966const raf = inBrowser
7967 ? window.requestAnimationFrame
7968 ? window.requestAnimationFrame.bind(window)
7969 : setTimeout
7970 : /* istanbul ignore next */ fn => fn();
7971
7972function nextFrame (fn) {
7973 raf(() => {
7974 raf(fn);
7975 });
7976}
7977
7978function addTransitionClass (el, cls) {
7979 const transitionClasses = el._transitionClasses || (el._transitionClasses = []);
7980 if (transitionClasses.indexOf(cls) < 0) {
7981 transitionClasses.push(cls);
7982 addClass(el, cls);
7983 }
7984}
7985
7986function removeTransitionClass (el, cls) {
7987 if (el._transitionClasses) {
7988 remove(el._transitionClasses, cls);
7989 }
7990 removeClass(el, cls);
7991}
7992
7993function whenTransitionEnds (
7994 el,
7995 expectedType,
7996 cb
7997) {
7998 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
7999 if (!type) return cb()
8000 const event = type === TRANSITION ? transitionEndEvent : animationEndEvent;
8001 let ended = 0;
8002 const end = () => {
8003 el.removeEventListener(event, onEnd);
8004 cb();
8005 };
8006 const onEnd = e => {
8007 if (e.target === el) {
8008 if (++ended >= propCount) {
8009 end();
8010 }
8011 }
8012 };
8013 setTimeout(() => {
8014 if (ended < propCount) {
8015 end();
8016 }
8017 }, timeout + 1);
8018 el.addEventListener(event, onEnd);
8019}
8020
8021const transformRE = /\b(transform|all)(,|$)/;
8022
8023function getTransitionInfo (el, expectedType) {
8024 const styles = window.getComputedStyle(el);
8025 // JSDOM may return undefined for transition properties
8026 const transitionDelays = (styles[transitionProp + 'Delay'] || '').split(', ');
8027 const transitionDurations = (styles[transitionProp + 'Duration'] || '').split(', ');
8028 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
8029 const animationDelays = (styles[animationProp + 'Delay'] || '').split(', ');
8030 const animationDurations = (styles[animationProp + 'Duration'] || '').split(', ');
8031 const animationTimeout = getTimeout(animationDelays, animationDurations);
8032
8033 let type;
8034 let timeout = 0;
8035 let propCount = 0;
8036 /* istanbul ignore if */
8037 if (expectedType === TRANSITION) {
8038 if (transitionTimeout > 0) {
8039 type = TRANSITION;
8040 timeout = transitionTimeout;
8041 propCount = transitionDurations.length;
8042 }
8043 } else if (expectedType === ANIMATION) {
8044 if (animationTimeout > 0) {
8045 type = ANIMATION;
8046 timeout = animationTimeout;
8047 propCount = animationDurations.length;
8048 }
8049 } else {
8050 timeout = Math.max(transitionTimeout, animationTimeout);
8051 type = timeout > 0
8052 ? transitionTimeout > animationTimeout
8053 ? TRANSITION
8054 : ANIMATION
8055 : null;
8056 propCount = type
8057 ? type === TRANSITION
8058 ? transitionDurations.length
8059 : animationDurations.length
8060 : 0;
8061 }
8062 const hasTransform =
8063 type === TRANSITION &&
8064 transformRE.test(styles[transitionProp + 'Property']);
8065 return {
8066 type,
8067 timeout,
8068 propCount,
8069 hasTransform
8070 }
8071}
8072
8073function getTimeout (delays, durations) {
8074 /* istanbul ignore next */
8075 while (delays.length < durations.length) {
8076 delays = delays.concat(delays);
8077 }
8078
8079 return Math.max.apply(null, durations.map((d, i) => {
8080 return toMs(d) + toMs(delays[i])
8081 }))
8082}
8083
8084// Old versions of Chromium (below 61.0.3163.100) formats floating pointer numbers
8085// in a locale-dependent way, using a comma instead of a dot.
8086// If comma is not replaced with a dot, the input will be rounded down (i.e. acting
8087// as a floor function) causing unexpected behaviors
8088function toMs (s) {
8089 return Number(s.slice(0, -1).replace(',', '.')) * 1000
8090}
8091
8092/* */
8093
8094function enter (vnode, toggleDisplay) {
8095 const el = vnode.elm;
8096
8097 // call leave callback now
8098 if (isDef(el._leaveCb)) {
8099 el._leaveCb.cancelled = true;
8100 el._leaveCb();
8101 }
8102
8103 const data = resolveTransition(vnode.data.transition);
8104 if (isUndef(data)) {
8105 return
8106 }
8107
8108 /* istanbul ignore if */
8109 if (isDef(el._enterCb) || el.nodeType !== 1) {
8110 return
8111 }
8112
8113 const {
8114 css,
8115 type,
8116 enterClass,
8117 enterToClass,
8118 enterActiveClass,
8119 appearClass,
8120 appearToClass,
8121 appearActiveClass,
8122 beforeEnter,
8123 enter,
8124 afterEnter,
8125 enterCancelled,
8126 beforeAppear,
8127 appear,
8128 afterAppear,
8129 appearCancelled,
8130 duration
8131 } = data;
8132
8133 // activeInstance will always be the <transition> component managing this
8134 // transition. One edge case to check is when the <transition> is placed
8135 // as the root node of a child component. In that case we need to check
8136 // <transition>'s parent for appear check.
8137 let context = activeInstance;
8138 let transitionNode = activeInstance.$vnode;
8139 while (transitionNode && transitionNode.parent) {
8140 transitionNode = transitionNode.parent;
8141 context = transitionNode.context;
8142 }
8143
8144 const isAppear = !context._isMounted || !vnode.isRootInsert;
8145
8146 if (isAppear && !appear && appear !== '') {
8147 return
8148 }
8149
8150 const startClass = isAppear && appearClass
8151 ? appearClass
8152 : enterClass;
8153 const activeClass = isAppear && appearActiveClass
8154 ? appearActiveClass
8155 : enterActiveClass;
8156 const toClass = isAppear && appearToClass
8157 ? appearToClass
8158 : enterToClass;
8159
8160 const beforeEnterHook = isAppear
8161 ? (beforeAppear || beforeEnter)
8162 : beforeEnter;
8163 const enterHook = isAppear
8164 ? (typeof appear === 'function' ? appear : enter)
8165 : enter;
8166 const afterEnterHook = isAppear
8167 ? (afterAppear || afterEnter)
8168 : afterEnter;
8169 const enterCancelledHook = isAppear
8170 ? (appearCancelled || enterCancelled)
8171 : enterCancelled;
8172
8173 const explicitEnterDuration = toNumber(
8174 isObject(duration)
8175 ? duration.enter
8176 : duration
8177 );
8178
8179 if (explicitEnterDuration != null) {
8180 checkDuration(explicitEnterDuration, 'enter', vnode);
8181 }
8182
8183 const expectsCSS = css !== false && !isIE9;
8184 const userWantsControl = getHookArgumentsLength(enterHook);
8185
8186 const cb = el._enterCb = once(() => {
8187 if (expectsCSS) {
8188 removeTransitionClass(el, toClass);
8189 removeTransitionClass(el, activeClass);
8190 }
8191 if (cb.cancelled) {
8192 if (expectsCSS) {
8193 removeTransitionClass(el, startClass);
8194 }
8195 enterCancelledHook && enterCancelledHook(el);
8196 } else {
8197 afterEnterHook && afterEnterHook(el);
8198 }
8199 el._enterCb = null;
8200 });
8201
8202 if (!vnode.data.show) {
8203 // remove pending leave element on enter by injecting an insert hook
8204 mergeVNodeHook(vnode, 'insert', () => {
8205 const parent = el.parentNode;
8206 const pendingNode = parent && parent._pending && parent._pending[vnode.key];
8207 if (pendingNode &&
8208 pendingNode.tag === vnode.tag &&
8209 pendingNode.elm._leaveCb
8210 ) {
8211 pendingNode.elm._leaveCb();
8212 }
8213 enterHook && enterHook(el, cb);
8214 });
8215 }
8216
8217 // start enter transition
8218 beforeEnterHook && beforeEnterHook(el);
8219 if (expectsCSS) {
8220 addTransitionClass(el, startClass);
8221 addTransitionClass(el, activeClass);
8222 nextFrame(() => {
8223 removeTransitionClass(el, startClass);
8224 if (!cb.cancelled) {
8225 addTransitionClass(el, toClass);
8226 if (!userWantsControl) {
8227 if (isValidDuration(explicitEnterDuration)) {
8228 setTimeout(cb, explicitEnterDuration);
8229 } else {
8230 whenTransitionEnds(el, type, cb);
8231 }
8232 }
8233 }
8234 });
8235 }
8236
8237 if (vnode.data.show) {
8238 toggleDisplay && toggleDisplay();
8239 enterHook && enterHook(el, cb);
8240 }
8241
8242 if (!expectsCSS && !userWantsControl) {
8243 cb();
8244 }
8245}
8246
8247function leave (vnode, rm) {
8248 const el = vnode.elm;
8249
8250 // call enter callback now
8251 if (isDef(el._enterCb)) {
8252 el._enterCb.cancelled = true;
8253 el._enterCb();
8254 }
8255
8256 const data = resolveTransition(vnode.data.transition);
8257 if (isUndef(data) || el.nodeType !== 1) {
8258 return rm()
8259 }
8260
8261 /* istanbul ignore if */
8262 if (isDef(el._leaveCb)) {
8263 return
8264 }
8265
8266 const {
8267 css,
8268 type,
8269 leaveClass,
8270 leaveToClass,
8271 leaveActiveClass,
8272 beforeLeave,
8273 leave,
8274 afterLeave,
8275 leaveCancelled,
8276 delayLeave,
8277 duration
8278 } = data;
8279
8280 const expectsCSS = css !== false && !isIE9;
8281 const userWantsControl = getHookArgumentsLength(leave);
8282
8283 const explicitLeaveDuration = toNumber(
8284 isObject(duration)
8285 ? duration.leave
8286 : duration
8287 );
8288
8289 if (isDef(explicitLeaveDuration)) {
8290 checkDuration(explicitLeaveDuration, 'leave', vnode);
8291 }
8292
8293 const cb = el._leaveCb = once(() => {
8294 if (el.parentNode && el.parentNode._pending) {
8295 el.parentNode._pending[vnode.key] = null;
8296 }
8297 if (expectsCSS) {
8298 removeTransitionClass(el, leaveToClass);
8299 removeTransitionClass(el, leaveActiveClass);
8300 }
8301 if (cb.cancelled) {
8302 if (expectsCSS) {
8303 removeTransitionClass(el, leaveClass);
8304 }
8305 leaveCancelled && leaveCancelled(el);
8306 } else {
8307 rm();
8308 afterLeave && afterLeave(el);
8309 }
8310 el._leaveCb = null;
8311 });
8312
8313 if (delayLeave) {
8314 delayLeave(performLeave);
8315 } else {
8316 performLeave();
8317 }
8318
8319 function performLeave () {
8320 // the delayed leave may have already been cancelled
8321 if (cb.cancelled) {
8322 return
8323 }
8324 // record leaving element
8325 if (!vnode.data.show && el.parentNode) {
8326 (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode;
8327 }
8328 beforeLeave && beforeLeave(el);
8329 if (expectsCSS) {
8330 addTransitionClass(el, leaveClass);
8331 addTransitionClass(el, leaveActiveClass);
8332 nextFrame(() => {
8333 removeTransitionClass(el, leaveClass);
8334 if (!cb.cancelled) {
8335 addTransitionClass(el, leaveToClass);
8336 if (!userWantsControl) {
8337 if (isValidDuration(explicitLeaveDuration)) {
8338 setTimeout(cb, explicitLeaveDuration);
8339 } else {
8340 whenTransitionEnds(el, type, cb);
8341 }
8342 }
8343 }
8344 });
8345 }
8346 leave && leave(el, cb);
8347 if (!expectsCSS && !userWantsControl) {
8348 cb();
8349 }
8350 }
8351}
8352
8353// only used in dev mode
8354function checkDuration (val, name, vnode) {
8355 if (typeof val !== 'number') {
8356 warn(
8357 `<transition> explicit ${name} duration is not a valid number - ` +
8358 `got ${JSON.stringify(val)}.`,
8359 vnode.context
8360 );
8361 } else if (isNaN(val)) {
8362 warn(
8363 `<transition> explicit ${name} duration is NaN - ` +
8364 'the duration expression might be incorrect.',
8365 vnode.context
8366 );
8367 }
8368}
8369
8370function isValidDuration (val) {
8371 return typeof val === 'number' && !isNaN(val)
8372}
8373
8374/**
8375 * Normalize a transition hook's argument length. The hook may be:
8376 * - a merged hook (invoker) with the original in .fns
8377 * - a wrapped component method (check ._length)
8378 * - a plain function (.length)
8379 */
8380function getHookArgumentsLength (fn) {
8381 if (isUndef(fn)) {
8382 return false
8383 }
8384 const invokerFns = fn.fns;
8385 if (isDef(invokerFns)) {
8386 // invoker
8387 return getHookArgumentsLength(
8388 Array.isArray(invokerFns)
8389 ? invokerFns[0]
8390 : invokerFns
8391 )
8392 } else {
8393 return (fn._length || fn.length) > 1
8394 }
8395}
8396
8397function _enter (_, vnode) {
8398 if (vnode.data.show !== true) {
8399 enter(vnode);
8400 }
8401}
8402
8403var transition = inBrowser ? {
8404 create: _enter,
8405 activate: _enter,
8406 remove (vnode, rm) {
8407 /* istanbul ignore else */
8408 if (vnode.data.show !== true) {
8409 leave(vnode, rm);
8410 } else {
8411 rm();
8412 }
8413 }
8414} : {};
8415
8416var platformModules = [
8417 attrs,
8418 klass,
8419 events,
8420 domProps,
8421 style,
8422 transition
8423];
8424
8425/* */
8426
8427// the directive module should be applied last, after all
8428// built-in modules have been applied.
8429const modules = platformModules.concat(baseModules);
8430
8431const patch = createPatchFunction({ nodeOps, modules });
8432
8433/**
8434 * Not type checking this file because flow doesn't like attaching
8435 * properties to Elements.
8436 */
8437
8438/* istanbul ignore if */
8439if (isIE9) {
8440 // http://www.matts411.com/post/internet-explorer-9-oninput/
8441 document.addEventListener('selectionchange', () => {
8442 const el = document.activeElement;
8443 if (el && el.vmodel) {
8444 trigger(el, 'input');
8445 }
8446 });
8447}
8448
8449const directive = {
8450 inserted (el, binding, vnode, oldVnode) {
8451 if (vnode.tag === 'select') {
8452 // #6903
8453 if (oldVnode.elm && !oldVnode.elm._vOptions) {
8454 mergeVNodeHook(vnode, 'postpatch', () => {
8455 directive.componentUpdated(el, binding, vnode);
8456 });
8457 } else {
8458 setSelected(el, binding, vnode.context);
8459 }
8460 el._vOptions = [].map.call(el.options, getValue);
8461 } else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
8462 el._vModifiers = binding.modifiers;
8463 if (!binding.modifiers.lazy) {
8464 el.addEventListener('compositionstart', onCompositionStart);
8465 el.addEventListener('compositionend', onCompositionEnd);
8466 // Safari < 10.2 & UIWebView doesn't fire compositionend when
8467 // switching focus before confirming composition choice
8468 // this also fixes the issue where some browsers e.g. iOS Chrome
8469 // fires "change" instead of "input" on autocomplete.
8470 el.addEventListener('change', onCompositionEnd);
8471 /* istanbul ignore if */
8472 if (isIE9) {
8473 el.vmodel = true;
8474 }
8475 }
8476 }
8477 },
8478
8479 componentUpdated (el, binding, vnode) {
8480 if (vnode.tag === 'select') {
8481 setSelected(el, binding, vnode.context);
8482 // in case the options rendered by v-for have changed,
8483 // it's possible that the value is out-of-sync with the rendered options.
8484 // detect such cases and filter out values that no longer has a matching
8485 // option in the DOM.
8486 const prevOptions = el._vOptions;
8487 const curOptions = el._vOptions = [].map.call(el.options, getValue);
8488 if (curOptions.some((o, i) => !looseEqual(o, prevOptions[i]))) {
8489 // trigger change event if
8490 // no matching option found for at least one value
8491 const needReset = el.multiple
8492 ? binding.value.some(v => hasNoMatchingOption(v, curOptions))
8493 : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions);
8494 if (needReset) {
8495 trigger(el, 'change');
8496 }
8497 }
8498 }
8499 }
8500};
8501
8502function setSelected (el, binding, vm) {
8503 actuallySetSelected(el, binding, vm);
8504 /* istanbul ignore if */
8505 if (isIE || isEdge) {
8506 setTimeout(() => {
8507 actuallySetSelected(el, binding, vm);
8508 }, 0);
8509 }
8510}
8511
8512function actuallySetSelected (el, binding, vm) {
8513 const value = binding.value;
8514 const isMultiple = el.multiple;
8515 if (isMultiple && !Array.isArray(value)) {
8516 warn(
8517 `<select multiple v-model="${binding.expression}"> ` +
8518 `expects an Array value for its binding, but got ${
8519 Object.prototype.toString.call(value).slice(8, -1)
8520 }`,
8521 vm
8522 );
8523 return
8524 }
8525 let selected, option;
8526 for (let i = 0, l = el.options.length; i < l; i++) {
8527 option = el.options[i];
8528 if (isMultiple) {
8529 selected = looseIndexOf(value, getValue(option)) > -1;
8530 if (option.selected !== selected) {
8531 option.selected = selected;
8532 }
8533 } else {
8534 if (looseEqual(getValue(option), value)) {
8535 if (el.selectedIndex !== i) {
8536 el.selectedIndex = i;
8537 }
8538 return
8539 }
8540 }
8541 }
8542 if (!isMultiple) {
8543 el.selectedIndex = -1;
8544 }
8545}
8546
8547function hasNoMatchingOption (value, options) {
8548 return options.every(o => !looseEqual(o, value))
8549}
8550
8551function getValue (option) {
8552 return '_value' in option
8553 ? option._value
8554 : option.value
8555}
8556
8557function onCompositionStart (e) {
8558 e.target.composing = true;
8559}
8560
8561function onCompositionEnd (e) {
8562 // prevent triggering an input event for no reason
8563 if (!e.target.composing) return
8564 e.target.composing = false;
8565 trigger(e.target, 'input');
8566}
8567
8568function trigger (el, type) {
8569 const e = document.createEvent('HTMLEvents');
8570 e.initEvent(type, true, true);
8571 el.dispatchEvent(e);
8572}
8573
8574/* */
8575
8576// recursively search for possible transition defined inside the component root
8577function locateNode (vnode) {
8578 return vnode.componentInstance && (!vnode.data || !vnode.data.transition)
8579 ? locateNode(vnode.componentInstance._vnode)
8580 : vnode
8581}
8582
8583var show = {
8584 bind (el, { value }, vnode) {
8585 vnode = locateNode(vnode);
8586 const transition$$1 = vnode.data && vnode.data.transition;
8587 const originalDisplay = el.__vOriginalDisplay =
8588 el.style.display === 'none' ? '' : el.style.display;
8589 if (value && transition$$1) {
8590 vnode.data.show = true;
8591 enter(vnode, () => {
8592 el.style.display = originalDisplay;
8593 });
8594 } else {
8595 el.style.display = value ? originalDisplay : 'none';
8596 }
8597 },
8598
8599 update (el, { value, oldValue }, vnode) {
8600 /* istanbul ignore if */
8601 if (!value === !oldValue) return
8602 vnode = locateNode(vnode);
8603 const transition$$1 = vnode.data && vnode.data.transition;
8604 if (transition$$1) {
8605 vnode.data.show = true;
8606 if (value) {
8607 enter(vnode, () => {
8608 el.style.display = el.__vOriginalDisplay;
8609 });
8610 } else {
8611 leave(vnode, () => {
8612 el.style.display = 'none';
8613 });
8614 }
8615 } else {
8616 el.style.display = value ? el.__vOriginalDisplay : 'none';
8617 }
8618 },
8619
8620 unbind (
8621 el,
8622 binding,
8623 vnode,
8624 oldVnode,
8625 isDestroy
8626 ) {
8627 if (!isDestroy) {
8628 el.style.display = el.__vOriginalDisplay;
8629 }
8630 }
8631};
8632
8633var platformDirectives = {
8634 model: directive,
8635 show
8636};
8637
8638/* */
8639
8640const transitionProps = {
8641 name: String,
8642 appear: Boolean,
8643 css: Boolean,
8644 mode: String,
8645 type: String,
8646 enterClass: String,
8647 leaveClass: String,
8648 enterToClass: String,
8649 leaveToClass: String,
8650 enterActiveClass: String,
8651 leaveActiveClass: String,
8652 appearClass: String,
8653 appearActiveClass: String,
8654 appearToClass: String,
8655 duration: [Number, String, Object]
8656};
8657
8658// in case the child is also an abstract component, e.g. <keep-alive>
8659// we want to recursively retrieve the real component to be rendered
8660function getRealChild (vnode) {
8661 const compOptions = vnode && vnode.componentOptions;
8662 if (compOptions && compOptions.Ctor.options.abstract) {
8663 return getRealChild(getFirstComponentChild(compOptions.children))
8664 } else {
8665 return vnode
8666 }
8667}
8668
8669function extractTransitionData (comp) {
8670 const data = {};
8671 const options = comp.$options;
8672 // props
8673 for (const key in options.propsData) {
8674 data[key] = comp[key];
8675 }
8676 // events.
8677 // extract listeners and pass them directly to the transition methods
8678 const listeners = options._parentListeners;
8679 for (const key in listeners) {
8680 data[camelize(key)] = listeners[key];
8681 }
8682 return data
8683}
8684
8685function placeholder (h, rawChild) {
8686 if (/\d-keep-alive$/.test(rawChild.tag)) {
8687 return h('keep-alive', {
8688 props: rawChild.componentOptions.propsData
8689 })
8690 }
8691}
8692
8693function hasParentTransition (vnode) {
8694 while ((vnode = vnode.parent)) {
8695 if (vnode.data.transition) {
8696 return true
8697 }
8698 }
8699}
8700
8701function isSameChild (child, oldChild) {
8702 return oldChild.key === child.key && oldChild.tag === child.tag
8703}
8704
8705const isNotTextNode = (c) => c.tag || isAsyncPlaceholder(c);
8706
8707const isVShowDirective = d => d.name === 'show';
8708
8709var Transition = {
8710 name: 'transition',
8711 props: transitionProps,
8712 abstract: true,
8713
8714 render (h) {
8715 let children = this.$slots.default;
8716 if (!children) {
8717 return
8718 }
8719
8720 // filter out text nodes (possible whitespaces)
8721 children = children.filter(isNotTextNode);
8722 /* istanbul ignore if */
8723 if (!children.length) {
8724 return
8725 }
8726
8727 // warn multiple elements
8728 if (children.length > 1) {
8729 warn(
8730 '<transition> can only be used on a single element. Use ' +
8731 '<transition-group> for lists.',
8732 this.$parent
8733 );
8734 }
8735
8736 const mode = this.mode;
8737
8738 // warn invalid mode
8739 if (mode && mode !== 'in-out' && mode !== 'out-in'
8740 ) {
8741 warn(
8742 'invalid <transition> mode: ' + mode,
8743 this.$parent
8744 );
8745 }
8746
8747 const rawChild = children[0];
8748
8749 // if this is a component root node and the component's
8750 // parent container node also has transition, skip.
8751 if (hasParentTransition(this.$vnode)) {
8752 return rawChild
8753 }
8754
8755 // apply transition data to child
8756 // use getRealChild() to ignore abstract components e.g. keep-alive
8757 const child = getRealChild(rawChild);
8758 /* istanbul ignore if */
8759 if (!child) {
8760 return rawChild
8761 }
8762
8763 if (this._leaving) {
8764 return placeholder(h, rawChild)
8765 }
8766
8767 // ensure a key that is unique to the vnode type and to this transition
8768 // component instance. This key will be used to remove pending leaving nodes
8769 // during entering.
8770 const id = `__transition-${this._uid}-`;
8771 child.key = child.key == null
8772 ? child.isComment
8773 ? id + 'comment'
8774 : id + child.tag
8775 : isPrimitive(child.key)
8776 ? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
8777 : child.key;
8778
8779 const data = (child.data || (child.data = {})).transition = extractTransitionData(this);
8780 const oldRawChild = this._vnode;
8781 const oldChild = getRealChild(oldRawChild);
8782
8783 // mark v-show
8784 // so that the transition module can hand over the control to the directive
8785 if (child.data.directives && child.data.directives.some(isVShowDirective)) {
8786 child.data.show = true;
8787 }
8788
8789 if (
8790 oldChild &&
8791 oldChild.data &&
8792 !isSameChild(child, oldChild) &&
8793 !isAsyncPlaceholder(oldChild) &&
8794 // #6687 component root is a comment node
8795 !(oldChild.componentInstance && oldChild.componentInstance._vnode.isComment)
8796 ) {
8797 // replace old child transition data with fresh one
8798 // important for dynamic transitions!
8799 const oldData = oldChild.data.transition = extend({}, data);
8800 // handle transition mode
8801 if (mode === 'out-in') {
8802 // return placeholder node and queue update when leave finishes
8803 this._leaving = true;
8804 mergeVNodeHook(oldData, 'afterLeave', () => {
8805 this._leaving = false;
8806 this.$forceUpdate();
8807 });
8808 return placeholder(h, rawChild)
8809 } else if (mode === 'in-out') {
8810 if (isAsyncPlaceholder(child)) {
8811 return oldRawChild
8812 }
8813 let delayedLeave;
8814 const performLeave = () => { delayedLeave(); };
8815 mergeVNodeHook(data, 'afterEnter', performLeave);
8816 mergeVNodeHook(data, 'enterCancelled', performLeave);
8817 mergeVNodeHook(oldData, 'delayLeave', leave => { delayedLeave = leave; });
8818 }
8819 }
8820
8821 return rawChild
8822 }
8823};
8824
8825/* */
8826
8827const props = extend({
8828 tag: String,
8829 moveClass: String
8830}, transitionProps);
8831
8832delete props.mode;
8833
8834var TransitionGroup = {
8835 props,
8836
8837 beforeMount () {
8838 const update = this._update;
8839 this._update = (vnode, hydrating) => {
8840 const restoreActiveInstance = setActiveInstance(this);
8841 // force removing pass
8842 this.__patch__(
8843 this._vnode,
8844 this.kept,
8845 false, // hydrating
8846 true // removeOnly (!important, avoids unnecessary moves)
8847 );
8848 this._vnode = this.kept;
8849 restoreActiveInstance();
8850 update.call(this, vnode, hydrating);
8851 };
8852 },
8853
8854 render (h) {
8855 const tag = this.tag || this.$vnode.data.tag || 'span';
8856 const map = Object.create(null);
8857 const prevChildren = this.prevChildren = this.children;
8858 const rawChildren = this.$slots.default || [];
8859 const children = this.children = [];
8860 const transitionData = extractTransitionData(this);
8861
8862 for (let i = 0; i < rawChildren.length; i++) {
8863 const c = rawChildren[i];
8864 if (c.tag) {
8865 if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
8866 children.push(c);
8867 map[c.key] = c
8868 ;(c.data || (c.data = {})).transition = transitionData;
8869 } else {
8870 const opts = c.componentOptions;
8871 const name = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag;
8872 warn(`<transition-group> children must be keyed: <${name}>`);
8873 }
8874 }
8875 }
8876
8877 if (prevChildren) {
8878 const kept = [];
8879 const removed = [];
8880 for (let i = 0; i < prevChildren.length; i++) {
8881 const c = prevChildren[i];
8882 c.data.transition = transitionData;
8883 c.data.pos = c.elm.getBoundingClientRect();
8884 if (map[c.key]) {
8885 kept.push(c);
8886 } else {
8887 removed.push(c);
8888 }
8889 }
8890 this.kept = h(tag, null, kept);
8891 this.removed = removed;
8892 }
8893
8894 return h(tag, null, children)
8895 },
8896
8897 updated () {
8898 const children = this.prevChildren;
8899 const moveClass = this.moveClass || ((this.name || 'v') + '-move');
8900 if (!children.length || !this.hasMove(children[0].elm, moveClass)) {
8901 return
8902 }
8903
8904 // we divide the work into three loops to avoid mixing DOM reads and writes
8905 // in each iteration - which helps prevent layout thrashing.
8906 children.forEach(callPendingCbs);
8907 children.forEach(recordPosition);
8908 children.forEach(applyTranslation);
8909
8910 // force reflow to put everything in position
8911 // assign to this to avoid being removed in tree-shaking
8912 // $flow-disable-line
8913 this._reflow = document.body.offsetHeight;
8914
8915 children.forEach((c) => {
8916 if (c.data.moved) {
8917 const el = c.elm;
8918 const s = el.style;
8919 addTransitionClass(el, moveClass);
8920 s.transform = s.WebkitTransform = s.transitionDuration = '';
8921 el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {
8922 if (e && e.target !== el) {
8923 return
8924 }
8925 if (!e || /transform$/.test(e.propertyName)) {
8926 el.removeEventListener(transitionEndEvent, cb);
8927 el._moveCb = null;
8928 removeTransitionClass(el, moveClass);
8929 }
8930 });
8931 }
8932 });
8933 },
8934
8935 methods: {
8936 hasMove (el, moveClass) {
8937 /* istanbul ignore if */
8938 if (!hasTransition) {
8939 return false
8940 }
8941 /* istanbul ignore if */
8942 if (this._hasMove) {
8943 return this._hasMove
8944 }
8945 // Detect whether an element with the move class applied has
8946 // CSS transitions. Since the element may be inside an entering
8947 // transition at this very moment, we make a clone of it and remove
8948 // all other transition classes applied to ensure only the move class
8949 // is applied.
8950 const clone = el.cloneNode();
8951 if (el._transitionClasses) {
8952 el._transitionClasses.forEach((cls) => { removeClass(clone, cls); });
8953 }
8954 addClass(clone, moveClass);
8955 clone.style.display = 'none';
8956 this.$el.appendChild(clone);
8957 const info = getTransitionInfo(clone);
8958 this.$el.removeChild(clone);
8959 return (this._hasMove = info.hasTransform)
8960 }
8961 }
8962};
8963
8964function callPendingCbs (c) {
8965 /* istanbul ignore if */
8966 if (c.elm._moveCb) {
8967 c.elm._moveCb();
8968 }
8969 /* istanbul ignore if */
8970 if (c.elm._enterCb) {
8971 c.elm._enterCb();
8972 }
8973}
8974
8975function recordPosition (c) {
8976 c.data.newPos = c.elm.getBoundingClientRect();
8977}
8978
8979function applyTranslation (c) {
8980 const oldPos = c.data.pos;
8981 const newPos = c.data.newPos;
8982 const dx = oldPos.left - newPos.left;
8983 const dy = oldPos.top - newPos.top;
8984 if (dx || dy) {
8985 c.data.moved = true;
8986 const s = c.elm.style;
8987 s.transform = s.WebkitTransform = `translate(${dx}px,${dy}px)`;
8988 s.transitionDuration = '0s';
8989 }
8990}
8991
8992var platformComponents = {
8993 Transition,
8994 TransitionGroup
8995};
8996
8997/* */
8998
8999// install platform specific utils
9000Vue.config.mustUseProp = mustUseProp;
9001Vue.config.isReservedTag = isReservedTag;
9002Vue.config.isReservedAttr = isReservedAttr;
9003Vue.config.getTagNamespace = getTagNamespace;
9004Vue.config.isUnknownElement = isUnknownElement;
9005
9006// install platform runtime directives & components
9007extend(Vue.options.directives, platformDirectives);
9008extend(Vue.options.components, platformComponents);
9009
9010// install platform patch function
9011Vue.prototype.__patch__ = inBrowser ? patch : noop;
9012
9013// public mount method
9014Vue.prototype.$mount = function (
9015 el,
9016 hydrating
9017) {
9018 el = el && inBrowser ? query(el) : undefined;
9019 return mountComponent(this, el, hydrating)
9020};
9021
9022// devtools global hook
9023/* istanbul ignore next */
9024if (inBrowser) {
9025 setTimeout(() => {
9026 if (config.devtools) {
9027 if (devtools) {
9028 devtools.emit('init', Vue);
9029 } else {
9030 console[console.info ? 'info' : 'log'](
9031 'Download the Vue Devtools extension for a better development experience:\n' +
9032 'https://github.com/vuejs/vue-devtools'
9033 );
9034 }
9035 }
9036 if (config.productionTip !== false &&
9037 typeof console !== 'undefined'
9038 ) {
9039 console[console.info ? 'info' : 'log'](
9040 `You are running Vue in development mode.\n` +
9041 `Make sure to turn on production mode when deploying for production.\n` +
9042 `See more tips at https://vuejs.org/guide/deployment.html`
9043 );
9044 }
9045 }, 0);
9046}
9047
9048/* */
9049
9050const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;
9051const regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
9052
9053const buildRegex = cached(delimiters => {
9054 const open = delimiters[0].replace(regexEscapeRE, '\\$&');
9055 const close = delimiters[1].replace(regexEscapeRE, '\\$&');
9056 return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
9057});
9058
9059
9060
9061function parseText (
9062 text,
9063 delimiters
9064) {
9065 const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
9066 if (!tagRE.test(text)) {
9067 return
9068 }
9069 const tokens = [];
9070 const rawTokens = [];
9071 let lastIndex = tagRE.lastIndex = 0;
9072 let match, index, tokenValue;
9073 while ((match = tagRE.exec(text))) {
9074 index = match.index;
9075 // push text token
9076 if (index > lastIndex) {
9077 rawTokens.push(tokenValue = text.slice(lastIndex, index));
9078 tokens.push(JSON.stringify(tokenValue));
9079 }
9080 // tag token
9081 const exp = parseFilters(match[1].trim());
9082 tokens.push(`_s(${exp})`);
9083 rawTokens.push({ '@binding': exp });
9084 lastIndex = index + match[0].length;
9085 }
9086 if (lastIndex < text.length) {
9087 rawTokens.push(tokenValue = text.slice(lastIndex));
9088 tokens.push(JSON.stringify(tokenValue));
9089 }
9090 return {
9091 expression: tokens.join('+'),
9092 tokens: rawTokens
9093 }
9094}
9095
9096/* */
9097
9098function transformNode (el, options) {
9099 const warn = options.warn || baseWarn;
9100 const staticClass = getAndRemoveAttr(el, 'class');
9101 if (staticClass) {
9102 const res = parseText(staticClass, options.delimiters);
9103 if (res) {
9104 warn(
9105 `class="${staticClass}": ` +
9106 'Interpolation inside attributes has been removed. ' +
9107 'Use v-bind or the colon shorthand instead. For example, ' +
9108 'instead of <div class="{{ val }}">, use <div :class="val">.',
9109 el.rawAttrsMap['class']
9110 );
9111 }
9112 }
9113 if (staticClass) {
9114 el.staticClass = JSON.stringify(staticClass);
9115 }
9116 const classBinding = getBindingAttr(el, 'class', false /* getStatic */);
9117 if (classBinding) {
9118 el.classBinding = classBinding;
9119 }
9120}
9121
9122function genData (el) {
9123 let data = '';
9124 if (el.staticClass) {
9125 data += `staticClass:${el.staticClass},`;
9126 }
9127 if (el.classBinding) {
9128 data += `class:${el.classBinding},`;
9129 }
9130 return data
9131}
9132
9133var klass$1 = {
9134 staticKeys: ['staticClass'],
9135 transformNode,
9136 genData
9137};
9138
9139/* */
9140
9141function transformNode$1 (el, options) {
9142 const warn = options.warn || baseWarn;
9143 const staticStyle = getAndRemoveAttr(el, 'style');
9144 if (staticStyle) {
9145 /* istanbul ignore if */
9146 {
9147 const res = parseText(staticStyle, options.delimiters);
9148 if (res) {
9149 warn(
9150 `style="${staticStyle}": ` +
9151 'Interpolation inside attributes has been removed. ' +
9152 'Use v-bind or the colon shorthand instead. For example, ' +
9153 'instead of <div style="{{ val }}">, use <div :style="val">.',
9154 el.rawAttrsMap['style']
9155 );
9156 }
9157 }
9158 el.staticStyle = JSON.stringify(parseStyleText(staticStyle));
9159 }
9160
9161 const styleBinding = getBindingAttr(el, 'style', false /* getStatic */);
9162 if (styleBinding) {
9163 el.styleBinding = styleBinding;
9164 }
9165}
9166
9167function genData$1 (el) {
9168 let data = '';
9169 if (el.staticStyle) {
9170 data += `staticStyle:${el.staticStyle},`;
9171 }
9172 if (el.styleBinding) {
9173 data += `style:(${el.styleBinding}),`;
9174 }
9175 return data
9176}
9177
9178var style$1 = {
9179 staticKeys: ['staticStyle'],
9180 transformNode: transformNode$1,
9181 genData: genData$1
9182};
9183
9184/* */
9185
9186let decoder;
9187
9188var he = {
9189 decode (html) {
9190 decoder = decoder || document.createElement('div');
9191 decoder.innerHTML = html;
9192 return decoder.textContent
9193 }
9194};
9195
9196/* */
9197
9198const isUnaryTag = makeMap(
9199 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
9200 'link,meta,param,source,track,wbr'
9201);
9202
9203// Elements that you can, intentionally, leave open
9204// (and which close themselves)
9205const canBeLeftOpenTag = makeMap(
9206 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source'
9207);
9208
9209// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
9210// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
9211const isNonPhrasingTag = makeMap(
9212 'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
9213 'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
9214 'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
9215 'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
9216 'title,tr,track'
9217);
9218
9219/**
9220 * Not type-checking this file because it's mostly vendor code.
9221 */
9222
9223// Regular Expressions for parsing tags and attributes
9224const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9225const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9226const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*`;
9227const qnameCapture = `((?:${ncname}\\:)?${ncname})`;
9228const startTagOpen = new RegExp(`^<${qnameCapture}`);
9229const startTagClose = /^\s*(\/?)>/;
9230const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`);
9231const doctype = /^<!DOCTYPE [^>]+>/i;
9232// #7298: escape - to avoid being pased as HTML comment when inlined in page
9233const comment = /^<!\--/;
9234const conditionalComment = /^<!\[/;
9235
9236// Special Elements (can contain anything)
9237const isPlainTextElement = makeMap('script,style,textarea', true);
9238const reCache = {};
9239
9240const decodingMap = {
9241 '&lt;': '<',
9242 '&gt;': '>',
9243 '&quot;': '"',
9244 '&amp;': '&',
9245 '&#10;': '\n',
9246 '&#9;': '\t',
9247 '&#39;': "'"
9248};
9249const encodedAttr = /&(?:lt|gt|quot|amp|#39);/g;
9250const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#39|#10|#9);/g;
9251
9252// #5992
9253const isIgnoreNewlineTag = makeMap('pre,textarea', true);
9254const shouldIgnoreFirstNewline = (tag, html) => tag && isIgnoreNewlineTag(tag) && html[0] === '\n';
9255
9256function decodeAttr (value, shouldDecodeNewlines) {
9257 const re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr;
9258 return value.replace(re, match => decodingMap[match])
9259}
9260
9261function parseHTML (html, options) {
9262 const stack = [];
9263 const expectHTML = options.expectHTML;
9264 const isUnaryTag$$1 = options.isUnaryTag || no;
9265 const canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;
9266 let index = 0;
9267 let last, lastTag;
9268 while (html) {
9269 last = html;
9270 // Make sure we're not in a plaintext content element like script/style
9271 if (!lastTag || !isPlainTextElement(lastTag)) {
9272 let textEnd = html.indexOf('<');
9273 if (textEnd === 0) {
9274 // Comment:
9275 if (comment.test(html)) {
9276 const commentEnd = html.indexOf('-->');
9277
9278 if (commentEnd >= 0) {
9279 if (options.shouldKeepComment) {
9280 options.comment(html.substring(4, commentEnd), index, index + commentEnd + 3);
9281 }
9282 advance(commentEnd + 3);
9283 continue
9284 }
9285 }
9286
9287 // http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
9288 if (conditionalComment.test(html)) {
9289 const conditionalEnd = html.indexOf(']>');
9290
9291 if (conditionalEnd >= 0) {
9292 advance(conditionalEnd + 2);
9293 continue
9294 }
9295 }
9296
9297 // Doctype:
9298 const doctypeMatch = html.match(doctype);
9299 if (doctypeMatch) {
9300 advance(doctypeMatch[0].length);
9301 continue
9302 }
9303
9304 // End tag:
9305 const endTagMatch = html.match(endTag);
9306 if (endTagMatch) {
9307 const curIndex = index;
9308 advance(endTagMatch[0].length);
9309 parseEndTag(endTagMatch[1], curIndex, index);
9310 continue
9311 }
9312
9313 // Start tag:
9314 const startTagMatch = parseStartTag();
9315 if (startTagMatch) {
9316 handleStartTag(startTagMatch);
9317 if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
9318 advance(1);
9319 }
9320 continue
9321 }
9322 }
9323
9324 let text, rest, next;
9325 if (textEnd >= 0) {
9326 rest = html.slice(textEnd);
9327 while (
9328 !endTag.test(rest) &&
9329 !startTagOpen.test(rest) &&
9330 !comment.test(rest) &&
9331 !conditionalComment.test(rest)
9332 ) {
9333 // < in plain text, be forgiving and treat it as text
9334 next = rest.indexOf('<', 1);
9335 if (next < 0) break
9336 textEnd += next;
9337 rest = html.slice(textEnd);
9338 }
9339 text = html.substring(0, textEnd);
9340 }
9341
9342 if (textEnd < 0) {
9343 text = html;
9344 }
9345
9346 if (text) {
9347 advance(text.length);
9348 }
9349
9350 if (options.chars && text) {
9351 options.chars(text, index - text.length, index);
9352 }
9353 } else {
9354 let endTagLength = 0;
9355 const stackedTag = lastTag.toLowerCase();
9356 const reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i'));
9357 const rest = html.replace(reStackedTag, function (all, text, endTag) {
9358 endTagLength = endTag.length;
9359 if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
9360 text = text
9361 .replace(/<!\--([\s\S]*?)-->/g, '$1') // #7298
9362 .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
9363 }
9364 if (shouldIgnoreFirstNewline(stackedTag, text)) {
9365 text = text.slice(1);
9366 }
9367 if (options.chars) {
9368 options.chars(text);
9369 }
9370 return ''
9371 });
9372 index += html.length - rest.length;
9373 html = rest;
9374 parseEndTag(stackedTag, index - endTagLength, index);
9375 }
9376
9377 if (html === last) {
9378 options.chars && options.chars(html);
9379 if (!stack.length && options.warn) {
9380 options.warn(`Mal-formatted tag at end of template: "${html}"`, { start: index + html.length });
9381 }
9382 break
9383 }
9384 }
9385
9386 // Clean up any remaining tags
9387 parseEndTag();
9388
9389 function advance (n) {
9390 index += n;
9391 html = html.substring(n);
9392 }
9393
9394 function parseStartTag () {
9395 const start = html.match(startTagOpen);
9396 if (start) {
9397 const match = {
9398 tagName: start[1],
9399 attrs: [],
9400 start: index
9401 };
9402 advance(start[0].length);
9403 let end, attr;
9404 while (!(end = html.match(startTagClose)) && (attr = html.match(dynamicArgAttribute) || html.match(attribute))) {
9405 attr.start = index;
9406 advance(attr[0].length);
9407 attr.end = index;
9408 match.attrs.push(attr);
9409 }
9410 if (end) {
9411 match.unarySlash = end[1];
9412 advance(end[0].length);
9413 match.end = index;
9414 return match
9415 }
9416 }
9417 }
9418
9419 function handleStartTag (match) {
9420 const tagName = match.tagName;
9421 const unarySlash = match.unarySlash;
9422
9423 if (expectHTML) {
9424 if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
9425 parseEndTag(lastTag);
9426 }
9427 if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) {
9428 parseEndTag(tagName);
9429 }
9430 }
9431
9432 const unary = isUnaryTag$$1(tagName) || !!unarySlash;
9433
9434 const l = match.attrs.length;
9435 const attrs = new Array(l);
9436 for (let i = 0; i < l; i++) {
9437 const args = match.attrs[i];
9438 const value = args[3] || args[4] || args[5] || '';
9439 const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'
9440 ? options.shouldDecodeNewlinesForHref
9441 : options.shouldDecodeNewlines;
9442 attrs[i] = {
9443 name: args[1],
9444 value: decodeAttr(value, shouldDecodeNewlines)
9445 };
9446 if (options.outputSourceRange) {
9447 attrs[i].start = args.start + args[0].match(/^\s*/).length;
9448 attrs[i].end = args.end;
9449 }
9450 }
9451
9452 if (!unary) {
9453 stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs, start: match.start, end: match.end });
9454 lastTag = tagName;
9455 }
9456
9457 if (options.start) {
9458 options.start(tagName, attrs, unary, match.start, match.end);
9459 }
9460 }
9461
9462 function parseEndTag (tagName, start, end) {
9463 let pos, lowerCasedTagName;
9464 if (start == null) start = index;
9465 if (end == null) end = index;
9466
9467 // Find the closest opened tag of the same type
9468 if (tagName) {
9469 lowerCasedTagName = tagName.toLowerCase();
9470 for (pos = stack.length - 1; pos >= 0; pos--) {
9471 if (stack[pos].lowerCasedTag === lowerCasedTagName) {
9472 break
9473 }
9474 }
9475 } else {
9476 // If no tag name is provided, clean shop
9477 pos = 0;
9478 }
9479
9480 if (pos >= 0) {
9481 // Close all the open elements, up the stack
9482 for (let i = stack.length - 1; i >= pos; i--) {
9483 if (i > pos || !tagName &&
9484 options.warn
9485 ) {
9486 options.warn(
9487 `tag <${stack[i].tag}> has no matching end tag.`,
9488 { start: stack[i].start, end: stack[i].end }
9489 );
9490 }
9491 if (options.end) {
9492 options.end(stack[i].tag, start, end);
9493 }
9494 }
9495
9496 // Remove the open elements from the stack
9497 stack.length = pos;
9498 lastTag = pos && stack[pos - 1].tag;
9499 } else if (lowerCasedTagName === 'br') {
9500 if (options.start) {
9501 options.start(tagName, [], true, start, end);
9502 }
9503 } else if (lowerCasedTagName === 'p') {
9504 if (options.start) {
9505 options.start(tagName, [], false, start, end);
9506 }
9507 if (options.end) {
9508 options.end(tagName, start, end);
9509 }
9510 }
9511 }
9512}
9513
9514/* */
9515
9516const onRE = /^@|^v-on:/;
9517const dirRE = /^v-|^@|^:/;
9518const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
9519const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
9520const stripParensRE = /^\(|\)$/g;
9521const dynamicArgRE = /^\[.*\]$/;
9522
9523const argRE = /:(.*)$/;
9524const bindRE = /^:|^\.|^v-bind:/;
9525const modifierRE = /\.[^.\]]+(?=[^\]]*$)/g;
9526
9527const slotRE = /^v-slot(:|$)|^#/;
9528
9529const lineBreakRE = /[\r\n]/;
9530const whitespaceRE$1 = /\s+/g;
9531
9532const invalidAttributeRE = /[\s"'<>\/=]/;
9533
9534const decodeHTMLCached = cached(he.decode);
9535
9536const emptySlotScopeToken = `_empty_`;
9537
9538// configurable state
9539let warn$2;
9540let delimiters;
9541let transforms;
9542let preTransforms;
9543let postTransforms;
9544let platformIsPreTag;
9545let platformMustUseProp;
9546let platformGetTagNamespace;
9547let maybeComponent;
9548
9549function createASTElement (
9550 tag,
9551 attrs,
9552 parent
9553) {
9554 return {
9555 type: 1,
9556 tag,
9557 attrsList: attrs,
9558 attrsMap: makeAttrsMap(attrs),
9559 rawAttrsMap: {},
9560 parent,
9561 children: []
9562 }
9563}
9564
9565/**
9566 * Convert HTML string to AST.
9567 */
9568function parse (
9569 template,
9570 options
9571) {
9572 warn$2 = options.warn || baseWarn;
9573
9574 platformIsPreTag = options.isPreTag || no;
9575 platformMustUseProp = options.mustUseProp || no;
9576 platformGetTagNamespace = options.getTagNamespace || no;
9577 const isReservedTag = options.isReservedTag || no;
9578 maybeComponent = (el) => !!el.component || !isReservedTag(el.tag);
9579
9580 transforms = pluckModuleFunction(options.modules, 'transformNode');
9581 preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
9582 postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');
9583
9584 delimiters = options.delimiters;
9585
9586 const stack = [];
9587 const preserveWhitespace = options.preserveWhitespace !== false;
9588 const whitespaceOption = options.whitespace;
9589 let root;
9590 let currentParent;
9591 let inVPre = false;
9592 let inPre = false;
9593 let warned = false;
9594
9595 function warnOnce (msg, range) {
9596 if (!warned) {
9597 warned = true;
9598 warn$2(msg, range);
9599 }
9600 }
9601
9602 function closeElement (element) {
9603 trimEndingWhitespace(element);
9604 if (!inVPre && !element.processed) {
9605 element = processElement(element, options);
9606 }
9607 // tree management
9608 if (!stack.length && element !== root) {
9609 // allow root elements with v-if, v-else-if and v-else
9610 if (root.if && (element.elseif || element.else)) {
9611 {
9612 checkRootConstraints(element);
9613 }
9614 addIfCondition(root, {
9615 exp: element.elseif,
9616 block: element
9617 });
9618 } else {
9619 warnOnce(
9620 `Component template should contain exactly one root element. ` +
9621 `If you are using v-if on multiple elements, ` +
9622 `use v-else-if to chain them instead.`,
9623 { start: element.start }
9624 );
9625 }
9626 }
9627 if (currentParent && !element.forbidden) {
9628 if (element.elseif || element.else) {
9629 processIfConditions(element, currentParent);
9630 } else {
9631 if (element.slotScope) {
9632 // scoped slot
9633 // keep it in the children list so that v-else(-if) conditions can
9634 // find it as the prev node.
9635 const name = element.slotTarget || '"default"'
9636 ;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element;
9637 }
9638 currentParent.children.push(element);
9639 element.parent = currentParent;
9640 }
9641 }
9642
9643 // final children cleanup
9644 // filter out scoped slots
9645 element.children = element.children.filter(c => !(c).slotScope);
9646 // remove trailing whitespace node again
9647 trimEndingWhitespace(element);
9648
9649 // check pre state
9650 if (element.pre) {
9651 inVPre = false;
9652 }
9653 if (platformIsPreTag(element.tag)) {
9654 inPre = false;
9655 }
9656 // apply post-transforms
9657 for (let i = 0; i < postTransforms.length; i++) {
9658 postTransforms[i](element, options);
9659 }
9660 }
9661
9662 function trimEndingWhitespace (el) {
9663 // remove trailing whitespace node
9664 if (!inPre) {
9665 let lastNode;
9666 while (
9667 (lastNode = el.children[el.children.length - 1]) &&
9668 lastNode.type === 3 &&
9669 lastNode.text === ' '
9670 ) {
9671 el.children.pop();
9672 }
9673 }
9674 }
9675
9676 function checkRootConstraints (el) {
9677 if (el.tag === 'slot' || el.tag === 'template') {
9678 warnOnce(
9679 `Cannot use <${el.tag}> as component root element because it may ` +
9680 'contain multiple nodes.',
9681 { start: el.start }
9682 );
9683 }
9684 if (el.attrsMap.hasOwnProperty('v-for')) {
9685 warnOnce(
9686 'Cannot use v-for on stateful component root element because ' +
9687 'it renders multiple elements.',
9688 el.rawAttrsMap['v-for']
9689 );
9690 }
9691 }
9692
9693 parseHTML(template, {
9694 warn: warn$2,
9695 expectHTML: options.expectHTML,
9696 isUnaryTag: options.isUnaryTag,
9697 canBeLeftOpenTag: options.canBeLeftOpenTag,
9698 shouldDecodeNewlines: options.shouldDecodeNewlines,
9699 shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
9700 shouldKeepComment: options.comments,
9701 outputSourceRange: options.outputSourceRange,
9702 start (tag, attrs, unary, start, end) {
9703 // check namespace.
9704 // inherit parent ns if there is one
9705 const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);
9706
9707 // handle IE svg bug
9708 /* istanbul ignore if */
9709 if (isIE && ns === 'svg') {
9710 attrs = guardIESVGBug(attrs);
9711 }
9712
9713 let element = createASTElement(tag, attrs, currentParent);
9714 if (ns) {
9715 element.ns = ns;
9716 }
9717
9718 {
9719 if (options.outputSourceRange) {
9720 element.start = start;
9721 element.end = end;
9722 element.rawAttrsMap = element.attrsList.reduce((cumulated, attr) => {
9723 cumulated[attr.name] = attr;
9724 return cumulated
9725 }, {});
9726 }
9727 attrs.forEach(attr => {
9728 if (invalidAttributeRE.test(attr.name)) {
9729 warn$2(
9730 `Invalid dynamic argument expression: attribute names cannot contain ` +
9731 `spaces, quotes, <, >, / or =.`,
9732 {
9733 start: attr.start + attr.name.indexOf(`[`),
9734 end: attr.start + attr.name.length
9735 }
9736 );
9737 }
9738 });
9739 }
9740
9741 if (isForbiddenTag(element) && !isServerRendering()) {
9742 element.forbidden = true;
9743 warn$2(
9744 'Templates should only be responsible for mapping the state to the ' +
9745 'UI. Avoid placing tags with side-effects in your templates, such as ' +
9746 `<${tag}>` + ', as they will not be parsed.',
9747 { start: element.start }
9748 );
9749 }
9750
9751 // apply pre-transforms
9752 for (let i = 0; i < preTransforms.length; i++) {
9753 element = preTransforms[i](element, options) || element;
9754 }
9755
9756 if (!inVPre) {
9757 processPre(element);
9758 if (element.pre) {
9759 inVPre = true;
9760 }
9761 }
9762 if (platformIsPreTag(element.tag)) {
9763 inPre = true;
9764 }
9765 if (inVPre) {
9766 processRawAttrs(element);
9767 } else if (!element.processed) {
9768 // structural directives
9769 processFor(element);
9770 processIf(element);
9771 processOnce(element);
9772 }
9773
9774 if (!root) {
9775 root = element;
9776 {
9777 checkRootConstraints(root);
9778 }
9779 }
9780
9781 if (!unary) {
9782 currentParent = element;
9783 stack.push(element);
9784 } else {
9785 closeElement(element);
9786 }
9787 },
9788
9789 end (tag, start, end) {
9790 const element = stack[stack.length - 1];
9791 // pop stack
9792 stack.length -= 1;
9793 currentParent = stack[stack.length - 1];
9794 if (options.outputSourceRange) {
9795 element.end = end;
9796 }
9797 closeElement(element);
9798 },
9799
9800 chars (text, start, end) {
9801 if (!currentParent) {
9802 {
9803 if (text === template) {
9804 warnOnce(
9805 'Component template requires a root element, rather than just text.',
9806 { start }
9807 );
9808 } else if ((text = text.trim())) {
9809 warnOnce(
9810 `text "${text}" outside root element will be ignored.`,
9811 { start }
9812 );
9813 }
9814 }
9815 return
9816 }
9817 // IE textarea placeholder bug
9818 /* istanbul ignore if */
9819 if (isIE &&
9820 currentParent.tag === 'textarea' &&
9821 currentParent.attrsMap.placeholder === text
9822 ) {
9823 return
9824 }
9825 const children = currentParent.children;
9826 if (inPre || text.trim()) {
9827 text = isTextTag(currentParent) ? text : decodeHTMLCached(text);
9828 } else if (!children.length) {
9829 // remove the whitespace-only node right after an opening tag
9830 text = '';
9831 } else if (whitespaceOption) {
9832 if (whitespaceOption === 'condense') {
9833 // in condense mode, remove the whitespace node if it contains
9834 // line break, otherwise condense to a single space
9835 text = lineBreakRE.test(text) ? '' : ' ';
9836 } else {
9837 text = ' ';
9838 }
9839 } else {
9840 text = preserveWhitespace ? ' ' : '';
9841 }
9842 if (text) {
9843 if (whitespaceOption === 'condense') {
9844 // condense consecutive whitespaces into single space
9845 text = text.replace(whitespaceRE$1, ' ');
9846 }
9847 let res;
9848 let child;
9849 if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {
9850 child = {
9851 type: 2,
9852 expression: res.expression,
9853 tokens: res.tokens,
9854 text
9855 };
9856 } else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') {
9857 child = {
9858 type: 3,
9859 text
9860 };
9861 }
9862 if (child) {
9863 if (options.outputSourceRange) {
9864 child.start = start;
9865 child.end = end;
9866 }
9867 children.push(child);
9868 }
9869 }
9870 },
9871 comment (text, start, end) {
9872 // adding anyting as a sibling to the root node is forbidden
9873 // comments should still be allowed, but ignored
9874 if (currentParent) {
9875 const child = {
9876 type: 3,
9877 text,
9878 isComment: true
9879 };
9880 if (options.outputSourceRange) {
9881 child.start = start;
9882 child.end = end;
9883 }
9884 currentParent.children.push(child);
9885 }
9886 }
9887 });
9888 return root
9889}
9890
9891function processPre (el) {
9892 if (getAndRemoveAttr(el, 'v-pre') != null) {
9893 el.pre = true;
9894 }
9895}
9896
9897function processRawAttrs (el) {
9898 const list = el.attrsList;
9899 const len = list.length;
9900 if (len) {
9901 const attrs = el.attrs = new Array(len);
9902 for (let i = 0; i < len; i++) {
9903 attrs[i] = {
9904 name: list[i].name,
9905 value: JSON.stringify(list[i].value)
9906 };
9907 if (list[i].start != null) {
9908 attrs[i].start = list[i].start;
9909 attrs[i].end = list[i].end;
9910 }
9911 }
9912 } else if (!el.pre) {
9913 // non root node in pre blocks with no attributes
9914 el.plain = true;
9915 }
9916}
9917
9918function processElement (
9919 element,
9920 options
9921) {
9922 processKey(element);
9923
9924 // determine whether this is a plain element after
9925 // removing structural attributes
9926 element.plain = (
9927 !element.key &&
9928 !element.scopedSlots &&
9929 !element.attrsList.length
9930 );
9931
9932 processRef(element);
9933 processSlotContent(element);
9934 processSlotOutlet(element);
9935 processComponent(element);
9936 for (let i = 0; i < transforms.length; i++) {
9937 element = transforms[i](element, options) || element;
9938 }
9939 processAttrs(element);
9940 return element
9941}
9942
9943function processKey (el) {
9944 const exp = getBindingAttr(el, 'key');
9945 if (exp) {
9946 {
9947 if (el.tag === 'template') {
9948 warn$2(
9949 `<template> cannot be keyed. Place the key on real elements instead.`,
9950 getRawBindingAttr(el, 'key')
9951 );
9952 }
9953 if (el.for) {
9954 const iterator = el.iterator2 || el.iterator1;
9955 const parent = el.parent;
9956 if (iterator && iterator === exp && parent && parent.tag === 'transition-group') {
9957 warn$2(
9958 `Do not use v-for index as key on <transition-group> children, ` +
9959 `this is the same as not using keys.`,
9960 getRawBindingAttr(el, 'key'),
9961 true /* tip */
9962 );
9963 }
9964 }
9965 }
9966 el.key = exp;
9967 }
9968}
9969
9970function processRef (el) {
9971 const ref = getBindingAttr(el, 'ref');
9972 if (ref) {
9973 el.ref = ref;
9974 el.refInFor = checkInFor(el);
9975 }
9976}
9977
9978function processFor (el) {
9979 let exp;
9980 if ((exp = getAndRemoveAttr(el, 'v-for'))) {
9981 const res = parseFor(exp);
9982 if (res) {
9983 extend(el, res);
9984 } else {
9985 warn$2(
9986 `Invalid v-for expression: ${exp}`,
9987 el.rawAttrsMap['v-for']
9988 );
9989 }
9990 }
9991}
9992
9993
9994
9995function parseFor (exp) {
9996 const inMatch = exp.match(forAliasRE);
9997 if (!inMatch) return
9998 const res = {};
9999 res.for = inMatch[2].trim();
10000 const alias = inMatch[1].trim().replace(stripParensRE, '');
10001 const iteratorMatch = alias.match(forIteratorRE);
10002 if (iteratorMatch) {
10003 res.alias = alias.replace(forIteratorRE, '').trim();
10004 res.iterator1 = iteratorMatch[1].trim();
10005 if (iteratorMatch[2]) {
10006 res.iterator2 = iteratorMatch[2].trim();
10007 }
10008 } else {
10009 res.alias = alias;
10010 }
10011 return res
10012}
10013
10014function processIf (el) {
10015 const exp = getAndRemoveAttr(el, 'v-if');
10016 if (exp) {
10017 el.if = exp;
10018 addIfCondition(el, {
10019 exp: exp,
10020 block: el
10021 });
10022 } else {
10023 if (getAndRemoveAttr(el, 'v-else') != null) {
10024 el.else = true;
10025 }
10026 const elseif = getAndRemoveAttr(el, 'v-else-if');
10027 if (elseif) {
10028 el.elseif = elseif;
10029 }
10030 }
10031}
10032
10033function processIfConditions (el, parent) {
10034 const prev = findPrevElement(parent.children);
10035 if (prev && prev.if) {
10036 addIfCondition(prev, {
10037 exp: el.elseif,
10038 block: el
10039 });
10040 } else {
10041 warn$2(
10042 `v-${el.elseif ? ('else-if="' + el.elseif + '"') : 'else'} ` +
10043 `used on element <${el.tag}> without corresponding v-if.`,
10044 el.rawAttrsMap[el.elseif ? 'v-else-if' : 'v-else']
10045 );
10046 }
10047}
10048
10049function findPrevElement (children) {
10050 let i = children.length;
10051 while (i--) {
10052 if (children[i].type === 1) {
10053 return children[i]
10054 } else {
10055 if (children[i].text !== ' ') {
10056 warn$2(
10057 `text "${children[i].text.trim()}" between v-if and v-else(-if) ` +
10058 `will be ignored.`,
10059 children[i]
10060 );
10061 }
10062 children.pop();
10063 }
10064 }
10065}
10066
10067function addIfCondition (el, condition) {
10068 if (!el.ifConditions) {
10069 el.ifConditions = [];
10070 }
10071 el.ifConditions.push(condition);
10072}
10073
10074function processOnce (el) {
10075 const once$$1 = getAndRemoveAttr(el, 'v-once');
10076 if (once$$1 != null) {
10077 el.once = true;
10078 }
10079}
10080
10081// handle content being passed to a component as slot,
10082// e.g. <template slot="xxx">, <div slot-scope="xxx">
10083function processSlotContent (el) {
10084 let slotScope;
10085 if (el.tag === 'template') {
10086 slotScope = getAndRemoveAttr(el, 'scope');
10087 /* istanbul ignore if */
10088 if (slotScope) {
10089 warn$2(
10090 `the "scope" attribute for scoped slots have been deprecated and ` +
10091 `replaced by "slot-scope" since 2.5. The new "slot-scope" attribute ` +
10092 `can also be used on plain elements in addition to <template> to ` +
10093 `denote scoped slots.`,
10094 el.rawAttrsMap['scope'],
10095 true
10096 );
10097 }
10098 el.slotScope = slotScope || getAndRemoveAttr(el, 'slot-scope');
10099 } else if ((slotScope = getAndRemoveAttr(el, 'slot-scope'))) {
10100 /* istanbul ignore if */
10101 if (el.attrsMap['v-for']) {
10102 warn$2(
10103 `Ambiguous combined usage of slot-scope and v-for on <${el.tag}> ` +
10104 `(v-for takes higher priority). Use a wrapper <template> for the ` +
10105 `scoped slot to make it clearer.`,
10106 el.rawAttrsMap['slot-scope'],
10107 true
10108 );
10109 }
10110 el.slotScope = slotScope;
10111 }
10112
10113 // slot="xxx"
10114 const slotTarget = getBindingAttr(el, 'slot');
10115 if (slotTarget) {
10116 el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget;
10117 el.slotTargetDynamic = !!(el.attrsMap[':slot'] || el.attrsMap['v-bind:slot']);
10118 // preserve slot as an attribute for native shadow DOM compat
10119 // only for non-scoped slots.
10120 if (el.tag !== 'template' && !el.slotScope) {
10121 addAttr(el, 'slot', slotTarget, getRawBindingAttr(el, 'slot'));
10122 }
10123 }
10124
10125 // 2.6 v-slot syntax
10126 {
10127 if (el.tag === 'template') {
10128 // v-slot on <template>
10129 const slotBinding = getAndRemoveAttrByRegex(el, slotRE);
10130 if (slotBinding) {
10131 {
10132 if (el.slotTarget || el.slotScope) {
10133 warn$2(
10134 `Unexpected mixed usage of different slot syntaxes.`,
10135 el
10136 );
10137 }
10138 if (el.parent && !maybeComponent(el.parent)) {
10139 warn$2(
10140 `<template v-slot> can only appear at the root level inside ` +
10141 `the receiving the component`,
10142 el
10143 );
10144 }
10145 }
10146 const { name, dynamic } = getSlotName(slotBinding);
10147 el.slotTarget = name;
10148 el.slotTargetDynamic = dynamic;
10149 el.slotScope = slotBinding.value || emptySlotScopeToken; // force it into a scoped slot for perf
10150 }
10151 } else {
10152 // v-slot on component, denotes default slot
10153 const slotBinding = getAndRemoveAttrByRegex(el, slotRE);
10154 if (slotBinding) {
10155 {
10156 if (!maybeComponent(el)) {
10157 warn$2(
10158 `v-slot can only be used on components or <template>.`,
10159 slotBinding
10160 );
10161 }
10162 if (el.slotScope || el.slotTarget) {
10163 warn$2(
10164 `Unexpected mixed usage of different slot syntaxes.`,
10165 el
10166 );
10167 }
10168 if (el.scopedSlots) {
10169 warn$2(
10170 `To avoid scope ambiguity, the default slot should also use ` +
10171 `<template> syntax when there are other named slots.`,
10172 slotBinding
10173 );
10174 }
10175 }
10176 // add the component's children to its default slot
10177 const slots = el.scopedSlots || (el.scopedSlots = {});
10178 const { name, dynamic } = getSlotName(slotBinding);
10179 const slotContainer = slots[name] = createASTElement('template', [], el);
10180 slotContainer.slotTarget = name;
10181 slotContainer.slotTargetDynamic = dynamic;
10182 slotContainer.children = el.children.filter((c) => {
10183 if (!c.slotScope) {
10184 c.parent = slotContainer;
10185 return true
10186 }
10187 });
10188 slotContainer.slotScope = slotBinding.value || emptySlotScopeToken;
10189 // remove children as they are returned from scopedSlots now
10190 el.children = [];
10191 // mark el non-plain so data gets generated
10192 el.plain = false;
10193 }
10194 }
10195 }
10196}
10197
10198function getSlotName (binding) {
10199 let name = binding.name.replace(slotRE, '');
10200 if (!name) {
10201 if (binding.name[0] !== '#') {
10202 name = 'default';
10203 } else {
10204 warn$2(
10205 `v-slot shorthand syntax requires a slot name.`,
10206 binding
10207 );
10208 }
10209 }
10210 return dynamicArgRE.test(name)
10211 // dynamic [name]
10212 ? { name: name.slice(1, -1), dynamic: true }
10213 // static name
10214 : { name: `"${name}"`, dynamic: false }
10215}
10216
10217// handle <slot/> outlets
10218function processSlotOutlet (el) {
10219 if (el.tag === 'slot') {
10220 el.slotName = getBindingAttr(el, 'name');
10221 if (el.key) {
10222 warn$2(
10223 `\`key\` does not work on <slot> because slots are abstract outlets ` +
10224 `and can possibly expand into multiple elements. ` +
10225 `Use the key on a wrapping element instead.`,
10226 getRawBindingAttr(el, 'key')
10227 );
10228 }
10229 }
10230}
10231
10232function processComponent (el) {
10233 let binding;
10234 if ((binding = getBindingAttr(el, 'is'))) {
10235 el.component = binding;
10236 }
10237 if (getAndRemoveAttr(el, 'inline-template') != null) {
10238 el.inlineTemplate = true;
10239 }
10240}
10241
10242function processAttrs (el) {
10243 const list = el.attrsList;
10244 let i, l, name, rawName, value, modifiers, syncGen, isDynamic;
10245 for (i = 0, l = list.length; i < l; i++) {
10246 name = rawName = list[i].name;
10247 value = list[i].value;
10248 if (dirRE.test(name)) {
10249 // mark element as dynamic
10250 el.hasBindings = true;
10251 // modifiers
10252 modifiers = parseModifiers(name.replace(dirRE, ''));
10253 // support .foo shorthand syntax for the .prop modifier
10254 if (modifiers) {
10255 name = name.replace(modifierRE, '');
10256 }
10257 if (bindRE.test(name)) { // v-bind
10258 name = name.replace(bindRE, '');
10259 value = parseFilters(value);
10260 isDynamic = dynamicArgRE.test(name);
10261 if (isDynamic) {
10262 name = name.slice(1, -1);
10263 }
10264 if (
10265 value.trim().length === 0
10266 ) {
10267 warn$2(
10268 `The value for a v-bind expression cannot be empty. Found in "v-bind:${name}"`
10269 );
10270 }
10271 if (modifiers) {
10272 if (modifiers.prop && !isDynamic) {
10273 name = camelize(name);
10274 if (name === 'innerHtml') name = 'innerHTML';
10275 }
10276 if (modifiers.camel && !isDynamic) {
10277 name = camelize(name);
10278 }
10279 if (modifiers.sync) {
10280 syncGen = genAssignmentCode(value, `$event`);
10281 if (!isDynamic) {
10282 addHandler(
10283 el,
10284 `update:${camelize(name)}`,
10285 syncGen,
10286 null,
10287 false,
10288 warn$2,
10289 list[i]
10290 );
10291 if (hyphenate(name) !== camelize(name)) {
10292 addHandler(
10293 el,
10294 `update:${hyphenate(name)}`,
10295 syncGen,
10296 null,
10297 false,
10298 warn$2,
10299 list[i]
10300 );
10301 }
10302 } else {
10303 // handler w/ dynamic event name
10304 addHandler(
10305 el,
10306 `"update:"+(${name})`,
10307 syncGen,
10308 null,
10309 false,
10310 warn$2,
10311 list[i],
10312 true // dynamic
10313 );
10314 }
10315 }
10316 }
10317 if ((modifiers && modifiers.prop) || (
10318 !el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)
10319 )) {
10320 addProp(el, name, value, list[i], isDynamic);
10321 } else {
10322 addAttr(el, name, value, list[i], isDynamic);
10323 }
10324 } else if (onRE.test(name)) { // v-on
10325 name = name.replace(onRE, '');
10326 isDynamic = dynamicArgRE.test(name);
10327 if (isDynamic) {
10328 name = name.slice(1, -1);
10329 }
10330 addHandler(el, name, value, modifiers, false, warn$2, list[i], isDynamic);
10331 } else { // normal directives
10332 name = name.replace(dirRE, '');
10333 // parse arg
10334 const argMatch = name.match(argRE);
10335 let arg = argMatch && argMatch[1];
10336 isDynamic = false;
10337 if (arg) {
10338 name = name.slice(0, -(arg.length + 1));
10339 if (dynamicArgRE.test(arg)) {
10340 arg = arg.slice(1, -1);
10341 isDynamic = true;
10342 }
10343 }
10344 addDirective(el, name, rawName, value, arg, isDynamic, modifiers, list[i]);
10345 if (name === 'model') {
10346 checkForAliasModel(el, value);
10347 }
10348 }
10349 } else {
10350 // literal attribute
10351 {
10352 const res = parseText(value, delimiters);
10353 if (res) {
10354 warn$2(
10355 `${name}="${value}": ` +
10356 'Interpolation inside attributes has been removed. ' +
10357 'Use v-bind or the colon shorthand instead. For example, ' +
10358 'instead of <div id="{{ val }}">, use <div :id="val">.',
10359 list[i]
10360 );
10361 }
10362 }
10363 addAttr(el, name, JSON.stringify(value), list[i]);
10364 // #6887 firefox doesn't update muted state if set via attribute
10365 // even immediately after element creation
10366 if (!el.component &&
10367 name === 'muted' &&
10368 platformMustUseProp(el.tag, el.attrsMap.type, name)) {
10369 addProp(el, name, 'true', list[i]);
10370 }
10371 }
10372 }
10373}
10374
10375function checkInFor (el) {
10376 let parent = el;
10377 while (parent) {
10378 if (parent.for !== undefined) {
10379 return true
10380 }
10381 parent = parent.parent;
10382 }
10383 return false
10384}
10385
10386function parseModifiers (name) {
10387 const match = name.match(modifierRE);
10388 if (match) {
10389 const ret = {};
10390 match.forEach(m => { ret[m.slice(1)] = true; });
10391 return ret
10392 }
10393}
10394
10395function makeAttrsMap (attrs) {
10396 const map = {};
10397 for (let i = 0, l = attrs.length; i < l; i++) {
10398 if (
10399 map[attrs[i].name] && !isIE && !isEdge
10400 ) {
10401 warn$2('duplicate attribute: ' + attrs[i].name, attrs[i]);
10402 }
10403 map[attrs[i].name] = attrs[i].value;
10404 }
10405 return map
10406}
10407
10408// for script (e.g. type="x/template") or style, do not decode content
10409function isTextTag (el) {
10410 return el.tag === 'script' || el.tag === 'style'
10411}
10412
10413function isForbiddenTag (el) {
10414 return (
10415 el.tag === 'style' ||
10416 (el.tag === 'script' && (
10417 !el.attrsMap.type ||
10418 el.attrsMap.type === 'text/javascript'
10419 ))
10420 )
10421}
10422
10423const ieNSBug = /^xmlns:NS\d+/;
10424const ieNSPrefix = /^NS\d+:/;
10425
10426/* istanbul ignore next */
10427function guardIESVGBug (attrs) {
10428 const res = [];
10429 for (let i = 0; i < attrs.length; i++) {
10430 const attr = attrs[i];
10431 if (!ieNSBug.test(attr.name)) {
10432 attr.name = attr.name.replace(ieNSPrefix, '');
10433 res.push(attr);
10434 }
10435 }
10436 return res
10437}
10438
10439function checkForAliasModel (el, value) {
10440 let _el = el;
10441 while (_el) {
10442 if (_el.for && _el.alias === value) {
10443 warn$2(
10444 `<${el.tag} v-model="${value}">: ` +
10445 `You are binding v-model directly to a v-for iteration alias. ` +
10446 `This will not be able to modify the v-for source array because ` +
10447 `writing to the alias is like modifying a function local variable. ` +
10448 `Consider using an array of objects and use v-model on an object property instead.`,
10449 el.rawAttrsMap['v-model']
10450 );
10451 }
10452 _el = _el.parent;
10453 }
10454}
10455
10456/* */
10457
10458function preTransformNode (el, options) {
10459 if (el.tag === 'input') {
10460 const map = el.attrsMap;
10461 if (!map['v-model']) {
10462 return
10463 }
10464
10465 let typeBinding;
10466 if (map[':type'] || map['v-bind:type']) {
10467 typeBinding = getBindingAttr(el, 'type');
10468 }
10469 if (!map.type && !typeBinding && map['v-bind']) {
10470 typeBinding = `(${map['v-bind']}).type`;
10471 }
10472
10473 if (typeBinding) {
10474 const ifCondition = getAndRemoveAttr(el, 'v-if', true);
10475 const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``;
10476 const hasElse = getAndRemoveAttr(el, 'v-else', true) != null;
10477 const elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true);
10478 // 1. checkbox
10479 const branch0 = cloneASTElement(el);
10480 // process for on the main node
10481 processFor(branch0);
10482 addRawAttr(branch0, 'type', 'checkbox');
10483 processElement(branch0, options);
10484 branch0.processed = true; // prevent it from double-processed
10485 branch0.if = `(${typeBinding})==='checkbox'` + ifConditionExtra;
10486 addIfCondition(branch0, {
10487 exp: branch0.if,
10488 block: branch0
10489 });
10490 // 2. add radio else-if condition
10491 const branch1 = cloneASTElement(el);
10492 getAndRemoveAttr(branch1, 'v-for', true);
10493 addRawAttr(branch1, 'type', 'radio');
10494 processElement(branch1, options);
10495 addIfCondition(branch0, {
10496 exp: `(${typeBinding})==='radio'` + ifConditionExtra,
10497 block: branch1
10498 });
10499 // 3. other
10500 const branch2 = cloneASTElement(el);
10501 getAndRemoveAttr(branch2, 'v-for', true);
10502 addRawAttr(branch2, ':type', typeBinding);
10503 processElement(branch2, options);
10504 addIfCondition(branch0, {
10505 exp: ifCondition,
10506 block: branch2
10507 });
10508
10509 if (hasElse) {
10510 branch0.else = true;
10511 } else if (elseIfCondition) {
10512 branch0.elseif = elseIfCondition;
10513 }
10514
10515 return branch0
10516 }
10517 }
10518}
10519
10520function cloneASTElement (el) {
10521 return createASTElement(el.tag, el.attrsList.slice(), el.parent)
10522}
10523
10524var model$1 = {
10525 preTransformNode
10526};
10527
10528var modules$1 = [
10529 klass$1,
10530 style$1,
10531 model$1
10532];
10533
10534/* */
10535
10536function text (el, dir) {
10537 if (dir.value) {
10538 addProp(el, 'textContent', `_s(${dir.value})`, dir);
10539 }
10540}
10541
10542/* */
10543
10544function html (el, dir) {
10545 if (dir.value) {
10546 addProp(el, 'innerHTML', `_s(${dir.value})`, dir);
10547 }
10548}
10549
10550var directives$1 = {
10551 model,
10552 text,
10553 html
10554};
10555
10556/* */
10557
10558const baseOptions = {
10559 expectHTML: true,
10560 modules: modules$1,
10561 directives: directives$1,
10562 isPreTag,
10563 isUnaryTag,
10564 mustUseProp,
10565 canBeLeftOpenTag,
10566 isReservedTag,
10567 getTagNamespace,
10568 staticKeys: genStaticKeys(modules$1)
10569};
10570
10571/* */
10572
10573let isStaticKey;
10574let isPlatformReservedTag;
10575
10576const genStaticKeysCached = cached(genStaticKeys$1);
10577
10578/**
10579 * Goal of the optimizer: walk the generated template AST tree
10580 * and detect sub-trees that are purely static, i.e. parts of
10581 * the DOM that never needs to change.
10582 *
10583 * Once we detect these sub-trees, we can:
10584 *
10585 * 1. Hoist them into constants, so that we no longer need to
10586 * create fresh nodes for them on each re-render;
10587 * 2. Completely skip them in the patching process.
10588 */
10589function optimize (root, options) {
10590 if (!root) return
10591 isStaticKey = genStaticKeysCached(options.staticKeys || '');
10592 isPlatformReservedTag = options.isReservedTag || no;
10593 // first pass: mark all non-static nodes.
10594 markStatic$1(root);
10595 // second pass: mark static roots.
10596 markStaticRoots(root, false);
10597}
10598
10599function genStaticKeys$1 (keys) {
10600 return makeMap(
10601 'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +
10602 (keys ? ',' + keys : '')
10603 )
10604}
10605
10606function markStatic$1 (node) {
10607 node.static = isStatic(node);
10608 if (node.type === 1) {
10609 // do not make component slot content static. this avoids
10610 // 1. components not able to mutate slot nodes
10611 // 2. static slot content fails for hot-reloading
10612 if (
10613 !isPlatformReservedTag(node.tag) &&
10614 node.tag !== 'slot' &&
10615 node.attrsMap['inline-template'] == null
10616 ) {
10617 return
10618 }
10619 for (let i = 0, l = node.children.length; i < l; i++) {
10620 const child = node.children[i];
10621 markStatic$1(child);
10622 if (!child.static) {
10623 node.static = false;
10624 }
10625 }
10626 if (node.ifConditions) {
10627 for (let i = 1, l = node.ifConditions.length; i < l; i++) {
10628 const block = node.ifConditions[i].block;
10629 markStatic$1(block);
10630 if (!block.static) {
10631 node.static = false;
10632 }
10633 }
10634 }
10635 }
10636}
10637
10638function markStaticRoots (node, isInFor) {
10639 if (node.type === 1) {
10640 if (node.static || node.once) {
10641 node.staticInFor = isInFor;
10642 }
10643 // For a node to qualify as a static root, it should have children that
10644 // are not just static text. Otherwise the cost of hoisting out will
10645 // outweigh the benefits and it's better off to just always render it fresh.
10646 if (node.static && node.children.length && !(
10647 node.children.length === 1 &&
10648 node.children[0].type === 3
10649 )) {
10650 node.staticRoot = true;
10651 return
10652 } else {
10653 node.staticRoot = false;
10654 }
10655 if (node.children) {
10656 for (let i = 0, l = node.children.length; i < l; i++) {
10657 markStaticRoots(node.children[i], isInFor || !!node.for);
10658 }
10659 }
10660 if (node.ifConditions) {
10661 for (let i = 1, l = node.ifConditions.length; i < l; i++) {
10662 markStaticRoots(node.ifConditions[i].block, isInFor);
10663 }
10664 }
10665 }
10666}
10667
10668function isStatic (node) {
10669 if (node.type === 2) { // expression
10670 return false
10671 }
10672 if (node.type === 3) { // text
10673 return true
10674 }
10675 return !!(node.pre || (
10676 !node.hasBindings && // no dynamic bindings
10677 !node.if && !node.for && // not v-if or v-for or v-else
10678 !isBuiltInTag(node.tag) && // not a built-in
10679 isPlatformReservedTag(node.tag) && // not a component
10680 !isDirectChildOfTemplateFor(node) &&
10681 Object.keys(node).every(isStaticKey)
10682 ))
10683}
10684
10685function isDirectChildOfTemplateFor (node) {
10686 while (node.parent) {
10687 node = node.parent;
10688 if (node.tag !== 'template') {
10689 return false
10690 }
10691 if (node.for) {
10692 return true
10693 }
10694 }
10695 return false
10696}
10697
10698/* */
10699
10700const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;
10701const fnInvokeRE = /\([^)]*?\);*$/;
10702const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
10703
10704// KeyboardEvent.keyCode aliases
10705const keyCodes = {
10706 esc: 27,
10707 tab: 9,
10708 enter: 13,
10709 space: 32,
10710 up: 38,
10711 left: 37,
10712 right: 39,
10713 down: 40,
10714 'delete': [8, 46]
10715};
10716
10717// KeyboardEvent.key aliases
10718const keyNames = {
10719 // #7880: IE11 and Edge use `Esc` for Escape key name.
10720 esc: ['Esc', 'Escape'],
10721 tab: 'Tab',
10722 enter: 'Enter',
10723 // #9112: IE11 uses `Spacebar` for Space key name.
10724 space: [' ', 'Spacebar'],
10725 // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
10726 up: ['Up', 'ArrowUp'],
10727 left: ['Left', 'ArrowLeft'],
10728 right: ['Right', 'ArrowRight'],
10729 down: ['Down', 'ArrowDown'],
10730 // #9112: IE11 uses `Del` for Delete key name.
10731 'delete': ['Backspace', 'Delete', 'Del']
10732};
10733
10734// #4868: modifiers that prevent the execution of the listener
10735// need to explicitly return null so that we can determine whether to remove
10736// the listener for .once
10737const genGuard = condition => `if(${condition})return null;`;
10738
10739const modifierCode = {
10740 stop: '$event.stopPropagation();',
10741 prevent: '$event.preventDefault();',
10742 self: genGuard(`$event.target !== $event.currentTarget`),
10743 ctrl: genGuard(`!$event.ctrlKey`),
10744 shift: genGuard(`!$event.shiftKey`),
10745 alt: genGuard(`!$event.altKey`),
10746 meta: genGuard(`!$event.metaKey`),
10747 left: genGuard(`'button' in $event && $event.button !== 0`),
10748 middle: genGuard(`'button' in $event && $event.button !== 1`),
10749 right: genGuard(`'button' in $event && $event.button !== 2`)
10750};
10751
10752function genHandlers (
10753 events,
10754 isNative
10755) {
10756 const prefix = isNative ? 'nativeOn:' : 'on:';
10757 let staticHandlers = ``;
10758 let dynamicHandlers = ``;
10759 for (const name in events) {
10760 const handlerCode = genHandler(events[name]);
10761 if (events[name] && events[name].dynamic) {
10762 dynamicHandlers += `${name},${handlerCode},`;
10763 } else {
10764 staticHandlers += `"${name}":${handlerCode},`;
10765 }
10766 }
10767 staticHandlers = `{${staticHandlers.slice(0, -1)}}`;
10768 if (dynamicHandlers) {
10769 return prefix + `_d(${staticHandlers},[${dynamicHandlers.slice(0, -1)}])`
10770 } else {
10771 return prefix + staticHandlers
10772 }
10773}
10774
10775function genHandler (handler) {
10776 if (!handler) {
10777 return 'function(){}'
10778 }
10779
10780 if (Array.isArray(handler)) {
10781 return `[${handler.map(handler => genHandler(handler)).join(',')}]`
10782 }
10783
10784 const isMethodPath = simplePathRE.test(handler.value);
10785 const isFunctionExpression = fnExpRE.test(handler.value);
10786 const isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''));
10787
10788 if (!handler.modifiers) {
10789 if (isMethodPath || isFunctionExpression) {
10790 return handler.value
10791 }
10792 return `function($event){${
10793 isFunctionInvocation ? `return ${handler.value}` : handler.value
10794 }}` // inline statement
10795 } else {
10796 let code = '';
10797 let genModifierCode = '';
10798 const keys = [];
10799 for (const key in handler.modifiers) {
10800 if (modifierCode[key]) {
10801 genModifierCode += modifierCode[key];
10802 // left/right
10803 if (keyCodes[key]) {
10804 keys.push(key);
10805 }
10806 } else if (key === 'exact') {
10807 const modifiers = (handler.modifiers);
10808 genModifierCode += genGuard(
10809 ['ctrl', 'shift', 'alt', 'meta']
10810 .filter(keyModifier => !modifiers[keyModifier])
10811 .map(keyModifier => `$event.${keyModifier}Key`)
10812 .join('||')
10813 );
10814 } else {
10815 keys.push(key);
10816 }
10817 }
10818 if (keys.length) {
10819 code += genKeyFilter(keys);
10820 }
10821 // Make sure modifiers like prevent and stop get executed after key filtering
10822 if (genModifierCode) {
10823 code += genModifierCode;
10824 }
10825 const handlerCode = isMethodPath
10826 ? `return ${handler.value}($event)`
10827 : isFunctionExpression
10828 ? `return (${handler.value})($event)`
10829 : isFunctionInvocation
10830 ? `return ${handler.value}`
10831 : handler.value;
10832 return `function($event){${code}${handlerCode}}`
10833 }
10834}
10835
10836function genKeyFilter (keys) {
10837 return (
10838 // make sure the key filters only apply to KeyboardEvents
10839 // #9441: can't use 'keyCode' in $event because Chrome autofill fires fake
10840 // key events that do not have keyCode property...
10841 `if(!$event.type.indexOf('key')&&` +
10842 `${keys.map(genFilterCode).join('&&')})return null;`
10843 )
10844}
10845
10846function genFilterCode (key) {
10847 const keyVal = parseInt(key, 10);
10848 if (keyVal) {
10849 return `$event.keyCode!==${keyVal}`
10850 }
10851 const keyCode = keyCodes[key];
10852 const keyName = keyNames[key];
10853 return (
10854 `_k($event.keyCode,` +
10855 `${JSON.stringify(key)},` +
10856 `${JSON.stringify(keyCode)},` +
10857 `$event.key,` +
10858 `${JSON.stringify(keyName)}` +
10859 `)`
10860 )
10861}
10862
10863/* */
10864
10865function on (el, dir) {
10866 if (dir.modifiers) {
10867 warn(`v-on without argument does not support modifiers.`);
10868 }
10869 el.wrapListeners = (code) => `_g(${code},${dir.value})`;
10870}
10871
10872/* */
10873
10874function bind$1 (el, dir) {
10875 el.wrapData = (code) => {
10876 return `_b(${code},'${el.tag}',${dir.value},${
10877 dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
10878 }${
10879 dir.modifiers && dir.modifiers.sync ? ',true' : ''
10880 })`
10881 };
10882}
10883
10884/* */
10885
10886var baseDirectives = {
10887 on,
10888 bind: bind$1,
10889 cloak: noop
10890};
10891
10892/* */
10893
10894
10895
10896
10897
10898class CodegenState {
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909 constructor (options) {
10910 this.options = options;
10911 this.warn = options.warn || baseWarn;
10912 this.transforms = pluckModuleFunction(options.modules, 'transformCode');
10913 this.dataGenFns = pluckModuleFunction(options.modules, 'genData');
10914 this.directives = extend(extend({}, baseDirectives), options.directives);
10915 const isReservedTag = options.isReservedTag || no;
10916 this.maybeComponent = (el) => !!el.component || !isReservedTag(el.tag);
10917 this.onceId = 0;
10918 this.staticRenderFns = [];
10919 this.pre = false;
10920 }
10921}
10922
10923
10924
10925function generate (
10926 ast,
10927 options
10928) {
10929 const state = new CodegenState(options);
10930 const code = ast ? genElement(ast, state) : '_c("div")';
10931 return {
10932 render: `with(this){return ${code}}`,
10933 staticRenderFns: state.staticRenderFns
10934 }
10935}
10936
10937function genElement (el, state) {
10938 if (el.parent) {
10939 el.pre = el.pre || el.parent.pre;
10940 }
10941
10942 if (el.staticRoot && !el.staticProcessed) {
10943 return genStatic(el, state)
10944 } else if (el.once && !el.onceProcessed) {
10945 return genOnce(el, state)
10946 } else if (el.for && !el.forProcessed) {
10947 return genFor(el, state)
10948 } else if (el.if && !el.ifProcessed) {
10949 return genIf(el, state)
10950 } else if (el.tag === 'template' && !el.slotTarget && !state.pre) {
10951 return genChildren(el, state) || 'void 0'
10952 } else if (el.tag === 'slot') {
10953 return genSlot(el, state)
10954 } else {
10955 // component or element
10956 let code;
10957 if (el.component) {
10958 code = genComponent(el.component, el, state);
10959 } else {
10960 let data;
10961 if (!el.plain || (el.pre && state.maybeComponent(el))) {
10962 data = genData$2(el, state);
10963 }
10964
10965 const children = el.inlineTemplate ? null : genChildren(el, state, true);
10966 code = `_c('${el.tag}'${
10967 data ? `,${data}` : '' // data
10968 }${
10969 children ? `,${children}` : '' // children
10970 })`;
10971 }
10972 // module transforms
10973 for (let i = 0; i < state.transforms.length; i++) {
10974 code = state.transforms[i](el, code);
10975 }
10976 return code
10977 }
10978}
10979
10980// hoist static sub-trees out
10981function genStatic (el, state) {
10982 el.staticProcessed = true;
10983 // Some elements (templates) need to behave differently inside of a v-pre
10984 // node. All pre nodes are static roots, so we can use this as a location to
10985 // wrap a state change and reset it upon exiting the pre node.
10986 const originalPreState = state.pre;
10987 if (el.pre) {
10988 state.pre = el.pre;
10989 }
10990 state.staticRenderFns.push(`with(this){return ${genElement(el, state)}}`);
10991 state.pre = originalPreState;
10992 return `_m(${
10993 state.staticRenderFns.length - 1
10994 }${
10995 el.staticInFor ? ',true' : ''
10996 })`
10997}
10998
10999// v-once
11000function genOnce (el, state) {
11001 el.onceProcessed = true;
11002 if (el.if && !el.ifProcessed) {
11003 return genIf(el, state)
11004 } else if (el.staticInFor) {
11005 let key = '';
11006 let parent = el.parent;
11007 while (parent) {
11008 if (parent.for) {
11009 key = parent.key;
11010 break
11011 }
11012 parent = parent.parent;
11013 }
11014 if (!key) {
11015 state.warn(
11016 `v-once can only be used inside v-for that is keyed. `,
11017 el.rawAttrsMap['v-once']
11018 );
11019 return genElement(el, state)
11020 }
11021 return `_o(${genElement(el, state)},${state.onceId++},${key})`
11022 } else {
11023 return genStatic(el, state)
11024 }
11025}
11026
11027function genIf (
11028 el,
11029 state,
11030 altGen,
11031 altEmpty
11032) {
11033 el.ifProcessed = true; // avoid recursion
11034 return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
11035}
11036
11037function genIfConditions (
11038 conditions,
11039 state,
11040 altGen,
11041 altEmpty
11042) {
11043 if (!conditions.length) {
11044 return altEmpty || '_e()'
11045 }
11046
11047 const condition = conditions.shift();
11048 if (condition.exp) {
11049 return `(${condition.exp})?${
11050 genTernaryExp(condition.block)
11051 }:${
11052 genIfConditions(conditions, state, altGen, altEmpty)
11053 }`
11054 } else {
11055 return `${genTernaryExp(condition.block)}`
11056 }
11057
11058 // v-if with v-once should generate code like (a)?_m(0):_m(1)
11059 function genTernaryExp (el) {
11060 return altGen
11061 ? altGen(el, state)
11062 : el.once
11063 ? genOnce(el, state)
11064 : genElement(el, state)
11065 }
11066}
11067
11068function genFor (
11069 el,
11070 state,
11071 altGen,
11072 altHelper
11073) {
11074 const exp = el.for;
11075 const alias = el.alias;
11076 const iterator1 = el.iterator1 ? `,${el.iterator1}` : '';
11077 const iterator2 = el.iterator2 ? `,${el.iterator2}` : '';
11078
11079 if (state.maybeComponent(el) &&
11080 el.tag !== 'slot' &&
11081 el.tag !== 'template' &&
11082 !el.key
11083 ) {
11084 state.warn(
11085 `<${el.tag} v-for="${alias} in ${exp}">: component lists rendered with ` +
11086 `v-for should have explicit keys. ` +
11087 `See https://vuejs.org/guide/list.html#key for more info.`,
11088 el.rawAttrsMap['v-for'],
11089 true /* tip */
11090 );
11091 }
11092
11093 el.forProcessed = true; // avoid recursion
11094 return `${altHelper || '_l'}((${exp}),` +
11095 `function(${alias}${iterator1}${iterator2}){` +
11096 `return ${(altGen || genElement)(el, state)}` +
11097 '})'
11098}
11099
11100function genData$2 (el, state) {
11101 let data = '{';
11102
11103 // directives first.
11104 // directives may mutate the el's other properties before they are generated.
11105 const dirs = genDirectives(el, state);
11106 if (dirs) data += dirs + ',';
11107
11108 // key
11109 if (el.key) {
11110 data += `key:${el.key},`;
11111 }
11112 // ref
11113 if (el.ref) {
11114 data += `ref:${el.ref},`;
11115 }
11116 if (el.refInFor) {
11117 data += `refInFor:true,`;
11118 }
11119 // pre
11120 if (el.pre) {
11121 data += `pre:true,`;
11122 }
11123 // record original tag name for components using "is" attribute
11124 if (el.component) {
11125 data += `tag:"${el.tag}",`;
11126 }
11127 // module data generation functions
11128 for (let i = 0; i < state.dataGenFns.length; i++) {
11129 data += state.dataGenFns[i](el);
11130 }
11131 // attributes
11132 if (el.attrs) {
11133 data += `attrs:${genProps(el.attrs)},`;
11134 }
11135 // DOM props
11136 if (el.props) {
11137 data += `domProps:${genProps(el.props)},`;
11138 }
11139 // event handlers
11140 if (el.events) {
11141 data += `${genHandlers(el.events, false)},`;
11142 }
11143 if (el.nativeEvents) {
11144 data += `${genHandlers(el.nativeEvents, true)},`;
11145 }
11146 // slot target
11147 // only for non-scoped slots
11148 if (el.slotTarget && !el.slotScope) {
11149 data += `slot:${el.slotTarget},`;
11150 }
11151 // scoped slots
11152 if (el.scopedSlots) {
11153 data += `${genScopedSlots(el, el.scopedSlots, state)},`;
11154 }
11155 // component v-model
11156 if (el.model) {
11157 data += `model:{value:${
11158 el.model.value
11159 },callback:${
11160 el.model.callback
11161 },expression:${
11162 el.model.expression
11163 }},`;
11164 }
11165 // inline-template
11166 if (el.inlineTemplate) {
11167 const inlineTemplate = genInlineTemplate(el, state);
11168 if (inlineTemplate) {
11169 data += `${inlineTemplate},`;
11170 }
11171 }
11172 data = data.replace(/,$/, '') + '}';
11173 // v-bind dynamic argument wrap
11174 // v-bind with dynamic arguments must be applied using the same v-bind object
11175 // merge helper so that class/style/mustUseProp attrs are handled correctly.
11176 if (el.dynamicAttrs) {
11177 data = `_b(${data},"${el.tag}",${genProps(el.dynamicAttrs)})`;
11178 }
11179 // v-bind data wrap
11180 if (el.wrapData) {
11181 data = el.wrapData(data);
11182 }
11183 // v-on data wrap
11184 if (el.wrapListeners) {
11185 data = el.wrapListeners(data);
11186 }
11187 return data
11188}
11189
11190function genDirectives (el, state) {
11191 const dirs = el.directives;
11192 if (!dirs) return
11193 let res = 'directives:[';
11194 let hasRuntime = false;
11195 let i, l, dir, needRuntime;
11196 for (i = 0, l = dirs.length; i < l; i++) {
11197 dir = dirs[i];
11198 needRuntime = true;
11199 const gen = state.directives[dir.name];
11200 if (gen) {
11201 // compile-time directive that manipulates AST.
11202 // returns true if it also needs a runtime counterpart.
11203 needRuntime = !!gen(el, dir, state.warn);
11204 }
11205 if (needRuntime) {
11206 hasRuntime = true;
11207 res += `{name:"${dir.name}",rawName:"${dir.rawName}"${
11208 dir.value ? `,value:(${dir.value}),expression:${JSON.stringify(dir.value)}` : ''
11209 }${
11210 dir.arg ? `,arg:${dir.isDynamicArg ? dir.arg : `"${dir.arg}"`}` : ''
11211 }${
11212 dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
11213 }},`;
11214 }
11215 }
11216 if (hasRuntime) {
11217 return res.slice(0, -1) + ']'
11218 }
11219}
11220
11221function genInlineTemplate (el, state) {
11222 const ast = el.children[0];
11223 if (el.children.length !== 1 || ast.type !== 1) {
11224 state.warn(
11225 'Inline-template components must have exactly one child element.',
11226 { start: el.start }
11227 );
11228 }
11229 if (ast && ast.type === 1) {
11230 const inlineRenderFns = generate(ast, state.options);
11231 return `inlineTemplate:{render:function(){${
11232 inlineRenderFns.render
11233 }},staticRenderFns:[${
11234 inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',')
11235 }]}`
11236 }
11237}
11238
11239function genScopedSlots (
11240 el,
11241 slots,
11242 state
11243) {
11244 // by default scoped slots are considered "stable", this allows child
11245 // components with only scoped slots to skip forced updates from parent.
11246 // but in some cases we have to bail-out of this optimization
11247 // for example if the slot contains dynamic names, has v-if or v-for on them...
11248 let needsForceUpdate = el.for || Object.keys(slots).some(key => {
11249 const slot = slots[key];
11250 return (
11251 slot.slotTargetDynamic ||
11252 slot.if ||
11253 slot.for ||
11254 containsSlotChild(slot) // is passing down slot from parent which may be dynamic
11255 )
11256 });
11257
11258 // #9534: if a component with scoped slots is inside a conditional branch,
11259 // it's possible for the same component to be reused but with different
11260 // compiled slot content. To avoid that, we generate a unique key based on
11261 // the generated code of all the slot contents.
11262 let needsKey = !!el.if;
11263
11264 // OR when it is inside another scoped slot or v-for (the reactivity may be
11265 // disconnected due to the intermediate scope variable)
11266 // #9438, #9506
11267 // TODO: this can be further optimized by properly analyzing in-scope bindings
11268 // and skip force updating ones that do not actually use scope variables.
11269 if (!needsForceUpdate) {
11270 let parent = el.parent;
11271 while (parent) {
11272 if (
11273 (parent.slotScope && parent.slotScope !== emptySlotScopeToken) ||
11274 parent.for
11275 ) {
11276 needsForceUpdate = true;
11277 break
11278 }
11279 if (parent.if) {
11280 needsKey = true;
11281 }
11282 parent = parent.parent;
11283 }
11284 }
11285
11286 const generatedSlots = Object.keys(slots)
11287 .map(key => genScopedSlot(slots[key], state))
11288 .join(',');
11289
11290 return `scopedSlots:_u([${generatedSlots}]${
11291 needsForceUpdate ? `,null,true` : ``
11292 }${
11293 !needsForceUpdate && needsKey ? `,null,false,${hash(generatedSlots)}` : ``
11294 })`
11295}
11296
11297function hash(str) {
11298 let hash = 5381;
11299 let i = str.length;
11300 while(i) {
11301 hash = (hash * 33) ^ str.charCodeAt(--i);
11302 }
11303 return hash >>> 0
11304}
11305
11306function containsSlotChild (el) {
11307 if (el.type === 1) {
11308 if (el.tag === 'slot') {
11309 return true
11310 }
11311 return el.children.some(containsSlotChild)
11312 }
11313 return false
11314}
11315
11316function genScopedSlot (
11317 el,
11318 state
11319) {
11320 const isLegacySyntax = el.attrsMap['slot-scope'];
11321 if (el.if && !el.ifProcessed && !isLegacySyntax) {
11322 return genIf(el, state, genScopedSlot, `null`)
11323 }
11324 if (el.for && !el.forProcessed) {
11325 return genFor(el, state, genScopedSlot)
11326 }
11327 const slotScope = el.slotScope === emptySlotScopeToken
11328 ? ``
11329 : String(el.slotScope);
11330 const fn = `function(${slotScope}){` +
11331 `return ${el.tag === 'template'
11332 ? el.if && isLegacySyntax
11333 ? `(${el.if})?${genChildren(el, state) || 'undefined'}:undefined`
11334 : genChildren(el, state) || 'undefined'
11335 : genElement(el, state)
11336 }}`;
11337 // reverse proxy v-slot without scope on this.$slots
11338 const reverseProxy = slotScope ? `` : `,proxy:true`;
11339 return `{key:${el.slotTarget || `"default"`},fn:${fn}${reverseProxy}}`
11340}
11341
11342function genChildren (
11343 el,
11344 state,
11345 checkSkip,
11346 altGenElement,
11347 altGenNode
11348) {
11349 const children = el.children;
11350 if (children.length) {
11351 const el = children[0];
11352 // optimize single v-for
11353 if (children.length === 1 &&
11354 el.for &&
11355 el.tag !== 'template' &&
11356 el.tag !== 'slot'
11357 ) {
11358 const normalizationType = checkSkip
11359 ? state.maybeComponent(el) ? `,1` : `,0`
11360 : ``;
11361 return `${(altGenElement || genElement)(el, state)}${normalizationType}`
11362 }
11363 const normalizationType = checkSkip
11364 ? getNormalizationType(children, state.maybeComponent)
11365 : 0;
11366 const gen = altGenNode || genNode;
11367 return `[${children.map(c => gen(c, state)).join(',')}]${
11368 normalizationType ? `,${normalizationType}` : ''
11369 }`
11370 }
11371}
11372
11373// determine the normalization needed for the children array.
11374// 0: no normalization needed
11375// 1: simple normalization needed (possible 1-level deep nested array)
11376// 2: full normalization needed
11377function getNormalizationType (
11378 children,
11379 maybeComponent
11380) {
11381 let res = 0;
11382 for (let i = 0; i < children.length; i++) {
11383 const el = children[i];
11384 if (el.type !== 1) {
11385 continue
11386 }
11387 if (needsNormalization(el) ||
11388 (el.ifConditions && el.ifConditions.some(c => needsNormalization(c.block)))) {
11389 res = 2;
11390 break
11391 }
11392 if (maybeComponent(el) ||
11393 (el.ifConditions && el.ifConditions.some(c => maybeComponent(c.block)))) {
11394 res = 1;
11395 }
11396 }
11397 return res
11398}
11399
11400function needsNormalization (el) {
11401 return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'
11402}
11403
11404function genNode (node, state) {
11405 if (node.type === 1) {
11406 return genElement(node, state)
11407 } else if (node.type === 3 && node.isComment) {
11408 return genComment(node)
11409 } else {
11410 return genText(node)
11411 }
11412}
11413
11414function genText (text) {
11415 return `_v(${text.type === 2
11416 ? text.expression // no need for () because already wrapped in _s()
11417 : transformSpecialNewlines(JSON.stringify(text.text))
11418 })`
11419}
11420
11421function genComment (comment) {
11422 return `_e(${JSON.stringify(comment.text)})`
11423}
11424
11425function genSlot (el, state) {
11426 const slotName = el.slotName || '"default"';
11427 const children = genChildren(el, state);
11428 let res = `_t(${slotName}${children ? `,${children}` : ''}`;
11429 const attrs = el.attrs || el.dynamicAttrs
11430 ? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
11431 // slot props are camelized
11432 name: camelize(attr.name),
11433 value: attr.value,
11434 dynamic: attr.dynamic
11435 })))
11436 : null;
11437 const bind$$1 = el.attrsMap['v-bind'];
11438 if ((attrs || bind$$1) && !children) {
11439 res += `,null`;
11440 }
11441 if (attrs) {
11442 res += `,${attrs}`;
11443 }
11444 if (bind$$1) {
11445 res += `${attrs ? '' : ',null'},${bind$$1}`;
11446 }
11447 return res + ')'
11448}
11449
11450// componentName is el.component, take it as argument to shun flow's pessimistic refinement
11451function genComponent (
11452 componentName,
11453 el,
11454 state
11455) {
11456 const children = el.inlineTemplate ? null : genChildren(el, state, true);
11457 return `_c(${componentName},${genData$2(el, state)}${
11458 children ? `,${children}` : ''
11459 })`
11460}
11461
11462function genProps (props) {
11463 let staticProps = ``;
11464 let dynamicProps = ``;
11465 for (let i = 0; i < props.length; i++) {
11466 const prop = props[i];
11467 const value = transformSpecialNewlines(prop.value);
11468 if (prop.dynamic) {
11469 dynamicProps += `${prop.name},${value},`;
11470 } else {
11471 staticProps += `"${prop.name}":${value},`;
11472 }
11473 }
11474 staticProps = `{${staticProps.slice(0, -1)}}`;
11475 if (dynamicProps) {
11476 return `_d(${staticProps},[${dynamicProps.slice(0, -1)}])`
11477 } else {
11478 return staticProps
11479 }
11480}
11481
11482// #3895, #4268
11483function transformSpecialNewlines (text) {
11484 return text
11485 .replace(/\u2028/g, '\\u2028')
11486 .replace(/\u2029/g, '\\u2029')
11487}
11488
11489/* */
11490
11491
11492
11493// these keywords should not appear inside expressions, but operators like
11494// typeof, instanceof and in are allowed
11495const prohibitedKeywordRE = new RegExp('\\b' + (
11496 'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
11497 'super,throw,while,yield,delete,export,import,return,switch,default,' +
11498 'extends,finally,continue,debugger,function,arguments'
11499).split(',').join('\\b|\\b') + '\\b');
11500
11501// these unary operators should not be used as property/method names
11502const unaryOperatorsRE = new RegExp('\\b' + (
11503 'delete,typeof,void'
11504).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)');
11505
11506// strip strings in expressions
11507const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
11508
11509// detect problematic expressions in a template
11510function detectErrors (ast, warn) {
11511 if (ast) {
11512 checkNode(ast, warn);
11513 }
11514}
11515
11516function checkNode (node, warn) {
11517 if (node.type === 1) {
11518 for (const name in node.attrsMap) {
11519 if (dirRE.test(name)) {
11520 const value = node.attrsMap[name];
11521 if (value) {
11522 const range = node.rawAttrsMap[name];
11523 if (name === 'v-for') {
11524 checkFor(node, `v-for="${value}"`, warn, range);
11525 } else if (onRE.test(name)) {
11526 checkEvent(value, `${name}="${value}"`, warn, range);
11527 } else {
11528 checkExpression(value, `${name}="${value}"`, warn, range);
11529 }
11530 }
11531 }
11532 }
11533 if (node.children) {
11534 for (let i = 0; i < node.children.length; i++) {
11535 checkNode(node.children[i], warn);
11536 }
11537 }
11538 } else if (node.type === 2) {
11539 checkExpression(node.expression, node.text, warn, node);
11540 }
11541}
11542
11543function checkEvent (exp, text, warn, range) {
11544 const stipped = exp.replace(stripStringRE, '');
11545 const keywordMatch = stipped.match(unaryOperatorsRE);
11546 if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {
11547 warn(
11548 `avoid using JavaScript unary operator as property name: ` +
11549 `"${keywordMatch[0]}" in expression ${text.trim()}`,
11550 range
11551 );
11552 }
11553 checkExpression(exp, text, warn, range);
11554}
11555
11556function checkFor (node, text, warn, range) {
11557 checkExpression(node.for || '', text, warn, range);
11558 checkIdentifier(node.alias, 'v-for alias', text, warn, range);
11559 checkIdentifier(node.iterator1, 'v-for iterator', text, warn, range);
11560 checkIdentifier(node.iterator2, 'v-for iterator', text, warn, range);
11561}
11562
11563function checkIdentifier (
11564 ident,
11565 type,
11566 text,
11567 warn,
11568 range
11569) {
11570 if (typeof ident === 'string') {
11571 try {
11572 new Function(`var ${ident}=_`);
11573 } catch (e) {
11574 warn(`invalid ${type} "${ident}" in expression: ${text.trim()}`, range);
11575 }
11576 }
11577}
11578
11579function checkExpression (exp, text, warn, range) {
11580 try {
11581 new Function(`return ${exp}`);
11582 } catch (e) {
11583 const keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);
11584 if (keywordMatch) {
11585 warn(
11586 `avoid using JavaScript keyword as property name: ` +
11587 `"${keywordMatch[0]}"\n Raw expression: ${text.trim()}`,
11588 range
11589 );
11590 } else {
11591 warn(
11592 `invalid expression: ${e.message} in\n\n` +
11593 ` ${exp}\n\n` +
11594 ` Raw expression: ${text.trim()}\n`,
11595 range
11596 );
11597 }
11598 }
11599}
11600
11601/* */
11602
11603const range = 2;
11604
11605function generateCodeFrame (
11606 source,
11607 start = 0,
11608 end = source.length
11609) {
11610 const lines = source.split(/\r?\n/);
11611 let count = 0;
11612 const res = [];
11613 for (let i = 0; i < lines.length; i++) {
11614 count += lines[i].length + 1;
11615 if (count >= start) {
11616 for (let j = i - range; j <= i + range || end > count; j++) {
11617 if (j < 0 || j >= lines.length) continue
11618 res.push(`${j + 1}${repeat(` `, 3 - String(j + 1).length)}| ${lines[j]}`);
11619 const lineLength = lines[j].length;
11620 if (j === i) {
11621 // push underline
11622 const pad = start - (count - lineLength) + 1;
11623 const length = end > count ? lineLength - pad : end - start;
11624 res.push(` | ` + repeat(` `, pad) + repeat(`^`, length));
11625 } else if (j > i) {
11626 if (end > count) {
11627 const length = Math.min(end - count, lineLength);
11628 res.push(` | ` + repeat(`^`, length));
11629 }
11630 count += lineLength + 1;
11631 }
11632 }
11633 break
11634 }
11635 }
11636 return res.join('\n')
11637}
11638
11639function repeat (str, n) {
11640 let result = '';
11641 if (n > 0) {
11642 while (true) { // eslint-disable-line
11643 if (n & 1) result += str;
11644 n >>>= 1;
11645 if (n <= 0) break
11646 str += str;
11647 }
11648 }
11649 return result
11650}
11651
11652/* */
11653
11654
11655
11656function createFunction (code, errors) {
11657 try {
11658 return new Function(code)
11659 } catch (err) {
11660 errors.push({ err, code });
11661 return noop
11662 }
11663}
11664
11665function createCompileToFunctionFn (compile) {
11666 const cache = Object.create(null);
11667
11668 return function compileToFunctions (
11669 template,
11670 options,
11671 vm
11672 ) {
11673 options = extend({}, options);
11674 const warn$$1 = options.warn || warn;
11675 delete options.warn;
11676
11677 /* istanbul ignore if */
11678 {
11679 // detect possible CSP restriction
11680 try {
11681 new Function('return 1');
11682 } catch (e) {
11683 if (e.toString().match(/unsafe-eval|CSP/)) {
11684 warn$$1(
11685 'It seems you are using the standalone build of Vue.js in an ' +
11686 'environment with Content Security Policy that prohibits unsafe-eval. ' +
11687 'The template compiler cannot work in this environment. Consider ' +
11688 'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
11689 'templates into render functions.'
11690 );
11691 }
11692 }
11693 }
11694
11695 // check cache
11696 const key = options.delimiters
11697 ? String(options.delimiters) + template
11698 : template;
11699 if (cache[key]) {
11700 return cache[key]
11701 }
11702
11703 // compile
11704 const compiled = compile(template, options);
11705
11706 // check compilation errors/tips
11707 {
11708 if (compiled.errors && compiled.errors.length) {
11709 if (options.outputSourceRange) {
11710 compiled.errors.forEach(e => {
11711 warn$$1(
11712 `Error compiling template:\n\n${e.msg}\n\n` +
11713 generateCodeFrame(template, e.start, e.end),
11714 vm
11715 );
11716 });
11717 } else {
11718 warn$$1(
11719 `Error compiling template:\n\n${template}\n\n` +
11720 compiled.errors.map(e => `- ${e}`).join('\n') + '\n',
11721 vm
11722 );
11723 }
11724 }
11725 if (compiled.tips && compiled.tips.length) {
11726 if (options.outputSourceRange) {
11727 compiled.tips.forEach(e => tip(e.msg, vm));
11728 } else {
11729 compiled.tips.forEach(msg => tip(msg, vm));
11730 }
11731 }
11732 }
11733
11734 // turn code into functions
11735 const res = {};
11736 const fnGenErrors = [];
11737 res.render = createFunction(compiled.render, fnGenErrors);
11738 res.staticRenderFns = compiled.staticRenderFns.map(code => {
11739 return createFunction(code, fnGenErrors)
11740 });
11741
11742 // check function generation errors.
11743 // this should only happen if there is a bug in the compiler itself.
11744 // mostly for codegen development use
11745 /* istanbul ignore if */
11746 {
11747 if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {
11748 warn$$1(
11749 `Failed to generate render function:\n\n` +
11750 fnGenErrors.map(({ err, code }) => `${err.toString()} in\n\n${code}\n`).join('\n'),
11751 vm
11752 );
11753 }
11754 }
11755
11756 return (cache[key] = res)
11757 }
11758}
11759
11760/* */
11761
11762function createCompilerCreator (baseCompile) {
11763 return function createCompiler (baseOptions) {
11764 function compile (
11765 template,
11766 options
11767 ) {
11768 const finalOptions = Object.create(baseOptions);
11769 const errors = [];
11770 const tips = [];
11771
11772 let warn = (msg, range, tip) => {
11773 (tip ? tips : errors).push(msg);
11774 };
11775
11776 if (options) {
11777 if (options.outputSourceRange) {
11778 // $flow-disable-line
11779 const leadingSpaceLength = template.match(/^\s*/)[0].length;
11780
11781 warn = (msg, range, tip) => {
11782 const data = { msg };
11783 if (range) {
11784 if (range.start != null) {
11785 data.start = range.start + leadingSpaceLength;
11786 }
11787 if (range.end != null) {
11788 data.end = range.end + leadingSpaceLength;
11789 }
11790 }
11791 (tip ? tips : errors).push(data);
11792 };
11793 }
11794 // merge custom modules
11795 if (options.modules) {
11796 finalOptions.modules =
11797 (baseOptions.modules || []).concat(options.modules);
11798 }
11799 // merge custom directives
11800 if (options.directives) {
11801 finalOptions.directives = extend(
11802 Object.create(baseOptions.directives || null),
11803 options.directives
11804 );
11805 }
11806 // copy other options
11807 for (const key in options) {
11808 if (key !== 'modules' && key !== 'directives') {
11809 finalOptions[key] = options[key];
11810 }
11811 }
11812 }
11813
11814 finalOptions.warn = warn;
11815
11816 const compiled = baseCompile(template.trim(), finalOptions);
11817 {
11818 detectErrors(compiled.ast, warn);
11819 }
11820 compiled.errors = errors;
11821 compiled.tips = tips;
11822 return compiled
11823 }
11824
11825 return {
11826 compile,
11827 compileToFunctions: createCompileToFunctionFn(compile)
11828 }
11829 }
11830}
11831
11832/* */
11833
11834// `createCompilerCreator` allows creating compilers that use alternative
11835// parser/optimizer/codegen, e.g the SSR optimizing compiler.
11836// Here we just export a default compiler using the default parts.
11837const createCompiler = createCompilerCreator(function baseCompile (
11838 template,
11839 options
11840) {
11841 const ast = parse(template.trim(), options);
11842 if (options.optimize !== false) {
11843 optimize(ast, options);
11844 }
11845 const code = generate(ast, options);
11846 return {
11847 ast,
11848 render: code.render,
11849 staticRenderFns: code.staticRenderFns
11850 }
11851});
11852
11853/* */
11854
11855const { compile, compileToFunctions } = createCompiler(baseOptions);
11856
11857/* */
11858
11859// check whether current browser encodes a char inside attribute values
11860let div;
11861function getShouldDecode (href) {
11862 div = div || document.createElement('div');
11863 div.innerHTML = href ? `<a href="\n"/>` : `<div a="\n"/>`;
11864 return div.innerHTML.indexOf('&#10;') > 0
11865}
11866
11867// #3663: IE encodes newlines inside attribute values while other browsers don't
11868const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false;
11869// #6828: chrome encodes content in a[href]
11870const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false;
11871
11872/* */
11873
11874const idToTemplate = cached(id => {
11875 const el = query(id);
11876 return el && el.innerHTML
11877});
11878
11879const mount = Vue.prototype.$mount;
11880Vue.prototype.$mount = function (
11881 el,
11882 hydrating
11883) {
11884 el = el && query(el);
11885
11886 /* istanbul ignore if */
11887 if (el === document.body || el === document.documentElement) {
11888 warn(
11889 `Do not mount Vue to <html> or <body> - mount to normal elements instead.`
11890 );
11891 return this
11892 }
11893
11894 const options = this.$options;
11895 // resolve template/el and convert to render function
11896 if (!options.render) {
11897 let template = options.template;
11898 if (template) {
11899 if (typeof template === 'string') {
11900 if (template.charAt(0) === '#') {
11901 template = idToTemplate(template);
11902 /* istanbul ignore if */
11903 if (!template) {
11904 warn(
11905 `Template element not found or is empty: ${options.template}`,
11906 this
11907 );
11908 }
11909 }
11910 } else if (template.nodeType) {
11911 template = template.innerHTML;
11912 } else {
11913 {
11914 warn('invalid template option:' + template, this);
11915 }
11916 return this
11917 }
11918 } else if (el) {
11919 template = getOuterHTML(el);
11920 }
11921 if (template) {
11922 /* istanbul ignore if */
11923 if (config.performance && mark) {
11924 mark('compile');
11925 }
11926
11927 const { render, staticRenderFns } = compileToFunctions(template, {
11928 outputSourceRange: "development" !== 'production',
11929 shouldDecodeNewlines,
11930 shouldDecodeNewlinesForHref,
11931 delimiters: options.delimiters,
11932 comments: options.comments
11933 }, this);
11934 options.render = render;
11935 options.staticRenderFns = staticRenderFns;
11936
11937 /* istanbul ignore if */
11938 if (config.performance && mark) {
11939 mark('compile end');
11940 measure(`vue ${this._name} compile`, 'compile', 'compile end');
11941 }
11942 }
11943 }
11944 return mount.call(this, el, hydrating)
11945};
11946
11947/**
11948 * Get outerHTML of elements, taking care
11949 * of SVG elements in IE as well.
11950 */
11951function getOuterHTML (el) {
11952 if (el.outerHTML) {
11953 return el.outerHTML
11954 } else {
11955 const container = document.createElement('div');
11956 container.appendChild(el.cloneNode(true));
11957 return container.innerHTML
11958 }
11959}
11960
11961Vue.compile = compileToFunctions;
11962
11963export default Vue;