UNPKG

557 kBJavaScriptView Raw
1var Vue = (function (exports) {
2 'use strict';
3
4 /**
5 * Make a map and return a function for checking if a key
6 * is in that map.
7 * IMPORTANT: all calls of this function must be prefixed with
8 * \/\*#\_\_PURE\_\_\*\/
9 * So that rollup can tree-shake them if necessary.
10 */
11 function makeMap(str, expectsLowerCase) {
12 const map = Object.create(null);
13 const list = str.split(',');
14 for (let i = 0; i < list.length; i++) {
15 map[list[i]] = true;
16 }
17 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
18 }
19
20 /**
21 * dev only flag -> name mapping
22 */
23 const PatchFlagNames = {
24 [1 /* TEXT */]: `TEXT`,
25 [2 /* CLASS */]: `CLASS`,
26 [4 /* STYLE */]: `STYLE`,
27 [8 /* PROPS */]: `PROPS`,
28 [16 /* FULL_PROPS */]: `FULL_PROPS`,
29 [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
30 [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
31 [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
32 [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
33 [512 /* NEED_PATCH */]: `NEED_PATCH`,
34 [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
35 [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
36 [-1 /* HOISTED */]: `HOISTED`,
37 [-2 /* BAIL */]: `BAIL`
38 };
39
40 /**
41 * Dev only
42 */
43 const slotFlagsText = {
44 [1 /* STABLE */]: 'STABLE',
45 [2 /* DYNAMIC */]: 'DYNAMIC',
46 [3 /* FORWARDED */]: 'FORWARDED'
47 };
48
49 const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
50 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
51 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
52 const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
53
54 const range = 2;
55 function generateCodeFrame(source, start = 0, end = source.length) {
56 const lines = source.split(/\r?\n/);
57 let count = 0;
58 const res = [];
59 for (let i = 0; i < lines.length; i++) {
60 count += lines[i].length + 1;
61 if (count >= start) {
62 for (let j = i - range; j <= i + range || end > count; j++) {
63 if (j < 0 || j >= lines.length)
64 continue;
65 const line = j + 1;
66 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
67 const lineLength = lines[j].length;
68 if (j === i) {
69 // push underline
70 const pad = start - (count - lineLength) + 1;
71 const length = Math.max(1, end > count ? lineLength - pad : end - start);
72 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
73 }
74 else if (j > i) {
75 if (end > count) {
76 const length = Math.max(Math.min(end - count, lineLength), 1);
77 res.push(` | ` + '^'.repeat(length));
78 }
79 count += lineLength + 1;
80 }
81 }
82 break;
83 }
84 }
85 return res.join('\n');
86 }
87
88 /**
89 * On the client we only need to offer special cases for boolean attributes that
90 * have different names from their corresponding dom properties:
91 * - itemscope -> N/A
92 * - allowfullscreen -> allowFullscreen
93 * - formnovalidate -> formNoValidate
94 * - ismap -> isMap
95 * - nomodule -> noModule
96 * - novalidate -> noValidate
97 * - readonly -> readOnly
98 */
99 const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
100 const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
101
102 function normalizeStyle(value) {
103 if (isArray(value)) {
104 const res = {};
105 for (let i = 0; i < value.length; i++) {
106 const item = value[i];
107 const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item);
108 if (normalized) {
109 for (const key in normalized) {
110 res[key] = normalized[key];
111 }
112 }
113 }
114 return res;
115 }
116 else if (isObject(value)) {
117 return value;
118 }
119 }
120 const listDelimiterRE = /;(?![^(]*\))/g;
121 const propertyDelimiterRE = /:(.+)/;
122 function parseStringStyle(cssText) {
123 const ret = {};
124 cssText.split(listDelimiterRE).forEach(item => {
125 if (item) {
126 const tmp = item.split(propertyDelimiterRE);
127 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
128 }
129 });
130 return ret;
131 }
132 function normalizeClass(value) {
133 let res = '';
134 if (isString(value)) {
135 res = value;
136 }
137 else if (isArray(value)) {
138 for (let i = 0; i < value.length; i++) {
139 const normalized = normalizeClass(value[i]);
140 if (normalized) {
141 res += normalized + ' ';
142 }
143 }
144 }
145 else if (isObject(value)) {
146 for (const name in value) {
147 if (value[name]) {
148 res += name + ' ';
149 }
150 }
151 }
152 return res.trim();
153 }
154
155 // These tag configs are shared between compiler-dom and runtime-dom, so they
156 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
157 const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
158 'header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,' +
159 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
160 'data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,' +
161 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
162 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
163 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
164 'option,output,progress,select,textarea,details,dialog,menu,' +
165 'summary,template,blockquote,iframe,tfoot';
166 // https://developer.mozilla.org/en-US/docs/Web/SVG/Element
167 const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
168 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
169 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
170 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
171 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
172 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
173 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
174 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
175 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
176 'text,textPath,title,tspan,unknown,use,view';
177 const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
178 const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
179 const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
180 const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
181
182 function looseCompareArrays(a, b) {
183 if (a.length !== b.length)
184 return false;
185 let equal = true;
186 for (let i = 0; equal && i < a.length; i++) {
187 equal = looseEqual(a[i], b[i]);
188 }
189 return equal;
190 }
191 function looseEqual(a, b) {
192 if (a === b)
193 return true;
194 let aValidType = isDate(a);
195 let bValidType = isDate(b);
196 if (aValidType || bValidType) {
197 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
198 }
199 aValidType = isArray(a);
200 bValidType = isArray(b);
201 if (aValidType || bValidType) {
202 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
203 }
204 aValidType = isObject(a);
205 bValidType = isObject(b);
206 if (aValidType || bValidType) {
207 /* istanbul ignore if: this if will probably never be called */
208 if (!aValidType || !bValidType) {
209 return false;
210 }
211 const aKeysCount = Object.keys(a).length;
212 const bKeysCount = Object.keys(b).length;
213 if (aKeysCount !== bKeysCount) {
214 return false;
215 }
216 for (const key in a) {
217 const aHasKey = a.hasOwnProperty(key);
218 const bHasKey = b.hasOwnProperty(key);
219 if ((aHasKey && !bHasKey) ||
220 (!aHasKey && bHasKey) ||
221 !looseEqual(a[key], b[key])) {
222 return false;
223 }
224 }
225 }
226 return String(a) === String(b);
227 }
228 function looseIndexOf(arr, val) {
229 return arr.findIndex(item => looseEqual(item, val));
230 }
231
232 /**
233 * For converting {{ interpolation }} values to displayed strings.
234 * @private
235 */
236 const toDisplayString = (val) => {
237 return val == null
238 ? ''
239 : isObject(val)
240 ? JSON.stringify(val, replacer, 2)
241 : String(val);
242 };
243 const replacer = (_key, val) => {
244 if (isMap(val)) {
245 return {
246 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
247 entries[`${key} =>`] = val;
248 return entries;
249 }, {})
250 };
251 }
252 else if (isSet(val)) {
253 return {
254 [`Set(${val.size})`]: [...val.values()]
255 };
256 }
257 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
258 return String(val);
259 }
260 return val;
261 };
262
263 const EMPTY_OBJ = Object.freeze({})
264 ;
265 const EMPTY_ARR = Object.freeze([]) ;
266 const NOOP = () => { };
267 /**
268 * Always return false.
269 */
270 const NO = () => false;
271 const onRE = /^on[^a-z]/;
272 const isOn = (key) => onRE.test(key);
273 const isModelListener = (key) => key.startsWith('onUpdate:');
274 const extend = Object.assign;
275 const remove = (arr, el) => {
276 const i = arr.indexOf(el);
277 if (i > -1) {
278 arr.splice(i, 1);
279 }
280 };
281 const hasOwnProperty = Object.prototype.hasOwnProperty;
282 const hasOwn = (val, key) => hasOwnProperty.call(val, key);
283 const isArray = Array.isArray;
284 const isMap = (val) => toTypeString(val) === '[object Map]';
285 const isSet = (val) => toTypeString(val) === '[object Set]';
286 const isDate = (val) => val instanceof Date;
287 const isFunction = (val) => typeof val === 'function';
288 const isString = (val) => typeof val === 'string';
289 const isSymbol = (val) => typeof val === 'symbol';
290 const isObject = (val) => val !== null && typeof val === 'object';
291 const isPromise = (val) => {
292 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
293 };
294 const objectToString = Object.prototype.toString;
295 const toTypeString = (value) => objectToString.call(value);
296 const toRawType = (value) => {
297 // extract "RawType" from strings like "[object RawType]"
298 return toTypeString(value).slice(8, -1);
299 };
300 const isPlainObject = (val) => toTypeString(val) === '[object Object]';
301 const isIntegerKey = (key) => isString(key) &&
302 key !== 'NaN' &&
303 key[0] !== '-' &&
304 '' + parseInt(key, 10) === key;
305 const isReservedProp = /*#__PURE__*/ makeMap(
306 // the leading comma is intentional so empty string "" is also included
307 ',key,ref,' +
308 'onVnodeBeforeMount,onVnodeMounted,' +
309 'onVnodeBeforeUpdate,onVnodeUpdated,' +
310 'onVnodeBeforeUnmount,onVnodeUnmounted');
311 const cacheStringFunction = (fn) => {
312 const cache = Object.create(null);
313 return ((str) => {
314 const hit = cache[str];
315 return hit || (cache[str] = fn(str));
316 });
317 };
318 const camelizeRE = /-(\w)/g;
319 /**
320 * @private
321 */
322 const camelize = cacheStringFunction((str) => {
323 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
324 });
325 const hyphenateRE = /\B([A-Z])/g;
326 /**
327 * @private
328 */
329 const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
330 /**
331 * @private
332 */
333 const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
334 /**
335 * @private
336 */
337 const toHandlerKey = cacheStringFunction((str) => (str ? `on${capitalize(str)}` : ``));
338 // compare whether a value has changed, accounting for NaN.
339 const hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue);
340 const invokeArrayFns = (fns, arg) => {
341 for (let i = 0; i < fns.length; i++) {
342 fns[i](arg);
343 }
344 };
345 const def = (obj, key, value) => {
346 Object.defineProperty(obj, key, {
347 configurable: true,
348 enumerable: false,
349 value
350 });
351 };
352 const toNumber = (val) => {
353 const n = parseFloat(val);
354 return isNaN(n) ? val : n;
355 };
356 let _globalThis;
357 const getGlobalThis = () => {
358 return (_globalThis ||
359 (_globalThis =
360 typeof globalThis !== 'undefined'
361 ? globalThis
362 : typeof self !== 'undefined'
363 ? self
364 : typeof window !== 'undefined'
365 ? window
366 : typeof global !== 'undefined'
367 ? global
368 : {}));
369 };
370
371 const targetMap = new WeakMap();
372 const effectStack = [];
373 let activeEffect;
374 const ITERATE_KEY = Symbol('iterate' );
375 const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
376 function isEffect(fn) {
377 return fn && fn._isEffect === true;
378 }
379 function effect(fn, options = EMPTY_OBJ) {
380 if (isEffect(fn)) {
381 fn = fn.raw;
382 }
383 const effect = createReactiveEffect(fn, options);
384 if (!options.lazy) {
385 effect();
386 }
387 return effect;
388 }
389 function stop(effect) {
390 if (effect.active) {
391 cleanup(effect);
392 if (effect.options.onStop) {
393 effect.options.onStop();
394 }
395 effect.active = false;
396 }
397 }
398 let uid = 0;
399 function createReactiveEffect(fn, options) {
400 const effect = function reactiveEffect() {
401 if (!effect.active) {
402 return options.scheduler ? undefined : fn();
403 }
404 if (!effectStack.includes(effect)) {
405 cleanup(effect);
406 try {
407 enableTracking();
408 effectStack.push(effect);
409 activeEffect = effect;
410 return fn();
411 }
412 finally {
413 effectStack.pop();
414 resetTracking();
415 activeEffect = effectStack[effectStack.length - 1];
416 }
417 }
418 };
419 effect.id = uid++;
420 effect.allowRecurse = !!options.allowRecurse;
421 effect._isEffect = true;
422 effect.active = true;
423 effect.raw = fn;
424 effect.deps = [];
425 effect.options = options;
426 return effect;
427 }
428 function cleanup(effect) {
429 const { deps } = effect;
430 if (deps.length) {
431 for (let i = 0; i < deps.length; i++) {
432 deps[i].delete(effect);
433 }
434 deps.length = 0;
435 }
436 }
437 let shouldTrack = true;
438 const trackStack = [];
439 function pauseTracking() {
440 trackStack.push(shouldTrack);
441 shouldTrack = false;
442 }
443 function enableTracking() {
444 trackStack.push(shouldTrack);
445 shouldTrack = true;
446 }
447 function resetTracking() {
448 const last = trackStack.pop();
449 shouldTrack = last === undefined ? true : last;
450 }
451 function track(target, type, key) {
452 if (!shouldTrack || activeEffect === undefined) {
453 return;
454 }
455 let depsMap = targetMap.get(target);
456 if (!depsMap) {
457 targetMap.set(target, (depsMap = new Map()));
458 }
459 let dep = depsMap.get(key);
460 if (!dep) {
461 depsMap.set(key, (dep = new Set()));
462 }
463 if (!dep.has(activeEffect)) {
464 dep.add(activeEffect);
465 activeEffect.deps.push(dep);
466 if (activeEffect.options.onTrack) {
467 activeEffect.options.onTrack({
468 effect: activeEffect,
469 target,
470 type,
471 key
472 });
473 }
474 }
475 }
476 function trigger(target, type, key, newValue, oldValue, oldTarget) {
477 const depsMap = targetMap.get(target);
478 if (!depsMap) {
479 // never been tracked
480 return;
481 }
482 const effects = new Set();
483 const add = (effectsToAdd) => {
484 if (effectsToAdd) {
485 effectsToAdd.forEach(effect => {
486 if (effect !== activeEffect || effect.allowRecurse) {
487 effects.add(effect);
488 }
489 });
490 }
491 };
492 if (type === "clear" /* CLEAR */) {
493 // collection being cleared
494 // trigger all effects for target
495 depsMap.forEach(add);
496 }
497 else if (key === 'length' && isArray(target)) {
498 depsMap.forEach((dep, key) => {
499 if (key === 'length' || key >= newValue) {
500 add(dep);
501 }
502 });
503 }
504 else {
505 // schedule runs for SET | ADD | DELETE
506 if (key !== void 0) {
507 add(depsMap.get(key));
508 }
509 // also run for iteration key on ADD | DELETE | Map.SET
510 switch (type) {
511 case "add" /* ADD */:
512 if (!isArray(target)) {
513 add(depsMap.get(ITERATE_KEY));
514 if (isMap(target)) {
515 add(depsMap.get(MAP_KEY_ITERATE_KEY));
516 }
517 }
518 else if (isIntegerKey(key)) {
519 // new index added to array -> length changes
520 add(depsMap.get('length'));
521 }
522 break;
523 case "delete" /* DELETE */:
524 if (!isArray(target)) {
525 add(depsMap.get(ITERATE_KEY));
526 if (isMap(target)) {
527 add(depsMap.get(MAP_KEY_ITERATE_KEY));
528 }
529 }
530 break;
531 case "set" /* SET */:
532 if (isMap(target)) {
533 add(depsMap.get(ITERATE_KEY));
534 }
535 break;
536 }
537 }
538 const run = (effect) => {
539 if (effect.options.onTrigger) {
540 effect.options.onTrigger({
541 effect,
542 target,
543 key,
544 type,
545 newValue,
546 oldValue,
547 oldTarget
548 });
549 }
550 if (effect.options.scheduler) {
551 effect.options.scheduler(effect);
552 }
553 else {
554 effect();
555 }
556 };
557 effects.forEach(run);
558 }
559
560 const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
561 const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
562 .map(key => Symbol[key])
563 .filter(isSymbol));
564 const get = /*#__PURE__*/ createGetter();
565 const shallowGet = /*#__PURE__*/ createGetter(false, true);
566 const readonlyGet = /*#__PURE__*/ createGetter(true);
567 const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
568 const arrayInstrumentations = {};
569 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
570 const method = Array.prototype[key];
571 arrayInstrumentations[key] = function (...args) {
572 const arr = toRaw(this);
573 for (let i = 0, l = this.length; i < l; i++) {
574 track(arr, "get" /* GET */, i + '');
575 }
576 // we run the method using the original args first (which may be reactive)
577 const res = method.apply(arr, args);
578 if (res === -1 || res === false) {
579 // if that didn't work, run it again using raw values.
580 return method.apply(arr, args.map(toRaw));
581 }
582 else {
583 return res;
584 }
585 };
586 });
587 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
588 const method = Array.prototype[key];
589 arrayInstrumentations[key] = function (...args) {
590 pauseTracking();
591 const res = method.apply(this, args);
592 resetTracking();
593 return res;
594 };
595 });
596 function createGetter(isReadonly = false, shallow = false) {
597 return function get(target, key, receiver) {
598 if (key === "__v_isReactive" /* IS_REACTIVE */) {
599 return !isReadonly;
600 }
601 else if (key === "__v_isReadonly" /* IS_READONLY */) {
602 return isReadonly;
603 }
604 else if (key === "__v_raw" /* RAW */ &&
605 receiver ===
606 (isReadonly
607 ? shallow
608 ? shallowReadonlyMap
609 : readonlyMap
610 : shallow
611 ? shallowReactiveMap
612 : reactiveMap).get(target)) {
613 return target;
614 }
615 const targetIsArray = isArray(target);
616 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
617 return Reflect.get(arrayInstrumentations, key, receiver);
618 }
619 const res = Reflect.get(target, key, receiver);
620 if (isSymbol(key)
621 ? builtInSymbols.has(key)
622 : isNonTrackableKeys(key)) {
623 return res;
624 }
625 if (!isReadonly) {
626 track(target, "get" /* GET */, key);
627 }
628 if (shallow) {
629 return res;
630 }
631 if (isRef(res)) {
632 // ref unwrapping - does not apply for Array + integer key.
633 const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
634 return shouldUnwrap ? res.value : res;
635 }
636 if (isObject(res)) {
637 // Convert returned value into a proxy as well. we do the isObject check
638 // here to avoid invalid value warning. Also need to lazy access readonly
639 // and reactive here to avoid circular dependency.
640 return isReadonly ? readonly(res) : reactive(res);
641 }
642 return res;
643 };
644 }
645 const set = /*#__PURE__*/ createSetter();
646 const shallowSet = /*#__PURE__*/ createSetter(true);
647 function createSetter(shallow = false) {
648 return function set(target, key, value, receiver) {
649 let oldValue = target[key];
650 if (!shallow) {
651 value = toRaw(value);
652 oldValue = toRaw(oldValue);
653 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
654 oldValue.value = value;
655 return true;
656 }
657 }
658 const hadKey = isArray(target) && isIntegerKey(key)
659 ? Number(key) < target.length
660 : hasOwn(target, key);
661 const result = Reflect.set(target, key, value, receiver);
662 // don't trigger if target is something up in the prototype chain of original
663 if (target === toRaw(receiver)) {
664 if (!hadKey) {
665 trigger(target, "add" /* ADD */, key, value);
666 }
667 else if (hasChanged(value, oldValue)) {
668 trigger(target, "set" /* SET */, key, value, oldValue);
669 }
670 }
671 return result;
672 };
673 }
674 function deleteProperty(target, key) {
675 const hadKey = hasOwn(target, key);
676 const oldValue = target[key];
677 const result = Reflect.deleteProperty(target, key);
678 if (result && hadKey) {
679 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
680 }
681 return result;
682 }
683 function has(target, key) {
684 const result = Reflect.has(target, key);
685 if (!isSymbol(key) || !builtInSymbols.has(key)) {
686 track(target, "has" /* HAS */, key);
687 }
688 return result;
689 }
690 function ownKeys(target) {
691 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
692 return Reflect.ownKeys(target);
693 }
694 const mutableHandlers = {
695 get,
696 set,
697 deleteProperty,
698 has,
699 ownKeys
700 };
701 const readonlyHandlers = {
702 get: readonlyGet,
703 set(target, key) {
704 {
705 console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
706 }
707 return true;
708 },
709 deleteProperty(target, key) {
710 {
711 console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
712 }
713 return true;
714 }
715 };
716 const shallowReactiveHandlers = extend({}, mutableHandlers, {
717 get: shallowGet,
718 set: shallowSet
719 });
720 // Props handlers are special in the sense that it should not unwrap top-level
721 // refs (in order to allow refs to be explicitly passed down), but should
722 // retain the reactivity of the normal readonly object.
723 const shallowReadonlyHandlers = extend({}, readonlyHandlers, {
724 get: shallowReadonlyGet
725 });
726
727 const toReactive = (value) => isObject(value) ? reactive(value) : value;
728 const toReadonly = (value) => isObject(value) ? readonly(value) : value;
729 const toShallow = (value) => value;
730 const getProto = (v) => Reflect.getPrototypeOf(v);
731 function get$1(target, key, isReadonly = false, isShallow = false) {
732 // #1772: readonly(reactive(Map)) should return readonly + reactive version
733 // of the value
734 target = target["__v_raw" /* RAW */];
735 const rawTarget = toRaw(target);
736 const rawKey = toRaw(key);
737 if (key !== rawKey) {
738 !isReadonly && track(rawTarget, "get" /* GET */, key);
739 }
740 !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
741 const { has } = getProto(rawTarget);
742 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
743 if (has.call(rawTarget, key)) {
744 return wrap(target.get(key));
745 }
746 else if (has.call(rawTarget, rawKey)) {
747 return wrap(target.get(rawKey));
748 }
749 }
750 function has$1(key, isReadonly = false) {
751 const target = this["__v_raw" /* RAW */];
752 const rawTarget = toRaw(target);
753 const rawKey = toRaw(key);
754 if (key !== rawKey) {
755 !isReadonly && track(rawTarget, "has" /* HAS */, key);
756 }
757 !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
758 return key === rawKey
759 ? target.has(key)
760 : target.has(key) || target.has(rawKey);
761 }
762 function size(target, isReadonly = false) {
763 target = target["__v_raw" /* RAW */];
764 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
765 return Reflect.get(target, 'size', target);
766 }
767 function add(value) {
768 value = toRaw(value);
769 const target = toRaw(this);
770 const proto = getProto(target);
771 const hadKey = proto.has.call(target, value);
772 if (!hadKey) {
773 target.add(value);
774 trigger(target, "add" /* ADD */, value, value);
775 }
776 return this;
777 }
778 function set$1(key, value) {
779 value = toRaw(value);
780 const target = toRaw(this);
781 const { has, get } = getProto(target);
782 let hadKey = has.call(target, key);
783 if (!hadKey) {
784 key = toRaw(key);
785 hadKey = has.call(target, key);
786 }
787 else {
788 checkIdentityKeys(target, has, key);
789 }
790 const oldValue = get.call(target, key);
791 target.set(key, value);
792 if (!hadKey) {
793 trigger(target, "add" /* ADD */, key, value);
794 }
795 else if (hasChanged(value, oldValue)) {
796 trigger(target, "set" /* SET */, key, value, oldValue);
797 }
798 return this;
799 }
800 function deleteEntry(key) {
801 const target = toRaw(this);
802 const { has, get } = getProto(target);
803 let hadKey = has.call(target, key);
804 if (!hadKey) {
805 key = toRaw(key);
806 hadKey = has.call(target, key);
807 }
808 else {
809 checkIdentityKeys(target, has, key);
810 }
811 const oldValue = get ? get.call(target, key) : undefined;
812 // forward the operation before queueing reactions
813 const result = target.delete(key);
814 if (hadKey) {
815 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
816 }
817 return result;
818 }
819 function clear() {
820 const target = toRaw(this);
821 const hadItems = target.size !== 0;
822 const oldTarget = isMap(target)
823 ? new Map(target)
824 : new Set(target)
825 ;
826 // forward the operation before queueing reactions
827 const result = target.clear();
828 if (hadItems) {
829 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
830 }
831 return result;
832 }
833 function createForEach(isReadonly, isShallow) {
834 return function forEach(callback, thisArg) {
835 const observed = this;
836 const target = observed["__v_raw" /* RAW */];
837 const rawTarget = toRaw(target);
838 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
839 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
840 return target.forEach((value, key) => {
841 // important: make sure the callback is
842 // 1. invoked with the reactive map as `this` and 3rd arg
843 // 2. the value received should be a corresponding reactive/readonly.
844 return callback.call(thisArg, wrap(value), wrap(key), observed);
845 });
846 };
847 }
848 function createIterableMethod(method, isReadonly, isShallow) {
849 return function (...args) {
850 const target = this["__v_raw" /* RAW */];
851 const rawTarget = toRaw(target);
852 const targetIsMap = isMap(rawTarget);
853 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
854 const isKeyOnly = method === 'keys' && targetIsMap;
855 const innerIterator = target[method](...args);
856 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
857 !isReadonly &&
858 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
859 // return a wrapped iterator which returns observed versions of the
860 // values emitted from the real iterator
861 return {
862 // iterator protocol
863 next() {
864 const { value, done } = innerIterator.next();
865 return done
866 ? { value, done }
867 : {
868 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
869 done
870 };
871 },
872 // iterable protocol
873 [Symbol.iterator]() {
874 return this;
875 }
876 };
877 };
878 }
879 function createReadonlyMethod(type) {
880 return function (...args) {
881 {
882 const key = args[0] ? `on key "${args[0]}" ` : ``;
883 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
884 }
885 return type === "delete" /* DELETE */ ? false : this;
886 };
887 }
888 const mutableInstrumentations = {
889 get(key) {
890 return get$1(this, key);
891 },
892 get size() {
893 return size(this);
894 },
895 has: has$1,
896 add,
897 set: set$1,
898 delete: deleteEntry,
899 clear,
900 forEach: createForEach(false, false)
901 };
902 const shallowInstrumentations = {
903 get(key) {
904 return get$1(this, key, false, true);
905 },
906 get size() {
907 return size(this);
908 },
909 has: has$1,
910 add,
911 set: set$1,
912 delete: deleteEntry,
913 clear,
914 forEach: createForEach(false, true)
915 };
916 const readonlyInstrumentations = {
917 get(key) {
918 return get$1(this, key, true);
919 },
920 get size() {
921 return size(this, true);
922 },
923 has(key) {
924 return has$1.call(this, key, true);
925 },
926 add: createReadonlyMethod("add" /* ADD */),
927 set: createReadonlyMethod("set" /* SET */),
928 delete: createReadonlyMethod("delete" /* DELETE */),
929 clear: createReadonlyMethod("clear" /* CLEAR */),
930 forEach: createForEach(true, false)
931 };
932 const shallowReadonlyInstrumentations = {
933 get(key) {
934 return get$1(this, key, true, true);
935 },
936 get size() {
937 return size(this, true);
938 },
939 has(key) {
940 return has$1.call(this, key, true);
941 },
942 add: createReadonlyMethod("add" /* ADD */),
943 set: createReadonlyMethod("set" /* SET */),
944 delete: createReadonlyMethod("delete" /* DELETE */),
945 clear: createReadonlyMethod("clear" /* CLEAR */),
946 forEach: createForEach(true, true)
947 };
948 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
949 iteratorMethods.forEach(method => {
950 mutableInstrumentations[method] = createIterableMethod(method, false, false);
951 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
952 shallowInstrumentations[method] = createIterableMethod(method, false, true);
953 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
954 });
955 function createInstrumentationGetter(isReadonly, shallow) {
956 const instrumentations = shallow
957 ? isReadonly
958 ? shallowReadonlyInstrumentations
959 : shallowInstrumentations
960 : isReadonly
961 ? readonlyInstrumentations
962 : mutableInstrumentations;
963 return (target, key, receiver) => {
964 if (key === "__v_isReactive" /* IS_REACTIVE */) {
965 return !isReadonly;
966 }
967 else if (key === "__v_isReadonly" /* IS_READONLY */) {
968 return isReadonly;
969 }
970 else if (key === "__v_raw" /* RAW */) {
971 return target;
972 }
973 return Reflect.get(hasOwn(instrumentations, key) && key in target
974 ? instrumentations
975 : target, key, receiver);
976 };
977 }
978 const mutableCollectionHandlers = {
979 get: createInstrumentationGetter(false, false)
980 };
981 const shallowCollectionHandlers = {
982 get: createInstrumentationGetter(false, true)
983 };
984 const readonlyCollectionHandlers = {
985 get: createInstrumentationGetter(true, false)
986 };
987 const shallowReadonlyCollectionHandlers = {
988 get: createInstrumentationGetter(true, true)
989 };
990 function checkIdentityKeys(target, has, key) {
991 const rawKey = toRaw(key);
992 if (rawKey !== key && has.call(target, rawKey)) {
993 const type = toRawType(target);
994 console.warn(`Reactive ${type} contains both the raw and reactive ` +
995 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
996 `which can lead to inconsistencies. ` +
997 `Avoid differentiating between the raw and reactive versions ` +
998 `of an object and only use the reactive version if possible.`);
999 }
1000 }
1001
1002 const reactiveMap = new WeakMap();
1003 const shallowReactiveMap = new WeakMap();
1004 const readonlyMap = new WeakMap();
1005 const shallowReadonlyMap = new WeakMap();
1006 function targetTypeMap(rawType) {
1007 switch (rawType) {
1008 case 'Object':
1009 case 'Array':
1010 return 1 /* COMMON */;
1011 case 'Map':
1012 case 'Set':
1013 case 'WeakMap':
1014 case 'WeakSet':
1015 return 2 /* COLLECTION */;
1016 default:
1017 return 0 /* INVALID */;
1018 }
1019 }
1020 function getTargetType(value) {
1021 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1022 ? 0 /* INVALID */
1023 : targetTypeMap(toRawType(value));
1024 }
1025 function reactive(target) {
1026 // if trying to observe a readonly proxy, return the readonly version.
1027 if (target && target["__v_isReadonly" /* IS_READONLY */]) {
1028 return target;
1029 }
1030 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1031 }
1032 /**
1033 * Return a shallowly-reactive copy of the original object, where only the root
1034 * level properties are reactive. It also does not auto-unwrap refs (even at the
1035 * root level).
1036 */
1037 function shallowReactive(target) {
1038 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1039 }
1040 /**
1041 * Creates a readonly copy of the original object. Note the returned copy is not
1042 * made reactive, but `readonly` can be called on an already reactive object.
1043 */
1044 function readonly(target) {
1045 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1046 }
1047 /**
1048 * Returns a reactive-copy of the original object, where only the root level
1049 * properties are readonly, and does NOT unwrap refs nor recursively convert
1050 * returned properties.
1051 * This is used for creating the props proxy object for stateful components.
1052 */
1053 function shallowReadonly(target) {
1054 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1055 }
1056 function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1057 if (!isObject(target)) {
1058 {
1059 console.warn(`value cannot be made reactive: ${String(target)}`);
1060 }
1061 return target;
1062 }
1063 // target is already a Proxy, return it.
1064 // exception: calling readonly() on a reactive object
1065 if (target["__v_raw" /* RAW */] &&
1066 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1067 return target;
1068 }
1069 // target already has corresponding Proxy
1070 const existingProxy = proxyMap.get(target);
1071 if (existingProxy) {
1072 return existingProxy;
1073 }
1074 // only a whitelist of value types can be observed.
1075 const targetType = getTargetType(target);
1076 if (targetType === 0 /* INVALID */) {
1077 return target;
1078 }
1079 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1080 proxyMap.set(target, proxy);
1081 return proxy;
1082 }
1083 function isReactive(value) {
1084 if (isReadonly(value)) {
1085 return isReactive(value["__v_raw" /* RAW */]);
1086 }
1087 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1088 }
1089 function isReadonly(value) {
1090 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1091 }
1092 function isProxy(value) {
1093 return isReactive(value) || isReadonly(value);
1094 }
1095 function toRaw(observed) {
1096 return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed);
1097 }
1098 function markRaw(value) {
1099 def(value, "__v_skip" /* SKIP */, true);
1100 return value;
1101 }
1102
1103 const convert = (val) => isObject(val) ? reactive(val) : val;
1104 function isRef(r) {
1105 return Boolean(r && r.__v_isRef === true);
1106 }
1107 function ref(value) {
1108 return createRef(value);
1109 }
1110 function shallowRef(value) {
1111 return createRef(value, true);
1112 }
1113 class RefImpl {
1114 constructor(_rawValue, _shallow = false) {
1115 this._rawValue = _rawValue;
1116 this._shallow = _shallow;
1117 this.__v_isRef = true;
1118 this._value = _shallow ? _rawValue : convert(_rawValue);
1119 }
1120 get value() {
1121 track(toRaw(this), "get" /* GET */, 'value');
1122 return this._value;
1123 }
1124 set value(newVal) {
1125 if (hasChanged(toRaw(newVal), this._rawValue)) {
1126 this._rawValue = newVal;
1127 this._value = this._shallow ? newVal : convert(newVal);
1128 trigger(toRaw(this), "set" /* SET */, 'value', newVal);
1129 }
1130 }
1131 }
1132 function createRef(rawValue, shallow = false) {
1133 if (isRef(rawValue)) {
1134 return rawValue;
1135 }
1136 return new RefImpl(rawValue, shallow);
1137 }
1138 function triggerRef(ref) {
1139 trigger(toRaw(ref), "set" /* SET */, 'value', ref.value );
1140 }
1141 function unref(ref) {
1142 return isRef(ref) ? ref.value : ref;
1143 }
1144 const shallowUnwrapHandlers = {
1145 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1146 set: (target, key, value, receiver) => {
1147 const oldValue = target[key];
1148 if (isRef(oldValue) && !isRef(value)) {
1149 oldValue.value = value;
1150 return true;
1151 }
1152 else {
1153 return Reflect.set(target, key, value, receiver);
1154 }
1155 }
1156 };
1157 function proxyRefs(objectWithRefs) {
1158 return isReactive(objectWithRefs)
1159 ? objectWithRefs
1160 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1161 }
1162 class CustomRefImpl {
1163 constructor(factory) {
1164 this.__v_isRef = true;
1165 const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value'));
1166 this._get = get;
1167 this._set = set;
1168 }
1169 get value() {
1170 return this._get();
1171 }
1172 set value(newVal) {
1173 this._set(newVal);
1174 }
1175 }
1176 function customRef(factory) {
1177 return new CustomRefImpl(factory);
1178 }
1179 function toRefs(object) {
1180 if (!isProxy(object)) {
1181 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1182 }
1183 const ret = isArray(object) ? new Array(object.length) : {};
1184 for (const key in object) {
1185 ret[key] = toRef(object, key);
1186 }
1187 return ret;
1188 }
1189 class ObjectRefImpl {
1190 constructor(_object, _key) {
1191 this._object = _object;
1192 this._key = _key;
1193 this.__v_isRef = true;
1194 }
1195 get value() {
1196 return this._object[this._key];
1197 }
1198 set value(newVal) {
1199 this._object[this._key] = newVal;
1200 }
1201 }
1202 function toRef(object, key) {
1203 return isRef(object[key])
1204 ? object[key]
1205 : new ObjectRefImpl(object, key);
1206 }
1207
1208 class ComputedRefImpl {
1209 constructor(getter, _setter, isReadonly) {
1210 this._setter = _setter;
1211 this._dirty = true;
1212 this.__v_isRef = true;
1213 this.effect = effect(getter, {
1214 lazy: true,
1215 scheduler: () => {
1216 if (!this._dirty) {
1217 this._dirty = true;
1218 trigger(toRaw(this), "set" /* SET */, 'value');
1219 }
1220 }
1221 });
1222 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1223 }
1224 get value() {
1225 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1226 const self = toRaw(this);
1227 if (self._dirty) {
1228 self._value = this.effect();
1229 self._dirty = false;
1230 }
1231 track(self, "get" /* GET */, 'value');
1232 return self._value;
1233 }
1234 set value(newValue) {
1235 this._setter(newValue);
1236 }
1237 }
1238 function computed(getterOrOptions) {
1239 let getter;
1240 let setter;
1241 if (isFunction(getterOrOptions)) {
1242 getter = getterOrOptions;
1243 setter = () => {
1244 console.warn('Write operation failed: computed value is readonly');
1245 }
1246 ;
1247 }
1248 else {
1249 getter = getterOrOptions.get;
1250 setter = getterOrOptions.set;
1251 }
1252 return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);
1253 }
1254
1255 const stack = [];
1256 function pushWarningContext(vnode) {
1257 stack.push(vnode);
1258 }
1259 function popWarningContext() {
1260 stack.pop();
1261 }
1262 function warn(msg, ...args) {
1263 // avoid props formatting or warn handler tracking deps that might be mutated
1264 // during patch, leading to infinite recursion.
1265 pauseTracking();
1266 const instance = stack.length ? stack[stack.length - 1].component : null;
1267 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1268 const trace = getComponentTrace();
1269 if (appWarnHandler) {
1270 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1271 msg + args.join(''),
1272 instance && instance.proxy,
1273 trace
1274 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1275 .join('\n'),
1276 trace
1277 ]);
1278 }
1279 else {
1280 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1281 /* istanbul ignore if */
1282 if (trace.length &&
1283 // avoid spamming console during tests
1284 !false) {
1285 warnArgs.push(`\n`, ...formatTrace(trace));
1286 }
1287 console.warn(...warnArgs);
1288 }
1289 resetTracking();
1290 }
1291 function getComponentTrace() {
1292 let currentVNode = stack[stack.length - 1];
1293 if (!currentVNode) {
1294 return [];
1295 }
1296 // we can't just use the stack because it will be incomplete during updates
1297 // that did not start from the root. Re-construct the parent chain using
1298 // instance parent pointers.
1299 const normalizedStack = [];
1300 while (currentVNode) {
1301 const last = normalizedStack[0];
1302 if (last && last.vnode === currentVNode) {
1303 last.recurseCount++;
1304 }
1305 else {
1306 normalizedStack.push({
1307 vnode: currentVNode,
1308 recurseCount: 0
1309 });
1310 }
1311 const parentInstance = currentVNode.component && currentVNode.component.parent;
1312 currentVNode = parentInstance && parentInstance.vnode;
1313 }
1314 return normalizedStack;
1315 }
1316 /* istanbul ignore next */
1317 function formatTrace(trace) {
1318 const logs = [];
1319 trace.forEach((entry, i) => {
1320 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1321 });
1322 return logs;
1323 }
1324 function formatTraceEntry({ vnode, recurseCount }) {
1325 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1326 const isRoot = vnode.component ? vnode.component.parent == null : false;
1327 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1328 const close = `>` + postfix;
1329 return vnode.props
1330 ? [open, ...formatProps(vnode.props), close]
1331 : [open + close];
1332 }
1333 /* istanbul ignore next */
1334 function formatProps(props) {
1335 const res = [];
1336 const keys = Object.keys(props);
1337 keys.slice(0, 3).forEach(key => {
1338 res.push(...formatProp(key, props[key]));
1339 });
1340 if (keys.length > 3) {
1341 res.push(` ...`);
1342 }
1343 return res;
1344 }
1345 /* istanbul ignore next */
1346 function formatProp(key, value, raw) {
1347 if (isString(value)) {
1348 value = JSON.stringify(value);
1349 return raw ? value : [`${key}=${value}`];
1350 }
1351 else if (typeof value === 'number' ||
1352 typeof value === 'boolean' ||
1353 value == null) {
1354 return raw ? value : [`${key}=${value}`];
1355 }
1356 else if (isRef(value)) {
1357 value = formatProp(key, toRaw(value.value), true);
1358 return raw ? value : [`${key}=Ref<`, value, `>`];
1359 }
1360 else if (isFunction(value)) {
1361 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1362 }
1363 else {
1364 value = toRaw(value);
1365 return raw ? value : [`${key}=`, value];
1366 }
1367 }
1368
1369 const ErrorTypeStrings = {
1370 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1371 ["c" /* CREATED */]: 'created hook',
1372 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1373 ["m" /* MOUNTED */]: 'mounted hook',
1374 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1375 ["u" /* UPDATED */]: 'updated',
1376 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1377 ["um" /* UNMOUNTED */]: 'unmounted hook',
1378 ["a" /* ACTIVATED */]: 'activated hook',
1379 ["da" /* DEACTIVATED */]: 'deactivated hook',
1380 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1381 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1382 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1383 [0 /* SETUP_FUNCTION */]: 'setup function',
1384 [1 /* RENDER_FUNCTION */]: 'render function',
1385 [2 /* WATCH_GETTER */]: 'watcher getter',
1386 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1387 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1388 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1389 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1390 [7 /* VNODE_HOOK */]: 'vnode hook',
1391 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1392 [9 /* TRANSITION_HOOK */]: 'transition hook',
1393 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1394 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1395 [12 /* FUNCTION_REF */]: 'ref function',
1396 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1397 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1398 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
1399 };
1400 function callWithErrorHandling(fn, instance, type, args) {
1401 let res;
1402 try {
1403 res = args ? fn(...args) : fn();
1404 }
1405 catch (err) {
1406 handleError(err, instance, type);
1407 }
1408 return res;
1409 }
1410 function callWithAsyncErrorHandling(fn, instance, type, args) {
1411 if (isFunction(fn)) {
1412 const res = callWithErrorHandling(fn, instance, type, args);
1413 if (res && isPromise(res)) {
1414 res.catch(err => {
1415 handleError(err, instance, type);
1416 });
1417 }
1418 return res;
1419 }
1420 const values = [];
1421 for (let i = 0; i < fn.length; i++) {
1422 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1423 }
1424 return values;
1425 }
1426 function handleError(err, instance, type, throwInDev = true) {
1427 const contextVNode = instance ? instance.vnode : null;
1428 if (instance) {
1429 let cur = instance.parent;
1430 // the exposed instance is the render proxy to keep it consistent with 2.x
1431 const exposedInstance = instance.proxy;
1432 // in production the hook receives only the error code
1433 const errorInfo = ErrorTypeStrings[type] ;
1434 while (cur) {
1435 const errorCapturedHooks = cur.ec;
1436 if (errorCapturedHooks) {
1437 for (let i = 0; i < errorCapturedHooks.length; i++) {
1438 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1439 return;
1440 }
1441 }
1442 }
1443 cur = cur.parent;
1444 }
1445 // app-level handling
1446 const appErrorHandler = instance.appContext.config.errorHandler;
1447 if (appErrorHandler) {
1448 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1449 return;
1450 }
1451 }
1452 logError(err, type, contextVNode, throwInDev);
1453 }
1454 function logError(err, type, contextVNode, throwInDev = true) {
1455 {
1456 const info = ErrorTypeStrings[type];
1457 if (contextVNode) {
1458 pushWarningContext(contextVNode);
1459 }
1460 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1461 if (contextVNode) {
1462 popWarningContext();
1463 }
1464 // crash in dev by default so it's more noticeable
1465 if (throwInDev) {
1466 throw err;
1467 }
1468 else {
1469 console.error(err);
1470 }
1471 }
1472 }
1473
1474 let isFlushing = false;
1475 let isFlushPending = false;
1476 const queue = [];
1477 let flushIndex = 0;
1478 const pendingPreFlushCbs = [];
1479 let activePreFlushCbs = null;
1480 let preFlushIndex = 0;
1481 const pendingPostFlushCbs = [];
1482 let activePostFlushCbs = null;
1483 let postFlushIndex = 0;
1484 const resolvedPromise = Promise.resolve();
1485 let currentFlushPromise = null;
1486 let currentPreFlushParentJob = null;
1487 const RECURSION_LIMIT = 100;
1488 function nextTick(fn) {
1489 const p = currentFlushPromise || resolvedPromise;
1490 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1491 }
1492 // #2768
1493 // Use binary-search to find a suitable position in the queue,
1494 // so that the queue maintains the increasing order of job's id,
1495 // which can prevent the job from being skipped and also can avoid repeated patching.
1496 function findInsertionIndex(job) {
1497 // the start index should be `flushIndex + 1`
1498 let start = flushIndex + 1;
1499 let end = queue.length;
1500 const jobId = getId(job);
1501 while (start < end) {
1502 const middle = (start + end) >>> 1;
1503 const middleJobId = getId(queue[middle]);
1504 middleJobId < jobId ? (start = middle + 1) : (end = middle);
1505 }
1506 return start;
1507 }
1508 function queueJob(job) {
1509 // the dedupe search uses the startIndex argument of Array.includes()
1510 // by default the search index includes the current job that is being run
1511 // so it cannot recursively trigger itself again.
1512 // if the job is a watch() callback, the search will start with a +1 index to
1513 // allow it recursively trigger itself - it is the user's responsibility to
1514 // ensure it doesn't end up in an infinite loop.
1515 if ((!queue.length ||
1516 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1517 job !== currentPreFlushParentJob) {
1518 const pos = findInsertionIndex(job);
1519 if (pos > -1) {
1520 queue.splice(pos, 0, job);
1521 }
1522 else {
1523 queue.push(job);
1524 }
1525 queueFlush();
1526 }
1527 }
1528 function queueFlush() {
1529 if (!isFlushing && !isFlushPending) {
1530 isFlushPending = true;
1531 currentFlushPromise = resolvedPromise.then(flushJobs);
1532 }
1533 }
1534 function invalidateJob(job) {
1535 const i = queue.indexOf(job);
1536 if (i > flushIndex) {
1537 queue.splice(i, 1);
1538 }
1539 }
1540 function queueCb(cb, activeQueue, pendingQueue, index) {
1541 if (!isArray(cb)) {
1542 if (!activeQueue ||
1543 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1544 pendingQueue.push(cb);
1545 }
1546 }
1547 else {
1548 // if cb is an array, it is a component lifecycle hook which can only be
1549 // triggered by a job, which is already deduped in the main queue, so
1550 // we can skip duplicate check here to improve perf
1551 pendingQueue.push(...cb);
1552 }
1553 queueFlush();
1554 }
1555 function queuePreFlushCb(cb) {
1556 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1557 }
1558 function queuePostFlushCb(cb) {
1559 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1560 }
1561 function flushPreFlushCbs(seen, parentJob = null) {
1562 if (pendingPreFlushCbs.length) {
1563 currentPreFlushParentJob = parentJob;
1564 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1565 pendingPreFlushCbs.length = 0;
1566 {
1567 seen = seen || new Map();
1568 }
1569 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1570 {
1571 checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex]);
1572 }
1573 activePreFlushCbs[preFlushIndex]();
1574 }
1575 activePreFlushCbs = null;
1576 preFlushIndex = 0;
1577 currentPreFlushParentJob = null;
1578 // recursively flush until it drains
1579 flushPreFlushCbs(seen, parentJob);
1580 }
1581 }
1582 function flushPostFlushCbs(seen) {
1583 if (pendingPostFlushCbs.length) {
1584 const deduped = [...new Set(pendingPostFlushCbs)];
1585 pendingPostFlushCbs.length = 0;
1586 // #1947 already has active queue, nested flushPostFlushCbs call
1587 if (activePostFlushCbs) {
1588 activePostFlushCbs.push(...deduped);
1589 return;
1590 }
1591 activePostFlushCbs = deduped;
1592 {
1593 seen = seen || new Map();
1594 }
1595 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1596 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1597 {
1598 checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex]);
1599 }
1600 activePostFlushCbs[postFlushIndex]();
1601 }
1602 activePostFlushCbs = null;
1603 postFlushIndex = 0;
1604 }
1605 }
1606 const getId = (job) => job.id == null ? Infinity : job.id;
1607 function flushJobs(seen) {
1608 isFlushPending = false;
1609 isFlushing = true;
1610 {
1611 seen = seen || new Map();
1612 }
1613 flushPreFlushCbs(seen);
1614 // Sort queue before flush.
1615 // This ensures that:
1616 // 1. Components are updated from parent to child. (because parent is always
1617 // created before the child so its render effect will have smaller
1618 // priority number)
1619 // 2. If a component is unmounted during a parent component's update,
1620 // its update can be skipped.
1621 queue.sort((a, b) => getId(a) - getId(b));
1622 try {
1623 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1624 const job = queue[flushIndex];
1625 if (job) {
1626 if (true) {
1627 checkRecursiveUpdates(seen, job);
1628 }
1629 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1630 }
1631 }
1632 }
1633 finally {
1634 flushIndex = 0;
1635 queue.length = 0;
1636 flushPostFlushCbs(seen);
1637 isFlushing = false;
1638 currentFlushPromise = null;
1639 // some postFlushCb queued jobs!
1640 // keep flushing until it drains.
1641 if (queue.length || pendingPostFlushCbs.length) {
1642 flushJobs(seen);
1643 }
1644 }
1645 }
1646 function checkRecursiveUpdates(seen, fn) {
1647 if (!seen.has(fn)) {
1648 seen.set(fn, 1);
1649 }
1650 else {
1651 const count = seen.get(fn);
1652 if (count > RECURSION_LIMIT) {
1653 throw new Error(`Maximum recursive updates exceeded. ` +
1654 `This means you have a reactive effect that is mutating its own ` +
1655 `dependencies and thus recursively triggering itself. Possible sources ` +
1656 `include component template, render function, updated hook or ` +
1657 `watcher source function.`);
1658 }
1659 else {
1660 seen.set(fn, count + 1);
1661 }
1662 }
1663 }
1664
1665 /* eslint-disable no-restricted-globals */
1666 let isHmrUpdating = false;
1667 const hmrDirtyComponents = new Set();
1668 // Expose the HMR runtime on the global object
1669 // This makes it entirely tree-shakable without polluting the exports and makes
1670 // it easier to be used in toolings like vue-loader
1671 // Note: for a component to be eligible for HMR it also needs the __hmrId option
1672 // to be set so that its instances can be registered / removed.
1673 {
1674 const globalObject = typeof global !== 'undefined'
1675 ? global
1676 : typeof self !== 'undefined'
1677 ? self
1678 : typeof window !== 'undefined'
1679 ? window
1680 : {};
1681 globalObject.__VUE_HMR_RUNTIME__ = {
1682 createRecord: tryWrap(createRecord),
1683 rerender: tryWrap(rerender),
1684 reload: tryWrap(reload)
1685 };
1686 }
1687 const map = new Map();
1688 function registerHMR(instance) {
1689 const id = instance.type.__hmrId;
1690 let record = map.get(id);
1691 if (!record) {
1692 createRecord(id, instance.type);
1693 record = map.get(id);
1694 }
1695 record.instances.add(instance);
1696 }
1697 function unregisterHMR(instance) {
1698 map.get(instance.type.__hmrId).instances.delete(instance);
1699 }
1700 function createRecord(id, component) {
1701 if (!component) {
1702 warn(`HMR API usage is out of date.\n` +
1703 `Please upgrade vue-loader/vite/rollup-plugin-vue or other relevant ` +
1704 `dependency that handles Vue SFC compilation.`);
1705 component = {};
1706 }
1707 if (map.has(id)) {
1708 return false;
1709 }
1710 map.set(id, {
1711 component: isClassComponent(component) ? component.__vccOpts : component,
1712 instances: new Set()
1713 });
1714 return true;
1715 }
1716 function rerender(id, newRender) {
1717 const record = map.get(id);
1718 if (!record)
1719 return;
1720 if (newRender)
1721 record.component.render = newRender;
1722 // Array.from creates a snapshot which avoids the set being mutated during
1723 // updates
1724 Array.from(record.instances).forEach(instance => {
1725 if (newRender) {
1726 instance.render = newRender;
1727 }
1728 instance.renderCache = [];
1729 // this flag forces child components with slot content to update
1730 isHmrUpdating = true;
1731 instance.update();
1732 isHmrUpdating = false;
1733 });
1734 }
1735 function reload(id, newComp) {
1736 const record = map.get(id);
1737 if (!record)
1738 return;
1739 // Array.from creates a snapshot which avoids the set being mutated during
1740 // updates
1741 const { component, instances } = record;
1742 if (!hmrDirtyComponents.has(component)) {
1743 // 1. Update existing comp definition to match new one
1744 newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp;
1745 extend(component, newComp);
1746 for (const key in component) {
1747 if (!(key in newComp)) {
1748 delete component[key];
1749 }
1750 }
1751 // 2. Mark component dirty. This forces the renderer to replace the component
1752 // on patch.
1753 hmrDirtyComponents.add(component);
1754 // 3. Make sure to unmark the component after the reload.
1755 queuePostFlushCb(() => {
1756 hmrDirtyComponents.delete(component);
1757 });
1758 }
1759 Array.from(instances).forEach(instance => {
1760 if (instance.parent) {
1761 // 4. Force the parent instance to re-render. This will cause all updated
1762 // components to be unmounted and re-mounted. Queue the update so that we
1763 // don't end up forcing the same parent to re-render multiple times.
1764 queueJob(instance.parent.update);
1765 }
1766 else if (instance.appContext.reload) {
1767 // root instance mounted via createApp() has a reload method
1768 instance.appContext.reload();
1769 }
1770 else if (typeof window !== 'undefined') {
1771 // root instance inside tree created via raw render(). Force reload.
1772 window.location.reload();
1773 }
1774 else {
1775 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
1776 }
1777 });
1778 }
1779 function tryWrap(fn) {
1780 return (id, arg) => {
1781 try {
1782 return fn(id, arg);
1783 }
1784 catch (e) {
1785 console.error(e);
1786 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
1787 `Full reload required.`);
1788 }
1789 };
1790 }
1791
1792 function setDevtoolsHook(hook) {
1793 exports.devtools = hook;
1794 }
1795 function devtoolsInitApp(app, version) {
1796 // TODO queue if devtools is undefined
1797 if (!exports.devtools)
1798 return;
1799 exports.devtools.emit("app:init" /* APP_INIT */, app, version, {
1800 Fragment,
1801 Text,
1802 Comment,
1803 Static
1804 });
1805 }
1806 function devtoolsUnmountApp(app) {
1807 if (!exports.devtools)
1808 return;
1809 exports.devtools.emit("app:unmount" /* APP_UNMOUNT */, app);
1810 }
1811 const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
1812 const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
1813 const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
1814 function createDevtoolsComponentHook(hook) {
1815 return (component) => {
1816 if (!exports.devtools)
1817 return;
1818 exports.devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
1819 };
1820 }
1821 function devtoolsComponentEmit(component, event, params) {
1822 if (!exports.devtools)
1823 return;
1824 exports.devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
1825 }
1826
1827 function emit(instance, event, ...rawArgs) {
1828 const props = instance.vnode.props || EMPTY_OBJ;
1829 {
1830 const { emitsOptions, propsOptions: [propsOptions] } = instance;
1831 if (emitsOptions) {
1832 if (!(event in emitsOptions)) {
1833 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
1834 warn(`Component emitted event "${event}" but it is neither declared in ` +
1835 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
1836 }
1837 }
1838 else {
1839 const validator = emitsOptions[event];
1840 if (isFunction(validator)) {
1841 const isValid = validator(...rawArgs);
1842 if (!isValid) {
1843 warn(`Invalid event arguments: event validation failed for event "${event}".`);
1844 }
1845 }
1846 }
1847 }
1848 }
1849 let args = rawArgs;
1850 const isModelListener = event.startsWith('update:');
1851 // for v-model update:xxx events, apply modifiers on args
1852 const modelArg = isModelListener && event.slice(7);
1853 if (modelArg && modelArg in props) {
1854 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
1855 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
1856 if (trim) {
1857 args = rawArgs.map(a => a.trim());
1858 }
1859 else if (number) {
1860 args = rawArgs.map(toNumber);
1861 }
1862 }
1863 {
1864 devtoolsComponentEmit(instance, event, args);
1865 }
1866 {
1867 const lowerCaseEvent = event.toLowerCase();
1868 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
1869 warn(`Event "${lowerCaseEvent}" is emitted in component ` +
1870 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
1871 `Note that HTML attributes are case-insensitive and you cannot use ` +
1872 `v-on to listen to camelCase events when using in-DOM templates. ` +
1873 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
1874 }
1875 }
1876 let handlerName;
1877 let handler = props[(handlerName = toHandlerKey(event))] ||
1878 // also try camelCase event handler (#2249)
1879 props[(handlerName = toHandlerKey(camelize(event)))];
1880 // for v-model update:xxx events, also trigger kebab-case equivalent
1881 // for props passed via kebab-case
1882 if (!handler && isModelListener) {
1883 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
1884 }
1885 if (handler) {
1886 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1887 }
1888 const onceHandler = props[handlerName + `Once`];
1889 if (onceHandler) {
1890 if (!instance.emitted) {
1891 (instance.emitted = {})[handlerName] = true;
1892 }
1893 else if (instance.emitted[handlerName]) {
1894 return;
1895 }
1896 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1897 }
1898 }
1899 function normalizeEmitsOptions(comp, appContext, asMixin = false) {
1900 if (!appContext.deopt && comp.__emits !== undefined) {
1901 return comp.__emits;
1902 }
1903 const raw = comp.emits;
1904 let normalized = {};
1905 // apply mixin/extends props
1906 let hasExtends = false;
1907 if (!isFunction(comp)) {
1908 const extendEmits = (raw) => {
1909 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
1910 if (normalizedFromExtend) {
1911 hasExtends = true;
1912 extend(normalized, normalizedFromExtend);
1913 }
1914 };
1915 if (!asMixin && appContext.mixins.length) {
1916 appContext.mixins.forEach(extendEmits);
1917 }
1918 if (comp.extends) {
1919 extendEmits(comp.extends);
1920 }
1921 if (comp.mixins) {
1922 comp.mixins.forEach(extendEmits);
1923 }
1924 }
1925 if (!raw && !hasExtends) {
1926 return (comp.__emits = null);
1927 }
1928 if (isArray(raw)) {
1929 raw.forEach(key => (normalized[key] = null));
1930 }
1931 else {
1932 extend(normalized, raw);
1933 }
1934 return (comp.__emits = normalized);
1935 }
1936 // Check if an incoming prop key is a declared emit event listener.
1937 // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
1938 // both considered matched listeners.
1939 function isEmitListener(options, key) {
1940 if (!options || !isOn(key)) {
1941 return false;
1942 }
1943 key = key.slice(2).replace(/Once$/, '');
1944 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
1945 hasOwn(options, hyphenate(key)) ||
1946 hasOwn(options, key));
1947 }
1948
1949 let isRenderingCompiledSlot = 0;
1950 const setCompiledSlotRendering = (n) => (isRenderingCompiledSlot += n);
1951 /**
1952 * Compiler runtime helper for rendering `<slot/>`
1953 * @private
1954 */
1955 function renderSlot(slots, name, props = {},
1956 // this is not a user-facing function, so the fallback is always generated by
1957 // the compiler and guaranteed to be a function returning an array
1958 fallback, noSlotted) {
1959 let slot = slots[name];
1960 if (slot && slot.length > 1) {
1961 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
1962 `function. You need to mark this component with $dynamic-slots in the ` +
1963 `parent template.`);
1964 slot = () => [];
1965 }
1966 // a compiled slot disables block tracking by default to avoid manual
1967 // invocation interfering with template-based block tracking, but in
1968 // `renderSlot` we can be sure that it's template-based so we can force
1969 // enable it.
1970 isRenderingCompiledSlot++;
1971 openBlock();
1972 const validSlotContent = slot && ensureValidVNode(slot(props));
1973 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
1974 ? 64 /* STABLE_FRAGMENT */
1975 : -2 /* BAIL */);
1976 if (!noSlotted && rendered.scopeId) {
1977 rendered.slotScopeIds = [rendered.scopeId + '-s'];
1978 }
1979 isRenderingCompiledSlot--;
1980 return rendered;
1981 }
1982 function ensureValidVNode(vnodes) {
1983 return vnodes.some(child => {
1984 if (!isVNode(child))
1985 return true;
1986 if (child.type === Comment)
1987 return false;
1988 if (child.type === Fragment &&
1989 !ensureValidVNode(child.children))
1990 return false;
1991 return true;
1992 })
1993 ? vnodes
1994 : null;
1995 }
1996
1997 /**
1998 * mark the current rendering instance for asset resolution (e.g.
1999 * resolveComponent, resolveDirective) during render
2000 */
2001 let currentRenderingInstance = null;
2002 let currentScopeId = null;
2003 /**
2004 * Note: rendering calls maybe nested. The function returns the parent rendering
2005 * instance if present, which should be restored after the render is done:
2006 *
2007 * ```js
2008 * const prev = setCurrentRenderingInstance(i)
2009 * // ...render
2010 * setCurrentRenderingInstance(prev)
2011 * ```
2012 */
2013 function setCurrentRenderingInstance(instance) {
2014 const prev = currentRenderingInstance;
2015 currentRenderingInstance = instance;
2016 currentScopeId = (instance && instance.type.__scopeId) || null;
2017 return prev;
2018 }
2019 /**
2020 * Set scope id when creating hoisted vnodes.
2021 * @private compiler helper
2022 */
2023 function pushScopeId(id) {
2024 currentScopeId = id;
2025 }
2026 /**
2027 * Technically we no longer need this after 3.0.8 but we need to keep the same
2028 * API for backwards compat w/ code generated by compilers.
2029 * @private
2030 */
2031 function popScopeId() {
2032 currentScopeId = null;
2033 }
2034 /**
2035 * Only for backwards compat
2036 * @private
2037 */
2038 const withScopeId = (_id) => withCtx;
2039 /**
2040 * Wrap a slot function to memoize current rendering instance
2041 * @private compiler helper
2042 */
2043 function withCtx(fn, ctx = currentRenderingInstance) {
2044 if (!ctx)
2045 return fn;
2046 const renderFnWithContext = (...args) => {
2047 // If a user calls a compiled slot inside a template expression (#1745), it
2048 // can mess up block tracking, so by default we need to push a null block to
2049 // avoid that. This isn't necessary if rendering a compiled `<slot>`.
2050 if (!isRenderingCompiledSlot) {
2051 openBlock(true /* null block that disables tracking */);
2052 }
2053 const prevInstance = setCurrentRenderingInstance(ctx);
2054 const res = fn(...args);
2055 setCurrentRenderingInstance(prevInstance);
2056 if (!isRenderingCompiledSlot) {
2057 closeBlock();
2058 }
2059 return res;
2060 };
2061 // mark this as a compiled slot function.
2062 // this is used in vnode.ts -> normalizeChildren() to set the slot
2063 // rendering flag.
2064 renderFnWithContext._c = true;
2065 return renderFnWithContext;
2066 }
2067
2068 /**
2069 * dev only flag to track whether $attrs was used during render.
2070 * If $attrs was used during render then the warning for failed attrs
2071 * fallthrough can be suppressed.
2072 */
2073 let accessedAttrs = false;
2074 function markAttrsAccessed() {
2075 accessedAttrs = true;
2076 }
2077 function renderComponentRoot(instance) {
2078 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance;
2079 let result;
2080 const prev = setCurrentRenderingInstance(instance);
2081 {
2082 accessedAttrs = false;
2083 }
2084 try {
2085 let fallthroughAttrs;
2086 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
2087 // withProxy is a proxy with a different `has` trap only for
2088 // runtime-compiled render functions using `with` block.
2089 const proxyToUse = withProxy || proxy;
2090 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2091 fallthroughAttrs = attrs;
2092 }
2093 else {
2094 // functional
2095 const render = Component;
2096 // in dev, mark attrs accessed if optional props (attrs === props)
2097 if (true && attrs === props) {
2098 markAttrsAccessed();
2099 }
2100 result = normalizeVNode(render.length > 1
2101 ? render(props, true
2102 ? {
2103 get attrs() {
2104 markAttrsAccessed();
2105 return attrs;
2106 },
2107 slots,
2108 emit
2109 }
2110 : { attrs, slots, emit })
2111 : render(props, null /* we know it doesn't need it */));
2112 fallthroughAttrs = Component.props
2113 ? attrs
2114 : getFunctionalFallthrough(attrs);
2115 }
2116 // attr merging
2117 // in dev mode, comments are preserved, and it's possible for a template
2118 // to have comments along side the root element which makes it a fragment
2119 let root = result;
2120 let setRoot = undefined;
2121 if (true &&
2122 result.patchFlag > 0 &&
2123 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
2124 ;
2125 [root, setRoot] = getChildRoot(result);
2126 }
2127 if (Component.inheritAttrs !== false && fallthroughAttrs) {
2128 const keys = Object.keys(fallthroughAttrs);
2129 const { shapeFlag } = root;
2130 if (keys.length) {
2131 if (shapeFlag & 1 /* ELEMENT */ ||
2132 shapeFlag & 6 /* COMPONENT */) {
2133 if (propsOptions && keys.some(isModelListener)) {
2134 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2135 // prop, it indicates this component expects to handle v-model and
2136 // it should not fallthrough.
2137 // related: #1543, #1643, #1989
2138 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2139 }
2140 root = cloneVNode(root, fallthroughAttrs);
2141 }
2142 else if (true && !accessedAttrs && root.type !== Comment) {
2143 const allAttrs = Object.keys(attrs);
2144 const eventAttrs = [];
2145 const extraAttrs = [];
2146 for (let i = 0, l = allAttrs.length; i < l; i++) {
2147 const key = allAttrs[i];
2148 if (isOn(key)) {
2149 // ignore v-model handlers when they fail to fallthrough
2150 if (!isModelListener(key)) {
2151 // remove `on`, lowercase first letter to reflect event casing
2152 // accurately
2153 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2154 }
2155 }
2156 else {
2157 extraAttrs.push(key);
2158 }
2159 }
2160 if (extraAttrs.length) {
2161 warn(`Extraneous non-props attributes (` +
2162 `${extraAttrs.join(', ')}) ` +
2163 `were passed to component but could not be automatically inherited ` +
2164 `because component renders fragment or text root nodes.`);
2165 }
2166 if (eventAttrs.length) {
2167 warn(`Extraneous non-emits event listeners (` +
2168 `${eventAttrs.join(', ')}) ` +
2169 `were passed to component but could not be automatically inherited ` +
2170 `because component renders fragment or text root nodes. ` +
2171 `If the listener is intended to be a component custom event listener only, ` +
2172 `declare it using the "emits" option.`);
2173 }
2174 }
2175 }
2176 }
2177 // inherit directives
2178 if (vnode.dirs) {
2179 if (true && !isElementRoot(root)) {
2180 warn(`Runtime directive used on component with non-element root node. ` +
2181 `The directives will not function as intended.`);
2182 }
2183 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2184 }
2185 // inherit transition data
2186 if (vnode.transition) {
2187 if (true && !isElementRoot(root)) {
2188 warn(`Component inside <Transition> renders non-element root node ` +
2189 `that cannot be animated.`);
2190 }
2191 root.transition = vnode.transition;
2192 }
2193 if (true && setRoot) {
2194 setRoot(root);
2195 }
2196 else {
2197 result = root;
2198 }
2199 }
2200 catch (err) {
2201 blockStack.length = 0;
2202 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2203 result = createVNode(Comment);
2204 }
2205 setCurrentRenderingInstance(prev);
2206 return result;
2207 }
2208 /**
2209 * dev only
2210 * In dev mode, template root level comments are rendered, which turns the
2211 * template into a fragment root, but we need to locate the single element
2212 * root for attrs and scope id processing.
2213 */
2214 const getChildRoot = (vnode) => {
2215 const rawChildren = vnode.children;
2216 const dynamicChildren = vnode.dynamicChildren;
2217 const childRoot = filterSingleRoot(rawChildren);
2218 if (!childRoot) {
2219 return [vnode, undefined];
2220 }
2221 const index = rawChildren.indexOf(childRoot);
2222 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2223 const setRoot = (updatedRoot) => {
2224 rawChildren[index] = updatedRoot;
2225 if (dynamicChildren) {
2226 if (dynamicIndex > -1) {
2227 dynamicChildren[dynamicIndex] = updatedRoot;
2228 }
2229 else if (updatedRoot.patchFlag > 0) {
2230 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2231 }
2232 }
2233 };
2234 return [normalizeVNode(childRoot), setRoot];
2235 };
2236 function filterSingleRoot(children) {
2237 let singleRoot;
2238 for (let i = 0; i < children.length; i++) {
2239 const child = children[i];
2240 if (isVNode(child)) {
2241 // ignore user comment
2242 if (child.type !== Comment || child.children === 'v-if') {
2243 if (singleRoot) {
2244 // has more than 1 non-comment child, return now
2245 return;
2246 }
2247 else {
2248 singleRoot = child;
2249 }
2250 }
2251 }
2252 else {
2253 return;
2254 }
2255 }
2256 return singleRoot;
2257 }
2258 const getFunctionalFallthrough = (attrs) => {
2259 let res;
2260 for (const key in attrs) {
2261 if (key === 'class' || key === 'style' || isOn(key)) {
2262 (res || (res = {}))[key] = attrs[key];
2263 }
2264 }
2265 return res;
2266 };
2267 const filterModelListeners = (attrs, props) => {
2268 const res = {};
2269 for (const key in attrs) {
2270 if (!isModelListener(key) || !(key.slice(9) in props)) {
2271 res[key] = attrs[key];
2272 }
2273 }
2274 return res;
2275 };
2276 const isElementRoot = (vnode) => {
2277 return (vnode.shapeFlag & 6 /* COMPONENT */ ||
2278 vnode.shapeFlag & 1 /* ELEMENT */ ||
2279 vnode.type === Comment // potential v-if branch switch
2280 );
2281 };
2282 function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2283 const { props: prevProps, children: prevChildren, component } = prevVNode;
2284 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2285 const emits = component.emitsOptions;
2286 // Parent component's render function was hot-updated. Since this may have
2287 // caused the child component's slots content to have changed, we need to
2288 // force the child to update as well.
2289 if ((prevChildren || nextChildren) && isHmrUpdating) {
2290 return true;
2291 }
2292 // force child update for runtime directive or transition on component vnode.
2293 if (nextVNode.dirs || nextVNode.transition) {
2294 return true;
2295 }
2296 if (optimized && patchFlag >= 0) {
2297 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2298 // slot content that references values that might have changed,
2299 // e.g. in a v-for
2300 return true;
2301 }
2302 if (patchFlag & 16 /* FULL_PROPS */) {
2303 if (!prevProps) {
2304 return !!nextProps;
2305 }
2306 // presence of this flag indicates props are always non-null
2307 return hasPropsChanged(prevProps, nextProps, emits);
2308 }
2309 else if (patchFlag & 8 /* PROPS */) {
2310 const dynamicProps = nextVNode.dynamicProps;
2311 for (let i = 0; i < dynamicProps.length; i++) {
2312 const key = dynamicProps[i];
2313 if (nextProps[key] !== prevProps[key] &&
2314 !isEmitListener(emits, key)) {
2315 return true;
2316 }
2317 }
2318 }
2319 }
2320 else {
2321 // this path is only taken by manually written render functions
2322 // so presence of any children leads to a forced update
2323 if (prevChildren || nextChildren) {
2324 if (!nextChildren || !nextChildren.$stable) {
2325 return true;
2326 }
2327 }
2328 if (prevProps === nextProps) {
2329 return false;
2330 }
2331 if (!prevProps) {
2332 return !!nextProps;
2333 }
2334 if (!nextProps) {
2335 return true;
2336 }
2337 return hasPropsChanged(prevProps, nextProps, emits);
2338 }
2339 return false;
2340 }
2341 function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2342 const nextKeys = Object.keys(nextProps);
2343 if (nextKeys.length !== Object.keys(prevProps).length) {
2344 return true;
2345 }
2346 for (let i = 0; i < nextKeys.length; i++) {
2347 const key = nextKeys[i];
2348 if (nextProps[key] !== prevProps[key] &&
2349 !isEmitListener(emitsOptions, key)) {
2350 return true;
2351 }
2352 }
2353 return false;
2354 }
2355 function updateHOCHostEl({ vnode, parent }, el // HostNode
2356 ) {
2357 while (parent && parent.subTree === vnode) {
2358 (vnode = parent.vnode).el = el;
2359 parent = parent.parent;
2360 }
2361 }
2362
2363 const isSuspense = (type) => type.__isSuspense;
2364 // Suspense exposes a component-like API, and is treated like a component
2365 // in the compiler, but internally it's a special built-in type that hooks
2366 // directly into the renderer.
2367 const SuspenseImpl = {
2368 name: 'Suspense',
2369 // In order to make Suspense tree-shakable, we need to avoid importing it
2370 // directly in the renderer. The renderer checks for the __isSuspense flag
2371 // on a vnode's type and calls the `process` method, passing in renderer
2372 // internals.
2373 __isSuspense: true,
2374 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2375 // platform-specific impl passed from renderer
2376 rendererInternals) {
2377 if (n1 == null) {
2378 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2379 }
2380 else {
2381 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2382 }
2383 },
2384 hydrate: hydrateSuspense,
2385 create: createSuspenseBoundary
2386 };
2387 // Force-casted public typing for h and TSX props inference
2388 const Suspense = (SuspenseImpl
2389 );
2390 function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2391 const { p: patch, o: { createElement } } = rendererInternals;
2392 const hiddenContainer = createElement('div');
2393 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2394 // start mounting the content subtree in an off-dom container
2395 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2396 // now check if we have encountered any async deps
2397 if (suspense.deps > 0) {
2398 // has async
2399 // mount the fallback tree
2400 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2401 isSVG, slotScopeIds);
2402 setActiveBranch(suspense, vnode.ssFallback);
2403 }
2404 else {
2405 // Suspense has no async deps. Just resolve.
2406 suspense.resolve();
2407 }
2408 }
2409 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2410 const suspense = (n2.suspense = n1.suspense);
2411 suspense.vnode = n2;
2412 n2.el = n1.el;
2413 const newBranch = n2.ssContent;
2414 const newFallback = n2.ssFallback;
2415 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2416 if (pendingBranch) {
2417 suspense.pendingBranch = newBranch;
2418 if (isSameVNodeType(newBranch, pendingBranch)) {
2419 // same root type but content may have changed.
2420 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2421 if (suspense.deps <= 0) {
2422 suspense.resolve();
2423 }
2424 else if (isInFallback) {
2425 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2426 isSVG, slotScopeIds, optimized);
2427 setActiveBranch(suspense, newFallback);
2428 }
2429 }
2430 else {
2431 // toggled before pending tree is resolved
2432 suspense.pendingId++;
2433 if (isHydrating) {
2434 // if toggled before hydration is finished, the current DOM tree is
2435 // no longer valid. set it as the active branch so it will be unmounted
2436 // when resolved
2437 suspense.isHydrating = false;
2438 suspense.activeBranch = pendingBranch;
2439 }
2440 else {
2441 unmount(pendingBranch, parentComponent, suspense);
2442 }
2443 // increment pending ID. this is used to invalidate async callbacks
2444 // reset suspense state
2445 suspense.deps = 0;
2446 // discard effects from pending branch
2447 suspense.effects.length = 0;
2448 // discard previous container
2449 suspense.hiddenContainer = createElement('div');
2450 if (isInFallback) {
2451 // already in fallback state
2452 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2453 if (suspense.deps <= 0) {
2454 suspense.resolve();
2455 }
2456 else {
2457 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2458 isSVG, slotScopeIds, optimized);
2459 setActiveBranch(suspense, newFallback);
2460 }
2461 }
2462 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2463 // toggled "back" to current active branch
2464 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2465 // force resolve
2466 suspense.resolve(true);
2467 }
2468 else {
2469 // switched to a 3rd branch
2470 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2471 if (suspense.deps <= 0) {
2472 suspense.resolve();
2473 }
2474 }
2475 }
2476 }
2477 else {
2478 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2479 // root did not change, just normal patch
2480 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2481 setActiveBranch(suspense, newBranch);
2482 }
2483 else {
2484 // root node toggled
2485 // invoke @pending event
2486 const onPending = n2.props && n2.props.onPending;
2487 if (isFunction(onPending)) {
2488 onPending();
2489 }
2490 // mount pending branch in off-dom container
2491 suspense.pendingBranch = newBranch;
2492 suspense.pendingId++;
2493 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2494 if (suspense.deps <= 0) {
2495 // incoming branch has no async deps, resolve now.
2496 suspense.resolve();
2497 }
2498 else {
2499 const { timeout, pendingId } = suspense;
2500 if (timeout > 0) {
2501 setTimeout(() => {
2502 if (suspense.pendingId === pendingId) {
2503 suspense.fallback(newFallback);
2504 }
2505 }, timeout);
2506 }
2507 else if (timeout === 0) {
2508 suspense.fallback(newFallback);
2509 }
2510 }
2511 }
2512 }
2513 }
2514 let hasWarned = false;
2515 function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2516 /* istanbul ignore if */
2517 if (!hasWarned) {
2518 hasWarned = true;
2519 // @ts-ignore `console.info` cannot be null error
2520 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2521 }
2522 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2523 const timeout = toNumber(vnode.props && vnode.props.timeout);
2524 const suspense = {
2525 vnode,
2526 parent,
2527 parentComponent,
2528 isSVG,
2529 container,
2530 hiddenContainer,
2531 anchor,
2532 deps: 0,
2533 pendingId: 0,
2534 timeout: typeof timeout === 'number' ? timeout : -1,
2535 activeBranch: null,
2536 pendingBranch: null,
2537 isInFallback: true,
2538 isHydrating,
2539 isUnmounted: false,
2540 effects: [],
2541 resolve(resume = false) {
2542 {
2543 if (!resume && !suspense.pendingBranch) {
2544 throw new Error(`suspense.resolve() is called without a pending branch.`);
2545 }
2546 if (suspense.isUnmounted) {
2547 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2548 }
2549 }
2550 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2551 if (suspense.isHydrating) {
2552 suspense.isHydrating = false;
2553 }
2554 else if (!resume) {
2555 const delayEnter = activeBranch &&
2556 pendingBranch.transition &&
2557 pendingBranch.transition.mode === 'out-in';
2558 if (delayEnter) {
2559 activeBranch.transition.afterLeave = () => {
2560 if (pendingId === suspense.pendingId) {
2561 move(pendingBranch, container, anchor, 0 /* ENTER */);
2562 }
2563 };
2564 }
2565 // this is initial anchor on mount
2566 let { anchor } = suspense;
2567 // unmount current active tree
2568 if (activeBranch) {
2569 // if the fallback tree was mounted, it may have been moved
2570 // as part of a parent suspense. get the latest anchor for insertion
2571 anchor = next(activeBranch);
2572 unmount(activeBranch, parentComponent, suspense, true);
2573 }
2574 if (!delayEnter) {
2575 // move content from off-dom container to actual container
2576 move(pendingBranch, container, anchor, 0 /* ENTER */);
2577 }
2578 }
2579 setActiveBranch(suspense, pendingBranch);
2580 suspense.pendingBranch = null;
2581 suspense.isInFallback = false;
2582 // flush buffered effects
2583 // check if there is a pending parent suspense
2584 let parent = suspense.parent;
2585 let hasUnresolvedAncestor = false;
2586 while (parent) {
2587 if (parent.pendingBranch) {
2588 // found a pending parent suspense, merge buffered post jobs
2589 // into that parent
2590 parent.effects.push(...effects);
2591 hasUnresolvedAncestor = true;
2592 break;
2593 }
2594 parent = parent.parent;
2595 }
2596 // no pending parent suspense, flush all jobs
2597 if (!hasUnresolvedAncestor) {
2598 queuePostFlushCb(effects);
2599 }
2600 suspense.effects = [];
2601 // invoke @resolve event
2602 const onResolve = vnode.props && vnode.props.onResolve;
2603 if (isFunction(onResolve)) {
2604 onResolve();
2605 }
2606 },
2607 fallback(fallbackVNode) {
2608 if (!suspense.pendingBranch) {
2609 return;
2610 }
2611 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2612 // invoke @fallback event
2613 const onFallback = vnode.props && vnode.props.onFallback;
2614 if (isFunction(onFallback)) {
2615 onFallback();
2616 }
2617 const anchor = next(activeBranch);
2618 const mountFallback = () => {
2619 if (!suspense.isInFallback) {
2620 return;
2621 }
2622 // mount the fallback tree
2623 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2624 isSVG, slotScopeIds, optimized);
2625 setActiveBranch(suspense, fallbackVNode);
2626 };
2627 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
2628 if (delayEnter) {
2629 activeBranch.transition.afterLeave = mountFallback;
2630 }
2631 // unmount current active branch
2632 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
2633 true // shouldRemove
2634 );
2635 suspense.isInFallback = true;
2636 if (!delayEnter) {
2637 mountFallback();
2638 }
2639 },
2640 move(container, anchor, type) {
2641 suspense.activeBranch &&
2642 move(suspense.activeBranch, container, anchor, type);
2643 suspense.container = container;
2644 },
2645 next() {
2646 return suspense.activeBranch && next(suspense.activeBranch);
2647 },
2648 registerDep(instance, setupRenderEffect) {
2649 const isInPendingSuspense = !!suspense.pendingBranch;
2650 if (isInPendingSuspense) {
2651 suspense.deps++;
2652 }
2653 const hydratedEl = instance.vnode.el;
2654 instance
2655 .asyncDep.catch(err => {
2656 handleError(err, instance, 0 /* SETUP_FUNCTION */);
2657 })
2658 .then(asyncSetupResult => {
2659 // retry when the setup() promise resolves.
2660 // component may have been unmounted before resolve.
2661 if (instance.isUnmounted ||
2662 suspense.isUnmounted ||
2663 suspense.pendingId !== instance.suspenseId) {
2664 return;
2665 }
2666 // retry from this component
2667 instance.asyncResolved = true;
2668 const { vnode } = instance;
2669 {
2670 pushWarningContext(vnode);
2671 }
2672 handleSetupResult(instance, asyncSetupResult, false);
2673 if (hydratedEl) {
2674 // vnode may have been replaced if an update happened before the
2675 // async dep is resolved.
2676 vnode.el = hydratedEl;
2677 }
2678 const placeholder = !hydratedEl && instance.subTree.el;
2679 setupRenderEffect(instance, vnode,
2680 // component may have been moved before resolve.
2681 // if this is not a hydration, instance.subTree will be the comment
2682 // placeholder.
2683 parentNode(hydratedEl || instance.subTree.el),
2684 // anchor will not be used if this is hydration, so only need to
2685 // consider the comment placeholder case.
2686 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
2687 if (placeholder) {
2688 remove(placeholder);
2689 }
2690 updateHOCHostEl(instance, vnode.el);
2691 {
2692 popWarningContext();
2693 }
2694 // only decrease deps count if suspense is not already resolved
2695 if (isInPendingSuspense && --suspense.deps === 0) {
2696 suspense.resolve();
2697 }
2698 });
2699 },
2700 unmount(parentSuspense, doRemove) {
2701 suspense.isUnmounted = true;
2702 if (suspense.activeBranch) {
2703 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
2704 }
2705 if (suspense.pendingBranch) {
2706 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
2707 }
2708 }
2709 };
2710 return suspense;
2711 }
2712 function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
2713 /* eslint-disable no-restricted-globals */
2714 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
2715 // there are two possible scenarios for server-rendered suspense:
2716 // - success: ssr content should be fully resolved
2717 // - failure: ssr content should be the fallback branch.
2718 // however, on the client we don't really know if it has failed or not
2719 // attempt to hydrate the DOM assuming it has succeeded, but we still
2720 // need to construct a suspense boundary first
2721 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
2722 if (suspense.deps === 0) {
2723 suspense.resolve();
2724 }
2725 return result;
2726 /* eslint-enable no-restricted-globals */
2727 }
2728 function normalizeSuspenseChildren(vnode) {
2729 const { shapeFlag, children } = vnode;
2730 let content;
2731 let fallback;
2732 if (shapeFlag & 32 /* SLOTS_CHILDREN */) {
2733 content = normalizeSuspenseSlot(children.default);
2734 fallback = normalizeSuspenseSlot(children.fallback);
2735 }
2736 else {
2737 content = normalizeSuspenseSlot(children);
2738 fallback = normalizeVNode(null);
2739 }
2740 return {
2741 content,
2742 fallback
2743 };
2744 }
2745 function normalizeSuspenseSlot(s) {
2746 if (isFunction(s)) {
2747 s = s();
2748 }
2749 if (isArray(s)) {
2750 const singleChild = filterSingleRoot(s);
2751 if (!singleChild) {
2752 warn(`<Suspense> slots expect a single root node.`);
2753 }
2754 s = singleChild;
2755 }
2756 return normalizeVNode(s);
2757 }
2758 function queueEffectWithSuspense(fn, suspense) {
2759 if (suspense && suspense.pendingBranch) {
2760 if (isArray(fn)) {
2761 suspense.effects.push(...fn);
2762 }
2763 else {
2764 suspense.effects.push(fn);
2765 }
2766 }
2767 else {
2768 queuePostFlushCb(fn);
2769 }
2770 }
2771 function setActiveBranch(suspense, branch) {
2772 suspense.activeBranch = branch;
2773 const { vnode, parentComponent } = suspense;
2774 const el = (vnode.el = branch.el);
2775 // in case suspense is the root node of a component,
2776 // recursively update the HOC el
2777 if (parentComponent && parentComponent.subTree === vnode) {
2778 parentComponent.vnode.el = el;
2779 updateHOCHostEl(parentComponent, el);
2780 }
2781 }
2782
2783 function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
2784 isSSR = false) {
2785 const props = {};
2786 const attrs = {};
2787 def(attrs, InternalObjectKey, 1);
2788 instance.propsDefaults = Object.create(null);
2789 setFullProps(instance, rawProps, props, attrs);
2790 // validation
2791 {
2792 validateProps(rawProps || {}, props, instance);
2793 }
2794 if (isStateful) {
2795 // stateful
2796 instance.props = isSSR ? props : shallowReactive(props);
2797 }
2798 else {
2799 if (!instance.type.props) {
2800 // functional w/ optional props, props === attrs
2801 instance.props = attrs;
2802 }
2803 else {
2804 // functional w/ declared props
2805 instance.props = props;
2806 }
2807 }
2808 instance.attrs = attrs;
2809 }
2810 function updateProps(instance, rawProps, rawPrevProps, optimized) {
2811 const { props, attrs, vnode: { patchFlag } } = instance;
2812 const rawCurrentProps = toRaw(props);
2813 const [options] = instance.propsOptions;
2814 if (
2815 // always force full diff in dev
2816 // - #1942 if hmr is enabled with sfc component
2817 // - vite#872 non-sfc component used by sfc component
2818 !((instance.type.__hmrId ||
2819 (instance.parent && instance.parent.type.__hmrId))) &&
2820 (optimized || patchFlag > 0) &&
2821 !(patchFlag & 16 /* FULL_PROPS */)) {
2822 if (patchFlag & 8 /* PROPS */) {
2823 // Compiler-generated props & no keys change, just set the updated
2824 // the props.
2825 const propsToUpdate = instance.vnode.dynamicProps;
2826 for (let i = 0; i < propsToUpdate.length; i++) {
2827 const key = propsToUpdate[i];
2828 // PROPS flag guarantees rawProps to be non-null
2829 const value = rawProps[key];
2830 if (options) {
2831 // attr / props separation was done on init and will be consistent
2832 // in this code path, so just check if attrs have it.
2833 if (hasOwn(attrs, key)) {
2834 attrs[key] = value;
2835 }
2836 else {
2837 const camelizedKey = camelize(key);
2838 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
2839 }
2840 }
2841 else {
2842 attrs[key] = value;
2843 }
2844 }
2845 }
2846 }
2847 else {
2848 // full props update.
2849 setFullProps(instance, rawProps, props, attrs);
2850 // in case of dynamic props, check if we need to delete keys from
2851 // the props object
2852 let kebabKey;
2853 for (const key in rawCurrentProps) {
2854 if (!rawProps ||
2855 // for camelCase
2856 (!hasOwn(rawProps, key) &&
2857 // it's possible the original props was passed in as kebab-case
2858 // and converted to camelCase (#955)
2859 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
2860 if (options) {
2861 if (rawPrevProps &&
2862 // for camelCase
2863 (rawPrevProps[key] !== undefined ||
2864 // for kebab-case
2865 rawPrevProps[kebabKey] !== undefined)) {
2866 props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
2867 }
2868 }
2869 else {
2870 delete props[key];
2871 }
2872 }
2873 }
2874 // in the case of functional component w/o props declaration, props and
2875 // attrs point to the same object so it should already have been updated.
2876 if (attrs !== rawCurrentProps) {
2877 for (const key in attrs) {
2878 if (!rawProps || !hasOwn(rawProps, key)) {
2879 delete attrs[key];
2880 }
2881 }
2882 }
2883 }
2884 // trigger updates for $attrs in case it's used in component slots
2885 trigger(instance, "set" /* SET */, '$attrs');
2886 {
2887 validateProps(rawProps || {}, props, instance);
2888 }
2889 }
2890 function setFullProps(instance, rawProps, props, attrs) {
2891 const [options, needCastKeys] = instance.propsOptions;
2892 if (rawProps) {
2893 for (const key in rawProps) {
2894 const value = rawProps[key];
2895 // key, ref are reserved and never passed down
2896 if (isReservedProp(key)) {
2897 continue;
2898 }
2899 // prop option names are camelized during normalization, so to support
2900 // kebab -> camel conversion here we need to camelize the key.
2901 let camelKey;
2902 if (options && hasOwn(options, (camelKey = camelize(key)))) {
2903 props[camelKey] = value;
2904 }
2905 else if (!isEmitListener(instance.emitsOptions, key)) {
2906 // Any non-declared (either as a prop or an emitted event) props are put
2907 // into a separate `attrs` object for spreading. Make sure to preserve
2908 // original key casing
2909 attrs[key] = value;
2910 }
2911 }
2912 }
2913 if (needCastKeys) {
2914 const rawCurrentProps = toRaw(props);
2915 for (let i = 0; i < needCastKeys.length; i++) {
2916 const key = needCastKeys[i];
2917 props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
2918 }
2919 }
2920 }
2921 function resolvePropValue(options, props, key, value, instance) {
2922 const opt = options[key];
2923 if (opt != null) {
2924 const hasDefault = hasOwn(opt, 'default');
2925 // default values
2926 if (hasDefault && value === undefined) {
2927 const defaultValue = opt.default;
2928 if (opt.type !== Function && isFunction(defaultValue)) {
2929 const { propsDefaults } = instance;
2930 if (key in propsDefaults) {
2931 value = propsDefaults[key];
2932 }
2933 else {
2934 setCurrentInstance(instance);
2935 value = propsDefaults[key] = defaultValue(props);
2936 setCurrentInstance(null);
2937 }
2938 }
2939 else {
2940 value = defaultValue;
2941 }
2942 }
2943 // boolean casting
2944 if (opt[0 /* shouldCast */]) {
2945 if (!hasOwn(props, key) && !hasDefault) {
2946 value = false;
2947 }
2948 else if (opt[1 /* shouldCastTrue */] &&
2949 (value === '' || value === hyphenate(key))) {
2950 value = true;
2951 }
2952 }
2953 }
2954 return value;
2955 }
2956 function normalizePropsOptions(comp, appContext, asMixin = false) {
2957 if (!appContext.deopt && comp.__props) {
2958 return comp.__props;
2959 }
2960 const raw = comp.props;
2961 const normalized = {};
2962 const needCastKeys = [];
2963 // apply mixin/extends props
2964 let hasExtends = false;
2965 if (!isFunction(comp)) {
2966 const extendProps = (raw) => {
2967 hasExtends = true;
2968 const [props, keys] = normalizePropsOptions(raw, appContext, true);
2969 extend(normalized, props);
2970 if (keys)
2971 needCastKeys.push(...keys);
2972 };
2973 if (!asMixin && appContext.mixins.length) {
2974 appContext.mixins.forEach(extendProps);
2975 }
2976 if (comp.extends) {
2977 extendProps(comp.extends);
2978 }
2979 if (comp.mixins) {
2980 comp.mixins.forEach(extendProps);
2981 }
2982 }
2983 if (!raw && !hasExtends) {
2984 return (comp.__props = EMPTY_ARR);
2985 }
2986 if (isArray(raw)) {
2987 for (let i = 0; i < raw.length; i++) {
2988 if (!isString(raw[i])) {
2989 warn(`props must be strings when using array syntax.`, raw[i]);
2990 }
2991 const normalizedKey = camelize(raw[i]);
2992 if (validatePropName(normalizedKey)) {
2993 normalized[normalizedKey] = EMPTY_OBJ;
2994 }
2995 }
2996 }
2997 else if (raw) {
2998 if (!isObject(raw)) {
2999 warn(`invalid props options`, raw);
3000 }
3001 for (const key in raw) {
3002 const normalizedKey = camelize(key);
3003 if (validatePropName(normalizedKey)) {
3004 const opt = raw[key];
3005 const prop = (normalized[normalizedKey] =
3006 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
3007 if (prop) {
3008 const booleanIndex = getTypeIndex(Boolean, prop.type);
3009 const stringIndex = getTypeIndex(String, prop.type);
3010 prop[0 /* shouldCast */] = booleanIndex > -1;
3011 prop[1 /* shouldCastTrue */] =
3012 stringIndex < 0 || booleanIndex < stringIndex;
3013 // if the prop needs boolean casting or default value
3014 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
3015 needCastKeys.push(normalizedKey);
3016 }
3017 }
3018 }
3019 }
3020 }
3021 return (comp.__props = [normalized, needCastKeys]);
3022 }
3023 function validatePropName(key) {
3024 if (key[0] !== '$') {
3025 return true;
3026 }
3027 else {
3028 warn(`Invalid prop name: "${key}" is a reserved property.`);
3029 }
3030 return false;
3031 }
3032 // use function string name to check type constructors
3033 // so that it works across vms / iframes.
3034 function getType(ctor) {
3035 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
3036 return match ? match[1] : '';
3037 }
3038 function isSameType(a, b) {
3039 return getType(a) === getType(b);
3040 }
3041 function getTypeIndex(type, expectedTypes) {
3042 if (isArray(expectedTypes)) {
3043 return expectedTypes.findIndex(t => isSameType(t, type));
3044 }
3045 else if (isFunction(expectedTypes)) {
3046 return isSameType(expectedTypes, type) ? 0 : -1;
3047 }
3048 return -1;
3049 }
3050 /**
3051 * dev only
3052 */
3053 function validateProps(rawProps, props, instance) {
3054 const resolvedValues = toRaw(props);
3055 const options = instance.propsOptions[0];
3056 for (const key in options) {
3057 let opt = options[key];
3058 if (opt == null)
3059 continue;
3060 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
3061 }
3062 }
3063 /**
3064 * dev only
3065 */
3066 function validateProp(name, value, prop, isAbsent) {
3067 const { type, required, validator } = prop;
3068 // required!
3069 if (required && isAbsent) {
3070 warn('Missing required prop: "' + name + '"');
3071 return;
3072 }
3073 // missing but optional
3074 if (value == null && !prop.required) {
3075 return;
3076 }
3077 // type check
3078 if (type != null && type !== true) {
3079 let isValid = false;
3080 const types = isArray(type) ? type : [type];
3081 const expectedTypes = [];
3082 // value is valid as long as one of the specified types match
3083 for (let i = 0; i < types.length && !isValid; i++) {
3084 const { valid, expectedType } = assertType(value, types[i]);
3085 expectedTypes.push(expectedType || '');
3086 isValid = valid;
3087 }
3088 if (!isValid) {
3089 warn(getInvalidTypeMessage(name, value, expectedTypes));
3090 return;
3091 }
3092 }
3093 // custom validator
3094 if (validator && !validator(value)) {
3095 warn('Invalid prop: custom validator check failed for prop "' + name + '".');
3096 }
3097 }
3098 const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
3099 /**
3100 * dev only
3101 */
3102 function assertType(value, type) {
3103 let valid;
3104 const expectedType = getType(type);
3105 if (isSimpleType(expectedType)) {
3106 const t = typeof value;
3107 valid = t === expectedType.toLowerCase();
3108 // for primitive wrapper objects
3109 if (!valid && t === 'object') {
3110 valid = value instanceof type;
3111 }
3112 }
3113 else if (expectedType === 'Object') {
3114 valid = isObject(value);
3115 }
3116 else if (expectedType === 'Array') {
3117 valid = isArray(value);
3118 }
3119 else {
3120 valid = value instanceof type;
3121 }
3122 return {
3123 valid,
3124 expectedType
3125 };
3126 }
3127 /**
3128 * dev only
3129 */
3130 function getInvalidTypeMessage(name, value, expectedTypes) {
3131 let message = `Invalid prop: type check failed for prop "${name}".` +
3132 ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
3133 const expectedType = expectedTypes[0];
3134 const receivedType = toRawType(value);
3135 const expectedValue = styleValue(value, expectedType);
3136 const receivedValue = styleValue(value, receivedType);
3137 // check if we need to specify expected value
3138 if (expectedTypes.length === 1 &&
3139 isExplicable(expectedType) &&
3140 !isBoolean(expectedType, receivedType)) {
3141 message += ` with value ${expectedValue}`;
3142 }
3143 message += `, got ${receivedType} `;
3144 // check if we need to specify received value
3145 if (isExplicable(receivedType)) {
3146 message += `with value ${receivedValue}.`;
3147 }
3148 return message;
3149 }
3150 /**
3151 * dev only
3152 */
3153 function styleValue(value, type) {
3154 if (type === 'String') {
3155 return `"${value}"`;
3156 }
3157 else if (type === 'Number') {
3158 return `${Number(value)}`;
3159 }
3160 else {
3161 return `${value}`;
3162 }
3163 }
3164 /**
3165 * dev only
3166 */
3167 function isExplicable(type) {
3168 const explicitTypes = ['string', 'number', 'boolean'];
3169 return explicitTypes.some(elem => type.toLowerCase() === elem);
3170 }
3171 /**
3172 * dev only
3173 */
3174 function isBoolean(...args) {
3175 return args.some(elem => elem.toLowerCase() === 'boolean');
3176 }
3177
3178 function injectHook(type, hook, target = currentInstance, prepend = false) {
3179 if (target) {
3180 const hooks = target[type] || (target[type] = []);
3181 // cache the error handling wrapper for injected hooks so the same hook
3182 // can be properly deduped by the scheduler. "__weh" stands for "with error
3183 // handling".
3184 const wrappedHook = hook.__weh ||
3185 (hook.__weh = (...args) => {
3186 if (target.isUnmounted) {
3187 return;
3188 }
3189 // disable tracking inside all lifecycle hooks
3190 // since they can potentially be called inside effects.
3191 pauseTracking();
3192 // Set currentInstance during hook invocation.
3193 // This assumes the hook does not synchronously trigger other hooks, which
3194 // can only be false when the user does something really funky.
3195 setCurrentInstance(target);
3196 const res = callWithAsyncErrorHandling(hook, target, type, args);
3197 setCurrentInstance(null);
3198 resetTracking();
3199 return res;
3200 });
3201 if (prepend) {
3202 hooks.unshift(wrappedHook);
3203 }
3204 else {
3205 hooks.push(wrappedHook);
3206 }
3207 return wrappedHook;
3208 }
3209 else {
3210 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
3211 warn(`${apiName} is called when there is no active component instance to be ` +
3212 `associated with. ` +
3213 `Lifecycle injection APIs can only be used during execution of setup().` +
3214 (` If you are using async setup(), make sure to register lifecycle ` +
3215 `hooks before the first await statement.`
3216 ));
3217 }
3218 }
3219 const createHook = (lifecycle) => (hook, target = currentInstance) =>
3220 // post-create lifecycle registrations are noops during SSR
3221 !isInSSRComponentSetup && injectHook(lifecycle, hook, target);
3222 const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
3223 const onMounted = createHook("m" /* MOUNTED */);
3224 const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
3225 const onUpdated = createHook("u" /* UPDATED */);
3226 const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
3227 const onUnmounted = createHook("um" /* UNMOUNTED */);
3228 const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
3229 const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
3230 const onErrorCaptured = (hook, target = currentInstance) => {
3231 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
3232 };
3233
3234 // Simple effect.
3235 function watchEffect(effect, options) {
3236 return doWatch(effect, null, options);
3237 }
3238 // initial value for watchers to trigger on undefined initial values
3239 const INITIAL_WATCHER_VALUE = {};
3240 // implementation
3241 function watch(source, cb, options) {
3242 if (!isFunction(cb)) {
3243 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3244 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3245 `supports \`watch(source, cb, options?) signature.`);
3246 }
3247 return doWatch(source, cb, options);
3248 }
3249 function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
3250 if (!cb) {
3251 if (immediate !== undefined) {
3252 warn(`watch() "immediate" option is only respected when using the ` +
3253 `watch(source, callback, options?) signature.`);
3254 }
3255 if (deep !== undefined) {
3256 warn(`watch() "deep" option is only respected when using the ` +
3257 `watch(source, callback, options?) signature.`);
3258 }
3259 }
3260 const warnInvalidSource = (s) => {
3261 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3262 `a reactive object, or an array of these types.`);
3263 };
3264 let getter;
3265 let forceTrigger = false;
3266 if (isRef(source)) {
3267 getter = () => source.value;
3268 forceTrigger = !!source._shallow;
3269 }
3270 else if (isReactive(source)) {
3271 getter = () => source;
3272 deep = true;
3273 }
3274 else if (isArray(source)) {
3275 getter = () => source.map(s => {
3276 if (isRef(s)) {
3277 return s.value;
3278 }
3279 else if (isReactive(s)) {
3280 return traverse(s);
3281 }
3282 else if (isFunction(s)) {
3283 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */, [
3284 instance && instance.proxy
3285 ]);
3286 }
3287 else {
3288 warnInvalidSource(s);
3289 }
3290 });
3291 }
3292 else if (isFunction(source)) {
3293 if (cb) {
3294 // getter with cb
3295 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */, [
3296 instance && instance.proxy
3297 ]);
3298 }
3299 else {
3300 // no cb -> simple effect
3301 getter = () => {
3302 if (instance && instance.isUnmounted) {
3303 return;
3304 }
3305 if (cleanup) {
3306 cleanup();
3307 }
3308 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
3309 };
3310 }
3311 }
3312 else {
3313 getter = NOOP;
3314 warnInvalidSource(source);
3315 }
3316 if (cb && deep) {
3317 const baseGetter = getter;
3318 getter = () => traverse(baseGetter());
3319 }
3320 let cleanup;
3321 let onInvalidate = (fn) => {
3322 cleanup = runner.options.onStop = () => {
3323 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3324 };
3325 };
3326 let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
3327 const job = () => {
3328 if (!runner.active) {
3329 return;
3330 }
3331 if (cb) {
3332 // watch(source, cb)
3333 const newValue = runner();
3334 if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
3335 // cleanup before running cb again
3336 if (cleanup) {
3337 cleanup();
3338 }
3339 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3340 newValue,
3341 // pass undefined as the old value when it's changed for the first time
3342 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3343 onInvalidate
3344 ]);
3345 oldValue = newValue;
3346 }
3347 }
3348 else {
3349 // watchEffect
3350 runner();
3351 }
3352 };
3353 // important: mark the job as a watcher callback so that scheduler knows
3354 // it is allowed to self-trigger (#1727)
3355 job.allowRecurse = !!cb;
3356 let scheduler;
3357 if (flush === 'sync') {
3358 scheduler = job;
3359 }
3360 else if (flush === 'post') {
3361 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3362 }
3363 else {
3364 // default: 'pre'
3365 scheduler = () => {
3366 if (!instance || instance.isMounted) {
3367 queuePreFlushCb(job);
3368 }
3369 else {
3370 // with 'pre' option, the first call must happen before
3371 // the component is mounted so it is called synchronously.
3372 job();
3373 }
3374 };
3375 }
3376 const runner = effect(getter, {
3377 lazy: true,
3378 onTrack,
3379 onTrigger,
3380 scheduler
3381 });
3382 recordInstanceBoundEffect(runner, instance);
3383 // initial run
3384 if (cb) {
3385 if (immediate) {
3386 job();
3387 }
3388 else {
3389 oldValue = runner();
3390 }
3391 }
3392 else if (flush === 'post') {
3393 queuePostRenderEffect(runner, instance && instance.suspense);
3394 }
3395 else {
3396 runner();
3397 }
3398 return () => {
3399 stop(runner);
3400 if (instance) {
3401 remove(instance.effects, runner);
3402 }
3403 };
3404 }
3405 // this.$watch
3406 function instanceWatch(source, cb, options) {
3407 const publicThis = this.proxy;
3408 const getter = isString(source)
3409 ? () => publicThis[source]
3410 : source.bind(publicThis);
3411 return doWatch(getter, cb.bind(publicThis), options, this);
3412 }
3413 function traverse(value, seen = new Set()) {
3414 if (!isObject(value) || seen.has(value)) {
3415 return value;
3416 }
3417 seen.add(value);
3418 if (isRef(value)) {
3419 traverse(value.value, seen);
3420 }
3421 else if (isArray(value)) {
3422 for (let i = 0; i < value.length; i++) {
3423 traverse(value[i], seen);
3424 }
3425 }
3426 else if (isSet(value) || isMap(value)) {
3427 value.forEach((v) => {
3428 traverse(v, seen);
3429 });
3430 }
3431 else {
3432 for (const key in value) {
3433 traverse(value[key], seen);
3434 }
3435 }
3436 return value;
3437 }
3438
3439 function useTransitionState() {
3440 const state = {
3441 isMounted: false,
3442 isLeaving: false,
3443 isUnmounting: false,
3444 leavingVNodes: new Map()
3445 };
3446 onMounted(() => {
3447 state.isMounted = true;
3448 });
3449 onBeforeUnmount(() => {
3450 state.isUnmounting = true;
3451 });
3452 return state;
3453 }
3454 const TransitionHookValidator = [Function, Array];
3455 const BaseTransitionImpl = {
3456 name: `BaseTransition`,
3457 props: {
3458 mode: String,
3459 appear: Boolean,
3460 persisted: Boolean,
3461 // enter
3462 onBeforeEnter: TransitionHookValidator,
3463 onEnter: TransitionHookValidator,
3464 onAfterEnter: TransitionHookValidator,
3465 onEnterCancelled: TransitionHookValidator,
3466 // leave
3467 onBeforeLeave: TransitionHookValidator,
3468 onLeave: TransitionHookValidator,
3469 onAfterLeave: TransitionHookValidator,
3470 onLeaveCancelled: TransitionHookValidator,
3471 // appear
3472 onBeforeAppear: TransitionHookValidator,
3473 onAppear: TransitionHookValidator,
3474 onAfterAppear: TransitionHookValidator,
3475 onAppearCancelled: TransitionHookValidator
3476 },
3477 setup(props, { slots }) {
3478 const instance = getCurrentInstance();
3479 const state = useTransitionState();
3480 let prevTransitionKey;
3481 return () => {
3482 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3483 if (!children || !children.length) {
3484 return;
3485 }
3486 // warn multiple elements
3487 if (children.length > 1) {
3488 warn('<transition> can only be used on a single element or component. Use ' +
3489 '<transition-group> for lists.');
3490 }
3491 // there's no need to track reactivity for these props so use the raw
3492 // props for a bit better perf
3493 const rawProps = toRaw(props);
3494 const { mode } = rawProps;
3495 // check mode
3496 if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
3497 warn(`invalid <transition> mode: ${mode}`);
3498 }
3499 // at this point children has a guaranteed length of 1.
3500 const child = children[0];
3501 if (state.isLeaving) {
3502 return emptyPlaceholder(child);
3503 }
3504 // in the case of <transition><keep-alive/></transition>, we need to
3505 // compare the type of the kept-alive children.
3506 const innerChild = getKeepAliveChild(child);
3507 if (!innerChild) {
3508 return emptyPlaceholder(child);
3509 }
3510 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3511 setTransitionHooks(innerChild, enterHooks);
3512 const oldChild = instance.subTree;
3513 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3514 let transitionKeyChanged = false;
3515 const { getTransitionKey } = innerChild.type;
3516 if (getTransitionKey) {
3517 const key = getTransitionKey();
3518 if (prevTransitionKey === undefined) {
3519 prevTransitionKey = key;
3520 }
3521 else if (key !== prevTransitionKey) {
3522 prevTransitionKey = key;
3523 transitionKeyChanged = true;
3524 }
3525 }
3526 // handle mode
3527 if (oldInnerChild &&
3528 oldInnerChild.type !== Comment &&
3529 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3530 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3531 // update old tree's hooks in case of dynamic transition
3532 setTransitionHooks(oldInnerChild, leavingHooks);
3533 // switching between different views
3534 if (mode === 'out-in') {
3535 state.isLeaving = true;
3536 // return placeholder node and queue update when leave finishes
3537 leavingHooks.afterLeave = () => {
3538 state.isLeaving = false;
3539 instance.update();
3540 };
3541 return emptyPlaceholder(child);
3542 }
3543 else if (mode === 'in-out' && innerChild.type !== Comment) {
3544 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3545 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3546 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3547 // early removal callback
3548 el._leaveCb = () => {
3549 earlyRemove();
3550 el._leaveCb = undefined;
3551 delete enterHooks.delayedLeave;
3552 };
3553 enterHooks.delayedLeave = delayedLeave;
3554 };
3555 }
3556 }
3557 return child;
3558 };
3559 }
3560 };
3561 // export the public type for h/tsx inference
3562 // also to avoid inline import() in generated d.ts files
3563 const BaseTransition = BaseTransitionImpl;
3564 function getLeavingNodesForType(state, vnode) {
3565 const { leavingVNodes } = state;
3566 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3567 if (!leavingVNodesCache) {
3568 leavingVNodesCache = Object.create(null);
3569 leavingVNodes.set(vnode.type, leavingVNodesCache);
3570 }
3571 return leavingVNodesCache;
3572 }
3573 // The transition hooks are attached to the vnode as vnode.transition
3574 // and will be called at appropriate timing in the renderer.
3575 function resolveTransitionHooks(vnode, props, state, instance) {
3576 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3577 const key = String(vnode.key);
3578 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3579 const callHook = (hook, args) => {
3580 hook &&
3581 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3582 };
3583 const hooks = {
3584 mode,
3585 persisted,
3586 beforeEnter(el) {
3587 let hook = onBeforeEnter;
3588 if (!state.isMounted) {
3589 if (appear) {
3590 hook = onBeforeAppear || onBeforeEnter;
3591 }
3592 else {
3593 return;
3594 }
3595 }
3596 // for same element (v-show)
3597 if (el._leaveCb) {
3598 el._leaveCb(true /* cancelled */);
3599 }
3600 // for toggled element with same key (v-if)
3601 const leavingVNode = leavingVNodesCache[key];
3602 if (leavingVNode &&
3603 isSameVNodeType(vnode, leavingVNode) &&
3604 leavingVNode.el._leaveCb) {
3605 // force early removal (not cancelled)
3606 leavingVNode.el._leaveCb();
3607 }
3608 callHook(hook, [el]);
3609 },
3610 enter(el) {
3611 let hook = onEnter;
3612 let afterHook = onAfterEnter;
3613 let cancelHook = onEnterCancelled;
3614 if (!state.isMounted) {
3615 if (appear) {
3616 hook = onAppear || onEnter;
3617 afterHook = onAfterAppear || onAfterEnter;
3618 cancelHook = onAppearCancelled || onEnterCancelled;
3619 }
3620 else {
3621 return;
3622 }
3623 }
3624 let called = false;
3625 const done = (el._enterCb = (cancelled) => {
3626 if (called)
3627 return;
3628 called = true;
3629 if (cancelled) {
3630 callHook(cancelHook, [el]);
3631 }
3632 else {
3633 callHook(afterHook, [el]);
3634 }
3635 if (hooks.delayedLeave) {
3636 hooks.delayedLeave();
3637 }
3638 el._enterCb = undefined;
3639 });
3640 if (hook) {
3641 hook(el, done);
3642 if (hook.length <= 1) {
3643 done();
3644 }
3645 }
3646 else {
3647 done();
3648 }
3649 },
3650 leave(el, remove) {
3651 const key = String(vnode.key);
3652 if (el._enterCb) {
3653 el._enterCb(true /* cancelled */);
3654 }
3655 if (state.isUnmounting) {
3656 return remove();
3657 }
3658 callHook(onBeforeLeave, [el]);
3659 let called = false;
3660 const done = (el._leaveCb = (cancelled) => {
3661 if (called)
3662 return;
3663 called = true;
3664 remove();
3665 if (cancelled) {
3666 callHook(onLeaveCancelled, [el]);
3667 }
3668 else {
3669 callHook(onAfterLeave, [el]);
3670 }
3671 el._leaveCb = undefined;
3672 if (leavingVNodesCache[key] === vnode) {
3673 delete leavingVNodesCache[key];
3674 }
3675 });
3676 leavingVNodesCache[key] = vnode;
3677 if (onLeave) {
3678 onLeave(el, done);
3679 if (onLeave.length <= 1) {
3680 done();
3681 }
3682 }
3683 else {
3684 done();
3685 }
3686 },
3687 clone(vnode) {
3688 return resolveTransitionHooks(vnode, props, state, instance);
3689 }
3690 };
3691 return hooks;
3692 }
3693 // the placeholder really only handles one special case: KeepAlive
3694 // in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3695 // placeholder with empty content to avoid the KeepAlive instance from being
3696 // unmounted.
3697 function emptyPlaceholder(vnode) {
3698 if (isKeepAlive(vnode)) {
3699 vnode = cloneVNode(vnode);
3700 vnode.children = null;
3701 return vnode;
3702 }
3703 }
3704 function getKeepAliveChild(vnode) {
3705 return isKeepAlive(vnode)
3706 ? vnode.children
3707 ? vnode.children[0]
3708 : undefined
3709 : vnode;
3710 }
3711 function setTransitionHooks(vnode, hooks) {
3712 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3713 setTransitionHooks(vnode.component.subTree, hooks);
3714 }
3715 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3716 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3717 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3718 }
3719 else {
3720 vnode.transition = hooks;
3721 }
3722 }
3723 function getTransitionRawChildren(children, keepComment = false) {
3724 let ret = [];
3725 let keyedFragmentCount = 0;
3726 for (let i = 0; i < children.length; i++) {
3727 const child = children[i];
3728 // handle fragment children case, e.g. v-for
3729 if (child.type === Fragment) {
3730 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3731 keyedFragmentCount++;
3732 ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
3733 }
3734 // comment placeholders should be skipped, e.g. v-if
3735 else if (keepComment || child.type !== Comment) {
3736 ret.push(child);
3737 }
3738 }
3739 // #1126 if a transition children list contains multiple sub fragments, these
3740 // fragments will be merged into a flat children array. Since each v-for
3741 // fragment may contain different static bindings inside, we need to de-op
3742 // these children to force full diffs to ensure correct behavior.
3743 if (keyedFragmentCount > 1) {
3744 for (let i = 0; i < ret.length; i++) {
3745 ret[i].patchFlag = -2 /* BAIL */;
3746 }
3747 }
3748 return ret;
3749 }
3750
3751 const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3752 const KeepAliveImpl = {
3753 name: `KeepAlive`,
3754 // Marker for special handling inside the renderer. We are not using a ===
3755 // check directly on KeepAlive in the renderer, because importing it directly
3756 // would prevent it from being tree-shaken.
3757 __isKeepAlive: true,
3758 props: {
3759 include: [String, RegExp, Array],
3760 exclude: [String, RegExp, Array],
3761 max: [String, Number]
3762 },
3763 setup(props, { slots }) {
3764 const instance = getCurrentInstance();
3765 // KeepAlive communicates with the instantiated renderer via the
3766 // ctx where the renderer passes in its internals,
3767 // and the KeepAlive instance exposes activate/deactivate implementations.
3768 // The whole point of this is to avoid importing KeepAlive directly in the
3769 // renderer to facilitate tree-shaking.
3770 const sharedContext = instance.ctx;
3771 // if the internal renderer is not registered, it indicates that this is server-side rendering,
3772 // for KeepAlive, we just need to render its children
3773 if (!sharedContext.renderer) {
3774 return slots.default;
3775 }
3776 const cache = new Map();
3777 const keys = new Set();
3778 let current = null;
3779 const parentSuspense = instance.suspense;
3780 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3781 const storageContainer = createElement('div');
3782 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3783 const instance = vnode.component;
3784 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3785 // in case props have changed
3786 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3787 queuePostRenderEffect(() => {
3788 instance.isDeactivated = false;
3789 if (instance.a) {
3790 invokeArrayFns(instance.a);
3791 }
3792 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3793 if (vnodeHook) {
3794 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3795 }
3796 }, parentSuspense);
3797 };
3798 sharedContext.deactivate = (vnode) => {
3799 const instance = vnode.component;
3800 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3801 queuePostRenderEffect(() => {
3802 if (instance.da) {
3803 invokeArrayFns(instance.da);
3804 }
3805 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3806 if (vnodeHook) {
3807 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3808 }
3809 instance.isDeactivated = true;
3810 }, parentSuspense);
3811 };
3812 function unmount(vnode) {
3813 // reset the shapeFlag so it can be properly unmounted
3814 resetShapeFlag(vnode);
3815 _unmount(vnode, instance, parentSuspense);
3816 }
3817 function pruneCache(filter) {
3818 cache.forEach((vnode, key) => {
3819 const name = getComponentName(vnode.type);
3820 if (name && (!filter || !filter(name))) {
3821 pruneCacheEntry(key);
3822 }
3823 });
3824 }
3825 function pruneCacheEntry(key) {
3826 const cached = cache.get(key);
3827 if (!current || cached.type !== current.type) {
3828 unmount(cached);
3829 }
3830 else if (current) {
3831 // current active instance should no longer be kept-alive.
3832 // we can't unmount it now but it might be later, so reset its flag now.
3833 resetShapeFlag(current);
3834 }
3835 cache.delete(key);
3836 keys.delete(key);
3837 }
3838 // prune cache on include/exclude prop change
3839 watch(() => [props.include, props.exclude], ([include, exclude]) => {
3840 include && pruneCache(name => matches(include, name));
3841 exclude && pruneCache(name => !matches(exclude, name));
3842 },
3843 // prune post-render after `current` has been updated
3844 { flush: 'post', deep: true });
3845 // cache sub tree after render
3846 let pendingCacheKey = null;
3847 const cacheSubtree = () => {
3848 // fix #1621, the pendingCacheKey could be 0
3849 if (pendingCacheKey != null) {
3850 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
3851 }
3852 };
3853 onMounted(cacheSubtree);
3854 onUpdated(cacheSubtree);
3855 onBeforeUnmount(() => {
3856 cache.forEach(cached => {
3857 const { subTree, suspense } = instance;
3858 const vnode = getInnerChild(subTree);
3859 if (cached.type === vnode.type) {
3860 // current instance will be unmounted as part of keep-alive's unmount
3861 resetShapeFlag(vnode);
3862 // but invoke its deactivated hook here
3863 const da = vnode.component.da;
3864 da && queuePostRenderEffect(da, suspense);
3865 return;
3866 }
3867 unmount(cached);
3868 });
3869 });
3870 return () => {
3871 pendingCacheKey = null;
3872 if (!slots.default) {
3873 return null;
3874 }
3875 const children = slots.default();
3876 const rawVNode = children[0];
3877 if (children.length > 1) {
3878 {
3879 warn(`KeepAlive should contain exactly one component child.`);
3880 }
3881 current = null;
3882 return children;
3883 }
3884 else if (!isVNode(rawVNode) ||
3885 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
3886 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
3887 current = null;
3888 return rawVNode;
3889 }
3890 let vnode = getInnerChild(rawVNode);
3891 const comp = vnode.type;
3892 const name = getComponentName(comp);
3893 const { include, exclude, max } = props;
3894 if ((include && (!name || !matches(include, name))) ||
3895 (exclude && name && matches(exclude, name))) {
3896 current = vnode;
3897 return rawVNode;
3898 }
3899 const key = vnode.key == null ? comp : vnode.key;
3900 const cachedVNode = cache.get(key);
3901 // clone vnode if it's reused because we are going to mutate it
3902 if (vnode.el) {
3903 vnode = cloneVNode(vnode);
3904 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
3905 rawVNode.ssContent = vnode;
3906 }
3907 }
3908 // #1513 it's possible for the returned vnode to be cloned due to attr
3909 // fallthrough or scopeId, so the vnode here may not be the final vnode
3910 // that is mounted. Instead of caching it directly, we store the pending
3911 // key and cache `instance.subTree` (the normalized vnode) in
3912 // beforeMount/beforeUpdate hooks.
3913 pendingCacheKey = key;
3914 if (cachedVNode) {
3915 // copy over mounted state
3916 vnode.el = cachedVNode.el;
3917 vnode.component = cachedVNode.component;
3918 if (vnode.transition) {
3919 // recursively update transition hooks on subTree
3920 setTransitionHooks(vnode, vnode.transition);
3921 }
3922 // avoid vnode being mounted as fresh
3923 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
3924 // make this key the freshest
3925 keys.delete(key);
3926 keys.add(key);
3927 }
3928 else {
3929 keys.add(key);
3930 // prune oldest entry
3931 if (max && keys.size > parseInt(max, 10)) {
3932 pruneCacheEntry(keys.values().next().value);
3933 }
3934 }
3935 // avoid vnode being unmounted
3936 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
3937 current = vnode;
3938 return rawVNode;
3939 };
3940 }
3941 };
3942 // export the public type for h/tsx inference
3943 // also to avoid inline import() in generated d.ts files
3944 const KeepAlive = KeepAliveImpl;
3945 function matches(pattern, name) {
3946 if (isArray(pattern)) {
3947 return pattern.some((p) => matches(p, name));
3948 }
3949 else if (isString(pattern)) {
3950 return pattern.split(',').indexOf(name) > -1;
3951 }
3952 else if (pattern.test) {
3953 return pattern.test(name);
3954 }
3955 /* istanbul ignore next */
3956 return false;
3957 }
3958 function onActivated(hook, target) {
3959 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
3960 }
3961 function onDeactivated(hook, target) {
3962 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
3963 }
3964 function registerKeepAliveHook(hook, type, target = currentInstance) {
3965 // cache the deactivate branch check wrapper for injected hooks so the same
3966 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
3967 // deactivation check".
3968 const wrappedHook = hook.__wdc ||
3969 (hook.__wdc = () => {
3970 // only fire the hook if the target instance is NOT in a deactivated branch.
3971 let current = target;
3972 while (current) {
3973 if (current.isDeactivated) {
3974 return;
3975 }
3976 current = current.parent;
3977 }
3978 hook();
3979 });
3980 injectHook(type, wrappedHook, target);
3981 // In addition to registering it on the target instance, we walk up the parent
3982 // chain and register it on all ancestor instances that are keep-alive roots.
3983 // This avoids the need to walk the entire component tree when invoking these
3984 // hooks, and more importantly, avoids the need to track child components in
3985 // arrays.
3986 if (target) {
3987 let current = target.parent;
3988 while (current && current.parent) {
3989 if (isKeepAlive(current.parent.vnode)) {
3990 injectToKeepAliveRoot(wrappedHook, type, target, current);
3991 }
3992 current = current.parent;
3993 }
3994 }
3995 }
3996 function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
3997 // injectHook wraps the original for error handling, so make sure to remove
3998 // the wrapped version.
3999 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4000 onUnmounted(() => {
4001 remove(keepAliveRoot[type], injected);
4002 }, target);
4003 }
4004 function resetShapeFlag(vnode) {
4005 let shapeFlag = vnode.shapeFlag;
4006 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
4007 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4008 }
4009 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
4010 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
4011 }
4012 vnode.shapeFlag = shapeFlag;
4013 }
4014 function getInnerChild(vnode) {
4015 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
4016 }
4017
4018 const isInternalKey = (key) => key[0] === '_' || key === '$stable';
4019 const normalizeSlotValue = (value) => isArray(value)
4020 ? value.map(normalizeVNode)
4021 : [normalizeVNode(value)];
4022 const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => {
4023 if (currentInstance) {
4024 warn(`Slot "${key}" invoked outside of the render function: ` +
4025 `this will not track dependencies used in the slot. ` +
4026 `Invoke the slot function inside the render function instead.`);
4027 }
4028 return normalizeSlotValue(rawSlot(props));
4029 }, ctx);
4030 const normalizeObjectSlots = (rawSlots, slots) => {
4031 const ctx = rawSlots._ctx;
4032 for (const key in rawSlots) {
4033 if (isInternalKey(key))
4034 continue;
4035 const value = rawSlots[key];
4036 if (isFunction(value)) {
4037 slots[key] = normalizeSlot(key, value, ctx);
4038 }
4039 else if (value != null) {
4040 {
4041 warn(`Non-function value encountered for slot "${key}". ` +
4042 `Prefer function slots for better performance.`);
4043 }
4044 const normalized = normalizeSlotValue(value);
4045 slots[key] = () => normalized;
4046 }
4047 }
4048 };
4049 const normalizeVNodeSlots = (instance, children) => {
4050 if (!isKeepAlive(instance.vnode)) {
4051 warn(`Non-function value encountered for default slot. ` +
4052 `Prefer function slots for better performance.`);
4053 }
4054 const normalized = normalizeSlotValue(children);
4055 instance.slots.default = () => normalized;
4056 };
4057 const initSlots = (instance, children) => {
4058 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4059 const type = children._;
4060 if (type) {
4061 instance.slots = children;
4062 // make compiler marker non-enumerable
4063 def(children, '_', type);
4064 }
4065 else {
4066 normalizeObjectSlots(children, (instance.slots = {}));
4067 }
4068 }
4069 else {
4070 instance.slots = {};
4071 if (children) {
4072 normalizeVNodeSlots(instance, children);
4073 }
4074 }
4075 def(instance.slots, InternalObjectKey, 1);
4076 };
4077 const updateSlots = (instance, children, optimized) => {
4078 const { vnode, slots } = instance;
4079 let needDeletionCheck = true;
4080 let deletionComparisonTarget = EMPTY_OBJ;
4081 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4082 const type = children._;
4083 if (type) {
4084 // compiled slots.
4085 if (isHmrUpdating) {
4086 // Parent was HMR updated so slot content may have changed.
4087 // force update slots and mark instance for hmr as well
4088 extend(slots, children);
4089 }
4090 else if (optimized && type === 1 /* STABLE */) {
4091 // compiled AND stable.
4092 // no need to update, and skip stale slots removal.
4093 needDeletionCheck = false;
4094 }
4095 else {
4096 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
4097 // normalization.
4098 extend(slots, children);
4099 // #2893
4100 // when rendering the optimized slots by manually written render function,
4101 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
4102 // i.e. let the `renderSlot` create the bailed Fragment
4103 if (!optimized && type === 1 /* STABLE */) {
4104 delete slots._;
4105 }
4106 }
4107 }
4108 else {
4109 needDeletionCheck = !children.$stable;
4110 normalizeObjectSlots(children, slots);
4111 }
4112 deletionComparisonTarget = children;
4113 }
4114 else if (children) {
4115 // non slot object children (direct value) passed to a component
4116 normalizeVNodeSlots(instance, children);
4117 deletionComparisonTarget = { default: 1 };
4118 }
4119 // delete stale slots
4120 if (needDeletionCheck) {
4121 for (const key in slots) {
4122 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
4123 delete slots[key];
4124 }
4125 }
4126 }
4127 };
4128
4129 /**
4130 Runtime helper for applying directives to a vnode. Example usage:
4131
4132 const comp = resolveComponent('comp')
4133 const foo = resolveDirective('foo')
4134 const bar = resolveDirective('bar')
4135
4136 return withDirectives(h(comp), [
4137 [foo, this.x],
4138 [bar, this.y]
4139 ])
4140 */
4141 const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
4142 function validateDirectiveName(name) {
4143 if (isBuiltInDirective(name)) {
4144 warn('Do not use built-in directive ids as custom directive id: ' + name);
4145 }
4146 }
4147 /**
4148 * Adds directives to a VNode.
4149 */
4150 function withDirectives(vnode, directives) {
4151 const internalInstance = currentRenderingInstance;
4152 if (internalInstance === null) {
4153 warn(`withDirectives can only be used inside render functions.`);
4154 return vnode;
4155 }
4156 const instance = internalInstance.proxy;
4157 const bindings = vnode.dirs || (vnode.dirs = []);
4158 for (let i = 0; i < directives.length; i++) {
4159 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4160 if (isFunction(dir)) {
4161 dir = {
4162 mounted: dir,
4163 updated: dir
4164 };
4165 }
4166 bindings.push({
4167 dir,
4168 instance,
4169 value,
4170 oldValue: void 0,
4171 arg,
4172 modifiers
4173 });
4174 }
4175 return vnode;
4176 }
4177 function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4178 const bindings = vnode.dirs;
4179 const oldBindings = prevVNode && prevVNode.dirs;
4180 for (let i = 0; i < bindings.length; i++) {
4181 const binding = bindings[i];
4182 if (oldBindings) {
4183 binding.oldValue = oldBindings[i].value;
4184 }
4185 const hook = binding.dir[name];
4186 if (hook) {
4187 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4188 vnode.el,
4189 binding,
4190 vnode,
4191 prevVNode
4192 ]);
4193 }
4194 }
4195 }
4196
4197 function createAppContext() {
4198 return {
4199 app: null,
4200 config: {
4201 isNativeTag: NO,
4202 performance: false,
4203 globalProperties: {},
4204 optionMergeStrategies: {},
4205 isCustomElement: NO,
4206 errorHandler: undefined,
4207 warnHandler: undefined
4208 },
4209 mixins: [],
4210 components: {},
4211 directives: {},
4212 provides: Object.create(null)
4213 };
4214 }
4215 let uid$1 = 0;
4216 function createAppAPI(render, hydrate) {
4217 return function createApp(rootComponent, rootProps = null) {
4218 if (rootProps != null && !isObject(rootProps)) {
4219 warn(`root props passed to app.mount() must be an object.`);
4220 rootProps = null;
4221 }
4222 const context = createAppContext();
4223 const installedPlugins = new Set();
4224 let isMounted = false;
4225 const app = (context.app = {
4226 _uid: uid$1++,
4227 _component: rootComponent,
4228 _props: rootProps,
4229 _container: null,
4230 _context: context,
4231 version,
4232 get config() {
4233 return context.config;
4234 },
4235 set config(v) {
4236 {
4237 warn(`app.config cannot be replaced. Modify individual options instead.`);
4238 }
4239 },
4240 use(plugin, ...options) {
4241 if (installedPlugins.has(plugin)) {
4242 warn(`Plugin has already been applied to target app.`);
4243 }
4244 else if (plugin && isFunction(plugin.install)) {
4245 installedPlugins.add(plugin);
4246 plugin.install(app, ...options);
4247 }
4248 else if (isFunction(plugin)) {
4249 installedPlugins.add(plugin);
4250 plugin(app, ...options);
4251 }
4252 else {
4253 warn(`A plugin must either be a function or an object with an "install" ` +
4254 `function.`);
4255 }
4256 return app;
4257 },
4258 mixin(mixin) {
4259 {
4260 if (!context.mixins.includes(mixin)) {
4261 context.mixins.push(mixin);
4262 // global mixin with props/emits de-optimizes props/emits
4263 // normalization caching.
4264 if (mixin.props || mixin.emits) {
4265 context.deopt = true;
4266 }
4267 }
4268 else {
4269 warn('Mixin has already been applied to target app' +
4270 (mixin.name ? `: ${mixin.name}` : ''));
4271 }
4272 }
4273 return app;
4274 },
4275 component(name, component) {
4276 {
4277 validateComponentName(name, context.config);
4278 }
4279 if (!component) {
4280 return context.components[name];
4281 }
4282 if (context.components[name]) {
4283 warn(`Component "${name}" has already been registered in target app.`);
4284 }
4285 context.components[name] = component;
4286 return app;
4287 },
4288 directive(name, directive) {
4289 {
4290 validateDirectiveName(name);
4291 }
4292 if (!directive) {
4293 return context.directives[name];
4294 }
4295 if (context.directives[name]) {
4296 warn(`Directive "${name}" has already been registered in target app.`);
4297 }
4298 context.directives[name] = directive;
4299 return app;
4300 },
4301 mount(rootContainer, isHydrate, isSVG) {
4302 if (!isMounted) {
4303 const vnode = createVNode(rootComponent, rootProps);
4304 // store app context on the root VNode.
4305 // this will be set on the root instance on initial mount.
4306 vnode.appContext = context;
4307 // HMR root reload
4308 {
4309 context.reload = () => {
4310 render(cloneVNode(vnode), rootContainer, isSVG);
4311 };
4312 }
4313 if (isHydrate && hydrate) {
4314 hydrate(vnode, rootContainer);
4315 }
4316 else {
4317 render(vnode, rootContainer, isSVG);
4318 }
4319 isMounted = true;
4320 app._container = rootContainer;
4321 rootContainer.__vue_app__ = app;
4322 {
4323 devtoolsInitApp(app, version);
4324 }
4325 return vnode.component.proxy;
4326 }
4327 else {
4328 warn(`App has already been mounted.\n` +
4329 `If you want to remount the same app, move your app creation logic ` +
4330 `into a factory function and create fresh app instances for each ` +
4331 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
4332 }
4333 },
4334 unmount() {
4335 if (isMounted) {
4336 render(null, app._container);
4337 {
4338 devtoolsUnmountApp(app);
4339 }
4340 delete app._container.__vue_app__;
4341 }
4342 else {
4343 warn(`Cannot unmount an app that is not mounted.`);
4344 }
4345 },
4346 provide(key, value) {
4347 if (key in context.provides) {
4348 warn(`App already provides property with key "${String(key)}". ` +
4349 `It will be overwritten with the new value.`);
4350 }
4351 // TypeScript doesn't allow symbols as index type
4352 // https://github.com/Microsoft/TypeScript/issues/24587
4353 context.provides[key] = value;
4354 return app;
4355 }
4356 });
4357 return app;
4358 };
4359 }
4360
4361 let hasMismatch = false;
4362 const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4363 const isComment = (node) => node.nodeType === 8 /* COMMENT */;
4364 // Note: hydration is DOM-specific
4365 // But we have to place it in core due to tight coupling with core - splitting
4366 // it out creates a ton of unnecessary complexity.
4367 // Hydration also depends on some renderer internal logic which needs to be
4368 // passed in via arguments.
4369 function createHydrationFunctions(rendererInternals) {
4370 const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
4371 const hydrate = (vnode, container) => {
4372 if (!container.hasChildNodes()) {
4373 warn(`Attempting to hydrate existing markup but container is empty. ` +
4374 `Performing full mount instead.`);
4375 patch(null, vnode, container);
4376 return;
4377 }
4378 hasMismatch = false;
4379 hydrateNode(container.firstChild, vnode, null, null, null);
4380 flushPostFlushCbs();
4381 if (hasMismatch && !false) {
4382 // this error should show up in production
4383 console.error(`Hydration completed but contains mismatches.`);
4384 }
4385 };
4386 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
4387 const isFragmentStart = isComment(node) && node.data === '[';
4388 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
4389 const { type, ref, shapeFlag } = vnode;
4390 const domType = node.nodeType;
4391 vnode.el = node;
4392 let nextNode = null;
4393 switch (type) {
4394 case Text:
4395 if (domType !== 3 /* TEXT */) {
4396 nextNode = onMismatch();
4397 }
4398 else {
4399 if (node.data !== vnode.children) {
4400 hasMismatch = true;
4401 warn(`Hydration text mismatch:` +
4402 `\n- Client: ${JSON.stringify(node.data)}` +
4403 `\n- Server: ${JSON.stringify(vnode.children)}`);
4404 node.data = vnode.children;
4405 }
4406 nextNode = nextSibling(node);
4407 }
4408 break;
4409 case Comment:
4410 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
4411 nextNode = onMismatch();
4412 }
4413 else {
4414 nextNode = nextSibling(node);
4415 }
4416 break;
4417 case Static:
4418 if (domType !== 1 /* ELEMENT */) {
4419 nextNode = onMismatch();
4420 }
4421 else {
4422 // determine anchor, adopt content
4423 nextNode = node;
4424 // if the static vnode has its content stripped during build,
4425 // adopt it from the server-rendered HTML.
4426 const needToAdoptContent = !vnode.children.length;
4427 for (let i = 0; i < vnode.staticCount; i++) {
4428 if (needToAdoptContent)
4429 vnode.children += nextNode.outerHTML;
4430 if (i === vnode.staticCount - 1) {
4431 vnode.anchor = nextNode;
4432 }
4433 nextNode = nextSibling(nextNode);
4434 }
4435 return nextNode;
4436 }
4437 break;
4438 case Fragment:
4439 if (!isFragmentStart) {
4440 nextNode = onMismatch();
4441 }
4442 else {
4443 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4444 }
4445 break;
4446 default:
4447 if (shapeFlag & 1 /* ELEMENT */) {
4448 if (domType !== 1 /* ELEMENT */ ||
4449 vnode.type.toLowerCase() !==
4450 node.tagName.toLowerCase()) {
4451 nextNode = onMismatch();
4452 }
4453 else {
4454 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4455 }
4456 }
4457 else if (shapeFlag & 6 /* COMPONENT */) {
4458 // when setting up the render effect, if the initial vnode already
4459 // has .el set, the component will perform hydration instead of mount
4460 // on its sub-tree.
4461 vnode.slotScopeIds = slotScopeIds;
4462 const container = parentNode(node);
4463 const hydrateComponent = () => {
4464 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
4465 };
4466 // async component
4467 const loadAsync = vnode.type.__asyncLoader;
4468 if (loadAsync) {
4469 loadAsync().then(hydrateComponent);
4470 }
4471 else {
4472 hydrateComponent();
4473 }
4474 // component may be async, so in the case of fragments we cannot rely
4475 // on component's rendered output to determine the end of the fragment
4476 // instead, we do a lookahead to find the end anchor node.
4477 nextNode = isFragmentStart
4478 ? locateClosingAsyncAnchor(node)
4479 : nextSibling(node);
4480 }
4481 else if (shapeFlag & 64 /* TELEPORT */) {
4482 if (domType !== 8 /* COMMENT */) {
4483 nextNode = onMismatch();
4484 }
4485 else {
4486 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
4487 }
4488 }
4489 else if (shapeFlag & 128 /* SUSPENSE */) {
4490 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
4491 }
4492 else {
4493 warn('Invalid HostVNode type:', type, `(${typeof type})`);
4494 }
4495 }
4496 if (ref != null) {
4497 setRef(ref, null, parentSuspense, vnode);
4498 }
4499 return nextNode;
4500 };
4501 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4502 optimized = optimized || !!vnode.dynamicChildren;
4503 const { props, patchFlag, shapeFlag, dirs } = vnode;
4504 // skip props & children if this is hoisted static nodes
4505 if (patchFlag !== -1 /* HOISTED */) {
4506 if (dirs) {
4507 invokeDirectiveHook(vnode, null, parentComponent, 'created');
4508 }
4509 // props
4510 if (props) {
4511 if (!optimized ||
4512 (patchFlag & 16 /* FULL_PROPS */ ||
4513 patchFlag & 32 /* HYDRATE_EVENTS */)) {
4514 for (const key in props) {
4515 if (!isReservedProp(key) && isOn(key)) {
4516 patchProp(el, key, null, props[key]);
4517 }
4518 }
4519 }
4520 else if (props.onClick) {
4521 // Fast path for click listeners (which is most often) to avoid
4522 // iterating through props.
4523 patchProp(el, 'onClick', null, props.onClick);
4524 }
4525 }
4526 // vnode / directive hooks
4527 let vnodeHooks;
4528 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
4529 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4530 }
4531 if (dirs) {
4532 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
4533 }
4534 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
4535 queueEffectWithSuspense(() => {
4536 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4537 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
4538 }, parentSuspense);
4539 }
4540 // children
4541 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
4542 // skip if element has innerHTML / textContent
4543 !(props && (props.innerHTML || props.textContent))) {
4544 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
4545 let hasWarned = false;
4546 while (next) {
4547 hasMismatch = true;
4548 if (!hasWarned) {
4549 warn(`Hydration children mismatch in <${vnode.type}>: ` +
4550 `server rendered element contains more child nodes than client vdom.`);
4551 hasWarned = true;
4552 }
4553 // The SSRed DOM contains more nodes than it should. Remove them.
4554 const cur = next;
4555 next = next.nextSibling;
4556 remove(cur);
4557 }
4558 }
4559 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
4560 if (el.textContent !== vnode.children) {
4561 hasMismatch = true;
4562 warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
4563 `- Client: ${el.textContent}\n` +
4564 `- Server: ${vnode.children}`);
4565 el.textContent = vnode.children;
4566 }
4567 }
4568 }
4569 return el.nextSibling;
4570 };
4571 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4572 optimized = optimized || !!parentVNode.dynamicChildren;
4573 const children = parentVNode.children;
4574 const l = children.length;
4575 let hasWarned = false;
4576 for (let i = 0; i < l; i++) {
4577 const vnode = optimized
4578 ? children[i]
4579 : (children[i] = normalizeVNode(children[i]));
4580 if (node) {
4581 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4582 }
4583 else if (vnode.type === Text && !vnode.children) {
4584 continue;
4585 }
4586 else {
4587 hasMismatch = true;
4588 if (!hasWarned) {
4589 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
4590 `server rendered element contains fewer child nodes than client vdom.`);
4591 hasWarned = true;
4592 }
4593 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
4594 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
4595 }
4596 }
4597 return node;
4598 };
4599 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4600 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
4601 if (fragmentSlotScopeIds) {
4602 slotScopeIds = slotScopeIds
4603 ? slotScopeIds.concat(fragmentSlotScopeIds)
4604 : fragmentSlotScopeIds;
4605 }
4606 const container = parentNode(node);
4607 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
4608 if (next && isComment(next) && next.data === ']') {
4609 return nextSibling((vnode.anchor = next));
4610 }
4611 else {
4612 // fragment didn't hydrate successfully, since we didn't get a end anchor
4613 // back. This should have led to node/children mismatch warnings.
4614 hasMismatch = true;
4615 // since the anchor is missing, we need to create one and insert it
4616 insert((vnode.anchor = createComment(`]`)), container, next);
4617 return next;
4618 }
4619 };
4620 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
4621 hasMismatch = true;
4622 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
4623 ? `(text)`
4624 : isComment(node) && node.data === '['
4625 ? `(start of fragment)`
4626 : ``);
4627 vnode.el = null;
4628 if (isFragment) {
4629 // remove excessive fragment nodes
4630 const end = locateClosingAsyncAnchor(node);
4631 while (true) {
4632 const next = nextSibling(node);
4633 if (next && next !== end) {
4634 remove(next);
4635 }
4636 else {
4637 break;
4638 }
4639 }
4640 }
4641 const next = nextSibling(node);
4642 const container = parentNode(node);
4643 remove(node);
4644 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
4645 return next;
4646 };
4647 const locateClosingAsyncAnchor = (node) => {
4648 let match = 0;
4649 while (node) {
4650 node = nextSibling(node);
4651 if (node && isComment(node)) {
4652 if (node.data === '[')
4653 match++;
4654 if (node.data === ']') {
4655 if (match === 0) {
4656 return nextSibling(node);
4657 }
4658 else {
4659 match--;
4660 }
4661 }
4662 }
4663 }
4664 return node;
4665 };
4666 return [hydrate, hydrateNode];
4667 }
4668
4669 let supported;
4670 let perf;
4671 function startMeasure(instance, type) {
4672 if (instance.appContext.config.performance && isSupported()) {
4673 perf.mark(`vue-${type}-${instance.uid}`);
4674 }
4675 }
4676 function endMeasure(instance, type) {
4677 if (instance.appContext.config.performance && isSupported()) {
4678 const startTag = `vue-${type}-${instance.uid}`;
4679 const endTag = startTag + `:end`;
4680 perf.mark(endTag);
4681 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
4682 perf.clearMarks(startTag);
4683 perf.clearMarks(endTag);
4684 }
4685 }
4686 function isSupported() {
4687 if (supported !== undefined) {
4688 return supported;
4689 }
4690 /* eslint-disable no-restricted-globals */
4691 if (typeof window !== 'undefined' && window.performance) {
4692 supported = true;
4693 perf = window.performance;
4694 }
4695 else {
4696 supported = false;
4697 }
4698 /* eslint-enable no-restricted-globals */
4699 return supported;
4700 }
4701
4702 // implementation, close to no-op
4703 function defineComponent(options) {
4704 return isFunction(options) ? { setup: options, name: options.name } : options;
4705 }
4706
4707 const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
4708 function defineAsyncComponent(source) {
4709 if (isFunction(source)) {
4710 source = { loader: source };
4711 }
4712 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
4713 suspensible = true, onError: userOnError } = source;
4714 let pendingRequest = null;
4715 let resolvedComp;
4716 let retries = 0;
4717 const retry = () => {
4718 retries++;
4719 pendingRequest = null;
4720 return load();
4721 };
4722 const load = () => {
4723 let thisRequest;
4724 return (pendingRequest ||
4725 (thisRequest = pendingRequest = loader()
4726 .catch(err => {
4727 err = err instanceof Error ? err : new Error(String(err));
4728 if (userOnError) {
4729 return new Promise((resolve, reject) => {
4730 const userRetry = () => resolve(retry());
4731 const userFail = () => reject(err);
4732 userOnError(err, userRetry, userFail, retries + 1);
4733 });
4734 }
4735 else {
4736 throw err;
4737 }
4738 })
4739 .then((comp) => {
4740 if (thisRequest !== pendingRequest && pendingRequest) {
4741 return pendingRequest;
4742 }
4743 if (!comp) {
4744 warn(`Async component loader resolved to undefined. ` +
4745 `If you are using retry(), make sure to return its return value.`);
4746 }
4747 // interop module default
4748 if (comp &&
4749 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
4750 comp = comp.default;
4751 }
4752 if (comp && !isObject(comp) && !isFunction(comp)) {
4753 throw new Error(`Invalid async component load result: ${comp}`);
4754 }
4755 resolvedComp = comp;
4756 return comp;
4757 })));
4758 };
4759 return defineComponent({
4760 __asyncLoader: load,
4761 name: 'AsyncComponentWrapper',
4762 setup() {
4763 const instance = currentInstance;
4764 // already resolved
4765 if (resolvedComp) {
4766 return () => createInnerComp(resolvedComp, instance);
4767 }
4768 const onError = (err) => {
4769 pendingRequest = null;
4770 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
4771 };
4772 // suspense-controlled or SSR.
4773 if ((suspensible && instance.suspense) ||
4774 (false )) {
4775 return load()
4776 .then(comp => {
4777 return () => createInnerComp(comp, instance);
4778 })
4779 .catch(err => {
4780 onError(err);
4781 return () => errorComponent
4782 ? createVNode(errorComponent, {
4783 error: err
4784 })
4785 : null;
4786 });
4787 }
4788 const loaded = ref(false);
4789 const error = ref();
4790 const delayed = ref(!!delay);
4791 if (delay) {
4792 setTimeout(() => {
4793 delayed.value = false;
4794 }, delay);
4795 }
4796 if (timeout != null) {
4797 setTimeout(() => {
4798 if (!loaded.value && !error.value) {
4799 const err = new Error(`Async component timed out after ${timeout}ms.`);
4800 onError(err);
4801 error.value = err;
4802 }
4803 }, timeout);
4804 }
4805 load()
4806 .then(() => {
4807 loaded.value = true;
4808 })
4809 .catch(err => {
4810 onError(err);
4811 error.value = err;
4812 });
4813 return () => {
4814 if (loaded.value && resolvedComp) {
4815 return createInnerComp(resolvedComp, instance);
4816 }
4817 else if (error.value && errorComponent) {
4818 return createVNode(errorComponent, {
4819 error: error.value
4820 });
4821 }
4822 else if (loadingComponent && !delayed.value) {
4823 return createVNode(loadingComponent);
4824 }
4825 };
4826 }
4827 });
4828 }
4829 function createInnerComp(comp, { vnode: { ref, props, children } }) {
4830 const vnode = createVNode(comp, props, children);
4831 // ensure inner component inherits the async wrapper's ref owner
4832 vnode.ref = ref;
4833 return vnode;
4834 }
4835
4836 function createDevEffectOptions(instance) {
4837 return {
4838 scheduler: queueJob,
4839 allowRecurse: true,
4840 onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0,
4841 onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 0
4842 };
4843 }
4844 const queuePostRenderEffect = queueEffectWithSuspense
4845 ;
4846 const setRef = (rawRef, oldRawRef, parentSuspense, vnode) => {
4847 if (isArray(rawRef)) {
4848 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode));
4849 return;
4850 }
4851 let value;
4852 if (!vnode) {
4853 // means unmount
4854 value = null;
4855 }
4856 else if (isAsyncWrapper(vnode)) {
4857 // when mounting async components, nothing needs to be done,
4858 // because the template ref is forwarded to inner component
4859 return;
4860 }
4861 else if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
4862 value = vnode.component.exposed || vnode.component.proxy;
4863 }
4864 else {
4865 value = vnode.el;
4866 }
4867 const { i: owner, r: ref } = rawRef;
4868 if (!owner) {
4869 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
4870 `A vnode with ref must be created inside the render function.`);
4871 return;
4872 }
4873 const oldRef = oldRawRef && oldRawRef.r;
4874 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
4875 const setupState = owner.setupState;
4876 // unset old ref
4877 if (oldRef != null && oldRef !== ref) {
4878 if (isString(oldRef)) {
4879 refs[oldRef] = null;
4880 if (hasOwn(setupState, oldRef)) {
4881 setupState[oldRef] = null;
4882 }
4883 }
4884 else if (isRef(oldRef)) {
4885 oldRef.value = null;
4886 }
4887 }
4888 if (isString(ref)) {
4889 const doSet = () => {
4890 refs[ref] = value;
4891 if (hasOwn(setupState, ref)) {
4892 setupState[ref] = value;
4893 }
4894 };
4895 // #1789: for non-null values, set them after render
4896 // null values means this is unmount and it should not overwrite another
4897 // ref with the same key
4898 if (value) {
4899 doSet.id = -1;
4900 queuePostRenderEffect(doSet, parentSuspense);
4901 }
4902 else {
4903 doSet();
4904 }
4905 }
4906 else if (isRef(ref)) {
4907 const doSet = () => {
4908 ref.value = value;
4909 };
4910 if (value) {
4911 doSet.id = -1;
4912 queuePostRenderEffect(doSet, parentSuspense);
4913 }
4914 else {
4915 doSet();
4916 }
4917 }
4918 else if (isFunction(ref)) {
4919 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
4920 }
4921 else {
4922 warn('Invalid template ref type:', value, `(${typeof value})`);
4923 }
4924 };
4925 /**
4926 * The createRenderer function accepts two generic arguments:
4927 * HostNode and HostElement, corresponding to Node and Element types in the
4928 * host environment. For example, for runtime-dom, HostNode would be the DOM
4929 * `Node` interface and HostElement would be the DOM `Element` interface.
4930 *
4931 * Custom renderers can pass in the platform specific types like this:
4932 *
4933 * ``` js
4934 * const { render, createApp } = createRenderer<Node, Element>({
4935 * patchProp,
4936 * ...nodeOps
4937 * })
4938 * ```
4939 */
4940 function createRenderer(options) {
4941 return baseCreateRenderer(options);
4942 }
4943 // Separate API for creating hydration-enabled renderer.
4944 // Hydration logic is only used when calling this function, making it
4945 // tree-shakable.
4946 function createHydrationRenderer(options) {
4947 return baseCreateRenderer(options, createHydrationFunctions);
4948 }
4949 // implementation
4950 function baseCreateRenderer(options, createHydrationFns) {
4951 {
4952 const target = getGlobalThis();
4953 target.__VUE__ = true;
4954 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__);
4955 }
4956 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
4957 // Note: functions inside this closure should use `const xxx = () => {}`
4958 // style in order to prevent being inlined by minifiers.
4959 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = false) => {
4960 // patching & not same type, unmount old tree
4961 if (n1 && !isSameVNodeType(n1, n2)) {
4962 anchor = getNextHostNode(n1);
4963 unmount(n1, parentComponent, parentSuspense, true);
4964 n1 = null;
4965 }
4966 if (n2.patchFlag === -2 /* BAIL */) {
4967 optimized = false;
4968 n2.dynamicChildren = null;
4969 }
4970 const { type, ref, shapeFlag } = n2;
4971 switch (type) {
4972 case Text:
4973 processText(n1, n2, container, anchor);
4974 break;
4975 case Comment:
4976 processCommentNode(n1, n2, container, anchor);
4977 break;
4978 case Static:
4979 if (n1 == null) {
4980 mountStaticNode(n2, container, anchor, isSVG);
4981 }
4982 else {
4983 patchStaticNode(n1, n2, container, isSVG);
4984 }
4985 break;
4986 case Fragment:
4987 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
4988 break;
4989 default:
4990 if (shapeFlag & 1 /* ELEMENT */) {
4991 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
4992 }
4993 else if (shapeFlag & 6 /* COMPONENT */) {
4994 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
4995 }
4996 else if (shapeFlag & 64 /* TELEPORT */) {
4997 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
4998 }
4999 else if (shapeFlag & 128 /* SUSPENSE */) {
5000 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
5001 }
5002 else {
5003 warn('Invalid VNode type:', type, `(${typeof type})`);
5004 }
5005 }
5006 // set ref
5007 if (ref != null && parentComponent) {
5008 setRef(ref, n1 && n1.ref, parentSuspense, n2);
5009 }
5010 };
5011 const processText = (n1, n2, container, anchor) => {
5012 if (n1 == null) {
5013 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
5014 }
5015 else {
5016 const el = (n2.el = n1.el);
5017 if (n2.children !== n1.children) {
5018 hostSetText(el, n2.children);
5019 }
5020 }
5021 };
5022 const processCommentNode = (n1, n2, container, anchor) => {
5023 if (n1 == null) {
5024 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
5025 }
5026 else {
5027 // there's no support for dynamic comments
5028 n2.el = n1.el;
5029 }
5030 };
5031 const mountStaticNode = (n2, container, anchor, isSVG) => {
5032 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5033 };
5034 /**
5035 * Dev / HMR only
5036 */
5037 const patchStaticNode = (n1, n2, container, isSVG) => {
5038 // static nodes are only patched during dev for HMR
5039 if (n2.children !== n1.children) {
5040 const anchor = hostNextSibling(n1.anchor);
5041 // remove existing
5042 removeStaticNode(n1);
5043 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5044 }
5045 else {
5046 n2.el = n1.el;
5047 n2.anchor = n1.anchor;
5048 }
5049 };
5050 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
5051 let next;
5052 while (el && el !== anchor) {
5053 next = hostNextSibling(el);
5054 hostInsert(el, container, nextSibling);
5055 el = next;
5056 }
5057 hostInsert(anchor, container, nextSibling);
5058 };
5059 const removeStaticNode = ({ el, anchor }) => {
5060 let next;
5061 while (el && el !== anchor) {
5062 next = hostNextSibling(el);
5063 hostRemove(el);
5064 el = next;
5065 }
5066 hostRemove(anchor);
5067 };
5068 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5069 isSVG = isSVG || n2.type === 'svg';
5070 if (n1 == null) {
5071 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5072 }
5073 else {
5074 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5075 }
5076 };
5077 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5078 let el;
5079 let vnodeHook;
5080 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
5081 {
5082 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
5083 // mount children first, since some props may rely on child content
5084 // being already rendered, e.g. `<select value>`
5085 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5086 hostSetElementText(el, vnode.children);
5087 }
5088 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5089 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized || !!vnode.dynamicChildren);
5090 }
5091 if (dirs) {
5092 invokeDirectiveHook(vnode, null, parentComponent, 'created');
5093 }
5094 // props
5095 if (props) {
5096 for (const key in props) {
5097 if (!isReservedProp(key)) {
5098 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5099 }
5100 }
5101 if ((vnodeHook = props.onVnodeBeforeMount)) {
5102 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5103 }
5104 }
5105 // scopeId
5106 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
5107 }
5108 {
5109 Object.defineProperty(el, '__vnode', {
5110 value: vnode,
5111 enumerable: false
5112 });
5113 Object.defineProperty(el, '__vueParentComponent', {
5114 value: parentComponent,
5115 enumerable: false
5116 });
5117 }
5118 if (dirs) {
5119 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
5120 }
5121 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
5122 // #1689 For inside suspense + suspense resolved case, just call it
5123 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
5124 transition &&
5125 !transition.persisted;
5126 if (needCallTransitionHooks) {
5127 transition.beforeEnter(el);
5128 }
5129 hostInsert(el, container, anchor);
5130 if ((vnodeHook = props && props.onVnodeMounted) ||
5131 needCallTransitionHooks ||
5132 dirs) {
5133 queuePostRenderEffect(() => {
5134 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5135 needCallTransitionHooks && transition.enter(el);
5136 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
5137 }, parentSuspense);
5138 }
5139 };
5140 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
5141 if (scopeId) {
5142 hostSetScopeId(el, scopeId);
5143 }
5144 if (slotScopeIds) {
5145 for (let i = 0; i < slotScopeIds.length; i++) {
5146 hostSetScopeId(el, slotScopeIds[i]);
5147 }
5148 }
5149 if (parentComponent) {
5150 let subTree = parentComponent.subTree;
5151 if (subTree.patchFlag > 0 &&
5152 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
5153 subTree =
5154 filterSingleRoot(subTree.children) || subTree;
5155 }
5156 if (vnode === subTree) {
5157 const parentVNode = parentComponent.vnode;
5158 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
5159 }
5160 }
5161 };
5162 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, slotScopeIds, start = 0) => {
5163 for (let i = start; i < children.length; i++) {
5164 const child = (children[i] = optimized
5165 ? cloneIfMounted(children[i])
5166 : normalizeVNode(children[i]));
5167 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized, slotScopeIds);
5168 }
5169 };
5170 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5171 const el = (n2.el = n1.el);
5172 let { patchFlag, dynamicChildren, dirs } = n2;
5173 // #1426 take the old vnode's patch flag into account since user may clone a
5174 // compiler-generated vnode, which de-opts to FULL_PROPS
5175 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
5176 const oldProps = n1.props || EMPTY_OBJ;
5177 const newProps = n2.props || EMPTY_OBJ;
5178 let vnodeHook;
5179 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5180 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5181 }
5182 if (dirs) {
5183 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5184 }
5185 if (isHmrUpdating) {
5186 // HMR updated, force full diff
5187 patchFlag = 0;
5188 optimized = false;
5189 dynamicChildren = null;
5190 }
5191 if (patchFlag > 0) {
5192 // the presence of a patchFlag means this element's render code was
5193 // generated by the compiler and can take the fast path.
5194 // in this path old node and new node are guaranteed to have the same shape
5195 // (i.e. at the exact same position in the source template)
5196 if (patchFlag & 16 /* FULL_PROPS */) {
5197 // element props contain dynamic keys, full diff needed
5198 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5199 }
5200 else {
5201 // class
5202 // this flag is matched when the element has dynamic class bindings.
5203 if (patchFlag & 2 /* CLASS */) {
5204 if (oldProps.class !== newProps.class) {
5205 hostPatchProp(el, 'class', null, newProps.class, isSVG);
5206 }
5207 }
5208 // style
5209 // this flag is matched when the element has dynamic style bindings
5210 if (patchFlag & 4 /* STYLE */) {
5211 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
5212 }
5213 // props
5214 // This flag is matched when the element has dynamic prop/attr bindings
5215 // other than class and style. The keys of dynamic prop/attrs are saved for
5216 // faster iteration.
5217 // Note dynamic keys like :[foo]="bar" will cause this optimization to
5218 // bail out and go through a full diff because we need to unset the old key
5219 if (patchFlag & 8 /* PROPS */) {
5220 // if the flag is present then dynamicProps must be non-null
5221 const propsToUpdate = n2.dynamicProps;
5222 for (let i = 0; i < propsToUpdate.length; i++) {
5223 const key = propsToUpdate[i];
5224 const prev = oldProps[key];
5225 const next = newProps[key];
5226 if (next !== prev ||
5227 (hostForcePatchProp && hostForcePatchProp(el, key))) {
5228 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
5229 }
5230 }
5231 }
5232 }
5233 // text
5234 // This flag is matched when the element has only dynamic text children.
5235 if (patchFlag & 1 /* TEXT */) {
5236 if (n1.children !== n2.children) {
5237 hostSetElementText(el, n2.children);
5238 }
5239 }
5240 }
5241 else if (!optimized && dynamicChildren == null) {
5242 // unoptimized, full diff
5243 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5244 }
5245 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
5246 if (dynamicChildren) {
5247 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
5248 if (parentComponent && parentComponent.type.__hmrId) {
5249 traverseStaticChildren(n1, n2);
5250 }
5251 }
5252 else if (!optimized) {
5253 // full diff
5254 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
5255 }
5256 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
5257 queuePostRenderEffect(() => {
5258 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5259 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
5260 }, parentSuspense);
5261 }
5262 };
5263 // The fast path for blocks.
5264 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
5265 for (let i = 0; i < newChildren.length; i++) {
5266 const oldVNode = oldChildren[i];
5267 const newVNode = newChildren[i];
5268 // Determine the container (parent element) for the patch.
5269 const container =
5270 // - In the case of a Fragment, we need to provide the actual parent
5271 // of the Fragment itself so it can move its children.
5272 oldVNode.type === Fragment ||
5273 // - In the case of different nodes, there is going to be a replacement
5274 // which also requires the correct parent container
5275 !isSameVNodeType(oldVNode, newVNode) ||
5276 // - In the case of a component, it could contain anything.
5277 oldVNode.shapeFlag & 6 /* COMPONENT */ ||
5278 oldVNode.shapeFlag & 64 /* TELEPORT */
5279 ? hostParentNode(oldVNode.el)
5280 : // In other cases, the parent container is not actually used so we
5281 // just pass the block element here to avoid a DOM parentNode call.
5282 fallbackContainer;
5283 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
5284 }
5285 };
5286 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
5287 if (oldProps !== newProps) {
5288 for (const key in newProps) {
5289 // empty string is not valid prop
5290 if (isReservedProp(key))
5291 continue;
5292 const next = newProps[key];
5293 const prev = oldProps[key];
5294 if (next !== prev ||
5295 (hostForcePatchProp && hostForcePatchProp(el, key))) {
5296 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5297 }
5298 }
5299 if (oldProps !== EMPTY_OBJ) {
5300 for (const key in oldProps) {
5301 if (!isReservedProp(key) && !(key in newProps)) {
5302 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5303 }
5304 }
5305 }
5306 }
5307 };
5308 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5309 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
5310 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
5311 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
5312 if (patchFlag > 0) {
5313 optimized = true;
5314 }
5315 // check if this is a slot fragment with :slotted scope ids
5316 if (fragmentSlotScopeIds) {
5317 slotScopeIds = slotScopeIds
5318 ? slotScopeIds.concat(fragmentSlotScopeIds)
5319 : fragmentSlotScopeIds;
5320 }
5321 if (isHmrUpdating) {
5322 // HMR updated, force full diff
5323 patchFlag = 0;
5324 optimized = false;
5325 dynamicChildren = null;
5326 }
5327 if (n1 == null) {
5328 hostInsert(fragmentStartAnchor, container, anchor);
5329 hostInsert(fragmentEndAnchor, container, anchor);
5330 // a fragment can only have array children
5331 // since they are either generated by the compiler, or implicitly created
5332 // from arrays.
5333 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5334 }
5335 else {
5336 if (patchFlag > 0 &&
5337 patchFlag & 64 /* STABLE_FRAGMENT */ &&
5338 dynamicChildren &&
5339 // #2715 the previous fragment could've been a BAILed one as a result
5340 // of renderSlot() with no valid children
5341 n1.dynamicChildren) {
5342 // a stable fragment (template root or <template v-for>) doesn't need to
5343 // patch children order, but it may contain dynamicChildren.
5344 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
5345 if (parentComponent && parentComponent.type.__hmrId) {
5346 traverseStaticChildren(n1, n2);
5347 }
5348 else if (
5349 // #2080 if the stable fragment has a key, it's a <template v-for> that may
5350 // get moved around. Make sure all root level vnodes inherit el.
5351 // #2134 or if it's a component root, it may also get moved around
5352 // as the component is being moved.
5353 n2.key != null ||
5354 (parentComponent && n2 === parentComponent.subTree)) {
5355 traverseStaticChildren(n1, n2, true /* shallow */);
5356 }
5357 }
5358 else {
5359 // keyed / unkeyed, or manual fragments.
5360 // for keyed & unkeyed, since they are compiler generated from v-for,
5361 // each child is guaranteed to be a block so the fragment will never
5362 // have dynamicChildren.
5363 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5364 }
5365 }
5366 };
5367 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5368 n2.slotScopeIds = slotScopeIds;
5369 if (n1 == null) {
5370 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
5371 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
5372 }
5373 else {
5374 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5375 }
5376 }
5377 else {
5378 updateComponent(n1, n2, optimized);
5379 }
5380 };
5381 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5382 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
5383 if (instance.type.__hmrId) {
5384 registerHMR(instance);
5385 }
5386 {
5387 pushWarningContext(initialVNode);
5388 startMeasure(instance, `mount`);
5389 }
5390 // inject renderer internals for keepAlive
5391 if (isKeepAlive(initialVNode)) {
5392 instance.ctx.renderer = internals;
5393 }
5394 // resolve props and slots for setup context
5395 {
5396 startMeasure(instance, `init`);
5397 }
5398 setupComponent(instance);
5399 {
5400 endMeasure(instance, `init`);
5401 }
5402 // setup() is async. This component relies on async logic to be resolved
5403 // before proceeding
5404 if (instance.asyncDep) {
5405 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
5406 // Give it a placeholder if this is not hydration
5407 // TODO handle self-defined fallback
5408 if (!initialVNode.el) {
5409 const placeholder = (instance.subTree = createVNode(Comment));
5410 processCommentNode(null, placeholder, container, anchor);
5411 }
5412 return;
5413 }
5414 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
5415 {
5416 popWarningContext();
5417 endMeasure(instance, `mount`);
5418 }
5419 };
5420 const updateComponent = (n1, n2, optimized) => {
5421 const instance = (n2.component = n1.component);
5422 if (shouldUpdateComponent(n1, n2, optimized)) {
5423 if (instance.asyncDep &&
5424 !instance.asyncResolved) {
5425 // async & still pending - just update props and slots
5426 // since the component's reactive effect for render isn't set-up yet
5427 {
5428 pushWarningContext(n2);
5429 }
5430 updateComponentPreRender(instance, n2, optimized);
5431 {
5432 popWarningContext();
5433 }
5434 return;
5435 }
5436 else {
5437 // normal update
5438 instance.next = n2;
5439 // in case the child component is also queued, remove it to avoid
5440 // double updating the same child component in the same flush.
5441 invalidateJob(instance.update);
5442 // instance.update is the reactive effect runner.
5443 instance.update();
5444 }
5445 }
5446 else {
5447 // no update needed. just copy over properties
5448 n2.component = n1.component;
5449 n2.el = n1.el;
5450 instance.vnode = n2;
5451 }
5452 };
5453 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
5454 // create reactive effect for rendering
5455 instance.update = effect(function componentEffect() {
5456 if (!instance.isMounted) {
5457 let vnodeHook;
5458 const { el, props } = initialVNode;
5459 const { bm, m, parent } = instance;
5460 // beforeMount hook
5461 if (bm) {
5462 invokeArrayFns(bm);
5463 }
5464 // onVnodeBeforeMount
5465 if ((vnodeHook = props && props.onVnodeBeforeMount)) {
5466 invokeVNodeHook(vnodeHook, parent, initialVNode);
5467 }
5468 // render
5469 {
5470 startMeasure(instance, `render`);
5471 }
5472 const subTree = (instance.subTree = renderComponentRoot(instance));
5473 {
5474 endMeasure(instance, `render`);
5475 }
5476 if (el && hydrateNode) {
5477 {
5478 startMeasure(instance, `hydrate`);
5479 }
5480 // vnode has adopted host node - perform hydration instead of mount.
5481 hydrateNode(initialVNode.el, subTree, instance, parentSuspense, null);
5482 {
5483 endMeasure(instance, `hydrate`);
5484 }
5485 }
5486 else {
5487 {
5488 startMeasure(instance, `patch`);
5489 }
5490 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
5491 {
5492 endMeasure(instance, `patch`);
5493 }
5494 initialVNode.el = subTree.el;
5495 }
5496 // mounted hook
5497 if (m) {
5498 queuePostRenderEffect(m, parentSuspense);
5499 }
5500 // onVnodeMounted
5501 if ((vnodeHook = props && props.onVnodeMounted)) {
5502 const scopedInitialVNode = initialVNode;
5503 queuePostRenderEffect(() => {
5504 invokeVNodeHook(vnodeHook, parent, scopedInitialVNode);
5505 }, parentSuspense);
5506 }
5507 // activated hook for keep-alive roots.
5508 // #1742 activated hook must be accessed after first render
5509 // since the hook may be injected by a child keep-alive
5510 const { a } = instance;
5511 if (a &&
5512 initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5513 queuePostRenderEffect(a, parentSuspense);
5514 }
5515 instance.isMounted = true;
5516 {
5517 devtoolsComponentAdded(instance);
5518 }
5519 // #2458: deference mount-only object parameters to prevent memleaks
5520 initialVNode = container = anchor = null;
5521 }
5522 else {
5523 // updateComponent
5524 // This is triggered by mutation of component's own state (next: null)
5525 // OR parent calling processComponent (next: VNode)
5526 let { next, bu, u, parent, vnode } = instance;
5527 let originNext = next;
5528 let vnodeHook;
5529 {
5530 pushWarningContext(next || instance.vnode);
5531 }
5532 if (next) {
5533 next.el = vnode.el;
5534 updateComponentPreRender(instance, next, optimized);
5535 }
5536 else {
5537 next = vnode;
5538 }
5539 // beforeUpdate hook
5540 if (bu) {
5541 invokeArrayFns(bu);
5542 }
5543 // onVnodeBeforeUpdate
5544 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
5545 invokeVNodeHook(vnodeHook, parent, next, vnode);
5546 }
5547 // render
5548 {
5549 startMeasure(instance, `render`);
5550 }
5551 const nextTree = renderComponentRoot(instance);
5552 {
5553 endMeasure(instance, `render`);
5554 }
5555 const prevTree = instance.subTree;
5556 instance.subTree = nextTree;
5557 {
5558 startMeasure(instance, `patch`);
5559 }
5560 patch(prevTree, nextTree,
5561 // parent may have changed if it's in a teleport
5562 hostParentNode(prevTree.el),
5563 // anchor may have changed if it's in a fragment
5564 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
5565 {
5566 endMeasure(instance, `patch`);
5567 }
5568 next.el = nextTree.el;
5569 if (originNext === null) {
5570 // self-triggered update. In case of HOC, update parent component
5571 // vnode el. HOC is indicated by parent instance's subTree pointing
5572 // to child component's vnode
5573 updateHOCHostEl(instance, nextTree.el);
5574 }
5575 // updated hook
5576 if (u) {
5577 queuePostRenderEffect(u, parentSuspense);
5578 }
5579 // onVnodeUpdated
5580 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
5581 queuePostRenderEffect(() => {
5582 invokeVNodeHook(vnodeHook, parent, next, vnode);
5583 }, parentSuspense);
5584 }
5585 {
5586 devtoolsComponentUpdated(instance);
5587 }
5588 {
5589 popWarningContext();
5590 }
5591 }
5592 }, createDevEffectOptions(instance) );
5593 };
5594 const updateComponentPreRender = (instance, nextVNode, optimized) => {
5595 nextVNode.component = instance;
5596 const prevProps = instance.vnode.props;
5597 instance.vnode = nextVNode;
5598 instance.next = null;
5599 updateProps(instance, nextVNode.props, prevProps, optimized);
5600 updateSlots(instance, nextVNode.children, optimized);
5601 pauseTracking();
5602 // props update may have triggered pre-flush watchers.
5603 // flush them before the render update.
5604 flushPreFlushCbs(undefined, instance.update);
5605 resetTracking();
5606 };
5607 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
5608 const c1 = n1 && n1.children;
5609 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
5610 const c2 = n2.children;
5611 const { patchFlag, shapeFlag } = n2;
5612 // fast path
5613 if (patchFlag > 0) {
5614 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
5615 // this could be either fully-keyed or mixed (some keyed some not)
5616 // presence of patchFlag means children are guaranteed to be arrays
5617 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5618 return;
5619 }
5620 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
5621 // unkeyed
5622 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5623 return;
5624 }
5625 }
5626 // children has 3 possibilities: text, array or no children.
5627 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5628 // text children fast path
5629 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5630 unmountChildren(c1, parentComponent, parentSuspense);
5631 }
5632 if (c2 !== c1) {
5633 hostSetElementText(container, c2);
5634 }
5635 }
5636 else {
5637 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5638 // prev children was array
5639 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5640 // two arrays, cannot assume anything, do full diff
5641 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5642 }
5643 else {
5644 // no new children, just unmount old
5645 unmountChildren(c1, parentComponent, parentSuspense, true);
5646 }
5647 }
5648 else {
5649 // prev children was text OR null
5650 // new children is array OR null
5651 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
5652 hostSetElementText(container, '');
5653 }
5654 // mount new if array
5655 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5656 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5657 }
5658 }
5659 }
5660 };
5661 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5662 c1 = c1 || EMPTY_ARR;
5663 c2 = c2 || EMPTY_ARR;
5664 const oldLength = c1.length;
5665 const newLength = c2.length;
5666 const commonLength = Math.min(oldLength, newLength);
5667 let i;
5668 for (i = 0; i < commonLength; i++) {
5669 const nextChild = (c2[i] = optimized
5670 ? cloneIfMounted(c2[i])
5671 : normalizeVNode(c2[i]));
5672 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5673 }
5674 if (oldLength > newLength) {
5675 // remove old
5676 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
5677 }
5678 else {
5679 // mount new
5680 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
5681 }
5682 };
5683 // can be all-keyed or mixed
5684 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5685 let i = 0;
5686 const l2 = c2.length;
5687 let e1 = c1.length - 1; // prev ending index
5688 let e2 = l2 - 1; // next ending index
5689 // 1. sync from start
5690 // (a b) c
5691 // (a b) d e
5692 while (i <= e1 && i <= e2) {
5693 const n1 = c1[i];
5694 const n2 = (c2[i] = optimized
5695 ? cloneIfMounted(c2[i])
5696 : normalizeVNode(c2[i]));
5697 if (isSameVNodeType(n1, n2)) {
5698 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5699 }
5700 else {
5701 break;
5702 }
5703 i++;
5704 }
5705 // 2. sync from end
5706 // a (b c)
5707 // d e (b c)
5708 while (i <= e1 && i <= e2) {
5709 const n1 = c1[e1];
5710 const n2 = (c2[e2] = optimized
5711 ? cloneIfMounted(c2[e2])
5712 : normalizeVNode(c2[e2]));
5713 if (isSameVNodeType(n1, n2)) {
5714 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5715 }
5716 else {
5717 break;
5718 }
5719 e1--;
5720 e2--;
5721 }
5722 // 3. common sequence + mount
5723 // (a b)
5724 // (a b) c
5725 // i = 2, e1 = 1, e2 = 2
5726 // (a b)
5727 // c (a b)
5728 // i = 0, e1 = -1, e2 = 0
5729 if (i > e1) {
5730 if (i <= e2) {
5731 const nextPos = e2 + 1;
5732 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
5733 while (i <= e2) {
5734 patch(null, (c2[i] = optimized
5735 ? cloneIfMounted(c2[i])
5736 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5737 i++;
5738 }
5739 }
5740 }
5741 // 4. common sequence + unmount
5742 // (a b) c
5743 // (a b)
5744 // i = 2, e1 = 2, e2 = 1
5745 // a (b c)
5746 // (b c)
5747 // i = 0, e1 = 0, e2 = -1
5748 else if (i > e2) {
5749 while (i <= e1) {
5750 unmount(c1[i], parentComponent, parentSuspense, true);
5751 i++;
5752 }
5753 }
5754 // 5. unknown sequence
5755 // [i ... e1 + 1]: a b [c d e] f g
5756 // [i ... e2 + 1]: a b [e d c h] f g
5757 // i = 2, e1 = 4, e2 = 5
5758 else {
5759 const s1 = i; // prev starting index
5760 const s2 = i; // next starting index
5761 // 5.1 build key:index map for newChildren
5762 const keyToNewIndexMap = new Map();
5763 for (i = s2; i <= e2; i++) {
5764 const nextChild = (c2[i] = optimized
5765 ? cloneIfMounted(c2[i])
5766 : normalizeVNode(c2[i]));
5767 if (nextChild.key != null) {
5768 if (keyToNewIndexMap.has(nextChild.key)) {
5769 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
5770 }
5771 keyToNewIndexMap.set(nextChild.key, i);
5772 }
5773 }
5774 // 5.2 loop through old children left to be patched and try to patch
5775 // matching nodes & remove nodes that are no longer present
5776 let j;
5777 let patched = 0;
5778 const toBePatched = e2 - s2 + 1;
5779 let moved = false;
5780 // used to track whether any node has moved
5781 let maxNewIndexSoFar = 0;
5782 // works as Map<newIndex, oldIndex>
5783 // Note that oldIndex is offset by +1
5784 // and oldIndex = 0 is a special value indicating the new node has
5785 // no corresponding old node.
5786 // used for determining longest stable subsequence
5787 const newIndexToOldIndexMap = new Array(toBePatched);
5788 for (i = 0; i < toBePatched; i++)
5789 newIndexToOldIndexMap[i] = 0;
5790 for (i = s1; i <= e1; i++) {
5791 const prevChild = c1[i];
5792 if (patched >= toBePatched) {
5793 // all new children have been patched so this can only be a removal
5794 unmount(prevChild, parentComponent, parentSuspense, true);
5795 continue;
5796 }
5797 let newIndex;
5798 if (prevChild.key != null) {
5799 newIndex = keyToNewIndexMap.get(prevChild.key);
5800 }
5801 else {
5802 // key-less node, try to locate a key-less node of the same type
5803 for (j = s2; j <= e2; j++) {
5804 if (newIndexToOldIndexMap[j - s2] === 0 &&
5805 isSameVNodeType(prevChild, c2[j])) {
5806 newIndex = j;
5807 break;
5808 }
5809 }
5810 }
5811 if (newIndex === undefined) {
5812 unmount(prevChild, parentComponent, parentSuspense, true);
5813 }
5814 else {
5815 newIndexToOldIndexMap[newIndex - s2] = i + 1;
5816 if (newIndex >= maxNewIndexSoFar) {
5817 maxNewIndexSoFar = newIndex;
5818 }
5819 else {
5820 moved = true;
5821 }
5822 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5823 patched++;
5824 }
5825 }
5826 // 5.3 move and mount
5827 // generate longest stable subsequence only when nodes have moved
5828 const increasingNewIndexSequence = moved
5829 ? getSequence(newIndexToOldIndexMap)
5830 : EMPTY_ARR;
5831 j = increasingNewIndexSequence.length - 1;
5832 // looping backwards so that we can use last patched node as anchor
5833 for (i = toBePatched - 1; i >= 0; i--) {
5834 const nextIndex = s2 + i;
5835 const nextChild = c2[nextIndex];
5836 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
5837 if (newIndexToOldIndexMap[i] === 0) {
5838 // mount new
5839 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5840 }
5841 else if (moved) {
5842 // move if:
5843 // There is no stable subsequence (e.g. a reverse)
5844 // OR current node is not among the stable sequence
5845 if (j < 0 || i !== increasingNewIndexSequence[j]) {
5846 move(nextChild, container, anchor, 2 /* REORDER */);
5847 }
5848 else {
5849 j--;
5850 }
5851 }
5852 }
5853 }
5854 };
5855 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
5856 const { el, type, transition, children, shapeFlag } = vnode;
5857 if (shapeFlag & 6 /* COMPONENT */) {
5858 move(vnode.component.subTree, container, anchor, moveType);
5859 return;
5860 }
5861 if (shapeFlag & 128 /* SUSPENSE */) {
5862 vnode.suspense.move(container, anchor, moveType);
5863 return;
5864 }
5865 if (shapeFlag & 64 /* TELEPORT */) {
5866 type.move(vnode, container, anchor, internals);
5867 return;
5868 }
5869 if (type === Fragment) {
5870 hostInsert(el, container, anchor);
5871 for (let i = 0; i < children.length; i++) {
5872 move(children[i], container, anchor, moveType);
5873 }
5874 hostInsert(vnode.anchor, container, anchor);
5875 return;
5876 }
5877 if (type === Static) {
5878 moveStaticNode(vnode, container, anchor);
5879 return;
5880 }
5881 // single nodes
5882 const needTransition = moveType !== 2 /* REORDER */ &&
5883 shapeFlag & 1 /* ELEMENT */ &&
5884 transition;
5885 if (needTransition) {
5886 if (moveType === 0 /* ENTER */) {
5887 transition.beforeEnter(el);
5888 hostInsert(el, container, anchor);
5889 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
5890 }
5891 else {
5892 const { leave, delayLeave, afterLeave } = transition;
5893 const remove = () => hostInsert(el, container, anchor);
5894 const performLeave = () => {
5895 leave(el, () => {
5896 remove();
5897 afterLeave && afterLeave();
5898 });
5899 };
5900 if (delayLeave) {
5901 delayLeave(el, remove, performLeave);
5902 }
5903 else {
5904 performLeave();
5905 }
5906 }
5907 }
5908 else {
5909 hostInsert(el, container, anchor);
5910 }
5911 };
5912 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
5913 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
5914 // unset ref
5915 if (ref != null) {
5916 setRef(ref, null, parentSuspense, null);
5917 }
5918 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5919 parentComponent.ctx.deactivate(vnode);
5920 return;
5921 }
5922 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
5923 let vnodeHook;
5924 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {
5925 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5926 }
5927 if (shapeFlag & 6 /* COMPONENT */) {
5928 unmountComponent(vnode.component, parentSuspense, doRemove);
5929 }
5930 else {
5931 if (shapeFlag & 128 /* SUSPENSE */) {
5932 vnode.suspense.unmount(parentSuspense, doRemove);
5933 return;
5934 }
5935 if (shouldInvokeDirs) {
5936 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
5937 }
5938 if (shapeFlag & 64 /* TELEPORT */) {
5939 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
5940 }
5941 else if (dynamicChildren &&
5942 // #1153: fast path should not be taken for non-stable (v-for) fragments
5943 (type !== Fragment ||
5944 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
5945 // fast path for block nodes: only need to unmount dynamic children.
5946 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
5947 }
5948 else if ((type === Fragment &&
5949 (patchFlag & 128 /* KEYED_FRAGMENT */ ||
5950 patchFlag & 256 /* UNKEYED_FRAGMENT */)) ||
5951 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
5952 unmountChildren(children, parentComponent, parentSuspense);
5953 }
5954 if (doRemove) {
5955 remove(vnode);
5956 }
5957 }
5958 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {
5959 queuePostRenderEffect(() => {
5960 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5961 shouldInvokeDirs &&
5962 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
5963 }, parentSuspense);
5964 }
5965 };
5966 const remove = vnode => {
5967 const { type, el, anchor, transition } = vnode;
5968 if (type === Fragment) {
5969 removeFragment(el, anchor);
5970 return;
5971 }
5972 if (type === Static) {
5973 removeStaticNode(vnode);
5974 return;
5975 }
5976 const performRemove = () => {
5977 hostRemove(el);
5978 if (transition && !transition.persisted && transition.afterLeave) {
5979 transition.afterLeave();
5980 }
5981 };
5982 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
5983 transition &&
5984 !transition.persisted) {
5985 const { leave, delayLeave } = transition;
5986 const performLeave = () => leave(el, performRemove);
5987 if (delayLeave) {
5988 delayLeave(vnode.el, performRemove, performLeave);
5989 }
5990 else {
5991 performLeave();
5992 }
5993 }
5994 else {
5995 performRemove();
5996 }
5997 };
5998 const removeFragment = (cur, end) => {
5999 // For fragments, directly remove all contained DOM nodes.
6000 // (fragment child nodes cannot have transition)
6001 let next;
6002 while (cur !== end) {
6003 next = hostNextSibling(cur);
6004 hostRemove(cur);
6005 cur = next;
6006 }
6007 hostRemove(end);
6008 };
6009 const unmountComponent = (instance, parentSuspense, doRemove) => {
6010 if (instance.type.__hmrId) {
6011 unregisterHMR(instance);
6012 }
6013 const { bum, effects, update, subTree, um } = instance;
6014 // beforeUnmount hook
6015 if (bum) {
6016 invokeArrayFns(bum);
6017 }
6018 if (effects) {
6019 for (let i = 0; i < effects.length; i++) {
6020 stop(effects[i]);
6021 }
6022 }
6023 // update may be null if a component is unmounted before its async
6024 // setup has resolved.
6025 if (update) {
6026 stop(update);
6027 unmount(subTree, instance, parentSuspense, doRemove);
6028 }
6029 // unmounted hook
6030 if (um) {
6031 queuePostRenderEffect(um, parentSuspense);
6032 }
6033 queuePostRenderEffect(() => {
6034 instance.isUnmounted = true;
6035 }, parentSuspense);
6036 // A component with async dep inside a pending suspense is unmounted before
6037 // its async dep resolves. This should remove the dep from the suspense, and
6038 // cause the suspense to resolve immediately if that was the last dep.
6039 if (parentSuspense &&
6040 parentSuspense.pendingBranch &&
6041 !parentSuspense.isUnmounted &&
6042 instance.asyncDep &&
6043 !instance.asyncResolved &&
6044 instance.suspenseId === parentSuspense.pendingId) {
6045 parentSuspense.deps--;
6046 if (parentSuspense.deps === 0) {
6047 parentSuspense.resolve();
6048 }
6049 }
6050 {
6051 devtoolsComponentRemoved(instance);
6052 }
6053 };
6054 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
6055 for (let i = start; i < children.length; i++) {
6056 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
6057 }
6058 };
6059 const getNextHostNode = vnode => {
6060 if (vnode.shapeFlag & 6 /* COMPONENT */) {
6061 return getNextHostNode(vnode.component.subTree);
6062 }
6063 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
6064 return vnode.suspense.next();
6065 }
6066 return hostNextSibling((vnode.anchor || vnode.el));
6067 };
6068 const render = (vnode, container, isSVG) => {
6069 if (vnode == null) {
6070 if (container._vnode) {
6071 unmount(container._vnode, null, null, true);
6072 }
6073 }
6074 else {
6075 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
6076 }
6077 flushPostFlushCbs();
6078 container._vnode = vnode;
6079 };
6080 const internals = {
6081 p: patch,
6082 um: unmount,
6083 m: move,
6084 r: remove,
6085 mt: mountComponent,
6086 mc: mountChildren,
6087 pc: patchChildren,
6088 pbc: patchBlockChildren,
6089 n: getNextHostNode,
6090 o: options
6091 };
6092 let hydrate;
6093 let hydrateNode;
6094 if (createHydrationFns) {
6095 [hydrate, hydrateNode] = createHydrationFns(internals);
6096 }
6097 return {
6098 render,
6099 hydrate,
6100 createApp: createAppAPI(render, hydrate)
6101 };
6102 }
6103 function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6104 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6105 vnode,
6106 prevVNode
6107 ]);
6108 }
6109 /**
6110 * #1156
6111 * When a component is HMR-enabled, we need to make sure that all static nodes
6112 * inside a block also inherit the DOM element from the previous tree so that
6113 * HMR updates (which are full updates) can retrieve the element for patching.
6114 *
6115 * #2080
6116 * Inside keyed `template` fragment static children, if a fragment is moved,
6117 * the children will always moved so that need inherit el form previous nodes
6118 * to ensure correct moved position.
6119 */
6120 function traverseStaticChildren(n1, n2, shallow = false) {
6121 const ch1 = n1.children;
6122 const ch2 = n2.children;
6123 if (isArray(ch1) && isArray(ch2)) {
6124 for (let i = 0; i < ch1.length; i++) {
6125 // this is only called in the optimized path so array children are
6126 // guaranteed to be vnodes
6127 const c1 = ch1[i];
6128 let c2 = ch2[i];
6129 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
6130 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
6131 c2 = ch2[i] = cloneIfMounted(ch2[i]);
6132 c2.el = c1.el;
6133 }
6134 if (!shallow)
6135 traverseStaticChildren(c1, c2);
6136 }
6137 // also inherit for comment nodes, but not placeholders (e.g. v-if which
6138 // would have received .el during block patch)
6139 if (c2.type === Comment && !c2.el) {
6140 c2.el = c1.el;
6141 }
6142 }
6143 }
6144 }
6145 // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
6146 function getSequence(arr) {
6147 const p = arr.slice();
6148 const result = [0];
6149 let i, j, u, v, c;
6150 const len = arr.length;
6151 for (i = 0; i < len; i++) {
6152 const arrI = arr[i];
6153 if (arrI !== 0) {
6154 j = result[result.length - 1];
6155 if (arr[j] < arrI) {
6156 p[i] = j;
6157 result.push(i);
6158 continue;
6159 }
6160 u = 0;
6161 v = result.length - 1;
6162 while (u < v) {
6163 c = ((u + v) / 2) | 0;
6164 if (arr[result[c]] < arrI) {
6165 u = c + 1;
6166 }
6167 else {
6168 v = c;
6169 }
6170 }
6171 if (arrI < arr[result[u]]) {
6172 if (u > 0) {
6173 p[i] = result[u - 1];
6174 }
6175 result[u] = i;
6176 }
6177 }
6178 }
6179 u = result.length;
6180 v = result[u - 1];
6181 while (u-- > 0) {
6182 result[u] = v;
6183 v = p[v];
6184 }
6185 return result;
6186 }
6187
6188 const isTeleport = (type) => type.__isTeleport;
6189 const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
6190 const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
6191 const resolveTarget = (props, select) => {
6192 const targetSelector = props && props.to;
6193 if (isString(targetSelector)) {
6194 if (!select) {
6195 warn(`Current renderer does not support string target for Teleports. ` +
6196 `(missing querySelector renderer option)`);
6197 return null;
6198 }
6199 else {
6200 const target = select(targetSelector);
6201 if (!target) {
6202 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
6203 `Note the target element must exist before the component is mounted - ` +
6204 `i.e. the target cannot be rendered by the component itself, and ` +
6205 `ideally should be outside of the entire Vue component tree.`);
6206 }
6207 return target;
6208 }
6209 }
6210 else {
6211 if (!targetSelector && !isTeleportDisabled(props)) {
6212 warn(`Invalid Teleport target: ${targetSelector}`);
6213 }
6214 return targetSelector;
6215 }
6216 };
6217 const TeleportImpl = {
6218 __isTeleport: true,
6219 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
6220 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
6221 const disabled = isTeleportDisabled(n2.props);
6222 const { shapeFlag, children } = n2;
6223 // #3302
6224 // HMR updated, force full diff
6225 if (isHmrUpdating) {
6226 optimized = false;
6227 n2.dynamicChildren = null;
6228 }
6229 if (n1 == null) {
6230 // insert anchors in the main view
6231 const placeholder = (n2.el = createComment('teleport start')
6232 );
6233 const mainAnchor = (n2.anchor = createComment('teleport end')
6234 );
6235 insert(placeholder, container, anchor);
6236 insert(mainAnchor, container, anchor);
6237 const target = (n2.target = resolveTarget(n2.props, querySelector));
6238 const targetAnchor = (n2.targetAnchor = createText(''));
6239 if (target) {
6240 insert(targetAnchor, target);
6241 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
6242 isSVG = isSVG || isTargetSVG(target);
6243 }
6244 else if (!disabled) {
6245 warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
6246 }
6247 const mount = (container, anchor) => {
6248 // Teleport *always* has Array children. This is enforced in both the
6249 // compiler and vnode children normalization.
6250 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6251 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6252 }
6253 };
6254 if (disabled) {
6255 mount(container, mainAnchor);
6256 }
6257 else if (target) {
6258 mount(target, targetAnchor);
6259 }
6260 }
6261 else {
6262 // update content
6263 n2.el = n1.el;
6264 const mainAnchor = (n2.anchor = n1.anchor);
6265 const target = (n2.target = n1.target);
6266 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
6267 const wasDisabled = isTeleportDisabled(n1.props);
6268 const currentContainer = wasDisabled ? container : target;
6269 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
6270 isSVG = isSVG || isTargetSVG(target);
6271 if (n2.dynamicChildren) {
6272 // fast path when the teleport happens to be a block root
6273 patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
6274 // even in block tree mode we need to make sure all root-level nodes
6275 // in the teleport inherit previous DOM references so that they can
6276 // be moved in future patches.
6277 traverseStaticChildren(n1, n2, true);
6278 }
6279 else if (!optimized) {
6280 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
6281 }
6282 if (disabled) {
6283 if (!wasDisabled) {
6284 // enabled -> disabled
6285 // move into main container
6286 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
6287 }
6288 }
6289 else {
6290 // target changed
6291 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
6292 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
6293 if (nextTarget) {
6294 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
6295 }
6296 else {
6297 warn('Invalid Teleport target on update:', target, `(${typeof target})`);
6298 }
6299 }
6300 else if (wasDisabled) {
6301 // disabled -> enabled
6302 // move into teleport target
6303 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
6304 }
6305 }
6306 }
6307 },
6308 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
6309 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
6310 if (target) {
6311 hostRemove(targetAnchor);
6312 }
6313 // an unmounted teleport should always remove its children if not disabled
6314 if (doRemove || !isTeleportDisabled(props)) {
6315 hostRemove(anchor);
6316 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6317 for (let i = 0; i < children.length; i++) {
6318 unmount(children[i], parentComponent, parentSuspense, true, optimized);
6319 }
6320 }
6321 }
6322 },
6323 move: moveTeleport,
6324 hydrate: hydrateTeleport
6325 };
6326 function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
6327 // move target anchor if this is a target change.
6328 if (moveType === 0 /* TARGET_CHANGE */) {
6329 insert(vnode.targetAnchor, container, parentAnchor);
6330 }
6331 const { el, anchor, shapeFlag, children, props } = vnode;
6332 const isReorder = moveType === 2 /* REORDER */;
6333 // move main view anchor if this is a re-order.
6334 if (isReorder) {
6335 insert(el, container, parentAnchor);
6336 }
6337 // if this is a re-order and teleport is enabled (content is in target)
6338 // do not move children. So the opposite is: only move children if this
6339 // is not a reorder, or the teleport is disabled
6340 if (!isReorder || isTeleportDisabled(props)) {
6341 // Teleport has either Array children or no children.
6342 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6343 for (let i = 0; i < children.length; i++) {
6344 move(children[i], container, parentAnchor, 2 /* REORDER */);
6345 }
6346 }
6347 }
6348 // move main view anchor if this is a re-order.
6349 if (isReorder) {
6350 insert(anchor, container, parentAnchor);
6351 }
6352 }
6353 function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
6354 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
6355 if (target) {
6356 // if multiple teleports rendered to the same target element, we need to
6357 // pick up from where the last teleport finished instead of the first node
6358 const targetNode = target._lpa || target.firstChild;
6359 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
6360 if (isTeleportDisabled(vnode.props)) {
6361 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
6362 vnode.targetAnchor = targetNode;
6363 }
6364 else {
6365 vnode.anchor = nextSibling(node);
6366 vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
6367 }
6368 target._lpa =
6369 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
6370 }
6371 }
6372 return vnode.anchor && nextSibling(vnode.anchor);
6373 }
6374 // Force-casted public typing for h and TSX props inference
6375 const Teleport = TeleportImpl;
6376
6377 const COMPONENTS = 'components';
6378 const DIRECTIVES = 'directives';
6379 /**
6380 * @private
6381 */
6382 function resolveComponent(name, maybeSelfReference) {
6383 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
6384 }
6385 const NULL_DYNAMIC_COMPONENT = Symbol();
6386 /**
6387 * @private
6388 */
6389 function resolveDynamicComponent(component) {
6390 if (isString(component)) {
6391 return resolveAsset(COMPONENTS, component, false) || component;
6392 }
6393 else {
6394 // invalid types will fallthrough to createVNode and raise warning
6395 return (component || NULL_DYNAMIC_COMPONENT);
6396 }
6397 }
6398 /**
6399 * @private
6400 */
6401 function resolveDirective(name) {
6402 return resolveAsset(DIRECTIVES, name);
6403 }
6404 // implementation
6405 function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
6406 const instance = currentRenderingInstance || currentInstance;
6407 if (instance) {
6408 const Component = instance.type;
6409 // explicit self name has highest priority
6410 if (type === COMPONENTS) {
6411 const selfName = getComponentName(Component);
6412 if (selfName &&
6413 (selfName === name ||
6414 selfName === camelize(name) ||
6415 selfName === capitalize(camelize(name)))) {
6416 return Component;
6417 }
6418 }
6419 const res =
6420 // local registration
6421 // check instance[type] first for components with mixin or extends.
6422 resolve(instance[type] || Component[type], name) ||
6423 // global registration
6424 resolve(instance.appContext[type], name);
6425 if (!res && maybeSelfReference) {
6426 // fallback to implicit self-reference
6427 return Component;
6428 }
6429 if (warnMissing && !res) {
6430 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
6431 }
6432 return res;
6433 }
6434 else {
6435 warn(`resolve${capitalize(type.slice(0, -1))} ` +
6436 `can only be used in render() or setup().`);
6437 }
6438 }
6439 function resolve(registry, name) {
6440 return (registry &&
6441 (registry[name] ||
6442 registry[camelize(name)] ||
6443 registry[capitalize(camelize(name))]));
6444 }
6445
6446 const Fragment = Symbol('Fragment' );
6447 const Text = Symbol('Text' );
6448 const Comment = Symbol('Comment' );
6449 const Static = Symbol('Static' );
6450 // Since v-if and v-for are the two possible ways node structure can dynamically
6451 // change, once we consider v-if branches and each v-for fragment a block, we
6452 // can divide a template into nested blocks, and within each block the node
6453 // structure would be stable. This allows us to skip most children diffing
6454 // and only worry about the dynamic nodes (indicated by patch flags).
6455 const blockStack = [];
6456 let currentBlock = null;
6457 /**
6458 * Open a block.
6459 * This must be called before `createBlock`. It cannot be part of `createBlock`
6460 * because the children of the block are evaluated before `createBlock` itself
6461 * is called. The generated code typically looks like this:
6462 *
6463 * ```js
6464 * function render() {
6465 * return (openBlock(),createBlock('div', null, [...]))
6466 * }
6467 * ```
6468 * disableTracking is true when creating a v-for fragment block, since a v-for
6469 * fragment always diffs its children.
6470 *
6471 * @private
6472 */
6473 function openBlock(disableTracking = false) {
6474 blockStack.push((currentBlock = disableTracking ? null : []));
6475 }
6476 function closeBlock() {
6477 blockStack.pop();
6478 currentBlock = blockStack[blockStack.length - 1] || null;
6479 }
6480 // Whether we should be tracking dynamic child nodes inside a block.
6481 // Only tracks when this value is > 0
6482 // We are not using a simple boolean because this value may need to be
6483 // incremented/decremented by nested usage of v-once (see below)
6484 let shouldTrack$1 = 1;
6485 /**
6486 * Block tracking sometimes needs to be disabled, for example during the
6487 * creation of a tree that needs to be cached by v-once. The compiler generates
6488 * code like this:
6489 *
6490 * ``` js
6491 * _cache[1] || (
6492 * setBlockTracking(-1),
6493 * _cache[1] = createVNode(...),
6494 * setBlockTracking(1),
6495 * _cache[1]
6496 * )
6497 * ```
6498 *
6499 * @private
6500 */
6501 function setBlockTracking(value) {
6502 shouldTrack$1 += value;
6503 }
6504 /**
6505 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
6506 * A block root keeps track of dynamic nodes within the block in the
6507 * `dynamicChildren` array.
6508 *
6509 * @private
6510 */
6511 function createBlock(type, props, children, patchFlag, dynamicProps) {
6512 const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
6513 // save current block children on the block vnode
6514 vnode.dynamicChildren = currentBlock || EMPTY_ARR;
6515 // close block
6516 closeBlock();
6517 // a block is always going to be patched, so track it as a child of its
6518 // parent block
6519 if (shouldTrack$1 > 0 && currentBlock) {
6520 currentBlock.push(vnode);
6521 }
6522 return vnode;
6523 }
6524 function isVNode(value) {
6525 return value ? value.__v_isVNode === true : false;
6526 }
6527 function isSameVNodeType(n1, n2) {
6528 if (n2.shapeFlag & 6 /* COMPONENT */ &&
6529 hmrDirtyComponents.has(n2.type)) {
6530 // HMR only: if the component has been hot-updated, force a reload.
6531 return false;
6532 }
6533 return n1.type === n2.type && n1.key === n2.key;
6534 }
6535 let vnodeArgsTransformer;
6536 /**
6537 * Internal API for registering an arguments transform for createVNode
6538 * used for creating stubs in the test-utils
6539 * It is *internal* but needs to be exposed for test-utils to pick up proper
6540 * typings
6541 */
6542 function transformVNodeArgs(transformer) {
6543 vnodeArgsTransformer = transformer;
6544 }
6545 const createVNodeWithArgsTransform = (...args) => {
6546 return _createVNode(...(vnodeArgsTransformer
6547 ? vnodeArgsTransformer(args, currentRenderingInstance)
6548 : args));
6549 };
6550 const InternalObjectKey = `__vInternal`;
6551 const normalizeKey = ({ key }) => key != null ? key : null;
6552 const normalizeRef = ({ ref }) => {
6553 return (ref != null
6554 ? isString(ref) || isRef(ref) || isFunction(ref)
6555 ? { i: currentRenderingInstance, r: ref }
6556 : ref
6557 : null);
6558 };
6559 const createVNode = (createVNodeWithArgsTransform
6560 );
6561 function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
6562 if (!type || type === NULL_DYNAMIC_COMPONENT) {
6563 if (!type) {
6564 warn(`Invalid vnode type when creating vnode: ${type}.`);
6565 }
6566 type = Comment;
6567 }
6568 if (isVNode(type)) {
6569 // createVNode receiving an existing vnode. This happens in cases like
6570 // <component :is="vnode"/>
6571 // #2078 make sure to merge refs during the clone instead of overwriting it
6572 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
6573 if (children) {
6574 normalizeChildren(cloned, children);
6575 }
6576 return cloned;
6577 }
6578 // class component normalization.
6579 if (isClassComponent(type)) {
6580 type = type.__vccOpts;
6581 }
6582 // class & style normalization.
6583 if (props) {
6584 // for reactive or proxy objects, we need to clone it to enable mutation.
6585 if (isProxy(props) || InternalObjectKey in props) {
6586 props = extend({}, props);
6587 }
6588 let { class: klass, style } = props;
6589 if (klass && !isString(klass)) {
6590 props.class = normalizeClass(klass);
6591 }
6592 if (isObject(style)) {
6593 // reactive state objects need to be cloned since they are likely to be
6594 // mutated
6595 if (isProxy(style) && !isArray(style)) {
6596 style = extend({}, style);
6597 }
6598 props.style = normalizeStyle(style);
6599 }
6600 }
6601 // encode the vnode type information into a bitmap
6602 const shapeFlag = isString(type)
6603 ? 1 /* ELEMENT */
6604 : isSuspense(type)
6605 ? 128 /* SUSPENSE */
6606 : isTeleport(type)
6607 ? 64 /* TELEPORT */
6608 : isObject(type)
6609 ? 4 /* STATEFUL_COMPONENT */
6610 : isFunction(type)
6611 ? 2 /* FUNCTIONAL_COMPONENT */
6612 : 0;
6613 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
6614 type = toRaw(type);
6615 warn(`Vue received a Component which was made a reactive object. This can ` +
6616 `lead to unnecessary performance overhead, and should be avoided by ` +
6617 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
6618 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
6619 }
6620 const vnode = {
6621 __v_isVNode: true,
6622 ["__v_skip" /* SKIP */]: true,
6623 type,
6624 props,
6625 key: props && normalizeKey(props),
6626 ref: props && normalizeRef(props),
6627 scopeId: currentScopeId,
6628 slotScopeIds: null,
6629 children: null,
6630 component: null,
6631 suspense: null,
6632 ssContent: null,
6633 ssFallback: null,
6634 dirs: null,
6635 transition: null,
6636 el: null,
6637 anchor: null,
6638 target: null,
6639 targetAnchor: null,
6640 staticCount: 0,
6641 shapeFlag,
6642 patchFlag,
6643 dynamicProps,
6644 dynamicChildren: null,
6645 appContext: null
6646 };
6647 // validate key
6648 if (vnode.key !== vnode.key) {
6649 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
6650 }
6651 normalizeChildren(vnode, children);
6652 // normalize suspense children
6653 if (shapeFlag & 128 /* SUSPENSE */) {
6654 const { content, fallback } = normalizeSuspenseChildren(vnode);
6655 vnode.ssContent = content;
6656 vnode.ssFallback = fallback;
6657 }
6658 if (shouldTrack$1 > 0 &&
6659 // avoid a block node from tracking itself
6660 !isBlockNode &&
6661 // has current parent block
6662 currentBlock &&
6663 // presence of a patch flag indicates this node needs patching on updates.
6664 // component nodes also should always be patched, because even if the
6665 // component doesn't need to update, it needs to persist the instance on to
6666 // the next vnode so that it can be properly unmounted later.
6667 (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
6668 // the EVENTS flag is only for hydration and if it is the only flag, the
6669 // vnode should not be considered dynamic due to handler caching.
6670 patchFlag !== 32 /* HYDRATE_EVENTS */) {
6671 currentBlock.push(vnode);
6672 }
6673 return vnode;
6674 }
6675 function cloneVNode(vnode, extraProps, mergeRef = false) {
6676 // This is intentionally NOT using spread or extend to avoid the runtime
6677 // key enumeration cost.
6678 const { props, ref, patchFlag, children } = vnode;
6679 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
6680 return {
6681 __v_isVNode: true,
6682 ["__v_skip" /* SKIP */]: true,
6683 type: vnode.type,
6684 props: mergedProps,
6685 key: mergedProps && normalizeKey(mergedProps),
6686 ref: extraProps && extraProps.ref
6687 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
6688 // if the vnode itself already has a ref, cloneVNode will need to merge
6689 // the refs so the single vnode can be set on multiple refs
6690 mergeRef && ref
6691 ? isArray(ref)
6692 ? ref.concat(normalizeRef(extraProps))
6693 : [ref, normalizeRef(extraProps)]
6694 : normalizeRef(extraProps)
6695 : ref,
6696 scopeId: vnode.scopeId,
6697 slotScopeIds: vnode.slotScopeIds,
6698 children: patchFlag === -1 /* HOISTED */ && isArray(children)
6699 ? children.map(deepCloneVNode)
6700 : children,
6701 target: vnode.target,
6702 targetAnchor: vnode.targetAnchor,
6703 staticCount: vnode.staticCount,
6704 shapeFlag: vnode.shapeFlag,
6705 // if the vnode is cloned with extra props, we can no longer assume its
6706 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
6707 // note: perserve flag for fragments since they use the flag for children
6708 // fast paths only.
6709 patchFlag: extraProps && vnode.type !== Fragment
6710 ? patchFlag === -1 // hoisted node
6711 ? 16 /* FULL_PROPS */
6712 : patchFlag | 16 /* FULL_PROPS */
6713 : patchFlag,
6714 dynamicProps: vnode.dynamicProps,
6715 dynamicChildren: vnode.dynamicChildren,
6716 appContext: vnode.appContext,
6717 dirs: vnode.dirs,
6718 transition: vnode.transition,
6719 // These should technically only be non-null on mounted VNodes. However,
6720 // they *should* be copied for kept-alive vnodes. So we just always copy
6721 // them since them being non-null during a mount doesn't affect the logic as
6722 // they will simply be overwritten.
6723 component: vnode.component,
6724 suspense: vnode.suspense,
6725 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
6726 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
6727 el: vnode.el,
6728 anchor: vnode.anchor
6729 };
6730 }
6731 /**
6732 * Dev only, for HMR of hoisted vnodes reused in v-for
6733 * https://github.com/vitejs/vite/issues/2022
6734 */
6735 function deepCloneVNode(vnode) {
6736 const cloned = cloneVNode(vnode);
6737 if (isArray(vnode.children)) {
6738 cloned.children = vnode.children.map(deepCloneVNode);
6739 }
6740 return cloned;
6741 }
6742 /**
6743 * @private
6744 */
6745 function createTextVNode(text = ' ', flag = 0) {
6746 return createVNode(Text, null, text, flag);
6747 }
6748 /**
6749 * @private
6750 */
6751 function createStaticVNode(content, numberOfNodes) {
6752 // A static vnode can contain multiple stringified elements, and the number
6753 // of elements is necessary for hydration.
6754 const vnode = createVNode(Static, null, content);
6755 vnode.staticCount = numberOfNodes;
6756 return vnode;
6757 }
6758 /**
6759 * @private
6760 */
6761 function createCommentVNode(text = '',
6762 // when used as the v-else branch, the comment node must be created as a
6763 // block to ensure correct updates.
6764 asBlock = false) {
6765 return asBlock
6766 ? (openBlock(), createBlock(Comment, null, text))
6767 : createVNode(Comment, null, text);
6768 }
6769 function normalizeVNode(child) {
6770 if (child == null || typeof child === 'boolean') {
6771 // empty placeholder
6772 return createVNode(Comment);
6773 }
6774 else if (isArray(child)) {
6775 // fragment
6776 return createVNode(Fragment, null, child);
6777 }
6778 else if (typeof child === 'object') {
6779 // already vnode, this should be the most common since compiled templates
6780 // always produce all-vnode children arrays
6781 return child.el === null ? child : cloneVNode(child);
6782 }
6783 else {
6784 // strings and numbers
6785 return createVNode(Text, null, String(child));
6786 }
6787 }
6788 // optimized normalization for template-compiled render fns
6789 function cloneIfMounted(child) {
6790 return child.el === null ? child : cloneVNode(child);
6791 }
6792 function normalizeChildren(vnode, children) {
6793 let type = 0;
6794 const { shapeFlag } = vnode;
6795 if (children == null) {
6796 children = null;
6797 }
6798 else if (isArray(children)) {
6799 type = 16 /* ARRAY_CHILDREN */;
6800 }
6801 else if (typeof children === 'object') {
6802 if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
6803 // Normalize slot to plain children for plain element and Teleport
6804 const slot = children.default;
6805 if (slot) {
6806 // _c marker is added by withCtx() indicating this is a compiled slot
6807 slot._c && setCompiledSlotRendering(1);
6808 normalizeChildren(vnode, slot());
6809 slot._c && setCompiledSlotRendering(-1);
6810 }
6811 return;
6812 }
6813 else {
6814 type = 32 /* SLOTS_CHILDREN */;
6815 const slotFlag = children._;
6816 if (!slotFlag && !(InternalObjectKey in children)) {
6817 children._ctx = currentRenderingInstance;
6818 }
6819 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
6820 // a child component receives forwarded slots from the parent.
6821 // its slot type is determined by its parent's slot type.
6822 if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
6823 children._ = 2 /* DYNAMIC */;
6824 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
6825 }
6826 else {
6827 children._ = 1 /* STABLE */;
6828 }
6829 }
6830 }
6831 }
6832 else if (isFunction(children)) {
6833 children = { default: children, _ctx: currentRenderingInstance };
6834 type = 32 /* SLOTS_CHILDREN */;
6835 }
6836 else {
6837 children = String(children);
6838 // force teleport children to array so it can be moved around
6839 if (shapeFlag & 64 /* TELEPORT */) {
6840 type = 16 /* ARRAY_CHILDREN */;
6841 children = [createTextVNode(children)];
6842 }
6843 else {
6844 type = 8 /* TEXT_CHILDREN */;
6845 }
6846 }
6847 vnode.children = children;
6848 vnode.shapeFlag |= type;
6849 }
6850 function mergeProps(...args) {
6851 const ret = extend({}, args[0]);
6852 for (let i = 1; i < args.length; i++) {
6853 const toMerge = args[i];
6854 for (const key in toMerge) {
6855 if (key === 'class') {
6856 if (ret.class !== toMerge.class) {
6857 ret.class = normalizeClass([ret.class, toMerge.class]);
6858 }
6859 }
6860 else if (key === 'style') {
6861 ret.style = normalizeStyle([ret.style, toMerge.style]);
6862 }
6863 else if (isOn(key)) {
6864 const existing = ret[key];
6865 const incoming = toMerge[key];
6866 if (existing !== incoming) {
6867 ret[key] = existing
6868 ? [].concat(existing, toMerge[key])
6869 : incoming;
6870 }
6871 }
6872 else if (key !== '') {
6873 ret[key] = toMerge[key];
6874 }
6875 }
6876 }
6877 return ret;
6878 }
6879
6880 function provide(key, value) {
6881 if (!currentInstance) {
6882 {
6883 warn(`provide() can only be used inside setup().`);
6884 }
6885 }
6886 else {
6887 let provides = currentInstance.provides;
6888 // by default an instance inherits its parent's provides object
6889 // but when it needs to provide values of its own, it creates its
6890 // own provides object using parent provides object as prototype.
6891 // this way in `inject` we can simply look up injections from direct
6892 // parent and let the prototype chain do the work.
6893 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
6894 if (parentProvides === provides) {
6895 provides = currentInstance.provides = Object.create(parentProvides);
6896 }
6897 // TS doesn't allow symbol as index type
6898 provides[key] = value;
6899 }
6900 }
6901 function inject(key, defaultValue, treatDefaultAsFactory = false) {
6902 // fallback to `currentRenderingInstance` so that this can be called in
6903 // a functional component
6904 const instance = currentInstance || currentRenderingInstance;
6905 if (instance) {
6906 // #2400
6907 // to support `app.use` plugins,
6908 // fallback to appContext's `provides` if the intance is at root
6909 const provides = instance.parent == null
6910 ? instance.vnode.appContext && instance.vnode.appContext.provides
6911 : instance.parent.provides;
6912 if (provides && key in provides) {
6913 // TS doesn't allow symbol as index type
6914 return provides[key];
6915 }
6916 else if (arguments.length > 1) {
6917 return treatDefaultAsFactory && isFunction(defaultValue)
6918 ? defaultValue()
6919 : defaultValue;
6920 }
6921 else {
6922 warn(`injection "${String(key)}" not found.`);
6923 }
6924 }
6925 else {
6926 warn(`inject() can only be used inside setup() or functional components.`);
6927 }
6928 }
6929
6930 function createDuplicateChecker() {
6931 const cache = Object.create(null);
6932 return (type, key) => {
6933 if (cache[key]) {
6934 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
6935 }
6936 else {
6937 cache[key] = type;
6938 }
6939 };
6940 }
6941 let shouldCacheAccess = true;
6942 function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
6943 const {
6944 // composition
6945 mixins, extends: extendsOptions,
6946 // state
6947 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
6948 // assets
6949 components, directives,
6950 // lifecycle
6951 beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured,
6952 // public API
6953 expose } = options;
6954 const publicThis = instance.proxy;
6955 const ctx = instance.ctx;
6956 const globalMixins = instance.appContext.mixins;
6957 if (asMixin && render && instance.render === NOOP) {
6958 instance.render = render;
6959 }
6960 // applyOptions is called non-as-mixin once per instance
6961 if (!asMixin) {
6962 shouldCacheAccess = false;
6963 callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
6964 shouldCacheAccess = true;
6965 // global mixins are applied first
6966 applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
6967 }
6968 // extending a base component...
6969 if (extendsOptions) {
6970 applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
6971 }
6972 // local mixins
6973 if (mixins) {
6974 applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
6975 }
6976 const checkDuplicateProperties = createDuplicateChecker() ;
6977 {
6978 const [propsOptions] = instance.propsOptions;
6979 if (propsOptions) {
6980 for (const key in propsOptions) {
6981 checkDuplicateProperties("Props" /* PROPS */, key);
6982 }
6983 }
6984 }
6985 // options initialization order (to be consistent with Vue 2):
6986 // - props (already done outside of this function)
6987 // - inject
6988 // - methods
6989 // - data (deferred since it relies on `this` access)
6990 // - computed
6991 // - watch (deferred since it relies on `this` access)
6992 if (injectOptions) {
6993 if (isArray(injectOptions)) {
6994 for (let i = 0; i < injectOptions.length; i++) {
6995 const key = injectOptions[i];
6996 ctx[key] = inject(key);
6997 {
6998 checkDuplicateProperties("Inject" /* INJECT */, key);
6999 }
7000 }
7001 }
7002 else {
7003 for (const key in injectOptions) {
7004 const opt = injectOptions[key];
7005 if (isObject(opt)) {
7006 ctx[key] = inject(opt.from || key, opt.default, true /* treat default function as factory */);
7007 }
7008 else {
7009 ctx[key] = inject(opt);
7010 }
7011 {
7012 checkDuplicateProperties("Inject" /* INJECT */, key);
7013 }
7014 }
7015 }
7016 }
7017 if (methods) {
7018 for (const key in methods) {
7019 const methodHandler = methods[key];
7020 if (isFunction(methodHandler)) {
7021 // In dev mode, we use the `createRenderContext` function to define methods to the proxy target,
7022 // and those are read-only but reconfigurable, so it needs to be redefined here
7023 {
7024 Object.defineProperty(ctx, key, {
7025 value: methodHandler.bind(publicThis),
7026 configurable: true,
7027 enumerable: true,
7028 writable: true
7029 });
7030 }
7031 {
7032 checkDuplicateProperties("Methods" /* METHODS */, key);
7033 }
7034 }
7035 else {
7036 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
7037 `Did you reference the function correctly?`);
7038 }
7039 }
7040 }
7041 if (!asMixin) {
7042 if (deferredData.length) {
7043 deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis));
7044 }
7045 if (dataOptions) {
7046 // @ts-ignore dataOptions is not fully type safe
7047 resolveData(instance, dataOptions, publicThis);
7048 }
7049 {
7050 const rawData = toRaw(instance.data);
7051 for (const key in rawData) {
7052 checkDuplicateProperties("Data" /* DATA */, key);
7053 // expose data on ctx during dev
7054 if (key[0] !== '$' && key[0] !== '_') {
7055 Object.defineProperty(ctx, key, {
7056 configurable: true,
7057 enumerable: true,
7058 get: () => rawData[key],
7059 set: NOOP
7060 });
7061 }
7062 }
7063 }
7064 }
7065 else if (dataOptions) {
7066 deferredData.push(dataOptions);
7067 }
7068 if (computedOptions) {
7069 for (const key in computedOptions) {
7070 const opt = computedOptions[key];
7071 const get = isFunction(opt)
7072 ? opt.bind(publicThis, publicThis)
7073 : isFunction(opt.get)
7074 ? opt.get.bind(publicThis, publicThis)
7075 : NOOP;
7076 if (get === NOOP) {
7077 warn(`Computed property "${key}" has no getter.`);
7078 }
7079 const set = !isFunction(opt) && isFunction(opt.set)
7080 ? opt.set.bind(publicThis)
7081 : () => {
7082 warn(`Write operation failed: computed property "${key}" is readonly.`);
7083 }
7084 ;
7085 const c = computed$1({
7086 get,
7087 set
7088 });
7089 Object.defineProperty(ctx, key, {
7090 enumerable: true,
7091 configurable: true,
7092 get: () => c.value,
7093 set: v => (c.value = v)
7094 });
7095 {
7096 checkDuplicateProperties("Computed" /* COMPUTED */, key);
7097 }
7098 }
7099 }
7100 if (watchOptions) {
7101 deferredWatch.push(watchOptions);
7102 }
7103 if (!asMixin && deferredWatch.length) {
7104 deferredWatch.forEach(watchOptions => {
7105 for (const key in watchOptions) {
7106 createWatcher(watchOptions[key], ctx, publicThis, key);
7107 }
7108 });
7109 }
7110 if (provideOptions) {
7111 deferredProvide.push(provideOptions);
7112 }
7113 if (!asMixin && deferredProvide.length) {
7114 deferredProvide.forEach(provideOptions => {
7115 const provides = isFunction(provideOptions)
7116 ? provideOptions.call(publicThis)
7117 : provideOptions;
7118 Reflect.ownKeys(provides).forEach(key => {
7119 provide(key, provides[key]);
7120 });
7121 });
7122 }
7123 // asset options.
7124 // To reduce memory usage, only components with mixins or extends will have
7125 // resolved asset registry attached to instance.
7126 if (asMixin) {
7127 if (components) {
7128 extend(instance.components ||
7129 (instance.components = extend({}, instance.type.components)), components);
7130 }
7131 if (directives) {
7132 extend(instance.directives ||
7133 (instance.directives = extend({}, instance.type.directives)), directives);
7134 }
7135 }
7136 // lifecycle options
7137 if (!asMixin) {
7138 callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
7139 }
7140 if (beforeMount) {
7141 onBeforeMount(beforeMount.bind(publicThis));
7142 }
7143 if (mounted) {
7144 onMounted(mounted.bind(publicThis));
7145 }
7146 if (beforeUpdate) {
7147 onBeforeUpdate(beforeUpdate.bind(publicThis));
7148 }
7149 if (updated) {
7150 onUpdated(updated.bind(publicThis));
7151 }
7152 if (activated) {
7153 onActivated(activated.bind(publicThis));
7154 }
7155 if (deactivated) {
7156 onDeactivated(deactivated.bind(publicThis));
7157 }
7158 if (errorCaptured) {
7159 onErrorCaptured(errorCaptured.bind(publicThis));
7160 }
7161 if (renderTracked) {
7162 onRenderTracked(renderTracked.bind(publicThis));
7163 }
7164 if (renderTriggered) {
7165 onRenderTriggered(renderTriggered.bind(publicThis));
7166 }
7167 if (beforeDestroy) {
7168 warn(`\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`);
7169 }
7170 if (beforeUnmount) {
7171 onBeforeUnmount(beforeUnmount.bind(publicThis));
7172 }
7173 if (destroyed) {
7174 warn(`\`destroyed\` has been renamed to \`unmounted\`.`);
7175 }
7176 if (unmounted) {
7177 onUnmounted(unmounted.bind(publicThis));
7178 }
7179 if (isArray(expose)) {
7180 if (!asMixin) {
7181 if (expose.length) {
7182 const exposed = instance.exposed || (instance.exposed = proxyRefs({}));
7183 expose.forEach(key => {
7184 exposed[key] = toRef(publicThis, key);
7185 });
7186 }
7187 else if (!instance.exposed) {
7188 instance.exposed = EMPTY_OBJ;
7189 }
7190 }
7191 else {
7192 warn(`The \`expose\` option is ignored when used in mixins.`);
7193 }
7194 }
7195 }
7196 function callSyncHook(name, type, options, instance, globalMixins) {
7197 for (let i = 0; i < globalMixins.length; i++) {
7198 callHookWithMixinAndExtends(name, type, globalMixins[i], instance);
7199 }
7200 callHookWithMixinAndExtends(name, type, options, instance);
7201 }
7202 function callHookWithMixinAndExtends(name, type, options, instance) {
7203 const { extends: base, mixins } = options;
7204 const selfHook = options[name];
7205 if (base) {
7206 callHookWithMixinAndExtends(name, type, base, instance);
7207 }
7208 if (mixins) {
7209 for (let i = 0; i < mixins.length; i++) {
7210 callHookWithMixinAndExtends(name, type, mixins[i], instance);
7211 }
7212 }
7213 if (selfHook) {
7214 callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
7215 }
7216 }
7217 function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
7218 for (let i = 0; i < mixins.length; i++) {
7219 applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
7220 }
7221 }
7222 function resolveData(instance, dataFn, publicThis) {
7223 if (!isFunction(dataFn)) {
7224 warn(`The data option must be a function. ` +
7225 `Plain object usage is no longer supported.`);
7226 }
7227 shouldCacheAccess = false;
7228 const data = dataFn.call(publicThis, publicThis);
7229 shouldCacheAccess = true;
7230 if (isPromise(data)) {
7231 warn(`data() returned a Promise - note data() cannot be async; If you ` +
7232 `intend to perform data fetching before component renders, use ` +
7233 `async setup() + <Suspense>.`);
7234 }
7235 if (!isObject(data)) {
7236 warn(`data() should return an object.`);
7237 }
7238 else if (instance.data === EMPTY_OBJ) {
7239 instance.data = reactive(data);
7240 }
7241 else {
7242 // existing data: this is a mixin or extends.
7243 extend(instance.data, data);
7244 }
7245 }
7246 function createWatcher(raw, ctx, publicThis, key) {
7247 const getter = key.includes('.')
7248 ? createPathGetter(publicThis, key)
7249 : () => publicThis[key];
7250 if (isString(raw)) {
7251 const handler = ctx[raw];
7252 if (isFunction(handler)) {
7253 watch(getter, handler);
7254 }
7255 else {
7256 warn(`Invalid watch handler specified by key "${raw}"`, handler);
7257 }
7258 }
7259 else if (isFunction(raw)) {
7260 watch(getter, raw.bind(publicThis));
7261 }
7262 else if (isObject(raw)) {
7263 if (isArray(raw)) {
7264 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
7265 }
7266 else {
7267 const handler = isFunction(raw.handler)
7268 ? raw.handler.bind(publicThis)
7269 : ctx[raw.handler];
7270 if (isFunction(handler)) {
7271 watch(getter, handler, raw);
7272 }
7273 else {
7274 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
7275 }
7276 }
7277 }
7278 else {
7279 warn(`Invalid watch option: "${key}"`, raw);
7280 }
7281 }
7282 function createPathGetter(ctx, path) {
7283 const segments = path.split('.');
7284 return () => {
7285 let cur = ctx;
7286 for (let i = 0; i < segments.length && cur; i++) {
7287 cur = cur[segments[i]];
7288 }
7289 return cur;
7290 };
7291 }
7292 function resolveMergedOptions(instance) {
7293 const raw = instance.type;
7294 const { __merged, mixins, extends: extendsOptions } = raw;
7295 if (__merged)
7296 return __merged;
7297 const globalMixins = instance.appContext.mixins;
7298 if (!globalMixins.length && !mixins && !extendsOptions)
7299 return raw;
7300 const options = {};
7301 globalMixins.forEach(m => mergeOptions(options, m, instance));
7302 mergeOptions(options, raw, instance);
7303 return (raw.__merged = options);
7304 }
7305 function mergeOptions(to, from, instance) {
7306 const strats = instance.appContext.config.optionMergeStrategies;
7307 const { mixins, extends: extendsOptions } = from;
7308 extendsOptions && mergeOptions(to, extendsOptions, instance);
7309 mixins &&
7310 mixins.forEach((m) => mergeOptions(to, m, instance));
7311 for (const key in from) {
7312 if (strats && hasOwn(strats, key)) {
7313 to[key] = strats[key](to[key], from[key], instance.proxy, key);
7314 }
7315 else {
7316 to[key] = from[key];
7317 }
7318 }
7319 }
7320
7321 /**
7322 * #2437 In Vue 3, functional components do not have a public instance proxy but
7323 * they exist in the internal parent chain. For code that relies on traversing
7324 * public $parent chains, skip functional ones and go to the parent instead.
7325 */
7326 const getPublicInstance = (i) => {
7327 if (!i)
7328 return null;
7329 if (isStatefulComponent(i))
7330 return i.exposed ? i.exposed : i.proxy;
7331 return getPublicInstance(i.parent);
7332 };
7333 const publicPropertiesMap = extend(Object.create(null), {
7334 $: i => i,
7335 $el: i => i.vnode.el,
7336 $data: i => i.data,
7337 $props: i => (shallowReadonly(i.props) ),
7338 $attrs: i => (shallowReadonly(i.attrs) ),
7339 $slots: i => (shallowReadonly(i.slots) ),
7340 $refs: i => (shallowReadonly(i.refs) ),
7341 $parent: i => getPublicInstance(i.parent),
7342 $root: i => getPublicInstance(i.root),
7343 $emit: i => i.emit,
7344 $options: i => (resolveMergedOptions(i) ),
7345 $forceUpdate: i => () => queueJob(i.update),
7346 $nextTick: i => nextTick.bind(i.proxy),
7347 $watch: i => (instanceWatch.bind(i) )
7348 });
7349 const PublicInstanceProxyHandlers = {
7350 get({ _: instance }, key) {
7351 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
7352 // let @vue/reactivity know it should never observe Vue public instances.
7353 if (key === "__v_skip" /* SKIP */) {
7354 return true;
7355 }
7356 // for internal formatters to know that this is a Vue instance
7357 if (key === '__isVue') {
7358 return true;
7359 }
7360 // data / props / ctx
7361 // This getter gets called for every property access on the render context
7362 // during render and is a major hotspot. The most expensive part of this
7363 // is the multiple hasOwn() calls. It's much faster to do a simple property
7364 // access on a plain object, so we use an accessCache object (with null
7365 // prototype) to memoize what access type a key corresponds to.
7366 let normalizedProps;
7367 if (key[0] !== '$') {
7368 const n = accessCache[key];
7369 if (n !== undefined) {
7370 switch (n) {
7371 case 0 /* SETUP */:
7372 return setupState[key];
7373 case 1 /* DATA */:
7374 return data[key];
7375 case 3 /* CONTEXT */:
7376 return ctx[key];
7377 case 2 /* PROPS */:
7378 return props[key];
7379 // default: just fallthrough
7380 }
7381 }
7382 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7383 accessCache[key] = 0 /* SETUP */;
7384 return setupState[key];
7385 }
7386 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7387 accessCache[key] = 1 /* DATA */;
7388 return data[key];
7389 }
7390 else if (
7391 // only cache other properties when instance has declared (thus stable)
7392 // props
7393 (normalizedProps = instance.propsOptions[0]) &&
7394 hasOwn(normalizedProps, key)) {
7395 accessCache[key] = 2 /* PROPS */;
7396 return props[key];
7397 }
7398 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7399 accessCache[key] = 3 /* CONTEXT */;
7400 return ctx[key];
7401 }
7402 else if (shouldCacheAccess) {
7403 accessCache[key] = 4 /* OTHER */;
7404 }
7405 }
7406 const publicGetter = publicPropertiesMap[key];
7407 let cssModule, globalProperties;
7408 // public $xxx properties
7409 if (publicGetter) {
7410 if (key === '$attrs') {
7411 track(instance, "get" /* GET */, key);
7412 markAttrsAccessed();
7413 }
7414 return publicGetter(instance);
7415 }
7416 else if (
7417 // css module (injected by vue-loader)
7418 (cssModule = type.__cssModules) &&
7419 (cssModule = cssModule[key])) {
7420 return cssModule;
7421 }
7422 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7423 // user may set custom properties to `this` that start with `$`
7424 accessCache[key] = 3 /* CONTEXT */;
7425 return ctx[key];
7426 }
7427 else if (
7428 // global properties
7429 ((globalProperties = appContext.config.globalProperties),
7430 hasOwn(globalProperties, key))) {
7431 return globalProperties[key];
7432 }
7433 else if (currentRenderingInstance &&
7434 (!isString(key) ||
7435 // #1091 avoid internal isRef/isVNode checks on component instance leading
7436 // to infinite warning loop
7437 key.indexOf('__v') !== 0)) {
7438 if (data !== EMPTY_OBJ &&
7439 (key[0] === '$' || key[0] === '_') &&
7440 hasOwn(data, key)) {
7441 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
7442 `character ("$" or "_") and is not proxied on the render context.`);
7443 }
7444 else if (instance === currentRenderingInstance) {
7445 warn(`Property ${JSON.stringify(key)} was accessed during render ` +
7446 `but is not defined on instance.`);
7447 }
7448 }
7449 },
7450 set({ _: instance }, key, value) {
7451 const { data, setupState, ctx } = instance;
7452 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7453 setupState[key] = value;
7454 }
7455 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7456 data[key] = value;
7457 }
7458 else if (hasOwn(instance.props, key)) {
7459 warn(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
7460 return false;
7461 }
7462 if (key[0] === '$' && key.slice(1) in instance) {
7463 warn(`Attempting to mutate public property "${key}". ` +
7464 `Properties starting with $ are reserved and readonly.`, instance);
7465 return false;
7466 }
7467 else {
7468 if (key in instance.appContext.config.globalProperties) {
7469 Object.defineProperty(ctx, key, {
7470 enumerable: true,
7471 configurable: true,
7472 value
7473 });
7474 }
7475 else {
7476 ctx[key] = value;
7477 }
7478 }
7479 return true;
7480 },
7481 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7482 let normalizedProps;
7483 return (accessCache[key] !== undefined ||
7484 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7485 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7486 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
7487 hasOwn(ctx, key) ||
7488 hasOwn(publicPropertiesMap, key) ||
7489 hasOwn(appContext.config.globalProperties, key));
7490 }
7491 };
7492 {
7493 PublicInstanceProxyHandlers.ownKeys = (target) => {
7494 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
7495 `The keys will be empty in production mode to avoid performance overhead.`);
7496 return Reflect.ownKeys(target);
7497 };
7498 }
7499 const RuntimeCompiledPublicInstanceProxyHandlers = extend({}, PublicInstanceProxyHandlers, {
7500 get(target, key) {
7501 // fast path for unscopables when using `with` block
7502 if (key === Symbol.unscopables) {
7503 return;
7504 }
7505 return PublicInstanceProxyHandlers.get(target, key, target);
7506 },
7507 has(_, key) {
7508 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
7509 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
7510 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
7511 }
7512 return has;
7513 }
7514 });
7515 // In dev mode, the proxy target exposes the same properties as seen on `this`
7516 // for easier console inspection. In prod mode it will be an empty object so
7517 // these properties definitions can be skipped.
7518 function createRenderContext(instance) {
7519 const target = {};
7520 // expose internal instance for proxy handlers
7521 Object.defineProperty(target, `_`, {
7522 configurable: true,
7523 enumerable: false,
7524 get: () => instance
7525 });
7526 // expose public properties
7527 Object.keys(publicPropertiesMap).forEach(key => {
7528 Object.defineProperty(target, key, {
7529 configurable: true,
7530 enumerable: false,
7531 get: () => publicPropertiesMap[key](instance),
7532 // intercepted by the proxy so no need for implementation,
7533 // but needed to prevent set errors
7534 set: NOOP
7535 });
7536 });
7537 // expose global properties
7538 const { globalProperties } = instance.appContext.config;
7539 Object.keys(globalProperties).forEach(key => {
7540 Object.defineProperty(target, key, {
7541 configurable: true,
7542 enumerable: false,
7543 get: () => globalProperties[key],
7544 set: NOOP
7545 });
7546 });
7547 return target;
7548 }
7549 // dev only
7550 function exposePropsOnRenderContext(instance) {
7551 const { ctx, propsOptions: [propsOptions] } = instance;
7552 if (propsOptions) {
7553 Object.keys(propsOptions).forEach(key => {
7554 Object.defineProperty(ctx, key, {
7555 enumerable: true,
7556 configurable: true,
7557 get: () => instance.props[key],
7558 set: NOOP
7559 });
7560 });
7561 }
7562 }
7563 // dev only
7564 function exposeSetupStateOnRenderContext(instance) {
7565 const { ctx, setupState } = instance;
7566 Object.keys(toRaw(setupState)).forEach(key => {
7567 if (key[0] === '$' || key[0] === '_') {
7568 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
7569 `which are reserved prefixes for Vue internals.`);
7570 return;
7571 }
7572 Object.defineProperty(ctx, key, {
7573 enumerable: true,
7574 configurable: true,
7575 get: () => setupState[key],
7576 set: NOOP
7577 });
7578 });
7579 }
7580
7581 const emptyAppContext = createAppContext();
7582 let uid$2 = 0;
7583 function createComponentInstance(vnode, parent, suspense) {
7584 const type = vnode.type;
7585 // inherit parent app context - or - if root, adopt from root vnode
7586 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
7587 const instance = {
7588 uid: uid$2++,
7589 vnode,
7590 type,
7591 parent,
7592 appContext,
7593 root: null,
7594 next: null,
7595 subTree: null,
7596 update: null,
7597 render: null,
7598 proxy: null,
7599 exposed: null,
7600 withProxy: null,
7601 effects: null,
7602 provides: parent ? parent.provides : Object.create(appContext.provides),
7603 accessCache: null,
7604 renderCache: [],
7605 // local resovled assets
7606 components: null,
7607 directives: null,
7608 // resolved props and emits options
7609 propsOptions: normalizePropsOptions(type, appContext),
7610 emitsOptions: normalizeEmitsOptions(type, appContext),
7611 // emit
7612 emit: null,
7613 emitted: null,
7614 // props default value
7615 propsDefaults: EMPTY_OBJ,
7616 // state
7617 ctx: EMPTY_OBJ,
7618 data: EMPTY_OBJ,
7619 props: EMPTY_OBJ,
7620 attrs: EMPTY_OBJ,
7621 slots: EMPTY_OBJ,
7622 refs: EMPTY_OBJ,
7623 setupState: EMPTY_OBJ,
7624 setupContext: null,
7625 // suspense related
7626 suspense,
7627 suspenseId: suspense ? suspense.pendingId : 0,
7628 asyncDep: null,
7629 asyncResolved: false,
7630 // lifecycle hooks
7631 // not using enums here because it results in computed properties
7632 isMounted: false,
7633 isUnmounted: false,
7634 isDeactivated: false,
7635 bc: null,
7636 c: null,
7637 bm: null,
7638 m: null,
7639 bu: null,
7640 u: null,
7641 um: null,
7642 bum: null,
7643 da: null,
7644 a: null,
7645 rtg: null,
7646 rtc: null,
7647 ec: null
7648 };
7649 {
7650 instance.ctx = createRenderContext(instance);
7651 }
7652 instance.root = parent ? parent.root : instance;
7653 instance.emit = emit.bind(null, instance);
7654 return instance;
7655 }
7656 let currentInstance = null;
7657 const getCurrentInstance = () => currentInstance || currentRenderingInstance;
7658 const setCurrentInstance = (instance) => {
7659 currentInstance = instance;
7660 };
7661 const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
7662 function validateComponentName(name, config) {
7663 const appIsNativeTag = config.isNativeTag || NO;
7664 if (isBuiltInTag(name) || appIsNativeTag(name)) {
7665 warn('Do not use built-in or reserved HTML elements as component id: ' + name);
7666 }
7667 }
7668 function isStatefulComponent(instance) {
7669 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
7670 }
7671 let isInSSRComponentSetup = false;
7672 function setupComponent(instance, isSSR = false) {
7673 isInSSRComponentSetup = isSSR;
7674 const { props, children } = instance.vnode;
7675 const isStateful = isStatefulComponent(instance);
7676 initProps(instance, props, isStateful, isSSR);
7677 initSlots(instance, children);
7678 const setupResult = isStateful
7679 ? setupStatefulComponent(instance, isSSR)
7680 : undefined;
7681 isInSSRComponentSetup = false;
7682 return setupResult;
7683 }
7684 function setupStatefulComponent(instance, isSSR) {
7685 const Component = instance.type;
7686 {
7687 if (Component.name) {
7688 validateComponentName(Component.name, instance.appContext.config);
7689 }
7690 if (Component.components) {
7691 const names = Object.keys(Component.components);
7692 for (let i = 0; i < names.length; i++) {
7693 validateComponentName(names[i], instance.appContext.config);
7694 }
7695 }
7696 if (Component.directives) {
7697 const names = Object.keys(Component.directives);
7698 for (let i = 0; i < names.length; i++) {
7699 validateDirectiveName(names[i]);
7700 }
7701 }
7702 }
7703 // 0. create render proxy property access cache
7704 instance.accessCache = Object.create(null);
7705 // 1. create public instance / render proxy
7706 // also mark it raw so it's never observed
7707 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
7708 {
7709 exposePropsOnRenderContext(instance);
7710 }
7711 // 2. call setup()
7712 const { setup } = Component;
7713 if (setup) {
7714 const setupContext = (instance.setupContext =
7715 setup.length > 1 ? createSetupContext(instance) : null);
7716 currentInstance = instance;
7717 pauseTracking();
7718 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
7719 resetTracking();
7720 currentInstance = null;
7721 if (isPromise(setupResult)) {
7722 if (isSSR) {
7723 // return the promise so server-renderer can wait on it
7724 return setupResult
7725 .then((resolvedResult) => {
7726 handleSetupResult(instance, resolvedResult, isSSR);
7727 })
7728 .catch(e => {
7729 handleError(e, instance, 0 /* SETUP_FUNCTION */);
7730 });
7731 }
7732 else {
7733 // async setup returned Promise.
7734 // bail here and wait for re-entry.
7735 instance.asyncDep = setupResult;
7736 }
7737 }
7738 else {
7739 handleSetupResult(instance, setupResult, isSSR);
7740 }
7741 }
7742 else {
7743 finishComponentSetup(instance, isSSR);
7744 }
7745 }
7746 function handleSetupResult(instance, setupResult, isSSR) {
7747 if (isFunction(setupResult)) {
7748 // setup returned an inline render function
7749 {
7750 instance.render = setupResult;
7751 }
7752 }
7753 else if (isObject(setupResult)) {
7754 if (isVNode(setupResult)) {
7755 warn(`setup() should not return VNodes directly - ` +
7756 `return a render function instead.`);
7757 }
7758 // setup returned bindings.
7759 // assuming a render function compiled from template is present.
7760 {
7761 instance.devtoolsRawSetupState = setupResult;
7762 }
7763 instance.setupState = proxyRefs(setupResult);
7764 {
7765 exposeSetupStateOnRenderContext(instance);
7766 }
7767 }
7768 else if (setupResult !== undefined) {
7769 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
7770 }
7771 finishComponentSetup(instance, isSSR);
7772 }
7773 let compile;
7774 // dev only
7775 const isRuntimeOnly = () => !compile;
7776 /**
7777 * For runtime-dom to register the compiler.
7778 * Note the exported method uses any to avoid d.ts relying on the compiler types.
7779 */
7780 function registerRuntimeCompiler(_compile) {
7781 compile = _compile;
7782 }
7783 function finishComponentSetup(instance, isSSR) {
7784 const Component = instance.type;
7785 // template / render function normalization
7786 if (!instance.render) {
7787 // could be set from setup()
7788 if (compile && Component.template && !Component.render) {
7789 {
7790 startMeasure(instance, `compile`);
7791 }
7792 Component.render = compile(Component.template, {
7793 isCustomElement: instance.appContext.config.isCustomElement,
7794 delimiters: Component.delimiters
7795 });
7796 {
7797 endMeasure(instance, `compile`);
7798 }
7799 }
7800 instance.render = (Component.render || NOOP);
7801 // for runtime-compiled render functions using `with` blocks, the render
7802 // proxy used needs a different `has` handler which is more performant and
7803 // also only allows a whitelist of globals to fallthrough.
7804 if (instance.render._rc) {
7805 instance.withProxy = new Proxy(instance.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
7806 }
7807 }
7808 // support for 2.x options
7809 {
7810 currentInstance = instance;
7811 pauseTracking();
7812 applyOptions(instance, Component);
7813 resetTracking();
7814 currentInstance = null;
7815 }
7816 // warn missing template/render
7817 // the runtime compilation of template in SSR is done by server-render
7818 if (!Component.render && instance.render === NOOP && !isSSR) {
7819 /* istanbul ignore if */
7820 if (!compile && Component.template) {
7821 warn(`Component provided template option but ` +
7822 `runtime compilation is not supported in this build of Vue.` +
7823 (` Use "vue.global.js" instead.`
7824 ) /* should not happen */);
7825 }
7826 else {
7827 warn(`Component is missing template or render function.`);
7828 }
7829 }
7830 }
7831 const attrHandlers = {
7832 get: (target, key) => {
7833 {
7834 markAttrsAccessed();
7835 }
7836 return target[key];
7837 },
7838 set: () => {
7839 warn(`setupContext.attrs is readonly.`);
7840 return false;
7841 },
7842 deleteProperty: () => {
7843 warn(`setupContext.attrs is readonly.`);
7844 return false;
7845 }
7846 };
7847 function createSetupContext(instance) {
7848 const expose = exposed => {
7849 if (instance.exposed) {
7850 warn(`expose() should be called only once per setup().`);
7851 }
7852 instance.exposed = proxyRefs(exposed);
7853 };
7854 {
7855 // We use getters in dev in case libs like test-utils overwrite instance
7856 // properties (overwrites should not be done in prod)
7857 return Object.freeze({
7858 get attrs() {
7859 return new Proxy(instance.attrs, attrHandlers);
7860 },
7861 get slots() {
7862 return shallowReadonly(instance.slots);
7863 },
7864 get emit() {
7865 return (event, ...args) => instance.emit(event, ...args);
7866 },
7867 expose
7868 });
7869 }
7870 }
7871 // record effects created during a component's setup() so that they can be
7872 // stopped when the component unmounts
7873 function recordInstanceBoundEffect(effect, instance = currentInstance) {
7874 if (instance) {
7875 (instance.effects || (instance.effects = [])).push(effect);
7876 }
7877 }
7878 const classifyRE = /(?:^|[-_])(\w)/g;
7879 const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
7880 function getComponentName(Component) {
7881 return isFunction(Component)
7882 ? Component.displayName || Component.name
7883 : Component.name;
7884 }
7885 /* istanbul ignore next */
7886 function formatComponentName(instance, Component, isRoot = false) {
7887 let name = getComponentName(Component);
7888 if (!name && Component.__file) {
7889 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
7890 if (match) {
7891 name = match[1];
7892 }
7893 }
7894 if (!name && instance && instance.parent) {
7895 // try to infer the name based on reverse resolution
7896 const inferFromRegistry = (registry) => {
7897 for (const key in registry) {
7898 if (registry[key] === Component) {
7899 return key;
7900 }
7901 }
7902 };
7903 name =
7904 inferFromRegistry(instance.components ||
7905 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
7906 }
7907 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
7908 }
7909 function isClassComponent(value) {
7910 return isFunction(value) && '__vccOpts' in value;
7911 }
7912
7913 function computed$1(getterOrOptions) {
7914 const c = computed(getterOrOptions);
7915 recordInstanceBoundEffect(c.effect);
7916 return c;
7917 }
7918
7919 // implementation
7920 function defineProps() {
7921 {
7922 warn(`defineProps() is a compiler-hint helper that is only usable inside ` +
7923 `<script setup> of a single file component. Its arguments should be ` +
7924 `compiled away and passing it at runtime has no effect.`);
7925 }
7926 return null;
7927 }
7928 // implementation
7929 function defineEmit() {
7930 {
7931 warn(`defineEmit() is a compiler-hint helper that is only usable inside ` +
7932 `<script setup> of a single file component. Its arguments should be ` +
7933 `compiled away and passing it at runtime has no effect.`);
7934 }
7935 return null;
7936 }
7937 function useContext() {
7938 const i = getCurrentInstance();
7939 if (!i) {
7940 warn(`useContext() called without active instance.`);
7941 }
7942 return i.setupContext || (i.setupContext = createSetupContext(i));
7943 }
7944
7945 // Actual implementation
7946 function h(type, propsOrChildren, children) {
7947 const l = arguments.length;
7948 if (l === 2) {
7949 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
7950 // single vnode without props
7951 if (isVNode(propsOrChildren)) {
7952 return createVNode(type, null, [propsOrChildren]);
7953 }
7954 // props without children
7955 return createVNode(type, propsOrChildren);
7956 }
7957 else {
7958 // omit props
7959 return createVNode(type, null, propsOrChildren);
7960 }
7961 }
7962 else {
7963 if (l > 3) {
7964 children = Array.prototype.slice.call(arguments, 2);
7965 }
7966 else if (l === 3 && isVNode(children)) {
7967 children = [children];
7968 }
7969 return createVNode(type, propsOrChildren, children);
7970 }
7971 }
7972
7973 const ssrContextKey = Symbol(`ssrContext` );
7974 const useSSRContext = () => {
7975 {
7976 warn(`useSSRContext() is not supported in the global build.`);
7977 }
7978 };
7979
7980 function initCustomFormatter() {
7981 /* eslint-disable no-restricted-globals */
7982 if (typeof window === 'undefined') {
7983 return;
7984 }
7985 const vueStyle = { style: 'color:#3ba776' };
7986 const numberStyle = { style: 'color:#0b1bc9' };
7987 const stringStyle = { style: 'color:#b62e24' };
7988 const keywordStyle = { style: 'color:#9d288c' };
7989 // custom formatter for Chrome
7990 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
7991 const formatter = {
7992 header(obj) {
7993 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
7994 if (!isObject(obj)) {
7995 return null;
7996 }
7997 if (obj.__isVue) {
7998 return ['div', vueStyle, `VueInstance`];
7999 }
8000 else if (isRef(obj)) {
8001 return [
8002 'div',
8003 {},
8004 ['span', vueStyle, genRefFlag(obj)],
8005 '<',
8006 formatValue(obj.value),
8007 `>`
8008 ];
8009 }
8010 else if (isReactive(obj)) {
8011 return [
8012 'div',
8013 {},
8014 ['span', vueStyle, 'Reactive'],
8015 '<',
8016 formatValue(obj),
8017 `>${isReadonly(obj) ? ` (readonly)` : ``}`
8018 ];
8019 }
8020 else if (isReadonly(obj)) {
8021 return [
8022 'div',
8023 {},
8024 ['span', vueStyle, 'Readonly'],
8025 '<',
8026 formatValue(obj),
8027 '>'
8028 ];
8029 }
8030 return null;
8031 },
8032 hasBody(obj) {
8033 return obj && obj.__isVue;
8034 },
8035 body(obj) {
8036 if (obj && obj.__isVue) {
8037 return [
8038 'div',
8039 {},
8040 ...formatInstance(obj.$)
8041 ];
8042 }
8043 }
8044 };
8045 function formatInstance(instance) {
8046 const blocks = [];
8047 if (instance.type.props && instance.props) {
8048 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
8049 }
8050 if (instance.setupState !== EMPTY_OBJ) {
8051 blocks.push(createInstanceBlock('setup', instance.setupState));
8052 }
8053 if (instance.data !== EMPTY_OBJ) {
8054 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
8055 }
8056 const computed = extractKeys(instance, 'computed');
8057 if (computed) {
8058 blocks.push(createInstanceBlock('computed', computed));
8059 }
8060 const injected = extractKeys(instance, 'inject');
8061 if (injected) {
8062 blocks.push(createInstanceBlock('injected', injected));
8063 }
8064 blocks.push([
8065 'div',
8066 {},
8067 [
8068 'span',
8069 {
8070 style: keywordStyle.style + ';opacity:0.66'
8071 },
8072 '$ (internal): '
8073 ],
8074 ['object', { object: instance }]
8075 ]);
8076 return blocks;
8077 }
8078 function createInstanceBlock(type, target) {
8079 target = extend({}, target);
8080 if (!Object.keys(target).length) {
8081 return ['span', {}];
8082 }
8083 return [
8084 'div',
8085 { style: 'line-height:1.25em;margin-bottom:0.6em' },
8086 [
8087 'div',
8088 {
8089 style: 'color:#476582'
8090 },
8091 type
8092 ],
8093 [
8094 'div',
8095 {
8096 style: 'padding-left:1.25em'
8097 },
8098 ...Object.keys(target).map(key => {
8099 return [
8100 'div',
8101 {},
8102 ['span', keywordStyle, key + ': '],
8103 formatValue(target[key], false)
8104 ];
8105 })
8106 ]
8107 ];
8108 }
8109 function formatValue(v, asRaw = true) {
8110 if (typeof v === 'number') {
8111 return ['span', numberStyle, v];
8112 }
8113 else if (typeof v === 'string') {
8114 return ['span', stringStyle, JSON.stringify(v)];
8115 }
8116 else if (typeof v === 'boolean') {
8117 return ['span', keywordStyle, v];
8118 }
8119 else if (isObject(v)) {
8120 return ['object', { object: asRaw ? toRaw(v) : v }];
8121 }
8122 else {
8123 return ['span', stringStyle, String(v)];
8124 }
8125 }
8126 function extractKeys(instance, type) {
8127 const Comp = instance.type;
8128 if (isFunction(Comp)) {
8129 return;
8130 }
8131 const extracted = {};
8132 for (const key in instance.ctx) {
8133 if (isKeyOfType(Comp, key, type)) {
8134 extracted[key] = instance.ctx[key];
8135 }
8136 }
8137 return extracted;
8138 }
8139 function isKeyOfType(Comp, key, type) {
8140 const opts = Comp[type];
8141 if ((isArray(opts) && opts.includes(key)) ||
8142 (isObject(opts) && key in opts)) {
8143 return true;
8144 }
8145 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
8146 return true;
8147 }
8148 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
8149 return true;
8150 }
8151 }
8152 function genRefFlag(v) {
8153 if (v._shallow) {
8154 return `ShallowRef`;
8155 }
8156 if (v.effect) {
8157 return `ComputedRef`;
8158 }
8159 return `Ref`;
8160 }
8161 if (window.devtoolsFormatters) {
8162 window.devtoolsFormatters.push(formatter);
8163 }
8164 else {
8165 window.devtoolsFormatters = [formatter];
8166 }
8167 }
8168
8169 /**
8170 * Actual implementation
8171 */
8172 function renderList(source, renderItem) {
8173 let ret;
8174 if (isArray(source) || isString(source)) {
8175 ret = new Array(source.length);
8176 for (let i = 0, l = source.length; i < l; i++) {
8177 ret[i] = renderItem(source[i], i);
8178 }
8179 }
8180 else if (typeof source === 'number') {
8181 if (!Number.isInteger(source)) {
8182 warn(`The v-for range expect an integer value but got ${source}.`);
8183 return [];
8184 }
8185 ret = new Array(source);
8186 for (let i = 0; i < source; i++) {
8187 ret[i] = renderItem(i + 1, i);
8188 }
8189 }
8190 else if (isObject(source)) {
8191 if (source[Symbol.iterator]) {
8192 ret = Array.from(source, renderItem);
8193 }
8194 else {
8195 const keys = Object.keys(source);
8196 ret = new Array(keys.length);
8197 for (let i = 0, l = keys.length; i < l; i++) {
8198 const key = keys[i];
8199 ret[i] = renderItem(source[key], key, i);
8200 }
8201 }
8202 }
8203 else {
8204 ret = [];
8205 }
8206 return ret;
8207 }
8208
8209 /**
8210 * For prefixing keys in v-on="obj" with "on"
8211 * @private
8212 */
8213 function toHandlers(obj) {
8214 const ret = {};
8215 if (!isObject(obj)) {
8216 warn(`v-on with no argument expects an object value.`);
8217 return ret;
8218 }
8219 for (const key in obj) {
8220 ret[toHandlerKey(key)] = obj[key];
8221 }
8222 return ret;
8223 }
8224
8225 /**
8226 * Compiler runtime helper for creating dynamic slots object
8227 * @private
8228 */
8229 function createSlots(slots, dynamicSlots) {
8230 for (let i = 0; i < dynamicSlots.length; i++) {
8231 const slot = dynamicSlots[i];
8232 // array of dynamic slot generated by <template v-for="..." #[...]>
8233 if (isArray(slot)) {
8234 for (let j = 0; j < slot.length; j++) {
8235 slots[slot[j].name] = slot[j].fn;
8236 }
8237 }
8238 else if (slot) {
8239 // conditional single slot generated by <template v-if="..." #foo>
8240 slots[slot.name] = slot.fn;
8241 }
8242 }
8243 return slots;
8244 }
8245
8246 // Core API ------------------------------------------------------------------
8247 const version = "3.0.11";
8248 /**
8249 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
8250 * @internal
8251 */
8252 const ssrUtils = (null);
8253
8254 const svgNS = 'http://www.w3.org/2000/svg';
8255 const doc = (typeof document !== 'undefined' ? document : null);
8256 let tempContainer;
8257 let tempSVGContainer;
8258 const nodeOps = {
8259 insert: (child, parent, anchor) => {
8260 parent.insertBefore(child, anchor || null);
8261 },
8262 remove: child => {
8263 const parent = child.parentNode;
8264 if (parent) {
8265 parent.removeChild(child);
8266 }
8267 },
8268 createElement: (tag, isSVG, is, props) => {
8269 const el = isSVG
8270 ? doc.createElementNS(svgNS, tag)
8271 : doc.createElement(tag, is ? { is } : undefined);
8272 if (tag === 'select' && props && props.multiple != null) {
8273 el.setAttribute('multiple', props.multiple);
8274 }
8275 return el;
8276 },
8277 createText: text => doc.createTextNode(text),
8278 createComment: text => doc.createComment(text),
8279 setText: (node, text) => {
8280 node.nodeValue = text;
8281 },
8282 setElementText: (el, text) => {
8283 el.textContent = text;
8284 },
8285 parentNode: node => node.parentNode,
8286 nextSibling: node => node.nextSibling,
8287 querySelector: selector => doc.querySelector(selector),
8288 setScopeId(el, id) {
8289 el.setAttribute(id, '');
8290 },
8291 cloneNode(el) {
8292 const cloned = el.cloneNode(true);
8293 // #3072
8294 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
8295 // - normally, elements using `:value` bindings will not be hoisted, but if
8296 // the bound value is a constant, e.g. `:value="true"` - they do get
8297 // hoisted.
8298 // - in production, hoisted nodes are cloned when subsequent inserts, but
8299 // cloneNode() does not copy the custom property we attached.
8300 // - This may need to account for other custom DOM properties we attach to
8301 // elements in addition to `_value` in the future.
8302 if (`_value` in el) {
8303 cloned._value = el._value;
8304 }
8305 return cloned;
8306 },
8307 // __UNSAFE__
8308 // Reason: innerHTML.
8309 // Static content here can only come from compiled templates.
8310 // As long as the user only uses trusted templates, this is safe.
8311 insertStaticContent(content, parent, anchor, isSVG) {
8312 const temp = isSVG
8313 ? tempSVGContainer ||
8314 (tempSVGContainer = doc.createElementNS(svgNS, 'svg'))
8315 : tempContainer || (tempContainer = doc.createElement('div'));
8316 temp.innerHTML = content;
8317 const first = temp.firstChild;
8318 let node = first;
8319 let last = node;
8320 while (node) {
8321 last = node;
8322 nodeOps.insert(node, parent, anchor);
8323 node = temp.firstChild;
8324 }
8325 return [first, last];
8326 }
8327 };
8328
8329 // compiler should normalize class + :class bindings on the same element
8330 // into a single binding ['staticClass', dynamic]
8331 function patchClass(el, value, isSVG) {
8332 if (value == null) {
8333 value = '';
8334 }
8335 if (isSVG) {
8336 el.setAttribute('class', value);
8337 }
8338 else {
8339 // directly setting className should be faster than setAttribute in theory
8340 // if this is an element during a transition, take the temporary transition
8341 // classes into account.
8342 const transitionClasses = el._vtc;
8343 if (transitionClasses) {
8344 value = (value
8345 ? [value, ...transitionClasses]
8346 : [...transitionClasses]).join(' ');
8347 }
8348 el.className = value;
8349 }
8350 }
8351
8352 function patchStyle(el, prev, next) {
8353 const style = el.style;
8354 if (!next) {
8355 el.removeAttribute('style');
8356 }
8357 else if (isString(next)) {
8358 if (prev !== next) {
8359 const current = style.display;
8360 style.cssText = next;
8361 // indicates that the `display` of the element is controlled by `v-show`,
8362 // so we always keep the current `display` value regardless of the `style` value,
8363 // thus handing over control to `v-show`.
8364 if ('_vod' in el) {
8365 style.display = current;
8366 }
8367 }
8368 }
8369 else {
8370 for (const key in next) {
8371 setStyle(style, key, next[key]);
8372 }
8373 if (prev && !isString(prev)) {
8374 for (const key in prev) {
8375 if (next[key] == null) {
8376 setStyle(style, key, '');
8377 }
8378 }
8379 }
8380 }
8381 }
8382 const importantRE = /\s*!important$/;
8383 function setStyle(style, name, val) {
8384 if (isArray(val)) {
8385 val.forEach(v => setStyle(style, name, v));
8386 }
8387 else {
8388 if (name.startsWith('--')) {
8389 // custom property definition
8390 style.setProperty(name, val);
8391 }
8392 else {
8393 const prefixed = autoPrefix(style, name);
8394 if (importantRE.test(val)) {
8395 // !important
8396 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
8397 }
8398 else {
8399 style[prefixed] = val;
8400 }
8401 }
8402 }
8403 }
8404 const prefixes = ['Webkit', 'Moz', 'ms'];
8405 const prefixCache = {};
8406 function autoPrefix(style, rawName) {
8407 const cached = prefixCache[rawName];
8408 if (cached) {
8409 return cached;
8410 }
8411 let name = camelize(rawName);
8412 if (name !== 'filter' && name in style) {
8413 return (prefixCache[rawName] = name);
8414 }
8415 name = capitalize(name);
8416 for (let i = 0; i < prefixes.length; i++) {
8417 const prefixed = prefixes[i] + name;
8418 if (prefixed in style) {
8419 return (prefixCache[rawName] = prefixed);
8420 }
8421 }
8422 return rawName;
8423 }
8424
8425 const xlinkNS = 'http://www.w3.org/1999/xlink';
8426 function patchAttr(el, key, value, isSVG) {
8427 if (isSVG && key.startsWith('xlink:')) {
8428 if (value == null) {
8429 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
8430 }
8431 else {
8432 el.setAttributeNS(xlinkNS, key, value);
8433 }
8434 }
8435 else {
8436 // note we are only checking boolean attributes that don't have a
8437 // corresponding dom prop of the same name here.
8438 const isBoolean = isSpecialBooleanAttr(key);
8439 if (value == null || (isBoolean && value === false)) {
8440 el.removeAttribute(key);
8441 }
8442 else {
8443 el.setAttribute(key, isBoolean ? '' : value);
8444 }
8445 }
8446 }
8447
8448 // __UNSAFE__
8449 // functions. The user is responsible for using them with only trusted content.
8450 function patchDOMProp(el, key, value,
8451 // the following args are passed only due to potential innerHTML/textContent
8452 // overriding existing VNodes, in which case the old tree must be properly
8453 // unmounted.
8454 prevChildren, parentComponent, parentSuspense, unmountChildren) {
8455 if (key === 'innerHTML' || key === 'textContent') {
8456 if (prevChildren) {
8457 unmountChildren(prevChildren, parentComponent, parentSuspense);
8458 }
8459 el[key] = value == null ? '' : value;
8460 return;
8461 }
8462 if (key === 'value' && el.tagName !== 'PROGRESS') {
8463 // store value as _value as well since
8464 // non-string values will be stringified.
8465 el._value = value;
8466 const newValue = value == null ? '' : value;
8467 if (el.value !== newValue) {
8468 el.value = newValue;
8469 }
8470 return;
8471 }
8472 if (value === '' || value == null) {
8473 const type = typeof el[key];
8474 if (value === '' && type === 'boolean') {
8475 // e.g. <select multiple> compiles to { multiple: '' }
8476 el[key] = true;
8477 return;
8478 }
8479 else if (value == null && type === 'string') {
8480 // e.g. <div :id="null">
8481 el[key] = '';
8482 el.removeAttribute(key);
8483 return;
8484 }
8485 else if (type === 'number') {
8486 // e.g. <img :width="null">
8487 el[key] = 0;
8488 el.removeAttribute(key);
8489 return;
8490 }
8491 }
8492 // some properties perform value validation and throw
8493 try {
8494 el[key] = value;
8495 }
8496 catch (e) {
8497 {
8498 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
8499 `value ${value} is invalid.`, e);
8500 }
8501 }
8502 }
8503
8504 // Async edge case fix requires storing an event listener's attach timestamp.
8505 let _getNow = Date.now;
8506 let skipTimestampCheck = false;
8507 if (typeof window !== 'undefined') {
8508 // Determine what event timestamp the browser is using. Annoyingly, the
8509 // timestamp can either be hi-res (relative to page load) or low-res
8510 // (relative to UNIX epoch), so in order to compare time we have to use the
8511 // same timestamp type when saving the flush timestamp.
8512 if (_getNow() > document.createEvent('Event').timeStamp) {
8513 // if the low-res timestamp which is bigger than the event timestamp
8514 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
8515 // and we need to use the hi-res version for event listeners as well.
8516 _getNow = () => performance.now();
8517 }
8518 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
8519 // and does not fire microtasks in between event propagation, so safe to exclude.
8520 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
8521 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
8522 }
8523 // To avoid the overhead of repeatedly calling performance.now(), we cache
8524 // and use the same timestamp for all event listeners attached in the same tick.
8525 let cachedNow = 0;
8526 const p = Promise.resolve();
8527 const reset = () => {
8528 cachedNow = 0;
8529 };
8530 const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
8531 function addEventListener(el, event, handler, options) {
8532 el.addEventListener(event, handler, options);
8533 }
8534 function removeEventListener(el, event, handler, options) {
8535 el.removeEventListener(event, handler, options);
8536 }
8537 function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
8538 // vei = vue event invokers
8539 const invokers = el._vei || (el._vei = {});
8540 const existingInvoker = invokers[rawName];
8541 if (nextValue && existingInvoker) {
8542 // patch
8543 existingInvoker.value = nextValue;
8544 }
8545 else {
8546 const [name, options] = parseName(rawName);
8547 if (nextValue) {
8548 // add
8549 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
8550 addEventListener(el, name, invoker, options);
8551 }
8552 else if (existingInvoker) {
8553 // remove
8554 removeEventListener(el, name, existingInvoker, options);
8555 invokers[rawName] = undefined;
8556 }
8557 }
8558 }
8559 const optionsModifierRE = /(?:Once|Passive|Capture)$/;
8560 function parseName(name) {
8561 let options;
8562 if (optionsModifierRE.test(name)) {
8563 options = {};
8564 let m;
8565 while ((m = name.match(optionsModifierRE))) {
8566 name = name.slice(0, name.length - m[0].length);
8567 options[m[0].toLowerCase()] = true;
8568 }
8569 }
8570 return [hyphenate(name.slice(2)), options];
8571 }
8572 function createInvoker(initialValue, instance) {
8573 const invoker = (e) => {
8574 // async edge case #6566: inner click event triggers patch, event handler
8575 // attached to outer element during patch, and triggered again. This
8576 // happens because browsers fire microtask ticks between event propagation.
8577 // the solution is simple: we save the timestamp when a handler is attached,
8578 // and the handler would only fire if the event passed to it was fired
8579 // AFTER it was attached.
8580 const timeStamp = e.timeStamp || _getNow();
8581 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
8582 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
8583 }
8584 };
8585 invoker.value = initialValue;
8586 invoker.attached = getNow();
8587 return invoker;
8588 }
8589 function patchStopImmediatePropagation(e, value) {
8590 if (isArray(value)) {
8591 const originalStop = e.stopImmediatePropagation;
8592 e.stopImmediatePropagation = () => {
8593 originalStop.call(e);
8594 e._stopped = true;
8595 };
8596 return value.map(fn => (e) => !e._stopped && fn(e));
8597 }
8598 else {
8599 return value;
8600 }
8601 }
8602
8603 const nativeOnRE = /^on[a-z]/;
8604 const forcePatchProp = (_, key) => key === 'value';
8605 const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
8606 switch (key) {
8607 // special
8608 case 'class':
8609 patchClass(el, nextValue, isSVG);
8610 break;
8611 case 'style':
8612 patchStyle(el, prevValue, nextValue);
8613 break;
8614 default:
8615 if (isOn(key)) {
8616 // ignore v-model listeners
8617 if (!isModelListener(key)) {
8618 patchEvent(el, key, prevValue, nextValue, parentComponent);
8619 }
8620 }
8621 else if (shouldSetAsProp(el, key, nextValue, isSVG)) {
8622 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
8623 }
8624 else {
8625 // special case for <input v-model type="checkbox"> with
8626 // :true-value & :false-value
8627 // store value as dom properties since non-string values will be
8628 // stringified.
8629 if (key === 'true-value') {
8630 el._trueValue = nextValue;
8631 }
8632 else if (key === 'false-value') {
8633 el._falseValue = nextValue;
8634 }
8635 patchAttr(el, key, nextValue, isSVG);
8636 }
8637 break;
8638 }
8639 };
8640 function shouldSetAsProp(el, key, value, isSVG) {
8641 if (isSVG) {
8642 // most keys must be set as attribute on svg elements to work
8643 // ...except innerHTML
8644 if (key === 'innerHTML') {
8645 return true;
8646 }
8647 // or native onclick with function values
8648 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
8649 return true;
8650 }
8651 return false;
8652 }
8653 // spellcheck and draggable are numerated attrs, however their
8654 // corresponding DOM properties are actually booleans - this leads to
8655 // setting it with a string "false" value leading it to be coerced to
8656 // `true`, so we need to always treat them as attributes.
8657 // Note that `contentEditable` doesn't have this problem: its DOM
8658 // property is also enumerated string values.
8659 if (key === 'spellcheck' || key === 'draggable') {
8660 return false;
8661 }
8662 // #1787, #2840 form property on form elements is readonly and must be set as
8663 // attribute.
8664 if (key === 'form') {
8665 return false;
8666 }
8667 // #1526 <input list> must be set as attribute
8668 if (key === 'list' && el.tagName === 'INPUT') {
8669 return false;
8670 }
8671 // #2766 <textarea type> must be set as attribute
8672 if (key === 'type' && el.tagName === 'TEXTAREA') {
8673 return false;
8674 }
8675 // native onclick with string value, must be set as attribute
8676 if (nativeOnRE.test(key) && isString(value)) {
8677 return false;
8678 }
8679 return key in el;
8680 }
8681
8682 function useCssModule(name = '$style') {
8683 /* istanbul ignore else */
8684 {
8685 {
8686 warn(`useCssModule() is not supported in the global build.`);
8687 }
8688 return EMPTY_OBJ;
8689 }
8690 }
8691
8692 /**
8693 * Runtime helper for SFC's CSS variable injection feature.
8694 * @private
8695 */
8696 function useCssVars(getter) {
8697 const instance = getCurrentInstance();
8698 /* istanbul ignore next */
8699 if (!instance) {
8700 warn(`useCssVars is called without current active component instance.`);
8701 return;
8702 }
8703 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
8704 onMounted(() => watchEffect(setVars, { flush: 'post' }));
8705 onUpdated(setVars);
8706 }
8707 function setVarsOnVNode(vnode, vars) {
8708 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
8709 const suspense = vnode.suspense;
8710 vnode = suspense.activeBranch;
8711 if (suspense.pendingBranch && !suspense.isHydrating) {
8712 suspense.effects.push(() => {
8713 setVarsOnVNode(suspense.activeBranch, vars);
8714 });
8715 }
8716 }
8717 // drill down HOCs until it's a non-component vnode
8718 while (vnode.component) {
8719 vnode = vnode.component.subTree;
8720 }
8721 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
8722 const style = vnode.el.style;
8723 for (const key in vars) {
8724 style.setProperty(`--${key}`, vars[key]);
8725 }
8726 }
8727 else if (vnode.type === Fragment) {
8728 vnode.children.forEach(c => setVarsOnVNode(c, vars));
8729 }
8730 }
8731
8732 const TRANSITION = 'transition';
8733 const ANIMATION = 'animation';
8734 // DOM Transition is a higher-order-component based on the platform-agnostic
8735 // base Transition component, with DOM-specific logic.
8736 const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
8737 Transition.displayName = 'Transition';
8738 const DOMTransitionPropsValidators = {
8739 name: String,
8740 type: String,
8741 css: {
8742 type: Boolean,
8743 default: true
8744 },
8745 duration: [String, Number, Object],
8746 enterFromClass: String,
8747 enterActiveClass: String,
8748 enterToClass: String,
8749 appearFromClass: String,
8750 appearActiveClass: String,
8751 appearToClass: String,
8752 leaveFromClass: String,
8753 leaveActiveClass: String,
8754 leaveToClass: String
8755 };
8756 const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
8757 function resolveTransitionProps(rawProps) {
8758 let { name = 'v', type, css = true, 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;
8759 const baseProps = {};
8760 for (const key in rawProps) {
8761 if (!(key in DOMTransitionPropsValidators)) {
8762 baseProps[key] = rawProps[key];
8763 }
8764 }
8765 if (!css) {
8766 return baseProps;
8767 }
8768 const durations = normalizeDuration(duration);
8769 const enterDuration = durations && durations[0];
8770 const leaveDuration = durations && durations[1];
8771 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
8772 const finishEnter = (el, isAppear, done) => {
8773 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
8774 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
8775 done && done();
8776 };
8777 const finishLeave = (el, done) => {
8778 removeTransitionClass(el, leaveToClass);
8779 removeTransitionClass(el, leaveActiveClass);
8780 done && done();
8781 };
8782 const makeEnterHook = (isAppear) => {
8783 return (el, done) => {
8784 const hook = isAppear ? onAppear : onEnter;
8785 const resolve = () => finishEnter(el, isAppear, done);
8786 hook && hook(el, resolve);
8787 nextFrame(() => {
8788 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
8789 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
8790 if (!(hook && hook.length > 1)) {
8791 whenTransitionEnds(el, type, enterDuration, resolve);
8792 }
8793 });
8794 };
8795 };
8796 return extend(baseProps, {
8797 onBeforeEnter(el) {
8798 onBeforeEnter && onBeforeEnter(el);
8799 addTransitionClass(el, enterFromClass);
8800 addTransitionClass(el, enterActiveClass);
8801 },
8802 onBeforeAppear(el) {
8803 onBeforeAppear && onBeforeAppear(el);
8804 addTransitionClass(el, appearFromClass);
8805 addTransitionClass(el, appearActiveClass);
8806 },
8807 onEnter: makeEnterHook(false),
8808 onAppear: makeEnterHook(true),
8809 onLeave(el, done) {
8810 const resolve = () => finishLeave(el, done);
8811 addTransitionClass(el, leaveFromClass);
8812 // force reflow so *-leave-from classes immediately take effect (#2593)
8813 forceReflow();
8814 addTransitionClass(el, leaveActiveClass);
8815 nextFrame(() => {
8816 removeTransitionClass(el, leaveFromClass);
8817 addTransitionClass(el, leaveToClass);
8818 if (!(onLeave && onLeave.length > 1)) {
8819 whenTransitionEnds(el, type, leaveDuration, resolve);
8820 }
8821 });
8822 onLeave && onLeave(el, resolve);
8823 },
8824 onEnterCancelled(el) {
8825 finishEnter(el, false);
8826 onEnterCancelled && onEnterCancelled(el);
8827 },
8828 onAppearCancelled(el) {
8829 finishEnter(el, true);
8830 onAppearCancelled && onAppearCancelled(el);
8831 },
8832 onLeaveCancelled(el) {
8833 finishLeave(el);
8834 onLeaveCancelled && onLeaveCancelled(el);
8835 }
8836 });
8837 }
8838 function normalizeDuration(duration) {
8839 if (duration == null) {
8840 return null;
8841 }
8842 else if (isObject(duration)) {
8843 return [NumberOf(duration.enter), NumberOf(duration.leave)];
8844 }
8845 else {
8846 const n = NumberOf(duration);
8847 return [n, n];
8848 }
8849 }
8850 function NumberOf(val) {
8851 const res = toNumber(val);
8852 validateDuration(res);
8853 return res;
8854 }
8855 function validateDuration(val) {
8856 if (typeof val !== 'number') {
8857 warn(`<transition> explicit duration is not a valid number - ` +
8858 `got ${JSON.stringify(val)}.`);
8859 }
8860 else if (isNaN(val)) {
8861 warn(`<transition> explicit duration is NaN - ` +
8862 'the duration expression might be incorrect.');
8863 }
8864 }
8865 function addTransitionClass(el, cls) {
8866 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
8867 (el._vtc ||
8868 (el._vtc = new Set())).add(cls);
8869 }
8870 function removeTransitionClass(el, cls) {
8871 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
8872 const { _vtc } = el;
8873 if (_vtc) {
8874 _vtc.delete(cls);
8875 if (!_vtc.size) {
8876 el._vtc = undefined;
8877 }
8878 }
8879 }
8880 function nextFrame(cb) {
8881 requestAnimationFrame(() => {
8882 requestAnimationFrame(cb);
8883 });
8884 }
8885 let endId = 0;
8886 function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
8887 const id = (el._endId = ++endId);
8888 const resolveIfNotStale = () => {
8889 if (id === el._endId) {
8890 resolve();
8891 }
8892 };
8893 if (explicitTimeout) {
8894 return setTimeout(resolveIfNotStale, explicitTimeout);
8895 }
8896 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
8897 if (!type) {
8898 return resolve();
8899 }
8900 const endEvent = type + 'end';
8901 let ended = 0;
8902 const end = () => {
8903 el.removeEventListener(endEvent, onEnd);
8904 resolveIfNotStale();
8905 };
8906 const onEnd = (e) => {
8907 if (e.target === el && ++ended >= propCount) {
8908 end();
8909 }
8910 };
8911 setTimeout(() => {
8912 if (ended < propCount) {
8913 end();
8914 }
8915 }, timeout + 1);
8916 el.addEventListener(endEvent, onEnd);
8917 }
8918 function getTransitionInfo(el, expectedType) {
8919 const styles = window.getComputedStyle(el);
8920 // JSDOM may return undefined for transition properties
8921 const getStyleProperties = (key) => (styles[key] || '').split(', ');
8922 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
8923 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
8924 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
8925 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
8926 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
8927 const animationTimeout = getTimeout(animationDelays, animationDurations);
8928 let type = null;
8929 let timeout = 0;
8930 let propCount = 0;
8931 /* istanbul ignore if */
8932 if (expectedType === TRANSITION) {
8933 if (transitionTimeout > 0) {
8934 type = TRANSITION;
8935 timeout = transitionTimeout;
8936 propCount = transitionDurations.length;
8937 }
8938 }
8939 else if (expectedType === ANIMATION) {
8940 if (animationTimeout > 0) {
8941 type = ANIMATION;
8942 timeout = animationTimeout;
8943 propCount = animationDurations.length;
8944 }
8945 }
8946 else {
8947 timeout = Math.max(transitionTimeout, animationTimeout);
8948 type =
8949 timeout > 0
8950 ? transitionTimeout > animationTimeout
8951 ? TRANSITION
8952 : ANIMATION
8953 : null;
8954 propCount = type
8955 ? type === TRANSITION
8956 ? transitionDurations.length
8957 : animationDurations.length
8958 : 0;
8959 }
8960 const hasTransform = type === TRANSITION &&
8961 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
8962 return {
8963 type,
8964 timeout,
8965 propCount,
8966 hasTransform
8967 };
8968 }
8969 function getTimeout(delays, durations) {
8970 while (delays.length < durations.length) {
8971 delays = delays.concat(delays);
8972 }
8973 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
8974 }
8975 // Old versions of Chromium (below 61.0.3163.100) formats floating pointer
8976 // numbers in a locale-dependent way, using a comma instead of a dot.
8977 // If comma is not replaced with a dot, the input will be rounded down
8978 // (i.e. acting as a floor function) causing unexpected behaviors
8979 function toMs(s) {
8980 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
8981 }
8982 // synchronously force layout to put elements into a certain state
8983 function forceReflow() {
8984 return document.body.offsetHeight;
8985 }
8986
8987 const positionMap = new WeakMap();
8988 const newPositionMap = new WeakMap();
8989 const TransitionGroupImpl = {
8990 name: 'TransitionGroup',
8991 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
8992 tag: String,
8993 moveClass: String
8994 }),
8995 setup(props, { slots }) {
8996 const instance = getCurrentInstance();
8997 const state = useTransitionState();
8998 let prevChildren;
8999 let children;
9000 onUpdated(() => {
9001 // children is guaranteed to exist after initial render
9002 if (!prevChildren.length) {
9003 return;
9004 }
9005 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
9006 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
9007 return;
9008 }
9009 // we divide the work into three loops to avoid mixing DOM reads and writes
9010 // in each iteration - which helps prevent layout thrashing.
9011 prevChildren.forEach(callPendingCbs);
9012 prevChildren.forEach(recordPosition);
9013 const movedChildren = prevChildren.filter(applyTranslation);
9014 // force reflow to put everything in position
9015 forceReflow();
9016 movedChildren.forEach(c => {
9017 const el = c.el;
9018 const style = el.style;
9019 addTransitionClass(el, moveClass);
9020 style.transform = style.webkitTransform = style.transitionDuration = '';
9021 const cb = (el._moveCb = (e) => {
9022 if (e && e.target !== el) {
9023 return;
9024 }
9025 if (!e || /transform$/.test(e.propertyName)) {
9026 el.removeEventListener('transitionend', cb);
9027 el._moveCb = null;
9028 removeTransitionClass(el, moveClass);
9029 }
9030 });
9031 el.addEventListener('transitionend', cb);
9032 });
9033 });
9034 return () => {
9035 const rawProps = toRaw(props);
9036 const cssTransitionProps = resolveTransitionProps(rawProps);
9037 const tag = rawProps.tag || Fragment;
9038 prevChildren = children;
9039 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
9040 for (let i = 0; i < children.length; i++) {
9041 const child = children[i];
9042 if (child.key != null) {
9043 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
9044 }
9045 else {
9046 warn(`<TransitionGroup> children must be keyed.`);
9047 }
9048 }
9049 if (prevChildren) {
9050 for (let i = 0; i < prevChildren.length; i++) {
9051 const child = prevChildren[i];
9052 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
9053 positionMap.set(child, child.el.getBoundingClientRect());
9054 }
9055 }
9056 return createVNode(tag, null, children);
9057 };
9058 }
9059 };
9060 const TransitionGroup = TransitionGroupImpl;
9061 function callPendingCbs(c) {
9062 const el = c.el;
9063 if (el._moveCb) {
9064 el._moveCb();
9065 }
9066 if (el._enterCb) {
9067 el._enterCb();
9068 }
9069 }
9070 function recordPosition(c) {
9071 newPositionMap.set(c, c.el.getBoundingClientRect());
9072 }
9073 function applyTranslation(c) {
9074 const oldPos = positionMap.get(c);
9075 const newPos = newPositionMap.get(c);
9076 const dx = oldPos.left - newPos.left;
9077 const dy = oldPos.top - newPos.top;
9078 if (dx || dy) {
9079 const s = c.el.style;
9080 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
9081 s.transitionDuration = '0s';
9082 return c;
9083 }
9084 }
9085 function hasCSSTransform(el, root, moveClass) {
9086 // Detect whether an element with the move class applied has
9087 // CSS transitions. Since the element may be inside an entering
9088 // transition at this very moment, we make a clone of it and remove
9089 // all other transition classes applied to ensure only the move class
9090 // is applied.
9091 const clone = el.cloneNode();
9092 if (el._vtc) {
9093 el._vtc.forEach(cls => {
9094 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
9095 });
9096 }
9097 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
9098 clone.style.display = 'none';
9099 const container = (root.nodeType === 1
9100 ? root
9101 : root.parentNode);
9102 container.appendChild(clone);
9103 const { hasTransform } = getTransitionInfo(clone);
9104 container.removeChild(clone);
9105 return hasTransform;
9106 }
9107
9108 const getModelAssigner = (vnode) => {
9109 const fn = vnode.props['onUpdate:modelValue'];
9110 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
9111 };
9112 function onCompositionStart(e) {
9113 e.target.composing = true;
9114 }
9115 function onCompositionEnd(e) {
9116 const target = e.target;
9117 if (target.composing) {
9118 target.composing = false;
9119 trigger$1(target, 'input');
9120 }
9121 }
9122 function trigger$1(el, type) {
9123 const e = document.createEvent('HTMLEvents');
9124 e.initEvent(type, true, true);
9125 el.dispatchEvent(e);
9126 }
9127 // We are exporting the v-model runtime directly as vnode hooks so that it can
9128 // be tree-shaken in case v-model is never used.
9129 const vModelText = {
9130 created(el, { modifiers: { lazy, trim, number } }, vnode) {
9131 el._assign = getModelAssigner(vnode);
9132 const castToNumber = number || el.type === 'number';
9133 addEventListener(el, lazy ? 'change' : 'input', e => {
9134 if (e.target.composing)
9135 return;
9136 let domValue = el.value;
9137 if (trim) {
9138 domValue = domValue.trim();
9139 }
9140 else if (castToNumber) {
9141 domValue = toNumber(domValue);
9142 }
9143 el._assign(domValue);
9144 });
9145 if (trim) {
9146 addEventListener(el, 'change', () => {
9147 el.value = el.value.trim();
9148 });
9149 }
9150 if (!lazy) {
9151 addEventListener(el, 'compositionstart', onCompositionStart);
9152 addEventListener(el, 'compositionend', onCompositionEnd);
9153 // Safari < 10.2 & UIWebView doesn't fire compositionend when
9154 // switching focus before confirming composition choice
9155 // this also fixes the issue where some browsers e.g. iOS Chrome
9156 // fires "change" instead of "input" on autocomplete.
9157 addEventListener(el, 'change', onCompositionEnd);
9158 }
9159 },
9160 // set value on mounted so it's after min/max for type="range"
9161 mounted(el, { value }) {
9162 el.value = value == null ? '' : value;
9163 },
9164 beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
9165 el._assign = getModelAssigner(vnode);
9166 // avoid clearing unresolved text. #2302
9167 if (el.composing)
9168 return;
9169 if (document.activeElement === el) {
9170 if (trim && el.value.trim() === value) {
9171 return;
9172 }
9173 if ((number || el.type === 'number') && toNumber(el.value) === value) {
9174 return;
9175 }
9176 }
9177 const newValue = value == null ? '' : value;
9178 if (el.value !== newValue) {
9179 el.value = newValue;
9180 }
9181 }
9182 };
9183 const vModelCheckbox = {
9184 created(el, _, vnode) {
9185 el._assign = getModelAssigner(vnode);
9186 addEventListener(el, 'change', () => {
9187 const modelValue = el._modelValue;
9188 const elementValue = getValue(el);
9189 const checked = el.checked;
9190 const assign = el._assign;
9191 if (isArray(modelValue)) {
9192 const index = looseIndexOf(modelValue, elementValue);
9193 const found = index !== -1;
9194 if (checked && !found) {
9195 assign(modelValue.concat(elementValue));
9196 }
9197 else if (!checked && found) {
9198 const filtered = [...modelValue];
9199 filtered.splice(index, 1);
9200 assign(filtered);
9201 }
9202 }
9203 else if (isSet(modelValue)) {
9204 const cloned = new Set(modelValue);
9205 if (checked) {
9206 cloned.add(elementValue);
9207 }
9208 else {
9209 cloned.delete(elementValue);
9210 }
9211 assign(cloned);
9212 }
9213 else {
9214 assign(getCheckboxValue(el, checked));
9215 }
9216 });
9217 },
9218 // set initial checked on mount to wait for true-value/false-value
9219 mounted: setChecked,
9220 beforeUpdate(el, binding, vnode) {
9221 el._assign = getModelAssigner(vnode);
9222 setChecked(el, binding, vnode);
9223 }
9224 };
9225 function setChecked(el, { value, oldValue }, vnode) {
9226 el._modelValue = value;
9227 if (isArray(value)) {
9228 el.checked = looseIndexOf(value, vnode.props.value) > -1;
9229 }
9230 else if (isSet(value)) {
9231 el.checked = value.has(vnode.props.value);
9232 }
9233 else if (value !== oldValue) {
9234 el.checked = looseEqual(value, getCheckboxValue(el, true));
9235 }
9236 }
9237 const vModelRadio = {
9238 created(el, { value }, vnode) {
9239 el.checked = looseEqual(value, vnode.props.value);
9240 el._assign = getModelAssigner(vnode);
9241 addEventListener(el, 'change', () => {
9242 el._assign(getValue(el));
9243 });
9244 },
9245 beforeUpdate(el, { value, oldValue }, vnode) {
9246 el._assign = getModelAssigner(vnode);
9247 if (value !== oldValue) {
9248 el.checked = looseEqual(value, vnode.props.value);
9249 }
9250 }
9251 };
9252 const vModelSelect = {
9253 created(el, { value, modifiers: { number } }, vnode) {
9254 const isSetModel = isSet(value);
9255 addEventListener(el, 'change', () => {
9256 const selectedVal = Array.prototype.filter
9257 .call(el.options, (o) => o.selected)
9258 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
9259 el._assign(el.multiple
9260 ? isSetModel
9261 ? new Set(selectedVal)
9262 : selectedVal
9263 : selectedVal[0]);
9264 });
9265 el._assign = getModelAssigner(vnode);
9266 },
9267 // set value in mounted & updated because <select> relies on its children
9268 // <option>s.
9269 mounted(el, { value }) {
9270 setSelected(el, value);
9271 },
9272 beforeUpdate(el, _binding, vnode) {
9273 el._assign = getModelAssigner(vnode);
9274 },
9275 updated(el, { value }) {
9276 setSelected(el, value);
9277 }
9278 };
9279 function setSelected(el, value) {
9280 const isMultiple = el.multiple;
9281 if (isMultiple && !isArray(value) && !isSet(value)) {
9282 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
9283 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
9284 return;
9285 }
9286 for (let i = 0, l = el.options.length; i < l; i++) {
9287 const option = el.options[i];
9288 const optionValue = getValue(option);
9289 if (isMultiple) {
9290 if (isArray(value)) {
9291 option.selected = looseIndexOf(value, optionValue) > -1;
9292 }
9293 else {
9294 option.selected = value.has(optionValue);
9295 }
9296 }
9297 else {
9298 if (looseEqual(getValue(option), value)) {
9299 el.selectedIndex = i;
9300 return;
9301 }
9302 }
9303 }
9304 if (!isMultiple) {
9305 el.selectedIndex = -1;
9306 }
9307 }
9308 // retrieve raw value set via :value bindings
9309 function getValue(el) {
9310 return '_value' in el ? el._value : el.value;
9311 }
9312 // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
9313 function getCheckboxValue(el, checked) {
9314 const key = checked ? '_trueValue' : '_falseValue';
9315 return key in el ? el[key] : checked;
9316 }
9317 const vModelDynamic = {
9318 created(el, binding, vnode) {
9319 callModelHook(el, binding, vnode, null, 'created');
9320 },
9321 mounted(el, binding, vnode) {
9322 callModelHook(el, binding, vnode, null, 'mounted');
9323 },
9324 beforeUpdate(el, binding, vnode, prevVNode) {
9325 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
9326 },
9327 updated(el, binding, vnode, prevVNode) {
9328 callModelHook(el, binding, vnode, prevVNode, 'updated');
9329 }
9330 };
9331 function callModelHook(el, binding, vnode, prevVNode, hook) {
9332 let modelToUse;
9333 switch (el.tagName) {
9334 case 'SELECT':
9335 modelToUse = vModelSelect;
9336 break;
9337 case 'TEXTAREA':
9338 modelToUse = vModelText;
9339 break;
9340 default:
9341 switch (vnode.props && vnode.props.type) {
9342 case 'checkbox':
9343 modelToUse = vModelCheckbox;
9344 break;
9345 case 'radio':
9346 modelToUse = vModelRadio;
9347 break;
9348 default:
9349 modelToUse = vModelText;
9350 }
9351 }
9352 const fn = modelToUse[hook];
9353 fn && fn(el, binding, vnode, prevVNode);
9354 }
9355
9356 const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
9357 const modifierGuards = {
9358 stop: e => e.stopPropagation(),
9359 prevent: e => e.preventDefault(),
9360 self: e => e.target !== e.currentTarget,
9361 ctrl: e => !e.ctrlKey,
9362 shift: e => !e.shiftKey,
9363 alt: e => !e.altKey,
9364 meta: e => !e.metaKey,
9365 left: e => 'button' in e && e.button !== 0,
9366 middle: e => 'button' in e && e.button !== 1,
9367 right: e => 'button' in e && e.button !== 2,
9368 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
9369 };
9370 /**
9371 * @private
9372 */
9373 const withModifiers = (fn, modifiers) => {
9374 return (event, ...args) => {
9375 for (let i = 0; i < modifiers.length; i++) {
9376 const guard = modifierGuards[modifiers[i]];
9377 if (guard && guard(event, modifiers))
9378 return;
9379 }
9380 return fn(event, ...args);
9381 };
9382 };
9383 // Kept for 2.x compat.
9384 // Note: IE11 compat for `spacebar` and `del` is removed for now.
9385 const keyNames = {
9386 esc: 'escape',
9387 space: ' ',
9388 up: 'arrow-up',
9389 left: 'arrow-left',
9390 right: 'arrow-right',
9391 down: 'arrow-down',
9392 delete: 'backspace'
9393 };
9394 /**
9395 * @private
9396 */
9397 const withKeys = (fn, modifiers) => {
9398 return (event) => {
9399 if (!('key' in event))
9400 return;
9401 const eventKey = hyphenate(event.key);
9402 if (
9403 // None of the provided key modifiers match the current event key
9404 !modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
9405 return;
9406 }
9407 return fn(event);
9408 };
9409 };
9410
9411 const vShow = {
9412 beforeMount(el, { value }, { transition }) {
9413 el._vod = el.style.display === 'none' ? '' : el.style.display;
9414 if (transition && value) {
9415 transition.beforeEnter(el);
9416 }
9417 else {
9418 setDisplay(el, value);
9419 }
9420 },
9421 mounted(el, { value }, { transition }) {
9422 if (transition && value) {
9423 transition.enter(el);
9424 }
9425 },
9426 updated(el, { value, oldValue }, { transition }) {
9427 if (!value === !oldValue)
9428 return;
9429 if (transition) {
9430 if (value) {
9431 transition.beforeEnter(el);
9432 setDisplay(el, true);
9433 transition.enter(el);
9434 }
9435 else {
9436 transition.leave(el, () => {
9437 setDisplay(el, false);
9438 });
9439 }
9440 }
9441 else {
9442 setDisplay(el, value);
9443 }
9444 },
9445 beforeUnmount(el, { value }) {
9446 setDisplay(el, value);
9447 }
9448 };
9449 function setDisplay(el, value) {
9450 el.style.display = value ? el._vod : 'none';
9451 }
9452
9453 const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps);
9454 // lazy create the renderer - this makes core renderer logic tree-shakable
9455 // in case the user only imports reactivity utilities from Vue.
9456 let renderer;
9457 let enabledHydration = false;
9458 function ensureRenderer() {
9459 return renderer || (renderer = createRenderer(rendererOptions));
9460 }
9461 function ensureHydrationRenderer() {
9462 renderer = enabledHydration
9463 ? renderer
9464 : createHydrationRenderer(rendererOptions);
9465 enabledHydration = true;
9466 return renderer;
9467 }
9468 // use explicit type casts here to avoid import() calls in rolled-up d.ts
9469 const render = ((...args) => {
9470 ensureRenderer().render(...args);
9471 });
9472 const hydrate = ((...args) => {
9473 ensureHydrationRenderer().hydrate(...args);
9474 });
9475 const createApp = ((...args) => {
9476 const app = ensureRenderer().createApp(...args);
9477 {
9478 injectNativeTagCheck(app);
9479 injectCustomElementCheck(app);
9480 }
9481 const { mount } = app;
9482 app.mount = (containerOrSelector) => {
9483 const container = normalizeContainer(containerOrSelector);
9484 if (!container)
9485 return;
9486 const component = app._component;
9487 if (!isFunction(component) && !component.render && !component.template) {
9488 component.template = container.innerHTML;
9489 }
9490 // clear content before mounting
9491 container.innerHTML = '';
9492 const proxy = mount(container, false, container instanceof SVGElement);
9493 if (container instanceof Element) {
9494 container.removeAttribute('v-cloak');
9495 container.setAttribute('data-v-app', '');
9496 }
9497 return proxy;
9498 };
9499 return app;
9500 });
9501 const createSSRApp = ((...args) => {
9502 const app = ensureHydrationRenderer().createApp(...args);
9503 {
9504 injectNativeTagCheck(app);
9505 injectCustomElementCheck(app);
9506 }
9507 const { mount } = app;
9508 app.mount = (containerOrSelector) => {
9509 const container = normalizeContainer(containerOrSelector);
9510 if (container) {
9511 return mount(container, true, container instanceof SVGElement);
9512 }
9513 };
9514 return app;
9515 });
9516 function injectNativeTagCheck(app) {
9517 // Inject `isNativeTag`
9518 // this is used for component name validation (dev only)
9519 Object.defineProperty(app.config, 'isNativeTag', {
9520 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
9521 writable: false
9522 });
9523 }
9524 // dev only
9525 function injectCustomElementCheck(app) {
9526 if (isRuntimeOnly()) {
9527 const value = app.config.isCustomElement;
9528 Object.defineProperty(app.config, 'isCustomElement', {
9529 get() {
9530 return value;
9531 },
9532 set() {
9533 warn(`The \`isCustomElement\` config option is only respected when using the runtime compiler.` +
9534 `If you are using the runtime-only build, \`isCustomElement\` must be passed to \`@vue/compiler-dom\` in the build setup instead` +
9535 `- for example, via the \`compilerOptions\` option in vue-loader: https://vue-loader.vuejs.org/options.html#compileroptions.`);
9536 }
9537 });
9538 }
9539 }
9540 function normalizeContainer(container) {
9541 if (isString(container)) {
9542 const res = document.querySelector(container);
9543 if (!res) {
9544 warn(`Failed to mount app: mount target selector "${container}" returned null.`);
9545 }
9546 return res;
9547 }
9548 if (container instanceof window.ShadowRoot &&
9549 container.mode === 'closed') {
9550 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
9551 }
9552 return container;
9553 }
9554
9555 function initDev() {
9556 {
9557 {
9558 console.info(`You are running a development build of Vue.\n` +
9559 `Make sure to use the production build (*.prod.js) when deploying for production.`);
9560 }
9561 initCustomFormatter();
9562 }
9563 }
9564
9565 function defaultOnError(error) {
9566 throw error;
9567 }
9568 function createCompilerError(code, loc, messages, additionalMessage) {
9569 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
9570 ;
9571 const error = new SyntaxError(String(msg));
9572 error.code = code;
9573 error.loc = loc;
9574 return error;
9575 }
9576 const errorMessages = {
9577 // parse errors
9578 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
9579 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
9580 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
9581 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
9582 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
9583 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
9584 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
9585 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
9586 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
9587 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
9588 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
9589 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
9590 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
9591 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
9592 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
9593 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
9594 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
9595 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
9596 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
9597 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
9598 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
9599 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
9600 // Vue-specific parse errors
9601 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
9602 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
9603 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
9604 [26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
9605 'Note that dynamic directive argument cannot contain spaces.',
9606 // transform errors
9607 [27 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
9608 [28 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
9609 [29 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if.`,
9610 [30 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
9611 [31 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
9612 [32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
9613 [33 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
9614 [34 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
9615 [35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
9616 [36 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
9617 `When there are multiple named slots, all slots should use <template> ` +
9618 `syntax to avoid scope ambiguity.`,
9619 [37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
9620 [38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
9621 `default slot. These children will be ignored.`,
9622 [39 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
9623 [40 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
9624 [41 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
9625 [42 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
9626 [43 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
9627 [44 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
9628 // generic errors
9629 [45 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
9630 [46 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
9631 [47 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
9632 [48 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`
9633 };
9634
9635 const FRAGMENT = Symbol(`Fragment` );
9636 const TELEPORT = Symbol(`Teleport` );
9637 const SUSPENSE = Symbol(`Suspense` );
9638 const KEEP_ALIVE = Symbol(`KeepAlive` );
9639 const BASE_TRANSITION = Symbol(`BaseTransition` );
9640 const OPEN_BLOCK = Symbol(`openBlock` );
9641 const CREATE_BLOCK = Symbol(`createBlock` );
9642 const CREATE_VNODE = Symbol(`createVNode` );
9643 const CREATE_COMMENT = Symbol(`createCommentVNode` );
9644 const CREATE_TEXT = Symbol(`createTextVNode` );
9645 const CREATE_STATIC = Symbol(`createStaticVNode` );
9646 const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
9647 const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
9648 const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
9649 const WITH_DIRECTIVES = Symbol(`withDirectives` );
9650 const RENDER_LIST = Symbol(`renderList` );
9651 const RENDER_SLOT = Symbol(`renderSlot` );
9652 const CREATE_SLOTS = Symbol(`createSlots` );
9653 const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
9654 const MERGE_PROPS = Symbol(`mergeProps` );
9655 const TO_HANDLERS = Symbol(`toHandlers` );
9656 const CAMELIZE = Symbol(`camelize` );
9657 const CAPITALIZE = Symbol(`capitalize` );
9658 const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
9659 const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
9660 const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
9661 const POP_SCOPE_ID = Symbol(`popScopeId` );
9662 const WITH_SCOPE_ID = Symbol(`withScopeId` );
9663 const WITH_CTX = Symbol(`withCtx` );
9664 const UNREF = Symbol(`unref` );
9665 const IS_REF = Symbol(`isRef` );
9666 // Name mapping for runtime helpers that need to be imported from 'vue' in
9667 // generated code. Make sure these are correctly exported in the runtime!
9668 // Using `any` here because TS doesn't allow symbols as index type.
9669 const helperNameMap = {
9670 [FRAGMENT]: `Fragment`,
9671 [TELEPORT]: `Teleport`,
9672 [SUSPENSE]: `Suspense`,
9673 [KEEP_ALIVE]: `KeepAlive`,
9674 [BASE_TRANSITION]: `BaseTransition`,
9675 [OPEN_BLOCK]: `openBlock`,
9676 [CREATE_BLOCK]: `createBlock`,
9677 [CREATE_VNODE]: `createVNode`,
9678 [CREATE_COMMENT]: `createCommentVNode`,
9679 [CREATE_TEXT]: `createTextVNode`,
9680 [CREATE_STATIC]: `createStaticVNode`,
9681 [RESOLVE_COMPONENT]: `resolveComponent`,
9682 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
9683 [RESOLVE_DIRECTIVE]: `resolveDirective`,
9684 [WITH_DIRECTIVES]: `withDirectives`,
9685 [RENDER_LIST]: `renderList`,
9686 [RENDER_SLOT]: `renderSlot`,
9687 [CREATE_SLOTS]: `createSlots`,
9688 [TO_DISPLAY_STRING]: `toDisplayString`,
9689 [MERGE_PROPS]: `mergeProps`,
9690 [TO_HANDLERS]: `toHandlers`,
9691 [CAMELIZE]: `camelize`,
9692 [CAPITALIZE]: `capitalize`,
9693 [TO_HANDLER_KEY]: `toHandlerKey`,
9694 [SET_BLOCK_TRACKING]: `setBlockTracking`,
9695 [PUSH_SCOPE_ID]: `pushScopeId`,
9696 [POP_SCOPE_ID]: `popScopeId`,
9697 [WITH_SCOPE_ID]: `withScopeId`,
9698 [WITH_CTX]: `withCtx`,
9699 [UNREF]: `unref`,
9700 [IS_REF]: `isRef`
9701 };
9702 function registerRuntimeHelpers(helpers) {
9703 Object.getOwnPropertySymbols(helpers).forEach(s => {
9704 helperNameMap[s] = helpers[s];
9705 });
9706 }
9707
9708 // AST Utilities ---------------------------------------------------------------
9709 // Some expressions, e.g. sequence and conditional expressions, are never
9710 // associated with template nodes, so their source locations are just a stub.
9711 // Container types like CompoundExpression also don't need a real location.
9712 const locStub = {
9713 source: '',
9714 start: { line: 1, column: 1, offset: 0 },
9715 end: { line: 1, column: 1, offset: 0 }
9716 };
9717 function createRoot(children, loc = locStub) {
9718 return {
9719 type: 0 /* ROOT */,
9720 children,
9721 helpers: [],
9722 components: [],
9723 directives: [],
9724 hoists: [],
9725 imports: [],
9726 cached: 0,
9727 temps: 0,
9728 codegenNode: undefined,
9729 loc
9730 };
9731 }
9732 function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) {
9733 if (context) {
9734 if (isBlock) {
9735 context.helper(OPEN_BLOCK);
9736 context.helper(CREATE_BLOCK);
9737 }
9738 else {
9739 context.helper(CREATE_VNODE);
9740 }
9741 if (directives) {
9742 context.helper(WITH_DIRECTIVES);
9743 }
9744 }
9745 return {
9746 type: 13 /* VNODE_CALL */,
9747 tag,
9748 props,
9749 children,
9750 patchFlag,
9751 dynamicProps,
9752 directives,
9753 isBlock,
9754 disableTracking,
9755 loc
9756 };
9757 }
9758 function createArrayExpression(elements, loc = locStub) {
9759 return {
9760 type: 17 /* JS_ARRAY_EXPRESSION */,
9761 loc,
9762 elements
9763 };
9764 }
9765 function createObjectExpression(properties, loc = locStub) {
9766 return {
9767 type: 15 /* JS_OBJECT_EXPRESSION */,
9768 loc,
9769 properties
9770 };
9771 }
9772 function createObjectProperty(key, value) {
9773 return {
9774 type: 16 /* JS_PROPERTY */,
9775 loc: locStub,
9776 key: isString(key) ? createSimpleExpression(key, true) : key,
9777 value
9778 };
9779 }
9780 function createSimpleExpression(content, isStatic, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
9781 return {
9782 type: 4 /* SIMPLE_EXPRESSION */,
9783 loc,
9784 content,
9785 isStatic,
9786 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
9787 };
9788 }
9789 function createCompoundExpression(children, loc = locStub) {
9790 return {
9791 type: 8 /* COMPOUND_EXPRESSION */,
9792 loc,
9793 children
9794 };
9795 }
9796 function createCallExpression(callee, args = [], loc = locStub) {
9797 return {
9798 type: 14 /* JS_CALL_EXPRESSION */,
9799 loc,
9800 callee,
9801 arguments: args
9802 };
9803 }
9804 function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
9805 return {
9806 type: 18 /* JS_FUNCTION_EXPRESSION */,
9807 params,
9808 returns,
9809 newline,
9810 isSlot,
9811 loc
9812 };
9813 }
9814 function createConditionalExpression(test, consequent, alternate, newline = true) {
9815 return {
9816 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
9817 test,
9818 consequent,
9819 alternate,
9820 newline,
9821 loc: locStub
9822 };
9823 }
9824 function createCacheExpression(index, value, isVNode = false) {
9825 return {
9826 type: 20 /* JS_CACHE_EXPRESSION */,
9827 index,
9828 value,
9829 isVNode,
9830 loc: locStub
9831 };
9832 }
9833
9834 const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
9835 const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
9836 function isCoreComponent(tag) {
9837 if (isBuiltInType(tag, 'Teleport')) {
9838 return TELEPORT;
9839 }
9840 else if (isBuiltInType(tag, 'Suspense')) {
9841 return SUSPENSE;
9842 }
9843 else if (isBuiltInType(tag, 'KeepAlive')) {
9844 return KEEP_ALIVE;
9845 }
9846 else if (isBuiltInType(tag, 'BaseTransition')) {
9847 return BASE_TRANSITION;
9848 }
9849 }
9850 const nonIdentifierRE = /^\d|[^\$\w]/;
9851 const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
9852 const memberExpRE = /^[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*(?:\s*\.\s*[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*|\[[^\]]+\])*$/;
9853 const isMemberExpression = (path) => {
9854 if (!path)
9855 return false;
9856 return memberExpRE.test(path.trim());
9857 };
9858 function getInnerRange(loc, offset, length) {
9859 const source = loc.source.substr(offset, length);
9860 const newLoc = {
9861 source,
9862 start: advancePositionWithClone(loc.start, loc.source, offset),
9863 end: loc.end
9864 };
9865 if (length != null) {
9866 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
9867 }
9868 return newLoc;
9869 }
9870 function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
9871 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
9872 }
9873 // advance by mutation without cloning (for performance reasons), since this
9874 // gets called a lot in the parser
9875 function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
9876 let linesCount = 0;
9877 let lastNewLinePos = -1;
9878 for (let i = 0; i < numberOfCharacters; i++) {
9879 if (source.charCodeAt(i) === 10 /* newline char code */) {
9880 linesCount++;
9881 lastNewLinePos = i;
9882 }
9883 }
9884 pos.offset += numberOfCharacters;
9885 pos.line += linesCount;
9886 pos.column =
9887 lastNewLinePos === -1
9888 ? pos.column + numberOfCharacters
9889 : numberOfCharacters - lastNewLinePos;
9890 return pos;
9891 }
9892 function assert(condition, msg) {
9893 /* istanbul ignore if */
9894 if (!condition) {
9895 throw new Error(msg || `unexpected compiler condition`);
9896 }
9897 }
9898 function findDir(node, name, allowEmpty = false) {
9899 for (let i = 0; i < node.props.length; i++) {
9900 const p = node.props[i];
9901 if (p.type === 7 /* DIRECTIVE */ &&
9902 (allowEmpty || p.exp) &&
9903 (isString(name) ? p.name === name : name.test(p.name))) {
9904 return p;
9905 }
9906 }
9907 }
9908 function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
9909 for (let i = 0; i < node.props.length; i++) {
9910 const p = node.props[i];
9911 if (p.type === 6 /* ATTRIBUTE */) {
9912 if (dynamicOnly)
9913 continue;
9914 if (p.name === name && (p.value || allowEmpty)) {
9915 return p;
9916 }
9917 }
9918 else if (p.name === 'bind' &&
9919 (p.exp || allowEmpty) &&
9920 isBindKey(p.arg, name)) {
9921 return p;
9922 }
9923 }
9924 }
9925 function isBindKey(arg, name) {
9926 return !!(arg && isStaticExp(arg) && arg.content === name);
9927 }
9928 function hasDynamicKeyVBind(node) {
9929 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
9930 p.name === 'bind' &&
9931 (!p.arg || // v-bind="obj"
9932 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
9933 !p.arg.isStatic) // v-bind:[foo]
9934 );
9935 }
9936 function isText(node) {
9937 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
9938 }
9939 function isVSlot(p) {
9940 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
9941 }
9942 function isTemplateNode(node) {
9943 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
9944 }
9945 function isSlotOutlet(node) {
9946 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
9947 }
9948 function injectProp(node, prop, context) {
9949 let propsWithInjection;
9950 const props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
9951 if (props == null || isString(props)) {
9952 propsWithInjection = createObjectExpression([prop]);
9953 }
9954 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
9955 // merged props... add ours
9956 // only inject key to object literal if it's the first argument so that
9957 // if doesn't override user provided keys
9958 const first = props.arguments[0];
9959 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
9960 first.properties.unshift(prop);
9961 }
9962 else {
9963 if (props.callee === TO_HANDLERS) {
9964 // #2366
9965 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
9966 createObjectExpression([prop]),
9967 props
9968 ]);
9969 }
9970 else {
9971 props.arguments.unshift(createObjectExpression([prop]));
9972 }
9973 }
9974 !propsWithInjection && (propsWithInjection = props);
9975 }
9976 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
9977 let alreadyExists = false;
9978 // check existing key to avoid overriding user provided keys
9979 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
9980 const propKeyName = prop.key.content;
9981 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
9982 p.key.content === propKeyName);
9983 }
9984 if (!alreadyExists) {
9985 props.properties.unshift(prop);
9986 }
9987 propsWithInjection = props;
9988 }
9989 else {
9990 // single v-bind with expression, return a merged replacement
9991 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
9992 createObjectExpression([prop]),
9993 props
9994 ]);
9995 }
9996 if (node.type === 13 /* VNODE_CALL */) {
9997 node.props = propsWithInjection;
9998 }
9999 else {
10000 node.arguments[2] = propsWithInjection;
10001 }
10002 }
10003 function toValidAssetId(name, type) {
10004 return `_${type}_${name.replace(/[^\w]/g, '_')}`;
10005 }
10006
10007 // The default decoder only provides escapes for characters reserved as part of
10008 // the template syntax, and is only used if the custom renderer did not provide
10009 // a platform-specific decoder.
10010 const decodeRE = /&(gt|lt|amp|apos|quot);/g;
10011 const decodeMap = {
10012 gt: '>',
10013 lt: '<',
10014 amp: '&',
10015 apos: "'",
10016 quot: '"'
10017 };
10018 const defaultParserOptions = {
10019 delimiters: [`{{`, `}}`],
10020 getNamespace: () => 0 /* HTML */,
10021 getTextMode: () => 0 /* DATA */,
10022 isVoidTag: NO,
10023 isPreTag: NO,
10024 isCustomElement: NO,
10025 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
10026 onError: defaultOnError,
10027 comments: false
10028 };
10029 function baseParse(content, options = {}) {
10030 const context = createParserContext(content, options);
10031 const start = getCursor(context);
10032 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
10033 }
10034 function createParserContext(content, rawOptions) {
10035 const options = extend({}, defaultParserOptions);
10036 for (const key in rawOptions) {
10037 // @ts-ignore
10038 options[key] = rawOptions[key] || defaultParserOptions[key];
10039 }
10040 return {
10041 options,
10042 column: 1,
10043 line: 1,
10044 offset: 0,
10045 originalSource: content,
10046 source: content,
10047 inPre: false,
10048 inVPre: false
10049 };
10050 }
10051 function parseChildren(context, mode, ancestors) {
10052 const parent = last(ancestors);
10053 const ns = parent ? parent.ns : 0 /* HTML */;
10054 const nodes = [];
10055 while (!isEnd(context, mode, ancestors)) {
10056 const s = context.source;
10057 let node = undefined;
10058 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
10059 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
10060 // '{{'
10061 node = parseInterpolation(context, mode);
10062 }
10063 else if (mode === 0 /* DATA */ && s[0] === '<') {
10064 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
10065 if (s.length === 1) {
10066 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
10067 }
10068 else if (s[1] === '!') {
10069 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
10070 if (startsWith(s, '<!--')) {
10071 node = parseComment(context);
10072 }
10073 else if (startsWith(s, '<!DOCTYPE')) {
10074 // Ignore DOCTYPE by a limitation.
10075 node = parseBogusComment(context);
10076 }
10077 else if (startsWith(s, '<![CDATA[')) {
10078 if (ns !== 0 /* HTML */) {
10079 node = parseCDATA(context, ancestors);
10080 }
10081 else {
10082 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
10083 node = parseBogusComment(context);
10084 }
10085 }
10086 else {
10087 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
10088 node = parseBogusComment(context);
10089 }
10090 }
10091 else if (s[1] === '/') {
10092 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
10093 if (s.length === 2) {
10094 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
10095 }
10096 else if (s[2] === '>') {
10097 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
10098 advanceBy(context, 3);
10099 continue;
10100 }
10101 else if (/[a-z]/i.test(s[2])) {
10102 emitError(context, 23 /* X_INVALID_END_TAG */);
10103 parseTag(context, 1 /* End */, parent);
10104 continue;
10105 }
10106 else {
10107 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
10108 node = parseBogusComment(context);
10109 }
10110 }
10111 else if (/[a-z]/i.test(s[1])) {
10112 node = parseElement(context, ancestors);
10113 }
10114 else if (s[1] === '?') {
10115 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
10116 node = parseBogusComment(context);
10117 }
10118 else {
10119 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
10120 }
10121 }
10122 }
10123 if (!node) {
10124 node = parseText(context, mode);
10125 }
10126 if (isArray(node)) {
10127 for (let i = 0; i < node.length; i++) {
10128 pushNode(nodes, node[i]);
10129 }
10130 }
10131 else {
10132 pushNode(nodes, node);
10133 }
10134 }
10135 // Whitespace management for more efficient output
10136 // (same as v2 whitespace: 'condense')
10137 let removedWhitespace = false;
10138 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
10139 for (let i = 0; i < nodes.length; i++) {
10140 const node = nodes[i];
10141 if (!context.inPre && node.type === 2 /* TEXT */) {
10142 if (!/[^\t\r\n\f ]/.test(node.content)) {
10143 const prev = nodes[i - 1];
10144 const next = nodes[i + 1];
10145 // If:
10146 // - the whitespace is the first or last node, or:
10147 // - the whitespace is adjacent to a comment, or:
10148 // - the whitespace is between two elements AND contains newline
10149 // Then the whitespace is ignored.
10150 if (!prev ||
10151 !next ||
10152 prev.type === 3 /* COMMENT */ ||
10153 next.type === 3 /* COMMENT */ ||
10154 (prev.type === 1 /* ELEMENT */ &&
10155 next.type === 1 /* ELEMENT */ &&
10156 /[\r\n]/.test(node.content))) {
10157 removedWhitespace = true;
10158 nodes[i] = null;
10159 }
10160 else {
10161 // Otherwise, condensed consecutive whitespace inside the text
10162 // down to a single space
10163 node.content = ' ';
10164 }
10165 }
10166 else {
10167 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
10168 }
10169 }
10170 }
10171 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
10172 // remove leading newline per html spec
10173 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
10174 const first = nodes[0];
10175 if (first && first.type === 2 /* TEXT */) {
10176 first.content = first.content.replace(/^\r?\n/, '');
10177 }
10178 }
10179 }
10180 return removedWhitespace ? nodes.filter(Boolean) : nodes;
10181 }
10182 function pushNode(nodes, node) {
10183 if (node.type === 2 /* TEXT */) {
10184 const prev = last(nodes);
10185 // Merge if both this and the previous node are text and those are
10186 // consecutive. This happens for cases like "a < b".
10187 if (prev &&
10188 prev.type === 2 /* TEXT */ &&
10189 prev.loc.end.offset === node.loc.start.offset) {
10190 prev.content += node.content;
10191 prev.loc.end = node.loc.end;
10192 prev.loc.source += node.loc.source;
10193 return;
10194 }
10195 }
10196 nodes.push(node);
10197 }
10198 function parseCDATA(context, ancestors) {
10199 advanceBy(context, 9);
10200 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
10201 if (context.source.length === 0) {
10202 emitError(context, 6 /* EOF_IN_CDATA */);
10203 }
10204 else {
10205 advanceBy(context, 3);
10206 }
10207 return nodes;
10208 }
10209 function parseComment(context) {
10210 const start = getCursor(context);
10211 let content;
10212 // Regular comment.
10213 const match = /--(\!)?>/.exec(context.source);
10214 if (!match) {
10215 content = context.source.slice(4);
10216 advanceBy(context, context.source.length);
10217 emitError(context, 7 /* EOF_IN_COMMENT */);
10218 }
10219 else {
10220 if (match.index <= 3) {
10221 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
10222 }
10223 if (match[1]) {
10224 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
10225 }
10226 content = context.source.slice(4, match.index);
10227 // Advancing with reporting nested comments.
10228 const s = context.source.slice(0, match.index);
10229 let prevIndex = 1, nestedIndex = 0;
10230 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
10231 advanceBy(context, nestedIndex - prevIndex + 1);
10232 if (nestedIndex + 4 < s.length) {
10233 emitError(context, 16 /* NESTED_COMMENT */);
10234 }
10235 prevIndex = nestedIndex + 1;
10236 }
10237 advanceBy(context, match.index + match[0].length - prevIndex + 1);
10238 }
10239 return {
10240 type: 3 /* COMMENT */,
10241 content,
10242 loc: getSelection(context, start)
10243 };
10244 }
10245 function parseBogusComment(context) {
10246 const start = getCursor(context);
10247 const contentStart = context.source[1] === '?' ? 1 : 2;
10248 let content;
10249 const closeIndex = context.source.indexOf('>');
10250 if (closeIndex === -1) {
10251 content = context.source.slice(contentStart);
10252 advanceBy(context, context.source.length);
10253 }
10254 else {
10255 content = context.source.slice(contentStart, closeIndex);
10256 advanceBy(context, closeIndex + 1);
10257 }
10258 return {
10259 type: 3 /* COMMENT */,
10260 content,
10261 loc: getSelection(context, start)
10262 };
10263 }
10264 function parseElement(context, ancestors) {
10265 // Start tag.
10266 const wasInPre = context.inPre;
10267 const wasInVPre = context.inVPre;
10268 const parent = last(ancestors);
10269 const element = parseTag(context, 0 /* Start */, parent);
10270 const isPreBoundary = context.inPre && !wasInPre;
10271 const isVPreBoundary = context.inVPre && !wasInVPre;
10272 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
10273 return element;
10274 }
10275 // Children.
10276 ancestors.push(element);
10277 const mode = context.options.getTextMode(element, parent);
10278 const children = parseChildren(context, mode, ancestors);
10279 ancestors.pop();
10280 element.children = children;
10281 // End tag.
10282 if (startsWithEndTagOpen(context.source, element.tag)) {
10283 parseTag(context, 1 /* End */, parent);
10284 }
10285 else {
10286 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
10287 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
10288 const first = children[0];
10289 if (first && startsWith(first.loc.source, '<!--')) {
10290 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
10291 }
10292 }
10293 }
10294 element.loc = getSelection(context, element.loc.start);
10295 if (isPreBoundary) {
10296 context.inPre = false;
10297 }
10298 if (isVPreBoundary) {
10299 context.inVPre = false;
10300 }
10301 return element;
10302 }
10303 const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
10304 /**
10305 * Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
10306 */
10307 function parseTag(context, type, parent) {
10308 // Tag open.
10309 const start = getCursor(context);
10310 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
10311 const tag = match[1];
10312 const ns = context.options.getNamespace(tag, parent);
10313 advanceBy(context, match[0].length);
10314 advanceSpaces(context);
10315 // save current state in case we need to re-parse attributes with v-pre
10316 const cursor = getCursor(context);
10317 const currentSource = context.source;
10318 // Attributes.
10319 let props = parseAttributes(context, type);
10320 // check <pre> tag
10321 if (context.options.isPreTag(tag)) {
10322 context.inPre = true;
10323 }
10324 // check v-pre
10325 if (!context.inVPre &&
10326 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
10327 context.inVPre = true;
10328 // reset context
10329 extend(context, cursor);
10330 context.source = currentSource;
10331 // re-parse attrs and filter out v-pre itself
10332 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
10333 }
10334 // Tag close.
10335 let isSelfClosing = false;
10336 if (context.source.length === 0) {
10337 emitError(context, 9 /* EOF_IN_TAG */);
10338 }
10339 else {
10340 isSelfClosing = startsWith(context.source, '/>');
10341 if (type === 1 /* End */ && isSelfClosing) {
10342 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
10343 }
10344 advanceBy(context, isSelfClosing ? 2 : 1);
10345 }
10346 let tagType = 0 /* ELEMENT */;
10347 const options = context.options;
10348 if (!context.inVPre && !options.isCustomElement(tag)) {
10349 const hasVIs = props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'is');
10350 if (options.isNativeTag && !hasVIs) {
10351 if (!options.isNativeTag(tag))
10352 tagType = 1 /* COMPONENT */;
10353 }
10354 else if (hasVIs ||
10355 isCoreComponent(tag) ||
10356 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
10357 /^[A-Z]/.test(tag) ||
10358 tag === 'component') {
10359 tagType = 1 /* COMPONENT */;
10360 }
10361 if (tag === 'slot') {
10362 tagType = 2 /* SLOT */;
10363 }
10364 else if (tag === 'template' &&
10365 props.some(p => {
10366 return (p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name));
10367 })) {
10368 tagType = 3 /* TEMPLATE */;
10369 }
10370 }
10371 return {
10372 type: 1 /* ELEMENT */,
10373 ns,
10374 tag,
10375 tagType,
10376 props,
10377 isSelfClosing,
10378 children: [],
10379 loc: getSelection(context, start),
10380 codegenNode: undefined // to be created during transform phase
10381 };
10382 }
10383 function parseAttributes(context, type) {
10384 const props = [];
10385 const attributeNames = new Set();
10386 while (context.source.length > 0 &&
10387 !startsWith(context.source, '>') &&
10388 !startsWith(context.source, '/>')) {
10389 if (startsWith(context.source, '/')) {
10390 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
10391 advanceBy(context, 1);
10392 advanceSpaces(context);
10393 continue;
10394 }
10395 if (type === 1 /* End */) {
10396 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
10397 }
10398 const attr = parseAttribute(context, attributeNames);
10399 if (type === 0 /* Start */) {
10400 props.push(attr);
10401 }
10402 if (/^[^\t\r\n\f />]/.test(context.source)) {
10403 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
10404 }
10405 advanceSpaces(context);
10406 }
10407 return props;
10408 }
10409 function parseAttribute(context, nameSet) {
10410 // Name.
10411 const start = getCursor(context);
10412 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
10413 const name = match[0];
10414 if (nameSet.has(name)) {
10415 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
10416 }
10417 nameSet.add(name);
10418 if (name[0] === '=') {
10419 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
10420 }
10421 {
10422 const pattern = /["'<]/g;
10423 let m;
10424 while ((m = pattern.exec(name))) {
10425 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
10426 }
10427 }
10428 advanceBy(context, name.length);
10429 // Value
10430 let value = undefined;
10431 if (/^[\t\r\n\f ]*=/.test(context.source)) {
10432 advanceSpaces(context);
10433 advanceBy(context, 1);
10434 advanceSpaces(context);
10435 value = parseAttributeValue(context);
10436 if (!value) {
10437 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
10438 }
10439 }
10440 const loc = getSelection(context, start);
10441 if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {
10442 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
10443 const dirName = match[1] ||
10444 (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');
10445 let arg;
10446 if (match[2]) {
10447 const isSlot = dirName === 'slot';
10448 const startOffset = name.lastIndexOf(match[2]);
10449 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
10450 let content = match[2];
10451 let isStatic = true;
10452 if (content.startsWith('[')) {
10453 isStatic = false;
10454 if (!content.endsWith(']')) {
10455 emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
10456 }
10457 content = content.substr(1, content.length - 2);
10458 }
10459 else if (isSlot) {
10460 // #1241 special case for v-slot: vuetify relies extensively on slot
10461 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
10462 // supports such usage so we are keeping it consistent with 2.x.
10463 content += match[3] || '';
10464 }
10465 arg = {
10466 type: 4 /* SIMPLE_EXPRESSION */,
10467 content,
10468 isStatic,
10469 constType: isStatic
10470 ? 3 /* CAN_STRINGIFY */
10471 : 0 /* NOT_CONSTANT */,
10472 loc
10473 };
10474 }
10475 if (value && value.isQuoted) {
10476 const valueLoc = value.loc;
10477 valueLoc.start.offset++;
10478 valueLoc.start.column++;
10479 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
10480 valueLoc.source = valueLoc.source.slice(1, -1);
10481 }
10482 return {
10483 type: 7 /* DIRECTIVE */,
10484 name: dirName,
10485 exp: value && {
10486 type: 4 /* SIMPLE_EXPRESSION */,
10487 content: value.content,
10488 isStatic: false,
10489 // Treat as non-constant by default. This can be potentially set to
10490 // other values by `transformExpression` to make it eligible for hoisting.
10491 constType: 0 /* NOT_CONSTANT */,
10492 loc: value.loc
10493 },
10494 arg,
10495 modifiers: match[3] ? match[3].substr(1).split('.') : [],
10496 loc
10497 };
10498 }
10499 return {
10500 type: 6 /* ATTRIBUTE */,
10501 name,
10502 value: value && {
10503 type: 2 /* TEXT */,
10504 content: value.content,
10505 loc: value.loc
10506 },
10507 loc
10508 };
10509 }
10510 function parseAttributeValue(context) {
10511 const start = getCursor(context);
10512 let content;
10513 const quote = context.source[0];
10514 const isQuoted = quote === `"` || quote === `'`;
10515 if (isQuoted) {
10516 // Quoted value.
10517 advanceBy(context, 1);
10518 const endIndex = context.source.indexOf(quote);
10519 if (endIndex === -1) {
10520 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
10521 }
10522 else {
10523 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
10524 advanceBy(context, 1);
10525 }
10526 }
10527 else {
10528 // Unquoted
10529 const match = /^[^\t\r\n\f >]+/.exec(context.source);
10530 if (!match) {
10531 return undefined;
10532 }
10533 const unexpectedChars = /["'<=`]/g;
10534 let m;
10535 while ((m = unexpectedChars.exec(match[0]))) {
10536 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
10537 }
10538 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
10539 }
10540 return { content, isQuoted, loc: getSelection(context, start) };
10541 }
10542 function parseInterpolation(context, mode) {
10543 const [open, close] = context.options.delimiters;
10544 const closeIndex = context.source.indexOf(close, open.length);
10545 if (closeIndex === -1) {
10546 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
10547 return undefined;
10548 }
10549 const start = getCursor(context);
10550 advanceBy(context, open.length);
10551 const innerStart = getCursor(context);
10552 const innerEnd = getCursor(context);
10553 const rawContentLength = closeIndex - open.length;
10554 const rawContent = context.source.slice(0, rawContentLength);
10555 const preTrimContent = parseTextData(context, rawContentLength, mode);
10556 const content = preTrimContent.trim();
10557 const startOffset = preTrimContent.indexOf(content);
10558 if (startOffset > 0) {
10559 advancePositionWithMutation(innerStart, rawContent, startOffset);
10560 }
10561 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
10562 advancePositionWithMutation(innerEnd, rawContent, endOffset);
10563 advanceBy(context, close.length);
10564 return {
10565 type: 5 /* INTERPOLATION */,
10566 content: {
10567 type: 4 /* SIMPLE_EXPRESSION */,
10568 isStatic: false,
10569 // Set `isConstant` to false by default and will decide in transformExpression
10570 constType: 0 /* NOT_CONSTANT */,
10571 content,
10572 loc: getSelection(context, innerStart, innerEnd)
10573 },
10574 loc: getSelection(context, start)
10575 };
10576 }
10577 function parseText(context, mode) {
10578 const endTokens = ['<', context.options.delimiters[0]];
10579 if (mode === 3 /* CDATA */) {
10580 endTokens.push(']]>');
10581 }
10582 let endIndex = context.source.length;
10583 for (let i = 0; i < endTokens.length; i++) {
10584 const index = context.source.indexOf(endTokens[i], 1);
10585 if (index !== -1 && endIndex > index) {
10586 endIndex = index;
10587 }
10588 }
10589 const start = getCursor(context);
10590 const content = parseTextData(context, endIndex, mode);
10591 return {
10592 type: 2 /* TEXT */,
10593 content,
10594 loc: getSelection(context, start)
10595 };
10596 }
10597 /**
10598 * Get text data with a given length from the current location.
10599 * This translates HTML entities in the text data.
10600 */
10601 function parseTextData(context, length, mode) {
10602 const rawText = context.source.slice(0, length);
10603 advanceBy(context, length);
10604 if (mode === 2 /* RAWTEXT */ ||
10605 mode === 3 /* CDATA */ ||
10606 rawText.indexOf('&') === -1) {
10607 return rawText;
10608 }
10609 else {
10610 // DATA or RCDATA containing "&"". Entity decoding required.
10611 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
10612 }
10613 }
10614 function getCursor(context) {
10615 const { column, line, offset } = context;
10616 return { column, line, offset };
10617 }
10618 function getSelection(context, start, end) {
10619 end = end || getCursor(context);
10620 return {
10621 start,
10622 end,
10623 source: context.originalSource.slice(start.offset, end.offset)
10624 };
10625 }
10626 function last(xs) {
10627 return xs[xs.length - 1];
10628 }
10629 function startsWith(source, searchString) {
10630 return source.startsWith(searchString);
10631 }
10632 function advanceBy(context, numberOfCharacters) {
10633 const { source } = context;
10634 advancePositionWithMutation(context, source, numberOfCharacters);
10635 context.source = source.slice(numberOfCharacters);
10636 }
10637 function advanceSpaces(context) {
10638 const match = /^[\t\r\n\f ]+/.exec(context.source);
10639 if (match) {
10640 advanceBy(context, match[0].length);
10641 }
10642 }
10643 function getNewPosition(context, start, numberOfCharacters) {
10644 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
10645 }
10646 function emitError(context, code, offset, loc = getCursor(context)) {
10647 if (offset) {
10648 loc.offset += offset;
10649 loc.column += offset;
10650 }
10651 context.options.onError(createCompilerError(code, {
10652 start: loc,
10653 end: loc,
10654 source: ''
10655 }));
10656 }
10657 function isEnd(context, mode, ancestors) {
10658 const s = context.source;
10659 switch (mode) {
10660 case 0 /* DATA */:
10661 if (startsWith(s, '</')) {
10662 // TODO: probably bad performance
10663 for (let i = ancestors.length - 1; i >= 0; --i) {
10664 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
10665 return true;
10666 }
10667 }
10668 }
10669 break;
10670 case 1 /* RCDATA */:
10671 case 2 /* RAWTEXT */: {
10672 const parent = last(ancestors);
10673 if (parent && startsWithEndTagOpen(s, parent.tag)) {
10674 return true;
10675 }
10676 break;
10677 }
10678 case 3 /* CDATA */:
10679 if (startsWith(s, ']]>')) {
10680 return true;
10681 }
10682 break;
10683 }
10684 return !s;
10685 }
10686 function startsWithEndTagOpen(source, tag) {
10687 return (startsWith(source, '</') &&
10688 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
10689 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
10690 }
10691
10692 function hoistStatic(root, context) {
10693 walk(root, context,
10694 // Root node is unfortunately non-hoistable due to potential parent
10695 // fallthrough attributes.
10696 isSingleElementRoot(root, root.children[0]));
10697 }
10698 function isSingleElementRoot(root, child) {
10699 const { children } = root;
10700 return (children.length === 1 &&
10701 child.type === 1 /* ELEMENT */ &&
10702 !isSlotOutlet(child));
10703 }
10704 function walk(node, context, doNotHoistNode = false) {
10705 let hasHoistedNode = false;
10706 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
10707 // static bindings with expressions. These expressions are guaranteed to be
10708 // constant so they are still eligible for hoisting, but they are only
10709 // available at runtime and therefore cannot be evaluated ahead of time.
10710 // This is only a concern for pre-stringification (via transformHoist by
10711 // @vue/compiler-dom), but doing it here allows us to perform only one full
10712 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
10713 // stringficiation threshold is met.
10714 let canStringify = true;
10715 const { children } = node;
10716 for (let i = 0; i < children.length; i++) {
10717 const child = children[i];
10718 // only plain elements & text calls are eligible for hoisting.
10719 if (child.type === 1 /* ELEMENT */ &&
10720 child.tagType === 0 /* ELEMENT */) {
10721 const constantType = doNotHoistNode
10722 ? 0 /* NOT_CONSTANT */
10723 : getConstantType(child, context);
10724 if (constantType > 0 /* NOT_CONSTANT */) {
10725 if (constantType < 3 /* CAN_STRINGIFY */) {
10726 canStringify = false;
10727 }
10728 if (constantType >= 2 /* CAN_HOIST */) {
10729 child.codegenNode.patchFlag =
10730 -1 /* HOISTED */ + (` /* HOISTED */` );
10731 child.codegenNode = context.hoist(child.codegenNode);
10732 hasHoistedNode = true;
10733 continue;
10734 }
10735 }
10736 else {
10737 // node may contain dynamic children, but its props may be eligible for
10738 // hoisting.
10739 const codegenNode = child.codegenNode;
10740 if (codegenNode.type === 13 /* VNODE_CALL */) {
10741 const flag = getPatchFlag(codegenNode);
10742 if ((!flag ||
10743 flag === 512 /* NEED_PATCH */ ||
10744 flag === 1 /* TEXT */) &&
10745 getGeneratedPropsConstantType(child, context) >=
10746 2 /* CAN_HOIST */) {
10747 const props = getNodeProps(child);
10748 if (props) {
10749 codegenNode.props = context.hoist(props);
10750 }
10751 }
10752 }
10753 }
10754 }
10755 else if (child.type === 12 /* TEXT_CALL */) {
10756 const contentType = getConstantType(child.content, context);
10757 if (contentType > 0) {
10758 if (contentType < 3 /* CAN_STRINGIFY */) {
10759 canStringify = false;
10760 }
10761 if (contentType >= 2 /* CAN_HOIST */) {
10762 child.codegenNode = context.hoist(child.codegenNode);
10763 hasHoistedNode = true;
10764 }
10765 }
10766 }
10767 // walk further
10768 if (child.type === 1 /* ELEMENT */) {
10769 const isComponent = child.tagType === 1 /* COMPONENT */;
10770 if (isComponent) {
10771 context.scopes.vSlot++;
10772 }
10773 walk(child, context);
10774 if (isComponent) {
10775 context.scopes.vSlot--;
10776 }
10777 }
10778 else if (child.type === 11 /* FOR */) {
10779 // Do not hoist v-for single child because it has to be a block
10780 walk(child, context, child.children.length === 1);
10781 }
10782 else if (child.type === 9 /* IF */) {
10783 for (let i = 0; i < child.branches.length; i++) {
10784 // Do not hoist v-if single child because it has to be a block
10785 walk(child.branches[i], context, child.branches[i].children.length === 1);
10786 }
10787 }
10788 }
10789 if (canStringify && hasHoistedNode && context.transformHoist) {
10790 context.transformHoist(children, context, node);
10791 }
10792 }
10793 function getConstantType(node, context) {
10794 const { constantCache } = context;
10795 switch (node.type) {
10796 case 1 /* ELEMENT */:
10797 if (node.tagType !== 0 /* ELEMENT */) {
10798 return 0 /* NOT_CONSTANT */;
10799 }
10800 const cached = constantCache.get(node);
10801 if (cached !== undefined) {
10802 return cached;
10803 }
10804 const codegenNode = node.codegenNode;
10805 if (codegenNode.type !== 13 /* VNODE_CALL */) {
10806 return 0 /* NOT_CONSTANT */;
10807 }
10808 const flag = getPatchFlag(codegenNode);
10809 if (!flag) {
10810 let returnType = 3 /* CAN_STRINGIFY */;
10811 // Element itself has no patch flag. However we still need to check:
10812 // 1. Even for a node with no patch flag, it is possible for it to contain
10813 // non-hoistable expressions that refers to scope variables, e.g. compiler
10814 // injected keys or cached event handlers. Therefore we need to always
10815 // check the codegenNode's props to be sure.
10816 const generatedPropsType = getGeneratedPropsConstantType(node, context);
10817 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
10818 constantCache.set(node, 0 /* NOT_CONSTANT */);
10819 return 0 /* NOT_CONSTANT */;
10820 }
10821 if (generatedPropsType < returnType) {
10822 returnType = generatedPropsType;
10823 }
10824 // 2. its children.
10825 for (let i = 0; i < node.children.length; i++) {
10826 const childType = getConstantType(node.children[i], context);
10827 if (childType === 0 /* NOT_CONSTANT */) {
10828 constantCache.set(node, 0 /* NOT_CONSTANT */);
10829 return 0 /* NOT_CONSTANT */;
10830 }
10831 if (childType < returnType) {
10832 returnType = childType;
10833 }
10834 }
10835 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
10836 // type, check if any of the props can cause the type to be lowered
10837 // we can skip can_patch because it's guaranteed by the absence of a
10838 // patchFlag.
10839 if (returnType > 1 /* CAN_SKIP_PATCH */) {
10840 for (let i = 0; i < node.props.length; i++) {
10841 const p = node.props[i];
10842 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
10843 const expType = getConstantType(p.exp, context);
10844 if (expType === 0 /* NOT_CONSTANT */) {
10845 constantCache.set(node, 0 /* NOT_CONSTANT */);
10846 return 0 /* NOT_CONSTANT */;
10847 }
10848 if (expType < returnType) {
10849 returnType = expType;
10850 }
10851 }
10852 }
10853 }
10854 // only svg/foreignObject could be block here, however if they are
10855 // static then they don't need to be blocks since there will be no
10856 // nested updates.
10857 if (codegenNode.isBlock) {
10858 context.removeHelper(OPEN_BLOCK);
10859 context.removeHelper(CREATE_BLOCK);
10860 codegenNode.isBlock = false;
10861 context.helper(CREATE_VNODE);
10862 }
10863 constantCache.set(node, returnType);
10864 return returnType;
10865 }
10866 else {
10867 constantCache.set(node, 0 /* NOT_CONSTANT */);
10868 return 0 /* NOT_CONSTANT */;
10869 }
10870 case 2 /* TEXT */:
10871 case 3 /* COMMENT */:
10872 return 3 /* CAN_STRINGIFY */;
10873 case 9 /* IF */:
10874 case 11 /* FOR */:
10875 case 10 /* IF_BRANCH */:
10876 return 0 /* NOT_CONSTANT */;
10877 case 5 /* INTERPOLATION */:
10878 case 12 /* TEXT_CALL */:
10879 return getConstantType(node.content, context);
10880 case 4 /* SIMPLE_EXPRESSION */:
10881 return node.constType;
10882 case 8 /* COMPOUND_EXPRESSION */:
10883 let returnType = 3 /* CAN_STRINGIFY */;
10884 for (let i = 0; i < node.children.length; i++) {
10885 const child = node.children[i];
10886 if (isString(child) || isSymbol(child)) {
10887 continue;
10888 }
10889 const childType = getConstantType(child, context);
10890 if (childType === 0 /* NOT_CONSTANT */) {
10891 return 0 /* NOT_CONSTANT */;
10892 }
10893 else if (childType < returnType) {
10894 returnType = childType;
10895 }
10896 }
10897 return returnType;
10898 default:
10899 return 0 /* NOT_CONSTANT */;
10900 }
10901 }
10902 function getGeneratedPropsConstantType(node, context) {
10903 let returnType = 3 /* CAN_STRINGIFY */;
10904 const props = getNodeProps(node);
10905 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
10906 const { properties } = props;
10907 for (let i = 0; i < properties.length; i++) {
10908 const { key, value } = properties[i];
10909 const keyType = getConstantType(key, context);
10910 if (keyType === 0 /* NOT_CONSTANT */) {
10911 return keyType;
10912 }
10913 if (keyType < returnType) {
10914 returnType = keyType;
10915 }
10916 if (value.type !== 4 /* SIMPLE_EXPRESSION */) {
10917 return 0 /* NOT_CONSTANT */;
10918 }
10919 const valueType = getConstantType(value, context);
10920 if (valueType === 0 /* NOT_CONSTANT */) {
10921 return valueType;
10922 }
10923 if (valueType < returnType) {
10924 returnType = valueType;
10925 }
10926 }
10927 }
10928 return returnType;
10929 }
10930 function getNodeProps(node) {
10931 const codegenNode = node.codegenNode;
10932 if (codegenNode.type === 13 /* VNODE_CALL */) {
10933 return codegenNode.props;
10934 }
10935 }
10936 function getPatchFlag(node) {
10937 const flag = node.patchFlag;
10938 return flag ? parseInt(flag, 10) : undefined;
10939 }
10940
10941 function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError }) {
10942 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
10943 const context = {
10944 // options
10945 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
10946 prefixIdentifiers,
10947 hoistStatic,
10948 cacheHandlers,
10949 nodeTransforms,
10950 directiveTransforms,
10951 transformHoist,
10952 isBuiltInComponent,
10953 isCustomElement,
10954 expressionPlugins,
10955 scopeId,
10956 slotted,
10957 ssr,
10958 ssrCssVars,
10959 bindingMetadata,
10960 inline,
10961 isTS,
10962 onError,
10963 // state
10964 root,
10965 helpers: new Map(),
10966 components: new Set(),
10967 directives: new Set(),
10968 hoists: [],
10969 imports: [],
10970 constantCache: new Map(),
10971 temps: 0,
10972 cached: 0,
10973 identifiers: Object.create(null),
10974 scopes: {
10975 vFor: 0,
10976 vSlot: 0,
10977 vPre: 0,
10978 vOnce: 0
10979 },
10980 parent: null,
10981 currentNode: root,
10982 childIndex: 0,
10983 // methods
10984 helper(name) {
10985 const count = context.helpers.get(name) || 0;
10986 context.helpers.set(name, count + 1);
10987 return name;
10988 },
10989 removeHelper(name) {
10990 const count = context.helpers.get(name);
10991 if (count) {
10992 const currentCount = count - 1;
10993 if (!currentCount) {
10994 context.helpers.delete(name);
10995 }
10996 else {
10997 context.helpers.set(name, currentCount);
10998 }
10999 }
11000 },
11001 helperString(name) {
11002 return `_${helperNameMap[context.helper(name)]}`;
11003 },
11004 replaceNode(node) {
11005 /* istanbul ignore if */
11006 {
11007 if (!context.currentNode) {
11008 throw new Error(`Node being replaced is already removed.`);
11009 }
11010 if (!context.parent) {
11011 throw new Error(`Cannot replace root node.`);
11012 }
11013 }
11014 context.parent.children[context.childIndex] = context.currentNode = node;
11015 },
11016 removeNode(node) {
11017 if (!context.parent) {
11018 throw new Error(`Cannot remove root node.`);
11019 }
11020 const list = context.parent.children;
11021 const removalIndex = node
11022 ? list.indexOf(node)
11023 : context.currentNode
11024 ? context.childIndex
11025 : -1;
11026 /* istanbul ignore if */
11027 if (removalIndex < 0) {
11028 throw new Error(`node being removed is not a child of current parent`);
11029 }
11030 if (!node || node === context.currentNode) {
11031 // current node removed
11032 context.currentNode = null;
11033 context.onNodeRemoved();
11034 }
11035 else {
11036 // sibling node removed
11037 if (context.childIndex > removalIndex) {
11038 context.childIndex--;
11039 context.onNodeRemoved();
11040 }
11041 }
11042 context.parent.children.splice(removalIndex, 1);
11043 },
11044 onNodeRemoved: () => { },
11045 addIdentifiers(exp) {
11046 },
11047 removeIdentifiers(exp) {
11048 },
11049 hoist(exp) {
11050 context.hoists.push(exp);
11051 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
11052 identifier.hoisted = exp;
11053 return identifier;
11054 },
11055 cache(exp, isVNode = false) {
11056 return createCacheExpression(++context.cached, exp, isVNode);
11057 }
11058 };
11059 return context;
11060 }
11061 function transform(root, options) {
11062 const context = createTransformContext(root, options);
11063 traverseNode(root, context);
11064 if (options.hoistStatic) {
11065 hoistStatic(root, context);
11066 }
11067 if (!options.ssr) {
11068 createRootCodegen(root, context);
11069 }
11070 // finalize meta information
11071 root.helpers = [...context.helpers.keys()];
11072 root.components = [...context.components];
11073 root.directives = [...context.directives];
11074 root.imports = context.imports;
11075 root.hoists = context.hoists;
11076 root.temps = context.temps;
11077 root.cached = context.cached;
11078 }
11079 function createRootCodegen(root, context) {
11080 const { helper, removeHelper } = context;
11081 const { children } = root;
11082 if (children.length === 1) {
11083 const child = children[0];
11084 // if the single child is an element, turn it into a block.
11085 if (isSingleElementRoot(root, child) && child.codegenNode) {
11086 // single element root is never hoisted so codegenNode will never be
11087 // SimpleExpressionNode
11088 const codegenNode = child.codegenNode;
11089 if (codegenNode.type === 13 /* VNODE_CALL */) {
11090 if (!codegenNode.isBlock) {
11091 removeHelper(CREATE_VNODE);
11092 codegenNode.isBlock = true;
11093 helper(OPEN_BLOCK);
11094 helper(CREATE_BLOCK);
11095 }
11096 }
11097 root.codegenNode = codegenNode;
11098 }
11099 else {
11100 // - single <slot/>, IfNode, ForNode: already blocks.
11101 // - single text node: always patched.
11102 // root codegen falls through via genNode()
11103 root.codegenNode = child;
11104 }
11105 }
11106 else if (children.length > 1) {
11107 // root has multiple nodes - return a fragment block.
11108 let patchFlag = 64 /* STABLE_FRAGMENT */;
11109 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
11110 // check if the fragment actually contains a single valid child with
11111 // the rest being comments
11112 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
11113 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
11114 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
11115 }
11116 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true);
11117 }
11118 else ;
11119 }
11120 function traverseChildren(parent, context) {
11121 let i = 0;
11122 const nodeRemoved = () => {
11123 i--;
11124 };
11125 for (; i < parent.children.length; i++) {
11126 const child = parent.children[i];
11127 if (isString(child))
11128 continue;
11129 context.parent = parent;
11130 context.childIndex = i;
11131 context.onNodeRemoved = nodeRemoved;
11132 traverseNode(child, context);
11133 }
11134 }
11135 function traverseNode(node, context) {
11136 context.currentNode = node;
11137 // apply transform plugins
11138 const { nodeTransforms } = context;
11139 const exitFns = [];
11140 for (let i = 0; i < nodeTransforms.length; i++) {
11141 const onExit = nodeTransforms[i](node, context);
11142 if (onExit) {
11143 if (isArray(onExit)) {
11144 exitFns.push(...onExit);
11145 }
11146 else {
11147 exitFns.push(onExit);
11148 }
11149 }
11150 if (!context.currentNode) {
11151 // node was removed
11152 return;
11153 }
11154 else {
11155 // node may have been replaced
11156 node = context.currentNode;
11157 }
11158 }
11159 switch (node.type) {
11160 case 3 /* COMMENT */:
11161 if (!context.ssr) {
11162 // inject import for the Comment symbol, which is needed for creating
11163 // comment nodes with `createVNode`
11164 context.helper(CREATE_COMMENT);
11165 }
11166 break;
11167 case 5 /* INTERPOLATION */:
11168 // no need to traverse, but we need to inject toString helper
11169 if (!context.ssr) {
11170 context.helper(TO_DISPLAY_STRING);
11171 }
11172 break;
11173 // for container types, further traverse downwards
11174 case 9 /* IF */:
11175 for (let i = 0; i < node.branches.length; i++) {
11176 traverseNode(node.branches[i], context);
11177 }
11178 break;
11179 case 10 /* IF_BRANCH */:
11180 case 11 /* FOR */:
11181 case 1 /* ELEMENT */:
11182 case 0 /* ROOT */:
11183 traverseChildren(node, context);
11184 break;
11185 }
11186 // exit transforms
11187 context.currentNode = node;
11188 let i = exitFns.length;
11189 while (i--) {
11190 exitFns[i]();
11191 }
11192 }
11193 function createStructuralDirectiveTransform(name, fn) {
11194 const matches = isString(name)
11195 ? (n) => n === name
11196 : (n) => name.test(n);
11197 return (node, context) => {
11198 if (node.type === 1 /* ELEMENT */) {
11199 const { props } = node;
11200 // structural directive transforms are not concerned with slots
11201 // as they are handled separately in vSlot.ts
11202 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
11203 return;
11204 }
11205 const exitFns = [];
11206 for (let i = 0; i < props.length; i++) {
11207 const prop = props[i];
11208 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
11209 // structural directives are removed to avoid infinite recursion
11210 // also we remove them *before* applying so that it can further
11211 // traverse itself in case it moves the node around
11212 props.splice(i, 1);
11213 i--;
11214 const onExit = fn(node, prop, context);
11215 if (onExit)
11216 exitFns.push(onExit);
11217 }
11218 }
11219 return exitFns;
11220 }
11221 };
11222 }
11223
11224 const PURE_ANNOTATION = `/*#__PURE__*/`;
11225 function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
11226 const context = {
11227 mode,
11228 prefixIdentifiers,
11229 sourceMap,
11230 filename,
11231 scopeId,
11232 optimizeImports,
11233 runtimeGlobalName,
11234 runtimeModuleName,
11235 ssr,
11236 source: ast.loc.source,
11237 code: ``,
11238 column: 1,
11239 line: 1,
11240 offset: 0,
11241 indentLevel: 0,
11242 pure: false,
11243 map: undefined,
11244 helper(key) {
11245 return `_${helperNameMap[key]}`;
11246 },
11247 push(code, node) {
11248 context.code += code;
11249 },
11250 indent() {
11251 newline(++context.indentLevel);
11252 },
11253 deindent(withoutNewLine = false) {
11254 if (withoutNewLine) {
11255 --context.indentLevel;
11256 }
11257 else {
11258 newline(--context.indentLevel);
11259 }
11260 },
11261 newline() {
11262 newline(context.indentLevel);
11263 }
11264 };
11265 function newline(n) {
11266 context.push('\n' + ` `.repeat(n));
11267 }
11268 return context;
11269 }
11270 function generate(ast, options = {}) {
11271 const context = createCodegenContext(ast, options);
11272 if (options.onContextCreated)
11273 options.onContextCreated(context);
11274 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
11275 const hasHelpers = ast.helpers.length > 0;
11276 const useWithBlock = !prefixIdentifiers && mode !== 'module';
11277 // preambles
11278 // in setup() inline mode, the preamble is generated in a sub context
11279 // and returned separately.
11280 const preambleContext = context;
11281 {
11282 genFunctionPreamble(ast, preambleContext);
11283 }
11284 // enter render function
11285 const functionName = ssr ? `ssrRender` : `render`;
11286 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
11287 const signature = args.join(', ');
11288 {
11289 push(`function ${functionName}(${signature}) {`);
11290 }
11291 indent();
11292 if (useWithBlock) {
11293 push(`with (_ctx) {`);
11294 indent();
11295 // function mode const declarations should be inside with block
11296 // also they should be renamed to avoid collision with user properties
11297 if (hasHelpers) {
11298 push(`const { ${ast.helpers
11299 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
11300 .join(', ')} } = _Vue`);
11301 push(`\n`);
11302 newline();
11303 }
11304 }
11305 // generate asset resolution statements
11306 if (ast.components.length) {
11307 genAssets(ast.components, 'component', context);
11308 if (ast.directives.length || ast.temps > 0) {
11309 newline();
11310 }
11311 }
11312 if (ast.directives.length) {
11313 genAssets(ast.directives, 'directive', context);
11314 if (ast.temps > 0) {
11315 newline();
11316 }
11317 }
11318 if (ast.temps > 0) {
11319 push(`let `);
11320 for (let i = 0; i < ast.temps; i++) {
11321 push(`${i > 0 ? `, ` : ``}_temp${i}`);
11322 }
11323 }
11324 if (ast.components.length || ast.directives.length || ast.temps) {
11325 push(`\n`);
11326 newline();
11327 }
11328 // generate the VNode tree expression
11329 if (!ssr) {
11330 push(`return `);
11331 }
11332 if (ast.codegenNode) {
11333 genNode(ast.codegenNode, context);
11334 }
11335 else {
11336 push(`null`);
11337 }
11338 if (useWithBlock) {
11339 deindent();
11340 push(`}`);
11341 }
11342 deindent();
11343 push(`}`);
11344 return {
11345 ast,
11346 code: context.code,
11347 preamble: ``,
11348 // SourceMapGenerator does have toJSON() method but it's not in the types
11349 map: context.map ? context.map.toJSON() : undefined
11350 };
11351 }
11352 function genFunctionPreamble(ast, context) {
11353 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;
11354 const VueBinding = runtimeGlobalName;
11355 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
11356 // Generate const declaration for helpers
11357 // In prefix mode, we place the const declaration at top so it's done
11358 // only once; But if we not prefixing, we place the declaration inside the
11359 // with block so it doesn't incur the `in` check cost for every helper access.
11360 if (ast.helpers.length > 0) {
11361 {
11362 // "with" mode.
11363 // save Vue in a separate variable to avoid collision
11364 push(`const _Vue = ${VueBinding}\n`);
11365 // in "with" mode, helpers are declared inside the with block to avoid
11366 // has check cost, but hoists are lifted out of the function - we need
11367 // to provide the helper here.
11368 if (ast.hoists.length) {
11369 const staticHelpers = [
11370 CREATE_VNODE,
11371 CREATE_COMMENT,
11372 CREATE_TEXT,
11373 CREATE_STATIC
11374 ]
11375 .filter(helper => ast.helpers.includes(helper))
11376 .map(aliasHelper)
11377 .join(', ');
11378 push(`const { ${staticHelpers} } = _Vue\n`);
11379 }
11380 }
11381 }
11382 genHoists(ast.hoists, context);
11383 newline();
11384 push(`return `);
11385 }
11386 function genAssets(assets, type, { helper, push, newline }) {
11387 const resolver = helper(type === 'component' ? RESOLVE_COMPONENT : RESOLVE_DIRECTIVE);
11388 for (let i = 0; i < assets.length; i++) {
11389 let id = assets[i];
11390 // potential component implicit self-reference inferred from SFC filename
11391 const maybeSelfReference = id.endsWith('__self');
11392 if (maybeSelfReference) {
11393 id = id.slice(0, -6);
11394 }
11395 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})`);
11396 if (i < assets.length - 1) {
11397 newline();
11398 }
11399 }
11400 }
11401 function genHoists(hoists, context) {
11402 if (!hoists.length) {
11403 return;
11404 }
11405 context.pure = true;
11406 const { push, newline, helper, scopeId, mode } = context;
11407 newline();
11408 hoists.forEach((exp, i) => {
11409 if (exp) {
11410 push(`const _hoisted_${i + 1} = `);
11411 genNode(exp, context);
11412 newline();
11413 }
11414 });
11415 context.pure = false;
11416 }
11417 function isText$1(n) {
11418 return (isString(n) ||
11419 n.type === 4 /* SIMPLE_EXPRESSION */ ||
11420 n.type === 2 /* TEXT */ ||
11421 n.type === 5 /* INTERPOLATION */ ||
11422 n.type === 8 /* COMPOUND_EXPRESSION */);
11423 }
11424 function genNodeListAsArray(nodes, context) {
11425 const multilines = nodes.length > 3 ||
11426 (nodes.some(n => isArray(n) || !isText$1(n)));
11427 context.push(`[`);
11428 multilines && context.indent();
11429 genNodeList(nodes, context, multilines);
11430 multilines && context.deindent();
11431 context.push(`]`);
11432 }
11433 function genNodeList(nodes, context, multilines = false, comma = true) {
11434 const { push, newline } = context;
11435 for (let i = 0; i < nodes.length; i++) {
11436 const node = nodes[i];
11437 if (isString(node)) {
11438 push(node);
11439 }
11440 else if (isArray(node)) {
11441 genNodeListAsArray(node, context);
11442 }
11443 else {
11444 genNode(node, context);
11445 }
11446 if (i < nodes.length - 1) {
11447 if (multilines) {
11448 comma && push(',');
11449 newline();
11450 }
11451 else {
11452 comma && push(', ');
11453 }
11454 }
11455 }
11456 }
11457 function genNode(node, context) {
11458 if (isString(node)) {
11459 context.push(node);
11460 return;
11461 }
11462 if (isSymbol(node)) {
11463 context.push(context.helper(node));
11464 return;
11465 }
11466 switch (node.type) {
11467 case 1 /* ELEMENT */:
11468 case 9 /* IF */:
11469 case 11 /* FOR */:
11470 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
11471 `Apply appropriate transforms first.`);
11472 genNode(node.codegenNode, context);
11473 break;
11474 case 2 /* TEXT */:
11475 genText(node, context);
11476 break;
11477 case 4 /* SIMPLE_EXPRESSION */:
11478 genExpression(node, context);
11479 break;
11480 case 5 /* INTERPOLATION */:
11481 genInterpolation(node, context);
11482 break;
11483 case 12 /* TEXT_CALL */:
11484 genNode(node.codegenNode, context);
11485 break;
11486 case 8 /* COMPOUND_EXPRESSION */:
11487 genCompoundExpression(node, context);
11488 break;
11489 case 3 /* COMMENT */:
11490 genComment(node, context);
11491 break;
11492 case 13 /* VNODE_CALL */:
11493 genVNodeCall(node, context);
11494 break;
11495 case 14 /* JS_CALL_EXPRESSION */:
11496 genCallExpression(node, context);
11497 break;
11498 case 15 /* JS_OBJECT_EXPRESSION */:
11499 genObjectExpression(node, context);
11500 break;
11501 case 17 /* JS_ARRAY_EXPRESSION */:
11502 genArrayExpression(node, context);
11503 break;
11504 case 18 /* JS_FUNCTION_EXPRESSION */:
11505 genFunctionExpression(node, context);
11506 break;
11507 case 19 /* JS_CONDITIONAL_EXPRESSION */:
11508 genConditionalExpression(node, context);
11509 break;
11510 case 20 /* JS_CACHE_EXPRESSION */:
11511 genCacheExpression(node, context);
11512 break;
11513 // SSR only types
11514 case 21 /* JS_BLOCK_STATEMENT */:
11515 break;
11516 case 22 /* JS_TEMPLATE_LITERAL */:
11517 break;
11518 case 23 /* JS_IF_STATEMENT */:
11519 break;
11520 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
11521 break;
11522 case 25 /* JS_SEQUENCE_EXPRESSION */:
11523 break;
11524 case 26 /* JS_RETURN_STATEMENT */:
11525 break;
11526 /* istanbul ignore next */
11527 case 10 /* IF_BRANCH */:
11528 // noop
11529 break;
11530 default:
11531 {
11532 assert(false, `unhandled codegen node type: ${node.type}`);
11533 // make sure we exhaust all possible types
11534 const exhaustiveCheck = node;
11535 return exhaustiveCheck;
11536 }
11537 }
11538 }
11539 function genText(node, context) {
11540 context.push(JSON.stringify(node.content), node);
11541 }
11542 function genExpression(node, context) {
11543 const { content, isStatic } = node;
11544 context.push(isStatic ? JSON.stringify(content) : content, node);
11545 }
11546 function genInterpolation(node, context) {
11547 const { push, helper, pure } = context;
11548 if (pure)
11549 push(PURE_ANNOTATION);
11550 push(`${helper(TO_DISPLAY_STRING)}(`);
11551 genNode(node.content, context);
11552 push(`)`);
11553 }
11554 function genCompoundExpression(node, context) {
11555 for (let i = 0; i < node.children.length; i++) {
11556 const child = node.children[i];
11557 if (isString(child)) {
11558 context.push(child);
11559 }
11560 else {
11561 genNode(child, context);
11562 }
11563 }
11564 }
11565 function genExpressionAsPropertyKey(node, context) {
11566 const { push } = context;
11567 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
11568 push(`[`);
11569 genCompoundExpression(node, context);
11570 push(`]`);
11571 }
11572 else if (node.isStatic) {
11573 // only quote keys if necessary
11574 const text = isSimpleIdentifier(node.content)
11575 ? node.content
11576 : JSON.stringify(node.content);
11577 push(text, node);
11578 }
11579 else {
11580 push(`[${node.content}]`, node);
11581 }
11582 }
11583 function genComment(node, context) {
11584 {
11585 const { push, helper, pure } = context;
11586 if (pure) {
11587 push(PURE_ANNOTATION);
11588 }
11589 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
11590 }
11591 }
11592 function genVNodeCall(node, context) {
11593 const { push, helper, pure } = context;
11594 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;
11595 if (directives) {
11596 push(helper(WITH_DIRECTIVES) + `(`);
11597 }
11598 if (isBlock) {
11599 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
11600 }
11601 if (pure) {
11602 push(PURE_ANNOTATION);
11603 }
11604 push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);
11605 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
11606 push(`)`);
11607 if (isBlock) {
11608 push(`)`);
11609 }
11610 if (directives) {
11611 push(`, `);
11612 genNode(directives, context);
11613 push(`)`);
11614 }
11615 }
11616 function genNullableArgs(args) {
11617 let i = args.length;
11618 while (i--) {
11619 if (args[i] != null)
11620 break;
11621 }
11622 return args.slice(0, i + 1).map(arg => arg || `null`);
11623 }
11624 // JavaScript
11625 function genCallExpression(node, context) {
11626 const { push, helper, pure } = context;
11627 const callee = isString(node.callee) ? node.callee : helper(node.callee);
11628 if (pure) {
11629 push(PURE_ANNOTATION);
11630 }
11631 push(callee + `(`, node);
11632 genNodeList(node.arguments, context);
11633 push(`)`);
11634 }
11635 function genObjectExpression(node, context) {
11636 const { push, indent, deindent, newline } = context;
11637 const { properties } = node;
11638 if (!properties.length) {
11639 push(`{}`, node);
11640 return;
11641 }
11642 const multilines = properties.length > 1 ||
11643 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
11644 push(multilines ? `{` : `{ `);
11645 multilines && indent();
11646 for (let i = 0; i < properties.length; i++) {
11647 const { key, value } = properties[i];
11648 // key
11649 genExpressionAsPropertyKey(key, context);
11650 push(`: `);
11651 // value
11652 genNode(value, context);
11653 if (i < properties.length - 1) {
11654 // will only reach this if it's multilines
11655 push(`,`);
11656 newline();
11657 }
11658 }
11659 multilines && deindent();
11660 push(multilines ? `}` : ` }`);
11661 }
11662 function genArrayExpression(node, context) {
11663 genNodeListAsArray(node.elements, context);
11664 }
11665 function genFunctionExpression(node, context) {
11666 const { push, indent, deindent, scopeId, mode } = context;
11667 const { params, returns, body, newline, isSlot } = node;
11668 if (isSlot) {
11669 // wrap slot functions with owner context
11670 push(`_${helperNameMap[WITH_CTX]}(`);
11671 }
11672 push(`(`, node);
11673 if (isArray(params)) {
11674 genNodeList(params, context);
11675 }
11676 else if (params) {
11677 genNode(params, context);
11678 }
11679 push(`) => `);
11680 if (newline || body) {
11681 push(`{`);
11682 indent();
11683 }
11684 if (returns) {
11685 if (newline) {
11686 push(`return `);
11687 }
11688 if (isArray(returns)) {
11689 genNodeListAsArray(returns, context);
11690 }
11691 else {
11692 genNode(returns, context);
11693 }
11694 }
11695 else if (body) {
11696 genNode(body, context);
11697 }
11698 if (newline || body) {
11699 deindent();
11700 push(`}`);
11701 }
11702 if (isSlot) {
11703 push(`)`);
11704 }
11705 }
11706 function genConditionalExpression(node, context) {
11707 const { test, consequent, alternate, newline: needNewline } = node;
11708 const { push, indent, deindent, newline } = context;
11709 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
11710 const needsParens = !isSimpleIdentifier(test.content);
11711 needsParens && push(`(`);
11712 genExpression(test, context);
11713 needsParens && push(`)`);
11714 }
11715 else {
11716 push(`(`);
11717 genNode(test, context);
11718 push(`)`);
11719 }
11720 needNewline && indent();
11721 context.indentLevel++;
11722 needNewline || push(` `);
11723 push(`? `);
11724 genNode(consequent, context);
11725 context.indentLevel--;
11726 needNewline && newline();
11727 needNewline || push(` `);
11728 push(`: `);
11729 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
11730 if (!isNested) {
11731 context.indentLevel++;
11732 }
11733 genNode(alternate, context);
11734 if (!isNested) {
11735 context.indentLevel--;
11736 }
11737 needNewline && deindent(true /* without newline */);
11738 }
11739 function genCacheExpression(node, context) {
11740 const { push, helper, indent, deindent, newline } = context;
11741 push(`_cache[${node.index}] || (`);
11742 if (node.isVNode) {
11743 indent();
11744 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
11745 newline();
11746 }
11747 push(`_cache[${node.index}] = `);
11748 genNode(node.value, context);
11749 if (node.isVNode) {
11750 push(`,`);
11751 newline();
11752 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
11753 newline();
11754 push(`_cache[${node.index}]`);
11755 deindent();
11756 }
11757 push(`)`);
11758 }
11759
11760 // these keywords should not appear inside expressions, but operators like
11761 // typeof, instanceof and in are allowed
11762 const prohibitedKeywordRE = new RegExp('\\b' +
11763 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
11764 'super,throw,while,yield,delete,export,import,return,switch,default,' +
11765 'extends,finally,continue,debugger,function,arguments,typeof,void')
11766 .split(',')
11767 .join('\\b|\\b') +
11768 '\\b');
11769 // strip strings in expressions
11770 const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
11771 /**
11772 * Validate a non-prefixed expression.
11773 * This is only called when using the in-browser runtime compiler since it
11774 * doesn't prefix expressions.
11775 */
11776 function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
11777 const exp = node.content;
11778 // empty expressions are validated per-directive since some directives
11779 // do allow empty expressions.
11780 if (!exp.trim()) {
11781 return;
11782 }
11783 try {
11784 new Function(asRawStatements
11785 ? ` ${exp} `
11786 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
11787 }
11788 catch (e) {
11789 let message = e.message;
11790 const keywordMatch = exp
11791 .replace(stripStringRE, '')
11792 .match(prohibitedKeywordRE);
11793 if (keywordMatch) {
11794 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
11795 }
11796 context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
11797 }
11798 }
11799
11800 const transformExpression = (node, context) => {
11801 if (node.type === 5 /* INTERPOLATION */) {
11802 node.content = processExpression(node.content, context);
11803 }
11804 else if (node.type === 1 /* ELEMENT */) {
11805 // handle directives on element
11806 for (let i = 0; i < node.props.length; i++) {
11807 const dir = node.props[i];
11808 // do not process for v-on & v-for since they are special handled
11809 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
11810 const exp = dir.exp;
11811 const arg = dir.arg;
11812 // do not process exp if this is v-on:arg - we need special handling
11813 // for wrapping inline statements.
11814 if (exp &&
11815 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
11816 !(dir.name === 'on' && arg)) {
11817 dir.exp = processExpression(exp, context,
11818 // slot args must be processed as function params
11819 dir.name === 'slot');
11820 }
11821 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
11822 dir.arg = processExpression(arg, context);
11823 }
11824 }
11825 }
11826 }
11827 };
11828 // Important: since this function uses Node.js only dependencies, it should
11829 // always be used with a leading !true check so that it can be
11830 // tree-shaken from the browser build.
11831 function processExpression(node, context,
11832 // some expressions like v-slot props & v-for aliases should be parsed as
11833 // function params
11834 asParams = false,
11835 // v-on handler values may contain multiple statements
11836 asRawStatements = false) {
11837 {
11838 {
11839 // simple in-browser validation (same logic in 2.x)
11840 validateBrowserExpression(node, context, asParams, asRawStatements);
11841 }
11842 return node;
11843 }
11844 }
11845
11846 const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
11847 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
11848 // #1587: We need to dynamically increment the key based on the current
11849 // node's sibling nodes, since chained v-if/else branches are
11850 // rendered at the same depth
11851 const siblings = context.parent.children;
11852 let i = siblings.indexOf(ifNode);
11853 let key = 0;
11854 while (i-- >= 0) {
11855 const sibling = siblings[i];
11856 if (sibling && sibling.type === 9 /* IF */) {
11857 key += sibling.branches.length;
11858 }
11859 }
11860 // Exit callback. Complete the codegenNode when all children have been
11861 // transformed.
11862 return () => {
11863 if (isRoot) {
11864 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
11865 }
11866 else {
11867 // attach this branch's codegen node to the v-if root.
11868 const parentCondition = getParentCondition(ifNode.codegenNode);
11869 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
11870 }
11871 };
11872 });
11873 });
11874 // target-agnostic transform used for both Client and SSR
11875 function processIf(node, dir, context, processCodegen) {
11876 if (dir.name !== 'else' &&
11877 (!dir.exp || !dir.exp.content.trim())) {
11878 const loc = dir.exp ? dir.exp.loc : node.loc;
11879 context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));
11880 dir.exp = createSimpleExpression(`true`, false, loc);
11881 }
11882 if (dir.exp) {
11883 validateBrowserExpression(dir.exp, context);
11884 }
11885 if (dir.name === 'if') {
11886 const branch = createIfBranch(node, dir);
11887 const ifNode = {
11888 type: 9 /* IF */,
11889 loc: node.loc,
11890 branches: [branch]
11891 };
11892 context.replaceNode(ifNode);
11893 if (processCodegen) {
11894 return processCodegen(ifNode, branch, true);
11895 }
11896 }
11897 else {
11898 // locate the adjacent v-if
11899 const siblings = context.parent.children;
11900 const comments = [];
11901 let i = siblings.indexOf(node);
11902 while (i-- >= -1) {
11903 const sibling = siblings[i];
11904 if (sibling && sibling.type === 3 /* COMMENT */) {
11905 context.removeNode(sibling);
11906 comments.unshift(sibling);
11907 continue;
11908 }
11909 if (sibling &&
11910 sibling.type === 2 /* TEXT */ &&
11911 !sibling.content.trim().length) {
11912 context.removeNode(sibling);
11913 continue;
11914 }
11915 if (sibling && sibling.type === 9 /* IF */) {
11916 // move the node to the if node's branches
11917 context.removeNode();
11918 const branch = createIfBranch(node, dir);
11919 if (comments.length) {
11920 branch.children = [...comments, ...branch.children];
11921 }
11922 // check if user is forcing same key on different branches
11923 {
11924 const key = branch.userKey;
11925 if (key) {
11926 sibling.branches.forEach(({ userKey }) => {
11927 if (isSameKey(userKey, key)) {
11928 context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
11929 }
11930 });
11931 }
11932 }
11933 sibling.branches.push(branch);
11934 const onExit = processCodegen && processCodegen(sibling, branch, false);
11935 // since the branch was removed, it will not be traversed.
11936 // make sure to traverse here.
11937 traverseNode(branch, context);
11938 // call on exit
11939 if (onExit)
11940 onExit();
11941 // make sure to reset currentNode after traversal to indicate this
11942 // node has been removed.
11943 context.currentNode = null;
11944 }
11945 else {
11946 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
11947 }
11948 break;
11949 }
11950 }
11951 }
11952 function createIfBranch(node, dir) {
11953 return {
11954 type: 10 /* IF_BRANCH */,
11955 loc: node.loc,
11956 condition: dir.name === 'else' ? undefined : dir.exp,
11957 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
11958 ? node.children
11959 : [node],
11960 userKey: findProp(node, `key`)
11961 };
11962 }
11963 function createCodegenNodeForBranch(branch, keyIndex, context) {
11964 if (branch.condition) {
11965 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
11966 // make sure to pass in asBlock: true so that the comment node call
11967 // closes the current block.
11968 createCallExpression(context.helper(CREATE_COMMENT), [
11969 '"v-if"' ,
11970 'true'
11971 ]));
11972 }
11973 else {
11974 return createChildrenCodegenNode(branch, keyIndex, context);
11975 }
11976 }
11977 function createChildrenCodegenNode(branch, keyIndex, context) {
11978 const { helper, removeHelper } = context;
11979 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
11980 const { children } = branch;
11981 const firstChild = children[0];
11982 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
11983 if (needFragmentWrapper) {
11984 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
11985 // optimize away nested fragments when child is a ForNode
11986 const vnodeCall = firstChild.codegenNode;
11987 injectProp(vnodeCall, keyProperty, context);
11988 return vnodeCall;
11989 }
11990 else {
11991 let patchFlag = 64 /* STABLE_FRAGMENT */;
11992 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
11993 // check if the fragment actually contains a single valid child with
11994 // the rest being comments
11995 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
11996 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
11997 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
11998 }
11999 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, branch.loc);
12000 }
12001 }
12002 else {
12003 const vnodeCall = firstChild
12004 .codegenNode;
12005 // Change createVNode to createBlock.
12006 if (vnodeCall.type === 13 /* VNODE_CALL */ && !vnodeCall.isBlock) {
12007 removeHelper(CREATE_VNODE);
12008 vnodeCall.isBlock = true;
12009 helper(OPEN_BLOCK);
12010 helper(CREATE_BLOCK);
12011 }
12012 // inject branch key
12013 injectProp(vnodeCall, keyProperty, context);
12014 return vnodeCall;
12015 }
12016 }
12017 function isSameKey(a, b) {
12018 if (!a || a.type !== b.type) {
12019 return false;
12020 }
12021 if (a.type === 6 /* ATTRIBUTE */) {
12022 if (a.value.content !== b.value.content) {
12023 return false;
12024 }
12025 }
12026 else {
12027 // directive
12028 const exp = a.exp;
12029 const branchExp = b.exp;
12030 if (exp.type !== branchExp.type) {
12031 return false;
12032 }
12033 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
12034 (exp.isStatic !== branchExp.isStatic ||
12035 exp.content !== branchExp.content)) {
12036 return false;
12037 }
12038 }
12039 return true;
12040 }
12041 function getParentCondition(node) {
12042 while (true) {
12043 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12044 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12045 node = node.alternate;
12046 }
12047 else {
12048 return node;
12049 }
12050 }
12051 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
12052 node = node.value;
12053 }
12054 }
12055 }
12056
12057 const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
12058 const { helper, removeHelper } = context;
12059 return processFor(node, dir, context, forNode => {
12060 // create the loop render function expression now, and add the
12061 // iterator on exit after all children have been traversed
12062 const renderExp = createCallExpression(helper(RENDER_LIST), [
12063 forNode.source
12064 ]);
12065 const keyProp = findProp(node, `key`);
12066 const keyProperty = keyProp
12067 ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */
12068 ? createSimpleExpression(keyProp.value.content, true)
12069 : keyProp.exp)
12070 : null;
12071 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
12072 forNode.source.constType > 0 /* NOT_CONSTANT */;
12073 const fragmentFlag = isStableFragment
12074 ? 64 /* STABLE_FRAGMENT */
12075 : keyProp
12076 ? 128 /* KEYED_FRAGMENT */
12077 : 256 /* UNKEYED_FRAGMENT */;
12078 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
12079 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);
12080 return () => {
12081 // finish the codegen now that all children have been traversed
12082 let childBlock;
12083 const isTemplate = isTemplateNode(node);
12084 const { children } = forNode;
12085 // check <template v-for> key placement
12086 if (isTemplate) {
12087 node.children.some(c => {
12088 if (c.type === 1 /* ELEMENT */) {
12089 const key = findProp(c, 'key');
12090 if (key) {
12091 context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
12092 return true;
12093 }
12094 }
12095 });
12096 }
12097 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
12098 const slotOutlet = isSlotOutlet(node)
12099 ? node
12100 : isTemplate &&
12101 node.children.length === 1 &&
12102 isSlotOutlet(node.children[0])
12103 ? node.children[0] // api-extractor somehow fails to infer this
12104 : null;
12105 if (slotOutlet) {
12106 // <slot v-for="..."> or <template v-for="..."><slot/></template>
12107 childBlock = slotOutlet.codegenNode;
12108 if (isTemplate && keyProperty) {
12109 // <template v-for="..." :key="..."><slot/></template>
12110 // we need to inject the key to the renderSlot() call.
12111 // the props for renderSlot is passed as the 3rd argument.
12112 injectProp(childBlock, keyProperty, context);
12113 }
12114 }
12115 else if (needFragmentWrapper) {
12116 // <template v-for="..."> with text or multi-elements
12117 // should generate a fragment block for each loop
12118 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
12119 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
12120 ), undefined, undefined, true);
12121 }
12122 else {
12123 // Normal element v-for. Directly use the child's codegenNode
12124 // but mark it as a block.
12125 childBlock = children[0]
12126 .codegenNode;
12127 if (isTemplate && keyProperty) {
12128 injectProp(childBlock, keyProperty, context);
12129 }
12130 if (childBlock.isBlock !== !isStableFragment) {
12131 if (childBlock.isBlock) {
12132 // switch from block to vnode
12133 removeHelper(OPEN_BLOCK);
12134 removeHelper(CREATE_BLOCK);
12135 }
12136 else {
12137 // switch from vnode to block
12138 removeHelper(CREATE_VNODE);
12139 }
12140 }
12141 childBlock.isBlock = !isStableFragment;
12142 if (childBlock.isBlock) {
12143 helper(OPEN_BLOCK);
12144 helper(CREATE_BLOCK);
12145 }
12146 else {
12147 helper(CREATE_VNODE);
12148 }
12149 }
12150 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
12151 };
12152 });
12153 });
12154 // target-agnostic transform used for both Client and SSR
12155 function processFor(node, dir, context, processCodegen) {
12156 if (!dir.exp) {
12157 context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
12158 return;
12159 }
12160 const parseResult = parseForExpression(
12161 // can only be simple expression because vFor transform is applied
12162 // before expression transform.
12163 dir.exp, context);
12164 if (!parseResult) {
12165 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
12166 return;
12167 }
12168 const { addIdentifiers, removeIdentifiers, scopes } = context;
12169 const { source, value, key, index } = parseResult;
12170 const forNode = {
12171 type: 11 /* FOR */,
12172 loc: dir.loc,
12173 source,
12174 valueAlias: value,
12175 keyAlias: key,
12176 objectIndexAlias: index,
12177 parseResult,
12178 children: isTemplateNode(node) ? node.children : [node]
12179 };
12180 context.replaceNode(forNode);
12181 // bookkeeping
12182 scopes.vFor++;
12183 const onExit = processCodegen && processCodegen(forNode);
12184 return () => {
12185 scopes.vFor--;
12186 if (onExit)
12187 onExit();
12188 };
12189 }
12190 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
12191 // This regex doesn't cover the case if key or index aliases have destructuring,
12192 // but those do not make sense in the first place, so this works in practice.
12193 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
12194 const stripParensRE = /^\(|\)$/g;
12195 function parseForExpression(input, context) {
12196 const loc = input.loc;
12197 const exp = input.content;
12198 const inMatch = exp.match(forAliasRE);
12199 if (!inMatch)
12200 return;
12201 const [, LHS, RHS] = inMatch;
12202 const result = {
12203 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
12204 value: undefined,
12205 key: undefined,
12206 index: undefined
12207 };
12208 {
12209 validateBrowserExpression(result.source, context);
12210 }
12211 let valueContent = LHS.trim()
12212 .replace(stripParensRE, '')
12213 .trim();
12214 const trimmedOffset = LHS.indexOf(valueContent);
12215 const iteratorMatch = valueContent.match(forIteratorRE);
12216 if (iteratorMatch) {
12217 valueContent = valueContent.replace(forIteratorRE, '').trim();
12218 const keyContent = iteratorMatch[1].trim();
12219 let keyOffset;
12220 if (keyContent) {
12221 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
12222 result.key = createAliasExpression(loc, keyContent, keyOffset);
12223 {
12224 validateBrowserExpression(result.key, context, true);
12225 }
12226 }
12227 if (iteratorMatch[2]) {
12228 const indexContent = iteratorMatch[2].trim();
12229 if (indexContent) {
12230 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
12231 ? keyOffset + keyContent.length
12232 : trimmedOffset + valueContent.length));
12233 {
12234 validateBrowserExpression(result.index, context, true);
12235 }
12236 }
12237 }
12238 }
12239 if (valueContent) {
12240 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
12241 {
12242 validateBrowserExpression(result.value, context, true);
12243 }
12244 }
12245 return result;
12246 }
12247 function createAliasExpression(range, content, offset) {
12248 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
12249 }
12250 function createForLoopParams({ value, key, index }) {
12251 const params = [];
12252 if (value) {
12253 params.push(value);
12254 }
12255 if (key) {
12256 if (!value) {
12257 params.push(createSimpleExpression(`_`, false));
12258 }
12259 params.push(key);
12260 }
12261 if (index) {
12262 if (!key) {
12263 if (!value) {
12264 params.push(createSimpleExpression(`_`, false));
12265 }
12266 params.push(createSimpleExpression(`__`, false));
12267 }
12268 params.push(index);
12269 }
12270 return params;
12271 }
12272
12273 const defaultFallback = createSimpleExpression(`undefined`, false);
12274 // A NodeTransform that:
12275 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
12276 // by transformExpression. This is only applied in non-browser builds with
12277 // { prefixIdentifiers: true }.
12278 // 2. Track v-slot depths so that we know a slot is inside another slot.
12279 // Note the exit callback is executed before buildSlots() on the same node,
12280 // so only nested slots see positive numbers.
12281 const trackSlotScopes = (node, context) => {
12282 if (node.type === 1 /* ELEMENT */ &&
12283 (node.tagType === 1 /* COMPONENT */ ||
12284 node.tagType === 3 /* TEMPLATE */)) {
12285 // We are only checking non-empty v-slot here
12286 // since we only care about slots that introduce scope variables.
12287 const vSlot = findDir(node, 'slot');
12288 if (vSlot) {
12289 vSlot.exp;
12290 context.scopes.vSlot++;
12291 return () => {
12292 context.scopes.vSlot--;
12293 };
12294 }
12295 }
12296 };
12297 const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
12298 // Instead of being a DirectiveTransform, v-slot processing is called during
12299 // transformElement to build the slots object for a component.
12300 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
12301 context.helper(WITH_CTX);
12302 const { children, loc } = node;
12303 const slotsProperties = [];
12304 const dynamicSlots = [];
12305 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));
12306 // If the slot is inside a v-for or another v-slot, force it to be dynamic
12307 // since it likely uses a scope variable.
12308 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
12309 // 1. Check for slot with slotProps on component itself.
12310 // <Comp v-slot="{ prop }"/>
12311 const onComponentSlot = findDir(node, 'slot', true);
12312 if (onComponentSlot) {
12313 const { arg, exp } = onComponentSlot;
12314 if (arg && !isStaticExp(arg)) {
12315 hasDynamicSlots = true;
12316 }
12317 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
12318 }
12319 // 2. Iterate through children and check for template slots
12320 // <template v-slot:foo="{ prop }">
12321 let hasTemplateSlots = false;
12322 let hasNamedDefaultSlot = false;
12323 const implicitDefaultChildren = [];
12324 const seenSlotNames = new Set();
12325 for (let i = 0; i < children.length; i++) {
12326 const slotElement = children[i];
12327 let slotDir;
12328 if (!isTemplateNode(slotElement) ||
12329 !(slotDir = findDir(slotElement, 'slot', true))) {
12330 // not a <template v-slot>, skip.
12331 if (slotElement.type !== 3 /* COMMENT */) {
12332 implicitDefaultChildren.push(slotElement);
12333 }
12334 continue;
12335 }
12336 if (onComponentSlot) {
12337 // already has on-component slot - this is incorrect usage.
12338 context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
12339 break;
12340 }
12341 hasTemplateSlots = true;
12342 const { children: slotChildren, loc: slotLoc } = slotElement;
12343 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
12344 // check if name is dynamic.
12345 let staticSlotName;
12346 if (isStaticExp(slotName)) {
12347 staticSlotName = slotName ? slotName.content : `default`;
12348 }
12349 else {
12350 hasDynamicSlots = true;
12351 }
12352 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
12353 // check if this slot is conditional (v-if/v-for)
12354 let vIf;
12355 let vElse;
12356 let vFor;
12357 if ((vIf = findDir(slotElement, 'if'))) {
12358 hasDynamicSlots = true;
12359 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
12360 }
12361 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
12362 // find adjacent v-if
12363 let j = i;
12364 let prev;
12365 while (j--) {
12366 prev = children[j];
12367 if (prev.type !== 3 /* COMMENT */) {
12368 break;
12369 }
12370 }
12371 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
12372 // remove node
12373 children.splice(i, 1);
12374 i--;
12375 // attach this slot to previous conditional
12376 let conditional = dynamicSlots[dynamicSlots.length - 1];
12377 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12378 conditional = conditional.alternate;
12379 }
12380 conditional.alternate = vElse.exp
12381 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
12382 : buildDynamicSlot(slotName, slotFunction);
12383 }
12384 else {
12385 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
12386 }
12387 }
12388 else if ((vFor = findDir(slotElement, 'for'))) {
12389 hasDynamicSlots = true;
12390 const parseResult = vFor.parseResult ||
12391 parseForExpression(vFor.exp, context);
12392 if (parseResult) {
12393 // Render the dynamic slots as an array and add it to the createSlot()
12394 // args. The runtime knows how to handle it appropriately.
12395 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
12396 parseResult.source,
12397 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
12398 ]));
12399 }
12400 else {
12401 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
12402 }
12403 }
12404 else {
12405 // check duplicate static names
12406 if (staticSlotName) {
12407 if (seenSlotNames.has(staticSlotName)) {
12408 context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
12409 continue;
12410 }
12411 seenSlotNames.add(staticSlotName);
12412 if (staticSlotName === 'default') {
12413 hasNamedDefaultSlot = true;
12414 }
12415 }
12416 slotsProperties.push(createObjectProperty(slotName, slotFunction));
12417 }
12418 }
12419 if (!onComponentSlot) {
12420 if (!hasTemplateSlots) {
12421 // implicit default slot (on component)
12422 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
12423 }
12424 else if (implicitDefaultChildren.length) {
12425 // implicit default slot (mixed with named slots)
12426 if (hasNamedDefaultSlot) {
12427 context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
12428 }
12429 else {
12430 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
12431 }
12432 }
12433 }
12434 const slotFlag = hasDynamicSlots
12435 ? 2 /* DYNAMIC */
12436 : hasForwardedSlots(node.children)
12437 ? 3 /* FORWARDED */
12438 : 1 /* STABLE */;
12439 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
12440 // 2 = compiled but dynamic = can skip normalization, but must run diff
12441 // 1 = compiled and static = can skip normalization AND diff as optimized
12442 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
12443 if (dynamicSlots.length) {
12444 slots = createCallExpression(context.helper(CREATE_SLOTS), [
12445 slots,
12446 createArrayExpression(dynamicSlots)
12447 ]);
12448 }
12449 return {
12450 slots,
12451 hasDynamicSlots
12452 };
12453 }
12454 function buildDynamicSlot(name, fn) {
12455 return createObjectExpression([
12456 createObjectProperty(`name`, name),
12457 createObjectProperty(`fn`, fn)
12458 ]);
12459 }
12460 function hasForwardedSlots(children) {
12461 for (let i = 0; i < children.length; i++) {
12462 const child = children[i];
12463 switch (child.type) {
12464 case 1 /* ELEMENT */:
12465 if (child.tagType === 2 /* SLOT */ ||
12466 (child.tagType === 0 /* ELEMENT */ &&
12467 hasForwardedSlots(child.children))) {
12468 return true;
12469 }
12470 break;
12471 case 9 /* IF */:
12472 if (hasForwardedSlots(child.branches))
12473 return true;
12474 break;
12475 case 10 /* IF_BRANCH */:
12476 case 11 /* FOR */:
12477 if (hasForwardedSlots(child.children))
12478 return true;
12479 break;
12480 }
12481 }
12482 return false;
12483 }
12484
12485 // some directive transforms (e.g. v-model) may return a symbol for runtime
12486 // import, which should be used instead of a resolveDirective call.
12487 const directiveImportMap = new WeakMap();
12488 // generate a JavaScript AST for this element's codegen
12489 const transformElement = (node, context) => {
12490 // perform the work on exit, after all child expressions have been
12491 // processed and merged.
12492 return function postTransformElement() {
12493 node = context.currentNode;
12494 if (!(node.type === 1 /* ELEMENT */ &&
12495 (node.tagType === 0 /* ELEMENT */ ||
12496 node.tagType === 1 /* COMPONENT */))) {
12497 return;
12498 }
12499 const { tag, props } = node;
12500 const isComponent = node.tagType === 1 /* COMPONENT */;
12501 // The goal of the transform is to create a codegenNode implementing the
12502 // VNodeCall interface.
12503 const vnodeTag = isComponent
12504 ? resolveComponentType(node, context)
12505 : `"${tag}"`;
12506 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
12507 let vnodeProps;
12508 let vnodeChildren;
12509 let vnodePatchFlag;
12510 let patchFlag = 0;
12511 let vnodeDynamicProps;
12512 let dynamicPropNames;
12513 let vnodeDirectives;
12514 let shouldUseBlock =
12515 // dynamic component may resolve to plain elements
12516 isDynamicComponent ||
12517 vnodeTag === TELEPORT ||
12518 vnodeTag === SUSPENSE ||
12519 (!isComponent &&
12520 // <svg> and <foreignObject> must be forced into blocks so that block
12521 // updates inside get proper isSVG flag at runtime. (#639, #643)
12522 // This is technically web-specific, but splitting the logic out of core
12523 // leads to too much unnecessary complexity.
12524 (tag === 'svg' ||
12525 tag === 'foreignObject' ||
12526 // #938: elements with dynamic keys should be forced into blocks
12527 findProp(node, 'key', true)));
12528 // props
12529 if (props.length > 0) {
12530 const propsBuildResult = buildProps(node, context);
12531 vnodeProps = propsBuildResult.props;
12532 patchFlag = propsBuildResult.patchFlag;
12533 dynamicPropNames = propsBuildResult.dynamicPropNames;
12534 const directives = propsBuildResult.directives;
12535 vnodeDirectives =
12536 directives && directives.length
12537 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
12538 : undefined;
12539 }
12540 // children
12541 if (node.children.length > 0) {
12542 if (vnodeTag === KEEP_ALIVE) {
12543 // Although a built-in component, we compile KeepAlive with raw children
12544 // instead of slot functions so that it can be used inside Transition
12545 // or other Transition-wrapping HOCs.
12546 // To ensure correct updates with block optimizations, we need to:
12547 // 1. Force keep-alive into a block. This avoids its children being
12548 // collected by a parent block.
12549 shouldUseBlock = true;
12550 // 2. Force keep-alive to always be updated, since it uses raw children.
12551 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
12552 if (node.children.length > 1) {
12553 context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
12554 start: node.children[0].loc.start,
12555 end: node.children[node.children.length - 1].loc.end,
12556 source: ''
12557 }));
12558 }
12559 }
12560 const shouldBuildAsSlots = isComponent &&
12561 // Teleport is not a real component and has dedicated runtime handling
12562 vnodeTag !== TELEPORT &&
12563 // explained above.
12564 vnodeTag !== KEEP_ALIVE;
12565 if (shouldBuildAsSlots) {
12566 const { slots, hasDynamicSlots } = buildSlots(node, context);
12567 vnodeChildren = slots;
12568 if (hasDynamicSlots) {
12569 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
12570 }
12571 }
12572 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
12573 const child = node.children[0];
12574 const type = child.type;
12575 // check for dynamic text children
12576 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
12577 type === 8 /* COMPOUND_EXPRESSION */;
12578 if (hasDynamicTextChild &&
12579 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
12580 patchFlag |= 1 /* TEXT */;
12581 }
12582 // pass directly if the only child is a text node
12583 // (plain / interpolation / expression)
12584 if (hasDynamicTextChild || type === 2 /* TEXT */) {
12585 vnodeChildren = child;
12586 }
12587 else {
12588 vnodeChildren = node.children;
12589 }
12590 }
12591 else {
12592 vnodeChildren = node.children;
12593 }
12594 }
12595 // patchFlag & dynamicPropNames
12596 if (patchFlag !== 0) {
12597 {
12598 if (patchFlag < 0) {
12599 // special flags (negative and mutually exclusive)
12600 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
12601 }
12602 else {
12603 // bitwise flags
12604 const flagNames = Object.keys(PatchFlagNames)
12605 .map(Number)
12606 .filter(n => n > 0 && patchFlag & n)
12607 .map(n => PatchFlagNames[n])
12608 .join(`, `);
12609 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
12610 }
12611 }
12612 if (dynamicPropNames && dynamicPropNames.length) {
12613 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
12614 }
12615 }
12616 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);
12617 };
12618 };
12619 function resolveComponentType(node, context, ssr = false) {
12620 const { tag } = node;
12621 // 1. dynamic component
12622 const isProp = isComponentTag(tag)
12623 ? findProp(node, 'is')
12624 : findDir(node, 'is');
12625 if (isProp) {
12626 const exp = isProp.type === 6 /* ATTRIBUTE */
12627 ? isProp.value && createSimpleExpression(isProp.value.content, true)
12628 : isProp.exp;
12629 if (exp) {
12630 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
12631 exp
12632 ]);
12633 }
12634 }
12635 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
12636 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
12637 if (builtIn) {
12638 // built-ins are simply fallthroughs / have special handling during ssr
12639 // so we don't need to import their runtime equivalents
12640 if (!ssr)
12641 context.helper(builtIn);
12642 return builtIn;
12643 }
12644 // 5. user component (resolve)
12645 context.helper(RESOLVE_COMPONENT);
12646 context.components.add(tag);
12647 return toValidAssetId(tag, `component`);
12648 }
12649 function buildProps(node, context, props = node.props, ssr = false) {
12650 const { tag, loc: elementLoc } = node;
12651 const isComponent = node.tagType === 1 /* COMPONENT */;
12652 let properties = [];
12653 const mergeArgs = [];
12654 const runtimeDirectives = [];
12655 // patchFlag analysis
12656 let patchFlag = 0;
12657 let hasRef = false;
12658 let hasClassBinding = false;
12659 let hasStyleBinding = false;
12660 let hasHydrationEventBinding = false;
12661 let hasDynamicKeys = false;
12662 let hasVnodeHook = false;
12663 const dynamicPropNames = [];
12664 const analyzePatchFlag = ({ key, value }) => {
12665 if (isStaticExp(key)) {
12666 const name = key.content;
12667 const isEventHandler = isOn(name);
12668 if (!isComponent &&
12669 isEventHandler &&
12670 // omit the flag for click handlers because hydration gives click
12671 // dedicated fast path.
12672 name.toLowerCase() !== 'onclick' &&
12673 // omit v-model handlers
12674 name !== 'onUpdate:modelValue' &&
12675 // omit onVnodeXXX hooks
12676 !isReservedProp(name)) {
12677 hasHydrationEventBinding = true;
12678 }
12679 if (isEventHandler && isReservedProp(name)) {
12680 hasVnodeHook = true;
12681 }
12682 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
12683 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
12684 value.type === 8 /* COMPOUND_EXPRESSION */) &&
12685 getConstantType(value, context) > 0)) {
12686 // skip if the prop is a cached handler or has constant value
12687 return;
12688 }
12689 if (name === 'ref') {
12690 hasRef = true;
12691 }
12692 else if (name === 'class' && !isComponent) {
12693 hasClassBinding = true;
12694 }
12695 else if (name === 'style' && !isComponent) {
12696 hasStyleBinding = true;
12697 }
12698 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
12699 dynamicPropNames.push(name);
12700 }
12701 }
12702 else {
12703 hasDynamicKeys = true;
12704 }
12705 };
12706 for (let i = 0; i < props.length; i++) {
12707 // static attribute
12708 const prop = props[i];
12709 if (prop.type === 6 /* ATTRIBUTE */) {
12710 const { loc, name, value } = prop;
12711 let isStatic = true;
12712 if (name === 'ref') {
12713 hasRef = true;
12714 }
12715 // skip :is on <component>
12716 if (name === 'is' && isComponentTag(tag)) {
12717 continue;
12718 }
12719 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
12720 }
12721 else {
12722 // directives
12723 const { name, arg, exp, loc } = prop;
12724 const isBind = name === 'bind';
12725 const isOn = name === 'on';
12726 // skip v-slot - it is handled by its dedicated transform.
12727 if (name === 'slot') {
12728 if (!isComponent) {
12729 context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));
12730 }
12731 continue;
12732 }
12733 // skip v-once - it is handled by its dedicated transform.
12734 if (name === 'once') {
12735 continue;
12736 }
12737 // skip v-is and :is on <component>
12738 if (name === 'is' ||
12739 (isBind && isComponentTag(tag) && isBindKey(arg, 'is'))) {
12740 continue;
12741 }
12742 // skip v-on in SSR compilation
12743 if (isOn && ssr) {
12744 continue;
12745 }
12746 // special case for v-bind and v-on with no argument
12747 if (!arg && (isBind || isOn)) {
12748 hasDynamicKeys = true;
12749 if (exp) {
12750 if (properties.length) {
12751 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
12752 properties = [];
12753 }
12754 if (isBind) {
12755 mergeArgs.push(exp);
12756 }
12757 else {
12758 // v-on="obj" -> toHandlers(obj)
12759 mergeArgs.push({
12760 type: 14 /* JS_CALL_EXPRESSION */,
12761 loc,
12762 callee: context.helper(TO_HANDLERS),
12763 arguments: [exp]
12764 });
12765 }
12766 }
12767 else {
12768 context.onError(createCompilerError(isBind
12769 ? 33 /* X_V_BIND_NO_EXPRESSION */
12770 : 34 /* X_V_ON_NO_EXPRESSION */, loc));
12771 }
12772 continue;
12773 }
12774 const directiveTransform = context.directiveTransforms[name];
12775 if (directiveTransform) {
12776 // has built-in directive transform.
12777 const { props, needRuntime } = directiveTransform(prop, node, context);
12778 !ssr && props.forEach(analyzePatchFlag);
12779 properties.push(...props);
12780 if (needRuntime) {
12781 runtimeDirectives.push(prop);
12782 if (isSymbol(needRuntime)) {
12783 directiveImportMap.set(prop, needRuntime);
12784 }
12785 }
12786 }
12787 else {
12788 // no built-in transform, this is a user custom directive.
12789 runtimeDirectives.push(prop);
12790 }
12791 }
12792 }
12793 let propsExpression = undefined;
12794 // has v-bind="object" or v-on="object", wrap with mergeProps
12795 if (mergeArgs.length) {
12796 if (properties.length) {
12797 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
12798 }
12799 if (mergeArgs.length > 1) {
12800 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
12801 }
12802 else {
12803 // single v-bind with nothing else - no need for a mergeProps call
12804 propsExpression = mergeArgs[0];
12805 }
12806 }
12807 else if (properties.length) {
12808 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
12809 }
12810 // patchFlag analysis
12811 if (hasDynamicKeys) {
12812 patchFlag |= 16 /* FULL_PROPS */;
12813 }
12814 else {
12815 if (hasClassBinding) {
12816 patchFlag |= 2 /* CLASS */;
12817 }
12818 if (hasStyleBinding) {
12819 patchFlag |= 4 /* STYLE */;
12820 }
12821 if (dynamicPropNames.length) {
12822 patchFlag |= 8 /* PROPS */;
12823 }
12824 if (hasHydrationEventBinding) {
12825 patchFlag |= 32 /* HYDRATE_EVENTS */;
12826 }
12827 }
12828 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
12829 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
12830 patchFlag |= 512 /* NEED_PATCH */;
12831 }
12832 return {
12833 props: propsExpression,
12834 directives: runtimeDirectives,
12835 patchFlag,
12836 dynamicPropNames
12837 };
12838 }
12839 // Dedupe props in an object literal.
12840 // Literal duplicated attributes would have been warned during the parse phase,
12841 // however, it's possible to encounter duplicated `onXXX` handlers with different
12842 // modifiers. We also need to merge static and dynamic class / style attributes.
12843 // - onXXX handlers / style: merge into array
12844 // - class: merge into single expression with concatenation
12845 function dedupeProperties(properties) {
12846 const knownProps = new Map();
12847 const deduped = [];
12848 for (let i = 0; i < properties.length; i++) {
12849 const prop = properties[i];
12850 // dynamic keys are always allowed
12851 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
12852 deduped.push(prop);
12853 continue;
12854 }
12855 const name = prop.key.content;
12856 const existing = knownProps.get(name);
12857 if (existing) {
12858 if (name === 'style' || name === 'class' || name.startsWith('on')) {
12859 mergeAsArray(existing, prop);
12860 }
12861 // unexpected duplicate, should have emitted error during parse
12862 }
12863 else {
12864 knownProps.set(name, prop);
12865 deduped.push(prop);
12866 }
12867 }
12868 return deduped;
12869 }
12870 function mergeAsArray(existing, incoming) {
12871 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
12872 existing.value.elements.push(incoming.value);
12873 }
12874 else {
12875 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
12876 }
12877 }
12878 function buildDirectiveArgs(dir, context) {
12879 const dirArgs = [];
12880 const runtime = directiveImportMap.get(dir);
12881 if (runtime) {
12882 // built-in directive with runtime
12883 dirArgs.push(context.helperString(runtime));
12884 }
12885 else {
12886 {
12887 // inject statement for resolving directive
12888 context.helper(RESOLVE_DIRECTIVE);
12889 context.directives.add(dir.name);
12890 dirArgs.push(toValidAssetId(dir.name, `directive`));
12891 }
12892 }
12893 const { loc } = dir;
12894 if (dir.exp)
12895 dirArgs.push(dir.exp);
12896 if (dir.arg) {
12897 if (!dir.exp) {
12898 dirArgs.push(`void 0`);
12899 }
12900 dirArgs.push(dir.arg);
12901 }
12902 if (Object.keys(dir.modifiers).length) {
12903 if (!dir.arg) {
12904 if (!dir.exp) {
12905 dirArgs.push(`void 0`);
12906 }
12907 dirArgs.push(`void 0`);
12908 }
12909 const trueExpression = createSimpleExpression(`true`, false, loc);
12910 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
12911 }
12912 return createArrayExpression(dirArgs, dir.loc);
12913 }
12914 function stringifyDynamicPropNames(props) {
12915 let propsNamesString = `[`;
12916 for (let i = 0, l = props.length; i < l; i++) {
12917 propsNamesString += JSON.stringify(props[i]);
12918 if (i < l - 1)
12919 propsNamesString += ', ';
12920 }
12921 return propsNamesString + `]`;
12922 }
12923 function isComponentTag(tag) {
12924 return tag[0].toLowerCase() + tag.slice(1) === 'component';
12925 }
12926
12927 const transformSlotOutlet = (node, context) => {
12928 if (isSlotOutlet(node)) {
12929 const { children, loc } = node;
12930 const { slotName, slotProps } = processSlotOutlet(node, context);
12931 const slotArgs = [
12932 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
12933 slotName
12934 ];
12935 if (slotProps) {
12936 slotArgs.push(slotProps);
12937 }
12938 if (children.length) {
12939 if (!slotProps) {
12940 slotArgs.push(`{}`);
12941 }
12942 slotArgs.push(createFunctionExpression([], children, false, false, loc));
12943 }
12944 if (context.scopeId && !context.slotted) {
12945 if (!slotProps) {
12946 slotArgs.push(`{}`);
12947 }
12948 if (!children.length) {
12949 slotArgs.push(`undefined`);
12950 }
12951 slotArgs.push(`true`);
12952 }
12953 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
12954 }
12955 };
12956 function processSlotOutlet(node, context) {
12957 let slotName = `"default"`;
12958 let slotProps = undefined;
12959 const nonNameProps = [];
12960 for (let i = 0; i < node.props.length; i++) {
12961 const p = node.props[i];
12962 if (p.type === 6 /* ATTRIBUTE */) {
12963 if (p.value) {
12964 if (p.name === 'name') {
12965 slotName = JSON.stringify(p.value.content);
12966 }
12967 else {
12968 p.name = camelize(p.name);
12969 nonNameProps.push(p);
12970 }
12971 }
12972 }
12973 else {
12974 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
12975 if (p.exp)
12976 slotName = p.exp;
12977 }
12978 else {
12979 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
12980 p.arg.content = camelize(p.arg.content);
12981 }
12982 nonNameProps.push(p);
12983 }
12984 }
12985 }
12986 if (nonNameProps.length > 0) {
12987 const { props, directives } = buildProps(node, context, nonNameProps);
12988 slotProps = props;
12989 if (directives.length) {
12990 context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
12991 }
12992 }
12993 return {
12994 slotName,
12995 slotProps
12996 };
12997 }
12998
12999 const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;
13000 const transformOn = (dir, node, context, augmentor) => {
13001 const { loc, modifiers, arg } = dir;
13002 if (!dir.exp && !modifiers.length) {
13003 context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));
13004 }
13005 let eventName;
13006 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13007 if (arg.isStatic) {
13008 const rawName = arg.content;
13009 // for all event listeners, auto convert it to camelCase. See issue #2249
13010 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
13011 }
13012 else {
13013 // #2388
13014 eventName = createCompoundExpression([
13015 `${context.helperString(TO_HANDLER_KEY)}(`,
13016 arg,
13017 `)`
13018 ]);
13019 }
13020 }
13021 else {
13022 // already a compound expression.
13023 eventName = arg;
13024 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
13025 eventName.children.push(`)`);
13026 }
13027 // handler processing
13028 let exp = dir.exp;
13029 if (exp && !exp.content.trim()) {
13030 exp = undefined;
13031 }
13032 let shouldCache = context.cacheHandlers && !exp;
13033 if (exp) {
13034 const isMemberExp = isMemberExpression(exp.content);
13035 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
13036 const hasMultipleStatements = exp.content.includes(`;`);
13037 {
13038 validateBrowserExpression(exp, context, false, hasMultipleStatements);
13039 }
13040 if (isInlineStatement || (shouldCache && isMemberExp)) {
13041 // wrap inline statement in a function expression
13042 exp = createCompoundExpression([
13043 `${isInlineStatement
13044 ? `$event`
13045 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
13046 exp,
13047 hasMultipleStatements ? `}` : `)`
13048 ]);
13049 }
13050 }
13051 let ret = {
13052 props: [
13053 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
13054 ]
13055 };
13056 // apply extended compiler augmentor
13057 if (augmentor) {
13058 ret = augmentor(ret);
13059 }
13060 if (shouldCache) {
13061 // cache handlers so that it's always the same handler being passed down.
13062 // this avoids unnecessary re-renders when users use inline handlers on
13063 // components.
13064 ret.props[0].value = context.cache(ret.props[0].value);
13065 }
13066 return ret;
13067 };
13068
13069 // v-bind without arg is handled directly in ./transformElements.ts due to it affecting
13070 // codegen for the entire props object. This transform here is only for v-bind
13071 // *with* args.
13072 const transformBind = (dir, node, context) => {
13073 const { exp, modifiers, loc } = dir;
13074 const arg = dir.arg;
13075 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
13076 arg.children.unshift(`(`);
13077 arg.children.push(`) || ""`);
13078 }
13079 else if (!arg.isStatic) {
13080 arg.content = `${arg.content} || ""`;
13081 }
13082 // .prop is no longer necessary due to new patch behavior
13083 // .sync is replaced by v-model:arg
13084 if (modifiers.includes('camel')) {
13085 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13086 if (arg.isStatic) {
13087 arg.content = camelize(arg.content);
13088 }
13089 else {
13090 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
13091 }
13092 }
13093 else {
13094 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
13095 arg.children.push(`)`);
13096 }
13097 }
13098 if (!exp ||
13099 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
13100 context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));
13101 return {
13102 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
13103 };
13104 }
13105 return {
13106 props: [createObjectProperty(arg, exp)]
13107 };
13108 };
13109
13110 // Merge adjacent text nodes and expressions into a single expression
13111 // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
13112 const transformText = (node, context) => {
13113 if (node.type === 0 /* ROOT */ ||
13114 node.type === 1 /* ELEMENT */ ||
13115 node.type === 11 /* FOR */ ||
13116 node.type === 10 /* IF_BRANCH */) {
13117 // perform the transform on node exit so that all expressions have already
13118 // been processed.
13119 return () => {
13120 const children = node.children;
13121 let currentContainer = undefined;
13122 let hasText = false;
13123 for (let i = 0; i < children.length; i++) {
13124 const child = children[i];
13125 if (isText(child)) {
13126 hasText = true;
13127 for (let j = i + 1; j < children.length; j++) {
13128 const next = children[j];
13129 if (isText(next)) {
13130 if (!currentContainer) {
13131 currentContainer = children[i] = {
13132 type: 8 /* COMPOUND_EXPRESSION */,
13133 loc: child.loc,
13134 children: [child]
13135 };
13136 }
13137 // merge adjacent text node into current
13138 currentContainer.children.push(` + `, next);
13139 children.splice(j, 1);
13140 j--;
13141 }
13142 else {
13143 currentContainer = undefined;
13144 break;
13145 }
13146 }
13147 }
13148 }
13149 if (!hasText ||
13150 // if this is a plain element with a single text child, leave it
13151 // as-is since the runtime has dedicated fast path for this by directly
13152 // setting textContent of the element.
13153 // for component root it's always normalized anyway.
13154 (children.length === 1 &&
13155 (node.type === 0 /* ROOT */ ||
13156 (node.type === 1 /* ELEMENT */ &&
13157 node.tagType === 0 /* ELEMENT */)))) {
13158 return;
13159 }
13160 // pre-convert text nodes into createTextVNode(text) calls to avoid
13161 // runtime normalization.
13162 for (let i = 0; i < children.length; i++) {
13163 const child = children[i];
13164 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
13165 const callArgs = [];
13166 // createTextVNode defaults to single whitespace, so if it is a
13167 // single space the code could be an empty call to save bytes.
13168 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
13169 callArgs.push(child);
13170 }
13171 // mark dynamic text with flag so it gets patched inside a block
13172 if (!context.ssr &&
13173 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
13174 callArgs.push(1 /* TEXT */ +
13175 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
13176 }
13177 children[i] = {
13178 type: 12 /* TEXT_CALL */,
13179 content: child,
13180 loc: child.loc,
13181 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
13182 };
13183 }
13184 }
13185 };
13186 }
13187 };
13188
13189 const seen = new WeakSet();
13190 const transformOnce = (node, context) => {
13191 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
13192 if (seen.has(node)) {
13193 return;
13194 }
13195 seen.add(node);
13196 context.helper(SET_BLOCK_TRACKING);
13197 return () => {
13198 const cur = context.currentNode;
13199 if (cur.codegenNode) {
13200 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
13201 }
13202 };
13203 }
13204 };
13205
13206 const transformModel = (dir, node, context) => {
13207 const { exp, arg } = dir;
13208 if (!exp) {
13209 context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
13210 return createTransformProps();
13211 }
13212 const rawExp = exp.loc.source;
13213 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
13214 // im SFC <script setup> inline mode, the exp may have been transformed into
13215 // _unref(exp)
13216 context.bindingMetadata[rawExp];
13217 const maybeRef = !true /* SETUP_CONST */;
13218 if (!isMemberExpression(expString) && !maybeRef) {
13219 context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
13220 return createTransformProps();
13221 }
13222 const propName = arg ? arg : createSimpleExpression('modelValue', true);
13223 const eventName = arg
13224 ? isStaticExp(arg)
13225 ? `onUpdate:${arg.content}`
13226 : createCompoundExpression(['"onUpdate:" + ', arg])
13227 : `onUpdate:modelValue`;
13228 let assignmentExp;
13229 const eventArg = context.isTS ? `($event: any)` : `$event`;
13230 {
13231 assignmentExp = createCompoundExpression([
13232 `${eventArg} => (`,
13233 exp,
13234 ` = $event)`
13235 ]);
13236 }
13237 const props = [
13238 // modelValue: foo
13239 createObjectProperty(propName, dir.exp),
13240 // "onUpdate:modelValue": $event => (foo = $event)
13241 createObjectProperty(eventName, assignmentExp)
13242 ];
13243 // modelModifiers: { foo: true, "bar-baz": true }
13244 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
13245 const modifiers = dir.modifiers
13246 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
13247 .join(`, `);
13248 const modifiersKey = arg
13249 ? isStaticExp(arg)
13250 ? `${arg.content}Modifiers`
13251 : createCompoundExpression([arg, ' + "Modifiers"'])
13252 : `modelModifiers`;
13253 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
13254 }
13255 return createTransformProps(props);
13256 };
13257 function createTransformProps(props = []) {
13258 return { props };
13259 }
13260
13261 function getBaseTransformPreset(prefixIdentifiers) {
13262 return [
13263 [
13264 transformOnce,
13265 transformIf,
13266 transformFor,
13267 ...([transformExpression]
13268 ),
13269 transformSlotOutlet,
13270 transformElement,
13271 trackSlotScopes,
13272 transformText
13273 ],
13274 {
13275 on: transformOn,
13276 bind: transformBind,
13277 model: transformModel
13278 }
13279 ];
13280 }
13281 // we name it `baseCompile` so that higher order compilers like
13282 // @vue/compiler-dom can export `compile` while re-exporting everything else.
13283 function baseCompile(template, options = {}) {
13284 const onError = options.onError || defaultOnError;
13285 const isModuleMode = options.mode === 'module';
13286 /* istanbul ignore if */
13287 {
13288 if (options.prefixIdentifiers === true) {
13289 onError(createCompilerError(45 /* X_PREFIX_ID_NOT_SUPPORTED */));
13290 }
13291 else if (isModuleMode) {
13292 onError(createCompilerError(46 /* X_MODULE_MODE_NOT_SUPPORTED */));
13293 }
13294 }
13295 const prefixIdentifiers = !true ;
13296 if (options.cacheHandlers) {
13297 onError(createCompilerError(47 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
13298 }
13299 if (options.scopeId && !isModuleMode) {
13300 onError(createCompilerError(48 /* X_SCOPE_ID_NOT_SUPPORTED */));
13301 }
13302 const ast = isString(template) ? baseParse(template, options) : template;
13303 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
13304 transform(ast, extend({}, options, {
13305 prefixIdentifiers,
13306 nodeTransforms: [
13307 ...nodeTransforms,
13308 ...(options.nodeTransforms || []) // user transforms
13309 ],
13310 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
13311 )
13312 }));
13313 return generate(ast, extend({}, options, {
13314 prefixIdentifiers
13315 }));
13316 }
13317
13318 const noopDirectiveTransform = () => ({ props: [] });
13319
13320 const V_MODEL_RADIO = Symbol(`vModelRadio` );
13321 const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
13322 const V_MODEL_TEXT = Symbol(`vModelText` );
13323 const V_MODEL_SELECT = Symbol(`vModelSelect` );
13324 const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
13325 const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
13326 const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
13327 const V_SHOW = Symbol(`vShow` );
13328 const TRANSITION$1 = Symbol(`Transition` );
13329 const TRANSITION_GROUP = Symbol(`TransitionGroup` );
13330 registerRuntimeHelpers({
13331 [V_MODEL_RADIO]: `vModelRadio`,
13332 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
13333 [V_MODEL_TEXT]: `vModelText`,
13334 [V_MODEL_SELECT]: `vModelSelect`,
13335 [V_MODEL_DYNAMIC]: `vModelDynamic`,
13336 [V_ON_WITH_MODIFIERS]: `withModifiers`,
13337 [V_ON_WITH_KEYS]: `withKeys`,
13338 [V_SHOW]: `vShow`,
13339 [TRANSITION$1]: `Transition`,
13340 [TRANSITION_GROUP]: `TransitionGroup`
13341 });
13342
13343 /* eslint-disable no-restricted-globals */
13344 let decoder;
13345 function decodeHtmlBrowser(raw) {
13346 (decoder || (decoder = document.createElement('div'))).innerHTML = raw;
13347 return decoder.textContent;
13348 }
13349
13350 const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
13351 const parserOptions = {
13352 isVoidTag,
13353 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
13354 isPreTag: tag => tag === 'pre',
13355 decodeEntities: decodeHtmlBrowser ,
13356 isBuiltInComponent: (tag) => {
13357 if (isBuiltInType(tag, `Transition`)) {
13358 return TRANSITION$1;
13359 }
13360 else if (isBuiltInType(tag, `TransitionGroup`)) {
13361 return TRANSITION_GROUP;
13362 }
13363 },
13364 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
13365 getNamespace(tag, parent) {
13366 let ns = parent ? parent.ns : 0 /* HTML */;
13367 if (parent && ns === 2 /* MATH_ML */) {
13368 if (parent.tag === 'annotation-xml') {
13369 if (tag === 'svg') {
13370 return 1 /* SVG */;
13371 }
13372 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
13373 a.name === 'encoding' &&
13374 a.value != null &&
13375 (a.value.content === 'text/html' ||
13376 a.value.content === 'application/xhtml+xml'))) {
13377 ns = 0 /* HTML */;
13378 }
13379 }
13380 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
13381 tag !== 'mglyph' &&
13382 tag !== 'malignmark') {
13383 ns = 0 /* HTML */;
13384 }
13385 }
13386 else if (parent && ns === 1 /* SVG */) {
13387 if (parent.tag === 'foreignObject' ||
13388 parent.tag === 'desc' ||
13389 parent.tag === 'title') {
13390 ns = 0 /* HTML */;
13391 }
13392 }
13393 if (ns === 0 /* HTML */) {
13394 if (tag === 'svg') {
13395 return 1 /* SVG */;
13396 }
13397 if (tag === 'math') {
13398 return 2 /* MATH_ML */;
13399 }
13400 }
13401 return ns;
13402 },
13403 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
13404 getTextMode({ tag, ns }) {
13405 if (ns === 0 /* HTML */) {
13406 if (tag === 'textarea' || tag === 'title') {
13407 return 1 /* RCDATA */;
13408 }
13409 if (isRawTextContainer(tag)) {
13410 return 2 /* RAWTEXT */;
13411 }
13412 }
13413 return 0 /* DATA */;
13414 }
13415 };
13416
13417 // Parse inline CSS strings for static style attributes into an object.
13418 // This is a NodeTransform since it works on the static `style` attribute and
13419 // converts it into a dynamic equivalent:
13420 // style="color: red" -> :style='{ "color": "red" }'
13421 // It is then processed by `transformElement` and included in the generated
13422 // props.
13423 const transformStyle = node => {
13424 if (node.type === 1 /* ELEMENT */) {
13425 node.props.forEach((p, i) => {
13426 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
13427 // replace p with an expression node
13428 node.props[i] = {
13429 type: 7 /* DIRECTIVE */,
13430 name: `bind`,
13431 arg: createSimpleExpression(`style`, true, p.loc),
13432 exp: parseInlineCSS(p.value.content, p.loc),
13433 modifiers: [],
13434 loc: p.loc
13435 };
13436 }
13437 });
13438 }
13439 };
13440 const parseInlineCSS = (cssText, loc) => {
13441 const normalized = parseStringStyle(cssText);
13442 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
13443 };
13444
13445 function createDOMCompilerError(code, loc) {
13446 return createCompilerError(code, loc, DOMErrorMessages );
13447 }
13448 const DOMErrorMessages = {
13449 [49 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
13450 [50 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
13451 [51 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
13452 [52 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
13453 [53 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
13454 [54 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
13455 [55 /* 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.`,
13456 [56 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
13457 [57 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
13458 [58 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
13459 [59 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
13460 };
13461
13462 const transformVHtml = (dir, node, context) => {
13463 const { exp, loc } = dir;
13464 if (!exp) {
13465 context.onError(createDOMCompilerError(49 /* X_V_HTML_NO_EXPRESSION */, loc));
13466 }
13467 if (node.children.length) {
13468 context.onError(createDOMCompilerError(50 /* X_V_HTML_WITH_CHILDREN */, loc));
13469 node.children.length = 0;
13470 }
13471 return {
13472 props: [
13473 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
13474 ]
13475 };
13476 };
13477
13478 const transformVText = (dir, node, context) => {
13479 const { exp, loc } = dir;
13480 if (!exp) {
13481 context.onError(createDOMCompilerError(51 /* X_V_TEXT_NO_EXPRESSION */, loc));
13482 }
13483 if (node.children.length) {
13484 context.onError(createDOMCompilerError(52 /* X_V_TEXT_WITH_CHILDREN */, loc));
13485 node.children.length = 0;
13486 }
13487 return {
13488 props: [
13489 createObjectProperty(createSimpleExpression(`textContent`, true), exp
13490 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
13491 : createSimpleExpression('', true))
13492 ]
13493 };
13494 };
13495
13496 const transformModel$1 = (dir, node, context) => {
13497 const baseResult = transformModel(dir, node, context);
13498 // base transform has errors OR component v-model (only need props)
13499 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
13500 return baseResult;
13501 }
13502 if (dir.arg) {
13503 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
13504 }
13505 function checkDuplicatedValue() {
13506 const value = findProp(node, 'value');
13507 if (value) {
13508 context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
13509 }
13510 }
13511 const { tag } = node;
13512 const isCustomElement = context.isCustomElement(tag);
13513 if (tag === 'input' ||
13514 tag === 'textarea' ||
13515 tag === 'select' ||
13516 isCustomElement) {
13517 let directiveToUse = V_MODEL_TEXT;
13518 let isInvalidType = false;
13519 if (tag === 'input' || isCustomElement) {
13520 const type = findProp(node, `type`);
13521 if (type) {
13522 if (type.type === 7 /* DIRECTIVE */) {
13523 // :type="foo"
13524 directiveToUse = V_MODEL_DYNAMIC;
13525 }
13526 else if (type.value) {
13527 switch (type.value.content) {
13528 case 'radio':
13529 directiveToUse = V_MODEL_RADIO;
13530 break;
13531 case 'checkbox':
13532 directiveToUse = V_MODEL_CHECKBOX;
13533 break;
13534 case 'file':
13535 isInvalidType = true;
13536 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
13537 break;
13538 default:
13539 // text type
13540 checkDuplicatedValue();
13541 break;
13542 }
13543 }
13544 }
13545 else if (hasDynamicKeyVBind(node)) {
13546 // element has bindings with dynamic keys, which can possibly contain
13547 // "type".
13548 directiveToUse = V_MODEL_DYNAMIC;
13549 }
13550 else {
13551 // text type
13552 checkDuplicatedValue();
13553 }
13554 }
13555 else if (tag === 'select') {
13556 directiveToUse = V_MODEL_SELECT;
13557 }
13558 else {
13559 // textarea
13560 checkDuplicatedValue();
13561 }
13562 // inject runtime directive
13563 // by returning the helper symbol via needRuntime
13564 // the import will replaced a resolveDirective call.
13565 if (!isInvalidType) {
13566 baseResult.needRuntime = context.helper(directiveToUse);
13567 }
13568 }
13569 else {
13570 context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
13571 }
13572 // native vmodel doesn't need the `modelValue` props since they are also
13573 // passed to the runtime as `binding.value`. removing it reduces code size.
13574 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
13575 p.key.content === 'modelValue'));
13576 return baseResult;
13577 };
13578
13579 const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
13580 const isNonKeyModifier = /*#__PURE__*/ makeMap(
13581 // event propagation management
13582`stop,prevent,self,` +
13583 // system modifiers + exact
13584 `ctrl,shift,alt,meta,exact,` +
13585 // mouse
13586 `middle`);
13587 // left & right could be mouse or key modifiers based on event type
13588 const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
13589 const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
13590 const resolveModifiers = (key, modifiers) => {
13591 const keyModifiers = [];
13592 const nonKeyModifiers = [];
13593 const eventOptionModifiers = [];
13594 for (let i = 0; i < modifiers.length; i++) {
13595 const modifier = modifiers[i];
13596 if (isEventOptionModifier(modifier)) {
13597 // eventOptionModifiers: modifiers for addEventListener() options,
13598 // e.g. .passive & .capture
13599 eventOptionModifiers.push(modifier);
13600 }
13601 else {
13602 // runtimeModifiers: modifiers that needs runtime guards
13603 if (maybeKeyModifier(modifier)) {
13604 if (isStaticExp(key)) {
13605 if (isKeyboardEvent(key.content)) {
13606 keyModifiers.push(modifier);
13607 }
13608 else {
13609 nonKeyModifiers.push(modifier);
13610 }
13611 }
13612 else {
13613 keyModifiers.push(modifier);
13614 nonKeyModifiers.push(modifier);
13615 }
13616 }
13617 else {
13618 if (isNonKeyModifier(modifier)) {
13619 nonKeyModifiers.push(modifier);
13620 }
13621 else {
13622 keyModifiers.push(modifier);
13623 }
13624 }
13625 }
13626 }
13627 return {
13628 keyModifiers,
13629 nonKeyModifiers,
13630 eventOptionModifiers
13631 };
13632 };
13633 const transformClick = (key, event) => {
13634 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
13635 return isStaticClick
13636 ? createSimpleExpression(event, true)
13637 : key.type !== 4 /* SIMPLE_EXPRESSION */
13638 ? createCompoundExpression([
13639 `(`,
13640 key,
13641 `) === "onClick" ? "${event}" : (`,
13642 key,
13643 `)`
13644 ])
13645 : key;
13646 };
13647 const transformOn$1 = (dir, node, context) => {
13648 return transformOn(dir, node, context, baseResult => {
13649 const { modifiers } = dir;
13650 if (!modifiers.length)
13651 return baseResult;
13652 let { key, value: handlerExp } = baseResult.props[0];
13653 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers);
13654 // normalize click.right and click.middle since they don't actually fire
13655 if (nonKeyModifiers.includes('right')) {
13656 key = transformClick(key, `onContextmenu`);
13657 }
13658 if (nonKeyModifiers.includes('middle')) {
13659 key = transformClick(key, `onMouseup`);
13660 }
13661 if (nonKeyModifiers.length) {
13662 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
13663 handlerExp,
13664 JSON.stringify(nonKeyModifiers)
13665 ]);
13666 }
13667 if (keyModifiers.length &&
13668 // if event name is dynamic, always wrap with keys guard
13669 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
13670 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
13671 handlerExp,
13672 JSON.stringify(keyModifiers)
13673 ]);
13674 }
13675 if (eventOptionModifiers.length) {
13676 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
13677 key = isStaticExp(key)
13678 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
13679 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
13680 }
13681 return {
13682 props: [createObjectProperty(key, handlerExp)]
13683 };
13684 });
13685 };
13686
13687 const transformShow = (dir, node, context) => {
13688 const { exp, loc } = dir;
13689 if (!exp) {
13690 context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */, loc));
13691 }
13692 return {
13693 props: [],
13694 needRuntime: context.helper(V_SHOW)
13695 };
13696 };
13697
13698 const warnTransitionChildren = (node, context) => {
13699 if (node.type === 1 /* ELEMENT */ &&
13700 node.tagType === 1 /* COMPONENT */) {
13701 const component = context.isBuiltInComponent(node.tag);
13702 if (component === TRANSITION$1) {
13703 return () => {
13704 if (node.children.length && hasMultipleChildren(node)) {
13705 context.onError(createDOMCompilerError(58 /* X_TRANSITION_INVALID_CHILDREN */, {
13706 start: node.children[0].loc.start,
13707 end: node.children[node.children.length - 1].loc.end,
13708 source: ''
13709 }));
13710 }
13711 };
13712 }
13713 }
13714 };
13715 function hasMultipleChildren(node) {
13716 // #1352 filter out potential comment nodes.
13717 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */));
13718 const child = children[0];
13719 return (children.length !== 1 ||
13720 child.type === 11 /* FOR */ ||
13721 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
13722 }
13723
13724 const ignoreSideEffectTags = (node, context) => {
13725 if (node.type === 1 /* ELEMENT */ &&
13726 node.tagType === 0 /* ELEMENT */ &&
13727 (node.tag === 'script' || node.tag === 'style')) {
13728 context.onError(createDOMCompilerError(59 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
13729 context.removeNode();
13730 }
13731 };
13732
13733 const DOMNodeTransforms = [
13734 transformStyle,
13735 ...([warnTransitionChildren] )
13736 ];
13737 const DOMDirectiveTransforms = {
13738 cloak: noopDirectiveTransform,
13739 html: transformVHtml,
13740 text: transformVText,
13741 model: transformModel$1,
13742 on: transformOn$1,
13743 show: transformShow
13744 };
13745 function compile$1(template, options = {}) {
13746 return baseCompile(template, extend({}, parserOptions, options, {
13747 nodeTransforms: [
13748 // ignore <script> and <tag>
13749 // this is not put inside DOMNodeTransforms because that list is used
13750 // by compiler-ssr to generate vnode fallback branches
13751 ignoreSideEffectTags,
13752 ...DOMNodeTransforms,
13753 ...(options.nodeTransforms || [])
13754 ],
13755 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
13756 transformHoist: null
13757 }));
13758 }
13759
13760 // This entry is the "full-build" that includes both the runtime
13761 {
13762 initDev();
13763 }
13764 const compileCache = Object.create(null);
13765 function compileToFunction(template, options) {
13766 if (!isString(template)) {
13767 if (template.nodeType) {
13768 template = template.innerHTML;
13769 }
13770 else {
13771 warn(`invalid template option: `, template);
13772 return NOOP;
13773 }
13774 }
13775 const key = template;
13776 const cached = compileCache[key];
13777 if (cached) {
13778 return cached;
13779 }
13780 if (template[0] === '#') {
13781 const el = document.querySelector(template);
13782 if (!el) {
13783 warn(`Template element not found or is empty: ${template}`);
13784 }
13785 // __UNSAFE__
13786 // Reason: potential execution of JS expressions in in-DOM template.
13787 // The user must make sure the in-DOM template is trusted. If it's rendered
13788 // by the server, the template should not contain any user data.
13789 template = el ? el.innerHTML : ``;
13790 }
13791 const { code } = compile$1(template, extend({
13792 hoistStatic: true,
13793 onError(err) {
13794 {
13795 const message = `Template compilation error: ${err.message}`;
13796 const codeFrame = err.loc &&
13797 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
13798 warn(codeFrame ? `${message}\n${codeFrame}` : message);
13799 }
13800 }
13801 }, options));
13802 // The wildcard import results in a huge object with every export
13803 // with keys that cannot be mangled, and can be quite heavy size-wise.
13804 // In the global build we know `Vue` is available globally so we can avoid
13805 // the wildcard object.
13806 const render = (new Function(code)()
13807 );
13808 render._rc = true;
13809 return (compileCache[key] = render);
13810 }
13811 registerRuntimeCompiler(compileToFunction);
13812
13813 exports.BaseTransition = BaseTransition;
13814 exports.Comment = Comment;
13815 exports.Fragment = Fragment;
13816 exports.KeepAlive = KeepAlive;
13817 exports.Static = Static;
13818 exports.Suspense = Suspense;
13819 exports.Teleport = Teleport;
13820 exports.Text = Text;
13821 exports.Transition = Transition;
13822 exports.TransitionGroup = TransitionGroup;
13823 exports.callWithAsyncErrorHandling = callWithAsyncErrorHandling;
13824 exports.callWithErrorHandling = callWithErrorHandling;
13825 exports.camelize = camelize;
13826 exports.capitalize = capitalize;
13827 exports.cloneVNode = cloneVNode;
13828 exports.compile = compileToFunction;
13829 exports.computed = computed$1;
13830 exports.createApp = createApp;
13831 exports.createBlock = createBlock;
13832 exports.createCommentVNode = createCommentVNode;
13833 exports.createHydrationRenderer = createHydrationRenderer;
13834 exports.createRenderer = createRenderer;
13835 exports.createSSRApp = createSSRApp;
13836 exports.createSlots = createSlots;
13837 exports.createStaticVNode = createStaticVNode;
13838 exports.createTextVNode = createTextVNode;
13839 exports.createVNode = createVNode;
13840 exports.customRef = customRef;
13841 exports.defineAsyncComponent = defineAsyncComponent;
13842 exports.defineComponent = defineComponent;
13843 exports.defineEmit = defineEmit;
13844 exports.defineProps = defineProps;
13845 exports.getCurrentInstance = getCurrentInstance;
13846 exports.getTransitionRawChildren = getTransitionRawChildren;
13847 exports.h = h;
13848 exports.handleError = handleError;
13849 exports.hydrate = hydrate;
13850 exports.initCustomFormatter = initCustomFormatter;
13851 exports.inject = inject;
13852 exports.isProxy = isProxy;
13853 exports.isReactive = isReactive;
13854 exports.isReadonly = isReadonly;
13855 exports.isRef = isRef;
13856 exports.isRuntimeOnly = isRuntimeOnly;
13857 exports.isVNode = isVNode;
13858 exports.markRaw = markRaw;
13859 exports.mergeProps = mergeProps;
13860 exports.nextTick = nextTick;
13861 exports.onActivated = onActivated;
13862 exports.onBeforeMount = onBeforeMount;
13863 exports.onBeforeUnmount = onBeforeUnmount;
13864 exports.onBeforeUpdate = onBeforeUpdate;
13865 exports.onDeactivated = onDeactivated;
13866 exports.onErrorCaptured = onErrorCaptured;
13867 exports.onMounted = onMounted;
13868 exports.onRenderTracked = onRenderTracked;
13869 exports.onRenderTriggered = onRenderTriggered;
13870 exports.onUnmounted = onUnmounted;
13871 exports.onUpdated = onUpdated;
13872 exports.openBlock = openBlock;
13873 exports.popScopeId = popScopeId;
13874 exports.provide = provide;
13875 exports.proxyRefs = proxyRefs;
13876 exports.pushScopeId = pushScopeId;
13877 exports.queuePostFlushCb = queuePostFlushCb;
13878 exports.reactive = reactive;
13879 exports.readonly = readonly;
13880 exports.ref = ref;
13881 exports.registerRuntimeCompiler = registerRuntimeCompiler;
13882 exports.render = render;
13883 exports.renderList = renderList;
13884 exports.renderSlot = renderSlot;
13885 exports.resolveComponent = resolveComponent;
13886 exports.resolveDirective = resolveDirective;
13887 exports.resolveDynamicComponent = resolveDynamicComponent;
13888 exports.resolveTransitionHooks = resolveTransitionHooks;
13889 exports.setBlockTracking = setBlockTracking;
13890 exports.setDevtoolsHook = setDevtoolsHook;
13891 exports.setTransitionHooks = setTransitionHooks;
13892 exports.shallowReactive = shallowReactive;
13893 exports.shallowReadonly = shallowReadonly;
13894 exports.shallowRef = shallowRef;
13895 exports.ssrContextKey = ssrContextKey;
13896 exports.ssrUtils = ssrUtils;
13897 exports.toDisplayString = toDisplayString;
13898 exports.toHandlerKey = toHandlerKey;
13899 exports.toHandlers = toHandlers;
13900 exports.toRaw = toRaw;
13901 exports.toRef = toRef;
13902 exports.toRefs = toRefs;
13903 exports.transformVNodeArgs = transformVNodeArgs;
13904 exports.triggerRef = triggerRef;
13905 exports.unref = unref;
13906 exports.useContext = useContext;
13907 exports.useCssModule = useCssModule;
13908 exports.useCssVars = useCssVars;
13909 exports.useSSRContext = useSSRContext;
13910 exports.useTransitionState = useTransitionState;
13911 exports.vModelCheckbox = vModelCheckbox;
13912 exports.vModelDynamic = vModelDynamic;
13913 exports.vModelRadio = vModelRadio;
13914 exports.vModelSelect = vModelSelect;
13915 exports.vModelText = vModelText;
13916 exports.vShow = vShow;
13917 exports.version = version;
13918 exports.warn = warn;
13919 exports.watch = watch;
13920 exports.watchEffect = watchEffect;
13921 exports.withCtx = withCtx;
13922 exports.withDirectives = withDirectives;
13923 exports.withKeys = withKeys;
13924 exports.withModifiers = withModifiers;
13925 exports.withScopeId = withScopeId;
13926
13927 Object.defineProperty(exports, '__esModule', { value: true });
13928
13929 return exports;
13930
13931}({}));