UNPKG

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