UNPKG

611 kBJavaScriptView Raw
1/**
2 * Make a map and return a function for checking if a key
3 * is in that map.
4 * IMPORTANT: all calls of this function must be prefixed with
5 * \/\*#\_\_PURE\_\_\*\/
6 * So that rollup can tree-shake them if necessary.
7 */
8function makeMap(str, expectsLowerCase) {
9 const map = Object.create(null);
10 const list = str.split(',');
11 for (let i = 0; i < list.length; i++) {
12 map[list[i]] = true;
13 }
14 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
15}
16
17/**
18 * dev only flag -> name mapping
19 */
20const PatchFlagNames = {
21 [1 /* TEXT */]: `TEXT`,
22 [2 /* CLASS */]: `CLASS`,
23 [4 /* STYLE */]: `STYLE`,
24 [8 /* PROPS */]: `PROPS`,
25 [16 /* FULL_PROPS */]: `FULL_PROPS`,
26 [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
27 [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
28 [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
29 [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
30 [512 /* NEED_PATCH */]: `NEED_PATCH`,
31 [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
32 [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
33 [-1 /* HOISTED */]: `HOISTED`,
34 [-2 /* BAIL */]: `BAIL`
35};
36
37/**
38 * Dev only
39 */
40const slotFlagsText = {
41 [1 /* STABLE */]: 'STABLE',
42 [2 /* DYNAMIC */]: 'DYNAMIC',
43 [3 /* FORWARDED */]: 'FORWARDED'
44};
45
46const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
47 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
48 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
49const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
50
51const range = 2;
52function generateCodeFrame(source, start = 0, end = source.length) {
53 // Split the content into individual lines but capture the newline sequence
54 // that separated each line. This is important because the actual sequence is
55 // needed to properly take into account the full line length for offset
56 // comparison
57 let lines = source.split(/(\r?\n)/);
58 // Separate the lines and newline sequences into separate arrays for easier referencing
59 const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
60 lines = lines.filter((_, idx) => idx % 2 === 0);
61 let count = 0;
62 const res = [];
63 for (let i = 0; i < lines.length; i++) {
64 count +=
65 lines[i].length +
66 ((newlineSequences[i] && newlineSequences[i].length) || 0);
67 if (count >= start) {
68 for (let j = i - range; j <= i + range || end > count; j++) {
69 if (j < 0 || j >= lines.length)
70 continue;
71 const line = j + 1;
72 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
73 const lineLength = lines[j].length;
74 const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
75 if (j === i) {
76 // push underline
77 const pad = start - (count - (lineLength + newLineSeqLength));
78 const length = Math.max(1, end > count ? lineLength - pad : end - start);
79 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
80 }
81 else if (j > i) {
82 if (end > count) {
83 const length = Math.max(Math.min(end - count, lineLength), 1);
84 res.push(` | ` + '^'.repeat(length));
85 }
86 count += lineLength + newLineSeqLength;
87 }
88 }
89 break;
90 }
91 }
92 return res.join('\n');
93}
94
95/**
96 * On the client we only need to offer special cases for boolean attributes that
97 * have different names from their corresponding dom properties:
98 * - itemscope -> N/A
99 * - allowfullscreen -> allowFullscreen
100 * - formnovalidate -> formNoValidate
101 * - ismap -> isMap
102 * - nomodule -> noModule
103 * - novalidate -> noValidate
104 * - readonly -> readOnly
105 */
106const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
107const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
108/**
109 * Boolean attributes should be included if the value is truthy or ''.
110 * e.g. `<select multiple>` compiles to `{ multiple: '' }`
111 */
112function includeBooleanAttr(value) {
113 return !!value || value === '';
114}
115
116function normalizeStyle(value) {
117 if (isArray(value)) {
118 const res = {};
119 for (let i = 0; i < value.length; i++) {
120 const item = value[i];
121 const normalized = isString(item)
122 ? parseStringStyle(item)
123 : normalizeStyle(item);
124 if (normalized) {
125 for (const key in normalized) {
126 res[key] = normalized[key];
127 }
128 }
129 }
130 return res;
131 }
132 else if (isString(value)) {
133 return value;
134 }
135 else if (isObject(value)) {
136 return value;
137 }
138}
139const listDelimiterRE = /;(?![^(]*\))/g;
140const propertyDelimiterRE = /:(.+)/;
141function parseStringStyle(cssText) {
142 const ret = {};
143 cssText.split(listDelimiterRE).forEach(item => {
144 if (item) {
145 const tmp = item.split(propertyDelimiterRE);
146 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
147 }
148 });
149 return ret;
150}
151function normalizeClass(value) {
152 let res = '';
153 if (isString(value)) {
154 res = value;
155 }
156 else if (isArray(value)) {
157 for (let i = 0; i < value.length; i++) {
158 const normalized = normalizeClass(value[i]);
159 if (normalized) {
160 res += normalized + ' ';
161 }
162 }
163 }
164 else if (isObject(value)) {
165 for (const name in value) {
166 if (value[name]) {
167 res += name + ' ';
168 }
169 }
170 }
171 return res.trim();
172}
173function normalizeProps(props) {
174 if (!props)
175 return null;
176 let { class: klass, style } = props;
177 if (klass && !isString(klass)) {
178 props.class = normalizeClass(klass);
179 }
180 if (style) {
181 props.style = normalizeStyle(style);
182 }
183 return props;
184}
185
186// These tag configs are shared between compiler-dom and runtime-dom, so they
187// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
188const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
189 'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
190 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
191 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
192 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
193 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
194 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
195 'option,output,progress,select,textarea,details,dialog,menu,' +
196 'summary,template,blockquote,iframe,tfoot';
197// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
198const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
199 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
200 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
201 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
202 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
203 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
204 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
205 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
206 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
207 'text,textPath,title,tspan,unknown,use,view';
208const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
209/**
210 * Compiler only.
211 * Do NOT use in runtime code paths unless behind `true` flag.
212 */
213const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
214/**
215 * Compiler only.
216 * Do NOT use in runtime code paths unless behind `true` flag.
217 */
218const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
219/**
220 * Compiler only.
221 * Do NOT use in runtime code paths unless behind `true` flag.
222 */
223const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
224
225function looseCompareArrays(a, b) {
226 if (a.length !== b.length)
227 return false;
228 let equal = true;
229 for (let i = 0; equal && i < a.length; i++) {
230 equal = looseEqual(a[i], b[i]);
231 }
232 return equal;
233}
234function looseEqual(a, b) {
235 if (a === b)
236 return true;
237 let aValidType = isDate(a);
238 let bValidType = isDate(b);
239 if (aValidType || bValidType) {
240 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
241 }
242 aValidType = isSymbol(a);
243 bValidType = isSymbol(b);
244 if (aValidType || bValidType) {
245 return a === b;
246 }
247 aValidType = isArray(a);
248 bValidType = isArray(b);
249 if (aValidType || bValidType) {
250 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
251 }
252 aValidType = isObject(a);
253 bValidType = isObject(b);
254 if (aValidType || bValidType) {
255 /* istanbul ignore if: this if will probably never be called */
256 if (!aValidType || !bValidType) {
257 return false;
258 }
259 const aKeysCount = Object.keys(a).length;
260 const bKeysCount = Object.keys(b).length;
261 if (aKeysCount !== bKeysCount) {
262 return false;
263 }
264 for (const key in a) {
265 const aHasKey = a.hasOwnProperty(key);
266 const bHasKey = b.hasOwnProperty(key);
267 if ((aHasKey && !bHasKey) ||
268 (!aHasKey && bHasKey) ||
269 !looseEqual(a[key], b[key])) {
270 return false;
271 }
272 }
273 }
274 return String(a) === String(b);
275}
276function looseIndexOf(arr, val) {
277 return arr.findIndex(item => looseEqual(item, val));
278}
279
280/**
281 * For converting {{ interpolation }} values to displayed strings.
282 * @private
283 */
284const toDisplayString = (val) => {
285 return isString(val)
286 ? val
287 : val == null
288 ? ''
289 : isArray(val) ||
290 (isObject(val) &&
291 (val.toString === objectToString || !isFunction(val.toString)))
292 ? JSON.stringify(val, replacer, 2)
293 : String(val);
294};
295const replacer = (_key, val) => {
296 // can't use isRef here since @vue/shared has no deps
297 if (val && val.__v_isRef) {
298 return replacer(_key, val.value);
299 }
300 else if (isMap(val)) {
301 return {
302 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
303 entries[`${key} =>`] = val;
304 return entries;
305 }, {})
306 };
307 }
308 else if (isSet(val)) {
309 return {
310 [`Set(${val.size})`]: [...val.values()]
311 };
312 }
313 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
314 return String(val);
315 }
316 return val;
317};
318
319const EMPTY_OBJ = Object.freeze({})
320 ;
321const EMPTY_ARR = Object.freeze([]) ;
322const NOOP = () => { };
323/**
324 * Always return false.
325 */
326const NO = () => false;
327const onRE = /^on[^a-z]/;
328const isOn = (key) => onRE.test(key);
329const isModelListener = (key) => key.startsWith('onUpdate:');
330const extend = Object.assign;
331const remove = (arr, el) => {
332 const i = arr.indexOf(el);
333 if (i > -1) {
334 arr.splice(i, 1);
335 }
336};
337const hasOwnProperty = Object.prototype.hasOwnProperty;
338const hasOwn = (val, key) => hasOwnProperty.call(val, key);
339const isArray = Array.isArray;
340const isMap = (val) => toTypeString(val) === '[object Map]';
341const isSet = (val) => toTypeString(val) === '[object Set]';
342const isDate = (val) => toTypeString(val) === '[object Date]';
343const isFunction = (val) => typeof val === 'function';
344const isString = (val) => typeof val === 'string';
345const isSymbol = (val) => typeof val === 'symbol';
346const isObject = (val) => val !== null && typeof val === 'object';
347const isPromise = (val) => {
348 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
349};
350const objectToString = Object.prototype.toString;
351const toTypeString = (value) => objectToString.call(value);
352const toRawType = (value) => {
353 // extract "RawType" from strings like "[object RawType]"
354 return toTypeString(value).slice(8, -1);
355};
356const isPlainObject = (val) => toTypeString(val) === '[object Object]';
357const isIntegerKey = (key) => isString(key) &&
358 key !== 'NaN' &&
359 key[0] !== '-' &&
360 '' + parseInt(key, 10) === key;
361const isReservedProp = /*#__PURE__*/ makeMap(
362// the leading comma is intentional so empty string "" is also included
363',key,ref,ref_for,ref_key,' +
364 'onVnodeBeforeMount,onVnodeMounted,' +
365 'onVnodeBeforeUpdate,onVnodeUpdated,' +
366 'onVnodeBeforeUnmount,onVnodeUnmounted');
367const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
368const cacheStringFunction = (fn) => {
369 const cache = Object.create(null);
370 return ((str) => {
371 const hit = cache[str];
372 return hit || (cache[str] = fn(str));
373 });
374};
375const camelizeRE = /-(\w)/g;
376/**
377 * @private
378 */
379const camelize = cacheStringFunction((str) => {
380 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
381});
382const hyphenateRE = /\B([A-Z])/g;
383/**
384 * @private
385 */
386const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
387/**
388 * @private
389 */
390const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
391/**
392 * @private
393 */
394const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
395// compare whether a value has changed, accounting for NaN.
396const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
397const invokeArrayFns = (fns, arg) => {
398 for (let i = 0; i < fns.length; i++) {
399 fns[i](arg);
400 }
401};
402const def = (obj, key, value) => {
403 Object.defineProperty(obj, key, {
404 configurable: true,
405 enumerable: false,
406 value
407 });
408};
409const toNumber = (val) => {
410 const n = parseFloat(val);
411 return isNaN(n) ? val : n;
412};
413let _globalThis;
414const getGlobalThis = () => {
415 return (_globalThis ||
416 (_globalThis =
417 typeof globalThis !== 'undefined'
418 ? globalThis
419 : typeof self !== 'undefined'
420 ? self
421 : typeof window !== 'undefined'
422 ? window
423 : typeof global !== 'undefined'
424 ? global
425 : {}));
426};
427
428function warn(msg, ...args) {
429 console.warn(`[Vue warn] ${msg}`, ...args);
430}
431
432let activeEffectScope;
433class EffectScope {
434 constructor(detached = false) {
435 /**
436 * @internal
437 */
438 this.active = true;
439 /**
440 * @internal
441 */
442 this.effects = [];
443 /**
444 * @internal
445 */
446 this.cleanups = [];
447 if (!detached && activeEffectScope) {
448 this.parent = activeEffectScope;
449 this.index =
450 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
451 }
452 }
453 run(fn) {
454 if (this.active) {
455 const currentEffectScope = activeEffectScope;
456 try {
457 activeEffectScope = this;
458 return fn();
459 }
460 finally {
461 activeEffectScope = currentEffectScope;
462 }
463 }
464 else {
465 warn(`cannot run an inactive effect scope.`);
466 }
467 }
468 /**
469 * This should only be called on non-detached scopes
470 * @internal
471 */
472 on() {
473 activeEffectScope = this;
474 }
475 /**
476 * This should only be called on non-detached scopes
477 * @internal
478 */
479 off() {
480 activeEffectScope = this.parent;
481 }
482 stop(fromParent) {
483 if (this.active) {
484 let i, l;
485 for (i = 0, l = this.effects.length; i < l; i++) {
486 this.effects[i].stop();
487 }
488 for (i = 0, l = this.cleanups.length; i < l; i++) {
489 this.cleanups[i]();
490 }
491 if (this.scopes) {
492 for (i = 0, l = this.scopes.length; i < l; i++) {
493 this.scopes[i].stop(true);
494 }
495 }
496 // nested scope, dereference from parent to avoid memory leaks
497 if (this.parent && !fromParent) {
498 // optimized O(1) removal
499 const last = this.parent.scopes.pop();
500 if (last && last !== this) {
501 this.parent.scopes[this.index] = last;
502 last.index = this.index;
503 }
504 }
505 this.active = false;
506 }
507 }
508}
509function effectScope(detached) {
510 return new EffectScope(detached);
511}
512function recordEffectScope(effect, scope = activeEffectScope) {
513 if (scope && scope.active) {
514 scope.effects.push(effect);
515 }
516}
517function getCurrentScope() {
518 return activeEffectScope;
519}
520function onScopeDispose(fn) {
521 if (activeEffectScope) {
522 activeEffectScope.cleanups.push(fn);
523 }
524 else {
525 warn(`onScopeDispose() is called when there is no active effect scope` +
526 ` to be associated with.`);
527 }
528}
529
530const createDep = (effects) => {
531 const dep = new Set(effects);
532 dep.w = 0;
533 dep.n = 0;
534 return dep;
535};
536const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
537const newTracked = (dep) => (dep.n & trackOpBit) > 0;
538const initDepMarkers = ({ deps }) => {
539 if (deps.length) {
540 for (let i = 0; i < deps.length; i++) {
541 deps[i].w |= trackOpBit; // set was tracked
542 }
543 }
544};
545const finalizeDepMarkers = (effect) => {
546 const { deps } = effect;
547 if (deps.length) {
548 let ptr = 0;
549 for (let i = 0; i < deps.length; i++) {
550 const dep = deps[i];
551 if (wasTracked(dep) && !newTracked(dep)) {
552 dep.delete(effect);
553 }
554 else {
555 deps[ptr++] = dep;
556 }
557 // clear bits
558 dep.w &= ~trackOpBit;
559 dep.n &= ~trackOpBit;
560 }
561 deps.length = ptr;
562 }
563};
564
565const targetMap = new WeakMap();
566// The number of effects currently being tracked recursively.
567let effectTrackDepth = 0;
568let trackOpBit = 1;
569/**
570 * The bitwise track markers support at most 30 levels of recursion.
571 * This value is chosen to enable modern JS engines to use a SMI on all platforms.
572 * When recursion depth is greater, fall back to using a full cleanup.
573 */
574const maxMarkerBits = 30;
575let activeEffect;
576const ITERATE_KEY = Symbol('iterate' );
577const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
578class ReactiveEffect {
579 constructor(fn, scheduler = null, scope) {
580 this.fn = fn;
581 this.scheduler = scheduler;
582 this.active = true;
583 this.deps = [];
584 this.parent = undefined;
585 recordEffectScope(this, scope);
586 }
587 run() {
588 if (!this.active) {
589 return this.fn();
590 }
591 let parent = activeEffect;
592 let lastShouldTrack = shouldTrack;
593 while (parent) {
594 if (parent === this) {
595 return;
596 }
597 parent = parent.parent;
598 }
599 try {
600 this.parent = activeEffect;
601 activeEffect = this;
602 shouldTrack = true;
603 trackOpBit = 1 << ++effectTrackDepth;
604 if (effectTrackDepth <= maxMarkerBits) {
605 initDepMarkers(this);
606 }
607 else {
608 cleanupEffect(this);
609 }
610 return this.fn();
611 }
612 finally {
613 if (effectTrackDepth <= maxMarkerBits) {
614 finalizeDepMarkers(this);
615 }
616 trackOpBit = 1 << --effectTrackDepth;
617 activeEffect = this.parent;
618 shouldTrack = lastShouldTrack;
619 this.parent = undefined;
620 if (this.deferStop) {
621 this.stop();
622 }
623 }
624 }
625 stop() {
626 // stopped while running itself - defer the cleanup
627 if (activeEffect === this) {
628 this.deferStop = true;
629 }
630 else if (this.active) {
631 cleanupEffect(this);
632 if (this.onStop) {
633 this.onStop();
634 }
635 this.active = false;
636 }
637 }
638}
639function cleanupEffect(effect) {
640 const { deps } = effect;
641 if (deps.length) {
642 for (let i = 0; i < deps.length; i++) {
643 deps[i].delete(effect);
644 }
645 deps.length = 0;
646 }
647}
648function effect(fn, options) {
649 if (fn.effect) {
650 fn = fn.effect.fn;
651 }
652 const _effect = new ReactiveEffect(fn);
653 if (options) {
654 extend(_effect, options);
655 if (options.scope)
656 recordEffectScope(_effect, options.scope);
657 }
658 if (!options || !options.lazy) {
659 _effect.run();
660 }
661 const runner = _effect.run.bind(_effect);
662 runner.effect = _effect;
663 return runner;
664}
665function stop(runner) {
666 runner.effect.stop();
667}
668let shouldTrack = true;
669const trackStack = [];
670function pauseTracking() {
671 trackStack.push(shouldTrack);
672 shouldTrack = false;
673}
674function resetTracking() {
675 const last = trackStack.pop();
676 shouldTrack = last === undefined ? true : last;
677}
678function track(target, type, key) {
679 if (shouldTrack && activeEffect) {
680 let depsMap = targetMap.get(target);
681 if (!depsMap) {
682 targetMap.set(target, (depsMap = new Map()));
683 }
684 let dep = depsMap.get(key);
685 if (!dep) {
686 depsMap.set(key, (dep = createDep()));
687 }
688 const eventInfo = { effect: activeEffect, target, type, key }
689 ;
690 trackEffects(dep, eventInfo);
691 }
692}
693function trackEffects(dep, debuggerEventExtraInfo) {
694 let shouldTrack = false;
695 if (effectTrackDepth <= maxMarkerBits) {
696 if (!newTracked(dep)) {
697 dep.n |= trackOpBit; // set newly tracked
698 shouldTrack = !wasTracked(dep);
699 }
700 }
701 else {
702 // Full cleanup mode.
703 shouldTrack = !dep.has(activeEffect);
704 }
705 if (shouldTrack) {
706 dep.add(activeEffect);
707 activeEffect.deps.push(dep);
708 if (activeEffect.onTrack) {
709 activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo));
710 }
711 }
712}
713function trigger(target, type, key, newValue, oldValue, oldTarget) {
714 const depsMap = targetMap.get(target);
715 if (!depsMap) {
716 // never been tracked
717 return;
718 }
719 let deps = [];
720 if (type === "clear" /* CLEAR */) {
721 // collection being cleared
722 // trigger all effects for target
723 deps = [...depsMap.values()];
724 }
725 else if (key === 'length' && isArray(target)) {
726 depsMap.forEach((dep, key) => {
727 if (key === 'length' || key >= newValue) {
728 deps.push(dep);
729 }
730 });
731 }
732 else {
733 // schedule runs for SET | ADD | DELETE
734 if (key !== void 0) {
735 deps.push(depsMap.get(key));
736 }
737 // also run for iteration key on ADD | DELETE | Map.SET
738 switch (type) {
739 case "add" /* ADD */:
740 if (!isArray(target)) {
741 deps.push(depsMap.get(ITERATE_KEY));
742 if (isMap(target)) {
743 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
744 }
745 }
746 else if (isIntegerKey(key)) {
747 // new index added to array -> length changes
748 deps.push(depsMap.get('length'));
749 }
750 break;
751 case "delete" /* DELETE */:
752 if (!isArray(target)) {
753 deps.push(depsMap.get(ITERATE_KEY));
754 if (isMap(target)) {
755 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
756 }
757 }
758 break;
759 case "set" /* SET */:
760 if (isMap(target)) {
761 deps.push(depsMap.get(ITERATE_KEY));
762 }
763 break;
764 }
765 }
766 const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
767 ;
768 if (deps.length === 1) {
769 if (deps[0]) {
770 {
771 triggerEffects(deps[0], eventInfo);
772 }
773 }
774 }
775 else {
776 const effects = [];
777 for (const dep of deps) {
778 if (dep) {
779 effects.push(...dep);
780 }
781 }
782 {
783 triggerEffects(createDep(effects), eventInfo);
784 }
785 }
786}
787function triggerEffects(dep, debuggerEventExtraInfo) {
788 // spread into array for stabilization
789 const effects = isArray(dep) ? dep : [...dep];
790 for (const effect of effects) {
791 if (effect.computed) {
792 triggerEffect(effect, debuggerEventExtraInfo);
793 }
794 }
795 for (const effect of effects) {
796 if (!effect.computed) {
797 triggerEffect(effect, debuggerEventExtraInfo);
798 }
799 }
800}
801function triggerEffect(effect, debuggerEventExtraInfo) {
802 if (effect !== activeEffect || effect.allowRecurse) {
803 if (effect.onTrigger) {
804 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
805 }
806 if (effect.scheduler) {
807 effect.scheduler();
808 }
809 else {
810 effect.run();
811 }
812 }
813}
814
815const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
816const builtInSymbols = new Set(
817/*#__PURE__*/
818Object.getOwnPropertyNames(Symbol)
819 // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
820 // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
821 // function
822 .filter(key => key !== 'arguments' && key !== 'caller')
823 .map(key => Symbol[key])
824 .filter(isSymbol));
825const get = /*#__PURE__*/ createGetter();
826const shallowGet = /*#__PURE__*/ createGetter(false, true);
827const readonlyGet = /*#__PURE__*/ createGetter(true);
828const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
829const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
830function createArrayInstrumentations() {
831 const instrumentations = {};
832 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
833 instrumentations[key] = function (...args) {
834 const arr = toRaw(this);
835 for (let i = 0, l = this.length; i < l; i++) {
836 track(arr, "get" /* GET */, i + '');
837 }
838 // we run the method using the original args first (which may be reactive)
839 const res = arr[key](...args);
840 if (res === -1 || res === false) {
841 // if that didn't work, run it again using raw values.
842 return arr[key](...args.map(toRaw));
843 }
844 else {
845 return res;
846 }
847 };
848 });
849 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
850 instrumentations[key] = function (...args) {
851 pauseTracking();
852 const res = toRaw(this)[key].apply(this, args);
853 resetTracking();
854 return res;
855 };
856 });
857 return instrumentations;
858}
859function createGetter(isReadonly = false, shallow = false) {
860 return function get(target, key, receiver) {
861 if (key === "__v_isReactive" /* IS_REACTIVE */) {
862 return !isReadonly;
863 }
864 else if (key === "__v_isReadonly" /* IS_READONLY */) {
865 return isReadonly;
866 }
867 else if (key === "__v_isShallow" /* IS_SHALLOW */) {
868 return shallow;
869 }
870 else if (key === "__v_raw" /* RAW */ &&
871 receiver ===
872 (isReadonly
873 ? shallow
874 ? shallowReadonlyMap
875 : readonlyMap
876 : shallow
877 ? shallowReactiveMap
878 : reactiveMap).get(target)) {
879 return target;
880 }
881 const targetIsArray = isArray(target);
882 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
883 return Reflect.get(arrayInstrumentations, key, receiver);
884 }
885 const res = Reflect.get(target, key, receiver);
886 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
887 return res;
888 }
889 if (!isReadonly) {
890 track(target, "get" /* GET */, key);
891 }
892 if (shallow) {
893 return res;
894 }
895 if (isRef(res)) {
896 // ref unwrapping - skip unwrap for Array + integer key.
897 return targetIsArray && isIntegerKey(key) ? res : res.value;
898 }
899 if (isObject(res)) {
900 // Convert returned value into a proxy as well. we do the isObject check
901 // here to avoid invalid value warning. Also need to lazy access readonly
902 // and reactive here to avoid circular dependency.
903 return isReadonly ? readonly(res) : reactive(res);
904 }
905 return res;
906 };
907}
908const set = /*#__PURE__*/ createSetter();
909const shallowSet = /*#__PURE__*/ createSetter(true);
910function createSetter(shallow = false) {
911 return function set(target, key, value, receiver) {
912 let oldValue = target[key];
913 if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
914 return false;
915 }
916 if (!shallow && !isReadonly(value)) {
917 if (!isShallow(value)) {
918 value = toRaw(value);
919 oldValue = toRaw(oldValue);
920 }
921 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
922 oldValue.value = value;
923 return true;
924 }
925 }
926 const hadKey = isArray(target) && isIntegerKey(key)
927 ? Number(key) < target.length
928 : hasOwn(target, key);
929 const result = Reflect.set(target, key, value, receiver);
930 // don't trigger if target is something up in the prototype chain of original
931 if (target === toRaw(receiver)) {
932 if (!hadKey) {
933 trigger(target, "add" /* ADD */, key, value);
934 }
935 else if (hasChanged(value, oldValue)) {
936 trigger(target, "set" /* SET */, key, value, oldValue);
937 }
938 }
939 return result;
940 };
941}
942function deleteProperty(target, key) {
943 const hadKey = hasOwn(target, key);
944 const oldValue = target[key];
945 const result = Reflect.deleteProperty(target, key);
946 if (result && hadKey) {
947 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
948 }
949 return result;
950}
951function has(target, key) {
952 const result = Reflect.has(target, key);
953 if (!isSymbol(key) || !builtInSymbols.has(key)) {
954 track(target, "has" /* HAS */, key);
955 }
956 return result;
957}
958function ownKeys(target) {
959 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
960 return Reflect.ownKeys(target);
961}
962const mutableHandlers = {
963 get,
964 set,
965 deleteProperty,
966 has,
967 ownKeys
968};
969const readonlyHandlers = {
970 get: readonlyGet,
971 set(target, key) {
972 {
973 warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
974 }
975 return true;
976 },
977 deleteProperty(target, key) {
978 {
979 warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
980 }
981 return true;
982 }
983};
984const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
985 get: shallowGet,
986 set: shallowSet
987});
988// Props handlers are special in the sense that it should not unwrap top-level
989// refs (in order to allow refs to be explicitly passed down), but should
990// retain the reactivity of the normal readonly object.
991const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
992 get: shallowReadonlyGet
993});
994
995const toShallow = (value) => value;
996const getProto = (v) => Reflect.getPrototypeOf(v);
997function get$1(target, key, isReadonly = false, isShallow = false) {
998 // #1772: readonly(reactive(Map)) should return readonly + reactive version
999 // of the value
1000 target = target["__v_raw" /* RAW */];
1001 const rawTarget = toRaw(target);
1002 const rawKey = toRaw(key);
1003 if (!isReadonly) {
1004 if (key !== rawKey) {
1005 track(rawTarget, "get" /* GET */, key);
1006 }
1007 track(rawTarget, "get" /* GET */, rawKey);
1008 }
1009 const { has } = getProto(rawTarget);
1010 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1011 if (has.call(rawTarget, key)) {
1012 return wrap(target.get(key));
1013 }
1014 else if (has.call(rawTarget, rawKey)) {
1015 return wrap(target.get(rawKey));
1016 }
1017 else if (target !== rawTarget) {
1018 // #3602 readonly(reactive(Map))
1019 // ensure that the nested reactive `Map` can do tracking for itself
1020 target.get(key);
1021 }
1022}
1023function has$1(key, isReadonly = false) {
1024 const target = this["__v_raw" /* RAW */];
1025 const rawTarget = toRaw(target);
1026 const rawKey = toRaw(key);
1027 if (!isReadonly) {
1028 if (key !== rawKey) {
1029 track(rawTarget, "has" /* HAS */, key);
1030 }
1031 track(rawTarget, "has" /* HAS */, rawKey);
1032 }
1033 return key === rawKey
1034 ? target.has(key)
1035 : target.has(key) || target.has(rawKey);
1036}
1037function size(target, isReadonly = false) {
1038 target = target["__v_raw" /* RAW */];
1039 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
1040 return Reflect.get(target, 'size', target);
1041}
1042function add(value) {
1043 value = toRaw(value);
1044 const target = toRaw(this);
1045 const proto = getProto(target);
1046 const hadKey = proto.has.call(target, value);
1047 if (!hadKey) {
1048 target.add(value);
1049 trigger(target, "add" /* ADD */, value, value);
1050 }
1051 return this;
1052}
1053function set$1(key, value) {
1054 value = toRaw(value);
1055 const target = toRaw(this);
1056 const { has, get } = getProto(target);
1057 let hadKey = has.call(target, key);
1058 if (!hadKey) {
1059 key = toRaw(key);
1060 hadKey = has.call(target, key);
1061 }
1062 else {
1063 checkIdentityKeys(target, has, key);
1064 }
1065 const oldValue = get.call(target, key);
1066 target.set(key, value);
1067 if (!hadKey) {
1068 trigger(target, "add" /* ADD */, key, value);
1069 }
1070 else if (hasChanged(value, oldValue)) {
1071 trigger(target, "set" /* SET */, key, value, oldValue);
1072 }
1073 return this;
1074}
1075function deleteEntry(key) {
1076 const target = toRaw(this);
1077 const { has, get } = getProto(target);
1078 let hadKey = has.call(target, key);
1079 if (!hadKey) {
1080 key = toRaw(key);
1081 hadKey = has.call(target, key);
1082 }
1083 else {
1084 checkIdentityKeys(target, has, key);
1085 }
1086 const oldValue = get ? get.call(target, key) : undefined;
1087 // forward the operation before queueing reactions
1088 const result = target.delete(key);
1089 if (hadKey) {
1090 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
1091 }
1092 return result;
1093}
1094function clear() {
1095 const target = toRaw(this);
1096 const hadItems = target.size !== 0;
1097 const oldTarget = isMap(target)
1098 ? new Map(target)
1099 : new Set(target)
1100 ;
1101 // forward the operation before queueing reactions
1102 const result = target.clear();
1103 if (hadItems) {
1104 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
1105 }
1106 return result;
1107}
1108function createForEach(isReadonly, isShallow) {
1109 return function forEach(callback, thisArg) {
1110 const observed = this;
1111 const target = observed["__v_raw" /* RAW */];
1112 const rawTarget = toRaw(target);
1113 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1114 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
1115 return target.forEach((value, key) => {
1116 // important: make sure the callback is
1117 // 1. invoked with the reactive map as `this` and 3rd arg
1118 // 2. the value received should be a corresponding reactive/readonly.
1119 return callback.call(thisArg, wrap(value), wrap(key), observed);
1120 });
1121 };
1122}
1123function createIterableMethod(method, isReadonly, isShallow) {
1124 return function (...args) {
1125 const target = this["__v_raw" /* RAW */];
1126 const rawTarget = toRaw(target);
1127 const targetIsMap = isMap(rawTarget);
1128 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
1129 const isKeyOnly = method === 'keys' && targetIsMap;
1130 const innerIterator = target[method](...args);
1131 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1132 !isReadonly &&
1133 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
1134 // return a wrapped iterator which returns observed versions of the
1135 // values emitted from the real iterator
1136 return {
1137 // iterator protocol
1138 next() {
1139 const { value, done } = innerIterator.next();
1140 return done
1141 ? { value, done }
1142 : {
1143 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1144 done
1145 };
1146 },
1147 // iterable protocol
1148 [Symbol.iterator]() {
1149 return this;
1150 }
1151 };
1152 };
1153}
1154function createReadonlyMethod(type) {
1155 return function (...args) {
1156 {
1157 const key = args[0] ? `on key "${args[0]}" ` : ``;
1158 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
1159 }
1160 return type === "delete" /* DELETE */ ? false : this;
1161 };
1162}
1163function createInstrumentations() {
1164 const mutableInstrumentations = {
1165 get(key) {
1166 return get$1(this, key);
1167 },
1168 get size() {
1169 return size(this);
1170 },
1171 has: has$1,
1172 add,
1173 set: set$1,
1174 delete: deleteEntry,
1175 clear,
1176 forEach: createForEach(false, false)
1177 };
1178 const shallowInstrumentations = {
1179 get(key) {
1180 return get$1(this, key, false, true);
1181 },
1182 get size() {
1183 return size(this);
1184 },
1185 has: has$1,
1186 add,
1187 set: set$1,
1188 delete: deleteEntry,
1189 clear,
1190 forEach: createForEach(false, true)
1191 };
1192 const readonlyInstrumentations = {
1193 get(key) {
1194 return get$1(this, key, true);
1195 },
1196 get size() {
1197 return size(this, true);
1198 },
1199 has(key) {
1200 return has$1.call(this, key, true);
1201 },
1202 add: createReadonlyMethod("add" /* ADD */),
1203 set: createReadonlyMethod("set" /* SET */),
1204 delete: createReadonlyMethod("delete" /* DELETE */),
1205 clear: createReadonlyMethod("clear" /* CLEAR */),
1206 forEach: createForEach(true, false)
1207 };
1208 const shallowReadonlyInstrumentations = {
1209 get(key) {
1210 return get$1(this, key, true, true);
1211 },
1212 get size() {
1213 return size(this, true);
1214 },
1215 has(key) {
1216 return has$1.call(this, key, true);
1217 },
1218 add: createReadonlyMethod("add" /* ADD */),
1219 set: createReadonlyMethod("set" /* SET */),
1220 delete: createReadonlyMethod("delete" /* DELETE */),
1221 clear: createReadonlyMethod("clear" /* CLEAR */),
1222 forEach: createForEach(true, true)
1223 };
1224 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
1225 iteratorMethods.forEach(method => {
1226 mutableInstrumentations[method] = createIterableMethod(method, false, false);
1227 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
1228 shallowInstrumentations[method] = createIterableMethod(method, false, true);
1229 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
1230 });
1231 return [
1232 mutableInstrumentations,
1233 readonlyInstrumentations,
1234 shallowInstrumentations,
1235 shallowReadonlyInstrumentations
1236 ];
1237}
1238const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
1239function createInstrumentationGetter(isReadonly, shallow) {
1240 const instrumentations = shallow
1241 ? isReadonly
1242 ? shallowReadonlyInstrumentations
1243 : shallowInstrumentations
1244 : isReadonly
1245 ? readonlyInstrumentations
1246 : mutableInstrumentations;
1247 return (target, key, receiver) => {
1248 if (key === "__v_isReactive" /* IS_REACTIVE */) {
1249 return !isReadonly;
1250 }
1251 else if (key === "__v_isReadonly" /* IS_READONLY */) {
1252 return isReadonly;
1253 }
1254 else if (key === "__v_raw" /* RAW */) {
1255 return target;
1256 }
1257 return Reflect.get(hasOwn(instrumentations, key) && key in target
1258 ? instrumentations
1259 : target, key, receiver);
1260 };
1261}
1262const mutableCollectionHandlers = {
1263 get: /*#__PURE__*/ createInstrumentationGetter(false, false)
1264};
1265const shallowCollectionHandlers = {
1266 get: /*#__PURE__*/ createInstrumentationGetter(false, true)
1267};
1268const readonlyCollectionHandlers = {
1269 get: /*#__PURE__*/ createInstrumentationGetter(true, false)
1270};
1271const shallowReadonlyCollectionHandlers = {
1272 get: /*#__PURE__*/ createInstrumentationGetter(true, true)
1273};
1274function checkIdentityKeys(target, has, key) {
1275 const rawKey = toRaw(key);
1276 if (rawKey !== key && has.call(target, rawKey)) {
1277 const type = toRawType(target);
1278 console.warn(`Reactive ${type} contains both the raw and reactive ` +
1279 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
1280 `which can lead to inconsistencies. ` +
1281 `Avoid differentiating between the raw and reactive versions ` +
1282 `of an object and only use the reactive version if possible.`);
1283 }
1284}
1285
1286const reactiveMap = new WeakMap();
1287const shallowReactiveMap = new WeakMap();
1288const readonlyMap = new WeakMap();
1289const shallowReadonlyMap = new WeakMap();
1290function targetTypeMap(rawType) {
1291 switch (rawType) {
1292 case 'Object':
1293 case 'Array':
1294 return 1 /* COMMON */;
1295 case 'Map':
1296 case 'Set':
1297 case 'WeakMap':
1298 case 'WeakSet':
1299 return 2 /* COLLECTION */;
1300 default:
1301 return 0 /* INVALID */;
1302 }
1303}
1304function getTargetType(value) {
1305 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1306 ? 0 /* INVALID */
1307 : targetTypeMap(toRawType(value));
1308}
1309function reactive(target) {
1310 // if trying to observe a readonly proxy, return the readonly version.
1311 if (isReadonly(target)) {
1312 return target;
1313 }
1314 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1315}
1316/**
1317 * Return a shallowly-reactive copy of the original object, where only the root
1318 * level properties are reactive. It also does not auto-unwrap refs (even at the
1319 * root level).
1320 */
1321function shallowReactive(target) {
1322 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1323}
1324/**
1325 * Creates a readonly copy of the original object. Note the returned copy is not
1326 * made reactive, but `readonly` can be called on an already reactive object.
1327 */
1328function readonly(target) {
1329 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1330}
1331/**
1332 * Returns a reactive-copy of the original object, where only the root level
1333 * properties are readonly, and does NOT unwrap refs nor recursively convert
1334 * returned properties.
1335 * This is used for creating the props proxy object for stateful components.
1336 */
1337function shallowReadonly(target) {
1338 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1339}
1340function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1341 if (!isObject(target)) {
1342 {
1343 console.warn(`value cannot be made reactive: ${String(target)}`);
1344 }
1345 return target;
1346 }
1347 // target is already a Proxy, return it.
1348 // exception: calling readonly() on a reactive object
1349 if (target["__v_raw" /* RAW */] &&
1350 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1351 return target;
1352 }
1353 // target already has corresponding Proxy
1354 const existingProxy = proxyMap.get(target);
1355 if (existingProxy) {
1356 return existingProxy;
1357 }
1358 // only specific value types can be observed.
1359 const targetType = getTargetType(target);
1360 if (targetType === 0 /* INVALID */) {
1361 return target;
1362 }
1363 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1364 proxyMap.set(target, proxy);
1365 return proxy;
1366}
1367function isReactive(value) {
1368 if (isReadonly(value)) {
1369 return isReactive(value["__v_raw" /* RAW */]);
1370 }
1371 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1372}
1373function isReadonly(value) {
1374 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1375}
1376function isShallow(value) {
1377 return !!(value && value["__v_isShallow" /* IS_SHALLOW */]);
1378}
1379function isProxy(value) {
1380 return isReactive(value) || isReadonly(value);
1381}
1382function toRaw(observed) {
1383 const raw = observed && observed["__v_raw" /* RAW */];
1384 return raw ? toRaw(raw) : observed;
1385}
1386function markRaw(value) {
1387 def(value, "__v_skip" /* SKIP */, true);
1388 return value;
1389}
1390const toReactive = (value) => isObject(value) ? reactive(value) : value;
1391const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1392
1393function trackRefValue(ref) {
1394 if (shouldTrack && activeEffect) {
1395 ref = toRaw(ref);
1396 {
1397 trackEffects(ref.dep || (ref.dep = createDep()), {
1398 target: ref,
1399 type: "get" /* GET */,
1400 key: 'value'
1401 });
1402 }
1403 }
1404}
1405function triggerRefValue(ref, newVal) {
1406 ref = toRaw(ref);
1407 if (ref.dep) {
1408 {
1409 triggerEffects(ref.dep, {
1410 target: ref,
1411 type: "set" /* SET */,
1412 key: 'value',
1413 newValue: newVal
1414 });
1415 }
1416 }
1417}
1418function isRef(r) {
1419 return !!(r && r.__v_isRef === true);
1420}
1421function ref(value) {
1422 return createRef(value, false);
1423}
1424function shallowRef(value) {
1425 return createRef(value, true);
1426}
1427function createRef(rawValue, shallow) {
1428 if (isRef(rawValue)) {
1429 return rawValue;
1430 }
1431 return new RefImpl(rawValue, shallow);
1432}
1433class RefImpl {
1434 constructor(value, __v_isShallow) {
1435 this.__v_isShallow = __v_isShallow;
1436 this.dep = undefined;
1437 this.__v_isRef = true;
1438 this._rawValue = __v_isShallow ? value : toRaw(value);
1439 this._value = __v_isShallow ? value : toReactive(value);
1440 }
1441 get value() {
1442 trackRefValue(this);
1443 return this._value;
1444 }
1445 set value(newVal) {
1446 newVal = this.__v_isShallow ? newVal : toRaw(newVal);
1447 if (hasChanged(newVal, this._rawValue)) {
1448 this._rawValue = newVal;
1449 this._value = this.__v_isShallow ? newVal : toReactive(newVal);
1450 triggerRefValue(this, newVal);
1451 }
1452 }
1453}
1454function triggerRef(ref) {
1455 triggerRefValue(ref, ref.value );
1456}
1457function unref(ref) {
1458 return isRef(ref) ? ref.value : ref;
1459}
1460const shallowUnwrapHandlers = {
1461 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1462 set: (target, key, value, receiver) => {
1463 const oldValue = target[key];
1464 if (isRef(oldValue) && !isRef(value)) {
1465 oldValue.value = value;
1466 return true;
1467 }
1468 else {
1469 return Reflect.set(target, key, value, receiver);
1470 }
1471 }
1472};
1473function proxyRefs(objectWithRefs) {
1474 return isReactive(objectWithRefs)
1475 ? objectWithRefs
1476 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1477}
1478class CustomRefImpl {
1479 constructor(factory) {
1480 this.dep = undefined;
1481 this.__v_isRef = true;
1482 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
1483 this._get = get;
1484 this._set = set;
1485 }
1486 get value() {
1487 return this._get();
1488 }
1489 set value(newVal) {
1490 this._set(newVal);
1491 }
1492}
1493function customRef(factory) {
1494 return new CustomRefImpl(factory);
1495}
1496function toRefs(object) {
1497 if (!isProxy(object)) {
1498 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1499 }
1500 const ret = isArray(object) ? new Array(object.length) : {};
1501 for (const key in object) {
1502 ret[key] = toRef(object, key);
1503 }
1504 return ret;
1505}
1506class ObjectRefImpl {
1507 constructor(_object, _key, _defaultValue) {
1508 this._object = _object;
1509 this._key = _key;
1510 this._defaultValue = _defaultValue;
1511 this.__v_isRef = true;
1512 }
1513 get value() {
1514 const val = this._object[this._key];
1515 return val === undefined ? this._defaultValue : val;
1516 }
1517 set value(newVal) {
1518 this._object[this._key] = newVal;
1519 }
1520}
1521function toRef(object, key, defaultValue) {
1522 const val = object[key];
1523 return isRef(val)
1524 ? val
1525 : new ObjectRefImpl(object, key, defaultValue);
1526}
1527
1528class ComputedRefImpl {
1529 constructor(getter, _setter, isReadonly, isSSR) {
1530 this._setter = _setter;
1531 this.dep = undefined;
1532 this.__v_isRef = true;
1533 this._dirty = true;
1534 this.effect = new ReactiveEffect(getter, () => {
1535 if (!this._dirty) {
1536 this._dirty = true;
1537 triggerRefValue(this);
1538 }
1539 });
1540 this.effect.computed = this;
1541 this.effect.active = this._cacheable = !isSSR;
1542 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1543 }
1544 get value() {
1545 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1546 const self = toRaw(this);
1547 trackRefValue(self);
1548 if (self._dirty || !self._cacheable) {
1549 self._dirty = false;
1550 self._value = self.effect.run();
1551 }
1552 return self._value;
1553 }
1554 set value(newValue) {
1555 this._setter(newValue);
1556 }
1557}
1558function computed(getterOrOptions, debugOptions, isSSR = false) {
1559 let getter;
1560 let setter;
1561 const onlyGetter = isFunction(getterOrOptions);
1562 if (onlyGetter) {
1563 getter = getterOrOptions;
1564 setter = () => {
1565 console.warn('Write operation failed: computed value is readonly');
1566 }
1567 ;
1568 }
1569 else {
1570 getter = getterOrOptions.get;
1571 setter = getterOrOptions.set;
1572 }
1573 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1574 if (debugOptions && !isSSR) {
1575 cRef.effect.onTrack = debugOptions.onTrack;
1576 cRef.effect.onTrigger = debugOptions.onTrigger;
1577 }
1578 return cRef;
1579}
1580
1581const stack = [];
1582function pushWarningContext(vnode) {
1583 stack.push(vnode);
1584}
1585function popWarningContext() {
1586 stack.pop();
1587}
1588function warn$1(msg, ...args) {
1589 // avoid props formatting or warn handler tracking deps that might be mutated
1590 // during patch, leading to infinite recursion.
1591 pauseTracking();
1592 const instance = stack.length ? stack[stack.length - 1].component : null;
1593 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1594 const trace = getComponentTrace();
1595 if (appWarnHandler) {
1596 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1597 msg + args.join(''),
1598 instance && instance.proxy,
1599 trace
1600 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1601 .join('\n'),
1602 trace
1603 ]);
1604 }
1605 else {
1606 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1607 /* istanbul ignore if */
1608 if (trace.length &&
1609 // avoid spamming console during tests
1610 !false) {
1611 warnArgs.push(`\n`, ...formatTrace(trace));
1612 }
1613 console.warn(...warnArgs);
1614 }
1615 resetTracking();
1616}
1617function getComponentTrace() {
1618 let currentVNode = stack[stack.length - 1];
1619 if (!currentVNode) {
1620 return [];
1621 }
1622 // we can't just use the stack because it will be incomplete during updates
1623 // that did not start from the root. Re-construct the parent chain using
1624 // instance parent pointers.
1625 const normalizedStack = [];
1626 while (currentVNode) {
1627 const last = normalizedStack[0];
1628 if (last && last.vnode === currentVNode) {
1629 last.recurseCount++;
1630 }
1631 else {
1632 normalizedStack.push({
1633 vnode: currentVNode,
1634 recurseCount: 0
1635 });
1636 }
1637 const parentInstance = currentVNode.component && currentVNode.component.parent;
1638 currentVNode = parentInstance && parentInstance.vnode;
1639 }
1640 return normalizedStack;
1641}
1642/* istanbul ignore next */
1643function formatTrace(trace) {
1644 const logs = [];
1645 trace.forEach((entry, i) => {
1646 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1647 });
1648 return logs;
1649}
1650function formatTraceEntry({ vnode, recurseCount }) {
1651 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1652 const isRoot = vnode.component ? vnode.component.parent == null : false;
1653 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1654 const close = `>` + postfix;
1655 return vnode.props
1656 ? [open, ...formatProps(vnode.props), close]
1657 : [open + close];
1658}
1659/* istanbul ignore next */
1660function formatProps(props) {
1661 const res = [];
1662 const keys = Object.keys(props);
1663 keys.slice(0, 3).forEach(key => {
1664 res.push(...formatProp(key, props[key]));
1665 });
1666 if (keys.length > 3) {
1667 res.push(` ...`);
1668 }
1669 return res;
1670}
1671/* istanbul ignore next */
1672function formatProp(key, value, raw) {
1673 if (isString(value)) {
1674 value = JSON.stringify(value);
1675 return raw ? value : [`${key}=${value}`];
1676 }
1677 else if (typeof value === 'number' ||
1678 typeof value === 'boolean' ||
1679 value == null) {
1680 return raw ? value : [`${key}=${value}`];
1681 }
1682 else if (isRef(value)) {
1683 value = formatProp(key, toRaw(value.value), true);
1684 return raw ? value : [`${key}=Ref<`, value, `>`];
1685 }
1686 else if (isFunction(value)) {
1687 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1688 }
1689 else {
1690 value = toRaw(value);
1691 return raw ? value : [`${key}=`, value];
1692 }
1693}
1694
1695const ErrorTypeStrings = {
1696 ["sp" /* SERVER_PREFETCH */]: 'serverPrefetch hook',
1697 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1698 ["c" /* CREATED */]: 'created hook',
1699 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1700 ["m" /* MOUNTED */]: 'mounted hook',
1701 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1702 ["u" /* UPDATED */]: 'updated',
1703 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1704 ["um" /* UNMOUNTED */]: 'unmounted hook',
1705 ["a" /* ACTIVATED */]: 'activated hook',
1706 ["da" /* DEACTIVATED */]: 'deactivated hook',
1707 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1708 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1709 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1710 [0 /* SETUP_FUNCTION */]: 'setup function',
1711 [1 /* RENDER_FUNCTION */]: 'render function',
1712 [2 /* WATCH_GETTER */]: 'watcher getter',
1713 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1714 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1715 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1716 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1717 [7 /* VNODE_HOOK */]: 'vnode hook',
1718 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1719 [9 /* TRANSITION_HOOK */]: 'transition hook',
1720 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1721 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1722 [12 /* FUNCTION_REF */]: 'ref function',
1723 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1724 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1725 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
1726};
1727function callWithErrorHandling(fn, instance, type, args) {
1728 let res;
1729 try {
1730 res = args ? fn(...args) : fn();
1731 }
1732 catch (err) {
1733 handleError(err, instance, type);
1734 }
1735 return res;
1736}
1737function callWithAsyncErrorHandling(fn, instance, type, args) {
1738 if (isFunction(fn)) {
1739 const res = callWithErrorHandling(fn, instance, type, args);
1740 if (res && isPromise(res)) {
1741 res.catch(err => {
1742 handleError(err, instance, type);
1743 });
1744 }
1745 return res;
1746 }
1747 const values = [];
1748 for (let i = 0; i < fn.length; i++) {
1749 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1750 }
1751 return values;
1752}
1753function handleError(err, instance, type, throwInDev = true) {
1754 const contextVNode = instance ? instance.vnode : null;
1755 if (instance) {
1756 let cur = instance.parent;
1757 // the exposed instance is the render proxy to keep it consistent with 2.x
1758 const exposedInstance = instance.proxy;
1759 // in production the hook receives only the error code
1760 const errorInfo = ErrorTypeStrings[type] ;
1761 while (cur) {
1762 const errorCapturedHooks = cur.ec;
1763 if (errorCapturedHooks) {
1764 for (let i = 0; i < errorCapturedHooks.length; i++) {
1765 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1766 return;
1767 }
1768 }
1769 }
1770 cur = cur.parent;
1771 }
1772 // app-level handling
1773 const appErrorHandler = instance.appContext.config.errorHandler;
1774 if (appErrorHandler) {
1775 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1776 return;
1777 }
1778 }
1779 logError(err, type, contextVNode, throwInDev);
1780}
1781function logError(err, type, contextVNode, throwInDev = true) {
1782 {
1783 const info = ErrorTypeStrings[type];
1784 if (contextVNode) {
1785 pushWarningContext(contextVNode);
1786 }
1787 warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1788 if (contextVNode) {
1789 popWarningContext();
1790 }
1791 // crash in dev by default so it's more noticeable
1792 if (throwInDev) {
1793 throw err;
1794 }
1795 else {
1796 console.error(err);
1797 }
1798 }
1799}
1800
1801let isFlushing = false;
1802let isFlushPending = false;
1803const queue = [];
1804let flushIndex = 0;
1805const pendingPreFlushCbs = [];
1806let activePreFlushCbs = null;
1807let preFlushIndex = 0;
1808const pendingPostFlushCbs = [];
1809let activePostFlushCbs = null;
1810let postFlushIndex = 0;
1811const resolvedPromise = /*#__PURE__*/ Promise.resolve();
1812let currentFlushPromise = null;
1813let currentPreFlushParentJob = null;
1814const RECURSION_LIMIT = 100;
1815function nextTick(fn) {
1816 const p = currentFlushPromise || resolvedPromise;
1817 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1818}
1819// #2768
1820// Use binary-search to find a suitable position in the queue,
1821// so that the queue maintains the increasing order of job's id,
1822// which can prevent the job from being skipped and also can avoid repeated patching.
1823function findInsertionIndex(id) {
1824 // the start index should be `flushIndex + 1`
1825 let start = flushIndex + 1;
1826 let end = queue.length;
1827 while (start < end) {
1828 const middle = (start + end) >>> 1;
1829 const middleJobId = getId(queue[middle]);
1830 middleJobId < id ? (start = middle + 1) : (end = middle);
1831 }
1832 return start;
1833}
1834function queueJob(job) {
1835 // the dedupe search uses the startIndex argument of Array.includes()
1836 // by default the search index includes the current job that is being run
1837 // so it cannot recursively trigger itself again.
1838 // if the job is a watch() callback, the search will start with a +1 index to
1839 // allow it recursively trigger itself - it is the user's responsibility to
1840 // ensure it doesn't end up in an infinite loop.
1841 if ((!queue.length ||
1842 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1843 job !== currentPreFlushParentJob) {
1844 if (job.id == null) {
1845 queue.push(job);
1846 }
1847 else {
1848 queue.splice(findInsertionIndex(job.id), 0, job);
1849 }
1850 queueFlush();
1851 }
1852}
1853function queueFlush() {
1854 if (!isFlushing && !isFlushPending) {
1855 isFlushPending = true;
1856 currentFlushPromise = resolvedPromise.then(flushJobs);
1857 }
1858}
1859function invalidateJob(job) {
1860 const i = queue.indexOf(job);
1861 if (i > flushIndex) {
1862 queue.splice(i, 1);
1863 }
1864}
1865function queueCb(cb, activeQueue, pendingQueue, index) {
1866 if (!isArray(cb)) {
1867 if (!activeQueue ||
1868 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1869 pendingQueue.push(cb);
1870 }
1871 }
1872 else {
1873 // if cb is an array, it is a component lifecycle hook which can only be
1874 // triggered by a job, which is already deduped in the main queue, so
1875 // we can skip duplicate check here to improve perf
1876 pendingQueue.push(...cb);
1877 }
1878 queueFlush();
1879}
1880function queuePreFlushCb(cb) {
1881 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1882}
1883function queuePostFlushCb(cb) {
1884 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1885}
1886function flushPreFlushCbs(seen, parentJob = null) {
1887 if (pendingPreFlushCbs.length) {
1888 currentPreFlushParentJob = parentJob;
1889 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1890 pendingPreFlushCbs.length = 0;
1891 {
1892 seen = seen || new Map();
1893 }
1894 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1895 if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) {
1896 continue;
1897 }
1898 activePreFlushCbs[preFlushIndex]();
1899 }
1900 activePreFlushCbs = null;
1901 preFlushIndex = 0;
1902 currentPreFlushParentJob = null;
1903 // recursively flush until it drains
1904 flushPreFlushCbs(seen, parentJob);
1905 }
1906}
1907function flushPostFlushCbs(seen) {
1908 // flush any pre cbs queued during the flush (e.g. pre watchers)
1909 flushPreFlushCbs();
1910 if (pendingPostFlushCbs.length) {
1911 const deduped = [...new Set(pendingPostFlushCbs)];
1912 pendingPostFlushCbs.length = 0;
1913 // #1947 already has active queue, nested flushPostFlushCbs call
1914 if (activePostFlushCbs) {
1915 activePostFlushCbs.push(...deduped);
1916 return;
1917 }
1918 activePostFlushCbs = deduped;
1919 {
1920 seen = seen || new Map();
1921 }
1922 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1923 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1924 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
1925 continue;
1926 }
1927 activePostFlushCbs[postFlushIndex]();
1928 }
1929 activePostFlushCbs = null;
1930 postFlushIndex = 0;
1931 }
1932}
1933const getId = (job) => job.id == null ? Infinity : job.id;
1934function flushJobs(seen) {
1935 isFlushPending = false;
1936 isFlushing = true;
1937 {
1938 seen = seen || new Map();
1939 }
1940 flushPreFlushCbs(seen);
1941 // Sort queue before flush.
1942 // This ensures that:
1943 // 1. Components are updated from parent to child. (because parent is always
1944 // created before the child so its render effect will have smaller
1945 // priority number)
1946 // 2. If a component is unmounted during a parent component's update,
1947 // its update can be skipped.
1948 queue.sort((a, b) => getId(a) - getId(b));
1949 // conditional usage of checkRecursiveUpdate must be determined out of
1950 // try ... catch block since Rollup by default de-optimizes treeshaking
1951 // inside try-catch. This can leave all warning code unshaked. Although
1952 // they would get eventually shaken by a minifier like terser, some minifiers
1953 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610)
1954 const check = (job) => checkRecursiveUpdates(seen, job)
1955 ;
1956 try {
1957 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1958 const job = queue[flushIndex];
1959 if (job && job.active !== false) {
1960 if (true && check(job)) {
1961 continue;
1962 }
1963 // console.log(`running:`, job.id)
1964 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1965 }
1966 }
1967 }
1968 finally {
1969 flushIndex = 0;
1970 queue.length = 0;
1971 flushPostFlushCbs(seen);
1972 isFlushing = false;
1973 currentFlushPromise = null;
1974 // some postFlushCb queued jobs!
1975 // keep flushing until it drains.
1976 if (queue.length ||
1977 pendingPreFlushCbs.length ||
1978 pendingPostFlushCbs.length) {
1979 flushJobs(seen);
1980 }
1981 }
1982}
1983function checkRecursiveUpdates(seen, fn) {
1984 if (!seen.has(fn)) {
1985 seen.set(fn, 1);
1986 }
1987 else {
1988 const count = seen.get(fn);
1989 if (count > RECURSION_LIMIT) {
1990 const instance = fn.ownerInstance;
1991 const componentName = instance && getComponentName(instance.type);
1992 warn$1(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
1993 `This means you have a reactive effect that is mutating its own ` +
1994 `dependencies and thus recursively triggering itself. Possible sources ` +
1995 `include component template, render function, updated hook or ` +
1996 `watcher source function.`);
1997 return true;
1998 }
1999 else {
2000 seen.set(fn, count + 1);
2001 }
2002 }
2003}
2004
2005/* eslint-disable no-restricted-globals */
2006let isHmrUpdating = false;
2007const hmrDirtyComponents = new Set();
2008// Expose the HMR runtime on the global object
2009// This makes it entirely tree-shakable without polluting the exports and makes
2010// it easier to be used in toolings like vue-loader
2011// Note: for a component to be eligible for HMR it also needs the __hmrId option
2012// to be set so that its instances can be registered / removed.
2013{
2014 getGlobalThis().__VUE_HMR_RUNTIME__ = {
2015 createRecord: tryWrap(createRecord),
2016 rerender: tryWrap(rerender),
2017 reload: tryWrap(reload)
2018 };
2019}
2020const map = new Map();
2021function registerHMR(instance) {
2022 const id = instance.type.__hmrId;
2023 let record = map.get(id);
2024 if (!record) {
2025 createRecord(id, instance.type);
2026 record = map.get(id);
2027 }
2028 record.instances.add(instance);
2029}
2030function unregisterHMR(instance) {
2031 map.get(instance.type.__hmrId).instances.delete(instance);
2032}
2033function createRecord(id, initialDef) {
2034 if (map.has(id)) {
2035 return false;
2036 }
2037 map.set(id, {
2038 initialDef: normalizeClassComponent(initialDef),
2039 instances: new Set()
2040 });
2041 return true;
2042}
2043function normalizeClassComponent(component) {
2044 return isClassComponent(component) ? component.__vccOpts : component;
2045}
2046function rerender(id, newRender) {
2047 const record = map.get(id);
2048 if (!record) {
2049 return;
2050 }
2051 // update initial record (for not-yet-rendered component)
2052 record.initialDef.render = newRender;
2053 [...record.instances].forEach(instance => {
2054 if (newRender) {
2055 instance.render = newRender;
2056 normalizeClassComponent(instance.type).render = newRender;
2057 }
2058 instance.renderCache = [];
2059 // this flag forces child components with slot content to update
2060 isHmrUpdating = true;
2061 instance.update();
2062 isHmrUpdating = false;
2063 });
2064}
2065function reload(id, newComp) {
2066 const record = map.get(id);
2067 if (!record)
2068 return;
2069 newComp = normalizeClassComponent(newComp);
2070 // update initial def (for not-yet-rendered components)
2071 updateComponentDef(record.initialDef, newComp);
2072 // create a snapshot which avoids the set being mutated during updates
2073 const instances = [...record.instances];
2074 for (const instance of instances) {
2075 const oldComp = normalizeClassComponent(instance.type);
2076 if (!hmrDirtyComponents.has(oldComp)) {
2077 // 1. Update existing comp definition to match new one
2078 if (oldComp !== record.initialDef) {
2079 updateComponentDef(oldComp, newComp);
2080 }
2081 // 2. mark definition dirty. This forces the renderer to replace the
2082 // component on patch.
2083 hmrDirtyComponents.add(oldComp);
2084 }
2085 // 3. invalidate options resolution cache
2086 instance.appContext.optionsCache.delete(instance.type);
2087 // 4. actually update
2088 if (instance.ceReload) {
2089 // custom element
2090 hmrDirtyComponents.add(oldComp);
2091 instance.ceReload(newComp.styles);
2092 hmrDirtyComponents.delete(oldComp);
2093 }
2094 else if (instance.parent) {
2095 // 4. Force the parent instance to re-render. This will cause all updated
2096 // components to be unmounted and re-mounted. Queue the update so that we
2097 // don't end up forcing the same parent to re-render multiple times.
2098 queueJob(instance.parent.update);
2099 // instance is the inner component of an async custom element
2100 // invoke to reset styles
2101 if (instance.parent.type.__asyncLoader &&
2102 instance.parent.ceReload) {
2103 instance.parent.ceReload(newComp.styles);
2104 }
2105 }
2106 else if (instance.appContext.reload) {
2107 // root instance mounted via createApp() has a reload method
2108 instance.appContext.reload();
2109 }
2110 else if (typeof window !== 'undefined') {
2111 // root instance inside tree created via raw render(). Force reload.
2112 window.location.reload();
2113 }
2114 else {
2115 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
2116 }
2117 }
2118 // 5. make sure to cleanup dirty hmr components after update
2119 queuePostFlushCb(() => {
2120 for (const instance of instances) {
2121 hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
2122 }
2123 });
2124}
2125function updateComponentDef(oldComp, newComp) {
2126 extend(oldComp, newComp);
2127 for (const key in oldComp) {
2128 if (key !== '__file' && !(key in newComp)) {
2129 delete oldComp[key];
2130 }
2131 }
2132}
2133function tryWrap(fn) {
2134 return (id, arg) => {
2135 try {
2136 return fn(id, arg);
2137 }
2138 catch (e) {
2139 console.error(e);
2140 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
2141 `Full reload required.`);
2142 }
2143 };
2144}
2145
2146let devtools;
2147let buffer = [];
2148let devtoolsNotInstalled = false;
2149function emit(event, ...args) {
2150 if (devtools) {
2151 devtools.emit(event, ...args);
2152 }
2153 else if (!devtoolsNotInstalled) {
2154 buffer.push({ event, args });
2155 }
2156}
2157function setDevtoolsHook(hook, target) {
2158 var _a, _b;
2159 devtools = hook;
2160 if (devtools) {
2161 devtools.enabled = true;
2162 buffer.forEach(({ event, args }) => devtools.emit(event, ...args));
2163 buffer = [];
2164 }
2165 else if (
2166 // handle late devtools injection - only do this if we are in an actual
2167 // browser environment to avoid the timer handle stalling test runner exit
2168 // (#4815)
2169 typeof window !== 'undefined' &&
2170 // some envs mock window but not fully
2171 window.HTMLElement &&
2172 // also exclude jsdom
2173 !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
2174 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
2175 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
2176 replay.push((newHook) => {
2177 setDevtoolsHook(newHook, target);
2178 });
2179 // clear buffer after 3s - the user probably doesn't have devtools installed
2180 // at all, and keeping the buffer will cause memory leaks (#4738)
2181 setTimeout(() => {
2182 if (!devtools) {
2183 target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
2184 devtoolsNotInstalled = true;
2185 buffer = [];
2186 }
2187 }, 3000);
2188 }
2189 else {
2190 // non-browser env, assume not installed
2191 devtoolsNotInstalled = true;
2192 buffer = [];
2193 }
2194}
2195function devtoolsInitApp(app, version) {
2196 emit("app:init" /* APP_INIT */, app, version, {
2197 Fragment,
2198 Text,
2199 Comment,
2200 Static
2201 });
2202}
2203function devtoolsUnmountApp(app) {
2204 emit("app:unmount" /* APP_UNMOUNT */, app);
2205}
2206const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
2207const devtoolsComponentUpdated =
2208/*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
2209const devtoolsComponentRemoved =
2210/*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
2211function createDevtoolsComponentHook(hook) {
2212 return (component) => {
2213 emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
2214 };
2215}
2216const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
2217const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
2218function createDevtoolsPerformanceHook(hook) {
2219 return (component, type, time) => {
2220 emit(hook, component.appContext.app, component.uid, component, type, time);
2221 };
2222}
2223function devtoolsComponentEmit(component, event, params) {
2224 emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
2225}
2226
2227function emit$1(instance, event, ...rawArgs) {
2228 if (instance.isUnmounted)
2229 return;
2230 const props = instance.vnode.props || EMPTY_OBJ;
2231 {
2232 const { emitsOptions, propsOptions: [propsOptions] } = instance;
2233 if (emitsOptions) {
2234 if (!(event in emitsOptions) &&
2235 !(false )) {
2236 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
2237 warn$1(`Component emitted event "${event}" but it is neither declared in ` +
2238 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
2239 }
2240 }
2241 else {
2242 const validator = emitsOptions[event];
2243 if (isFunction(validator)) {
2244 const isValid = validator(...rawArgs);
2245 if (!isValid) {
2246 warn$1(`Invalid event arguments: event validation failed for event "${event}".`);
2247 }
2248 }
2249 }
2250 }
2251 }
2252 let args = rawArgs;
2253 const isModelListener = event.startsWith('update:');
2254 // for v-model update:xxx events, apply modifiers on args
2255 const modelArg = isModelListener && event.slice(7);
2256 if (modelArg && modelArg in props) {
2257 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
2258 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
2259 if (trim) {
2260 args = rawArgs.map(a => a.trim());
2261 }
2262 if (number) {
2263 args = rawArgs.map(toNumber);
2264 }
2265 }
2266 {
2267 devtoolsComponentEmit(instance, event, args);
2268 }
2269 {
2270 const lowerCaseEvent = event.toLowerCase();
2271 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
2272 warn$1(`Event "${lowerCaseEvent}" is emitted in component ` +
2273 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
2274 `Note that HTML attributes are case-insensitive and you cannot use ` +
2275 `v-on to listen to camelCase events when using in-DOM templates. ` +
2276 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
2277 }
2278 }
2279 let handlerName;
2280 let handler = props[(handlerName = toHandlerKey(event))] ||
2281 // also try camelCase event handler (#2249)
2282 props[(handlerName = toHandlerKey(camelize(event)))];
2283 // for v-model update:xxx events, also trigger kebab-case equivalent
2284 // for props passed via kebab-case
2285 if (!handler && isModelListener) {
2286 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
2287 }
2288 if (handler) {
2289 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2290 }
2291 const onceHandler = props[handlerName + `Once`];
2292 if (onceHandler) {
2293 if (!instance.emitted) {
2294 instance.emitted = {};
2295 }
2296 else if (instance.emitted[handlerName]) {
2297 return;
2298 }
2299 instance.emitted[handlerName] = true;
2300 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2301 }
2302}
2303function normalizeEmitsOptions(comp, appContext, asMixin = false) {
2304 const cache = appContext.emitsCache;
2305 const cached = cache.get(comp);
2306 if (cached !== undefined) {
2307 return cached;
2308 }
2309 const raw = comp.emits;
2310 let normalized = {};
2311 // apply mixin/extends props
2312 let hasExtends = false;
2313 if (!isFunction(comp)) {
2314 const extendEmits = (raw) => {
2315 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
2316 if (normalizedFromExtend) {
2317 hasExtends = true;
2318 extend(normalized, normalizedFromExtend);
2319 }
2320 };
2321 if (!asMixin && appContext.mixins.length) {
2322 appContext.mixins.forEach(extendEmits);
2323 }
2324 if (comp.extends) {
2325 extendEmits(comp.extends);
2326 }
2327 if (comp.mixins) {
2328 comp.mixins.forEach(extendEmits);
2329 }
2330 }
2331 if (!raw && !hasExtends) {
2332 cache.set(comp, null);
2333 return null;
2334 }
2335 if (isArray(raw)) {
2336 raw.forEach(key => (normalized[key] = null));
2337 }
2338 else {
2339 extend(normalized, raw);
2340 }
2341 cache.set(comp, normalized);
2342 return normalized;
2343}
2344// Check if an incoming prop key is a declared emit event listener.
2345// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
2346// both considered matched listeners.
2347function isEmitListener(options, key) {
2348 if (!options || !isOn(key)) {
2349 return false;
2350 }
2351 key = key.slice(2).replace(/Once$/, '');
2352 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
2353 hasOwn(options, hyphenate(key)) ||
2354 hasOwn(options, key));
2355}
2356
2357/**
2358 * mark the current rendering instance for asset resolution (e.g.
2359 * resolveComponent, resolveDirective) during render
2360 */
2361let currentRenderingInstance = null;
2362let currentScopeId = null;
2363/**
2364 * Note: rendering calls maybe nested. The function returns the parent rendering
2365 * instance if present, which should be restored after the render is done:
2366 *
2367 * ```js
2368 * const prev = setCurrentRenderingInstance(i)
2369 * // ...render
2370 * setCurrentRenderingInstance(prev)
2371 * ```
2372 */
2373function setCurrentRenderingInstance(instance) {
2374 const prev = currentRenderingInstance;
2375 currentRenderingInstance = instance;
2376 currentScopeId = (instance && instance.type.__scopeId) || null;
2377 return prev;
2378}
2379/**
2380 * Set scope id when creating hoisted vnodes.
2381 * @private compiler helper
2382 */
2383function pushScopeId(id) {
2384 currentScopeId = id;
2385}
2386/**
2387 * Technically we no longer need this after 3.0.8 but we need to keep the same
2388 * API for backwards compat w/ code generated by compilers.
2389 * @private
2390 */
2391function popScopeId() {
2392 currentScopeId = null;
2393}
2394/**
2395 * Only for backwards compat
2396 * @private
2397 */
2398const withScopeId = (_id) => withCtx;
2399/**
2400 * Wrap a slot function to memoize current rendering instance
2401 * @private compiler helper
2402 */
2403function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
2404) {
2405 if (!ctx)
2406 return fn;
2407 // already normalized
2408 if (fn._n) {
2409 return fn;
2410 }
2411 const renderFnWithContext = (...args) => {
2412 // If a user calls a compiled slot inside a template expression (#1745), it
2413 // can mess up block tracking, so by default we disable block tracking and
2414 // force bail out when invoking a compiled slot (indicated by the ._d flag).
2415 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
2416 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
2417 if (renderFnWithContext._d) {
2418 setBlockTracking(-1);
2419 }
2420 const prevInstance = setCurrentRenderingInstance(ctx);
2421 const res = fn(...args);
2422 setCurrentRenderingInstance(prevInstance);
2423 if (renderFnWithContext._d) {
2424 setBlockTracking(1);
2425 }
2426 {
2427 devtoolsComponentUpdated(ctx);
2428 }
2429 return res;
2430 };
2431 // mark normalized to avoid duplicated wrapping
2432 renderFnWithContext._n = true;
2433 // mark this as compiled by default
2434 // this is used in vnode.ts -> normalizeChildren() to set the slot
2435 // rendering flag.
2436 renderFnWithContext._c = true;
2437 // disable block tracking by default
2438 renderFnWithContext._d = true;
2439 return renderFnWithContext;
2440}
2441
2442/**
2443 * dev only flag to track whether $attrs was used during render.
2444 * If $attrs was used during render then the warning for failed attrs
2445 * fallthrough can be suppressed.
2446 */
2447let accessedAttrs = false;
2448function markAttrsAccessed() {
2449 accessedAttrs = true;
2450}
2451function renderComponentRoot(instance) {
2452 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
2453 let result;
2454 let fallthroughAttrs;
2455 const prev = setCurrentRenderingInstance(instance);
2456 {
2457 accessedAttrs = false;
2458 }
2459 try {
2460 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
2461 // withProxy is a proxy with a different `has` trap only for
2462 // runtime-compiled render functions using `with` block.
2463 const proxyToUse = withProxy || proxy;
2464 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2465 fallthroughAttrs = attrs;
2466 }
2467 else {
2468 // functional
2469 const render = Component;
2470 // in dev, mark attrs accessed if optional props (attrs === props)
2471 if (true && attrs === props) {
2472 markAttrsAccessed();
2473 }
2474 result = normalizeVNode(render.length > 1
2475 ? render(props, true
2476 ? {
2477 get attrs() {
2478 markAttrsAccessed();
2479 return attrs;
2480 },
2481 slots,
2482 emit
2483 }
2484 : { attrs, slots, emit })
2485 : render(props, null /* we know it doesn't need it */));
2486 fallthroughAttrs = Component.props
2487 ? attrs
2488 : getFunctionalFallthrough(attrs);
2489 }
2490 }
2491 catch (err) {
2492 blockStack.length = 0;
2493 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2494 result = createVNode(Comment);
2495 }
2496 // attr merging
2497 // in dev mode, comments are preserved, and it's possible for a template
2498 // to have comments along side the root element which makes it a fragment
2499 let root = result;
2500 let setRoot = undefined;
2501 if (result.patchFlag > 0 &&
2502 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
2503 [root, setRoot] = getChildRoot(result);
2504 }
2505 if (fallthroughAttrs && inheritAttrs !== false) {
2506 const keys = Object.keys(fallthroughAttrs);
2507 const { shapeFlag } = root;
2508 if (keys.length) {
2509 if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) {
2510 if (propsOptions && keys.some(isModelListener)) {
2511 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2512 // prop, it indicates this component expects to handle v-model and
2513 // it should not fallthrough.
2514 // related: #1543, #1643, #1989
2515 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2516 }
2517 root = cloneVNode(root, fallthroughAttrs);
2518 }
2519 else if (!accessedAttrs && root.type !== Comment) {
2520 const allAttrs = Object.keys(attrs);
2521 const eventAttrs = [];
2522 const extraAttrs = [];
2523 for (let i = 0, l = allAttrs.length; i < l; i++) {
2524 const key = allAttrs[i];
2525 if (isOn(key)) {
2526 // ignore v-model handlers when they fail to fallthrough
2527 if (!isModelListener(key)) {
2528 // remove `on`, lowercase first letter to reflect event casing
2529 // accurately
2530 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2531 }
2532 }
2533 else {
2534 extraAttrs.push(key);
2535 }
2536 }
2537 if (extraAttrs.length) {
2538 warn$1(`Extraneous non-props attributes (` +
2539 `${extraAttrs.join(', ')}) ` +
2540 `were passed to component but could not be automatically inherited ` +
2541 `because component renders fragment or text root nodes.`);
2542 }
2543 if (eventAttrs.length) {
2544 warn$1(`Extraneous non-emits event listeners (` +
2545 `${eventAttrs.join(', ')}) ` +
2546 `were passed to component but could not be automatically inherited ` +
2547 `because component renders fragment or text root nodes. ` +
2548 `If the listener is intended to be a component custom event listener only, ` +
2549 `declare it using the "emits" option.`);
2550 }
2551 }
2552 }
2553 }
2554 // inherit directives
2555 if (vnode.dirs) {
2556 if (!isElementRoot(root)) {
2557 warn$1(`Runtime directive used on component with non-element root node. ` +
2558 `The directives will not function as intended.`);
2559 }
2560 // clone before mutating since the root may be a hoisted vnode
2561 root = cloneVNode(root);
2562 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2563 }
2564 // inherit transition data
2565 if (vnode.transition) {
2566 if (!isElementRoot(root)) {
2567 warn$1(`Component inside <Transition> renders non-element root node ` +
2568 `that cannot be animated.`);
2569 }
2570 root.transition = vnode.transition;
2571 }
2572 if (setRoot) {
2573 setRoot(root);
2574 }
2575 else {
2576 result = root;
2577 }
2578 setCurrentRenderingInstance(prev);
2579 return result;
2580}
2581/**
2582 * dev only
2583 * In dev mode, template root level comments are rendered, which turns the
2584 * template into a fragment root, but we need to locate the single element
2585 * root for attrs and scope id processing.
2586 */
2587const getChildRoot = (vnode) => {
2588 const rawChildren = vnode.children;
2589 const dynamicChildren = vnode.dynamicChildren;
2590 const childRoot = filterSingleRoot(rawChildren);
2591 if (!childRoot) {
2592 return [vnode, undefined];
2593 }
2594 const index = rawChildren.indexOf(childRoot);
2595 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2596 const setRoot = (updatedRoot) => {
2597 rawChildren[index] = updatedRoot;
2598 if (dynamicChildren) {
2599 if (dynamicIndex > -1) {
2600 dynamicChildren[dynamicIndex] = updatedRoot;
2601 }
2602 else if (updatedRoot.patchFlag > 0) {
2603 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2604 }
2605 }
2606 };
2607 return [normalizeVNode(childRoot), setRoot];
2608};
2609function filterSingleRoot(children) {
2610 let singleRoot;
2611 for (let i = 0; i < children.length; i++) {
2612 const child = children[i];
2613 if (isVNode(child)) {
2614 // ignore user comment
2615 if (child.type !== Comment || child.children === 'v-if') {
2616 if (singleRoot) {
2617 // has more than 1 non-comment child, return now
2618 return;
2619 }
2620 else {
2621 singleRoot = child;
2622 }
2623 }
2624 }
2625 else {
2626 return;
2627 }
2628 }
2629 return singleRoot;
2630}
2631const getFunctionalFallthrough = (attrs) => {
2632 let res;
2633 for (const key in attrs) {
2634 if (key === 'class' || key === 'style' || isOn(key)) {
2635 (res || (res = {}))[key] = attrs[key];
2636 }
2637 }
2638 return res;
2639};
2640const filterModelListeners = (attrs, props) => {
2641 const res = {};
2642 for (const key in attrs) {
2643 if (!isModelListener(key) || !(key.slice(9) in props)) {
2644 res[key] = attrs[key];
2645 }
2646 }
2647 return res;
2648};
2649const isElementRoot = (vnode) => {
2650 return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) ||
2651 vnode.type === Comment // potential v-if branch switch
2652 );
2653};
2654function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2655 const { props: prevProps, children: prevChildren, component } = prevVNode;
2656 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2657 const emits = component.emitsOptions;
2658 // Parent component's render function was hot-updated. Since this may have
2659 // caused the child component's slots content to have changed, we need to
2660 // force the child to update as well.
2661 if ((prevChildren || nextChildren) && isHmrUpdating) {
2662 return true;
2663 }
2664 // force child update for runtime directive or transition on component vnode.
2665 if (nextVNode.dirs || nextVNode.transition) {
2666 return true;
2667 }
2668 if (optimized && patchFlag >= 0) {
2669 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2670 // slot content that references values that might have changed,
2671 // e.g. in a v-for
2672 return true;
2673 }
2674 if (patchFlag & 16 /* FULL_PROPS */) {
2675 if (!prevProps) {
2676 return !!nextProps;
2677 }
2678 // presence of this flag indicates props are always non-null
2679 return hasPropsChanged(prevProps, nextProps, emits);
2680 }
2681 else if (patchFlag & 8 /* PROPS */) {
2682 const dynamicProps = nextVNode.dynamicProps;
2683 for (let i = 0; i < dynamicProps.length; i++) {
2684 const key = dynamicProps[i];
2685 if (nextProps[key] !== prevProps[key] &&
2686 !isEmitListener(emits, key)) {
2687 return true;
2688 }
2689 }
2690 }
2691 }
2692 else {
2693 // this path is only taken by manually written render functions
2694 // so presence of any children leads to a forced update
2695 if (prevChildren || nextChildren) {
2696 if (!nextChildren || !nextChildren.$stable) {
2697 return true;
2698 }
2699 }
2700 if (prevProps === nextProps) {
2701 return false;
2702 }
2703 if (!prevProps) {
2704 return !!nextProps;
2705 }
2706 if (!nextProps) {
2707 return true;
2708 }
2709 return hasPropsChanged(prevProps, nextProps, emits);
2710 }
2711 return false;
2712}
2713function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2714 const nextKeys = Object.keys(nextProps);
2715 if (nextKeys.length !== Object.keys(prevProps).length) {
2716 return true;
2717 }
2718 for (let i = 0; i < nextKeys.length; i++) {
2719 const key = nextKeys[i];
2720 if (nextProps[key] !== prevProps[key] &&
2721 !isEmitListener(emitsOptions, key)) {
2722 return true;
2723 }
2724 }
2725 return false;
2726}
2727function updateHOCHostEl({ vnode, parent }, el // HostNode
2728) {
2729 while (parent && parent.subTree === vnode) {
2730 (vnode = parent.vnode).el = el;
2731 parent = parent.parent;
2732 }
2733}
2734
2735const isSuspense = (type) => type.__isSuspense;
2736// Suspense exposes a component-like API, and is treated like a component
2737// in the compiler, but internally it's a special built-in type that hooks
2738// directly into the renderer.
2739const SuspenseImpl = {
2740 name: 'Suspense',
2741 // In order to make Suspense tree-shakable, we need to avoid importing it
2742 // directly in the renderer. The renderer checks for the __isSuspense flag
2743 // on a vnode's type and calls the `process` method, passing in renderer
2744 // internals.
2745 __isSuspense: true,
2746 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2747 // platform-specific impl passed from renderer
2748 rendererInternals) {
2749 if (n1 == null) {
2750 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2751 }
2752 else {
2753 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2754 }
2755 },
2756 hydrate: hydrateSuspense,
2757 create: createSuspenseBoundary,
2758 normalize: normalizeSuspenseChildren
2759};
2760// Force-casted public typing for h and TSX props inference
2761const Suspense = (SuspenseImpl );
2762function triggerEvent(vnode, name) {
2763 const eventListener = vnode.props && vnode.props[name];
2764 if (isFunction(eventListener)) {
2765 eventListener();
2766 }
2767}
2768function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2769 const { p: patch, o: { createElement } } = rendererInternals;
2770 const hiddenContainer = createElement('div');
2771 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2772 // start mounting the content subtree in an off-dom container
2773 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2774 // now check if we have encountered any async deps
2775 if (suspense.deps > 0) {
2776 // has async
2777 // invoke @fallback event
2778 triggerEvent(vnode, 'onPending');
2779 triggerEvent(vnode, 'onFallback');
2780 // mount the fallback tree
2781 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2782 isSVG, slotScopeIds);
2783 setActiveBranch(suspense, vnode.ssFallback);
2784 }
2785 else {
2786 // Suspense has no async deps. Just resolve.
2787 suspense.resolve();
2788 }
2789}
2790function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2791 const suspense = (n2.suspense = n1.suspense);
2792 suspense.vnode = n2;
2793 n2.el = n1.el;
2794 const newBranch = n2.ssContent;
2795 const newFallback = n2.ssFallback;
2796 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2797 if (pendingBranch) {
2798 suspense.pendingBranch = newBranch;
2799 if (isSameVNodeType(newBranch, pendingBranch)) {
2800 // same root type but content may have changed.
2801 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2802 if (suspense.deps <= 0) {
2803 suspense.resolve();
2804 }
2805 else if (isInFallback) {
2806 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2807 isSVG, slotScopeIds, optimized);
2808 setActiveBranch(suspense, newFallback);
2809 }
2810 }
2811 else {
2812 // toggled before pending tree is resolved
2813 suspense.pendingId++;
2814 if (isHydrating) {
2815 // if toggled before hydration is finished, the current DOM tree is
2816 // no longer valid. set it as the active branch so it will be unmounted
2817 // when resolved
2818 suspense.isHydrating = false;
2819 suspense.activeBranch = pendingBranch;
2820 }
2821 else {
2822 unmount(pendingBranch, parentComponent, suspense);
2823 }
2824 // increment pending ID. this is used to invalidate async callbacks
2825 // reset suspense state
2826 suspense.deps = 0;
2827 // discard effects from pending branch
2828 suspense.effects.length = 0;
2829 // discard previous container
2830 suspense.hiddenContainer = createElement('div');
2831 if (isInFallback) {
2832 // already in fallback state
2833 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2834 if (suspense.deps <= 0) {
2835 suspense.resolve();
2836 }
2837 else {
2838 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2839 isSVG, slotScopeIds, optimized);
2840 setActiveBranch(suspense, newFallback);
2841 }
2842 }
2843 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2844 // toggled "back" to current active branch
2845 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2846 // force resolve
2847 suspense.resolve(true);
2848 }
2849 else {
2850 // switched to a 3rd branch
2851 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2852 if (suspense.deps <= 0) {
2853 suspense.resolve();
2854 }
2855 }
2856 }
2857 }
2858 else {
2859 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2860 // root did not change, just normal patch
2861 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2862 setActiveBranch(suspense, newBranch);
2863 }
2864 else {
2865 // root node toggled
2866 // invoke @pending event
2867 triggerEvent(n2, 'onPending');
2868 // mount pending branch in off-dom container
2869 suspense.pendingBranch = newBranch;
2870 suspense.pendingId++;
2871 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2872 if (suspense.deps <= 0) {
2873 // incoming branch has no async deps, resolve now.
2874 suspense.resolve();
2875 }
2876 else {
2877 const { timeout, pendingId } = suspense;
2878 if (timeout > 0) {
2879 setTimeout(() => {
2880 if (suspense.pendingId === pendingId) {
2881 suspense.fallback(newFallback);
2882 }
2883 }, timeout);
2884 }
2885 else if (timeout === 0) {
2886 suspense.fallback(newFallback);
2887 }
2888 }
2889 }
2890 }
2891}
2892let hasWarned = false;
2893function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2894 /* istanbul ignore if */
2895 if (!hasWarned) {
2896 hasWarned = true;
2897 // @ts-ignore `console.info` cannot be null error
2898 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2899 }
2900 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2901 const timeout = toNumber(vnode.props && vnode.props.timeout);
2902 const suspense = {
2903 vnode,
2904 parent,
2905 parentComponent,
2906 isSVG,
2907 container,
2908 hiddenContainer,
2909 anchor,
2910 deps: 0,
2911 pendingId: 0,
2912 timeout: typeof timeout === 'number' ? timeout : -1,
2913 activeBranch: null,
2914 pendingBranch: null,
2915 isInFallback: true,
2916 isHydrating,
2917 isUnmounted: false,
2918 effects: [],
2919 resolve(resume = false) {
2920 {
2921 if (!resume && !suspense.pendingBranch) {
2922 throw new Error(`suspense.resolve() is called without a pending branch.`);
2923 }
2924 if (suspense.isUnmounted) {
2925 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2926 }
2927 }
2928 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2929 if (suspense.isHydrating) {
2930 suspense.isHydrating = false;
2931 }
2932 else if (!resume) {
2933 const delayEnter = activeBranch &&
2934 pendingBranch.transition &&
2935 pendingBranch.transition.mode === 'out-in';
2936 if (delayEnter) {
2937 activeBranch.transition.afterLeave = () => {
2938 if (pendingId === suspense.pendingId) {
2939 move(pendingBranch, container, anchor, 0 /* ENTER */);
2940 }
2941 };
2942 }
2943 // this is initial anchor on mount
2944 let { anchor } = suspense;
2945 // unmount current active tree
2946 if (activeBranch) {
2947 // if the fallback tree was mounted, it may have been moved
2948 // as part of a parent suspense. get the latest anchor for insertion
2949 anchor = next(activeBranch);
2950 unmount(activeBranch, parentComponent, suspense, true);
2951 }
2952 if (!delayEnter) {
2953 // move content from off-dom container to actual container
2954 move(pendingBranch, container, anchor, 0 /* ENTER */);
2955 }
2956 }
2957 setActiveBranch(suspense, pendingBranch);
2958 suspense.pendingBranch = null;
2959 suspense.isInFallback = false;
2960 // flush buffered effects
2961 // check if there is a pending parent suspense
2962 let parent = suspense.parent;
2963 let hasUnresolvedAncestor = false;
2964 while (parent) {
2965 if (parent.pendingBranch) {
2966 // found a pending parent suspense, merge buffered post jobs
2967 // into that parent
2968 parent.effects.push(...effects);
2969 hasUnresolvedAncestor = true;
2970 break;
2971 }
2972 parent = parent.parent;
2973 }
2974 // no pending parent suspense, flush all jobs
2975 if (!hasUnresolvedAncestor) {
2976 queuePostFlushCb(effects);
2977 }
2978 suspense.effects = [];
2979 // invoke @resolve event
2980 triggerEvent(vnode, 'onResolve');
2981 },
2982 fallback(fallbackVNode) {
2983 if (!suspense.pendingBranch) {
2984 return;
2985 }
2986 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2987 // invoke @fallback event
2988 triggerEvent(vnode, 'onFallback');
2989 const anchor = next(activeBranch);
2990 const mountFallback = () => {
2991 if (!suspense.isInFallback) {
2992 return;
2993 }
2994 // mount the fallback tree
2995 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2996 isSVG, slotScopeIds, optimized);
2997 setActiveBranch(suspense, fallbackVNode);
2998 };
2999 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
3000 if (delayEnter) {
3001 activeBranch.transition.afterLeave = mountFallback;
3002 }
3003 suspense.isInFallback = true;
3004 // unmount current active branch
3005 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
3006 true // shouldRemove
3007 );
3008 if (!delayEnter) {
3009 mountFallback();
3010 }
3011 },
3012 move(container, anchor, type) {
3013 suspense.activeBranch &&
3014 move(suspense.activeBranch, container, anchor, type);
3015 suspense.container = container;
3016 },
3017 next() {
3018 return suspense.activeBranch && next(suspense.activeBranch);
3019 },
3020 registerDep(instance, setupRenderEffect) {
3021 const isInPendingSuspense = !!suspense.pendingBranch;
3022 if (isInPendingSuspense) {
3023 suspense.deps++;
3024 }
3025 const hydratedEl = instance.vnode.el;
3026 instance
3027 .asyncDep.catch(err => {
3028 handleError(err, instance, 0 /* SETUP_FUNCTION */);
3029 })
3030 .then(asyncSetupResult => {
3031 // retry when the setup() promise resolves.
3032 // component may have been unmounted before resolve.
3033 if (instance.isUnmounted ||
3034 suspense.isUnmounted ||
3035 suspense.pendingId !== instance.suspenseId) {
3036 return;
3037 }
3038 // retry from this component
3039 instance.asyncResolved = true;
3040 const { vnode } = instance;
3041 {
3042 pushWarningContext(vnode);
3043 }
3044 handleSetupResult(instance, asyncSetupResult, false);
3045 if (hydratedEl) {
3046 // vnode may have been replaced if an update happened before the
3047 // async dep is resolved.
3048 vnode.el = hydratedEl;
3049 }
3050 const placeholder = !hydratedEl && instance.subTree.el;
3051 setupRenderEffect(instance, vnode,
3052 // component may have been moved before resolve.
3053 // if this is not a hydration, instance.subTree will be the comment
3054 // placeholder.
3055 parentNode(hydratedEl || instance.subTree.el),
3056 // anchor will not be used if this is hydration, so only need to
3057 // consider the comment placeholder case.
3058 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
3059 if (placeholder) {
3060 remove(placeholder);
3061 }
3062 updateHOCHostEl(instance, vnode.el);
3063 {
3064 popWarningContext();
3065 }
3066 // only decrease deps count if suspense is not already resolved
3067 if (isInPendingSuspense && --suspense.deps === 0) {
3068 suspense.resolve();
3069 }
3070 });
3071 },
3072 unmount(parentSuspense, doRemove) {
3073 suspense.isUnmounted = true;
3074 if (suspense.activeBranch) {
3075 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
3076 }
3077 if (suspense.pendingBranch) {
3078 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
3079 }
3080 }
3081 };
3082 return suspense;
3083}
3084function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
3085 /* eslint-disable no-restricted-globals */
3086 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
3087 // there are two possible scenarios for server-rendered suspense:
3088 // - success: ssr content should be fully resolved
3089 // - failure: ssr content should be the fallback branch.
3090 // however, on the client we don't really know if it has failed or not
3091 // attempt to hydrate the DOM assuming it has succeeded, but we still
3092 // need to construct a suspense boundary first
3093 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
3094 if (suspense.deps === 0) {
3095 suspense.resolve();
3096 }
3097 return result;
3098 /* eslint-enable no-restricted-globals */
3099}
3100function normalizeSuspenseChildren(vnode) {
3101 const { shapeFlag, children } = vnode;
3102 const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
3103 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
3104 vnode.ssFallback = isSlotChildren
3105 ? normalizeSuspenseSlot(children.fallback)
3106 : createVNode(Comment);
3107}
3108function normalizeSuspenseSlot(s) {
3109 let block;
3110 if (isFunction(s)) {
3111 const trackBlock = isBlockTreeEnabled && s._c;
3112 if (trackBlock) {
3113 // disableTracking: false
3114 // allow block tracking for compiled slots
3115 // (see ./componentRenderContext.ts)
3116 s._d = false;
3117 openBlock();
3118 }
3119 s = s();
3120 if (trackBlock) {
3121 s._d = true;
3122 block = currentBlock;
3123 closeBlock();
3124 }
3125 }
3126 if (isArray(s)) {
3127 const singleChild = filterSingleRoot(s);
3128 if (!singleChild) {
3129 warn$1(`<Suspense> slots expect a single root node.`);
3130 }
3131 s = singleChild;
3132 }
3133 s = normalizeVNode(s);
3134 if (block && !s.dynamicChildren) {
3135 s.dynamicChildren = block.filter(c => c !== s);
3136 }
3137 return s;
3138}
3139function queueEffectWithSuspense(fn, suspense) {
3140 if (suspense && suspense.pendingBranch) {
3141 if (isArray(fn)) {
3142 suspense.effects.push(...fn);
3143 }
3144 else {
3145 suspense.effects.push(fn);
3146 }
3147 }
3148 else {
3149 queuePostFlushCb(fn);
3150 }
3151}
3152function setActiveBranch(suspense, branch) {
3153 suspense.activeBranch = branch;
3154 const { vnode, parentComponent } = suspense;
3155 const el = (vnode.el = branch.el);
3156 // in case suspense is the root node of a component,
3157 // recursively update the HOC el
3158 if (parentComponent && parentComponent.subTree === vnode) {
3159 parentComponent.vnode.el = el;
3160 updateHOCHostEl(parentComponent, el);
3161 }
3162}
3163
3164function provide(key, value) {
3165 if (!currentInstance) {
3166 {
3167 warn$1(`provide() can only be used inside setup().`);
3168 }
3169 }
3170 else {
3171 let provides = currentInstance.provides;
3172 // by default an instance inherits its parent's provides object
3173 // but when it needs to provide values of its own, it creates its
3174 // own provides object using parent provides object as prototype.
3175 // this way in `inject` we can simply look up injections from direct
3176 // parent and let the prototype chain do the work.
3177 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
3178 if (parentProvides === provides) {
3179 provides = currentInstance.provides = Object.create(parentProvides);
3180 }
3181 // TS doesn't allow symbol as index type
3182 provides[key] = value;
3183 }
3184}
3185function inject(key, defaultValue, treatDefaultAsFactory = false) {
3186 // fallback to `currentRenderingInstance` so that this can be called in
3187 // a functional component
3188 const instance = currentInstance || currentRenderingInstance;
3189 if (instance) {
3190 // #2400
3191 // to support `app.use` plugins,
3192 // fallback to appContext's `provides` if the instance is at root
3193 const provides = instance.parent == null
3194 ? instance.vnode.appContext && instance.vnode.appContext.provides
3195 : instance.parent.provides;
3196 if (provides && key in provides) {
3197 // TS doesn't allow symbol as index type
3198 return provides[key];
3199 }
3200 else if (arguments.length > 1) {
3201 return treatDefaultAsFactory && isFunction(defaultValue)
3202 ? defaultValue.call(instance.proxy)
3203 : defaultValue;
3204 }
3205 else {
3206 warn$1(`injection "${String(key)}" not found.`);
3207 }
3208 }
3209 else {
3210 warn$1(`inject() can only be used inside setup() or functional components.`);
3211 }
3212}
3213
3214// Simple effect.
3215function watchEffect(effect, options) {
3216 return doWatch(effect, null, options);
3217}
3218function watchPostEffect(effect, options) {
3219 return doWatch(effect, null, (Object.assign(Object.assign({}, options), { flush: 'post' }) ));
3220}
3221function watchSyncEffect(effect, options) {
3222 return doWatch(effect, null, (Object.assign(Object.assign({}, options), { flush: 'sync' }) ));
3223}
3224// initial value for watchers to trigger on undefined initial values
3225const INITIAL_WATCHER_VALUE = {};
3226// implementation
3227function watch(source, cb, options) {
3228 if (!isFunction(cb)) {
3229 warn$1(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3230 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3231 `supports \`watch(source, cb, options?) signature.`);
3232 }
3233 return doWatch(source, cb, options);
3234}
3235function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
3236 if (!cb) {
3237 if (immediate !== undefined) {
3238 warn$1(`watch() "immediate" option is only respected when using the ` +
3239 `watch(source, callback, options?) signature.`);
3240 }
3241 if (deep !== undefined) {
3242 warn$1(`watch() "deep" option is only respected when using the ` +
3243 `watch(source, callback, options?) signature.`);
3244 }
3245 }
3246 const warnInvalidSource = (s) => {
3247 warn$1(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3248 `a reactive object, or an array of these types.`);
3249 };
3250 const instance = currentInstance;
3251 let getter;
3252 let forceTrigger = false;
3253 let isMultiSource = false;
3254 if (isRef(source)) {
3255 getter = () => source.value;
3256 forceTrigger = isShallow(source);
3257 }
3258 else if (isReactive(source)) {
3259 getter = () => source;
3260 deep = true;
3261 }
3262 else if (isArray(source)) {
3263 isMultiSource = true;
3264 forceTrigger = source.some(s => isReactive(s) || isShallow(s));
3265 getter = () => source.map(s => {
3266 if (isRef(s)) {
3267 return s.value;
3268 }
3269 else if (isReactive(s)) {
3270 return traverse(s);
3271 }
3272 else if (isFunction(s)) {
3273 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
3274 }
3275 else {
3276 warnInvalidSource(s);
3277 }
3278 });
3279 }
3280 else if (isFunction(source)) {
3281 if (cb) {
3282 // getter with cb
3283 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
3284 }
3285 else {
3286 // no cb -> simple effect
3287 getter = () => {
3288 if (instance && instance.isUnmounted) {
3289 return;
3290 }
3291 if (cleanup) {
3292 cleanup();
3293 }
3294 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onCleanup]);
3295 };
3296 }
3297 }
3298 else {
3299 getter = NOOP;
3300 warnInvalidSource(source);
3301 }
3302 if (cb && deep) {
3303 const baseGetter = getter;
3304 getter = () => traverse(baseGetter());
3305 }
3306 let cleanup;
3307 let onCleanup = (fn) => {
3308 cleanup = effect.onStop = () => {
3309 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3310 };
3311 };
3312 let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;
3313 const job = () => {
3314 if (!effect.active) {
3315 return;
3316 }
3317 if (cb) {
3318 // watch(source, cb)
3319 const newValue = effect.run();
3320 if (deep ||
3321 forceTrigger ||
3322 (isMultiSource
3323 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
3324 : hasChanged(newValue, oldValue)) ||
3325 (false )) {
3326 // cleanup before running cb again
3327 if (cleanup) {
3328 cleanup();
3329 }
3330 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3331 newValue,
3332 // pass undefined as the old value when it's changed for the first time
3333 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3334 onCleanup
3335 ]);
3336 oldValue = newValue;
3337 }
3338 }
3339 else {
3340 // watchEffect
3341 effect.run();
3342 }
3343 };
3344 // important: mark the job as a watcher callback so that scheduler knows
3345 // it is allowed to self-trigger (#1727)
3346 job.allowRecurse = !!cb;
3347 let scheduler;
3348 if (flush === 'sync') {
3349 scheduler = job; // the scheduler function gets called directly
3350 }
3351 else if (flush === 'post') {
3352 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3353 }
3354 else {
3355 // default: 'pre'
3356 scheduler = () => queuePreFlushCb(job);
3357 }
3358 const effect = new ReactiveEffect(getter, scheduler);
3359 {
3360 effect.onTrack = onTrack;
3361 effect.onTrigger = onTrigger;
3362 }
3363 // initial run
3364 if (cb) {
3365 if (immediate) {
3366 job();
3367 }
3368 else {
3369 oldValue = effect.run();
3370 }
3371 }
3372 else if (flush === 'post') {
3373 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
3374 }
3375 else {
3376 effect.run();
3377 }
3378 return () => {
3379 effect.stop();
3380 if (instance && instance.scope) {
3381 remove(instance.scope.effects, effect);
3382 }
3383 };
3384}
3385// this.$watch
3386function instanceWatch(source, value, options) {
3387 const publicThis = this.proxy;
3388 const getter = isString(source)
3389 ? source.includes('.')
3390 ? createPathGetter(publicThis, source)
3391 : () => publicThis[source]
3392 : source.bind(publicThis, publicThis);
3393 let cb;
3394 if (isFunction(value)) {
3395 cb = value;
3396 }
3397 else {
3398 cb = value.handler;
3399 options = value;
3400 }
3401 const cur = currentInstance;
3402 setCurrentInstance(this);
3403 const res = doWatch(getter, cb.bind(publicThis), options);
3404 if (cur) {
3405 setCurrentInstance(cur);
3406 }
3407 else {
3408 unsetCurrentInstance();
3409 }
3410 return res;
3411}
3412function createPathGetter(ctx, path) {
3413 const segments = path.split('.');
3414 return () => {
3415 let cur = ctx;
3416 for (let i = 0; i < segments.length && cur; i++) {
3417 cur = cur[segments[i]];
3418 }
3419 return cur;
3420 };
3421}
3422function traverse(value, seen) {
3423 if (!isObject(value) || value["__v_skip" /* SKIP */]) {
3424 return value;
3425 }
3426 seen = seen || new Set();
3427 if (seen.has(value)) {
3428 return value;
3429 }
3430 seen.add(value);
3431 if (isRef(value)) {
3432 traverse(value.value, seen);
3433 }
3434 else if (isArray(value)) {
3435 for (let i = 0; i < value.length; i++) {
3436 traverse(value[i], seen);
3437 }
3438 }
3439 else if (isSet(value) || isMap(value)) {
3440 value.forEach((v) => {
3441 traverse(v, seen);
3442 });
3443 }
3444 else if (isPlainObject(value)) {
3445 for (const key in value) {
3446 traverse(value[key], seen);
3447 }
3448 }
3449 return value;
3450}
3451
3452function useTransitionState() {
3453 const state = {
3454 isMounted: false,
3455 isLeaving: false,
3456 isUnmounting: false,
3457 leavingVNodes: new Map()
3458 };
3459 onMounted(() => {
3460 state.isMounted = true;
3461 });
3462 onBeforeUnmount(() => {
3463 state.isUnmounting = true;
3464 });
3465 return state;
3466}
3467const TransitionHookValidator = [Function, Array];
3468const BaseTransitionImpl = {
3469 name: `BaseTransition`,
3470 props: {
3471 mode: String,
3472 appear: Boolean,
3473 persisted: Boolean,
3474 // enter
3475 onBeforeEnter: TransitionHookValidator,
3476 onEnter: TransitionHookValidator,
3477 onAfterEnter: TransitionHookValidator,
3478 onEnterCancelled: TransitionHookValidator,
3479 // leave
3480 onBeforeLeave: TransitionHookValidator,
3481 onLeave: TransitionHookValidator,
3482 onAfterLeave: TransitionHookValidator,
3483 onLeaveCancelled: TransitionHookValidator,
3484 // appear
3485 onBeforeAppear: TransitionHookValidator,
3486 onAppear: TransitionHookValidator,
3487 onAfterAppear: TransitionHookValidator,
3488 onAppearCancelled: TransitionHookValidator
3489 },
3490 setup(props, { slots }) {
3491 const instance = getCurrentInstance();
3492 const state = useTransitionState();
3493 let prevTransitionKey;
3494 return () => {
3495 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3496 if (!children || !children.length) {
3497 return;
3498 }
3499 let child = children[0];
3500 if (children.length > 1) {
3501 let hasFound = false;
3502 // locate first non-comment child
3503 for (const c of children) {
3504 if (c.type !== Comment) {
3505 if (hasFound) {
3506 // warn more than one non-comment child
3507 warn$1('<transition> can only be used on a single element or component. ' +
3508 'Use <transition-group> for lists.');
3509 break;
3510 }
3511 child = c;
3512 hasFound = true;
3513 }
3514 }
3515 }
3516 // there's no need to track reactivity for these props so use the raw
3517 // props for a bit better perf
3518 const rawProps = toRaw(props);
3519 const { mode } = rawProps;
3520 // check mode
3521 if (mode &&
3522 mode !== 'in-out' &&
3523 mode !== 'out-in' &&
3524 mode !== 'default') {
3525 warn$1(`invalid <transition> mode: ${mode}`);
3526 }
3527 if (state.isLeaving) {
3528 return emptyPlaceholder(child);
3529 }
3530 // in the case of <transition><keep-alive/></transition>, we need to
3531 // compare the type of the kept-alive children.
3532 const innerChild = getKeepAliveChild(child);
3533 if (!innerChild) {
3534 return emptyPlaceholder(child);
3535 }
3536 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3537 setTransitionHooks(innerChild, enterHooks);
3538 const oldChild = instance.subTree;
3539 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3540 let transitionKeyChanged = false;
3541 const { getTransitionKey } = innerChild.type;
3542 if (getTransitionKey) {
3543 const key = getTransitionKey();
3544 if (prevTransitionKey === undefined) {
3545 prevTransitionKey = key;
3546 }
3547 else if (key !== prevTransitionKey) {
3548 prevTransitionKey = key;
3549 transitionKeyChanged = true;
3550 }
3551 }
3552 // handle mode
3553 if (oldInnerChild &&
3554 oldInnerChild.type !== Comment &&
3555 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3556 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3557 // update old tree's hooks in case of dynamic transition
3558 setTransitionHooks(oldInnerChild, leavingHooks);
3559 // switching between different views
3560 if (mode === 'out-in') {
3561 state.isLeaving = true;
3562 // return placeholder node and queue update when leave finishes
3563 leavingHooks.afterLeave = () => {
3564 state.isLeaving = false;
3565 instance.update();
3566 };
3567 return emptyPlaceholder(child);
3568 }
3569 else if (mode === 'in-out' && innerChild.type !== Comment) {
3570 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3571 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3572 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3573 // early removal callback
3574 el._leaveCb = () => {
3575 earlyRemove();
3576 el._leaveCb = undefined;
3577 delete enterHooks.delayedLeave;
3578 };
3579 enterHooks.delayedLeave = delayedLeave;
3580 };
3581 }
3582 }
3583 return child;
3584 };
3585 }
3586};
3587// export the public type for h/tsx inference
3588// also to avoid inline import() in generated d.ts files
3589const BaseTransition = BaseTransitionImpl;
3590function getLeavingNodesForType(state, vnode) {
3591 const { leavingVNodes } = state;
3592 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3593 if (!leavingVNodesCache) {
3594 leavingVNodesCache = Object.create(null);
3595 leavingVNodes.set(vnode.type, leavingVNodesCache);
3596 }
3597 return leavingVNodesCache;
3598}
3599// The transition hooks are attached to the vnode as vnode.transition
3600// and will be called at appropriate timing in the renderer.
3601function resolveTransitionHooks(vnode, props, state, instance) {
3602 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3603 const key = String(vnode.key);
3604 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3605 const callHook = (hook, args) => {
3606 hook &&
3607 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3608 };
3609 const callAsyncHook = (hook, args) => {
3610 const done = args[1];
3611 callHook(hook, args);
3612 if (isArray(hook)) {
3613 if (hook.every(hook => hook.length <= 1))
3614 done();
3615 }
3616 else if (hook.length <= 1) {
3617 done();
3618 }
3619 };
3620 const hooks = {
3621 mode,
3622 persisted,
3623 beforeEnter(el) {
3624 let hook = onBeforeEnter;
3625 if (!state.isMounted) {
3626 if (appear) {
3627 hook = onBeforeAppear || onBeforeEnter;
3628 }
3629 else {
3630 return;
3631 }
3632 }
3633 // for same element (v-show)
3634 if (el._leaveCb) {
3635 el._leaveCb(true /* cancelled */);
3636 }
3637 // for toggled element with same key (v-if)
3638 const leavingVNode = leavingVNodesCache[key];
3639 if (leavingVNode &&
3640 isSameVNodeType(vnode, leavingVNode) &&
3641 leavingVNode.el._leaveCb) {
3642 // force early removal (not cancelled)
3643 leavingVNode.el._leaveCb();
3644 }
3645 callHook(hook, [el]);
3646 },
3647 enter(el) {
3648 let hook = onEnter;
3649 let afterHook = onAfterEnter;
3650 let cancelHook = onEnterCancelled;
3651 if (!state.isMounted) {
3652 if (appear) {
3653 hook = onAppear || onEnter;
3654 afterHook = onAfterAppear || onAfterEnter;
3655 cancelHook = onAppearCancelled || onEnterCancelled;
3656 }
3657 else {
3658 return;
3659 }
3660 }
3661 let called = false;
3662 const done = (el._enterCb = (cancelled) => {
3663 if (called)
3664 return;
3665 called = true;
3666 if (cancelled) {
3667 callHook(cancelHook, [el]);
3668 }
3669 else {
3670 callHook(afterHook, [el]);
3671 }
3672 if (hooks.delayedLeave) {
3673 hooks.delayedLeave();
3674 }
3675 el._enterCb = undefined;
3676 });
3677 if (hook) {
3678 callAsyncHook(hook, [el, done]);
3679 }
3680 else {
3681 done();
3682 }
3683 },
3684 leave(el, remove) {
3685 const key = String(vnode.key);
3686 if (el._enterCb) {
3687 el._enterCb(true /* cancelled */);
3688 }
3689 if (state.isUnmounting) {
3690 return remove();
3691 }
3692 callHook(onBeforeLeave, [el]);
3693 let called = false;
3694 const done = (el._leaveCb = (cancelled) => {
3695 if (called)
3696 return;
3697 called = true;
3698 remove();
3699 if (cancelled) {
3700 callHook(onLeaveCancelled, [el]);
3701 }
3702 else {
3703 callHook(onAfterLeave, [el]);
3704 }
3705 el._leaveCb = undefined;
3706 if (leavingVNodesCache[key] === vnode) {
3707 delete leavingVNodesCache[key];
3708 }
3709 });
3710 leavingVNodesCache[key] = vnode;
3711 if (onLeave) {
3712 callAsyncHook(onLeave, [el, done]);
3713 }
3714 else {
3715 done();
3716 }
3717 },
3718 clone(vnode) {
3719 return resolveTransitionHooks(vnode, props, state, instance);
3720 }
3721 };
3722 return hooks;
3723}
3724// the placeholder really only handles one special case: KeepAlive
3725// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3726// placeholder with empty content to avoid the KeepAlive instance from being
3727// unmounted.
3728function emptyPlaceholder(vnode) {
3729 if (isKeepAlive(vnode)) {
3730 vnode = cloneVNode(vnode);
3731 vnode.children = null;
3732 return vnode;
3733 }
3734}
3735function getKeepAliveChild(vnode) {
3736 return isKeepAlive(vnode)
3737 ? vnode.children
3738 ? vnode.children[0]
3739 : undefined
3740 : vnode;
3741}
3742function setTransitionHooks(vnode, hooks) {
3743 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3744 setTransitionHooks(vnode.component.subTree, hooks);
3745 }
3746 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3747 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3748 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3749 }
3750 else {
3751 vnode.transition = hooks;
3752 }
3753}
3754function getTransitionRawChildren(children, keepComment = false, parentKey) {
3755 let ret = [];
3756 let keyedFragmentCount = 0;
3757 for (let i = 0; i < children.length; i++) {
3758 let child = children[i];
3759 // #5360 inherit parent key in case of <template v-for>
3760 const key = parentKey == null
3761 ? child.key
3762 : String(parentKey) + String(child.key != null ? child.key : i);
3763 // handle fragment children case, e.g. v-for
3764 if (child.type === Fragment) {
3765 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3766 keyedFragmentCount++;
3767 ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key));
3768 }
3769 // comment placeholders should be skipped, e.g. v-if
3770 else if (keepComment || child.type !== Comment) {
3771 ret.push(key != null ? cloneVNode(child, { key }) : child);
3772 }
3773 }
3774 // #1126 if a transition children list contains multiple sub fragments, these
3775 // fragments will be merged into a flat children array. Since each v-for
3776 // fragment may contain different static bindings inside, we need to de-op
3777 // these children to force full diffs to ensure correct behavior.
3778 if (keyedFragmentCount > 1) {
3779 for (let i = 0; i < ret.length; i++) {
3780 ret[i].patchFlag = -2 /* BAIL */;
3781 }
3782 }
3783 return ret;
3784}
3785
3786// implementation, close to no-op
3787function defineComponent(options) {
3788 return isFunction(options) ? { setup: options, name: options.name } : options;
3789}
3790
3791const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
3792function defineAsyncComponent(source) {
3793 if (isFunction(source)) {
3794 source = { loader: source };
3795 }
3796 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
3797 suspensible = true, onError: userOnError } = source;
3798 let pendingRequest = null;
3799 let resolvedComp;
3800 let retries = 0;
3801 const retry = () => {
3802 retries++;
3803 pendingRequest = null;
3804 return load();
3805 };
3806 const load = () => {
3807 let thisRequest;
3808 return (pendingRequest ||
3809 (thisRequest = pendingRequest =
3810 loader()
3811 .catch(err => {
3812 err = err instanceof Error ? err : new Error(String(err));
3813 if (userOnError) {
3814 return new Promise((resolve, reject) => {
3815 const userRetry = () => resolve(retry());
3816 const userFail = () => reject(err);
3817 userOnError(err, userRetry, userFail, retries + 1);
3818 });
3819 }
3820 else {
3821 throw err;
3822 }
3823 })
3824 .then((comp) => {
3825 if (thisRequest !== pendingRequest && pendingRequest) {
3826 return pendingRequest;
3827 }
3828 if (!comp) {
3829 warn$1(`Async component loader resolved to undefined. ` +
3830 `If you are using retry(), make sure to return its return value.`);
3831 }
3832 // interop module default
3833 if (comp &&
3834 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3835 comp = comp.default;
3836 }
3837 if (comp && !isObject(comp) && !isFunction(comp)) {
3838 throw new Error(`Invalid async component load result: ${comp}`);
3839 }
3840 resolvedComp = comp;
3841 return comp;
3842 })));
3843 };
3844 return defineComponent({
3845 name: 'AsyncComponentWrapper',
3846 __asyncLoader: load,
3847 get __asyncResolved() {
3848 return resolvedComp;
3849 },
3850 setup() {
3851 const instance = currentInstance;
3852 // already resolved
3853 if (resolvedComp) {
3854 return () => createInnerComp(resolvedComp, instance);
3855 }
3856 const onError = (err) => {
3857 pendingRequest = null;
3858 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3859 };
3860 // suspense-controlled or SSR.
3861 if ((suspensible && instance.suspense) ||
3862 (false )) {
3863 return load()
3864 .then(comp => {
3865 return () => createInnerComp(comp, instance);
3866 })
3867 .catch(err => {
3868 onError(err);
3869 return () => errorComponent
3870 ? createVNode(errorComponent, {
3871 error: err
3872 })
3873 : null;
3874 });
3875 }
3876 const loaded = ref(false);
3877 const error = ref();
3878 const delayed = ref(!!delay);
3879 if (delay) {
3880 setTimeout(() => {
3881 delayed.value = false;
3882 }, delay);
3883 }
3884 if (timeout != null) {
3885 setTimeout(() => {
3886 if (!loaded.value && !error.value) {
3887 const err = new Error(`Async component timed out after ${timeout}ms.`);
3888 onError(err);
3889 error.value = err;
3890 }
3891 }, timeout);
3892 }
3893 load()
3894 .then(() => {
3895 loaded.value = true;
3896 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3897 // parent is keep-alive, force update so the loaded component's
3898 // name is taken into account
3899 queueJob(instance.parent.update);
3900 }
3901 })
3902 .catch(err => {
3903 onError(err);
3904 error.value = err;
3905 });
3906 return () => {
3907 if (loaded.value && resolvedComp) {
3908 return createInnerComp(resolvedComp, instance);
3909 }
3910 else if (error.value && errorComponent) {
3911 return createVNode(errorComponent, {
3912 error: error.value
3913 });
3914 }
3915 else if (loadingComponent && !delayed.value) {
3916 return createVNode(loadingComponent);
3917 }
3918 };
3919 }
3920 });
3921}
3922function createInnerComp(comp, { vnode: { ref, props, children, shapeFlag }, parent }) {
3923 const vnode = createVNode(comp, props, children);
3924 // ensure inner component inherits the async wrapper's ref owner
3925 vnode.ref = ref;
3926 return vnode;
3927}
3928
3929const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3930const KeepAliveImpl = {
3931 name: `KeepAlive`,
3932 // Marker for special handling inside the renderer. We are not using a ===
3933 // check directly on KeepAlive in the renderer, because importing it directly
3934 // would prevent it from being tree-shaken.
3935 __isKeepAlive: true,
3936 props: {
3937 include: [String, RegExp, Array],
3938 exclude: [String, RegExp, Array],
3939 max: [String, Number]
3940 },
3941 setup(props, { slots }) {
3942 const instance = getCurrentInstance();
3943 // KeepAlive communicates with the instantiated renderer via the
3944 // ctx where the renderer passes in its internals,
3945 // and the KeepAlive instance exposes activate/deactivate implementations.
3946 // The whole point of this is to avoid importing KeepAlive directly in the
3947 // renderer to facilitate tree-shaking.
3948 const sharedContext = instance.ctx;
3949 const cache = new Map();
3950 const keys = new Set();
3951 let current = null;
3952 {
3953 instance.__v_cache = cache;
3954 }
3955 const parentSuspense = instance.suspense;
3956 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3957 const storageContainer = createElement('div');
3958 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3959 const instance = vnode.component;
3960 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3961 // in case props have changed
3962 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3963 queuePostRenderEffect(() => {
3964 instance.isDeactivated = false;
3965 if (instance.a) {
3966 invokeArrayFns(instance.a);
3967 }
3968 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3969 if (vnodeHook) {
3970 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3971 }
3972 }, parentSuspense);
3973 {
3974 // Update components tree
3975 devtoolsComponentAdded(instance);
3976 }
3977 };
3978 sharedContext.deactivate = (vnode) => {
3979 const instance = vnode.component;
3980 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3981 queuePostRenderEffect(() => {
3982 if (instance.da) {
3983 invokeArrayFns(instance.da);
3984 }
3985 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3986 if (vnodeHook) {
3987 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3988 }
3989 instance.isDeactivated = true;
3990 }, parentSuspense);
3991 {
3992 // Update components tree
3993 devtoolsComponentAdded(instance);
3994 }
3995 };
3996 function unmount(vnode) {
3997 // reset the shapeFlag so it can be properly unmounted
3998 resetShapeFlag(vnode);
3999 _unmount(vnode, instance, parentSuspense, true);
4000 }
4001 function pruneCache(filter) {
4002 cache.forEach((vnode, key) => {
4003 const name = getComponentName(vnode.type);
4004 if (name && (!filter || !filter(name))) {
4005 pruneCacheEntry(key);
4006 }
4007 });
4008 }
4009 function pruneCacheEntry(key) {
4010 const cached = cache.get(key);
4011 if (!current || cached.type !== current.type) {
4012 unmount(cached);
4013 }
4014 else if (current) {
4015 // current active instance should no longer be kept-alive.
4016 // we can't unmount it now but it might be later, so reset its flag now.
4017 resetShapeFlag(current);
4018 }
4019 cache.delete(key);
4020 keys.delete(key);
4021 }
4022 // prune cache on include/exclude prop change
4023 watch(() => [props.include, props.exclude], ([include, exclude]) => {
4024 include && pruneCache(name => matches(include, name));
4025 exclude && pruneCache(name => !matches(exclude, name));
4026 },
4027 // prune post-render after `current` has been updated
4028 { flush: 'post', deep: true });
4029 // cache sub tree after render
4030 let pendingCacheKey = null;
4031 const cacheSubtree = () => {
4032 // fix #1621, the pendingCacheKey could be 0
4033 if (pendingCacheKey != null) {
4034 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
4035 }
4036 };
4037 onMounted(cacheSubtree);
4038 onUpdated(cacheSubtree);
4039 onBeforeUnmount(() => {
4040 cache.forEach(cached => {
4041 const { subTree, suspense } = instance;
4042 const vnode = getInnerChild(subTree);
4043 if (cached.type === vnode.type) {
4044 // current instance will be unmounted as part of keep-alive's unmount
4045 resetShapeFlag(vnode);
4046 // but invoke its deactivated hook here
4047 const da = vnode.component.da;
4048 da && queuePostRenderEffect(da, suspense);
4049 return;
4050 }
4051 unmount(cached);
4052 });
4053 });
4054 return () => {
4055 pendingCacheKey = null;
4056 if (!slots.default) {
4057 return null;
4058 }
4059 const children = slots.default();
4060 const rawVNode = children[0];
4061 if (children.length > 1) {
4062 {
4063 warn$1(`KeepAlive should contain exactly one component child.`);
4064 }
4065 current = null;
4066 return children;
4067 }
4068 else if (!isVNode(rawVNode) ||
4069 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
4070 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
4071 current = null;
4072 return rawVNode;
4073 }
4074 let vnode = getInnerChild(rawVNode);
4075 const comp = vnode.type;
4076 // for async components, name check should be based in its loaded
4077 // inner component if available
4078 const name = getComponentName(isAsyncWrapper(vnode)
4079 ? vnode.type.__asyncResolved || {}
4080 : comp);
4081 const { include, exclude, max } = props;
4082 if ((include && (!name || !matches(include, name))) ||
4083 (exclude && name && matches(exclude, name))) {
4084 current = vnode;
4085 return rawVNode;
4086 }
4087 const key = vnode.key == null ? comp : vnode.key;
4088 const cachedVNode = cache.get(key);
4089 // clone vnode if it's reused because we are going to mutate it
4090 if (vnode.el) {
4091 vnode = cloneVNode(vnode);
4092 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
4093 rawVNode.ssContent = vnode;
4094 }
4095 }
4096 // #1513 it's possible for the returned vnode to be cloned due to attr
4097 // fallthrough or scopeId, so the vnode here may not be the final vnode
4098 // that is mounted. Instead of caching it directly, we store the pending
4099 // key and cache `instance.subTree` (the normalized vnode) in
4100 // beforeMount/beforeUpdate hooks.
4101 pendingCacheKey = key;
4102 if (cachedVNode) {
4103 // copy over mounted state
4104 vnode.el = cachedVNode.el;
4105 vnode.component = cachedVNode.component;
4106 if (vnode.transition) {
4107 // recursively update transition hooks on subTree
4108 setTransitionHooks(vnode, vnode.transition);
4109 }
4110 // avoid vnode being mounted as fresh
4111 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
4112 // make this key the freshest
4113 keys.delete(key);
4114 keys.add(key);
4115 }
4116 else {
4117 keys.add(key);
4118 // prune oldest entry
4119 if (max && keys.size > parseInt(max, 10)) {
4120 pruneCacheEntry(keys.values().next().value);
4121 }
4122 }
4123 // avoid vnode being unmounted
4124 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4125 current = vnode;
4126 return isSuspense(rawVNode.type) ? rawVNode : vnode;
4127 };
4128 }
4129};
4130// export the public type for h/tsx inference
4131// also to avoid inline import() in generated d.ts files
4132const KeepAlive = KeepAliveImpl;
4133function matches(pattern, name) {
4134 if (isArray(pattern)) {
4135 return pattern.some((p) => matches(p, name));
4136 }
4137 else if (isString(pattern)) {
4138 return pattern.split(',').includes(name);
4139 }
4140 else if (pattern.test) {
4141 return pattern.test(name);
4142 }
4143 /* istanbul ignore next */
4144 return false;
4145}
4146function onActivated(hook, target) {
4147 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
4148}
4149function onDeactivated(hook, target) {
4150 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
4151}
4152function registerKeepAliveHook(hook, type, target = currentInstance) {
4153 // cache the deactivate branch check wrapper for injected hooks so the same
4154 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
4155 // deactivation check".
4156 const wrappedHook = hook.__wdc ||
4157 (hook.__wdc = () => {
4158 // only fire the hook if the target instance is NOT in a deactivated branch.
4159 let current = target;
4160 while (current) {
4161 if (current.isDeactivated) {
4162 return;
4163 }
4164 current = current.parent;
4165 }
4166 return hook();
4167 });
4168 injectHook(type, wrappedHook, target);
4169 // In addition to registering it on the target instance, we walk up the parent
4170 // chain and register it on all ancestor instances that are keep-alive roots.
4171 // This avoids the need to walk the entire component tree when invoking these
4172 // hooks, and more importantly, avoids the need to track child components in
4173 // arrays.
4174 if (target) {
4175 let current = target.parent;
4176 while (current && current.parent) {
4177 if (isKeepAlive(current.parent.vnode)) {
4178 injectToKeepAliveRoot(wrappedHook, type, target, current);
4179 }
4180 current = current.parent;
4181 }
4182 }
4183}
4184function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
4185 // injectHook wraps the original for error handling, so make sure to remove
4186 // the wrapped version.
4187 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4188 onUnmounted(() => {
4189 remove(keepAliveRoot[type], injected);
4190 }, target);
4191}
4192function resetShapeFlag(vnode) {
4193 let shapeFlag = vnode.shapeFlag;
4194 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
4195 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4196 }
4197 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
4198 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
4199 }
4200 vnode.shapeFlag = shapeFlag;
4201}
4202function getInnerChild(vnode) {
4203 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
4204}
4205
4206function injectHook(type, hook, target = currentInstance, prepend = false) {
4207 if (target) {
4208 const hooks = target[type] || (target[type] = []);
4209 // cache the error handling wrapper for injected hooks so the same hook
4210 // can be properly deduped by the scheduler. "__weh" stands for "with error
4211 // handling".
4212 const wrappedHook = hook.__weh ||
4213 (hook.__weh = (...args) => {
4214 if (target.isUnmounted) {
4215 return;
4216 }
4217 // disable tracking inside all lifecycle hooks
4218 // since they can potentially be called inside effects.
4219 pauseTracking();
4220 // Set currentInstance during hook invocation.
4221 // This assumes the hook does not synchronously trigger other hooks, which
4222 // can only be false when the user does something really funky.
4223 setCurrentInstance(target);
4224 const res = callWithAsyncErrorHandling(hook, target, type, args);
4225 unsetCurrentInstance();
4226 resetTracking();
4227 return res;
4228 });
4229 if (prepend) {
4230 hooks.unshift(wrappedHook);
4231 }
4232 else {
4233 hooks.push(wrappedHook);
4234 }
4235 return wrappedHook;
4236 }
4237 else {
4238 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
4239 warn$1(`${apiName} is called when there is no active component instance to be ` +
4240 `associated with. ` +
4241 `Lifecycle injection APIs can only be used during execution of setup().` +
4242 (` If you are using async setup(), make sure to register lifecycle ` +
4243 `hooks before the first await statement.`
4244 ));
4245 }
4246}
4247const createHook = (lifecycle) => (hook, target = currentInstance) =>
4248// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
4249(!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
4250 injectHook(lifecycle, hook, target);
4251const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
4252const onMounted = createHook("m" /* MOUNTED */);
4253const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
4254const onUpdated = createHook("u" /* UPDATED */);
4255const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
4256const onUnmounted = createHook("um" /* UNMOUNTED */);
4257const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
4258const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
4259const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
4260function onErrorCaptured(hook, target = currentInstance) {
4261 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
4262}
4263
4264/**
4265Runtime helper for applying directives to a vnode. Example usage:
4266
4267const comp = resolveComponent('comp')
4268const foo = resolveDirective('foo')
4269const bar = resolveDirective('bar')
4270
4271return withDirectives(h(comp), [
4272 [foo, this.x],
4273 [bar, this.y]
4274])
4275*/
4276function validateDirectiveName(name) {
4277 if (isBuiltInDirective(name)) {
4278 warn$1('Do not use built-in directive ids as custom directive id: ' + name);
4279 }
4280}
4281/**
4282 * Adds directives to a VNode.
4283 */
4284function withDirectives(vnode, directives) {
4285 const internalInstance = currentRenderingInstance;
4286 if (internalInstance === null) {
4287 warn$1(`withDirectives can only be used inside render functions.`);
4288 return vnode;
4289 }
4290 const instance = getExposeProxy(internalInstance) ||
4291 internalInstance.proxy;
4292 const bindings = vnode.dirs || (vnode.dirs = []);
4293 for (let i = 0; i < directives.length; i++) {
4294 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4295 if (isFunction(dir)) {
4296 dir = {
4297 mounted: dir,
4298 updated: dir
4299 };
4300 }
4301 if (dir.deep) {
4302 traverse(value);
4303 }
4304 bindings.push({
4305 dir,
4306 instance,
4307 value,
4308 oldValue: void 0,
4309 arg,
4310 modifiers
4311 });
4312 }
4313 return vnode;
4314}
4315function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4316 const bindings = vnode.dirs;
4317 const oldBindings = prevVNode && prevVNode.dirs;
4318 for (let i = 0; i < bindings.length; i++) {
4319 const binding = bindings[i];
4320 if (oldBindings) {
4321 binding.oldValue = oldBindings[i].value;
4322 }
4323 let hook = binding.dir[name];
4324 if (hook) {
4325 // disable tracking inside all lifecycle hooks
4326 // since they can potentially be called inside effects.
4327 pauseTracking();
4328 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4329 vnode.el,
4330 binding,
4331 vnode,
4332 prevVNode
4333 ]);
4334 resetTracking();
4335 }
4336 }
4337}
4338
4339const COMPONENTS = 'components';
4340const DIRECTIVES = 'directives';
4341/**
4342 * @private
4343 */
4344function resolveComponent(name, maybeSelfReference) {
4345 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
4346}
4347const NULL_DYNAMIC_COMPONENT = Symbol();
4348/**
4349 * @private
4350 */
4351function resolveDynamicComponent(component) {
4352 if (isString(component)) {
4353 return resolveAsset(COMPONENTS, component, false) || component;
4354 }
4355 else {
4356 // invalid types will fallthrough to createVNode and raise warning
4357 return (component || NULL_DYNAMIC_COMPONENT);
4358 }
4359}
4360/**
4361 * @private
4362 */
4363function resolveDirective(name) {
4364 return resolveAsset(DIRECTIVES, name);
4365}
4366// implementation
4367function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
4368 const instance = currentRenderingInstance || currentInstance;
4369 if (instance) {
4370 const Component = instance.type;
4371 // explicit self name has highest priority
4372 if (type === COMPONENTS) {
4373 const selfName = getComponentName(Component);
4374 if (selfName &&
4375 (selfName === name ||
4376 selfName === camelize(name) ||
4377 selfName === capitalize(camelize(name)))) {
4378 return Component;
4379 }
4380 }
4381 const res =
4382 // local registration
4383 // check instance[type] first which is resolved for options API
4384 resolve(instance[type] || Component[type], name) ||
4385 // global registration
4386 resolve(instance.appContext[type], name);
4387 if (!res && maybeSelfReference) {
4388 // fallback to implicit self-reference
4389 return Component;
4390 }
4391 if (warnMissing && !res) {
4392 const extra = type === COMPONENTS
4393 ? `\nIf this is a native custom element, make sure to exclude it from ` +
4394 `component resolution via compilerOptions.isCustomElement.`
4395 : ``;
4396 warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
4397 }
4398 return res;
4399 }
4400 else {
4401 warn$1(`resolve${capitalize(type.slice(0, -1))} ` +
4402 `can only be used in render() or setup().`);
4403 }
4404}
4405function resolve(registry, name) {
4406 return (registry &&
4407 (registry[name] ||
4408 registry[camelize(name)] ||
4409 registry[capitalize(camelize(name))]));
4410}
4411
4412/**
4413 * Actual implementation
4414 */
4415function renderList(source, renderItem, cache, index) {
4416 let ret;
4417 const cached = (cache && cache[index]);
4418 if (isArray(source) || isString(source)) {
4419 ret = new Array(source.length);
4420 for (let i = 0, l = source.length; i < l; i++) {
4421 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
4422 }
4423 }
4424 else if (typeof source === 'number') {
4425 if (!Number.isInteger(source)) {
4426 warn$1(`The v-for range expect an integer value but got ${source}.`);
4427 }
4428 ret = new Array(source);
4429 for (let i = 0; i < source; i++) {
4430 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
4431 }
4432 }
4433 else if (isObject(source)) {
4434 if (source[Symbol.iterator]) {
4435 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
4436 }
4437 else {
4438 const keys = Object.keys(source);
4439 ret = new Array(keys.length);
4440 for (let i = 0, l = keys.length; i < l; i++) {
4441 const key = keys[i];
4442 ret[i] = renderItem(source[key], key, i, cached && cached[i]);
4443 }
4444 }
4445 }
4446 else {
4447 ret = [];
4448 }
4449 if (cache) {
4450 cache[index] = ret;
4451 }
4452 return ret;
4453}
4454
4455/**
4456 * Compiler runtime helper for creating dynamic slots object
4457 * @private
4458 */
4459function createSlots(slots, dynamicSlots) {
4460 for (let i = 0; i < dynamicSlots.length; i++) {
4461 const slot = dynamicSlots[i];
4462 // array of dynamic slot generated by <template v-for="..." #[...]>
4463 if (isArray(slot)) {
4464 for (let j = 0; j < slot.length; j++) {
4465 slots[slot[j].name] = slot[j].fn;
4466 }
4467 }
4468 else if (slot) {
4469 // conditional single slot generated by <template v-if="..." #foo>
4470 slots[slot.name] = slot.fn;
4471 }
4472 }
4473 return slots;
4474}
4475
4476/**
4477 * Compiler runtime helper for rendering `<slot/>`
4478 * @private
4479 */
4480function renderSlot(slots, name, props = {},
4481// this is not a user-facing function, so the fallback is always generated by
4482// the compiler and guaranteed to be a function returning an array
4483fallback, noSlotted) {
4484 if (currentRenderingInstance.isCE ||
4485 (currentRenderingInstance.parent &&
4486 isAsyncWrapper(currentRenderingInstance.parent) &&
4487 currentRenderingInstance.parent.isCE)) {
4488 return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback());
4489 }
4490 let slot = slots[name];
4491 if (slot && slot.length > 1) {
4492 warn$1(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
4493 `function. You need to mark this component with $dynamic-slots in the ` +
4494 `parent template.`);
4495 slot = () => [];
4496 }
4497 // a compiled slot disables block tracking by default to avoid manual
4498 // invocation interfering with template-based block tracking, but in
4499 // `renderSlot` we can be sure that it's template-based so we can force
4500 // enable it.
4501 if (slot && slot._c) {
4502 slot._d = false;
4503 }
4504 openBlock();
4505 const validSlotContent = slot && ensureValidVNode(slot(props));
4506 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
4507 ? 64 /* STABLE_FRAGMENT */
4508 : -2 /* BAIL */);
4509 if (!noSlotted && rendered.scopeId) {
4510 rendered.slotScopeIds = [rendered.scopeId + '-s'];
4511 }
4512 if (slot && slot._c) {
4513 slot._d = true;
4514 }
4515 return rendered;
4516}
4517function ensureValidVNode(vnodes) {
4518 return vnodes.some(child => {
4519 if (!isVNode(child))
4520 return true;
4521 if (child.type === Comment)
4522 return false;
4523 if (child.type === Fragment &&
4524 !ensureValidVNode(child.children))
4525 return false;
4526 return true;
4527 })
4528 ? vnodes
4529 : null;
4530}
4531
4532/**
4533 * For prefixing keys in v-on="obj" with "on"
4534 * @private
4535 */
4536function toHandlers(obj) {
4537 const ret = {};
4538 if (!isObject(obj)) {
4539 warn$1(`v-on with no argument expects an object value.`);
4540 return ret;
4541 }
4542 for (const key in obj) {
4543 ret[toHandlerKey(key)] = obj[key];
4544 }
4545 return ret;
4546}
4547
4548/**
4549 * #2437 In Vue 3, functional components do not have a public instance proxy but
4550 * they exist in the internal parent chain. For code that relies on traversing
4551 * public $parent chains, skip functional ones and go to the parent instead.
4552 */
4553const getPublicInstance = (i) => {
4554 if (!i)
4555 return null;
4556 if (isStatefulComponent(i))
4557 return getExposeProxy(i) || i.proxy;
4558 return getPublicInstance(i.parent);
4559};
4560const publicPropertiesMap =
4561// Move PURE marker to new line to workaround compiler discarding it
4562// due to type annotation
4563/*#__PURE__*/ extend(Object.create(null), {
4564 $: i => i,
4565 $el: i => i.vnode.el,
4566 $data: i => i.data,
4567 $props: i => (shallowReadonly(i.props) ),
4568 $attrs: i => (shallowReadonly(i.attrs) ),
4569 $slots: i => (shallowReadonly(i.slots) ),
4570 $refs: i => (shallowReadonly(i.refs) ),
4571 $parent: i => getPublicInstance(i.parent),
4572 $root: i => getPublicInstance(i.root),
4573 $emit: i => i.emit,
4574 $options: i => (resolveMergedOptions(i) ),
4575 $forceUpdate: i => i.f || (i.f = () => queueJob(i.update)),
4576 $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)),
4577 $watch: i => (instanceWatch.bind(i) )
4578});
4579const isReservedPrefix = (key) => key === '_' || key === '$';
4580const PublicInstanceProxyHandlers = {
4581 get({ _: instance }, key) {
4582 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
4583 // for internal formatters to know that this is a Vue instance
4584 if (key === '__isVue') {
4585 return true;
4586 }
4587 // prioritize <script setup> bindings during dev.
4588 // this allows even properties that start with _ or $ to be used - so that
4589 // it aligns with the production behavior where the render fn is inlined and
4590 // indeed has access to all declared variables.
4591 if (setupState !== EMPTY_OBJ &&
4592 setupState.__isScriptSetup &&
4593 hasOwn(setupState, key)) {
4594 return setupState[key];
4595 }
4596 // data / props / ctx
4597 // This getter gets called for every property access on the render context
4598 // during render and is a major hotspot. The most expensive part of this
4599 // is the multiple hasOwn() calls. It's much faster to do a simple property
4600 // access on a plain object, so we use an accessCache object (with null
4601 // prototype) to memoize what access type a key corresponds to.
4602 let normalizedProps;
4603 if (key[0] !== '$') {
4604 const n = accessCache[key];
4605 if (n !== undefined) {
4606 switch (n) {
4607 case 1 /* SETUP */:
4608 return setupState[key];
4609 case 2 /* DATA */:
4610 return data[key];
4611 case 4 /* CONTEXT */:
4612 return ctx[key];
4613 case 3 /* PROPS */:
4614 return props[key];
4615 // default: just fallthrough
4616 }
4617 }
4618 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
4619 accessCache[key] = 1 /* SETUP */;
4620 return setupState[key];
4621 }
4622 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4623 accessCache[key] = 2 /* DATA */;
4624 return data[key];
4625 }
4626 else if (
4627 // only cache other properties when instance has declared (thus stable)
4628 // props
4629 (normalizedProps = instance.propsOptions[0]) &&
4630 hasOwn(normalizedProps, key)) {
4631 accessCache[key] = 3 /* PROPS */;
4632 return props[key];
4633 }
4634 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4635 accessCache[key] = 4 /* CONTEXT */;
4636 return ctx[key];
4637 }
4638 else if (shouldCacheAccess) {
4639 accessCache[key] = 0 /* OTHER */;
4640 }
4641 }
4642 const publicGetter = publicPropertiesMap[key];
4643 let cssModule, globalProperties;
4644 // public $xxx properties
4645 if (publicGetter) {
4646 if (key === '$attrs') {
4647 track(instance, "get" /* GET */, key);
4648 markAttrsAccessed();
4649 }
4650 return publicGetter(instance);
4651 }
4652 else if (
4653 // css module (injected by vue-loader)
4654 (cssModule = type.__cssModules) &&
4655 (cssModule = cssModule[key])) {
4656 return cssModule;
4657 }
4658 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4659 // user may set custom properties to `this` that start with `$`
4660 accessCache[key] = 4 /* CONTEXT */;
4661 return ctx[key];
4662 }
4663 else if (
4664 // global properties
4665 ((globalProperties = appContext.config.globalProperties),
4666 hasOwn(globalProperties, key))) {
4667 {
4668 return globalProperties[key];
4669 }
4670 }
4671 else if (currentRenderingInstance &&
4672 (!isString(key) ||
4673 // #1091 avoid internal isRef/isVNode checks on component instance leading
4674 // to infinite warning loop
4675 key.indexOf('__v') !== 0)) {
4676 if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {
4677 warn$1(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
4678 `character ("$" or "_") and is not proxied on the render context.`);
4679 }
4680 else if (instance === currentRenderingInstance) {
4681 warn$1(`Property ${JSON.stringify(key)} was accessed during render ` +
4682 `but is not defined on instance.`);
4683 }
4684 }
4685 },
4686 set({ _: instance }, key, value) {
4687 const { data, setupState, ctx } = instance;
4688 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
4689 setupState[key] = value;
4690 return true;
4691 }
4692 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4693 data[key] = value;
4694 return true;
4695 }
4696 else if (hasOwn(instance.props, key)) {
4697 warn$1(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
4698 return false;
4699 }
4700 if (key[0] === '$' && key.slice(1) in instance) {
4701 warn$1(`Attempting to mutate public property "${key}". ` +
4702 `Properties starting with $ are reserved and readonly.`, instance);
4703 return false;
4704 }
4705 else {
4706 if (key in instance.appContext.config.globalProperties) {
4707 Object.defineProperty(ctx, key, {
4708 enumerable: true,
4709 configurable: true,
4710 value
4711 });
4712 }
4713 else {
4714 ctx[key] = value;
4715 }
4716 }
4717 return true;
4718 },
4719 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
4720 let normalizedProps;
4721 return (!!accessCache[key] ||
4722 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
4723 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
4724 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
4725 hasOwn(ctx, key) ||
4726 hasOwn(publicPropertiesMap, key) ||
4727 hasOwn(appContext.config.globalProperties, key));
4728 },
4729 defineProperty(target, key, descriptor) {
4730 if (descriptor.get != null) {
4731 // invalidate key cache of a getter based property #5417
4732 target._.accessCache[key] = 0;
4733 }
4734 else if (hasOwn(descriptor, 'value')) {
4735 this.set(target, key, descriptor.value, null);
4736 }
4737 return Reflect.defineProperty(target, key, descriptor);
4738 }
4739};
4740{
4741 PublicInstanceProxyHandlers.ownKeys = (target) => {
4742 warn$1(`Avoid app logic that relies on enumerating keys on a component instance. ` +
4743 `The keys will be empty in production mode to avoid performance overhead.`);
4744 return Reflect.ownKeys(target);
4745 };
4746}
4747const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, {
4748 get(target, key) {
4749 // fast path for unscopables when using `with` block
4750 if (key === Symbol.unscopables) {
4751 return;
4752 }
4753 return PublicInstanceProxyHandlers.get(target, key, target);
4754 },
4755 has(_, key) {
4756 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
4757 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
4758 warn$1(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
4759 }
4760 return has;
4761 }
4762});
4763// dev only
4764// In dev mode, the proxy target exposes the same properties as seen on `this`
4765// for easier console inspection. In prod mode it will be an empty object so
4766// these properties definitions can be skipped.
4767function createDevRenderContext(instance) {
4768 const target = {};
4769 // expose internal instance for proxy handlers
4770 Object.defineProperty(target, `_`, {
4771 configurable: true,
4772 enumerable: false,
4773 get: () => instance
4774 });
4775 // expose public properties
4776 Object.keys(publicPropertiesMap).forEach(key => {
4777 Object.defineProperty(target, key, {
4778 configurable: true,
4779 enumerable: false,
4780 get: () => publicPropertiesMap[key](instance),
4781 // intercepted by the proxy so no need for implementation,
4782 // but needed to prevent set errors
4783 set: NOOP
4784 });
4785 });
4786 return target;
4787}
4788// dev only
4789function exposePropsOnRenderContext(instance) {
4790 const { ctx, propsOptions: [propsOptions] } = instance;
4791 if (propsOptions) {
4792 Object.keys(propsOptions).forEach(key => {
4793 Object.defineProperty(ctx, key, {
4794 enumerable: true,
4795 configurable: true,
4796 get: () => instance.props[key],
4797 set: NOOP
4798 });
4799 });
4800 }
4801}
4802// dev only
4803function exposeSetupStateOnRenderContext(instance) {
4804 const { ctx, setupState } = instance;
4805 Object.keys(toRaw(setupState)).forEach(key => {
4806 if (!setupState.__isScriptSetup) {
4807 if (isReservedPrefix(key[0])) {
4808 warn$1(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
4809 `which are reserved prefixes for Vue internals.`);
4810 return;
4811 }
4812 Object.defineProperty(ctx, key, {
4813 enumerable: true,
4814 configurable: true,
4815 get: () => setupState[key],
4816 set: NOOP
4817 });
4818 }
4819 });
4820}
4821
4822function createDuplicateChecker() {
4823 const cache = Object.create(null);
4824 return (type, key) => {
4825 if (cache[key]) {
4826 warn$1(`${type} property "${key}" is already defined in ${cache[key]}.`);
4827 }
4828 else {
4829 cache[key] = type;
4830 }
4831 };
4832}
4833let shouldCacheAccess = true;
4834function applyOptions(instance) {
4835 const options = resolveMergedOptions(instance);
4836 const publicThis = instance.proxy;
4837 const ctx = instance.ctx;
4838 // do not cache property access on public proxy during state initialization
4839 shouldCacheAccess = false;
4840 // call beforeCreate first before accessing other options since
4841 // the hook may mutate resolved options (#2791)
4842 if (options.beforeCreate) {
4843 callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
4844 }
4845 const {
4846 // state
4847 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
4848 // lifecycle
4849 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
4850 // public API
4851 expose, inheritAttrs,
4852 // assets
4853 components, directives, filters } = options;
4854 const checkDuplicateProperties = createDuplicateChecker() ;
4855 {
4856 const [propsOptions] = instance.propsOptions;
4857 if (propsOptions) {
4858 for (const key in propsOptions) {
4859 checkDuplicateProperties("Props" /* PROPS */, key);
4860 }
4861 }
4862 }
4863 // options initialization order (to be consistent with Vue 2):
4864 // - props (already done outside of this function)
4865 // - inject
4866 // - methods
4867 // - data (deferred since it relies on `this` access)
4868 // - computed
4869 // - watch (deferred since it relies on `this` access)
4870 if (injectOptions) {
4871 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
4872 }
4873 if (methods) {
4874 for (const key in methods) {
4875 const methodHandler = methods[key];
4876 if (isFunction(methodHandler)) {
4877 // In dev mode, we use the `createRenderContext` function to define
4878 // methods to the proxy target, and those are read-only but
4879 // reconfigurable, so it needs to be redefined here
4880 {
4881 Object.defineProperty(ctx, key, {
4882 value: methodHandler.bind(publicThis),
4883 configurable: true,
4884 enumerable: true,
4885 writable: true
4886 });
4887 }
4888 {
4889 checkDuplicateProperties("Methods" /* METHODS */, key);
4890 }
4891 }
4892 else {
4893 warn$1(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
4894 `Did you reference the function correctly?`);
4895 }
4896 }
4897 }
4898 if (dataOptions) {
4899 if (!isFunction(dataOptions)) {
4900 warn$1(`The data option must be a function. ` +
4901 `Plain object usage is no longer supported.`);
4902 }
4903 const data = dataOptions.call(publicThis, publicThis);
4904 if (isPromise(data)) {
4905 warn$1(`data() returned a Promise - note data() cannot be async; If you ` +
4906 `intend to perform data fetching before component renders, use ` +
4907 `async setup() + <Suspense>.`);
4908 }
4909 if (!isObject(data)) {
4910 warn$1(`data() should return an object.`);
4911 }
4912 else {
4913 instance.data = reactive(data);
4914 {
4915 for (const key in data) {
4916 checkDuplicateProperties("Data" /* DATA */, key);
4917 // expose data on ctx during dev
4918 if (!isReservedPrefix(key[0])) {
4919 Object.defineProperty(ctx, key, {
4920 configurable: true,
4921 enumerable: true,
4922 get: () => data[key],
4923 set: NOOP
4924 });
4925 }
4926 }
4927 }
4928 }
4929 }
4930 // state initialization complete at this point - start caching access
4931 shouldCacheAccess = true;
4932 if (computedOptions) {
4933 for (const key in computedOptions) {
4934 const opt = computedOptions[key];
4935 const get = isFunction(opt)
4936 ? opt.bind(publicThis, publicThis)
4937 : isFunction(opt.get)
4938 ? opt.get.bind(publicThis, publicThis)
4939 : NOOP;
4940 if (get === NOOP) {
4941 warn$1(`Computed property "${key}" has no getter.`);
4942 }
4943 const set = !isFunction(opt) && isFunction(opt.set)
4944 ? opt.set.bind(publicThis)
4945 : () => {
4946 warn$1(`Write operation failed: computed property "${key}" is readonly.`);
4947 }
4948 ;
4949 const c = computed$1({
4950 get,
4951 set
4952 });
4953 Object.defineProperty(ctx, key, {
4954 enumerable: true,
4955 configurable: true,
4956 get: () => c.value,
4957 set: v => (c.value = v)
4958 });
4959 {
4960 checkDuplicateProperties("Computed" /* COMPUTED */, key);
4961 }
4962 }
4963 }
4964 if (watchOptions) {
4965 for (const key in watchOptions) {
4966 createWatcher(watchOptions[key], ctx, publicThis, key);
4967 }
4968 }
4969 if (provideOptions) {
4970 const provides = isFunction(provideOptions)
4971 ? provideOptions.call(publicThis)
4972 : provideOptions;
4973 Reflect.ownKeys(provides).forEach(key => {
4974 provide(key, provides[key]);
4975 });
4976 }
4977 if (created) {
4978 callHook(created, instance, "c" /* CREATED */);
4979 }
4980 function registerLifecycleHook(register, hook) {
4981 if (isArray(hook)) {
4982 hook.forEach(_hook => register(_hook.bind(publicThis)));
4983 }
4984 else if (hook) {
4985 register(hook.bind(publicThis));
4986 }
4987 }
4988 registerLifecycleHook(onBeforeMount, beforeMount);
4989 registerLifecycleHook(onMounted, mounted);
4990 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
4991 registerLifecycleHook(onUpdated, updated);
4992 registerLifecycleHook(onActivated, activated);
4993 registerLifecycleHook(onDeactivated, deactivated);
4994 registerLifecycleHook(onErrorCaptured, errorCaptured);
4995 registerLifecycleHook(onRenderTracked, renderTracked);
4996 registerLifecycleHook(onRenderTriggered, renderTriggered);
4997 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
4998 registerLifecycleHook(onUnmounted, unmounted);
4999 registerLifecycleHook(onServerPrefetch, serverPrefetch);
5000 if (isArray(expose)) {
5001 if (expose.length) {
5002 const exposed = instance.exposed || (instance.exposed = {});
5003 expose.forEach(key => {
5004 Object.defineProperty(exposed, key, {
5005 get: () => publicThis[key],
5006 set: val => (publicThis[key] = val)
5007 });
5008 });
5009 }
5010 else if (!instance.exposed) {
5011 instance.exposed = {};
5012 }
5013 }
5014 // options that are handled when creating the instance but also need to be
5015 // applied from mixins
5016 if (render && instance.render === NOOP) {
5017 instance.render = render;
5018 }
5019 if (inheritAttrs != null) {
5020 instance.inheritAttrs = inheritAttrs;
5021 }
5022 // asset options.
5023 if (components)
5024 instance.components = components;
5025 if (directives)
5026 instance.directives = directives;
5027}
5028function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
5029 if (isArray(injectOptions)) {
5030 injectOptions = normalizeInject(injectOptions);
5031 }
5032 for (const key in injectOptions) {
5033 const opt = injectOptions[key];
5034 let injected;
5035 if (isObject(opt)) {
5036 if ('default' in opt) {
5037 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
5038 }
5039 else {
5040 injected = inject(opt.from || key);
5041 }
5042 }
5043 else {
5044 injected = inject(opt);
5045 }
5046 if (isRef(injected)) {
5047 // TODO remove the check in 3.3
5048 if (unwrapRef) {
5049 Object.defineProperty(ctx, key, {
5050 enumerable: true,
5051 configurable: true,
5052 get: () => injected.value,
5053 set: v => (injected.value = v)
5054 });
5055 }
5056 else {
5057 {
5058 warn$1(`injected property "${key}" is a ref and will be auto-unwrapped ` +
5059 `and no longer needs \`.value\` in the next minor release. ` +
5060 `To opt-in to the new behavior now, ` +
5061 `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
5062 `temporary and will not be needed in the future.)`);
5063 }
5064 ctx[key] = injected;
5065 }
5066 }
5067 else {
5068 ctx[key] = injected;
5069 }
5070 {
5071 checkDuplicateProperties("Inject" /* INJECT */, key);
5072 }
5073 }
5074}
5075function callHook(hook, instance, type) {
5076 callWithAsyncErrorHandling(isArray(hook)
5077 ? hook.map(h => h.bind(instance.proxy))
5078 : hook.bind(instance.proxy), instance, type);
5079}
5080function createWatcher(raw, ctx, publicThis, key) {
5081 const getter = key.includes('.')
5082 ? createPathGetter(publicThis, key)
5083 : () => publicThis[key];
5084 if (isString(raw)) {
5085 const handler = ctx[raw];
5086 if (isFunction(handler)) {
5087 watch(getter, handler);
5088 }
5089 else {
5090 warn$1(`Invalid watch handler specified by key "${raw}"`, handler);
5091 }
5092 }
5093 else if (isFunction(raw)) {
5094 watch(getter, raw.bind(publicThis));
5095 }
5096 else if (isObject(raw)) {
5097 if (isArray(raw)) {
5098 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
5099 }
5100 else {
5101 const handler = isFunction(raw.handler)
5102 ? raw.handler.bind(publicThis)
5103 : ctx[raw.handler];
5104 if (isFunction(handler)) {
5105 watch(getter, handler, raw);
5106 }
5107 else {
5108 warn$1(`Invalid watch handler specified by key "${raw.handler}"`, handler);
5109 }
5110 }
5111 }
5112 else {
5113 warn$1(`Invalid watch option: "${key}"`, raw);
5114 }
5115}
5116/**
5117 * Resolve merged options and cache it on the component.
5118 * This is done only once per-component since the merging does not involve
5119 * instances.
5120 */
5121function resolveMergedOptions(instance) {
5122 const base = instance.type;
5123 const { mixins, extends: extendsOptions } = base;
5124 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
5125 const cached = cache.get(base);
5126 let resolved;
5127 if (cached) {
5128 resolved = cached;
5129 }
5130 else if (!globalMixins.length && !mixins && !extendsOptions) {
5131 {
5132 resolved = base;
5133 }
5134 }
5135 else {
5136 resolved = {};
5137 if (globalMixins.length) {
5138 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
5139 }
5140 mergeOptions(resolved, base, optionMergeStrategies);
5141 }
5142 cache.set(base, resolved);
5143 return resolved;
5144}
5145function mergeOptions(to, from, strats, asMixin = false) {
5146 const { mixins, extends: extendsOptions } = from;
5147 if (extendsOptions) {
5148 mergeOptions(to, extendsOptions, strats, true);
5149 }
5150 if (mixins) {
5151 mixins.forEach((m) => mergeOptions(to, m, strats, true));
5152 }
5153 for (const key in from) {
5154 if (asMixin && key === 'expose') {
5155 warn$1(`"expose" option is ignored when declared in mixins or extends. ` +
5156 `It should only be declared in the base component itself.`);
5157 }
5158 else {
5159 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
5160 to[key] = strat ? strat(to[key], from[key]) : from[key];
5161 }
5162 }
5163 return to;
5164}
5165const internalOptionMergeStrats = {
5166 data: mergeDataFn,
5167 props: mergeObjectOptions,
5168 emits: mergeObjectOptions,
5169 // objects
5170 methods: mergeObjectOptions,
5171 computed: mergeObjectOptions,
5172 // lifecycle
5173 beforeCreate: mergeAsArray,
5174 created: mergeAsArray,
5175 beforeMount: mergeAsArray,
5176 mounted: mergeAsArray,
5177 beforeUpdate: mergeAsArray,
5178 updated: mergeAsArray,
5179 beforeDestroy: mergeAsArray,
5180 beforeUnmount: mergeAsArray,
5181 destroyed: mergeAsArray,
5182 unmounted: mergeAsArray,
5183 activated: mergeAsArray,
5184 deactivated: mergeAsArray,
5185 errorCaptured: mergeAsArray,
5186 serverPrefetch: mergeAsArray,
5187 // assets
5188 components: mergeObjectOptions,
5189 directives: mergeObjectOptions,
5190 // watch
5191 watch: mergeWatchOptions,
5192 // provide / inject
5193 provide: mergeDataFn,
5194 inject: mergeInject
5195};
5196function mergeDataFn(to, from) {
5197 if (!from) {
5198 return to;
5199 }
5200 if (!to) {
5201 return from;
5202 }
5203 return function mergedDataFn() {
5204 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
5205 };
5206}
5207function mergeInject(to, from) {
5208 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
5209}
5210function normalizeInject(raw) {
5211 if (isArray(raw)) {
5212 const res = {};
5213 for (let i = 0; i < raw.length; i++) {
5214 res[raw[i]] = raw[i];
5215 }
5216 return res;
5217 }
5218 return raw;
5219}
5220function mergeAsArray(to, from) {
5221 return to ? [...new Set([].concat(to, from))] : from;
5222}
5223function mergeObjectOptions(to, from) {
5224 return to ? extend(extend(Object.create(null), to), from) : from;
5225}
5226function mergeWatchOptions(to, from) {
5227 if (!to)
5228 return from;
5229 if (!from)
5230 return to;
5231 const merged = extend(Object.create(null), to);
5232 for (const key in from) {
5233 merged[key] = mergeAsArray(to[key], from[key]);
5234 }
5235 return merged;
5236}
5237
5238function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
5239isSSR = false) {
5240 const props = {};
5241 const attrs = {};
5242 def(attrs, InternalObjectKey, 1);
5243 instance.propsDefaults = Object.create(null);
5244 setFullProps(instance, rawProps, props, attrs);
5245 // ensure all declared prop keys are present
5246 for (const key in instance.propsOptions[0]) {
5247 if (!(key in props)) {
5248 props[key] = undefined;
5249 }
5250 }
5251 // validation
5252 {
5253 validateProps(rawProps || {}, props, instance);
5254 }
5255 if (isStateful) {
5256 // stateful
5257 instance.props = isSSR ? props : shallowReactive(props);
5258 }
5259 else {
5260 if (!instance.type.props) {
5261 // functional w/ optional props, props === attrs
5262 instance.props = attrs;
5263 }
5264 else {
5265 // functional w/ declared props
5266 instance.props = props;
5267 }
5268 }
5269 instance.attrs = attrs;
5270}
5271function updateProps(instance, rawProps, rawPrevProps, optimized) {
5272 const { props, attrs, vnode: { patchFlag } } = instance;
5273 const rawCurrentProps = toRaw(props);
5274 const [options] = instance.propsOptions;
5275 let hasAttrsChanged = false;
5276 if (
5277 // always force full diff in dev
5278 // - #1942 if hmr is enabled with sfc component
5279 // - vite#872 non-sfc component used by sfc component
5280 !((instance.type.__hmrId ||
5281 (instance.parent && instance.parent.type.__hmrId))) &&
5282 (optimized || patchFlag > 0) &&
5283 !(patchFlag & 16 /* FULL_PROPS */)) {
5284 if (patchFlag & 8 /* PROPS */) {
5285 // Compiler-generated props & no keys change, just set the updated
5286 // the props.
5287 const propsToUpdate = instance.vnode.dynamicProps;
5288 for (let i = 0; i < propsToUpdate.length; i++) {
5289 let key = propsToUpdate[i];
5290 // skip if the prop key is a declared emit event listener
5291 if (isEmitListener(instance.emitsOptions, key)) {
5292 continue;
5293 }
5294 // PROPS flag guarantees rawProps to be non-null
5295 const value = rawProps[key];
5296 if (options) {
5297 // attr / props separation was done on init and will be consistent
5298 // in this code path, so just check if attrs have it.
5299 if (hasOwn(attrs, key)) {
5300 if (value !== attrs[key]) {
5301 attrs[key] = value;
5302 hasAttrsChanged = true;
5303 }
5304 }
5305 else {
5306 const camelizedKey = camelize(key);
5307 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
5308 }
5309 }
5310 else {
5311 if (value !== attrs[key]) {
5312 attrs[key] = value;
5313 hasAttrsChanged = true;
5314 }
5315 }
5316 }
5317 }
5318 }
5319 else {
5320 // full props update.
5321 if (setFullProps(instance, rawProps, props, attrs)) {
5322 hasAttrsChanged = true;
5323 }
5324 // in case of dynamic props, check if we need to delete keys from
5325 // the props object
5326 let kebabKey;
5327 for (const key in rawCurrentProps) {
5328 if (!rawProps ||
5329 // for camelCase
5330 (!hasOwn(rawProps, key) &&
5331 // it's possible the original props was passed in as kebab-case
5332 // and converted to camelCase (#955)
5333 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
5334 if (options) {
5335 if (rawPrevProps &&
5336 // for camelCase
5337 (rawPrevProps[key] !== undefined ||
5338 // for kebab-case
5339 rawPrevProps[kebabKey] !== undefined)) {
5340 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
5341 }
5342 }
5343 else {
5344 delete props[key];
5345 }
5346 }
5347 }
5348 // in the case of functional component w/o props declaration, props and
5349 // attrs point to the same object so it should already have been updated.
5350 if (attrs !== rawCurrentProps) {
5351 for (const key in attrs) {
5352 if (!rawProps ||
5353 (!hasOwn(rawProps, key) &&
5354 (!false ))) {
5355 delete attrs[key];
5356 hasAttrsChanged = true;
5357 }
5358 }
5359 }
5360 }
5361 // trigger updates for $attrs in case it's used in component slots
5362 if (hasAttrsChanged) {
5363 trigger(instance, "set" /* SET */, '$attrs');
5364 }
5365 {
5366 validateProps(rawProps || {}, props, instance);
5367 }
5368}
5369function setFullProps(instance, rawProps, props, attrs) {
5370 const [options, needCastKeys] = instance.propsOptions;
5371 let hasAttrsChanged = false;
5372 let rawCastValues;
5373 if (rawProps) {
5374 for (let key in rawProps) {
5375 // key, ref are reserved and never passed down
5376 if (isReservedProp(key)) {
5377 continue;
5378 }
5379 const value = rawProps[key];
5380 // prop option names are camelized during normalization, so to support
5381 // kebab -> camel conversion here we need to camelize the key.
5382 let camelKey;
5383 if (options && hasOwn(options, (camelKey = camelize(key)))) {
5384 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
5385 props[camelKey] = value;
5386 }
5387 else {
5388 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
5389 }
5390 }
5391 else if (!isEmitListener(instance.emitsOptions, key)) {
5392 if (!(key in attrs) || value !== attrs[key]) {
5393 attrs[key] = value;
5394 hasAttrsChanged = true;
5395 }
5396 }
5397 }
5398 }
5399 if (needCastKeys) {
5400 const rawCurrentProps = toRaw(props);
5401 const castValues = rawCastValues || EMPTY_OBJ;
5402 for (let i = 0; i < needCastKeys.length; i++) {
5403 const key = needCastKeys[i];
5404 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
5405 }
5406 }
5407 return hasAttrsChanged;
5408}
5409function resolvePropValue(options, props, key, value, instance, isAbsent) {
5410 const opt = options[key];
5411 if (opt != null) {
5412 const hasDefault = hasOwn(opt, 'default');
5413 // default values
5414 if (hasDefault && value === undefined) {
5415 const defaultValue = opt.default;
5416 if (opt.type !== Function && isFunction(defaultValue)) {
5417 const { propsDefaults } = instance;
5418 if (key in propsDefaults) {
5419 value = propsDefaults[key];
5420 }
5421 else {
5422 setCurrentInstance(instance);
5423 value = propsDefaults[key] = defaultValue.call(null, props);
5424 unsetCurrentInstance();
5425 }
5426 }
5427 else {
5428 value = defaultValue;
5429 }
5430 }
5431 // boolean casting
5432 if (opt[0 /* shouldCast */]) {
5433 if (isAbsent && !hasDefault) {
5434 value = false;
5435 }
5436 else if (opt[1 /* shouldCastTrue */] &&
5437 (value === '' || value === hyphenate(key))) {
5438 value = true;
5439 }
5440 }
5441 }
5442 return value;
5443}
5444function normalizePropsOptions(comp, appContext, asMixin = false) {
5445 const cache = appContext.propsCache;
5446 const cached = cache.get(comp);
5447 if (cached) {
5448 return cached;
5449 }
5450 const raw = comp.props;
5451 const normalized = {};
5452 const needCastKeys = [];
5453 // apply mixin/extends props
5454 let hasExtends = false;
5455 if (!isFunction(comp)) {
5456 const extendProps = (raw) => {
5457 hasExtends = true;
5458 const [props, keys] = normalizePropsOptions(raw, appContext, true);
5459 extend(normalized, props);
5460 if (keys)
5461 needCastKeys.push(...keys);
5462 };
5463 if (!asMixin && appContext.mixins.length) {
5464 appContext.mixins.forEach(extendProps);
5465 }
5466 if (comp.extends) {
5467 extendProps(comp.extends);
5468 }
5469 if (comp.mixins) {
5470 comp.mixins.forEach(extendProps);
5471 }
5472 }
5473 if (!raw && !hasExtends) {
5474 cache.set(comp, EMPTY_ARR);
5475 return EMPTY_ARR;
5476 }
5477 if (isArray(raw)) {
5478 for (let i = 0; i < raw.length; i++) {
5479 if (!isString(raw[i])) {
5480 warn$1(`props must be strings when using array syntax.`, raw[i]);
5481 }
5482 const normalizedKey = camelize(raw[i]);
5483 if (validatePropName(normalizedKey)) {
5484 normalized[normalizedKey] = EMPTY_OBJ;
5485 }
5486 }
5487 }
5488 else if (raw) {
5489 if (!isObject(raw)) {
5490 warn$1(`invalid props options`, raw);
5491 }
5492 for (const key in raw) {
5493 const normalizedKey = camelize(key);
5494 if (validatePropName(normalizedKey)) {
5495 const opt = raw[key];
5496 const prop = (normalized[normalizedKey] =
5497 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
5498 if (prop) {
5499 const booleanIndex = getTypeIndex(Boolean, prop.type);
5500 const stringIndex = getTypeIndex(String, prop.type);
5501 prop[0 /* shouldCast */] = booleanIndex > -1;
5502 prop[1 /* shouldCastTrue */] =
5503 stringIndex < 0 || booleanIndex < stringIndex;
5504 // if the prop needs boolean casting or default value
5505 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
5506 needCastKeys.push(normalizedKey);
5507 }
5508 }
5509 }
5510 }
5511 }
5512 const res = [normalized, needCastKeys];
5513 cache.set(comp, res);
5514 return res;
5515}
5516function validatePropName(key) {
5517 if (key[0] !== '$') {
5518 return true;
5519 }
5520 else {
5521 warn$1(`Invalid prop name: "${key}" is a reserved property.`);
5522 }
5523 return false;
5524}
5525// use function string name to check type constructors
5526// so that it works across vms / iframes.
5527function getType(ctor) {
5528 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
5529 return match ? match[1] : ctor === null ? 'null' : '';
5530}
5531function isSameType(a, b) {
5532 return getType(a) === getType(b);
5533}
5534function getTypeIndex(type, expectedTypes) {
5535 if (isArray(expectedTypes)) {
5536 return expectedTypes.findIndex(t => isSameType(t, type));
5537 }
5538 else if (isFunction(expectedTypes)) {
5539 return isSameType(expectedTypes, type) ? 0 : -1;
5540 }
5541 return -1;
5542}
5543/**
5544 * dev only
5545 */
5546function validateProps(rawProps, props, instance) {
5547 const resolvedValues = toRaw(props);
5548 const options = instance.propsOptions[0];
5549 for (const key in options) {
5550 let opt = options[key];
5551 if (opt == null)
5552 continue;
5553 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
5554 }
5555}
5556/**
5557 * dev only
5558 */
5559function validateProp(name, value, prop, isAbsent) {
5560 const { type, required, validator } = prop;
5561 // required!
5562 if (required && isAbsent) {
5563 warn$1('Missing required prop: "' + name + '"');
5564 return;
5565 }
5566 // missing but optional
5567 if (value == null && !prop.required) {
5568 return;
5569 }
5570 // type check
5571 if (type != null && type !== true) {
5572 let isValid = false;
5573 const types = isArray(type) ? type : [type];
5574 const expectedTypes = [];
5575 // value is valid as long as one of the specified types match
5576 for (let i = 0; i < types.length && !isValid; i++) {
5577 const { valid, expectedType } = assertType(value, types[i]);
5578 expectedTypes.push(expectedType || '');
5579 isValid = valid;
5580 }
5581 if (!isValid) {
5582 warn$1(getInvalidTypeMessage(name, value, expectedTypes));
5583 return;
5584 }
5585 }
5586 // custom validator
5587 if (validator && !validator(value)) {
5588 warn$1('Invalid prop: custom validator check failed for prop "' + name + '".');
5589 }
5590}
5591const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
5592/**
5593 * dev only
5594 */
5595function assertType(value, type) {
5596 let valid;
5597 const expectedType = getType(type);
5598 if (isSimpleType(expectedType)) {
5599 const t = typeof value;
5600 valid = t === expectedType.toLowerCase();
5601 // for primitive wrapper objects
5602 if (!valid && t === 'object') {
5603 valid = value instanceof type;
5604 }
5605 }
5606 else if (expectedType === 'Object') {
5607 valid = isObject(value);
5608 }
5609 else if (expectedType === 'Array') {
5610 valid = isArray(value);
5611 }
5612 else if (expectedType === 'null') {
5613 valid = value === null;
5614 }
5615 else {
5616 valid = value instanceof type;
5617 }
5618 return {
5619 valid,
5620 expectedType
5621 };
5622}
5623/**
5624 * dev only
5625 */
5626function getInvalidTypeMessage(name, value, expectedTypes) {
5627 let message = `Invalid prop: type check failed for prop "${name}".` +
5628 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
5629 const expectedType = expectedTypes[0];
5630 const receivedType = toRawType(value);
5631 const expectedValue = styleValue(value, expectedType);
5632 const receivedValue = styleValue(value, receivedType);
5633 // check if we need to specify expected value
5634 if (expectedTypes.length === 1 &&
5635 isExplicable(expectedType) &&
5636 !isBoolean(expectedType, receivedType)) {
5637 message += ` with value ${expectedValue}`;
5638 }
5639 message += `, got ${receivedType} `;
5640 // check if we need to specify received value
5641 if (isExplicable(receivedType)) {
5642 message += `with value ${receivedValue}.`;
5643 }
5644 return message;
5645}
5646/**
5647 * dev only
5648 */
5649function styleValue(value, type) {
5650 if (type === 'String') {
5651 return `"${value}"`;
5652 }
5653 else if (type === 'Number') {
5654 return `${Number(value)}`;
5655 }
5656 else {
5657 return `${value}`;
5658 }
5659}
5660/**
5661 * dev only
5662 */
5663function isExplicable(type) {
5664 const explicitTypes = ['string', 'number', 'boolean'];
5665 return explicitTypes.some(elem => type.toLowerCase() === elem);
5666}
5667/**
5668 * dev only
5669 */
5670function isBoolean(...args) {
5671 return args.some(elem => elem.toLowerCase() === 'boolean');
5672}
5673
5674const isInternalKey = (key) => key[0] === '_' || key === '$stable';
5675const normalizeSlotValue = (value) => isArray(value)
5676 ? value.map(normalizeVNode)
5677 : [normalizeVNode(value)];
5678const normalizeSlot = (key, rawSlot, ctx) => {
5679 if (rawSlot._n) {
5680 // already normalized - #5353
5681 return rawSlot;
5682 }
5683 const normalized = withCtx((...args) => {
5684 if (currentInstance) {
5685 warn$1(`Slot "${key}" invoked outside of the render function: ` +
5686 `this will not track dependencies used in the slot. ` +
5687 `Invoke the slot function inside the render function instead.`);
5688 }
5689 return normalizeSlotValue(rawSlot(...args));
5690 }, ctx);
5691 normalized._c = false;
5692 return normalized;
5693};
5694const normalizeObjectSlots = (rawSlots, slots, instance) => {
5695 const ctx = rawSlots._ctx;
5696 for (const key in rawSlots) {
5697 if (isInternalKey(key))
5698 continue;
5699 const value = rawSlots[key];
5700 if (isFunction(value)) {
5701 slots[key] = normalizeSlot(key, value, ctx);
5702 }
5703 else if (value != null) {
5704 {
5705 warn$1(`Non-function value encountered for slot "${key}". ` +
5706 `Prefer function slots for better performance.`);
5707 }
5708 const normalized = normalizeSlotValue(value);
5709 slots[key] = () => normalized;
5710 }
5711 }
5712};
5713const normalizeVNodeSlots = (instance, children) => {
5714 if (!isKeepAlive(instance.vnode) &&
5715 !(false )) {
5716 warn$1(`Non-function value encountered for default slot. ` +
5717 `Prefer function slots for better performance.`);
5718 }
5719 const normalized = normalizeSlotValue(children);
5720 instance.slots.default = () => normalized;
5721};
5722const initSlots = (instance, children) => {
5723 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5724 const type = children._;
5725 if (type) {
5726 // users can get the shallow readonly version of the slots object through `this.$slots`,
5727 // we should avoid the proxy object polluting the slots of the internal instance
5728 instance.slots = toRaw(children);
5729 // make compiler marker non-enumerable
5730 def(children, '_', type);
5731 }
5732 else {
5733 normalizeObjectSlots(children, (instance.slots = {}));
5734 }
5735 }
5736 else {
5737 instance.slots = {};
5738 if (children) {
5739 normalizeVNodeSlots(instance, children);
5740 }
5741 }
5742 def(instance.slots, InternalObjectKey, 1);
5743};
5744const updateSlots = (instance, children, optimized) => {
5745 const { vnode, slots } = instance;
5746 let needDeletionCheck = true;
5747 let deletionComparisonTarget = EMPTY_OBJ;
5748 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5749 const type = children._;
5750 if (type) {
5751 // compiled slots.
5752 if (isHmrUpdating) {
5753 // Parent was HMR updated so slot content may have changed.
5754 // force update slots and mark instance for hmr as well
5755 extend(slots, children);
5756 }
5757 else if (optimized && type === 1 /* STABLE */) {
5758 // compiled AND stable.
5759 // no need to update, and skip stale slots removal.
5760 needDeletionCheck = false;
5761 }
5762 else {
5763 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
5764 // normalization.
5765 extend(slots, children);
5766 // #2893
5767 // when rendering the optimized slots by manually written render function,
5768 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
5769 // i.e. let the `renderSlot` create the bailed Fragment
5770 if (!optimized && type === 1 /* STABLE */) {
5771 delete slots._;
5772 }
5773 }
5774 }
5775 else {
5776 needDeletionCheck = !children.$stable;
5777 normalizeObjectSlots(children, slots);
5778 }
5779 deletionComparisonTarget = children;
5780 }
5781 else if (children) {
5782 // non slot object children (direct value) passed to a component
5783 normalizeVNodeSlots(instance, children);
5784 deletionComparisonTarget = { default: 1 };
5785 }
5786 // delete stale slots
5787 if (needDeletionCheck) {
5788 for (const key in slots) {
5789 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
5790 delete slots[key];
5791 }
5792 }
5793 }
5794};
5795
5796function createAppContext() {
5797 return {
5798 app: null,
5799 config: {
5800 isNativeTag: NO,
5801 performance: false,
5802 globalProperties: {},
5803 optionMergeStrategies: {},
5804 errorHandler: undefined,
5805 warnHandler: undefined,
5806 compilerOptions: {}
5807 },
5808 mixins: [],
5809 components: {},
5810 directives: {},
5811 provides: Object.create(null),
5812 optionsCache: new WeakMap(),
5813 propsCache: new WeakMap(),
5814 emitsCache: new WeakMap()
5815 };
5816}
5817let uid = 0;
5818function createAppAPI(render, hydrate) {
5819 return function createApp(rootComponent, rootProps = null) {
5820 if (!isFunction(rootComponent)) {
5821 rootComponent = Object.assign({}, rootComponent);
5822 }
5823 if (rootProps != null && !isObject(rootProps)) {
5824 warn$1(`root props passed to app.mount() must be an object.`);
5825 rootProps = null;
5826 }
5827 const context = createAppContext();
5828 const installedPlugins = new Set();
5829 let isMounted = false;
5830 const app = (context.app = {
5831 _uid: uid++,
5832 _component: rootComponent,
5833 _props: rootProps,
5834 _container: null,
5835 _context: context,
5836 _instance: null,
5837 version,
5838 get config() {
5839 return context.config;
5840 },
5841 set config(v) {
5842 {
5843 warn$1(`app.config cannot be replaced. Modify individual options instead.`);
5844 }
5845 },
5846 use(plugin, ...options) {
5847 if (installedPlugins.has(plugin)) {
5848 warn$1(`Plugin has already been applied to target app.`);
5849 }
5850 else if (plugin && isFunction(plugin.install)) {
5851 installedPlugins.add(plugin);
5852 plugin.install(app, ...options);
5853 }
5854 else if (isFunction(plugin)) {
5855 installedPlugins.add(plugin);
5856 plugin(app, ...options);
5857 }
5858 else {
5859 warn$1(`A plugin must either be a function or an object with an "install" ` +
5860 `function.`);
5861 }
5862 return app;
5863 },
5864 mixin(mixin) {
5865 {
5866 if (!context.mixins.includes(mixin)) {
5867 context.mixins.push(mixin);
5868 }
5869 else {
5870 warn$1('Mixin has already been applied to target app' +
5871 (mixin.name ? `: ${mixin.name}` : ''));
5872 }
5873 }
5874 return app;
5875 },
5876 component(name, component) {
5877 {
5878 validateComponentName(name, context.config);
5879 }
5880 if (!component) {
5881 return context.components[name];
5882 }
5883 if (context.components[name]) {
5884 warn$1(`Component "${name}" has already been registered in target app.`);
5885 }
5886 context.components[name] = component;
5887 return app;
5888 },
5889 directive(name, directive) {
5890 {
5891 validateDirectiveName(name);
5892 }
5893 if (!directive) {
5894 return context.directives[name];
5895 }
5896 if (context.directives[name]) {
5897 warn$1(`Directive "${name}" has already been registered in target app.`);
5898 }
5899 context.directives[name] = directive;
5900 return app;
5901 },
5902 mount(rootContainer, isHydrate, isSVG) {
5903 if (!isMounted) {
5904 // #5571
5905 if (rootContainer.__vue_app__) {
5906 warn$1(`There is already an app instance mounted on the host container.\n` +
5907 ` If you want to mount another app on the same host container,` +
5908 ` you need to unmount the previous app by calling \`app.unmount()\` first.`);
5909 }
5910 const vnode = createVNode(rootComponent, rootProps);
5911 // store app context on the root VNode.
5912 // this will be set on the root instance on initial mount.
5913 vnode.appContext = context;
5914 // HMR root reload
5915 {
5916 context.reload = () => {
5917 render(cloneVNode(vnode), rootContainer, isSVG);
5918 };
5919 }
5920 if (isHydrate && hydrate) {
5921 hydrate(vnode, rootContainer);
5922 }
5923 else {
5924 render(vnode, rootContainer, isSVG);
5925 }
5926 isMounted = true;
5927 app._container = rootContainer;
5928 rootContainer.__vue_app__ = app;
5929 {
5930 app._instance = vnode.component;
5931 devtoolsInitApp(app, version);
5932 }
5933 return getExposeProxy(vnode.component) || vnode.component.proxy;
5934 }
5935 else {
5936 warn$1(`App has already been mounted.\n` +
5937 `If you want to remount the same app, move your app creation logic ` +
5938 `into a factory function and create fresh app instances for each ` +
5939 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
5940 }
5941 },
5942 unmount() {
5943 if (isMounted) {
5944 render(null, app._container);
5945 {
5946 app._instance = null;
5947 devtoolsUnmountApp(app);
5948 }
5949 delete app._container.__vue_app__;
5950 }
5951 else {
5952 warn$1(`Cannot unmount an app that is not mounted.`);
5953 }
5954 },
5955 provide(key, value) {
5956 if (key in context.provides) {
5957 warn$1(`App already provides property with key "${String(key)}". ` +
5958 `It will be overwritten with the new value.`);
5959 }
5960 context.provides[key] = value;
5961 return app;
5962 }
5963 });
5964 return app;
5965 };
5966}
5967
5968/**
5969 * Function for handling a template ref
5970 */
5971function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
5972 if (isArray(rawRef)) {
5973 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
5974 return;
5975 }
5976 if (isAsyncWrapper(vnode) && !isUnmount) {
5977 // when mounting async components, nothing needs to be done,
5978 // because the template ref is forwarded to inner component
5979 return;
5980 }
5981 const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
5982 ? getExposeProxy(vnode.component) || vnode.component.proxy
5983 : vnode.el;
5984 const value = isUnmount ? null : refValue;
5985 const { i: owner, r: ref } = rawRef;
5986 if (!owner) {
5987 warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
5988 `A vnode with ref must be created inside the render function.`);
5989 return;
5990 }
5991 const oldRef = oldRawRef && oldRawRef.r;
5992 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
5993 const setupState = owner.setupState;
5994 // dynamic ref changed. unset old ref
5995 if (oldRef != null && oldRef !== ref) {
5996 if (isString(oldRef)) {
5997 refs[oldRef] = null;
5998 if (hasOwn(setupState, oldRef)) {
5999 setupState[oldRef] = null;
6000 }
6001 }
6002 else if (isRef(oldRef)) {
6003 oldRef.value = null;
6004 }
6005 }
6006 if (isFunction(ref)) {
6007 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6008 }
6009 else {
6010 const _isString = isString(ref);
6011 const _isRef = isRef(ref);
6012 if (_isString || _isRef) {
6013 const doSet = () => {
6014 if (rawRef.f) {
6015 const existing = _isString ? refs[ref] : ref.value;
6016 if (isUnmount) {
6017 isArray(existing) && remove(existing, refValue);
6018 }
6019 else {
6020 if (!isArray(existing)) {
6021 if (_isString) {
6022 refs[ref] = [refValue];
6023 if (hasOwn(setupState, ref)) {
6024 setupState[ref] = refs[ref];
6025 }
6026 }
6027 else {
6028 ref.value = [refValue];
6029 if (rawRef.k)
6030 refs[rawRef.k] = ref.value;
6031 }
6032 }
6033 else if (!existing.includes(refValue)) {
6034 existing.push(refValue);
6035 }
6036 }
6037 }
6038 else if (_isString) {
6039 refs[ref] = value;
6040 if (hasOwn(setupState, ref)) {
6041 setupState[ref] = value;
6042 }
6043 }
6044 else if (isRef(ref)) {
6045 ref.value = value;
6046 if (rawRef.k)
6047 refs[rawRef.k] = value;
6048 }
6049 else {
6050 warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6051 }
6052 };
6053 if (value) {
6054 doSet.id = -1;
6055 queuePostRenderEffect(doSet, parentSuspense);
6056 }
6057 else {
6058 doSet();
6059 }
6060 }
6061 else {
6062 warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6063 }
6064 }
6065}
6066
6067let hasMismatch = false;
6068const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
6069const isComment = (node) => node.nodeType === 8 /* COMMENT */;
6070// Note: hydration is DOM-specific
6071// But we have to place it in core due to tight coupling with core - splitting
6072// it out creates a ton of unnecessary complexity.
6073// Hydration also depends on some renderer internal logic which needs to be
6074// passed in via arguments.
6075function createHydrationFunctions(rendererInternals) {
6076 const { mt: mountComponent, p: patch, o: { patchProp, createText, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
6077 const hydrate = (vnode, container) => {
6078 if (!container.hasChildNodes()) {
6079 warn$1(`Attempting to hydrate existing markup but container is empty. ` +
6080 `Performing full mount instead.`);
6081 patch(null, vnode, container);
6082 flushPostFlushCbs();
6083 return;
6084 }
6085 hasMismatch = false;
6086 hydrateNode(container.firstChild, vnode, null, null, null);
6087 flushPostFlushCbs();
6088 if (hasMismatch && !false) {
6089 // this error should show up in production
6090 console.error(`Hydration completed but contains mismatches.`);
6091 }
6092 };
6093 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
6094 const isFragmentStart = isComment(node) && node.data === '[';
6095 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
6096 const { type, ref, shapeFlag, patchFlag } = vnode;
6097 const domType = node.nodeType;
6098 vnode.el = node;
6099 if (patchFlag === -2 /* BAIL */) {
6100 optimized = false;
6101 vnode.dynamicChildren = null;
6102 }
6103 let nextNode = null;
6104 switch (type) {
6105 case Text:
6106 if (domType !== 3 /* TEXT */) {
6107 // #5728 empty text node inside a slot can cause hydration failure
6108 // because the server rendered HTML won't contain a text node
6109 if (vnode.children === '') {
6110 insert((vnode.el = createText('')), parentNode(node), node);
6111 nextNode = node;
6112 }
6113 else {
6114 nextNode = onMismatch();
6115 }
6116 }
6117 else {
6118 if (node.data !== vnode.children) {
6119 hasMismatch = true;
6120 warn$1(`Hydration text mismatch:` +
6121 `\n- Client: ${JSON.stringify(node.data)}` +
6122 `\n- Server: ${JSON.stringify(vnode.children)}`);
6123 node.data = vnode.children;
6124 }
6125 nextNode = nextSibling(node);
6126 }
6127 break;
6128 case Comment:
6129 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
6130 nextNode = onMismatch();
6131 }
6132 else {
6133 nextNode = nextSibling(node);
6134 }
6135 break;
6136 case Static:
6137 if (domType !== 1 /* ELEMENT */) {
6138 nextNode = onMismatch();
6139 }
6140 else {
6141 // determine anchor, adopt content
6142 nextNode = node;
6143 // if the static vnode has its content stripped during build,
6144 // adopt it from the server-rendered HTML.
6145 const needToAdoptContent = !vnode.children.length;
6146 for (let i = 0; i < vnode.staticCount; i++) {
6147 if (needToAdoptContent)
6148 vnode.children += nextNode.outerHTML;
6149 if (i === vnode.staticCount - 1) {
6150 vnode.anchor = nextNode;
6151 }
6152 nextNode = nextSibling(nextNode);
6153 }
6154 return nextNode;
6155 }
6156 break;
6157 case Fragment:
6158 if (!isFragmentStart) {
6159 nextNode = onMismatch();
6160 }
6161 else {
6162 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6163 }
6164 break;
6165 default:
6166 if (shapeFlag & 1 /* ELEMENT */) {
6167 if (domType !== 1 /* ELEMENT */ ||
6168 vnode.type.toLowerCase() !==
6169 node.tagName.toLowerCase()) {
6170 nextNode = onMismatch();
6171 }
6172 else {
6173 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6174 }
6175 }
6176 else if (shapeFlag & 6 /* COMPONENT */) {
6177 // when setting up the render effect, if the initial vnode already
6178 // has .el set, the component will perform hydration instead of mount
6179 // on its sub-tree.
6180 vnode.slotScopeIds = slotScopeIds;
6181 const container = parentNode(node);
6182 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
6183 // component may be async, so in the case of fragments we cannot rely
6184 // on component's rendered output to determine the end of the fragment
6185 // instead, we do a lookahead to find the end anchor node.
6186 nextNode = isFragmentStart
6187 ? locateClosingAsyncAnchor(node)
6188 : nextSibling(node);
6189 // #4293 teleport as component root
6190 if (nextNode &&
6191 isComment(nextNode) &&
6192 nextNode.data === 'teleport end') {
6193 nextNode = nextSibling(nextNode);
6194 }
6195 // #3787
6196 // if component is async, it may get moved / unmounted before its
6197 // inner component is loaded, so we need to give it a placeholder
6198 // vnode that matches its adopted DOM.
6199 if (isAsyncWrapper(vnode)) {
6200 let subTree;
6201 if (isFragmentStart) {
6202 subTree = createVNode(Fragment);
6203 subTree.anchor = nextNode
6204 ? nextNode.previousSibling
6205 : container.lastChild;
6206 }
6207 else {
6208 subTree =
6209 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
6210 }
6211 subTree.el = node;
6212 vnode.component.subTree = subTree;
6213 }
6214 }
6215 else if (shapeFlag & 64 /* TELEPORT */) {
6216 if (domType !== 8 /* COMMENT */) {
6217 nextNode = onMismatch();
6218 }
6219 else {
6220 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
6221 }
6222 }
6223 else if (shapeFlag & 128 /* SUSPENSE */) {
6224 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
6225 }
6226 else {
6227 warn$1('Invalid HostVNode type:', type, `(${typeof type})`);
6228 }
6229 }
6230 if (ref != null) {
6231 setRef(ref, null, parentSuspense, vnode);
6232 }
6233 return nextNode;
6234 };
6235 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6236 optimized = optimized || !!vnode.dynamicChildren;
6237 const { type, props, patchFlag, shapeFlag, dirs } = vnode;
6238 // #4006 for form elements with non-string v-model value bindings
6239 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
6240 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
6241 // skip props & children if this is hoisted static nodes
6242 // #5405 in dev, always hydrate children for HMR
6243 {
6244 if (dirs) {
6245 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6246 }
6247 // props
6248 if (props) {
6249 if (forcePatchValue ||
6250 !optimized ||
6251 patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) {
6252 for (const key in props) {
6253 if ((forcePatchValue && key.endsWith('value')) ||
6254 (isOn(key) && !isReservedProp(key))) {
6255 patchProp(el, key, null, props[key], false, undefined, parentComponent);
6256 }
6257 }
6258 }
6259 else if (props.onClick) {
6260 // Fast path for click listeners (which is most often) to avoid
6261 // iterating through props.
6262 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent);
6263 }
6264 }
6265 // vnode / directive hooks
6266 let vnodeHooks;
6267 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
6268 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6269 }
6270 if (dirs) {
6271 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6272 }
6273 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
6274 queueEffectWithSuspense(() => {
6275 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6276 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6277 }, parentSuspense);
6278 }
6279 // children
6280 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
6281 // skip if element has innerHTML / textContent
6282 !(props && (props.innerHTML || props.textContent))) {
6283 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
6284 let hasWarned = false;
6285 while (next) {
6286 hasMismatch = true;
6287 if (!hasWarned) {
6288 warn$1(`Hydration children mismatch in <${vnode.type}>: ` +
6289 `server rendered element contains more child nodes than client vdom.`);
6290 hasWarned = true;
6291 }
6292 // The SSRed DOM contains more nodes than it should. Remove them.
6293 const cur = next;
6294 next = next.nextSibling;
6295 remove(cur);
6296 }
6297 }
6298 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6299 if (el.textContent !== vnode.children) {
6300 hasMismatch = true;
6301 warn$1(`Hydration text content mismatch in <${vnode.type}>:\n` +
6302 `- Client: ${el.textContent}\n` +
6303 `- Server: ${vnode.children}`);
6304 el.textContent = vnode.children;
6305 }
6306 }
6307 }
6308 return el.nextSibling;
6309 };
6310 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6311 optimized = optimized || !!parentVNode.dynamicChildren;
6312 const children = parentVNode.children;
6313 const l = children.length;
6314 let hasWarned = false;
6315 for (let i = 0; i < l; i++) {
6316 const vnode = optimized
6317 ? children[i]
6318 : (children[i] = normalizeVNode(children[i]));
6319 if (node) {
6320 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6321 }
6322 else if (vnode.type === Text && !vnode.children) {
6323 continue;
6324 }
6325 else {
6326 hasMismatch = true;
6327 if (!hasWarned) {
6328 warn$1(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
6329 `server rendered element contains fewer child nodes than client vdom.`);
6330 hasWarned = true;
6331 }
6332 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
6333 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6334 }
6335 }
6336 return node;
6337 };
6338 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6339 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
6340 if (fragmentSlotScopeIds) {
6341 slotScopeIds = slotScopeIds
6342 ? slotScopeIds.concat(fragmentSlotScopeIds)
6343 : fragmentSlotScopeIds;
6344 }
6345 const container = parentNode(node);
6346 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
6347 if (next && isComment(next) && next.data === ']') {
6348 return nextSibling((vnode.anchor = next));
6349 }
6350 else {
6351 // fragment didn't hydrate successfully, since we didn't get a end anchor
6352 // back. This should have led to node/children mismatch warnings.
6353 hasMismatch = true;
6354 // since the anchor is missing, we need to create one and insert it
6355 insert((vnode.anchor = createComment(`]`)), container, next);
6356 return next;
6357 }
6358 };
6359 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
6360 hasMismatch = true;
6361 warn$1(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
6362 ? `(text)`
6363 : isComment(node) && node.data === '['
6364 ? `(start of fragment)`
6365 : ``);
6366 vnode.el = null;
6367 if (isFragment) {
6368 // remove excessive fragment nodes
6369 const end = locateClosingAsyncAnchor(node);
6370 while (true) {
6371 const next = nextSibling(node);
6372 if (next && next !== end) {
6373 remove(next);
6374 }
6375 else {
6376 break;
6377 }
6378 }
6379 }
6380 const next = nextSibling(node);
6381 const container = parentNode(node);
6382 remove(node);
6383 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6384 return next;
6385 };
6386 const locateClosingAsyncAnchor = (node) => {
6387 let match = 0;
6388 while (node) {
6389 node = nextSibling(node);
6390 if (node && isComment(node)) {
6391 if (node.data === '[')
6392 match++;
6393 if (node.data === ']') {
6394 if (match === 0) {
6395 return nextSibling(node);
6396 }
6397 else {
6398 match--;
6399 }
6400 }
6401 }
6402 }
6403 return node;
6404 };
6405 return [hydrate, hydrateNode];
6406}
6407
6408/* eslint-disable no-restricted-globals */
6409let supported;
6410let perf;
6411function startMeasure(instance, type) {
6412 if (instance.appContext.config.performance && isSupported()) {
6413 perf.mark(`vue-${type}-${instance.uid}`);
6414 }
6415 {
6416 devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now());
6417 }
6418}
6419function endMeasure(instance, type) {
6420 if (instance.appContext.config.performance && isSupported()) {
6421 const startTag = `vue-${type}-${instance.uid}`;
6422 const endTag = startTag + `:end`;
6423 perf.mark(endTag);
6424 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
6425 perf.clearMarks(startTag);
6426 perf.clearMarks(endTag);
6427 }
6428 {
6429 devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now());
6430 }
6431}
6432function isSupported() {
6433 if (supported !== undefined) {
6434 return supported;
6435 }
6436 if (typeof window !== 'undefined' && window.performance) {
6437 supported = true;
6438 perf = window.performance;
6439 }
6440 else {
6441 supported = false;
6442 }
6443 return supported;
6444}
6445
6446const queuePostRenderEffect = queueEffectWithSuspense
6447 ;
6448/**
6449 * The createRenderer function accepts two generic arguments:
6450 * HostNode and HostElement, corresponding to Node and Element types in the
6451 * host environment. For example, for runtime-dom, HostNode would be the DOM
6452 * `Node` interface and HostElement would be the DOM `Element` interface.
6453 *
6454 * Custom renderers can pass in the platform specific types like this:
6455 *
6456 * ``` js
6457 * const { render, createApp } = createRenderer<Node, Element>({
6458 * patchProp,
6459 * ...nodeOps
6460 * })
6461 * ```
6462 */
6463function createRenderer(options) {
6464 return baseCreateRenderer(options);
6465}
6466// Separate API for creating hydration-enabled renderer.
6467// Hydration logic is only used when calling this function, making it
6468// tree-shakable.
6469function createHydrationRenderer(options) {
6470 return baseCreateRenderer(options, createHydrationFunctions);
6471}
6472// implementation
6473function baseCreateRenderer(options, createHydrationFns) {
6474 const target = getGlobalThis();
6475 target.__VUE__ = true;
6476 {
6477 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
6478 }
6479 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;
6480 // Note: functions inside this closure should use `const xxx = () => {}`
6481 // style in order to prevent being inlined by minifiers.
6482 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
6483 if (n1 === n2) {
6484 return;
6485 }
6486 // patching & not same type, unmount old tree
6487 if (n1 && !isSameVNodeType(n1, n2)) {
6488 anchor = getNextHostNode(n1);
6489 unmount(n1, parentComponent, parentSuspense, true);
6490 n1 = null;
6491 }
6492 if (n2.patchFlag === -2 /* BAIL */) {
6493 optimized = false;
6494 n2.dynamicChildren = null;
6495 }
6496 const { type, ref, shapeFlag } = n2;
6497 switch (type) {
6498 case Text:
6499 processText(n1, n2, container, anchor);
6500 break;
6501 case Comment:
6502 processCommentNode(n1, n2, container, anchor);
6503 break;
6504 case Static:
6505 if (n1 == null) {
6506 mountStaticNode(n2, container, anchor, isSVG);
6507 }
6508 else {
6509 patchStaticNode(n1, n2, container, isSVG);
6510 }
6511 break;
6512 case Fragment:
6513 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6514 break;
6515 default:
6516 if (shapeFlag & 1 /* ELEMENT */) {
6517 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6518 }
6519 else if (shapeFlag & 6 /* COMPONENT */) {
6520 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6521 }
6522 else if (shapeFlag & 64 /* TELEPORT */) {
6523 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6524 }
6525 else if (shapeFlag & 128 /* SUSPENSE */) {
6526 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6527 }
6528 else {
6529 warn$1('Invalid VNode type:', type, `(${typeof type})`);
6530 }
6531 }
6532 // set ref
6533 if (ref != null && parentComponent) {
6534 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
6535 }
6536 };
6537 const processText = (n1, n2, container, anchor) => {
6538 if (n1 == null) {
6539 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
6540 }
6541 else {
6542 const el = (n2.el = n1.el);
6543 if (n2.children !== n1.children) {
6544 hostSetText(el, n2.children);
6545 }
6546 }
6547 };
6548 const processCommentNode = (n1, n2, container, anchor) => {
6549 if (n1 == null) {
6550 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
6551 }
6552 else {
6553 // there's no support for dynamic comments
6554 n2.el = n1.el;
6555 }
6556 };
6557 const mountStaticNode = (n2, container, anchor, isSVG) => {
6558 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG, n2.el, n2.anchor);
6559 };
6560 /**
6561 * Dev / HMR only
6562 */
6563 const patchStaticNode = (n1, n2, container, isSVG) => {
6564 // static nodes are only patched during dev for HMR
6565 if (n2.children !== n1.children) {
6566 const anchor = hostNextSibling(n1.anchor);
6567 // remove existing
6568 removeStaticNode(n1);
6569 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
6570 }
6571 else {
6572 n2.el = n1.el;
6573 n2.anchor = n1.anchor;
6574 }
6575 };
6576 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
6577 let next;
6578 while (el && el !== anchor) {
6579 next = hostNextSibling(el);
6580 hostInsert(el, container, nextSibling);
6581 el = next;
6582 }
6583 hostInsert(anchor, container, nextSibling);
6584 };
6585 const removeStaticNode = ({ el, anchor }) => {
6586 let next;
6587 while (el && el !== anchor) {
6588 next = hostNextSibling(el);
6589 hostRemove(el);
6590 el = next;
6591 }
6592 hostRemove(anchor);
6593 };
6594 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6595 isSVG = isSVG || n2.type === 'svg';
6596 if (n1 == null) {
6597 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6598 }
6599 else {
6600 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6601 }
6602 };
6603 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6604 let el;
6605 let vnodeHook;
6606 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
6607 {
6608 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6609 // mount children first, since some props may rely on child content
6610 // being already rendered, e.g. `<select value>`
6611 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6612 hostSetElementText(el, vnode.children);
6613 }
6614 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6615 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6616 }
6617 if (dirs) {
6618 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6619 }
6620 // props
6621 if (props) {
6622 for (const key in props) {
6623 if (key !== 'value' && !isReservedProp(key)) {
6624 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6625 }
6626 }
6627 /**
6628 * Special case for setting value on DOM elements:
6629 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6630 * - it needs to be forced (#1471)
6631 * #2353 proposes adding another renderer option to configure this, but
6632 * the properties affects are so finite it is worth special casing it
6633 * here to reduce the complexity. (Special casing it also should not
6634 * affect non-DOM renderers)
6635 */
6636 if ('value' in props) {
6637 hostPatchProp(el, 'value', null, props.value);
6638 }
6639 if ((vnodeHook = props.onVnodeBeforeMount)) {
6640 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6641 }
6642 }
6643 // scopeId
6644 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6645 }
6646 {
6647 Object.defineProperty(el, '__vnode', {
6648 value: vnode,
6649 enumerable: false
6650 });
6651 Object.defineProperty(el, '__vueParentComponent', {
6652 value: parentComponent,
6653 enumerable: false
6654 });
6655 }
6656 if (dirs) {
6657 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6658 }
6659 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
6660 // #1689 For inside suspense + suspense resolved case, just call it
6661 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
6662 transition &&
6663 !transition.persisted;
6664 if (needCallTransitionHooks) {
6665 transition.beforeEnter(el);
6666 }
6667 hostInsert(el, container, anchor);
6668 if ((vnodeHook = props && props.onVnodeMounted) ||
6669 needCallTransitionHooks ||
6670 dirs) {
6671 queuePostRenderEffect(() => {
6672 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6673 needCallTransitionHooks && transition.enter(el);
6674 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6675 }, parentSuspense);
6676 }
6677 };
6678 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
6679 if (scopeId) {
6680 hostSetScopeId(el, scopeId);
6681 }
6682 if (slotScopeIds) {
6683 for (let i = 0; i < slotScopeIds.length; i++) {
6684 hostSetScopeId(el, slotScopeIds[i]);
6685 }
6686 }
6687 if (parentComponent) {
6688 let subTree = parentComponent.subTree;
6689 if (subTree.patchFlag > 0 &&
6690 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
6691 subTree =
6692 filterSingleRoot(subTree.children) || subTree;
6693 }
6694 if (vnode === subTree) {
6695 const parentVNode = parentComponent.vnode;
6696 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
6697 }
6698 }
6699 };
6700 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
6701 for (let i = start; i < children.length; i++) {
6702 const child = (children[i] = optimized
6703 ? cloneIfMounted(children[i])
6704 : normalizeVNode(children[i]));
6705 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6706 }
6707 };
6708 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6709 const el = (n2.el = n1.el);
6710 let { patchFlag, dynamicChildren, dirs } = n2;
6711 // #1426 take the old vnode's patch flag into account since user may clone a
6712 // compiler-generated vnode, which de-opts to FULL_PROPS
6713 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
6714 const oldProps = n1.props || EMPTY_OBJ;
6715 const newProps = n2.props || EMPTY_OBJ;
6716 let vnodeHook;
6717 // disable recurse in beforeUpdate hooks
6718 parentComponent && toggleRecurse(parentComponent, false);
6719 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6720 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6721 }
6722 if (dirs) {
6723 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6724 }
6725 parentComponent && toggleRecurse(parentComponent, true);
6726 if (isHmrUpdating) {
6727 // HMR updated, force full diff
6728 patchFlag = 0;
6729 optimized = false;
6730 dynamicChildren = null;
6731 }
6732 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
6733 if (dynamicChildren) {
6734 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
6735 if (parentComponent && parentComponent.type.__hmrId) {
6736 traverseStaticChildren(n1, n2);
6737 }
6738 }
6739 else if (!optimized) {
6740 // full diff
6741 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
6742 }
6743 if (patchFlag > 0) {
6744 // the presence of a patchFlag means this element's render code was
6745 // generated by the compiler and can take the fast path.
6746 // in this path old node and new node are guaranteed to have the same shape
6747 // (i.e. at the exact same position in the source template)
6748 if (patchFlag & 16 /* FULL_PROPS */) {
6749 // element props contain dynamic keys, full diff needed
6750 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6751 }
6752 else {
6753 // class
6754 // this flag is matched when the element has dynamic class bindings.
6755 if (patchFlag & 2 /* CLASS */) {
6756 if (oldProps.class !== newProps.class) {
6757 hostPatchProp(el, 'class', null, newProps.class, isSVG);
6758 }
6759 }
6760 // style
6761 // this flag is matched when the element has dynamic style bindings
6762 if (patchFlag & 4 /* STYLE */) {
6763 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
6764 }
6765 // props
6766 // This flag is matched when the element has dynamic prop/attr bindings
6767 // other than class and style. The keys of dynamic prop/attrs are saved for
6768 // faster iteration.
6769 // Note dynamic keys like :[foo]="bar" will cause this optimization to
6770 // bail out and go through a full diff because we need to unset the old key
6771 if (patchFlag & 8 /* PROPS */) {
6772 // if the flag is present then dynamicProps must be non-null
6773 const propsToUpdate = n2.dynamicProps;
6774 for (let i = 0; i < propsToUpdate.length; i++) {
6775 const key = propsToUpdate[i];
6776 const prev = oldProps[key];
6777 const next = newProps[key];
6778 // #1471 force patch value
6779 if (next !== prev || key === 'value') {
6780 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
6781 }
6782 }
6783 }
6784 }
6785 // text
6786 // This flag is matched when the element has only dynamic text children.
6787 if (patchFlag & 1 /* TEXT */) {
6788 if (n1.children !== n2.children) {
6789 hostSetElementText(el, n2.children);
6790 }
6791 }
6792 }
6793 else if (!optimized && dynamicChildren == null) {
6794 // unoptimized, full diff
6795 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6796 }
6797 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
6798 queuePostRenderEffect(() => {
6799 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6800 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
6801 }, parentSuspense);
6802 }
6803 };
6804 // The fast path for blocks.
6805 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
6806 for (let i = 0; i < newChildren.length; i++) {
6807 const oldVNode = oldChildren[i];
6808 const newVNode = newChildren[i];
6809 // Determine the container (parent element) for the patch.
6810 const container =
6811 // oldVNode may be an errored async setup() component inside Suspense
6812 // which will not have a mounted element
6813 oldVNode.el &&
6814 // - In the case of a Fragment, we need to provide the actual parent
6815 // of the Fragment itself so it can move its children.
6816 (oldVNode.type === Fragment ||
6817 // - In the case of different nodes, there is going to be a replacement
6818 // which also requires the correct parent container
6819 !isSameVNodeType(oldVNode, newVNode) ||
6820 // - In the case of a component, it could contain anything.
6821 oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */))
6822 ? hostParentNode(oldVNode.el)
6823 : // In other cases, the parent container is not actually used so we
6824 // just pass the block element here to avoid a DOM parentNode call.
6825 fallbackContainer;
6826 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
6827 }
6828 };
6829 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
6830 if (oldProps !== newProps) {
6831 for (const key in newProps) {
6832 // empty string is not valid prop
6833 if (isReservedProp(key))
6834 continue;
6835 const next = newProps[key];
6836 const prev = oldProps[key];
6837 // defer patching value
6838 if (next !== prev && key !== 'value') {
6839 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6840 }
6841 }
6842 if (oldProps !== EMPTY_OBJ) {
6843 for (const key in oldProps) {
6844 if (!isReservedProp(key) && !(key in newProps)) {
6845 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6846 }
6847 }
6848 }
6849 if ('value' in newProps) {
6850 hostPatchProp(el, 'value', oldProps.value, newProps.value);
6851 }
6852 }
6853 };
6854 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6855 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
6856 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
6857 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
6858 if (// #5523 dev root fragment may inherit directives
6859 (isHmrUpdating || patchFlag & 2048 /* DEV_ROOT_FRAGMENT */)) {
6860 // HMR updated / Dev root fragment (w/ comments), force full diff
6861 patchFlag = 0;
6862 optimized = false;
6863 dynamicChildren = null;
6864 }
6865 // check if this is a slot fragment with :slotted scope ids
6866 if (fragmentSlotScopeIds) {
6867 slotScopeIds = slotScopeIds
6868 ? slotScopeIds.concat(fragmentSlotScopeIds)
6869 : fragmentSlotScopeIds;
6870 }
6871 if (n1 == null) {
6872 hostInsert(fragmentStartAnchor, container, anchor);
6873 hostInsert(fragmentEndAnchor, container, anchor);
6874 // a fragment can only have array children
6875 // since they are either generated by the compiler, or implicitly created
6876 // from arrays.
6877 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6878 }
6879 else {
6880 if (patchFlag > 0 &&
6881 patchFlag & 64 /* STABLE_FRAGMENT */ &&
6882 dynamicChildren &&
6883 // #2715 the previous fragment could've been a BAILed one as a result
6884 // of renderSlot() with no valid children
6885 n1.dynamicChildren) {
6886 // a stable fragment (template root or <template v-for>) doesn't need to
6887 // patch children order, but it may contain dynamicChildren.
6888 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
6889 if (parentComponent && parentComponent.type.__hmrId) {
6890 traverseStaticChildren(n1, n2);
6891 }
6892 else if (
6893 // #2080 if the stable fragment has a key, it's a <template v-for> that may
6894 // get moved around. Make sure all root level vnodes inherit el.
6895 // #2134 or if it's a component root, it may also get moved around
6896 // as the component is being moved.
6897 n2.key != null ||
6898 (parentComponent && n2 === parentComponent.subTree)) {
6899 traverseStaticChildren(n1, n2, true /* shallow */);
6900 }
6901 }
6902 else {
6903 // keyed / unkeyed, or manual fragments.
6904 // for keyed & unkeyed, since they are compiler generated from v-for,
6905 // each child is guaranteed to be a block so the fragment will never
6906 // have dynamicChildren.
6907 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6908 }
6909 }
6910 };
6911 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6912 n2.slotScopeIds = slotScopeIds;
6913 if (n1 == null) {
6914 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
6915 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
6916 }
6917 else {
6918 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
6919 }
6920 }
6921 else {
6922 updateComponent(n1, n2, optimized);
6923 }
6924 };
6925 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
6926 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
6927 if (instance.type.__hmrId) {
6928 registerHMR(instance);
6929 }
6930 {
6931 pushWarningContext(initialVNode);
6932 startMeasure(instance, `mount`);
6933 }
6934 // inject renderer internals for keepAlive
6935 if (isKeepAlive(initialVNode)) {
6936 instance.ctx.renderer = internals;
6937 }
6938 // resolve props and slots for setup context
6939 {
6940 {
6941 startMeasure(instance, `init`);
6942 }
6943 setupComponent(instance);
6944 {
6945 endMeasure(instance, `init`);
6946 }
6947 }
6948 // setup() is async. This component relies on async logic to be resolved
6949 // before proceeding
6950 if (instance.asyncDep) {
6951 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
6952 // Give it a placeholder if this is not hydration
6953 // TODO handle self-defined fallback
6954 if (!initialVNode.el) {
6955 const placeholder = (instance.subTree = createVNode(Comment));
6956 processCommentNode(null, placeholder, container, anchor);
6957 }
6958 return;
6959 }
6960 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
6961 {
6962 popWarningContext();
6963 endMeasure(instance, `mount`);
6964 }
6965 };
6966 const updateComponent = (n1, n2, optimized) => {
6967 const instance = (n2.component = n1.component);
6968 if (shouldUpdateComponent(n1, n2, optimized)) {
6969 if (instance.asyncDep &&
6970 !instance.asyncResolved) {
6971 // async & still pending - just update props and slots
6972 // since the component's reactive effect for render isn't set-up yet
6973 {
6974 pushWarningContext(n2);
6975 }
6976 updateComponentPreRender(instance, n2, optimized);
6977 {
6978 popWarningContext();
6979 }
6980 return;
6981 }
6982 else {
6983 // normal update
6984 instance.next = n2;
6985 // in case the child component is also queued, remove it to avoid
6986 // double updating the same child component in the same flush.
6987 invalidateJob(instance.update);
6988 // instance.update is the reactive effect.
6989 instance.update();
6990 }
6991 }
6992 else {
6993 // no update needed. just copy over properties
6994 n2.el = n1.el;
6995 instance.vnode = n2;
6996 }
6997 };
6998 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
6999 const componentUpdateFn = () => {
7000 if (!instance.isMounted) {
7001 let vnodeHook;
7002 const { el, props } = initialVNode;
7003 const { bm, m, parent } = instance;
7004 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
7005 toggleRecurse(instance, false);
7006 // beforeMount hook
7007 if (bm) {
7008 invokeArrayFns(bm);
7009 }
7010 // onVnodeBeforeMount
7011 if (!isAsyncWrapperVNode &&
7012 (vnodeHook = props && props.onVnodeBeforeMount)) {
7013 invokeVNodeHook(vnodeHook, parent, initialVNode);
7014 }
7015 toggleRecurse(instance, true);
7016 if (el && hydrateNode) {
7017 // vnode has adopted host node - perform hydration instead of mount.
7018 const hydrateSubTree = () => {
7019 {
7020 startMeasure(instance, `render`);
7021 }
7022 instance.subTree = renderComponentRoot(instance);
7023 {
7024 endMeasure(instance, `render`);
7025 }
7026 {
7027 startMeasure(instance, `hydrate`);
7028 }
7029 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
7030 {
7031 endMeasure(instance, `hydrate`);
7032 }
7033 };
7034 if (isAsyncWrapperVNode) {
7035 initialVNode.type.__asyncLoader().then(
7036 // note: we are moving the render call into an async callback,
7037 // which means it won't track dependencies - but it's ok because
7038 // a server-rendered async wrapper is already in resolved state
7039 // and it will never need to change.
7040 () => !instance.isUnmounted && hydrateSubTree());
7041 }
7042 else {
7043 hydrateSubTree();
7044 }
7045 }
7046 else {
7047 {
7048 startMeasure(instance, `render`);
7049 }
7050 const subTree = (instance.subTree = renderComponentRoot(instance));
7051 {
7052 endMeasure(instance, `render`);
7053 }
7054 {
7055 startMeasure(instance, `patch`);
7056 }
7057 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
7058 {
7059 endMeasure(instance, `patch`);
7060 }
7061 initialVNode.el = subTree.el;
7062 }
7063 // mounted hook
7064 if (m) {
7065 queuePostRenderEffect(m, parentSuspense);
7066 }
7067 // onVnodeMounted
7068 if (!isAsyncWrapperVNode &&
7069 (vnodeHook = props && props.onVnodeMounted)) {
7070 const scopedInitialVNode = initialVNode;
7071 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
7072 }
7073 // activated hook for keep-alive roots.
7074 // #1742 activated hook must be accessed after first render
7075 // since the hook may be injected by a child keep-alive
7076 if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */ ||
7077 (parent &&
7078 isAsyncWrapper(parent.vnode) &&
7079 parent.vnode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */)) {
7080 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
7081 }
7082 instance.isMounted = true;
7083 {
7084 devtoolsComponentAdded(instance);
7085 }
7086 // #2458: deference mount-only object parameters to prevent memleaks
7087 initialVNode = container = anchor = null;
7088 }
7089 else {
7090 // updateComponent
7091 // This is triggered by mutation of component's own state (next: null)
7092 // OR parent calling processComponent (next: VNode)
7093 let { next, bu, u, parent, vnode } = instance;
7094 let originNext = next;
7095 let vnodeHook;
7096 {
7097 pushWarningContext(next || instance.vnode);
7098 }
7099 // Disallow component effect recursion during pre-lifecycle hooks.
7100 toggleRecurse(instance, false);
7101 if (next) {
7102 next.el = vnode.el;
7103 updateComponentPreRender(instance, next, optimized);
7104 }
7105 else {
7106 next = vnode;
7107 }
7108 // beforeUpdate hook
7109 if (bu) {
7110 invokeArrayFns(bu);
7111 }
7112 // onVnodeBeforeUpdate
7113 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
7114 invokeVNodeHook(vnodeHook, parent, next, vnode);
7115 }
7116 toggleRecurse(instance, true);
7117 // render
7118 {
7119 startMeasure(instance, `render`);
7120 }
7121 const nextTree = renderComponentRoot(instance);
7122 {
7123 endMeasure(instance, `render`);
7124 }
7125 const prevTree = instance.subTree;
7126 instance.subTree = nextTree;
7127 {
7128 startMeasure(instance, `patch`);
7129 }
7130 patch(prevTree, nextTree,
7131 // parent may have changed if it's in a teleport
7132 hostParentNode(prevTree.el),
7133 // anchor may have changed if it's in a fragment
7134 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
7135 {
7136 endMeasure(instance, `patch`);
7137 }
7138 next.el = nextTree.el;
7139 if (originNext === null) {
7140 // self-triggered update. In case of HOC, update parent component
7141 // vnode el. HOC is indicated by parent instance's subTree pointing
7142 // to child component's vnode
7143 updateHOCHostEl(instance, nextTree.el);
7144 }
7145 // updated hook
7146 if (u) {
7147 queuePostRenderEffect(u, parentSuspense);
7148 }
7149 // onVnodeUpdated
7150 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
7151 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
7152 }
7153 {
7154 devtoolsComponentUpdated(instance);
7155 }
7156 {
7157 popWarningContext();
7158 }
7159 }
7160 };
7161 // create reactive effect for rendering
7162 const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(update), instance.scope // track it in component's effect scope
7163 ));
7164 const update = (instance.update = () => effect.run());
7165 update.id = instance.uid;
7166 // allowRecurse
7167 // #1801, #2043 component render effects should allow recursive updates
7168 toggleRecurse(instance, true);
7169 {
7170 effect.onTrack = instance.rtc
7171 ? e => invokeArrayFns(instance.rtc, e)
7172 : void 0;
7173 effect.onTrigger = instance.rtg
7174 ? e => invokeArrayFns(instance.rtg, e)
7175 : void 0;
7176 update.ownerInstance = instance;
7177 }
7178 update();
7179 };
7180 const updateComponentPreRender = (instance, nextVNode, optimized) => {
7181 nextVNode.component = instance;
7182 const prevProps = instance.vnode.props;
7183 instance.vnode = nextVNode;
7184 instance.next = null;
7185 updateProps(instance, nextVNode.props, prevProps, optimized);
7186 updateSlots(instance, nextVNode.children, optimized);
7187 pauseTracking();
7188 // props update may have triggered pre-flush watchers.
7189 // flush them before the render update.
7190 flushPreFlushCbs(undefined, instance.update);
7191 resetTracking();
7192 };
7193 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
7194 const c1 = n1 && n1.children;
7195 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
7196 const c2 = n2.children;
7197 const { patchFlag, shapeFlag } = n2;
7198 // fast path
7199 if (patchFlag > 0) {
7200 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
7201 // this could be either fully-keyed or mixed (some keyed some not)
7202 // presence of patchFlag means children are guaranteed to be arrays
7203 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7204 return;
7205 }
7206 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
7207 // unkeyed
7208 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7209 return;
7210 }
7211 }
7212 // children has 3 possibilities: text, array or no children.
7213 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
7214 // text children fast path
7215 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
7216 unmountChildren(c1, parentComponent, parentSuspense);
7217 }
7218 if (c2 !== c1) {
7219 hostSetElementText(container, c2);
7220 }
7221 }
7222 else {
7223 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
7224 // prev children was array
7225 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7226 // two arrays, cannot assume anything, do full diff
7227 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7228 }
7229 else {
7230 // no new children, just unmount old
7231 unmountChildren(c1, parentComponent, parentSuspense, true);
7232 }
7233 }
7234 else {
7235 // prev children was text OR null
7236 // new children is array OR null
7237 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
7238 hostSetElementText(container, '');
7239 }
7240 // mount new if array
7241 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7242 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7243 }
7244 }
7245 }
7246 };
7247 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7248 c1 = c1 || EMPTY_ARR;
7249 c2 = c2 || EMPTY_ARR;
7250 const oldLength = c1.length;
7251 const newLength = c2.length;
7252 const commonLength = Math.min(oldLength, newLength);
7253 let i;
7254 for (i = 0; i < commonLength; i++) {
7255 const nextChild = (c2[i] = optimized
7256 ? cloneIfMounted(c2[i])
7257 : normalizeVNode(c2[i]));
7258 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7259 }
7260 if (oldLength > newLength) {
7261 // remove old
7262 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
7263 }
7264 else {
7265 // mount new
7266 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
7267 }
7268 };
7269 // can be all-keyed or mixed
7270 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7271 let i = 0;
7272 const l2 = c2.length;
7273 let e1 = c1.length - 1; // prev ending index
7274 let e2 = l2 - 1; // next ending index
7275 // 1. sync from start
7276 // (a b) c
7277 // (a b) d e
7278 while (i <= e1 && i <= e2) {
7279 const n1 = c1[i];
7280 const n2 = (c2[i] = optimized
7281 ? cloneIfMounted(c2[i])
7282 : normalizeVNode(c2[i]));
7283 if (isSameVNodeType(n1, n2)) {
7284 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7285 }
7286 else {
7287 break;
7288 }
7289 i++;
7290 }
7291 // 2. sync from end
7292 // a (b c)
7293 // d e (b c)
7294 while (i <= e1 && i <= e2) {
7295 const n1 = c1[e1];
7296 const n2 = (c2[e2] = optimized
7297 ? cloneIfMounted(c2[e2])
7298 : normalizeVNode(c2[e2]));
7299 if (isSameVNodeType(n1, n2)) {
7300 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7301 }
7302 else {
7303 break;
7304 }
7305 e1--;
7306 e2--;
7307 }
7308 // 3. common sequence + mount
7309 // (a b)
7310 // (a b) c
7311 // i = 2, e1 = 1, e2 = 2
7312 // (a b)
7313 // c (a b)
7314 // i = 0, e1 = -1, e2 = 0
7315 if (i > e1) {
7316 if (i <= e2) {
7317 const nextPos = e2 + 1;
7318 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
7319 while (i <= e2) {
7320 patch(null, (c2[i] = optimized
7321 ? cloneIfMounted(c2[i])
7322 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7323 i++;
7324 }
7325 }
7326 }
7327 // 4. common sequence + unmount
7328 // (a b) c
7329 // (a b)
7330 // i = 2, e1 = 2, e2 = 1
7331 // a (b c)
7332 // (b c)
7333 // i = 0, e1 = 0, e2 = -1
7334 else if (i > e2) {
7335 while (i <= e1) {
7336 unmount(c1[i], parentComponent, parentSuspense, true);
7337 i++;
7338 }
7339 }
7340 // 5. unknown sequence
7341 // [i ... e1 + 1]: a b [c d e] f g
7342 // [i ... e2 + 1]: a b [e d c h] f g
7343 // i = 2, e1 = 4, e2 = 5
7344 else {
7345 const s1 = i; // prev starting index
7346 const s2 = i; // next starting index
7347 // 5.1 build key:index map for newChildren
7348 const keyToNewIndexMap = new Map();
7349 for (i = s2; i <= e2; i++) {
7350 const nextChild = (c2[i] = optimized
7351 ? cloneIfMounted(c2[i])
7352 : normalizeVNode(c2[i]));
7353 if (nextChild.key != null) {
7354 if (keyToNewIndexMap.has(nextChild.key)) {
7355 warn$1(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
7356 }
7357 keyToNewIndexMap.set(nextChild.key, i);
7358 }
7359 }
7360 // 5.2 loop through old children left to be patched and try to patch
7361 // matching nodes & remove nodes that are no longer present
7362 let j;
7363 let patched = 0;
7364 const toBePatched = e2 - s2 + 1;
7365 let moved = false;
7366 // used to track whether any node has moved
7367 let maxNewIndexSoFar = 0;
7368 // works as Map<newIndex, oldIndex>
7369 // Note that oldIndex is offset by +1
7370 // and oldIndex = 0 is a special value indicating the new node has
7371 // no corresponding old node.
7372 // used for determining longest stable subsequence
7373 const newIndexToOldIndexMap = new Array(toBePatched);
7374 for (i = 0; i < toBePatched; i++)
7375 newIndexToOldIndexMap[i] = 0;
7376 for (i = s1; i <= e1; i++) {
7377 const prevChild = c1[i];
7378 if (patched >= toBePatched) {
7379 // all new children have been patched so this can only be a removal
7380 unmount(prevChild, parentComponent, parentSuspense, true);
7381 continue;
7382 }
7383 let newIndex;
7384 if (prevChild.key != null) {
7385 newIndex = keyToNewIndexMap.get(prevChild.key);
7386 }
7387 else {
7388 // key-less node, try to locate a key-less node of the same type
7389 for (j = s2; j <= e2; j++) {
7390 if (newIndexToOldIndexMap[j - s2] === 0 &&
7391 isSameVNodeType(prevChild, c2[j])) {
7392 newIndex = j;
7393 break;
7394 }
7395 }
7396 }
7397 if (newIndex === undefined) {
7398 unmount(prevChild, parentComponent, parentSuspense, true);
7399 }
7400 else {
7401 newIndexToOldIndexMap[newIndex - s2] = i + 1;
7402 if (newIndex >= maxNewIndexSoFar) {
7403 maxNewIndexSoFar = newIndex;
7404 }
7405 else {
7406 moved = true;
7407 }
7408 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7409 patched++;
7410 }
7411 }
7412 // 5.3 move and mount
7413 // generate longest stable subsequence only when nodes have moved
7414 const increasingNewIndexSequence = moved
7415 ? getSequence(newIndexToOldIndexMap)
7416 : EMPTY_ARR;
7417 j = increasingNewIndexSequence.length - 1;
7418 // looping backwards so that we can use last patched node as anchor
7419 for (i = toBePatched - 1; i >= 0; i--) {
7420 const nextIndex = s2 + i;
7421 const nextChild = c2[nextIndex];
7422 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
7423 if (newIndexToOldIndexMap[i] === 0) {
7424 // mount new
7425 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7426 }
7427 else if (moved) {
7428 // move if:
7429 // There is no stable subsequence (e.g. a reverse)
7430 // OR current node is not among the stable sequence
7431 if (j < 0 || i !== increasingNewIndexSequence[j]) {
7432 move(nextChild, container, anchor, 2 /* REORDER */);
7433 }
7434 else {
7435 j--;
7436 }
7437 }
7438 }
7439 }
7440 };
7441 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
7442 const { el, type, transition, children, shapeFlag } = vnode;
7443 if (shapeFlag & 6 /* COMPONENT */) {
7444 move(vnode.component.subTree, container, anchor, moveType);
7445 return;
7446 }
7447 if (shapeFlag & 128 /* SUSPENSE */) {
7448 vnode.suspense.move(container, anchor, moveType);
7449 return;
7450 }
7451 if (shapeFlag & 64 /* TELEPORT */) {
7452 type.move(vnode, container, anchor, internals);
7453 return;
7454 }
7455 if (type === Fragment) {
7456 hostInsert(el, container, anchor);
7457 for (let i = 0; i < children.length; i++) {
7458 move(children[i], container, anchor, moveType);
7459 }
7460 hostInsert(vnode.anchor, container, anchor);
7461 return;
7462 }
7463 if (type === Static) {
7464 moveStaticNode(vnode, container, anchor);
7465 return;
7466 }
7467 // single nodes
7468 const needTransition = moveType !== 2 /* REORDER */ &&
7469 shapeFlag & 1 /* ELEMENT */ &&
7470 transition;
7471 if (needTransition) {
7472 if (moveType === 0 /* ENTER */) {
7473 transition.beforeEnter(el);
7474 hostInsert(el, container, anchor);
7475 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
7476 }
7477 else {
7478 const { leave, delayLeave, afterLeave } = transition;
7479 const remove = () => hostInsert(el, container, anchor);
7480 const performLeave = () => {
7481 leave(el, () => {
7482 remove();
7483 afterLeave && afterLeave();
7484 });
7485 };
7486 if (delayLeave) {
7487 delayLeave(el, remove, performLeave);
7488 }
7489 else {
7490 performLeave();
7491 }
7492 }
7493 }
7494 else {
7495 hostInsert(el, container, anchor);
7496 }
7497 };
7498 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
7499 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
7500 // unset ref
7501 if (ref != null) {
7502 setRef(ref, null, parentSuspense, vnode, true);
7503 }
7504 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
7505 parentComponent.ctx.deactivate(vnode);
7506 return;
7507 }
7508 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
7509 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
7510 let vnodeHook;
7511 if (shouldInvokeVnodeHook &&
7512 (vnodeHook = props && props.onVnodeBeforeUnmount)) {
7513 invokeVNodeHook(vnodeHook, parentComponent, vnode);
7514 }
7515 if (shapeFlag & 6 /* COMPONENT */) {
7516 unmountComponent(vnode.component, parentSuspense, doRemove);
7517 }
7518 else {
7519 if (shapeFlag & 128 /* SUSPENSE */) {
7520 vnode.suspense.unmount(parentSuspense, doRemove);
7521 return;
7522 }
7523 if (shouldInvokeDirs) {
7524 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
7525 }
7526 if (shapeFlag & 64 /* TELEPORT */) {
7527 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
7528 }
7529 else if (dynamicChildren &&
7530 // #1153: fast path should not be taken for non-stable (v-for) fragments
7531 (type !== Fragment ||
7532 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
7533 // fast path for block nodes: only need to unmount dynamic children.
7534 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
7535 }
7536 else if ((type === Fragment &&
7537 patchFlag &
7538 (128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) ||
7539 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
7540 unmountChildren(children, parentComponent, parentSuspense);
7541 }
7542 if (doRemove) {
7543 remove(vnode);
7544 }
7545 }
7546 if ((shouldInvokeVnodeHook &&
7547 (vnodeHook = props && props.onVnodeUnmounted)) ||
7548 shouldInvokeDirs) {
7549 queuePostRenderEffect(() => {
7550 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
7551 shouldInvokeDirs &&
7552 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
7553 }, parentSuspense);
7554 }
7555 };
7556 const remove = vnode => {
7557 const { type, el, anchor, transition } = vnode;
7558 if (type === Fragment) {
7559 if (vnode.patchFlag > 0 &&
7560 vnode.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */ &&
7561 transition &&
7562 !transition.persisted) {
7563 vnode.children.forEach(child => {
7564 if (child.type === Comment) {
7565 hostRemove(child.el);
7566 }
7567 else {
7568 remove(child);
7569 }
7570 });
7571 }
7572 else {
7573 removeFragment(el, anchor);
7574 }
7575 return;
7576 }
7577 if (type === Static) {
7578 removeStaticNode(vnode);
7579 return;
7580 }
7581 const performRemove = () => {
7582 hostRemove(el);
7583 if (transition && !transition.persisted && transition.afterLeave) {
7584 transition.afterLeave();
7585 }
7586 };
7587 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
7588 transition &&
7589 !transition.persisted) {
7590 const { leave, delayLeave } = transition;
7591 const performLeave = () => leave(el, performRemove);
7592 if (delayLeave) {
7593 delayLeave(vnode.el, performRemove, performLeave);
7594 }
7595 else {
7596 performLeave();
7597 }
7598 }
7599 else {
7600 performRemove();
7601 }
7602 };
7603 const removeFragment = (cur, end) => {
7604 // For fragments, directly remove all contained DOM nodes.
7605 // (fragment child nodes cannot have transition)
7606 let next;
7607 while (cur !== end) {
7608 next = hostNextSibling(cur);
7609 hostRemove(cur);
7610 cur = next;
7611 }
7612 hostRemove(end);
7613 };
7614 const unmountComponent = (instance, parentSuspense, doRemove) => {
7615 if (instance.type.__hmrId) {
7616 unregisterHMR(instance);
7617 }
7618 const { bum, scope, update, subTree, um } = instance;
7619 // beforeUnmount hook
7620 if (bum) {
7621 invokeArrayFns(bum);
7622 }
7623 // stop effects in component scope
7624 scope.stop();
7625 // update may be null if a component is unmounted before its async
7626 // setup has resolved.
7627 if (update) {
7628 // so that scheduler will no longer invoke it
7629 update.active = false;
7630 unmount(subTree, instance, parentSuspense, doRemove);
7631 }
7632 // unmounted hook
7633 if (um) {
7634 queuePostRenderEffect(um, parentSuspense);
7635 }
7636 queuePostRenderEffect(() => {
7637 instance.isUnmounted = true;
7638 }, parentSuspense);
7639 // A component with async dep inside a pending suspense is unmounted before
7640 // its async dep resolves. This should remove the dep from the suspense, and
7641 // cause the suspense to resolve immediately if that was the last dep.
7642 if (parentSuspense &&
7643 parentSuspense.pendingBranch &&
7644 !parentSuspense.isUnmounted &&
7645 instance.asyncDep &&
7646 !instance.asyncResolved &&
7647 instance.suspenseId === parentSuspense.pendingId) {
7648 parentSuspense.deps--;
7649 if (parentSuspense.deps === 0) {
7650 parentSuspense.resolve();
7651 }
7652 }
7653 {
7654 devtoolsComponentRemoved(instance);
7655 }
7656 };
7657 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
7658 for (let i = start; i < children.length; i++) {
7659 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
7660 }
7661 };
7662 const getNextHostNode = vnode => {
7663 if (vnode.shapeFlag & 6 /* COMPONENT */) {
7664 return getNextHostNode(vnode.component.subTree);
7665 }
7666 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
7667 return vnode.suspense.next();
7668 }
7669 return hostNextSibling((vnode.anchor || vnode.el));
7670 };
7671 const render = (vnode, container, isSVG) => {
7672 if (vnode == null) {
7673 if (container._vnode) {
7674 unmount(container._vnode, null, null, true);
7675 }
7676 }
7677 else {
7678 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
7679 }
7680 flushPostFlushCbs();
7681 container._vnode = vnode;
7682 };
7683 const internals = {
7684 p: patch,
7685 um: unmount,
7686 m: move,
7687 r: remove,
7688 mt: mountComponent,
7689 mc: mountChildren,
7690 pc: patchChildren,
7691 pbc: patchBlockChildren,
7692 n: getNextHostNode,
7693 o: options
7694 };
7695 let hydrate;
7696 let hydrateNode;
7697 if (createHydrationFns) {
7698 [hydrate, hydrateNode] = createHydrationFns(internals);
7699 }
7700 return {
7701 render,
7702 hydrate,
7703 createApp: createAppAPI(render, hydrate)
7704 };
7705}
7706function toggleRecurse({ effect, update }, allowed) {
7707 effect.allowRecurse = update.allowRecurse = allowed;
7708}
7709/**
7710 * #1156
7711 * When a component is HMR-enabled, we need to make sure that all static nodes
7712 * inside a block also inherit the DOM element from the previous tree so that
7713 * HMR updates (which are full updates) can retrieve the element for patching.
7714 *
7715 * #2080
7716 * Inside keyed `template` fragment static children, if a fragment is moved,
7717 * the children will always be moved. Therefore, in order to ensure correct move
7718 * position, el should be inherited from previous nodes.
7719 */
7720function traverseStaticChildren(n1, n2, shallow = false) {
7721 const ch1 = n1.children;
7722 const ch2 = n2.children;
7723 if (isArray(ch1) && isArray(ch2)) {
7724 for (let i = 0; i < ch1.length; i++) {
7725 // this is only called in the optimized path so array children are
7726 // guaranteed to be vnodes
7727 const c1 = ch1[i];
7728 let c2 = ch2[i];
7729 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
7730 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
7731 c2 = ch2[i] = cloneIfMounted(ch2[i]);
7732 c2.el = c1.el;
7733 }
7734 if (!shallow)
7735 traverseStaticChildren(c1, c2);
7736 }
7737 // also inherit for comment nodes, but not placeholders (e.g. v-if which
7738 // would have received .el during block patch)
7739 if (c2.type === Comment && !c2.el) {
7740 c2.el = c1.el;
7741 }
7742 }
7743 }
7744}
7745// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
7746function getSequence(arr) {
7747 const p = arr.slice();
7748 const result = [0];
7749 let i, j, u, v, c;
7750 const len = arr.length;
7751 for (i = 0; i < len; i++) {
7752 const arrI = arr[i];
7753 if (arrI !== 0) {
7754 j = result[result.length - 1];
7755 if (arr[j] < arrI) {
7756 p[i] = j;
7757 result.push(i);
7758 continue;
7759 }
7760 u = 0;
7761 v = result.length - 1;
7762 while (u < v) {
7763 c = (u + v) >> 1;
7764 if (arr[result[c]] < arrI) {
7765 u = c + 1;
7766 }
7767 else {
7768 v = c;
7769 }
7770 }
7771 if (arrI < arr[result[u]]) {
7772 if (u > 0) {
7773 p[i] = result[u - 1];
7774 }
7775 result[u] = i;
7776 }
7777 }
7778 }
7779 u = result.length;
7780 v = result[u - 1];
7781 while (u-- > 0) {
7782 result[u] = v;
7783 v = p[v];
7784 }
7785 return result;
7786}
7787
7788const isTeleport = (type) => type.__isTeleport;
7789const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
7790const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
7791const resolveTarget = (props, select) => {
7792 const targetSelector = props && props.to;
7793 if (isString(targetSelector)) {
7794 if (!select) {
7795 warn$1(`Current renderer does not support string target for Teleports. ` +
7796 `(missing querySelector renderer option)`);
7797 return null;
7798 }
7799 else {
7800 const target = select(targetSelector);
7801 if (!target) {
7802 warn$1(`Failed to locate Teleport target with selector "${targetSelector}". ` +
7803 `Note the target element must exist before the component is mounted - ` +
7804 `i.e. the target cannot be rendered by the component itself, and ` +
7805 `ideally should be outside of the entire Vue component tree.`);
7806 }
7807 return target;
7808 }
7809 }
7810 else {
7811 if (!targetSelector && !isTeleportDisabled(props)) {
7812 warn$1(`Invalid Teleport target: ${targetSelector}`);
7813 }
7814 return targetSelector;
7815 }
7816};
7817const TeleportImpl = {
7818 __isTeleport: true,
7819 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
7820 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
7821 const disabled = isTeleportDisabled(n2.props);
7822 let { shapeFlag, children, dynamicChildren } = n2;
7823 // #3302
7824 // HMR updated, force full diff
7825 if (isHmrUpdating) {
7826 optimized = false;
7827 dynamicChildren = null;
7828 }
7829 if (n1 == null) {
7830 // insert anchors in the main view
7831 const placeholder = (n2.el = createComment('teleport start')
7832 );
7833 const mainAnchor = (n2.anchor = createComment('teleport end')
7834 );
7835 insert(placeholder, container, anchor);
7836 insert(mainAnchor, container, anchor);
7837 const target = (n2.target = resolveTarget(n2.props, querySelector));
7838 const targetAnchor = (n2.targetAnchor = createText(''));
7839 if (target) {
7840 insert(targetAnchor, target);
7841 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
7842 isSVG = isSVG || isTargetSVG(target);
7843 }
7844 else if (!disabled) {
7845 warn$1('Invalid Teleport target on mount:', target, `(${typeof target})`);
7846 }
7847 const mount = (container, anchor) => {
7848 // Teleport *always* has Array children. This is enforced in both the
7849 // compiler and vnode children normalization.
7850 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7851 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7852 }
7853 };
7854 if (disabled) {
7855 mount(container, mainAnchor);
7856 }
7857 else if (target) {
7858 mount(target, targetAnchor);
7859 }
7860 }
7861 else {
7862 // update content
7863 n2.el = n1.el;
7864 const mainAnchor = (n2.anchor = n1.anchor);
7865 const target = (n2.target = n1.target);
7866 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
7867 const wasDisabled = isTeleportDisabled(n1.props);
7868 const currentContainer = wasDisabled ? container : target;
7869 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
7870 isSVG = isSVG || isTargetSVG(target);
7871 if (dynamicChildren) {
7872 // fast path when the teleport happens to be a block root
7873 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
7874 // even in block tree mode we need to make sure all root-level nodes
7875 // in the teleport inherit previous DOM references so that they can
7876 // be moved in future patches.
7877 traverseStaticChildren(n1, n2, true);
7878 }
7879 else if (!optimized) {
7880 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
7881 }
7882 if (disabled) {
7883 if (!wasDisabled) {
7884 // enabled -> disabled
7885 // move into main container
7886 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
7887 }
7888 }
7889 else {
7890 // target changed
7891 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
7892 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
7893 if (nextTarget) {
7894 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
7895 }
7896 else {
7897 warn$1('Invalid Teleport target on update:', target, `(${typeof target})`);
7898 }
7899 }
7900 else if (wasDisabled) {
7901 // disabled -> enabled
7902 // move into teleport target
7903 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
7904 }
7905 }
7906 }
7907 },
7908 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
7909 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
7910 if (target) {
7911 hostRemove(targetAnchor);
7912 }
7913 // an unmounted teleport should always remove its children if not disabled
7914 if (doRemove || !isTeleportDisabled(props)) {
7915 hostRemove(anchor);
7916 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7917 for (let i = 0; i < children.length; i++) {
7918 const child = children[i];
7919 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
7920 }
7921 }
7922 }
7923 },
7924 move: moveTeleport,
7925 hydrate: hydrateTeleport
7926};
7927function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
7928 // move target anchor if this is a target change.
7929 if (moveType === 0 /* TARGET_CHANGE */) {
7930 insert(vnode.targetAnchor, container, parentAnchor);
7931 }
7932 const { el, anchor, shapeFlag, children, props } = vnode;
7933 const isReorder = moveType === 2 /* REORDER */;
7934 // move main view anchor if this is a re-order.
7935 if (isReorder) {
7936 insert(el, container, parentAnchor);
7937 }
7938 // if this is a re-order and teleport is enabled (content is in target)
7939 // do not move children. So the opposite is: only move children if this
7940 // is not a reorder, or the teleport is disabled
7941 if (!isReorder || isTeleportDisabled(props)) {
7942 // Teleport has either Array children or no children.
7943 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7944 for (let i = 0; i < children.length; i++) {
7945 move(children[i], container, parentAnchor, 2 /* REORDER */);
7946 }
7947 }
7948 }
7949 // move main view anchor if this is a re-order.
7950 if (isReorder) {
7951 insert(anchor, container, parentAnchor);
7952 }
7953}
7954function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
7955 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
7956 if (target) {
7957 // if multiple teleports rendered to the same target element, we need to
7958 // pick up from where the last teleport finished instead of the first node
7959 const targetNode = target._lpa || target.firstChild;
7960 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
7961 if (isTeleportDisabled(vnode.props)) {
7962 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
7963 vnode.targetAnchor = targetNode;
7964 }
7965 else {
7966 vnode.anchor = nextSibling(node);
7967 // lookahead until we find the target anchor
7968 // we cannot rely on return value of hydrateChildren() because there
7969 // could be nested teleports
7970 let targetAnchor = targetNode;
7971 while (targetAnchor) {
7972 targetAnchor = nextSibling(targetAnchor);
7973 if (targetAnchor &&
7974 targetAnchor.nodeType === 8 &&
7975 targetAnchor.data === 'teleport anchor') {
7976 vnode.targetAnchor = targetAnchor;
7977 target._lpa =
7978 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
7979 break;
7980 }
7981 }
7982 hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
7983 }
7984 }
7985 }
7986 return vnode.anchor && nextSibling(vnode.anchor);
7987}
7988// Force-casted public typing for h and TSX props inference
7989const Teleport = TeleportImpl;
7990
7991const Fragment = Symbol('Fragment' );
7992const Text = Symbol('Text' );
7993const Comment = Symbol('Comment' );
7994const Static = Symbol('Static' );
7995// Since v-if and v-for are the two possible ways node structure can dynamically
7996// change, once we consider v-if branches and each v-for fragment a block, we
7997// can divide a template into nested blocks, and within each block the node
7998// structure would be stable. This allows us to skip most children diffing
7999// and only worry about the dynamic nodes (indicated by patch flags).
8000const blockStack = [];
8001let currentBlock = null;
8002/**
8003 * Open a block.
8004 * This must be called before `createBlock`. It cannot be part of `createBlock`
8005 * because the children of the block are evaluated before `createBlock` itself
8006 * is called. The generated code typically looks like this:
8007 *
8008 * ```js
8009 * function render() {
8010 * return (openBlock(),createBlock('div', null, [...]))
8011 * }
8012 * ```
8013 * disableTracking is true when creating a v-for fragment block, since a v-for
8014 * fragment always diffs its children.
8015 *
8016 * @private
8017 */
8018function openBlock(disableTracking = false) {
8019 blockStack.push((currentBlock = disableTracking ? null : []));
8020}
8021function closeBlock() {
8022 blockStack.pop();
8023 currentBlock = blockStack[blockStack.length - 1] || null;
8024}
8025// Whether we should be tracking dynamic child nodes inside a block.
8026// Only tracks when this value is > 0
8027// We are not using a simple boolean because this value may need to be
8028// incremented/decremented by nested usage of v-once (see below)
8029let isBlockTreeEnabled = 1;
8030/**
8031 * Block tracking sometimes needs to be disabled, for example during the
8032 * creation of a tree that needs to be cached by v-once. The compiler generates
8033 * code like this:
8034 *
8035 * ``` js
8036 * _cache[1] || (
8037 * setBlockTracking(-1),
8038 * _cache[1] = createVNode(...),
8039 * setBlockTracking(1),
8040 * _cache[1]
8041 * )
8042 * ```
8043 *
8044 * @private
8045 */
8046function setBlockTracking(value) {
8047 isBlockTreeEnabled += value;
8048}
8049function setupBlock(vnode) {
8050 // save current block children on the block vnode
8051 vnode.dynamicChildren =
8052 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
8053 // close block
8054 closeBlock();
8055 // a block is always going to be patched, so track it as a child of its
8056 // parent block
8057 if (isBlockTreeEnabled > 0 && currentBlock) {
8058 currentBlock.push(vnode);
8059 }
8060 return vnode;
8061}
8062/**
8063 * @private
8064 */
8065function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
8066 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
8067}
8068/**
8069 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
8070 * A block root keeps track of dynamic nodes within the block in the
8071 * `dynamicChildren` array.
8072 *
8073 * @private
8074 */
8075function createBlock(type, props, children, patchFlag, dynamicProps) {
8076 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
8077}
8078function isVNode(value) {
8079 return value ? value.__v_isVNode === true : false;
8080}
8081function isSameVNodeType(n1, n2) {
8082 if (n2.shapeFlag & 6 /* COMPONENT */ &&
8083 hmrDirtyComponents.has(n2.type)) {
8084 // HMR only: if the component has been hot-updated, force a reload.
8085 return false;
8086 }
8087 return n1.type === n2.type && n1.key === n2.key;
8088}
8089let vnodeArgsTransformer;
8090/**
8091 * Internal API for registering an arguments transform for createVNode
8092 * used for creating stubs in the test-utils
8093 * It is *internal* but needs to be exposed for test-utils to pick up proper
8094 * typings
8095 */
8096function transformVNodeArgs(transformer) {
8097 vnodeArgsTransformer = transformer;
8098}
8099const createVNodeWithArgsTransform = (...args) => {
8100 return _createVNode(...(vnodeArgsTransformer
8101 ? vnodeArgsTransformer(args, currentRenderingInstance)
8102 : args));
8103};
8104const InternalObjectKey = `__vInternal`;
8105const normalizeKey = ({ key }) => key != null ? key : null;
8106const normalizeRef = ({ ref, ref_key, ref_for }) => {
8107 return (ref != null
8108 ? isString(ref) || isRef(ref) || isFunction(ref)
8109 ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8110 : ref
8111 : null);
8112};
8113function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
8114 const vnode = {
8115 __v_isVNode: true,
8116 __v_skip: true,
8117 type,
8118 props,
8119 key: props && normalizeKey(props),
8120 ref: props && normalizeRef(props),
8121 scopeId: currentScopeId,
8122 slotScopeIds: null,
8123 children,
8124 component: null,
8125 suspense: null,
8126 ssContent: null,
8127 ssFallback: null,
8128 dirs: null,
8129 transition: null,
8130 el: null,
8131 anchor: null,
8132 target: null,
8133 targetAnchor: null,
8134 staticCount: 0,
8135 shapeFlag,
8136 patchFlag,
8137 dynamicProps,
8138 dynamicChildren: null,
8139 appContext: null
8140 };
8141 if (needFullChildrenNormalization) {
8142 normalizeChildren(vnode, children);
8143 // normalize suspense children
8144 if (shapeFlag & 128 /* SUSPENSE */) {
8145 type.normalize(vnode);
8146 }
8147 }
8148 else if (children) {
8149 // compiled element vnode - if children is passed, only possible types are
8150 // string or Array.
8151 vnode.shapeFlag |= isString(children)
8152 ? 8 /* TEXT_CHILDREN */
8153 : 16 /* ARRAY_CHILDREN */;
8154 }
8155 // validate key
8156 if (vnode.key !== vnode.key) {
8157 warn$1(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
8158 }
8159 // track vnode for block tree
8160 if (isBlockTreeEnabled > 0 &&
8161 // avoid a block node from tracking itself
8162 !isBlockNode &&
8163 // has current parent block
8164 currentBlock &&
8165 // presence of a patch flag indicates this node needs patching on updates.
8166 // component nodes also should always be patched, because even if the
8167 // component doesn't need to update, it needs to persist the instance on to
8168 // the next vnode so that it can be properly unmounted later.
8169 (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
8170 // the EVENTS flag is only for hydration and if it is the only flag, the
8171 // vnode should not be considered dynamic due to handler caching.
8172 vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
8173 currentBlock.push(vnode);
8174 }
8175 return vnode;
8176}
8177const createVNode = (createVNodeWithArgsTransform );
8178function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
8179 if (!type || type === NULL_DYNAMIC_COMPONENT) {
8180 if (!type) {
8181 warn$1(`Invalid vnode type when creating vnode: ${type}.`);
8182 }
8183 type = Comment;
8184 }
8185 if (isVNode(type)) {
8186 // createVNode receiving an existing vnode. This happens in cases like
8187 // <component :is="vnode"/>
8188 // #2078 make sure to merge refs during the clone instead of overwriting it
8189 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
8190 if (children) {
8191 normalizeChildren(cloned, children);
8192 }
8193 if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) {
8194 if (cloned.shapeFlag & 6 /* COMPONENT */) {
8195 currentBlock[currentBlock.indexOf(type)] = cloned;
8196 }
8197 else {
8198 currentBlock.push(cloned);
8199 }
8200 }
8201 cloned.patchFlag |= -2 /* BAIL */;
8202 return cloned;
8203 }
8204 // class component normalization.
8205 if (isClassComponent(type)) {
8206 type = type.__vccOpts;
8207 }
8208 // class & style normalization.
8209 if (props) {
8210 // for reactive or proxy objects, we need to clone it to enable mutation.
8211 props = guardReactiveProps(props);
8212 let { class: klass, style } = props;
8213 if (klass && !isString(klass)) {
8214 props.class = normalizeClass(klass);
8215 }
8216 if (isObject(style)) {
8217 // reactive state objects need to be cloned since they are likely to be
8218 // mutated
8219 if (isProxy(style) && !isArray(style)) {
8220 style = extend({}, style);
8221 }
8222 props.style = normalizeStyle(style);
8223 }
8224 }
8225 // encode the vnode type information into a bitmap
8226 const shapeFlag = isString(type)
8227 ? 1 /* ELEMENT */
8228 : isSuspense(type)
8229 ? 128 /* SUSPENSE */
8230 : isTeleport(type)
8231 ? 64 /* TELEPORT */
8232 : isObject(type)
8233 ? 4 /* STATEFUL_COMPONENT */
8234 : isFunction(type)
8235 ? 2 /* FUNCTIONAL_COMPONENT */
8236 : 0;
8237 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
8238 type = toRaw(type);
8239 warn$1(`Vue received a Component which was made a reactive object. This can ` +
8240 `lead to unnecessary performance overhead, and should be avoided by ` +
8241 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
8242 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
8243 }
8244 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
8245}
8246function guardReactiveProps(props) {
8247 if (!props)
8248 return null;
8249 return isProxy(props) || InternalObjectKey in props
8250 ? extend({}, props)
8251 : props;
8252}
8253function cloneVNode(vnode, extraProps, mergeRef = false) {
8254 // This is intentionally NOT using spread or extend to avoid the runtime
8255 // key enumeration cost.
8256 const { props, ref, patchFlag, children } = vnode;
8257 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
8258 const cloned = {
8259 __v_isVNode: true,
8260 __v_skip: true,
8261 type: vnode.type,
8262 props: mergedProps,
8263 key: mergedProps && normalizeKey(mergedProps),
8264 ref: extraProps && extraProps.ref
8265 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
8266 // if the vnode itself already has a ref, cloneVNode will need to merge
8267 // the refs so the single vnode can be set on multiple refs
8268 mergeRef && ref
8269 ? isArray(ref)
8270 ? ref.concat(normalizeRef(extraProps))
8271 : [ref, normalizeRef(extraProps)]
8272 : normalizeRef(extraProps)
8273 : ref,
8274 scopeId: vnode.scopeId,
8275 slotScopeIds: vnode.slotScopeIds,
8276 children: patchFlag === -1 /* HOISTED */ && isArray(children)
8277 ? children.map(deepCloneVNode)
8278 : children,
8279 target: vnode.target,
8280 targetAnchor: vnode.targetAnchor,
8281 staticCount: vnode.staticCount,
8282 shapeFlag: vnode.shapeFlag,
8283 // if the vnode is cloned with extra props, we can no longer assume its
8284 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
8285 // note: preserve flag for fragments since they use the flag for children
8286 // fast paths only.
8287 patchFlag: extraProps && vnode.type !== Fragment
8288 ? patchFlag === -1 // hoisted node
8289 ? 16 /* FULL_PROPS */
8290 : patchFlag | 16 /* FULL_PROPS */
8291 : patchFlag,
8292 dynamicProps: vnode.dynamicProps,
8293 dynamicChildren: vnode.dynamicChildren,
8294 appContext: vnode.appContext,
8295 dirs: vnode.dirs,
8296 transition: vnode.transition,
8297 // These should technically only be non-null on mounted VNodes. However,
8298 // they *should* be copied for kept-alive vnodes. So we just always copy
8299 // them since them being non-null during a mount doesn't affect the logic as
8300 // they will simply be overwritten.
8301 component: vnode.component,
8302 suspense: vnode.suspense,
8303 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
8304 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
8305 el: vnode.el,
8306 anchor: vnode.anchor
8307 };
8308 return cloned;
8309}
8310/**
8311 * Dev only, for HMR of hoisted vnodes reused in v-for
8312 * https://github.com/vitejs/vite/issues/2022
8313 */
8314function deepCloneVNode(vnode) {
8315 const cloned = cloneVNode(vnode);
8316 if (isArray(vnode.children)) {
8317 cloned.children = vnode.children.map(deepCloneVNode);
8318 }
8319 return cloned;
8320}
8321/**
8322 * @private
8323 */
8324function createTextVNode(text = ' ', flag = 0) {
8325 return createVNode(Text, null, text, flag);
8326}
8327/**
8328 * @private
8329 */
8330function createStaticVNode(content, numberOfNodes) {
8331 // A static vnode can contain multiple stringified elements, and the number
8332 // of elements is necessary for hydration.
8333 const vnode = createVNode(Static, null, content);
8334 vnode.staticCount = numberOfNodes;
8335 return vnode;
8336}
8337/**
8338 * @private
8339 */
8340function createCommentVNode(text = '',
8341// when used as the v-else branch, the comment node must be created as a
8342// block to ensure correct updates.
8343asBlock = false) {
8344 return asBlock
8345 ? (openBlock(), createBlock(Comment, null, text))
8346 : createVNode(Comment, null, text);
8347}
8348function normalizeVNode(child) {
8349 if (child == null || typeof child === 'boolean') {
8350 // empty placeholder
8351 return createVNode(Comment);
8352 }
8353 else if (isArray(child)) {
8354 // fragment
8355 return createVNode(Fragment, null,
8356 // #3666, avoid reference pollution when reusing vnode
8357 child.slice());
8358 }
8359 else if (typeof child === 'object') {
8360 // already vnode, this should be the most common since compiled templates
8361 // always produce all-vnode children arrays
8362 return cloneIfMounted(child);
8363 }
8364 else {
8365 // strings and numbers
8366 return createVNode(Text, null, String(child));
8367 }
8368}
8369// optimized normalization for template-compiled render fns
8370function cloneIfMounted(child) {
8371 return child.el === null || child.memo ? child : cloneVNode(child);
8372}
8373function normalizeChildren(vnode, children) {
8374 let type = 0;
8375 const { shapeFlag } = vnode;
8376 if (children == null) {
8377 children = null;
8378 }
8379 else if (isArray(children)) {
8380 type = 16 /* ARRAY_CHILDREN */;
8381 }
8382 else if (typeof children === 'object') {
8383 if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
8384 // Normalize slot to plain children for plain element and Teleport
8385 const slot = children.default;
8386 if (slot) {
8387 // _c marker is added by withCtx() indicating this is a compiled slot
8388 slot._c && (slot._d = false);
8389 normalizeChildren(vnode, slot());
8390 slot._c && (slot._d = true);
8391 }
8392 return;
8393 }
8394 else {
8395 type = 32 /* SLOTS_CHILDREN */;
8396 const slotFlag = children._;
8397 if (!slotFlag && !(InternalObjectKey in children)) {
8398 children._ctx = currentRenderingInstance;
8399 }
8400 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
8401 // a child component receives forwarded slots from the parent.
8402 // its slot type is determined by its parent's slot type.
8403 if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
8404 children._ = 1 /* STABLE */;
8405 }
8406 else {
8407 children._ = 2 /* DYNAMIC */;
8408 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
8409 }
8410 }
8411 }
8412 }
8413 else if (isFunction(children)) {
8414 children = { default: children, _ctx: currentRenderingInstance };
8415 type = 32 /* SLOTS_CHILDREN */;
8416 }
8417 else {
8418 children = String(children);
8419 // force teleport children to array so it can be moved around
8420 if (shapeFlag & 64 /* TELEPORT */) {
8421 type = 16 /* ARRAY_CHILDREN */;
8422 children = [createTextVNode(children)];
8423 }
8424 else {
8425 type = 8 /* TEXT_CHILDREN */;
8426 }
8427 }
8428 vnode.children = children;
8429 vnode.shapeFlag |= type;
8430}
8431function mergeProps(...args) {
8432 const ret = {};
8433 for (let i = 0; i < args.length; i++) {
8434 const toMerge = args[i];
8435 for (const key in toMerge) {
8436 if (key === 'class') {
8437 if (ret.class !== toMerge.class) {
8438 ret.class = normalizeClass([ret.class, toMerge.class]);
8439 }
8440 }
8441 else if (key === 'style') {
8442 ret.style = normalizeStyle([ret.style, toMerge.style]);
8443 }
8444 else if (isOn(key)) {
8445 const existing = ret[key];
8446 const incoming = toMerge[key];
8447 if (incoming &&
8448 existing !== incoming &&
8449 !(isArray(existing) && existing.includes(incoming))) {
8450 ret[key] = existing
8451 ? [].concat(existing, incoming)
8452 : incoming;
8453 }
8454 }
8455 else if (key !== '') {
8456 ret[key] = toMerge[key];
8457 }
8458 }
8459 }
8460 return ret;
8461}
8462function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8463 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
8464 vnode,
8465 prevVNode
8466 ]);
8467}
8468
8469const emptyAppContext = createAppContext();
8470let uid$1 = 0;
8471function createComponentInstance(vnode, parent, suspense) {
8472 const type = vnode.type;
8473 // inherit parent app context - or - if root, adopt from root vnode
8474 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
8475 const instance = {
8476 uid: uid$1++,
8477 vnode,
8478 type,
8479 parent,
8480 appContext,
8481 root: null,
8482 next: null,
8483 subTree: null,
8484 effect: null,
8485 update: null,
8486 scope: new EffectScope(true /* detached */),
8487 render: null,
8488 proxy: null,
8489 exposed: null,
8490 exposeProxy: null,
8491 withProxy: null,
8492 provides: parent ? parent.provides : Object.create(appContext.provides),
8493 accessCache: null,
8494 renderCache: [],
8495 // local resolved assets
8496 components: null,
8497 directives: null,
8498 // resolved props and emits options
8499 propsOptions: normalizePropsOptions(type, appContext),
8500 emitsOptions: normalizeEmitsOptions(type, appContext),
8501 // emit
8502 emit: null,
8503 emitted: null,
8504 // props default value
8505 propsDefaults: EMPTY_OBJ,
8506 // inheritAttrs
8507 inheritAttrs: type.inheritAttrs,
8508 // state
8509 ctx: EMPTY_OBJ,
8510 data: EMPTY_OBJ,
8511 props: EMPTY_OBJ,
8512 attrs: EMPTY_OBJ,
8513 slots: EMPTY_OBJ,
8514 refs: EMPTY_OBJ,
8515 setupState: EMPTY_OBJ,
8516 setupContext: null,
8517 // suspense related
8518 suspense,
8519 suspenseId: suspense ? suspense.pendingId : 0,
8520 asyncDep: null,
8521 asyncResolved: false,
8522 // lifecycle hooks
8523 // not using enums here because it results in computed properties
8524 isMounted: false,
8525 isUnmounted: false,
8526 isDeactivated: false,
8527 bc: null,
8528 c: null,
8529 bm: null,
8530 m: null,
8531 bu: null,
8532 u: null,
8533 um: null,
8534 bum: null,
8535 da: null,
8536 a: null,
8537 rtg: null,
8538 rtc: null,
8539 ec: null,
8540 sp: null
8541 };
8542 {
8543 instance.ctx = createDevRenderContext(instance);
8544 }
8545 instance.root = parent ? parent.root : instance;
8546 instance.emit = emit$1.bind(null, instance);
8547 // apply custom element special handling
8548 if (vnode.ce) {
8549 vnode.ce(instance);
8550 }
8551 return instance;
8552}
8553let currentInstance = null;
8554const getCurrentInstance = () => currentInstance || currentRenderingInstance;
8555const setCurrentInstance = (instance) => {
8556 currentInstance = instance;
8557 instance.scope.on();
8558};
8559const unsetCurrentInstance = () => {
8560 currentInstance && currentInstance.scope.off();
8561 currentInstance = null;
8562};
8563const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
8564function validateComponentName(name, config) {
8565 const appIsNativeTag = config.isNativeTag || NO;
8566 if (isBuiltInTag(name) || appIsNativeTag(name)) {
8567 warn$1('Do not use built-in or reserved HTML elements as component id: ' + name);
8568 }
8569}
8570function isStatefulComponent(instance) {
8571 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
8572}
8573let isInSSRComponentSetup = false;
8574function setupComponent(instance, isSSR = false) {
8575 isInSSRComponentSetup = isSSR;
8576 const { props, children } = instance.vnode;
8577 const isStateful = isStatefulComponent(instance);
8578 initProps(instance, props, isStateful, isSSR);
8579 initSlots(instance, children);
8580 const setupResult = isStateful
8581 ? setupStatefulComponent(instance, isSSR)
8582 : undefined;
8583 isInSSRComponentSetup = false;
8584 return setupResult;
8585}
8586function setupStatefulComponent(instance, isSSR) {
8587 var _a;
8588 const Component = instance.type;
8589 {
8590 if (Component.name) {
8591 validateComponentName(Component.name, instance.appContext.config);
8592 }
8593 if (Component.components) {
8594 const names = Object.keys(Component.components);
8595 for (let i = 0; i < names.length; i++) {
8596 validateComponentName(names[i], instance.appContext.config);
8597 }
8598 }
8599 if (Component.directives) {
8600 const names = Object.keys(Component.directives);
8601 for (let i = 0; i < names.length; i++) {
8602 validateDirectiveName(names[i]);
8603 }
8604 }
8605 if (Component.compilerOptions && isRuntimeOnly()) {
8606 warn$1(`"compilerOptions" is only supported when using a build of Vue that ` +
8607 `includes the runtime compiler. Since you are using a runtime-only ` +
8608 `build, the options should be passed via your build tool config instead.`);
8609 }
8610 }
8611 // 0. create render proxy property access cache
8612 instance.accessCache = Object.create(null);
8613 // 1. create public instance / render proxy
8614 // also mark it raw so it's never observed
8615 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
8616 {
8617 exposePropsOnRenderContext(instance);
8618 }
8619 // 2. call setup()
8620 const { setup } = Component;
8621 if (setup) {
8622 const setupContext = (instance.setupContext =
8623 setup.length > 1 ? createSetupContext(instance) : null);
8624 setCurrentInstance(instance);
8625 pauseTracking();
8626 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
8627 resetTracking();
8628 unsetCurrentInstance();
8629 if (isPromise(setupResult)) {
8630 setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
8631 if (isSSR) {
8632 // return the promise so server-renderer can wait on it
8633 return setupResult
8634 .then((resolvedResult) => {
8635 handleSetupResult(instance, resolvedResult, isSSR);
8636 })
8637 .catch(e => {
8638 handleError(e, instance, 0 /* SETUP_FUNCTION */);
8639 });
8640 }
8641 else {
8642 // async setup returned Promise.
8643 // bail here and wait for re-entry.
8644 instance.asyncDep = setupResult;
8645 if (!instance.suspense) {
8646 const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
8647 warn$1(`Component <${name}>: setup function returned a promise, but no ` +
8648 `<Suspense> boundary was found in the parent component tree. ` +
8649 `A component with async setup() must be nested in a <Suspense> ` +
8650 `in order to be rendered.`);
8651 }
8652 }
8653 }
8654 else {
8655 handleSetupResult(instance, setupResult, isSSR);
8656 }
8657 }
8658 else {
8659 finishComponentSetup(instance, isSSR);
8660 }
8661}
8662function handleSetupResult(instance, setupResult, isSSR) {
8663 if (isFunction(setupResult)) {
8664 // setup returned an inline render function
8665 {
8666 instance.render = setupResult;
8667 }
8668 }
8669 else if (isObject(setupResult)) {
8670 if (isVNode(setupResult)) {
8671 warn$1(`setup() should not return VNodes directly - ` +
8672 `return a render function instead.`);
8673 }
8674 // setup returned bindings.
8675 // assuming a render function compiled from template is present.
8676 {
8677 instance.devtoolsRawSetupState = setupResult;
8678 }
8679 instance.setupState = proxyRefs(setupResult);
8680 {
8681 exposeSetupStateOnRenderContext(instance);
8682 }
8683 }
8684 else if (setupResult !== undefined) {
8685 warn$1(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
8686 }
8687 finishComponentSetup(instance, isSSR);
8688}
8689let compile;
8690let installWithProxy;
8691/**
8692 * For runtime-dom to register the compiler.
8693 * Note the exported method uses any to avoid d.ts relying on the compiler types.
8694 */
8695function registerRuntimeCompiler(_compile) {
8696 compile = _compile;
8697 installWithProxy = i => {
8698 if (i.render._rc) {
8699 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
8700 }
8701 };
8702}
8703// dev only
8704const isRuntimeOnly = () => !compile;
8705function finishComponentSetup(instance, isSSR, skipOptions) {
8706 const Component = instance.type;
8707 // template / render function normalization
8708 // could be already set when returned from setup()
8709 if (!instance.render) {
8710 // only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
8711 // is done by server-renderer
8712 if (!isSSR && compile && !Component.render) {
8713 const template = Component.template;
8714 if (template) {
8715 {
8716 startMeasure(instance, `compile`);
8717 }
8718 const { isCustomElement, compilerOptions } = instance.appContext.config;
8719 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
8720 const finalCompilerOptions = extend(extend({
8721 isCustomElement,
8722 delimiters
8723 }, compilerOptions), componentCompilerOptions);
8724 Component.render = compile(template, finalCompilerOptions);
8725 {
8726 endMeasure(instance, `compile`);
8727 }
8728 }
8729 }
8730 instance.render = (Component.render || NOOP);
8731 // for runtime-compiled render functions using `with` blocks, the render
8732 // proxy used needs a different `has` handler which is more performant and
8733 // also only allows a whitelist of globals to fallthrough.
8734 if (installWithProxy) {
8735 installWithProxy(instance);
8736 }
8737 }
8738 // support for 2.x options
8739 {
8740 setCurrentInstance(instance);
8741 pauseTracking();
8742 applyOptions(instance);
8743 resetTracking();
8744 unsetCurrentInstance();
8745 }
8746 // warn missing template/render
8747 // the runtime compilation of template in SSR is done by server-render
8748 if (!Component.render && instance.render === NOOP && !isSSR) {
8749 /* istanbul ignore if */
8750 if (!compile && Component.template) {
8751 warn$1(`Component provided template option but ` +
8752 `runtime compilation is not supported in this build of Vue.` +
8753 (` Use "vue.esm-browser.js" instead.`
8754 ) /* should not happen */);
8755 }
8756 else {
8757 warn$1(`Component is missing template or render function.`);
8758 }
8759 }
8760}
8761function createAttrsProxy(instance) {
8762 return new Proxy(instance.attrs, {
8763 get(target, key) {
8764 markAttrsAccessed();
8765 track(instance, "get" /* GET */, '$attrs');
8766 return target[key];
8767 },
8768 set() {
8769 warn$1(`setupContext.attrs is readonly.`);
8770 return false;
8771 },
8772 deleteProperty() {
8773 warn$1(`setupContext.attrs is readonly.`);
8774 return false;
8775 }
8776 }
8777 );
8778}
8779function createSetupContext(instance) {
8780 const expose = exposed => {
8781 if (instance.exposed) {
8782 warn$1(`expose() should be called only once per setup().`);
8783 }
8784 instance.exposed = exposed || {};
8785 };
8786 let attrs;
8787 {
8788 // We use getters in dev in case libs like test-utils overwrite instance
8789 // properties (overwrites should not be done in prod)
8790 return Object.freeze({
8791 get attrs() {
8792 return attrs || (attrs = createAttrsProxy(instance));
8793 },
8794 get slots() {
8795 return shallowReadonly(instance.slots);
8796 },
8797 get emit() {
8798 return (event, ...args) => instance.emit(event, ...args);
8799 },
8800 expose
8801 });
8802 }
8803}
8804function getExposeProxy(instance) {
8805 if (instance.exposed) {
8806 return (instance.exposeProxy ||
8807 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
8808 get(target, key) {
8809 if (key in target) {
8810 return target[key];
8811 }
8812 else if (key in publicPropertiesMap) {
8813 return publicPropertiesMap[key](instance);
8814 }
8815 }
8816 })));
8817 }
8818}
8819const classifyRE = /(?:^|[-_])(\w)/g;
8820const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
8821function getComponentName(Component) {
8822 return isFunction(Component)
8823 ? Component.displayName || Component.name
8824 : Component.name;
8825}
8826/* istanbul ignore next */
8827function formatComponentName(instance, Component, isRoot = false) {
8828 let name = getComponentName(Component);
8829 if (!name && Component.__file) {
8830 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
8831 if (match) {
8832 name = match[1];
8833 }
8834 }
8835 if (!name && instance && instance.parent) {
8836 // try to infer the name based on reverse resolution
8837 const inferFromRegistry = (registry) => {
8838 for (const key in registry) {
8839 if (registry[key] === Component) {
8840 return key;
8841 }
8842 }
8843 };
8844 name =
8845 inferFromRegistry(instance.components ||
8846 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
8847 }
8848 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
8849}
8850function isClassComponent(value) {
8851 return isFunction(value) && '__vccOpts' in value;
8852}
8853
8854const computed$1 = ((getterOrOptions, debugOptions) => {
8855 // @ts-ignore
8856 return computed(getterOrOptions, debugOptions, isInSSRComponentSetup);
8857});
8858
8859// dev only
8860const warnRuntimeUsage = (method) => warn$1(`${method}() is a compiler-hint helper that is only usable inside ` +
8861 `<script setup> of a single file component. Its arguments should be ` +
8862 `compiled away and passing it at runtime has no effect.`);
8863// implementation
8864function defineProps() {
8865 {
8866 warnRuntimeUsage(`defineProps`);
8867 }
8868 return null;
8869}
8870// implementation
8871function defineEmits() {
8872 {
8873 warnRuntimeUsage(`defineEmits`);
8874 }
8875 return null;
8876}
8877/**
8878 * Vue `<script setup>` compiler macro for declaring a component's exposed
8879 * instance properties when it is accessed by a parent component via template
8880 * refs.
8881 *
8882 * `<script setup>` components are closed by default - i.e. variables inside
8883 * the `<script setup>` scope is not exposed to parent unless explicitly exposed
8884 * via `defineExpose`.
8885 *
8886 * This is only usable inside `<script setup>`, is compiled away in the
8887 * output and should **not** be actually called at runtime.
8888 */
8889function defineExpose(exposed) {
8890 {
8891 warnRuntimeUsage(`defineExpose`);
8892 }
8893}
8894/**
8895 * Vue `<script setup>` compiler macro for providing props default values when
8896 * using type-based `defineProps` declaration.
8897 *
8898 * Example usage:
8899 * ```ts
8900 * withDefaults(defineProps<{
8901 * size?: number
8902 * labels?: string[]
8903 * }>(), {
8904 * size: 3,
8905 * labels: () => ['default label']
8906 * })
8907 * ```
8908 *
8909 * This is only usable inside `<script setup>`, is compiled away in the output
8910 * and should **not** be actually called at runtime.
8911 */
8912function withDefaults(props, defaults) {
8913 {
8914 warnRuntimeUsage(`withDefaults`);
8915 }
8916 return null;
8917}
8918function useSlots() {
8919 return getContext().slots;
8920}
8921function useAttrs() {
8922 return getContext().attrs;
8923}
8924function getContext() {
8925 const i = getCurrentInstance();
8926 if (!i) {
8927 warn$1(`useContext() called without active instance.`);
8928 }
8929 return i.setupContext || (i.setupContext = createSetupContext(i));
8930}
8931/**
8932 * Runtime helper for merging default declarations. Imported by compiled code
8933 * only.
8934 * @internal
8935 */
8936function mergeDefaults(raw, defaults) {
8937 const props = isArray(raw)
8938 ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {})
8939 : raw;
8940 for (const key in defaults) {
8941 const opt = props[key];
8942 if (opt) {
8943 if (isArray(opt) || isFunction(opt)) {
8944 props[key] = { type: opt, default: defaults[key] };
8945 }
8946 else {
8947 opt.default = defaults[key];
8948 }
8949 }
8950 else if (opt === null) {
8951 props[key] = { default: defaults[key] };
8952 }
8953 else {
8954 warn$1(`props default key "${key}" has no corresponding declaration.`);
8955 }
8956 }
8957 return props;
8958}
8959/**
8960 * Used to create a proxy for the rest element when destructuring props with
8961 * defineProps().
8962 * @internal
8963 */
8964function createPropsRestProxy(props, excludedKeys) {
8965 const ret = {};
8966 for (const key in props) {
8967 if (!excludedKeys.includes(key)) {
8968 Object.defineProperty(ret, key, {
8969 enumerable: true,
8970 get: () => props[key]
8971 });
8972 }
8973 }
8974 return ret;
8975}
8976/**
8977 * `<script setup>` helper for persisting the current instance context over
8978 * async/await flows.
8979 *
8980 * `@vue/compiler-sfc` converts the following:
8981 *
8982 * ```ts
8983 * const x = await foo()
8984 * ```
8985 *
8986 * into:
8987 *
8988 * ```ts
8989 * let __temp, __restore
8990 * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
8991 * ```
8992 * @internal
8993 */
8994function withAsyncContext(getAwaitable) {
8995 const ctx = getCurrentInstance();
8996 if (!ctx) {
8997 warn$1(`withAsyncContext called without active current instance. ` +
8998 `This is likely a bug.`);
8999 }
9000 let awaitable = getAwaitable();
9001 unsetCurrentInstance();
9002 if (isPromise(awaitable)) {
9003 awaitable = awaitable.catch(e => {
9004 setCurrentInstance(ctx);
9005 throw e;
9006 });
9007 }
9008 return [awaitable, () => setCurrentInstance(ctx)];
9009}
9010
9011// Actual implementation
9012function h(type, propsOrChildren, children) {
9013 const l = arguments.length;
9014 if (l === 2) {
9015 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
9016 // single vnode without props
9017 if (isVNode(propsOrChildren)) {
9018 return createVNode(type, null, [propsOrChildren]);
9019 }
9020 // props without children
9021 return createVNode(type, propsOrChildren);
9022 }
9023 else {
9024 // omit props
9025 return createVNode(type, null, propsOrChildren);
9026 }
9027 }
9028 else {
9029 if (l > 3) {
9030 children = Array.prototype.slice.call(arguments, 2);
9031 }
9032 else if (l === 3 && isVNode(children)) {
9033 children = [children];
9034 }
9035 return createVNode(type, propsOrChildren, children);
9036 }
9037}
9038
9039const ssrContextKey = Symbol(`ssrContext` );
9040const useSSRContext = () => {
9041 {
9042 const ctx = inject(ssrContextKey);
9043 if (!ctx) {
9044 warn$1(`Server rendering context not provided. Make sure to only call ` +
9045 `useSSRContext() conditionally in the server build.`);
9046 }
9047 return ctx;
9048 }
9049};
9050
9051function initCustomFormatter() {
9052 /* eslint-disable no-restricted-globals */
9053 if (typeof window === 'undefined') {
9054 return;
9055 }
9056 const vueStyle = { style: 'color:#3ba776' };
9057 const numberStyle = { style: 'color:#0b1bc9' };
9058 const stringStyle = { style: 'color:#b62e24' };
9059 const keywordStyle = { style: 'color:#9d288c' };
9060 // custom formatter for Chrome
9061 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
9062 const formatter = {
9063 header(obj) {
9064 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
9065 if (!isObject(obj)) {
9066 return null;
9067 }
9068 if (obj.__isVue) {
9069 return ['div', vueStyle, `VueInstance`];
9070 }
9071 else if (isRef(obj)) {
9072 return [
9073 'div',
9074 {},
9075 ['span', vueStyle, genRefFlag(obj)],
9076 '<',
9077 formatValue(obj.value),
9078 `>`
9079 ];
9080 }
9081 else if (isReactive(obj)) {
9082 return [
9083 'div',
9084 {},
9085 ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
9086 '<',
9087 formatValue(obj),
9088 `>${isReadonly(obj) ? ` (readonly)` : ``}`
9089 ];
9090 }
9091 else if (isReadonly(obj)) {
9092 return [
9093 'div',
9094 {},
9095 ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
9096 '<',
9097 formatValue(obj),
9098 '>'
9099 ];
9100 }
9101 return null;
9102 },
9103 hasBody(obj) {
9104 return obj && obj.__isVue;
9105 },
9106 body(obj) {
9107 if (obj && obj.__isVue) {
9108 return [
9109 'div',
9110 {},
9111 ...formatInstance(obj.$)
9112 ];
9113 }
9114 }
9115 };
9116 function formatInstance(instance) {
9117 const blocks = [];
9118 if (instance.type.props && instance.props) {
9119 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
9120 }
9121 if (instance.setupState !== EMPTY_OBJ) {
9122 blocks.push(createInstanceBlock('setup', instance.setupState));
9123 }
9124 if (instance.data !== EMPTY_OBJ) {
9125 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
9126 }
9127 const computed = extractKeys(instance, 'computed');
9128 if (computed) {
9129 blocks.push(createInstanceBlock('computed', computed));
9130 }
9131 const injected = extractKeys(instance, 'inject');
9132 if (injected) {
9133 blocks.push(createInstanceBlock('injected', injected));
9134 }
9135 blocks.push([
9136 'div',
9137 {},
9138 [
9139 'span',
9140 {
9141 style: keywordStyle.style + ';opacity:0.66'
9142 },
9143 '$ (internal): '
9144 ],
9145 ['object', { object: instance }]
9146 ]);
9147 return blocks;
9148 }
9149 function createInstanceBlock(type, target) {
9150 target = extend({}, target);
9151 if (!Object.keys(target).length) {
9152 return ['span', {}];
9153 }
9154 return [
9155 'div',
9156 { style: 'line-height:1.25em;margin-bottom:0.6em' },
9157 [
9158 'div',
9159 {
9160 style: 'color:#476582'
9161 },
9162 type
9163 ],
9164 [
9165 'div',
9166 {
9167 style: 'padding-left:1.25em'
9168 },
9169 ...Object.keys(target).map(key => {
9170 return [
9171 'div',
9172 {},
9173 ['span', keywordStyle, key + ': '],
9174 formatValue(target[key], false)
9175 ];
9176 })
9177 ]
9178 ];
9179 }
9180 function formatValue(v, asRaw = true) {
9181 if (typeof v === 'number') {
9182 return ['span', numberStyle, v];
9183 }
9184 else if (typeof v === 'string') {
9185 return ['span', stringStyle, JSON.stringify(v)];
9186 }
9187 else if (typeof v === 'boolean') {
9188 return ['span', keywordStyle, v];
9189 }
9190 else if (isObject(v)) {
9191 return ['object', { object: asRaw ? toRaw(v) : v }];
9192 }
9193 else {
9194 return ['span', stringStyle, String(v)];
9195 }
9196 }
9197 function extractKeys(instance, type) {
9198 const Comp = instance.type;
9199 if (isFunction(Comp)) {
9200 return;
9201 }
9202 const extracted = {};
9203 for (const key in instance.ctx) {
9204 if (isKeyOfType(Comp, key, type)) {
9205 extracted[key] = instance.ctx[key];
9206 }
9207 }
9208 return extracted;
9209 }
9210 function isKeyOfType(Comp, key, type) {
9211 const opts = Comp[type];
9212 if ((isArray(opts) && opts.includes(key)) ||
9213 (isObject(opts) && key in opts)) {
9214 return true;
9215 }
9216 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
9217 return true;
9218 }
9219 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
9220 return true;
9221 }
9222 }
9223 function genRefFlag(v) {
9224 if (isShallow(v)) {
9225 return `ShallowRef`;
9226 }
9227 if (v.effect) {
9228 return `ComputedRef`;
9229 }
9230 return `Ref`;
9231 }
9232 if (window.devtoolsFormatters) {
9233 window.devtoolsFormatters.push(formatter);
9234 }
9235 else {
9236 window.devtoolsFormatters = [formatter];
9237 }
9238}
9239
9240function withMemo(memo, render, cache, index) {
9241 const cached = cache[index];
9242 if (cached && isMemoSame(cached, memo)) {
9243 return cached;
9244 }
9245 const ret = render();
9246 // shallow clone
9247 ret.memo = memo.slice();
9248 return (cache[index] = ret);
9249}
9250function isMemoSame(cached, memo) {
9251 const prev = cached.memo;
9252 if (prev.length != memo.length) {
9253 return false;
9254 }
9255 for (let i = 0; i < prev.length; i++) {
9256 if (hasChanged(prev[i], memo[i])) {
9257 return false;
9258 }
9259 }
9260 // make sure to let parent block track it when returning cached
9261 if (isBlockTreeEnabled > 0 && currentBlock) {
9262 currentBlock.push(cached);
9263 }
9264 return true;
9265}
9266
9267// Core API ------------------------------------------------------------------
9268const version = "3.2.36";
9269/**
9270 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
9271 * @internal
9272 */
9273const ssrUtils = (null);
9274/**
9275 * @internal only exposed in compat builds
9276 */
9277const resolveFilter = null;
9278/**
9279 * @internal only exposed in compat builds.
9280 */
9281const compatUtils = (null);
9282
9283const svgNS = 'http://www.w3.org/2000/svg';
9284const doc = (typeof document !== 'undefined' ? document : null);
9285const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
9286const nodeOps = {
9287 insert: (child, parent, anchor) => {
9288 parent.insertBefore(child, anchor || null);
9289 },
9290 remove: child => {
9291 const parent = child.parentNode;
9292 if (parent) {
9293 parent.removeChild(child);
9294 }
9295 },
9296 createElement: (tag, isSVG, is, props) => {
9297 const el = isSVG
9298 ? doc.createElementNS(svgNS, tag)
9299 : doc.createElement(tag, is ? { is } : undefined);
9300 if (tag === 'select' && props && props.multiple != null) {
9301 el.setAttribute('multiple', props.multiple);
9302 }
9303 return el;
9304 },
9305 createText: text => doc.createTextNode(text),
9306 createComment: text => doc.createComment(text),
9307 setText: (node, text) => {
9308 node.nodeValue = text;
9309 },
9310 setElementText: (el, text) => {
9311 el.textContent = text;
9312 },
9313 parentNode: node => node.parentNode,
9314 nextSibling: node => node.nextSibling,
9315 querySelector: selector => doc.querySelector(selector),
9316 setScopeId(el, id) {
9317 el.setAttribute(id, '');
9318 },
9319 cloneNode(el) {
9320 const cloned = el.cloneNode(true);
9321 // #3072
9322 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
9323 // - normally, elements using `:value` bindings will not be hoisted, but if
9324 // the bound value is a constant, e.g. `:value="true"` - they do get
9325 // hoisted.
9326 // - in production, hoisted nodes are cloned when subsequent inserts, but
9327 // cloneNode() does not copy the custom property we attached.
9328 // - This may need to account for other custom DOM properties we attach to
9329 // elements in addition to `_value` in the future.
9330 if (`_value` in el) {
9331 cloned._value = el._value;
9332 }
9333 return cloned;
9334 },
9335 // __UNSAFE__
9336 // Reason: innerHTML.
9337 // Static content here can only come from compiled templates.
9338 // As long as the user only uses trusted templates, this is safe.
9339 insertStaticContent(content, parent, anchor, isSVG, start, end) {
9340 // <parent> before | first ... last | anchor </parent>
9341 const before = anchor ? anchor.previousSibling : parent.lastChild;
9342 // #5308 can only take cached path if:
9343 // - has a single root node
9344 // - nextSibling info is still available
9345 if (start && (start === end || start.nextSibling)) {
9346 // cached
9347 while (true) {
9348 parent.insertBefore(start.cloneNode(true), anchor);
9349 if (start === end || !(start = start.nextSibling))
9350 break;
9351 }
9352 }
9353 else {
9354 // fresh insert
9355 templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
9356 const template = templateContainer.content;
9357 if (isSVG) {
9358 // remove outer svg wrapper
9359 const wrapper = template.firstChild;
9360 while (wrapper.firstChild) {
9361 template.appendChild(wrapper.firstChild);
9362 }
9363 template.removeChild(wrapper);
9364 }
9365 parent.insertBefore(template, anchor);
9366 }
9367 return [
9368 // first
9369 before ? before.nextSibling : parent.firstChild,
9370 // last
9371 anchor ? anchor.previousSibling : parent.lastChild
9372 ];
9373 }
9374};
9375
9376// compiler should normalize class + :class bindings on the same element
9377// into a single binding ['staticClass', dynamic]
9378function patchClass(el, value, isSVG) {
9379 // directly setting className should be faster than setAttribute in theory
9380 // if this is an element during a transition, take the temporary transition
9381 // classes into account.
9382 const transitionClasses = el._vtc;
9383 if (transitionClasses) {
9384 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
9385 }
9386 if (value == null) {
9387 el.removeAttribute('class');
9388 }
9389 else if (isSVG) {
9390 el.setAttribute('class', value);
9391 }
9392 else {
9393 el.className = value;
9394 }
9395}
9396
9397function patchStyle(el, prev, next) {
9398 const style = el.style;
9399 const isCssString = isString(next);
9400 if (next && !isCssString) {
9401 for (const key in next) {
9402 setStyle(style, key, next[key]);
9403 }
9404 if (prev && !isString(prev)) {
9405 for (const key in prev) {
9406 if (next[key] == null) {
9407 setStyle(style, key, '');
9408 }
9409 }
9410 }
9411 }
9412 else {
9413 const currentDisplay = style.display;
9414 if (isCssString) {
9415 if (prev !== next) {
9416 style.cssText = next;
9417 }
9418 }
9419 else if (prev) {
9420 el.removeAttribute('style');
9421 }
9422 // indicates that the `display` of the element is controlled by `v-show`,
9423 // so we always keep the current `display` value regardless of the `style`
9424 // value, thus handing over control to `v-show`.
9425 if ('_vod' in el) {
9426 style.display = currentDisplay;
9427 }
9428 }
9429}
9430const importantRE = /\s*!important$/;
9431function setStyle(style, name, val) {
9432 if (isArray(val)) {
9433 val.forEach(v => setStyle(style, name, v));
9434 }
9435 else {
9436 if (val == null)
9437 val = '';
9438 if (name.startsWith('--')) {
9439 // custom property definition
9440 style.setProperty(name, val);
9441 }
9442 else {
9443 const prefixed = autoPrefix(style, name);
9444 if (importantRE.test(val)) {
9445 // !important
9446 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
9447 }
9448 else {
9449 style[prefixed] = val;
9450 }
9451 }
9452 }
9453}
9454const prefixes = ['Webkit', 'Moz', 'ms'];
9455const prefixCache = {};
9456function autoPrefix(style, rawName) {
9457 const cached = prefixCache[rawName];
9458 if (cached) {
9459 return cached;
9460 }
9461 let name = camelize(rawName);
9462 if (name !== 'filter' && name in style) {
9463 return (prefixCache[rawName] = name);
9464 }
9465 name = capitalize(name);
9466 for (let i = 0; i < prefixes.length; i++) {
9467 const prefixed = prefixes[i] + name;
9468 if (prefixed in style) {
9469 return (prefixCache[rawName] = prefixed);
9470 }
9471 }
9472 return rawName;
9473}
9474
9475const xlinkNS = 'http://www.w3.org/1999/xlink';
9476function patchAttr(el, key, value, isSVG, instance) {
9477 if (isSVG && key.startsWith('xlink:')) {
9478 if (value == null) {
9479 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
9480 }
9481 else {
9482 el.setAttributeNS(xlinkNS, key, value);
9483 }
9484 }
9485 else {
9486 // note we are only checking boolean attributes that don't have a
9487 // corresponding dom prop of the same name here.
9488 const isBoolean = isSpecialBooleanAttr(key);
9489 if (value == null || (isBoolean && !includeBooleanAttr(value))) {
9490 el.removeAttribute(key);
9491 }
9492 else {
9493 el.setAttribute(key, isBoolean ? '' : value);
9494 }
9495 }
9496}
9497
9498// __UNSAFE__
9499// functions. The user is responsible for using them with only trusted content.
9500function patchDOMProp(el, key, value,
9501// the following args are passed only due to potential innerHTML/textContent
9502// overriding existing VNodes, in which case the old tree must be properly
9503// unmounted.
9504prevChildren, parentComponent, parentSuspense, unmountChildren) {
9505 if (key === 'innerHTML' || key === 'textContent') {
9506 if (prevChildren) {
9507 unmountChildren(prevChildren, parentComponent, parentSuspense);
9508 }
9509 el[key] = value == null ? '' : value;
9510 return;
9511 }
9512 if (key === 'value' &&
9513 el.tagName !== 'PROGRESS' &&
9514 // custom elements may use _value internally
9515 !el.tagName.includes('-')) {
9516 // store value as _value as well since
9517 // non-string values will be stringified.
9518 el._value = value;
9519 const newValue = value == null ? '' : value;
9520 if (el.value !== newValue ||
9521 // #4956: always set for OPTION elements because its value falls back to
9522 // textContent if no value attribute is present. And setting .value for
9523 // OPTION has no side effect
9524 el.tagName === 'OPTION') {
9525 el.value = newValue;
9526 }
9527 if (value == null) {
9528 el.removeAttribute(key);
9529 }
9530 return;
9531 }
9532 let needRemove = false;
9533 if (value === '' || value == null) {
9534 const type = typeof el[key];
9535 if (type === 'boolean') {
9536 // e.g. <select multiple> compiles to { multiple: '' }
9537 value = includeBooleanAttr(value);
9538 }
9539 else if (value == null && type === 'string') {
9540 // e.g. <div :id="null">
9541 value = '';
9542 needRemove = true;
9543 }
9544 else if (type === 'number') {
9545 // e.g. <img :width="null">
9546 // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
9547 value = 0;
9548 needRemove = true;
9549 }
9550 }
9551 // some properties perform value validation and throw,
9552 // some properties has getter, no setter, will error in 'use strict'
9553 // eg. <select :type="null"></select> <select :willValidate="null"></select>
9554 try {
9555 el[key] = value;
9556 }
9557 catch (e) {
9558 {
9559 warn$1(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9560 `value ${value} is invalid.`, e);
9561 }
9562 }
9563 needRemove && el.removeAttribute(key);
9564}
9565
9566// Async edge case fix requires storing an event listener's attach timestamp.
9567const [_getNow, skipTimestampCheck] = /*#__PURE__*/ (() => {
9568 let _getNow = Date.now;
9569 let skipTimestampCheck = false;
9570 if (typeof window !== 'undefined') {
9571 // Determine what event timestamp the browser is using. Annoyingly, the
9572 // timestamp can either be hi-res (relative to page load) or low-res
9573 // (relative to UNIX epoch), so in order to compare time we have to use the
9574 // same timestamp type when saving the flush timestamp.
9575 if (Date.now() > document.createEvent('Event').timeStamp) {
9576 // if the low-res timestamp which is bigger than the event timestamp
9577 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
9578 // and we need to use the hi-res version for event listeners as well.
9579 _getNow = performance.now.bind(performance);
9580 }
9581 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
9582 // and does not fire microtasks in between event propagation, so safe to exclude.
9583 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
9584 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
9585 }
9586 return [_getNow, skipTimestampCheck];
9587})();
9588// To avoid the overhead of repeatedly calling performance.now(), we cache
9589// and use the same timestamp for all event listeners attached in the same tick.
9590let cachedNow = 0;
9591const p = /*#__PURE__*/ Promise.resolve();
9592const reset = () => {
9593 cachedNow = 0;
9594};
9595const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
9596function addEventListener(el, event, handler, options) {
9597 el.addEventListener(event, handler, options);
9598}
9599function removeEventListener(el, event, handler, options) {
9600 el.removeEventListener(event, handler, options);
9601}
9602function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9603 // vei = vue event invokers
9604 const invokers = el._vei || (el._vei = {});
9605 const existingInvoker = invokers[rawName];
9606 if (nextValue && existingInvoker) {
9607 // patch
9608 existingInvoker.value = nextValue;
9609 }
9610 else {
9611 const [name, options] = parseName(rawName);
9612 if (nextValue) {
9613 // add
9614 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9615 addEventListener(el, name, invoker, options);
9616 }
9617 else if (existingInvoker) {
9618 // remove
9619 removeEventListener(el, name, existingInvoker, options);
9620 invokers[rawName] = undefined;
9621 }
9622 }
9623}
9624const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9625function parseName(name) {
9626 let options;
9627 if (optionsModifierRE.test(name)) {
9628 options = {};
9629 let m;
9630 while ((m = name.match(optionsModifierRE))) {
9631 name = name.slice(0, name.length - m[0].length);
9632 options[m[0].toLowerCase()] = true;
9633 }
9634 }
9635 return [hyphenate(name.slice(2)), options];
9636}
9637function createInvoker(initialValue, instance) {
9638 const invoker = (e) => {
9639 // async edge case #6566: inner click event triggers patch, event handler
9640 // attached to outer element during patch, and triggered again. This
9641 // happens because browsers fire microtask ticks between event propagation.
9642 // the solution is simple: we save the timestamp when a handler is attached,
9643 // and the handler would only fire if the event passed to it was fired
9644 // AFTER it was attached.
9645 const timeStamp = e.timeStamp || _getNow();
9646 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
9647 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
9648 }
9649 };
9650 invoker.value = initialValue;
9651 invoker.attached = getNow();
9652 return invoker;
9653}
9654function patchStopImmediatePropagation(e, value) {
9655 if (isArray(value)) {
9656 const originalStop = e.stopImmediatePropagation;
9657 e.stopImmediatePropagation = () => {
9658 originalStop.call(e);
9659 e._stopped = true;
9660 };
9661 return value.map(fn => (e) => !e._stopped && fn && fn(e));
9662 }
9663 else {
9664 return value;
9665 }
9666}
9667
9668const nativeOnRE = /^on[a-z]/;
9669const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9670 if (key === 'class') {
9671 patchClass(el, nextValue, isSVG);
9672 }
9673 else if (key === 'style') {
9674 patchStyle(el, prevValue, nextValue);
9675 }
9676 else if (isOn(key)) {
9677 // ignore v-model listeners
9678 if (!isModelListener(key)) {
9679 patchEvent(el, key, prevValue, nextValue, parentComponent);
9680 }
9681 }
9682 else if (key[0] === '.'
9683 ? ((key = key.slice(1)), true)
9684 : key[0] === '^'
9685 ? ((key = key.slice(1)), false)
9686 : shouldSetAsProp(el, key, nextValue, isSVG)) {
9687 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9688 }
9689 else {
9690 // special case for <input v-model type="checkbox"> with
9691 // :true-value & :false-value
9692 // store value as dom properties since non-string values will be
9693 // stringified.
9694 if (key === 'true-value') {
9695 el._trueValue = nextValue;
9696 }
9697 else if (key === 'false-value') {
9698 el._falseValue = nextValue;
9699 }
9700 patchAttr(el, key, nextValue, isSVG);
9701 }
9702};
9703function shouldSetAsProp(el, key, value, isSVG) {
9704 if (isSVG) {
9705 // most keys must be set as attribute on svg elements to work
9706 // ...except innerHTML & textContent
9707 if (key === 'innerHTML' || key === 'textContent') {
9708 return true;
9709 }
9710 // or native onclick with function values
9711 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9712 return true;
9713 }
9714 return false;
9715 }
9716 // these are enumerated attrs, however their corresponding DOM properties
9717 // are actually booleans - this leads to setting it with a string "false"
9718 // value leading it to be coerced to `true`, so we need to always treat
9719 // them as attributes.
9720 // Note that `contentEditable` doesn't have this problem: its DOM
9721 // property is also enumerated string values.
9722 if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
9723 return false;
9724 }
9725 // #1787, #2840 form property on form elements is readonly and must be set as
9726 // attribute.
9727 if (key === 'form') {
9728 return false;
9729 }
9730 // #1526 <input list> must be set as attribute
9731 if (key === 'list' && el.tagName === 'INPUT') {
9732 return false;
9733 }
9734 // #2766 <textarea type> must be set as attribute
9735 if (key === 'type' && el.tagName === 'TEXTAREA') {
9736 return false;
9737 }
9738 // native onclick with string value, must be set as attribute
9739 if (nativeOnRE.test(key) && isString(value)) {
9740 return false;
9741 }
9742 return key in el;
9743}
9744
9745function defineCustomElement(options, hydrate) {
9746 const Comp = defineComponent(options);
9747 class VueCustomElement extends VueElement {
9748 constructor(initialProps) {
9749 super(Comp, initialProps, hydrate);
9750 }
9751 }
9752 VueCustomElement.def = Comp;
9753 return VueCustomElement;
9754}
9755const defineSSRCustomElement = ((options) => {
9756 // @ts-ignore
9757 return defineCustomElement(options, hydrate);
9758});
9759const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
9760});
9761class VueElement extends BaseClass {
9762 constructor(_def, _props = {}, hydrate) {
9763 super();
9764 this._def = _def;
9765 this._props = _props;
9766 /**
9767 * @internal
9768 */
9769 this._instance = null;
9770 this._connected = false;
9771 this._resolved = false;
9772 this._numberProps = null;
9773 if (this.shadowRoot && hydrate) {
9774 hydrate(this._createVNode(), this.shadowRoot);
9775 }
9776 else {
9777 if (this.shadowRoot) {
9778 warn$1(`Custom element has pre-rendered declarative shadow root but is not ` +
9779 `defined as hydratable. Use \`defineSSRCustomElement\`.`);
9780 }
9781 this.attachShadow({ mode: 'open' });
9782 }
9783 }
9784 connectedCallback() {
9785 this._connected = true;
9786 if (!this._instance) {
9787 this._resolveDef();
9788 }
9789 }
9790 disconnectedCallback() {
9791 this._connected = false;
9792 nextTick(() => {
9793 if (!this._connected) {
9794 render(null, this.shadowRoot);
9795 this._instance = null;
9796 }
9797 });
9798 }
9799 /**
9800 * resolve inner component definition (handle possible async component)
9801 */
9802 _resolveDef() {
9803 if (this._resolved) {
9804 return;
9805 }
9806 this._resolved = true;
9807 // set initial attrs
9808 for (let i = 0; i < this.attributes.length; i++) {
9809 this._setAttr(this.attributes[i].name);
9810 }
9811 // watch future attr changes
9812 new MutationObserver(mutations => {
9813 for (const m of mutations) {
9814 this._setAttr(m.attributeName);
9815 }
9816 }).observe(this, { attributes: true });
9817 const resolve = (def) => {
9818 const { props, styles } = def;
9819 const hasOptions = !isArray(props);
9820 const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
9821 // cast Number-type props set before resolve
9822 let numberProps;
9823 if (hasOptions) {
9824 for (const key in this._props) {
9825 const opt = props[key];
9826 if (opt === Number || (opt && opt.type === Number)) {
9827 this._props[key] = toNumber(this._props[key]);
9828 (numberProps || (numberProps = Object.create(null)))[key] = true;
9829 }
9830 }
9831 }
9832 this._numberProps = numberProps;
9833 // check if there are props set pre-upgrade or connect
9834 for (const key of Object.keys(this)) {
9835 if (key[0] !== '_') {
9836 this._setProp(key, this[key], true, false);
9837 }
9838 }
9839 // defining getter/setters on prototype
9840 for (const key of rawKeys.map(camelize)) {
9841 Object.defineProperty(this, key, {
9842 get() {
9843 return this._getProp(key);
9844 },
9845 set(val) {
9846 this._setProp(key, val);
9847 }
9848 });
9849 }
9850 // apply CSS
9851 this._applyStyles(styles);
9852 // initial render
9853 this._update();
9854 };
9855 const asyncDef = this._def.__asyncLoader;
9856 if (asyncDef) {
9857 asyncDef().then(resolve);
9858 }
9859 else {
9860 resolve(this._def);
9861 }
9862 }
9863 _setAttr(key) {
9864 let value = this.getAttribute(key);
9865 if (this._numberProps && this._numberProps[key]) {
9866 value = toNumber(value);
9867 }
9868 this._setProp(camelize(key), value, false);
9869 }
9870 /**
9871 * @internal
9872 */
9873 _getProp(key) {
9874 return this._props[key];
9875 }
9876 /**
9877 * @internal
9878 */
9879 _setProp(key, val, shouldReflect = true, shouldUpdate = true) {
9880 if (val !== this._props[key]) {
9881 this._props[key] = val;
9882 if (shouldUpdate && this._instance) {
9883 this._update();
9884 }
9885 // reflect
9886 if (shouldReflect) {
9887 if (val === true) {
9888 this.setAttribute(hyphenate(key), '');
9889 }
9890 else if (typeof val === 'string' || typeof val === 'number') {
9891 this.setAttribute(hyphenate(key), val + '');
9892 }
9893 else if (!val) {
9894 this.removeAttribute(hyphenate(key));
9895 }
9896 }
9897 }
9898 }
9899 _update() {
9900 render(this._createVNode(), this.shadowRoot);
9901 }
9902 _createVNode() {
9903 const vnode = createVNode(this._def, extend({}, this._props));
9904 if (!this._instance) {
9905 vnode.ce = instance => {
9906 this._instance = instance;
9907 instance.isCE = true;
9908 // HMR
9909 {
9910 instance.ceReload = newStyles => {
9911 // always reset styles
9912 if (this._styles) {
9913 this._styles.forEach(s => this.shadowRoot.removeChild(s));
9914 this._styles.length = 0;
9915 }
9916 this._applyStyles(newStyles);
9917 // if this is an async component, ceReload is called from the inner
9918 // component so no need to reload the async wrapper
9919 if (!this._def.__asyncLoader) {
9920 // reload
9921 this._instance = null;
9922 this._update();
9923 }
9924 };
9925 }
9926 // intercept emit
9927 instance.emit = (event, ...args) => {
9928 this.dispatchEvent(new CustomEvent(event, {
9929 detail: args
9930 }));
9931 };
9932 // locate nearest Vue custom element parent for provide/inject
9933 let parent = this;
9934 while ((parent =
9935 parent && (parent.parentNode || parent.host))) {
9936 if (parent instanceof VueElement) {
9937 instance.parent = parent._instance;
9938 break;
9939 }
9940 }
9941 };
9942 }
9943 return vnode;
9944 }
9945 _applyStyles(styles) {
9946 if (styles) {
9947 styles.forEach(css => {
9948 const s = document.createElement('style');
9949 s.textContent = css;
9950 this.shadowRoot.appendChild(s);
9951 // record for HMR
9952 {
9953 (this._styles || (this._styles = [])).push(s);
9954 }
9955 });
9956 }
9957 }
9958}
9959
9960function useCssModule(name = '$style') {
9961 /* istanbul ignore else */
9962 {
9963 const instance = getCurrentInstance();
9964 if (!instance) {
9965 warn$1(`useCssModule must be called inside setup()`);
9966 return EMPTY_OBJ;
9967 }
9968 const modules = instance.type.__cssModules;
9969 if (!modules) {
9970 warn$1(`Current instance does not have CSS modules injected.`);
9971 return EMPTY_OBJ;
9972 }
9973 const mod = modules[name];
9974 if (!mod) {
9975 warn$1(`Current instance does not have CSS module named "${name}".`);
9976 return EMPTY_OBJ;
9977 }
9978 return mod;
9979 }
9980}
9981
9982/**
9983 * Runtime helper for SFC's CSS variable injection feature.
9984 * @private
9985 */
9986function useCssVars(getter) {
9987 const instance = getCurrentInstance();
9988 /* istanbul ignore next */
9989 if (!instance) {
9990 warn$1(`useCssVars is called without current active component instance.`);
9991 return;
9992 }
9993 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
9994 watchPostEffect(setVars);
9995 onMounted(() => {
9996 const ob = new MutationObserver(setVars);
9997 ob.observe(instance.subTree.el.parentNode, { childList: true });
9998 onUnmounted(() => ob.disconnect());
9999 });
10000}
10001function setVarsOnVNode(vnode, vars) {
10002 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
10003 const suspense = vnode.suspense;
10004 vnode = suspense.activeBranch;
10005 if (suspense.pendingBranch && !suspense.isHydrating) {
10006 suspense.effects.push(() => {
10007 setVarsOnVNode(suspense.activeBranch, vars);
10008 });
10009 }
10010 }
10011 // drill down HOCs until it's a non-component vnode
10012 while (vnode.component) {
10013 vnode = vnode.component.subTree;
10014 }
10015 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
10016 setVarsOnNode(vnode.el, vars);
10017 }
10018 else if (vnode.type === Fragment) {
10019 vnode.children.forEach(c => setVarsOnVNode(c, vars));
10020 }
10021 else if (vnode.type === Static) {
10022 let { el, anchor } = vnode;
10023 while (el) {
10024 setVarsOnNode(el, vars);
10025 if (el === anchor)
10026 break;
10027 el = el.nextSibling;
10028 }
10029 }
10030}
10031function setVarsOnNode(el, vars) {
10032 if (el.nodeType === 1) {
10033 const style = el.style;
10034 for (const key in vars) {
10035 style.setProperty(`--${key}`, vars[key]);
10036 }
10037 }
10038}
10039
10040const TRANSITION = 'transition';
10041const ANIMATION = 'animation';
10042// DOM Transition is a higher-order-component based on the platform-agnostic
10043// base Transition component, with DOM-specific logic.
10044const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
10045Transition.displayName = 'Transition';
10046const DOMTransitionPropsValidators = {
10047 name: String,
10048 type: String,
10049 css: {
10050 type: Boolean,
10051 default: true
10052 },
10053 duration: [String, Number, Object],
10054 enterFromClass: String,
10055 enterActiveClass: String,
10056 enterToClass: String,
10057 appearFromClass: String,
10058 appearActiveClass: String,
10059 appearToClass: String,
10060 leaveFromClass: String,
10061 leaveActiveClass: String,
10062 leaveToClass: String
10063};
10064const TransitionPropsValidators = (Transition.props =
10065 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
10066/**
10067 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
10068 * with custom HOCs.
10069 */
10070const callHook$1 = (hook, args = []) => {
10071 if (isArray(hook)) {
10072 hook.forEach(h => h(...args));
10073 }
10074 else if (hook) {
10075 hook(...args);
10076 }
10077};
10078/**
10079 * Check if a hook expects a callback (2nd arg), which means the user
10080 * intends to explicitly control the end of the transition.
10081 */
10082const hasExplicitCallback = (hook) => {
10083 return hook
10084 ? isArray(hook)
10085 ? hook.some(h => h.length > 1)
10086 : hook.length > 1
10087 : false;
10088};
10089function resolveTransitionProps(rawProps) {
10090 const baseProps = {};
10091 for (const key in rawProps) {
10092 if (!(key in DOMTransitionPropsValidators)) {
10093 baseProps[key] = rawProps[key];
10094 }
10095 }
10096 if (rawProps.css === false) {
10097 return baseProps;
10098 }
10099 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;
10100 const durations = normalizeDuration(duration);
10101 const enterDuration = durations && durations[0];
10102 const leaveDuration = durations && durations[1];
10103 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
10104 const finishEnter = (el, isAppear, done) => {
10105 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
10106 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
10107 done && done();
10108 };
10109 const finishLeave = (el, done) => {
10110 el._isLeaving = false;
10111 removeTransitionClass(el, leaveFromClass);
10112 removeTransitionClass(el, leaveToClass);
10113 removeTransitionClass(el, leaveActiveClass);
10114 done && done();
10115 };
10116 const makeEnterHook = (isAppear) => {
10117 return (el, done) => {
10118 const hook = isAppear ? onAppear : onEnter;
10119 const resolve = () => finishEnter(el, isAppear, done);
10120 callHook$1(hook, [el, resolve]);
10121 nextFrame(() => {
10122 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
10123 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
10124 if (!hasExplicitCallback(hook)) {
10125 whenTransitionEnds(el, type, enterDuration, resolve);
10126 }
10127 });
10128 };
10129 };
10130 return extend(baseProps, {
10131 onBeforeEnter(el) {
10132 callHook$1(onBeforeEnter, [el]);
10133 addTransitionClass(el, enterFromClass);
10134 addTransitionClass(el, enterActiveClass);
10135 },
10136 onBeforeAppear(el) {
10137 callHook$1(onBeforeAppear, [el]);
10138 addTransitionClass(el, appearFromClass);
10139 addTransitionClass(el, appearActiveClass);
10140 },
10141 onEnter: makeEnterHook(false),
10142 onAppear: makeEnterHook(true),
10143 onLeave(el, done) {
10144 el._isLeaving = true;
10145 const resolve = () => finishLeave(el, done);
10146 addTransitionClass(el, leaveFromClass);
10147 // force reflow so *-leave-from classes immediately take effect (#2593)
10148 forceReflow();
10149 addTransitionClass(el, leaveActiveClass);
10150 nextFrame(() => {
10151 if (!el._isLeaving) {
10152 // cancelled
10153 return;
10154 }
10155 removeTransitionClass(el, leaveFromClass);
10156 addTransitionClass(el, leaveToClass);
10157 if (!hasExplicitCallback(onLeave)) {
10158 whenTransitionEnds(el, type, leaveDuration, resolve);
10159 }
10160 });
10161 callHook$1(onLeave, [el, resolve]);
10162 },
10163 onEnterCancelled(el) {
10164 finishEnter(el, false);
10165 callHook$1(onEnterCancelled, [el]);
10166 },
10167 onAppearCancelled(el) {
10168 finishEnter(el, true);
10169 callHook$1(onAppearCancelled, [el]);
10170 },
10171 onLeaveCancelled(el) {
10172 finishLeave(el);
10173 callHook$1(onLeaveCancelled, [el]);
10174 }
10175 });
10176}
10177function normalizeDuration(duration) {
10178 if (duration == null) {
10179 return null;
10180 }
10181 else if (isObject(duration)) {
10182 return [NumberOf(duration.enter), NumberOf(duration.leave)];
10183 }
10184 else {
10185 const n = NumberOf(duration);
10186 return [n, n];
10187 }
10188}
10189function NumberOf(val) {
10190 const res = toNumber(val);
10191 validateDuration(res);
10192 return res;
10193}
10194function validateDuration(val) {
10195 if (typeof val !== 'number') {
10196 warn$1(`<transition> explicit duration is not a valid number - ` +
10197 `got ${JSON.stringify(val)}.`);
10198 }
10199 else if (isNaN(val)) {
10200 warn$1(`<transition> explicit duration is NaN - ` +
10201 'the duration expression might be incorrect.');
10202 }
10203}
10204function addTransitionClass(el, cls) {
10205 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
10206 (el._vtc ||
10207 (el._vtc = new Set())).add(cls);
10208}
10209function removeTransitionClass(el, cls) {
10210 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
10211 const { _vtc } = el;
10212 if (_vtc) {
10213 _vtc.delete(cls);
10214 if (!_vtc.size) {
10215 el._vtc = undefined;
10216 }
10217 }
10218}
10219function nextFrame(cb) {
10220 requestAnimationFrame(() => {
10221 requestAnimationFrame(cb);
10222 });
10223}
10224let endId = 0;
10225function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
10226 const id = (el._endId = ++endId);
10227 const resolveIfNotStale = () => {
10228 if (id === el._endId) {
10229 resolve();
10230 }
10231 };
10232 if (explicitTimeout) {
10233 return setTimeout(resolveIfNotStale, explicitTimeout);
10234 }
10235 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
10236 if (!type) {
10237 return resolve();
10238 }
10239 const endEvent = type + 'end';
10240 let ended = 0;
10241 const end = () => {
10242 el.removeEventListener(endEvent, onEnd);
10243 resolveIfNotStale();
10244 };
10245 const onEnd = (e) => {
10246 if (e.target === el && ++ended >= propCount) {
10247 end();
10248 }
10249 };
10250 setTimeout(() => {
10251 if (ended < propCount) {
10252 end();
10253 }
10254 }, timeout + 1);
10255 el.addEventListener(endEvent, onEnd);
10256}
10257function getTransitionInfo(el, expectedType) {
10258 const styles = window.getComputedStyle(el);
10259 // JSDOM may return undefined for transition properties
10260 const getStyleProperties = (key) => (styles[key] || '').split(', ');
10261 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
10262 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
10263 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
10264 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
10265 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
10266 const animationTimeout = getTimeout(animationDelays, animationDurations);
10267 let type = null;
10268 let timeout = 0;
10269 let propCount = 0;
10270 /* istanbul ignore if */
10271 if (expectedType === TRANSITION) {
10272 if (transitionTimeout > 0) {
10273 type = TRANSITION;
10274 timeout = transitionTimeout;
10275 propCount = transitionDurations.length;
10276 }
10277 }
10278 else if (expectedType === ANIMATION) {
10279 if (animationTimeout > 0) {
10280 type = ANIMATION;
10281 timeout = animationTimeout;
10282 propCount = animationDurations.length;
10283 }
10284 }
10285 else {
10286 timeout = Math.max(transitionTimeout, animationTimeout);
10287 type =
10288 timeout > 0
10289 ? transitionTimeout > animationTimeout
10290 ? TRANSITION
10291 : ANIMATION
10292 : null;
10293 propCount = type
10294 ? type === TRANSITION
10295 ? transitionDurations.length
10296 : animationDurations.length
10297 : 0;
10298 }
10299 const hasTransform = type === TRANSITION &&
10300 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
10301 return {
10302 type,
10303 timeout,
10304 propCount,
10305 hasTransform
10306 };
10307}
10308function getTimeout(delays, durations) {
10309 while (delays.length < durations.length) {
10310 delays = delays.concat(delays);
10311 }
10312 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
10313}
10314// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
10315// numbers in a locale-dependent way, using a comma instead of a dot.
10316// If comma is not replaced with a dot, the input will be rounded down
10317// (i.e. acting as a floor function) causing unexpected behaviors
10318function toMs(s) {
10319 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
10320}
10321// synchronously force layout to put elements into a certain state
10322function forceReflow() {
10323 return document.body.offsetHeight;
10324}
10325
10326const positionMap = new WeakMap();
10327const newPositionMap = new WeakMap();
10328const TransitionGroupImpl = {
10329 name: 'TransitionGroup',
10330 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
10331 tag: String,
10332 moveClass: String
10333 }),
10334 setup(props, { slots }) {
10335 const instance = getCurrentInstance();
10336 const state = useTransitionState();
10337 let prevChildren;
10338 let children;
10339 onUpdated(() => {
10340 // children is guaranteed to exist after initial render
10341 if (!prevChildren.length) {
10342 return;
10343 }
10344 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
10345 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
10346 return;
10347 }
10348 // we divide the work into three loops to avoid mixing DOM reads and writes
10349 // in each iteration - which helps prevent layout thrashing.
10350 prevChildren.forEach(callPendingCbs);
10351 prevChildren.forEach(recordPosition);
10352 const movedChildren = prevChildren.filter(applyTranslation);
10353 // force reflow to put everything in position
10354 forceReflow();
10355 movedChildren.forEach(c => {
10356 const el = c.el;
10357 const style = el.style;
10358 addTransitionClass(el, moveClass);
10359 style.transform = style.webkitTransform = style.transitionDuration = '';
10360 const cb = (el._moveCb = (e) => {
10361 if (e && e.target !== el) {
10362 return;
10363 }
10364 if (!e || /transform$/.test(e.propertyName)) {
10365 el.removeEventListener('transitionend', cb);
10366 el._moveCb = null;
10367 removeTransitionClass(el, moveClass);
10368 }
10369 });
10370 el.addEventListener('transitionend', cb);
10371 });
10372 });
10373 return () => {
10374 const rawProps = toRaw(props);
10375 const cssTransitionProps = resolveTransitionProps(rawProps);
10376 let tag = rawProps.tag || Fragment;
10377 prevChildren = children;
10378 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
10379 for (let i = 0; i < children.length; i++) {
10380 const child = children[i];
10381 if (child.key != null) {
10382 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10383 }
10384 else {
10385 warn$1(`<TransitionGroup> children must be keyed.`);
10386 }
10387 }
10388 if (prevChildren) {
10389 for (let i = 0; i < prevChildren.length; i++) {
10390 const child = prevChildren[i];
10391 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10392 positionMap.set(child, child.el.getBoundingClientRect());
10393 }
10394 }
10395 return createVNode(tag, null, children);
10396 };
10397 }
10398};
10399const TransitionGroup = TransitionGroupImpl;
10400function callPendingCbs(c) {
10401 const el = c.el;
10402 if (el._moveCb) {
10403 el._moveCb();
10404 }
10405 if (el._enterCb) {
10406 el._enterCb();
10407 }
10408}
10409function recordPosition(c) {
10410 newPositionMap.set(c, c.el.getBoundingClientRect());
10411}
10412function applyTranslation(c) {
10413 const oldPos = positionMap.get(c);
10414 const newPos = newPositionMap.get(c);
10415 const dx = oldPos.left - newPos.left;
10416 const dy = oldPos.top - newPos.top;
10417 if (dx || dy) {
10418 const s = c.el.style;
10419 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
10420 s.transitionDuration = '0s';
10421 return c;
10422 }
10423}
10424function hasCSSTransform(el, root, moveClass) {
10425 // Detect whether an element with the move class applied has
10426 // CSS transitions. Since the element may be inside an entering
10427 // transition at this very moment, we make a clone of it and remove
10428 // all other transition classes applied to ensure only the move class
10429 // is applied.
10430 const clone = el.cloneNode();
10431 if (el._vtc) {
10432 el._vtc.forEach(cls => {
10433 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
10434 });
10435 }
10436 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
10437 clone.style.display = 'none';
10438 const container = (root.nodeType === 1 ? root : root.parentNode);
10439 container.appendChild(clone);
10440 const { hasTransform } = getTransitionInfo(clone);
10441 container.removeChild(clone);
10442 return hasTransform;
10443}
10444
10445const getModelAssigner = (vnode) => {
10446 const fn = vnode.props['onUpdate:modelValue'] ||
10447 (false );
10448 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
10449};
10450function onCompositionStart(e) {
10451 e.target.composing = true;
10452}
10453function onCompositionEnd(e) {
10454 const target = e.target;
10455 if (target.composing) {
10456 target.composing = false;
10457 target.dispatchEvent(new Event('input'));
10458 }
10459}
10460// We are exporting the v-model runtime directly as vnode hooks so that it can
10461// be tree-shaken in case v-model is never used.
10462const vModelText = {
10463 created(el, { modifiers: { lazy, trim, number } }, vnode) {
10464 el._assign = getModelAssigner(vnode);
10465 const castToNumber = number || (vnode.props && vnode.props.type === 'number');
10466 addEventListener(el, lazy ? 'change' : 'input', e => {
10467 if (e.target.composing)
10468 return;
10469 let domValue = el.value;
10470 if (trim) {
10471 domValue = domValue.trim();
10472 }
10473 if (castToNumber) {
10474 domValue = toNumber(domValue);
10475 }
10476 el._assign(domValue);
10477 });
10478 if (trim) {
10479 addEventListener(el, 'change', () => {
10480 el.value = el.value.trim();
10481 });
10482 }
10483 if (!lazy) {
10484 addEventListener(el, 'compositionstart', onCompositionStart);
10485 addEventListener(el, 'compositionend', onCompositionEnd);
10486 // Safari < 10.2 & UIWebView doesn't fire compositionend when
10487 // switching focus before confirming composition choice
10488 // this also fixes the issue where some browsers e.g. iOS Chrome
10489 // fires "change" instead of "input" on autocomplete.
10490 addEventListener(el, 'change', onCompositionEnd);
10491 }
10492 },
10493 // set value on mounted so it's after min/max for type="range"
10494 mounted(el, { value }) {
10495 el.value = value == null ? '' : value;
10496 },
10497 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
10498 el._assign = getModelAssigner(vnode);
10499 // avoid clearing unresolved text. #2302
10500 if (el.composing)
10501 return;
10502 if (document.activeElement === el && el.type !== 'range') {
10503 if (lazy) {
10504 return;
10505 }
10506 if (trim && el.value.trim() === value) {
10507 return;
10508 }
10509 if ((number || el.type === 'number') && toNumber(el.value) === value) {
10510 return;
10511 }
10512 }
10513 const newValue = value == null ? '' : value;
10514 if (el.value !== newValue) {
10515 el.value = newValue;
10516 }
10517 }
10518};
10519const vModelCheckbox = {
10520 // #4096 array checkboxes need to be deep traversed
10521 deep: true,
10522 created(el, _, vnode) {
10523 el._assign = getModelAssigner(vnode);
10524 addEventListener(el, 'change', () => {
10525 const modelValue = el._modelValue;
10526 const elementValue = getValue(el);
10527 const checked = el.checked;
10528 const assign = el._assign;
10529 if (isArray(modelValue)) {
10530 const index = looseIndexOf(modelValue, elementValue);
10531 const found = index !== -1;
10532 if (checked && !found) {
10533 assign(modelValue.concat(elementValue));
10534 }
10535 else if (!checked && found) {
10536 const filtered = [...modelValue];
10537 filtered.splice(index, 1);
10538 assign(filtered);
10539 }
10540 }
10541 else if (isSet(modelValue)) {
10542 const cloned = new Set(modelValue);
10543 if (checked) {
10544 cloned.add(elementValue);
10545 }
10546 else {
10547 cloned.delete(elementValue);
10548 }
10549 assign(cloned);
10550 }
10551 else {
10552 assign(getCheckboxValue(el, checked));
10553 }
10554 });
10555 },
10556 // set initial checked on mount to wait for true-value/false-value
10557 mounted: setChecked,
10558 beforeUpdate(el, binding, vnode) {
10559 el._assign = getModelAssigner(vnode);
10560 setChecked(el, binding, vnode);
10561 }
10562};
10563function setChecked(el, { value, oldValue }, vnode) {
10564 el._modelValue = value;
10565 if (isArray(value)) {
10566 el.checked = looseIndexOf(value, vnode.props.value) > -1;
10567 }
10568 else if (isSet(value)) {
10569 el.checked = value.has(vnode.props.value);
10570 }
10571 else if (value !== oldValue) {
10572 el.checked = looseEqual(value, getCheckboxValue(el, true));
10573 }
10574}
10575const vModelRadio = {
10576 created(el, { value }, vnode) {
10577 el.checked = looseEqual(value, vnode.props.value);
10578 el._assign = getModelAssigner(vnode);
10579 addEventListener(el, 'change', () => {
10580 el._assign(getValue(el));
10581 });
10582 },
10583 beforeUpdate(el, { value, oldValue }, vnode) {
10584 el._assign = getModelAssigner(vnode);
10585 if (value !== oldValue) {
10586 el.checked = looseEqual(value, vnode.props.value);
10587 }
10588 }
10589};
10590const vModelSelect = {
10591 // <select multiple> value need to be deep traversed
10592 deep: true,
10593 created(el, { value, modifiers: { number } }, vnode) {
10594 const isSetModel = isSet(value);
10595 addEventListener(el, 'change', () => {
10596 const selectedVal = Array.prototype.filter
10597 .call(el.options, (o) => o.selected)
10598 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
10599 el._assign(el.multiple
10600 ? isSetModel
10601 ? new Set(selectedVal)
10602 : selectedVal
10603 : selectedVal[0]);
10604 });
10605 el._assign = getModelAssigner(vnode);
10606 },
10607 // set value in mounted & updated because <select> relies on its children
10608 // <option>s.
10609 mounted(el, { value }) {
10610 setSelected(el, value);
10611 },
10612 beforeUpdate(el, _binding, vnode) {
10613 el._assign = getModelAssigner(vnode);
10614 },
10615 updated(el, { value }) {
10616 setSelected(el, value);
10617 }
10618};
10619function setSelected(el, value) {
10620 const isMultiple = el.multiple;
10621 if (isMultiple && !isArray(value) && !isSet(value)) {
10622 warn$1(`<select multiple v-model> expects an Array or Set value for its binding, ` +
10623 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
10624 return;
10625 }
10626 for (let i = 0, l = el.options.length; i < l; i++) {
10627 const option = el.options[i];
10628 const optionValue = getValue(option);
10629 if (isMultiple) {
10630 if (isArray(value)) {
10631 option.selected = looseIndexOf(value, optionValue) > -1;
10632 }
10633 else {
10634 option.selected = value.has(optionValue);
10635 }
10636 }
10637 else {
10638 if (looseEqual(getValue(option), value)) {
10639 if (el.selectedIndex !== i)
10640 el.selectedIndex = i;
10641 return;
10642 }
10643 }
10644 }
10645 if (!isMultiple && el.selectedIndex !== -1) {
10646 el.selectedIndex = -1;
10647 }
10648}
10649// retrieve raw value set via :value bindings
10650function getValue(el) {
10651 return '_value' in el ? el._value : el.value;
10652}
10653// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
10654function getCheckboxValue(el, checked) {
10655 const key = checked ? '_trueValue' : '_falseValue';
10656 return key in el ? el[key] : checked;
10657}
10658const vModelDynamic = {
10659 created(el, binding, vnode) {
10660 callModelHook(el, binding, vnode, null, 'created');
10661 },
10662 mounted(el, binding, vnode) {
10663 callModelHook(el, binding, vnode, null, 'mounted');
10664 },
10665 beforeUpdate(el, binding, vnode, prevVNode) {
10666 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
10667 },
10668 updated(el, binding, vnode, prevVNode) {
10669 callModelHook(el, binding, vnode, prevVNode, 'updated');
10670 }
10671};
10672function resolveDynamicModel(tagName, type) {
10673 switch (tagName) {
10674 case 'SELECT':
10675 return vModelSelect;
10676 case 'TEXTAREA':
10677 return vModelText;
10678 default:
10679 switch (type) {
10680 case 'checkbox':
10681 return vModelCheckbox;
10682 case 'radio':
10683 return vModelRadio;
10684 default:
10685 return vModelText;
10686 }
10687 }
10688}
10689function callModelHook(el, binding, vnode, prevVNode, hook) {
10690 const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
10691 const fn = modelToUse[hook];
10692 fn && fn(el, binding, vnode, prevVNode);
10693}
10694
10695const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
10696const modifierGuards = {
10697 stop: e => e.stopPropagation(),
10698 prevent: e => e.preventDefault(),
10699 self: e => e.target !== e.currentTarget,
10700 ctrl: e => !e.ctrlKey,
10701 shift: e => !e.shiftKey,
10702 alt: e => !e.altKey,
10703 meta: e => !e.metaKey,
10704 left: e => 'button' in e && e.button !== 0,
10705 middle: e => 'button' in e && e.button !== 1,
10706 right: e => 'button' in e && e.button !== 2,
10707 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
10708};
10709/**
10710 * @private
10711 */
10712const withModifiers = (fn, modifiers) => {
10713 return (event, ...args) => {
10714 for (let i = 0; i < modifiers.length; i++) {
10715 const guard = modifierGuards[modifiers[i]];
10716 if (guard && guard(event, modifiers))
10717 return;
10718 }
10719 return fn(event, ...args);
10720 };
10721};
10722// Kept for 2.x compat.
10723// Note: IE11 compat for `spacebar` and `del` is removed for now.
10724const keyNames = {
10725 esc: 'escape',
10726 space: ' ',
10727 up: 'arrow-up',
10728 left: 'arrow-left',
10729 right: 'arrow-right',
10730 down: 'arrow-down',
10731 delete: 'backspace'
10732};
10733/**
10734 * @private
10735 */
10736const withKeys = (fn, modifiers) => {
10737 return (event) => {
10738 if (!('key' in event)) {
10739 return;
10740 }
10741 const eventKey = hyphenate(event.key);
10742 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
10743 return fn(event);
10744 }
10745 };
10746};
10747
10748const vShow = {
10749 beforeMount(el, { value }, { transition }) {
10750 el._vod = el.style.display === 'none' ? '' : el.style.display;
10751 if (transition && value) {
10752 transition.beforeEnter(el);
10753 }
10754 else {
10755 setDisplay(el, value);
10756 }
10757 },
10758 mounted(el, { value }, { transition }) {
10759 if (transition && value) {
10760 transition.enter(el);
10761 }
10762 },
10763 updated(el, { value, oldValue }, { transition }) {
10764 if (!value === !oldValue)
10765 return;
10766 if (transition) {
10767 if (value) {
10768 transition.beforeEnter(el);
10769 setDisplay(el, true);
10770 transition.enter(el);
10771 }
10772 else {
10773 transition.leave(el, () => {
10774 setDisplay(el, false);
10775 });
10776 }
10777 }
10778 else {
10779 setDisplay(el, value);
10780 }
10781 },
10782 beforeUnmount(el, { value }) {
10783 setDisplay(el, value);
10784 }
10785};
10786function setDisplay(el, value) {
10787 el.style.display = value ? el._vod : 'none';
10788}
10789
10790const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps);
10791// lazy create the renderer - this makes core renderer logic tree-shakable
10792// in case the user only imports reactivity utilities from Vue.
10793let renderer;
10794let enabledHydration = false;
10795function ensureRenderer() {
10796 return (renderer ||
10797 (renderer = createRenderer(rendererOptions)));
10798}
10799function ensureHydrationRenderer() {
10800 renderer = enabledHydration
10801 ? renderer
10802 : createHydrationRenderer(rendererOptions);
10803 enabledHydration = true;
10804 return renderer;
10805}
10806// use explicit type casts here to avoid import() calls in rolled-up d.ts
10807const render = ((...args) => {
10808 ensureRenderer().render(...args);
10809});
10810const hydrate = ((...args) => {
10811 ensureHydrationRenderer().hydrate(...args);
10812});
10813const createApp = ((...args) => {
10814 const app = ensureRenderer().createApp(...args);
10815 {
10816 injectNativeTagCheck(app);
10817 injectCompilerOptionsCheck(app);
10818 }
10819 const { mount } = app;
10820 app.mount = (containerOrSelector) => {
10821 const container = normalizeContainer(containerOrSelector);
10822 if (!container)
10823 return;
10824 const component = app._component;
10825 if (!isFunction(component) && !component.render && !component.template) {
10826 // __UNSAFE__
10827 // Reason: potential execution of JS expressions in in-DOM template.
10828 // The user must make sure the in-DOM template is trusted. If it's
10829 // rendered by the server, the template should not contain any user data.
10830 component.template = container.innerHTML;
10831 }
10832 // clear content before mounting
10833 container.innerHTML = '';
10834 const proxy = mount(container, false, container instanceof SVGElement);
10835 if (container instanceof Element) {
10836 container.removeAttribute('v-cloak');
10837 container.setAttribute('data-v-app', '');
10838 }
10839 return proxy;
10840 };
10841 return app;
10842});
10843const createSSRApp = ((...args) => {
10844 const app = ensureHydrationRenderer().createApp(...args);
10845 {
10846 injectNativeTagCheck(app);
10847 injectCompilerOptionsCheck(app);
10848 }
10849 const { mount } = app;
10850 app.mount = (containerOrSelector) => {
10851 const container = normalizeContainer(containerOrSelector);
10852 if (container) {
10853 return mount(container, true, container instanceof SVGElement);
10854 }
10855 };
10856 return app;
10857});
10858function injectNativeTagCheck(app) {
10859 // Inject `isNativeTag`
10860 // this is used for component name validation (dev only)
10861 Object.defineProperty(app.config, 'isNativeTag', {
10862 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
10863 writable: false
10864 });
10865}
10866// dev only
10867function injectCompilerOptionsCheck(app) {
10868 if (isRuntimeOnly()) {
10869 const isCustomElement = app.config.isCustomElement;
10870 Object.defineProperty(app.config, 'isCustomElement', {
10871 get() {
10872 return isCustomElement;
10873 },
10874 set() {
10875 warn$1(`The \`isCustomElement\` config option is deprecated. Use ` +
10876 `\`compilerOptions.isCustomElement\` instead.`);
10877 }
10878 });
10879 const compilerOptions = app.config.compilerOptions;
10880 const msg = `The \`compilerOptions\` config option is only respected when using ` +
10881 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
10882 `Since you are using the runtime-only build, \`compilerOptions\` ` +
10883 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
10884 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
10885 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
10886 `- 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`;
10887 Object.defineProperty(app.config, 'compilerOptions', {
10888 get() {
10889 warn$1(msg);
10890 return compilerOptions;
10891 },
10892 set() {
10893 warn$1(msg);
10894 }
10895 });
10896 }
10897}
10898function normalizeContainer(container) {
10899 if (isString(container)) {
10900 const res = document.querySelector(container);
10901 if (!res) {
10902 warn$1(`Failed to mount app: mount target selector "${container}" returned null.`);
10903 }
10904 return res;
10905 }
10906 if (window.ShadowRoot &&
10907 container instanceof window.ShadowRoot &&
10908 container.mode === 'closed') {
10909 warn$1(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
10910 }
10911 return container;
10912}
10913/**
10914 * @internal
10915 */
10916const initDirectivesForSSR = NOOP;
10917
10918var runtimeDom = /*#__PURE__*/Object.freeze({
10919 __proto__: null,
10920 render: render,
10921 hydrate: hydrate,
10922 createApp: createApp,
10923 createSSRApp: createSSRApp,
10924 initDirectivesForSSR: initDirectivesForSSR,
10925 defineCustomElement: defineCustomElement,
10926 defineSSRCustomElement: defineSSRCustomElement,
10927 VueElement: VueElement,
10928 useCssModule: useCssModule,
10929 useCssVars: useCssVars,
10930 Transition: Transition,
10931 TransitionGroup: TransitionGroup,
10932 vModelText: vModelText,
10933 vModelCheckbox: vModelCheckbox,
10934 vModelRadio: vModelRadio,
10935 vModelSelect: vModelSelect,
10936 vModelDynamic: vModelDynamic,
10937 withModifiers: withModifiers,
10938 withKeys: withKeys,
10939 vShow: vShow,
10940 reactive: reactive,
10941 ref: ref,
10942 readonly: readonly,
10943 unref: unref,
10944 proxyRefs: proxyRefs,
10945 isRef: isRef,
10946 toRef: toRef,
10947 toRefs: toRefs,
10948 isProxy: isProxy,
10949 isReactive: isReactive,
10950 isReadonly: isReadonly,
10951 isShallow: isShallow,
10952 customRef: customRef,
10953 triggerRef: triggerRef,
10954 shallowRef: shallowRef,
10955 shallowReactive: shallowReactive,
10956 shallowReadonly: shallowReadonly,
10957 markRaw: markRaw,
10958 toRaw: toRaw,
10959 effect: effect,
10960 stop: stop,
10961 ReactiveEffect: ReactiveEffect,
10962 effectScope: effectScope,
10963 EffectScope: EffectScope,
10964 getCurrentScope: getCurrentScope,
10965 onScopeDispose: onScopeDispose,
10966 computed: computed$1,
10967 watch: watch,
10968 watchEffect: watchEffect,
10969 watchPostEffect: watchPostEffect,
10970 watchSyncEffect: watchSyncEffect,
10971 onBeforeMount: onBeforeMount,
10972 onMounted: onMounted,
10973 onBeforeUpdate: onBeforeUpdate,
10974 onUpdated: onUpdated,
10975 onBeforeUnmount: onBeforeUnmount,
10976 onUnmounted: onUnmounted,
10977 onActivated: onActivated,
10978 onDeactivated: onDeactivated,
10979 onRenderTracked: onRenderTracked,
10980 onRenderTriggered: onRenderTriggered,
10981 onErrorCaptured: onErrorCaptured,
10982 onServerPrefetch: onServerPrefetch,
10983 provide: provide,
10984 inject: inject,
10985 nextTick: nextTick,
10986 defineComponent: defineComponent,
10987 defineAsyncComponent: defineAsyncComponent,
10988 useAttrs: useAttrs,
10989 useSlots: useSlots,
10990 defineProps: defineProps,
10991 defineEmits: defineEmits,
10992 defineExpose: defineExpose,
10993 withDefaults: withDefaults,
10994 mergeDefaults: mergeDefaults,
10995 createPropsRestProxy: createPropsRestProxy,
10996 withAsyncContext: withAsyncContext,
10997 getCurrentInstance: getCurrentInstance,
10998 h: h,
10999 createVNode: createVNode,
11000 cloneVNode: cloneVNode,
11001 mergeProps: mergeProps,
11002 isVNode: isVNode,
11003 Fragment: Fragment,
11004 Text: Text,
11005 Comment: Comment,
11006 Static: Static,
11007 Teleport: Teleport,
11008 Suspense: Suspense,
11009 KeepAlive: KeepAlive,
11010 BaseTransition: BaseTransition,
11011 withDirectives: withDirectives,
11012 useSSRContext: useSSRContext,
11013 ssrContextKey: ssrContextKey,
11014 createRenderer: createRenderer,
11015 createHydrationRenderer: createHydrationRenderer,
11016 queuePostFlushCb: queuePostFlushCb,
11017 warn: warn$1,
11018 handleError: handleError,
11019 callWithErrorHandling: callWithErrorHandling,
11020 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
11021 resolveComponent: resolveComponent,
11022 resolveDirective: resolveDirective,
11023 resolveDynamicComponent: resolveDynamicComponent,
11024 registerRuntimeCompiler: registerRuntimeCompiler,
11025 isRuntimeOnly: isRuntimeOnly,
11026 useTransitionState: useTransitionState,
11027 resolveTransitionHooks: resolveTransitionHooks,
11028 setTransitionHooks: setTransitionHooks,
11029 getTransitionRawChildren: getTransitionRawChildren,
11030 initCustomFormatter: initCustomFormatter,
11031 get devtools () { return devtools; },
11032 setDevtoolsHook: setDevtoolsHook,
11033 withCtx: withCtx,
11034 pushScopeId: pushScopeId,
11035 popScopeId: popScopeId,
11036 withScopeId: withScopeId,
11037 renderList: renderList,
11038 toHandlers: toHandlers,
11039 renderSlot: renderSlot,
11040 createSlots: createSlots,
11041 withMemo: withMemo,
11042 isMemoSame: isMemoSame,
11043 openBlock: openBlock,
11044 createBlock: createBlock,
11045 setBlockTracking: setBlockTracking,
11046 createTextVNode: createTextVNode,
11047 createCommentVNode: createCommentVNode,
11048 createStaticVNode: createStaticVNode,
11049 createElementVNode: createBaseVNode,
11050 createElementBlock: createElementBlock,
11051 guardReactiveProps: guardReactiveProps,
11052 toDisplayString: toDisplayString,
11053 camelize: camelize,
11054 capitalize: capitalize,
11055 toHandlerKey: toHandlerKey,
11056 normalizeProps: normalizeProps,
11057 normalizeClass: normalizeClass,
11058 normalizeStyle: normalizeStyle,
11059 transformVNodeArgs: transformVNodeArgs,
11060 version: version,
11061 ssrUtils: ssrUtils,
11062 resolveFilter: resolveFilter,
11063 compatUtils: compatUtils
11064});
11065
11066function initDev() {
11067 {
11068 {
11069 console.info(`You are running a development build of Vue.\n` +
11070 `Make sure to use the production build (*.prod.js) when deploying for production.`);
11071 }
11072 initCustomFormatter();
11073 }
11074}
11075
11076function defaultOnError(error) {
11077 throw error;
11078}
11079function defaultOnWarn(msg) {
11080 console.warn(`[Vue warn] ${msg.message}`);
11081}
11082function createCompilerError(code, loc, messages, additionalMessage) {
11083 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
11084 ;
11085 const error = new SyntaxError(String(msg));
11086 error.code = code;
11087 error.loc = loc;
11088 return error;
11089}
11090const errorMessages = {
11091 // parse errors
11092 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
11093 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
11094 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
11095 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
11096 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
11097 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
11098 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
11099 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
11100 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
11101 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
11102 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
11103 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
11104 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
11105 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
11106 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
11107 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
11108 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
11109 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
11110 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
11111 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
11112 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
11113 [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
11114 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
11115 // Vue-specific parse errors
11116 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
11117 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
11118 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
11119 [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
11120 'Note that dynamic directive argument cannot contain spaces.',
11121 [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
11122 // transform errors
11123 [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
11124 [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
11125 [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
11126 [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
11127 [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
11128 [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
11129 [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
11130 [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
11131 [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
11132 [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
11133 `When there are multiple named slots, all slots should use <template> ` +
11134 `syntax to avoid scope ambiguity.`,
11135 [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
11136 [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
11137 `default slot. These children will be ignored.`,
11138 [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
11139 [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
11140 [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
11141 [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.`,
11142 [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
11143 [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
11144 // generic errors
11145 [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
11146 [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
11147 [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
11148 [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
11149 // just to fulfill types
11150 [50 /* __EXTEND_POINT__ */]: ``
11151};
11152
11153const FRAGMENT = Symbol(`Fragment` );
11154const TELEPORT = Symbol(`Teleport` );
11155const SUSPENSE = Symbol(`Suspense` );
11156const KEEP_ALIVE = Symbol(`KeepAlive` );
11157const BASE_TRANSITION = Symbol(`BaseTransition` );
11158const OPEN_BLOCK = Symbol(`openBlock` );
11159const CREATE_BLOCK = Symbol(`createBlock` );
11160const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` );
11161const CREATE_VNODE = Symbol(`createVNode` );
11162const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` );
11163const CREATE_COMMENT = Symbol(`createCommentVNode` );
11164const CREATE_TEXT = Symbol(`createTextVNode` );
11165const CREATE_STATIC = Symbol(`createStaticVNode` );
11166const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
11167const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
11168const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
11169const RESOLVE_FILTER = Symbol(`resolveFilter` );
11170const WITH_DIRECTIVES = Symbol(`withDirectives` );
11171const RENDER_LIST = Symbol(`renderList` );
11172const RENDER_SLOT = Symbol(`renderSlot` );
11173const CREATE_SLOTS = Symbol(`createSlots` );
11174const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
11175const MERGE_PROPS = Symbol(`mergeProps` );
11176const NORMALIZE_CLASS = Symbol(`normalizeClass` );
11177const NORMALIZE_STYLE = Symbol(`normalizeStyle` );
11178const NORMALIZE_PROPS = Symbol(`normalizeProps` );
11179const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` );
11180const TO_HANDLERS = Symbol(`toHandlers` );
11181const CAMELIZE = Symbol(`camelize` );
11182const CAPITALIZE = Symbol(`capitalize` );
11183const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
11184const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
11185const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
11186const POP_SCOPE_ID = Symbol(`popScopeId` );
11187const WITH_CTX = Symbol(`withCtx` );
11188const UNREF = Symbol(`unref` );
11189const IS_REF = Symbol(`isRef` );
11190const WITH_MEMO = Symbol(`withMemo` );
11191const IS_MEMO_SAME = Symbol(`isMemoSame` );
11192// Name mapping for runtime helpers that need to be imported from 'vue' in
11193// generated code. Make sure these are correctly exported in the runtime!
11194// Using `any` here because TS doesn't allow symbols as index type.
11195const helperNameMap = {
11196 [FRAGMENT]: `Fragment`,
11197 [TELEPORT]: `Teleport`,
11198 [SUSPENSE]: `Suspense`,
11199 [KEEP_ALIVE]: `KeepAlive`,
11200 [BASE_TRANSITION]: `BaseTransition`,
11201 [OPEN_BLOCK]: `openBlock`,
11202 [CREATE_BLOCK]: `createBlock`,
11203 [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
11204 [CREATE_VNODE]: `createVNode`,
11205 [CREATE_ELEMENT_VNODE]: `createElementVNode`,
11206 [CREATE_COMMENT]: `createCommentVNode`,
11207 [CREATE_TEXT]: `createTextVNode`,
11208 [CREATE_STATIC]: `createStaticVNode`,
11209 [RESOLVE_COMPONENT]: `resolveComponent`,
11210 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
11211 [RESOLVE_DIRECTIVE]: `resolveDirective`,
11212 [RESOLVE_FILTER]: `resolveFilter`,
11213 [WITH_DIRECTIVES]: `withDirectives`,
11214 [RENDER_LIST]: `renderList`,
11215 [RENDER_SLOT]: `renderSlot`,
11216 [CREATE_SLOTS]: `createSlots`,
11217 [TO_DISPLAY_STRING]: `toDisplayString`,
11218 [MERGE_PROPS]: `mergeProps`,
11219 [NORMALIZE_CLASS]: `normalizeClass`,
11220 [NORMALIZE_STYLE]: `normalizeStyle`,
11221 [NORMALIZE_PROPS]: `normalizeProps`,
11222 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
11223 [TO_HANDLERS]: `toHandlers`,
11224 [CAMELIZE]: `camelize`,
11225 [CAPITALIZE]: `capitalize`,
11226 [TO_HANDLER_KEY]: `toHandlerKey`,
11227 [SET_BLOCK_TRACKING]: `setBlockTracking`,
11228 [PUSH_SCOPE_ID]: `pushScopeId`,
11229 [POP_SCOPE_ID]: `popScopeId`,
11230 [WITH_CTX]: `withCtx`,
11231 [UNREF]: `unref`,
11232 [IS_REF]: `isRef`,
11233 [WITH_MEMO]: `withMemo`,
11234 [IS_MEMO_SAME]: `isMemoSame`
11235};
11236function registerRuntimeHelpers(helpers) {
11237 Object.getOwnPropertySymbols(helpers).forEach(s => {
11238 helperNameMap[s] = helpers[s];
11239 });
11240}
11241
11242// AST Utilities ---------------------------------------------------------------
11243// Some expressions, e.g. sequence and conditional expressions, are never
11244// associated with template nodes, so their source locations are just a stub.
11245// Container types like CompoundExpression also don't need a real location.
11246const locStub = {
11247 source: '',
11248 start: { line: 1, column: 1, offset: 0 },
11249 end: { line: 1, column: 1, offset: 0 }
11250};
11251function createRoot(children, loc = locStub) {
11252 return {
11253 type: 0 /* ROOT */,
11254 children,
11255 helpers: [],
11256 components: [],
11257 directives: [],
11258 hoists: [],
11259 imports: [],
11260 cached: 0,
11261 temps: 0,
11262 codegenNode: undefined,
11263 loc
11264 };
11265}
11266function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
11267 if (context) {
11268 if (isBlock) {
11269 context.helper(OPEN_BLOCK);
11270 context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
11271 }
11272 else {
11273 context.helper(getVNodeHelper(context.inSSR, isComponent));
11274 }
11275 if (directives) {
11276 context.helper(WITH_DIRECTIVES);
11277 }
11278 }
11279 return {
11280 type: 13 /* VNODE_CALL */,
11281 tag,
11282 props,
11283 children,
11284 patchFlag,
11285 dynamicProps,
11286 directives,
11287 isBlock,
11288 disableTracking,
11289 isComponent,
11290 loc
11291 };
11292}
11293function createArrayExpression(elements, loc = locStub) {
11294 return {
11295 type: 17 /* JS_ARRAY_EXPRESSION */,
11296 loc,
11297 elements
11298 };
11299}
11300function createObjectExpression(properties, loc = locStub) {
11301 return {
11302 type: 15 /* JS_OBJECT_EXPRESSION */,
11303 loc,
11304 properties
11305 };
11306}
11307function createObjectProperty(key, value) {
11308 return {
11309 type: 16 /* JS_PROPERTY */,
11310 loc: locStub,
11311 key: isString(key) ? createSimpleExpression(key, true) : key,
11312 value
11313 };
11314}
11315function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
11316 return {
11317 type: 4 /* SIMPLE_EXPRESSION */,
11318 loc,
11319 content,
11320 isStatic,
11321 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
11322 };
11323}
11324function createCompoundExpression(children, loc = locStub) {
11325 return {
11326 type: 8 /* COMPOUND_EXPRESSION */,
11327 loc,
11328 children
11329 };
11330}
11331function createCallExpression(callee, args = [], loc = locStub) {
11332 return {
11333 type: 14 /* JS_CALL_EXPRESSION */,
11334 loc,
11335 callee,
11336 arguments: args
11337 };
11338}
11339function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
11340 return {
11341 type: 18 /* JS_FUNCTION_EXPRESSION */,
11342 params,
11343 returns,
11344 newline,
11345 isSlot,
11346 loc
11347 };
11348}
11349function createConditionalExpression(test, consequent, alternate, newline = true) {
11350 return {
11351 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
11352 test,
11353 consequent,
11354 alternate,
11355 newline,
11356 loc: locStub
11357 };
11358}
11359function createCacheExpression(index, value, isVNode = false) {
11360 return {
11361 type: 20 /* JS_CACHE_EXPRESSION */,
11362 index,
11363 value,
11364 isVNode,
11365 loc: locStub
11366 };
11367}
11368function createBlockStatement(body) {
11369 return {
11370 type: 21 /* JS_BLOCK_STATEMENT */,
11371 body,
11372 loc: locStub
11373 };
11374}
11375
11376const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
11377const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
11378function isCoreComponent(tag) {
11379 if (isBuiltInType(tag, 'Teleport')) {
11380 return TELEPORT;
11381 }
11382 else if (isBuiltInType(tag, 'Suspense')) {
11383 return SUSPENSE;
11384 }
11385 else if (isBuiltInType(tag, 'KeepAlive')) {
11386 return KEEP_ALIVE;
11387 }
11388 else if (isBuiltInType(tag, 'BaseTransition')) {
11389 return BASE_TRANSITION;
11390 }
11391}
11392const nonIdentifierRE = /^\d|[^\$\w]/;
11393const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
11394const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
11395const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
11396const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
11397/**
11398 * Simple lexer to check if an expression is a member expression. This is
11399 * lax and only checks validity at the root level (i.e. does not validate exps
11400 * inside square brackets), but it's ok since these are only used on template
11401 * expressions and false positives are invalid expressions in the first place.
11402 */
11403const isMemberExpressionBrowser = (path) => {
11404 // remove whitespaces around . or [ first
11405 path = path.trim().replace(whitespaceRE, s => s.trim());
11406 let state = 0 /* inMemberExp */;
11407 let stateStack = [];
11408 let currentOpenBracketCount = 0;
11409 let currentOpenParensCount = 0;
11410 let currentStringType = null;
11411 for (let i = 0; i < path.length; i++) {
11412 const char = path.charAt(i);
11413 switch (state) {
11414 case 0 /* inMemberExp */:
11415 if (char === '[') {
11416 stateStack.push(state);
11417 state = 1 /* inBrackets */;
11418 currentOpenBracketCount++;
11419 }
11420 else if (char === '(') {
11421 stateStack.push(state);
11422 state = 2 /* inParens */;
11423 currentOpenParensCount++;
11424 }
11425 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
11426 return false;
11427 }
11428 break;
11429 case 1 /* inBrackets */:
11430 if (char === `'` || char === `"` || char === '`') {
11431 stateStack.push(state);
11432 state = 3 /* inString */;
11433 currentStringType = char;
11434 }
11435 else if (char === `[`) {
11436 currentOpenBracketCount++;
11437 }
11438 else if (char === `]`) {
11439 if (!--currentOpenBracketCount) {
11440 state = stateStack.pop();
11441 }
11442 }
11443 break;
11444 case 2 /* inParens */:
11445 if (char === `'` || char === `"` || char === '`') {
11446 stateStack.push(state);
11447 state = 3 /* inString */;
11448 currentStringType = char;
11449 }
11450 else if (char === `(`) {
11451 currentOpenParensCount++;
11452 }
11453 else if (char === `)`) {
11454 // if the exp ends as a call then it should not be considered valid
11455 if (i === path.length - 1) {
11456 return false;
11457 }
11458 if (!--currentOpenParensCount) {
11459 state = stateStack.pop();
11460 }
11461 }
11462 break;
11463 case 3 /* inString */:
11464 if (char === currentStringType) {
11465 state = stateStack.pop();
11466 currentStringType = null;
11467 }
11468 break;
11469 }
11470 }
11471 return !currentOpenBracketCount && !currentOpenParensCount;
11472};
11473const isMemberExpression = isMemberExpressionBrowser
11474 ;
11475function getInnerRange(loc, offset, length) {
11476 const source = loc.source.slice(offset, offset + length);
11477 const newLoc = {
11478 source,
11479 start: advancePositionWithClone(loc.start, loc.source, offset),
11480 end: loc.end
11481 };
11482 if (length != null) {
11483 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
11484 }
11485 return newLoc;
11486}
11487function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
11488 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
11489}
11490// advance by mutation without cloning (for performance reasons), since this
11491// gets called a lot in the parser
11492function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
11493 let linesCount = 0;
11494 let lastNewLinePos = -1;
11495 for (let i = 0; i < numberOfCharacters; i++) {
11496 if (source.charCodeAt(i) === 10 /* newline char code */) {
11497 linesCount++;
11498 lastNewLinePos = i;
11499 }
11500 }
11501 pos.offset += numberOfCharacters;
11502 pos.line += linesCount;
11503 pos.column =
11504 lastNewLinePos === -1
11505 ? pos.column + numberOfCharacters
11506 : numberOfCharacters - lastNewLinePos;
11507 return pos;
11508}
11509function assert(condition, msg) {
11510 /* istanbul ignore if */
11511 if (!condition) {
11512 throw new Error(msg || `unexpected compiler condition`);
11513 }
11514}
11515function findDir(node, name, allowEmpty = false) {
11516 for (let i = 0; i < node.props.length; i++) {
11517 const p = node.props[i];
11518 if (p.type === 7 /* DIRECTIVE */ &&
11519 (allowEmpty || p.exp) &&
11520 (isString(name) ? p.name === name : name.test(p.name))) {
11521 return p;
11522 }
11523 }
11524}
11525function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11526 for (let i = 0; i < node.props.length; i++) {
11527 const p = node.props[i];
11528 if (p.type === 6 /* ATTRIBUTE */) {
11529 if (dynamicOnly)
11530 continue;
11531 if (p.name === name && (p.value || allowEmpty)) {
11532 return p;
11533 }
11534 }
11535 else if (p.name === 'bind' &&
11536 (p.exp || allowEmpty) &&
11537 isStaticArgOf(p.arg, name)) {
11538 return p;
11539 }
11540 }
11541}
11542function isStaticArgOf(arg, name) {
11543 return !!(arg && isStaticExp(arg) && arg.content === name);
11544}
11545function hasDynamicKeyVBind(node) {
11546 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
11547 p.name === 'bind' &&
11548 (!p.arg || // v-bind="obj"
11549 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
11550 !p.arg.isStatic) // v-bind:[foo]
11551 );
11552}
11553function isText(node) {
11554 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
11555}
11556function isVSlot(p) {
11557 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
11558}
11559function isTemplateNode(node) {
11560 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
11561}
11562function isSlotOutlet(node) {
11563 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
11564}
11565function getVNodeHelper(ssr, isComponent) {
11566 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
11567}
11568function getVNodeBlockHelper(ssr, isComponent) {
11569 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
11570}
11571const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
11572function getUnnormalizedProps(props, callPath = []) {
11573 if (props &&
11574 !isString(props) &&
11575 props.type === 14 /* JS_CALL_EXPRESSION */) {
11576 const callee = props.callee;
11577 if (!isString(callee) && propsHelperSet.has(callee)) {
11578 return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
11579 }
11580 }
11581 return [props, callPath];
11582}
11583function injectProp(node, prop, context) {
11584 let propsWithInjection;
11585 /**
11586 * 1. mergeProps(...)
11587 * 2. toHandlers(...)
11588 * 3. normalizeProps(...)
11589 * 4. normalizeProps(guardReactiveProps(...))
11590 *
11591 * we need to get the real props before normalization
11592 */
11593 let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11594 let callPath = [];
11595 let parentCall;
11596 if (props &&
11597 !isString(props) &&
11598 props.type === 14 /* JS_CALL_EXPRESSION */) {
11599 const ret = getUnnormalizedProps(props);
11600 props = ret[0];
11601 callPath = ret[1];
11602 parentCall = callPath[callPath.length - 1];
11603 }
11604 if (props == null || isString(props)) {
11605 propsWithInjection = createObjectExpression([prop]);
11606 }
11607 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
11608 // merged props... add ours
11609 // only inject key to object literal if it's the first argument so that
11610 // if doesn't override user provided keys
11611 const first = props.arguments[0];
11612 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
11613 first.properties.unshift(prop);
11614 }
11615 else {
11616 if (props.callee === TO_HANDLERS) {
11617 // #2366
11618 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11619 createObjectExpression([prop]),
11620 props
11621 ]);
11622 }
11623 else {
11624 props.arguments.unshift(createObjectExpression([prop]));
11625 }
11626 }
11627 !propsWithInjection && (propsWithInjection = props);
11628 }
11629 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
11630 let alreadyExists = false;
11631 // check existing key to avoid overriding user provided keys
11632 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
11633 const propKeyName = prop.key.content;
11634 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
11635 p.key.content === propKeyName);
11636 }
11637 if (!alreadyExists) {
11638 props.properties.unshift(prop);
11639 }
11640 propsWithInjection = props;
11641 }
11642 else {
11643 // single v-bind with expression, return a merged replacement
11644 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11645 createObjectExpression([prop]),
11646 props
11647 ]);
11648 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
11649 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
11650 // the `guardReactiveProps` will no longer be needed
11651 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
11652 parentCall = callPath[callPath.length - 2];
11653 }
11654 }
11655 if (node.type === 13 /* VNODE_CALL */) {
11656 if (parentCall) {
11657 parentCall.arguments[0] = propsWithInjection;
11658 }
11659 else {
11660 node.props = propsWithInjection;
11661 }
11662 }
11663 else {
11664 if (parentCall) {
11665 parentCall.arguments[0] = propsWithInjection;
11666 }
11667 else {
11668 node.arguments[2] = propsWithInjection;
11669 }
11670 }
11671}
11672function toValidAssetId(name, type) {
11673 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
11674 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
11675 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
11676 })}`;
11677}
11678function getMemoedVNodeCall(node) {
11679 if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
11680 return node.arguments[1].returns;
11681 }
11682 else {
11683 return node;
11684 }
11685}
11686function makeBlock(node, { helper, removeHelper, inSSR }) {
11687 if (!node.isBlock) {
11688 node.isBlock = true;
11689 removeHelper(getVNodeHelper(inSSR, node.isComponent));
11690 helper(OPEN_BLOCK);
11691 helper(getVNodeBlockHelper(inSSR, node.isComponent));
11692 }
11693}
11694
11695const deprecationData = {
11696 ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
11697 message: `Platform-native elements with "is" prop will no longer be ` +
11698 `treated as components in Vue 3 unless the "is" value is explicitly ` +
11699 `prefixed with "vue:".`,
11700 link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
11701 },
11702 ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
11703 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
11704 `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
11705 `\`v-model:${key}\`.`,
11706 link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
11707 },
11708 ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
11709 message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
11710 `Vue 3 will automatically set a binding as DOM property when appropriate.`
11711 },
11712 ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
11713 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
11714 `object spread: it will now overwrite an existing non-mergeable attribute ` +
11715 `that appears before v-bind in the case of conflict. ` +
11716 `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
11717 `You can also suppress this warning if the usage is intended.`,
11718 link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
11719 },
11720 ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
11721 message: `.native modifier for v-on has been removed as is no longer necessary.`,
11722 link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
11723 },
11724 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
11725 message: `v-if / v-for precedence when used on the same element has changed ` +
11726 `in Vue 3: v-if now takes higher precedence and will no longer have ` +
11727 `access to v-for scope variables. It is best to avoid the ambiguity ` +
11728 `with <template> tags or use a computed property that filters v-for ` +
11729 `data source.`,
11730 link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
11731 },
11732 ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
11733 message: `<template> with no special directives will render as a native template ` +
11734 `element instead of its inner content in Vue 3.`
11735 },
11736 ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
11737 message: `"inline-template" has been removed in Vue 3.`,
11738 link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
11739 },
11740 ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
11741 message: `filters have been removed in Vue 3. ` +
11742 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
11743 `Use method calls or computed properties instead.`,
11744 link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
11745 }
11746};
11747function getCompatValue(key, context) {
11748 const config = context.options
11749 ? context.options.compatConfig
11750 : context.compatConfig;
11751 const value = config && config[key];
11752 if (key === 'MODE') {
11753 return value || 3; // compiler defaults to v3 behavior
11754 }
11755 else {
11756 return value;
11757 }
11758}
11759function isCompatEnabled(key, context) {
11760 const mode = getCompatValue('MODE', context);
11761 const value = getCompatValue(key, context);
11762 // in v3 mode, only enable if explicitly set to true
11763 // otherwise enable for any non-false value
11764 return mode === 3 ? value === true : value !== false;
11765}
11766function checkCompatEnabled(key, context, loc, ...args) {
11767 const enabled = isCompatEnabled(key, context);
11768 if (enabled) {
11769 warnDeprecation(key, context, loc, ...args);
11770 }
11771 return enabled;
11772}
11773function warnDeprecation(key, context, loc, ...args) {
11774 const val = getCompatValue(key, context);
11775 if (val === 'suppress-warning') {
11776 return;
11777 }
11778 const { message, link } = deprecationData[key];
11779 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
11780 const err = new SyntaxError(msg);
11781 err.code = key;
11782 if (loc)
11783 err.loc = loc;
11784 context.onWarn(err);
11785}
11786
11787// The default decoder only provides escapes for characters reserved as part of
11788// the template syntax, and is only used if the custom renderer did not provide
11789// a platform-specific decoder.
11790const decodeRE = /&(gt|lt|amp|apos|quot);/g;
11791const decodeMap = {
11792 gt: '>',
11793 lt: '<',
11794 amp: '&',
11795 apos: "'",
11796 quot: '"'
11797};
11798const defaultParserOptions = {
11799 delimiters: [`{{`, `}}`],
11800 getNamespace: () => 0 /* HTML */,
11801 getTextMode: () => 0 /* DATA */,
11802 isVoidTag: NO,
11803 isPreTag: NO,
11804 isCustomElement: NO,
11805 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
11806 onError: defaultOnError,
11807 onWarn: defaultOnWarn,
11808 comments: true
11809};
11810function baseParse(content, options = {}) {
11811 const context = createParserContext(content, options);
11812 const start = getCursor(context);
11813 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
11814}
11815function createParserContext(content, rawOptions) {
11816 const options = extend({}, defaultParserOptions);
11817 let key;
11818 for (key in rawOptions) {
11819 // @ts-ignore
11820 options[key] =
11821 rawOptions[key] === undefined
11822 ? defaultParserOptions[key]
11823 : rawOptions[key];
11824 }
11825 return {
11826 options,
11827 column: 1,
11828 line: 1,
11829 offset: 0,
11830 originalSource: content,
11831 source: content,
11832 inPre: false,
11833 inVPre: false,
11834 onWarn: options.onWarn
11835 };
11836}
11837function parseChildren(context, mode, ancestors) {
11838 const parent = last(ancestors);
11839 const ns = parent ? parent.ns : 0 /* HTML */;
11840 const nodes = [];
11841 while (!isEnd(context, mode, ancestors)) {
11842 const s = context.source;
11843 let node = undefined;
11844 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
11845 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
11846 // '{{'
11847 node = parseInterpolation(context, mode);
11848 }
11849 else if (mode === 0 /* DATA */ && s[0] === '<') {
11850 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
11851 if (s.length === 1) {
11852 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
11853 }
11854 else if (s[1] === '!') {
11855 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
11856 if (startsWith(s, '<!--')) {
11857 node = parseComment(context);
11858 }
11859 else if (startsWith(s, '<!DOCTYPE')) {
11860 // Ignore DOCTYPE by a limitation.
11861 node = parseBogusComment(context);
11862 }
11863 else if (startsWith(s, '<![CDATA[')) {
11864 if (ns !== 0 /* HTML */) {
11865 node = parseCDATA(context, ancestors);
11866 }
11867 else {
11868 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
11869 node = parseBogusComment(context);
11870 }
11871 }
11872 else {
11873 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
11874 node = parseBogusComment(context);
11875 }
11876 }
11877 else if (s[1] === '/') {
11878 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
11879 if (s.length === 2) {
11880 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
11881 }
11882 else if (s[2] === '>') {
11883 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
11884 advanceBy(context, 3);
11885 continue;
11886 }
11887 else if (/[a-z]/i.test(s[2])) {
11888 emitError(context, 23 /* X_INVALID_END_TAG */);
11889 parseTag(context, 1 /* End */, parent);
11890 continue;
11891 }
11892 else {
11893 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
11894 node = parseBogusComment(context);
11895 }
11896 }
11897 else if (/[a-z]/i.test(s[1])) {
11898 node = parseElement(context, ancestors);
11899 }
11900 else if (s[1] === '?') {
11901 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
11902 node = parseBogusComment(context);
11903 }
11904 else {
11905 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
11906 }
11907 }
11908 }
11909 if (!node) {
11910 node = parseText(context, mode);
11911 }
11912 if (isArray(node)) {
11913 for (let i = 0; i < node.length; i++) {
11914 pushNode(nodes, node[i]);
11915 }
11916 }
11917 else {
11918 pushNode(nodes, node);
11919 }
11920 }
11921 // Whitespace handling strategy like v2
11922 let removedWhitespace = false;
11923 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
11924 const shouldCondense = context.options.whitespace !== 'preserve';
11925 for (let i = 0; i < nodes.length; i++) {
11926 const node = nodes[i];
11927 if (!context.inPre && node.type === 2 /* TEXT */) {
11928 if (!/[^\t\r\n\f ]/.test(node.content)) {
11929 const prev = nodes[i - 1];
11930 const next = nodes[i + 1];
11931 // Remove if:
11932 // - the whitespace is the first or last node, or:
11933 // - (condense mode) the whitespace is adjacent to a comment, or:
11934 // - (condense mode) the whitespace is between two elements AND contains newline
11935 if (!prev ||
11936 !next ||
11937 (shouldCondense &&
11938 (prev.type === 3 /* COMMENT */ ||
11939 next.type === 3 /* COMMENT */ ||
11940 (prev.type === 1 /* ELEMENT */ &&
11941 next.type === 1 /* ELEMENT */ &&
11942 /[\r\n]/.test(node.content))))) {
11943 removedWhitespace = true;
11944 nodes[i] = null;
11945 }
11946 else {
11947 // Otherwise, the whitespace is condensed into a single space
11948 node.content = ' ';
11949 }
11950 }
11951 else if (shouldCondense) {
11952 // in condense mode, consecutive whitespaces in text are condensed
11953 // down to a single space.
11954 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11955 }
11956 }
11957 // Remove comment nodes if desired by configuration.
11958 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
11959 removedWhitespace = true;
11960 nodes[i] = null;
11961 }
11962 }
11963 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
11964 // remove leading newline per html spec
11965 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
11966 const first = nodes[0];
11967 if (first && first.type === 2 /* TEXT */) {
11968 first.content = first.content.replace(/^\r?\n/, '');
11969 }
11970 }
11971 }
11972 return removedWhitespace ? nodes.filter(Boolean) : nodes;
11973}
11974function pushNode(nodes, node) {
11975 if (node.type === 2 /* TEXT */) {
11976 const prev = last(nodes);
11977 // Merge if both this and the previous node are text and those are
11978 // consecutive. This happens for cases like "a < b".
11979 if (prev &&
11980 prev.type === 2 /* TEXT */ &&
11981 prev.loc.end.offset === node.loc.start.offset) {
11982 prev.content += node.content;
11983 prev.loc.end = node.loc.end;
11984 prev.loc.source += node.loc.source;
11985 return;
11986 }
11987 }
11988 nodes.push(node);
11989}
11990function parseCDATA(context, ancestors) {
11991 advanceBy(context, 9);
11992 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
11993 if (context.source.length === 0) {
11994 emitError(context, 6 /* EOF_IN_CDATA */);
11995 }
11996 else {
11997 advanceBy(context, 3);
11998 }
11999 return nodes;
12000}
12001function parseComment(context) {
12002 const start = getCursor(context);
12003 let content;
12004 // Regular comment.
12005 const match = /--(\!)?>/.exec(context.source);
12006 if (!match) {
12007 content = context.source.slice(4);
12008 advanceBy(context, context.source.length);
12009 emitError(context, 7 /* EOF_IN_COMMENT */);
12010 }
12011 else {
12012 if (match.index <= 3) {
12013 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
12014 }
12015 if (match[1]) {
12016 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
12017 }
12018 content = context.source.slice(4, match.index);
12019 // Advancing with reporting nested comments.
12020 const s = context.source.slice(0, match.index);
12021 let prevIndex = 1, nestedIndex = 0;
12022 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
12023 advanceBy(context, nestedIndex - prevIndex + 1);
12024 if (nestedIndex + 4 < s.length) {
12025 emitError(context, 16 /* NESTED_COMMENT */);
12026 }
12027 prevIndex = nestedIndex + 1;
12028 }
12029 advanceBy(context, match.index + match[0].length - prevIndex + 1);
12030 }
12031 return {
12032 type: 3 /* COMMENT */,
12033 content,
12034 loc: getSelection(context, start)
12035 };
12036}
12037function parseBogusComment(context) {
12038 const start = getCursor(context);
12039 const contentStart = context.source[1] === '?' ? 1 : 2;
12040 let content;
12041 const closeIndex = context.source.indexOf('>');
12042 if (closeIndex === -1) {
12043 content = context.source.slice(contentStart);
12044 advanceBy(context, context.source.length);
12045 }
12046 else {
12047 content = context.source.slice(contentStart, closeIndex);
12048 advanceBy(context, closeIndex + 1);
12049 }
12050 return {
12051 type: 3 /* COMMENT */,
12052 content,
12053 loc: getSelection(context, start)
12054 };
12055}
12056function parseElement(context, ancestors) {
12057 // Start tag.
12058 const wasInPre = context.inPre;
12059 const wasInVPre = context.inVPre;
12060 const parent = last(ancestors);
12061 const element = parseTag(context, 0 /* Start */, parent);
12062 const isPreBoundary = context.inPre && !wasInPre;
12063 const isVPreBoundary = context.inVPre && !wasInVPre;
12064 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
12065 // #4030 self-closing <pre> tag
12066 if (isPreBoundary) {
12067 context.inPre = false;
12068 }
12069 if (isVPreBoundary) {
12070 context.inVPre = false;
12071 }
12072 return element;
12073 }
12074 // Children.
12075 ancestors.push(element);
12076 const mode = context.options.getTextMode(element, parent);
12077 const children = parseChildren(context, mode, ancestors);
12078 ancestors.pop();
12079 element.children = children;
12080 // End tag.
12081 if (startsWithEndTagOpen(context.source, element.tag)) {
12082 parseTag(context, 1 /* End */, parent);
12083 }
12084 else {
12085 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
12086 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
12087 const first = children[0];
12088 if (first && startsWith(first.loc.source, '<!--')) {
12089 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
12090 }
12091 }
12092 }
12093 element.loc = getSelection(context, element.loc.start);
12094 if (isPreBoundary) {
12095 context.inPre = false;
12096 }
12097 if (isVPreBoundary) {
12098 context.inVPre = false;
12099 }
12100 return element;
12101}
12102const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
12103function parseTag(context, type, parent) {
12104 // Tag open.
12105 const start = getCursor(context);
12106 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
12107 const tag = match[1];
12108 const ns = context.options.getNamespace(tag, parent);
12109 advanceBy(context, match[0].length);
12110 advanceSpaces(context);
12111 // save current state in case we need to re-parse attributes with v-pre
12112 const cursor = getCursor(context);
12113 const currentSource = context.source;
12114 // check <pre> tag
12115 if (context.options.isPreTag(tag)) {
12116 context.inPre = true;
12117 }
12118 // Attributes.
12119 let props = parseAttributes(context, type);
12120 // check v-pre
12121 if (type === 0 /* Start */ &&
12122 !context.inVPre &&
12123 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
12124 context.inVPre = true;
12125 // reset context
12126 extend(context, cursor);
12127 context.source = currentSource;
12128 // re-parse attrs and filter out v-pre itself
12129 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
12130 }
12131 // Tag close.
12132 let isSelfClosing = false;
12133 if (context.source.length === 0) {
12134 emitError(context, 9 /* EOF_IN_TAG */);
12135 }
12136 else {
12137 isSelfClosing = startsWith(context.source, '/>');
12138 if (type === 1 /* End */ && isSelfClosing) {
12139 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
12140 }
12141 advanceBy(context, isSelfClosing ? 2 : 1);
12142 }
12143 if (type === 1 /* End */) {
12144 return;
12145 }
12146 let tagType = 0 /* ELEMENT */;
12147 if (!context.inVPre) {
12148 if (tag === 'slot') {
12149 tagType = 2 /* SLOT */;
12150 }
12151 else if (tag === 'template') {
12152 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
12153 tagType = 3 /* TEMPLATE */;
12154 }
12155 }
12156 else if (isComponent(tag, props, context)) {
12157 tagType = 1 /* COMPONENT */;
12158 }
12159 }
12160 return {
12161 type: 1 /* ELEMENT */,
12162 ns,
12163 tag,
12164 tagType,
12165 props,
12166 isSelfClosing,
12167 children: [],
12168 loc: getSelection(context, start),
12169 codegenNode: undefined // to be created during transform phase
12170 };
12171}
12172function isComponent(tag, props, context) {
12173 const options = context.options;
12174 if (options.isCustomElement(tag)) {
12175 return false;
12176 }
12177 if (tag === 'component' ||
12178 /^[A-Z]/.test(tag) ||
12179 isCoreComponent(tag) ||
12180 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
12181 (options.isNativeTag && !options.isNativeTag(tag))) {
12182 return true;
12183 }
12184 // at this point the tag should be a native tag, but check for potential "is"
12185 // casting
12186 for (let i = 0; i < props.length; i++) {
12187 const p = props[i];
12188 if (p.type === 6 /* ATTRIBUTE */) {
12189 if (p.name === 'is' && p.value) {
12190 if (p.value.content.startsWith('vue:')) {
12191 return true;
12192 }
12193 }
12194 }
12195 else {
12196 // directive
12197 // v-is (TODO Deprecate)
12198 if (p.name === 'is') {
12199 return true;
12200 }
12201 else if (
12202 // :is on plain element - only treat as component in compat mode
12203 p.name === 'bind' &&
12204 isStaticArgOf(p.arg, 'is') &&
12205 false &&
12206 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
12207 return true;
12208 }
12209 }
12210 }
12211}
12212function parseAttributes(context, type) {
12213 const props = [];
12214 const attributeNames = new Set();
12215 while (context.source.length > 0 &&
12216 !startsWith(context.source, '>') &&
12217 !startsWith(context.source, '/>')) {
12218 if (startsWith(context.source, '/')) {
12219 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
12220 advanceBy(context, 1);
12221 advanceSpaces(context);
12222 continue;
12223 }
12224 if (type === 1 /* End */) {
12225 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
12226 }
12227 const attr = parseAttribute(context, attributeNames);
12228 // Trim whitespace between class
12229 // https://github.com/vuejs/core/issues/4251
12230 if (attr.type === 6 /* ATTRIBUTE */ &&
12231 attr.value &&
12232 attr.name === 'class') {
12233 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
12234 }
12235 if (type === 0 /* Start */) {
12236 props.push(attr);
12237 }
12238 if (/^[^\t\r\n\f />]/.test(context.source)) {
12239 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
12240 }
12241 advanceSpaces(context);
12242 }
12243 return props;
12244}
12245function parseAttribute(context, nameSet) {
12246 // Name.
12247 const start = getCursor(context);
12248 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
12249 const name = match[0];
12250 if (nameSet.has(name)) {
12251 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
12252 }
12253 nameSet.add(name);
12254 if (name[0] === '=') {
12255 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
12256 }
12257 {
12258 const pattern = /["'<]/g;
12259 let m;
12260 while ((m = pattern.exec(name))) {
12261 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
12262 }
12263 }
12264 advanceBy(context, name.length);
12265 // Value
12266 let value = undefined;
12267 if (/^[\t\r\n\f ]*=/.test(context.source)) {
12268 advanceSpaces(context);
12269 advanceBy(context, 1);
12270 advanceSpaces(context);
12271 value = parseAttributeValue(context);
12272 if (!value) {
12273 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
12274 }
12275 }
12276 const loc = getSelection(context, start);
12277 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
12278 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
12279 let isPropShorthand = startsWith(name, '.');
12280 let dirName = match[1] ||
12281 (isPropShorthand || startsWith(name, ':')
12282 ? 'bind'
12283 : startsWith(name, '@')
12284 ? 'on'
12285 : 'slot');
12286 let arg;
12287 if (match[2]) {
12288 const isSlot = dirName === 'slot';
12289 const startOffset = name.lastIndexOf(match[2]);
12290 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
12291 let content = match[2];
12292 let isStatic = true;
12293 if (content.startsWith('[')) {
12294 isStatic = false;
12295 if (!content.endsWith(']')) {
12296 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
12297 content = content.slice(1);
12298 }
12299 else {
12300 content = content.slice(1, content.length - 1);
12301 }
12302 }
12303 else if (isSlot) {
12304 // #1241 special case for v-slot: vuetify relies extensively on slot
12305 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
12306 // supports such usage so we are keeping it consistent with 2.x.
12307 content += match[3] || '';
12308 }
12309 arg = {
12310 type: 4 /* SIMPLE_EXPRESSION */,
12311 content,
12312 isStatic,
12313 constType: isStatic
12314 ? 3 /* CAN_STRINGIFY */
12315 : 0 /* NOT_CONSTANT */,
12316 loc
12317 };
12318 }
12319 if (value && value.isQuoted) {
12320 const valueLoc = value.loc;
12321 valueLoc.start.offset++;
12322 valueLoc.start.column++;
12323 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
12324 valueLoc.source = valueLoc.source.slice(1, -1);
12325 }
12326 const modifiers = match[3] ? match[3].slice(1).split('.') : [];
12327 if (isPropShorthand)
12328 modifiers.push('prop');
12329 return {
12330 type: 7 /* DIRECTIVE */,
12331 name: dirName,
12332 exp: value && {
12333 type: 4 /* SIMPLE_EXPRESSION */,
12334 content: value.content,
12335 isStatic: false,
12336 // Treat as non-constant by default. This can be potentially set to
12337 // other values by `transformExpression` to make it eligible for hoisting.
12338 constType: 0 /* NOT_CONSTANT */,
12339 loc: value.loc
12340 },
12341 arg,
12342 modifiers,
12343 loc
12344 };
12345 }
12346 // missing directive name or illegal directive name
12347 if (!context.inVPre && startsWith(name, 'v-')) {
12348 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);
12349 }
12350 return {
12351 type: 6 /* ATTRIBUTE */,
12352 name,
12353 value: value && {
12354 type: 2 /* TEXT */,
12355 content: value.content,
12356 loc: value.loc
12357 },
12358 loc
12359 };
12360}
12361function parseAttributeValue(context) {
12362 const start = getCursor(context);
12363 let content;
12364 const quote = context.source[0];
12365 const isQuoted = quote === `"` || quote === `'`;
12366 if (isQuoted) {
12367 // Quoted value.
12368 advanceBy(context, 1);
12369 const endIndex = context.source.indexOf(quote);
12370 if (endIndex === -1) {
12371 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
12372 }
12373 else {
12374 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
12375 advanceBy(context, 1);
12376 }
12377 }
12378 else {
12379 // Unquoted
12380 const match = /^[^\t\r\n\f >]+/.exec(context.source);
12381 if (!match) {
12382 return undefined;
12383 }
12384 const unexpectedChars = /["'<=`]/g;
12385 let m;
12386 while ((m = unexpectedChars.exec(match[0]))) {
12387 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
12388 }
12389 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
12390 }
12391 return { content, isQuoted, loc: getSelection(context, start) };
12392}
12393function parseInterpolation(context, mode) {
12394 const [open, close] = context.options.delimiters;
12395 const closeIndex = context.source.indexOf(close, open.length);
12396 if (closeIndex === -1) {
12397 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
12398 return undefined;
12399 }
12400 const start = getCursor(context);
12401 advanceBy(context, open.length);
12402 const innerStart = getCursor(context);
12403 const innerEnd = getCursor(context);
12404 const rawContentLength = closeIndex - open.length;
12405 const rawContent = context.source.slice(0, rawContentLength);
12406 const preTrimContent = parseTextData(context, rawContentLength, mode);
12407 const content = preTrimContent.trim();
12408 const startOffset = preTrimContent.indexOf(content);
12409 if (startOffset > 0) {
12410 advancePositionWithMutation(innerStart, rawContent, startOffset);
12411 }
12412 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
12413 advancePositionWithMutation(innerEnd, rawContent, endOffset);
12414 advanceBy(context, close.length);
12415 return {
12416 type: 5 /* INTERPOLATION */,
12417 content: {
12418 type: 4 /* SIMPLE_EXPRESSION */,
12419 isStatic: false,
12420 // Set `isConstant` to false by default and will decide in transformExpression
12421 constType: 0 /* NOT_CONSTANT */,
12422 content,
12423 loc: getSelection(context, innerStart, innerEnd)
12424 },
12425 loc: getSelection(context, start)
12426 };
12427}
12428function parseText(context, mode) {
12429 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
12430 let endIndex = context.source.length;
12431 for (let i = 0; i < endTokens.length; i++) {
12432 const index = context.source.indexOf(endTokens[i], 1);
12433 if (index !== -1 && endIndex > index) {
12434 endIndex = index;
12435 }
12436 }
12437 const start = getCursor(context);
12438 const content = parseTextData(context, endIndex, mode);
12439 return {
12440 type: 2 /* TEXT */,
12441 content,
12442 loc: getSelection(context, start)
12443 };
12444}
12445/**
12446 * Get text data with a given length from the current location.
12447 * This translates HTML entities in the text data.
12448 */
12449function parseTextData(context, length, mode) {
12450 const rawText = context.source.slice(0, length);
12451 advanceBy(context, length);
12452 if (mode === 2 /* RAWTEXT */ ||
12453 mode === 3 /* CDATA */ ||
12454 !rawText.includes('&')) {
12455 return rawText;
12456 }
12457 else {
12458 // DATA or RCDATA containing "&"". Entity decoding required.
12459 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
12460 }
12461}
12462function getCursor(context) {
12463 const { column, line, offset } = context;
12464 return { column, line, offset };
12465}
12466function getSelection(context, start, end) {
12467 end = end || getCursor(context);
12468 return {
12469 start,
12470 end,
12471 source: context.originalSource.slice(start.offset, end.offset)
12472 };
12473}
12474function last(xs) {
12475 return xs[xs.length - 1];
12476}
12477function startsWith(source, searchString) {
12478 return source.startsWith(searchString);
12479}
12480function advanceBy(context, numberOfCharacters) {
12481 const { source } = context;
12482 advancePositionWithMutation(context, source, numberOfCharacters);
12483 context.source = source.slice(numberOfCharacters);
12484}
12485function advanceSpaces(context) {
12486 const match = /^[\t\r\n\f ]+/.exec(context.source);
12487 if (match) {
12488 advanceBy(context, match[0].length);
12489 }
12490}
12491function getNewPosition(context, start, numberOfCharacters) {
12492 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
12493}
12494function emitError(context, code, offset, loc = getCursor(context)) {
12495 if (offset) {
12496 loc.offset += offset;
12497 loc.column += offset;
12498 }
12499 context.options.onError(createCompilerError(code, {
12500 start: loc,
12501 end: loc,
12502 source: ''
12503 }));
12504}
12505function isEnd(context, mode, ancestors) {
12506 const s = context.source;
12507 switch (mode) {
12508 case 0 /* DATA */:
12509 if (startsWith(s, '</')) {
12510 // TODO: probably bad performance
12511 for (let i = ancestors.length - 1; i >= 0; --i) {
12512 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
12513 return true;
12514 }
12515 }
12516 }
12517 break;
12518 case 1 /* RCDATA */:
12519 case 2 /* RAWTEXT */: {
12520 const parent = last(ancestors);
12521 if (parent && startsWithEndTagOpen(s, parent.tag)) {
12522 return true;
12523 }
12524 break;
12525 }
12526 case 3 /* CDATA */:
12527 if (startsWith(s, ']]>')) {
12528 return true;
12529 }
12530 break;
12531 }
12532 return !s;
12533}
12534function startsWithEndTagOpen(source, tag) {
12535 return (startsWith(source, '</') &&
12536 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
12537 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
12538}
12539
12540function hoistStatic(root, context) {
12541 walk(root, context,
12542 // Root node is unfortunately non-hoistable due to potential parent
12543 // fallthrough attributes.
12544 isSingleElementRoot(root, root.children[0]));
12545}
12546function isSingleElementRoot(root, child) {
12547 const { children } = root;
12548 return (children.length === 1 &&
12549 child.type === 1 /* ELEMENT */ &&
12550 !isSlotOutlet(child));
12551}
12552function walk(node, context, doNotHoistNode = false) {
12553 const { children } = node;
12554 const originalCount = children.length;
12555 let hoistedCount = 0;
12556 for (let i = 0; i < children.length; i++) {
12557 const child = children[i];
12558 // only plain elements & text calls are eligible for hoisting.
12559 if (child.type === 1 /* ELEMENT */ &&
12560 child.tagType === 0 /* ELEMENT */) {
12561 const constantType = doNotHoistNode
12562 ? 0 /* NOT_CONSTANT */
12563 : getConstantType(child, context);
12564 if (constantType > 0 /* NOT_CONSTANT */) {
12565 if (constantType >= 2 /* CAN_HOIST */) {
12566 child.codegenNode.patchFlag =
12567 -1 /* HOISTED */ + (` /* HOISTED */` );
12568 child.codegenNode = context.hoist(child.codegenNode);
12569 hoistedCount++;
12570 continue;
12571 }
12572 }
12573 else {
12574 // node may contain dynamic children, but its props may be eligible for
12575 // hoisting.
12576 const codegenNode = child.codegenNode;
12577 if (codegenNode.type === 13 /* VNODE_CALL */) {
12578 const flag = getPatchFlag(codegenNode);
12579 if ((!flag ||
12580 flag === 512 /* NEED_PATCH */ ||
12581 flag === 1 /* TEXT */) &&
12582 getGeneratedPropsConstantType(child, context) >=
12583 2 /* CAN_HOIST */) {
12584 const props = getNodeProps(child);
12585 if (props) {
12586 codegenNode.props = context.hoist(props);
12587 }
12588 }
12589 if (codegenNode.dynamicProps) {
12590 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
12591 }
12592 }
12593 }
12594 }
12595 else if (child.type === 12 /* TEXT_CALL */ &&
12596 getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
12597 child.codegenNode = context.hoist(child.codegenNode);
12598 hoistedCount++;
12599 }
12600 // walk further
12601 if (child.type === 1 /* ELEMENT */) {
12602 const isComponent = child.tagType === 1 /* COMPONENT */;
12603 if (isComponent) {
12604 context.scopes.vSlot++;
12605 }
12606 walk(child, context);
12607 if (isComponent) {
12608 context.scopes.vSlot--;
12609 }
12610 }
12611 else if (child.type === 11 /* FOR */) {
12612 // Do not hoist v-for single child because it has to be a block
12613 walk(child, context, child.children.length === 1);
12614 }
12615 else if (child.type === 9 /* IF */) {
12616 for (let i = 0; i < child.branches.length; i++) {
12617 // Do not hoist v-if single child because it has to be a block
12618 walk(child.branches[i], context, child.branches[i].children.length === 1);
12619 }
12620 }
12621 }
12622 if (hoistedCount && context.transformHoist) {
12623 context.transformHoist(children, context, node);
12624 }
12625 // all children were hoisted - the entire children array is hoistable.
12626 if (hoistedCount &&
12627 hoistedCount === originalCount &&
12628 node.type === 1 /* ELEMENT */ &&
12629 node.tagType === 0 /* ELEMENT */ &&
12630 node.codegenNode &&
12631 node.codegenNode.type === 13 /* VNODE_CALL */ &&
12632 isArray(node.codegenNode.children)) {
12633 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
12634 }
12635}
12636function getConstantType(node, context) {
12637 const { constantCache } = context;
12638 switch (node.type) {
12639 case 1 /* ELEMENT */:
12640 if (node.tagType !== 0 /* ELEMENT */) {
12641 return 0 /* NOT_CONSTANT */;
12642 }
12643 const cached = constantCache.get(node);
12644 if (cached !== undefined) {
12645 return cached;
12646 }
12647 const codegenNode = node.codegenNode;
12648 if (codegenNode.type !== 13 /* VNODE_CALL */) {
12649 return 0 /* NOT_CONSTANT */;
12650 }
12651 if (codegenNode.isBlock &&
12652 node.tag !== 'svg' &&
12653 node.tag !== 'foreignObject') {
12654 return 0 /* NOT_CONSTANT */;
12655 }
12656 const flag = getPatchFlag(codegenNode);
12657 if (!flag) {
12658 let returnType = 3 /* CAN_STRINGIFY */;
12659 // Element itself has no patch flag. However we still need to check:
12660 // 1. Even for a node with no patch flag, it is possible for it to contain
12661 // non-hoistable expressions that refers to scope variables, e.g. compiler
12662 // injected keys or cached event handlers. Therefore we need to always
12663 // check the codegenNode's props to be sure.
12664 const generatedPropsType = getGeneratedPropsConstantType(node, context);
12665 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
12666 constantCache.set(node, 0 /* NOT_CONSTANT */);
12667 return 0 /* NOT_CONSTANT */;
12668 }
12669 if (generatedPropsType < returnType) {
12670 returnType = generatedPropsType;
12671 }
12672 // 2. its children.
12673 for (let i = 0; i < node.children.length; i++) {
12674 const childType = getConstantType(node.children[i], context);
12675 if (childType === 0 /* NOT_CONSTANT */) {
12676 constantCache.set(node, 0 /* NOT_CONSTANT */);
12677 return 0 /* NOT_CONSTANT */;
12678 }
12679 if (childType < returnType) {
12680 returnType = childType;
12681 }
12682 }
12683 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
12684 // type, check if any of the props can cause the type to be lowered
12685 // we can skip can_patch because it's guaranteed by the absence of a
12686 // patchFlag.
12687 if (returnType > 1 /* CAN_SKIP_PATCH */) {
12688 for (let i = 0; i < node.props.length; i++) {
12689 const p = node.props[i];
12690 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
12691 const expType = getConstantType(p.exp, context);
12692 if (expType === 0 /* NOT_CONSTANT */) {
12693 constantCache.set(node, 0 /* NOT_CONSTANT */);
12694 return 0 /* NOT_CONSTANT */;
12695 }
12696 if (expType < returnType) {
12697 returnType = expType;
12698 }
12699 }
12700 }
12701 }
12702 // only svg/foreignObject could be block here, however if they are
12703 // static then they don't need to be blocks since there will be no
12704 // nested updates.
12705 if (codegenNode.isBlock) {
12706 // except set custom directives.
12707 for (let i = 0; i < node.props.length; i++) {
12708 const p = node.props[i];
12709 if (p.type === 7 /* DIRECTIVE */) {
12710 constantCache.set(node, 0 /* NOT_CONSTANT */);
12711 return 0 /* NOT_CONSTANT */;
12712 }
12713 }
12714 context.removeHelper(OPEN_BLOCK);
12715 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
12716 codegenNode.isBlock = false;
12717 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
12718 }
12719 constantCache.set(node, returnType);
12720 return returnType;
12721 }
12722 else {
12723 constantCache.set(node, 0 /* NOT_CONSTANT */);
12724 return 0 /* NOT_CONSTANT */;
12725 }
12726 case 2 /* TEXT */:
12727 case 3 /* COMMENT */:
12728 return 3 /* CAN_STRINGIFY */;
12729 case 9 /* IF */:
12730 case 11 /* FOR */:
12731 case 10 /* IF_BRANCH */:
12732 return 0 /* NOT_CONSTANT */;
12733 case 5 /* INTERPOLATION */:
12734 case 12 /* TEXT_CALL */:
12735 return getConstantType(node.content, context);
12736 case 4 /* SIMPLE_EXPRESSION */:
12737 return node.constType;
12738 case 8 /* COMPOUND_EXPRESSION */:
12739 let returnType = 3 /* CAN_STRINGIFY */;
12740 for (let i = 0; i < node.children.length; i++) {
12741 const child = node.children[i];
12742 if (isString(child) || isSymbol(child)) {
12743 continue;
12744 }
12745 const childType = getConstantType(child, context);
12746 if (childType === 0 /* NOT_CONSTANT */) {
12747 return 0 /* NOT_CONSTANT */;
12748 }
12749 else if (childType < returnType) {
12750 returnType = childType;
12751 }
12752 }
12753 return returnType;
12754 default:
12755 return 0 /* NOT_CONSTANT */;
12756 }
12757}
12758const allowHoistedHelperSet = new Set([
12759 NORMALIZE_CLASS,
12760 NORMALIZE_STYLE,
12761 NORMALIZE_PROPS,
12762 GUARD_REACTIVE_PROPS
12763]);
12764function getConstantTypeOfHelperCall(value, context) {
12765 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
12766 !isString(value.callee) &&
12767 allowHoistedHelperSet.has(value.callee)) {
12768 const arg = value.arguments[0];
12769 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
12770 return getConstantType(arg, context);
12771 }
12772 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
12773 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
12774 return getConstantTypeOfHelperCall(arg, context);
12775 }
12776 }
12777 return 0 /* NOT_CONSTANT */;
12778}
12779function getGeneratedPropsConstantType(node, context) {
12780 let returnType = 3 /* CAN_STRINGIFY */;
12781 const props = getNodeProps(node);
12782 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
12783 const { properties } = props;
12784 for (let i = 0; i < properties.length; i++) {
12785 const { key, value } = properties[i];
12786 const keyType = getConstantType(key, context);
12787 if (keyType === 0 /* NOT_CONSTANT */) {
12788 return keyType;
12789 }
12790 if (keyType < returnType) {
12791 returnType = keyType;
12792 }
12793 let valueType;
12794 if (value.type === 4 /* SIMPLE_EXPRESSION */) {
12795 valueType = getConstantType(value, context);
12796 }
12797 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12798 // some helper calls can be hoisted,
12799 // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12800 // in this case we need to respect the ConstantType of the helper's arguments
12801 valueType = getConstantTypeOfHelperCall(value, context);
12802 }
12803 else {
12804 valueType = 0 /* NOT_CONSTANT */;
12805 }
12806 if (valueType === 0 /* NOT_CONSTANT */) {
12807 return valueType;
12808 }
12809 if (valueType < returnType) {
12810 returnType = valueType;
12811 }
12812 }
12813 }
12814 return returnType;
12815}
12816function getNodeProps(node) {
12817 const codegenNode = node.codegenNode;
12818 if (codegenNode.type === 13 /* VNODE_CALL */) {
12819 return codegenNode.props;
12820 }
12821}
12822function getPatchFlag(node) {
12823 const flag = node.patchFlag;
12824 return flag ? parseInt(flag, 10) : undefined;
12825}
12826
12827function 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 }) {
12828 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
12829 const context = {
12830 // options
12831 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
12832 prefixIdentifiers,
12833 hoistStatic,
12834 cacheHandlers,
12835 nodeTransforms,
12836 directiveTransforms,
12837 transformHoist,
12838 isBuiltInComponent,
12839 isCustomElement,
12840 expressionPlugins,
12841 scopeId,
12842 slotted,
12843 ssr,
12844 inSSR,
12845 ssrCssVars,
12846 bindingMetadata,
12847 inline,
12848 isTS,
12849 onError,
12850 onWarn,
12851 compatConfig,
12852 // state
12853 root,
12854 helpers: new Map(),
12855 components: new Set(),
12856 directives: new Set(),
12857 hoists: [],
12858 imports: [],
12859 constantCache: new Map(),
12860 temps: 0,
12861 cached: 0,
12862 identifiers: Object.create(null),
12863 scopes: {
12864 vFor: 0,
12865 vSlot: 0,
12866 vPre: 0,
12867 vOnce: 0
12868 },
12869 parent: null,
12870 currentNode: root,
12871 childIndex: 0,
12872 inVOnce: false,
12873 // methods
12874 helper(name) {
12875 const count = context.helpers.get(name) || 0;
12876 context.helpers.set(name, count + 1);
12877 return name;
12878 },
12879 removeHelper(name) {
12880 const count = context.helpers.get(name);
12881 if (count) {
12882 const currentCount = count - 1;
12883 if (!currentCount) {
12884 context.helpers.delete(name);
12885 }
12886 else {
12887 context.helpers.set(name, currentCount);
12888 }
12889 }
12890 },
12891 helperString(name) {
12892 return `_${helperNameMap[context.helper(name)]}`;
12893 },
12894 replaceNode(node) {
12895 /* istanbul ignore if */
12896 {
12897 if (!context.currentNode) {
12898 throw new Error(`Node being replaced is already removed.`);
12899 }
12900 if (!context.parent) {
12901 throw new Error(`Cannot replace root node.`);
12902 }
12903 }
12904 context.parent.children[context.childIndex] = context.currentNode = node;
12905 },
12906 removeNode(node) {
12907 if (!context.parent) {
12908 throw new Error(`Cannot remove root node.`);
12909 }
12910 const list = context.parent.children;
12911 const removalIndex = node
12912 ? list.indexOf(node)
12913 : context.currentNode
12914 ? context.childIndex
12915 : -1;
12916 /* istanbul ignore if */
12917 if (removalIndex < 0) {
12918 throw new Error(`node being removed is not a child of current parent`);
12919 }
12920 if (!node || node === context.currentNode) {
12921 // current node removed
12922 context.currentNode = null;
12923 context.onNodeRemoved();
12924 }
12925 else {
12926 // sibling node removed
12927 if (context.childIndex > removalIndex) {
12928 context.childIndex--;
12929 context.onNodeRemoved();
12930 }
12931 }
12932 context.parent.children.splice(removalIndex, 1);
12933 },
12934 onNodeRemoved: () => { },
12935 addIdentifiers(exp) {
12936 },
12937 removeIdentifiers(exp) {
12938 },
12939 hoist(exp) {
12940 if (isString(exp))
12941 exp = createSimpleExpression(exp);
12942 context.hoists.push(exp);
12943 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
12944 identifier.hoisted = exp;
12945 return identifier;
12946 },
12947 cache(exp, isVNode = false) {
12948 return createCacheExpression(context.cached++, exp, isVNode);
12949 }
12950 };
12951 return context;
12952}
12953function transform(root, options) {
12954 const context = createTransformContext(root, options);
12955 traverseNode(root, context);
12956 if (options.hoistStatic) {
12957 hoistStatic(root, context);
12958 }
12959 if (!options.ssr) {
12960 createRootCodegen(root, context);
12961 }
12962 // finalize meta information
12963 root.helpers = [...context.helpers.keys()];
12964 root.components = [...context.components];
12965 root.directives = [...context.directives];
12966 root.imports = context.imports;
12967 root.hoists = context.hoists;
12968 root.temps = context.temps;
12969 root.cached = context.cached;
12970}
12971function createRootCodegen(root, context) {
12972 const { helper } = context;
12973 const { children } = root;
12974 if (children.length === 1) {
12975 const child = children[0];
12976 // if the single child is an element, turn it into a block.
12977 if (isSingleElementRoot(root, child) && child.codegenNode) {
12978 // single element root is never hoisted so codegenNode will never be
12979 // SimpleExpressionNode
12980 const codegenNode = child.codegenNode;
12981 if (codegenNode.type === 13 /* VNODE_CALL */) {
12982 makeBlock(codegenNode, context);
12983 }
12984 root.codegenNode = codegenNode;
12985 }
12986 else {
12987 // - single <slot/>, IfNode, ForNode: already blocks.
12988 // - single text node: always patched.
12989 // root codegen falls through via genNode()
12990 root.codegenNode = child;
12991 }
12992 }
12993 else if (children.length > 1) {
12994 // root has multiple nodes - return a fragment block.
12995 let patchFlag = 64 /* STABLE_FRAGMENT */;
12996 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
12997 // check if the fragment actually contains a single valid child with
12998 // the rest being comments
12999 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
13000 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
13001 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
13002 }
13003 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);
13004 }
13005 else ;
13006}
13007function traverseChildren(parent, context) {
13008 let i = 0;
13009 const nodeRemoved = () => {
13010 i--;
13011 };
13012 for (; i < parent.children.length; i++) {
13013 const child = parent.children[i];
13014 if (isString(child))
13015 continue;
13016 context.parent = parent;
13017 context.childIndex = i;
13018 context.onNodeRemoved = nodeRemoved;
13019 traverseNode(child, context);
13020 }
13021}
13022function traverseNode(node, context) {
13023 context.currentNode = node;
13024 // apply transform plugins
13025 const { nodeTransforms } = context;
13026 const exitFns = [];
13027 for (let i = 0; i < nodeTransforms.length; i++) {
13028 const onExit = nodeTransforms[i](node, context);
13029 if (onExit) {
13030 if (isArray(onExit)) {
13031 exitFns.push(...onExit);
13032 }
13033 else {
13034 exitFns.push(onExit);
13035 }
13036 }
13037 if (!context.currentNode) {
13038 // node was removed
13039 return;
13040 }
13041 else {
13042 // node may have been replaced
13043 node = context.currentNode;
13044 }
13045 }
13046 switch (node.type) {
13047 case 3 /* COMMENT */:
13048 if (!context.ssr) {
13049 // inject import for the Comment symbol, which is needed for creating
13050 // comment nodes with `createVNode`
13051 context.helper(CREATE_COMMENT);
13052 }
13053 break;
13054 case 5 /* INTERPOLATION */:
13055 // no need to traverse, but we need to inject toString helper
13056 if (!context.ssr) {
13057 context.helper(TO_DISPLAY_STRING);
13058 }
13059 break;
13060 // for container types, further traverse downwards
13061 case 9 /* IF */:
13062 for (let i = 0; i < node.branches.length; i++) {
13063 traverseNode(node.branches[i], context);
13064 }
13065 break;
13066 case 10 /* IF_BRANCH */:
13067 case 11 /* FOR */:
13068 case 1 /* ELEMENT */:
13069 case 0 /* ROOT */:
13070 traverseChildren(node, context);
13071 break;
13072 }
13073 // exit transforms
13074 context.currentNode = node;
13075 let i = exitFns.length;
13076 while (i--) {
13077 exitFns[i]();
13078 }
13079}
13080function createStructuralDirectiveTransform(name, fn) {
13081 const matches = isString(name)
13082 ? (n) => n === name
13083 : (n) => name.test(n);
13084 return (node, context) => {
13085 if (node.type === 1 /* ELEMENT */) {
13086 const { props } = node;
13087 // structural directive transforms are not concerned with slots
13088 // as they are handled separately in vSlot.ts
13089 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
13090 return;
13091 }
13092 const exitFns = [];
13093 for (let i = 0; i < props.length; i++) {
13094 const prop = props[i];
13095 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
13096 // structural directives are removed to avoid infinite recursion
13097 // also we remove them *before* applying so that it can further
13098 // traverse itself in case it moves the node around
13099 props.splice(i, 1);
13100 i--;
13101 const onExit = fn(node, prop, context);
13102 if (onExit)
13103 exitFns.push(onExit);
13104 }
13105 }
13106 return exitFns;
13107 }
13108 };
13109}
13110
13111const PURE_ANNOTATION = `/*#__PURE__*/`;
13112const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
13113function 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 }) {
13114 const context = {
13115 mode,
13116 prefixIdentifiers,
13117 sourceMap,
13118 filename,
13119 scopeId,
13120 optimizeImports,
13121 runtimeGlobalName,
13122 runtimeModuleName,
13123 ssrRuntimeModuleName,
13124 ssr,
13125 isTS,
13126 inSSR,
13127 source: ast.loc.source,
13128 code: ``,
13129 column: 1,
13130 line: 1,
13131 offset: 0,
13132 indentLevel: 0,
13133 pure: false,
13134 map: undefined,
13135 helper(key) {
13136 return `_${helperNameMap[key]}`;
13137 },
13138 push(code, node) {
13139 context.code += code;
13140 },
13141 indent() {
13142 newline(++context.indentLevel);
13143 },
13144 deindent(withoutNewLine = false) {
13145 if (withoutNewLine) {
13146 --context.indentLevel;
13147 }
13148 else {
13149 newline(--context.indentLevel);
13150 }
13151 },
13152 newline() {
13153 newline(context.indentLevel);
13154 }
13155 };
13156 function newline(n) {
13157 context.push('\n' + ` `.repeat(n));
13158 }
13159 return context;
13160}
13161function generate(ast, options = {}) {
13162 const context = createCodegenContext(ast, options);
13163 if (options.onContextCreated)
13164 options.onContextCreated(context);
13165 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
13166 const hasHelpers = ast.helpers.length > 0;
13167 const useWithBlock = !prefixIdentifiers && mode !== 'module';
13168 // preambles
13169 // in setup() inline mode, the preamble is generated in a sub context
13170 // and returned separately.
13171 const preambleContext = context;
13172 {
13173 genFunctionPreamble(ast, preambleContext);
13174 }
13175 // enter render function
13176 const functionName = ssr ? `ssrRender` : `render`;
13177 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
13178 const signature = args.join(', ');
13179 {
13180 push(`function ${functionName}(${signature}) {`);
13181 }
13182 indent();
13183 if (useWithBlock) {
13184 push(`with (_ctx) {`);
13185 indent();
13186 // function mode const declarations should be inside with block
13187 // also they should be renamed to avoid collision with user properties
13188 if (hasHelpers) {
13189 push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`);
13190 push(`\n`);
13191 newline();
13192 }
13193 }
13194 // generate asset resolution statements
13195 if (ast.components.length) {
13196 genAssets(ast.components, 'component', context);
13197 if (ast.directives.length || ast.temps > 0) {
13198 newline();
13199 }
13200 }
13201 if (ast.directives.length) {
13202 genAssets(ast.directives, 'directive', context);
13203 if (ast.temps > 0) {
13204 newline();
13205 }
13206 }
13207 if (ast.temps > 0) {
13208 push(`let `);
13209 for (let i = 0; i < ast.temps; i++) {
13210 push(`${i > 0 ? `, ` : ``}_temp${i}`);
13211 }
13212 }
13213 if (ast.components.length || ast.directives.length || ast.temps) {
13214 push(`\n`);
13215 newline();
13216 }
13217 // generate the VNode tree expression
13218 if (!ssr) {
13219 push(`return `);
13220 }
13221 if (ast.codegenNode) {
13222 genNode(ast.codegenNode, context);
13223 }
13224 else {
13225 push(`null`);
13226 }
13227 if (useWithBlock) {
13228 deindent();
13229 push(`}`);
13230 }
13231 deindent();
13232 push(`}`);
13233 return {
13234 ast,
13235 code: context.code,
13236 preamble: ``,
13237 // SourceMapGenerator does have toJSON() method but it's not in the types
13238 map: context.map ? context.map.toJSON() : undefined
13239 };
13240}
13241function genFunctionPreamble(ast, context) {
13242 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
13243 const VueBinding = runtimeGlobalName;
13244 // Generate const declaration for helpers
13245 // In prefix mode, we place the const declaration at top so it's done
13246 // only once; But if we not prefixing, we place the declaration inside the
13247 // with block so it doesn't incur the `in` check cost for every helper access.
13248 if (ast.helpers.length > 0) {
13249 {
13250 // "with" mode.
13251 // save Vue in a separate variable to avoid collision
13252 push(`const _Vue = ${VueBinding}\n`);
13253 // in "with" mode, helpers are declared inside the with block to avoid
13254 // has check cost, but hoists are lifted out of the function - we need
13255 // to provide the helper here.
13256 if (ast.hoists.length) {
13257 const staticHelpers = [
13258 CREATE_VNODE,
13259 CREATE_ELEMENT_VNODE,
13260 CREATE_COMMENT,
13261 CREATE_TEXT,
13262 CREATE_STATIC
13263 ]
13264 .filter(helper => ast.helpers.includes(helper))
13265 .map(aliasHelper)
13266 .join(', ');
13267 push(`const { ${staticHelpers} } = _Vue\n`);
13268 }
13269 }
13270 }
13271 genHoists(ast.hoists, context);
13272 newline();
13273 push(`return `);
13274}
13275function genAssets(assets, type, { helper, push, newline, isTS }) {
13276 const resolver = helper(type === 'component'
13277 ? RESOLVE_COMPONENT
13278 : RESOLVE_DIRECTIVE);
13279 for (let i = 0; i < assets.length; i++) {
13280 let id = assets[i];
13281 // potential component implicit self-reference inferred from SFC filename
13282 const maybeSelfReference = id.endsWith('__self');
13283 if (maybeSelfReference) {
13284 id = id.slice(0, -6);
13285 }
13286 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
13287 if (i < assets.length - 1) {
13288 newline();
13289 }
13290 }
13291}
13292function genHoists(hoists, context) {
13293 if (!hoists.length) {
13294 return;
13295 }
13296 context.pure = true;
13297 const { push, newline, helper, scopeId, mode } = context;
13298 newline();
13299 for (let i = 0; i < hoists.length; i++) {
13300 const exp = hoists[i];
13301 if (exp) {
13302 push(`const _hoisted_${i + 1} = ${``}`);
13303 genNode(exp, context);
13304 newline();
13305 }
13306 }
13307 context.pure = false;
13308}
13309function isText$1(n) {
13310 return (isString(n) ||
13311 n.type === 4 /* SIMPLE_EXPRESSION */ ||
13312 n.type === 2 /* TEXT */ ||
13313 n.type === 5 /* INTERPOLATION */ ||
13314 n.type === 8 /* COMPOUND_EXPRESSION */);
13315}
13316function genNodeListAsArray(nodes, context) {
13317 const multilines = nodes.length > 3 ||
13318 (nodes.some(n => isArray(n) || !isText$1(n)));
13319 context.push(`[`);
13320 multilines && context.indent();
13321 genNodeList(nodes, context, multilines);
13322 multilines && context.deindent();
13323 context.push(`]`);
13324}
13325function genNodeList(nodes, context, multilines = false, comma = true) {
13326 const { push, newline } = context;
13327 for (let i = 0; i < nodes.length; i++) {
13328 const node = nodes[i];
13329 if (isString(node)) {
13330 push(node);
13331 }
13332 else if (isArray(node)) {
13333 genNodeListAsArray(node, context);
13334 }
13335 else {
13336 genNode(node, context);
13337 }
13338 if (i < nodes.length - 1) {
13339 if (multilines) {
13340 comma && push(',');
13341 newline();
13342 }
13343 else {
13344 comma && push(', ');
13345 }
13346 }
13347 }
13348}
13349function genNode(node, context) {
13350 if (isString(node)) {
13351 context.push(node);
13352 return;
13353 }
13354 if (isSymbol(node)) {
13355 context.push(context.helper(node));
13356 return;
13357 }
13358 switch (node.type) {
13359 case 1 /* ELEMENT */:
13360 case 9 /* IF */:
13361 case 11 /* FOR */:
13362 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
13363 `Apply appropriate transforms first.`);
13364 genNode(node.codegenNode, context);
13365 break;
13366 case 2 /* TEXT */:
13367 genText(node, context);
13368 break;
13369 case 4 /* SIMPLE_EXPRESSION */:
13370 genExpression(node, context);
13371 break;
13372 case 5 /* INTERPOLATION */:
13373 genInterpolation(node, context);
13374 break;
13375 case 12 /* TEXT_CALL */:
13376 genNode(node.codegenNode, context);
13377 break;
13378 case 8 /* COMPOUND_EXPRESSION */:
13379 genCompoundExpression(node, context);
13380 break;
13381 case 3 /* COMMENT */:
13382 genComment(node, context);
13383 break;
13384 case 13 /* VNODE_CALL */:
13385 genVNodeCall(node, context);
13386 break;
13387 case 14 /* JS_CALL_EXPRESSION */:
13388 genCallExpression(node, context);
13389 break;
13390 case 15 /* JS_OBJECT_EXPRESSION */:
13391 genObjectExpression(node, context);
13392 break;
13393 case 17 /* JS_ARRAY_EXPRESSION */:
13394 genArrayExpression(node, context);
13395 break;
13396 case 18 /* JS_FUNCTION_EXPRESSION */:
13397 genFunctionExpression(node, context);
13398 break;
13399 case 19 /* JS_CONDITIONAL_EXPRESSION */:
13400 genConditionalExpression(node, context);
13401 break;
13402 case 20 /* JS_CACHE_EXPRESSION */:
13403 genCacheExpression(node, context);
13404 break;
13405 case 21 /* JS_BLOCK_STATEMENT */:
13406 genNodeList(node.body, context, true, false);
13407 break;
13408 // SSR only types
13409 case 22 /* JS_TEMPLATE_LITERAL */:
13410 break;
13411 case 23 /* JS_IF_STATEMENT */:
13412 break;
13413 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
13414 break;
13415 case 25 /* JS_SEQUENCE_EXPRESSION */:
13416 break;
13417 case 26 /* JS_RETURN_STATEMENT */:
13418 break;
13419 /* istanbul ignore next */
13420 case 10 /* IF_BRANCH */:
13421 // noop
13422 break;
13423 default:
13424 {
13425 assert(false, `unhandled codegen node type: ${node.type}`);
13426 // make sure we exhaust all possible types
13427 const exhaustiveCheck = node;
13428 return exhaustiveCheck;
13429 }
13430 }
13431}
13432function genText(node, context) {
13433 context.push(JSON.stringify(node.content), node);
13434}
13435function genExpression(node, context) {
13436 const { content, isStatic } = node;
13437 context.push(isStatic ? JSON.stringify(content) : content, node);
13438}
13439function genInterpolation(node, context) {
13440 const { push, helper, pure } = context;
13441 if (pure)
13442 push(PURE_ANNOTATION);
13443 push(`${helper(TO_DISPLAY_STRING)}(`);
13444 genNode(node.content, context);
13445 push(`)`);
13446}
13447function genCompoundExpression(node, context) {
13448 for (let i = 0; i < node.children.length; i++) {
13449 const child = node.children[i];
13450 if (isString(child)) {
13451 context.push(child);
13452 }
13453 else {
13454 genNode(child, context);
13455 }
13456 }
13457}
13458function genExpressionAsPropertyKey(node, context) {
13459 const { push } = context;
13460 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
13461 push(`[`);
13462 genCompoundExpression(node, context);
13463 push(`]`);
13464 }
13465 else if (node.isStatic) {
13466 // only quote keys if necessary
13467 const text = isSimpleIdentifier(node.content)
13468 ? node.content
13469 : JSON.stringify(node.content);
13470 push(text, node);
13471 }
13472 else {
13473 push(`[${node.content}]`, node);
13474 }
13475}
13476function genComment(node, context) {
13477 const { push, helper, pure } = context;
13478 if (pure) {
13479 push(PURE_ANNOTATION);
13480 }
13481 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
13482}
13483function genVNodeCall(node, context) {
13484 const { push, helper, pure } = context;
13485 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
13486 if (directives) {
13487 push(helper(WITH_DIRECTIVES) + `(`);
13488 }
13489 if (isBlock) {
13490 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
13491 }
13492 if (pure) {
13493 push(PURE_ANNOTATION);
13494 }
13495 const callHelper = isBlock
13496 ? getVNodeBlockHelper(context.inSSR, isComponent)
13497 : getVNodeHelper(context.inSSR, isComponent);
13498 push(helper(callHelper) + `(`, node);
13499 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
13500 push(`)`);
13501 if (isBlock) {
13502 push(`)`);
13503 }
13504 if (directives) {
13505 push(`, `);
13506 genNode(directives, context);
13507 push(`)`);
13508 }
13509}
13510function genNullableArgs(args) {
13511 let i = args.length;
13512 while (i--) {
13513 if (args[i] != null)
13514 break;
13515 }
13516 return args.slice(0, i + 1).map(arg => arg || `null`);
13517}
13518// JavaScript
13519function genCallExpression(node, context) {
13520 const { push, helper, pure } = context;
13521 const callee = isString(node.callee) ? node.callee : helper(node.callee);
13522 if (pure) {
13523 push(PURE_ANNOTATION);
13524 }
13525 push(callee + `(`, node);
13526 genNodeList(node.arguments, context);
13527 push(`)`);
13528}
13529function genObjectExpression(node, context) {
13530 const { push, indent, deindent, newline } = context;
13531 const { properties } = node;
13532 if (!properties.length) {
13533 push(`{}`, node);
13534 return;
13535 }
13536 const multilines = properties.length > 1 ||
13537 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
13538 push(multilines ? `{` : `{ `);
13539 multilines && indent();
13540 for (let i = 0; i < properties.length; i++) {
13541 const { key, value } = properties[i];
13542 // key
13543 genExpressionAsPropertyKey(key, context);
13544 push(`: `);
13545 // value
13546 genNode(value, context);
13547 if (i < properties.length - 1) {
13548 // will only reach this if it's multilines
13549 push(`,`);
13550 newline();
13551 }
13552 }
13553 multilines && deindent();
13554 push(multilines ? `}` : ` }`);
13555}
13556function genArrayExpression(node, context) {
13557 genNodeListAsArray(node.elements, context);
13558}
13559function genFunctionExpression(node, context) {
13560 const { push, indent, deindent } = context;
13561 const { params, returns, body, newline, isSlot } = node;
13562 if (isSlot) {
13563 // wrap slot functions with owner context
13564 push(`_${helperNameMap[WITH_CTX]}(`);
13565 }
13566 push(`(`, node);
13567 if (isArray(params)) {
13568 genNodeList(params, context);
13569 }
13570 else if (params) {
13571 genNode(params, context);
13572 }
13573 push(`) => `);
13574 if (newline || body) {
13575 push(`{`);
13576 indent();
13577 }
13578 if (returns) {
13579 if (newline) {
13580 push(`return `);
13581 }
13582 if (isArray(returns)) {
13583 genNodeListAsArray(returns, context);
13584 }
13585 else {
13586 genNode(returns, context);
13587 }
13588 }
13589 else if (body) {
13590 genNode(body, context);
13591 }
13592 if (newline || body) {
13593 deindent();
13594 push(`}`);
13595 }
13596 if (isSlot) {
13597 push(`)`);
13598 }
13599}
13600function genConditionalExpression(node, context) {
13601 const { test, consequent, alternate, newline: needNewline } = node;
13602 const { push, indent, deindent, newline } = context;
13603 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
13604 const needsParens = !isSimpleIdentifier(test.content);
13605 needsParens && push(`(`);
13606 genExpression(test, context);
13607 needsParens && push(`)`);
13608 }
13609 else {
13610 push(`(`);
13611 genNode(test, context);
13612 push(`)`);
13613 }
13614 needNewline && indent();
13615 context.indentLevel++;
13616 needNewline || push(` `);
13617 push(`? `);
13618 genNode(consequent, context);
13619 context.indentLevel--;
13620 needNewline && newline();
13621 needNewline || push(` `);
13622 push(`: `);
13623 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
13624 if (!isNested) {
13625 context.indentLevel++;
13626 }
13627 genNode(alternate, context);
13628 if (!isNested) {
13629 context.indentLevel--;
13630 }
13631 needNewline && deindent(true /* without newline */);
13632}
13633function genCacheExpression(node, context) {
13634 const { push, helper, indent, deindent, newline } = context;
13635 push(`_cache[${node.index}] || (`);
13636 if (node.isVNode) {
13637 indent();
13638 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
13639 newline();
13640 }
13641 push(`_cache[${node.index}] = `);
13642 genNode(node.value, context);
13643 if (node.isVNode) {
13644 push(`,`);
13645 newline();
13646 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
13647 newline();
13648 push(`_cache[${node.index}]`);
13649 deindent();
13650 }
13651 push(`)`);
13652}
13653
13654// these keywords should not appear inside expressions, but operators like
13655// typeof, instanceof and in are allowed
13656const prohibitedKeywordRE = new RegExp('\\b' +
13657 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
13658 'super,throw,while,yield,delete,export,import,return,switch,default,' +
13659 'extends,finally,continue,debugger,function,arguments,typeof,void')
13660 .split(',')
13661 .join('\\b|\\b') +
13662 '\\b');
13663// strip strings in expressions
13664const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
13665/**
13666 * Validate a non-prefixed expression.
13667 * This is only called when using the in-browser runtime compiler since it
13668 * doesn't prefix expressions.
13669 */
13670function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
13671 const exp = node.content;
13672 // empty expressions are validated per-directive since some directives
13673 // do allow empty expressions.
13674 if (!exp.trim()) {
13675 return;
13676 }
13677 try {
13678 new Function(asRawStatements
13679 ? ` ${exp} `
13680 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
13681 }
13682 catch (e) {
13683 let message = e.message;
13684 const keywordMatch = exp
13685 .replace(stripStringRE, '')
13686 .match(prohibitedKeywordRE);
13687 if (keywordMatch) {
13688 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
13689 }
13690 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
13691 }
13692}
13693
13694const transformExpression = (node, context) => {
13695 if (node.type === 5 /* INTERPOLATION */) {
13696 node.content = processExpression(node.content, context);
13697 }
13698 else if (node.type === 1 /* ELEMENT */) {
13699 // handle directives on element
13700 for (let i = 0; i < node.props.length; i++) {
13701 const dir = node.props[i];
13702 // do not process for v-on & v-for since they are special handled
13703 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
13704 const exp = dir.exp;
13705 const arg = dir.arg;
13706 // do not process exp if this is v-on:arg - we need special handling
13707 // for wrapping inline statements.
13708 if (exp &&
13709 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
13710 !(dir.name === 'on' && arg)) {
13711 dir.exp = processExpression(exp, context,
13712 // slot args must be processed as function params
13713 dir.name === 'slot');
13714 }
13715 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
13716 dir.arg = processExpression(arg, context);
13717 }
13718 }
13719 }
13720 }
13721};
13722// Important: since this function uses Node.js only dependencies, it should
13723// always be used with a leading !true check so that it can be
13724// tree-shaken from the browser build.
13725function processExpression(node, context,
13726// some expressions like v-slot props & v-for aliases should be parsed as
13727// function params
13728asParams = false,
13729// v-on handler values may contain multiple statements
13730asRawStatements = false, localVars = Object.create(context.identifiers)) {
13731 {
13732 {
13733 // simple in-browser validation (same logic in 2.x)
13734 validateBrowserExpression(node, context, asParams, asRawStatements);
13735 }
13736 return node;
13737 }
13738}
13739
13740const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
13741 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
13742 // #1587: We need to dynamically increment the key based on the current
13743 // node's sibling nodes, since chained v-if/else branches are
13744 // rendered at the same depth
13745 const siblings = context.parent.children;
13746 let i = siblings.indexOf(ifNode);
13747 let key = 0;
13748 while (i-- >= 0) {
13749 const sibling = siblings[i];
13750 if (sibling && sibling.type === 9 /* IF */) {
13751 key += sibling.branches.length;
13752 }
13753 }
13754 // Exit callback. Complete the codegenNode when all children have been
13755 // transformed.
13756 return () => {
13757 if (isRoot) {
13758 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
13759 }
13760 else {
13761 // attach this branch's codegen node to the v-if root.
13762 const parentCondition = getParentCondition(ifNode.codegenNode);
13763 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
13764 }
13765 };
13766 });
13767});
13768// target-agnostic transform used for both Client and SSR
13769function processIf(node, dir, context, processCodegen) {
13770 if (dir.name !== 'else' &&
13771 (!dir.exp || !dir.exp.content.trim())) {
13772 const loc = dir.exp ? dir.exp.loc : node.loc;
13773 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));
13774 dir.exp = createSimpleExpression(`true`, false, loc);
13775 }
13776 if (dir.exp) {
13777 validateBrowserExpression(dir.exp, context);
13778 }
13779 if (dir.name === 'if') {
13780 const branch = createIfBranch(node, dir);
13781 const ifNode = {
13782 type: 9 /* IF */,
13783 loc: node.loc,
13784 branches: [branch]
13785 };
13786 context.replaceNode(ifNode);
13787 if (processCodegen) {
13788 return processCodegen(ifNode, branch, true);
13789 }
13790 }
13791 else {
13792 // locate the adjacent v-if
13793 const siblings = context.parent.children;
13794 const comments = [];
13795 let i = siblings.indexOf(node);
13796 while (i-- >= -1) {
13797 const sibling = siblings[i];
13798 if (sibling && sibling.type === 3 /* COMMENT */) {
13799 context.removeNode(sibling);
13800 comments.unshift(sibling);
13801 continue;
13802 }
13803 if (sibling &&
13804 sibling.type === 2 /* TEXT */ &&
13805 !sibling.content.trim().length) {
13806 context.removeNode(sibling);
13807 continue;
13808 }
13809 if (sibling && sibling.type === 9 /* IF */) {
13810 // Check if v-else was followed by v-else-if
13811 if (dir.name === 'else-if' &&
13812 sibling.branches[sibling.branches.length - 1].condition === undefined) {
13813 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13814 }
13815 // move the node to the if node's branches
13816 context.removeNode();
13817 const branch = createIfBranch(node, dir);
13818 if (comments.length &&
13819 // #3619 ignore comments if the v-if is direct child of <transition>
13820 !(context.parent &&
13821 context.parent.type === 1 /* ELEMENT */ &&
13822 isBuiltInType(context.parent.tag, 'transition'))) {
13823 branch.children = [...comments, ...branch.children];
13824 }
13825 // check if user is forcing same key on different branches
13826 {
13827 const key = branch.userKey;
13828 if (key) {
13829 sibling.branches.forEach(({ userKey }) => {
13830 if (isSameKey(userKey, key)) {
13831 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
13832 }
13833 });
13834 }
13835 }
13836 sibling.branches.push(branch);
13837 const onExit = processCodegen && processCodegen(sibling, branch, false);
13838 // since the branch was removed, it will not be traversed.
13839 // make sure to traverse here.
13840 traverseNode(branch, context);
13841 // call on exit
13842 if (onExit)
13843 onExit();
13844 // make sure to reset currentNode after traversal to indicate this
13845 // node has been removed.
13846 context.currentNode = null;
13847 }
13848 else {
13849 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13850 }
13851 break;
13852 }
13853 }
13854}
13855function createIfBranch(node, dir) {
13856 const isTemplateIf = node.tagType === 3 /* TEMPLATE */;
13857 return {
13858 type: 10 /* IF_BRANCH */,
13859 loc: node.loc,
13860 condition: dir.name === 'else' ? undefined : dir.exp,
13861 children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
13862 userKey: findProp(node, `key`),
13863 isTemplateIf
13864 };
13865}
13866function createCodegenNodeForBranch(branch, keyIndex, context) {
13867 if (branch.condition) {
13868 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
13869 // make sure to pass in asBlock: true so that the comment node call
13870 // closes the current block.
13871 createCallExpression(context.helper(CREATE_COMMENT), [
13872 '"v-if"' ,
13873 'true'
13874 ]));
13875 }
13876 else {
13877 return createChildrenCodegenNode(branch, keyIndex, context);
13878 }
13879}
13880function createChildrenCodegenNode(branch, keyIndex, context) {
13881 const { helper } = context;
13882 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
13883 const { children } = branch;
13884 const firstChild = children[0];
13885 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
13886 if (needFragmentWrapper) {
13887 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
13888 // optimize away nested fragments when child is a ForNode
13889 const vnodeCall = firstChild.codegenNode;
13890 injectProp(vnodeCall, keyProperty, context);
13891 return vnodeCall;
13892 }
13893 else {
13894 let patchFlag = 64 /* STABLE_FRAGMENT */;
13895 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
13896 // check if the fragment actually contains a single valid child with
13897 // the rest being comments
13898 if (!branch.isTemplateIf &&
13899 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
13900 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
13901 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
13902 }
13903 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);
13904 }
13905 }
13906 else {
13907 const ret = firstChild.codegenNode;
13908 const vnodeCall = getMemoedVNodeCall(ret);
13909 // Change createVNode to createBlock.
13910 if (vnodeCall.type === 13 /* VNODE_CALL */) {
13911 makeBlock(vnodeCall, context);
13912 }
13913 // inject branch key
13914 injectProp(vnodeCall, keyProperty, context);
13915 return ret;
13916 }
13917}
13918function isSameKey(a, b) {
13919 if (!a || a.type !== b.type) {
13920 return false;
13921 }
13922 if (a.type === 6 /* ATTRIBUTE */) {
13923 if (a.value.content !== b.value.content) {
13924 return false;
13925 }
13926 }
13927 else {
13928 // directive
13929 const exp = a.exp;
13930 const branchExp = b.exp;
13931 if (exp.type !== branchExp.type) {
13932 return false;
13933 }
13934 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
13935 exp.isStatic !== branchExp.isStatic ||
13936 exp.content !== branchExp.content) {
13937 return false;
13938 }
13939 }
13940 return true;
13941}
13942function getParentCondition(node) {
13943 while (true) {
13944 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13945 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13946 node = node.alternate;
13947 }
13948 else {
13949 return node;
13950 }
13951 }
13952 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
13953 node = node.value;
13954 }
13955 }
13956}
13957
13958const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
13959 const { helper, removeHelper } = context;
13960 return processFor(node, dir, context, forNode => {
13961 // create the loop render function expression now, and add the
13962 // iterator on exit after all children have been traversed
13963 const renderExp = createCallExpression(helper(RENDER_LIST), [
13964 forNode.source
13965 ]);
13966 const isTemplate = isTemplateNode(node);
13967 const memo = findDir(node, 'memo');
13968 const keyProp = findProp(node, `key`);
13969 const keyExp = keyProp &&
13970 (keyProp.type === 6 /* ATTRIBUTE */
13971 ? createSimpleExpression(keyProp.value.content, true)
13972 : keyProp.exp);
13973 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
13974 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
13975 forNode.source.constType > 0 /* NOT_CONSTANT */;
13976 const fragmentFlag = isStableFragment
13977 ? 64 /* STABLE_FRAGMENT */
13978 : keyProp
13979 ? 128 /* KEYED_FRAGMENT */
13980 : 256 /* UNKEYED_FRAGMENT */;
13981 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
13982 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
13983 return () => {
13984 // finish the codegen now that all children have been traversed
13985 let childBlock;
13986 const { children } = forNode;
13987 // check <template v-for> key placement
13988 if (isTemplate) {
13989 node.children.some(c => {
13990 if (c.type === 1 /* ELEMENT */) {
13991 const key = findProp(c, 'key');
13992 if (key) {
13993 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
13994 return true;
13995 }
13996 }
13997 });
13998 }
13999 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
14000 const slotOutlet = isSlotOutlet(node)
14001 ? node
14002 : isTemplate &&
14003 node.children.length === 1 &&
14004 isSlotOutlet(node.children[0])
14005 ? node.children[0] // api-extractor somehow fails to infer this
14006 : null;
14007 if (slotOutlet) {
14008 // <slot v-for="..."> or <template v-for="..."><slot/></template>
14009 childBlock = slotOutlet.codegenNode;
14010 if (isTemplate && keyProperty) {
14011 // <template v-for="..." :key="..."><slot/></template>
14012 // we need to inject the key to the renderSlot() call.
14013 // the props for renderSlot is passed as the 3rd argument.
14014 injectProp(childBlock, keyProperty, context);
14015 }
14016 }
14017 else if (needFragmentWrapper) {
14018 // <template v-for="..."> with text or multi-elements
14019 // should generate a fragment block for each loop
14020 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
14021 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
14022 ), undefined, undefined, true, undefined, false /* isComponent */);
14023 }
14024 else {
14025 // Normal element v-for. Directly use the child's codegenNode
14026 // but mark it as a block.
14027 childBlock = children[0]
14028 .codegenNode;
14029 if (isTemplate && keyProperty) {
14030 injectProp(childBlock, keyProperty, context);
14031 }
14032 if (childBlock.isBlock !== !isStableFragment) {
14033 if (childBlock.isBlock) {
14034 // switch from block to vnode
14035 removeHelper(OPEN_BLOCK);
14036 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14037 }
14038 else {
14039 // switch from vnode to block
14040 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14041 }
14042 }
14043 childBlock.isBlock = !isStableFragment;
14044 if (childBlock.isBlock) {
14045 helper(OPEN_BLOCK);
14046 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14047 }
14048 else {
14049 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14050 }
14051 }
14052 if (memo) {
14053 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
14054 createSimpleExpression(`_cached`)
14055 ]));
14056 loop.body = createBlockStatement([
14057 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
14058 createCompoundExpression([
14059 `if (_cached`,
14060 ...(keyExp ? [` && _cached.key === `, keyExp] : []),
14061 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
14062 ]),
14063 createCompoundExpression([`const _item = `, childBlock]),
14064 createSimpleExpression(`_item.memo = _memo`),
14065 createSimpleExpression(`return _item`)
14066 ]);
14067 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
14068 }
14069 else {
14070 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
14071 }
14072 };
14073 });
14074});
14075// target-agnostic transform used for both Client and SSR
14076function processFor(node, dir, context, processCodegen) {
14077 if (!dir.exp) {
14078 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
14079 return;
14080 }
14081 const parseResult = parseForExpression(
14082 // can only be simple expression because vFor transform is applied
14083 // before expression transform.
14084 dir.exp, context);
14085 if (!parseResult) {
14086 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
14087 return;
14088 }
14089 const { addIdentifiers, removeIdentifiers, scopes } = context;
14090 const { source, value, key, index } = parseResult;
14091 const forNode = {
14092 type: 11 /* FOR */,
14093 loc: dir.loc,
14094 source,
14095 valueAlias: value,
14096 keyAlias: key,
14097 objectIndexAlias: index,
14098 parseResult,
14099 children: isTemplateNode(node) ? node.children : [node]
14100 };
14101 context.replaceNode(forNode);
14102 // bookkeeping
14103 scopes.vFor++;
14104 const onExit = processCodegen && processCodegen(forNode);
14105 return () => {
14106 scopes.vFor--;
14107 if (onExit)
14108 onExit();
14109 };
14110}
14111const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
14112// This regex doesn't cover the case if key or index aliases have destructuring,
14113// but those do not make sense in the first place, so this works in practice.
14114const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
14115const stripParensRE = /^\(|\)$/g;
14116function parseForExpression(input, context) {
14117 const loc = input.loc;
14118 const exp = input.content;
14119 const inMatch = exp.match(forAliasRE);
14120 if (!inMatch)
14121 return;
14122 const [, LHS, RHS] = inMatch;
14123 const result = {
14124 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
14125 value: undefined,
14126 key: undefined,
14127 index: undefined
14128 };
14129 {
14130 validateBrowserExpression(result.source, context);
14131 }
14132 let valueContent = LHS.trim().replace(stripParensRE, '').trim();
14133 const trimmedOffset = LHS.indexOf(valueContent);
14134 const iteratorMatch = valueContent.match(forIteratorRE);
14135 if (iteratorMatch) {
14136 valueContent = valueContent.replace(forIteratorRE, '').trim();
14137 const keyContent = iteratorMatch[1].trim();
14138 let keyOffset;
14139 if (keyContent) {
14140 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
14141 result.key = createAliasExpression(loc, keyContent, keyOffset);
14142 {
14143 validateBrowserExpression(result.key, context, true);
14144 }
14145 }
14146 if (iteratorMatch[2]) {
14147 const indexContent = iteratorMatch[2].trim();
14148 if (indexContent) {
14149 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
14150 ? keyOffset + keyContent.length
14151 : trimmedOffset + valueContent.length));
14152 {
14153 validateBrowserExpression(result.index, context, true);
14154 }
14155 }
14156 }
14157 }
14158 if (valueContent) {
14159 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
14160 {
14161 validateBrowserExpression(result.value, context, true);
14162 }
14163 }
14164 return result;
14165}
14166function createAliasExpression(range, content, offset) {
14167 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
14168}
14169function createForLoopParams({ value, key, index }, memoArgs = []) {
14170 return createParamsList([value, key, index, ...memoArgs]);
14171}
14172function createParamsList(args) {
14173 let i = args.length;
14174 while (i--) {
14175 if (args[i])
14176 break;
14177 }
14178 return args
14179 .slice(0, i + 1)
14180 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
14181}
14182
14183const defaultFallback = createSimpleExpression(`undefined`, false);
14184// A NodeTransform that:
14185// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
14186// by transformExpression. This is only applied in non-browser builds with
14187// { prefixIdentifiers: true }.
14188// 2. Track v-slot depths so that we know a slot is inside another slot.
14189// Note the exit callback is executed before buildSlots() on the same node,
14190// so only nested slots see positive numbers.
14191const trackSlotScopes = (node, context) => {
14192 if (node.type === 1 /* ELEMENT */ &&
14193 (node.tagType === 1 /* COMPONENT */ ||
14194 node.tagType === 3 /* TEMPLATE */)) {
14195 // We are only checking non-empty v-slot here
14196 // since we only care about slots that introduce scope variables.
14197 const vSlot = findDir(node, 'slot');
14198 if (vSlot) {
14199 vSlot.exp;
14200 context.scopes.vSlot++;
14201 return () => {
14202 context.scopes.vSlot--;
14203 };
14204 }
14205 }
14206};
14207const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
14208// Instead of being a DirectiveTransform, v-slot processing is called during
14209// transformElement to build the slots object for a component.
14210function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
14211 context.helper(WITH_CTX);
14212 const { children, loc } = node;
14213 const slotsProperties = [];
14214 const dynamicSlots = [];
14215 // If the slot is inside a v-for or another v-slot, force it to be dynamic
14216 // since it likely uses a scope variable.
14217 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
14218 // 1. Check for slot with slotProps on component itself.
14219 // <Comp v-slot="{ prop }"/>
14220 const onComponentSlot = findDir(node, 'slot', true);
14221 if (onComponentSlot) {
14222 const { arg, exp } = onComponentSlot;
14223 if (arg && !isStaticExp(arg)) {
14224 hasDynamicSlots = true;
14225 }
14226 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
14227 }
14228 // 2. Iterate through children and check for template slots
14229 // <template v-slot:foo="{ prop }">
14230 let hasTemplateSlots = false;
14231 let hasNamedDefaultSlot = false;
14232 const implicitDefaultChildren = [];
14233 const seenSlotNames = new Set();
14234 for (let i = 0; i < children.length; i++) {
14235 const slotElement = children[i];
14236 let slotDir;
14237 if (!isTemplateNode(slotElement) ||
14238 !(slotDir = findDir(slotElement, 'slot', true))) {
14239 // not a <template v-slot>, skip.
14240 if (slotElement.type !== 3 /* COMMENT */) {
14241 implicitDefaultChildren.push(slotElement);
14242 }
14243 continue;
14244 }
14245 if (onComponentSlot) {
14246 // already has on-component slot - this is incorrect usage.
14247 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
14248 break;
14249 }
14250 hasTemplateSlots = true;
14251 const { children: slotChildren, loc: slotLoc } = slotElement;
14252 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
14253 // check if name is dynamic.
14254 let staticSlotName;
14255 if (isStaticExp(slotName)) {
14256 staticSlotName = slotName ? slotName.content : `default`;
14257 }
14258 else {
14259 hasDynamicSlots = true;
14260 }
14261 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
14262 // check if this slot is conditional (v-if/v-for)
14263 let vIf;
14264 let vElse;
14265 let vFor;
14266 if ((vIf = findDir(slotElement, 'if'))) {
14267 hasDynamicSlots = true;
14268 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
14269 }
14270 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
14271 // find adjacent v-if
14272 let j = i;
14273 let prev;
14274 while (j--) {
14275 prev = children[j];
14276 if (prev.type !== 3 /* COMMENT */) {
14277 break;
14278 }
14279 }
14280 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
14281 // remove node
14282 children.splice(i, 1);
14283 i--;
14284 // attach this slot to previous conditional
14285 let conditional = dynamicSlots[dynamicSlots.length - 1];
14286 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
14287 conditional = conditional.alternate;
14288 }
14289 conditional.alternate = vElse.exp
14290 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
14291 : buildDynamicSlot(slotName, slotFunction);
14292 }
14293 else {
14294 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
14295 }
14296 }
14297 else if ((vFor = findDir(slotElement, 'for'))) {
14298 hasDynamicSlots = true;
14299 const parseResult = vFor.parseResult ||
14300 parseForExpression(vFor.exp, context);
14301 if (parseResult) {
14302 // Render the dynamic slots as an array and add it to the createSlot()
14303 // args. The runtime knows how to handle it appropriately.
14304 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
14305 parseResult.source,
14306 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
14307 ]));
14308 }
14309 else {
14310 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
14311 }
14312 }
14313 else {
14314 // check duplicate static names
14315 if (staticSlotName) {
14316 if (seenSlotNames.has(staticSlotName)) {
14317 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
14318 continue;
14319 }
14320 seenSlotNames.add(staticSlotName);
14321 if (staticSlotName === 'default') {
14322 hasNamedDefaultSlot = true;
14323 }
14324 }
14325 slotsProperties.push(createObjectProperty(slotName, slotFunction));
14326 }
14327 }
14328 if (!onComponentSlot) {
14329 const buildDefaultSlotProperty = (props, children) => {
14330 const fn = buildSlotFn(props, children, loc);
14331 return createObjectProperty(`default`, fn);
14332 };
14333 if (!hasTemplateSlots) {
14334 // implicit default slot (on component)
14335 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
14336 }
14337 else if (implicitDefaultChildren.length &&
14338 // #3766
14339 // with whitespace: 'preserve', whitespaces between slots will end up in
14340 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
14341 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
14342 // implicit default slot (mixed with named slots)
14343 if (hasNamedDefaultSlot) {
14344 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
14345 }
14346 else {
14347 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
14348 }
14349 }
14350 }
14351 const slotFlag = hasDynamicSlots
14352 ? 2 /* DYNAMIC */
14353 : hasForwardedSlots(node.children)
14354 ? 3 /* FORWARDED */
14355 : 1 /* STABLE */;
14356 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
14357 // 2 = compiled but dynamic = can skip normalization, but must run diff
14358 // 1 = compiled and static = can skip normalization AND diff as optimized
14359 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
14360 if (dynamicSlots.length) {
14361 slots = createCallExpression(context.helper(CREATE_SLOTS), [
14362 slots,
14363 createArrayExpression(dynamicSlots)
14364 ]);
14365 }
14366 return {
14367 slots,
14368 hasDynamicSlots
14369 };
14370}
14371function buildDynamicSlot(name, fn) {
14372 return createObjectExpression([
14373 createObjectProperty(`name`, name),
14374 createObjectProperty(`fn`, fn)
14375 ]);
14376}
14377function hasForwardedSlots(children) {
14378 for (let i = 0; i < children.length; i++) {
14379 const child = children[i];
14380 switch (child.type) {
14381 case 1 /* ELEMENT */:
14382 if (child.tagType === 2 /* SLOT */ ||
14383 hasForwardedSlots(child.children)) {
14384 return true;
14385 }
14386 break;
14387 case 9 /* IF */:
14388 if (hasForwardedSlots(child.branches))
14389 return true;
14390 break;
14391 case 10 /* IF_BRANCH */:
14392 case 11 /* FOR */:
14393 if (hasForwardedSlots(child.children))
14394 return true;
14395 break;
14396 }
14397 }
14398 return false;
14399}
14400function isNonWhitespaceContent(node) {
14401 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
14402 return true;
14403 return node.type === 2 /* TEXT */
14404 ? !!node.content.trim()
14405 : isNonWhitespaceContent(node.content);
14406}
14407
14408// some directive transforms (e.g. v-model) may return a symbol for runtime
14409// import, which should be used instead of a resolveDirective call.
14410const directiveImportMap = new WeakMap();
14411// generate a JavaScript AST for this element's codegen
14412const transformElement = (node, context) => {
14413 // perform the work on exit, after all child expressions have been
14414 // processed and merged.
14415 return function postTransformElement() {
14416 node = context.currentNode;
14417 if (!(node.type === 1 /* ELEMENT */ &&
14418 (node.tagType === 0 /* ELEMENT */ ||
14419 node.tagType === 1 /* COMPONENT */))) {
14420 return;
14421 }
14422 const { tag, props } = node;
14423 const isComponent = node.tagType === 1 /* COMPONENT */;
14424 // The goal of the transform is to create a codegenNode implementing the
14425 // VNodeCall interface.
14426 let vnodeTag = isComponent
14427 ? resolveComponentType(node, context)
14428 : `"${tag}"`;
14429 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
14430 let vnodeProps;
14431 let vnodeChildren;
14432 let vnodePatchFlag;
14433 let patchFlag = 0;
14434 let vnodeDynamicProps;
14435 let dynamicPropNames;
14436 let vnodeDirectives;
14437 let shouldUseBlock =
14438 // dynamic component may resolve to plain elements
14439 isDynamicComponent ||
14440 vnodeTag === TELEPORT ||
14441 vnodeTag === SUSPENSE ||
14442 (!isComponent &&
14443 // <svg> and <foreignObject> must be forced into blocks so that block
14444 // updates inside get proper isSVG flag at runtime. (#639, #643)
14445 // This is technically web-specific, but splitting the logic out of core
14446 // leads to too much unnecessary complexity.
14447 (tag === 'svg' || tag === 'foreignObject'));
14448 // props
14449 if (props.length > 0) {
14450 const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
14451 vnodeProps = propsBuildResult.props;
14452 patchFlag = propsBuildResult.patchFlag;
14453 dynamicPropNames = propsBuildResult.dynamicPropNames;
14454 const directives = propsBuildResult.directives;
14455 vnodeDirectives =
14456 directives && directives.length
14457 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14458 : undefined;
14459 if (propsBuildResult.shouldUseBlock) {
14460 shouldUseBlock = true;
14461 }
14462 }
14463 // children
14464 if (node.children.length > 0) {
14465 if (vnodeTag === KEEP_ALIVE) {
14466 // Although a built-in component, we compile KeepAlive with raw children
14467 // instead of slot functions so that it can be used inside Transition
14468 // or other Transition-wrapping HOCs.
14469 // To ensure correct updates with block optimizations, we need to:
14470 // 1. Force keep-alive into a block. This avoids its children being
14471 // collected by a parent block.
14472 shouldUseBlock = true;
14473 // 2. Force keep-alive to always be updated, since it uses raw children.
14474 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14475 if (node.children.length > 1) {
14476 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
14477 start: node.children[0].loc.start,
14478 end: node.children[node.children.length - 1].loc.end,
14479 source: ''
14480 }));
14481 }
14482 }
14483 const shouldBuildAsSlots = isComponent &&
14484 // Teleport is not a real component and has dedicated runtime handling
14485 vnodeTag !== TELEPORT &&
14486 // explained above.
14487 vnodeTag !== KEEP_ALIVE;
14488 if (shouldBuildAsSlots) {
14489 const { slots, hasDynamicSlots } = buildSlots(node, context);
14490 vnodeChildren = slots;
14491 if (hasDynamicSlots) {
14492 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14493 }
14494 }
14495 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
14496 const child = node.children[0];
14497 const type = child.type;
14498 // check for dynamic text children
14499 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
14500 type === 8 /* COMPOUND_EXPRESSION */;
14501 if (hasDynamicTextChild &&
14502 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
14503 patchFlag |= 1 /* TEXT */;
14504 }
14505 // pass directly if the only child is a text node
14506 // (plain / interpolation / expression)
14507 if (hasDynamicTextChild || type === 2 /* TEXT */) {
14508 vnodeChildren = child;
14509 }
14510 else {
14511 vnodeChildren = node.children;
14512 }
14513 }
14514 else {
14515 vnodeChildren = node.children;
14516 }
14517 }
14518 // patchFlag & dynamicPropNames
14519 if (patchFlag !== 0) {
14520 {
14521 if (patchFlag < 0) {
14522 // special flags (negative and mutually exclusive)
14523 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
14524 }
14525 else {
14526 // bitwise flags
14527 const flagNames = Object.keys(PatchFlagNames)
14528 .map(Number)
14529 .filter(n => n > 0 && patchFlag & n)
14530 .map(n => PatchFlagNames[n])
14531 .join(`, `);
14532 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
14533 }
14534 }
14535 if (dynamicPropNames && dynamicPropNames.length) {
14536 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
14537 }
14538 }
14539 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
14540 };
14541};
14542function resolveComponentType(node, context, ssr = false) {
14543 let { tag } = node;
14544 // 1. dynamic component
14545 const isExplicitDynamic = isComponentTag(tag);
14546 const isProp = findProp(node, 'is');
14547 if (isProp) {
14548 if (isExplicitDynamic ||
14549 (false )) {
14550 const exp = isProp.type === 6 /* ATTRIBUTE */
14551 ? isProp.value && createSimpleExpression(isProp.value.content, true)
14552 : isProp.exp;
14553 if (exp) {
14554 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14555 exp
14556 ]);
14557 }
14558 }
14559 else if (isProp.type === 6 /* ATTRIBUTE */ &&
14560 isProp.value.content.startsWith('vue:')) {
14561 // <button is="vue:xxx">
14562 // if not <component>, only is value that starts with "vue:" will be
14563 // treated as component by the parse phase and reach here, unless it's
14564 // compat mode where all is values are considered components
14565 tag = isProp.value.content.slice(4);
14566 }
14567 }
14568 // 1.5 v-is (TODO: Deprecate)
14569 const isDir = !isExplicitDynamic && findDir(node, 'is');
14570 if (isDir && isDir.exp) {
14571 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14572 isDir.exp
14573 ]);
14574 }
14575 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
14576 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
14577 if (builtIn) {
14578 // built-ins are simply fallthroughs / have special handling during ssr
14579 // so we don't need to import their runtime equivalents
14580 if (!ssr)
14581 context.helper(builtIn);
14582 return builtIn;
14583 }
14584 // 5. user component (resolve)
14585 context.helper(RESOLVE_COMPONENT);
14586 context.components.add(tag);
14587 return toValidAssetId(tag, `component`);
14588}
14589function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
14590 const { tag, loc: elementLoc, children } = node;
14591 let properties = [];
14592 const mergeArgs = [];
14593 const runtimeDirectives = [];
14594 const hasChildren = children.length > 0;
14595 let shouldUseBlock = false;
14596 // patchFlag analysis
14597 let patchFlag = 0;
14598 let hasRef = false;
14599 let hasClassBinding = false;
14600 let hasStyleBinding = false;
14601 let hasHydrationEventBinding = false;
14602 let hasDynamicKeys = false;
14603 let hasVnodeHook = false;
14604 const dynamicPropNames = [];
14605 const analyzePatchFlag = ({ key, value }) => {
14606 if (isStaticExp(key)) {
14607 const name = key.content;
14608 const isEventHandler = isOn(name);
14609 if (isEventHandler &&
14610 (!isComponent || isDynamicComponent) &&
14611 // omit the flag for click handlers because hydration gives click
14612 // dedicated fast path.
14613 name.toLowerCase() !== 'onclick' &&
14614 // omit v-model handlers
14615 name !== 'onUpdate:modelValue' &&
14616 // omit onVnodeXXX hooks
14617 !isReservedProp(name)) {
14618 hasHydrationEventBinding = true;
14619 }
14620 if (isEventHandler && isReservedProp(name)) {
14621 hasVnodeHook = true;
14622 }
14623 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
14624 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
14625 value.type === 8 /* COMPOUND_EXPRESSION */) &&
14626 getConstantType(value, context) > 0)) {
14627 // skip if the prop is a cached handler or has constant value
14628 return;
14629 }
14630 if (name === 'ref') {
14631 hasRef = true;
14632 }
14633 else if (name === 'class') {
14634 hasClassBinding = true;
14635 }
14636 else if (name === 'style') {
14637 hasStyleBinding = true;
14638 }
14639 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
14640 dynamicPropNames.push(name);
14641 }
14642 // treat the dynamic class and style binding of the component as dynamic props
14643 if (isComponent &&
14644 (name === 'class' || name === 'style') &&
14645 !dynamicPropNames.includes(name)) {
14646 dynamicPropNames.push(name);
14647 }
14648 }
14649 else {
14650 hasDynamicKeys = true;
14651 }
14652 };
14653 for (let i = 0; i < props.length; i++) {
14654 // static attribute
14655 const prop = props[i];
14656 if (prop.type === 6 /* ATTRIBUTE */) {
14657 const { loc, name, value } = prop;
14658 let isStatic = true;
14659 if (name === 'ref') {
14660 hasRef = true;
14661 if (context.scopes.vFor > 0) {
14662 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14663 }
14664 }
14665 // skip is on <component>, or is="vue:xxx"
14666 if (name === 'is' &&
14667 (isComponentTag(tag) ||
14668 (value && value.content.startsWith('vue:')) ||
14669 (false ))) {
14670 continue;
14671 }
14672 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14673 }
14674 else {
14675 // directives
14676 const { name, arg, exp, loc } = prop;
14677 const isVBind = name === 'bind';
14678 const isVOn = name === 'on';
14679 // skip v-slot - it is handled by its dedicated transform.
14680 if (name === 'slot') {
14681 if (!isComponent) {
14682 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));
14683 }
14684 continue;
14685 }
14686 // skip v-once/v-memo - they are handled by dedicated transforms.
14687 if (name === 'once' || name === 'memo') {
14688 continue;
14689 }
14690 // skip v-is and :is on <component>
14691 if (name === 'is' ||
14692 (isVBind &&
14693 isStaticArgOf(arg, 'is') &&
14694 (isComponentTag(tag) ||
14695 (false )))) {
14696 continue;
14697 }
14698 // skip v-on in SSR compilation
14699 if (isVOn && ssr) {
14700 continue;
14701 }
14702 if (
14703 // #938: elements with dynamic keys should be forced into blocks
14704 (isVBind && isStaticArgOf(arg, 'key')) ||
14705 // inline before-update hooks need to force block so that it is invoked
14706 // before children
14707 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14708 shouldUseBlock = true;
14709 }
14710 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14711 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14712 }
14713 // special case for v-bind and v-on with no argument
14714 if (!arg && (isVBind || isVOn)) {
14715 hasDynamicKeys = true;
14716 if (exp) {
14717 if (properties.length) {
14718 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14719 properties = [];
14720 }
14721 if (isVBind) {
14722 mergeArgs.push(exp);
14723 }
14724 else {
14725 // v-on="obj" -> toHandlers(obj)
14726 mergeArgs.push({
14727 type: 14 /* JS_CALL_EXPRESSION */,
14728 loc,
14729 callee: context.helper(TO_HANDLERS),
14730 arguments: [exp]
14731 });
14732 }
14733 }
14734 else {
14735 context.onError(createCompilerError(isVBind
14736 ? 34 /* X_V_BIND_NO_EXPRESSION */
14737 : 35 /* X_V_ON_NO_EXPRESSION */, loc));
14738 }
14739 continue;
14740 }
14741 const directiveTransform = context.directiveTransforms[name];
14742 if (directiveTransform) {
14743 // has built-in directive transform.
14744 const { props, needRuntime } = directiveTransform(prop, node, context);
14745 !ssr && props.forEach(analyzePatchFlag);
14746 properties.push(...props);
14747 if (needRuntime) {
14748 runtimeDirectives.push(prop);
14749 if (isSymbol(needRuntime)) {
14750 directiveImportMap.set(prop, needRuntime);
14751 }
14752 }
14753 }
14754 else if (!isBuiltInDirective(name)) {
14755 // no built-in transform, this is a user custom directive.
14756 runtimeDirectives.push(prop);
14757 // custom dirs may use beforeUpdate so they need to force blocks
14758 // to ensure before-update gets called before children update
14759 if (hasChildren) {
14760 shouldUseBlock = true;
14761 }
14762 }
14763 }
14764 }
14765 let propsExpression = undefined;
14766 // has v-bind="object" or v-on="object", wrap with mergeProps
14767 if (mergeArgs.length) {
14768 if (properties.length) {
14769 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14770 }
14771 if (mergeArgs.length > 1) {
14772 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
14773 }
14774 else {
14775 // single v-bind with nothing else - no need for a mergeProps call
14776 propsExpression = mergeArgs[0];
14777 }
14778 }
14779 else if (properties.length) {
14780 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
14781 }
14782 // patchFlag analysis
14783 if (hasDynamicKeys) {
14784 patchFlag |= 16 /* FULL_PROPS */;
14785 }
14786 else {
14787 if (hasClassBinding && !isComponent) {
14788 patchFlag |= 2 /* CLASS */;
14789 }
14790 if (hasStyleBinding && !isComponent) {
14791 patchFlag |= 4 /* STYLE */;
14792 }
14793 if (dynamicPropNames.length) {
14794 patchFlag |= 8 /* PROPS */;
14795 }
14796 if (hasHydrationEventBinding) {
14797 patchFlag |= 32 /* HYDRATE_EVENTS */;
14798 }
14799 }
14800 if (!shouldUseBlock &&
14801 (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14802 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14803 patchFlag |= 512 /* NEED_PATCH */;
14804 }
14805 // pre-normalize props, SSR is skipped for now
14806 if (!context.inSSR && propsExpression) {
14807 switch (propsExpression.type) {
14808 case 15 /* JS_OBJECT_EXPRESSION */:
14809 // means that there is no v-bind,
14810 // but still need to deal with dynamic key binding
14811 let classKeyIndex = -1;
14812 let styleKeyIndex = -1;
14813 let hasDynamicKey = false;
14814 for (let i = 0; i < propsExpression.properties.length; i++) {
14815 const key = propsExpression.properties[i].key;
14816 if (isStaticExp(key)) {
14817 if (key.content === 'class') {
14818 classKeyIndex = i;
14819 }
14820 else if (key.content === 'style') {
14821 styleKeyIndex = i;
14822 }
14823 }
14824 else if (!key.isHandlerKey) {
14825 hasDynamicKey = true;
14826 }
14827 }
14828 const classProp = propsExpression.properties[classKeyIndex];
14829 const styleProp = propsExpression.properties[styleKeyIndex];
14830 // no dynamic key
14831 if (!hasDynamicKey) {
14832 if (classProp && !isStaticExp(classProp.value)) {
14833 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
14834 }
14835 if (styleProp &&
14836 // the static style is compiled into an object,
14837 // so use `hasStyleBinding` to ensure that it is a dynamic style binding
14838 (hasStyleBinding ||
14839 (styleProp.value.type === 4 /* SIMPLE_EXPRESSION */ &&
14840 styleProp.value.content.trim()[0] === `[`) ||
14841 // v-bind:style and style both exist,
14842 // v-bind:style with static literal object
14843 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
14844 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
14845 }
14846 }
14847 else {
14848 // dynamic key binding, wrap with `normalizeProps`
14849 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
14850 }
14851 break;
14852 case 14 /* JS_CALL_EXPRESSION */:
14853 // mergeProps call, do nothing
14854 break;
14855 default:
14856 // single v-bind
14857 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
14858 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
14859 propsExpression
14860 ])
14861 ]);
14862 break;
14863 }
14864 }
14865 return {
14866 props: propsExpression,
14867 directives: runtimeDirectives,
14868 patchFlag,
14869 dynamicPropNames,
14870 shouldUseBlock
14871 };
14872}
14873// Dedupe props in an object literal.
14874// Literal duplicated attributes would have been warned during the parse phase,
14875// however, it's possible to encounter duplicated `onXXX` handlers with different
14876// modifiers. We also need to merge static and dynamic class / style attributes.
14877// - onXXX handlers / style: merge into array
14878// - class: merge into single expression with concatenation
14879function dedupeProperties(properties) {
14880 const knownProps = new Map();
14881 const deduped = [];
14882 for (let i = 0; i < properties.length; i++) {
14883 const prop = properties[i];
14884 // dynamic keys are always allowed
14885 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
14886 deduped.push(prop);
14887 continue;
14888 }
14889 const name = prop.key.content;
14890 const existing = knownProps.get(name);
14891 if (existing) {
14892 if (name === 'style' || name === 'class' || isOn(name)) {
14893 mergeAsArray$1(existing, prop);
14894 }
14895 // unexpected duplicate, should have emitted error during parse
14896 }
14897 else {
14898 knownProps.set(name, prop);
14899 deduped.push(prop);
14900 }
14901 }
14902 return deduped;
14903}
14904function mergeAsArray$1(existing, incoming) {
14905 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
14906 existing.value.elements.push(incoming.value);
14907 }
14908 else {
14909 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
14910 }
14911}
14912function buildDirectiveArgs(dir, context) {
14913 const dirArgs = [];
14914 const runtime = directiveImportMap.get(dir);
14915 if (runtime) {
14916 // built-in directive with runtime
14917 dirArgs.push(context.helperString(runtime));
14918 }
14919 else {
14920 {
14921 // inject statement for resolving directive
14922 context.helper(RESOLVE_DIRECTIVE);
14923 context.directives.add(dir.name);
14924 dirArgs.push(toValidAssetId(dir.name, `directive`));
14925 }
14926 }
14927 const { loc } = dir;
14928 if (dir.exp)
14929 dirArgs.push(dir.exp);
14930 if (dir.arg) {
14931 if (!dir.exp) {
14932 dirArgs.push(`void 0`);
14933 }
14934 dirArgs.push(dir.arg);
14935 }
14936 if (Object.keys(dir.modifiers).length) {
14937 if (!dir.arg) {
14938 if (!dir.exp) {
14939 dirArgs.push(`void 0`);
14940 }
14941 dirArgs.push(`void 0`);
14942 }
14943 const trueExpression = createSimpleExpression(`true`, false, loc);
14944 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
14945 }
14946 return createArrayExpression(dirArgs, dir.loc);
14947}
14948function stringifyDynamicPropNames(props) {
14949 let propsNamesString = `[`;
14950 for (let i = 0, l = props.length; i < l; i++) {
14951 propsNamesString += JSON.stringify(props[i]);
14952 if (i < l - 1)
14953 propsNamesString += ', ';
14954 }
14955 return propsNamesString + `]`;
14956}
14957function isComponentTag(tag) {
14958 return tag === 'component' || tag === 'Component';
14959}
14960
14961const transformSlotOutlet = (node, context) => {
14962 if (isSlotOutlet(node)) {
14963 const { children, loc } = node;
14964 const { slotName, slotProps } = processSlotOutlet(node, context);
14965 const slotArgs = [
14966 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
14967 slotName,
14968 '{}',
14969 'undefined',
14970 'true'
14971 ];
14972 let expectedLen = 2;
14973 if (slotProps) {
14974 slotArgs[2] = slotProps;
14975 expectedLen = 3;
14976 }
14977 if (children.length) {
14978 slotArgs[3] = createFunctionExpression([], children, false, false, loc);
14979 expectedLen = 4;
14980 }
14981 if (context.scopeId && !context.slotted) {
14982 expectedLen = 5;
14983 }
14984 slotArgs.splice(expectedLen); // remove unused arguments
14985 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
14986 }
14987};
14988function processSlotOutlet(node, context) {
14989 let slotName = `"default"`;
14990 let slotProps = undefined;
14991 const nonNameProps = [];
14992 for (let i = 0; i < node.props.length; i++) {
14993 const p = node.props[i];
14994 if (p.type === 6 /* ATTRIBUTE */) {
14995 if (p.value) {
14996 if (p.name === 'name') {
14997 slotName = JSON.stringify(p.value.content);
14998 }
14999 else {
15000 p.name = camelize(p.name);
15001 nonNameProps.push(p);
15002 }
15003 }
15004 }
15005 else {
15006 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
15007 if (p.exp)
15008 slotName = p.exp;
15009 }
15010 else {
15011 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
15012 p.arg.content = camelize(p.arg.content);
15013 }
15014 nonNameProps.push(p);
15015 }
15016 }
15017 }
15018 if (nonNameProps.length > 0) {
15019 const { props, directives } = buildProps(node, context, nonNameProps, false, false);
15020 slotProps = props;
15021 if (directives.length) {
15022 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
15023 }
15024 }
15025 return {
15026 slotName,
15027 slotProps
15028 };
15029}
15030
15031const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
15032const transformOn = (dir, node, context, augmentor) => {
15033 const { loc, modifiers, arg } = dir;
15034 if (!dir.exp && !modifiers.length) {
15035 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));
15036 }
15037 let eventName;
15038 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15039 if (arg.isStatic) {
15040 let rawName = arg.content;
15041 // TODO deprecate @vnodeXXX usage
15042 if (rawName.startsWith('vue:')) {
15043 rawName = `vnode-${rawName.slice(4)}`;
15044 }
15045 // for all event listeners, auto convert it to camelCase. See issue #2249
15046 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
15047 }
15048 else {
15049 // #2388
15050 eventName = createCompoundExpression([
15051 `${context.helperString(TO_HANDLER_KEY)}(`,
15052 arg,
15053 `)`
15054 ]);
15055 }
15056 }
15057 else {
15058 // already a compound expression.
15059 eventName = arg;
15060 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
15061 eventName.children.push(`)`);
15062 }
15063 // handler processing
15064 let exp = dir.exp;
15065 if (exp && !exp.content.trim()) {
15066 exp = undefined;
15067 }
15068 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
15069 if (exp) {
15070 const isMemberExp = isMemberExpression(exp.content);
15071 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
15072 const hasMultipleStatements = exp.content.includes(`;`);
15073 {
15074 validateBrowserExpression(exp, context, false, hasMultipleStatements);
15075 }
15076 if (isInlineStatement || (shouldCache && isMemberExp)) {
15077 // wrap inline statement in a function expression
15078 exp = createCompoundExpression([
15079 `${isInlineStatement
15080 ? `$event`
15081 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
15082 exp,
15083 hasMultipleStatements ? `}` : `)`
15084 ]);
15085 }
15086 }
15087 let ret = {
15088 props: [
15089 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
15090 ]
15091 };
15092 // apply extended compiler augmentor
15093 if (augmentor) {
15094 ret = augmentor(ret);
15095 }
15096 if (shouldCache) {
15097 // cache handlers so that it's always the same handler being passed down.
15098 // this avoids unnecessary re-renders when users use inline handlers on
15099 // components.
15100 ret.props[0].value = context.cache(ret.props[0].value);
15101 }
15102 // mark the key as handler for props normalization check
15103 ret.props.forEach(p => (p.key.isHandlerKey = true));
15104 return ret;
15105};
15106
15107// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
15108// codegen for the entire props object. This transform here is only for v-bind
15109// *with* args.
15110const transformBind = (dir, _node, context) => {
15111 const { exp, modifiers, loc } = dir;
15112 const arg = dir.arg;
15113 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
15114 arg.children.unshift(`(`);
15115 arg.children.push(`) || ""`);
15116 }
15117 else if (!arg.isStatic) {
15118 arg.content = `${arg.content} || ""`;
15119 }
15120 // .sync is replaced by v-model:arg
15121 if (modifiers.includes('camel')) {
15122 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15123 if (arg.isStatic) {
15124 arg.content = camelize(arg.content);
15125 }
15126 else {
15127 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
15128 }
15129 }
15130 else {
15131 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
15132 arg.children.push(`)`);
15133 }
15134 }
15135 if (!context.inSSR) {
15136 if (modifiers.includes('prop')) {
15137 injectPrefix(arg, '.');
15138 }
15139 if (modifiers.includes('attr')) {
15140 injectPrefix(arg, '^');
15141 }
15142 }
15143 if (!exp ||
15144 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
15145 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));
15146 return {
15147 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
15148 };
15149 }
15150 return {
15151 props: [createObjectProperty(arg, exp)]
15152 };
15153};
15154const injectPrefix = (arg, prefix) => {
15155 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15156 if (arg.isStatic) {
15157 arg.content = prefix + arg.content;
15158 }
15159 else {
15160 arg.content = `\`${prefix}\${${arg.content}}\``;
15161 }
15162 }
15163 else {
15164 arg.children.unshift(`'${prefix}' + (`);
15165 arg.children.push(`)`);
15166 }
15167};
15168
15169// Merge adjacent text nodes and expressions into a single expression
15170// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
15171const transformText = (node, context) => {
15172 if (node.type === 0 /* ROOT */ ||
15173 node.type === 1 /* ELEMENT */ ||
15174 node.type === 11 /* FOR */ ||
15175 node.type === 10 /* IF_BRANCH */) {
15176 // perform the transform on node exit so that all expressions have already
15177 // been processed.
15178 return () => {
15179 const children = node.children;
15180 let currentContainer = undefined;
15181 let hasText = false;
15182 for (let i = 0; i < children.length; i++) {
15183 const child = children[i];
15184 if (isText(child)) {
15185 hasText = true;
15186 for (let j = i + 1; j < children.length; j++) {
15187 const next = children[j];
15188 if (isText(next)) {
15189 if (!currentContainer) {
15190 currentContainer = children[i] = createCompoundExpression([child], child.loc);
15191 }
15192 // merge adjacent text node into current
15193 currentContainer.children.push(` + `, next);
15194 children.splice(j, 1);
15195 j--;
15196 }
15197 else {
15198 currentContainer = undefined;
15199 break;
15200 }
15201 }
15202 }
15203 }
15204 if (!hasText ||
15205 // if this is a plain element with a single text child, leave it
15206 // as-is since the runtime has dedicated fast path for this by directly
15207 // setting textContent of the element.
15208 // for component root it's always normalized anyway.
15209 (children.length === 1 &&
15210 (node.type === 0 /* ROOT */ ||
15211 (node.type === 1 /* ELEMENT */ &&
15212 node.tagType === 0 /* ELEMENT */ &&
15213 // #3756
15214 // custom directives can potentially add DOM elements arbitrarily,
15215 // we need to avoid setting textContent of the element at runtime
15216 // to avoid accidentally overwriting the DOM elements added
15217 // by the user through custom directives.
15218 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
15219 !context.directiveTransforms[p.name]) &&
15220 // in compat mode, <template> tags with no special directives
15221 // will be rendered as a fragment so its children must be
15222 // converted into vnodes.
15223 !(false ))))) {
15224 return;
15225 }
15226 // pre-convert text nodes into createTextVNode(text) calls to avoid
15227 // runtime normalization.
15228 for (let i = 0; i < children.length; i++) {
15229 const child = children[i];
15230 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
15231 const callArgs = [];
15232 // createTextVNode defaults to single whitespace, so if it is a
15233 // single space the code could be an empty call to save bytes.
15234 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
15235 callArgs.push(child);
15236 }
15237 // mark dynamic text with flag so it gets patched inside a block
15238 if (!context.ssr &&
15239 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
15240 callArgs.push(1 /* TEXT */ +
15241 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
15242 }
15243 children[i] = {
15244 type: 12 /* TEXT_CALL */,
15245 content: child,
15246 loc: child.loc,
15247 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
15248 };
15249 }
15250 }
15251 };
15252 }
15253};
15254
15255const seen = new WeakSet();
15256const transformOnce = (node, context) => {
15257 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
15258 if (seen.has(node) || context.inVOnce) {
15259 return;
15260 }
15261 seen.add(node);
15262 context.inVOnce = true;
15263 context.helper(SET_BLOCK_TRACKING);
15264 return () => {
15265 context.inVOnce = false;
15266 const cur = context.currentNode;
15267 if (cur.codegenNode) {
15268 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
15269 }
15270 };
15271 }
15272};
15273
15274const transformModel = (dir, node, context) => {
15275 const { exp, arg } = dir;
15276 if (!exp) {
15277 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
15278 return createTransformProps();
15279 }
15280 const rawExp = exp.loc.source;
15281 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
15282 // im SFC <script setup> inline mode, the exp may have been transformed into
15283 // _unref(exp)
15284 context.bindingMetadata[rawExp];
15285 const maybeRef = !true /* SETUP_CONST */;
15286 if (!expString.trim() ||
15287 (!isMemberExpression(expString) && !maybeRef)) {
15288 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
15289 return createTransformProps();
15290 }
15291 const propName = arg ? arg : createSimpleExpression('modelValue', true);
15292 const eventName = arg
15293 ? isStaticExp(arg)
15294 ? `onUpdate:${arg.content}`
15295 : createCompoundExpression(['"onUpdate:" + ', arg])
15296 : `onUpdate:modelValue`;
15297 let assignmentExp;
15298 const eventArg = context.isTS ? `($event: any)` : `$event`;
15299 {
15300 assignmentExp = createCompoundExpression([
15301 `${eventArg} => ((`,
15302 exp,
15303 `) = $event)`
15304 ]);
15305 }
15306 const props = [
15307 // modelValue: foo
15308 createObjectProperty(propName, dir.exp),
15309 // "onUpdate:modelValue": $event => (foo = $event)
15310 createObjectProperty(eventName, assignmentExp)
15311 ];
15312 // modelModifiers: { foo: true, "bar-baz": true }
15313 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
15314 const modifiers = dir.modifiers
15315 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
15316 .join(`, `);
15317 const modifiersKey = arg
15318 ? isStaticExp(arg)
15319 ? `${arg.content}Modifiers`
15320 : createCompoundExpression([arg, ' + "Modifiers"'])
15321 : `modelModifiers`;
15322 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
15323 }
15324 return createTransformProps(props);
15325};
15326function createTransformProps(props = []) {
15327 return { props };
15328}
15329
15330const seen$1 = new WeakSet();
15331const transformMemo = (node, context) => {
15332 if (node.type === 1 /* ELEMENT */) {
15333 const dir = findDir(node, 'memo');
15334 if (!dir || seen$1.has(node)) {
15335 return;
15336 }
15337 seen$1.add(node);
15338 return () => {
15339 const codegenNode = node.codegenNode ||
15340 context.currentNode.codegenNode;
15341 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
15342 // non-component sub tree should be turned into a block
15343 if (node.tagType !== 1 /* COMPONENT */) {
15344 makeBlock(codegenNode, context);
15345 }
15346 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
15347 dir.exp,
15348 createFunctionExpression(undefined, codegenNode),
15349 `_cache`,
15350 String(context.cached++)
15351 ]);
15352 }
15353 };
15354 }
15355};
15356
15357function getBaseTransformPreset(prefixIdentifiers) {
15358 return [
15359 [
15360 transformOnce,
15361 transformIf,
15362 transformMemo,
15363 transformFor,
15364 ...([]),
15365 ...([transformExpression]
15366 ),
15367 transformSlotOutlet,
15368 transformElement,
15369 trackSlotScopes,
15370 transformText
15371 ],
15372 {
15373 on: transformOn,
15374 bind: transformBind,
15375 model: transformModel
15376 }
15377 ];
15378}
15379// we name it `baseCompile` so that higher order compilers like
15380// @vue/compiler-dom can export `compile` while re-exporting everything else.
15381function baseCompile(template, options = {}) {
15382 const onError = options.onError || defaultOnError;
15383 const isModuleMode = options.mode === 'module';
15384 /* istanbul ignore if */
15385 {
15386 if (options.prefixIdentifiers === true) {
15387 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));
15388 }
15389 else if (isModuleMode) {
15390 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));
15391 }
15392 }
15393 const prefixIdentifiers = !true ;
15394 if (options.cacheHandlers) {
15395 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
15396 }
15397 if (options.scopeId && !isModuleMode) {
15398 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));
15399 }
15400 const ast = isString(template) ? baseParse(template, options) : template;
15401 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
15402 transform(ast, extend({}, options, {
15403 prefixIdentifiers,
15404 nodeTransforms: [
15405 ...nodeTransforms,
15406 ...(options.nodeTransforms || []) // user transforms
15407 ],
15408 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
15409 )
15410 }));
15411 return generate(ast, extend({}, options, {
15412 prefixIdentifiers
15413 }));
15414}
15415
15416const noopDirectiveTransform = () => ({ props: [] });
15417
15418const V_MODEL_RADIO = Symbol(`vModelRadio` );
15419const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
15420const V_MODEL_TEXT = Symbol(`vModelText` );
15421const V_MODEL_SELECT = Symbol(`vModelSelect` );
15422const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
15423const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
15424const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
15425const V_SHOW = Symbol(`vShow` );
15426const TRANSITION$1 = Symbol(`Transition` );
15427const TRANSITION_GROUP = Symbol(`TransitionGroup` );
15428registerRuntimeHelpers({
15429 [V_MODEL_RADIO]: `vModelRadio`,
15430 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
15431 [V_MODEL_TEXT]: `vModelText`,
15432 [V_MODEL_SELECT]: `vModelSelect`,
15433 [V_MODEL_DYNAMIC]: `vModelDynamic`,
15434 [V_ON_WITH_MODIFIERS]: `withModifiers`,
15435 [V_ON_WITH_KEYS]: `withKeys`,
15436 [V_SHOW]: `vShow`,
15437 [TRANSITION$1]: `Transition`,
15438 [TRANSITION_GROUP]: `TransitionGroup`
15439});
15440
15441/* eslint-disable no-restricted-globals */
15442let decoder;
15443function decodeHtmlBrowser(raw, asAttr = false) {
15444 if (!decoder) {
15445 decoder = document.createElement('div');
15446 }
15447 if (asAttr) {
15448 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
15449 return decoder.children[0].getAttribute('foo');
15450 }
15451 else {
15452 decoder.innerHTML = raw;
15453 return decoder.textContent;
15454 }
15455}
15456
15457const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
15458const parserOptions = {
15459 isVoidTag,
15460 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
15461 isPreTag: tag => tag === 'pre',
15462 decodeEntities: decodeHtmlBrowser ,
15463 isBuiltInComponent: (tag) => {
15464 if (isBuiltInType(tag, `Transition`)) {
15465 return TRANSITION$1;
15466 }
15467 else if (isBuiltInType(tag, `TransitionGroup`)) {
15468 return TRANSITION_GROUP;
15469 }
15470 },
15471 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
15472 getNamespace(tag, parent) {
15473 let ns = parent ? parent.ns : 0 /* HTML */;
15474 if (parent && ns === 2 /* MATH_ML */) {
15475 if (parent.tag === 'annotation-xml') {
15476 if (tag === 'svg') {
15477 return 1 /* SVG */;
15478 }
15479 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
15480 a.name === 'encoding' &&
15481 a.value != null &&
15482 (a.value.content === 'text/html' ||
15483 a.value.content === 'application/xhtml+xml'))) {
15484 ns = 0 /* HTML */;
15485 }
15486 }
15487 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
15488 tag !== 'mglyph' &&
15489 tag !== 'malignmark') {
15490 ns = 0 /* HTML */;
15491 }
15492 }
15493 else if (parent && ns === 1 /* SVG */) {
15494 if (parent.tag === 'foreignObject' ||
15495 parent.tag === 'desc' ||
15496 parent.tag === 'title') {
15497 ns = 0 /* HTML */;
15498 }
15499 }
15500 if (ns === 0 /* HTML */) {
15501 if (tag === 'svg') {
15502 return 1 /* SVG */;
15503 }
15504 if (tag === 'math') {
15505 return 2 /* MATH_ML */;
15506 }
15507 }
15508 return ns;
15509 },
15510 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
15511 getTextMode({ tag, ns }) {
15512 if (ns === 0 /* HTML */) {
15513 if (tag === 'textarea' || tag === 'title') {
15514 return 1 /* RCDATA */;
15515 }
15516 if (isRawTextContainer(tag)) {
15517 return 2 /* RAWTEXT */;
15518 }
15519 }
15520 return 0 /* DATA */;
15521 }
15522};
15523
15524// Parse inline CSS strings for static style attributes into an object.
15525// This is a NodeTransform since it works on the static `style` attribute and
15526// converts it into a dynamic equivalent:
15527// style="color: red" -> :style='{ "color": "red" }'
15528// It is then processed by `transformElement` and included in the generated
15529// props.
15530const transformStyle = node => {
15531 if (node.type === 1 /* ELEMENT */) {
15532 node.props.forEach((p, i) => {
15533 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
15534 // replace p with an expression node
15535 node.props[i] = {
15536 type: 7 /* DIRECTIVE */,
15537 name: `bind`,
15538 arg: createSimpleExpression(`style`, true, p.loc),
15539 exp: parseInlineCSS(p.value.content, p.loc),
15540 modifiers: [],
15541 loc: p.loc
15542 };
15543 }
15544 });
15545 }
15546};
15547const parseInlineCSS = (cssText, loc) => {
15548 const normalized = parseStringStyle(cssText);
15549 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
15550};
15551
15552function createDOMCompilerError(code, loc) {
15553 return createCompilerError(code, loc, DOMErrorMessages );
15554}
15555const DOMErrorMessages = {
15556 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
15557 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
15558 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
15559 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
15560 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
15561 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
15562 [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.`,
15563 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
15564 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
15565 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
15566 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
15567};
15568
15569const transformVHtml = (dir, node, context) => {
15570 const { exp, loc } = dir;
15571 if (!exp) {
15572 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));
15573 }
15574 if (node.children.length) {
15575 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));
15576 node.children.length = 0;
15577 }
15578 return {
15579 props: [
15580 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
15581 ]
15582 };
15583};
15584
15585const transformVText = (dir, node, context) => {
15586 const { exp, loc } = dir;
15587 if (!exp) {
15588 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));
15589 }
15590 if (node.children.length) {
15591 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));
15592 node.children.length = 0;
15593 }
15594 return {
15595 props: [
15596 createObjectProperty(createSimpleExpression(`textContent`, true), exp
15597 ? getConstantType(exp, context) > 0
15598 ? exp
15599 : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
15600 : createSimpleExpression('', true))
15601 ]
15602 };
15603};
15604
15605const transformModel$1 = (dir, node, context) => {
15606 const baseResult = transformModel(dir, node, context);
15607 // base transform has errors OR component v-model (only need props)
15608 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
15609 return baseResult;
15610 }
15611 if (dir.arg) {
15612 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
15613 }
15614 function checkDuplicatedValue() {
15615 const value = findProp(node, 'value');
15616 if (value) {
15617 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
15618 }
15619 }
15620 const { tag } = node;
15621 const isCustomElement = context.isCustomElement(tag);
15622 if (tag === 'input' ||
15623 tag === 'textarea' ||
15624 tag === 'select' ||
15625 isCustomElement) {
15626 let directiveToUse = V_MODEL_TEXT;
15627 let isInvalidType = false;
15628 if (tag === 'input' || isCustomElement) {
15629 const type = findProp(node, `type`);
15630 if (type) {
15631 if (type.type === 7 /* DIRECTIVE */) {
15632 // :type="foo"
15633 directiveToUse = V_MODEL_DYNAMIC;
15634 }
15635 else if (type.value) {
15636 switch (type.value.content) {
15637 case 'radio':
15638 directiveToUse = V_MODEL_RADIO;
15639 break;
15640 case 'checkbox':
15641 directiveToUse = V_MODEL_CHECKBOX;
15642 break;
15643 case 'file':
15644 isInvalidType = true;
15645 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
15646 break;
15647 default:
15648 // text type
15649 checkDuplicatedValue();
15650 break;
15651 }
15652 }
15653 }
15654 else if (hasDynamicKeyVBind(node)) {
15655 // element has bindings with dynamic keys, which can possibly contain
15656 // "type".
15657 directiveToUse = V_MODEL_DYNAMIC;
15658 }
15659 else {
15660 // text type
15661 checkDuplicatedValue();
15662 }
15663 }
15664 else if (tag === 'select') {
15665 directiveToUse = V_MODEL_SELECT;
15666 }
15667 else {
15668 // textarea
15669 checkDuplicatedValue();
15670 }
15671 // inject runtime directive
15672 // by returning the helper symbol via needRuntime
15673 // the import will replaced a resolveDirective call.
15674 if (!isInvalidType) {
15675 baseResult.needRuntime = context.helper(directiveToUse);
15676 }
15677 }
15678 else {
15679 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
15680 }
15681 // native vmodel doesn't need the `modelValue` props since they are also
15682 // passed to the runtime as `binding.value`. removing it reduces code size.
15683 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
15684 p.key.content === 'modelValue'));
15685 return baseResult;
15686};
15687
15688const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
15689const isNonKeyModifier = /*#__PURE__*/ makeMap(
15690// event propagation management
15691`stop,prevent,self,` +
15692 // system modifiers + exact
15693 `ctrl,shift,alt,meta,exact,` +
15694 // mouse
15695 `middle`);
15696// left & right could be mouse or key modifiers based on event type
15697const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
15698const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
15699const resolveModifiers = (key, modifiers, context, loc) => {
15700 const keyModifiers = [];
15701 const nonKeyModifiers = [];
15702 const eventOptionModifiers = [];
15703 for (let i = 0; i < modifiers.length; i++) {
15704 const modifier = modifiers[i];
15705 if (isEventOptionModifier(modifier)) {
15706 // eventOptionModifiers: modifiers for addEventListener() options,
15707 // e.g. .passive & .capture
15708 eventOptionModifiers.push(modifier);
15709 }
15710 else {
15711 // runtimeModifiers: modifiers that needs runtime guards
15712 if (maybeKeyModifier(modifier)) {
15713 if (isStaticExp(key)) {
15714 if (isKeyboardEvent(key.content)) {
15715 keyModifiers.push(modifier);
15716 }
15717 else {
15718 nonKeyModifiers.push(modifier);
15719 }
15720 }
15721 else {
15722 keyModifiers.push(modifier);
15723 nonKeyModifiers.push(modifier);
15724 }
15725 }
15726 else {
15727 if (isNonKeyModifier(modifier)) {
15728 nonKeyModifiers.push(modifier);
15729 }
15730 else {
15731 keyModifiers.push(modifier);
15732 }
15733 }
15734 }
15735 }
15736 return {
15737 keyModifiers,
15738 nonKeyModifiers,
15739 eventOptionModifiers
15740 };
15741};
15742const transformClick = (key, event) => {
15743 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
15744 return isStaticClick
15745 ? createSimpleExpression(event, true)
15746 : key.type !== 4 /* SIMPLE_EXPRESSION */
15747 ? createCompoundExpression([
15748 `(`,
15749 key,
15750 `) === "onClick" ? "${event}" : (`,
15751 key,
15752 `)`
15753 ])
15754 : key;
15755};
15756const transformOn$1 = (dir, node, context) => {
15757 return transformOn(dir, node, context, baseResult => {
15758 const { modifiers } = dir;
15759 if (!modifiers.length)
15760 return baseResult;
15761 let { key, value: handlerExp } = baseResult.props[0];
15762 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
15763 // normalize click.right and click.middle since they don't actually fire
15764 if (nonKeyModifiers.includes('right')) {
15765 key = transformClick(key, `onContextmenu`);
15766 }
15767 if (nonKeyModifiers.includes('middle')) {
15768 key = transformClick(key, `onMouseup`);
15769 }
15770 if (nonKeyModifiers.length) {
15771 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
15772 handlerExp,
15773 JSON.stringify(nonKeyModifiers)
15774 ]);
15775 }
15776 if (keyModifiers.length &&
15777 // if event name is dynamic, always wrap with keys guard
15778 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
15779 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
15780 handlerExp,
15781 JSON.stringify(keyModifiers)
15782 ]);
15783 }
15784 if (eventOptionModifiers.length) {
15785 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
15786 key = isStaticExp(key)
15787 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
15788 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
15789 }
15790 return {
15791 props: [createObjectProperty(key, handlerExp)]
15792 };
15793 });
15794};
15795
15796const transformShow = (dir, node, context) => {
15797 const { exp, loc } = dir;
15798 if (!exp) {
15799 context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc));
15800 }
15801 return {
15802 props: [],
15803 needRuntime: context.helper(V_SHOW)
15804 };
15805};
15806
15807const transformTransition = (node, context) => {
15808 if (node.type === 1 /* ELEMENT */ &&
15809 node.tagType === 1 /* COMPONENT */) {
15810 const component = context.isBuiltInComponent(node.tag);
15811 if (component === TRANSITION$1) {
15812 return () => {
15813 if (!node.children.length) {
15814 return;
15815 }
15816 // warn multiple transition children
15817 if (hasMultipleChildren(node)) {
15818 context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
15819 start: node.children[0].loc.start,
15820 end: node.children[node.children.length - 1].loc.end,
15821 source: ''
15822 }));
15823 }
15824 // check if it's s single child w/ v-show
15825 // if yes, inject "persisted: true" to the transition props
15826 const child = node.children[0];
15827 if (child.type === 1 /* ELEMENT */) {
15828 for (const p of child.props) {
15829 if (p.type === 7 /* DIRECTIVE */ && p.name === 'show') {
15830 node.props.push({
15831 type: 6 /* ATTRIBUTE */,
15832 name: 'persisted',
15833 value: undefined,
15834 loc: node.loc
15835 });
15836 }
15837 }
15838 }
15839 };
15840 }
15841 }
15842};
15843function hasMultipleChildren(node) {
15844 // #1352 filter out potential comment nodes.
15845 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ &&
15846 !(c.type === 2 /* TEXT */ && !c.content.trim())));
15847 const child = children[0];
15848 return (children.length !== 1 ||
15849 child.type === 11 /* FOR */ ||
15850 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
15851}
15852
15853const ignoreSideEffectTags = (node, context) => {
15854 if (node.type === 1 /* ELEMENT */ &&
15855 node.tagType === 0 /* ELEMENT */ &&
15856 (node.tag === 'script' || node.tag === 'style')) {
15857 context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
15858 context.removeNode();
15859 }
15860};
15861
15862const DOMNodeTransforms = [
15863 transformStyle,
15864 ...([transformTransition] )
15865];
15866const DOMDirectiveTransforms = {
15867 cloak: noopDirectiveTransform,
15868 html: transformVHtml,
15869 text: transformVText,
15870 model: transformModel$1,
15871 on: transformOn$1,
15872 show: transformShow
15873};
15874function compile$1(template, options = {}) {
15875 return baseCompile(template, extend({}, parserOptions, options, {
15876 nodeTransforms: [
15877 // ignore <script> and <tag>
15878 // this is not put inside DOMNodeTransforms because that list is used
15879 // by compiler-ssr to generate vnode fallback branches
15880 ignoreSideEffectTags,
15881 ...DOMNodeTransforms,
15882 ...(options.nodeTransforms || [])
15883 ],
15884 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
15885 transformHoist: null
15886 }));
15887}
15888
15889// This entry is the "full-build" that includes both the runtime
15890{
15891 initDev();
15892}
15893const compileCache = Object.create(null);
15894function compileToFunction(template, options) {
15895 if (!isString(template)) {
15896 if (template.nodeType) {
15897 template = template.innerHTML;
15898 }
15899 else {
15900 warn$1(`invalid template option: `, template);
15901 return NOOP;
15902 }
15903 }
15904 const key = template;
15905 const cached = compileCache[key];
15906 if (cached) {
15907 return cached;
15908 }
15909 if (template[0] === '#') {
15910 const el = document.querySelector(template);
15911 if (!el) {
15912 warn$1(`Template element not found or is empty: ${template}`);
15913 }
15914 // __UNSAFE__
15915 // Reason: potential execution of JS expressions in in-DOM template.
15916 // The user must make sure the in-DOM template is trusted. If it's rendered
15917 // by the server, the template should not contain any user data.
15918 template = el ? el.innerHTML : ``;
15919 }
15920 const { code } = compile$1(template, extend({
15921 hoistStatic: true,
15922 onError: onError ,
15923 onWarn: e => onError(e, true)
15924 }, options));
15925 function onError(err, asWarning = false) {
15926 const message = asWarning
15927 ? err.message
15928 : `Template compilation error: ${err.message}`;
15929 const codeFrame = err.loc &&
15930 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
15931 warn$1(codeFrame ? `${message}\n${codeFrame}` : message);
15932 }
15933 // The wildcard import results in a huge object with every export
15934 // with keys that cannot be mangled, and can be quite heavy size-wise.
15935 // In the global build we know `Vue` is available globally so we can avoid
15936 // the wildcard object.
15937 const render = (new Function('Vue', code)(runtimeDom));
15938 render._rc = true;
15939 return (compileCache[key] = render);
15940}
15941registerRuntimeCompiler(compileToFunction);
15942
15943export { BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compileToFunction as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createElementBlock, createBaseVNode as createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isShallow, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId };