UNPKG

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