UNPKG

641 kBJavaScriptView Raw
1var Vue = (function (exports) {
2 'use strict';
3
4 /**
5 * Make a map and return a function for checking if a key
6 * is in that map.
7 * IMPORTANT: all calls of this function must be prefixed with
8 * \/\*#\_\_PURE\_\_\*\/
9 * So that rollup can tree-shake them if necessary.
10 */
11 function makeMap(str, expectsLowerCase) {
12 const map = Object.create(null);
13 const list = str.split(',');
14 for (let i = 0; i < list.length; i++) {
15 map[list[i]] = true;
16 }
17 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
18 }
19
20 /**
21 * dev only flag -> name mapping
22 */
23 const PatchFlagNames = {
24 [1 /* TEXT */]: `TEXT`,
25 [2 /* CLASS */]: `CLASS`,
26 [4 /* STYLE */]: `STYLE`,
27 [8 /* PROPS */]: `PROPS`,
28 [16 /* FULL_PROPS */]: `FULL_PROPS`,
29 [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
30 [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
31 [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
32 [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
33 [512 /* NEED_PATCH */]: `NEED_PATCH`,
34 [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
35 [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
36 [-1 /* HOISTED */]: `HOISTED`,
37 [-2 /* BAIL */]: `BAIL`
38 };
39
40 /**
41 * Dev only
42 */
43 const slotFlagsText = {
44 [1 /* STABLE */]: 'STABLE',
45 [2 /* DYNAMIC */]: 'DYNAMIC',
46 [3 /* FORWARDED */]: 'FORWARDED'
47 };
48
49 const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
50 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
51 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
52 const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
53
54 const range = 2;
55 function generateCodeFrame(source, start = 0, end = source.length) {
56 // Split the content into individual lines but capture the newline sequence
57 // that separated each line. This is important because the actual sequence is
58 // needed to properly take into account the full line length for offset
59 // comparison
60 let lines = source.split(/(\r?\n)/);
61 // Separate the lines and newline sequences into separate arrays for easier referencing
62 const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
63 lines = lines.filter((_, idx) => idx % 2 === 0);
64 let count = 0;
65 const res = [];
66 for (let i = 0; i < lines.length; i++) {
67 count +=
68 lines[i].length +
69 ((newlineSequences[i] && newlineSequences[i].length) || 0);
70 if (count >= start) {
71 for (let j = i - range; j <= i + range || end > count; j++) {
72 if (j < 0 || j >= lines.length)
73 continue;
74 const line = j + 1;
75 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
76 const lineLength = lines[j].length;
77 const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
78 if (j === i) {
79 // push underline
80 const pad = start - (count - (lineLength + newLineSeqLength));
81 const length = Math.max(1, end > count ? lineLength - pad : end - start);
82 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
83 }
84 else if (j > i) {
85 if (end > count) {
86 const length = Math.max(Math.min(end - count, lineLength), 1);
87 res.push(` | ` + '^'.repeat(length));
88 }
89 count += lineLength + newLineSeqLength;
90 }
91 }
92 break;
93 }
94 }
95 return res.join('\n');
96 }
97
98 /**
99 * On the client we only need to offer special cases for boolean attributes that
100 * have different names from their corresponding dom properties:
101 * - itemscope -> N/A
102 * - allowfullscreen -> allowFullscreen
103 * - formnovalidate -> formNoValidate
104 * - ismap -> isMap
105 * - nomodule -> noModule
106 * - novalidate -> noValidate
107 * - readonly -> readOnly
108 */
109 const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
110 const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
111 /**
112 * Boolean attributes should be included if the value is truthy or ''.
113 * e.g. `<select multiple>` compiles to `{ multiple: '' }`
114 */
115 function includeBooleanAttr(value) {
116 return !!value || value === '';
117 }
118
119 function normalizeStyle(value) {
120 if (isArray(value)) {
121 const res = {};
122 for (let i = 0; i < value.length; i++) {
123 const item = value[i];
124 const normalized = isString(item)
125 ? parseStringStyle(item)
126 : normalizeStyle(item);
127 if (normalized) {
128 for (const key in normalized) {
129 res[key] = normalized[key];
130 }
131 }
132 }
133 return res;
134 }
135 else if (isString(value)) {
136 return value;
137 }
138 else if (isObject(value)) {
139 return value;
140 }
141 }
142 const listDelimiterRE = /;(?![^(]*\))/g;
143 const propertyDelimiterRE = /:(.+)/;
144 function parseStringStyle(cssText) {
145 const ret = {};
146 cssText.split(listDelimiterRE).forEach(item => {
147 if (item) {
148 const tmp = item.split(propertyDelimiterRE);
149 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
150 }
151 });
152 return ret;
153 }
154 function normalizeClass(value) {
155 let res = '';
156 if (isString(value)) {
157 res = value;
158 }
159 else if (isArray(value)) {
160 for (let i = 0; i < value.length; i++) {
161 const normalized = normalizeClass(value[i]);
162 if (normalized) {
163 res += normalized + ' ';
164 }
165 }
166 }
167 else if (isObject(value)) {
168 for (const name in value) {
169 if (value[name]) {
170 res += name + ' ';
171 }
172 }
173 }
174 return res.trim();
175 }
176 function normalizeProps(props) {
177 if (!props)
178 return null;
179 let { class: klass, style } = props;
180 if (klass && !isString(klass)) {
181 props.class = normalizeClass(klass);
182 }
183 if (style) {
184 props.style = normalizeStyle(style);
185 }
186 return props;
187 }
188
189 // These tag configs are shared between compiler-dom and runtime-dom, so they
190 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
191 const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
192 'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
193 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
194 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
195 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
196 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
197 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
198 'option,output,progress,select,textarea,details,dialog,menu,' +
199 'summary,template,blockquote,iframe,tfoot';
200 // https://developer.mozilla.org/en-US/docs/Web/SVG/Element
201 const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
202 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
203 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
204 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
205 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
206 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
207 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
208 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
209 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
210 'text,textPath,title,tspan,unknown,use,view';
211 const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
212 /**
213 * Compiler only.
214 * Do NOT use in runtime code paths unless behind `true` flag.
215 */
216 const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
217 /**
218 * Compiler only.
219 * Do NOT use in runtime code paths unless behind `true` flag.
220 */
221 const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
222 /**
223 * Compiler only.
224 * Do NOT use in runtime code paths unless behind `true` flag.
225 */
226 const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
227
228 function looseCompareArrays(a, b) {
229 if (a.length !== b.length)
230 return false;
231 let equal = true;
232 for (let i = 0; equal && i < a.length; i++) {
233 equal = looseEqual(a[i], b[i]);
234 }
235 return equal;
236 }
237 function looseEqual(a, b) {
238 if (a === b)
239 return true;
240 let aValidType = isDate(a);
241 let bValidType = isDate(b);
242 if (aValidType || bValidType) {
243 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
244 }
245 aValidType = isSymbol(a);
246 bValidType = isSymbol(b);
247 if (aValidType || bValidType) {
248 return a === b;
249 }
250 aValidType = isArray(a);
251 bValidType = isArray(b);
252 if (aValidType || bValidType) {
253 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
254 }
255 aValidType = isObject(a);
256 bValidType = isObject(b);
257 if (aValidType || bValidType) {
258 /* istanbul ignore if: this if will probably never be called */
259 if (!aValidType || !bValidType) {
260 return false;
261 }
262 const aKeysCount = Object.keys(a).length;
263 const bKeysCount = Object.keys(b).length;
264 if (aKeysCount !== bKeysCount) {
265 return false;
266 }
267 for (const key in a) {
268 const aHasKey = a.hasOwnProperty(key);
269 const bHasKey = b.hasOwnProperty(key);
270 if ((aHasKey && !bHasKey) ||
271 (!aHasKey && bHasKey) ||
272 !looseEqual(a[key], b[key])) {
273 return false;
274 }
275 }
276 }
277 return String(a) === String(b);
278 }
279 function looseIndexOf(arr, val) {
280 return arr.findIndex(item => looseEqual(item, val));
281 }
282
283 /**
284 * For converting {{ interpolation }} values to displayed strings.
285 * @private
286 */
287 const toDisplayString = (val) => {
288 return isString(val)
289 ? val
290 : val == null
291 ? ''
292 : isArray(val) ||
293 (isObject(val) &&
294 (val.toString === objectToString || !isFunction(val.toString)))
295 ? JSON.stringify(val, replacer, 2)
296 : String(val);
297 };
298 const replacer = (_key, val) => {
299 // can't use isRef here since @vue/shared has no deps
300 if (val && val.__v_isRef) {
301 return replacer(_key, val.value);
302 }
303 else if (isMap(val)) {
304 return {
305 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
306 entries[`${key} =>`] = val;
307 return entries;
308 }, {})
309 };
310 }
311 else if (isSet(val)) {
312 return {
313 [`Set(${val.size})`]: [...val.values()]
314 };
315 }
316 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
317 return String(val);
318 }
319 return val;
320 };
321
322 const EMPTY_OBJ = Object.freeze({})
323 ;
324 const EMPTY_ARR = Object.freeze([]) ;
325 const NOOP = () => { };
326 /**
327 * Always return false.
328 */
329 const NO = () => false;
330 const onRE = /^on[^a-z]/;
331 const isOn = (key) => onRE.test(key);
332 const isModelListener = (key) => key.startsWith('onUpdate:');
333 const extend = Object.assign;
334 const remove = (arr, el) => {
335 const i = arr.indexOf(el);
336 if (i > -1) {
337 arr.splice(i, 1);
338 }
339 };
340 const hasOwnProperty = Object.prototype.hasOwnProperty;
341 const hasOwn = (val, key) => hasOwnProperty.call(val, key);
342 const isArray = Array.isArray;
343 const isMap = (val) => toTypeString(val) === '[object Map]';
344 const isSet = (val) => toTypeString(val) === '[object Set]';
345 const isDate = (val) => toTypeString(val) === '[object Date]';
346 const isFunction = (val) => typeof val === 'function';
347 const isString = (val) => typeof val === 'string';
348 const isSymbol = (val) => typeof val === 'symbol';
349 const isObject = (val) => val !== null && typeof val === 'object';
350 const isPromise = (val) => {
351 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
352 };
353 const objectToString = Object.prototype.toString;
354 const toTypeString = (value) => objectToString.call(value);
355 const toRawType = (value) => {
356 // extract "RawType" from strings like "[object RawType]"
357 return toTypeString(value).slice(8, -1);
358 };
359 const isPlainObject = (val) => toTypeString(val) === '[object Object]';
360 const isIntegerKey = (key) => isString(key) &&
361 key !== 'NaN' &&
362 key[0] !== '-' &&
363 '' + parseInt(key, 10) === key;
364 const isReservedProp = /*#__PURE__*/ makeMap(
365 // the leading comma is intentional so empty string "" is also included
366 ',key,ref,ref_for,ref_key,' +
367 'onVnodeBeforeMount,onVnodeMounted,' +
368 'onVnodeBeforeUpdate,onVnodeUpdated,' +
369 'onVnodeBeforeUnmount,onVnodeUnmounted');
370 const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
371 const cacheStringFunction = (fn) => {
372 const cache = Object.create(null);
373 return ((str) => {
374 const hit = cache[str];
375 return hit || (cache[str] = fn(str));
376 });
377 };
378 const camelizeRE = /-(\w)/g;
379 /**
380 * @private
381 */
382 const camelize = cacheStringFunction((str) => {
383 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
384 });
385 const hyphenateRE = /\B([A-Z])/g;
386 /**
387 * @private
388 */
389 const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
390 /**
391 * @private
392 */
393 const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
394 /**
395 * @private
396 */
397 const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
398 // compare whether a value has changed, accounting for NaN.
399 const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
400 const invokeArrayFns = (fns, arg) => {
401 for (let i = 0; i < fns.length; i++) {
402 fns[i](arg);
403 }
404 };
405 const def = (obj, key, value) => {
406 Object.defineProperty(obj, key, {
407 configurable: true,
408 enumerable: false,
409 value
410 });
411 };
412 const toNumber = (val) => {
413 const n = parseFloat(val);
414 return isNaN(n) ? val : n;
415 };
416 let _globalThis;
417 const getGlobalThis = () => {
418 return (_globalThis ||
419 (_globalThis =
420 typeof globalThis !== 'undefined'
421 ? globalThis
422 : typeof self !== 'undefined'
423 ? self
424 : typeof window !== 'undefined'
425 ? window
426 : typeof global !== 'undefined'
427 ? global
428 : {}));
429 };
430
431 function warn(msg, ...args) {
432 console.warn(`[Vue warn] ${msg}`, ...args);
433 }
434
435 let activeEffectScope;
436 class EffectScope {
437 constructor(detached = false) {
438 /**
439 * @internal
440 */
441 this.active = true;
442 /**
443 * @internal
444 */
445 this.effects = [];
446 /**
447 * @internal
448 */
449 this.cleanups = [];
450 if (!detached && activeEffectScope) {
451 this.parent = activeEffectScope;
452 this.index =
453 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
454 }
455 }
456 run(fn) {
457 if (this.active) {
458 const currentEffectScope = activeEffectScope;
459 try {
460 activeEffectScope = this;
461 return fn();
462 }
463 finally {
464 activeEffectScope = currentEffectScope;
465 }
466 }
467 else {
468 warn(`cannot run an inactive effect scope.`);
469 }
470 }
471 /**
472 * This should only be called on non-detached scopes
473 * @internal
474 */
475 on() {
476 activeEffectScope = this;
477 }
478 /**
479 * This should only be called on non-detached scopes
480 * @internal
481 */
482 off() {
483 activeEffectScope = this.parent;
484 }
485 stop(fromParent) {
486 if (this.active) {
487 let i, l;
488 for (i = 0, l = this.effects.length; i < l; i++) {
489 this.effects[i].stop();
490 }
491 for (i = 0, l = this.cleanups.length; i < l; i++) {
492 this.cleanups[i]();
493 }
494 if (this.scopes) {
495 for (i = 0, l = this.scopes.length; i < l; i++) {
496 this.scopes[i].stop(true);
497 }
498 }
499 // nested scope, dereference from parent to avoid memory leaks
500 if (this.parent && !fromParent) {
501 // optimized O(1) removal
502 const last = this.parent.scopes.pop();
503 if (last && last !== this) {
504 this.parent.scopes[this.index] = last;
505 last.index = this.index;
506 }
507 }
508 this.active = false;
509 }
510 }
511 }
512 function effectScope(detached) {
513 return new EffectScope(detached);
514 }
515 function recordEffectScope(effect, scope = activeEffectScope) {
516 if (scope && scope.active) {
517 scope.effects.push(effect);
518 }
519 }
520 function getCurrentScope() {
521 return activeEffectScope;
522 }
523 function onScopeDispose(fn) {
524 if (activeEffectScope) {
525 activeEffectScope.cleanups.push(fn);
526 }
527 else {
528 warn(`onScopeDispose() is called when there is no active effect scope` +
529 ` to be associated with.`);
530 }
531 }
532
533 const createDep = (effects) => {
534 const dep = new Set(effects);
535 dep.w = 0;
536 dep.n = 0;
537 return dep;
538 };
539 const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
540 const newTracked = (dep) => (dep.n & trackOpBit) > 0;
541 const initDepMarkers = ({ deps }) => {
542 if (deps.length) {
543 for (let i = 0; i < deps.length; i++) {
544 deps[i].w |= trackOpBit; // set was tracked
545 }
546 }
547 };
548 const finalizeDepMarkers = (effect) => {
549 const { deps } = effect;
550 if (deps.length) {
551 let ptr = 0;
552 for (let i = 0; i < deps.length; i++) {
553 const dep = deps[i];
554 if (wasTracked(dep) && !newTracked(dep)) {
555 dep.delete(effect);
556 }
557 else {
558 deps[ptr++] = dep;
559 }
560 // clear bits
561 dep.w &= ~trackOpBit;
562 dep.n &= ~trackOpBit;
563 }
564 deps.length = ptr;
565 }
566 };
567
568 const targetMap = new WeakMap();
569 // The number of effects currently being tracked recursively.
570 let effectTrackDepth = 0;
571 let trackOpBit = 1;
572 /**
573 * The bitwise track markers support at most 30 levels of recursion.
574 * This value is chosen to enable modern JS engines to use a SMI on all platforms.
575 * When recursion depth is greater, fall back to using a full cleanup.
576 */
577 const maxMarkerBits = 30;
578 let activeEffect;
579 const ITERATE_KEY = Symbol('iterate' );
580 const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
581 class ReactiveEffect {
582 constructor(fn, scheduler = null, scope) {
583 this.fn = fn;
584 this.scheduler = scheduler;
585 this.active = true;
586 this.deps = [];
587 this.parent = undefined;
588 recordEffectScope(this, scope);
589 }
590 run() {
591 if (!this.active) {
592 return this.fn();
593 }
594 let parent = activeEffect;
595 let lastShouldTrack = shouldTrack;
596 while (parent) {
597 if (parent === this) {
598 return;
599 }
600 parent = parent.parent;
601 }
602 try {
603 this.parent = activeEffect;
604 activeEffect = this;
605 shouldTrack = true;
606 trackOpBit = 1 << ++effectTrackDepth;
607 if (effectTrackDepth <= maxMarkerBits) {
608 initDepMarkers(this);
609 }
610 else {
611 cleanupEffect(this);
612 }
613 return this.fn();
614 }
615 finally {
616 if (effectTrackDepth <= maxMarkerBits) {
617 finalizeDepMarkers(this);
618 }
619 trackOpBit = 1 << --effectTrackDepth;
620 activeEffect = this.parent;
621 shouldTrack = lastShouldTrack;
622 this.parent = undefined;
623 if (this.deferStop) {
624 this.stop();
625 }
626 }
627 }
628 stop() {
629 // stopped while running itself - defer the cleanup
630 if (activeEffect === this) {
631 this.deferStop = true;
632 }
633 else if (this.active) {
634 cleanupEffect(this);
635 if (this.onStop) {
636 this.onStop();
637 }
638 this.active = false;
639 }
640 }
641 }
642 function cleanupEffect(effect) {
643 const { deps } = effect;
644 if (deps.length) {
645 for (let i = 0; i < deps.length; i++) {
646 deps[i].delete(effect);
647 }
648 deps.length = 0;
649 }
650 }
651 function effect(fn, options) {
652 if (fn.effect) {
653 fn = fn.effect.fn;
654 }
655 const _effect = new ReactiveEffect(fn);
656 if (options) {
657 extend(_effect, options);
658 if (options.scope)
659 recordEffectScope(_effect, options.scope);
660 }
661 if (!options || !options.lazy) {
662 _effect.run();
663 }
664 const runner = _effect.run.bind(_effect);
665 runner.effect = _effect;
666 return runner;
667 }
668 function stop(runner) {
669 runner.effect.stop();
670 }
671 let shouldTrack = true;
672 const trackStack = [];
673 function pauseTracking() {
674 trackStack.push(shouldTrack);
675 shouldTrack = false;
676 }
677 function resetTracking() {
678 const last = trackStack.pop();
679 shouldTrack = last === undefined ? true : last;
680 }
681 function track(target, type, key) {
682 if (shouldTrack && activeEffect) {
683 let depsMap = targetMap.get(target);
684 if (!depsMap) {
685 targetMap.set(target, (depsMap = new Map()));
686 }
687 let dep = depsMap.get(key);
688 if (!dep) {
689 depsMap.set(key, (dep = createDep()));
690 }
691 const eventInfo = { effect: activeEffect, target, type, key }
692 ;
693 trackEffects(dep, eventInfo);
694 }
695 }
696 function trackEffects(dep, debuggerEventExtraInfo) {
697 let shouldTrack = false;
698 if (effectTrackDepth <= maxMarkerBits) {
699 if (!newTracked(dep)) {
700 dep.n |= trackOpBit; // set newly tracked
701 shouldTrack = !wasTracked(dep);
702 }
703 }
704 else {
705 // Full cleanup mode.
706 shouldTrack = !dep.has(activeEffect);
707 }
708 if (shouldTrack) {
709 dep.add(activeEffect);
710 activeEffect.deps.push(dep);
711 if (activeEffect.onTrack) {
712 activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo));
713 }
714 }
715 }
716 function trigger(target, type, key, newValue, oldValue, oldTarget) {
717 const depsMap = targetMap.get(target);
718 if (!depsMap) {
719 // never been tracked
720 return;
721 }
722 let deps = [];
723 if (type === "clear" /* CLEAR */) {
724 // collection being cleared
725 // trigger all effects for target
726 deps = [...depsMap.values()];
727 }
728 else if (key === 'length' && isArray(target)) {
729 depsMap.forEach((dep, key) => {
730 if (key === 'length' || key >= newValue) {
731 deps.push(dep);
732 }
733 });
734 }
735 else {
736 // schedule runs for SET | ADD | DELETE
737 if (key !== void 0) {
738 deps.push(depsMap.get(key));
739 }
740 // also run for iteration key on ADD | DELETE | Map.SET
741 switch (type) {
742 case "add" /* ADD */:
743 if (!isArray(target)) {
744 deps.push(depsMap.get(ITERATE_KEY));
745 if (isMap(target)) {
746 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
747 }
748 }
749 else if (isIntegerKey(key)) {
750 // new index added to array -> length changes
751 deps.push(depsMap.get('length'));
752 }
753 break;
754 case "delete" /* DELETE */:
755 if (!isArray(target)) {
756 deps.push(depsMap.get(ITERATE_KEY));
757 if (isMap(target)) {
758 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
759 }
760 }
761 break;
762 case "set" /* SET */:
763 if (isMap(target)) {
764 deps.push(depsMap.get(ITERATE_KEY));
765 }
766 break;
767 }
768 }
769 const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
770 ;
771 if (deps.length === 1) {
772 if (deps[0]) {
773 {
774 triggerEffects(deps[0], eventInfo);
775 }
776 }
777 }
778 else {
779 const effects = [];
780 for (const dep of deps) {
781 if (dep) {
782 effects.push(...dep);
783 }
784 }
785 {
786 triggerEffects(createDep(effects), eventInfo);
787 }
788 }
789 }
790 function triggerEffects(dep, debuggerEventExtraInfo) {
791 // spread into array for stabilization
792 const effects = isArray(dep) ? dep : [...dep];
793 for (const effect of effects) {
794 if (effect.computed) {
795 triggerEffect(effect, debuggerEventExtraInfo);
796 }
797 }
798 for (const effect of effects) {
799 if (!effect.computed) {
800 triggerEffect(effect, debuggerEventExtraInfo);
801 }
802 }
803 }
804 function triggerEffect(effect, debuggerEventExtraInfo) {
805 if (effect !== activeEffect || effect.allowRecurse) {
806 if (effect.onTrigger) {
807 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
808 }
809 if (effect.scheduler) {
810 effect.scheduler();
811 }
812 else {
813 effect.run();
814 }
815 }
816 }
817
818 const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
819 const builtInSymbols = new Set(
820 /*#__PURE__*/
821 Object.getOwnPropertyNames(Symbol)
822 // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
823 // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
824 // function
825 .filter(key => key !== 'arguments' && key !== 'caller')
826 .map(key => Symbol[key])
827 .filter(isSymbol));
828 const get = /*#__PURE__*/ createGetter();
829 const shallowGet = /*#__PURE__*/ createGetter(false, true);
830 const readonlyGet = /*#__PURE__*/ createGetter(true);
831 const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
832 const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
833 function createArrayInstrumentations() {
834 const instrumentations = {};
835 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
836 instrumentations[key] = function (...args) {
837 const arr = toRaw(this);
838 for (let i = 0, l = this.length; i < l; i++) {
839 track(arr, "get" /* GET */, i + '');
840 }
841 // we run the method using the original args first (which may be reactive)
842 const res = arr[key](...args);
843 if (res === -1 || res === false) {
844 // if that didn't work, run it again using raw values.
845 return arr[key](...args.map(toRaw));
846 }
847 else {
848 return res;
849 }
850 };
851 });
852 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
853 instrumentations[key] = function (...args) {
854 pauseTracking();
855 const res = toRaw(this)[key].apply(this, args);
856 resetTracking();
857 return res;
858 };
859 });
860 return instrumentations;
861 }
862 function createGetter(isReadonly = false, shallow = false) {
863 return function get(target, key, receiver) {
864 if (key === "__v_isReactive" /* IS_REACTIVE */) {
865 return !isReadonly;
866 }
867 else if (key === "__v_isReadonly" /* IS_READONLY */) {
868 return isReadonly;
869 }
870 else if (key === "__v_isShallow" /* IS_SHALLOW */) {
871 return shallow;
872 }
873 else if (key === "__v_raw" /* RAW */ &&
874 receiver ===
875 (isReadonly
876 ? shallow
877 ? shallowReadonlyMap
878 : readonlyMap
879 : shallow
880 ? shallowReactiveMap
881 : reactiveMap).get(target)) {
882 return target;
883 }
884 const targetIsArray = isArray(target);
885 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
886 return Reflect.get(arrayInstrumentations, key, receiver);
887 }
888 const res = Reflect.get(target, key, receiver);
889 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
890 return res;
891 }
892 if (!isReadonly) {
893 track(target, "get" /* GET */, key);
894 }
895 if (shallow) {
896 return res;
897 }
898 if (isRef(res)) {
899 // ref unwrapping - skip unwrap for Array + integer key.
900 return targetIsArray && isIntegerKey(key) ? res : res.value;
901 }
902 if (isObject(res)) {
903 // Convert returned value into a proxy as well. we do the isObject check
904 // here to avoid invalid value warning. Also need to lazy access readonly
905 // and reactive here to avoid circular dependency.
906 return isReadonly ? readonly(res) : reactive(res);
907 }
908 return res;
909 };
910 }
911 const set = /*#__PURE__*/ createSetter();
912 const shallowSet = /*#__PURE__*/ createSetter(true);
913 function createSetter(shallow = false) {
914 return function set(target, key, value, receiver) {
915 let oldValue = target[key];
916 if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
917 return false;
918 }
919 if (!shallow && !isReadonly(value)) {
920 if (!isShallow(value)) {
921 value = toRaw(value);
922 oldValue = toRaw(oldValue);
923 }
924 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
925 oldValue.value = value;
926 return true;
927 }
928 }
929 const hadKey = isArray(target) && isIntegerKey(key)
930 ? Number(key) < target.length
931 : hasOwn(target, key);
932 const result = Reflect.set(target, key, value, receiver);
933 // don't trigger if target is something up in the prototype chain of original
934 if (target === toRaw(receiver)) {
935 if (!hadKey) {
936 trigger(target, "add" /* ADD */, key, value);
937 }
938 else if (hasChanged(value, oldValue)) {
939 trigger(target, "set" /* SET */, key, value, oldValue);
940 }
941 }
942 return result;
943 };
944 }
945 function deleteProperty(target, key) {
946 const hadKey = hasOwn(target, key);
947 const oldValue = target[key];
948 const result = Reflect.deleteProperty(target, key);
949 if (result && hadKey) {
950 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
951 }
952 return result;
953 }
954 function has(target, key) {
955 const result = Reflect.has(target, key);
956 if (!isSymbol(key) || !builtInSymbols.has(key)) {
957 track(target, "has" /* HAS */, key);
958 }
959 return result;
960 }
961 function ownKeys(target) {
962 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
963 return Reflect.ownKeys(target);
964 }
965 const mutableHandlers = {
966 get,
967 set,
968 deleteProperty,
969 has,
970 ownKeys
971 };
972 const readonlyHandlers = {
973 get: readonlyGet,
974 set(target, key) {
975 {
976 warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
977 }
978 return true;
979 },
980 deleteProperty(target, key) {
981 {
982 warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
983 }
984 return true;
985 }
986 };
987 const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
988 get: shallowGet,
989 set: shallowSet
990 });
991 // Props handlers are special in the sense that it should not unwrap top-level
992 // refs (in order to allow refs to be explicitly passed down), but should
993 // retain the reactivity of the normal readonly object.
994 const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
995 get: shallowReadonlyGet
996 });
997
998 const toShallow = (value) => value;
999 const getProto = (v) => Reflect.getPrototypeOf(v);
1000 function get$1(target, key, isReadonly = false, isShallow = false) {
1001 // #1772: readonly(reactive(Map)) should return readonly + reactive version
1002 // of the value
1003 target = target["__v_raw" /* RAW */];
1004 const rawTarget = toRaw(target);
1005 const rawKey = toRaw(key);
1006 if (!isReadonly) {
1007 if (key !== rawKey) {
1008 track(rawTarget, "get" /* GET */, key);
1009 }
1010 track(rawTarget, "get" /* GET */, rawKey);
1011 }
1012 const { has } = getProto(rawTarget);
1013 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1014 if (has.call(rawTarget, key)) {
1015 return wrap(target.get(key));
1016 }
1017 else if (has.call(rawTarget, rawKey)) {
1018 return wrap(target.get(rawKey));
1019 }
1020 else if (target !== rawTarget) {
1021 // #3602 readonly(reactive(Map))
1022 // ensure that the nested reactive `Map` can do tracking for itself
1023 target.get(key);
1024 }
1025 }
1026 function has$1(key, isReadonly = false) {
1027 const target = this["__v_raw" /* RAW */];
1028 const rawTarget = toRaw(target);
1029 const rawKey = toRaw(key);
1030 if (!isReadonly) {
1031 if (key !== rawKey) {
1032 track(rawTarget, "has" /* HAS */, key);
1033 }
1034 track(rawTarget, "has" /* HAS */, rawKey);
1035 }
1036 return key === rawKey
1037 ? target.has(key)
1038 : target.has(key) || target.has(rawKey);
1039 }
1040 function size(target, isReadonly = false) {
1041 target = target["__v_raw" /* RAW */];
1042 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
1043 return Reflect.get(target, 'size', target);
1044 }
1045 function add(value) {
1046 value = toRaw(value);
1047 const target = toRaw(this);
1048 const proto = getProto(target);
1049 const hadKey = proto.has.call(target, value);
1050 if (!hadKey) {
1051 target.add(value);
1052 trigger(target, "add" /* ADD */, value, value);
1053 }
1054 return this;
1055 }
1056 function set$1(key, value) {
1057 value = toRaw(value);
1058 const target = toRaw(this);
1059 const { has, get } = getProto(target);
1060 let hadKey = has.call(target, key);
1061 if (!hadKey) {
1062 key = toRaw(key);
1063 hadKey = has.call(target, key);
1064 }
1065 else {
1066 checkIdentityKeys(target, has, key);
1067 }
1068 const oldValue = get.call(target, key);
1069 target.set(key, value);
1070 if (!hadKey) {
1071 trigger(target, "add" /* ADD */, key, value);
1072 }
1073 else if (hasChanged(value, oldValue)) {
1074 trigger(target, "set" /* SET */, key, value, oldValue);
1075 }
1076 return this;
1077 }
1078 function deleteEntry(key) {
1079 const target = toRaw(this);
1080 const { has, get } = getProto(target);
1081 let hadKey = has.call(target, key);
1082 if (!hadKey) {
1083 key = toRaw(key);
1084 hadKey = has.call(target, key);
1085 }
1086 else {
1087 checkIdentityKeys(target, has, key);
1088 }
1089 const oldValue = get ? get.call(target, key) : undefined;
1090 // forward the operation before queueing reactions
1091 const result = target.delete(key);
1092 if (hadKey) {
1093 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
1094 }
1095 return result;
1096 }
1097 function clear() {
1098 const target = toRaw(this);
1099 const hadItems = target.size !== 0;
1100 const oldTarget = isMap(target)
1101 ? new Map(target)
1102 : new Set(target)
1103 ;
1104 // forward the operation before queueing reactions
1105 const result = target.clear();
1106 if (hadItems) {
1107 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
1108 }
1109 return result;
1110 }
1111 function createForEach(isReadonly, isShallow) {
1112 return function forEach(callback, thisArg) {
1113 const observed = this;
1114 const target = observed["__v_raw" /* RAW */];
1115 const rawTarget = toRaw(target);
1116 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1117 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
1118 return target.forEach((value, key) => {
1119 // important: make sure the callback is
1120 // 1. invoked with the reactive map as `this` and 3rd arg
1121 // 2. the value received should be a corresponding reactive/readonly.
1122 return callback.call(thisArg, wrap(value), wrap(key), observed);
1123 });
1124 };
1125 }
1126 function createIterableMethod(method, isReadonly, isShallow) {
1127 return function (...args) {
1128 const target = this["__v_raw" /* RAW */];
1129 const rawTarget = toRaw(target);
1130 const targetIsMap = isMap(rawTarget);
1131 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
1132 const isKeyOnly = method === 'keys' && targetIsMap;
1133 const innerIterator = target[method](...args);
1134 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1135 !isReadonly &&
1136 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
1137 // return a wrapped iterator which returns observed versions of the
1138 // values emitted from the real iterator
1139 return {
1140 // iterator protocol
1141 next() {
1142 const { value, done } = innerIterator.next();
1143 return done
1144 ? { value, done }
1145 : {
1146 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1147 done
1148 };
1149 },
1150 // iterable protocol
1151 [Symbol.iterator]() {
1152 return this;
1153 }
1154 };
1155 };
1156 }
1157 function createReadonlyMethod(type) {
1158 return function (...args) {
1159 {
1160 const key = args[0] ? `on key "${args[0]}" ` : ``;
1161 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
1162 }
1163 return type === "delete" /* DELETE */ ? false : this;
1164 };
1165 }
1166 function createInstrumentations() {
1167 const mutableInstrumentations = {
1168 get(key) {
1169 return get$1(this, key);
1170 },
1171 get size() {
1172 return size(this);
1173 },
1174 has: has$1,
1175 add,
1176 set: set$1,
1177 delete: deleteEntry,
1178 clear,
1179 forEach: createForEach(false, false)
1180 };
1181 const shallowInstrumentations = {
1182 get(key) {
1183 return get$1(this, key, false, true);
1184 },
1185 get size() {
1186 return size(this);
1187 },
1188 has: has$1,
1189 add,
1190 set: set$1,
1191 delete: deleteEntry,
1192 clear,
1193 forEach: createForEach(false, true)
1194 };
1195 const readonlyInstrumentations = {
1196 get(key) {
1197 return get$1(this, key, true);
1198 },
1199 get size() {
1200 return size(this, true);
1201 },
1202 has(key) {
1203 return has$1.call(this, key, true);
1204 },
1205 add: createReadonlyMethod("add" /* ADD */),
1206 set: createReadonlyMethod("set" /* SET */),
1207 delete: createReadonlyMethod("delete" /* DELETE */),
1208 clear: createReadonlyMethod("clear" /* CLEAR */),
1209 forEach: createForEach(true, false)
1210 };
1211 const shallowReadonlyInstrumentations = {
1212 get(key) {
1213 return get$1(this, key, true, true);
1214 },
1215 get size() {
1216 return size(this, true);
1217 },
1218 has(key) {
1219 return has$1.call(this, key, true);
1220 },
1221 add: createReadonlyMethod("add" /* ADD */),
1222 set: createReadonlyMethod("set" /* SET */),
1223 delete: createReadonlyMethod("delete" /* DELETE */),
1224 clear: createReadonlyMethod("clear" /* CLEAR */),
1225 forEach: createForEach(true, true)
1226 };
1227 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
1228 iteratorMethods.forEach(method => {
1229 mutableInstrumentations[method] = createIterableMethod(method, false, false);
1230 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
1231 shallowInstrumentations[method] = createIterableMethod(method, false, true);
1232 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
1233 });
1234 return [
1235 mutableInstrumentations,
1236 readonlyInstrumentations,
1237 shallowInstrumentations,
1238 shallowReadonlyInstrumentations
1239 ];
1240 }
1241 const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
1242 function createInstrumentationGetter(isReadonly, shallow) {
1243 const instrumentations = shallow
1244 ? isReadonly
1245 ? shallowReadonlyInstrumentations
1246 : shallowInstrumentations
1247 : isReadonly
1248 ? readonlyInstrumentations
1249 : mutableInstrumentations;
1250 return (target, key, receiver) => {
1251 if (key === "__v_isReactive" /* IS_REACTIVE */) {
1252 return !isReadonly;
1253 }
1254 else if (key === "__v_isReadonly" /* IS_READONLY */) {
1255 return isReadonly;
1256 }
1257 else if (key === "__v_raw" /* RAW */) {
1258 return target;
1259 }
1260 return Reflect.get(hasOwn(instrumentations, key) && key in target
1261 ? instrumentations
1262 : target, key, receiver);
1263 };
1264 }
1265 const mutableCollectionHandlers = {
1266 get: /*#__PURE__*/ createInstrumentationGetter(false, false)
1267 };
1268 const shallowCollectionHandlers = {
1269 get: /*#__PURE__*/ createInstrumentationGetter(false, true)
1270 };
1271 const readonlyCollectionHandlers = {
1272 get: /*#__PURE__*/ createInstrumentationGetter(true, false)
1273 };
1274 const shallowReadonlyCollectionHandlers = {
1275 get: /*#__PURE__*/ createInstrumentationGetter(true, true)
1276 };
1277 function checkIdentityKeys(target, has, key) {
1278 const rawKey = toRaw(key);
1279 if (rawKey !== key && has.call(target, rawKey)) {
1280 const type = toRawType(target);
1281 console.warn(`Reactive ${type} contains both the raw and reactive ` +
1282 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
1283 `which can lead to inconsistencies. ` +
1284 `Avoid differentiating between the raw and reactive versions ` +
1285 `of an object and only use the reactive version if possible.`);
1286 }
1287 }
1288
1289 const reactiveMap = new WeakMap();
1290 const shallowReactiveMap = new WeakMap();
1291 const readonlyMap = new WeakMap();
1292 const shallowReadonlyMap = new WeakMap();
1293 function targetTypeMap(rawType) {
1294 switch (rawType) {
1295 case 'Object':
1296 case 'Array':
1297 return 1 /* COMMON */;
1298 case 'Map':
1299 case 'Set':
1300 case 'WeakMap':
1301 case 'WeakSet':
1302 return 2 /* COLLECTION */;
1303 default:
1304 return 0 /* INVALID */;
1305 }
1306 }
1307 function getTargetType(value) {
1308 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1309 ? 0 /* INVALID */
1310 : targetTypeMap(toRawType(value));
1311 }
1312 function reactive(target) {
1313 // if trying to observe a readonly proxy, return the readonly version.
1314 if (isReadonly(target)) {
1315 return target;
1316 }
1317 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1318 }
1319 /**
1320 * Return a shallowly-reactive copy of the original object, where only the root
1321 * level properties are reactive. It also does not auto-unwrap refs (even at the
1322 * root level).
1323 */
1324 function shallowReactive(target) {
1325 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1326 }
1327 /**
1328 * Creates a readonly copy of the original object. Note the returned copy is not
1329 * made reactive, but `readonly` can be called on an already reactive object.
1330 */
1331 function readonly(target) {
1332 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1333 }
1334 /**
1335 * Returns a reactive-copy of the original object, where only the root level
1336 * properties are readonly, and does NOT unwrap refs nor recursively convert
1337 * returned properties.
1338 * This is used for creating the props proxy object for stateful components.
1339 */
1340 function shallowReadonly(target) {
1341 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1342 }
1343 function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1344 if (!isObject(target)) {
1345 {
1346 console.warn(`value cannot be made reactive: ${String(target)}`);
1347 }
1348 return target;
1349 }
1350 // target is already a Proxy, return it.
1351 // exception: calling readonly() on a reactive object
1352 if (target["__v_raw" /* RAW */] &&
1353 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1354 return target;
1355 }
1356 // target already has corresponding Proxy
1357 const existingProxy = proxyMap.get(target);
1358 if (existingProxy) {
1359 return existingProxy;
1360 }
1361 // only specific value types can be observed.
1362 const targetType = getTargetType(target);
1363 if (targetType === 0 /* INVALID */) {
1364 return target;
1365 }
1366 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1367 proxyMap.set(target, proxy);
1368 return proxy;
1369 }
1370 function isReactive(value) {
1371 if (isReadonly(value)) {
1372 return isReactive(value["__v_raw" /* RAW */]);
1373 }
1374 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1375 }
1376 function isReadonly(value) {
1377 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1378 }
1379 function isShallow(value) {
1380 return !!(value && value["__v_isShallow" /* IS_SHALLOW */]);
1381 }
1382 function isProxy(value) {
1383 return isReactive(value) || isReadonly(value);
1384 }
1385 function toRaw(observed) {
1386 const raw = observed && observed["__v_raw" /* RAW */];
1387 return raw ? toRaw(raw) : observed;
1388 }
1389 function markRaw(value) {
1390 def(value, "__v_skip" /* SKIP */, true);
1391 return value;
1392 }
1393 const toReactive = (value) => isObject(value) ? reactive(value) : value;
1394 const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1395
1396 function trackRefValue(ref) {
1397 if (shouldTrack && activeEffect) {
1398 ref = toRaw(ref);
1399 {
1400 trackEffects(ref.dep || (ref.dep = createDep()), {
1401 target: ref,
1402 type: "get" /* GET */,
1403 key: 'value'
1404 });
1405 }
1406 }
1407 }
1408 function triggerRefValue(ref, newVal) {
1409 ref = toRaw(ref);
1410 if (ref.dep) {
1411 {
1412 triggerEffects(ref.dep, {
1413 target: ref,
1414 type: "set" /* SET */,
1415 key: 'value',
1416 newValue: newVal
1417 });
1418 }
1419 }
1420 }
1421 function isRef(r) {
1422 return !!(r && r.__v_isRef === true);
1423 }
1424 function ref(value) {
1425 return createRef(value, false);
1426 }
1427 function shallowRef(value) {
1428 return createRef(value, true);
1429 }
1430 function createRef(rawValue, shallow) {
1431 if (isRef(rawValue)) {
1432 return rawValue;
1433 }
1434 return new RefImpl(rawValue, shallow);
1435 }
1436 class RefImpl {
1437 constructor(value, __v_isShallow) {
1438 this.__v_isShallow = __v_isShallow;
1439 this.dep = undefined;
1440 this.__v_isRef = true;
1441 this._rawValue = __v_isShallow ? value : toRaw(value);
1442 this._value = __v_isShallow ? value : toReactive(value);
1443 }
1444 get value() {
1445 trackRefValue(this);
1446 return this._value;
1447 }
1448 set value(newVal) {
1449 newVal = this.__v_isShallow ? newVal : toRaw(newVal);
1450 if (hasChanged(newVal, this._rawValue)) {
1451 this._rawValue = newVal;
1452 this._value = this.__v_isShallow ? newVal : toReactive(newVal);
1453 triggerRefValue(this, newVal);
1454 }
1455 }
1456 }
1457 function triggerRef(ref) {
1458 triggerRefValue(ref, ref.value );
1459 }
1460 function unref(ref) {
1461 return isRef(ref) ? ref.value : ref;
1462 }
1463 const shallowUnwrapHandlers = {
1464 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1465 set: (target, key, value, receiver) => {
1466 const oldValue = target[key];
1467 if (isRef(oldValue) && !isRef(value)) {
1468 oldValue.value = value;
1469 return true;
1470 }
1471 else {
1472 return Reflect.set(target, key, value, receiver);
1473 }
1474 }
1475 };
1476 function proxyRefs(objectWithRefs) {
1477 return isReactive(objectWithRefs)
1478 ? objectWithRefs
1479 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1480 }
1481 class CustomRefImpl {
1482 constructor(factory) {
1483 this.dep = undefined;
1484 this.__v_isRef = true;
1485 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
1486 this._get = get;
1487 this._set = set;
1488 }
1489 get value() {
1490 return this._get();
1491 }
1492 set value(newVal) {
1493 this._set(newVal);
1494 }
1495 }
1496 function customRef(factory) {
1497 return new CustomRefImpl(factory);
1498 }
1499 function toRefs(object) {
1500 if (!isProxy(object)) {
1501 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1502 }
1503 const ret = isArray(object) ? new Array(object.length) : {};
1504 for (const key in object) {
1505 ret[key] = toRef(object, key);
1506 }
1507 return ret;
1508 }
1509 class ObjectRefImpl {
1510 constructor(_object, _key, _defaultValue) {
1511 this._object = _object;
1512 this._key = _key;
1513 this._defaultValue = _defaultValue;
1514 this.__v_isRef = true;
1515 }
1516 get value() {
1517 const val = this._object[this._key];
1518 return val === undefined ? this._defaultValue : val;
1519 }
1520 set value(newVal) {
1521 this._object[this._key] = newVal;
1522 }
1523 }
1524 function toRef(object, key, defaultValue) {
1525 const val = object[key];
1526 return isRef(val)
1527 ? val
1528 : new ObjectRefImpl(object, key, defaultValue);
1529 }
1530
1531 class ComputedRefImpl {
1532 constructor(getter, _setter, isReadonly, isSSR) {
1533 this._setter = _setter;
1534 this.dep = undefined;
1535 this.__v_isRef = true;
1536 this._dirty = true;
1537 this.effect = new ReactiveEffect(getter, () => {
1538 if (!this._dirty) {
1539 this._dirty = true;
1540 triggerRefValue(this);
1541 }
1542 });
1543 this.effect.computed = this;
1544 this.effect.active = this._cacheable = !isSSR;
1545 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1546 }
1547 get value() {
1548 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1549 const self = toRaw(this);
1550 trackRefValue(self);
1551 if (self._dirty || !self._cacheable) {
1552 self._dirty = false;
1553 self._value = self.effect.run();
1554 }
1555 return self._value;
1556 }
1557 set value(newValue) {
1558 this._setter(newValue);
1559 }
1560 }
1561 function computed(getterOrOptions, debugOptions, isSSR = false) {
1562 let getter;
1563 let setter;
1564 const onlyGetter = isFunction(getterOrOptions);
1565 if (onlyGetter) {
1566 getter = getterOrOptions;
1567 setter = () => {
1568 console.warn('Write operation failed: computed value is readonly');
1569 }
1570 ;
1571 }
1572 else {
1573 getter = getterOrOptions.get;
1574 setter = getterOrOptions.set;
1575 }
1576 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1577 if (debugOptions && !isSSR) {
1578 cRef.effect.onTrack = debugOptions.onTrack;
1579 cRef.effect.onTrigger = debugOptions.onTrigger;
1580 }
1581 return cRef;
1582 }
1583
1584 const stack = [];
1585 function pushWarningContext(vnode) {
1586 stack.push(vnode);
1587 }
1588 function popWarningContext() {
1589 stack.pop();
1590 }
1591 function warn$1(msg, ...args) {
1592 // avoid props formatting or warn handler tracking deps that might be mutated
1593 // during patch, leading to infinite recursion.
1594 pauseTracking();
1595 const instance = stack.length ? stack[stack.length - 1].component : null;
1596 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1597 const trace = getComponentTrace();
1598 if (appWarnHandler) {
1599 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1600 msg + args.join(''),
1601 instance && instance.proxy,
1602 trace
1603 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1604 .join('\n'),
1605 trace
1606 ]);
1607 }
1608 else {
1609 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1610 /* istanbul ignore if */
1611 if (trace.length &&
1612 // avoid spamming console during tests
1613 !false) {
1614 warnArgs.push(`\n`, ...formatTrace(trace));
1615 }
1616 console.warn(...warnArgs);
1617 }
1618 resetTracking();
1619 }
1620 function getComponentTrace() {
1621 let currentVNode = stack[stack.length - 1];
1622 if (!currentVNode) {
1623 return [];
1624 }
1625 // we can't just use the stack because it will be incomplete during updates
1626 // that did not start from the root. Re-construct the parent chain using
1627 // instance parent pointers.
1628 const normalizedStack = [];
1629 while (currentVNode) {
1630 const last = normalizedStack[0];
1631 if (last && last.vnode === currentVNode) {
1632 last.recurseCount++;
1633 }
1634 else {
1635 normalizedStack.push({
1636 vnode: currentVNode,
1637 recurseCount: 0
1638 });
1639 }
1640 const parentInstance = currentVNode.component && currentVNode.component.parent;
1641 currentVNode = parentInstance && parentInstance.vnode;
1642 }
1643 return normalizedStack;
1644 }
1645 /* istanbul ignore next */
1646 function formatTrace(trace) {
1647 const logs = [];
1648 trace.forEach((entry, i) => {
1649 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1650 });
1651 return logs;
1652 }
1653 function formatTraceEntry({ vnode, recurseCount }) {
1654 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1655 const isRoot = vnode.component ? vnode.component.parent == null : false;
1656 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1657 const close = `>` + postfix;
1658 return vnode.props
1659 ? [open, ...formatProps(vnode.props), close]
1660 : [open + close];
1661 }
1662 /* istanbul ignore next */
1663 function formatProps(props) {
1664 const res = [];
1665 const keys = Object.keys(props);
1666 keys.slice(0, 3).forEach(key => {
1667 res.push(...formatProp(key, props[key]));
1668 });
1669 if (keys.length > 3) {
1670 res.push(` ...`);
1671 }
1672 return res;
1673 }
1674 /* istanbul ignore next */
1675 function formatProp(key, value, raw) {
1676 if (isString(value)) {
1677 value = JSON.stringify(value);
1678 return raw ? value : [`${key}=${value}`];
1679 }
1680 else if (typeof value === 'number' ||
1681 typeof value === 'boolean' ||
1682 value == null) {
1683 return raw ? value : [`${key}=${value}`];
1684 }
1685 else if (isRef(value)) {
1686 value = formatProp(key, toRaw(value.value), true);
1687 return raw ? value : [`${key}=Ref<`, value, `>`];
1688 }
1689 else if (isFunction(value)) {
1690 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1691 }
1692 else {
1693 value = toRaw(value);
1694 return raw ? value : [`${key}=`, value];
1695 }
1696 }
1697
1698 const ErrorTypeStrings = {
1699 ["sp" /* SERVER_PREFETCH */]: 'serverPrefetch hook',
1700 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1701 ["c" /* CREATED */]: 'created hook',
1702 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1703 ["m" /* MOUNTED */]: 'mounted hook',
1704 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1705 ["u" /* UPDATED */]: 'updated',
1706 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1707 ["um" /* UNMOUNTED */]: 'unmounted hook',
1708 ["a" /* ACTIVATED */]: 'activated hook',
1709 ["da" /* DEACTIVATED */]: 'deactivated hook',
1710 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1711 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1712 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1713 [0 /* SETUP_FUNCTION */]: 'setup function',
1714 [1 /* RENDER_FUNCTION */]: 'render function',
1715 [2 /* WATCH_GETTER */]: 'watcher getter',
1716 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1717 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1718 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1719 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1720 [7 /* VNODE_HOOK */]: 'vnode hook',
1721 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1722 [9 /* TRANSITION_HOOK */]: 'transition hook',
1723 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1724 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1725 [12 /* FUNCTION_REF */]: 'ref function',
1726 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1727 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1728 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
1729 };
1730 function callWithErrorHandling(fn, instance, type, args) {
1731 let res;
1732 try {
1733 res = args ? fn(...args) : fn();
1734 }
1735 catch (err) {
1736 handleError(err, instance, type);
1737 }
1738 return res;
1739 }
1740 function callWithAsyncErrorHandling(fn, instance, type, args) {
1741 if (isFunction(fn)) {
1742 const res = callWithErrorHandling(fn, instance, type, args);
1743 if (res && isPromise(res)) {
1744 res.catch(err => {
1745 handleError(err, instance, type);
1746 });
1747 }
1748 return res;
1749 }
1750 const values = [];
1751 for (let i = 0; i < fn.length; i++) {
1752 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1753 }
1754 return values;
1755 }
1756 function handleError(err, instance, type, throwInDev = true) {
1757 const contextVNode = instance ? instance.vnode : null;
1758 if (instance) {
1759 let cur = instance.parent;
1760 // the exposed instance is the render proxy to keep it consistent with 2.x
1761 const exposedInstance = instance.proxy;
1762 // in production the hook receives only the error code
1763 const errorInfo = ErrorTypeStrings[type] ;
1764 while (cur) {
1765 const errorCapturedHooks = cur.ec;
1766 if (errorCapturedHooks) {
1767 for (let i = 0; i < errorCapturedHooks.length; i++) {
1768 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1769 return;
1770 }
1771 }
1772 }
1773 cur = cur.parent;
1774 }
1775 // app-level handling
1776 const appErrorHandler = instance.appContext.config.errorHandler;
1777 if (appErrorHandler) {
1778 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1779 return;
1780 }
1781 }
1782 logError(err, type, contextVNode, throwInDev);
1783 }
1784 function logError(err, type, contextVNode, throwInDev = true) {
1785 {
1786 const info = ErrorTypeStrings[type];
1787 if (contextVNode) {
1788 pushWarningContext(contextVNode);
1789 }
1790 warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1791 if (contextVNode) {
1792 popWarningContext();
1793 }
1794 // crash in dev by default so it's more noticeable
1795 if (throwInDev) {
1796 throw err;
1797 }
1798 else {
1799 console.error(err);
1800 }
1801 }
1802 }
1803
1804 let isFlushing = false;
1805 let isFlushPending = false;
1806 const queue = [];
1807 let flushIndex = 0;
1808 const pendingPreFlushCbs = [];
1809 let activePreFlushCbs = null;
1810 let preFlushIndex = 0;
1811 const pendingPostFlushCbs = [];
1812 let activePostFlushCbs = null;
1813 let postFlushIndex = 0;
1814 const resolvedPromise = /*#__PURE__*/ Promise.resolve();
1815 let currentFlushPromise = null;
1816 let currentPreFlushParentJob = null;
1817 const RECURSION_LIMIT = 100;
1818 function nextTick(fn) {
1819 const p = currentFlushPromise || resolvedPromise;
1820 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1821 }
1822 // #2768
1823 // Use binary-search to find a suitable position in the queue,
1824 // so that the queue maintains the increasing order of job's id,
1825 // which can prevent the job from being skipped and also can avoid repeated patching.
1826 function findInsertionIndex(id) {
1827 // the start index should be `flushIndex + 1`
1828 let start = flushIndex + 1;
1829 let end = queue.length;
1830 while (start < end) {
1831 const middle = (start + end) >>> 1;
1832 const middleJobId = getId(queue[middle]);
1833 middleJobId < id ? (start = middle + 1) : (end = middle);
1834 }
1835 return start;
1836 }
1837 function queueJob(job) {
1838 // the dedupe search uses the startIndex argument of Array.includes()
1839 // by default the search index includes the current job that is being run
1840 // so it cannot recursively trigger itself again.
1841 // if the job is a watch() callback, the search will start with a +1 index to
1842 // allow it recursively trigger itself - it is the user's responsibility to
1843 // ensure it doesn't end up in an infinite loop.
1844 if ((!queue.length ||
1845 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1846 job !== currentPreFlushParentJob) {
1847 if (job.id == null) {
1848 queue.push(job);
1849 }
1850 else {
1851 queue.splice(findInsertionIndex(job.id), 0, job);
1852 }
1853 queueFlush();
1854 }
1855 }
1856 function queueFlush() {
1857 if (!isFlushing && !isFlushPending) {
1858 isFlushPending = true;
1859 currentFlushPromise = resolvedPromise.then(flushJobs);
1860 }
1861 }
1862 function invalidateJob(job) {
1863 const i = queue.indexOf(job);
1864 if (i > flushIndex) {
1865 queue.splice(i, 1);
1866 }
1867 }
1868 function queueCb(cb, activeQueue, pendingQueue, index) {
1869 if (!isArray(cb)) {
1870 if (!activeQueue ||
1871 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1872 pendingQueue.push(cb);
1873 }
1874 }
1875 else {
1876 // if cb is an array, it is a component lifecycle hook which can only be
1877 // triggered by a job, which is already deduped in the main queue, so
1878 // we can skip duplicate check here to improve perf
1879 pendingQueue.push(...cb);
1880 }
1881 queueFlush();
1882 }
1883 function queuePreFlushCb(cb) {
1884 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1885 }
1886 function queuePostFlushCb(cb) {
1887 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1888 }
1889 function flushPreFlushCbs(seen, parentJob = null) {
1890 if (pendingPreFlushCbs.length) {
1891 currentPreFlushParentJob = parentJob;
1892 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1893 pendingPreFlushCbs.length = 0;
1894 {
1895 seen = seen || new Map();
1896 }
1897 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1898 if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) {
1899 continue;
1900 }
1901 activePreFlushCbs[preFlushIndex]();
1902 }
1903 activePreFlushCbs = null;
1904 preFlushIndex = 0;
1905 currentPreFlushParentJob = null;
1906 // recursively flush until it drains
1907 flushPreFlushCbs(seen, parentJob);
1908 }
1909 }
1910 function flushPostFlushCbs(seen) {
1911 // flush any pre cbs queued during the flush (e.g. pre watchers)
1912 flushPreFlushCbs();
1913 if (pendingPostFlushCbs.length) {
1914 const deduped = [...new Set(pendingPostFlushCbs)];
1915 pendingPostFlushCbs.length = 0;
1916 // #1947 already has active queue, nested flushPostFlushCbs call
1917 if (activePostFlushCbs) {
1918 activePostFlushCbs.push(...deduped);
1919 return;
1920 }
1921 activePostFlushCbs = deduped;
1922 {
1923 seen = seen || new Map();
1924 }
1925 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1926 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1927 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
1928 continue;
1929 }
1930 activePostFlushCbs[postFlushIndex]();
1931 }
1932 activePostFlushCbs = null;
1933 postFlushIndex = 0;
1934 }
1935 }
1936 const getId = (job) => job.id == null ? Infinity : job.id;
1937 function flushJobs(seen) {
1938 isFlushPending = false;
1939 isFlushing = true;
1940 {
1941 seen = seen || new Map();
1942 }
1943 flushPreFlushCbs(seen);
1944 // Sort queue before flush.
1945 // This ensures that:
1946 // 1. Components are updated from parent to child. (because parent is always
1947 // created before the child so its render effect will have smaller
1948 // priority number)
1949 // 2. If a component is unmounted during a parent component's update,
1950 // its update can be skipped.
1951 queue.sort((a, b) => getId(a) - getId(b));
1952 // conditional usage of checkRecursiveUpdate must be determined out of
1953 // try ... catch block since Rollup by default de-optimizes treeshaking
1954 // inside try-catch. This can leave all warning code unshaked. Although
1955 // they would get eventually shaken by a minifier like terser, some minifiers
1956 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610)
1957 const check = (job) => checkRecursiveUpdates(seen, job)
1958 ;
1959 try {
1960 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1961 const job = queue[flushIndex];
1962 if (job && job.active !== false) {
1963 if (true && check(job)) {
1964 continue;
1965 }
1966 // console.log(`running:`, job.id)
1967 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1968 }
1969 }
1970 }
1971 finally {
1972 flushIndex = 0;
1973 queue.length = 0;
1974 flushPostFlushCbs(seen);
1975 isFlushing = false;
1976 currentFlushPromise = null;
1977 // some postFlushCb queued jobs!
1978 // keep flushing until it drains.
1979 if (queue.length ||
1980 pendingPreFlushCbs.length ||
1981 pendingPostFlushCbs.length) {
1982 flushJobs(seen);
1983 }
1984 }
1985 }
1986 function checkRecursiveUpdates(seen, fn) {
1987 if (!seen.has(fn)) {
1988 seen.set(fn, 1);
1989 }
1990 else {
1991 const count = seen.get(fn);
1992 if (count > RECURSION_LIMIT) {
1993 const instance = fn.ownerInstance;
1994 const componentName = instance && getComponentName(instance.type);
1995 warn$1(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
1996 `This means you have a reactive effect that is mutating its own ` +
1997 `dependencies and thus recursively triggering itself. Possible sources ` +
1998 `include component template, render function, updated hook or ` +
1999 `watcher source function.`);
2000 return true;
2001 }
2002 else {
2003 seen.set(fn, count + 1);
2004 }
2005 }
2006 }
2007
2008 /* eslint-disable no-restricted-globals */
2009 let isHmrUpdating = false;
2010 const hmrDirtyComponents = new Set();
2011 // Expose the HMR runtime on the global object
2012 // This makes it entirely tree-shakable without polluting the exports and makes
2013 // it easier to be used in toolings like vue-loader
2014 // Note: for a component to be eligible for HMR it also needs the __hmrId option
2015 // to be set so that its instances can be registered / removed.
2016 {
2017 getGlobalThis().__VUE_HMR_RUNTIME__ = {
2018 createRecord: tryWrap(createRecord),
2019 rerender: tryWrap(rerender),
2020 reload: tryWrap(reload)
2021 };
2022 }
2023 const map = new Map();
2024 function registerHMR(instance) {
2025 const id = instance.type.__hmrId;
2026 let record = map.get(id);
2027 if (!record) {
2028 createRecord(id, instance.type);
2029 record = map.get(id);
2030 }
2031 record.instances.add(instance);
2032 }
2033 function unregisterHMR(instance) {
2034 map.get(instance.type.__hmrId).instances.delete(instance);
2035 }
2036 function createRecord(id, initialDef) {
2037 if (map.has(id)) {
2038 return false;
2039 }
2040 map.set(id, {
2041 initialDef: normalizeClassComponent(initialDef),
2042 instances: new Set()
2043 });
2044 return true;
2045 }
2046 function normalizeClassComponent(component) {
2047 return isClassComponent(component) ? component.__vccOpts : component;
2048 }
2049 function rerender(id, newRender) {
2050 const record = map.get(id);
2051 if (!record) {
2052 return;
2053 }
2054 // update initial record (for not-yet-rendered component)
2055 record.initialDef.render = newRender;
2056 [...record.instances].forEach(instance => {
2057 if (newRender) {
2058 instance.render = newRender;
2059 normalizeClassComponent(instance.type).render = newRender;
2060 }
2061 instance.renderCache = [];
2062 // this flag forces child components with slot content to update
2063 isHmrUpdating = true;
2064 instance.update();
2065 isHmrUpdating = false;
2066 });
2067 }
2068 function reload(id, newComp) {
2069 const record = map.get(id);
2070 if (!record)
2071 return;
2072 newComp = normalizeClassComponent(newComp);
2073 // update initial def (for not-yet-rendered components)
2074 updateComponentDef(record.initialDef, newComp);
2075 // create a snapshot which avoids the set being mutated during updates
2076 const instances = [...record.instances];
2077 for (const instance of instances) {
2078 const oldComp = normalizeClassComponent(instance.type);
2079 if (!hmrDirtyComponents.has(oldComp)) {
2080 // 1. Update existing comp definition to match new one
2081 if (oldComp !== record.initialDef) {
2082 updateComponentDef(oldComp, newComp);
2083 }
2084 // 2. mark definition dirty. This forces the renderer to replace the
2085 // component on patch.
2086 hmrDirtyComponents.add(oldComp);
2087 }
2088 // 3. invalidate options resolution cache
2089 instance.appContext.optionsCache.delete(instance.type);
2090 // 4. actually update
2091 if (instance.ceReload) {
2092 // custom element
2093 hmrDirtyComponents.add(oldComp);
2094 instance.ceReload(newComp.styles);
2095 hmrDirtyComponents.delete(oldComp);
2096 }
2097 else if (instance.parent) {
2098 // 4. Force the parent instance to re-render. This will cause all updated
2099 // components to be unmounted and re-mounted. Queue the update so that we
2100 // don't end up forcing the same parent to re-render multiple times.
2101 queueJob(instance.parent.update);
2102 // instance is the inner component of an async custom element
2103 // invoke to reset styles
2104 if (instance.parent.type.__asyncLoader &&
2105 instance.parent.ceReload) {
2106 instance.parent.ceReload(newComp.styles);
2107 }
2108 }
2109 else if (instance.appContext.reload) {
2110 // root instance mounted via createApp() has a reload method
2111 instance.appContext.reload();
2112 }
2113 else if (typeof window !== 'undefined') {
2114 // root instance inside tree created via raw render(). Force reload.
2115 window.location.reload();
2116 }
2117 else {
2118 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
2119 }
2120 }
2121 // 5. make sure to cleanup dirty hmr components after update
2122 queuePostFlushCb(() => {
2123 for (const instance of instances) {
2124 hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
2125 }
2126 });
2127 }
2128 function updateComponentDef(oldComp, newComp) {
2129 extend(oldComp, newComp);
2130 for (const key in oldComp) {
2131 if (key !== '__file' && !(key in newComp)) {
2132 delete oldComp[key];
2133 }
2134 }
2135 }
2136 function tryWrap(fn) {
2137 return (id, arg) => {
2138 try {
2139 return fn(id, arg);
2140 }
2141 catch (e) {
2142 console.error(e);
2143 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
2144 `Full reload required.`);
2145 }
2146 };
2147 }
2148
2149 let buffer = [];
2150 let devtoolsNotInstalled = false;
2151 function emit(event, ...args) {
2152 if (exports.devtools) {
2153 exports.devtools.emit(event, ...args);
2154 }
2155 else if (!devtoolsNotInstalled) {
2156 buffer.push({ event, args });
2157 }
2158 }
2159 function setDevtoolsHook(hook, target) {
2160 var _a, _b;
2161 exports.devtools = hook;
2162 if (exports.devtools) {
2163 exports.devtools.enabled = true;
2164 buffer.forEach(({ event, args }) => exports.devtools.emit(event, ...args));
2165 buffer = [];
2166 }
2167 else if (
2168 // handle late devtools injection - only do this if we are in an actual
2169 // browser environment to avoid the timer handle stalling test runner exit
2170 // (#4815)
2171 typeof window !== 'undefined' &&
2172 // some envs mock window but not fully
2173 window.HTMLElement &&
2174 // also exclude jsdom
2175 !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
2176 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
2177 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
2178 replay.push((newHook) => {
2179 setDevtoolsHook(newHook, target);
2180 });
2181 // clear buffer after 3s - the user probably doesn't have devtools installed
2182 // at all, and keeping the buffer will cause memory leaks (#4738)
2183 setTimeout(() => {
2184 if (!exports.devtools) {
2185 target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
2186 devtoolsNotInstalled = true;
2187 buffer = [];
2188 }
2189 }, 3000);
2190 }
2191 else {
2192 // non-browser env, assume not installed
2193 devtoolsNotInstalled = true;
2194 buffer = [];
2195 }
2196 }
2197 function devtoolsInitApp(app, version) {
2198 emit("app:init" /* APP_INIT */, app, version, {
2199 Fragment,
2200 Text,
2201 Comment,
2202 Static
2203 });
2204 }
2205 function devtoolsUnmountApp(app) {
2206 emit("app:unmount" /* APP_UNMOUNT */, app);
2207 }
2208 const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
2209 const devtoolsComponentUpdated =
2210 /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
2211 const devtoolsComponentRemoved =
2212 /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
2213 function createDevtoolsComponentHook(hook) {
2214 return (component) => {
2215 emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
2216 };
2217 }
2218 const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
2219 const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
2220 function createDevtoolsPerformanceHook(hook) {
2221 return (component, type, time) => {
2222 emit(hook, component.appContext.app, component.uid, component, type, time);
2223 };
2224 }
2225 function devtoolsComponentEmit(component, event, params) {
2226 emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
2227 }
2228
2229 function emit$1(instance, event, ...rawArgs) {
2230 if (instance.isUnmounted)
2231 return;
2232 const props = instance.vnode.props || EMPTY_OBJ;
2233 {
2234 const { emitsOptions, propsOptions: [propsOptions] } = instance;
2235 if (emitsOptions) {
2236 if (!(event in emitsOptions) &&
2237 !(false )) {
2238 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
2239 warn$1(`Component emitted event "${event}" but it is neither declared in ` +
2240 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
2241 }
2242 }
2243 else {
2244 const validator = emitsOptions[event];
2245 if (isFunction(validator)) {
2246 const isValid = validator(...rawArgs);
2247 if (!isValid) {
2248 warn$1(`Invalid event arguments: event validation failed for event "${event}".`);
2249 }
2250 }
2251 }
2252 }
2253 }
2254 let args = rawArgs;
2255 const isModelListener = event.startsWith('update:');
2256 // for v-model update:xxx events, apply modifiers on args
2257 const modelArg = isModelListener && event.slice(7);
2258 if (modelArg && modelArg in props) {
2259 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
2260 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
2261 if (trim) {
2262 args = rawArgs.map(a => a.trim());
2263 }
2264 if (number) {
2265 args = rawArgs.map(toNumber);
2266 }
2267 }
2268 {
2269 devtoolsComponentEmit(instance, event, args);
2270 }
2271 {
2272 const lowerCaseEvent = event.toLowerCase();
2273 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
2274 warn$1(`Event "${lowerCaseEvent}" is emitted in component ` +
2275 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
2276 `Note that HTML attributes are case-insensitive and you cannot use ` +
2277 `v-on to listen to camelCase events when using in-DOM templates. ` +
2278 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
2279 }
2280 }
2281 let handlerName;
2282 let handler = props[(handlerName = toHandlerKey(event))] ||
2283 // also try camelCase event handler (#2249)
2284 props[(handlerName = toHandlerKey(camelize(event)))];
2285 // for v-model update:xxx events, also trigger kebab-case equivalent
2286 // for props passed via kebab-case
2287 if (!handler && isModelListener) {
2288 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
2289 }
2290 if (handler) {
2291 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2292 }
2293 const onceHandler = props[handlerName + `Once`];
2294 if (onceHandler) {
2295 if (!instance.emitted) {
2296 instance.emitted = {};
2297 }
2298 else if (instance.emitted[handlerName]) {
2299 return;
2300 }
2301 instance.emitted[handlerName] = true;
2302 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2303 }
2304 }
2305 function normalizeEmitsOptions(comp, appContext, asMixin = false) {
2306 const cache = appContext.emitsCache;
2307 const cached = cache.get(comp);
2308 if (cached !== undefined) {
2309 return cached;
2310 }
2311 const raw = comp.emits;
2312 let normalized = {};
2313 // apply mixin/extends props
2314 let hasExtends = false;
2315 if (!isFunction(comp)) {
2316 const extendEmits = (raw) => {
2317 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
2318 if (normalizedFromExtend) {
2319 hasExtends = true;
2320 extend(normalized, normalizedFromExtend);
2321 }
2322 };
2323 if (!asMixin && appContext.mixins.length) {
2324 appContext.mixins.forEach(extendEmits);
2325 }
2326 if (comp.extends) {
2327 extendEmits(comp.extends);
2328 }
2329 if (comp.mixins) {
2330 comp.mixins.forEach(extendEmits);
2331 }
2332 }
2333 if (!raw && !hasExtends) {
2334 cache.set(comp, null);
2335 return null;
2336 }
2337 if (isArray(raw)) {
2338 raw.forEach(key => (normalized[key] = null));
2339 }
2340 else {
2341 extend(normalized, raw);
2342 }
2343 cache.set(comp, normalized);
2344 return normalized;
2345 }
2346 // Check if an incoming prop key is a declared emit event listener.
2347 // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
2348 // both considered matched listeners.
2349 function isEmitListener(options, key) {
2350 if (!options || !isOn(key)) {
2351 return false;
2352 }
2353 key = key.slice(2).replace(/Once$/, '');
2354 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
2355 hasOwn(options, hyphenate(key)) ||
2356 hasOwn(options, key));
2357 }
2358
2359 /**
2360 * mark the current rendering instance for asset resolution (e.g.
2361 * resolveComponent, resolveDirective) during render
2362 */
2363 let currentRenderingInstance = null;
2364 let currentScopeId = null;
2365 /**
2366 * Note: rendering calls maybe nested. The function returns the parent rendering
2367 * instance if present, which should be restored after the render is done:
2368 *
2369 * ```js
2370 * const prev = setCurrentRenderingInstance(i)
2371 * // ...render
2372 * setCurrentRenderingInstance(prev)
2373 * ```
2374 */
2375 function setCurrentRenderingInstance(instance) {
2376 const prev = currentRenderingInstance;
2377 currentRenderingInstance = instance;
2378 currentScopeId = (instance && instance.type.__scopeId) || null;
2379 return prev;
2380 }
2381 /**
2382 * Set scope id when creating hoisted vnodes.
2383 * @private compiler helper
2384 */
2385 function pushScopeId(id) {
2386 currentScopeId = id;
2387 }
2388 /**
2389 * Technically we no longer need this after 3.0.8 but we need to keep the same
2390 * API for backwards compat w/ code generated by compilers.
2391 * @private
2392 */
2393 function popScopeId() {
2394 currentScopeId = null;
2395 }
2396 /**
2397 * Only for backwards compat
2398 * @private
2399 */
2400 const withScopeId = (_id) => withCtx;
2401 /**
2402 * Wrap a slot function to memoize current rendering instance
2403 * @private compiler helper
2404 */
2405 function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
2406 ) {
2407 if (!ctx)
2408 return fn;
2409 // already normalized
2410 if (fn._n) {
2411 return fn;
2412 }
2413 const renderFnWithContext = (...args) => {
2414 // If a user calls a compiled slot inside a template expression (#1745), it
2415 // can mess up block tracking, so by default we disable block tracking and
2416 // force bail out when invoking a compiled slot (indicated by the ._d flag).
2417 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
2418 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
2419 if (renderFnWithContext._d) {
2420 setBlockTracking(-1);
2421 }
2422 const prevInstance = setCurrentRenderingInstance(ctx);
2423 const res = fn(...args);
2424 setCurrentRenderingInstance(prevInstance);
2425 if (renderFnWithContext._d) {
2426 setBlockTracking(1);
2427 }
2428 {
2429 devtoolsComponentUpdated(ctx);
2430 }
2431 return res;
2432 };
2433 // mark normalized to avoid duplicated wrapping
2434 renderFnWithContext._n = true;
2435 // mark this as compiled by default
2436 // this is used in vnode.ts -> normalizeChildren() to set the slot
2437 // rendering flag.
2438 renderFnWithContext._c = true;
2439 // disable block tracking by default
2440 renderFnWithContext._d = true;
2441 return renderFnWithContext;
2442 }
2443
2444 /**
2445 * dev only flag to track whether $attrs was used during render.
2446 * If $attrs was used during render then the warning for failed attrs
2447 * fallthrough can be suppressed.
2448 */
2449 let accessedAttrs = false;
2450 function markAttrsAccessed() {
2451 accessedAttrs = true;
2452 }
2453 function renderComponentRoot(instance) {
2454 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
2455 let result;
2456 let fallthroughAttrs;
2457 const prev = setCurrentRenderingInstance(instance);
2458 {
2459 accessedAttrs = false;
2460 }
2461 try {
2462 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
2463 // withProxy is a proxy with a different `has` trap only for
2464 // runtime-compiled render functions using `with` block.
2465 const proxyToUse = withProxy || proxy;
2466 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2467 fallthroughAttrs = attrs;
2468 }
2469 else {
2470 // functional
2471 const render = Component;
2472 // in dev, mark attrs accessed if optional props (attrs === props)
2473 if (true && attrs === props) {
2474 markAttrsAccessed();
2475 }
2476 result = normalizeVNode(render.length > 1
2477 ? render(props, true
2478 ? {
2479 get attrs() {
2480 markAttrsAccessed();
2481 return attrs;
2482 },
2483 slots,
2484 emit
2485 }
2486 : { attrs, slots, emit })
2487 : render(props, null /* we know it doesn't need it */));
2488 fallthroughAttrs = Component.props
2489 ? attrs
2490 : getFunctionalFallthrough(attrs);
2491 }
2492 }
2493 catch (err) {
2494 blockStack.length = 0;
2495 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2496 result = createVNode(Comment);
2497 }
2498 // attr merging
2499 // in dev mode, comments are preserved, and it's possible for a template
2500 // to have comments along side the root element which makes it a fragment
2501 let root = result;
2502 let setRoot = undefined;
2503 if (result.patchFlag > 0 &&
2504 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
2505 [root, setRoot] = getChildRoot(result);
2506 }
2507 if (fallthroughAttrs && inheritAttrs !== false) {
2508 const keys = Object.keys(fallthroughAttrs);
2509 const { shapeFlag } = root;
2510 if (keys.length) {
2511 if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) {
2512 if (propsOptions && keys.some(isModelListener)) {
2513 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2514 // prop, it indicates this component expects to handle v-model and
2515 // it should not fallthrough.
2516 // related: #1543, #1643, #1989
2517 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2518 }
2519 root = cloneVNode(root, fallthroughAttrs);
2520 }
2521 else if (!accessedAttrs && root.type !== Comment) {
2522 const allAttrs = Object.keys(attrs);
2523 const eventAttrs = [];
2524 const extraAttrs = [];
2525 for (let i = 0, l = allAttrs.length; i < l; i++) {
2526 const key = allAttrs[i];
2527 if (isOn(key)) {
2528 // ignore v-model handlers when they fail to fallthrough
2529 if (!isModelListener(key)) {
2530 // remove `on`, lowercase first letter to reflect event casing
2531 // accurately
2532 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2533 }
2534 }
2535 else {
2536 extraAttrs.push(key);
2537 }
2538 }
2539 if (extraAttrs.length) {
2540 warn$1(`Extraneous non-props attributes (` +
2541 `${extraAttrs.join(', ')}) ` +
2542 `were passed to component but could not be automatically inherited ` +
2543 `because component renders fragment or text root nodes.`);
2544 }
2545 if (eventAttrs.length) {
2546 warn$1(`Extraneous non-emits event listeners (` +
2547 `${eventAttrs.join(', ')}) ` +
2548 `were passed to component but could not be automatically inherited ` +
2549 `because component renders fragment or text root nodes. ` +
2550 `If the listener is intended to be a component custom event listener only, ` +
2551 `declare it using the "emits" option.`);
2552 }
2553 }
2554 }
2555 }
2556 // inherit directives
2557 if (vnode.dirs) {
2558 if (!isElementRoot(root)) {
2559 warn$1(`Runtime directive used on component with non-element root node. ` +
2560 `The directives will not function as intended.`);
2561 }
2562 // clone before mutating since the root may be a hoisted vnode
2563 root = cloneVNode(root);
2564 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2565 }
2566 // inherit transition data
2567 if (vnode.transition) {
2568 if (!isElementRoot(root)) {
2569 warn$1(`Component inside <Transition> renders non-element root node ` +
2570 `that cannot be animated.`);
2571 }
2572 root.transition = vnode.transition;
2573 }
2574 if (setRoot) {
2575 setRoot(root);
2576 }
2577 else {
2578 result = root;
2579 }
2580 setCurrentRenderingInstance(prev);
2581 return result;
2582 }
2583 /**
2584 * dev only
2585 * In dev mode, template root level comments are rendered, which turns the
2586 * template into a fragment root, but we need to locate the single element
2587 * root for attrs and scope id processing.
2588 */
2589 const getChildRoot = (vnode) => {
2590 const rawChildren = vnode.children;
2591 const dynamicChildren = vnode.dynamicChildren;
2592 const childRoot = filterSingleRoot(rawChildren);
2593 if (!childRoot) {
2594 return [vnode, undefined];
2595 }
2596 const index = rawChildren.indexOf(childRoot);
2597 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2598 const setRoot = (updatedRoot) => {
2599 rawChildren[index] = updatedRoot;
2600 if (dynamicChildren) {
2601 if (dynamicIndex > -1) {
2602 dynamicChildren[dynamicIndex] = updatedRoot;
2603 }
2604 else if (updatedRoot.patchFlag > 0) {
2605 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2606 }
2607 }
2608 };
2609 return [normalizeVNode(childRoot), setRoot];
2610 };
2611 function filterSingleRoot(children) {
2612 let singleRoot;
2613 for (let i = 0; i < children.length; i++) {
2614 const child = children[i];
2615 if (isVNode(child)) {
2616 // ignore user comment
2617 if (child.type !== Comment || child.children === 'v-if') {
2618 if (singleRoot) {
2619 // has more than 1 non-comment child, return now
2620 return;
2621 }
2622 else {
2623 singleRoot = child;
2624 }
2625 }
2626 }
2627 else {
2628 return;
2629 }
2630 }
2631 return singleRoot;
2632 }
2633 const getFunctionalFallthrough = (attrs) => {
2634 let res;
2635 for (const key in attrs) {
2636 if (key === 'class' || key === 'style' || isOn(key)) {
2637 (res || (res = {}))[key] = attrs[key];
2638 }
2639 }
2640 return res;
2641 };
2642 const filterModelListeners = (attrs, props) => {
2643 const res = {};
2644 for (const key in attrs) {
2645 if (!isModelListener(key) || !(key.slice(9) in props)) {
2646 res[key] = attrs[key];
2647 }
2648 }
2649 return res;
2650 };
2651 const isElementRoot = (vnode) => {
2652 return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) ||
2653 vnode.type === Comment // potential v-if branch switch
2654 );
2655 };
2656 function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2657 const { props: prevProps, children: prevChildren, component } = prevVNode;
2658 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2659 const emits = component.emitsOptions;
2660 // Parent component's render function was hot-updated. Since this may have
2661 // caused the child component's slots content to have changed, we need to
2662 // force the child to update as well.
2663 if ((prevChildren || nextChildren) && isHmrUpdating) {
2664 return true;
2665 }
2666 // force child update for runtime directive or transition on component vnode.
2667 if (nextVNode.dirs || nextVNode.transition) {
2668 return true;
2669 }
2670 if (optimized && patchFlag >= 0) {
2671 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2672 // slot content that references values that might have changed,
2673 // e.g. in a v-for
2674 return true;
2675 }
2676 if (patchFlag & 16 /* FULL_PROPS */) {
2677 if (!prevProps) {
2678 return !!nextProps;
2679 }
2680 // presence of this flag indicates props are always non-null
2681 return hasPropsChanged(prevProps, nextProps, emits);
2682 }
2683 else if (patchFlag & 8 /* PROPS */) {
2684 const dynamicProps = nextVNode.dynamicProps;
2685 for (let i = 0; i < dynamicProps.length; i++) {
2686 const key = dynamicProps[i];
2687 if (nextProps[key] !== prevProps[key] &&
2688 !isEmitListener(emits, key)) {
2689 return true;
2690 }
2691 }
2692 }
2693 }
2694 else {
2695 // this path is only taken by manually written render functions
2696 // so presence of any children leads to a forced update
2697 if (prevChildren || nextChildren) {
2698 if (!nextChildren || !nextChildren.$stable) {
2699 return true;
2700 }
2701 }
2702 if (prevProps === nextProps) {
2703 return false;
2704 }
2705 if (!prevProps) {
2706 return !!nextProps;
2707 }
2708 if (!nextProps) {
2709 return true;
2710 }
2711 return hasPropsChanged(prevProps, nextProps, emits);
2712 }
2713 return false;
2714 }
2715 function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2716 const nextKeys = Object.keys(nextProps);
2717 if (nextKeys.length !== Object.keys(prevProps).length) {
2718 return true;
2719 }
2720 for (let i = 0; i < nextKeys.length; i++) {
2721 const key = nextKeys[i];
2722 if (nextProps[key] !== prevProps[key] &&
2723 !isEmitListener(emitsOptions, key)) {
2724 return true;
2725 }
2726 }
2727 return false;
2728 }
2729 function updateHOCHostEl({ vnode, parent }, el // HostNode
2730 ) {
2731 while (parent && parent.subTree === vnode) {
2732 (vnode = parent.vnode).el = el;
2733 parent = parent.parent;
2734 }
2735 }
2736
2737 const isSuspense = (type) => type.__isSuspense;
2738 // Suspense exposes a component-like API, and is treated like a component
2739 // in the compiler, but internally it's a special built-in type that hooks
2740 // directly into the renderer.
2741 const SuspenseImpl = {
2742 name: 'Suspense',
2743 // In order to make Suspense tree-shakable, we need to avoid importing it
2744 // directly in the renderer. The renderer checks for the __isSuspense flag
2745 // on a vnode's type and calls the `process` method, passing in renderer
2746 // internals.
2747 __isSuspense: true,
2748 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2749 // platform-specific impl passed from renderer
2750 rendererInternals) {
2751 if (n1 == null) {
2752 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2753 }
2754 else {
2755 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2756 }
2757 },
2758 hydrate: hydrateSuspense,
2759 create: createSuspenseBoundary,
2760 normalize: normalizeSuspenseChildren
2761 };
2762 // Force-casted public typing for h and TSX props inference
2763 const Suspense = (SuspenseImpl );
2764 function triggerEvent(vnode, name) {
2765 const eventListener = vnode.props && vnode.props[name];
2766 if (isFunction(eventListener)) {
2767 eventListener();
2768 }
2769 }
2770 function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2771 const { p: patch, o: { createElement } } = rendererInternals;
2772 const hiddenContainer = createElement('div');
2773 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2774 // start mounting the content subtree in an off-dom container
2775 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2776 // now check if we have encountered any async deps
2777 if (suspense.deps > 0) {
2778 // has async
2779 // invoke @fallback event
2780 triggerEvent(vnode, 'onPending');
2781 triggerEvent(vnode, 'onFallback');
2782 // mount the fallback tree
2783 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2784 isSVG, slotScopeIds);
2785 setActiveBranch(suspense, vnode.ssFallback);
2786 }
2787 else {
2788 // Suspense has no async deps. Just resolve.
2789 suspense.resolve();
2790 }
2791 }
2792 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2793 const suspense = (n2.suspense = n1.suspense);
2794 suspense.vnode = n2;
2795 n2.el = n1.el;
2796 const newBranch = n2.ssContent;
2797 const newFallback = n2.ssFallback;
2798 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2799 if (pendingBranch) {
2800 suspense.pendingBranch = newBranch;
2801 if (isSameVNodeType(newBranch, pendingBranch)) {
2802 // same root type but content may have changed.
2803 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2804 if (suspense.deps <= 0) {
2805 suspense.resolve();
2806 }
2807 else if (isInFallback) {
2808 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2809 isSVG, slotScopeIds, optimized);
2810 setActiveBranch(suspense, newFallback);
2811 }
2812 }
2813 else {
2814 // toggled before pending tree is resolved
2815 suspense.pendingId++;
2816 if (isHydrating) {
2817 // if toggled before hydration is finished, the current DOM tree is
2818 // no longer valid. set it as the active branch so it will be unmounted
2819 // when resolved
2820 suspense.isHydrating = false;
2821 suspense.activeBranch = pendingBranch;
2822 }
2823 else {
2824 unmount(pendingBranch, parentComponent, suspense);
2825 }
2826 // increment pending ID. this is used to invalidate async callbacks
2827 // reset suspense state
2828 suspense.deps = 0;
2829 // discard effects from pending branch
2830 suspense.effects.length = 0;
2831 // discard previous container
2832 suspense.hiddenContainer = createElement('div');
2833 if (isInFallback) {
2834 // already in fallback state
2835 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2836 if (suspense.deps <= 0) {
2837 suspense.resolve();
2838 }
2839 else {
2840 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2841 isSVG, slotScopeIds, optimized);
2842 setActiveBranch(suspense, newFallback);
2843 }
2844 }
2845 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2846 // toggled "back" to current active branch
2847 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2848 // force resolve
2849 suspense.resolve(true);
2850 }
2851 else {
2852 // switched to a 3rd branch
2853 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2854 if (suspense.deps <= 0) {
2855 suspense.resolve();
2856 }
2857 }
2858 }
2859 }
2860 else {
2861 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2862 // root did not change, just normal patch
2863 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2864 setActiveBranch(suspense, newBranch);
2865 }
2866 else {
2867 // root node toggled
2868 // invoke @pending event
2869 triggerEvent(n2, 'onPending');
2870 // mount pending branch in off-dom container
2871 suspense.pendingBranch = newBranch;
2872 suspense.pendingId++;
2873 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2874 if (suspense.deps <= 0) {
2875 // incoming branch has no async deps, resolve now.
2876 suspense.resolve();
2877 }
2878 else {
2879 const { timeout, pendingId } = suspense;
2880 if (timeout > 0) {
2881 setTimeout(() => {
2882 if (suspense.pendingId === pendingId) {
2883 suspense.fallback(newFallback);
2884 }
2885 }, timeout);
2886 }
2887 else if (timeout === 0) {
2888 suspense.fallback(newFallback);
2889 }
2890 }
2891 }
2892 }
2893 }
2894 let hasWarned = false;
2895 function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2896 /* istanbul ignore if */
2897 if (!hasWarned) {
2898 hasWarned = true;
2899 // @ts-ignore `console.info` cannot be null error
2900 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2901 }
2902 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2903 const timeout = toNumber(vnode.props && vnode.props.timeout);
2904 const suspense = {
2905 vnode,
2906 parent,
2907 parentComponent,
2908 isSVG,
2909 container,
2910 hiddenContainer,
2911 anchor,
2912 deps: 0,
2913 pendingId: 0,
2914 timeout: typeof timeout === 'number' ? timeout : -1,
2915 activeBranch: null,
2916 pendingBranch: null,
2917 isInFallback: true,
2918 isHydrating,
2919 isUnmounted: false,
2920 effects: [],
2921 resolve(resume = false) {
2922 {
2923 if (!resume && !suspense.pendingBranch) {
2924 throw new Error(`suspense.resolve() is called without a pending branch.`);
2925 }
2926 if (suspense.isUnmounted) {
2927 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2928 }
2929 }
2930 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2931 if (suspense.isHydrating) {
2932 suspense.isHydrating = false;
2933 }
2934 else if (!resume) {
2935 const delayEnter = activeBranch &&
2936 pendingBranch.transition &&
2937 pendingBranch.transition.mode === 'out-in';
2938 if (delayEnter) {
2939 activeBranch.transition.afterLeave = () => {
2940 if (pendingId === suspense.pendingId) {
2941 move(pendingBranch, container, anchor, 0 /* ENTER */);
2942 }
2943 };
2944 }
2945 // this is initial anchor on mount
2946 let { anchor } = suspense;
2947 // unmount current active tree
2948 if (activeBranch) {
2949 // if the fallback tree was mounted, it may have been moved
2950 // as part of a parent suspense. get the latest anchor for insertion
2951 anchor = next(activeBranch);
2952 unmount(activeBranch, parentComponent, suspense, true);
2953 }
2954 if (!delayEnter) {
2955 // move content from off-dom container to actual container
2956 move(pendingBranch, container, anchor, 0 /* ENTER */);
2957 }
2958 }
2959 setActiveBranch(suspense, pendingBranch);
2960 suspense.pendingBranch = null;
2961 suspense.isInFallback = false;
2962 // flush buffered effects
2963 // check if there is a pending parent suspense
2964 let parent = suspense.parent;
2965 let hasUnresolvedAncestor = false;
2966 while (parent) {
2967 if (parent.pendingBranch) {
2968 // found a pending parent suspense, merge buffered post jobs
2969 // into that parent
2970 parent.effects.push(...effects);
2971 hasUnresolvedAncestor = true;
2972 break;
2973 }
2974 parent = parent.parent;
2975 }
2976 // no pending parent suspense, flush all jobs
2977 if (!hasUnresolvedAncestor) {
2978 queuePostFlushCb(effects);
2979 }
2980 suspense.effects = [];
2981 // invoke @resolve event
2982 triggerEvent(vnode, 'onResolve');
2983 },
2984 fallback(fallbackVNode) {
2985 if (!suspense.pendingBranch) {
2986 return;
2987 }
2988 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2989 // invoke @fallback event
2990 triggerEvent(vnode, 'onFallback');
2991 const anchor = next(activeBranch);
2992 const mountFallback = () => {
2993 if (!suspense.isInFallback) {
2994 return;
2995 }
2996 // mount the fallback tree
2997 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2998 isSVG, slotScopeIds, optimized);
2999 setActiveBranch(suspense, fallbackVNode);
3000 };
3001 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
3002 if (delayEnter) {
3003 activeBranch.transition.afterLeave = mountFallback;
3004 }
3005 suspense.isInFallback = true;
3006 // unmount current active branch
3007 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
3008 true // shouldRemove
3009 );
3010 if (!delayEnter) {
3011 mountFallback();
3012 }
3013 },
3014 move(container, anchor, type) {
3015 suspense.activeBranch &&
3016 move(suspense.activeBranch, container, anchor, type);
3017 suspense.container = container;
3018 },
3019 next() {
3020 return suspense.activeBranch && next(suspense.activeBranch);
3021 },
3022 registerDep(instance, setupRenderEffect) {
3023 const isInPendingSuspense = !!suspense.pendingBranch;
3024 if (isInPendingSuspense) {
3025 suspense.deps++;
3026 }
3027 const hydratedEl = instance.vnode.el;
3028 instance
3029 .asyncDep.catch(err => {
3030 handleError(err, instance, 0 /* SETUP_FUNCTION */);
3031 })
3032 .then(asyncSetupResult => {
3033 // retry when the setup() promise resolves.
3034 // component may have been unmounted before resolve.
3035 if (instance.isUnmounted ||
3036 suspense.isUnmounted ||
3037 suspense.pendingId !== instance.suspenseId) {
3038 return;
3039 }
3040 // retry from this component
3041 instance.asyncResolved = true;
3042 const { vnode } = instance;
3043 {
3044 pushWarningContext(vnode);
3045 }
3046 handleSetupResult(instance, asyncSetupResult, false);
3047 if (hydratedEl) {
3048 // vnode may have been replaced if an update happened before the
3049 // async dep is resolved.
3050 vnode.el = hydratedEl;
3051 }
3052 const placeholder = !hydratedEl && instance.subTree.el;
3053 setupRenderEffect(instance, vnode,
3054 // component may have been moved before resolve.
3055 // if this is not a hydration, instance.subTree will be the comment
3056 // placeholder.
3057 parentNode(hydratedEl || instance.subTree.el),
3058 // anchor will not be used if this is hydration, so only need to
3059 // consider the comment placeholder case.
3060 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
3061 if (placeholder) {
3062 remove(placeholder);
3063 }
3064 updateHOCHostEl(instance, vnode.el);
3065 {
3066 popWarningContext();
3067 }
3068 // only decrease deps count if suspense is not already resolved
3069 if (isInPendingSuspense && --suspense.deps === 0) {
3070 suspense.resolve();
3071 }
3072 });
3073 },
3074 unmount(parentSuspense, doRemove) {
3075 suspense.isUnmounted = true;
3076 if (suspense.activeBranch) {
3077 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
3078 }
3079 if (suspense.pendingBranch) {
3080 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
3081 }
3082 }
3083 };
3084 return suspense;
3085 }
3086 function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
3087 /* eslint-disable no-restricted-globals */
3088 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
3089 // there are two possible scenarios for server-rendered suspense:
3090 // - success: ssr content should be fully resolved
3091 // - failure: ssr content should be the fallback branch.
3092 // however, on the client we don't really know if it has failed or not
3093 // attempt to hydrate the DOM assuming it has succeeded, but we still
3094 // need to construct a suspense boundary first
3095 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
3096 if (suspense.deps === 0) {
3097 suspense.resolve();
3098 }
3099 return result;
3100 /* eslint-enable no-restricted-globals */
3101 }
3102 function normalizeSuspenseChildren(vnode) {
3103 const { shapeFlag, children } = vnode;
3104 const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
3105 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
3106 vnode.ssFallback = isSlotChildren
3107 ? normalizeSuspenseSlot(children.fallback)
3108 : createVNode(Comment);
3109 }
3110 function normalizeSuspenseSlot(s) {
3111 let block;
3112 if (isFunction(s)) {
3113 const trackBlock = isBlockTreeEnabled && s._c;
3114 if (trackBlock) {
3115 // disableTracking: false
3116 // allow block tracking for compiled slots
3117 // (see ./componentRenderContext.ts)
3118 s._d = false;
3119 openBlock();
3120 }
3121 s = s();
3122 if (trackBlock) {
3123 s._d = true;
3124 block = currentBlock;
3125 closeBlock();
3126 }
3127 }
3128 if (isArray(s)) {
3129 const singleChild = filterSingleRoot(s);
3130 if (!singleChild) {
3131 warn$1(`<Suspense> slots expect a single root node.`);
3132 }
3133 s = singleChild;
3134 }
3135 s = normalizeVNode(s);
3136 if (block && !s.dynamicChildren) {
3137 s.dynamicChildren = block.filter(c => c !== s);
3138 }
3139 return s;
3140 }
3141 function queueEffectWithSuspense(fn, suspense) {
3142 if (suspense && suspense.pendingBranch) {
3143 if (isArray(fn)) {
3144 suspense.effects.push(...fn);
3145 }
3146 else {
3147 suspense.effects.push(fn);
3148 }
3149 }
3150 else {
3151 queuePostFlushCb(fn);
3152 }
3153 }
3154 function setActiveBranch(suspense, branch) {
3155 suspense.activeBranch = branch;
3156 const { vnode, parentComponent } = suspense;
3157 const el = (vnode.el = branch.el);
3158 // in case suspense is the root node of a component,
3159 // recursively update the HOC el
3160 if (parentComponent && parentComponent.subTree === vnode) {
3161 parentComponent.vnode.el = el;
3162 updateHOCHostEl(parentComponent, el);
3163 }
3164 }
3165
3166 function provide(key, value) {
3167 if (!currentInstance) {
3168 {
3169 warn$1(`provide() can only be used inside setup().`);
3170 }
3171 }
3172 else {
3173 let provides = currentInstance.provides;
3174 // by default an instance inherits its parent's provides object
3175 // but when it needs to provide values of its own, it creates its
3176 // own provides object using parent provides object as prototype.
3177 // this way in `inject` we can simply look up injections from direct
3178 // parent and let the prototype chain do the work.
3179 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
3180 if (parentProvides === provides) {
3181 provides = currentInstance.provides = Object.create(parentProvides);
3182 }
3183 // TS doesn't allow symbol as index type
3184 provides[key] = value;
3185 }
3186 }
3187 function inject(key, defaultValue, treatDefaultAsFactory = false) {
3188 // fallback to `currentRenderingInstance` so that this can be called in
3189 // a functional component
3190 const instance = currentInstance || currentRenderingInstance;
3191 if (instance) {
3192 // #2400
3193 // to support `app.use` plugins,
3194 // fallback to appContext's `provides` if the instance is at root
3195 const provides = instance.parent == null
3196 ? instance.vnode.appContext && instance.vnode.appContext.provides
3197 : instance.parent.provides;
3198 if (provides && key in provides) {
3199 // TS doesn't allow symbol as index type
3200 return provides[key];
3201 }
3202 else if (arguments.length > 1) {
3203 return treatDefaultAsFactory && isFunction(defaultValue)
3204 ? defaultValue.call(instance.proxy)
3205 : defaultValue;
3206 }
3207 else {
3208 warn$1(`injection "${String(key)}" not found.`);
3209 }
3210 }
3211 else {
3212 warn$1(`inject() can only be used inside setup() or functional components.`);
3213 }
3214 }
3215
3216 // Simple effect.
3217 function watchEffect(effect, options) {
3218 return doWatch(effect, null, options);
3219 }
3220 function watchPostEffect(effect, options) {
3221 return doWatch(effect, null, (Object.assign(Object.assign({}, options), { flush: 'post' }) ));
3222 }
3223 function watchSyncEffect(effect, options) {
3224 return doWatch(effect, null, (Object.assign(Object.assign({}, options), { flush: 'sync' }) ));
3225 }
3226 // initial value for watchers to trigger on undefined initial values
3227 const INITIAL_WATCHER_VALUE = {};
3228 // implementation
3229 function watch(source, cb, options) {
3230 if (!isFunction(cb)) {
3231 warn$1(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3232 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3233 `supports \`watch(source, cb, options?) signature.`);
3234 }
3235 return doWatch(source, cb, options);
3236 }
3237 function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
3238 if (!cb) {
3239 if (immediate !== undefined) {
3240 warn$1(`watch() "immediate" option is only respected when using the ` +
3241 `watch(source, callback, options?) signature.`);
3242 }
3243 if (deep !== undefined) {
3244 warn$1(`watch() "deep" option is only respected when using the ` +
3245 `watch(source, callback, options?) signature.`);
3246 }
3247 }
3248 const warnInvalidSource = (s) => {
3249 warn$1(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3250 `a reactive object, or an array of these types.`);
3251 };
3252 const instance = currentInstance;
3253 let getter;
3254 let forceTrigger = false;
3255 let isMultiSource = false;
3256 if (isRef(source)) {
3257 getter = () => source.value;
3258 forceTrigger = isShallow(source);
3259 }
3260 else if (isReactive(source)) {
3261 getter = () => source;
3262 deep = true;
3263 }
3264 else if (isArray(source)) {
3265 isMultiSource = true;
3266 forceTrigger = source.some(s => isReactive(s) || isShallow(s));
3267 getter = () => source.map(s => {
3268 if (isRef(s)) {
3269 return s.value;
3270 }
3271 else if (isReactive(s)) {
3272 return traverse(s);
3273 }
3274 else if (isFunction(s)) {
3275 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
3276 }
3277 else {
3278 warnInvalidSource(s);
3279 }
3280 });
3281 }
3282 else if (isFunction(source)) {
3283 if (cb) {
3284 // getter with cb
3285 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
3286 }
3287 else {
3288 // no cb -> simple effect
3289 getter = () => {
3290 if (instance && instance.isUnmounted) {
3291 return;
3292 }
3293 if (cleanup) {
3294 cleanup();
3295 }
3296 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onCleanup]);
3297 };
3298 }
3299 }
3300 else {
3301 getter = NOOP;
3302 warnInvalidSource(source);
3303 }
3304 if (cb && deep) {
3305 const baseGetter = getter;
3306 getter = () => traverse(baseGetter());
3307 }
3308 let cleanup;
3309 let onCleanup = (fn) => {
3310 cleanup = effect.onStop = () => {
3311 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3312 };
3313 };
3314 let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;
3315 const job = () => {
3316 if (!effect.active) {
3317 return;
3318 }
3319 if (cb) {
3320 // watch(source, cb)
3321 const newValue = effect.run();
3322 if (deep ||
3323 forceTrigger ||
3324 (isMultiSource
3325 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
3326 : hasChanged(newValue, oldValue)) ||
3327 (false )) {
3328 // cleanup before running cb again
3329 if (cleanup) {
3330 cleanup();
3331 }
3332 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3333 newValue,
3334 // pass undefined as the old value when it's changed for the first time
3335 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3336 onCleanup
3337 ]);
3338 oldValue = newValue;
3339 }
3340 }
3341 else {
3342 // watchEffect
3343 effect.run();
3344 }
3345 };
3346 // important: mark the job as a watcher callback so that scheduler knows
3347 // it is allowed to self-trigger (#1727)
3348 job.allowRecurse = !!cb;
3349 let scheduler;
3350 if (flush === 'sync') {
3351 scheduler = job; // the scheduler function gets called directly
3352 }
3353 else if (flush === 'post') {
3354 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3355 }
3356 else {
3357 // default: 'pre'
3358 scheduler = () => queuePreFlushCb(job);
3359 }
3360 const effect = new ReactiveEffect(getter, scheduler);
3361 {
3362 effect.onTrack = onTrack;
3363 effect.onTrigger = onTrigger;
3364 }
3365 // initial run
3366 if (cb) {
3367 if (immediate) {
3368 job();
3369 }
3370 else {
3371 oldValue = effect.run();
3372 }
3373 }
3374 else if (flush === 'post') {
3375 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
3376 }
3377 else {
3378 effect.run();
3379 }
3380 return () => {
3381 effect.stop();
3382 if (instance && instance.scope) {
3383 remove(instance.scope.effects, effect);
3384 }
3385 };
3386 }
3387 // this.$watch
3388 function instanceWatch(source, value, options) {
3389 const publicThis = this.proxy;
3390 const getter = isString(source)
3391 ? source.includes('.')
3392 ? createPathGetter(publicThis, source)
3393 : () => publicThis[source]
3394 : source.bind(publicThis, publicThis);
3395 let cb;
3396 if (isFunction(value)) {
3397 cb = value;
3398 }
3399 else {
3400 cb = value.handler;
3401 options = value;
3402 }
3403 const cur = currentInstance;
3404 setCurrentInstance(this);
3405 const res = doWatch(getter, cb.bind(publicThis), options);
3406 if (cur) {
3407 setCurrentInstance(cur);
3408 }
3409 else {
3410 unsetCurrentInstance();
3411 }
3412 return res;
3413 }
3414 function createPathGetter(ctx, path) {
3415 const segments = path.split('.');
3416 return () => {
3417 let cur = ctx;
3418 for (let i = 0; i < segments.length && cur; i++) {
3419 cur = cur[segments[i]];
3420 }
3421 return cur;
3422 };
3423 }
3424 function traverse(value, seen) {
3425 if (!isObject(value) || value["__v_skip" /* SKIP */]) {
3426 return value;
3427 }
3428 seen = seen || new Set();
3429 if (seen.has(value)) {
3430 return value;
3431 }
3432 seen.add(value);
3433 if (isRef(value)) {
3434 traverse(value.value, seen);
3435 }
3436 else if (isArray(value)) {
3437 for (let i = 0; i < value.length; i++) {
3438 traverse(value[i], seen);
3439 }
3440 }
3441 else if (isSet(value) || isMap(value)) {
3442 value.forEach((v) => {
3443 traverse(v, seen);
3444 });
3445 }
3446 else if (isPlainObject(value)) {
3447 for (const key in value) {
3448 traverse(value[key], seen);
3449 }
3450 }
3451 return value;
3452 }
3453
3454 function useTransitionState() {
3455 const state = {
3456 isMounted: false,
3457 isLeaving: false,
3458 isUnmounting: false,
3459 leavingVNodes: new Map()
3460 };
3461 onMounted(() => {
3462 state.isMounted = true;
3463 });
3464 onBeforeUnmount(() => {
3465 state.isUnmounting = true;
3466 });
3467 return state;
3468 }
3469 const TransitionHookValidator = [Function, Array];
3470 const BaseTransitionImpl = {
3471 name: `BaseTransition`,
3472 props: {
3473 mode: String,
3474 appear: Boolean,
3475 persisted: Boolean,
3476 // enter
3477 onBeforeEnter: TransitionHookValidator,
3478 onEnter: TransitionHookValidator,
3479 onAfterEnter: TransitionHookValidator,
3480 onEnterCancelled: TransitionHookValidator,
3481 // leave
3482 onBeforeLeave: TransitionHookValidator,
3483 onLeave: TransitionHookValidator,
3484 onAfterLeave: TransitionHookValidator,
3485 onLeaveCancelled: TransitionHookValidator,
3486 // appear
3487 onBeforeAppear: TransitionHookValidator,
3488 onAppear: TransitionHookValidator,
3489 onAfterAppear: TransitionHookValidator,
3490 onAppearCancelled: TransitionHookValidator
3491 },
3492 setup(props, { slots }) {
3493 const instance = getCurrentInstance();
3494 const state = useTransitionState();
3495 let prevTransitionKey;
3496 return () => {
3497 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3498 if (!children || !children.length) {
3499 return;
3500 }
3501 let child = children[0];
3502 if (children.length > 1) {
3503 let hasFound = false;
3504 // locate first non-comment child
3505 for (const c of children) {
3506 if (c.type !== Comment) {
3507 if (hasFound) {
3508 // warn more than one non-comment child
3509 warn$1('<transition> can only be used on a single element or component. ' +
3510 'Use <transition-group> for lists.');
3511 break;
3512 }
3513 child = c;
3514 hasFound = true;
3515 }
3516 }
3517 }
3518 // there's no need to track reactivity for these props so use the raw
3519 // props for a bit better perf
3520 const rawProps = toRaw(props);
3521 const { mode } = rawProps;
3522 // check mode
3523 if (mode &&
3524 mode !== 'in-out' &&
3525 mode !== 'out-in' &&
3526 mode !== 'default') {
3527 warn$1(`invalid <transition> mode: ${mode}`);
3528 }
3529 if (state.isLeaving) {
3530 return emptyPlaceholder(child);
3531 }
3532 // in the case of <transition><keep-alive/></transition>, we need to
3533 // compare the type of the kept-alive children.
3534 const innerChild = getKeepAliveChild(child);
3535 if (!innerChild) {
3536 return emptyPlaceholder(child);
3537 }
3538 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3539 setTransitionHooks(innerChild, enterHooks);
3540 const oldChild = instance.subTree;
3541 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3542 let transitionKeyChanged = false;
3543 const { getTransitionKey } = innerChild.type;
3544 if (getTransitionKey) {
3545 const key = getTransitionKey();
3546 if (prevTransitionKey === undefined) {
3547 prevTransitionKey = key;
3548 }
3549 else if (key !== prevTransitionKey) {
3550 prevTransitionKey = key;
3551 transitionKeyChanged = true;
3552 }
3553 }
3554 // handle mode
3555 if (oldInnerChild &&
3556 oldInnerChild.type !== Comment &&
3557 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3558 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3559 // update old tree's hooks in case of dynamic transition
3560 setTransitionHooks(oldInnerChild, leavingHooks);
3561 // switching between different views
3562 if (mode === 'out-in') {
3563 state.isLeaving = true;
3564 // return placeholder node and queue update when leave finishes
3565 leavingHooks.afterLeave = () => {
3566 state.isLeaving = false;
3567 instance.update();
3568 };
3569 return emptyPlaceholder(child);
3570 }
3571 else if (mode === 'in-out' && innerChild.type !== Comment) {
3572 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3573 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3574 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3575 // early removal callback
3576 el._leaveCb = () => {
3577 earlyRemove();
3578 el._leaveCb = undefined;
3579 delete enterHooks.delayedLeave;
3580 };
3581 enterHooks.delayedLeave = delayedLeave;
3582 };
3583 }
3584 }
3585 return child;
3586 };
3587 }
3588 };
3589 // export the public type for h/tsx inference
3590 // also to avoid inline import() in generated d.ts files
3591 const BaseTransition = BaseTransitionImpl;
3592 function getLeavingNodesForType(state, vnode) {
3593 const { leavingVNodes } = state;
3594 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3595 if (!leavingVNodesCache) {
3596 leavingVNodesCache = Object.create(null);
3597 leavingVNodes.set(vnode.type, leavingVNodesCache);
3598 }
3599 return leavingVNodesCache;
3600 }
3601 // The transition hooks are attached to the vnode as vnode.transition
3602 // and will be called at appropriate timing in the renderer.
3603 function resolveTransitionHooks(vnode, props, state, instance) {
3604 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3605 const key = String(vnode.key);
3606 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3607 const callHook = (hook, args) => {
3608 hook &&
3609 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3610 };
3611 const callAsyncHook = (hook, args) => {
3612 const done = args[1];
3613 callHook(hook, args);
3614 if (isArray(hook)) {
3615 if (hook.every(hook => hook.length <= 1))
3616 done();
3617 }
3618 else if (hook.length <= 1) {
3619 done();
3620 }
3621 };
3622 const hooks = {
3623 mode,
3624 persisted,
3625 beforeEnter(el) {
3626 let hook = onBeforeEnter;
3627 if (!state.isMounted) {
3628 if (appear) {
3629 hook = onBeforeAppear || onBeforeEnter;
3630 }
3631 else {
3632 return;
3633 }
3634 }
3635 // for same element (v-show)
3636 if (el._leaveCb) {
3637 el._leaveCb(true /* cancelled */);
3638 }
3639 // for toggled element with same key (v-if)
3640 const leavingVNode = leavingVNodesCache[key];
3641 if (leavingVNode &&
3642 isSameVNodeType(vnode, leavingVNode) &&
3643 leavingVNode.el._leaveCb) {
3644 // force early removal (not cancelled)
3645 leavingVNode.el._leaveCb();
3646 }
3647 callHook(hook, [el]);
3648 },
3649 enter(el) {
3650 let hook = onEnter;
3651 let afterHook = onAfterEnter;
3652 let cancelHook = onEnterCancelled;
3653 if (!state.isMounted) {
3654 if (appear) {
3655 hook = onAppear || onEnter;
3656 afterHook = onAfterAppear || onAfterEnter;
3657 cancelHook = onAppearCancelled || onEnterCancelled;
3658 }
3659 else {
3660 return;
3661 }
3662 }
3663 let called = false;
3664 const done = (el._enterCb = (cancelled) => {
3665 if (called)
3666 return;
3667 called = true;
3668 if (cancelled) {
3669 callHook(cancelHook, [el]);
3670 }
3671 else {
3672 callHook(afterHook, [el]);
3673 }
3674 if (hooks.delayedLeave) {
3675 hooks.delayedLeave();
3676 }
3677 el._enterCb = undefined;
3678 });
3679 if (hook) {
3680 callAsyncHook(hook, [el, done]);
3681 }
3682 else {
3683 done();
3684 }
3685 },
3686 leave(el, remove) {
3687 const key = String(vnode.key);
3688 if (el._enterCb) {
3689 el._enterCb(true /* cancelled */);
3690 }
3691 if (state.isUnmounting) {
3692 return remove();
3693 }
3694 callHook(onBeforeLeave, [el]);
3695 let called = false;
3696 const done = (el._leaveCb = (cancelled) => {
3697 if (called)
3698 return;
3699 called = true;
3700 remove();
3701 if (cancelled) {
3702 callHook(onLeaveCancelled, [el]);
3703 }
3704 else {
3705 callHook(onAfterLeave, [el]);
3706 }
3707 el._leaveCb = undefined;
3708 if (leavingVNodesCache[key] === vnode) {
3709 delete leavingVNodesCache[key];
3710 }
3711 });
3712 leavingVNodesCache[key] = vnode;
3713 if (onLeave) {
3714 callAsyncHook(onLeave, [el, done]);
3715 }
3716 else {
3717 done();
3718 }
3719 },
3720 clone(vnode) {
3721 return resolveTransitionHooks(vnode, props, state, instance);
3722 }
3723 };
3724 return hooks;
3725 }
3726 // the placeholder really only handles one special case: KeepAlive
3727 // in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3728 // placeholder with empty content to avoid the KeepAlive instance from being
3729 // unmounted.
3730 function emptyPlaceholder(vnode) {
3731 if (isKeepAlive(vnode)) {
3732 vnode = cloneVNode(vnode);
3733 vnode.children = null;
3734 return vnode;
3735 }
3736 }
3737 function getKeepAliveChild(vnode) {
3738 return isKeepAlive(vnode)
3739 ? vnode.children
3740 ? vnode.children[0]
3741 : undefined
3742 : vnode;
3743 }
3744 function setTransitionHooks(vnode, hooks) {
3745 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3746 setTransitionHooks(vnode.component.subTree, hooks);
3747 }
3748 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3749 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3750 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3751 }
3752 else {
3753 vnode.transition = hooks;
3754 }
3755 }
3756 function getTransitionRawChildren(children, keepComment = false, parentKey) {
3757 let ret = [];
3758 let keyedFragmentCount = 0;
3759 for (let i = 0; i < children.length; i++) {
3760 let child = children[i];
3761 // #5360 inherit parent key in case of <template v-for>
3762 const key = parentKey == null
3763 ? child.key
3764 : String(parentKey) + String(child.key != null ? child.key : i);
3765 // handle fragment children case, e.g. v-for
3766 if (child.type === Fragment) {
3767 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3768 keyedFragmentCount++;
3769 ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key));
3770 }
3771 // comment placeholders should be skipped, e.g. v-if
3772 else if (keepComment || child.type !== Comment) {
3773 ret.push(key != null ? cloneVNode(child, { key }) : child);
3774 }
3775 }
3776 // #1126 if a transition children list contains multiple sub fragments, these
3777 // fragments will be merged into a flat children array. Since each v-for
3778 // fragment may contain different static bindings inside, we need to de-op
3779 // these children to force full diffs to ensure correct behavior.
3780 if (keyedFragmentCount > 1) {
3781 for (let i = 0; i < ret.length; i++) {
3782 ret[i].patchFlag = -2 /* BAIL */;
3783 }
3784 }
3785 return ret;
3786 }
3787
3788 // implementation, close to no-op
3789 function defineComponent(options) {
3790 return isFunction(options) ? { setup: options, name: options.name } : options;
3791 }
3792
3793 const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
3794 function defineAsyncComponent(source) {
3795 if (isFunction(source)) {
3796 source = { loader: source };
3797 }
3798 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
3799 suspensible = true, onError: userOnError } = source;
3800 let pendingRequest = null;
3801 let resolvedComp;
3802 let retries = 0;
3803 const retry = () => {
3804 retries++;
3805 pendingRequest = null;
3806 return load();
3807 };
3808 const load = () => {
3809 let thisRequest;
3810 return (pendingRequest ||
3811 (thisRequest = pendingRequest =
3812 loader()
3813 .catch(err => {
3814 err = err instanceof Error ? err : new Error(String(err));
3815 if (userOnError) {
3816 return new Promise((resolve, reject) => {
3817 const userRetry = () => resolve(retry());
3818 const userFail = () => reject(err);
3819 userOnError(err, userRetry, userFail, retries + 1);
3820 });
3821 }
3822 else {
3823 throw err;
3824 }
3825 })
3826 .then((comp) => {
3827 if (thisRequest !== pendingRequest && pendingRequest) {
3828 return pendingRequest;
3829 }
3830 if (!comp) {
3831 warn$1(`Async component loader resolved to undefined. ` +
3832 `If you are using retry(), make sure to return its return value.`);
3833 }
3834 // interop module default
3835 if (comp &&
3836 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3837 comp = comp.default;
3838 }
3839 if (comp && !isObject(comp) && !isFunction(comp)) {
3840 throw new Error(`Invalid async component load result: ${comp}`);
3841 }
3842 resolvedComp = comp;
3843 return comp;
3844 })));
3845 };
3846 return defineComponent({
3847 name: 'AsyncComponentWrapper',
3848 __asyncLoader: load,
3849 get __asyncResolved() {
3850 return resolvedComp;
3851 },
3852 setup() {
3853 const instance = currentInstance;
3854 // already resolved
3855 if (resolvedComp) {
3856 return () => createInnerComp(resolvedComp, instance);
3857 }
3858 const onError = (err) => {
3859 pendingRequest = null;
3860 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3861 };
3862 // suspense-controlled or SSR.
3863 if ((suspensible && instance.suspense) ||
3864 (false )) {
3865 return load()
3866 .then(comp => {
3867 return () => createInnerComp(comp, instance);
3868 })
3869 .catch(err => {
3870 onError(err);
3871 return () => errorComponent
3872 ? createVNode(errorComponent, {
3873 error: err
3874 })
3875 : null;
3876 });
3877 }
3878 const loaded = ref(false);
3879 const error = ref();
3880 const delayed = ref(!!delay);
3881 if (delay) {
3882 setTimeout(() => {
3883 delayed.value = false;
3884 }, delay);
3885 }
3886 if (timeout != null) {
3887 setTimeout(() => {
3888 if (!loaded.value && !error.value) {
3889 const err = new Error(`Async component timed out after ${timeout}ms.`);
3890 onError(err);
3891 error.value = err;
3892 }
3893 }, timeout);
3894 }
3895 load()
3896 .then(() => {
3897 loaded.value = true;
3898 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3899 // parent is keep-alive, force update so the loaded component's
3900 // name is taken into account
3901 queueJob(instance.parent.update);
3902 }
3903 })
3904 .catch(err => {
3905 onError(err);
3906 error.value = err;
3907 });
3908 return () => {
3909 if (loaded.value && resolvedComp) {
3910 return createInnerComp(resolvedComp, instance);
3911 }
3912 else if (error.value && errorComponent) {
3913 return createVNode(errorComponent, {
3914 error: error.value
3915 });
3916 }
3917 else if (loadingComponent && !delayed.value) {
3918 return createVNode(loadingComponent);
3919 }
3920 };
3921 }
3922 });
3923 }
3924 function createInnerComp(comp, { vnode: { ref, props, children, shapeFlag }, parent }) {
3925 const vnode = createVNode(comp, props, children);
3926 // ensure inner component inherits the async wrapper's ref owner
3927 vnode.ref = ref;
3928 return vnode;
3929 }
3930
3931 const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3932 const KeepAliveImpl = {
3933 name: `KeepAlive`,
3934 // Marker for special handling inside the renderer. We are not using a ===
3935 // check directly on KeepAlive in the renderer, because importing it directly
3936 // would prevent it from being tree-shaken.
3937 __isKeepAlive: true,
3938 props: {
3939 include: [String, RegExp, Array],
3940 exclude: [String, RegExp, Array],
3941 max: [String, Number]
3942 },
3943 setup(props, { slots }) {
3944 const instance = getCurrentInstance();
3945 // KeepAlive communicates with the instantiated renderer via the
3946 // ctx where the renderer passes in its internals,
3947 // and the KeepAlive instance exposes activate/deactivate implementations.
3948 // The whole point of this is to avoid importing KeepAlive directly in the
3949 // renderer to facilitate tree-shaking.
3950 const sharedContext = instance.ctx;
3951 const cache = new Map();
3952 const keys = new Set();
3953 let current = null;
3954 {
3955 instance.__v_cache = cache;
3956 }
3957 const parentSuspense = instance.suspense;
3958 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3959 const storageContainer = createElement('div');
3960 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3961 const instance = vnode.component;
3962 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3963 // in case props have changed
3964 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3965 queuePostRenderEffect(() => {
3966 instance.isDeactivated = false;
3967 if (instance.a) {
3968 invokeArrayFns(instance.a);
3969 }
3970 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3971 if (vnodeHook) {
3972 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3973 }
3974 }, parentSuspense);
3975 {
3976 // Update components tree
3977 devtoolsComponentAdded(instance);
3978 }
3979 };
3980 sharedContext.deactivate = (vnode) => {
3981 const instance = vnode.component;
3982 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3983 queuePostRenderEffect(() => {
3984 if (instance.da) {
3985 invokeArrayFns(instance.da);
3986 }
3987 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3988 if (vnodeHook) {
3989 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3990 }
3991 instance.isDeactivated = true;
3992 }, parentSuspense);
3993 {
3994 // Update components tree
3995 devtoolsComponentAdded(instance);
3996 }
3997 };
3998 function unmount(vnode) {
3999 // reset the shapeFlag so it can be properly unmounted
4000 resetShapeFlag(vnode);
4001 _unmount(vnode, instance, parentSuspense, true);
4002 }
4003 function pruneCache(filter) {
4004 cache.forEach((vnode, key) => {
4005 const name = getComponentName(vnode.type);
4006 if (name && (!filter || !filter(name))) {
4007 pruneCacheEntry(key);
4008 }
4009 });
4010 }
4011 function pruneCacheEntry(key) {
4012 const cached = cache.get(key);
4013 if (!current || cached.type !== current.type) {
4014 unmount(cached);
4015 }
4016 else if (current) {
4017 // current active instance should no longer be kept-alive.
4018 // we can't unmount it now but it might be later, so reset its flag now.
4019 resetShapeFlag(current);
4020 }
4021 cache.delete(key);
4022 keys.delete(key);
4023 }
4024 // prune cache on include/exclude prop change
4025 watch(() => [props.include, props.exclude], ([include, exclude]) => {
4026 include && pruneCache(name => matches(include, name));
4027 exclude && pruneCache(name => !matches(exclude, name));
4028 },
4029 // prune post-render after `current` has been updated
4030 { flush: 'post', deep: true });
4031 // cache sub tree after render
4032 let pendingCacheKey = null;
4033 const cacheSubtree = () => {
4034 // fix #1621, the pendingCacheKey could be 0
4035 if (pendingCacheKey != null) {
4036 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
4037 }
4038 };
4039 onMounted(cacheSubtree);
4040 onUpdated(cacheSubtree);
4041 onBeforeUnmount(() => {
4042 cache.forEach(cached => {
4043 const { subTree, suspense } = instance;
4044 const vnode = getInnerChild(subTree);
4045 if (cached.type === vnode.type) {
4046 // current instance will be unmounted as part of keep-alive's unmount
4047 resetShapeFlag(vnode);
4048 // but invoke its deactivated hook here
4049 const da = vnode.component.da;
4050 da && queuePostRenderEffect(da, suspense);
4051 return;
4052 }
4053 unmount(cached);
4054 });
4055 });
4056 return () => {
4057 pendingCacheKey = null;
4058 if (!slots.default) {
4059 return null;
4060 }
4061 const children = slots.default();
4062 const rawVNode = children[0];
4063 if (children.length > 1) {
4064 {
4065 warn$1(`KeepAlive should contain exactly one component child.`);
4066 }
4067 current = null;
4068 return children;
4069 }
4070 else if (!isVNode(rawVNode) ||
4071 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
4072 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
4073 current = null;
4074 return rawVNode;
4075 }
4076 let vnode = getInnerChild(rawVNode);
4077 const comp = vnode.type;
4078 // for async components, name check should be based in its loaded
4079 // inner component if available
4080 const name = getComponentName(isAsyncWrapper(vnode)
4081 ? vnode.type.__asyncResolved || {}
4082 : comp);
4083 const { include, exclude, max } = props;
4084 if ((include && (!name || !matches(include, name))) ||
4085 (exclude && name && matches(exclude, name))) {
4086 current = vnode;
4087 return rawVNode;
4088 }
4089 const key = vnode.key == null ? comp : vnode.key;
4090 const cachedVNode = cache.get(key);
4091 // clone vnode if it's reused because we are going to mutate it
4092 if (vnode.el) {
4093 vnode = cloneVNode(vnode);
4094 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
4095 rawVNode.ssContent = vnode;
4096 }
4097 }
4098 // #1513 it's possible for the returned vnode to be cloned due to attr
4099 // fallthrough or scopeId, so the vnode here may not be the final vnode
4100 // that is mounted. Instead of caching it directly, we store the pending
4101 // key and cache `instance.subTree` (the normalized vnode) in
4102 // beforeMount/beforeUpdate hooks.
4103 pendingCacheKey = key;
4104 if (cachedVNode) {
4105 // copy over mounted state
4106 vnode.el = cachedVNode.el;
4107 vnode.component = cachedVNode.component;
4108 if (vnode.transition) {
4109 // recursively update transition hooks on subTree
4110 setTransitionHooks(vnode, vnode.transition);
4111 }
4112 // avoid vnode being mounted as fresh
4113 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
4114 // make this key the freshest
4115 keys.delete(key);
4116 keys.add(key);
4117 }
4118 else {
4119 keys.add(key);
4120 // prune oldest entry
4121 if (max && keys.size > parseInt(max, 10)) {
4122 pruneCacheEntry(keys.values().next().value);
4123 }
4124 }
4125 // avoid vnode being unmounted
4126 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4127 current = vnode;
4128 return isSuspense(rawVNode.type) ? rawVNode : vnode;
4129 };
4130 }
4131 };
4132 // export the public type for h/tsx inference
4133 // also to avoid inline import() in generated d.ts files
4134 const KeepAlive = KeepAliveImpl;
4135 function matches(pattern, name) {
4136 if (isArray(pattern)) {
4137 return pattern.some((p) => matches(p, name));
4138 }
4139 else if (isString(pattern)) {
4140 return pattern.split(',').includes(name);
4141 }
4142 else if (pattern.test) {
4143 return pattern.test(name);
4144 }
4145 /* istanbul ignore next */
4146 return false;
4147 }
4148 function onActivated(hook, target) {
4149 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
4150 }
4151 function onDeactivated(hook, target) {
4152 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
4153 }
4154 function registerKeepAliveHook(hook, type, target = currentInstance) {
4155 // cache the deactivate branch check wrapper for injected hooks so the same
4156 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
4157 // deactivation check".
4158 const wrappedHook = hook.__wdc ||
4159 (hook.__wdc = () => {
4160 // only fire the hook if the target instance is NOT in a deactivated branch.
4161 let current = target;
4162 while (current) {
4163 if (current.isDeactivated) {
4164 return;
4165 }
4166 current = current.parent;
4167 }
4168 return hook();
4169 });
4170 injectHook(type, wrappedHook, target);
4171 // In addition to registering it on the target instance, we walk up the parent
4172 // chain and register it on all ancestor instances that are keep-alive roots.
4173 // This avoids the need to walk the entire component tree when invoking these
4174 // hooks, and more importantly, avoids the need to track child components in
4175 // arrays.
4176 if (target) {
4177 let current = target.parent;
4178 while (current && current.parent) {
4179 if (isKeepAlive(current.parent.vnode)) {
4180 injectToKeepAliveRoot(wrappedHook, type, target, current);
4181 }
4182 current = current.parent;
4183 }
4184 }
4185 }
4186 function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
4187 // injectHook wraps the original for error handling, so make sure to remove
4188 // the wrapped version.
4189 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4190 onUnmounted(() => {
4191 remove(keepAliveRoot[type], injected);
4192 }, target);
4193 }
4194 function resetShapeFlag(vnode) {
4195 let shapeFlag = vnode.shapeFlag;
4196 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
4197 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4198 }
4199 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
4200 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
4201 }
4202 vnode.shapeFlag = shapeFlag;
4203 }
4204 function getInnerChild(vnode) {
4205 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
4206 }
4207
4208 function injectHook(type, hook, target = currentInstance, prepend = false) {
4209 if (target) {
4210 const hooks = target[type] || (target[type] = []);
4211 // cache the error handling wrapper for injected hooks so the same hook
4212 // can be properly deduped by the scheduler. "__weh" stands for "with error
4213 // handling".
4214 const wrappedHook = hook.__weh ||
4215 (hook.__weh = (...args) => {
4216 if (target.isUnmounted) {
4217 return;
4218 }
4219 // disable tracking inside all lifecycle hooks
4220 // since they can potentially be called inside effects.
4221 pauseTracking();
4222 // Set currentInstance during hook invocation.
4223 // This assumes the hook does not synchronously trigger other hooks, which
4224 // can only be false when the user does something really funky.
4225 setCurrentInstance(target);
4226 const res = callWithAsyncErrorHandling(hook, target, type, args);
4227 unsetCurrentInstance();
4228 resetTracking();
4229 return res;
4230 });
4231 if (prepend) {
4232 hooks.unshift(wrappedHook);
4233 }
4234 else {
4235 hooks.push(wrappedHook);
4236 }
4237 return wrappedHook;
4238 }
4239 else {
4240 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
4241 warn$1(`${apiName} is called when there is no active component instance to be ` +
4242 `associated with. ` +
4243 `Lifecycle injection APIs can only be used during execution of setup().` +
4244 (` If you are using async setup(), make sure to register lifecycle ` +
4245 `hooks before the first await statement.`
4246 ));
4247 }
4248 }
4249 const createHook = (lifecycle) => (hook, target = currentInstance) =>
4250 // post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
4251 (!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
4252 injectHook(lifecycle, hook, target);
4253 const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
4254 const onMounted = createHook("m" /* MOUNTED */);
4255 const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
4256 const onUpdated = createHook("u" /* UPDATED */);
4257 const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
4258 const onUnmounted = createHook("um" /* UNMOUNTED */);
4259 const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
4260 const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
4261 const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
4262 function onErrorCaptured(hook, target = currentInstance) {
4263 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
4264 }
4265
4266 /**
4267 Runtime helper for applying directives to a vnode. Example usage:
4268
4269 const comp = resolveComponent('comp')
4270 const foo = resolveDirective('foo')
4271 const bar = resolveDirective('bar')
4272
4273 return withDirectives(h(comp), [
4274 [foo, this.x],
4275 [bar, this.y]
4276 ])
4277 */
4278 function validateDirectiveName(name) {
4279 if (isBuiltInDirective(name)) {
4280 warn$1('Do not use built-in directive ids as custom directive id: ' + name);
4281 }
4282 }
4283 /**
4284 * Adds directives to a VNode.
4285 */
4286 function withDirectives(vnode, directives) {
4287 const internalInstance = currentRenderingInstance;
4288 if (internalInstance === null) {
4289 warn$1(`withDirectives can only be used inside render functions.`);
4290 return vnode;
4291 }
4292 const instance = getExposeProxy(internalInstance) ||
4293 internalInstance.proxy;
4294 const bindings = vnode.dirs || (vnode.dirs = []);
4295 for (let i = 0; i < directives.length; i++) {
4296 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4297 if (isFunction(dir)) {
4298 dir = {
4299 mounted: dir,
4300 updated: dir
4301 };
4302 }
4303 if (dir.deep) {
4304 traverse(value);
4305 }
4306 bindings.push({
4307 dir,
4308 instance,
4309 value,
4310 oldValue: void 0,
4311 arg,
4312 modifiers
4313 });
4314 }
4315 return vnode;
4316 }
4317 function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4318 const bindings = vnode.dirs;
4319 const oldBindings = prevVNode && prevVNode.dirs;
4320 for (let i = 0; i < bindings.length; i++) {
4321 const binding = bindings[i];
4322 if (oldBindings) {
4323 binding.oldValue = oldBindings[i].value;
4324 }
4325 let hook = binding.dir[name];
4326 if (hook) {
4327 // disable tracking inside all lifecycle hooks
4328 // since they can potentially be called inside effects.
4329 pauseTracking();
4330 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4331 vnode.el,
4332 binding,
4333 vnode,
4334 prevVNode
4335 ]);
4336 resetTracking();
4337 }
4338 }
4339 }
4340
4341 const COMPONENTS = 'components';
4342 const DIRECTIVES = 'directives';
4343 /**
4344 * @private
4345 */
4346 function resolveComponent(name, maybeSelfReference) {
4347 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
4348 }
4349 const NULL_DYNAMIC_COMPONENT = Symbol();
4350 /**
4351 * @private
4352 */
4353 function resolveDynamicComponent(component) {
4354 if (isString(component)) {
4355 return resolveAsset(COMPONENTS, component, false) || component;
4356 }
4357 else {
4358 // invalid types will fallthrough to createVNode and raise warning
4359 return (component || NULL_DYNAMIC_COMPONENT);
4360 }
4361 }
4362 /**
4363 * @private
4364 */
4365 function resolveDirective(name) {
4366 return resolveAsset(DIRECTIVES, name);
4367 }
4368 // implementation
4369 function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
4370 const instance = currentRenderingInstance || currentInstance;
4371 if (instance) {
4372 const Component = instance.type;
4373 // explicit self name has highest priority
4374 if (type === COMPONENTS) {
4375 const selfName = getComponentName(Component);
4376 if (selfName &&
4377 (selfName === name ||
4378 selfName === camelize(name) ||
4379 selfName === capitalize(camelize(name)))) {
4380 return Component;
4381 }
4382 }
4383 const res =
4384 // local registration
4385 // check instance[type] first which is resolved for options API
4386 resolve(instance[type] || Component[type], name) ||
4387 // global registration
4388 resolve(instance.appContext[type], name);
4389 if (!res && maybeSelfReference) {
4390 // fallback to implicit self-reference
4391 return Component;
4392 }
4393 if (warnMissing && !res) {
4394 const extra = type === COMPONENTS
4395 ? `\nIf this is a native custom element, make sure to exclude it from ` +
4396 `component resolution via compilerOptions.isCustomElement.`
4397 : ``;
4398 warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
4399 }
4400 return res;
4401 }
4402 else {
4403 warn$1(`resolve${capitalize(type.slice(0, -1))} ` +
4404 `can only be used in render() or setup().`);
4405 }
4406 }
4407 function resolve(registry, name) {
4408 return (registry &&
4409 (registry[name] ||
4410 registry[camelize(name)] ||
4411 registry[capitalize(camelize(name))]));
4412 }
4413
4414 /**
4415 * Actual implementation
4416 */
4417 function renderList(source, renderItem, cache, index) {
4418 let ret;
4419 const cached = (cache && cache[index]);
4420 if (isArray(source) || isString(source)) {
4421 ret = new Array(source.length);
4422 for (let i = 0, l = source.length; i < l; i++) {
4423 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
4424 }
4425 }
4426 else if (typeof source === 'number') {
4427 if (!Number.isInteger(source)) {
4428 warn$1(`The v-for range expect an integer value but got ${source}.`);
4429 }
4430 ret = new Array(source);
4431 for (let i = 0; i < source; i++) {
4432 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
4433 }
4434 }
4435 else if (isObject(source)) {
4436 if (source[Symbol.iterator]) {
4437 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
4438 }
4439 else {
4440 const keys = Object.keys(source);
4441 ret = new Array(keys.length);
4442 for (let i = 0, l = keys.length; i < l; i++) {
4443 const key = keys[i];
4444 ret[i] = renderItem(source[key], key, i, cached && cached[i]);
4445 }
4446 }
4447 }
4448 else {
4449 ret = [];
4450 }
4451 if (cache) {
4452 cache[index] = ret;
4453 }
4454 return ret;
4455 }
4456
4457 /**
4458 * Compiler runtime helper for creating dynamic slots object
4459 * @private
4460 */
4461 function createSlots(slots, dynamicSlots) {
4462 for (let i = 0; i < dynamicSlots.length; i++) {
4463 const slot = dynamicSlots[i];
4464 // array of dynamic slot generated by <template v-for="..." #[...]>
4465 if (isArray(slot)) {
4466 for (let j = 0; j < slot.length; j++) {
4467 slots[slot[j].name] = slot[j].fn;
4468 }
4469 }
4470 else if (slot) {
4471 // conditional single slot generated by <template v-if="..." #foo>
4472 slots[slot.name] = slot.fn;
4473 }
4474 }
4475 return slots;
4476 }
4477
4478 /**
4479 * Compiler runtime helper for rendering `<slot/>`
4480 * @private
4481 */
4482 function renderSlot(slots, name, props = {},
4483 // this is not a user-facing function, so the fallback is always generated by
4484 // the compiler and guaranteed to be a function returning an array
4485 fallback, noSlotted) {
4486 if (currentRenderingInstance.isCE ||
4487 (currentRenderingInstance.parent &&
4488 isAsyncWrapper(currentRenderingInstance.parent) &&
4489 currentRenderingInstance.parent.isCE)) {
4490 return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback());
4491 }
4492 let slot = slots[name];
4493 if (slot && slot.length > 1) {
4494 warn$1(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
4495 `function. You need to mark this component with $dynamic-slots in the ` +
4496 `parent template.`);
4497 slot = () => [];
4498 }
4499 // a compiled slot disables block tracking by default to avoid manual
4500 // invocation interfering with template-based block tracking, but in
4501 // `renderSlot` we can be sure that it's template-based so we can force
4502 // enable it.
4503 if (slot && slot._c) {
4504 slot._d = false;
4505 }
4506 openBlock();
4507 const validSlotContent = slot && ensureValidVNode(slot(props));
4508 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
4509 ? 64 /* STABLE_FRAGMENT */
4510 : -2 /* BAIL */);
4511 if (!noSlotted && rendered.scopeId) {
4512 rendered.slotScopeIds = [rendered.scopeId + '-s'];
4513 }
4514 if (slot && slot._c) {
4515 slot._d = true;
4516 }
4517 return rendered;
4518 }
4519 function ensureValidVNode(vnodes) {
4520 return vnodes.some(child => {
4521 if (!isVNode(child))
4522 return true;
4523 if (child.type === Comment)
4524 return false;
4525 if (child.type === Fragment &&
4526 !ensureValidVNode(child.children))
4527 return false;
4528 return true;
4529 })
4530 ? vnodes
4531 : null;
4532 }
4533
4534 /**
4535 * For prefixing keys in v-on="obj" with "on"
4536 * @private
4537 */
4538 function toHandlers(obj) {
4539 const ret = {};
4540 if (!isObject(obj)) {
4541 warn$1(`v-on with no argument expects an object value.`);
4542 return ret;
4543 }
4544 for (const key in obj) {
4545 ret[toHandlerKey(key)] = obj[key];
4546 }
4547 return ret;
4548 }
4549
4550 /**
4551 * #2437 In Vue 3, functional components do not have a public instance proxy but
4552 * they exist in the internal parent chain. For code that relies on traversing
4553 * public $parent chains, skip functional ones and go to the parent instead.
4554 */
4555 const getPublicInstance = (i) => {
4556 if (!i)
4557 return null;
4558 if (isStatefulComponent(i))
4559 return getExposeProxy(i) || i.proxy;
4560 return getPublicInstance(i.parent);
4561 };
4562 const publicPropertiesMap =
4563 // Move PURE marker to new line to workaround compiler discarding it
4564 // due to type annotation
4565 /*#__PURE__*/ extend(Object.create(null), {
4566 $: i => i,
4567 $el: i => i.vnode.el,
4568 $data: i => i.data,
4569 $props: i => (shallowReadonly(i.props) ),
4570 $attrs: i => (shallowReadonly(i.attrs) ),
4571 $slots: i => (shallowReadonly(i.slots) ),
4572 $refs: i => (shallowReadonly(i.refs) ),
4573 $parent: i => getPublicInstance(i.parent),
4574 $root: i => getPublicInstance(i.root),
4575 $emit: i => i.emit,
4576 $options: i => (resolveMergedOptions(i) ),
4577 $forceUpdate: i => i.f || (i.f = () => queueJob(i.update)),
4578 $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)),
4579 $watch: i => (instanceWatch.bind(i) )
4580 });
4581 const isReservedPrefix = (key) => key === '_' || key === '$';
4582 const PublicInstanceProxyHandlers = {
4583 get({ _: instance }, key) {
4584 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
4585 // for internal formatters to know that this is a Vue instance
4586 if (key === '__isVue') {
4587 return true;
4588 }
4589 // prioritize <script setup> bindings during dev.
4590 // this allows even properties that start with _ or $ to be used - so that
4591 // it aligns with the production behavior where the render fn is inlined and
4592 // indeed has access to all declared variables.
4593 if (setupState !== EMPTY_OBJ &&
4594 setupState.__isScriptSetup &&
4595 hasOwn(setupState, key)) {
4596 return setupState[key];
4597 }
4598 // data / props / ctx
4599 // This getter gets called for every property access on the render context
4600 // during render and is a major hotspot. The most expensive part of this
4601 // is the multiple hasOwn() calls. It's much faster to do a simple property
4602 // access on a plain object, so we use an accessCache object (with null
4603 // prototype) to memoize what access type a key corresponds to.
4604 let normalizedProps;
4605 if (key[0] !== '$') {
4606 const n = accessCache[key];
4607 if (n !== undefined) {
4608 switch (n) {
4609 case 1 /* SETUP */:
4610 return setupState[key];
4611 case 2 /* DATA */:
4612 return data[key];
4613 case 4 /* CONTEXT */:
4614 return ctx[key];
4615 case 3 /* PROPS */:
4616 return props[key];
4617 // default: just fallthrough
4618 }
4619 }
4620 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
4621 accessCache[key] = 1 /* SETUP */;
4622 return setupState[key];
4623 }
4624 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4625 accessCache[key] = 2 /* DATA */;
4626 return data[key];
4627 }
4628 else if (
4629 // only cache other properties when instance has declared (thus stable)
4630 // props
4631 (normalizedProps = instance.propsOptions[0]) &&
4632 hasOwn(normalizedProps, key)) {
4633 accessCache[key] = 3 /* PROPS */;
4634 return props[key];
4635 }
4636 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4637 accessCache[key] = 4 /* CONTEXT */;
4638 return ctx[key];
4639 }
4640 else if (shouldCacheAccess) {
4641 accessCache[key] = 0 /* OTHER */;
4642 }
4643 }
4644 const publicGetter = publicPropertiesMap[key];
4645 let cssModule, globalProperties;
4646 // public $xxx properties
4647 if (publicGetter) {
4648 if (key === '$attrs') {
4649 track(instance, "get" /* GET */, key);
4650 markAttrsAccessed();
4651 }
4652 return publicGetter(instance);
4653 }
4654 else if (
4655 // css module (injected by vue-loader)
4656 (cssModule = type.__cssModules) &&
4657 (cssModule = cssModule[key])) {
4658 return cssModule;
4659 }
4660 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4661 // user may set custom properties to `this` that start with `$`
4662 accessCache[key] = 4 /* CONTEXT */;
4663 return ctx[key];
4664 }
4665 else if (
4666 // global properties
4667 ((globalProperties = appContext.config.globalProperties),
4668 hasOwn(globalProperties, key))) {
4669 {
4670 return globalProperties[key];
4671 }
4672 }
4673 else if (currentRenderingInstance &&
4674 (!isString(key) ||
4675 // #1091 avoid internal isRef/isVNode checks on component instance leading
4676 // to infinite warning loop
4677 key.indexOf('__v') !== 0)) {
4678 if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {
4679 warn$1(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
4680 `character ("$" or "_") and is not proxied on the render context.`);
4681 }
4682 else if (instance === currentRenderingInstance) {
4683 warn$1(`Property ${JSON.stringify(key)} was accessed during render ` +
4684 `but is not defined on instance.`);
4685 }
4686 }
4687 },
4688 set({ _: instance }, key, value) {
4689 const { data, setupState, ctx } = instance;
4690 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
4691 setupState[key] = value;
4692 return true;
4693 }
4694 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4695 data[key] = value;
4696 return true;
4697 }
4698 else if (hasOwn(instance.props, key)) {
4699 warn$1(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
4700 return false;
4701 }
4702 if (key[0] === '$' && key.slice(1) in instance) {
4703 warn$1(`Attempting to mutate public property "${key}". ` +
4704 `Properties starting with $ are reserved and readonly.`, instance);
4705 return false;
4706 }
4707 else {
4708 if (key in instance.appContext.config.globalProperties) {
4709 Object.defineProperty(ctx, key, {
4710 enumerable: true,
4711 configurable: true,
4712 value
4713 });
4714 }
4715 else {
4716 ctx[key] = value;
4717 }
4718 }
4719 return true;
4720 },
4721 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
4722 let normalizedProps;
4723 return (!!accessCache[key] ||
4724 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
4725 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
4726 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
4727 hasOwn(ctx, key) ||
4728 hasOwn(publicPropertiesMap, key) ||
4729 hasOwn(appContext.config.globalProperties, key));
4730 },
4731 defineProperty(target, key, descriptor) {
4732 if (descriptor.get != null) {
4733 // invalidate key cache of a getter based property #5417
4734 target._.accessCache[key] = 0;
4735 }
4736 else if (hasOwn(descriptor, 'value')) {
4737 this.set(target, key, descriptor.value, null);
4738 }
4739 return Reflect.defineProperty(target, key, descriptor);
4740 }
4741 };
4742 {
4743 PublicInstanceProxyHandlers.ownKeys = (target) => {
4744 warn$1(`Avoid app logic that relies on enumerating keys on a component instance. ` +
4745 `The keys will be empty in production mode to avoid performance overhead.`);
4746 return Reflect.ownKeys(target);
4747 };
4748 }
4749 const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, {
4750 get(target, key) {
4751 // fast path for unscopables when using `with` block
4752 if (key === Symbol.unscopables) {
4753 return;
4754 }
4755 return PublicInstanceProxyHandlers.get(target, key, target);
4756 },
4757 has(_, key) {
4758 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
4759 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
4760 warn$1(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
4761 }
4762 return has;
4763 }
4764 });
4765 // dev only
4766 // In dev mode, the proxy target exposes the same properties as seen on `this`
4767 // for easier console inspection. In prod mode it will be an empty object so
4768 // these properties definitions can be skipped.
4769 function createDevRenderContext(instance) {
4770 const target = {};
4771 // expose internal instance for proxy handlers
4772 Object.defineProperty(target, `_`, {
4773 configurable: true,
4774 enumerable: false,
4775 get: () => instance
4776 });
4777 // expose public properties
4778 Object.keys(publicPropertiesMap).forEach(key => {
4779 Object.defineProperty(target, key, {
4780 configurable: true,
4781 enumerable: false,
4782 get: () => publicPropertiesMap[key](instance),
4783 // intercepted by the proxy so no need for implementation,
4784 // but needed to prevent set errors
4785 set: NOOP
4786 });
4787 });
4788 return target;
4789 }
4790 // dev only
4791 function exposePropsOnRenderContext(instance) {
4792 const { ctx, propsOptions: [propsOptions] } = instance;
4793 if (propsOptions) {
4794 Object.keys(propsOptions).forEach(key => {
4795 Object.defineProperty(ctx, key, {
4796 enumerable: true,
4797 configurable: true,
4798 get: () => instance.props[key],
4799 set: NOOP
4800 });
4801 });
4802 }
4803 }
4804 // dev only
4805 function exposeSetupStateOnRenderContext(instance) {
4806 const { ctx, setupState } = instance;
4807 Object.keys(toRaw(setupState)).forEach(key => {
4808 if (!setupState.__isScriptSetup) {
4809 if (isReservedPrefix(key[0])) {
4810 warn$1(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
4811 `which are reserved prefixes for Vue internals.`);
4812 return;
4813 }
4814 Object.defineProperty(ctx, key, {
4815 enumerable: true,
4816 configurable: true,
4817 get: () => setupState[key],
4818 set: NOOP
4819 });
4820 }
4821 });
4822 }
4823
4824 function createDuplicateChecker() {
4825 const cache = Object.create(null);
4826 return (type, key) => {
4827 if (cache[key]) {
4828 warn$1(`${type} property "${key}" is already defined in ${cache[key]}.`);
4829 }
4830 else {
4831 cache[key] = type;
4832 }
4833 };
4834 }
4835 let shouldCacheAccess = true;
4836 function applyOptions(instance) {
4837 const options = resolveMergedOptions(instance);
4838 const publicThis = instance.proxy;
4839 const ctx = instance.ctx;
4840 // do not cache property access on public proxy during state initialization
4841 shouldCacheAccess = false;
4842 // call beforeCreate first before accessing other options since
4843 // the hook may mutate resolved options (#2791)
4844 if (options.beforeCreate) {
4845 callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
4846 }
4847 const {
4848 // state
4849 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
4850 // lifecycle
4851 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
4852 // public API
4853 expose, inheritAttrs,
4854 // assets
4855 components, directives, filters } = options;
4856 const checkDuplicateProperties = createDuplicateChecker() ;
4857 {
4858 const [propsOptions] = instance.propsOptions;
4859 if (propsOptions) {
4860 for (const key in propsOptions) {
4861 checkDuplicateProperties("Props" /* PROPS */, key);
4862 }
4863 }
4864 }
4865 // options initialization order (to be consistent with Vue 2):
4866 // - props (already done outside of this function)
4867 // - inject
4868 // - methods
4869 // - data (deferred since it relies on `this` access)
4870 // - computed
4871 // - watch (deferred since it relies on `this` access)
4872 if (injectOptions) {
4873 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
4874 }
4875 if (methods) {
4876 for (const key in methods) {
4877 const methodHandler = methods[key];
4878 if (isFunction(methodHandler)) {
4879 // In dev mode, we use the `createRenderContext` function to define
4880 // methods to the proxy target, and those are read-only but
4881 // reconfigurable, so it needs to be redefined here
4882 {
4883 Object.defineProperty(ctx, key, {
4884 value: methodHandler.bind(publicThis),
4885 configurable: true,
4886 enumerable: true,
4887 writable: true
4888 });
4889 }
4890 {
4891 checkDuplicateProperties("Methods" /* METHODS */, key);
4892 }
4893 }
4894 else {
4895 warn$1(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
4896 `Did you reference the function correctly?`);
4897 }
4898 }
4899 }
4900 if (dataOptions) {
4901 if (!isFunction(dataOptions)) {
4902 warn$1(`The data option must be a function. ` +
4903 `Plain object usage is no longer supported.`);
4904 }
4905 const data = dataOptions.call(publicThis, publicThis);
4906 if (isPromise(data)) {
4907 warn$1(`data() returned a Promise - note data() cannot be async; If you ` +
4908 `intend to perform data fetching before component renders, use ` +
4909 `async setup() + <Suspense>.`);
4910 }
4911 if (!isObject(data)) {
4912 warn$1(`data() should return an object.`);
4913 }
4914 else {
4915 instance.data = reactive(data);
4916 {
4917 for (const key in data) {
4918 checkDuplicateProperties("Data" /* DATA */, key);
4919 // expose data on ctx during dev
4920 if (!isReservedPrefix(key[0])) {
4921 Object.defineProperty(ctx, key, {
4922 configurable: true,
4923 enumerable: true,
4924 get: () => data[key],
4925 set: NOOP
4926 });
4927 }
4928 }
4929 }
4930 }
4931 }
4932 // state initialization complete at this point - start caching access
4933 shouldCacheAccess = true;
4934 if (computedOptions) {
4935 for (const key in computedOptions) {
4936 const opt = computedOptions[key];
4937 const get = isFunction(opt)
4938 ? opt.bind(publicThis, publicThis)
4939 : isFunction(opt.get)
4940 ? opt.get.bind(publicThis, publicThis)
4941 : NOOP;
4942 if (get === NOOP) {
4943 warn$1(`Computed property "${key}" has no getter.`);
4944 }
4945 const set = !isFunction(opt) && isFunction(opt.set)
4946 ? opt.set.bind(publicThis)
4947 : () => {
4948 warn$1(`Write operation failed: computed property "${key}" is readonly.`);
4949 }
4950 ;
4951 const c = computed$1({
4952 get,
4953 set
4954 });
4955 Object.defineProperty(ctx, key, {
4956 enumerable: true,
4957 configurable: true,
4958 get: () => c.value,
4959 set: v => (c.value = v)
4960 });
4961 {
4962 checkDuplicateProperties("Computed" /* COMPUTED */, key);
4963 }
4964 }
4965 }
4966 if (watchOptions) {
4967 for (const key in watchOptions) {
4968 createWatcher(watchOptions[key], ctx, publicThis, key);
4969 }
4970 }
4971 if (provideOptions) {
4972 const provides = isFunction(provideOptions)
4973 ? provideOptions.call(publicThis)
4974 : provideOptions;
4975 Reflect.ownKeys(provides).forEach(key => {
4976 provide(key, provides[key]);
4977 });
4978 }
4979 if (created) {
4980 callHook(created, instance, "c" /* CREATED */);
4981 }
4982 function registerLifecycleHook(register, hook) {
4983 if (isArray(hook)) {
4984 hook.forEach(_hook => register(_hook.bind(publicThis)));
4985 }
4986 else if (hook) {
4987 register(hook.bind(publicThis));
4988 }
4989 }
4990 registerLifecycleHook(onBeforeMount, beforeMount);
4991 registerLifecycleHook(onMounted, mounted);
4992 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
4993 registerLifecycleHook(onUpdated, updated);
4994 registerLifecycleHook(onActivated, activated);
4995 registerLifecycleHook(onDeactivated, deactivated);
4996 registerLifecycleHook(onErrorCaptured, errorCaptured);
4997 registerLifecycleHook(onRenderTracked, renderTracked);
4998 registerLifecycleHook(onRenderTriggered, renderTriggered);
4999 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
5000 registerLifecycleHook(onUnmounted, unmounted);
5001 registerLifecycleHook(onServerPrefetch, serverPrefetch);
5002 if (isArray(expose)) {
5003 if (expose.length) {
5004 const exposed = instance.exposed || (instance.exposed = {});
5005 expose.forEach(key => {
5006 Object.defineProperty(exposed, key, {
5007 get: () => publicThis[key],
5008 set: val => (publicThis[key] = val)
5009 });
5010 });
5011 }
5012 else if (!instance.exposed) {
5013 instance.exposed = {};
5014 }
5015 }
5016 // options that are handled when creating the instance but also need to be
5017 // applied from mixins
5018 if (render && instance.render === NOOP) {
5019 instance.render = render;
5020 }
5021 if (inheritAttrs != null) {
5022 instance.inheritAttrs = inheritAttrs;
5023 }
5024 // asset options.
5025 if (components)
5026 instance.components = components;
5027 if (directives)
5028 instance.directives = directives;
5029 }
5030 function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
5031 if (isArray(injectOptions)) {
5032 injectOptions = normalizeInject(injectOptions);
5033 }
5034 for (const key in injectOptions) {
5035 const opt = injectOptions[key];
5036 let injected;
5037 if (isObject(opt)) {
5038 if ('default' in opt) {
5039 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
5040 }
5041 else {
5042 injected = inject(opt.from || key);
5043 }
5044 }
5045 else {
5046 injected = inject(opt);
5047 }
5048 if (isRef(injected)) {
5049 // TODO remove the check in 3.3
5050 if (unwrapRef) {
5051 Object.defineProperty(ctx, key, {
5052 enumerable: true,
5053 configurable: true,
5054 get: () => injected.value,
5055 set: v => (injected.value = v)
5056 });
5057 }
5058 else {
5059 {
5060 warn$1(`injected property "${key}" is a ref and will be auto-unwrapped ` +
5061 `and no longer needs \`.value\` in the next minor release. ` +
5062 `To opt-in to the new behavior now, ` +
5063 `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
5064 `temporary and will not be needed in the future.)`);
5065 }
5066 ctx[key] = injected;
5067 }
5068 }
5069 else {
5070 ctx[key] = injected;
5071 }
5072 {
5073 checkDuplicateProperties("Inject" /* INJECT */, key);
5074 }
5075 }
5076 }
5077 function callHook(hook, instance, type) {
5078 callWithAsyncErrorHandling(isArray(hook)
5079 ? hook.map(h => h.bind(instance.proxy))
5080 : hook.bind(instance.proxy), instance, type);
5081 }
5082 function createWatcher(raw, ctx, publicThis, key) {
5083 const getter = key.includes('.')
5084 ? createPathGetter(publicThis, key)
5085 : () => publicThis[key];
5086 if (isString(raw)) {
5087 const handler = ctx[raw];
5088 if (isFunction(handler)) {
5089 watch(getter, handler);
5090 }
5091 else {
5092 warn$1(`Invalid watch handler specified by key "${raw}"`, handler);
5093 }
5094 }
5095 else if (isFunction(raw)) {
5096 watch(getter, raw.bind(publicThis));
5097 }
5098 else if (isObject(raw)) {
5099 if (isArray(raw)) {
5100 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
5101 }
5102 else {
5103 const handler = isFunction(raw.handler)
5104 ? raw.handler.bind(publicThis)
5105 : ctx[raw.handler];
5106 if (isFunction(handler)) {
5107 watch(getter, handler, raw);
5108 }
5109 else {
5110 warn$1(`Invalid watch handler specified by key "${raw.handler}"`, handler);
5111 }
5112 }
5113 }
5114 else {
5115 warn$1(`Invalid watch option: "${key}"`, raw);
5116 }
5117 }
5118 /**
5119 * Resolve merged options and cache it on the component.
5120 * This is done only once per-component since the merging does not involve
5121 * instances.
5122 */
5123 function resolveMergedOptions(instance) {
5124 const base = instance.type;
5125 const { mixins, extends: extendsOptions } = base;
5126 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
5127 const cached = cache.get(base);
5128 let resolved;
5129 if (cached) {
5130 resolved = cached;
5131 }
5132 else if (!globalMixins.length && !mixins && !extendsOptions) {
5133 {
5134 resolved = base;
5135 }
5136 }
5137 else {
5138 resolved = {};
5139 if (globalMixins.length) {
5140 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
5141 }
5142 mergeOptions(resolved, base, optionMergeStrategies);
5143 }
5144 cache.set(base, resolved);
5145 return resolved;
5146 }
5147 function mergeOptions(to, from, strats, asMixin = false) {
5148 const { mixins, extends: extendsOptions } = from;
5149 if (extendsOptions) {
5150 mergeOptions(to, extendsOptions, strats, true);
5151 }
5152 if (mixins) {
5153 mixins.forEach((m) => mergeOptions(to, m, strats, true));
5154 }
5155 for (const key in from) {
5156 if (asMixin && key === 'expose') {
5157 warn$1(`"expose" option is ignored when declared in mixins or extends. ` +
5158 `It should only be declared in the base component itself.`);
5159 }
5160 else {
5161 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
5162 to[key] = strat ? strat(to[key], from[key]) : from[key];
5163 }
5164 }
5165 return to;
5166 }
5167 const internalOptionMergeStrats = {
5168 data: mergeDataFn,
5169 props: mergeObjectOptions,
5170 emits: mergeObjectOptions,
5171 // objects
5172 methods: mergeObjectOptions,
5173 computed: mergeObjectOptions,
5174 // lifecycle
5175 beforeCreate: mergeAsArray,
5176 created: mergeAsArray,
5177 beforeMount: mergeAsArray,
5178 mounted: mergeAsArray,
5179 beforeUpdate: mergeAsArray,
5180 updated: mergeAsArray,
5181 beforeDestroy: mergeAsArray,
5182 beforeUnmount: mergeAsArray,
5183 destroyed: mergeAsArray,
5184 unmounted: mergeAsArray,
5185 activated: mergeAsArray,
5186 deactivated: mergeAsArray,
5187 errorCaptured: mergeAsArray,
5188 serverPrefetch: mergeAsArray,
5189 // assets
5190 components: mergeObjectOptions,
5191 directives: mergeObjectOptions,
5192 // watch
5193 watch: mergeWatchOptions,
5194 // provide / inject
5195 provide: mergeDataFn,
5196 inject: mergeInject
5197 };
5198 function mergeDataFn(to, from) {
5199 if (!from) {
5200 return to;
5201 }
5202 if (!to) {
5203 return from;
5204 }
5205 return function mergedDataFn() {
5206 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
5207 };
5208 }
5209 function mergeInject(to, from) {
5210 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
5211 }
5212 function normalizeInject(raw) {
5213 if (isArray(raw)) {
5214 const res = {};
5215 for (let i = 0; i < raw.length; i++) {
5216 res[raw[i]] = raw[i];
5217 }
5218 return res;
5219 }
5220 return raw;
5221 }
5222 function mergeAsArray(to, from) {
5223 return to ? [...new Set([].concat(to, from))] : from;
5224 }
5225 function mergeObjectOptions(to, from) {
5226 return to ? extend(extend(Object.create(null), to), from) : from;
5227 }
5228 function mergeWatchOptions(to, from) {
5229 if (!to)
5230 return from;
5231 if (!from)
5232 return to;
5233 const merged = extend(Object.create(null), to);
5234 for (const key in from) {
5235 merged[key] = mergeAsArray(to[key], from[key]);
5236 }
5237 return merged;
5238 }
5239
5240 function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
5241 isSSR = false) {
5242 const props = {};
5243 const attrs = {};
5244 def(attrs, InternalObjectKey, 1);
5245 instance.propsDefaults = Object.create(null);
5246 setFullProps(instance, rawProps, props, attrs);
5247 // ensure all declared prop keys are present
5248 for (const key in instance.propsOptions[0]) {
5249 if (!(key in props)) {
5250 props[key] = undefined;
5251 }
5252 }
5253 // validation
5254 {
5255 validateProps(rawProps || {}, props, instance);
5256 }
5257 if (isStateful) {
5258 // stateful
5259 instance.props = isSSR ? props : shallowReactive(props);
5260 }
5261 else {
5262 if (!instance.type.props) {
5263 // functional w/ optional props, props === attrs
5264 instance.props = attrs;
5265 }
5266 else {
5267 // functional w/ declared props
5268 instance.props = props;
5269 }
5270 }
5271 instance.attrs = attrs;
5272 }
5273 function updateProps(instance, rawProps, rawPrevProps, optimized) {
5274 const { props, attrs, vnode: { patchFlag } } = instance;
5275 const rawCurrentProps = toRaw(props);
5276 const [options] = instance.propsOptions;
5277 let hasAttrsChanged = false;
5278 if (
5279 // always force full diff in dev
5280 // - #1942 if hmr is enabled with sfc component
5281 // - vite#872 non-sfc component used by sfc component
5282 !((instance.type.__hmrId ||
5283 (instance.parent && instance.parent.type.__hmrId))) &&
5284 (optimized || patchFlag > 0) &&
5285 !(patchFlag & 16 /* FULL_PROPS */)) {
5286 if (patchFlag & 8 /* PROPS */) {
5287 // Compiler-generated props & no keys change, just set the updated
5288 // the props.
5289 const propsToUpdate = instance.vnode.dynamicProps;
5290 for (let i = 0; i < propsToUpdate.length; i++) {
5291 let key = propsToUpdate[i];
5292 // skip if the prop key is a declared emit event listener
5293 if (isEmitListener(instance.emitsOptions, key)) {
5294 continue;
5295 }
5296 // PROPS flag guarantees rawProps to be non-null
5297 const value = rawProps[key];
5298 if (options) {
5299 // attr / props separation was done on init and will be consistent
5300 // in this code path, so just check if attrs have it.
5301 if (hasOwn(attrs, key)) {
5302 if (value !== attrs[key]) {
5303 attrs[key] = value;
5304 hasAttrsChanged = true;
5305 }
5306 }
5307 else {
5308 const camelizedKey = camelize(key);
5309 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
5310 }
5311 }
5312 else {
5313 if (value !== attrs[key]) {
5314 attrs[key] = value;
5315 hasAttrsChanged = true;
5316 }
5317 }
5318 }
5319 }
5320 }
5321 else {
5322 // full props update.
5323 if (setFullProps(instance, rawProps, props, attrs)) {
5324 hasAttrsChanged = true;
5325 }
5326 // in case of dynamic props, check if we need to delete keys from
5327 // the props object
5328 let kebabKey;
5329 for (const key in rawCurrentProps) {
5330 if (!rawProps ||
5331 // for camelCase
5332 (!hasOwn(rawProps, key) &&
5333 // it's possible the original props was passed in as kebab-case
5334 // and converted to camelCase (#955)
5335 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
5336 if (options) {
5337 if (rawPrevProps &&
5338 // for camelCase
5339 (rawPrevProps[key] !== undefined ||
5340 // for kebab-case
5341 rawPrevProps[kebabKey] !== undefined)) {
5342 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
5343 }
5344 }
5345 else {
5346 delete props[key];
5347 }
5348 }
5349 }
5350 // in the case of functional component w/o props declaration, props and
5351 // attrs point to the same object so it should already have been updated.
5352 if (attrs !== rawCurrentProps) {
5353 for (const key in attrs) {
5354 if (!rawProps ||
5355 (!hasOwn(rawProps, key) &&
5356 (!false ))) {
5357 delete attrs[key];
5358 hasAttrsChanged = true;
5359 }
5360 }
5361 }
5362 }
5363 // trigger updates for $attrs in case it's used in component slots
5364 if (hasAttrsChanged) {
5365 trigger(instance, "set" /* SET */, '$attrs');
5366 }
5367 {
5368 validateProps(rawProps || {}, props, instance);
5369 }
5370 }
5371 function setFullProps(instance, rawProps, props, attrs) {
5372 const [options, needCastKeys] = instance.propsOptions;
5373 let hasAttrsChanged = false;
5374 let rawCastValues;
5375 if (rawProps) {
5376 for (let key in rawProps) {
5377 // key, ref are reserved and never passed down
5378 if (isReservedProp(key)) {
5379 continue;
5380 }
5381 const value = rawProps[key];
5382 // prop option names are camelized during normalization, so to support
5383 // kebab -> camel conversion here we need to camelize the key.
5384 let camelKey;
5385 if (options && hasOwn(options, (camelKey = camelize(key)))) {
5386 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
5387 props[camelKey] = value;
5388 }
5389 else {
5390 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
5391 }
5392 }
5393 else if (!isEmitListener(instance.emitsOptions, key)) {
5394 if (!(key in attrs) || value !== attrs[key]) {
5395 attrs[key] = value;
5396 hasAttrsChanged = true;
5397 }
5398 }
5399 }
5400 }
5401 if (needCastKeys) {
5402 const rawCurrentProps = toRaw(props);
5403 const castValues = rawCastValues || EMPTY_OBJ;
5404 for (let i = 0; i < needCastKeys.length; i++) {
5405 const key = needCastKeys[i];
5406 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
5407 }
5408 }
5409 return hasAttrsChanged;
5410 }
5411 function resolvePropValue(options, props, key, value, instance, isAbsent) {
5412 const opt = options[key];
5413 if (opt != null) {
5414 const hasDefault = hasOwn(opt, 'default');
5415 // default values
5416 if (hasDefault && value === undefined) {
5417 const defaultValue = opt.default;
5418 if (opt.type !== Function && isFunction(defaultValue)) {
5419 const { propsDefaults } = instance;
5420 if (key in propsDefaults) {
5421 value = propsDefaults[key];
5422 }
5423 else {
5424 setCurrentInstance(instance);
5425 value = propsDefaults[key] = defaultValue.call(null, props);
5426 unsetCurrentInstance();
5427 }
5428 }
5429 else {
5430 value = defaultValue;
5431 }
5432 }
5433 // boolean casting
5434 if (opt[0 /* shouldCast */]) {
5435 if (isAbsent && !hasDefault) {
5436 value = false;
5437 }
5438 else if (opt[1 /* shouldCastTrue */] &&
5439 (value === '' || value === hyphenate(key))) {
5440 value = true;
5441 }
5442 }
5443 }
5444 return value;
5445 }
5446 function normalizePropsOptions(comp, appContext, asMixin = false) {
5447 const cache = appContext.propsCache;
5448 const cached = cache.get(comp);
5449 if (cached) {
5450 return cached;
5451 }
5452 const raw = comp.props;
5453 const normalized = {};
5454 const needCastKeys = [];
5455 // apply mixin/extends props
5456 let hasExtends = false;
5457 if (!isFunction(comp)) {
5458 const extendProps = (raw) => {
5459 hasExtends = true;
5460 const [props, keys] = normalizePropsOptions(raw, appContext, true);
5461 extend(normalized, props);
5462 if (keys)
5463 needCastKeys.push(...keys);
5464 };
5465 if (!asMixin && appContext.mixins.length) {
5466 appContext.mixins.forEach(extendProps);
5467 }
5468 if (comp.extends) {
5469 extendProps(comp.extends);
5470 }
5471 if (comp.mixins) {
5472 comp.mixins.forEach(extendProps);
5473 }
5474 }
5475 if (!raw && !hasExtends) {
5476 cache.set(comp, EMPTY_ARR);
5477 return EMPTY_ARR;
5478 }
5479 if (isArray(raw)) {
5480 for (let i = 0; i < raw.length; i++) {
5481 if (!isString(raw[i])) {
5482 warn$1(`props must be strings when using array syntax.`, raw[i]);
5483 }
5484 const normalizedKey = camelize(raw[i]);
5485 if (validatePropName(normalizedKey)) {
5486 normalized[normalizedKey] = EMPTY_OBJ;
5487 }
5488 }
5489 }
5490 else if (raw) {
5491 if (!isObject(raw)) {
5492 warn$1(`invalid props options`, raw);
5493 }
5494 for (const key in raw) {
5495 const normalizedKey = camelize(key);
5496 if (validatePropName(normalizedKey)) {
5497 const opt = raw[key];
5498 const prop = (normalized[normalizedKey] =
5499 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
5500 if (prop) {
5501 const booleanIndex = getTypeIndex(Boolean, prop.type);
5502 const stringIndex = getTypeIndex(String, prop.type);
5503 prop[0 /* shouldCast */] = booleanIndex > -1;
5504 prop[1 /* shouldCastTrue */] =
5505 stringIndex < 0 || booleanIndex < stringIndex;
5506 // if the prop needs boolean casting or default value
5507 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
5508 needCastKeys.push(normalizedKey);
5509 }
5510 }
5511 }
5512 }
5513 }
5514 const res = [normalized, needCastKeys];
5515 cache.set(comp, res);
5516 return res;
5517 }
5518 function validatePropName(key) {
5519 if (key[0] !== '$') {
5520 return true;
5521 }
5522 else {
5523 warn$1(`Invalid prop name: "${key}" is a reserved property.`);
5524 }
5525 return false;
5526 }
5527 // use function string name to check type constructors
5528 // so that it works across vms / iframes.
5529 function getType(ctor) {
5530 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
5531 return match ? match[1] : ctor === null ? 'null' : '';
5532 }
5533 function isSameType(a, b) {
5534 return getType(a) === getType(b);
5535 }
5536 function getTypeIndex(type, expectedTypes) {
5537 if (isArray(expectedTypes)) {
5538 return expectedTypes.findIndex(t => isSameType(t, type));
5539 }
5540 else if (isFunction(expectedTypes)) {
5541 return isSameType(expectedTypes, type) ? 0 : -1;
5542 }
5543 return -1;
5544 }
5545 /**
5546 * dev only
5547 */
5548 function validateProps(rawProps, props, instance) {
5549 const resolvedValues = toRaw(props);
5550 const options = instance.propsOptions[0];
5551 for (const key in options) {
5552 let opt = options[key];
5553 if (opt == null)
5554 continue;
5555 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
5556 }
5557 }
5558 /**
5559 * dev only
5560 */
5561 function validateProp(name, value, prop, isAbsent) {
5562 const { type, required, validator } = prop;
5563 // required!
5564 if (required && isAbsent) {
5565 warn$1('Missing required prop: "' + name + '"');
5566 return;
5567 }
5568 // missing but optional
5569 if (value == null && !prop.required) {
5570 return;
5571 }
5572 // type check
5573 if (type != null && type !== true) {
5574 let isValid = false;
5575 const types = isArray(type) ? type : [type];
5576 const expectedTypes = [];
5577 // value is valid as long as one of the specified types match
5578 for (let i = 0; i < types.length && !isValid; i++) {
5579 const { valid, expectedType } = assertType(value, types[i]);
5580 expectedTypes.push(expectedType || '');
5581 isValid = valid;
5582 }
5583 if (!isValid) {
5584 warn$1(getInvalidTypeMessage(name, value, expectedTypes));
5585 return;
5586 }
5587 }
5588 // custom validator
5589 if (validator && !validator(value)) {
5590 warn$1('Invalid prop: custom validator check failed for prop "' + name + '".');
5591 }
5592 }
5593 const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
5594 /**
5595 * dev only
5596 */
5597 function assertType(value, type) {
5598 let valid;
5599 const expectedType = getType(type);
5600 if (isSimpleType(expectedType)) {
5601 const t = typeof value;
5602 valid = t === expectedType.toLowerCase();
5603 // for primitive wrapper objects
5604 if (!valid && t === 'object') {
5605 valid = value instanceof type;
5606 }
5607 }
5608 else if (expectedType === 'Object') {
5609 valid = isObject(value);
5610 }
5611 else if (expectedType === 'Array') {
5612 valid = isArray(value);
5613 }
5614 else if (expectedType === 'null') {
5615 valid = value === null;
5616 }
5617 else {
5618 valid = value instanceof type;
5619 }
5620 return {
5621 valid,
5622 expectedType
5623 };
5624 }
5625 /**
5626 * dev only
5627 */
5628 function getInvalidTypeMessage(name, value, expectedTypes) {
5629 let message = `Invalid prop: type check failed for prop "${name}".` +
5630 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
5631 const expectedType = expectedTypes[0];
5632 const receivedType = toRawType(value);
5633 const expectedValue = styleValue(value, expectedType);
5634 const receivedValue = styleValue(value, receivedType);
5635 // check if we need to specify expected value
5636 if (expectedTypes.length === 1 &&
5637 isExplicable(expectedType) &&
5638 !isBoolean(expectedType, receivedType)) {
5639 message += ` with value ${expectedValue}`;
5640 }
5641 message += `, got ${receivedType} `;
5642 // check if we need to specify received value
5643 if (isExplicable(receivedType)) {
5644 message += `with value ${receivedValue}.`;
5645 }
5646 return message;
5647 }
5648 /**
5649 * dev only
5650 */
5651 function styleValue(value, type) {
5652 if (type === 'String') {
5653 return `"${value}"`;
5654 }
5655 else if (type === 'Number') {
5656 return `${Number(value)}`;
5657 }
5658 else {
5659 return `${value}`;
5660 }
5661 }
5662 /**
5663 * dev only
5664 */
5665 function isExplicable(type) {
5666 const explicitTypes = ['string', 'number', 'boolean'];
5667 return explicitTypes.some(elem => type.toLowerCase() === elem);
5668 }
5669 /**
5670 * dev only
5671 */
5672 function isBoolean(...args) {
5673 return args.some(elem => elem.toLowerCase() === 'boolean');
5674 }
5675
5676 const isInternalKey = (key) => key[0] === '_' || key === '$stable';
5677 const normalizeSlotValue = (value) => isArray(value)
5678 ? value.map(normalizeVNode)
5679 : [normalizeVNode(value)];
5680 const normalizeSlot = (key, rawSlot, ctx) => {
5681 if (rawSlot._n) {
5682 // already normalized - #5353
5683 return rawSlot;
5684 }
5685 const normalized = withCtx((...args) => {
5686 if (currentInstance) {
5687 warn$1(`Slot "${key}" invoked outside of the render function: ` +
5688 `this will not track dependencies used in the slot. ` +
5689 `Invoke the slot function inside the render function instead.`);
5690 }
5691 return normalizeSlotValue(rawSlot(...args));
5692 }, ctx);
5693 normalized._c = false;
5694 return normalized;
5695 };
5696 const normalizeObjectSlots = (rawSlots, slots, instance) => {
5697 const ctx = rawSlots._ctx;
5698 for (const key in rawSlots) {
5699 if (isInternalKey(key))
5700 continue;
5701 const value = rawSlots[key];
5702 if (isFunction(value)) {
5703 slots[key] = normalizeSlot(key, value, ctx);
5704 }
5705 else if (value != null) {
5706 {
5707 warn$1(`Non-function value encountered for slot "${key}". ` +
5708 `Prefer function slots for better performance.`);
5709 }
5710 const normalized = normalizeSlotValue(value);
5711 slots[key] = () => normalized;
5712 }
5713 }
5714 };
5715 const normalizeVNodeSlots = (instance, children) => {
5716 if (!isKeepAlive(instance.vnode) &&
5717 !(false )) {
5718 warn$1(`Non-function value encountered for default slot. ` +
5719 `Prefer function slots for better performance.`);
5720 }
5721 const normalized = normalizeSlotValue(children);
5722 instance.slots.default = () => normalized;
5723 };
5724 const initSlots = (instance, children) => {
5725 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5726 const type = children._;
5727 if (type) {
5728 // users can get the shallow readonly version of the slots object through `this.$slots`,
5729 // we should avoid the proxy object polluting the slots of the internal instance
5730 instance.slots = toRaw(children);
5731 // make compiler marker non-enumerable
5732 def(children, '_', type);
5733 }
5734 else {
5735 normalizeObjectSlots(children, (instance.slots = {}));
5736 }
5737 }
5738 else {
5739 instance.slots = {};
5740 if (children) {
5741 normalizeVNodeSlots(instance, children);
5742 }
5743 }
5744 def(instance.slots, InternalObjectKey, 1);
5745 };
5746 const updateSlots = (instance, children, optimized) => {
5747 const { vnode, slots } = instance;
5748 let needDeletionCheck = true;
5749 let deletionComparisonTarget = EMPTY_OBJ;
5750 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5751 const type = children._;
5752 if (type) {
5753 // compiled slots.
5754 if (isHmrUpdating) {
5755 // Parent was HMR updated so slot content may have changed.
5756 // force update slots and mark instance for hmr as well
5757 extend(slots, children);
5758 }
5759 else if (optimized && type === 1 /* STABLE */) {
5760 // compiled AND stable.
5761 // no need to update, and skip stale slots removal.
5762 needDeletionCheck = false;
5763 }
5764 else {
5765 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
5766 // normalization.
5767 extend(slots, children);
5768 // #2893
5769 // when rendering the optimized slots by manually written render function,
5770 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
5771 // i.e. let the `renderSlot` create the bailed Fragment
5772 if (!optimized && type === 1 /* STABLE */) {
5773 delete slots._;
5774 }
5775 }
5776 }
5777 else {
5778 needDeletionCheck = !children.$stable;
5779 normalizeObjectSlots(children, slots);
5780 }
5781 deletionComparisonTarget = children;
5782 }
5783 else if (children) {
5784 // non slot object children (direct value) passed to a component
5785 normalizeVNodeSlots(instance, children);
5786 deletionComparisonTarget = { default: 1 };
5787 }
5788 // delete stale slots
5789 if (needDeletionCheck) {
5790 for (const key in slots) {
5791 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
5792 delete slots[key];
5793 }
5794 }
5795 }
5796 };
5797
5798 function createAppContext() {
5799 return {
5800 app: null,
5801 config: {
5802 isNativeTag: NO,
5803 performance: false,
5804 globalProperties: {},
5805 optionMergeStrategies: {},
5806 errorHandler: undefined,
5807 warnHandler: undefined,
5808 compilerOptions: {}
5809 },
5810 mixins: [],
5811 components: {},
5812 directives: {},
5813 provides: Object.create(null),
5814 optionsCache: new WeakMap(),
5815 propsCache: new WeakMap(),
5816 emitsCache: new WeakMap()
5817 };
5818 }
5819 let uid = 0;
5820 function createAppAPI(render, hydrate) {
5821 return function createApp(rootComponent, rootProps = null) {
5822 if (!isFunction(rootComponent)) {
5823 rootComponent = Object.assign({}, rootComponent);
5824 }
5825 if (rootProps != null && !isObject(rootProps)) {
5826 warn$1(`root props passed to app.mount() must be an object.`);
5827 rootProps = null;
5828 }
5829 const context = createAppContext();
5830 const installedPlugins = new Set();
5831 let isMounted = false;
5832 const app = (context.app = {
5833 _uid: uid++,
5834 _component: rootComponent,
5835 _props: rootProps,
5836 _container: null,
5837 _context: context,
5838 _instance: null,
5839 version,
5840 get config() {
5841 return context.config;
5842 },
5843 set config(v) {
5844 {
5845 warn$1(`app.config cannot be replaced. Modify individual options instead.`);
5846 }
5847 },
5848 use(plugin, ...options) {
5849 if (installedPlugins.has(plugin)) {
5850 warn$1(`Plugin has already been applied to target app.`);
5851 }
5852 else if (plugin && isFunction(plugin.install)) {
5853 installedPlugins.add(plugin);
5854 plugin.install(app, ...options);
5855 }
5856 else if (isFunction(plugin)) {
5857 installedPlugins.add(plugin);
5858 plugin(app, ...options);
5859 }
5860 else {
5861 warn$1(`A plugin must either be a function or an object with an "install" ` +
5862 `function.`);
5863 }
5864 return app;
5865 },
5866 mixin(mixin) {
5867 {
5868 if (!context.mixins.includes(mixin)) {
5869 context.mixins.push(mixin);
5870 }
5871 else {
5872 warn$1('Mixin has already been applied to target app' +
5873 (mixin.name ? `: ${mixin.name}` : ''));
5874 }
5875 }
5876 return app;
5877 },
5878 component(name, component) {
5879 {
5880 validateComponentName(name, context.config);
5881 }
5882 if (!component) {
5883 return context.components[name];
5884 }
5885 if (context.components[name]) {
5886 warn$1(`Component "${name}" has already been registered in target app.`);
5887 }
5888 context.components[name] = component;
5889 return app;
5890 },
5891 directive(name, directive) {
5892 {
5893 validateDirectiveName(name);
5894 }
5895 if (!directive) {
5896 return context.directives[name];
5897 }
5898 if (context.directives[name]) {
5899 warn$1(`Directive "${name}" has already been registered in target app.`);
5900 }
5901 context.directives[name] = directive;
5902 return app;
5903 },
5904 mount(rootContainer, isHydrate, isSVG) {
5905 if (!isMounted) {
5906 // #5571
5907 if (rootContainer.__vue_app__) {
5908 warn$1(`There is already an app instance mounted on the host container.\n` +
5909 ` If you want to mount another app on the same host container,` +
5910 ` you need to unmount the previous app by calling \`app.unmount()\` first.`);
5911 }
5912 const vnode = createVNode(rootComponent, rootProps);
5913 // store app context on the root VNode.
5914 // this will be set on the root instance on initial mount.
5915 vnode.appContext = context;
5916 // HMR root reload
5917 {
5918 context.reload = () => {
5919 render(cloneVNode(vnode), rootContainer, isSVG);
5920 };
5921 }
5922 if (isHydrate && hydrate) {
5923 hydrate(vnode, rootContainer);
5924 }
5925 else {
5926 render(vnode, rootContainer, isSVG);
5927 }
5928 isMounted = true;
5929 app._container = rootContainer;
5930 rootContainer.__vue_app__ = app;
5931 {
5932 app._instance = vnode.component;
5933 devtoolsInitApp(app, version);
5934 }
5935 return getExposeProxy(vnode.component) || vnode.component.proxy;
5936 }
5937 else {
5938 warn$1(`App has already been mounted.\n` +
5939 `If you want to remount the same app, move your app creation logic ` +
5940 `into a factory function and create fresh app instances for each ` +
5941 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
5942 }
5943 },
5944 unmount() {
5945 if (isMounted) {
5946 render(null, app._container);
5947 {
5948 app._instance = null;
5949 devtoolsUnmountApp(app);
5950 }
5951 delete app._container.__vue_app__;
5952 }
5953 else {
5954 warn$1(`Cannot unmount an app that is not mounted.`);
5955 }
5956 },
5957 provide(key, value) {
5958 if (key in context.provides) {
5959 warn$1(`App already provides property with key "${String(key)}". ` +
5960 `It will be overwritten with the new value.`);
5961 }
5962 context.provides[key] = value;
5963 return app;
5964 }
5965 });
5966 return app;
5967 };
5968 }
5969
5970 /**
5971 * Function for handling a template ref
5972 */
5973 function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
5974 if (isArray(rawRef)) {
5975 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
5976 return;
5977 }
5978 if (isAsyncWrapper(vnode) && !isUnmount) {
5979 // when mounting async components, nothing needs to be done,
5980 // because the template ref is forwarded to inner component
5981 return;
5982 }
5983 const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
5984 ? getExposeProxy(vnode.component) || vnode.component.proxy
5985 : vnode.el;
5986 const value = isUnmount ? null : refValue;
5987 const { i: owner, r: ref } = rawRef;
5988 if (!owner) {
5989 warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
5990 `A vnode with ref must be created inside the render function.`);
5991 return;
5992 }
5993 const oldRef = oldRawRef && oldRawRef.r;
5994 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
5995 const setupState = owner.setupState;
5996 // dynamic ref changed. unset old ref
5997 if (oldRef != null && oldRef !== ref) {
5998 if (isString(oldRef)) {
5999 refs[oldRef] = null;
6000 if (hasOwn(setupState, oldRef)) {
6001 setupState[oldRef] = null;
6002 }
6003 }
6004 else if (isRef(oldRef)) {
6005 oldRef.value = null;
6006 }
6007 }
6008 if (isFunction(ref)) {
6009 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6010 }
6011 else {
6012 const _isString = isString(ref);
6013 const _isRef = isRef(ref);
6014 if (_isString || _isRef) {
6015 const doSet = () => {
6016 if (rawRef.f) {
6017 const existing = _isString ? refs[ref] : ref.value;
6018 if (isUnmount) {
6019 isArray(existing) && remove(existing, refValue);
6020 }
6021 else {
6022 if (!isArray(existing)) {
6023 if (_isString) {
6024 refs[ref] = [refValue];
6025 if (hasOwn(setupState, ref)) {
6026 setupState[ref] = refs[ref];
6027 }
6028 }
6029 else {
6030 ref.value = [refValue];
6031 if (rawRef.k)
6032 refs[rawRef.k] = ref.value;
6033 }
6034 }
6035 else if (!existing.includes(refValue)) {
6036 existing.push(refValue);
6037 }
6038 }
6039 }
6040 else if (_isString) {
6041 refs[ref] = value;
6042 if (hasOwn(setupState, ref)) {
6043 setupState[ref] = value;
6044 }
6045 }
6046 else if (isRef(ref)) {
6047 ref.value = value;
6048 if (rawRef.k)
6049 refs[rawRef.k] = value;
6050 }
6051 else {
6052 warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6053 }
6054 };
6055 if (value) {
6056 doSet.id = -1;
6057 queuePostRenderEffect(doSet, parentSuspense);
6058 }
6059 else {
6060 doSet();
6061 }
6062 }
6063 else {
6064 warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6065 }
6066 }
6067 }
6068
6069 let hasMismatch = false;
6070 const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
6071 const isComment = (node) => node.nodeType === 8 /* COMMENT */;
6072 // Note: hydration is DOM-specific
6073 // But we have to place it in core due to tight coupling with core - splitting
6074 // it out creates a ton of unnecessary complexity.
6075 // Hydration also depends on some renderer internal logic which needs to be
6076 // passed in via arguments.
6077 function createHydrationFunctions(rendererInternals) {
6078 const { mt: mountComponent, p: patch, o: { patchProp, createText, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
6079 const hydrate = (vnode, container) => {
6080 if (!container.hasChildNodes()) {
6081 warn$1(`Attempting to hydrate existing markup but container is empty. ` +
6082 `Performing full mount instead.`);
6083 patch(null, vnode, container);
6084 flushPostFlushCbs();
6085 return;
6086 }
6087 hasMismatch = false;
6088 hydrateNode(container.firstChild, vnode, null, null, null);
6089 flushPostFlushCbs();
6090 if (hasMismatch && !false) {
6091 // this error should show up in production
6092 console.error(`Hydration completed but contains mismatches.`);
6093 }
6094 };
6095 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
6096 const isFragmentStart = isComment(node) && node.data === '[';
6097 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
6098 const { type, ref, shapeFlag, patchFlag } = vnode;
6099 const domType = node.nodeType;
6100 vnode.el = node;
6101 if (patchFlag === -2 /* BAIL */) {
6102 optimized = false;
6103 vnode.dynamicChildren = null;
6104 }
6105 let nextNode = null;
6106 switch (type) {
6107 case Text:
6108 if (domType !== 3 /* TEXT */) {
6109 // #5728 empty text node inside a slot can cause hydration failure
6110 // because the server rendered HTML won't contain a text node
6111 if (vnode.children === '') {
6112 insert((vnode.el = createText('')), parentNode(node), node);
6113 nextNode = node;
6114 }
6115 else {
6116 nextNode = onMismatch();
6117 }
6118 }
6119 else {
6120 if (node.data !== vnode.children) {
6121 hasMismatch = true;
6122 warn$1(`Hydration text mismatch:` +
6123 `\n- Client: ${JSON.stringify(node.data)}` +
6124 `\n- Server: ${JSON.stringify(vnode.children)}`);
6125 node.data = vnode.children;
6126 }
6127 nextNode = nextSibling(node);
6128 }
6129 break;
6130 case Comment:
6131 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
6132 nextNode = onMismatch();
6133 }
6134 else {
6135 nextNode = nextSibling(node);
6136 }
6137 break;
6138 case Static:
6139 if (domType !== 1 /* ELEMENT */) {
6140 nextNode = onMismatch();
6141 }
6142 else {
6143 // determine anchor, adopt content
6144 nextNode = node;
6145 // if the static vnode has its content stripped during build,
6146 // adopt it from the server-rendered HTML.
6147 const needToAdoptContent = !vnode.children.length;
6148 for (let i = 0; i < vnode.staticCount; i++) {
6149 if (needToAdoptContent)
6150 vnode.children += nextNode.outerHTML;
6151 if (i === vnode.staticCount - 1) {
6152 vnode.anchor = nextNode;
6153 }
6154 nextNode = nextSibling(nextNode);
6155 }
6156 return nextNode;
6157 }
6158 break;
6159 case Fragment:
6160 if (!isFragmentStart) {
6161 nextNode = onMismatch();
6162 }
6163 else {
6164 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6165 }
6166 break;
6167 default:
6168 if (shapeFlag & 1 /* ELEMENT */) {
6169 if (domType !== 1 /* ELEMENT */ ||
6170 vnode.type.toLowerCase() !==
6171 node.tagName.toLowerCase()) {
6172 nextNode = onMismatch();
6173 }
6174 else {
6175 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6176 }
6177 }
6178 else if (shapeFlag & 6 /* COMPONENT */) {
6179 // when setting up the render effect, if the initial vnode already
6180 // has .el set, the component will perform hydration instead of mount
6181 // on its sub-tree.
6182 vnode.slotScopeIds = slotScopeIds;
6183 const container = parentNode(node);
6184 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
6185 // component may be async, so in the case of fragments we cannot rely
6186 // on component's rendered output to determine the end of the fragment
6187 // instead, we do a lookahead to find the end anchor node.
6188 nextNode = isFragmentStart
6189 ? locateClosingAsyncAnchor(node)
6190 : nextSibling(node);
6191 // #4293 teleport as component root
6192 if (nextNode &&
6193 isComment(nextNode) &&
6194 nextNode.data === 'teleport end') {
6195 nextNode = nextSibling(nextNode);
6196 }
6197 // #3787
6198 // if component is async, it may get moved / unmounted before its
6199 // inner component is loaded, so we need to give it a placeholder
6200 // vnode that matches its adopted DOM.
6201 if (isAsyncWrapper(vnode)) {
6202 let subTree;
6203 if (isFragmentStart) {
6204 subTree = createVNode(Fragment);
6205 subTree.anchor = nextNode
6206 ? nextNode.previousSibling
6207 : container.lastChild;
6208 }
6209 else {
6210 subTree =
6211 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
6212 }
6213 subTree.el = node;
6214 vnode.component.subTree = subTree;
6215 }
6216 }
6217 else if (shapeFlag & 64 /* TELEPORT */) {
6218 if (domType !== 8 /* COMMENT */) {
6219 nextNode = onMismatch();
6220 }
6221 else {
6222 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
6223 }
6224 }
6225 else if (shapeFlag & 128 /* SUSPENSE */) {
6226 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
6227 }
6228 else {
6229 warn$1('Invalid HostVNode type:', type, `(${typeof type})`);
6230 }
6231 }
6232 if (ref != null) {
6233 setRef(ref, null, parentSuspense, vnode);
6234 }
6235 return nextNode;
6236 };
6237 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6238 optimized = optimized || !!vnode.dynamicChildren;
6239 const { type, props, patchFlag, shapeFlag, dirs } = vnode;
6240 // #4006 for form elements with non-string v-model value bindings
6241 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
6242 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
6243 // skip props & children if this is hoisted static nodes
6244 // #5405 in dev, always hydrate children for HMR
6245 {
6246 if (dirs) {
6247 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6248 }
6249 // props
6250 if (props) {
6251 if (forcePatchValue ||
6252 !optimized ||
6253 patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) {
6254 for (const key in props) {
6255 if ((forcePatchValue && key.endsWith('value')) ||
6256 (isOn(key) && !isReservedProp(key))) {
6257 patchProp(el, key, null, props[key], false, undefined, parentComponent);
6258 }
6259 }
6260 }
6261 else if (props.onClick) {
6262 // Fast path for click listeners (which is most often) to avoid
6263 // iterating through props.
6264 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent);
6265 }
6266 }
6267 // vnode / directive hooks
6268 let vnodeHooks;
6269 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
6270 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6271 }
6272 if (dirs) {
6273 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6274 }
6275 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
6276 queueEffectWithSuspense(() => {
6277 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6278 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6279 }, parentSuspense);
6280 }
6281 // children
6282 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
6283 // skip if element has innerHTML / textContent
6284 !(props && (props.innerHTML || props.textContent))) {
6285 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
6286 let hasWarned = false;
6287 while (next) {
6288 hasMismatch = true;
6289 if (!hasWarned) {
6290 warn$1(`Hydration children mismatch in <${vnode.type}>: ` +
6291 `server rendered element contains more child nodes than client vdom.`);
6292 hasWarned = true;
6293 }
6294 // The SSRed DOM contains more nodes than it should. Remove them.
6295 const cur = next;
6296 next = next.nextSibling;
6297 remove(cur);
6298 }
6299 }
6300 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6301 if (el.textContent !== vnode.children) {
6302 hasMismatch = true;
6303 warn$1(`Hydration text content mismatch in <${vnode.type}>:\n` +
6304 `- Client: ${el.textContent}\n` +
6305 `- Server: ${vnode.children}`);
6306 el.textContent = vnode.children;
6307 }
6308 }
6309 }
6310 return el.nextSibling;
6311 };
6312 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6313 optimized = optimized || !!parentVNode.dynamicChildren;
6314 const children = parentVNode.children;
6315 const l = children.length;
6316 let hasWarned = false;
6317 for (let i = 0; i < l; i++) {
6318 const vnode = optimized
6319 ? children[i]
6320 : (children[i] = normalizeVNode(children[i]));
6321 if (node) {
6322 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6323 }
6324 else if (vnode.type === Text && !vnode.children) {
6325 continue;
6326 }
6327 else {
6328 hasMismatch = true;
6329 if (!hasWarned) {
6330 warn$1(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
6331 `server rendered element contains fewer child nodes than client vdom.`);
6332 hasWarned = true;
6333 }
6334 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
6335 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6336 }
6337 }
6338 return node;
6339 };
6340 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6341 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
6342 if (fragmentSlotScopeIds) {
6343 slotScopeIds = slotScopeIds
6344 ? slotScopeIds.concat(fragmentSlotScopeIds)
6345 : fragmentSlotScopeIds;
6346 }
6347 const container = parentNode(node);
6348 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
6349 if (next && isComment(next) && next.data === ']') {
6350 return nextSibling((vnode.anchor = next));
6351 }
6352 else {
6353 // fragment didn't hydrate successfully, since we didn't get a end anchor
6354 // back. This should have led to node/children mismatch warnings.
6355 hasMismatch = true;
6356 // since the anchor is missing, we need to create one and insert it
6357 insert((vnode.anchor = createComment(`]`)), container, next);
6358 return next;
6359 }
6360 };
6361 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
6362 hasMismatch = true;
6363 warn$1(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
6364 ? `(text)`
6365 : isComment(node) && node.data === '['
6366 ? `(start of fragment)`
6367 : ``);
6368 vnode.el = null;
6369 if (isFragment) {
6370 // remove excessive fragment nodes
6371 const end = locateClosingAsyncAnchor(node);
6372 while (true) {
6373 const next = nextSibling(node);
6374 if (next && next !== end) {
6375 remove(next);
6376 }
6377 else {
6378 break;
6379 }
6380 }
6381 }
6382 const next = nextSibling(node);
6383 const container = parentNode(node);
6384 remove(node);
6385 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6386 return next;
6387 };
6388 const locateClosingAsyncAnchor = (node) => {
6389 let match = 0;
6390 while (node) {
6391 node = nextSibling(node);
6392 if (node && isComment(node)) {
6393 if (node.data === '[')
6394 match++;
6395 if (node.data === ']') {
6396 if (match === 0) {
6397 return nextSibling(node);
6398 }
6399 else {
6400 match--;
6401 }
6402 }
6403 }
6404 }
6405 return node;
6406 };
6407 return [hydrate, hydrateNode];
6408 }
6409
6410 /* eslint-disable no-restricted-globals */
6411 let supported;
6412 let perf;
6413 function startMeasure(instance, type) {
6414 if (instance.appContext.config.performance && isSupported()) {
6415 perf.mark(`vue-${type}-${instance.uid}`);
6416 }
6417 {
6418 devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now());
6419 }
6420 }
6421 function endMeasure(instance, type) {
6422 if (instance.appContext.config.performance && isSupported()) {
6423 const startTag = `vue-${type}-${instance.uid}`;
6424 const endTag = startTag + `:end`;
6425 perf.mark(endTag);
6426 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
6427 perf.clearMarks(startTag);
6428 perf.clearMarks(endTag);
6429 }
6430 {
6431 devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now());
6432 }
6433 }
6434 function isSupported() {
6435 if (supported !== undefined) {
6436 return supported;
6437 }
6438 if (typeof window !== 'undefined' && window.performance) {
6439 supported = true;
6440 perf = window.performance;
6441 }
6442 else {
6443 supported = false;
6444 }
6445 return supported;
6446 }
6447
6448 const queuePostRenderEffect = queueEffectWithSuspense
6449 ;
6450 /**
6451 * The createRenderer function accepts two generic arguments:
6452 * HostNode and HostElement, corresponding to Node and Element types in the
6453 * host environment. For example, for runtime-dom, HostNode would be the DOM
6454 * `Node` interface and HostElement would be the DOM `Element` interface.
6455 *
6456 * Custom renderers can pass in the platform specific types like this:
6457 *
6458 * ``` js
6459 * const { render, createApp } = createRenderer<Node, Element>({
6460 * patchProp,
6461 * ...nodeOps
6462 * })
6463 * ```
6464 */
6465 function createRenderer(options) {
6466 return baseCreateRenderer(options);
6467 }
6468 // Separate API for creating hydration-enabled renderer.
6469 // Hydration logic is only used when calling this function, making it
6470 // tree-shakable.
6471 function createHydrationRenderer(options) {
6472 return baseCreateRenderer(options, createHydrationFunctions);
6473 }
6474 // implementation
6475 function baseCreateRenderer(options, createHydrationFns) {
6476 const target = getGlobalThis();
6477 target.__VUE__ = true;
6478 {
6479 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
6480 }
6481 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
6482 // Note: functions inside this closure should use `const xxx = () => {}`
6483 // style in order to prevent being inlined by minifiers.
6484 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
6485 if (n1 === n2) {
6486 return;
6487 }
6488 // patching & not same type, unmount old tree
6489 if (n1 && !isSameVNodeType(n1, n2)) {
6490 anchor = getNextHostNode(n1);
6491 unmount(n1, parentComponent, parentSuspense, true);
6492 n1 = null;
6493 }
6494 if (n2.patchFlag === -2 /* BAIL */) {
6495 optimized = false;
6496 n2.dynamicChildren = null;
6497 }
6498 const { type, ref, shapeFlag } = n2;
6499 switch (type) {
6500 case Text:
6501 processText(n1, n2, container, anchor);
6502 break;
6503 case Comment:
6504 processCommentNode(n1, n2, container, anchor);
6505 break;
6506 case Static:
6507 if (n1 == null) {
6508 mountStaticNode(n2, container, anchor, isSVG);
6509 }
6510 else {
6511 patchStaticNode(n1, n2, container, isSVG);
6512 }
6513 break;
6514 case Fragment:
6515 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6516 break;
6517 default:
6518 if (shapeFlag & 1 /* ELEMENT */) {
6519 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6520 }
6521 else if (shapeFlag & 6 /* COMPONENT */) {
6522 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6523 }
6524 else if (shapeFlag & 64 /* TELEPORT */) {
6525 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6526 }
6527 else if (shapeFlag & 128 /* SUSPENSE */) {
6528 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6529 }
6530 else {
6531 warn$1('Invalid VNode type:', type, `(${typeof type})`);
6532 }
6533 }
6534 // set ref
6535 if (ref != null && parentComponent) {
6536 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
6537 }
6538 };
6539 const processText = (n1, n2, container, anchor) => {
6540 if (n1 == null) {
6541 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
6542 }
6543 else {
6544 const el = (n2.el = n1.el);
6545 if (n2.children !== n1.children) {
6546 hostSetText(el, n2.children);
6547 }
6548 }
6549 };
6550 const processCommentNode = (n1, n2, container, anchor) => {
6551 if (n1 == null) {
6552 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
6553 }
6554 else {
6555 // there's no support for dynamic comments
6556 n2.el = n1.el;
6557 }
6558 };
6559 const mountStaticNode = (n2, container, anchor, isSVG) => {
6560 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG, n2.el, n2.anchor);
6561 };
6562 /**
6563 * Dev / HMR only
6564 */
6565 const patchStaticNode = (n1, n2, container, isSVG) => {
6566 // static nodes are only patched during dev for HMR
6567 if (n2.children !== n1.children) {
6568 const anchor = hostNextSibling(n1.anchor);
6569 // remove existing
6570 removeStaticNode(n1);
6571 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
6572 }
6573 else {
6574 n2.el = n1.el;
6575 n2.anchor = n1.anchor;
6576 }
6577 };
6578 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
6579 let next;
6580 while (el && el !== anchor) {
6581 next = hostNextSibling(el);
6582 hostInsert(el, container, nextSibling);
6583 el = next;
6584 }
6585 hostInsert(anchor, container, nextSibling);
6586 };
6587 const removeStaticNode = ({ el, anchor }) => {
6588 let next;
6589 while (el && el !== anchor) {
6590 next = hostNextSibling(el);
6591 hostRemove(el);
6592 el = next;
6593 }
6594 hostRemove(anchor);
6595 };
6596 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6597 isSVG = isSVG || n2.type === 'svg';
6598 if (n1 == null) {
6599 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6600 }
6601 else {
6602 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6603 }
6604 };
6605 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6606 let el;
6607 let vnodeHook;
6608 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
6609 {
6610 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6611 // mount children first, since some props may rely on child content
6612 // being already rendered, e.g. `<select value>`
6613 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6614 hostSetElementText(el, vnode.children);
6615 }
6616 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6617 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6618 }
6619 if (dirs) {
6620 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6621 }
6622 // props
6623 if (props) {
6624 for (const key in props) {
6625 if (key !== 'value' && !isReservedProp(key)) {
6626 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6627 }
6628 }
6629 /**
6630 * Special case for setting value on DOM elements:
6631 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6632 * - it needs to be forced (#1471)
6633 * #2353 proposes adding another renderer option to configure this, but
6634 * the properties affects are so finite it is worth special casing it
6635 * here to reduce the complexity. (Special casing it also should not
6636 * affect non-DOM renderers)
6637 */
6638 if ('value' in props) {
6639 hostPatchProp(el, 'value', null, props.value);
6640 }
6641 if ((vnodeHook = props.onVnodeBeforeMount)) {
6642 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6643 }
6644 }
6645 // scopeId
6646 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6647 }
6648 {
6649 Object.defineProperty(el, '__vnode', {
6650 value: vnode,
6651 enumerable: false
6652 });
6653 Object.defineProperty(el, '__vueParentComponent', {
6654 value: parentComponent,
6655 enumerable: false
6656 });
6657 }
6658 if (dirs) {
6659 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6660 }
6661 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
6662 // #1689 For inside suspense + suspense resolved case, just call it
6663 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
6664 transition &&
6665 !transition.persisted;
6666 if (needCallTransitionHooks) {
6667 transition.beforeEnter(el);
6668 }
6669 hostInsert(el, container, anchor);
6670 if ((vnodeHook = props && props.onVnodeMounted) ||
6671 needCallTransitionHooks ||
6672 dirs) {
6673 queuePostRenderEffect(() => {
6674 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6675 needCallTransitionHooks && transition.enter(el);
6676 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6677 }, parentSuspense);
6678 }
6679 };
6680 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
6681 if (scopeId) {
6682 hostSetScopeId(el, scopeId);
6683 }
6684 if (slotScopeIds) {
6685 for (let i = 0; i < slotScopeIds.length; i++) {
6686 hostSetScopeId(el, slotScopeIds[i]);
6687 }
6688 }
6689 if (parentComponent) {
6690 let subTree = parentComponent.subTree;
6691 if (subTree.patchFlag > 0 &&
6692 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
6693 subTree =
6694 filterSingleRoot(subTree.children) || subTree;
6695 }
6696 if (vnode === subTree) {
6697 const parentVNode = parentComponent.vnode;
6698 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
6699 }
6700 }
6701 };
6702 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
6703 for (let i = start; i < children.length; i++) {
6704 const child = (children[i] = optimized
6705 ? cloneIfMounted(children[i])
6706 : normalizeVNode(children[i]));
6707 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6708 }
6709 };
6710 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6711 const el = (n2.el = n1.el);
6712 let { patchFlag, dynamicChildren, dirs } = n2;
6713 // #1426 take the old vnode's patch flag into account since user may clone a
6714 // compiler-generated vnode, which de-opts to FULL_PROPS
6715 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
6716 const oldProps = n1.props || EMPTY_OBJ;
6717 const newProps = n2.props || EMPTY_OBJ;
6718 let vnodeHook;
6719 // disable recurse in beforeUpdate hooks
6720 parentComponent && toggleRecurse(parentComponent, false);
6721 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6722 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6723 }
6724 if (dirs) {
6725 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6726 }
6727 parentComponent && toggleRecurse(parentComponent, true);
6728 if (isHmrUpdating) {
6729 // HMR updated, force full diff
6730 patchFlag = 0;
6731 optimized = false;
6732 dynamicChildren = null;
6733 }
6734 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
6735 if (dynamicChildren) {
6736 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
6737 if (parentComponent && parentComponent.type.__hmrId) {
6738 traverseStaticChildren(n1, n2);
6739 }
6740 }
6741 else if (!optimized) {
6742 // full diff
6743 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
6744 }
6745 if (patchFlag > 0) {
6746 // the presence of a patchFlag means this element's render code was
6747 // generated by the compiler and can take the fast path.
6748 // in this path old node and new node are guaranteed to have the same shape
6749 // (i.e. at the exact same position in the source template)
6750 if (patchFlag & 16 /* FULL_PROPS */) {
6751 // element props contain dynamic keys, full diff needed
6752 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6753 }
6754 else {
6755 // class
6756 // this flag is matched when the element has dynamic class bindings.
6757 if (patchFlag & 2 /* CLASS */) {
6758 if (oldProps.class !== newProps.class) {
6759 hostPatchProp(el, 'class', null, newProps.class, isSVG);
6760 }
6761 }
6762 // style
6763 // this flag is matched when the element has dynamic style bindings
6764 if (patchFlag & 4 /* STYLE */) {
6765 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
6766 }
6767 // props
6768 // This flag is matched when the element has dynamic prop/attr bindings
6769 // other than class and style. The keys of dynamic prop/attrs are saved for
6770 // faster iteration.
6771 // Note dynamic keys like :[foo]="bar" will cause this optimization to
6772 // bail out and go through a full diff because we need to unset the old key
6773 if (patchFlag & 8 /* PROPS */) {
6774 // if the flag is present then dynamicProps must be non-null
6775 const propsToUpdate = n2.dynamicProps;
6776 for (let i = 0; i < propsToUpdate.length; i++) {
6777 const key = propsToUpdate[i];
6778 const prev = oldProps[key];
6779 const next = newProps[key];
6780 // #1471 force patch value
6781 if (next !== prev || key === 'value') {
6782 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
6783 }
6784 }
6785 }
6786 }
6787 // text
6788 // This flag is matched when the element has only dynamic text children.
6789 if (patchFlag & 1 /* TEXT */) {
6790 if (n1.children !== n2.children) {
6791 hostSetElementText(el, n2.children);
6792 }
6793 }
6794 }
6795 else if (!optimized && dynamicChildren == null) {
6796 // unoptimized, full diff
6797 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6798 }
6799 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
6800 queuePostRenderEffect(() => {
6801 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6802 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
6803 }, parentSuspense);
6804 }
6805 };
6806 // The fast path for blocks.
6807 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
6808 for (let i = 0; i < newChildren.length; i++) {
6809 const oldVNode = oldChildren[i];
6810 const newVNode = newChildren[i];
6811 // Determine the container (parent element) for the patch.
6812 const container =
6813 // oldVNode may be an errored async setup() component inside Suspense
6814 // which will not have a mounted element
6815 oldVNode.el &&
6816 // - In the case of a Fragment, we need to provide the actual parent
6817 // of the Fragment itself so it can move its children.
6818 (oldVNode.type === Fragment ||
6819 // - In the case of different nodes, there is going to be a replacement
6820 // which also requires the correct parent container
6821 !isSameVNodeType(oldVNode, newVNode) ||
6822 // - In the case of a component, it could contain anything.
6823 oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */))
6824 ? hostParentNode(oldVNode.el)
6825 : // In other cases, the parent container is not actually used so we
6826 // just pass the block element here to avoid a DOM parentNode call.
6827 fallbackContainer;
6828 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
6829 }
6830 };
6831 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
6832 if (oldProps !== newProps) {
6833 for (const key in newProps) {
6834 // empty string is not valid prop
6835 if (isReservedProp(key))
6836 continue;
6837 const next = newProps[key];
6838 const prev = oldProps[key];
6839 // defer patching value
6840 if (next !== prev && key !== 'value') {
6841 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6842 }
6843 }
6844 if (oldProps !== EMPTY_OBJ) {
6845 for (const key in oldProps) {
6846 if (!isReservedProp(key) && !(key in newProps)) {
6847 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6848 }
6849 }
6850 }
6851 if ('value' in newProps) {
6852 hostPatchProp(el, 'value', oldProps.value, newProps.value);
6853 }
6854 }
6855 };
6856 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6857 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
6858 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
6859 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
6860 if (// #5523 dev root fragment may inherit directives
6861 (isHmrUpdating || patchFlag & 2048 /* DEV_ROOT_FRAGMENT */)) {
6862 // HMR updated / Dev root fragment (w/ comments), force full diff
6863 patchFlag = 0;
6864 optimized = false;
6865 dynamicChildren = null;
6866 }
6867 // check if this is a slot fragment with :slotted scope ids
6868 if (fragmentSlotScopeIds) {
6869 slotScopeIds = slotScopeIds
6870 ? slotScopeIds.concat(fragmentSlotScopeIds)
6871 : fragmentSlotScopeIds;
6872 }
6873 if (n1 == null) {
6874 hostInsert(fragmentStartAnchor, container, anchor);
6875 hostInsert(fragmentEndAnchor, container, anchor);
6876 // a fragment can only have array children
6877 // since they are either generated by the compiler, or implicitly created
6878 // from arrays.
6879 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6880 }
6881 else {
6882 if (patchFlag > 0 &&
6883 patchFlag & 64 /* STABLE_FRAGMENT */ &&
6884 dynamicChildren &&
6885 // #2715 the previous fragment could've been a BAILed one as a result
6886 // of renderSlot() with no valid children
6887 n1.dynamicChildren) {
6888 // a stable fragment (template root or <template v-for>) doesn't need to
6889 // patch children order, but it may contain dynamicChildren.
6890 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
6891 if (parentComponent && parentComponent.type.__hmrId) {
6892 traverseStaticChildren(n1, n2);
6893 }
6894 else if (
6895 // #2080 if the stable fragment has a key, it's a <template v-for> that may
6896 // get moved around. Make sure all root level vnodes inherit el.
6897 // #2134 or if it's a component root, it may also get moved around
6898 // as the component is being moved.
6899 n2.key != null ||
6900 (parentComponent && n2 === parentComponent.subTree)) {
6901 traverseStaticChildren(n1, n2, true /* shallow */);
6902 }
6903 }
6904 else {
6905 // keyed / unkeyed, or manual fragments.
6906 // for keyed & unkeyed, since they are compiler generated from v-for,
6907 // each child is guaranteed to be a block so the fragment will never
6908 // have dynamicChildren.
6909 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6910 }
6911 }
6912 };
6913 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6914 n2.slotScopeIds = slotScopeIds;
6915 if (n1 == null) {
6916 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
6917 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
6918 }
6919 else {
6920 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
6921 }
6922 }
6923 else {
6924 updateComponent(n1, n2, optimized);
6925 }
6926 };
6927 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
6928 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
6929 if (instance.type.__hmrId) {
6930 registerHMR(instance);
6931 }
6932 {
6933 pushWarningContext(initialVNode);
6934 startMeasure(instance, `mount`);
6935 }
6936 // inject renderer internals for keepAlive
6937 if (isKeepAlive(initialVNode)) {
6938 instance.ctx.renderer = internals;
6939 }
6940 // resolve props and slots for setup context
6941 {
6942 {
6943 startMeasure(instance, `init`);
6944 }
6945 setupComponent(instance);
6946 {
6947 endMeasure(instance, `init`);
6948 }
6949 }
6950 // setup() is async. This component relies on async logic to be resolved
6951 // before proceeding
6952 if (instance.asyncDep) {
6953 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
6954 // Give it a placeholder if this is not hydration
6955 // TODO handle self-defined fallback
6956 if (!initialVNode.el) {
6957 const placeholder = (instance.subTree = createVNode(Comment));
6958 processCommentNode(null, placeholder, container, anchor);
6959 }
6960 return;
6961 }
6962 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
6963 {
6964 popWarningContext();
6965 endMeasure(instance, `mount`);
6966 }
6967 };
6968 const updateComponent = (n1, n2, optimized) => {
6969 const instance = (n2.component = n1.component);
6970 if (shouldUpdateComponent(n1, n2, optimized)) {
6971 if (instance.asyncDep &&
6972 !instance.asyncResolved) {
6973 // async & still pending - just update props and slots
6974 // since the component's reactive effect for render isn't set-up yet
6975 {
6976 pushWarningContext(n2);
6977 }
6978 updateComponentPreRender(instance, n2, optimized);
6979 {
6980 popWarningContext();
6981 }
6982 return;
6983 }
6984 else {
6985 // normal update
6986 instance.next = n2;
6987 // in case the child component is also queued, remove it to avoid
6988 // double updating the same child component in the same flush.
6989 invalidateJob(instance.update);
6990 // instance.update is the reactive effect.
6991 instance.update();
6992 }
6993 }
6994 else {
6995 // no update needed. just copy over properties
6996 n2.el = n1.el;
6997 instance.vnode = n2;
6998 }
6999 };
7000 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
7001 const componentUpdateFn = () => {
7002 if (!instance.isMounted) {
7003 let vnodeHook;
7004 const { el, props } = initialVNode;
7005 const { bm, m, parent } = instance;
7006 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
7007 toggleRecurse(instance, false);
7008 // beforeMount hook
7009 if (bm) {
7010 invokeArrayFns(bm);
7011 }
7012 // onVnodeBeforeMount
7013 if (!isAsyncWrapperVNode &&
7014 (vnodeHook = props && props.onVnodeBeforeMount)) {
7015 invokeVNodeHook(vnodeHook, parent, initialVNode);
7016 }
7017 toggleRecurse(instance, true);
7018 if (el && hydrateNode) {
7019 // vnode has adopted host node - perform hydration instead of mount.
7020 const hydrateSubTree = () => {
7021 {
7022 startMeasure(instance, `render`);
7023 }
7024 instance.subTree = renderComponentRoot(instance);
7025 {
7026 endMeasure(instance, `render`);
7027 }
7028 {
7029 startMeasure(instance, `hydrate`);
7030 }
7031 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
7032 {
7033 endMeasure(instance, `hydrate`);
7034 }
7035 };
7036 if (isAsyncWrapperVNode) {
7037 initialVNode.type.__asyncLoader().then(
7038 // note: we are moving the render call into an async callback,
7039 // which means it won't track dependencies - but it's ok because
7040 // a server-rendered async wrapper is already in resolved state
7041 // and it will never need to change.
7042 () => !instance.isUnmounted && hydrateSubTree());
7043 }
7044 else {
7045 hydrateSubTree();
7046 }
7047 }
7048 else {
7049 {
7050 startMeasure(instance, `render`);
7051 }
7052 const subTree = (instance.subTree = renderComponentRoot(instance));
7053 {
7054 endMeasure(instance, `render`);
7055 }
7056 {
7057 startMeasure(instance, `patch`);
7058 }
7059 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
7060 {
7061 endMeasure(instance, `patch`);
7062 }
7063 initialVNode.el = subTree.el;
7064 }
7065 // mounted hook
7066 if (m) {
7067 queuePostRenderEffect(m, parentSuspense);
7068 }
7069 // onVnodeMounted
7070 if (!isAsyncWrapperVNode &&
7071 (vnodeHook = props && props.onVnodeMounted)) {
7072 const scopedInitialVNode = initialVNode;
7073 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
7074 }
7075 // activated hook for keep-alive roots.
7076 // #1742 activated hook must be accessed after first render
7077 // since the hook may be injected by a child keep-alive
7078 if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */ ||
7079 (parent &&
7080 isAsyncWrapper(parent.vnode) &&
7081 parent.vnode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */)) {
7082 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
7083 }
7084 instance.isMounted = true;
7085 {
7086 devtoolsComponentAdded(instance);
7087 }
7088 // #2458: deference mount-only object parameters to prevent memleaks
7089 initialVNode = container = anchor = null;
7090 }
7091 else {
7092 // updateComponent
7093 // This is triggered by mutation of component's own state (next: null)
7094 // OR parent calling processComponent (next: VNode)
7095 let { next, bu, u, parent, vnode } = instance;
7096 let originNext = next;
7097 let vnodeHook;
7098 {
7099 pushWarningContext(next || instance.vnode);
7100 }
7101 // Disallow component effect recursion during pre-lifecycle hooks.
7102 toggleRecurse(instance, false);
7103 if (next) {
7104 next.el = vnode.el;
7105 updateComponentPreRender(instance, next, optimized);
7106 }
7107 else {
7108 next = vnode;
7109 }
7110 // beforeUpdate hook
7111 if (bu) {
7112 invokeArrayFns(bu);
7113 }
7114 // onVnodeBeforeUpdate
7115 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
7116 invokeVNodeHook(vnodeHook, parent, next, vnode);
7117 }
7118 toggleRecurse(instance, true);
7119 // render
7120 {
7121 startMeasure(instance, `render`);
7122 }
7123 const nextTree = renderComponentRoot(instance);
7124 {
7125 endMeasure(instance, `render`);
7126 }
7127 const prevTree = instance.subTree;
7128 instance.subTree = nextTree;
7129 {
7130 startMeasure(instance, `patch`);
7131 }
7132 patch(prevTree, nextTree,
7133 // parent may have changed if it's in a teleport
7134 hostParentNode(prevTree.el),
7135 // anchor may have changed if it's in a fragment
7136 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
7137 {
7138 endMeasure(instance, `patch`);
7139 }
7140 next.el = nextTree.el;
7141 if (originNext === null) {
7142 // self-triggered update. In case of HOC, update parent component
7143 // vnode el. HOC is indicated by parent instance's subTree pointing
7144 // to child component's vnode
7145 updateHOCHostEl(instance, nextTree.el);
7146 }
7147 // updated hook
7148 if (u) {
7149 queuePostRenderEffect(u, parentSuspense);
7150 }
7151 // onVnodeUpdated
7152 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
7153 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
7154 }
7155 {
7156 devtoolsComponentUpdated(instance);
7157 }
7158 {
7159 popWarningContext();
7160 }
7161 }
7162 };
7163 // create reactive effect for rendering
7164 const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(update), instance.scope // track it in component's effect scope
7165 ));
7166 const update = (instance.update = () => effect.run());
7167 update.id = instance.uid;
7168 // allowRecurse
7169 // #1801, #2043 component render effects should allow recursive updates
7170 toggleRecurse(instance, true);
7171 {
7172 effect.onTrack = instance.rtc
7173 ? e => invokeArrayFns(instance.rtc, e)
7174 : void 0;
7175 effect.onTrigger = instance.rtg
7176 ? e => invokeArrayFns(instance.rtg, e)
7177 : void 0;
7178 update.ownerInstance = instance;
7179 }
7180 update();
7181 };
7182 const updateComponentPreRender = (instance, nextVNode, optimized) => {
7183 nextVNode.component = instance;
7184 const prevProps = instance.vnode.props;
7185 instance.vnode = nextVNode;
7186 instance.next = null;
7187 updateProps(instance, nextVNode.props, prevProps, optimized);
7188 updateSlots(instance, nextVNode.children, optimized);
7189 pauseTracking();
7190 // props update may have triggered pre-flush watchers.
7191 // flush them before the render update.
7192 flushPreFlushCbs(undefined, instance.update);
7193 resetTracking();
7194 };
7195 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
7196 const c1 = n1 && n1.children;
7197 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
7198 const c2 = n2.children;
7199 const { patchFlag, shapeFlag } = n2;
7200 // fast path
7201 if (patchFlag > 0) {
7202 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
7203 // this could be either fully-keyed or mixed (some keyed some not)
7204 // presence of patchFlag means children are guaranteed to be arrays
7205 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7206 return;
7207 }
7208 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
7209 // unkeyed
7210 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7211 return;
7212 }
7213 }
7214 // children has 3 possibilities: text, array or no children.
7215 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
7216 // text children fast path
7217 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
7218 unmountChildren(c1, parentComponent, parentSuspense);
7219 }
7220 if (c2 !== c1) {
7221 hostSetElementText(container, c2);
7222 }
7223 }
7224 else {
7225 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
7226 // prev children was array
7227 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7228 // two arrays, cannot assume anything, do full diff
7229 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7230 }
7231 else {
7232 // no new children, just unmount old
7233 unmountChildren(c1, parentComponent, parentSuspense, true);
7234 }
7235 }
7236 else {
7237 // prev children was text OR null
7238 // new children is array OR null
7239 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
7240 hostSetElementText(container, '');
7241 }
7242 // mount new if array
7243 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7244 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7245 }
7246 }
7247 }
7248 };
7249 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7250 c1 = c1 || EMPTY_ARR;
7251 c2 = c2 || EMPTY_ARR;
7252 const oldLength = c1.length;
7253 const newLength = c2.length;
7254 const commonLength = Math.min(oldLength, newLength);
7255 let i;
7256 for (i = 0; i < commonLength; i++) {
7257 const nextChild = (c2[i] = optimized
7258 ? cloneIfMounted(c2[i])
7259 : normalizeVNode(c2[i]));
7260 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7261 }
7262 if (oldLength > newLength) {
7263 // remove old
7264 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
7265 }
7266 else {
7267 // mount new
7268 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
7269 }
7270 };
7271 // can be all-keyed or mixed
7272 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7273 let i = 0;
7274 const l2 = c2.length;
7275 let e1 = c1.length - 1; // prev ending index
7276 let e2 = l2 - 1; // next ending index
7277 // 1. sync from start
7278 // (a b) c
7279 // (a b) d e
7280 while (i <= e1 && i <= e2) {
7281 const n1 = c1[i];
7282 const n2 = (c2[i] = optimized
7283 ? cloneIfMounted(c2[i])
7284 : normalizeVNode(c2[i]));
7285 if (isSameVNodeType(n1, n2)) {
7286 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7287 }
7288 else {
7289 break;
7290 }
7291 i++;
7292 }
7293 // 2. sync from end
7294 // a (b c)
7295 // d e (b c)
7296 while (i <= e1 && i <= e2) {
7297 const n1 = c1[e1];
7298 const n2 = (c2[e2] = optimized
7299 ? cloneIfMounted(c2[e2])
7300 : normalizeVNode(c2[e2]));
7301 if (isSameVNodeType(n1, n2)) {
7302 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7303 }
7304 else {
7305 break;
7306 }
7307 e1--;
7308 e2--;
7309 }
7310 // 3. common sequence + mount
7311 // (a b)
7312 // (a b) c
7313 // i = 2, e1 = 1, e2 = 2
7314 // (a b)
7315 // c (a b)
7316 // i = 0, e1 = -1, e2 = 0
7317 if (i > e1) {
7318 if (i <= e2) {
7319 const nextPos = e2 + 1;
7320 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
7321 while (i <= e2) {
7322 patch(null, (c2[i] = optimized
7323 ? cloneIfMounted(c2[i])
7324 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7325 i++;
7326 }
7327 }
7328 }
7329 // 4. common sequence + unmount
7330 // (a b) c
7331 // (a b)
7332 // i = 2, e1 = 2, e2 = 1
7333 // a (b c)
7334 // (b c)
7335 // i = 0, e1 = 0, e2 = -1
7336 else if (i > e2) {
7337 while (i <= e1) {
7338 unmount(c1[i], parentComponent, parentSuspense, true);
7339 i++;
7340 }
7341 }
7342 // 5. unknown sequence
7343 // [i ... e1 + 1]: a b [c d e] f g
7344 // [i ... e2 + 1]: a b [e d c h] f g
7345 // i = 2, e1 = 4, e2 = 5
7346 else {
7347 const s1 = i; // prev starting index
7348 const s2 = i; // next starting index
7349 // 5.1 build key:index map for newChildren
7350 const keyToNewIndexMap = new Map();
7351 for (i = s2; i <= e2; i++) {
7352 const nextChild = (c2[i] = optimized
7353 ? cloneIfMounted(c2[i])
7354 : normalizeVNode(c2[i]));
7355 if (nextChild.key != null) {
7356 if (keyToNewIndexMap.has(nextChild.key)) {
7357 warn$1(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
7358 }
7359 keyToNewIndexMap.set(nextChild.key, i);
7360 }
7361 }
7362 // 5.2 loop through old children left to be patched and try to patch
7363 // matching nodes & remove nodes that are no longer present
7364 let j;
7365 let patched = 0;
7366 const toBePatched = e2 - s2 + 1;
7367 let moved = false;
7368 // used to track whether any node has moved
7369 let maxNewIndexSoFar = 0;
7370 // works as Map<newIndex, oldIndex>
7371 // Note that oldIndex is offset by +1
7372 // and oldIndex = 0 is a special value indicating the new node has
7373 // no corresponding old node.
7374 // used for determining longest stable subsequence
7375 const newIndexToOldIndexMap = new Array(toBePatched);
7376 for (i = 0; i < toBePatched; i++)
7377 newIndexToOldIndexMap[i] = 0;
7378 for (i = s1; i <= e1; i++) {
7379 const prevChild = c1[i];
7380 if (patched >= toBePatched) {
7381 // all new children have been patched so this can only be a removal
7382 unmount(prevChild, parentComponent, parentSuspense, true);
7383 continue;
7384 }
7385 let newIndex;
7386 if (prevChild.key != null) {
7387 newIndex = keyToNewIndexMap.get(prevChild.key);
7388 }
7389 else {
7390 // key-less node, try to locate a key-less node of the same type
7391 for (j = s2; j <= e2; j++) {
7392 if (newIndexToOldIndexMap[j - s2] === 0 &&
7393 isSameVNodeType(prevChild, c2[j])) {
7394 newIndex = j;
7395 break;
7396 }
7397 }
7398 }
7399 if (newIndex === undefined) {
7400 unmount(prevChild, parentComponent, parentSuspense, true);
7401 }
7402 else {
7403 newIndexToOldIndexMap[newIndex - s2] = i + 1;
7404 if (newIndex >= maxNewIndexSoFar) {
7405 maxNewIndexSoFar = newIndex;
7406 }
7407 else {
7408 moved = true;
7409 }
7410 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7411 patched++;
7412 }
7413 }
7414 // 5.3 move and mount
7415 // generate longest stable subsequence only when nodes have moved
7416 const increasingNewIndexSequence = moved
7417 ? getSequence(newIndexToOldIndexMap)
7418 : EMPTY_ARR;
7419 j = increasingNewIndexSequence.length - 1;
7420 // looping backwards so that we can use last patched node as anchor
7421 for (i = toBePatched - 1; i >= 0; i--) {
7422 const nextIndex = s2 + i;
7423 const nextChild = c2[nextIndex];
7424 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
7425 if (newIndexToOldIndexMap[i] === 0) {
7426 // mount new
7427 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7428 }
7429 else if (moved) {
7430 // move if:
7431 // There is no stable subsequence (e.g. a reverse)
7432 // OR current node is not among the stable sequence
7433 if (j < 0 || i !== increasingNewIndexSequence[j]) {
7434 move(nextChild, container, anchor, 2 /* REORDER */);
7435 }
7436 else {
7437 j--;
7438 }
7439 }
7440 }
7441 }
7442 };
7443 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
7444 const { el, type, transition, children, shapeFlag } = vnode;
7445 if (shapeFlag & 6 /* COMPONENT */) {
7446 move(vnode.component.subTree, container, anchor, moveType);
7447 return;
7448 }
7449 if (shapeFlag & 128 /* SUSPENSE */) {
7450 vnode.suspense.move(container, anchor, moveType);
7451 return;
7452 }
7453 if (shapeFlag & 64 /* TELEPORT */) {
7454 type.move(vnode, container, anchor, internals);
7455 return;
7456 }
7457 if (type === Fragment) {
7458 hostInsert(el, container, anchor);
7459 for (let i = 0; i < children.length; i++) {
7460 move(children[i], container, anchor, moveType);
7461 }
7462 hostInsert(vnode.anchor, container, anchor);
7463 return;
7464 }
7465 if (type === Static) {
7466 moveStaticNode(vnode, container, anchor);
7467 return;
7468 }
7469 // single nodes
7470 const needTransition = moveType !== 2 /* REORDER */ &&
7471 shapeFlag & 1 /* ELEMENT */ &&
7472 transition;
7473 if (needTransition) {
7474 if (moveType === 0 /* ENTER */) {
7475 transition.beforeEnter(el);
7476 hostInsert(el, container, anchor);
7477 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
7478 }
7479 else {
7480 const { leave, delayLeave, afterLeave } = transition;
7481 const remove = () => hostInsert(el, container, anchor);
7482 const performLeave = () => {
7483 leave(el, () => {
7484 remove();
7485 afterLeave && afterLeave();
7486 });
7487 };
7488 if (delayLeave) {
7489 delayLeave(el, remove, performLeave);
7490 }
7491 else {
7492 performLeave();
7493 }
7494 }
7495 }
7496 else {
7497 hostInsert(el, container, anchor);
7498 }
7499 };
7500 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
7501 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
7502 // unset ref
7503 if (ref != null) {
7504 setRef(ref, null, parentSuspense, vnode, true);
7505 }
7506 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
7507 parentComponent.ctx.deactivate(vnode);
7508 return;
7509 }
7510 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
7511 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
7512 let vnodeHook;
7513 if (shouldInvokeVnodeHook &&
7514 (vnodeHook = props && props.onVnodeBeforeUnmount)) {
7515 invokeVNodeHook(vnodeHook, parentComponent, vnode);
7516 }
7517 if (shapeFlag & 6 /* COMPONENT */) {
7518 unmountComponent(vnode.component, parentSuspense, doRemove);
7519 }
7520 else {
7521 if (shapeFlag & 128 /* SUSPENSE */) {
7522 vnode.suspense.unmount(parentSuspense, doRemove);
7523 return;
7524 }
7525 if (shouldInvokeDirs) {
7526 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
7527 }
7528 if (shapeFlag & 64 /* TELEPORT */) {
7529 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
7530 }
7531 else if (dynamicChildren &&
7532 // #1153: fast path should not be taken for non-stable (v-for) fragments
7533 (type !== Fragment ||
7534 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
7535 // fast path for block nodes: only need to unmount dynamic children.
7536 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
7537 }
7538 else if ((type === Fragment &&
7539 patchFlag &
7540 (128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) ||
7541 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
7542 unmountChildren(children, parentComponent, parentSuspense);
7543 }
7544 if (doRemove) {
7545 remove(vnode);
7546 }
7547 }
7548 if ((shouldInvokeVnodeHook &&
7549 (vnodeHook = props && props.onVnodeUnmounted)) ||
7550 shouldInvokeDirs) {
7551 queuePostRenderEffect(() => {
7552 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
7553 shouldInvokeDirs &&
7554 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
7555 }, parentSuspense);
7556 }
7557 };
7558 const remove = vnode => {
7559 const { type, el, anchor, transition } = vnode;
7560 if (type === Fragment) {
7561 if (vnode.patchFlag > 0 &&
7562 vnode.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */ &&
7563 transition &&
7564 !transition.persisted) {
7565 vnode.children.forEach(child => {
7566 if (child.type === Comment) {
7567 hostRemove(child.el);
7568 }
7569 else {
7570 remove(child);
7571 }
7572 });
7573 }
7574 else {
7575 removeFragment(el, anchor);
7576 }
7577 return;
7578 }
7579 if (type === Static) {
7580 removeStaticNode(vnode);
7581 return;
7582 }
7583 const performRemove = () => {
7584 hostRemove(el);
7585 if (transition && !transition.persisted && transition.afterLeave) {
7586 transition.afterLeave();
7587 }
7588 };
7589 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
7590 transition &&
7591 !transition.persisted) {
7592 const { leave, delayLeave } = transition;
7593 const performLeave = () => leave(el, performRemove);
7594 if (delayLeave) {
7595 delayLeave(vnode.el, performRemove, performLeave);
7596 }
7597 else {
7598 performLeave();
7599 }
7600 }
7601 else {
7602 performRemove();
7603 }
7604 };
7605 const removeFragment = (cur, end) => {
7606 // For fragments, directly remove all contained DOM nodes.
7607 // (fragment child nodes cannot have transition)
7608 let next;
7609 while (cur !== end) {
7610 next = hostNextSibling(cur);
7611 hostRemove(cur);
7612 cur = next;
7613 }
7614 hostRemove(end);
7615 };
7616 const unmountComponent = (instance, parentSuspense, doRemove) => {
7617 if (instance.type.__hmrId) {
7618 unregisterHMR(instance);
7619 }
7620 const { bum, scope, update, subTree, um } = instance;
7621 // beforeUnmount hook
7622 if (bum) {
7623 invokeArrayFns(bum);
7624 }
7625 // stop effects in component scope
7626 scope.stop();
7627 // update may be null if a component is unmounted before its async
7628 // setup has resolved.
7629 if (update) {
7630 // so that scheduler will no longer invoke it
7631 update.active = false;
7632 unmount(subTree, instance, parentSuspense, doRemove);
7633 }
7634 // unmounted hook
7635 if (um) {
7636 queuePostRenderEffect(um, parentSuspense);
7637 }
7638 queuePostRenderEffect(() => {
7639 instance.isUnmounted = true;
7640 }, parentSuspense);
7641 // A component with async dep inside a pending suspense is unmounted before
7642 // its async dep resolves. This should remove the dep from the suspense, and
7643 // cause the suspense to resolve immediately if that was the last dep.
7644 if (parentSuspense &&
7645 parentSuspense.pendingBranch &&
7646 !parentSuspense.isUnmounted &&
7647 instance.asyncDep &&
7648 !instance.asyncResolved &&
7649 instance.suspenseId === parentSuspense.pendingId) {
7650 parentSuspense.deps--;
7651 if (parentSuspense.deps === 0) {
7652 parentSuspense.resolve();
7653 }
7654 }
7655 {
7656 devtoolsComponentRemoved(instance);
7657 }
7658 };
7659 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
7660 for (let i = start; i < children.length; i++) {
7661 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
7662 }
7663 };
7664 const getNextHostNode = vnode => {
7665 if (vnode.shapeFlag & 6 /* COMPONENT */) {
7666 return getNextHostNode(vnode.component.subTree);
7667 }
7668 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
7669 return vnode.suspense.next();
7670 }
7671 return hostNextSibling((vnode.anchor || vnode.el));
7672 };
7673 const render = (vnode, container, isSVG) => {
7674 if (vnode == null) {
7675 if (container._vnode) {
7676 unmount(container._vnode, null, null, true);
7677 }
7678 }
7679 else {
7680 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
7681 }
7682 flushPostFlushCbs();
7683 container._vnode = vnode;
7684 };
7685 const internals = {
7686 p: patch,
7687 um: unmount,
7688 m: move,
7689 r: remove,
7690 mt: mountComponent,
7691 mc: mountChildren,
7692 pc: patchChildren,
7693 pbc: patchBlockChildren,
7694 n: getNextHostNode,
7695 o: options
7696 };
7697 let hydrate;
7698 let hydrateNode;
7699 if (createHydrationFns) {
7700 [hydrate, hydrateNode] = createHydrationFns(internals);
7701 }
7702 return {
7703 render,
7704 hydrate,
7705 createApp: createAppAPI(render, hydrate)
7706 };
7707 }
7708 function toggleRecurse({ effect, update }, allowed) {
7709 effect.allowRecurse = update.allowRecurse = allowed;
7710 }
7711 /**
7712 * #1156
7713 * When a component is HMR-enabled, we need to make sure that all static nodes
7714 * inside a block also inherit the DOM element from the previous tree so that
7715 * HMR updates (which are full updates) can retrieve the element for patching.
7716 *
7717 * #2080
7718 * Inside keyed `template` fragment static children, if a fragment is moved,
7719 * the children will always be moved. Therefore, in order to ensure correct move
7720 * position, el should be inherited from previous nodes.
7721 */
7722 function traverseStaticChildren(n1, n2, shallow = false) {
7723 const ch1 = n1.children;
7724 const ch2 = n2.children;
7725 if (isArray(ch1) && isArray(ch2)) {
7726 for (let i = 0; i < ch1.length; i++) {
7727 // this is only called in the optimized path so array children are
7728 // guaranteed to be vnodes
7729 const c1 = ch1[i];
7730 let c2 = ch2[i];
7731 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
7732 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
7733 c2 = ch2[i] = cloneIfMounted(ch2[i]);
7734 c2.el = c1.el;
7735 }
7736 if (!shallow)
7737 traverseStaticChildren(c1, c2);
7738 }
7739 // also inherit for comment nodes, but not placeholders (e.g. v-if which
7740 // would have received .el during block patch)
7741 if (c2.type === Comment && !c2.el) {
7742 c2.el = c1.el;
7743 }
7744 }
7745 }
7746 }
7747 // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
7748 function getSequence(arr) {
7749 const p = arr.slice();
7750 const result = [0];
7751 let i, j, u, v, c;
7752 const len = arr.length;
7753 for (i = 0; i < len; i++) {
7754 const arrI = arr[i];
7755 if (arrI !== 0) {
7756 j = result[result.length - 1];
7757 if (arr[j] < arrI) {
7758 p[i] = j;
7759 result.push(i);
7760 continue;
7761 }
7762 u = 0;
7763 v = result.length - 1;
7764 while (u < v) {
7765 c = (u + v) >> 1;
7766 if (arr[result[c]] < arrI) {
7767 u = c + 1;
7768 }
7769 else {
7770 v = c;
7771 }
7772 }
7773 if (arrI < arr[result[u]]) {
7774 if (u > 0) {
7775 p[i] = result[u - 1];
7776 }
7777 result[u] = i;
7778 }
7779 }
7780 }
7781 u = result.length;
7782 v = result[u - 1];
7783 while (u-- > 0) {
7784 result[u] = v;
7785 v = p[v];
7786 }
7787 return result;
7788 }
7789
7790 const isTeleport = (type) => type.__isTeleport;
7791 const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
7792 const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
7793 const resolveTarget = (props, select) => {
7794 const targetSelector = props && props.to;
7795 if (isString(targetSelector)) {
7796 if (!select) {
7797 warn$1(`Current renderer does not support string target for Teleports. ` +
7798 `(missing querySelector renderer option)`);
7799 return null;
7800 }
7801 else {
7802 const target = select(targetSelector);
7803 if (!target) {
7804 warn$1(`Failed to locate Teleport target with selector "${targetSelector}". ` +
7805 `Note the target element must exist before the component is mounted - ` +
7806 `i.e. the target cannot be rendered by the component itself, and ` +
7807 `ideally should be outside of the entire Vue component tree.`);
7808 }
7809 return target;
7810 }
7811 }
7812 else {
7813 if (!targetSelector && !isTeleportDisabled(props)) {
7814 warn$1(`Invalid Teleport target: ${targetSelector}`);
7815 }
7816 return targetSelector;
7817 }
7818 };
7819 const TeleportImpl = {
7820 __isTeleport: true,
7821 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
7822 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
7823 const disabled = isTeleportDisabled(n2.props);
7824 let { shapeFlag, children, dynamicChildren } = n2;
7825 // #3302
7826 // HMR updated, force full diff
7827 if (isHmrUpdating) {
7828 optimized = false;
7829 dynamicChildren = null;
7830 }
7831 if (n1 == null) {
7832 // insert anchors in the main view
7833 const placeholder = (n2.el = createComment('teleport start')
7834 );
7835 const mainAnchor = (n2.anchor = createComment('teleport end')
7836 );
7837 insert(placeholder, container, anchor);
7838 insert(mainAnchor, container, anchor);
7839 const target = (n2.target = resolveTarget(n2.props, querySelector));
7840 const targetAnchor = (n2.targetAnchor = createText(''));
7841 if (target) {
7842 insert(targetAnchor, target);
7843 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
7844 isSVG = isSVG || isTargetSVG(target);
7845 }
7846 else if (!disabled) {
7847 warn$1('Invalid Teleport target on mount:', target, `(${typeof target})`);
7848 }
7849 const mount = (container, anchor) => {
7850 // Teleport *always* has Array children. This is enforced in both the
7851 // compiler and vnode children normalization.
7852 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7853 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7854 }
7855 };
7856 if (disabled) {
7857 mount(container, mainAnchor);
7858 }
7859 else if (target) {
7860 mount(target, targetAnchor);
7861 }
7862 }
7863 else {
7864 // update content
7865 n2.el = n1.el;
7866 const mainAnchor = (n2.anchor = n1.anchor);
7867 const target = (n2.target = n1.target);
7868 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
7869 const wasDisabled = isTeleportDisabled(n1.props);
7870 const currentContainer = wasDisabled ? container : target;
7871 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
7872 isSVG = isSVG || isTargetSVG(target);
7873 if (dynamicChildren) {
7874 // fast path when the teleport happens to be a block root
7875 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
7876 // even in block tree mode we need to make sure all root-level nodes
7877 // in the teleport inherit previous DOM references so that they can
7878 // be moved in future patches.
7879 traverseStaticChildren(n1, n2, true);
7880 }
7881 else if (!optimized) {
7882 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
7883 }
7884 if (disabled) {
7885 if (!wasDisabled) {
7886 // enabled -> disabled
7887 // move into main container
7888 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
7889 }
7890 }
7891 else {
7892 // target changed
7893 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
7894 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
7895 if (nextTarget) {
7896 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
7897 }
7898 else {
7899 warn$1('Invalid Teleport target on update:', target, `(${typeof target})`);
7900 }
7901 }
7902 else if (wasDisabled) {
7903 // disabled -> enabled
7904 // move into teleport target
7905 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
7906 }
7907 }
7908 }
7909 },
7910 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
7911 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
7912 if (target) {
7913 hostRemove(targetAnchor);
7914 }
7915 // an unmounted teleport should always remove its children if not disabled
7916 if (doRemove || !isTeleportDisabled(props)) {
7917 hostRemove(anchor);
7918 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7919 for (let i = 0; i < children.length; i++) {
7920 const child = children[i];
7921 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
7922 }
7923 }
7924 }
7925 },
7926 move: moveTeleport,
7927 hydrate: hydrateTeleport
7928 };
7929 function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
7930 // move target anchor if this is a target change.
7931 if (moveType === 0 /* TARGET_CHANGE */) {
7932 insert(vnode.targetAnchor, container, parentAnchor);
7933 }
7934 const { el, anchor, shapeFlag, children, props } = vnode;
7935 const isReorder = moveType === 2 /* REORDER */;
7936 // move main view anchor if this is a re-order.
7937 if (isReorder) {
7938 insert(el, container, parentAnchor);
7939 }
7940 // if this is a re-order and teleport is enabled (content is in target)
7941 // do not move children. So the opposite is: only move children if this
7942 // is not a reorder, or the teleport is disabled
7943 if (!isReorder || isTeleportDisabled(props)) {
7944 // Teleport has either Array children or no children.
7945 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7946 for (let i = 0; i < children.length; i++) {
7947 move(children[i], container, parentAnchor, 2 /* REORDER */);
7948 }
7949 }
7950 }
7951 // move main view anchor if this is a re-order.
7952 if (isReorder) {
7953 insert(anchor, container, parentAnchor);
7954 }
7955 }
7956 function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
7957 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
7958 if (target) {
7959 // if multiple teleports rendered to the same target element, we need to
7960 // pick up from where the last teleport finished instead of the first node
7961 const targetNode = target._lpa || target.firstChild;
7962 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
7963 if (isTeleportDisabled(vnode.props)) {
7964 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
7965 vnode.targetAnchor = targetNode;
7966 }
7967 else {
7968 vnode.anchor = nextSibling(node);
7969 // lookahead until we find the target anchor
7970 // we cannot rely on return value of hydrateChildren() because there
7971 // could be nested teleports
7972 let targetAnchor = targetNode;
7973 while (targetAnchor) {
7974 targetAnchor = nextSibling(targetAnchor);
7975 if (targetAnchor &&
7976 targetAnchor.nodeType === 8 &&
7977 targetAnchor.data === 'teleport anchor') {
7978 vnode.targetAnchor = targetAnchor;
7979 target._lpa =
7980 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
7981 break;
7982 }
7983 }
7984 hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
7985 }
7986 }
7987 }
7988 return vnode.anchor && nextSibling(vnode.anchor);
7989 }
7990 // Force-casted public typing for h and TSX props inference
7991 const Teleport = TeleportImpl;
7992
7993 const Fragment = Symbol('Fragment' );
7994 const Text = Symbol('Text' );
7995 const Comment = Symbol('Comment' );
7996 const Static = Symbol('Static' );
7997 // Since v-if and v-for are the two possible ways node structure can dynamically
7998 // change, once we consider v-if branches and each v-for fragment a block, we
7999 // can divide a template into nested blocks, and within each block the node
8000 // structure would be stable. This allows us to skip most children diffing
8001 // and only worry about the dynamic nodes (indicated by patch flags).
8002 const blockStack = [];
8003 let currentBlock = null;
8004 /**
8005 * Open a block.
8006 * This must be called before `createBlock`. It cannot be part of `createBlock`
8007 * because the children of the block are evaluated before `createBlock` itself
8008 * is called. The generated code typically looks like this:
8009 *
8010 * ```js
8011 * function render() {
8012 * return (openBlock(),createBlock('div', null, [...]))
8013 * }
8014 * ```
8015 * disableTracking is true when creating a v-for fragment block, since a v-for
8016 * fragment always diffs its children.
8017 *
8018 * @private
8019 */
8020 function openBlock(disableTracking = false) {
8021 blockStack.push((currentBlock = disableTracking ? null : []));
8022 }
8023 function closeBlock() {
8024 blockStack.pop();
8025 currentBlock = blockStack[blockStack.length - 1] || null;
8026 }
8027 // Whether we should be tracking dynamic child nodes inside a block.
8028 // Only tracks when this value is > 0
8029 // We are not using a simple boolean because this value may need to be
8030 // incremented/decremented by nested usage of v-once (see below)
8031 let isBlockTreeEnabled = 1;
8032 /**
8033 * Block tracking sometimes needs to be disabled, for example during the
8034 * creation of a tree that needs to be cached by v-once. The compiler generates
8035 * code like this:
8036 *
8037 * ``` js
8038 * _cache[1] || (
8039 * setBlockTracking(-1),
8040 * _cache[1] = createVNode(...),
8041 * setBlockTracking(1),
8042 * _cache[1]
8043 * )
8044 * ```
8045 *
8046 * @private
8047 */
8048 function setBlockTracking(value) {
8049 isBlockTreeEnabled += value;
8050 }
8051 function setupBlock(vnode) {
8052 // save current block children on the block vnode
8053 vnode.dynamicChildren =
8054 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
8055 // close block
8056 closeBlock();
8057 // a block is always going to be patched, so track it as a child of its
8058 // parent block
8059 if (isBlockTreeEnabled > 0 && currentBlock) {
8060 currentBlock.push(vnode);
8061 }
8062 return vnode;
8063 }
8064 /**
8065 * @private
8066 */
8067 function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
8068 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
8069 }
8070 /**
8071 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
8072 * A block root keeps track of dynamic nodes within the block in the
8073 * `dynamicChildren` array.
8074 *
8075 * @private
8076 */
8077 function createBlock(type, props, children, patchFlag, dynamicProps) {
8078 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
8079 }
8080 function isVNode(value) {
8081 return value ? value.__v_isVNode === true : false;
8082 }
8083 function isSameVNodeType(n1, n2) {
8084 if (n2.shapeFlag & 6 /* COMPONENT */ &&
8085 hmrDirtyComponents.has(n2.type)) {
8086 // HMR only: if the component has been hot-updated, force a reload.
8087 return false;
8088 }
8089 return n1.type === n2.type && n1.key === n2.key;
8090 }
8091 let vnodeArgsTransformer;
8092 /**
8093 * Internal API for registering an arguments transform for createVNode
8094 * used for creating stubs in the test-utils
8095 * It is *internal* but needs to be exposed for test-utils to pick up proper
8096 * typings
8097 */
8098 function transformVNodeArgs(transformer) {
8099 vnodeArgsTransformer = transformer;
8100 }
8101 const createVNodeWithArgsTransform = (...args) => {
8102 return _createVNode(...(vnodeArgsTransformer
8103 ? vnodeArgsTransformer(args, currentRenderingInstance)
8104 : args));
8105 };
8106 const InternalObjectKey = `__vInternal`;
8107 const normalizeKey = ({ key }) => key != null ? key : null;
8108 const normalizeRef = ({ ref, ref_key, ref_for }) => {
8109 return (ref != null
8110 ? isString(ref) || isRef(ref) || isFunction(ref)
8111 ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8112 : ref
8113 : null);
8114 };
8115 function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
8116 const vnode = {
8117 __v_isVNode: true,
8118 __v_skip: true,
8119 type,
8120 props,
8121 key: props && normalizeKey(props),
8122 ref: props && normalizeRef(props),
8123 scopeId: currentScopeId,
8124 slotScopeIds: null,
8125 children,
8126 component: null,
8127 suspense: null,
8128 ssContent: null,
8129 ssFallback: null,
8130 dirs: null,
8131 transition: null,
8132 el: null,
8133 anchor: null,
8134 target: null,
8135 targetAnchor: null,
8136 staticCount: 0,
8137 shapeFlag,
8138 patchFlag,
8139 dynamicProps,
8140 dynamicChildren: null,
8141 appContext: null
8142 };
8143 if (needFullChildrenNormalization) {
8144 normalizeChildren(vnode, children);
8145 // normalize suspense children
8146 if (shapeFlag & 128 /* SUSPENSE */) {
8147 type.normalize(vnode);
8148 }
8149 }
8150 else if (children) {
8151 // compiled element vnode - if children is passed, only possible types are
8152 // string or Array.
8153 vnode.shapeFlag |= isString(children)
8154 ? 8 /* TEXT_CHILDREN */
8155 : 16 /* ARRAY_CHILDREN */;
8156 }
8157 // validate key
8158 if (vnode.key !== vnode.key) {
8159 warn$1(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
8160 }
8161 // track vnode for block tree
8162 if (isBlockTreeEnabled > 0 &&
8163 // avoid a block node from tracking itself
8164 !isBlockNode &&
8165 // has current parent block
8166 currentBlock &&
8167 // presence of a patch flag indicates this node needs patching on updates.
8168 // component nodes also should always be patched, because even if the
8169 // component doesn't need to update, it needs to persist the instance on to
8170 // the next vnode so that it can be properly unmounted later.
8171 (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
8172 // the EVENTS flag is only for hydration and if it is the only flag, the
8173 // vnode should not be considered dynamic due to handler caching.
8174 vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
8175 currentBlock.push(vnode);
8176 }
8177 return vnode;
8178 }
8179 const createVNode = (createVNodeWithArgsTransform );
8180 function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
8181 if (!type || type === NULL_DYNAMIC_COMPONENT) {
8182 if (!type) {
8183 warn$1(`Invalid vnode type when creating vnode: ${type}.`);
8184 }
8185 type = Comment;
8186 }
8187 if (isVNode(type)) {
8188 // createVNode receiving an existing vnode. This happens in cases like
8189 // <component :is="vnode"/>
8190 // #2078 make sure to merge refs during the clone instead of overwriting it
8191 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
8192 if (children) {
8193 normalizeChildren(cloned, children);
8194 }
8195 if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) {
8196 if (cloned.shapeFlag & 6 /* COMPONENT */) {
8197 currentBlock[currentBlock.indexOf(type)] = cloned;
8198 }
8199 else {
8200 currentBlock.push(cloned);
8201 }
8202 }
8203 cloned.patchFlag |= -2 /* BAIL */;
8204 return cloned;
8205 }
8206 // class component normalization.
8207 if (isClassComponent(type)) {
8208 type = type.__vccOpts;
8209 }
8210 // class & style normalization.
8211 if (props) {
8212 // for reactive or proxy objects, we need to clone it to enable mutation.
8213 props = guardReactiveProps(props);
8214 let { class: klass, style } = props;
8215 if (klass && !isString(klass)) {
8216 props.class = normalizeClass(klass);
8217 }
8218 if (isObject(style)) {
8219 // reactive state objects need to be cloned since they are likely to be
8220 // mutated
8221 if (isProxy(style) && !isArray(style)) {
8222 style = extend({}, style);
8223 }
8224 props.style = normalizeStyle(style);
8225 }
8226 }
8227 // encode the vnode type information into a bitmap
8228 const shapeFlag = isString(type)
8229 ? 1 /* ELEMENT */
8230 : isSuspense(type)
8231 ? 128 /* SUSPENSE */
8232 : isTeleport(type)
8233 ? 64 /* TELEPORT */
8234 : isObject(type)
8235 ? 4 /* STATEFUL_COMPONENT */
8236 : isFunction(type)
8237 ? 2 /* FUNCTIONAL_COMPONENT */
8238 : 0;
8239 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
8240 type = toRaw(type);
8241 warn$1(`Vue received a Component which was made a reactive object. This can ` +
8242 `lead to unnecessary performance overhead, and should be avoided by ` +
8243 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
8244 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
8245 }
8246 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
8247 }
8248 function guardReactiveProps(props) {
8249 if (!props)
8250 return null;
8251 return isProxy(props) || InternalObjectKey in props
8252 ? extend({}, props)
8253 : props;
8254 }
8255 function cloneVNode(vnode, extraProps, mergeRef = false) {
8256 // This is intentionally NOT using spread or extend to avoid the runtime
8257 // key enumeration cost.
8258 const { props, ref, patchFlag, children } = vnode;
8259 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
8260 const cloned = {
8261 __v_isVNode: true,
8262 __v_skip: true,
8263 type: vnode.type,
8264 props: mergedProps,
8265 key: mergedProps && normalizeKey(mergedProps),
8266 ref: extraProps && extraProps.ref
8267 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
8268 // if the vnode itself already has a ref, cloneVNode will need to merge
8269 // the refs so the single vnode can be set on multiple refs
8270 mergeRef && ref
8271 ? isArray(ref)
8272 ? ref.concat(normalizeRef(extraProps))
8273 : [ref, normalizeRef(extraProps)]
8274 : normalizeRef(extraProps)
8275 : ref,
8276 scopeId: vnode.scopeId,
8277 slotScopeIds: vnode.slotScopeIds,
8278 children: patchFlag === -1 /* HOISTED */ && isArray(children)
8279 ? children.map(deepCloneVNode)
8280 : children,
8281 target: vnode.target,
8282 targetAnchor: vnode.targetAnchor,
8283 staticCount: vnode.staticCount,
8284 shapeFlag: vnode.shapeFlag,
8285 // if the vnode is cloned with extra props, we can no longer assume its
8286 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
8287 // note: preserve flag for fragments since they use the flag for children
8288 // fast paths only.
8289 patchFlag: extraProps && vnode.type !== Fragment
8290 ? patchFlag === -1 // hoisted node
8291 ? 16 /* FULL_PROPS */
8292 : patchFlag | 16 /* FULL_PROPS */
8293 : patchFlag,
8294 dynamicProps: vnode.dynamicProps,
8295 dynamicChildren: vnode.dynamicChildren,
8296 appContext: vnode.appContext,
8297 dirs: vnode.dirs,
8298 transition: vnode.transition,
8299 // These should technically only be non-null on mounted VNodes. However,
8300 // they *should* be copied for kept-alive vnodes. So we just always copy
8301 // them since them being non-null during a mount doesn't affect the logic as
8302 // they will simply be overwritten.
8303 component: vnode.component,
8304 suspense: vnode.suspense,
8305 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
8306 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
8307 el: vnode.el,
8308 anchor: vnode.anchor
8309 };
8310 return cloned;
8311 }
8312 /**
8313 * Dev only, for HMR of hoisted vnodes reused in v-for
8314 * https://github.com/vitejs/vite/issues/2022
8315 */
8316 function deepCloneVNode(vnode) {
8317 const cloned = cloneVNode(vnode);
8318 if (isArray(vnode.children)) {
8319 cloned.children = vnode.children.map(deepCloneVNode);
8320 }
8321 return cloned;
8322 }
8323 /**
8324 * @private
8325 */
8326 function createTextVNode(text = ' ', flag = 0) {
8327 return createVNode(Text, null, text, flag);
8328 }
8329 /**
8330 * @private
8331 */
8332 function createStaticVNode(content, numberOfNodes) {
8333 // A static vnode can contain multiple stringified elements, and the number
8334 // of elements is necessary for hydration.
8335 const vnode = createVNode(Static, null, content);
8336 vnode.staticCount = numberOfNodes;
8337 return vnode;
8338 }
8339 /**
8340 * @private
8341 */
8342 function createCommentVNode(text = '',
8343 // when used as the v-else branch, the comment node must be created as a
8344 // block to ensure correct updates.
8345 asBlock = false) {
8346 return asBlock
8347 ? (openBlock(), createBlock(Comment, null, text))
8348 : createVNode(Comment, null, text);
8349 }
8350 function normalizeVNode(child) {
8351 if (child == null || typeof child === 'boolean') {
8352 // empty placeholder
8353 return createVNode(Comment);
8354 }
8355 else if (isArray(child)) {
8356 // fragment
8357 return createVNode(Fragment, null,
8358 // #3666, avoid reference pollution when reusing vnode
8359 child.slice());
8360 }
8361 else if (typeof child === 'object') {
8362 // already vnode, this should be the most common since compiled templates
8363 // always produce all-vnode children arrays
8364 return cloneIfMounted(child);
8365 }
8366 else {
8367 // strings and numbers
8368 return createVNode(Text, null, String(child));
8369 }
8370 }
8371 // optimized normalization for template-compiled render fns
8372 function cloneIfMounted(child) {
8373 return child.el === null || child.memo ? child : cloneVNode(child);
8374 }
8375 function normalizeChildren(vnode, children) {
8376 let type = 0;
8377 const { shapeFlag } = vnode;
8378 if (children == null) {
8379 children = null;
8380 }
8381 else if (isArray(children)) {
8382 type = 16 /* ARRAY_CHILDREN */;
8383 }
8384 else if (typeof children === 'object') {
8385 if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
8386 // Normalize slot to plain children for plain element and Teleport
8387 const slot = children.default;
8388 if (slot) {
8389 // _c marker is added by withCtx() indicating this is a compiled slot
8390 slot._c && (slot._d = false);
8391 normalizeChildren(vnode, slot());
8392 slot._c && (slot._d = true);
8393 }
8394 return;
8395 }
8396 else {
8397 type = 32 /* SLOTS_CHILDREN */;
8398 const slotFlag = children._;
8399 if (!slotFlag && !(InternalObjectKey in children)) {
8400 children._ctx = currentRenderingInstance;
8401 }
8402 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
8403 // a child component receives forwarded slots from the parent.
8404 // its slot type is determined by its parent's slot type.
8405 if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
8406 children._ = 1 /* STABLE */;
8407 }
8408 else {
8409 children._ = 2 /* DYNAMIC */;
8410 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
8411 }
8412 }
8413 }
8414 }
8415 else if (isFunction(children)) {
8416 children = { default: children, _ctx: currentRenderingInstance };
8417 type = 32 /* SLOTS_CHILDREN */;
8418 }
8419 else {
8420 children = String(children);
8421 // force teleport children to array so it can be moved around
8422 if (shapeFlag & 64 /* TELEPORT */) {
8423 type = 16 /* ARRAY_CHILDREN */;
8424 children = [createTextVNode(children)];
8425 }
8426 else {
8427 type = 8 /* TEXT_CHILDREN */;
8428 }
8429 }
8430 vnode.children = children;
8431 vnode.shapeFlag |= type;
8432 }
8433 function mergeProps(...args) {
8434 const ret = {};
8435 for (let i = 0; i < args.length; i++) {
8436 const toMerge = args[i];
8437 for (const key in toMerge) {
8438 if (key === 'class') {
8439 if (ret.class !== toMerge.class) {
8440 ret.class = normalizeClass([ret.class, toMerge.class]);
8441 }
8442 }
8443 else if (key === 'style') {
8444 ret.style = normalizeStyle([ret.style, toMerge.style]);
8445 }
8446 else if (isOn(key)) {
8447 const existing = ret[key];
8448 const incoming = toMerge[key];
8449 if (incoming &&
8450 existing !== incoming &&
8451 !(isArray(existing) && existing.includes(incoming))) {
8452 ret[key] = existing
8453 ? [].concat(existing, incoming)
8454 : incoming;
8455 }
8456 }
8457 else if (key !== '') {
8458 ret[key] = toMerge[key];
8459 }
8460 }
8461 }
8462 return ret;
8463 }
8464 function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8465 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
8466 vnode,
8467 prevVNode
8468 ]);
8469 }
8470
8471 const emptyAppContext = createAppContext();
8472 let uid$1 = 0;
8473 function createComponentInstance(vnode, parent, suspense) {
8474 const type = vnode.type;
8475 // inherit parent app context - or - if root, adopt from root vnode
8476 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
8477 const instance = {
8478 uid: uid$1++,
8479 vnode,
8480 type,
8481 parent,
8482 appContext,
8483 root: null,
8484 next: null,
8485 subTree: null,
8486 effect: null,
8487 update: null,
8488 scope: new EffectScope(true /* detached */),
8489 render: null,
8490 proxy: null,
8491 exposed: null,
8492 exposeProxy: null,
8493 withProxy: null,
8494 provides: parent ? parent.provides : Object.create(appContext.provides),
8495 accessCache: null,
8496 renderCache: [],
8497 // local resolved assets
8498 components: null,
8499 directives: null,
8500 // resolved props and emits options
8501 propsOptions: normalizePropsOptions(type, appContext),
8502 emitsOptions: normalizeEmitsOptions(type, appContext),
8503 // emit
8504 emit: null,
8505 emitted: null,
8506 // props default value
8507 propsDefaults: EMPTY_OBJ,
8508 // inheritAttrs
8509 inheritAttrs: type.inheritAttrs,
8510 // state
8511 ctx: EMPTY_OBJ,
8512 data: EMPTY_OBJ,
8513 props: EMPTY_OBJ,
8514 attrs: EMPTY_OBJ,
8515 slots: EMPTY_OBJ,
8516 refs: EMPTY_OBJ,
8517 setupState: EMPTY_OBJ,
8518 setupContext: null,
8519 // suspense related
8520 suspense,
8521 suspenseId: suspense ? suspense.pendingId : 0,
8522 asyncDep: null,
8523 asyncResolved: false,
8524 // lifecycle hooks
8525 // not using enums here because it results in computed properties
8526 isMounted: false,
8527 isUnmounted: false,
8528 isDeactivated: false,
8529 bc: null,
8530 c: null,
8531 bm: null,
8532 m: null,
8533 bu: null,
8534 u: null,
8535 um: null,
8536 bum: null,
8537 da: null,
8538 a: null,
8539 rtg: null,
8540 rtc: null,
8541 ec: null,
8542 sp: null
8543 };
8544 {
8545 instance.ctx = createDevRenderContext(instance);
8546 }
8547 instance.root = parent ? parent.root : instance;
8548 instance.emit = emit$1.bind(null, instance);
8549 // apply custom element special handling
8550 if (vnode.ce) {
8551 vnode.ce(instance);
8552 }
8553 return instance;
8554 }
8555 let currentInstance = null;
8556 const getCurrentInstance = () => currentInstance || currentRenderingInstance;
8557 const setCurrentInstance = (instance) => {
8558 currentInstance = instance;
8559 instance.scope.on();
8560 };
8561 const unsetCurrentInstance = () => {
8562 currentInstance && currentInstance.scope.off();
8563 currentInstance = null;
8564 };
8565 const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
8566 function validateComponentName(name, config) {
8567 const appIsNativeTag = config.isNativeTag || NO;
8568 if (isBuiltInTag(name) || appIsNativeTag(name)) {
8569 warn$1('Do not use built-in or reserved HTML elements as component id: ' + name);
8570 }
8571 }
8572 function isStatefulComponent(instance) {
8573 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
8574 }
8575 let isInSSRComponentSetup = false;
8576 function setupComponent(instance, isSSR = false) {
8577 isInSSRComponentSetup = isSSR;
8578 const { props, children } = instance.vnode;
8579 const isStateful = isStatefulComponent(instance);
8580 initProps(instance, props, isStateful, isSSR);
8581 initSlots(instance, children);
8582 const setupResult = isStateful
8583 ? setupStatefulComponent(instance, isSSR)
8584 : undefined;
8585 isInSSRComponentSetup = false;
8586 return setupResult;
8587 }
8588 function setupStatefulComponent(instance, isSSR) {
8589 var _a;
8590 const Component = instance.type;
8591 {
8592 if (Component.name) {
8593 validateComponentName(Component.name, instance.appContext.config);
8594 }
8595 if (Component.components) {
8596 const names = Object.keys(Component.components);
8597 for (let i = 0; i < names.length; i++) {
8598 validateComponentName(names[i], instance.appContext.config);
8599 }
8600 }
8601 if (Component.directives) {
8602 const names = Object.keys(Component.directives);
8603 for (let i = 0; i < names.length; i++) {
8604 validateDirectiveName(names[i]);
8605 }
8606 }
8607 if (Component.compilerOptions && isRuntimeOnly()) {
8608 warn$1(`"compilerOptions" is only supported when using a build of Vue that ` +
8609 `includes the runtime compiler. Since you are using a runtime-only ` +
8610 `build, the options should be passed via your build tool config instead.`);
8611 }
8612 }
8613 // 0. create render proxy property access cache
8614 instance.accessCache = Object.create(null);
8615 // 1. create public instance / render proxy
8616 // also mark it raw so it's never observed
8617 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
8618 {
8619 exposePropsOnRenderContext(instance);
8620 }
8621 // 2. call setup()
8622 const { setup } = Component;
8623 if (setup) {
8624 const setupContext = (instance.setupContext =
8625 setup.length > 1 ? createSetupContext(instance) : null);
8626 setCurrentInstance(instance);
8627 pauseTracking();
8628 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
8629 resetTracking();
8630 unsetCurrentInstance();
8631 if (isPromise(setupResult)) {
8632 setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
8633 if (isSSR) {
8634 // return the promise so server-renderer can wait on it
8635 return setupResult
8636 .then((resolvedResult) => {
8637 handleSetupResult(instance, resolvedResult, isSSR);
8638 })
8639 .catch(e => {
8640 handleError(e, instance, 0 /* SETUP_FUNCTION */);
8641 });
8642 }
8643 else {
8644 // async setup returned Promise.
8645 // bail here and wait for re-entry.
8646 instance.asyncDep = setupResult;
8647 if (!instance.suspense) {
8648 const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
8649 warn$1(`Component <${name}>: setup function returned a promise, but no ` +
8650 `<Suspense> boundary was found in the parent component tree. ` +
8651 `A component with async setup() must be nested in a <Suspense> ` +
8652 `in order to be rendered.`);
8653 }
8654 }
8655 }
8656 else {
8657 handleSetupResult(instance, setupResult, isSSR);
8658 }
8659 }
8660 else {
8661 finishComponentSetup(instance, isSSR);
8662 }
8663 }
8664 function handleSetupResult(instance, setupResult, isSSR) {
8665 if (isFunction(setupResult)) {
8666 // setup returned an inline render function
8667 {
8668 instance.render = setupResult;
8669 }
8670 }
8671 else if (isObject(setupResult)) {
8672 if (isVNode(setupResult)) {
8673 warn$1(`setup() should not return VNodes directly - ` +
8674 `return a render function instead.`);
8675 }
8676 // setup returned bindings.
8677 // assuming a render function compiled from template is present.
8678 {
8679 instance.devtoolsRawSetupState = setupResult;
8680 }
8681 instance.setupState = proxyRefs(setupResult);
8682 {
8683 exposeSetupStateOnRenderContext(instance);
8684 }
8685 }
8686 else if (setupResult !== undefined) {
8687 warn$1(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
8688 }
8689 finishComponentSetup(instance, isSSR);
8690 }
8691 let compile;
8692 let installWithProxy;
8693 /**
8694 * For runtime-dom to register the compiler.
8695 * Note the exported method uses any to avoid d.ts relying on the compiler types.
8696 */
8697 function registerRuntimeCompiler(_compile) {
8698 compile = _compile;
8699 installWithProxy = i => {
8700 if (i.render._rc) {
8701 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
8702 }
8703 };
8704 }
8705 // dev only
8706 const isRuntimeOnly = () => !compile;
8707 function finishComponentSetup(instance, isSSR, skipOptions) {
8708 const Component = instance.type;
8709 // template / render function normalization
8710 // could be already set when returned from setup()
8711 if (!instance.render) {
8712 // only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
8713 // is done by server-renderer
8714 if (!isSSR && compile && !Component.render) {
8715 const template = Component.template;
8716 if (template) {
8717 {
8718 startMeasure(instance, `compile`);
8719 }
8720 const { isCustomElement, compilerOptions } = instance.appContext.config;
8721 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
8722 const finalCompilerOptions = extend(extend({
8723 isCustomElement,
8724 delimiters
8725 }, compilerOptions), componentCompilerOptions);
8726 Component.render = compile(template, finalCompilerOptions);
8727 {
8728 endMeasure(instance, `compile`);
8729 }
8730 }
8731 }
8732 instance.render = (Component.render || NOOP);
8733 // for runtime-compiled render functions using `with` blocks, the render
8734 // proxy used needs a different `has` handler which is more performant and
8735 // also only allows a whitelist of globals to fallthrough.
8736 if (installWithProxy) {
8737 installWithProxy(instance);
8738 }
8739 }
8740 // support for 2.x options
8741 {
8742 setCurrentInstance(instance);
8743 pauseTracking();
8744 applyOptions(instance);
8745 resetTracking();
8746 unsetCurrentInstance();
8747 }
8748 // warn missing template/render
8749 // the runtime compilation of template in SSR is done by server-render
8750 if (!Component.render && instance.render === NOOP && !isSSR) {
8751 /* istanbul ignore if */
8752 if (!compile && Component.template) {
8753 warn$1(`Component provided template option but ` +
8754 `runtime compilation is not supported in this build of Vue.` +
8755 (` Use "vue.global.js" instead.`
8756 ) /* should not happen */);
8757 }
8758 else {
8759 warn$1(`Component is missing template or render function.`);
8760 }
8761 }
8762 }
8763 function createAttrsProxy(instance) {
8764 return new Proxy(instance.attrs, {
8765 get(target, key) {
8766 markAttrsAccessed();
8767 track(instance, "get" /* GET */, '$attrs');
8768 return target[key];
8769 },
8770 set() {
8771 warn$1(`setupContext.attrs is readonly.`);
8772 return false;
8773 },
8774 deleteProperty() {
8775 warn$1(`setupContext.attrs is readonly.`);
8776 return false;
8777 }
8778 }
8779 );
8780 }
8781 function createSetupContext(instance) {
8782 const expose = exposed => {
8783 if (instance.exposed) {
8784 warn$1(`expose() should be called only once per setup().`);
8785 }
8786 instance.exposed = exposed || {};
8787 };
8788 let attrs;
8789 {
8790 // We use getters in dev in case libs like test-utils overwrite instance
8791 // properties (overwrites should not be done in prod)
8792 return Object.freeze({
8793 get attrs() {
8794 return attrs || (attrs = createAttrsProxy(instance));
8795 },
8796 get slots() {
8797 return shallowReadonly(instance.slots);
8798 },
8799 get emit() {
8800 return (event, ...args) => instance.emit(event, ...args);
8801 },
8802 expose
8803 });
8804 }
8805 }
8806 function getExposeProxy(instance) {
8807 if (instance.exposed) {
8808 return (instance.exposeProxy ||
8809 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
8810 get(target, key) {
8811 if (key in target) {
8812 return target[key];
8813 }
8814 else if (key in publicPropertiesMap) {
8815 return publicPropertiesMap[key](instance);
8816 }
8817 }
8818 })));
8819 }
8820 }
8821 const classifyRE = /(?:^|[-_])(\w)/g;
8822 const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
8823 function getComponentName(Component) {
8824 return isFunction(Component)
8825 ? Component.displayName || Component.name
8826 : Component.name;
8827 }
8828 /* istanbul ignore next */
8829 function formatComponentName(instance, Component, isRoot = false) {
8830 let name = getComponentName(Component);
8831 if (!name && Component.__file) {
8832 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
8833 if (match) {
8834 name = match[1];
8835 }
8836 }
8837 if (!name && instance && instance.parent) {
8838 // try to infer the name based on reverse resolution
8839 const inferFromRegistry = (registry) => {
8840 for (const key in registry) {
8841 if (registry[key] === Component) {
8842 return key;
8843 }
8844 }
8845 };
8846 name =
8847 inferFromRegistry(instance.components ||
8848 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
8849 }
8850 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
8851 }
8852 function isClassComponent(value) {
8853 return isFunction(value) && '__vccOpts' in value;
8854 }
8855
8856 const computed$1 = ((getterOrOptions, debugOptions) => {
8857 // @ts-ignore
8858 return computed(getterOrOptions, debugOptions, isInSSRComponentSetup);
8859 });
8860
8861 // dev only
8862 const warnRuntimeUsage = (method) => warn$1(`${method}() is a compiler-hint helper that is only usable inside ` +
8863 `<script setup> of a single file component. Its arguments should be ` +
8864 `compiled away and passing it at runtime has no effect.`);
8865 // implementation
8866 function defineProps() {
8867 {
8868 warnRuntimeUsage(`defineProps`);
8869 }
8870 return null;
8871 }
8872 // implementation
8873 function defineEmits() {
8874 {
8875 warnRuntimeUsage(`defineEmits`);
8876 }
8877 return null;
8878 }
8879 /**
8880 * Vue `<script setup>` compiler macro for declaring a component's exposed
8881 * instance properties when it is accessed by a parent component via template
8882 * refs.
8883 *
8884 * `<script setup>` components are closed by default - i.e. variables inside
8885 * the `<script setup>` scope is not exposed to parent unless explicitly exposed
8886 * via `defineExpose`.
8887 *
8888 * This is only usable inside `<script setup>`, is compiled away in the
8889 * output and should **not** be actually called at runtime.
8890 */
8891 function defineExpose(exposed) {
8892 {
8893 warnRuntimeUsage(`defineExpose`);
8894 }
8895 }
8896 /**
8897 * Vue `<script setup>` compiler macro for providing props default values when
8898 * using type-based `defineProps` declaration.
8899 *
8900 * Example usage:
8901 * ```ts
8902 * withDefaults(defineProps<{
8903 * size?: number
8904 * labels?: string[]
8905 * }>(), {
8906 * size: 3,
8907 * labels: () => ['default label']
8908 * })
8909 * ```
8910 *
8911 * This is only usable inside `<script setup>`, is compiled away in the output
8912 * and should **not** be actually called at runtime.
8913 */
8914 function withDefaults(props, defaults) {
8915 {
8916 warnRuntimeUsage(`withDefaults`);
8917 }
8918 return null;
8919 }
8920 function useSlots() {
8921 return getContext().slots;
8922 }
8923 function useAttrs() {
8924 return getContext().attrs;
8925 }
8926 function getContext() {
8927 const i = getCurrentInstance();
8928 if (!i) {
8929 warn$1(`useContext() called without active instance.`);
8930 }
8931 return i.setupContext || (i.setupContext = createSetupContext(i));
8932 }
8933 /**
8934 * Runtime helper for merging default declarations. Imported by compiled code
8935 * only.
8936 * @internal
8937 */
8938 function mergeDefaults(raw, defaults) {
8939 const props = isArray(raw)
8940 ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {})
8941 : raw;
8942 for (const key in defaults) {
8943 const opt = props[key];
8944 if (opt) {
8945 if (isArray(opt) || isFunction(opt)) {
8946 props[key] = { type: opt, default: defaults[key] };
8947 }
8948 else {
8949 opt.default = defaults[key];
8950 }
8951 }
8952 else if (opt === null) {
8953 props[key] = { default: defaults[key] };
8954 }
8955 else {
8956 warn$1(`props default key "${key}" has no corresponding declaration.`);
8957 }
8958 }
8959 return props;
8960 }
8961 /**
8962 * Used to create a proxy for the rest element when destructuring props with
8963 * defineProps().
8964 * @internal
8965 */
8966 function createPropsRestProxy(props, excludedKeys) {
8967 const ret = {};
8968 for (const key in props) {
8969 if (!excludedKeys.includes(key)) {
8970 Object.defineProperty(ret, key, {
8971 enumerable: true,
8972 get: () => props[key]
8973 });
8974 }
8975 }
8976 return ret;
8977 }
8978 /**
8979 * `<script setup>` helper for persisting the current instance context over
8980 * async/await flows.
8981 *
8982 * `@vue/compiler-sfc` converts the following:
8983 *
8984 * ```ts
8985 * const x = await foo()
8986 * ```
8987 *
8988 * into:
8989 *
8990 * ```ts
8991 * let __temp, __restore
8992 * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
8993 * ```
8994 * @internal
8995 */
8996 function withAsyncContext(getAwaitable) {
8997 const ctx = getCurrentInstance();
8998 if (!ctx) {
8999 warn$1(`withAsyncContext called without active current instance. ` +
9000 `This is likely a bug.`);
9001 }
9002 let awaitable = getAwaitable();
9003 unsetCurrentInstance();
9004 if (isPromise(awaitable)) {
9005 awaitable = awaitable.catch(e => {
9006 setCurrentInstance(ctx);
9007 throw e;
9008 });
9009 }
9010 return [awaitable, () => setCurrentInstance(ctx)];
9011 }
9012
9013 // Actual implementation
9014 function h(type, propsOrChildren, children) {
9015 const l = arguments.length;
9016 if (l === 2) {
9017 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
9018 // single vnode without props
9019 if (isVNode(propsOrChildren)) {
9020 return createVNode(type, null, [propsOrChildren]);
9021 }
9022 // props without children
9023 return createVNode(type, propsOrChildren);
9024 }
9025 else {
9026 // omit props
9027 return createVNode(type, null, propsOrChildren);
9028 }
9029 }
9030 else {
9031 if (l > 3) {
9032 children = Array.prototype.slice.call(arguments, 2);
9033 }
9034 else if (l === 3 && isVNode(children)) {
9035 children = [children];
9036 }
9037 return createVNode(type, propsOrChildren, children);
9038 }
9039 }
9040
9041 const ssrContextKey = Symbol(`ssrContext` );
9042 const useSSRContext = () => {
9043 {
9044 warn$1(`useSSRContext() is not supported in the global build.`);
9045 }
9046 };
9047
9048 function initCustomFormatter() {
9049 /* eslint-disable no-restricted-globals */
9050 if (typeof window === 'undefined') {
9051 return;
9052 }
9053 const vueStyle = { style: 'color:#3ba776' };
9054 const numberStyle = { style: 'color:#0b1bc9' };
9055 const stringStyle = { style: 'color:#b62e24' };
9056 const keywordStyle = { style: 'color:#9d288c' };
9057 // custom formatter for Chrome
9058 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
9059 const formatter = {
9060 header(obj) {
9061 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
9062 if (!isObject(obj)) {
9063 return null;
9064 }
9065 if (obj.__isVue) {
9066 return ['div', vueStyle, `VueInstance`];
9067 }
9068 else if (isRef(obj)) {
9069 return [
9070 'div',
9071 {},
9072 ['span', vueStyle, genRefFlag(obj)],
9073 '<',
9074 formatValue(obj.value),
9075 `>`
9076 ];
9077 }
9078 else if (isReactive(obj)) {
9079 return [
9080 'div',
9081 {},
9082 ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
9083 '<',
9084 formatValue(obj),
9085 `>${isReadonly(obj) ? ` (readonly)` : ``}`
9086 ];
9087 }
9088 else if (isReadonly(obj)) {
9089 return [
9090 'div',
9091 {},
9092 ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
9093 '<',
9094 formatValue(obj),
9095 '>'
9096 ];
9097 }
9098 return null;
9099 },
9100 hasBody(obj) {
9101 return obj && obj.__isVue;
9102 },
9103 body(obj) {
9104 if (obj && obj.__isVue) {
9105 return [
9106 'div',
9107 {},
9108 ...formatInstance(obj.$)
9109 ];
9110 }
9111 }
9112 };
9113 function formatInstance(instance) {
9114 const blocks = [];
9115 if (instance.type.props && instance.props) {
9116 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
9117 }
9118 if (instance.setupState !== EMPTY_OBJ) {
9119 blocks.push(createInstanceBlock('setup', instance.setupState));
9120 }
9121 if (instance.data !== EMPTY_OBJ) {
9122 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
9123 }
9124 const computed = extractKeys(instance, 'computed');
9125 if (computed) {
9126 blocks.push(createInstanceBlock('computed', computed));
9127 }
9128 const injected = extractKeys(instance, 'inject');
9129 if (injected) {
9130 blocks.push(createInstanceBlock('injected', injected));
9131 }
9132 blocks.push([
9133 'div',
9134 {},
9135 [
9136 'span',
9137 {
9138 style: keywordStyle.style + ';opacity:0.66'
9139 },
9140 '$ (internal): '
9141 ],
9142 ['object', { object: instance }]
9143 ]);
9144 return blocks;
9145 }
9146 function createInstanceBlock(type, target) {
9147 target = extend({}, target);
9148 if (!Object.keys(target).length) {
9149 return ['span', {}];
9150 }
9151 return [
9152 'div',
9153 { style: 'line-height:1.25em;margin-bottom:0.6em' },
9154 [
9155 'div',
9156 {
9157 style: 'color:#476582'
9158 },
9159 type
9160 ],
9161 [
9162 'div',
9163 {
9164 style: 'padding-left:1.25em'
9165 },
9166 ...Object.keys(target).map(key => {
9167 return [
9168 'div',
9169 {},
9170 ['span', keywordStyle, key + ': '],
9171 formatValue(target[key], false)
9172 ];
9173 })
9174 ]
9175 ];
9176 }
9177 function formatValue(v, asRaw = true) {
9178 if (typeof v === 'number') {
9179 return ['span', numberStyle, v];
9180 }
9181 else if (typeof v === 'string') {
9182 return ['span', stringStyle, JSON.stringify(v)];
9183 }
9184 else if (typeof v === 'boolean') {
9185 return ['span', keywordStyle, v];
9186 }
9187 else if (isObject(v)) {
9188 return ['object', { object: asRaw ? toRaw(v) : v }];
9189 }
9190 else {
9191 return ['span', stringStyle, String(v)];
9192 }
9193 }
9194 function extractKeys(instance, type) {
9195 const Comp = instance.type;
9196 if (isFunction(Comp)) {
9197 return;
9198 }
9199 const extracted = {};
9200 for (const key in instance.ctx) {
9201 if (isKeyOfType(Comp, key, type)) {
9202 extracted[key] = instance.ctx[key];
9203 }
9204 }
9205 return extracted;
9206 }
9207 function isKeyOfType(Comp, key, type) {
9208 const opts = Comp[type];
9209 if ((isArray(opts) && opts.includes(key)) ||
9210 (isObject(opts) && key in opts)) {
9211 return true;
9212 }
9213 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
9214 return true;
9215 }
9216 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
9217 return true;
9218 }
9219 }
9220 function genRefFlag(v) {
9221 if (isShallow(v)) {
9222 return `ShallowRef`;
9223 }
9224 if (v.effect) {
9225 return `ComputedRef`;
9226 }
9227 return `Ref`;
9228 }
9229 if (window.devtoolsFormatters) {
9230 window.devtoolsFormatters.push(formatter);
9231 }
9232 else {
9233 window.devtoolsFormatters = [formatter];
9234 }
9235 }
9236
9237 function withMemo(memo, render, cache, index) {
9238 const cached = cache[index];
9239 if (cached && isMemoSame(cached, memo)) {
9240 return cached;
9241 }
9242 const ret = render();
9243 // shallow clone
9244 ret.memo = memo.slice();
9245 return (cache[index] = ret);
9246 }
9247 function isMemoSame(cached, memo) {
9248 const prev = cached.memo;
9249 if (prev.length != memo.length) {
9250 return false;
9251 }
9252 for (let i = 0; i < prev.length; i++) {
9253 if (hasChanged(prev[i], memo[i])) {
9254 return false;
9255 }
9256 }
9257 // make sure to let parent block track it when returning cached
9258 if (isBlockTreeEnabled > 0 && currentBlock) {
9259 currentBlock.push(cached);
9260 }
9261 return true;
9262 }
9263
9264 // Core API ------------------------------------------------------------------
9265 const version = "3.2.36";
9266 /**
9267 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
9268 * @internal
9269 */
9270 const ssrUtils = (null);
9271 /**
9272 * @internal only exposed in compat builds
9273 */
9274 const resolveFilter = null;
9275 /**
9276 * @internal only exposed in compat builds.
9277 */
9278 const compatUtils = (null);
9279
9280 const svgNS = 'http://www.w3.org/2000/svg';
9281 const doc = (typeof document !== 'undefined' ? document : null);
9282 const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
9283 const nodeOps = {
9284 insert: (child, parent, anchor) => {
9285 parent.insertBefore(child, anchor || null);
9286 },
9287 remove: child => {
9288 const parent = child.parentNode;
9289 if (parent) {
9290 parent.removeChild(child);
9291 }
9292 },
9293 createElement: (tag, isSVG, is, props) => {
9294 const el = isSVG
9295 ? doc.createElementNS(svgNS, tag)
9296 : doc.createElement(tag, is ? { is } : undefined);
9297 if (tag === 'select' && props && props.multiple != null) {
9298 el.setAttribute('multiple', props.multiple);
9299 }
9300 return el;
9301 },
9302 createText: text => doc.createTextNode(text),
9303 createComment: text => doc.createComment(text),
9304 setText: (node, text) => {
9305 node.nodeValue = text;
9306 },
9307 setElementText: (el, text) => {
9308 el.textContent = text;
9309 },
9310 parentNode: node => node.parentNode,
9311 nextSibling: node => node.nextSibling,
9312 querySelector: selector => doc.querySelector(selector),
9313 setScopeId(el, id) {
9314 el.setAttribute(id, '');
9315 },
9316 cloneNode(el) {
9317 const cloned = el.cloneNode(true);
9318 // #3072
9319 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
9320 // - normally, elements using `:value` bindings will not be hoisted, but if
9321 // the bound value is a constant, e.g. `:value="true"` - they do get
9322 // hoisted.
9323 // - in production, hoisted nodes are cloned when subsequent inserts, but
9324 // cloneNode() does not copy the custom property we attached.
9325 // - This may need to account for other custom DOM properties we attach to
9326 // elements in addition to `_value` in the future.
9327 if (`_value` in el) {
9328 cloned._value = el._value;
9329 }
9330 return cloned;
9331 },
9332 // __UNSAFE__
9333 // Reason: innerHTML.
9334 // Static content here can only come from compiled templates.
9335 // As long as the user only uses trusted templates, this is safe.
9336 insertStaticContent(content, parent, anchor, isSVG, start, end) {
9337 // <parent> before | first ... last | anchor </parent>
9338 const before = anchor ? anchor.previousSibling : parent.lastChild;
9339 // #5308 can only take cached path if:
9340 // - has a single root node
9341 // - nextSibling info is still available
9342 if (start && (start === end || start.nextSibling)) {
9343 // cached
9344 while (true) {
9345 parent.insertBefore(start.cloneNode(true), anchor);
9346 if (start === end || !(start = start.nextSibling))
9347 break;
9348 }
9349 }
9350 else {
9351 // fresh insert
9352 templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
9353 const template = templateContainer.content;
9354 if (isSVG) {
9355 // remove outer svg wrapper
9356 const wrapper = template.firstChild;
9357 while (wrapper.firstChild) {
9358 template.appendChild(wrapper.firstChild);
9359 }
9360 template.removeChild(wrapper);
9361 }
9362 parent.insertBefore(template, anchor);
9363 }
9364 return [
9365 // first
9366 before ? before.nextSibling : parent.firstChild,
9367 // last
9368 anchor ? anchor.previousSibling : parent.lastChild
9369 ];
9370 }
9371 };
9372
9373 // compiler should normalize class + :class bindings on the same element
9374 // into a single binding ['staticClass', dynamic]
9375 function patchClass(el, value, isSVG) {
9376 // directly setting className should be faster than setAttribute in theory
9377 // if this is an element during a transition, take the temporary transition
9378 // classes into account.
9379 const transitionClasses = el._vtc;
9380 if (transitionClasses) {
9381 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
9382 }
9383 if (value == null) {
9384 el.removeAttribute('class');
9385 }
9386 else if (isSVG) {
9387 el.setAttribute('class', value);
9388 }
9389 else {
9390 el.className = value;
9391 }
9392 }
9393
9394 function patchStyle(el, prev, next) {
9395 const style = el.style;
9396 const isCssString = isString(next);
9397 if (next && !isCssString) {
9398 for (const key in next) {
9399 setStyle(style, key, next[key]);
9400 }
9401 if (prev && !isString(prev)) {
9402 for (const key in prev) {
9403 if (next[key] == null) {
9404 setStyle(style, key, '');
9405 }
9406 }
9407 }
9408 }
9409 else {
9410 const currentDisplay = style.display;
9411 if (isCssString) {
9412 if (prev !== next) {
9413 style.cssText = next;
9414 }
9415 }
9416 else if (prev) {
9417 el.removeAttribute('style');
9418 }
9419 // indicates that the `display` of the element is controlled by `v-show`,
9420 // so we always keep the current `display` value regardless of the `style`
9421 // value, thus handing over control to `v-show`.
9422 if ('_vod' in el) {
9423 style.display = currentDisplay;
9424 }
9425 }
9426 }
9427 const importantRE = /\s*!important$/;
9428 function setStyle(style, name, val) {
9429 if (isArray(val)) {
9430 val.forEach(v => setStyle(style, name, v));
9431 }
9432 else {
9433 if (val == null)
9434 val = '';
9435 if (name.startsWith('--')) {
9436 // custom property definition
9437 style.setProperty(name, val);
9438 }
9439 else {
9440 const prefixed = autoPrefix(style, name);
9441 if (importantRE.test(val)) {
9442 // !important
9443 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
9444 }
9445 else {
9446 style[prefixed] = val;
9447 }
9448 }
9449 }
9450 }
9451 const prefixes = ['Webkit', 'Moz', 'ms'];
9452 const prefixCache = {};
9453 function autoPrefix(style, rawName) {
9454 const cached = prefixCache[rawName];
9455 if (cached) {
9456 return cached;
9457 }
9458 let name = camelize(rawName);
9459 if (name !== 'filter' && name in style) {
9460 return (prefixCache[rawName] = name);
9461 }
9462 name = capitalize(name);
9463 for (let i = 0; i < prefixes.length; i++) {
9464 const prefixed = prefixes[i] + name;
9465 if (prefixed in style) {
9466 return (prefixCache[rawName] = prefixed);
9467 }
9468 }
9469 return rawName;
9470 }
9471
9472 const xlinkNS = 'http://www.w3.org/1999/xlink';
9473 function patchAttr(el, key, value, isSVG, instance) {
9474 if (isSVG && key.startsWith('xlink:')) {
9475 if (value == null) {
9476 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
9477 }
9478 else {
9479 el.setAttributeNS(xlinkNS, key, value);
9480 }
9481 }
9482 else {
9483 // note we are only checking boolean attributes that don't have a
9484 // corresponding dom prop of the same name here.
9485 const isBoolean = isSpecialBooleanAttr(key);
9486 if (value == null || (isBoolean && !includeBooleanAttr(value))) {
9487 el.removeAttribute(key);
9488 }
9489 else {
9490 el.setAttribute(key, isBoolean ? '' : value);
9491 }
9492 }
9493 }
9494
9495 // __UNSAFE__
9496 // functions. The user is responsible for using them with only trusted content.
9497 function patchDOMProp(el, key, value,
9498 // the following args are passed only due to potential innerHTML/textContent
9499 // overriding existing VNodes, in which case the old tree must be properly
9500 // unmounted.
9501 prevChildren, parentComponent, parentSuspense, unmountChildren) {
9502 if (key === 'innerHTML' || key === 'textContent') {
9503 if (prevChildren) {
9504 unmountChildren(prevChildren, parentComponent, parentSuspense);
9505 }
9506 el[key] = value == null ? '' : value;
9507 return;
9508 }
9509 if (key === 'value' &&
9510 el.tagName !== 'PROGRESS' &&
9511 // custom elements may use _value internally
9512 !el.tagName.includes('-')) {
9513 // store value as _value as well since
9514 // non-string values will be stringified.
9515 el._value = value;
9516 const newValue = value == null ? '' : value;
9517 if (el.value !== newValue ||
9518 // #4956: always set for OPTION elements because its value falls back to
9519 // textContent if no value attribute is present. And setting .value for
9520 // OPTION has no side effect
9521 el.tagName === 'OPTION') {
9522 el.value = newValue;
9523 }
9524 if (value == null) {
9525 el.removeAttribute(key);
9526 }
9527 return;
9528 }
9529 let needRemove = false;
9530 if (value === '' || value == null) {
9531 const type = typeof el[key];
9532 if (type === 'boolean') {
9533 // e.g. <select multiple> compiles to { multiple: '' }
9534 value = includeBooleanAttr(value);
9535 }
9536 else if (value == null && type === 'string') {
9537 // e.g. <div :id="null">
9538 value = '';
9539 needRemove = true;
9540 }
9541 else if (type === 'number') {
9542 // e.g. <img :width="null">
9543 // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
9544 value = 0;
9545 needRemove = true;
9546 }
9547 }
9548 // some properties perform value validation and throw,
9549 // some properties has getter, no setter, will error in 'use strict'
9550 // eg. <select :type="null"></select> <select :willValidate="null"></select>
9551 try {
9552 el[key] = value;
9553 }
9554 catch (e) {
9555 {
9556 warn$1(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9557 `value ${value} is invalid.`, e);
9558 }
9559 }
9560 needRemove && el.removeAttribute(key);
9561 }
9562
9563 // Async edge case fix requires storing an event listener's attach timestamp.
9564 const [_getNow, skipTimestampCheck] = /*#__PURE__*/ (() => {
9565 let _getNow = Date.now;
9566 let skipTimestampCheck = false;
9567 if (typeof window !== 'undefined') {
9568 // Determine what event timestamp the browser is using. Annoyingly, the
9569 // timestamp can either be hi-res (relative to page load) or low-res
9570 // (relative to UNIX epoch), so in order to compare time we have to use the
9571 // same timestamp type when saving the flush timestamp.
9572 if (Date.now() > document.createEvent('Event').timeStamp) {
9573 // if the low-res timestamp which is bigger than the event timestamp
9574 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
9575 // and we need to use the hi-res version for event listeners as well.
9576 _getNow = performance.now.bind(performance);
9577 }
9578 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
9579 // and does not fire microtasks in between event propagation, so safe to exclude.
9580 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
9581 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
9582 }
9583 return [_getNow, skipTimestampCheck];
9584 })();
9585 // To avoid the overhead of repeatedly calling performance.now(), we cache
9586 // and use the same timestamp for all event listeners attached in the same tick.
9587 let cachedNow = 0;
9588 const p = /*#__PURE__*/ Promise.resolve();
9589 const reset = () => {
9590 cachedNow = 0;
9591 };
9592 const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
9593 function addEventListener(el, event, handler, options) {
9594 el.addEventListener(event, handler, options);
9595 }
9596 function removeEventListener(el, event, handler, options) {
9597 el.removeEventListener(event, handler, options);
9598 }
9599 function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9600 // vei = vue event invokers
9601 const invokers = el._vei || (el._vei = {});
9602 const existingInvoker = invokers[rawName];
9603 if (nextValue && existingInvoker) {
9604 // patch
9605 existingInvoker.value = nextValue;
9606 }
9607 else {
9608 const [name, options] = parseName(rawName);
9609 if (nextValue) {
9610 // add
9611 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9612 addEventListener(el, name, invoker, options);
9613 }
9614 else if (existingInvoker) {
9615 // remove
9616 removeEventListener(el, name, existingInvoker, options);
9617 invokers[rawName] = undefined;
9618 }
9619 }
9620 }
9621 const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9622 function parseName(name) {
9623 let options;
9624 if (optionsModifierRE.test(name)) {
9625 options = {};
9626 let m;
9627 while ((m = name.match(optionsModifierRE))) {
9628 name = name.slice(0, name.length - m[0].length);
9629 options[m[0].toLowerCase()] = true;
9630 }
9631 }
9632 return [hyphenate(name.slice(2)), options];
9633 }
9634 function createInvoker(initialValue, instance) {
9635 const invoker = (e) => {
9636 // async edge case #6566: inner click event triggers patch, event handler
9637 // attached to outer element during patch, and triggered again. This
9638 // happens because browsers fire microtask ticks between event propagation.
9639 // the solution is simple: we save the timestamp when a handler is attached,
9640 // and the handler would only fire if the event passed to it was fired
9641 // AFTER it was attached.
9642 const timeStamp = e.timeStamp || _getNow();
9643 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
9644 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
9645 }
9646 };
9647 invoker.value = initialValue;
9648 invoker.attached = getNow();
9649 return invoker;
9650 }
9651 function patchStopImmediatePropagation(e, value) {
9652 if (isArray(value)) {
9653 const originalStop = e.stopImmediatePropagation;
9654 e.stopImmediatePropagation = () => {
9655 originalStop.call(e);
9656 e._stopped = true;
9657 };
9658 return value.map(fn => (e) => !e._stopped && fn && fn(e));
9659 }
9660 else {
9661 return value;
9662 }
9663 }
9664
9665 const nativeOnRE = /^on[a-z]/;
9666 const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9667 if (key === 'class') {
9668 patchClass(el, nextValue, isSVG);
9669 }
9670 else if (key === 'style') {
9671 patchStyle(el, prevValue, nextValue);
9672 }
9673 else if (isOn(key)) {
9674 // ignore v-model listeners
9675 if (!isModelListener(key)) {
9676 patchEvent(el, key, prevValue, nextValue, parentComponent);
9677 }
9678 }
9679 else if (key[0] === '.'
9680 ? ((key = key.slice(1)), true)
9681 : key[0] === '^'
9682 ? ((key = key.slice(1)), false)
9683 : shouldSetAsProp(el, key, nextValue, isSVG)) {
9684 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9685 }
9686 else {
9687 // special case for <input v-model type="checkbox"> with
9688 // :true-value & :false-value
9689 // store value as dom properties since non-string values will be
9690 // stringified.
9691 if (key === 'true-value') {
9692 el._trueValue = nextValue;
9693 }
9694 else if (key === 'false-value') {
9695 el._falseValue = nextValue;
9696 }
9697 patchAttr(el, key, nextValue, isSVG);
9698 }
9699 };
9700 function shouldSetAsProp(el, key, value, isSVG) {
9701 if (isSVG) {
9702 // most keys must be set as attribute on svg elements to work
9703 // ...except innerHTML & textContent
9704 if (key === 'innerHTML' || key === 'textContent') {
9705 return true;
9706 }
9707 // or native onclick with function values
9708 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9709 return true;
9710 }
9711 return false;
9712 }
9713 // these are enumerated attrs, however their corresponding DOM properties
9714 // are actually booleans - this leads to setting it with a string "false"
9715 // value leading it to be coerced to `true`, so we need to always treat
9716 // them as attributes.
9717 // Note that `contentEditable` doesn't have this problem: its DOM
9718 // property is also enumerated string values.
9719 if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
9720 return false;
9721 }
9722 // #1787, #2840 form property on form elements is readonly and must be set as
9723 // attribute.
9724 if (key === 'form') {
9725 return false;
9726 }
9727 // #1526 <input list> must be set as attribute
9728 if (key === 'list' && el.tagName === 'INPUT') {
9729 return false;
9730 }
9731 // #2766 <textarea type> must be set as attribute
9732 if (key === 'type' && el.tagName === 'TEXTAREA') {
9733 return false;
9734 }
9735 // native onclick with string value, must be set as attribute
9736 if (nativeOnRE.test(key) && isString(value)) {
9737 return false;
9738 }
9739 return key in el;
9740 }
9741
9742 function defineCustomElement(options, hydrate) {
9743 const Comp = defineComponent(options);
9744 class VueCustomElement extends VueElement {
9745 constructor(initialProps) {
9746 super(Comp, initialProps, hydrate);
9747 }
9748 }
9749 VueCustomElement.def = Comp;
9750 return VueCustomElement;
9751 }
9752 const defineSSRCustomElement = ((options) => {
9753 // @ts-ignore
9754 return defineCustomElement(options, hydrate);
9755 });
9756 const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
9757 });
9758 class VueElement extends BaseClass {
9759 constructor(_def, _props = {}, hydrate) {
9760 super();
9761 this._def = _def;
9762 this._props = _props;
9763 /**
9764 * @internal
9765 */
9766 this._instance = null;
9767 this._connected = false;
9768 this._resolved = false;
9769 this._numberProps = null;
9770 if (this.shadowRoot && hydrate) {
9771 hydrate(this._createVNode(), this.shadowRoot);
9772 }
9773 else {
9774 if (this.shadowRoot) {
9775 warn$1(`Custom element has pre-rendered declarative shadow root but is not ` +
9776 `defined as hydratable. Use \`defineSSRCustomElement\`.`);
9777 }
9778 this.attachShadow({ mode: 'open' });
9779 }
9780 }
9781 connectedCallback() {
9782 this._connected = true;
9783 if (!this._instance) {
9784 this._resolveDef();
9785 }
9786 }
9787 disconnectedCallback() {
9788 this._connected = false;
9789 nextTick(() => {
9790 if (!this._connected) {
9791 render(null, this.shadowRoot);
9792 this._instance = null;
9793 }
9794 });
9795 }
9796 /**
9797 * resolve inner component definition (handle possible async component)
9798 */
9799 _resolveDef() {
9800 if (this._resolved) {
9801 return;
9802 }
9803 this._resolved = true;
9804 // set initial attrs
9805 for (let i = 0; i < this.attributes.length; i++) {
9806 this._setAttr(this.attributes[i].name);
9807 }
9808 // watch future attr changes
9809 new MutationObserver(mutations => {
9810 for (const m of mutations) {
9811 this._setAttr(m.attributeName);
9812 }
9813 }).observe(this, { attributes: true });
9814 const resolve = (def) => {
9815 const { props, styles } = def;
9816 const hasOptions = !isArray(props);
9817 const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
9818 // cast Number-type props set before resolve
9819 let numberProps;
9820 if (hasOptions) {
9821 for (const key in this._props) {
9822 const opt = props[key];
9823 if (opt === Number || (opt && opt.type === Number)) {
9824 this._props[key] = toNumber(this._props[key]);
9825 (numberProps || (numberProps = Object.create(null)))[key] = true;
9826 }
9827 }
9828 }
9829 this._numberProps = numberProps;
9830 // check if there are props set pre-upgrade or connect
9831 for (const key of Object.keys(this)) {
9832 if (key[0] !== '_') {
9833 this._setProp(key, this[key], true, false);
9834 }
9835 }
9836 // defining getter/setters on prototype
9837 for (const key of rawKeys.map(camelize)) {
9838 Object.defineProperty(this, key, {
9839 get() {
9840 return this._getProp(key);
9841 },
9842 set(val) {
9843 this._setProp(key, val);
9844 }
9845 });
9846 }
9847 // apply CSS
9848 this._applyStyles(styles);
9849 // initial render
9850 this._update();
9851 };
9852 const asyncDef = this._def.__asyncLoader;
9853 if (asyncDef) {
9854 asyncDef().then(resolve);
9855 }
9856 else {
9857 resolve(this._def);
9858 }
9859 }
9860 _setAttr(key) {
9861 let value = this.getAttribute(key);
9862 if (this._numberProps && this._numberProps[key]) {
9863 value = toNumber(value);
9864 }
9865 this._setProp(camelize(key), value, false);
9866 }
9867 /**
9868 * @internal
9869 */
9870 _getProp(key) {
9871 return this._props[key];
9872 }
9873 /**
9874 * @internal
9875 */
9876 _setProp(key, val, shouldReflect = true, shouldUpdate = true) {
9877 if (val !== this._props[key]) {
9878 this._props[key] = val;
9879 if (shouldUpdate && this._instance) {
9880 this._update();
9881 }
9882 // reflect
9883 if (shouldReflect) {
9884 if (val === true) {
9885 this.setAttribute(hyphenate(key), '');
9886 }
9887 else if (typeof val === 'string' || typeof val === 'number') {
9888 this.setAttribute(hyphenate(key), val + '');
9889 }
9890 else if (!val) {
9891 this.removeAttribute(hyphenate(key));
9892 }
9893 }
9894 }
9895 }
9896 _update() {
9897 render(this._createVNode(), this.shadowRoot);
9898 }
9899 _createVNode() {
9900 const vnode = createVNode(this._def, extend({}, this._props));
9901 if (!this._instance) {
9902 vnode.ce = instance => {
9903 this._instance = instance;
9904 instance.isCE = true;
9905 // HMR
9906 {
9907 instance.ceReload = newStyles => {
9908 // always reset styles
9909 if (this._styles) {
9910 this._styles.forEach(s => this.shadowRoot.removeChild(s));
9911 this._styles.length = 0;
9912 }
9913 this._applyStyles(newStyles);
9914 // if this is an async component, ceReload is called from the inner
9915 // component so no need to reload the async wrapper
9916 if (!this._def.__asyncLoader) {
9917 // reload
9918 this._instance = null;
9919 this._update();
9920 }
9921 };
9922 }
9923 // intercept emit
9924 instance.emit = (event, ...args) => {
9925 this.dispatchEvent(new CustomEvent(event, {
9926 detail: args
9927 }));
9928 };
9929 // locate nearest Vue custom element parent for provide/inject
9930 let parent = this;
9931 while ((parent =
9932 parent && (parent.parentNode || parent.host))) {
9933 if (parent instanceof VueElement) {
9934 instance.parent = parent._instance;
9935 break;
9936 }
9937 }
9938 };
9939 }
9940 return vnode;
9941 }
9942 _applyStyles(styles) {
9943 if (styles) {
9944 styles.forEach(css => {
9945 const s = document.createElement('style');
9946 s.textContent = css;
9947 this.shadowRoot.appendChild(s);
9948 // record for HMR
9949 {
9950 (this._styles || (this._styles = [])).push(s);
9951 }
9952 });
9953 }
9954 }
9955 }
9956
9957 function useCssModule(name = '$style') {
9958 /* istanbul ignore else */
9959 {
9960 {
9961 warn$1(`useCssModule() is not supported in the global build.`);
9962 }
9963 return EMPTY_OBJ;
9964 }
9965 }
9966
9967 /**
9968 * Runtime helper for SFC's CSS variable injection feature.
9969 * @private
9970 */
9971 function useCssVars(getter) {
9972 const instance = getCurrentInstance();
9973 /* istanbul ignore next */
9974 if (!instance) {
9975 warn$1(`useCssVars is called without current active component instance.`);
9976 return;
9977 }
9978 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
9979 watchPostEffect(setVars);
9980 onMounted(() => {
9981 const ob = new MutationObserver(setVars);
9982 ob.observe(instance.subTree.el.parentNode, { childList: true });
9983 onUnmounted(() => ob.disconnect());
9984 });
9985 }
9986 function setVarsOnVNode(vnode, vars) {
9987 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
9988 const suspense = vnode.suspense;
9989 vnode = suspense.activeBranch;
9990 if (suspense.pendingBranch && !suspense.isHydrating) {
9991 suspense.effects.push(() => {
9992 setVarsOnVNode(suspense.activeBranch, vars);
9993 });
9994 }
9995 }
9996 // drill down HOCs until it's a non-component vnode
9997 while (vnode.component) {
9998 vnode = vnode.component.subTree;
9999 }
10000 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
10001 setVarsOnNode(vnode.el, vars);
10002 }
10003 else if (vnode.type === Fragment) {
10004 vnode.children.forEach(c => setVarsOnVNode(c, vars));
10005 }
10006 else if (vnode.type === Static) {
10007 let { el, anchor } = vnode;
10008 while (el) {
10009 setVarsOnNode(el, vars);
10010 if (el === anchor)
10011 break;
10012 el = el.nextSibling;
10013 }
10014 }
10015 }
10016 function setVarsOnNode(el, vars) {
10017 if (el.nodeType === 1) {
10018 const style = el.style;
10019 for (const key in vars) {
10020 style.setProperty(`--${key}`, vars[key]);
10021 }
10022 }
10023 }
10024
10025 const TRANSITION = 'transition';
10026 const ANIMATION = 'animation';
10027 // DOM Transition is a higher-order-component based on the platform-agnostic
10028 // base Transition component, with DOM-specific logic.
10029 const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
10030 Transition.displayName = 'Transition';
10031 const DOMTransitionPropsValidators = {
10032 name: String,
10033 type: String,
10034 css: {
10035 type: Boolean,
10036 default: true
10037 },
10038 duration: [String, Number, Object],
10039 enterFromClass: String,
10040 enterActiveClass: String,
10041 enterToClass: String,
10042 appearFromClass: String,
10043 appearActiveClass: String,
10044 appearToClass: String,
10045 leaveFromClass: String,
10046 leaveActiveClass: String,
10047 leaveToClass: String
10048 };
10049 const TransitionPropsValidators = (Transition.props =
10050 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
10051 /**
10052 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
10053 * with custom HOCs.
10054 */
10055 const callHook$1 = (hook, args = []) => {
10056 if (isArray(hook)) {
10057 hook.forEach(h => h(...args));
10058 }
10059 else if (hook) {
10060 hook(...args);
10061 }
10062 };
10063 /**
10064 * Check if a hook expects a callback (2nd arg), which means the user
10065 * intends to explicitly control the end of the transition.
10066 */
10067 const hasExplicitCallback = (hook) => {
10068 return hook
10069 ? isArray(hook)
10070 ? hook.some(h => h.length > 1)
10071 : hook.length > 1
10072 : false;
10073 };
10074 function resolveTransitionProps(rawProps) {
10075 const baseProps = {};
10076 for (const key in rawProps) {
10077 if (!(key in DOMTransitionPropsValidators)) {
10078 baseProps[key] = rawProps[key];
10079 }
10080 }
10081 if (rawProps.css === false) {
10082 return baseProps;
10083 }
10084 const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
10085 const durations = normalizeDuration(duration);
10086 const enterDuration = durations && durations[0];
10087 const leaveDuration = durations && durations[1];
10088 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
10089 const finishEnter = (el, isAppear, done) => {
10090 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
10091 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
10092 done && done();
10093 };
10094 const finishLeave = (el, done) => {
10095 el._isLeaving = false;
10096 removeTransitionClass(el, leaveFromClass);
10097 removeTransitionClass(el, leaveToClass);
10098 removeTransitionClass(el, leaveActiveClass);
10099 done && done();
10100 };
10101 const makeEnterHook = (isAppear) => {
10102 return (el, done) => {
10103 const hook = isAppear ? onAppear : onEnter;
10104 const resolve = () => finishEnter(el, isAppear, done);
10105 callHook$1(hook, [el, resolve]);
10106 nextFrame(() => {
10107 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
10108 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
10109 if (!hasExplicitCallback(hook)) {
10110 whenTransitionEnds(el, type, enterDuration, resolve);
10111 }
10112 });
10113 };
10114 };
10115 return extend(baseProps, {
10116 onBeforeEnter(el) {
10117 callHook$1(onBeforeEnter, [el]);
10118 addTransitionClass(el, enterFromClass);
10119 addTransitionClass(el, enterActiveClass);
10120 },
10121 onBeforeAppear(el) {
10122 callHook$1(onBeforeAppear, [el]);
10123 addTransitionClass(el, appearFromClass);
10124 addTransitionClass(el, appearActiveClass);
10125 },
10126 onEnter: makeEnterHook(false),
10127 onAppear: makeEnterHook(true),
10128 onLeave(el, done) {
10129 el._isLeaving = true;
10130 const resolve = () => finishLeave(el, done);
10131 addTransitionClass(el, leaveFromClass);
10132 // force reflow so *-leave-from classes immediately take effect (#2593)
10133 forceReflow();
10134 addTransitionClass(el, leaveActiveClass);
10135 nextFrame(() => {
10136 if (!el._isLeaving) {
10137 // cancelled
10138 return;
10139 }
10140 removeTransitionClass(el, leaveFromClass);
10141 addTransitionClass(el, leaveToClass);
10142 if (!hasExplicitCallback(onLeave)) {
10143 whenTransitionEnds(el, type, leaveDuration, resolve);
10144 }
10145 });
10146 callHook$1(onLeave, [el, resolve]);
10147 },
10148 onEnterCancelled(el) {
10149 finishEnter(el, false);
10150 callHook$1(onEnterCancelled, [el]);
10151 },
10152 onAppearCancelled(el) {
10153 finishEnter(el, true);
10154 callHook$1(onAppearCancelled, [el]);
10155 },
10156 onLeaveCancelled(el) {
10157 finishLeave(el);
10158 callHook$1(onLeaveCancelled, [el]);
10159 }
10160 });
10161 }
10162 function normalizeDuration(duration) {
10163 if (duration == null) {
10164 return null;
10165 }
10166 else if (isObject(duration)) {
10167 return [NumberOf(duration.enter), NumberOf(duration.leave)];
10168 }
10169 else {
10170 const n = NumberOf(duration);
10171 return [n, n];
10172 }
10173 }
10174 function NumberOf(val) {
10175 const res = toNumber(val);
10176 validateDuration(res);
10177 return res;
10178 }
10179 function validateDuration(val) {
10180 if (typeof val !== 'number') {
10181 warn$1(`<transition> explicit duration is not a valid number - ` +
10182 `got ${JSON.stringify(val)}.`);
10183 }
10184 else if (isNaN(val)) {
10185 warn$1(`<transition> explicit duration is NaN - ` +
10186 'the duration expression might be incorrect.');
10187 }
10188 }
10189 function addTransitionClass(el, cls) {
10190 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
10191 (el._vtc ||
10192 (el._vtc = new Set())).add(cls);
10193 }
10194 function removeTransitionClass(el, cls) {
10195 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
10196 const { _vtc } = el;
10197 if (_vtc) {
10198 _vtc.delete(cls);
10199 if (!_vtc.size) {
10200 el._vtc = undefined;
10201 }
10202 }
10203 }
10204 function nextFrame(cb) {
10205 requestAnimationFrame(() => {
10206 requestAnimationFrame(cb);
10207 });
10208 }
10209 let endId = 0;
10210 function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
10211 const id = (el._endId = ++endId);
10212 const resolveIfNotStale = () => {
10213 if (id === el._endId) {
10214 resolve();
10215 }
10216 };
10217 if (explicitTimeout) {
10218 return setTimeout(resolveIfNotStale, explicitTimeout);
10219 }
10220 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
10221 if (!type) {
10222 return resolve();
10223 }
10224 const endEvent = type + 'end';
10225 let ended = 0;
10226 const end = () => {
10227 el.removeEventListener(endEvent, onEnd);
10228 resolveIfNotStale();
10229 };
10230 const onEnd = (e) => {
10231 if (e.target === el && ++ended >= propCount) {
10232 end();
10233 }
10234 };
10235 setTimeout(() => {
10236 if (ended < propCount) {
10237 end();
10238 }
10239 }, timeout + 1);
10240 el.addEventListener(endEvent, onEnd);
10241 }
10242 function getTransitionInfo(el, expectedType) {
10243 const styles = window.getComputedStyle(el);
10244 // JSDOM may return undefined for transition properties
10245 const getStyleProperties = (key) => (styles[key] || '').split(', ');
10246 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
10247 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
10248 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
10249 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
10250 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
10251 const animationTimeout = getTimeout(animationDelays, animationDurations);
10252 let type = null;
10253 let timeout = 0;
10254 let propCount = 0;
10255 /* istanbul ignore if */
10256 if (expectedType === TRANSITION) {
10257 if (transitionTimeout > 0) {
10258 type = TRANSITION;
10259 timeout = transitionTimeout;
10260 propCount = transitionDurations.length;
10261 }
10262 }
10263 else if (expectedType === ANIMATION) {
10264 if (animationTimeout > 0) {
10265 type = ANIMATION;
10266 timeout = animationTimeout;
10267 propCount = animationDurations.length;
10268 }
10269 }
10270 else {
10271 timeout = Math.max(transitionTimeout, animationTimeout);
10272 type =
10273 timeout > 0
10274 ? transitionTimeout > animationTimeout
10275 ? TRANSITION
10276 : ANIMATION
10277 : null;
10278 propCount = type
10279 ? type === TRANSITION
10280 ? transitionDurations.length
10281 : animationDurations.length
10282 : 0;
10283 }
10284 const hasTransform = type === TRANSITION &&
10285 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
10286 return {
10287 type,
10288 timeout,
10289 propCount,
10290 hasTransform
10291 };
10292 }
10293 function getTimeout(delays, durations) {
10294 while (delays.length < durations.length) {
10295 delays = delays.concat(delays);
10296 }
10297 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
10298 }
10299 // Old versions of Chromium (below 61.0.3163.100) formats floating pointer
10300 // numbers in a locale-dependent way, using a comma instead of a dot.
10301 // If comma is not replaced with a dot, the input will be rounded down
10302 // (i.e. acting as a floor function) causing unexpected behaviors
10303 function toMs(s) {
10304 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
10305 }
10306 // synchronously force layout to put elements into a certain state
10307 function forceReflow() {
10308 return document.body.offsetHeight;
10309 }
10310
10311 const positionMap = new WeakMap();
10312 const newPositionMap = new WeakMap();
10313 const TransitionGroupImpl = {
10314 name: 'TransitionGroup',
10315 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
10316 tag: String,
10317 moveClass: String
10318 }),
10319 setup(props, { slots }) {
10320 const instance = getCurrentInstance();
10321 const state = useTransitionState();
10322 let prevChildren;
10323 let children;
10324 onUpdated(() => {
10325 // children is guaranteed to exist after initial render
10326 if (!prevChildren.length) {
10327 return;
10328 }
10329 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
10330 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
10331 return;
10332 }
10333 // we divide the work into three loops to avoid mixing DOM reads and writes
10334 // in each iteration - which helps prevent layout thrashing.
10335 prevChildren.forEach(callPendingCbs);
10336 prevChildren.forEach(recordPosition);
10337 const movedChildren = prevChildren.filter(applyTranslation);
10338 // force reflow to put everything in position
10339 forceReflow();
10340 movedChildren.forEach(c => {
10341 const el = c.el;
10342 const style = el.style;
10343 addTransitionClass(el, moveClass);
10344 style.transform = style.webkitTransform = style.transitionDuration = '';
10345 const cb = (el._moveCb = (e) => {
10346 if (e && e.target !== el) {
10347 return;
10348 }
10349 if (!e || /transform$/.test(e.propertyName)) {
10350 el.removeEventListener('transitionend', cb);
10351 el._moveCb = null;
10352 removeTransitionClass(el, moveClass);
10353 }
10354 });
10355 el.addEventListener('transitionend', cb);
10356 });
10357 });
10358 return () => {
10359 const rawProps = toRaw(props);
10360 const cssTransitionProps = resolveTransitionProps(rawProps);
10361 let tag = rawProps.tag || Fragment;
10362 prevChildren = children;
10363 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
10364 for (let i = 0; i < children.length; i++) {
10365 const child = children[i];
10366 if (child.key != null) {
10367 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10368 }
10369 else {
10370 warn$1(`<TransitionGroup> children must be keyed.`);
10371 }
10372 }
10373 if (prevChildren) {
10374 for (let i = 0; i < prevChildren.length; i++) {
10375 const child = prevChildren[i];
10376 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10377 positionMap.set(child, child.el.getBoundingClientRect());
10378 }
10379 }
10380 return createVNode(tag, null, children);
10381 };
10382 }
10383 };
10384 const TransitionGroup = TransitionGroupImpl;
10385 function callPendingCbs(c) {
10386 const el = c.el;
10387 if (el._moveCb) {
10388 el._moveCb();
10389 }
10390 if (el._enterCb) {
10391 el._enterCb();
10392 }
10393 }
10394 function recordPosition(c) {
10395 newPositionMap.set(c, c.el.getBoundingClientRect());
10396 }
10397 function applyTranslation(c) {
10398 const oldPos = positionMap.get(c);
10399 const newPos = newPositionMap.get(c);
10400 const dx = oldPos.left - newPos.left;
10401 const dy = oldPos.top - newPos.top;
10402 if (dx || dy) {
10403 const s = c.el.style;
10404 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
10405 s.transitionDuration = '0s';
10406 return c;
10407 }
10408 }
10409 function hasCSSTransform(el, root, moveClass) {
10410 // Detect whether an element with the move class applied has
10411 // CSS transitions. Since the element may be inside an entering
10412 // transition at this very moment, we make a clone of it and remove
10413 // all other transition classes applied to ensure only the move class
10414 // is applied.
10415 const clone = el.cloneNode();
10416 if (el._vtc) {
10417 el._vtc.forEach(cls => {
10418 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
10419 });
10420 }
10421 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
10422 clone.style.display = 'none';
10423 const container = (root.nodeType === 1 ? root : root.parentNode);
10424 container.appendChild(clone);
10425 const { hasTransform } = getTransitionInfo(clone);
10426 container.removeChild(clone);
10427 return hasTransform;
10428 }
10429
10430 const getModelAssigner = (vnode) => {
10431 const fn = vnode.props['onUpdate:modelValue'] ||
10432 (false );
10433 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
10434 };
10435 function onCompositionStart(e) {
10436 e.target.composing = true;
10437 }
10438 function onCompositionEnd(e) {
10439 const target = e.target;
10440 if (target.composing) {
10441 target.composing = false;
10442 target.dispatchEvent(new Event('input'));
10443 }
10444 }
10445 // We are exporting the v-model runtime directly as vnode hooks so that it can
10446 // be tree-shaken in case v-model is never used.
10447 const vModelText = {
10448 created(el, { modifiers: { lazy, trim, number } }, vnode) {
10449 el._assign = getModelAssigner(vnode);
10450 const castToNumber = number || (vnode.props && vnode.props.type === 'number');
10451 addEventListener(el, lazy ? 'change' : 'input', e => {
10452 if (e.target.composing)
10453 return;
10454 let domValue = el.value;
10455 if (trim) {
10456 domValue = domValue.trim();
10457 }
10458 if (castToNumber) {
10459 domValue = toNumber(domValue);
10460 }
10461 el._assign(domValue);
10462 });
10463 if (trim) {
10464 addEventListener(el, 'change', () => {
10465 el.value = el.value.trim();
10466 });
10467 }
10468 if (!lazy) {
10469 addEventListener(el, 'compositionstart', onCompositionStart);
10470 addEventListener(el, 'compositionend', onCompositionEnd);
10471 // Safari < 10.2 & UIWebView doesn't fire compositionend when
10472 // switching focus before confirming composition choice
10473 // this also fixes the issue where some browsers e.g. iOS Chrome
10474 // fires "change" instead of "input" on autocomplete.
10475 addEventListener(el, 'change', onCompositionEnd);
10476 }
10477 },
10478 // set value on mounted so it's after min/max for type="range"
10479 mounted(el, { value }) {
10480 el.value = value == null ? '' : value;
10481 },
10482 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
10483 el._assign = getModelAssigner(vnode);
10484 // avoid clearing unresolved text. #2302
10485 if (el.composing)
10486 return;
10487 if (document.activeElement === el && el.type !== 'range') {
10488 if (lazy) {
10489 return;
10490 }
10491 if (trim && el.value.trim() === value) {
10492 return;
10493 }
10494 if ((number || el.type === 'number') && toNumber(el.value) === value) {
10495 return;
10496 }
10497 }
10498 const newValue = value == null ? '' : value;
10499 if (el.value !== newValue) {
10500 el.value = newValue;
10501 }
10502 }
10503 };
10504 const vModelCheckbox = {
10505 // #4096 array checkboxes need to be deep traversed
10506 deep: true,
10507 created(el, _, vnode) {
10508 el._assign = getModelAssigner(vnode);
10509 addEventListener(el, 'change', () => {
10510 const modelValue = el._modelValue;
10511 const elementValue = getValue(el);
10512 const checked = el.checked;
10513 const assign = el._assign;
10514 if (isArray(modelValue)) {
10515 const index = looseIndexOf(modelValue, elementValue);
10516 const found = index !== -1;
10517 if (checked && !found) {
10518 assign(modelValue.concat(elementValue));
10519 }
10520 else if (!checked && found) {
10521 const filtered = [...modelValue];
10522 filtered.splice(index, 1);
10523 assign(filtered);
10524 }
10525 }
10526 else if (isSet(modelValue)) {
10527 const cloned = new Set(modelValue);
10528 if (checked) {
10529 cloned.add(elementValue);
10530 }
10531 else {
10532 cloned.delete(elementValue);
10533 }
10534 assign(cloned);
10535 }
10536 else {
10537 assign(getCheckboxValue(el, checked));
10538 }
10539 });
10540 },
10541 // set initial checked on mount to wait for true-value/false-value
10542 mounted: setChecked,
10543 beforeUpdate(el, binding, vnode) {
10544 el._assign = getModelAssigner(vnode);
10545 setChecked(el, binding, vnode);
10546 }
10547 };
10548 function setChecked(el, { value, oldValue }, vnode) {
10549 el._modelValue = value;
10550 if (isArray(value)) {
10551 el.checked = looseIndexOf(value, vnode.props.value) > -1;
10552 }
10553 else if (isSet(value)) {
10554 el.checked = value.has(vnode.props.value);
10555 }
10556 else if (value !== oldValue) {
10557 el.checked = looseEqual(value, getCheckboxValue(el, true));
10558 }
10559 }
10560 const vModelRadio = {
10561 created(el, { value }, vnode) {
10562 el.checked = looseEqual(value, vnode.props.value);
10563 el._assign = getModelAssigner(vnode);
10564 addEventListener(el, 'change', () => {
10565 el._assign(getValue(el));
10566 });
10567 },
10568 beforeUpdate(el, { value, oldValue }, vnode) {
10569 el._assign = getModelAssigner(vnode);
10570 if (value !== oldValue) {
10571 el.checked = looseEqual(value, vnode.props.value);
10572 }
10573 }
10574 };
10575 const vModelSelect = {
10576 // <select multiple> value need to be deep traversed
10577 deep: true,
10578 created(el, { value, modifiers: { number } }, vnode) {
10579 const isSetModel = isSet(value);
10580 addEventListener(el, 'change', () => {
10581 const selectedVal = Array.prototype.filter
10582 .call(el.options, (o) => o.selected)
10583 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
10584 el._assign(el.multiple
10585 ? isSetModel
10586 ? new Set(selectedVal)
10587 : selectedVal
10588 : selectedVal[0]);
10589 });
10590 el._assign = getModelAssigner(vnode);
10591 },
10592 // set value in mounted & updated because <select> relies on its children
10593 // <option>s.
10594 mounted(el, { value }) {
10595 setSelected(el, value);
10596 },
10597 beforeUpdate(el, _binding, vnode) {
10598 el._assign = getModelAssigner(vnode);
10599 },
10600 updated(el, { value }) {
10601 setSelected(el, value);
10602 }
10603 };
10604 function setSelected(el, value) {
10605 const isMultiple = el.multiple;
10606 if (isMultiple && !isArray(value) && !isSet(value)) {
10607 warn$1(`<select multiple v-model> expects an Array or Set value for its binding, ` +
10608 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
10609 return;
10610 }
10611 for (let i = 0, l = el.options.length; i < l; i++) {
10612 const option = el.options[i];
10613 const optionValue = getValue(option);
10614 if (isMultiple) {
10615 if (isArray(value)) {
10616 option.selected = looseIndexOf(value, optionValue) > -1;
10617 }
10618 else {
10619 option.selected = value.has(optionValue);
10620 }
10621 }
10622 else {
10623 if (looseEqual(getValue(option), value)) {
10624 if (el.selectedIndex !== i)
10625 el.selectedIndex = i;
10626 return;
10627 }
10628 }
10629 }
10630 if (!isMultiple && el.selectedIndex !== -1) {
10631 el.selectedIndex = -1;
10632 }
10633 }
10634 // retrieve raw value set via :value bindings
10635 function getValue(el) {
10636 return '_value' in el ? el._value : el.value;
10637 }
10638 // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
10639 function getCheckboxValue(el, checked) {
10640 const key = checked ? '_trueValue' : '_falseValue';
10641 return key in el ? el[key] : checked;
10642 }
10643 const vModelDynamic = {
10644 created(el, binding, vnode) {
10645 callModelHook(el, binding, vnode, null, 'created');
10646 },
10647 mounted(el, binding, vnode) {
10648 callModelHook(el, binding, vnode, null, 'mounted');
10649 },
10650 beforeUpdate(el, binding, vnode, prevVNode) {
10651 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
10652 },
10653 updated(el, binding, vnode, prevVNode) {
10654 callModelHook(el, binding, vnode, prevVNode, 'updated');
10655 }
10656 };
10657 function resolveDynamicModel(tagName, type) {
10658 switch (tagName) {
10659 case 'SELECT':
10660 return vModelSelect;
10661 case 'TEXTAREA':
10662 return vModelText;
10663 default:
10664 switch (type) {
10665 case 'checkbox':
10666 return vModelCheckbox;
10667 case 'radio':
10668 return vModelRadio;
10669 default:
10670 return vModelText;
10671 }
10672 }
10673 }
10674 function callModelHook(el, binding, vnode, prevVNode, hook) {
10675 const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
10676 const fn = modelToUse[hook];
10677 fn && fn(el, binding, vnode, prevVNode);
10678 }
10679
10680 const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
10681 const modifierGuards = {
10682 stop: e => e.stopPropagation(),
10683 prevent: e => e.preventDefault(),
10684 self: e => e.target !== e.currentTarget,
10685 ctrl: e => !e.ctrlKey,
10686 shift: e => !e.shiftKey,
10687 alt: e => !e.altKey,
10688 meta: e => !e.metaKey,
10689 left: e => 'button' in e && e.button !== 0,
10690 middle: e => 'button' in e && e.button !== 1,
10691 right: e => 'button' in e && e.button !== 2,
10692 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
10693 };
10694 /**
10695 * @private
10696 */
10697 const withModifiers = (fn, modifiers) => {
10698 return (event, ...args) => {
10699 for (let i = 0; i < modifiers.length; i++) {
10700 const guard = modifierGuards[modifiers[i]];
10701 if (guard && guard(event, modifiers))
10702 return;
10703 }
10704 return fn(event, ...args);
10705 };
10706 };
10707 // Kept for 2.x compat.
10708 // Note: IE11 compat for `spacebar` and `del` is removed for now.
10709 const keyNames = {
10710 esc: 'escape',
10711 space: ' ',
10712 up: 'arrow-up',
10713 left: 'arrow-left',
10714 right: 'arrow-right',
10715 down: 'arrow-down',
10716 delete: 'backspace'
10717 };
10718 /**
10719 * @private
10720 */
10721 const withKeys = (fn, modifiers) => {
10722 return (event) => {
10723 if (!('key' in event)) {
10724 return;
10725 }
10726 const eventKey = hyphenate(event.key);
10727 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
10728 return fn(event);
10729 }
10730 };
10731 };
10732
10733 const vShow = {
10734 beforeMount(el, { value }, { transition }) {
10735 el._vod = el.style.display === 'none' ? '' : el.style.display;
10736 if (transition && value) {
10737 transition.beforeEnter(el);
10738 }
10739 else {
10740 setDisplay(el, value);
10741 }
10742 },
10743 mounted(el, { value }, { transition }) {
10744 if (transition && value) {
10745 transition.enter(el);
10746 }
10747 },
10748 updated(el, { value, oldValue }, { transition }) {
10749 if (!value === !oldValue)
10750 return;
10751 if (transition) {
10752 if (value) {
10753 transition.beforeEnter(el);
10754 setDisplay(el, true);
10755 transition.enter(el);
10756 }
10757 else {
10758 transition.leave(el, () => {
10759 setDisplay(el, false);
10760 });
10761 }
10762 }
10763 else {
10764 setDisplay(el, value);
10765 }
10766 },
10767 beforeUnmount(el, { value }) {
10768 setDisplay(el, value);
10769 }
10770 };
10771 function setDisplay(el, value) {
10772 el.style.display = value ? el._vod : 'none';
10773 }
10774
10775 const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps);
10776 // lazy create the renderer - this makes core renderer logic tree-shakable
10777 // in case the user only imports reactivity utilities from Vue.
10778 let renderer;
10779 let enabledHydration = false;
10780 function ensureRenderer() {
10781 return (renderer ||
10782 (renderer = createRenderer(rendererOptions)));
10783 }
10784 function ensureHydrationRenderer() {
10785 renderer = enabledHydration
10786 ? renderer
10787 : createHydrationRenderer(rendererOptions);
10788 enabledHydration = true;
10789 return renderer;
10790 }
10791 // use explicit type casts here to avoid import() calls in rolled-up d.ts
10792 const render = ((...args) => {
10793 ensureRenderer().render(...args);
10794 });
10795 const hydrate = ((...args) => {
10796 ensureHydrationRenderer().hydrate(...args);
10797 });
10798 const createApp = ((...args) => {
10799 const app = ensureRenderer().createApp(...args);
10800 {
10801 injectNativeTagCheck(app);
10802 injectCompilerOptionsCheck(app);
10803 }
10804 const { mount } = app;
10805 app.mount = (containerOrSelector) => {
10806 const container = normalizeContainer(containerOrSelector);
10807 if (!container)
10808 return;
10809 const component = app._component;
10810 if (!isFunction(component) && !component.render && !component.template) {
10811 // __UNSAFE__
10812 // Reason: potential execution of JS expressions in in-DOM template.
10813 // The user must make sure the in-DOM template is trusted. If it's
10814 // rendered by the server, the template should not contain any user data.
10815 component.template = container.innerHTML;
10816 }
10817 // clear content before mounting
10818 container.innerHTML = '';
10819 const proxy = mount(container, false, container instanceof SVGElement);
10820 if (container instanceof Element) {
10821 container.removeAttribute('v-cloak');
10822 container.setAttribute('data-v-app', '');
10823 }
10824 return proxy;
10825 };
10826 return app;
10827 });
10828 const createSSRApp = ((...args) => {
10829 const app = ensureHydrationRenderer().createApp(...args);
10830 {
10831 injectNativeTagCheck(app);
10832 injectCompilerOptionsCheck(app);
10833 }
10834 const { mount } = app;
10835 app.mount = (containerOrSelector) => {
10836 const container = normalizeContainer(containerOrSelector);
10837 if (container) {
10838 return mount(container, true, container instanceof SVGElement);
10839 }
10840 };
10841 return app;
10842 });
10843 function injectNativeTagCheck(app) {
10844 // Inject `isNativeTag`
10845 // this is used for component name validation (dev only)
10846 Object.defineProperty(app.config, 'isNativeTag', {
10847 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
10848 writable: false
10849 });
10850 }
10851 // dev only
10852 function injectCompilerOptionsCheck(app) {
10853 if (isRuntimeOnly()) {
10854 const isCustomElement = app.config.isCustomElement;
10855 Object.defineProperty(app.config, 'isCustomElement', {
10856 get() {
10857 return isCustomElement;
10858 },
10859 set() {
10860 warn$1(`The \`isCustomElement\` config option is deprecated. Use ` +
10861 `\`compilerOptions.isCustomElement\` instead.`);
10862 }
10863 });
10864 const compilerOptions = app.config.compilerOptions;
10865 const msg = `The \`compilerOptions\` config option is only respected when using ` +
10866 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
10867 `Since you are using the runtime-only build, \`compilerOptions\` ` +
10868 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
10869 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
10870 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
10871 `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom`;
10872 Object.defineProperty(app.config, 'compilerOptions', {
10873 get() {
10874 warn$1(msg);
10875 return compilerOptions;
10876 },
10877 set() {
10878 warn$1(msg);
10879 }
10880 });
10881 }
10882 }
10883 function normalizeContainer(container) {
10884 if (isString(container)) {
10885 const res = document.querySelector(container);
10886 if (!res) {
10887 warn$1(`Failed to mount app: mount target selector "${container}" returned null.`);
10888 }
10889 return res;
10890 }
10891 if (window.ShadowRoot &&
10892 container instanceof window.ShadowRoot &&
10893 container.mode === 'closed') {
10894 warn$1(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
10895 }
10896 return container;
10897 }
10898 /**
10899 * @internal
10900 */
10901 const initDirectivesForSSR = NOOP;
10902
10903 function initDev() {
10904 {
10905 {
10906 console.info(`You are running a development build of Vue.\n` +
10907 `Make sure to use the production build (*.prod.js) when deploying for production.`);
10908 }
10909 initCustomFormatter();
10910 }
10911 }
10912
10913 function defaultOnError(error) {
10914 throw error;
10915 }
10916 function defaultOnWarn(msg) {
10917 console.warn(`[Vue warn] ${msg.message}`);
10918 }
10919 function createCompilerError(code, loc, messages, additionalMessage) {
10920 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
10921 ;
10922 const error = new SyntaxError(String(msg));
10923 error.code = code;
10924 error.loc = loc;
10925 return error;
10926 }
10927 const errorMessages = {
10928 // parse errors
10929 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
10930 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
10931 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
10932 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
10933 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
10934 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
10935 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
10936 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
10937 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
10938 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
10939 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
10940 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
10941 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
10942 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
10943 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
10944 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
10945 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
10946 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
10947 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
10948 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
10949 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
10950 [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
10951 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
10952 // Vue-specific parse errors
10953 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
10954 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
10955 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
10956 [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
10957 'Note that dynamic directive argument cannot contain spaces.',
10958 [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
10959 // transform errors
10960 [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
10961 [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
10962 [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
10963 [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
10964 [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
10965 [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
10966 [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
10967 [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
10968 [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
10969 [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
10970 `When there are multiple named slots, all slots should use <template> ` +
10971 `syntax to avoid scope ambiguity.`,
10972 [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
10973 [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
10974 `default slot. These children will be ignored.`,
10975 [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
10976 [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
10977 [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
10978 [43 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
10979 [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
10980 [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
10981 // generic errors
10982 [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
10983 [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
10984 [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
10985 [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
10986 // just to fulfill types
10987 [50 /* __EXTEND_POINT__ */]: ``
10988 };
10989
10990 const FRAGMENT = Symbol(`Fragment` );
10991 const TELEPORT = Symbol(`Teleport` );
10992 const SUSPENSE = Symbol(`Suspense` );
10993 const KEEP_ALIVE = Symbol(`KeepAlive` );
10994 const BASE_TRANSITION = Symbol(`BaseTransition` );
10995 const OPEN_BLOCK = Symbol(`openBlock` );
10996 const CREATE_BLOCK = Symbol(`createBlock` );
10997 const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` );
10998 const CREATE_VNODE = Symbol(`createVNode` );
10999 const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` );
11000 const CREATE_COMMENT = Symbol(`createCommentVNode` );
11001 const CREATE_TEXT = Symbol(`createTextVNode` );
11002 const CREATE_STATIC = Symbol(`createStaticVNode` );
11003 const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
11004 const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
11005 const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
11006 const RESOLVE_FILTER = Symbol(`resolveFilter` );
11007 const WITH_DIRECTIVES = Symbol(`withDirectives` );
11008 const RENDER_LIST = Symbol(`renderList` );
11009 const RENDER_SLOT = Symbol(`renderSlot` );
11010 const CREATE_SLOTS = Symbol(`createSlots` );
11011 const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
11012 const MERGE_PROPS = Symbol(`mergeProps` );
11013 const NORMALIZE_CLASS = Symbol(`normalizeClass` );
11014 const NORMALIZE_STYLE = Symbol(`normalizeStyle` );
11015 const NORMALIZE_PROPS = Symbol(`normalizeProps` );
11016 const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` );
11017 const TO_HANDLERS = Symbol(`toHandlers` );
11018 const CAMELIZE = Symbol(`camelize` );
11019 const CAPITALIZE = Symbol(`capitalize` );
11020 const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
11021 const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
11022 const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
11023 const POP_SCOPE_ID = Symbol(`popScopeId` );
11024 const WITH_CTX = Symbol(`withCtx` );
11025 const UNREF = Symbol(`unref` );
11026 const IS_REF = Symbol(`isRef` );
11027 const WITH_MEMO = Symbol(`withMemo` );
11028 const IS_MEMO_SAME = Symbol(`isMemoSame` );
11029 // Name mapping for runtime helpers that need to be imported from 'vue' in
11030 // generated code. Make sure these are correctly exported in the runtime!
11031 // Using `any` here because TS doesn't allow symbols as index type.
11032 const helperNameMap = {
11033 [FRAGMENT]: `Fragment`,
11034 [TELEPORT]: `Teleport`,
11035 [SUSPENSE]: `Suspense`,
11036 [KEEP_ALIVE]: `KeepAlive`,
11037 [BASE_TRANSITION]: `BaseTransition`,
11038 [OPEN_BLOCK]: `openBlock`,
11039 [CREATE_BLOCK]: `createBlock`,
11040 [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
11041 [CREATE_VNODE]: `createVNode`,
11042 [CREATE_ELEMENT_VNODE]: `createElementVNode`,
11043 [CREATE_COMMENT]: `createCommentVNode`,
11044 [CREATE_TEXT]: `createTextVNode`,
11045 [CREATE_STATIC]: `createStaticVNode`,
11046 [RESOLVE_COMPONENT]: `resolveComponent`,
11047 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
11048 [RESOLVE_DIRECTIVE]: `resolveDirective`,
11049 [RESOLVE_FILTER]: `resolveFilter`,
11050 [WITH_DIRECTIVES]: `withDirectives`,
11051 [RENDER_LIST]: `renderList`,
11052 [RENDER_SLOT]: `renderSlot`,
11053 [CREATE_SLOTS]: `createSlots`,
11054 [TO_DISPLAY_STRING]: `toDisplayString`,
11055 [MERGE_PROPS]: `mergeProps`,
11056 [NORMALIZE_CLASS]: `normalizeClass`,
11057 [NORMALIZE_STYLE]: `normalizeStyle`,
11058 [NORMALIZE_PROPS]: `normalizeProps`,
11059 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
11060 [TO_HANDLERS]: `toHandlers`,
11061 [CAMELIZE]: `camelize`,
11062 [CAPITALIZE]: `capitalize`,
11063 [TO_HANDLER_KEY]: `toHandlerKey`,
11064 [SET_BLOCK_TRACKING]: `setBlockTracking`,
11065 [PUSH_SCOPE_ID]: `pushScopeId`,
11066 [POP_SCOPE_ID]: `popScopeId`,
11067 [WITH_CTX]: `withCtx`,
11068 [UNREF]: `unref`,
11069 [IS_REF]: `isRef`,
11070 [WITH_MEMO]: `withMemo`,
11071 [IS_MEMO_SAME]: `isMemoSame`
11072 };
11073 function registerRuntimeHelpers(helpers) {
11074 Object.getOwnPropertySymbols(helpers).forEach(s => {
11075 helperNameMap[s] = helpers[s];
11076 });
11077 }
11078
11079 // AST Utilities ---------------------------------------------------------------
11080 // Some expressions, e.g. sequence and conditional expressions, are never
11081 // associated with template nodes, so their source locations are just a stub.
11082 // Container types like CompoundExpression also don't need a real location.
11083 const locStub = {
11084 source: '',
11085 start: { line: 1, column: 1, offset: 0 },
11086 end: { line: 1, column: 1, offset: 0 }
11087 };
11088 function createRoot(children, loc = locStub) {
11089 return {
11090 type: 0 /* ROOT */,
11091 children,
11092 helpers: [],
11093 components: [],
11094 directives: [],
11095 hoists: [],
11096 imports: [],
11097 cached: 0,
11098 temps: 0,
11099 codegenNode: undefined,
11100 loc
11101 };
11102 }
11103 function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
11104 if (context) {
11105 if (isBlock) {
11106 context.helper(OPEN_BLOCK);
11107 context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
11108 }
11109 else {
11110 context.helper(getVNodeHelper(context.inSSR, isComponent));
11111 }
11112 if (directives) {
11113 context.helper(WITH_DIRECTIVES);
11114 }
11115 }
11116 return {
11117 type: 13 /* VNODE_CALL */,
11118 tag,
11119 props,
11120 children,
11121 patchFlag,
11122 dynamicProps,
11123 directives,
11124 isBlock,
11125 disableTracking,
11126 isComponent,
11127 loc
11128 };
11129 }
11130 function createArrayExpression(elements, loc = locStub) {
11131 return {
11132 type: 17 /* JS_ARRAY_EXPRESSION */,
11133 loc,
11134 elements
11135 };
11136 }
11137 function createObjectExpression(properties, loc = locStub) {
11138 return {
11139 type: 15 /* JS_OBJECT_EXPRESSION */,
11140 loc,
11141 properties
11142 };
11143 }
11144 function createObjectProperty(key, value) {
11145 return {
11146 type: 16 /* JS_PROPERTY */,
11147 loc: locStub,
11148 key: isString(key) ? createSimpleExpression(key, true) : key,
11149 value
11150 };
11151 }
11152 function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
11153 return {
11154 type: 4 /* SIMPLE_EXPRESSION */,
11155 loc,
11156 content,
11157 isStatic,
11158 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
11159 };
11160 }
11161 function createCompoundExpression(children, loc = locStub) {
11162 return {
11163 type: 8 /* COMPOUND_EXPRESSION */,
11164 loc,
11165 children
11166 };
11167 }
11168 function createCallExpression(callee, args = [], loc = locStub) {
11169 return {
11170 type: 14 /* JS_CALL_EXPRESSION */,
11171 loc,
11172 callee,
11173 arguments: args
11174 };
11175 }
11176 function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
11177 return {
11178 type: 18 /* JS_FUNCTION_EXPRESSION */,
11179 params,
11180 returns,
11181 newline,
11182 isSlot,
11183 loc
11184 };
11185 }
11186 function createConditionalExpression(test, consequent, alternate, newline = true) {
11187 return {
11188 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
11189 test,
11190 consequent,
11191 alternate,
11192 newline,
11193 loc: locStub
11194 };
11195 }
11196 function createCacheExpression(index, value, isVNode = false) {
11197 return {
11198 type: 20 /* JS_CACHE_EXPRESSION */,
11199 index,
11200 value,
11201 isVNode,
11202 loc: locStub
11203 };
11204 }
11205 function createBlockStatement(body) {
11206 return {
11207 type: 21 /* JS_BLOCK_STATEMENT */,
11208 body,
11209 loc: locStub
11210 };
11211 }
11212
11213 const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
11214 const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
11215 function isCoreComponent(tag) {
11216 if (isBuiltInType(tag, 'Teleport')) {
11217 return TELEPORT;
11218 }
11219 else if (isBuiltInType(tag, 'Suspense')) {
11220 return SUSPENSE;
11221 }
11222 else if (isBuiltInType(tag, 'KeepAlive')) {
11223 return KEEP_ALIVE;
11224 }
11225 else if (isBuiltInType(tag, 'BaseTransition')) {
11226 return BASE_TRANSITION;
11227 }
11228 }
11229 const nonIdentifierRE = /^\d|[^\$\w]/;
11230 const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
11231 const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
11232 const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
11233 const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
11234 /**
11235 * Simple lexer to check if an expression is a member expression. This is
11236 * lax and only checks validity at the root level (i.e. does not validate exps
11237 * inside square brackets), but it's ok since these are only used on template
11238 * expressions and false positives are invalid expressions in the first place.
11239 */
11240 const isMemberExpressionBrowser = (path) => {
11241 // remove whitespaces around . or [ first
11242 path = path.trim().replace(whitespaceRE, s => s.trim());
11243 let state = 0 /* inMemberExp */;
11244 let stateStack = [];
11245 let currentOpenBracketCount = 0;
11246 let currentOpenParensCount = 0;
11247 let currentStringType = null;
11248 for (let i = 0; i < path.length; i++) {
11249 const char = path.charAt(i);
11250 switch (state) {
11251 case 0 /* inMemberExp */:
11252 if (char === '[') {
11253 stateStack.push(state);
11254 state = 1 /* inBrackets */;
11255 currentOpenBracketCount++;
11256 }
11257 else if (char === '(') {
11258 stateStack.push(state);
11259 state = 2 /* inParens */;
11260 currentOpenParensCount++;
11261 }
11262 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
11263 return false;
11264 }
11265 break;
11266 case 1 /* inBrackets */:
11267 if (char === `'` || char === `"` || char === '`') {
11268 stateStack.push(state);
11269 state = 3 /* inString */;
11270 currentStringType = char;
11271 }
11272 else if (char === `[`) {
11273 currentOpenBracketCount++;
11274 }
11275 else if (char === `]`) {
11276 if (!--currentOpenBracketCount) {
11277 state = stateStack.pop();
11278 }
11279 }
11280 break;
11281 case 2 /* inParens */:
11282 if (char === `'` || char === `"` || char === '`') {
11283 stateStack.push(state);
11284 state = 3 /* inString */;
11285 currentStringType = char;
11286 }
11287 else if (char === `(`) {
11288 currentOpenParensCount++;
11289 }
11290 else if (char === `)`) {
11291 // if the exp ends as a call then it should not be considered valid
11292 if (i === path.length - 1) {
11293 return false;
11294 }
11295 if (!--currentOpenParensCount) {
11296 state = stateStack.pop();
11297 }
11298 }
11299 break;
11300 case 3 /* inString */:
11301 if (char === currentStringType) {
11302 state = stateStack.pop();
11303 currentStringType = null;
11304 }
11305 break;
11306 }
11307 }
11308 return !currentOpenBracketCount && !currentOpenParensCount;
11309 };
11310 const isMemberExpression = isMemberExpressionBrowser
11311 ;
11312 function getInnerRange(loc, offset, length) {
11313 const source = loc.source.slice(offset, offset + length);
11314 const newLoc = {
11315 source,
11316 start: advancePositionWithClone(loc.start, loc.source, offset),
11317 end: loc.end
11318 };
11319 if (length != null) {
11320 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
11321 }
11322 return newLoc;
11323 }
11324 function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
11325 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
11326 }
11327 // advance by mutation without cloning (for performance reasons), since this
11328 // gets called a lot in the parser
11329 function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
11330 let linesCount = 0;
11331 let lastNewLinePos = -1;
11332 for (let i = 0; i < numberOfCharacters; i++) {
11333 if (source.charCodeAt(i) === 10 /* newline char code */) {
11334 linesCount++;
11335 lastNewLinePos = i;
11336 }
11337 }
11338 pos.offset += numberOfCharacters;
11339 pos.line += linesCount;
11340 pos.column =
11341 lastNewLinePos === -1
11342 ? pos.column + numberOfCharacters
11343 : numberOfCharacters - lastNewLinePos;
11344 return pos;
11345 }
11346 function assert(condition, msg) {
11347 /* istanbul ignore if */
11348 if (!condition) {
11349 throw new Error(msg || `unexpected compiler condition`);
11350 }
11351 }
11352 function findDir(node, name, allowEmpty = false) {
11353 for (let i = 0; i < node.props.length; i++) {
11354 const p = node.props[i];
11355 if (p.type === 7 /* DIRECTIVE */ &&
11356 (allowEmpty || p.exp) &&
11357 (isString(name) ? p.name === name : name.test(p.name))) {
11358 return p;
11359 }
11360 }
11361 }
11362 function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11363 for (let i = 0; i < node.props.length; i++) {
11364 const p = node.props[i];
11365 if (p.type === 6 /* ATTRIBUTE */) {
11366 if (dynamicOnly)
11367 continue;
11368 if (p.name === name && (p.value || allowEmpty)) {
11369 return p;
11370 }
11371 }
11372 else if (p.name === 'bind' &&
11373 (p.exp || allowEmpty) &&
11374 isStaticArgOf(p.arg, name)) {
11375 return p;
11376 }
11377 }
11378 }
11379 function isStaticArgOf(arg, name) {
11380 return !!(arg && isStaticExp(arg) && arg.content === name);
11381 }
11382 function hasDynamicKeyVBind(node) {
11383 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
11384 p.name === 'bind' &&
11385 (!p.arg || // v-bind="obj"
11386 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
11387 !p.arg.isStatic) // v-bind:[foo]
11388 );
11389 }
11390 function isText(node) {
11391 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
11392 }
11393 function isVSlot(p) {
11394 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
11395 }
11396 function isTemplateNode(node) {
11397 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
11398 }
11399 function isSlotOutlet(node) {
11400 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
11401 }
11402 function getVNodeHelper(ssr, isComponent) {
11403 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
11404 }
11405 function getVNodeBlockHelper(ssr, isComponent) {
11406 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
11407 }
11408 const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
11409 function getUnnormalizedProps(props, callPath = []) {
11410 if (props &&
11411 !isString(props) &&
11412 props.type === 14 /* JS_CALL_EXPRESSION */) {
11413 const callee = props.callee;
11414 if (!isString(callee) && propsHelperSet.has(callee)) {
11415 return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
11416 }
11417 }
11418 return [props, callPath];
11419 }
11420 function injectProp(node, prop, context) {
11421 let propsWithInjection;
11422 /**
11423 * 1. mergeProps(...)
11424 * 2. toHandlers(...)
11425 * 3. normalizeProps(...)
11426 * 4. normalizeProps(guardReactiveProps(...))
11427 *
11428 * we need to get the real props before normalization
11429 */
11430 let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11431 let callPath = [];
11432 let parentCall;
11433 if (props &&
11434 !isString(props) &&
11435 props.type === 14 /* JS_CALL_EXPRESSION */) {
11436 const ret = getUnnormalizedProps(props);
11437 props = ret[0];
11438 callPath = ret[1];
11439 parentCall = callPath[callPath.length - 1];
11440 }
11441 if (props == null || isString(props)) {
11442 propsWithInjection = createObjectExpression([prop]);
11443 }
11444 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
11445 // merged props... add ours
11446 // only inject key to object literal if it's the first argument so that
11447 // if doesn't override user provided keys
11448 const first = props.arguments[0];
11449 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
11450 first.properties.unshift(prop);
11451 }
11452 else {
11453 if (props.callee === TO_HANDLERS) {
11454 // #2366
11455 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11456 createObjectExpression([prop]),
11457 props
11458 ]);
11459 }
11460 else {
11461 props.arguments.unshift(createObjectExpression([prop]));
11462 }
11463 }
11464 !propsWithInjection && (propsWithInjection = props);
11465 }
11466 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
11467 let alreadyExists = false;
11468 // check existing key to avoid overriding user provided keys
11469 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
11470 const propKeyName = prop.key.content;
11471 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
11472 p.key.content === propKeyName);
11473 }
11474 if (!alreadyExists) {
11475 props.properties.unshift(prop);
11476 }
11477 propsWithInjection = props;
11478 }
11479 else {
11480 // single v-bind with expression, return a merged replacement
11481 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11482 createObjectExpression([prop]),
11483 props
11484 ]);
11485 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
11486 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
11487 // the `guardReactiveProps` will no longer be needed
11488 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
11489 parentCall = callPath[callPath.length - 2];
11490 }
11491 }
11492 if (node.type === 13 /* VNODE_CALL */) {
11493 if (parentCall) {
11494 parentCall.arguments[0] = propsWithInjection;
11495 }
11496 else {
11497 node.props = propsWithInjection;
11498 }
11499 }
11500 else {
11501 if (parentCall) {
11502 parentCall.arguments[0] = propsWithInjection;
11503 }
11504 else {
11505 node.arguments[2] = propsWithInjection;
11506 }
11507 }
11508 }
11509 function toValidAssetId(name, type) {
11510 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
11511 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
11512 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
11513 })}`;
11514 }
11515 function getMemoedVNodeCall(node) {
11516 if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
11517 return node.arguments[1].returns;
11518 }
11519 else {
11520 return node;
11521 }
11522 }
11523 function makeBlock(node, { helper, removeHelper, inSSR }) {
11524 if (!node.isBlock) {
11525 node.isBlock = true;
11526 removeHelper(getVNodeHelper(inSSR, node.isComponent));
11527 helper(OPEN_BLOCK);
11528 helper(getVNodeBlockHelper(inSSR, node.isComponent));
11529 }
11530 }
11531
11532 const deprecationData = {
11533 ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
11534 message: `Platform-native elements with "is" prop will no longer be ` +
11535 `treated as components in Vue 3 unless the "is" value is explicitly ` +
11536 `prefixed with "vue:".`,
11537 link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
11538 },
11539 ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
11540 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
11541 `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
11542 `\`v-model:${key}\`.`,
11543 link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
11544 },
11545 ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
11546 message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
11547 `Vue 3 will automatically set a binding as DOM property when appropriate.`
11548 },
11549 ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
11550 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
11551 `object spread: it will now overwrite an existing non-mergeable attribute ` +
11552 `that appears before v-bind in the case of conflict. ` +
11553 `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
11554 `You can also suppress this warning if the usage is intended.`,
11555 link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
11556 },
11557 ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
11558 message: `.native modifier for v-on has been removed as is no longer necessary.`,
11559 link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
11560 },
11561 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
11562 message: `v-if / v-for precedence when used on the same element has changed ` +
11563 `in Vue 3: v-if now takes higher precedence and will no longer have ` +
11564 `access to v-for scope variables. It is best to avoid the ambiguity ` +
11565 `with <template> tags or use a computed property that filters v-for ` +
11566 `data source.`,
11567 link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
11568 },
11569 ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
11570 message: `<template> with no special directives will render as a native template ` +
11571 `element instead of its inner content in Vue 3.`
11572 },
11573 ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
11574 message: `"inline-template" has been removed in Vue 3.`,
11575 link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
11576 },
11577 ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
11578 message: `filters have been removed in Vue 3. ` +
11579 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
11580 `Use method calls or computed properties instead.`,
11581 link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
11582 }
11583 };
11584 function getCompatValue(key, context) {
11585 const config = context.options
11586 ? context.options.compatConfig
11587 : context.compatConfig;
11588 const value = config && config[key];
11589 if (key === 'MODE') {
11590 return value || 3; // compiler defaults to v3 behavior
11591 }
11592 else {
11593 return value;
11594 }
11595 }
11596 function isCompatEnabled(key, context) {
11597 const mode = getCompatValue('MODE', context);
11598 const value = getCompatValue(key, context);
11599 // in v3 mode, only enable if explicitly set to true
11600 // otherwise enable for any non-false value
11601 return mode === 3 ? value === true : value !== false;
11602 }
11603 function checkCompatEnabled(key, context, loc, ...args) {
11604 const enabled = isCompatEnabled(key, context);
11605 if (enabled) {
11606 warnDeprecation(key, context, loc, ...args);
11607 }
11608 return enabled;
11609 }
11610 function warnDeprecation(key, context, loc, ...args) {
11611 const val = getCompatValue(key, context);
11612 if (val === 'suppress-warning') {
11613 return;
11614 }
11615 const { message, link } = deprecationData[key];
11616 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
11617 const err = new SyntaxError(msg);
11618 err.code = key;
11619 if (loc)
11620 err.loc = loc;
11621 context.onWarn(err);
11622 }
11623
11624 // The default decoder only provides escapes for characters reserved as part of
11625 // the template syntax, and is only used if the custom renderer did not provide
11626 // a platform-specific decoder.
11627 const decodeRE = /&(gt|lt|amp|apos|quot);/g;
11628 const decodeMap = {
11629 gt: '>',
11630 lt: '<',
11631 amp: '&',
11632 apos: "'",
11633 quot: '"'
11634 };
11635 const defaultParserOptions = {
11636 delimiters: [`{{`, `}}`],
11637 getNamespace: () => 0 /* HTML */,
11638 getTextMode: () => 0 /* DATA */,
11639 isVoidTag: NO,
11640 isPreTag: NO,
11641 isCustomElement: NO,
11642 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
11643 onError: defaultOnError,
11644 onWarn: defaultOnWarn,
11645 comments: true
11646 };
11647 function baseParse(content, options = {}) {
11648 const context = createParserContext(content, options);
11649 const start = getCursor(context);
11650 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
11651 }
11652 function createParserContext(content, rawOptions) {
11653 const options = extend({}, defaultParserOptions);
11654 let key;
11655 for (key in rawOptions) {
11656 // @ts-ignore
11657 options[key] =
11658 rawOptions[key] === undefined
11659 ? defaultParserOptions[key]
11660 : rawOptions[key];
11661 }
11662 return {
11663 options,
11664 column: 1,
11665 line: 1,
11666 offset: 0,
11667 originalSource: content,
11668 source: content,
11669 inPre: false,
11670 inVPre: false,
11671 onWarn: options.onWarn
11672 };
11673 }
11674 function parseChildren(context, mode, ancestors) {
11675 const parent = last(ancestors);
11676 const ns = parent ? parent.ns : 0 /* HTML */;
11677 const nodes = [];
11678 while (!isEnd(context, mode, ancestors)) {
11679 const s = context.source;
11680 let node = undefined;
11681 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
11682 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
11683 // '{{'
11684 node = parseInterpolation(context, mode);
11685 }
11686 else if (mode === 0 /* DATA */ && s[0] === '<') {
11687 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
11688 if (s.length === 1) {
11689 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
11690 }
11691 else if (s[1] === '!') {
11692 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
11693 if (startsWith(s, '<!--')) {
11694 node = parseComment(context);
11695 }
11696 else if (startsWith(s, '<!DOCTYPE')) {
11697 // Ignore DOCTYPE by a limitation.
11698 node = parseBogusComment(context);
11699 }
11700 else if (startsWith(s, '<![CDATA[')) {
11701 if (ns !== 0 /* HTML */) {
11702 node = parseCDATA(context, ancestors);
11703 }
11704 else {
11705 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
11706 node = parseBogusComment(context);
11707 }
11708 }
11709 else {
11710 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
11711 node = parseBogusComment(context);
11712 }
11713 }
11714 else if (s[1] === '/') {
11715 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
11716 if (s.length === 2) {
11717 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
11718 }
11719 else if (s[2] === '>') {
11720 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
11721 advanceBy(context, 3);
11722 continue;
11723 }
11724 else if (/[a-z]/i.test(s[2])) {
11725 emitError(context, 23 /* X_INVALID_END_TAG */);
11726 parseTag(context, 1 /* End */, parent);
11727 continue;
11728 }
11729 else {
11730 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
11731 node = parseBogusComment(context);
11732 }
11733 }
11734 else if (/[a-z]/i.test(s[1])) {
11735 node = parseElement(context, ancestors);
11736 }
11737 else if (s[1] === '?') {
11738 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
11739 node = parseBogusComment(context);
11740 }
11741 else {
11742 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
11743 }
11744 }
11745 }
11746 if (!node) {
11747 node = parseText(context, mode);
11748 }
11749 if (isArray(node)) {
11750 for (let i = 0; i < node.length; i++) {
11751 pushNode(nodes, node[i]);
11752 }
11753 }
11754 else {
11755 pushNode(nodes, node);
11756 }
11757 }
11758 // Whitespace handling strategy like v2
11759 let removedWhitespace = false;
11760 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
11761 const shouldCondense = context.options.whitespace !== 'preserve';
11762 for (let i = 0; i < nodes.length; i++) {
11763 const node = nodes[i];
11764 if (!context.inPre && node.type === 2 /* TEXT */) {
11765 if (!/[^\t\r\n\f ]/.test(node.content)) {
11766 const prev = nodes[i - 1];
11767 const next = nodes[i + 1];
11768 // Remove if:
11769 // - the whitespace is the first or last node, or:
11770 // - (condense mode) the whitespace is adjacent to a comment, or:
11771 // - (condense mode) the whitespace is between two elements AND contains newline
11772 if (!prev ||
11773 !next ||
11774 (shouldCondense &&
11775 (prev.type === 3 /* COMMENT */ ||
11776 next.type === 3 /* COMMENT */ ||
11777 (prev.type === 1 /* ELEMENT */ &&
11778 next.type === 1 /* ELEMENT */ &&
11779 /[\r\n]/.test(node.content))))) {
11780 removedWhitespace = true;
11781 nodes[i] = null;
11782 }
11783 else {
11784 // Otherwise, the whitespace is condensed into a single space
11785 node.content = ' ';
11786 }
11787 }
11788 else if (shouldCondense) {
11789 // in condense mode, consecutive whitespaces in text are condensed
11790 // down to a single space.
11791 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11792 }
11793 }
11794 // Remove comment nodes if desired by configuration.
11795 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
11796 removedWhitespace = true;
11797 nodes[i] = null;
11798 }
11799 }
11800 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
11801 // remove leading newline per html spec
11802 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
11803 const first = nodes[0];
11804 if (first && first.type === 2 /* TEXT */) {
11805 first.content = first.content.replace(/^\r?\n/, '');
11806 }
11807 }
11808 }
11809 return removedWhitespace ? nodes.filter(Boolean) : nodes;
11810 }
11811 function pushNode(nodes, node) {
11812 if (node.type === 2 /* TEXT */) {
11813 const prev = last(nodes);
11814 // Merge if both this and the previous node are text and those are
11815 // consecutive. This happens for cases like "a < b".
11816 if (prev &&
11817 prev.type === 2 /* TEXT */ &&
11818 prev.loc.end.offset === node.loc.start.offset) {
11819 prev.content += node.content;
11820 prev.loc.end = node.loc.end;
11821 prev.loc.source += node.loc.source;
11822 return;
11823 }
11824 }
11825 nodes.push(node);
11826 }
11827 function parseCDATA(context, ancestors) {
11828 advanceBy(context, 9);
11829 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
11830 if (context.source.length === 0) {
11831 emitError(context, 6 /* EOF_IN_CDATA */);
11832 }
11833 else {
11834 advanceBy(context, 3);
11835 }
11836 return nodes;
11837 }
11838 function parseComment(context) {
11839 const start = getCursor(context);
11840 let content;
11841 // Regular comment.
11842 const match = /--(\!)?>/.exec(context.source);
11843 if (!match) {
11844 content = context.source.slice(4);
11845 advanceBy(context, context.source.length);
11846 emitError(context, 7 /* EOF_IN_COMMENT */);
11847 }
11848 else {
11849 if (match.index <= 3) {
11850 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
11851 }
11852 if (match[1]) {
11853 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
11854 }
11855 content = context.source.slice(4, match.index);
11856 // Advancing with reporting nested comments.
11857 const s = context.source.slice(0, match.index);
11858 let prevIndex = 1, nestedIndex = 0;
11859 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
11860 advanceBy(context, nestedIndex - prevIndex + 1);
11861 if (nestedIndex + 4 < s.length) {
11862 emitError(context, 16 /* NESTED_COMMENT */);
11863 }
11864 prevIndex = nestedIndex + 1;
11865 }
11866 advanceBy(context, match.index + match[0].length - prevIndex + 1);
11867 }
11868 return {
11869 type: 3 /* COMMENT */,
11870 content,
11871 loc: getSelection(context, start)
11872 };
11873 }
11874 function parseBogusComment(context) {
11875 const start = getCursor(context);
11876 const contentStart = context.source[1] === '?' ? 1 : 2;
11877 let content;
11878 const closeIndex = context.source.indexOf('>');
11879 if (closeIndex === -1) {
11880 content = context.source.slice(contentStart);
11881 advanceBy(context, context.source.length);
11882 }
11883 else {
11884 content = context.source.slice(contentStart, closeIndex);
11885 advanceBy(context, closeIndex + 1);
11886 }
11887 return {
11888 type: 3 /* COMMENT */,
11889 content,
11890 loc: getSelection(context, start)
11891 };
11892 }
11893 function parseElement(context, ancestors) {
11894 // Start tag.
11895 const wasInPre = context.inPre;
11896 const wasInVPre = context.inVPre;
11897 const parent = last(ancestors);
11898 const element = parseTag(context, 0 /* Start */, parent);
11899 const isPreBoundary = context.inPre && !wasInPre;
11900 const isVPreBoundary = context.inVPre && !wasInVPre;
11901 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
11902 // #4030 self-closing <pre> tag
11903 if (isPreBoundary) {
11904 context.inPre = false;
11905 }
11906 if (isVPreBoundary) {
11907 context.inVPre = false;
11908 }
11909 return element;
11910 }
11911 // Children.
11912 ancestors.push(element);
11913 const mode = context.options.getTextMode(element, parent);
11914 const children = parseChildren(context, mode, ancestors);
11915 ancestors.pop();
11916 element.children = children;
11917 // End tag.
11918 if (startsWithEndTagOpen(context.source, element.tag)) {
11919 parseTag(context, 1 /* End */, parent);
11920 }
11921 else {
11922 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
11923 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
11924 const first = children[0];
11925 if (first && startsWith(first.loc.source, '<!--')) {
11926 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
11927 }
11928 }
11929 }
11930 element.loc = getSelection(context, element.loc.start);
11931 if (isPreBoundary) {
11932 context.inPre = false;
11933 }
11934 if (isVPreBoundary) {
11935 context.inVPre = false;
11936 }
11937 return element;
11938 }
11939 const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
11940 function parseTag(context, type, parent) {
11941 // Tag open.
11942 const start = getCursor(context);
11943 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
11944 const tag = match[1];
11945 const ns = context.options.getNamespace(tag, parent);
11946 advanceBy(context, match[0].length);
11947 advanceSpaces(context);
11948 // save current state in case we need to re-parse attributes with v-pre
11949 const cursor = getCursor(context);
11950 const currentSource = context.source;
11951 // check <pre> tag
11952 if (context.options.isPreTag(tag)) {
11953 context.inPre = true;
11954 }
11955 // Attributes.
11956 let props = parseAttributes(context, type);
11957 // check v-pre
11958 if (type === 0 /* Start */ &&
11959 !context.inVPre &&
11960 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
11961 context.inVPre = true;
11962 // reset context
11963 extend(context, cursor);
11964 context.source = currentSource;
11965 // re-parse attrs and filter out v-pre itself
11966 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
11967 }
11968 // Tag close.
11969 let isSelfClosing = false;
11970 if (context.source.length === 0) {
11971 emitError(context, 9 /* EOF_IN_TAG */);
11972 }
11973 else {
11974 isSelfClosing = startsWith(context.source, '/>');
11975 if (type === 1 /* End */ && isSelfClosing) {
11976 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
11977 }
11978 advanceBy(context, isSelfClosing ? 2 : 1);
11979 }
11980 if (type === 1 /* End */) {
11981 return;
11982 }
11983 let tagType = 0 /* ELEMENT */;
11984 if (!context.inVPre) {
11985 if (tag === 'slot') {
11986 tagType = 2 /* SLOT */;
11987 }
11988 else if (tag === 'template') {
11989 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
11990 tagType = 3 /* TEMPLATE */;
11991 }
11992 }
11993 else if (isComponent(tag, props, context)) {
11994 tagType = 1 /* COMPONENT */;
11995 }
11996 }
11997 return {
11998 type: 1 /* ELEMENT */,
11999 ns,
12000 tag,
12001 tagType,
12002 props,
12003 isSelfClosing,
12004 children: [],
12005 loc: getSelection(context, start),
12006 codegenNode: undefined // to be created during transform phase
12007 };
12008 }
12009 function isComponent(tag, props, context) {
12010 const options = context.options;
12011 if (options.isCustomElement(tag)) {
12012 return false;
12013 }
12014 if (tag === 'component' ||
12015 /^[A-Z]/.test(tag) ||
12016 isCoreComponent(tag) ||
12017 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
12018 (options.isNativeTag && !options.isNativeTag(tag))) {
12019 return true;
12020 }
12021 // at this point the tag should be a native tag, but check for potential "is"
12022 // casting
12023 for (let i = 0; i < props.length; i++) {
12024 const p = props[i];
12025 if (p.type === 6 /* ATTRIBUTE */) {
12026 if (p.name === 'is' && p.value) {
12027 if (p.value.content.startsWith('vue:')) {
12028 return true;
12029 }
12030 }
12031 }
12032 else {
12033 // directive
12034 // v-is (TODO Deprecate)
12035 if (p.name === 'is') {
12036 return true;
12037 }
12038 else if (
12039 // :is on plain element - only treat as component in compat mode
12040 p.name === 'bind' &&
12041 isStaticArgOf(p.arg, 'is') &&
12042 false &&
12043 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
12044 return true;
12045 }
12046 }
12047 }
12048 }
12049 function parseAttributes(context, type) {
12050 const props = [];
12051 const attributeNames = new Set();
12052 while (context.source.length > 0 &&
12053 !startsWith(context.source, '>') &&
12054 !startsWith(context.source, '/>')) {
12055 if (startsWith(context.source, '/')) {
12056 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
12057 advanceBy(context, 1);
12058 advanceSpaces(context);
12059 continue;
12060 }
12061 if (type === 1 /* End */) {
12062 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
12063 }
12064 const attr = parseAttribute(context, attributeNames);
12065 // Trim whitespace between class
12066 // https://github.com/vuejs/core/issues/4251
12067 if (attr.type === 6 /* ATTRIBUTE */ &&
12068 attr.value &&
12069 attr.name === 'class') {
12070 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
12071 }
12072 if (type === 0 /* Start */) {
12073 props.push(attr);
12074 }
12075 if (/^[^\t\r\n\f />]/.test(context.source)) {
12076 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
12077 }
12078 advanceSpaces(context);
12079 }
12080 return props;
12081 }
12082 function parseAttribute(context, nameSet) {
12083 // Name.
12084 const start = getCursor(context);
12085 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
12086 const name = match[0];
12087 if (nameSet.has(name)) {
12088 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
12089 }
12090 nameSet.add(name);
12091 if (name[0] === '=') {
12092 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
12093 }
12094 {
12095 const pattern = /["'<]/g;
12096 let m;
12097 while ((m = pattern.exec(name))) {
12098 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
12099 }
12100 }
12101 advanceBy(context, name.length);
12102 // Value
12103 let value = undefined;
12104 if (/^[\t\r\n\f ]*=/.test(context.source)) {
12105 advanceSpaces(context);
12106 advanceBy(context, 1);
12107 advanceSpaces(context);
12108 value = parseAttributeValue(context);
12109 if (!value) {
12110 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
12111 }
12112 }
12113 const loc = getSelection(context, start);
12114 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
12115 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
12116 let isPropShorthand = startsWith(name, '.');
12117 let dirName = match[1] ||
12118 (isPropShorthand || startsWith(name, ':')
12119 ? 'bind'
12120 : startsWith(name, '@')
12121 ? 'on'
12122 : 'slot');
12123 let arg;
12124 if (match[2]) {
12125 const isSlot = dirName === 'slot';
12126 const startOffset = name.lastIndexOf(match[2]);
12127 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
12128 let content = match[2];
12129 let isStatic = true;
12130 if (content.startsWith('[')) {
12131 isStatic = false;
12132 if (!content.endsWith(']')) {
12133 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
12134 content = content.slice(1);
12135 }
12136 else {
12137 content = content.slice(1, content.length - 1);
12138 }
12139 }
12140 else if (isSlot) {
12141 // #1241 special case for v-slot: vuetify relies extensively on slot
12142 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
12143 // supports such usage so we are keeping it consistent with 2.x.
12144 content += match[3] || '';
12145 }
12146 arg = {
12147 type: 4 /* SIMPLE_EXPRESSION */,
12148 content,
12149 isStatic,
12150 constType: isStatic
12151 ? 3 /* CAN_STRINGIFY */
12152 : 0 /* NOT_CONSTANT */,
12153 loc
12154 };
12155 }
12156 if (value && value.isQuoted) {
12157 const valueLoc = value.loc;
12158 valueLoc.start.offset++;
12159 valueLoc.start.column++;
12160 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
12161 valueLoc.source = valueLoc.source.slice(1, -1);
12162 }
12163 const modifiers = match[3] ? match[3].slice(1).split('.') : [];
12164 if (isPropShorthand)
12165 modifiers.push('prop');
12166 return {
12167 type: 7 /* DIRECTIVE */,
12168 name: dirName,
12169 exp: value && {
12170 type: 4 /* SIMPLE_EXPRESSION */,
12171 content: value.content,
12172 isStatic: false,
12173 // Treat as non-constant by default. This can be potentially set to
12174 // other values by `transformExpression` to make it eligible for hoisting.
12175 constType: 0 /* NOT_CONSTANT */,
12176 loc: value.loc
12177 },
12178 arg,
12179 modifiers,
12180 loc
12181 };
12182 }
12183 // missing directive name or illegal directive name
12184 if (!context.inVPre && startsWith(name, 'v-')) {
12185 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);
12186 }
12187 return {
12188 type: 6 /* ATTRIBUTE */,
12189 name,
12190 value: value && {
12191 type: 2 /* TEXT */,
12192 content: value.content,
12193 loc: value.loc
12194 },
12195 loc
12196 };
12197 }
12198 function parseAttributeValue(context) {
12199 const start = getCursor(context);
12200 let content;
12201 const quote = context.source[0];
12202 const isQuoted = quote === `"` || quote === `'`;
12203 if (isQuoted) {
12204 // Quoted value.
12205 advanceBy(context, 1);
12206 const endIndex = context.source.indexOf(quote);
12207 if (endIndex === -1) {
12208 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
12209 }
12210 else {
12211 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
12212 advanceBy(context, 1);
12213 }
12214 }
12215 else {
12216 // Unquoted
12217 const match = /^[^\t\r\n\f >]+/.exec(context.source);
12218 if (!match) {
12219 return undefined;
12220 }
12221 const unexpectedChars = /["'<=`]/g;
12222 let m;
12223 while ((m = unexpectedChars.exec(match[0]))) {
12224 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
12225 }
12226 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
12227 }
12228 return { content, isQuoted, loc: getSelection(context, start) };
12229 }
12230 function parseInterpolation(context, mode) {
12231 const [open, close] = context.options.delimiters;
12232 const closeIndex = context.source.indexOf(close, open.length);
12233 if (closeIndex === -1) {
12234 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
12235 return undefined;
12236 }
12237 const start = getCursor(context);
12238 advanceBy(context, open.length);
12239 const innerStart = getCursor(context);
12240 const innerEnd = getCursor(context);
12241 const rawContentLength = closeIndex - open.length;
12242 const rawContent = context.source.slice(0, rawContentLength);
12243 const preTrimContent = parseTextData(context, rawContentLength, mode);
12244 const content = preTrimContent.trim();
12245 const startOffset = preTrimContent.indexOf(content);
12246 if (startOffset > 0) {
12247 advancePositionWithMutation(innerStart, rawContent, startOffset);
12248 }
12249 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
12250 advancePositionWithMutation(innerEnd, rawContent, endOffset);
12251 advanceBy(context, close.length);
12252 return {
12253 type: 5 /* INTERPOLATION */,
12254 content: {
12255 type: 4 /* SIMPLE_EXPRESSION */,
12256 isStatic: false,
12257 // Set `isConstant` to false by default and will decide in transformExpression
12258 constType: 0 /* NOT_CONSTANT */,
12259 content,
12260 loc: getSelection(context, innerStart, innerEnd)
12261 },
12262 loc: getSelection(context, start)
12263 };
12264 }
12265 function parseText(context, mode) {
12266 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
12267 let endIndex = context.source.length;
12268 for (let i = 0; i < endTokens.length; i++) {
12269 const index = context.source.indexOf(endTokens[i], 1);
12270 if (index !== -1 && endIndex > index) {
12271 endIndex = index;
12272 }
12273 }
12274 const start = getCursor(context);
12275 const content = parseTextData(context, endIndex, mode);
12276 return {
12277 type: 2 /* TEXT */,
12278 content,
12279 loc: getSelection(context, start)
12280 };
12281 }
12282 /**
12283 * Get text data with a given length from the current location.
12284 * This translates HTML entities in the text data.
12285 */
12286 function parseTextData(context, length, mode) {
12287 const rawText = context.source.slice(0, length);
12288 advanceBy(context, length);
12289 if (mode === 2 /* RAWTEXT */ ||
12290 mode === 3 /* CDATA */ ||
12291 !rawText.includes('&')) {
12292 return rawText;
12293 }
12294 else {
12295 // DATA or RCDATA containing "&"". Entity decoding required.
12296 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
12297 }
12298 }
12299 function getCursor(context) {
12300 const { column, line, offset } = context;
12301 return { column, line, offset };
12302 }
12303 function getSelection(context, start, end) {
12304 end = end || getCursor(context);
12305 return {
12306 start,
12307 end,
12308 source: context.originalSource.slice(start.offset, end.offset)
12309 };
12310 }
12311 function last(xs) {
12312 return xs[xs.length - 1];
12313 }
12314 function startsWith(source, searchString) {
12315 return source.startsWith(searchString);
12316 }
12317 function advanceBy(context, numberOfCharacters) {
12318 const { source } = context;
12319 advancePositionWithMutation(context, source, numberOfCharacters);
12320 context.source = source.slice(numberOfCharacters);
12321 }
12322 function advanceSpaces(context) {
12323 const match = /^[\t\r\n\f ]+/.exec(context.source);
12324 if (match) {
12325 advanceBy(context, match[0].length);
12326 }
12327 }
12328 function getNewPosition(context, start, numberOfCharacters) {
12329 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
12330 }
12331 function emitError(context, code, offset, loc = getCursor(context)) {
12332 if (offset) {
12333 loc.offset += offset;
12334 loc.column += offset;
12335 }
12336 context.options.onError(createCompilerError(code, {
12337 start: loc,
12338 end: loc,
12339 source: ''
12340 }));
12341 }
12342 function isEnd(context, mode, ancestors) {
12343 const s = context.source;
12344 switch (mode) {
12345 case 0 /* DATA */:
12346 if (startsWith(s, '</')) {
12347 // TODO: probably bad performance
12348 for (let i = ancestors.length - 1; i >= 0; --i) {
12349 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
12350 return true;
12351 }
12352 }
12353 }
12354 break;
12355 case 1 /* RCDATA */:
12356 case 2 /* RAWTEXT */: {
12357 const parent = last(ancestors);
12358 if (parent && startsWithEndTagOpen(s, parent.tag)) {
12359 return true;
12360 }
12361 break;
12362 }
12363 case 3 /* CDATA */:
12364 if (startsWith(s, ']]>')) {
12365 return true;
12366 }
12367 break;
12368 }
12369 return !s;
12370 }
12371 function startsWithEndTagOpen(source, tag) {
12372 return (startsWith(source, '</') &&
12373 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
12374 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
12375 }
12376
12377 function hoistStatic(root, context) {
12378 walk(root, context,
12379 // Root node is unfortunately non-hoistable due to potential parent
12380 // fallthrough attributes.
12381 isSingleElementRoot(root, root.children[0]));
12382 }
12383 function isSingleElementRoot(root, child) {
12384 const { children } = root;
12385 return (children.length === 1 &&
12386 child.type === 1 /* ELEMENT */ &&
12387 !isSlotOutlet(child));
12388 }
12389 function walk(node, context, doNotHoistNode = false) {
12390 const { children } = node;
12391 const originalCount = children.length;
12392 let hoistedCount = 0;
12393 for (let i = 0; i < children.length; i++) {
12394 const child = children[i];
12395 // only plain elements & text calls are eligible for hoisting.
12396 if (child.type === 1 /* ELEMENT */ &&
12397 child.tagType === 0 /* ELEMENT */) {
12398 const constantType = doNotHoistNode
12399 ? 0 /* NOT_CONSTANT */
12400 : getConstantType(child, context);
12401 if (constantType > 0 /* NOT_CONSTANT */) {
12402 if (constantType >= 2 /* CAN_HOIST */) {
12403 child.codegenNode.patchFlag =
12404 -1 /* HOISTED */ + (` /* HOISTED */` );
12405 child.codegenNode = context.hoist(child.codegenNode);
12406 hoistedCount++;
12407 continue;
12408 }
12409 }
12410 else {
12411 // node may contain dynamic children, but its props may be eligible for
12412 // hoisting.
12413 const codegenNode = child.codegenNode;
12414 if (codegenNode.type === 13 /* VNODE_CALL */) {
12415 const flag = getPatchFlag(codegenNode);
12416 if ((!flag ||
12417 flag === 512 /* NEED_PATCH */ ||
12418 flag === 1 /* TEXT */) &&
12419 getGeneratedPropsConstantType(child, context) >=
12420 2 /* CAN_HOIST */) {
12421 const props = getNodeProps(child);
12422 if (props) {
12423 codegenNode.props = context.hoist(props);
12424 }
12425 }
12426 if (codegenNode.dynamicProps) {
12427 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
12428 }
12429 }
12430 }
12431 }
12432 else if (child.type === 12 /* TEXT_CALL */ &&
12433 getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
12434 child.codegenNode = context.hoist(child.codegenNode);
12435 hoistedCount++;
12436 }
12437 // walk further
12438 if (child.type === 1 /* ELEMENT */) {
12439 const isComponent = child.tagType === 1 /* COMPONENT */;
12440 if (isComponent) {
12441 context.scopes.vSlot++;
12442 }
12443 walk(child, context);
12444 if (isComponent) {
12445 context.scopes.vSlot--;
12446 }
12447 }
12448 else if (child.type === 11 /* FOR */) {
12449 // Do not hoist v-for single child because it has to be a block
12450 walk(child, context, child.children.length === 1);
12451 }
12452 else if (child.type === 9 /* IF */) {
12453 for (let i = 0; i < child.branches.length; i++) {
12454 // Do not hoist v-if single child because it has to be a block
12455 walk(child.branches[i], context, child.branches[i].children.length === 1);
12456 }
12457 }
12458 }
12459 if (hoistedCount && context.transformHoist) {
12460 context.transformHoist(children, context, node);
12461 }
12462 // all children were hoisted - the entire children array is hoistable.
12463 if (hoistedCount &&
12464 hoistedCount === originalCount &&
12465 node.type === 1 /* ELEMENT */ &&
12466 node.tagType === 0 /* ELEMENT */ &&
12467 node.codegenNode &&
12468 node.codegenNode.type === 13 /* VNODE_CALL */ &&
12469 isArray(node.codegenNode.children)) {
12470 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
12471 }
12472 }
12473 function getConstantType(node, context) {
12474 const { constantCache } = context;
12475 switch (node.type) {
12476 case 1 /* ELEMENT */:
12477 if (node.tagType !== 0 /* ELEMENT */) {
12478 return 0 /* NOT_CONSTANT */;
12479 }
12480 const cached = constantCache.get(node);
12481 if (cached !== undefined) {
12482 return cached;
12483 }
12484 const codegenNode = node.codegenNode;
12485 if (codegenNode.type !== 13 /* VNODE_CALL */) {
12486 return 0 /* NOT_CONSTANT */;
12487 }
12488 if (codegenNode.isBlock &&
12489 node.tag !== 'svg' &&
12490 node.tag !== 'foreignObject') {
12491 return 0 /* NOT_CONSTANT */;
12492 }
12493 const flag = getPatchFlag(codegenNode);
12494 if (!flag) {
12495 let returnType = 3 /* CAN_STRINGIFY */;
12496 // Element itself has no patch flag. However we still need to check:
12497 // 1. Even for a node with no patch flag, it is possible for it to contain
12498 // non-hoistable expressions that refers to scope variables, e.g. compiler
12499 // injected keys or cached event handlers. Therefore we need to always
12500 // check the codegenNode's props to be sure.
12501 const generatedPropsType = getGeneratedPropsConstantType(node, context);
12502 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
12503 constantCache.set(node, 0 /* NOT_CONSTANT */);
12504 return 0 /* NOT_CONSTANT */;
12505 }
12506 if (generatedPropsType < returnType) {
12507 returnType = generatedPropsType;
12508 }
12509 // 2. its children.
12510 for (let i = 0; i < node.children.length; i++) {
12511 const childType = getConstantType(node.children[i], context);
12512 if (childType === 0 /* NOT_CONSTANT */) {
12513 constantCache.set(node, 0 /* NOT_CONSTANT */);
12514 return 0 /* NOT_CONSTANT */;
12515 }
12516 if (childType < returnType) {
12517 returnType = childType;
12518 }
12519 }
12520 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
12521 // type, check if any of the props can cause the type to be lowered
12522 // we can skip can_patch because it's guaranteed by the absence of a
12523 // patchFlag.
12524 if (returnType > 1 /* CAN_SKIP_PATCH */) {
12525 for (let i = 0; i < node.props.length; i++) {
12526 const p = node.props[i];
12527 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
12528 const expType = getConstantType(p.exp, context);
12529 if (expType === 0 /* NOT_CONSTANT */) {
12530 constantCache.set(node, 0 /* NOT_CONSTANT */);
12531 return 0 /* NOT_CONSTANT */;
12532 }
12533 if (expType < returnType) {
12534 returnType = expType;
12535 }
12536 }
12537 }
12538 }
12539 // only svg/foreignObject could be block here, however if they are
12540 // static then they don't need to be blocks since there will be no
12541 // nested updates.
12542 if (codegenNode.isBlock) {
12543 // except set custom directives.
12544 for (let i = 0; i < node.props.length; i++) {
12545 const p = node.props[i];
12546 if (p.type === 7 /* DIRECTIVE */) {
12547 constantCache.set(node, 0 /* NOT_CONSTANT */);
12548 return 0 /* NOT_CONSTANT */;
12549 }
12550 }
12551 context.removeHelper(OPEN_BLOCK);
12552 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
12553 codegenNode.isBlock = false;
12554 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
12555 }
12556 constantCache.set(node, returnType);
12557 return returnType;
12558 }
12559 else {
12560 constantCache.set(node, 0 /* NOT_CONSTANT */);
12561 return 0 /* NOT_CONSTANT */;
12562 }
12563 case 2 /* TEXT */:
12564 case 3 /* COMMENT */:
12565 return 3 /* CAN_STRINGIFY */;
12566 case 9 /* IF */:
12567 case 11 /* FOR */:
12568 case 10 /* IF_BRANCH */:
12569 return 0 /* NOT_CONSTANT */;
12570 case 5 /* INTERPOLATION */:
12571 case 12 /* TEXT_CALL */:
12572 return getConstantType(node.content, context);
12573 case 4 /* SIMPLE_EXPRESSION */:
12574 return node.constType;
12575 case 8 /* COMPOUND_EXPRESSION */:
12576 let returnType = 3 /* CAN_STRINGIFY */;
12577 for (let i = 0; i < node.children.length; i++) {
12578 const child = node.children[i];
12579 if (isString(child) || isSymbol(child)) {
12580 continue;
12581 }
12582 const childType = getConstantType(child, context);
12583 if (childType === 0 /* NOT_CONSTANT */) {
12584 return 0 /* NOT_CONSTANT */;
12585 }
12586 else if (childType < returnType) {
12587 returnType = childType;
12588 }
12589 }
12590 return returnType;
12591 default:
12592 return 0 /* NOT_CONSTANT */;
12593 }
12594 }
12595 const allowHoistedHelperSet = new Set([
12596 NORMALIZE_CLASS,
12597 NORMALIZE_STYLE,
12598 NORMALIZE_PROPS,
12599 GUARD_REACTIVE_PROPS
12600 ]);
12601 function getConstantTypeOfHelperCall(value, context) {
12602 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
12603 !isString(value.callee) &&
12604 allowHoistedHelperSet.has(value.callee)) {
12605 const arg = value.arguments[0];
12606 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
12607 return getConstantType(arg, context);
12608 }
12609 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
12610 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
12611 return getConstantTypeOfHelperCall(arg, context);
12612 }
12613 }
12614 return 0 /* NOT_CONSTANT */;
12615 }
12616 function getGeneratedPropsConstantType(node, context) {
12617 let returnType = 3 /* CAN_STRINGIFY */;
12618 const props = getNodeProps(node);
12619 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
12620 const { properties } = props;
12621 for (let i = 0; i < properties.length; i++) {
12622 const { key, value } = properties[i];
12623 const keyType = getConstantType(key, context);
12624 if (keyType === 0 /* NOT_CONSTANT */) {
12625 return keyType;
12626 }
12627 if (keyType < returnType) {
12628 returnType = keyType;
12629 }
12630 let valueType;
12631 if (value.type === 4 /* SIMPLE_EXPRESSION */) {
12632 valueType = getConstantType(value, context);
12633 }
12634 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12635 // some helper calls can be hoisted,
12636 // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12637 // in this case we need to respect the ConstantType of the helper's arguments
12638 valueType = getConstantTypeOfHelperCall(value, context);
12639 }
12640 else {
12641 valueType = 0 /* NOT_CONSTANT */;
12642 }
12643 if (valueType === 0 /* NOT_CONSTANT */) {
12644 return valueType;
12645 }
12646 if (valueType < returnType) {
12647 returnType = valueType;
12648 }
12649 }
12650 }
12651 return returnType;
12652 }
12653 function getNodeProps(node) {
12654 const codegenNode = node.codegenNode;
12655 if (codegenNode.type === 13 /* VNODE_CALL */) {
12656 return codegenNode.props;
12657 }
12658 }
12659 function getPatchFlag(node) {
12660 const flag = node.patchFlag;
12661 return flag ? parseInt(flag, 10) : undefined;
12662 }
12663
12664 function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
12665 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
12666 const context = {
12667 // options
12668 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
12669 prefixIdentifiers,
12670 hoistStatic,
12671 cacheHandlers,
12672 nodeTransforms,
12673 directiveTransforms,
12674 transformHoist,
12675 isBuiltInComponent,
12676 isCustomElement,
12677 expressionPlugins,
12678 scopeId,
12679 slotted,
12680 ssr,
12681 inSSR,
12682 ssrCssVars,
12683 bindingMetadata,
12684 inline,
12685 isTS,
12686 onError,
12687 onWarn,
12688 compatConfig,
12689 // state
12690 root,
12691 helpers: new Map(),
12692 components: new Set(),
12693 directives: new Set(),
12694 hoists: [],
12695 imports: [],
12696 constantCache: new Map(),
12697 temps: 0,
12698 cached: 0,
12699 identifiers: Object.create(null),
12700 scopes: {
12701 vFor: 0,
12702 vSlot: 0,
12703 vPre: 0,
12704 vOnce: 0
12705 },
12706 parent: null,
12707 currentNode: root,
12708 childIndex: 0,
12709 inVOnce: false,
12710 // methods
12711 helper(name) {
12712 const count = context.helpers.get(name) || 0;
12713 context.helpers.set(name, count + 1);
12714 return name;
12715 },
12716 removeHelper(name) {
12717 const count = context.helpers.get(name);
12718 if (count) {
12719 const currentCount = count - 1;
12720 if (!currentCount) {
12721 context.helpers.delete(name);
12722 }
12723 else {
12724 context.helpers.set(name, currentCount);
12725 }
12726 }
12727 },
12728 helperString(name) {
12729 return `_${helperNameMap[context.helper(name)]}`;
12730 },
12731 replaceNode(node) {
12732 /* istanbul ignore if */
12733 {
12734 if (!context.currentNode) {
12735 throw new Error(`Node being replaced is already removed.`);
12736 }
12737 if (!context.parent) {
12738 throw new Error(`Cannot replace root node.`);
12739 }
12740 }
12741 context.parent.children[context.childIndex] = context.currentNode = node;
12742 },
12743 removeNode(node) {
12744 if (!context.parent) {
12745 throw new Error(`Cannot remove root node.`);
12746 }
12747 const list = context.parent.children;
12748 const removalIndex = node
12749 ? list.indexOf(node)
12750 : context.currentNode
12751 ? context.childIndex
12752 : -1;
12753 /* istanbul ignore if */
12754 if (removalIndex < 0) {
12755 throw new Error(`node being removed is not a child of current parent`);
12756 }
12757 if (!node || node === context.currentNode) {
12758 // current node removed
12759 context.currentNode = null;
12760 context.onNodeRemoved();
12761 }
12762 else {
12763 // sibling node removed
12764 if (context.childIndex > removalIndex) {
12765 context.childIndex--;
12766 context.onNodeRemoved();
12767 }
12768 }
12769 context.parent.children.splice(removalIndex, 1);
12770 },
12771 onNodeRemoved: () => { },
12772 addIdentifiers(exp) {
12773 },
12774 removeIdentifiers(exp) {
12775 },
12776 hoist(exp) {
12777 if (isString(exp))
12778 exp = createSimpleExpression(exp);
12779 context.hoists.push(exp);
12780 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
12781 identifier.hoisted = exp;
12782 return identifier;
12783 },
12784 cache(exp, isVNode = false) {
12785 return createCacheExpression(context.cached++, exp, isVNode);
12786 }
12787 };
12788 return context;
12789 }
12790 function transform(root, options) {
12791 const context = createTransformContext(root, options);
12792 traverseNode(root, context);
12793 if (options.hoistStatic) {
12794 hoistStatic(root, context);
12795 }
12796 if (!options.ssr) {
12797 createRootCodegen(root, context);
12798 }
12799 // finalize meta information
12800 root.helpers = [...context.helpers.keys()];
12801 root.components = [...context.components];
12802 root.directives = [...context.directives];
12803 root.imports = context.imports;
12804 root.hoists = context.hoists;
12805 root.temps = context.temps;
12806 root.cached = context.cached;
12807 }
12808 function createRootCodegen(root, context) {
12809 const { helper } = context;
12810 const { children } = root;
12811 if (children.length === 1) {
12812 const child = children[0];
12813 // if the single child is an element, turn it into a block.
12814 if (isSingleElementRoot(root, child) && child.codegenNode) {
12815 // single element root is never hoisted so codegenNode will never be
12816 // SimpleExpressionNode
12817 const codegenNode = child.codegenNode;
12818 if (codegenNode.type === 13 /* VNODE_CALL */) {
12819 makeBlock(codegenNode, context);
12820 }
12821 root.codegenNode = codegenNode;
12822 }
12823 else {
12824 // - single <slot/>, IfNode, ForNode: already blocks.
12825 // - single text node: always patched.
12826 // root codegen falls through via genNode()
12827 root.codegenNode = child;
12828 }
12829 }
12830 else if (children.length > 1) {
12831 // root has multiple nodes - return a fragment block.
12832 let patchFlag = 64 /* STABLE_FRAGMENT */;
12833 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
12834 // check if the fragment actually contains a single valid child with
12835 // the rest being comments
12836 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
12837 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
12838 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
12839 }
12840 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);
12841 }
12842 else ;
12843 }
12844 function traverseChildren(parent, context) {
12845 let i = 0;
12846 const nodeRemoved = () => {
12847 i--;
12848 };
12849 for (; i < parent.children.length; i++) {
12850 const child = parent.children[i];
12851 if (isString(child))
12852 continue;
12853 context.parent = parent;
12854 context.childIndex = i;
12855 context.onNodeRemoved = nodeRemoved;
12856 traverseNode(child, context);
12857 }
12858 }
12859 function traverseNode(node, context) {
12860 context.currentNode = node;
12861 // apply transform plugins
12862 const { nodeTransforms } = context;
12863 const exitFns = [];
12864 for (let i = 0; i < nodeTransforms.length; i++) {
12865 const onExit = nodeTransforms[i](node, context);
12866 if (onExit) {
12867 if (isArray(onExit)) {
12868 exitFns.push(...onExit);
12869 }
12870 else {
12871 exitFns.push(onExit);
12872 }
12873 }
12874 if (!context.currentNode) {
12875 // node was removed
12876 return;
12877 }
12878 else {
12879 // node may have been replaced
12880 node = context.currentNode;
12881 }
12882 }
12883 switch (node.type) {
12884 case 3 /* COMMENT */:
12885 if (!context.ssr) {
12886 // inject import for the Comment symbol, which is needed for creating
12887 // comment nodes with `createVNode`
12888 context.helper(CREATE_COMMENT);
12889 }
12890 break;
12891 case 5 /* INTERPOLATION */:
12892 // no need to traverse, but we need to inject toString helper
12893 if (!context.ssr) {
12894 context.helper(TO_DISPLAY_STRING);
12895 }
12896 break;
12897 // for container types, further traverse downwards
12898 case 9 /* IF */:
12899 for (let i = 0; i < node.branches.length; i++) {
12900 traverseNode(node.branches[i], context);
12901 }
12902 break;
12903 case 10 /* IF_BRANCH */:
12904 case 11 /* FOR */:
12905 case 1 /* ELEMENT */:
12906 case 0 /* ROOT */:
12907 traverseChildren(node, context);
12908 break;
12909 }
12910 // exit transforms
12911 context.currentNode = node;
12912 let i = exitFns.length;
12913 while (i--) {
12914 exitFns[i]();
12915 }
12916 }
12917 function createStructuralDirectiveTransform(name, fn) {
12918 const matches = isString(name)
12919 ? (n) => n === name
12920 : (n) => name.test(n);
12921 return (node, context) => {
12922 if (node.type === 1 /* ELEMENT */) {
12923 const { props } = node;
12924 // structural directive transforms are not concerned with slots
12925 // as they are handled separately in vSlot.ts
12926 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
12927 return;
12928 }
12929 const exitFns = [];
12930 for (let i = 0; i < props.length; i++) {
12931 const prop = props[i];
12932 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
12933 // structural directives are removed to avoid infinite recursion
12934 // also we remove them *before* applying so that it can further
12935 // traverse itself in case it moves the node around
12936 props.splice(i, 1);
12937 i--;
12938 const onExit = fn(node, prop, context);
12939 if (onExit)
12940 exitFns.push(onExit);
12941 }
12942 }
12943 return exitFns;
12944 }
12945 };
12946 }
12947
12948 const PURE_ANNOTATION = `/*#__PURE__*/`;
12949 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
12950 function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {
12951 const context = {
12952 mode,
12953 prefixIdentifiers,
12954 sourceMap,
12955 filename,
12956 scopeId,
12957 optimizeImports,
12958 runtimeGlobalName,
12959 runtimeModuleName,
12960 ssrRuntimeModuleName,
12961 ssr,
12962 isTS,
12963 inSSR,
12964 source: ast.loc.source,
12965 code: ``,
12966 column: 1,
12967 line: 1,
12968 offset: 0,
12969 indentLevel: 0,
12970 pure: false,
12971 map: undefined,
12972 helper(key) {
12973 return `_${helperNameMap[key]}`;
12974 },
12975 push(code, node) {
12976 context.code += code;
12977 },
12978 indent() {
12979 newline(++context.indentLevel);
12980 },
12981 deindent(withoutNewLine = false) {
12982 if (withoutNewLine) {
12983 --context.indentLevel;
12984 }
12985 else {
12986 newline(--context.indentLevel);
12987 }
12988 },
12989 newline() {
12990 newline(context.indentLevel);
12991 }
12992 };
12993 function newline(n) {
12994 context.push('\n' + ` `.repeat(n));
12995 }
12996 return context;
12997 }
12998 function generate(ast, options = {}) {
12999 const context = createCodegenContext(ast, options);
13000 if (options.onContextCreated)
13001 options.onContextCreated(context);
13002 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
13003 const hasHelpers = ast.helpers.length > 0;
13004 const useWithBlock = !prefixIdentifiers && mode !== 'module';
13005 // preambles
13006 // in setup() inline mode, the preamble is generated in a sub context
13007 // and returned separately.
13008 const preambleContext = context;
13009 {
13010 genFunctionPreamble(ast, preambleContext);
13011 }
13012 // enter render function
13013 const functionName = ssr ? `ssrRender` : `render`;
13014 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
13015 const signature = args.join(', ');
13016 {
13017 push(`function ${functionName}(${signature}) {`);
13018 }
13019 indent();
13020 if (useWithBlock) {
13021 push(`with (_ctx) {`);
13022 indent();
13023 // function mode const declarations should be inside with block
13024 // also they should be renamed to avoid collision with user properties
13025 if (hasHelpers) {
13026 push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`);
13027 push(`\n`);
13028 newline();
13029 }
13030 }
13031 // generate asset resolution statements
13032 if (ast.components.length) {
13033 genAssets(ast.components, 'component', context);
13034 if (ast.directives.length || ast.temps > 0) {
13035 newline();
13036 }
13037 }
13038 if (ast.directives.length) {
13039 genAssets(ast.directives, 'directive', context);
13040 if (ast.temps > 0) {
13041 newline();
13042 }
13043 }
13044 if (ast.temps > 0) {
13045 push(`let `);
13046 for (let i = 0; i < ast.temps; i++) {
13047 push(`${i > 0 ? `, ` : ``}_temp${i}`);
13048 }
13049 }
13050 if (ast.components.length || ast.directives.length || ast.temps) {
13051 push(`\n`);
13052 newline();
13053 }
13054 // generate the VNode tree expression
13055 if (!ssr) {
13056 push(`return `);
13057 }
13058 if (ast.codegenNode) {
13059 genNode(ast.codegenNode, context);
13060 }
13061 else {
13062 push(`null`);
13063 }
13064 if (useWithBlock) {
13065 deindent();
13066 push(`}`);
13067 }
13068 deindent();
13069 push(`}`);
13070 return {
13071 ast,
13072 code: context.code,
13073 preamble: ``,
13074 // SourceMapGenerator does have toJSON() method but it's not in the types
13075 map: context.map ? context.map.toJSON() : undefined
13076 };
13077 }
13078 function genFunctionPreamble(ast, context) {
13079 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
13080 const VueBinding = runtimeGlobalName;
13081 // Generate const declaration for helpers
13082 // In prefix mode, we place the const declaration at top so it's done
13083 // only once; But if we not prefixing, we place the declaration inside the
13084 // with block so it doesn't incur the `in` check cost for every helper access.
13085 if (ast.helpers.length > 0) {
13086 {
13087 // "with" mode.
13088 // save Vue in a separate variable to avoid collision
13089 push(`const _Vue = ${VueBinding}\n`);
13090 // in "with" mode, helpers are declared inside the with block to avoid
13091 // has check cost, but hoists are lifted out of the function - we need
13092 // to provide the helper here.
13093 if (ast.hoists.length) {
13094 const staticHelpers = [
13095 CREATE_VNODE,
13096 CREATE_ELEMENT_VNODE,
13097 CREATE_COMMENT,
13098 CREATE_TEXT,
13099 CREATE_STATIC
13100 ]
13101 .filter(helper => ast.helpers.includes(helper))
13102 .map(aliasHelper)
13103 .join(', ');
13104 push(`const { ${staticHelpers} } = _Vue\n`);
13105 }
13106 }
13107 }
13108 genHoists(ast.hoists, context);
13109 newline();
13110 push(`return `);
13111 }
13112 function genAssets(assets, type, { helper, push, newline, isTS }) {
13113 const resolver = helper(type === 'component'
13114 ? RESOLVE_COMPONENT
13115 : RESOLVE_DIRECTIVE);
13116 for (let i = 0; i < assets.length; i++) {
13117 let id = assets[i];
13118 // potential component implicit self-reference inferred from SFC filename
13119 const maybeSelfReference = id.endsWith('__self');
13120 if (maybeSelfReference) {
13121 id = id.slice(0, -6);
13122 }
13123 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
13124 if (i < assets.length - 1) {
13125 newline();
13126 }
13127 }
13128 }
13129 function genHoists(hoists, context) {
13130 if (!hoists.length) {
13131 return;
13132 }
13133 context.pure = true;
13134 const { push, newline, helper, scopeId, mode } = context;
13135 newline();
13136 for (let i = 0; i < hoists.length; i++) {
13137 const exp = hoists[i];
13138 if (exp) {
13139 push(`const _hoisted_${i + 1} = ${``}`);
13140 genNode(exp, context);
13141 newline();
13142 }
13143 }
13144 context.pure = false;
13145 }
13146 function isText$1(n) {
13147 return (isString(n) ||
13148 n.type === 4 /* SIMPLE_EXPRESSION */ ||
13149 n.type === 2 /* TEXT */ ||
13150 n.type === 5 /* INTERPOLATION */ ||
13151 n.type === 8 /* COMPOUND_EXPRESSION */);
13152 }
13153 function genNodeListAsArray(nodes, context) {
13154 const multilines = nodes.length > 3 ||
13155 (nodes.some(n => isArray(n) || !isText$1(n)));
13156 context.push(`[`);
13157 multilines && context.indent();
13158 genNodeList(nodes, context, multilines);
13159 multilines && context.deindent();
13160 context.push(`]`);
13161 }
13162 function genNodeList(nodes, context, multilines = false, comma = true) {
13163 const { push, newline } = context;
13164 for (let i = 0; i < nodes.length; i++) {
13165 const node = nodes[i];
13166 if (isString(node)) {
13167 push(node);
13168 }
13169 else if (isArray(node)) {
13170 genNodeListAsArray(node, context);
13171 }
13172 else {
13173 genNode(node, context);
13174 }
13175 if (i < nodes.length - 1) {
13176 if (multilines) {
13177 comma && push(',');
13178 newline();
13179 }
13180 else {
13181 comma && push(', ');
13182 }
13183 }
13184 }
13185 }
13186 function genNode(node, context) {
13187 if (isString(node)) {
13188 context.push(node);
13189 return;
13190 }
13191 if (isSymbol(node)) {
13192 context.push(context.helper(node));
13193 return;
13194 }
13195 switch (node.type) {
13196 case 1 /* ELEMENT */:
13197 case 9 /* IF */:
13198 case 11 /* FOR */:
13199 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
13200 `Apply appropriate transforms first.`);
13201 genNode(node.codegenNode, context);
13202 break;
13203 case 2 /* TEXT */:
13204 genText(node, context);
13205 break;
13206 case 4 /* SIMPLE_EXPRESSION */:
13207 genExpression(node, context);
13208 break;
13209 case 5 /* INTERPOLATION */:
13210 genInterpolation(node, context);
13211 break;
13212 case 12 /* TEXT_CALL */:
13213 genNode(node.codegenNode, context);
13214 break;
13215 case 8 /* COMPOUND_EXPRESSION */:
13216 genCompoundExpression(node, context);
13217 break;
13218 case 3 /* COMMENT */:
13219 genComment(node, context);
13220 break;
13221 case 13 /* VNODE_CALL */:
13222 genVNodeCall(node, context);
13223 break;
13224 case 14 /* JS_CALL_EXPRESSION */:
13225 genCallExpression(node, context);
13226 break;
13227 case 15 /* JS_OBJECT_EXPRESSION */:
13228 genObjectExpression(node, context);
13229 break;
13230 case 17 /* JS_ARRAY_EXPRESSION */:
13231 genArrayExpression(node, context);
13232 break;
13233 case 18 /* JS_FUNCTION_EXPRESSION */:
13234 genFunctionExpression(node, context);
13235 break;
13236 case 19 /* JS_CONDITIONAL_EXPRESSION */:
13237 genConditionalExpression(node, context);
13238 break;
13239 case 20 /* JS_CACHE_EXPRESSION */:
13240 genCacheExpression(node, context);
13241 break;
13242 case 21 /* JS_BLOCK_STATEMENT */:
13243 genNodeList(node.body, context, true, false);
13244 break;
13245 // SSR only types
13246 case 22 /* JS_TEMPLATE_LITERAL */:
13247 break;
13248 case 23 /* JS_IF_STATEMENT */:
13249 break;
13250 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
13251 break;
13252 case 25 /* JS_SEQUENCE_EXPRESSION */:
13253 break;
13254 case 26 /* JS_RETURN_STATEMENT */:
13255 break;
13256 /* istanbul ignore next */
13257 case 10 /* IF_BRANCH */:
13258 // noop
13259 break;
13260 default:
13261 {
13262 assert(false, `unhandled codegen node type: ${node.type}`);
13263 // make sure we exhaust all possible types
13264 const exhaustiveCheck = node;
13265 return exhaustiveCheck;
13266 }
13267 }
13268 }
13269 function genText(node, context) {
13270 context.push(JSON.stringify(node.content), node);
13271 }
13272 function genExpression(node, context) {
13273 const { content, isStatic } = node;
13274 context.push(isStatic ? JSON.stringify(content) : content, node);
13275 }
13276 function genInterpolation(node, context) {
13277 const { push, helper, pure } = context;
13278 if (pure)
13279 push(PURE_ANNOTATION);
13280 push(`${helper(TO_DISPLAY_STRING)}(`);
13281 genNode(node.content, context);
13282 push(`)`);
13283 }
13284 function genCompoundExpression(node, context) {
13285 for (let i = 0; i < node.children.length; i++) {
13286 const child = node.children[i];
13287 if (isString(child)) {
13288 context.push(child);
13289 }
13290 else {
13291 genNode(child, context);
13292 }
13293 }
13294 }
13295 function genExpressionAsPropertyKey(node, context) {
13296 const { push } = context;
13297 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
13298 push(`[`);
13299 genCompoundExpression(node, context);
13300 push(`]`);
13301 }
13302 else if (node.isStatic) {
13303 // only quote keys if necessary
13304 const text = isSimpleIdentifier(node.content)
13305 ? node.content
13306 : JSON.stringify(node.content);
13307 push(text, node);
13308 }
13309 else {
13310 push(`[${node.content}]`, node);
13311 }
13312 }
13313 function genComment(node, context) {
13314 const { push, helper, pure } = context;
13315 if (pure) {
13316 push(PURE_ANNOTATION);
13317 }
13318 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
13319 }
13320 function genVNodeCall(node, context) {
13321 const { push, helper, pure } = context;
13322 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
13323 if (directives) {
13324 push(helper(WITH_DIRECTIVES) + `(`);
13325 }
13326 if (isBlock) {
13327 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
13328 }
13329 if (pure) {
13330 push(PURE_ANNOTATION);
13331 }
13332 const callHelper = isBlock
13333 ? getVNodeBlockHelper(context.inSSR, isComponent)
13334 : getVNodeHelper(context.inSSR, isComponent);
13335 push(helper(callHelper) + `(`, node);
13336 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
13337 push(`)`);
13338 if (isBlock) {
13339 push(`)`);
13340 }
13341 if (directives) {
13342 push(`, `);
13343 genNode(directives, context);
13344 push(`)`);
13345 }
13346 }
13347 function genNullableArgs(args) {
13348 let i = args.length;
13349 while (i--) {
13350 if (args[i] != null)
13351 break;
13352 }
13353 return args.slice(0, i + 1).map(arg => arg || `null`);
13354 }
13355 // JavaScript
13356 function genCallExpression(node, context) {
13357 const { push, helper, pure } = context;
13358 const callee = isString(node.callee) ? node.callee : helper(node.callee);
13359 if (pure) {
13360 push(PURE_ANNOTATION);
13361 }
13362 push(callee + `(`, node);
13363 genNodeList(node.arguments, context);
13364 push(`)`);
13365 }
13366 function genObjectExpression(node, context) {
13367 const { push, indent, deindent, newline } = context;
13368 const { properties } = node;
13369 if (!properties.length) {
13370 push(`{}`, node);
13371 return;
13372 }
13373 const multilines = properties.length > 1 ||
13374 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
13375 push(multilines ? `{` : `{ `);
13376 multilines && indent();
13377 for (let i = 0; i < properties.length; i++) {
13378 const { key, value } = properties[i];
13379 // key
13380 genExpressionAsPropertyKey(key, context);
13381 push(`: `);
13382 // value
13383 genNode(value, context);
13384 if (i < properties.length - 1) {
13385 // will only reach this if it's multilines
13386 push(`,`);
13387 newline();
13388 }
13389 }
13390 multilines && deindent();
13391 push(multilines ? `}` : ` }`);
13392 }
13393 function genArrayExpression(node, context) {
13394 genNodeListAsArray(node.elements, context);
13395 }
13396 function genFunctionExpression(node, context) {
13397 const { push, indent, deindent } = context;
13398 const { params, returns, body, newline, isSlot } = node;
13399 if (isSlot) {
13400 // wrap slot functions with owner context
13401 push(`_${helperNameMap[WITH_CTX]}(`);
13402 }
13403 push(`(`, node);
13404 if (isArray(params)) {
13405 genNodeList(params, context);
13406 }
13407 else if (params) {
13408 genNode(params, context);
13409 }
13410 push(`) => `);
13411 if (newline || body) {
13412 push(`{`);
13413 indent();
13414 }
13415 if (returns) {
13416 if (newline) {
13417 push(`return `);
13418 }
13419 if (isArray(returns)) {
13420 genNodeListAsArray(returns, context);
13421 }
13422 else {
13423 genNode(returns, context);
13424 }
13425 }
13426 else if (body) {
13427 genNode(body, context);
13428 }
13429 if (newline || body) {
13430 deindent();
13431 push(`}`);
13432 }
13433 if (isSlot) {
13434 push(`)`);
13435 }
13436 }
13437 function genConditionalExpression(node, context) {
13438 const { test, consequent, alternate, newline: needNewline } = node;
13439 const { push, indent, deindent, newline } = context;
13440 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
13441 const needsParens = !isSimpleIdentifier(test.content);
13442 needsParens && push(`(`);
13443 genExpression(test, context);
13444 needsParens && push(`)`);
13445 }
13446 else {
13447 push(`(`);
13448 genNode(test, context);
13449 push(`)`);
13450 }
13451 needNewline && indent();
13452 context.indentLevel++;
13453 needNewline || push(` `);
13454 push(`? `);
13455 genNode(consequent, context);
13456 context.indentLevel--;
13457 needNewline && newline();
13458 needNewline || push(` `);
13459 push(`: `);
13460 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
13461 if (!isNested) {
13462 context.indentLevel++;
13463 }
13464 genNode(alternate, context);
13465 if (!isNested) {
13466 context.indentLevel--;
13467 }
13468 needNewline && deindent(true /* without newline */);
13469 }
13470 function genCacheExpression(node, context) {
13471 const { push, helper, indent, deindent, newline } = context;
13472 push(`_cache[${node.index}] || (`);
13473 if (node.isVNode) {
13474 indent();
13475 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
13476 newline();
13477 }
13478 push(`_cache[${node.index}] = `);
13479 genNode(node.value, context);
13480 if (node.isVNode) {
13481 push(`,`);
13482 newline();
13483 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
13484 newline();
13485 push(`_cache[${node.index}]`);
13486 deindent();
13487 }
13488 push(`)`);
13489 }
13490
13491 // these keywords should not appear inside expressions, but operators like
13492 // typeof, instanceof and in are allowed
13493 const prohibitedKeywordRE = new RegExp('\\b' +
13494 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
13495 'super,throw,while,yield,delete,export,import,return,switch,default,' +
13496 'extends,finally,continue,debugger,function,arguments,typeof,void')
13497 .split(',')
13498 .join('\\b|\\b') +
13499 '\\b');
13500 // strip strings in expressions
13501 const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
13502 /**
13503 * Validate a non-prefixed expression.
13504 * This is only called when using the in-browser runtime compiler since it
13505 * doesn't prefix expressions.
13506 */
13507 function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
13508 const exp = node.content;
13509 // empty expressions are validated per-directive since some directives
13510 // do allow empty expressions.
13511 if (!exp.trim()) {
13512 return;
13513 }
13514 try {
13515 new Function(asRawStatements
13516 ? ` ${exp} `
13517 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
13518 }
13519 catch (e) {
13520 let message = e.message;
13521 const keywordMatch = exp
13522 .replace(stripStringRE, '')
13523 .match(prohibitedKeywordRE);
13524 if (keywordMatch) {
13525 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
13526 }
13527 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
13528 }
13529 }
13530
13531 const transformExpression = (node, context) => {
13532 if (node.type === 5 /* INTERPOLATION */) {
13533 node.content = processExpression(node.content, context);
13534 }
13535 else if (node.type === 1 /* ELEMENT */) {
13536 // handle directives on element
13537 for (let i = 0; i < node.props.length; i++) {
13538 const dir = node.props[i];
13539 // do not process for v-on & v-for since they are special handled
13540 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
13541 const exp = dir.exp;
13542 const arg = dir.arg;
13543 // do not process exp if this is v-on:arg - we need special handling
13544 // for wrapping inline statements.
13545 if (exp &&
13546 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
13547 !(dir.name === 'on' && arg)) {
13548 dir.exp = processExpression(exp, context,
13549 // slot args must be processed as function params
13550 dir.name === 'slot');
13551 }
13552 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
13553 dir.arg = processExpression(arg, context);
13554 }
13555 }
13556 }
13557 }
13558 };
13559 // Important: since this function uses Node.js only dependencies, it should
13560 // always be used with a leading !true check so that it can be
13561 // tree-shaken from the browser build.
13562 function processExpression(node, context,
13563 // some expressions like v-slot props & v-for aliases should be parsed as
13564 // function params
13565 asParams = false,
13566 // v-on handler values may contain multiple statements
13567 asRawStatements = false, localVars = Object.create(context.identifiers)) {
13568 {
13569 {
13570 // simple in-browser validation (same logic in 2.x)
13571 validateBrowserExpression(node, context, asParams, asRawStatements);
13572 }
13573 return node;
13574 }
13575 }
13576
13577 const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
13578 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
13579 // #1587: We need to dynamically increment the key based on the current
13580 // node's sibling nodes, since chained v-if/else branches are
13581 // rendered at the same depth
13582 const siblings = context.parent.children;
13583 let i = siblings.indexOf(ifNode);
13584 let key = 0;
13585 while (i-- >= 0) {
13586 const sibling = siblings[i];
13587 if (sibling && sibling.type === 9 /* IF */) {
13588 key += sibling.branches.length;
13589 }
13590 }
13591 // Exit callback. Complete the codegenNode when all children have been
13592 // transformed.
13593 return () => {
13594 if (isRoot) {
13595 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
13596 }
13597 else {
13598 // attach this branch's codegen node to the v-if root.
13599 const parentCondition = getParentCondition(ifNode.codegenNode);
13600 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
13601 }
13602 };
13603 });
13604 });
13605 // target-agnostic transform used for both Client and SSR
13606 function processIf(node, dir, context, processCodegen) {
13607 if (dir.name !== 'else' &&
13608 (!dir.exp || !dir.exp.content.trim())) {
13609 const loc = dir.exp ? dir.exp.loc : node.loc;
13610 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));
13611 dir.exp = createSimpleExpression(`true`, false, loc);
13612 }
13613 if (dir.exp) {
13614 validateBrowserExpression(dir.exp, context);
13615 }
13616 if (dir.name === 'if') {
13617 const branch = createIfBranch(node, dir);
13618 const ifNode = {
13619 type: 9 /* IF */,
13620 loc: node.loc,
13621 branches: [branch]
13622 };
13623 context.replaceNode(ifNode);
13624 if (processCodegen) {
13625 return processCodegen(ifNode, branch, true);
13626 }
13627 }
13628 else {
13629 // locate the adjacent v-if
13630 const siblings = context.parent.children;
13631 const comments = [];
13632 let i = siblings.indexOf(node);
13633 while (i-- >= -1) {
13634 const sibling = siblings[i];
13635 if (sibling && sibling.type === 3 /* COMMENT */) {
13636 context.removeNode(sibling);
13637 comments.unshift(sibling);
13638 continue;
13639 }
13640 if (sibling &&
13641 sibling.type === 2 /* TEXT */ &&
13642 !sibling.content.trim().length) {
13643 context.removeNode(sibling);
13644 continue;
13645 }
13646 if (sibling && sibling.type === 9 /* IF */) {
13647 // Check if v-else was followed by v-else-if
13648 if (dir.name === 'else-if' &&
13649 sibling.branches[sibling.branches.length - 1].condition === undefined) {
13650 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13651 }
13652 // move the node to the if node's branches
13653 context.removeNode();
13654 const branch = createIfBranch(node, dir);
13655 if (comments.length &&
13656 // #3619 ignore comments if the v-if is direct child of <transition>
13657 !(context.parent &&
13658 context.parent.type === 1 /* ELEMENT */ &&
13659 isBuiltInType(context.parent.tag, 'transition'))) {
13660 branch.children = [...comments, ...branch.children];
13661 }
13662 // check if user is forcing same key on different branches
13663 {
13664 const key = branch.userKey;
13665 if (key) {
13666 sibling.branches.forEach(({ userKey }) => {
13667 if (isSameKey(userKey, key)) {
13668 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
13669 }
13670 });
13671 }
13672 }
13673 sibling.branches.push(branch);
13674 const onExit = processCodegen && processCodegen(sibling, branch, false);
13675 // since the branch was removed, it will not be traversed.
13676 // make sure to traverse here.
13677 traverseNode(branch, context);
13678 // call on exit
13679 if (onExit)
13680 onExit();
13681 // make sure to reset currentNode after traversal to indicate this
13682 // node has been removed.
13683 context.currentNode = null;
13684 }
13685 else {
13686 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13687 }
13688 break;
13689 }
13690 }
13691 }
13692 function createIfBranch(node, dir) {
13693 const isTemplateIf = node.tagType === 3 /* TEMPLATE */;
13694 return {
13695 type: 10 /* IF_BRANCH */,
13696 loc: node.loc,
13697 condition: dir.name === 'else' ? undefined : dir.exp,
13698 children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
13699 userKey: findProp(node, `key`),
13700 isTemplateIf
13701 };
13702 }
13703 function createCodegenNodeForBranch(branch, keyIndex, context) {
13704 if (branch.condition) {
13705 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
13706 // make sure to pass in asBlock: true so that the comment node call
13707 // closes the current block.
13708 createCallExpression(context.helper(CREATE_COMMENT), [
13709 '"v-if"' ,
13710 'true'
13711 ]));
13712 }
13713 else {
13714 return createChildrenCodegenNode(branch, keyIndex, context);
13715 }
13716 }
13717 function createChildrenCodegenNode(branch, keyIndex, context) {
13718 const { helper } = context;
13719 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
13720 const { children } = branch;
13721 const firstChild = children[0];
13722 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
13723 if (needFragmentWrapper) {
13724 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
13725 // optimize away nested fragments when child is a ForNode
13726 const vnodeCall = firstChild.codegenNode;
13727 injectProp(vnodeCall, keyProperty, context);
13728 return vnodeCall;
13729 }
13730 else {
13731 let patchFlag = 64 /* STABLE_FRAGMENT */;
13732 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
13733 // check if the fragment actually contains a single valid child with
13734 // the rest being comments
13735 if (!branch.isTemplateIf &&
13736 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
13737 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
13738 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
13739 }
13740 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);
13741 }
13742 }
13743 else {
13744 const ret = firstChild.codegenNode;
13745 const vnodeCall = getMemoedVNodeCall(ret);
13746 // Change createVNode to createBlock.
13747 if (vnodeCall.type === 13 /* VNODE_CALL */) {
13748 makeBlock(vnodeCall, context);
13749 }
13750 // inject branch key
13751 injectProp(vnodeCall, keyProperty, context);
13752 return ret;
13753 }
13754 }
13755 function isSameKey(a, b) {
13756 if (!a || a.type !== b.type) {
13757 return false;
13758 }
13759 if (a.type === 6 /* ATTRIBUTE */) {
13760 if (a.value.content !== b.value.content) {
13761 return false;
13762 }
13763 }
13764 else {
13765 // directive
13766 const exp = a.exp;
13767 const branchExp = b.exp;
13768 if (exp.type !== branchExp.type) {
13769 return false;
13770 }
13771 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
13772 exp.isStatic !== branchExp.isStatic ||
13773 exp.content !== branchExp.content) {
13774 return false;
13775 }
13776 }
13777 return true;
13778 }
13779 function getParentCondition(node) {
13780 while (true) {
13781 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13782 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13783 node = node.alternate;
13784 }
13785 else {
13786 return node;
13787 }
13788 }
13789 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
13790 node = node.value;
13791 }
13792 }
13793 }
13794
13795 const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
13796 const { helper, removeHelper } = context;
13797 return processFor(node, dir, context, forNode => {
13798 // create the loop render function expression now, and add the
13799 // iterator on exit after all children have been traversed
13800 const renderExp = createCallExpression(helper(RENDER_LIST), [
13801 forNode.source
13802 ]);
13803 const isTemplate = isTemplateNode(node);
13804 const memo = findDir(node, 'memo');
13805 const keyProp = findProp(node, `key`);
13806 const keyExp = keyProp &&
13807 (keyProp.type === 6 /* ATTRIBUTE */
13808 ? createSimpleExpression(keyProp.value.content, true)
13809 : keyProp.exp);
13810 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
13811 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
13812 forNode.source.constType > 0 /* NOT_CONSTANT */;
13813 const fragmentFlag = isStableFragment
13814 ? 64 /* STABLE_FRAGMENT */
13815 : keyProp
13816 ? 128 /* KEYED_FRAGMENT */
13817 : 256 /* UNKEYED_FRAGMENT */;
13818 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
13819 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
13820 return () => {
13821 // finish the codegen now that all children have been traversed
13822 let childBlock;
13823 const { children } = forNode;
13824 // check <template v-for> key placement
13825 if (isTemplate) {
13826 node.children.some(c => {
13827 if (c.type === 1 /* ELEMENT */) {
13828 const key = findProp(c, 'key');
13829 if (key) {
13830 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
13831 return true;
13832 }
13833 }
13834 });
13835 }
13836 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
13837 const slotOutlet = isSlotOutlet(node)
13838 ? node
13839 : isTemplate &&
13840 node.children.length === 1 &&
13841 isSlotOutlet(node.children[0])
13842 ? node.children[0] // api-extractor somehow fails to infer this
13843 : null;
13844 if (slotOutlet) {
13845 // <slot v-for="..."> or <template v-for="..."><slot/></template>
13846 childBlock = slotOutlet.codegenNode;
13847 if (isTemplate && keyProperty) {
13848 // <template v-for="..." :key="..."><slot/></template>
13849 // we need to inject the key to the renderSlot() call.
13850 // the props for renderSlot is passed as the 3rd argument.
13851 injectProp(childBlock, keyProperty, context);
13852 }
13853 }
13854 else if (needFragmentWrapper) {
13855 // <template v-for="..."> with text or multi-elements
13856 // should generate a fragment block for each loop
13857 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
13858 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
13859 ), undefined, undefined, true, undefined, false /* isComponent */);
13860 }
13861 else {
13862 // Normal element v-for. Directly use the child's codegenNode
13863 // but mark it as a block.
13864 childBlock = children[0]
13865 .codegenNode;
13866 if (isTemplate && keyProperty) {
13867 injectProp(childBlock, keyProperty, context);
13868 }
13869 if (childBlock.isBlock !== !isStableFragment) {
13870 if (childBlock.isBlock) {
13871 // switch from block to vnode
13872 removeHelper(OPEN_BLOCK);
13873 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
13874 }
13875 else {
13876 // switch from vnode to block
13877 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
13878 }
13879 }
13880 childBlock.isBlock = !isStableFragment;
13881 if (childBlock.isBlock) {
13882 helper(OPEN_BLOCK);
13883 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
13884 }
13885 else {
13886 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
13887 }
13888 }
13889 if (memo) {
13890 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
13891 createSimpleExpression(`_cached`)
13892 ]));
13893 loop.body = createBlockStatement([
13894 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
13895 createCompoundExpression([
13896 `if (_cached`,
13897 ...(keyExp ? [` && _cached.key === `, keyExp] : []),
13898 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
13899 ]),
13900 createCompoundExpression([`const _item = `, childBlock]),
13901 createSimpleExpression(`_item.memo = _memo`),
13902 createSimpleExpression(`return _item`)
13903 ]);
13904 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
13905 }
13906 else {
13907 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
13908 }
13909 };
13910 });
13911 });
13912 // target-agnostic transform used for both Client and SSR
13913 function processFor(node, dir, context, processCodegen) {
13914 if (!dir.exp) {
13915 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
13916 return;
13917 }
13918 const parseResult = parseForExpression(
13919 // can only be simple expression because vFor transform is applied
13920 // before expression transform.
13921 dir.exp, context);
13922 if (!parseResult) {
13923 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
13924 return;
13925 }
13926 const { addIdentifiers, removeIdentifiers, scopes } = context;
13927 const { source, value, key, index } = parseResult;
13928 const forNode = {
13929 type: 11 /* FOR */,
13930 loc: dir.loc,
13931 source,
13932 valueAlias: value,
13933 keyAlias: key,
13934 objectIndexAlias: index,
13935 parseResult,
13936 children: isTemplateNode(node) ? node.children : [node]
13937 };
13938 context.replaceNode(forNode);
13939 // bookkeeping
13940 scopes.vFor++;
13941 const onExit = processCodegen && processCodegen(forNode);
13942 return () => {
13943 scopes.vFor--;
13944 if (onExit)
13945 onExit();
13946 };
13947 }
13948 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
13949 // This regex doesn't cover the case if key or index aliases have destructuring,
13950 // but those do not make sense in the first place, so this works in practice.
13951 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
13952 const stripParensRE = /^\(|\)$/g;
13953 function parseForExpression(input, context) {
13954 const loc = input.loc;
13955 const exp = input.content;
13956 const inMatch = exp.match(forAliasRE);
13957 if (!inMatch)
13958 return;
13959 const [, LHS, RHS] = inMatch;
13960 const result = {
13961 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
13962 value: undefined,
13963 key: undefined,
13964 index: undefined
13965 };
13966 {
13967 validateBrowserExpression(result.source, context);
13968 }
13969 let valueContent = LHS.trim().replace(stripParensRE, '').trim();
13970 const trimmedOffset = LHS.indexOf(valueContent);
13971 const iteratorMatch = valueContent.match(forIteratorRE);
13972 if (iteratorMatch) {
13973 valueContent = valueContent.replace(forIteratorRE, '').trim();
13974 const keyContent = iteratorMatch[1].trim();
13975 let keyOffset;
13976 if (keyContent) {
13977 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
13978 result.key = createAliasExpression(loc, keyContent, keyOffset);
13979 {
13980 validateBrowserExpression(result.key, context, true);
13981 }
13982 }
13983 if (iteratorMatch[2]) {
13984 const indexContent = iteratorMatch[2].trim();
13985 if (indexContent) {
13986 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
13987 ? keyOffset + keyContent.length
13988 : trimmedOffset + valueContent.length));
13989 {
13990 validateBrowserExpression(result.index, context, true);
13991 }
13992 }
13993 }
13994 }
13995 if (valueContent) {
13996 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
13997 {
13998 validateBrowserExpression(result.value, context, true);
13999 }
14000 }
14001 return result;
14002 }
14003 function createAliasExpression(range, content, offset) {
14004 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
14005 }
14006 function createForLoopParams({ value, key, index }, memoArgs = []) {
14007 return createParamsList([value, key, index, ...memoArgs]);
14008 }
14009 function createParamsList(args) {
14010 let i = args.length;
14011 while (i--) {
14012 if (args[i])
14013 break;
14014 }
14015 return args
14016 .slice(0, i + 1)
14017 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
14018 }
14019
14020 const defaultFallback = createSimpleExpression(`undefined`, false);
14021 // A NodeTransform that:
14022 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
14023 // by transformExpression. This is only applied in non-browser builds with
14024 // { prefixIdentifiers: true }.
14025 // 2. Track v-slot depths so that we know a slot is inside another slot.
14026 // Note the exit callback is executed before buildSlots() on the same node,
14027 // so only nested slots see positive numbers.
14028 const trackSlotScopes = (node, context) => {
14029 if (node.type === 1 /* ELEMENT */ &&
14030 (node.tagType === 1 /* COMPONENT */ ||
14031 node.tagType === 3 /* TEMPLATE */)) {
14032 // We are only checking non-empty v-slot here
14033 // since we only care about slots that introduce scope variables.
14034 const vSlot = findDir(node, 'slot');
14035 if (vSlot) {
14036 vSlot.exp;
14037 context.scopes.vSlot++;
14038 return () => {
14039 context.scopes.vSlot--;
14040 };
14041 }
14042 }
14043 };
14044 const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
14045 // Instead of being a DirectiveTransform, v-slot processing is called during
14046 // transformElement to build the slots object for a component.
14047 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
14048 context.helper(WITH_CTX);
14049 const { children, loc } = node;
14050 const slotsProperties = [];
14051 const dynamicSlots = [];
14052 // If the slot is inside a v-for or another v-slot, force it to be dynamic
14053 // since it likely uses a scope variable.
14054 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
14055 // 1. Check for slot with slotProps on component itself.
14056 // <Comp v-slot="{ prop }"/>
14057 const onComponentSlot = findDir(node, 'slot', true);
14058 if (onComponentSlot) {
14059 const { arg, exp } = onComponentSlot;
14060 if (arg && !isStaticExp(arg)) {
14061 hasDynamicSlots = true;
14062 }
14063 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
14064 }
14065 // 2. Iterate through children and check for template slots
14066 // <template v-slot:foo="{ prop }">
14067 let hasTemplateSlots = false;
14068 let hasNamedDefaultSlot = false;
14069 const implicitDefaultChildren = [];
14070 const seenSlotNames = new Set();
14071 for (let i = 0; i < children.length; i++) {
14072 const slotElement = children[i];
14073 let slotDir;
14074 if (!isTemplateNode(slotElement) ||
14075 !(slotDir = findDir(slotElement, 'slot', true))) {
14076 // not a <template v-slot>, skip.
14077 if (slotElement.type !== 3 /* COMMENT */) {
14078 implicitDefaultChildren.push(slotElement);
14079 }
14080 continue;
14081 }
14082 if (onComponentSlot) {
14083 // already has on-component slot - this is incorrect usage.
14084 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
14085 break;
14086 }
14087 hasTemplateSlots = true;
14088 const { children: slotChildren, loc: slotLoc } = slotElement;
14089 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
14090 // check if name is dynamic.
14091 let staticSlotName;
14092 if (isStaticExp(slotName)) {
14093 staticSlotName = slotName ? slotName.content : `default`;
14094 }
14095 else {
14096 hasDynamicSlots = true;
14097 }
14098 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
14099 // check if this slot is conditional (v-if/v-for)
14100 let vIf;
14101 let vElse;
14102 let vFor;
14103 if ((vIf = findDir(slotElement, 'if'))) {
14104 hasDynamicSlots = true;
14105 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
14106 }
14107 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
14108 // find adjacent v-if
14109 let j = i;
14110 let prev;
14111 while (j--) {
14112 prev = children[j];
14113 if (prev.type !== 3 /* COMMENT */) {
14114 break;
14115 }
14116 }
14117 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
14118 // remove node
14119 children.splice(i, 1);
14120 i--;
14121 // attach this slot to previous conditional
14122 let conditional = dynamicSlots[dynamicSlots.length - 1];
14123 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
14124 conditional = conditional.alternate;
14125 }
14126 conditional.alternate = vElse.exp
14127 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
14128 : buildDynamicSlot(slotName, slotFunction);
14129 }
14130 else {
14131 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
14132 }
14133 }
14134 else if ((vFor = findDir(slotElement, 'for'))) {
14135 hasDynamicSlots = true;
14136 const parseResult = vFor.parseResult ||
14137 parseForExpression(vFor.exp, context);
14138 if (parseResult) {
14139 // Render the dynamic slots as an array and add it to the createSlot()
14140 // args. The runtime knows how to handle it appropriately.
14141 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
14142 parseResult.source,
14143 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
14144 ]));
14145 }
14146 else {
14147 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
14148 }
14149 }
14150 else {
14151 // check duplicate static names
14152 if (staticSlotName) {
14153 if (seenSlotNames.has(staticSlotName)) {
14154 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
14155 continue;
14156 }
14157 seenSlotNames.add(staticSlotName);
14158 if (staticSlotName === 'default') {
14159 hasNamedDefaultSlot = true;
14160 }
14161 }
14162 slotsProperties.push(createObjectProperty(slotName, slotFunction));
14163 }
14164 }
14165 if (!onComponentSlot) {
14166 const buildDefaultSlotProperty = (props, children) => {
14167 const fn = buildSlotFn(props, children, loc);
14168 return createObjectProperty(`default`, fn);
14169 };
14170 if (!hasTemplateSlots) {
14171 // implicit default slot (on component)
14172 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
14173 }
14174 else if (implicitDefaultChildren.length &&
14175 // #3766
14176 // with whitespace: 'preserve', whitespaces between slots will end up in
14177 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
14178 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
14179 // implicit default slot (mixed with named slots)
14180 if (hasNamedDefaultSlot) {
14181 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
14182 }
14183 else {
14184 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
14185 }
14186 }
14187 }
14188 const slotFlag = hasDynamicSlots
14189 ? 2 /* DYNAMIC */
14190 : hasForwardedSlots(node.children)
14191 ? 3 /* FORWARDED */
14192 : 1 /* STABLE */;
14193 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
14194 // 2 = compiled but dynamic = can skip normalization, but must run diff
14195 // 1 = compiled and static = can skip normalization AND diff as optimized
14196 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
14197 if (dynamicSlots.length) {
14198 slots = createCallExpression(context.helper(CREATE_SLOTS), [
14199 slots,
14200 createArrayExpression(dynamicSlots)
14201 ]);
14202 }
14203 return {
14204 slots,
14205 hasDynamicSlots
14206 };
14207 }
14208 function buildDynamicSlot(name, fn) {
14209 return createObjectExpression([
14210 createObjectProperty(`name`, name),
14211 createObjectProperty(`fn`, fn)
14212 ]);
14213 }
14214 function hasForwardedSlots(children) {
14215 for (let i = 0; i < children.length; i++) {
14216 const child = children[i];
14217 switch (child.type) {
14218 case 1 /* ELEMENT */:
14219 if (child.tagType === 2 /* SLOT */ ||
14220 hasForwardedSlots(child.children)) {
14221 return true;
14222 }
14223 break;
14224 case 9 /* IF */:
14225 if (hasForwardedSlots(child.branches))
14226 return true;
14227 break;
14228 case 10 /* IF_BRANCH */:
14229 case 11 /* FOR */:
14230 if (hasForwardedSlots(child.children))
14231 return true;
14232 break;
14233 }
14234 }
14235 return false;
14236 }
14237 function isNonWhitespaceContent(node) {
14238 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
14239 return true;
14240 return node.type === 2 /* TEXT */
14241 ? !!node.content.trim()
14242 : isNonWhitespaceContent(node.content);
14243 }
14244
14245 // some directive transforms (e.g. v-model) may return a symbol for runtime
14246 // import, which should be used instead of a resolveDirective call.
14247 const directiveImportMap = new WeakMap();
14248 // generate a JavaScript AST for this element's codegen
14249 const transformElement = (node, context) => {
14250 // perform the work on exit, after all child expressions have been
14251 // processed and merged.
14252 return function postTransformElement() {
14253 node = context.currentNode;
14254 if (!(node.type === 1 /* ELEMENT */ &&
14255 (node.tagType === 0 /* ELEMENT */ ||
14256 node.tagType === 1 /* COMPONENT */))) {
14257 return;
14258 }
14259 const { tag, props } = node;
14260 const isComponent = node.tagType === 1 /* COMPONENT */;
14261 // The goal of the transform is to create a codegenNode implementing the
14262 // VNodeCall interface.
14263 let vnodeTag = isComponent
14264 ? resolveComponentType(node, context)
14265 : `"${tag}"`;
14266 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
14267 let vnodeProps;
14268 let vnodeChildren;
14269 let vnodePatchFlag;
14270 let patchFlag = 0;
14271 let vnodeDynamicProps;
14272 let dynamicPropNames;
14273 let vnodeDirectives;
14274 let shouldUseBlock =
14275 // dynamic component may resolve to plain elements
14276 isDynamicComponent ||
14277 vnodeTag === TELEPORT ||
14278 vnodeTag === SUSPENSE ||
14279 (!isComponent &&
14280 // <svg> and <foreignObject> must be forced into blocks so that block
14281 // updates inside get proper isSVG flag at runtime. (#639, #643)
14282 // This is technically web-specific, but splitting the logic out of core
14283 // leads to too much unnecessary complexity.
14284 (tag === 'svg' || tag === 'foreignObject'));
14285 // props
14286 if (props.length > 0) {
14287 const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
14288 vnodeProps = propsBuildResult.props;
14289 patchFlag = propsBuildResult.patchFlag;
14290 dynamicPropNames = propsBuildResult.dynamicPropNames;
14291 const directives = propsBuildResult.directives;
14292 vnodeDirectives =
14293 directives && directives.length
14294 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14295 : undefined;
14296 if (propsBuildResult.shouldUseBlock) {
14297 shouldUseBlock = true;
14298 }
14299 }
14300 // children
14301 if (node.children.length > 0) {
14302 if (vnodeTag === KEEP_ALIVE) {
14303 // Although a built-in component, we compile KeepAlive with raw children
14304 // instead of slot functions so that it can be used inside Transition
14305 // or other Transition-wrapping HOCs.
14306 // To ensure correct updates with block optimizations, we need to:
14307 // 1. Force keep-alive into a block. This avoids its children being
14308 // collected by a parent block.
14309 shouldUseBlock = true;
14310 // 2. Force keep-alive to always be updated, since it uses raw children.
14311 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14312 if (node.children.length > 1) {
14313 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
14314 start: node.children[0].loc.start,
14315 end: node.children[node.children.length - 1].loc.end,
14316 source: ''
14317 }));
14318 }
14319 }
14320 const shouldBuildAsSlots = isComponent &&
14321 // Teleport is not a real component and has dedicated runtime handling
14322 vnodeTag !== TELEPORT &&
14323 // explained above.
14324 vnodeTag !== KEEP_ALIVE;
14325 if (shouldBuildAsSlots) {
14326 const { slots, hasDynamicSlots } = buildSlots(node, context);
14327 vnodeChildren = slots;
14328 if (hasDynamicSlots) {
14329 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14330 }
14331 }
14332 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
14333 const child = node.children[0];
14334 const type = child.type;
14335 // check for dynamic text children
14336 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
14337 type === 8 /* COMPOUND_EXPRESSION */;
14338 if (hasDynamicTextChild &&
14339 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
14340 patchFlag |= 1 /* TEXT */;
14341 }
14342 // pass directly if the only child is a text node
14343 // (plain / interpolation / expression)
14344 if (hasDynamicTextChild || type === 2 /* TEXT */) {
14345 vnodeChildren = child;
14346 }
14347 else {
14348 vnodeChildren = node.children;
14349 }
14350 }
14351 else {
14352 vnodeChildren = node.children;
14353 }
14354 }
14355 // patchFlag & dynamicPropNames
14356 if (patchFlag !== 0) {
14357 {
14358 if (patchFlag < 0) {
14359 // special flags (negative and mutually exclusive)
14360 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
14361 }
14362 else {
14363 // bitwise flags
14364 const flagNames = Object.keys(PatchFlagNames)
14365 .map(Number)
14366 .filter(n => n > 0 && patchFlag & n)
14367 .map(n => PatchFlagNames[n])
14368 .join(`, `);
14369 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
14370 }
14371 }
14372 if (dynamicPropNames && dynamicPropNames.length) {
14373 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
14374 }
14375 }
14376 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
14377 };
14378 };
14379 function resolveComponentType(node, context, ssr = false) {
14380 let { tag } = node;
14381 // 1. dynamic component
14382 const isExplicitDynamic = isComponentTag(tag);
14383 const isProp = findProp(node, 'is');
14384 if (isProp) {
14385 if (isExplicitDynamic ||
14386 (false )) {
14387 const exp = isProp.type === 6 /* ATTRIBUTE */
14388 ? isProp.value && createSimpleExpression(isProp.value.content, true)
14389 : isProp.exp;
14390 if (exp) {
14391 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14392 exp
14393 ]);
14394 }
14395 }
14396 else if (isProp.type === 6 /* ATTRIBUTE */ &&
14397 isProp.value.content.startsWith('vue:')) {
14398 // <button is="vue:xxx">
14399 // if not <component>, only is value that starts with "vue:" will be
14400 // treated as component by the parse phase and reach here, unless it's
14401 // compat mode where all is values are considered components
14402 tag = isProp.value.content.slice(4);
14403 }
14404 }
14405 // 1.5 v-is (TODO: Deprecate)
14406 const isDir = !isExplicitDynamic && findDir(node, 'is');
14407 if (isDir && isDir.exp) {
14408 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14409 isDir.exp
14410 ]);
14411 }
14412 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
14413 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
14414 if (builtIn) {
14415 // built-ins are simply fallthroughs / have special handling during ssr
14416 // so we don't need to import their runtime equivalents
14417 if (!ssr)
14418 context.helper(builtIn);
14419 return builtIn;
14420 }
14421 // 5. user component (resolve)
14422 context.helper(RESOLVE_COMPONENT);
14423 context.components.add(tag);
14424 return toValidAssetId(tag, `component`);
14425 }
14426 function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
14427 const { tag, loc: elementLoc, children } = node;
14428 let properties = [];
14429 const mergeArgs = [];
14430 const runtimeDirectives = [];
14431 const hasChildren = children.length > 0;
14432 let shouldUseBlock = false;
14433 // patchFlag analysis
14434 let patchFlag = 0;
14435 let hasRef = false;
14436 let hasClassBinding = false;
14437 let hasStyleBinding = false;
14438 let hasHydrationEventBinding = false;
14439 let hasDynamicKeys = false;
14440 let hasVnodeHook = false;
14441 const dynamicPropNames = [];
14442 const analyzePatchFlag = ({ key, value }) => {
14443 if (isStaticExp(key)) {
14444 const name = key.content;
14445 const isEventHandler = isOn(name);
14446 if (isEventHandler &&
14447 (!isComponent || isDynamicComponent) &&
14448 // omit the flag for click handlers because hydration gives click
14449 // dedicated fast path.
14450 name.toLowerCase() !== 'onclick' &&
14451 // omit v-model handlers
14452 name !== 'onUpdate:modelValue' &&
14453 // omit onVnodeXXX hooks
14454 !isReservedProp(name)) {
14455 hasHydrationEventBinding = true;
14456 }
14457 if (isEventHandler && isReservedProp(name)) {
14458 hasVnodeHook = true;
14459 }
14460 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
14461 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
14462 value.type === 8 /* COMPOUND_EXPRESSION */) &&
14463 getConstantType(value, context) > 0)) {
14464 // skip if the prop is a cached handler or has constant value
14465 return;
14466 }
14467 if (name === 'ref') {
14468 hasRef = true;
14469 }
14470 else if (name === 'class') {
14471 hasClassBinding = true;
14472 }
14473 else if (name === 'style') {
14474 hasStyleBinding = true;
14475 }
14476 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
14477 dynamicPropNames.push(name);
14478 }
14479 // treat the dynamic class and style binding of the component as dynamic props
14480 if (isComponent &&
14481 (name === 'class' || name === 'style') &&
14482 !dynamicPropNames.includes(name)) {
14483 dynamicPropNames.push(name);
14484 }
14485 }
14486 else {
14487 hasDynamicKeys = true;
14488 }
14489 };
14490 for (let i = 0; i < props.length; i++) {
14491 // static attribute
14492 const prop = props[i];
14493 if (prop.type === 6 /* ATTRIBUTE */) {
14494 const { loc, name, value } = prop;
14495 let isStatic = true;
14496 if (name === 'ref') {
14497 hasRef = true;
14498 if (context.scopes.vFor > 0) {
14499 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14500 }
14501 }
14502 // skip is on <component>, or is="vue:xxx"
14503 if (name === 'is' &&
14504 (isComponentTag(tag) ||
14505 (value && value.content.startsWith('vue:')) ||
14506 (false ))) {
14507 continue;
14508 }
14509 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14510 }
14511 else {
14512 // directives
14513 const { name, arg, exp, loc } = prop;
14514 const isVBind = name === 'bind';
14515 const isVOn = name === 'on';
14516 // skip v-slot - it is handled by its dedicated transform.
14517 if (name === 'slot') {
14518 if (!isComponent) {
14519 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));
14520 }
14521 continue;
14522 }
14523 // skip v-once/v-memo - they are handled by dedicated transforms.
14524 if (name === 'once' || name === 'memo') {
14525 continue;
14526 }
14527 // skip v-is and :is on <component>
14528 if (name === 'is' ||
14529 (isVBind &&
14530 isStaticArgOf(arg, 'is') &&
14531 (isComponentTag(tag) ||
14532 (false )))) {
14533 continue;
14534 }
14535 // skip v-on in SSR compilation
14536 if (isVOn && ssr) {
14537 continue;
14538 }
14539 if (
14540 // #938: elements with dynamic keys should be forced into blocks
14541 (isVBind && isStaticArgOf(arg, 'key')) ||
14542 // inline before-update hooks need to force block so that it is invoked
14543 // before children
14544 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14545 shouldUseBlock = true;
14546 }
14547 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14548 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14549 }
14550 // special case for v-bind and v-on with no argument
14551 if (!arg && (isVBind || isVOn)) {
14552 hasDynamicKeys = true;
14553 if (exp) {
14554 if (properties.length) {
14555 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14556 properties = [];
14557 }
14558 if (isVBind) {
14559 mergeArgs.push(exp);
14560 }
14561 else {
14562 // v-on="obj" -> toHandlers(obj)
14563 mergeArgs.push({
14564 type: 14 /* JS_CALL_EXPRESSION */,
14565 loc,
14566 callee: context.helper(TO_HANDLERS),
14567 arguments: [exp]
14568 });
14569 }
14570 }
14571 else {
14572 context.onError(createCompilerError(isVBind
14573 ? 34 /* X_V_BIND_NO_EXPRESSION */
14574 : 35 /* X_V_ON_NO_EXPRESSION */, loc));
14575 }
14576 continue;
14577 }
14578 const directiveTransform = context.directiveTransforms[name];
14579 if (directiveTransform) {
14580 // has built-in directive transform.
14581 const { props, needRuntime } = directiveTransform(prop, node, context);
14582 !ssr && props.forEach(analyzePatchFlag);
14583 properties.push(...props);
14584 if (needRuntime) {
14585 runtimeDirectives.push(prop);
14586 if (isSymbol(needRuntime)) {
14587 directiveImportMap.set(prop, needRuntime);
14588 }
14589 }
14590 }
14591 else if (!isBuiltInDirective(name)) {
14592 // no built-in transform, this is a user custom directive.
14593 runtimeDirectives.push(prop);
14594 // custom dirs may use beforeUpdate so they need to force blocks
14595 // to ensure before-update gets called before children update
14596 if (hasChildren) {
14597 shouldUseBlock = true;
14598 }
14599 }
14600 }
14601 }
14602 let propsExpression = undefined;
14603 // has v-bind="object" or v-on="object", wrap with mergeProps
14604 if (mergeArgs.length) {
14605 if (properties.length) {
14606 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14607 }
14608 if (mergeArgs.length > 1) {
14609 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
14610 }
14611 else {
14612 // single v-bind with nothing else - no need for a mergeProps call
14613 propsExpression = mergeArgs[0];
14614 }
14615 }
14616 else if (properties.length) {
14617 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
14618 }
14619 // patchFlag analysis
14620 if (hasDynamicKeys) {
14621 patchFlag |= 16 /* FULL_PROPS */;
14622 }
14623 else {
14624 if (hasClassBinding && !isComponent) {
14625 patchFlag |= 2 /* CLASS */;
14626 }
14627 if (hasStyleBinding && !isComponent) {
14628 patchFlag |= 4 /* STYLE */;
14629 }
14630 if (dynamicPropNames.length) {
14631 patchFlag |= 8 /* PROPS */;
14632 }
14633 if (hasHydrationEventBinding) {
14634 patchFlag |= 32 /* HYDRATE_EVENTS */;
14635 }
14636 }
14637 if (!shouldUseBlock &&
14638 (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14639 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14640 patchFlag |= 512 /* NEED_PATCH */;
14641 }
14642 // pre-normalize props, SSR is skipped for now
14643 if (!context.inSSR && propsExpression) {
14644 switch (propsExpression.type) {
14645 case 15 /* JS_OBJECT_EXPRESSION */:
14646 // means that there is no v-bind,
14647 // but still need to deal with dynamic key binding
14648 let classKeyIndex = -1;
14649 let styleKeyIndex = -1;
14650 let hasDynamicKey = false;
14651 for (let i = 0; i < propsExpression.properties.length; i++) {
14652 const key = propsExpression.properties[i].key;
14653 if (isStaticExp(key)) {
14654 if (key.content === 'class') {
14655 classKeyIndex = i;
14656 }
14657 else if (key.content === 'style') {
14658 styleKeyIndex = i;
14659 }
14660 }
14661 else if (!key.isHandlerKey) {
14662 hasDynamicKey = true;
14663 }
14664 }
14665 const classProp = propsExpression.properties[classKeyIndex];
14666 const styleProp = propsExpression.properties[styleKeyIndex];
14667 // no dynamic key
14668 if (!hasDynamicKey) {
14669 if (classProp && !isStaticExp(classProp.value)) {
14670 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
14671 }
14672 if (styleProp &&
14673 // the static style is compiled into an object,
14674 // so use `hasStyleBinding` to ensure that it is a dynamic style binding
14675 (hasStyleBinding ||
14676 (styleProp.value.type === 4 /* SIMPLE_EXPRESSION */ &&
14677 styleProp.value.content.trim()[0] === `[`) ||
14678 // v-bind:style and style both exist,
14679 // v-bind:style with static literal object
14680 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
14681 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
14682 }
14683 }
14684 else {
14685 // dynamic key binding, wrap with `normalizeProps`
14686 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
14687 }
14688 break;
14689 case 14 /* JS_CALL_EXPRESSION */:
14690 // mergeProps call, do nothing
14691 break;
14692 default:
14693 // single v-bind
14694 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
14695 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
14696 propsExpression
14697 ])
14698 ]);
14699 break;
14700 }
14701 }
14702 return {
14703 props: propsExpression,
14704 directives: runtimeDirectives,
14705 patchFlag,
14706 dynamicPropNames,
14707 shouldUseBlock
14708 };
14709 }
14710 // Dedupe props in an object literal.
14711 // Literal duplicated attributes would have been warned during the parse phase,
14712 // however, it's possible to encounter duplicated `onXXX` handlers with different
14713 // modifiers. We also need to merge static and dynamic class / style attributes.
14714 // - onXXX handlers / style: merge into array
14715 // - class: merge into single expression with concatenation
14716 function dedupeProperties(properties) {
14717 const knownProps = new Map();
14718 const deduped = [];
14719 for (let i = 0; i < properties.length; i++) {
14720 const prop = properties[i];
14721 // dynamic keys are always allowed
14722 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
14723 deduped.push(prop);
14724 continue;
14725 }
14726 const name = prop.key.content;
14727 const existing = knownProps.get(name);
14728 if (existing) {
14729 if (name === 'style' || name === 'class' || isOn(name)) {
14730 mergeAsArray$1(existing, prop);
14731 }
14732 // unexpected duplicate, should have emitted error during parse
14733 }
14734 else {
14735 knownProps.set(name, prop);
14736 deduped.push(prop);
14737 }
14738 }
14739 return deduped;
14740 }
14741 function mergeAsArray$1(existing, incoming) {
14742 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
14743 existing.value.elements.push(incoming.value);
14744 }
14745 else {
14746 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
14747 }
14748 }
14749 function buildDirectiveArgs(dir, context) {
14750 const dirArgs = [];
14751 const runtime = directiveImportMap.get(dir);
14752 if (runtime) {
14753 // built-in directive with runtime
14754 dirArgs.push(context.helperString(runtime));
14755 }
14756 else {
14757 {
14758 // inject statement for resolving directive
14759 context.helper(RESOLVE_DIRECTIVE);
14760 context.directives.add(dir.name);
14761 dirArgs.push(toValidAssetId(dir.name, `directive`));
14762 }
14763 }
14764 const { loc } = dir;
14765 if (dir.exp)
14766 dirArgs.push(dir.exp);
14767 if (dir.arg) {
14768 if (!dir.exp) {
14769 dirArgs.push(`void 0`);
14770 }
14771 dirArgs.push(dir.arg);
14772 }
14773 if (Object.keys(dir.modifiers).length) {
14774 if (!dir.arg) {
14775 if (!dir.exp) {
14776 dirArgs.push(`void 0`);
14777 }
14778 dirArgs.push(`void 0`);
14779 }
14780 const trueExpression = createSimpleExpression(`true`, false, loc);
14781 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
14782 }
14783 return createArrayExpression(dirArgs, dir.loc);
14784 }
14785 function stringifyDynamicPropNames(props) {
14786 let propsNamesString = `[`;
14787 for (let i = 0, l = props.length; i < l; i++) {
14788 propsNamesString += JSON.stringify(props[i]);
14789 if (i < l - 1)
14790 propsNamesString += ', ';
14791 }
14792 return propsNamesString + `]`;
14793 }
14794 function isComponentTag(tag) {
14795 return tag === 'component' || tag === 'Component';
14796 }
14797
14798 const transformSlotOutlet = (node, context) => {
14799 if (isSlotOutlet(node)) {
14800 const { children, loc } = node;
14801 const { slotName, slotProps } = processSlotOutlet(node, context);
14802 const slotArgs = [
14803 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
14804 slotName,
14805 '{}',
14806 'undefined',
14807 'true'
14808 ];
14809 let expectedLen = 2;
14810 if (slotProps) {
14811 slotArgs[2] = slotProps;
14812 expectedLen = 3;
14813 }
14814 if (children.length) {
14815 slotArgs[3] = createFunctionExpression([], children, false, false, loc);
14816 expectedLen = 4;
14817 }
14818 if (context.scopeId && !context.slotted) {
14819 expectedLen = 5;
14820 }
14821 slotArgs.splice(expectedLen); // remove unused arguments
14822 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
14823 }
14824 };
14825 function processSlotOutlet(node, context) {
14826 let slotName = `"default"`;
14827 let slotProps = undefined;
14828 const nonNameProps = [];
14829 for (let i = 0; i < node.props.length; i++) {
14830 const p = node.props[i];
14831 if (p.type === 6 /* ATTRIBUTE */) {
14832 if (p.value) {
14833 if (p.name === 'name') {
14834 slotName = JSON.stringify(p.value.content);
14835 }
14836 else {
14837 p.name = camelize(p.name);
14838 nonNameProps.push(p);
14839 }
14840 }
14841 }
14842 else {
14843 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
14844 if (p.exp)
14845 slotName = p.exp;
14846 }
14847 else {
14848 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
14849 p.arg.content = camelize(p.arg.content);
14850 }
14851 nonNameProps.push(p);
14852 }
14853 }
14854 }
14855 if (nonNameProps.length > 0) {
14856 const { props, directives } = buildProps(node, context, nonNameProps, false, false);
14857 slotProps = props;
14858 if (directives.length) {
14859 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
14860 }
14861 }
14862 return {
14863 slotName,
14864 slotProps
14865 };
14866 }
14867
14868 const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
14869 const transformOn = (dir, node, context, augmentor) => {
14870 const { loc, modifiers, arg } = dir;
14871 if (!dir.exp && !modifiers.length) {
14872 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));
14873 }
14874 let eventName;
14875 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14876 if (arg.isStatic) {
14877 let rawName = arg.content;
14878 // TODO deprecate @vnodeXXX usage
14879 if (rawName.startsWith('vue:')) {
14880 rawName = `vnode-${rawName.slice(4)}`;
14881 }
14882 // for all event listeners, auto convert it to camelCase. See issue #2249
14883 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
14884 }
14885 else {
14886 // #2388
14887 eventName = createCompoundExpression([
14888 `${context.helperString(TO_HANDLER_KEY)}(`,
14889 arg,
14890 `)`
14891 ]);
14892 }
14893 }
14894 else {
14895 // already a compound expression.
14896 eventName = arg;
14897 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
14898 eventName.children.push(`)`);
14899 }
14900 // handler processing
14901 let exp = dir.exp;
14902 if (exp && !exp.content.trim()) {
14903 exp = undefined;
14904 }
14905 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
14906 if (exp) {
14907 const isMemberExp = isMemberExpression(exp.content);
14908 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
14909 const hasMultipleStatements = exp.content.includes(`;`);
14910 {
14911 validateBrowserExpression(exp, context, false, hasMultipleStatements);
14912 }
14913 if (isInlineStatement || (shouldCache && isMemberExp)) {
14914 // wrap inline statement in a function expression
14915 exp = createCompoundExpression([
14916 `${isInlineStatement
14917 ? `$event`
14918 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
14919 exp,
14920 hasMultipleStatements ? `}` : `)`
14921 ]);
14922 }
14923 }
14924 let ret = {
14925 props: [
14926 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
14927 ]
14928 };
14929 // apply extended compiler augmentor
14930 if (augmentor) {
14931 ret = augmentor(ret);
14932 }
14933 if (shouldCache) {
14934 // cache handlers so that it's always the same handler being passed down.
14935 // this avoids unnecessary re-renders when users use inline handlers on
14936 // components.
14937 ret.props[0].value = context.cache(ret.props[0].value);
14938 }
14939 // mark the key as handler for props normalization check
14940 ret.props.forEach(p => (p.key.isHandlerKey = true));
14941 return ret;
14942 };
14943
14944 // v-bind without arg is handled directly in ./transformElements.ts due to it affecting
14945 // codegen for the entire props object. This transform here is only for v-bind
14946 // *with* args.
14947 const transformBind = (dir, _node, context) => {
14948 const { exp, modifiers, loc } = dir;
14949 const arg = dir.arg;
14950 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
14951 arg.children.unshift(`(`);
14952 arg.children.push(`) || ""`);
14953 }
14954 else if (!arg.isStatic) {
14955 arg.content = `${arg.content} || ""`;
14956 }
14957 // .sync is replaced by v-model:arg
14958 if (modifiers.includes('camel')) {
14959 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14960 if (arg.isStatic) {
14961 arg.content = camelize(arg.content);
14962 }
14963 else {
14964 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
14965 }
14966 }
14967 else {
14968 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
14969 arg.children.push(`)`);
14970 }
14971 }
14972 if (!context.inSSR) {
14973 if (modifiers.includes('prop')) {
14974 injectPrefix(arg, '.');
14975 }
14976 if (modifiers.includes('attr')) {
14977 injectPrefix(arg, '^');
14978 }
14979 }
14980 if (!exp ||
14981 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
14982 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));
14983 return {
14984 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
14985 };
14986 }
14987 return {
14988 props: [createObjectProperty(arg, exp)]
14989 };
14990 };
14991 const injectPrefix = (arg, prefix) => {
14992 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14993 if (arg.isStatic) {
14994 arg.content = prefix + arg.content;
14995 }
14996 else {
14997 arg.content = `\`${prefix}\${${arg.content}}\``;
14998 }
14999 }
15000 else {
15001 arg.children.unshift(`'${prefix}' + (`);
15002 arg.children.push(`)`);
15003 }
15004 };
15005
15006 // Merge adjacent text nodes and expressions into a single expression
15007 // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
15008 const transformText = (node, context) => {
15009 if (node.type === 0 /* ROOT */ ||
15010 node.type === 1 /* ELEMENT */ ||
15011 node.type === 11 /* FOR */ ||
15012 node.type === 10 /* IF_BRANCH */) {
15013 // perform the transform on node exit so that all expressions have already
15014 // been processed.
15015 return () => {
15016 const children = node.children;
15017 let currentContainer = undefined;
15018 let hasText = false;
15019 for (let i = 0; i < children.length; i++) {
15020 const child = children[i];
15021 if (isText(child)) {
15022 hasText = true;
15023 for (let j = i + 1; j < children.length; j++) {
15024 const next = children[j];
15025 if (isText(next)) {
15026 if (!currentContainer) {
15027 currentContainer = children[i] = createCompoundExpression([child], child.loc);
15028 }
15029 // merge adjacent text node into current
15030 currentContainer.children.push(` + `, next);
15031 children.splice(j, 1);
15032 j--;
15033 }
15034 else {
15035 currentContainer = undefined;
15036 break;
15037 }
15038 }
15039 }
15040 }
15041 if (!hasText ||
15042 // if this is a plain element with a single text child, leave it
15043 // as-is since the runtime has dedicated fast path for this by directly
15044 // setting textContent of the element.
15045 // for component root it's always normalized anyway.
15046 (children.length === 1 &&
15047 (node.type === 0 /* ROOT */ ||
15048 (node.type === 1 /* ELEMENT */ &&
15049 node.tagType === 0 /* ELEMENT */ &&
15050 // #3756
15051 // custom directives can potentially add DOM elements arbitrarily,
15052 // we need to avoid setting textContent of the element at runtime
15053 // to avoid accidentally overwriting the DOM elements added
15054 // by the user through custom directives.
15055 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
15056 !context.directiveTransforms[p.name]) &&
15057 // in compat mode, <template> tags with no special directives
15058 // will be rendered as a fragment so its children must be
15059 // converted into vnodes.
15060 !(false ))))) {
15061 return;
15062 }
15063 // pre-convert text nodes into createTextVNode(text) calls to avoid
15064 // runtime normalization.
15065 for (let i = 0; i < children.length; i++) {
15066 const child = children[i];
15067 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
15068 const callArgs = [];
15069 // createTextVNode defaults to single whitespace, so if it is a
15070 // single space the code could be an empty call to save bytes.
15071 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
15072 callArgs.push(child);
15073 }
15074 // mark dynamic text with flag so it gets patched inside a block
15075 if (!context.ssr &&
15076 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
15077 callArgs.push(1 /* TEXT */ +
15078 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
15079 }
15080 children[i] = {
15081 type: 12 /* TEXT_CALL */,
15082 content: child,
15083 loc: child.loc,
15084 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
15085 };
15086 }
15087 }
15088 };
15089 }
15090 };
15091
15092 const seen = new WeakSet();
15093 const transformOnce = (node, context) => {
15094 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
15095 if (seen.has(node) || context.inVOnce) {
15096 return;
15097 }
15098 seen.add(node);
15099 context.inVOnce = true;
15100 context.helper(SET_BLOCK_TRACKING);
15101 return () => {
15102 context.inVOnce = false;
15103 const cur = context.currentNode;
15104 if (cur.codegenNode) {
15105 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
15106 }
15107 };
15108 }
15109 };
15110
15111 const transformModel = (dir, node, context) => {
15112 const { exp, arg } = dir;
15113 if (!exp) {
15114 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
15115 return createTransformProps();
15116 }
15117 const rawExp = exp.loc.source;
15118 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
15119 // im SFC <script setup> inline mode, the exp may have been transformed into
15120 // _unref(exp)
15121 context.bindingMetadata[rawExp];
15122 const maybeRef = !true /* SETUP_CONST */;
15123 if (!expString.trim() ||
15124 (!isMemberExpression(expString) && !maybeRef)) {
15125 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
15126 return createTransformProps();
15127 }
15128 const propName = arg ? arg : createSimpleExpression('modelValue', true);
15129 const eventName = arg
15130 ? isStaticExp(arg)
15131 ? `onUpdate:${arg.content}`
15132 : createCompoundExpression(['"onUpdate:" + ', arg])
15133 : `onUpdate:modelValue`;
15134 let assignmentExp;
15135 const eventArg = context.isTS ? `($event: any)` : `$event`;
15136 {
15137 assignmentExp = createCompoundExpression([
15138 `${eventArg} => ((`,
15139 exp,
15140 `) = $event)`
15141 ]);
15142 }
15143 const props = [
15144 // modelValue: foo
15145 createObjectProperty(propName, dir.exp),
15146 // "onUpdate:modelValue": $event => (foo = $event)
15147 createObjectProperty(eventName, assignmentExp)
15148 ];
15149 // modelModifiers: { foo: true, "bar-baz": true }
15150 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
15151 const modifiers = dir.modifiers
15152 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
15153 .join(`, `);
15154 const modifiersKey = arg
15155 ? isStaticExp(arg)
15156 ? `${arg.content}Modifiers`
15157 : createCompoundExpression([arg, ' + "Modifiers"'])
15158 : `modelModifiers`;
15159 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
15160 }
15161 return createTransformProps(props);
15162 };
15163 function createTransformProps(props = []) {
15164 return { props };
15165 }
15166
15167 const seen$1 = new WeakSet();
15168 const transformMemo = (node, context) => {
15169 if (node.type === 1 /* ELEMENT */) {
15170 const dir = findDir(node, 'memo');
15171 if (!dir || seen$1.has(node)) {
15172 return;
15173 }
15174 seen$1.add(node);
15175 return () => {
15176 const codegenNode = node.codegenNode ||
15177 context.currentNode.codegenNode;
15178 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
15179 // non-component sub tree should be turned into a block
15180 if (node.tagType !== 1 /* COMPONENT */) {
15181 makeBlock(codegenNode, context);
15182 }
15183 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
15184 dir.exp,
15185 createFunctionExpression(undefined, codegenNode),
15186 `_cache`,
15187 String(context.cached++)
15188 ]);
15189 }
15190 };
15191 }
15192 };
15193
15194 function getBaseTransformPreset(prefixIdentifiers) {
15195 return [
15196 [
15197 transformOnce,
15198 transformIf,
15199 transformMemo,
15200 transformFor,
15201 ...([]),
15202 ...([transformExpression]
15203 ),
15204 transformSlotOutlet,
15205 transformElement,
15206 trackSlotScopes,
15207 transformText
15208 ],
15209 {
15210 on: transformOn,
15211 bind: transformBind,
15212 model: transformModel
15213 }
15214 ];
15215 }
15216 // we name it `baseCompile` so that higher order compilers like
15217 // @vue/compiler-dom can export `compile` while re-exporting everything else.
15218 function baseCompile(template, options = {}) {
15219 const onError = options.onError || defaultOnError;
15220 const isModuleMode = options.mode === 'module';
15221 /* istanbul ignore if */
15222 {
15223 if (options.prefixIdentifiers === true) {
15224 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));
15225 }
15226 else if (isModuleMode) {
15227 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));
15228 }
15229 }
15230 const prefixIdentifiers = !true ;
15231 if (options.cacheHandlers) {
15232 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
15233 }
15234 if (options.scopeId && !isModuleMode) {
15235 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));
15236 }
15237 const ast = isString(template) ? baseParse(template, options) : template;
15238 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
15239 transform(ast, extend({}, options, {
15240 prefixIdentifiers,
15241 nodeTransforms: [
15242 ...nodeTransforms,
15243 ...(options.nodeTransforms || []) // user transforms
15244 ],
15245 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
15246 )
15247 }));
15248 return generate(ast, extend({}, options, {
15249 prefixIdentifiers
15250 }));
15251 }
15252
15253 const noopDirectiveTransform = () => ({ props: [] });
15254
15255 const V_MODEL_RADIO = Symbol(`vModelRadio` );
15256 const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
15257 const V_MODEL_TEXT = Symbol(`vModelText` );
15258 const V_MODEL_SELECT = Symbol(`vModelSelect` );
15259 const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
15260 const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
15261 const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
15262 const V_SHOW = Symbol(`vShow` );
15263 const TRANSITION$1 = Symbol(`Transition` );
15264 const TRANSITION_GROUP = Symbol(`TransitionGroup` );
15265 registerRuntimeHelpers({
15266 [V_MODEL_RADIO]: `vModelRadio`,
15267 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
15268 [V_MODEL_TEXT]: `vModelText`,
15269 [V_MODEL_SELECT]: `vModelSelect`,
15270 [V_MODEL_DYNAMIC]: `vModelDynamic`,
15271 [V_ON_WITH_MODIFIERS]: `withModifiers`,
15272 [V_ON_WITH_KEYS]: `withKeys`,
15273 [V_SHOW]: `vShow`,
15274 [TRANSITION$1]: `Transition`,
15275 [TRANSITION_GROUP]: `TransitionGroup`
15276 });
15277
15278 /* eslint-disable no-restricted-globals */
15279 let decoder;
15280 function decodeHtmlBrowser(raw, asAttr = false) {
15281 if (!decoder) {
15282 decoder = document.createElement('div');
15283 }
15284 if (asAttr) {
15285 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
15286 return decoder.children[0].getAttribute('foo');
15287 }
15288 else {
15289 decoder.innerHTML = raw;
15290 return decoder.textContent;
15291 }
15292 }
15293
15294 const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
15295 const parserOptions = {
15296 isVoidTag,
15297 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
15298 isPreTag: tag => tag === 'pre',
15299 decodeEntities: decodeHtmlBrowser ,
15300 isBuiltInComponent: (tag) => {
15301 if (isBuiltInType(tag, `Transition`)) {
15302 return TRANSITION$1;
15303 }
15304 else if (isBuiltInType(tag, `TransitionGroup`)) {
15305 return TRANSITION_GROUP;
15306 }
15307 },
15308 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
15309 getNamespace(tag, parent) {
15310 let ns = parent ? parent.ns : 0 /* HTML */;
15311 if (parent && ns === 2 /* MATH_ML */) {
15312 if (parent.tag === 'annotation-xml') {
15313 if (tag === 'svg') {
15314 return 1 /* SVG */;
15315 }
15316 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
15317 a.name === 'encoding' &&
15318 a.value != null &&
15319 (a.value.content === 'text/html' ||
15320 a.value.content === 'application/xhtml+xml'))) {
15321 ns = 0 /* HTML */;
15322 }
15323 }
15324 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
15325 tag !== 'mglyph' &&
15326 tag !== 'malignmark') {
15327 ns = 0 /* HTML */;
15328 }
15329 }
15330 else if (parent && ns === 1 /* SVG */) {
15331 if (parent.tag === 'foreignObject' ||
15332 parent.tag === 'desc' ||
15333 parent.tag === 'title') {
15334 ns = 0 /* HTML */;
15335 }
15336 }
15337 if (ns === 0 /* HTML */) {
15338 if (tag === 'svg') {
15339 return 1 /* SVG */;
15340 }
15341 if (tag === 'math') {
15342 return 2 /* MATH_ML */;
15343 }
15344 }
15345 return ns;
15346 },
15347 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
15348 getTextMode({ tag, ns }) {
15349 if (ns === 0 /* HTML */) {
15350 if (tag === 'textarea' || tag === 'title') {
15351 return 1 /* RCDATA */;
15352 }
15353 if (isRawTextContainer(tag)) {
15354 return 2 /* RAWTEXT */;
15355 }
15356 }
15357 return 0 /* DATA */;
15358 }
15359 };
15360
15361 // Parse inline CSS strings for static style attributes into an object.
15362 // This is a NodeTransform since it works on the static `style` attribute and
15363 // converts it into a dynamic equivalent:
15364 // style="color: red" -> :style='{ "color": "red" }'
15365 // It is then processed by `transformElement` and included in the generated
15366 // props.
15367 const transformStyle = node => {
15368 if (node.type === 1 /* ELEMENT */) {
15369 node.props.forEach((p, i) => {
15370 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
15371 // replace p with an expression node
15372 node.props[i] = {
15373 type: 7 /* DIRECTIVE */,
15374 name: `bind`,
15375 arg: createSimpleExpression(`style`, true, p.loc),
15376 exp: parseInlineCSS(p.value.content, p.loc),
15377 modifiers: [],
15378 loc: p.loc
15379 };
15380 }
15381 });
15382 }
15383 };
15384 const parseInlineCSS = (cssText, loc) => {
15385 const normalized = parseStringStyle(cssText);
15386 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
15387 };
15388
15389 function createDOMCompilerError(code, loc) {
15390 return createCompilerError(code, loc, DOMErrorMessages );
15391 }
15392 const DOMErrorMessages = {
15393 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
15394 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
15395 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
15396 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
15397 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
15398 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
15399 [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
15400 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
15401 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
15402 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
15403 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
15404 };
15405
15406 const transformVHtml = (dir, node, context) => {
15407 const { exp, loc } = dir;
15408 if (!exp) {
15409 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));
15410 }
15411 if (node.children.length) {
15412 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));
15413 node.children.length = 0;
15414 }
15415 return {
15416 props: [
15417 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
15418 ]
15419 };
15420 };
15421
15422 const transformVText = (dir, node, context) => {
15423 const { exp, loc } = dir;
15424 if (!exp) {
15425 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));
15426 }
15427 if (node.children.length) {
15428 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));
15429 node.children.length = 0;
15430 }
15431 return {
15432 props: [
15433 createObjectProperty(createSimpleExpression(`textContent`, true), exp
15434 ? getConstantType(exp, context) > 0
15435 ? exp
15436 : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
15437 : createSimpleExpression('', true))
15438 ]
15439 };
15440 };
15441
15442 const transformModel$1 = (dir, node, context) => {
15443 const baseResult = transformModel(dir, node, context);
15444 // base transform has errors OR component v-model (only need props)
15445 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
15446 return baseResult;
15447 }
15448 if (dir.arg) {
15449 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
15450 }
15451 function checkDuplicatedValue() {
15452 const value = findProp(node, 'value');
15453 if (value) {
15454 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
15455 }
15456 }
15457 const { tag } = node;
15458 const isCustomElement = context.isCustomElement(tag);
15459 if (tag === 'input' ||
15460 tag === 'textarea' ||
15461 tag === 'select' ||
15462 isCustomElement) {
15463 let directiveToUse = V_MODEL_TEXT;
15464 let isInvalidType = false;
15465 if (tag === 'input' || isCustomElement) {
15466 const type = findProp(node, `type`);
15467 if (type) {
15468 if (type.type === 7 /* DIRECTIVE */) {
15469 // :type="foo"
15470 directiveToUse = V_MODEL_DYNAMIC;
15471 }
15472 else if (type.value) {
15473 switch (type.value.content) {
15474 case 'radio':
15475 directiveToUse = V_MODEL_RADIO;
15476 break;
15477 case 'checkbox':
15478 directiveToUse = V_MODEL_CHECKBOX;
15479 break;
15480 case 'file':
15481 isInvalidType = true;
15482 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
15483 break;
15484 default:
15485 // text type
15486 checkDuplicatedValue();
15487 break;
15488 }
15489 }
15490 }
15491 else if (hasDynamicKeyVBind(node)) {
15492 // element has bindings with dynamic keys, which can possibly contain
15493 // "type".
15494 directiveToUse = V_MODEL_DYNAMIC;
15495 }
15496 else {
15497 // text type
15498 checkDuplicatedValue();
15499 }
15500 }
15501 else if (tag === 'select') {
15502 directiveToUse = V_MODEL_SELECT;
15503 }
15504 else {
15505 // textarea
15506 checkDuplicatedValue();
15507 }
15508 // inject runtime directive
15509 // by returning the helper symbol via needRuntime
15510 // the import will replaced a resolveDirective call.
15511 if (!isInvalidType) {
15512 baseResult.needRuntime = context.helper(directiveToUse);
15513 }
15514 }
15515 else {
15516 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
15517 }
15518 // native vmodel doesn't need the `modelValue` props since they are also
15519 // passed to the runtime as `binding.value`. removing it reduces code size.
15520 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
15521 p.key.content === 'modelValue'));
15522 return baseResult;
15523 };
15524
15525 const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
15526 const isNonKeyModifier = /*#__PURE__*/ makeMap(
15527 // event propagation management
15528`stop,prevent,self,` +
15529 // system modifiers + exact
15530 `ctrl,shift,alt,meta,exact,` +
15531 // mouse
15532 `middle`);
15533 // left & right could be mouse or key modifiers based on event type
15534 const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
15535 const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
15536 const resolveModifiers = (key, modifiers, context, loc) => {
15537 const keyModifiers = [];
15538 const nonKeyModifiers = [];
15539 const eventOptionModifiers = [];
15540 for (let i = 0; i < modifiers.length; i++) {
15541 const modifier = modifiers[i];
15542 if (isEventOptionModifier(modifier)) {
15543 // eventOptionModifiers: modifiers for addEventListener() options,
15544 // e.g. .passive & .capture
15545 eventOptionModifiers.push(modifier);
15546 }
15547 else {
15548 // runtimeModifiers: modifiers that needs runtime guards
15549 if (maybeKeyModifier(modifier)) {
15550 if (isStaticExp(key)) {
15551 if (isKeyboardEvent(key.content)) {
15552 keyModifiers.push(modifier);
15553 }
15554 else {
15555 nonKeyModifiers.push(modifier);
15556 }
15557 }
15558 else {
15559 keyModifiers.push(modifier);
15560 nonKeyModifiers.push(modifier);
15561 }
15562 }
15563 else {
15564 if (isNonKeyModifier(modifier)) {
15565 nonKeyModifiers.push(modifier);
15566 }
15567 else {
15568 keyModifiers.push(modifier);
15569 }
15570 }
15571 }
15572 }
15573 return {
15574 keyModifiers,
15575 nonKeyModifiers,
15576 eventOptionModifiers
15577 };
15578 };
15579 const transformClick = (key, event) => {
15580 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
15581 return isStaticClick
15582 ? createSimpleExpression(event, true)
15583 : key.type !== 4 /* SIMPLE_EXPRESSION */
15584 ? createCompoundExpression([
15585 `(`,
15586 key,
15587 `) === "onClick" ? "${event}" : (`,
15588 key,
15589 `)`
15590 ])
15591 : key;
15592 };
15593 const transformOn$1 = (dir, node, context) => {
15594 return transformOn(dir, node, context, baseResult => {
15595 const { modifiers } = dir;
15596 if (!modifiers.length)
15597 return baseResult;
15598 let { key, value: handlerExp } = baseResult.props[0];
15599 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
15600 // normalize click.right and click.middle since they don't actually fire
15601 if (nonKeyModifiers.includes('right')) {
15602 key = transformClick(key, `onContextmenu`);
15603 }
15604 if (nonKeyModifiers.includes('middle')) {
15605 key = transformClick(key, `onMouseup`);
15606 }
15607 if (nonKeyModifiers.length) {
15608 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
15609 handlerExp,
15610 JSON.stringify(nonKeyModifiers)
15611 ]);
15612 }
15613 if (keyModifiers.length &&
15614 // if event name is dynamic, always wrap with keys guard
15615 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
15616 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
15617 handlerExp,
15618 JSON.stringify(keyModifiers)
15619 ]);
15620 }
15621 if (eventOptionModifiers.length) {
15622 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
15623 key = isStaticExp(key)
15624 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
15625 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
15626 }
15627 return {
15628 props: [createObjectProperty(key, handlerExp)]
15629 };
15630 });
15631 };
15632
15633 const transformShow = (dir, node, context) => {
15634 const { exp, loc } = dir;
15635 if (!exp) {
15636 context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc));
15637 }
15638 return {
15639 props: [],
15640 needRuntime: context.helper(V_SHOW)
15641 };
15642 };
15643
15644 const transformTransition = (node, context) => {
15645 if (node.type === 1 /* ELEMENT */ &&
15646 node.tagType === 1 /* COMPONENT */) {
15647 const component = context.isBuiltInComponent(node.tag);
15648 if (component === TRANSITION$1) {
15649 return () => {
15650 if (!node.children.length) {
15651 return;
15652 }
15653 // warn multiple transition children
15654 if (hasMultipleChildren(node)) {
15655 context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
15656 start: node.children[0].loc.start,
15657 end: node.children[node.children.length - 1].loc.end,
15658 source: ''
15659 }));
15660 }
15661 // check if it's s single child w/ v-show
15662 // if yes, inject "persisted: true" to the transition props
15663 const child = node.children[0];
15664 if (child.type === 1 /* ELEMENT */) {
15665 for (const p of child.props) {
15666 if (p.type === 7 /* DIRECTIVE */ && p.name === 'show') {
15667 node.props.push({
15668 type: 6 /* ATTRIBUTE */,
15669 name: 'persisted',
15670 value: undefined,
15671 loc: node.loc
15672 });
15673 }
15674 }
15675 }
15676 };
15677 }
15678 }
15679 };
15680 function hasMultipleChildren(node) {
15681 // #1352 filter out potential comment nodes.
15682 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ &&
15683 !(c.type === 2 /* TEXT */ && !c.content.trim())));
15684 const child = children[0];
15685 return (children.length !== 1 ||
15686 child.type === 11 /* FOR */ ||
15687 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
15688 }
15689
15690 const ignoreSideEffectTags = (node, context) => {
15691 if (node.type === 1 /* ELEMENT */ &&
15692 node.tagType === 0 /* ELEMENT */ &&
15693 (node.tag === 'script' || node.tag === 'style')) {
15694 context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
15695 context.removeNode();
15696 }
15697 };
15698
15699 const DOMNodeTransforms = [
15700 transformStyle,
15701 ...([transformTransition] )
15702 ];
15703 const DOMDirectiveTransforms = {
15704 cloak: noopDirectiveTransform,
15705 html: transformVHtml,
15706 text: transformVText,
15707 model: transformModel$1,
15708 on: transformOn$1,
15709 show: transformShow
15710 };
15711 function compile$1(template, options = {}) {
15712 return baseCompile(template, extend({}, parserOptions, options, {
15713 nodeTransforms: [
15714 // ignore <script> and <tag>
15715 // this is not put inside DOMNodeTransforms because that list is used
15716 // by compiler-ssr to generate vnode fallback branches
15717 ignoreSideEffectTags,
15718 ...DOMNodeTransforms,
15719 ...(options.nodeTransforms || [])
15720 ],
15721 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
15722 transformHoist: null
15723 }));
15724 }
15725
15726 // This entry is the "full-build" that includes both the runtime
15727 {
15728 initDev();
15729 }
15730 const compileCache = Object.create(null);
15731 function compileToFunction(template, options) {
15732 if (!isString(template)) {
15733 if (template.nodeType) {
15734 template = template.innerHTML;
15735 }
15736 else {
15737 warn$1(`invalid template option: `, template);
15738 return NOOP;
15739 }
15740 }
15741 const key = template;
15742 const cached = compileCache[key];
15743 if (cached) {
15744 return cached;
15745 }
15746 if (template[0] === '#') {
15747 const el = document.querySelector(template);
15748 if (!el) {
15749 warn$1(`Template element not found or is empty: ${template}`);
15750 }
15751 // __UNSAFE__
15752 // Reason: potential execution of JS expressions in in-DOM template.
15753 // The user must make sure the in-DOM template is trusted. If it's rendered
15754 // by the server, the template should not contain any user data.
15755 template = el ? el.innerHTML : ``;
15756 }
15757 const { code } = compile$1(template, extend({
15758 hoistStatic: true,
15759 onError: onError ,
15760 onWarn: e => onError(e, true)
15761 }, options));
15762 function onError(err, asWarning = false) {
15763 const message = asWarning
15764 ? err.message
15765 : `Template compilation error: ${err.message}`;
15766 const codeFrame = err.loc &&
15767 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
15768 warn$1(codeFrame ? `${message}\n${codeFrame}` : message);
15769 }
15770 // The wildcard import results in a huge object with every export
15771 // with keys that cannot be mangled, and can be quite heavy size-wise.
15772 // In the global build we know `Vue` is available globally so we can avoid
15773 // the wildcard object.
15774 const render = (new Function(code)() );
15775 render._rc = true;
15776 return (compileCache[key] = render);
15777 }
15778 registerRuntimeCompiler(compileToFunction);
15779
15780 exports.BaseTransition = BaseTransition;
15781 exports.Comment = Comment;
15782 exports.EffectScope = EffectScope;
15783 exports.Fragment = Fragment;
15784 exports.KeepAlive = KeepAlive;
15785 exports.ReactiveEffect = ReactiveEffect;
15786 exports.Static = Static;
15787 exports.Suspense = Suspense;
15788 exports.Teleport = Teleport;
15789 exports.Text = Text;
15790 exports.Transition = Transition;
15791 exports.TransitionGroup = TransitionGroup;
15792 exports.VueElement = VueElement;
15793 exports.callWithAsyncErrorHandling = callWithAsyncErrorHandling;
15794 exports.callWithErrorHandling = callWithErrorHandling;
15795 exports.camelize = camelize;
15796 exports.capitalize = capitalize;
15797 exports.cloneVNode = cloneVNode;
15798 exports.compatUtils = compatUtils;
15799 exports.compile = compileToFunction;
15800 exports.computed = computed$1;
15801 exports.createApp = createApp;
15802 exports.createBlock = createBlock;
15803 exports.createCommentVNode = createCommentVNode;
15804 exports.createElementBlock = createElementBlock;
15805 exports.createElementVNode = createBaseVNode;
15806 exports.createHydrationRenderer = createHydrationRenderer;
15807 exports.createPropsRestProxy = createPropsRestProxy;
15808 exports.createRenderer = createRenderer;
15809 exports.createSSRApp = createSSRApp;
15810 exports.createSlots = createSlots;
15811 exports.createStaticVNode = createStaticVNode;
15812 exports.createTextVNode = createTextVNode;
15813 exports.createVNode = createVNode;
15814 exports.customRef = customRef;
15815 exports.defineAsyncComponent = defineAsyncComponent;
15816 exports.defineComponent = defineComponent;
15817 exports.defineCustomElement = defineCustomElement;
15818 exports.defineEmits = defineEmits;
15819 exports.defineExpose = defineExpose;
15820 exports.defineProps = defineProps;
15821 exports.defineSSRCustomElement = defineSSRCustomElement;
15822 exports.effect = effect;
15823 exports.effectScope = effectScope;
15824 exports.getCurrentInstance = getCurrentInstance;
15825 exports.getCurrentScope = getCurrentScope;
15826 exports.getTransitionRawChildren = getTransitionRawChildren;
15827 exports.guardReactiveProps = guardReactiveProps;
15828 exports.h = h;
15829 exports.handleError = handleError;
15830 exports.hydrate = hydrate;
15831 exports.initCustomFormatter = initCustomFormatter;
15832 exports.initDirectivesForSSR = initDirectivesForSSR;
15833 exports.inject = inject;
15834 exports.isMemoSame = isMemoSame;
15835 exports.isProxy = isProxy;
15836 exports.isReactive = isReactive;
15837 exports.isReadonly = isReadonly;
15838 exports.isRef = isRef;
15839 exports.isRuntimeOnly = isRuntimeOnly;
15840 exports.isShallow = isShallow;
15841 exports.isVNode = isVNode;
15842 exports.markRaw = markRaw;
15843 exports.mergeDefaults = mergeDefaults;
15844 exports.mergeProps = mergeProps;
15845 exports.nextTick = nextTick;
15846 exports.normalizeClass = normalizeClass;
15847 exports.normalizeProps = normalizeProps;
15848 exports.normalizeStyle = normalizeStyle;
15849 exports.onActivated = onActivated;
15850 exports.onBeforeMount = onBeforeMount;
15851 exports.onBeforeUnmount = onBeforeUnmount;
15852 exports.onBeforeUpdate = onBeforeUpdate;
15853 exports.onDeactivated = onDeactivated;
15854 exports.onErrorCaptured = onErrorCaptured;
15855 exports.onMounted = onMounted;
15856 exports.onRenderTracked = onRenderTracked;
15857 exports.onRenderTriggered = onRenderTriggered;
15858 exports.onScopeDispose = onScopeDispose;
15859 exports.onServerPrefetch = onServerPrefetch;
15860 exports.onUnmounted = onUnmounted;
15861 exports.onUpdated = onUpdated;
15862 exports.openBlock = openBlock;
15863 exports.popScopeId = popScopeId;
15864 exports.provide = provide;
15865 exports.proxyRefs = proxyRefs;
15866 exports.pushScopeId = pushScopeId;
15867 exports.queuePostFlushCb = queuePostFlushCb;
15868 exports.reactive = reactive;
15869 exports.readonly = readonly;
15870 exports.ref = ref;
15871 exports.registerRuntimeCompiler = registerRuntimeCompiler;
15872 exports.render = render;
15873 exports.renderList = renderList;
15874 exports.renderSlot = renderSlot;
15875 exports.resolveComponent = resolveComponent;
15876 exports.resolveDirective = resolveDirective;
15877 exports.resolveDynamicComponent = resolveDynamicComponent;
15878 exports.resolveFilter = resolveFilter;
15879 exports.resolveTransitionHooks = resolveTransitionHooks;
15880 exports.setBlockTracking = setBlockTracking;
15881 exports.setDevtoolsHook = setDevtoolsHook;
15882 exports.setTransitionHooks = setTransitionHooks;
15883 exports.shallowReactive = shallowReactive;
15884 exports.shallowReadonly = shallowReadonly;
15885 exports.shallowRef = shallowRef;
15886 exports.ssrContextKey = ssrContextKey;
15887 exports.ssrUtils = ssrUtils;
15888 exports.stop = stop;
15889 exports.toDisplayString = toDisplayString;
15890 exports.toHandlerKey = toHandlerKey;
15891 exports.toHandlers = toHandlers;
15892 exports.toRaw = toRaw;
15893 exports.toRef = toRef;
15894 exports.toRefs = toRefs;
15895 exports.transformVNodeArgs = transformVNodeArgs;
15896 exports.triggerRef = triggerRef;
15897 exports.unref = unref;
15898 exports.useAttrs = useAttrs;
15899 exports.useCssModule = useCssModule;
15900 exports.useCssVars = useCssVars;
15901 exports.useSSRContext = useSSRContext;
15902 exports.useSlots = useSlots;
15903 exports.useTransitionState = useTransitionState;
15904 exports.vModelCheckbox = vModelCheckbox;
15905 exports.vModelDynamic = vModelDynamic;
15906 exports.vModelRadio = vModelRadio;
15907 exports.vModelSelect = vModelSelect;
15908 exports.vModelText = vModelText;
15909 exports.vShow = vShow;
15910 exports.version = version;
15911 exports.warn = warn$1;
15912 exports.watch = watch;
15913 exports.watchEffect = watchEffect;
15914 exports.watchPostEffect = watchPostEffect;
15915 exports.watchSyncEffect = watchSyncEffect;
15916 exports.withAsyncContext = withAsyncContext;
15917 exports.withCtx = withCtx;
15918 exports.withDefaults = withDefaults;
15919 exports.withDirectives = withDirectives;
15920 exports.withKeys = withKeys;
15921 exports.withMemo = withMemo;
15922 exports.withModifiers = withModifiers;
15923 exports.withScopeId = withScopeId;
15924
15925 Object.defineProperty(exports, '__esModule', { value: true });
15926
15927 return exports;
15928
15929}({}));