diff --git a/Dockerfile.embedded b/Dockerfile.embedded
index 378b2f9..4a3e612 100644
--- a/Dockerfile.embedded
+++ b/Dockerfile.embedded
@@ -6,6 +6,7 @@ COPY webui webui
 
 ### Build Vue.js into plain HTML/CSS/JS
 WORKDIR /app/webui
+RUN npm i
 RUN npm run build-embed
 
 FROM golang:1.19.1 AS builder
@@ -30,4 +31,4 @@ WORKDIR /app/
 COPY --from=builder /app/webapi ./
 
 ### Executable command
-CMD ["/app/webapi", "--db-filename", "/data/wasaphoto.db", "--data-path", "/data/data"]
\ No newline at end of file
+CMD ["/app/webapi", "--db-filename", "/data/wasaphoto.db", "--data-path", "/data/data"]
diff --git a/webui/node_modules/vite/dist/node/chunks/dep-94c1417a.js b/webui/node_modules/vite/dist/node/chunks/dep-94c1417a.js
index 94eabfb..f04be91 100644
--- a/webui/node_modules/vite/dist/node/chunks/dep-94c1417a.js
+++ b/webui/node_modules/vite/dist/node/chunks/dep-94c1417a.js
@@ -159,83 +159,83 @@ var pify$1 = pify$2.exports = function (obj, P, opts) {
 
 pify$1.all = pify$1;
 
-var fs = require$$0__default;
-var path$2 = require$$0;
-var pify = pify$2.exports;
-
-var stat = pify(fs.stat);
-var readFile = pify(fs.readFile);
-var resolve = path$2.resolve;
-
-var cache = Object.create(null);
-
-function convert(content, encoding) {
-	if (Buffer.isEncoding(encoding)) {
-		return content.toString(encoding);
-	}
-	return content;
-}
-
-readCache$1.exports = function (path, encoding) {
-	path = resolve(path);
-
-	return stat(path).then(function (stats) {
-		var item = cache[path];
-
-		if (item && item.mtime.getTime() === stats.mtime.getTime()) {
-			return convert(item.content, encoding);
-		}
-
-		return readFile(path).then(function (data) {
-			cache[path] = {
-				mtime: stats.mtime,
-				content: data
-			};
-
-			return convert(data, encoding);
-		});
-	}).catch(function (err) {
-		cache[path] = null;
-		return Promise.reject(err);
-	});
-};
-
-readCache$1.exports.sync = function (path, encoding) {
-	path = resolve(path);
-
-	try {
-		var stats = fs.statSync(path);
-		var item = cache[path];
-
-		if (item && item.mtime.getTime() === stats.mtime.getTime()) {
-			return convert(item.content, encoding);
-		}
-
-		var data = fs.readFileSync(path);
-
-		cache[path] = {
-			mtime: stats.mtime,
-			content: data
-		};
-
-		return convert(data, encoding);
-	} catch (err) {
-		cache[path] = null;
-		throw err;
-	}
-
-};
-
-readCache$1.exports.get = function (path, encoding) {
-	path = resolve(path);
-	if (cache[path]) {
-		return convert(cache[path].content, encoding);
-	}
-	return null;
-};
-
-readCache$1.exports.clear = function () {
-	cache = Object.create(null);
+var fs = require$$0__default;
+var path$2 = require$$0;
+var pify = pify$2.exports;
+
+var stat = pify(fs.stat);
+var readFile = pify(fs.readFile);
+var resolve = path$2.resolve;
+
+var cache = Object.create(null);
+
+function convert(content, encoding) {
+	if (Buffer.isEncoding(encoding)) {
+		return content.toString(encoding);
+	}
+	return content;
+}
+
+readCache$1.exports = function (path, encoding) {
+	path = resolve(path);
+
+	return stat(path).then(function (stats) {
+		var item = cache[path];
+
+		if (item && item.mtime.getTime() === stats.mtime.getTime()) {
+			return convert(item.content, encoding);
+		}
+
+		return readFile(path).then(function (data) {
+			cache[path] = {
+				mtime: stats.mtime,
+				content: data
+			};
+
+			return convert(data, encoding);
+		});
+	}).catch(function (err) {
+		cache[path] = null;
+		return Promise.reject(err);
+	});
+};
+
+readCache$1.exports.sync = function (path, encoding) {
+	path = resolve(path);
+
+	try {
+		var stats = fs.statSync(path);
+		var item = cache[path];
+
+		if (item && item.mtime.getTime() === stats.mtime.getTime()) {
+			return convert(item.content, encoding);
+		}
+
+		var data = fs.readFileSync(path);
+
+		cache[path] = {
+			mtime: stats.mtime,
+			content: data
+		};
+
+		return convert(data, encoding);
+	} catch (err) {
+		cache[path] = null;
+		throw err;
+	}
+
+};
+
+readCache$1.exports.get = function (path, encoding) {
+	path = resolve(path);
+	if (cache[path]) {
+		return convert(cache[path].content, encoding);
+	}
+	return null;
+};
+
+readCache$1.exports.clear = function () {
+	cache = Object.create(null);
 };
 
 const readCache = readCache$1.exports;
diff --git a/webui/node_modules/vite/dist/node/chunks/dep-9d3f225a.js b/webui/node_modules/vite/dist/node/chunks/dep-9d3f225a.js
index 9b3ae72..415fb80 100644
--- a/webui/node_modules/vite/dist/node/chunks/dep-9d3f225a.js
+++ b/webui/node_modules/vite/dist/node/chunks/dep-9d3f225a.js
@@ -22,599 +22,599 @@ function _mergeNamespaces(n, m) {
 
 var compilerDom_cjs$2 = {};
 
-/**
- * Make a map and return a function for checking if a key
- * is in that map.
- * IMPORTANT: all calls of this function must be prefixed with
- * \/\*#\_\_PURE\_\_\*\/
- * So that rollup can tree-shake them if necessary.
- */
-function makeMap(str, expectsLowerCase) {
-    const map = Object.create(null);
-    const list = str.split(',');
-    for (let i = 0; i < list.length; i++) {
-        map[list[i]] = true;
-    }
-    return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
+/**
+ * Make a map and return a function for checking if a key
+ * is in that map.
+ * IMPORTANT: all calls of this function must be prefixed with
+ * \/\*#\_\_PURE\_\_\*\/
+ * So that rollup can tree-shake them if necessary.
+ */
+function makeMap(str, expectsLowerCase) {
+    const map = Object.create(null);
+    const list = str.split(',');
+    for (let i = 0; i < list.length; i++) {
+        map[list[i]] = true;
+    }
+    return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
 }
 
-/**
- * dev only flag -> name mapping
- */
-const PatchFlagNames = {
-    [1 /* TEXT */]: `TEXT`,
-    [2 /* CLASS */]: `CLASS`,
-    [4 /* STYLE */]: `STYLE`,
-    [8 /* PROPS */]: `PROPS`,
-    [16 /* FULL_PROPS */]: `FULL_PROPS`,
-    [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
-    [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
-    [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
-    [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
-    [512 /* NEED_PATCH */]: `NEED_PATCH`,
-    [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
-    [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
-    [-1 /* HOISTED */]: `HOISTED`,
-    [-2 /* BAIL */]: `BAIL`
+/**
+ * dev only flag -> name mapping
+ */
+const PatchFlagNames = {
+    [1 /* TEXT */]: `TEXT`,
+    [2 /* CLASS */]: `CLASS`,
+    [4 /* STYLE */]: `STYLE`,
+    [8 /* PROPS */]: `PROPS`,
+    [16 /* FULL_PROPS */]: `FULL_PROPS`,
+    [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
+    [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
+    [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
+    [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
+    [512 /* NEED_PATCH */]: `NEED_PATCH`,
+    [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
+    [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
+    [-1 /* HOISTED */]: `HOISTED`,
+    [-2 /* BAIL */]: `BAIL`
 };
 
-/**
- * Dev only
- */
-const slotFlagsText = {
-    [1 /* STABLE */]: 'STABLE',
-    [2 /* DYNAMIC */]: 'DYNAMIC',
-    [3 /* FORWARDED */]: 'FORWARDED'
+/**
+ * Dev only
+ */
+const slotFlagsText = {
+    [1 /* STABLE */]: 'STABLE',
+    [2 /* DYNAMIC */]: 'DYNAMIC',
+    [3 /* FORWARDED */]: 'FORWARDED'
 };
 
-const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
-    'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
-    'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
+const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
+    'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
+    'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
 const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
 
-const range = 2;
-function generateCodeFrame(source, start = 0, end = source.length) {
-    // Split the content into individual lines but capture the newline sequence
-    // that separated each line. This is important because the actual sequence is
-    // needed to properly take into account the full line length for offset
-    // comparison
-    let lines = source.split(/(\r?\n)/);
-    // Separate the lines and newline sequences into separate arrays for easier referencing
-    const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
-    lines = lines.filter((_, idx) => idx % 2 === 0);
-    let count = 0;
-    const res = [];
-    for (let i = 0; i < lines.length; i++) {
-        count +=
-            lines[i].length +
-                ((newlineSequences[i] && newlineSequences[i].length) || 0);
-        if (count >= start) {
-            for (let j = i - range; j <= i + range || end > count; j++) {
-                if (j < 0 || j >= lines.length)
-                    continue;
-                const line = j + 1;
-                res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}|  ${lines[j]}`);
-                const lineLength = lines[j].length;
-                const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
-                if (j === i) {
-                    // push underline
-                    const pad = start - (count - (lineLength + newLineSeqLength));
-                    const length = Math.max(1, end > count ? lineLength - pad : end - start);
-                    res.push(`   |  ` + ' '.repeat(pad) + '^'.repeat(length));
-                }
-                else if (j > i) {
-                    if (end > count) {
-                        const length = Math.max(Math.min(end - count, lineLength), 1);
-                        res.push(`   |  ` + '^'.repeat(length));
-                    }
-                    count += lineLength + newLineSeqLength;
-                }
-            }
-            break;
-        }
-    }
-    return res.join('\n');
+const range = 2;
+function generateCodeFrame(source, start = 0, end = source.length) {
+    // Split the content into individual lines but capture the newline sequence
+    // that separated each line. This is important because the actual sequence is
+    // needed to properly take into account the full line length for offset
+    // comparison
+    let lines = source.split(/(\r?\n)/);
+    // Separate the lines and newline sequences into separate arrays for easier referencing
+    const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
+    lines = lines.filter((_, idx) => idx % 2 === 0);
+    let count = 0;
+    const res = [];
+    for (let i = 0; i < lines.length; i++) {
+        count +=
+            lines[i].length +
+                ((newlineSequences[i] && newlineSequences[i].length) || 0);
+        if (count >= start) {
+            for (let j = i - range; j <= i + range || end > count; j++) {
+                if (j < 0 || j >= lines.length)
+                    continue;
+                const line = j + 1;
+                res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}|  ${lines[j]}`);
+                const lineLength = lines[j].length;
+                const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
+                if (j === i) {
+                    // push underline
+                    const pad = start - (count - (lineLength + newLineSeqLength));
+                    const length = Math.max(1, end > count ? lineLength - pad : end - start);
+                    res.push(`   |  ` + ' '.repeat(pad) + '^'.repeat(length));
+                }
+                else if (j > i) {
+                    if (end > count) {
+                        const length = Math.max(Math.min(end - count, lineLength), 1);
+                        res.push(`   |  ` + '^'.repeat(length));
+                    }
+                    count += lineLength + newLineSeqLength;
+                }
+            }
+            break;
+        }
+    }
+    return res.join('\n');
 }
 
-/**
- * On the client we only need to offer special cases for boolean attributes that
- * have different names from their corresponding dom properties:
- * - itemscope -> N/A
- * - allowfullscreen -> allowFullscreen
- * - formnovalidate -> formNoValidate
- * - ismap -> isMap
- * - nomodule -> noModule
- * - novalidate -> noValidate
- * - readonly -> readOnly
- */
-const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
-const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
-/**
- * The full list is needed during SSR to produce the correct initial markup.
- */
-const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs +
-    `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` +
-    `loop,open,required,reversed,scoped,seamless,` +
-    `checked,muted,multiple,selected`);
-/**
- * Boolean attributes should be included if the value is truthy or ''.
- * e.g. `<select multiple>` compiles to `{ multiple: '' }`
- */
-function includeBooleanAttr(value) {
-    return !!value || value === '';
-}
-const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/;
-const attrValidationCache = {};
-function isSSRSafeAttrName(name) {
-    if (attrValidationCache.hasOwnProperty(name)) {
-        return attrValidationCache[name];
-    }
-    const isUnsafe = unsafeAttrCharRE.test(name);
-    if (isUnsafe) {
-        console.error(`unsafe attribute name: ${name}`);
-    }
-    return (attrValidationCache[name] = !isUnsafe);
-}
-const propsToAttrMap = {
-    acceptCharset: 'accept-charset',
-    className: 'class',
-    htmlFor: 'for',
-    httpEquiv: 'http-equiv'
-};
-/**
- * CSS properties that accept plain numbers
- */
-const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` +
-    `border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` +
-    `columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` +
-    `grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` +
-    `grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` +
-    `line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` +
-    // SVG
-    `fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` +
-    `stroke-miterlimit,stroke-opacity,stroke-width`);
-/**
- * Known attributes, this is used for stringification of runtime static nodes
- * so that we don't stringify bindings that cannot be set from HTML.
- * Don't also forget to allow `data-*` and `aria-*`!
- * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
- */
-const isKnownHtmlAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` +
-    `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` +
-    `border,buffered,capture,challenge,charset,checked,cite,class,code,` +
-    `codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` +
-    `coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` +
-    `disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` +
-    `formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` +
-    `height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` +
-    `ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` +
-    `manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` +
-    `open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` +
-    `referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` +
-    `selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` +
-    `start,step,style,summary,tabindex,target,title,translate,type,usemap,` +
-    `value,width,wrap`);
-/**
- * Generated from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
- */
-const isKnownSvgAttr = /*#__PURE__*/ makeMap(`xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,` +
-    `arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,` +
-    `baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,` +
-    `clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,` +
-    `color-interpolation-filters,color-profile,color-rendering,` +
-    `contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,` +
-    `descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,` +
-    `dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,` +
-    `fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,` +
-    `font-family,font-size,font-size-adjust,font-stretch,font-style,` +
-    `font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,` +
-    `glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,` +
-    `gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,` +
-    `horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,` +
-    `k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,` +
-    `lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,` +
-    `marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,` +
-    `mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,` +
-    `name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,` +
-    `overflow,overline-position,overline-thickness,panose-1,paint-order,path,` +
-    `pathLength,patternContentUnits,patternTransform,patternUnits,ping,` +
-    `pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,` +
-    `preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,` +
-    `rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,` +
-    `restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,` +
-    `specularConstant,specularExponent,speed,spreadMethod,startOffset,` +
-    `stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,` +
-    `strikethrough-position,strikethrough-thickness,string,stroke,` +
-    `stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,` +
-    `stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,` +
-    `systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,` +
-    `text-decoration,text-rendering,textLength,to,transform,transform-origin,` +
-    `type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,` +
-    `unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,` +
-    `v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,` +
-    `vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,` +
-    `writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,` +
-    `xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,` +
+/**
+ * On the client we only need to offer special cases for boolean attributes that
+ * have different names from their corresponding dom properties:
+ * - itemscope -> N/A
+ * - allowfullscreen -> allowFullscreen
+ * - formnovalidate -> formNoValidate
+ * - ismap -> isMap
+ * - nomodule -> noModule
+ * - novalidate -> noValidate
+ * - readonly -> readOnly
+ */
+const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
+const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
+/**
+ * The full list is needed during SSR to produce the correct initial markup.
+ */
+const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs +
+    `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` +
+    `loop,open,required,reversed,scoped,seamless,` +
+    `checked,muted,multiple,selected`);
+/**
+ * Boolean attributes should be included if the value is truthy or ''.
+ * e.g. `<select multiple>` compiles to `{ multiple: '' }`
+ */
+function includeBooleanAttr(value) {
+    return !!value || value === '';
+}
+const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/;
+const attrValidationCache = {};
+function isSSRSafeAttrName(name) {
+    if (attrValidationCache.hasOwnProperty(name)) {
+        return attrValidationCache[name];
+    }
+    const isUnsafe = unsafeAttrCharRE.test(name);
+    if (isUnsafe) {
+        console.error(`unsafe attribute name: ${name}`);
+    }
+    return (attrValidationCache[name] = !isUnsafe);
+}
+const propsToAttrMap = {
+    acceptCharset: 'accept-charset',
+    className: 'class',
+    htmlFor: 'for',
+    httpEquiv: 'http-equiv'
+};
+/**
+ * CSS properties that accept plain numbers
+ */
+const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` +
+    `border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` +
+    `columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` +
+    `grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` +
+    `grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` +
+    `line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` +
+    // SVG
+    `fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` +
+    `stroke-miterlimit,stroke-opacity,stroke-width`);
+/**
+ * Known attributes, this is used for stringification of runtime static nodes
+ * so that we don't stringify bindings that cannot be set from HTML.
+ * Don't also forget to allow `data-*` and `aria-*`!
+ * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
+ */
+const isKnownHtmlAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` +
+    `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` +
+    `border,buffered,capture,challenge,charset,checked,cite,class,code,` +
+    `codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` +
+    `coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` +
+    `disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` +
+    `formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` +
+    `height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` +
+    `ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` +
+    `manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` +
+    `open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` +
+    `referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` +
+    `selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` +
+    `start,step,style,summary,tabindex,target,title,translate,type,usemap,` +
+    `value,width,wrap`);
+/**
+ * Generated from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
+ */
+const isKnownSvgAttr = /*#__PURE__*/ makeMap(`xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,` +
+    `arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,` +
+    `baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,` +
+    `clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,` +
+    `color-interpolation-filters,color-profile,color-rendering,` +
+    `contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,` +
+    `descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,` +
+    `dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,` +
+    `fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,` +
+    `font-family,font-size,font-size-adjust,font-stretch,font-style,` +
+    `font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,` +
+    `glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,` +
+    `gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,` +
+    `horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,` +
+    `k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,` +
+    `lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,` +
+    `marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,` +
+    `mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,` +
+    `name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,` +
+    `overflow,overline-position,overline-thickness,panose-1,paint-order,path,` +
+    `pathLength,patternContentUnits,patternTransform,patternUnits,ping,` +
+    `pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,` +
+    `preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,` +
+    `rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,` +
+    `restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,` +
+    `specularConstant,specularExponent,speed,spreadMethod,startOffset,` +
+    `stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,` +
+    `strikethrough-position,strikethrough-thickness,string,stroke,` +
+    `stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,` +
+    `stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,` +
+    `systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,` +
+    `text-decoration,text-rendering,textLength,to,transform,transform-origin,` +
+    `type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,` +
+    `unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,` +
+    `v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,` +
+    `vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,` +
+    `writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,` +
+    `xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,` +
     `xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan`);
 
-function normalizeStyle(value) {
-    if (isArray(value)) {
-        const res = {};
-        for (let i = 0; i < value.length; i++) {
-            const item = value[i];
-            const normalized = isString(item)
-                ? parseStringStyle(item)
-                : normalizeStyle(item);
-            if (normalized) {
-                for (const key in normalized) {
-                    res[key] = normalized[key];
-                }
-            }
-        }
-        return res;
-    }
-    else if (isString(value)) {
-        return value;
-    }
-    else if (isObject(value)) {
-        return value;
-    }
-}
-const listDelimiterRE = /;(?![^(]*\))/g;
-const propertyDelimiterRE = /:(.+)/;
-function parseStringStyle(cssText) {
-    const ret = {};
-    cssText.split(listDelimiterRE).forEach(item => {
-        if (item) {
-            const tmp = item.split(propertyDelimiterRE);
-            tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
-        }
-    });
-    return ret;
-}
-function stringifyStyle(styles) {
-    let ret = '';
-    if (!styles || isString(styles)) {
-        return ret;
-    }
-    for (const key in styles) {
-        const value = styles[key];
-        const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key);
-        if (isString(value) ||
-            (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) {
-            // only render valid values
-            ret += `${normalizedKey}:${value};`;
-        }
-    }
-    return ret;
-}
-function normalizeClass(value) {
-    let res = '';
-    if (isString(value)) {
-        res = value;
-    }
-    else if (isArray(value)) {
-        for (let i = 0; i < value.length; i++) {
-            const normalized = normalizeClass(value[i]);
-            if (normalized) {
-                res += normalized + ' ';
-            }
-        }
-    }
-    else if (isObject(value)) {
-        for (const name in value) {
-            if (value[name]) {
-                res += name + ' ';
-            }
-        }
-    }
-    return res.trim();
-}
-function normalizeProps(props) {
-    if (!props)
-        return null;
-    let { class: klass, style } = props;
-    if (klass && !isString(klass)) {
-        props.class = normalizeClass(klass);
-    }
-    if (style) {
-        props.style = normalizeStyle(style);
-    }
-    return props;
+function normalizeStyle(value) {
+    if (isArray(value)) {
+        const res = {};
+        for (let i = 0; i < value.length; i++) {
+            const item = value[i];
+            const normalized = isString(item)
+                ? parseStringStyle(item)
+                : normalizeStyle(item);
+            if (normalized) {
+                for (const key in normalized) {
+                    res[key] = normalized[key];
+                }
+            }
+        }
+        return res;
+    }
+    else if (isString(value)) {
+        return value;
+    }
+    else if (isObject(value)) {
+        return value;
+    }
+}
+const listDelimiterRE = /;(?![^(]*\))/g;
+const propertyDelimiterRE = /:(.+)/;
+function parseStringStyle(cssText) {
+    const ret = {};
+    cssText.split(listDelimiterRE).forEach(item => {
+        if (item) {
+            const tmp = item.split(propertyDelimiterRE);
+            tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
+        }
+    });
+    return ret;
+}
+function stringifyStyle(styles) {
+    let ret = '';
+    if (!styles || isString(styles)) {
+        return ret;
+    }
+    for (const key in styles) {
+        const value = styles[key];
+        const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key);
+        if (isString(value) ||
+            (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) {
+            // only render valid values
+            ret += `${normalizedKey}:${value};`;
+        }
+    }
+    return ret;
+}
+function normalizeClass(value) {
+    let res = '';
+    if (isString(value)) {
+        res = value;
+    }
+    else if (isArray(value)) {
+        for (let i = 0; i < value.length; i++) {
+            const normalized = normalizeClass(value[i]);
+            if (normalized) {
+                res += normalized + ' ';
+            }
+        }
+    }
+    else if (isObject(value)) {
+        for (const name in value) {
+            if (value[name]) {
+                res += name + ' ';
+            }
+        }
+    }
+    return res.trim();
+}
+function normalizeProps(props) {
+    if (!props)
+        return null;
+    let { class: klass, style } = props;
+    if (klass && !isString(klass)) {
+        props.class = normalizeClass(klass);
+    }
+    if (style) {
+        props.style = normalizeStyle(style);
+    }
+    return props;
 }
 
-// These tag configs are shared between compiler-dom and runtime-dom, so they
-// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
-const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
-    'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
-    'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
-    'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
-    'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
-    'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
-    'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
-    'option,output,progress,select,textarea,details,dialog,menu,' +
-    'summary,template,blockquote,iframe,tfoot';
-// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
-const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
-    'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
-    'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
-    'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
-    'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
-    'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
-    'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
-    'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
-    'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
-    'text,textPath,title,tspan,unknown,use,view';
-const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
-/**
- * Compiler only.
- * Do NOT use in runtime code paths unless behind `(process.env.NODE_ENV !== 'production')` flag.
- */
-const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
-/**
- * Compiler only.
- * Do NOT use in runtime code paths unless behind `(process.env.NODE_ENV !== 'production')` flag.
- */
-const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
-/**
- * Compiler only.
- * Do NOT use in runtime code paths unless behind `(process.env.NODE_ENV !== 'production')` flag.
- */
+// These tag configs are shared between compiler-dom and runtime-dom, so they
+// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
+const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
+    'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
+    'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
+    'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
+    'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
+    'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
+    'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
+    'option,output,progress,select,textarea,details,dialog,menu,' +
+    'summary,template,blockquote,iframe,tfoot';
+// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
+const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
+    'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
+    'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
+    'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
+    'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
+    'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
+    'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
+    'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
+    'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
+    'text,textPath,title,tspan,unknown,use,view';
+const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
+/**
+ * Compiler only.
+ * Do NOT use in runtime code paths unless behind `(process.env.NODE_ENV !== 'production')` flag.
+ */
+const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
+/**
+ * Compiler only.
+ * Do NOT use in runtime code paths unless behind `(process.env.NODE_ENV !== 'production')` flag.
+ */
+const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
+/**
+ * Compiler only.
+ * Do NOT use in runtime code paths unless behind `(process.env.NODE_ENV !== 'production')` flag.
+ */
 const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
 
-const escapeRE = /["'&<>]/;
-function escapeHtml(string) {
-    const str = '' + string;
-    const match = escapeRE.exec(str);
-    if (!match) {
-        return str;
-    }
-    let html = '';
-    let escaped;
-    let index;
-    let lastIndex = 0;
-    for (index = match.index; index < str.length; index++) {
-        switch (str.charCodeAt(index)) {
-            case 34: // "
-                escaped = '&quot;';
-                break;
-            case 38: // &
-                escaped = '&amp;';
-                break;
-            case 39: // '
-                escaped = '&#39;';
-                break;
-            case 60: // <
-                escaped = '&lt;';
-                break;
-            case 62: // >
-                escaped = '&gt;';
-                break;
-            default:
-                continue;
-        }
-        if (lastIndex !== index) {
-            html += str.slice(lastIndex, index);
-        }
-        lastIndex = index + 1;
-        html += escaped;
-    }
-    return lastIndex !== index ? html + str.slice(lastIndex, index) : html;
-}
-// https://www.w3.org/TR/html52/syntax.html#comments
-const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g;
-function escapeHtmlComment(src) {
-    return src.replace(commentStripRE, '');
+const escapeRE = /["'&<>]/;
+function escapeHtml(string) {
+    const str = '' + string;
+    const match = escapeRE.exec(str);
+    if (!match) {
+        return str;
+    }
+    let html = '';
+    let escaped;
+    let index;
+    let lastIndex = 0;
+    for (index = match.index; index < str.length; index++) {
+        switch (str.charCodeAt(index)) {
+            case 34: // "
+                escaped = '&quot;';
+                break;
+            case 38: // &
+                escaped = '&amp;';
+                break;
+            case 39: // '
+                escaped = '&#39;';
+                break;
+            case 60: // <
+                escaped = '&lt;';
+                break;
+            case 62: // >
+                escaped = '&gt;';
+                break;
+            default:
+                continue;
+        }
+        if (lastIndex !== index) {
+            html += str.slice(lastIndex, index);
+        }
+        lastIndex = index + 1;
+        html += escaped;
+    }
+    return lastIndex !== index ? html + str.slice(lastIndex, index) : html;
+}
+// https://www.w3.org/TR/html52/syntax.html#comments
+const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g;
+function escapeHtmlComment(src) {
+    return src.replace(commentStripRE, '');
 }
 
-function looseCompareArrays(a, b) {
-    if (a.length !== b.length)
-        return false;
-    let equal = true;
-    for (let i = 0; equal && i < a.length; i++) {
-        equal = looseEqual(a[i], b[i]);
-    }
-    return equal;
-}
-function looseEqual(a, b) {
-    if (a === b)
-        return true;
-    let aValidType = isDate(a);
-    let bValidType = isDate(b);
-    if (aValidType || bValidType) {
-        return aValidType && bValidType ? a.getTime() === b.getTime() : false;
-    }
-    aValidType = isSymbol(a);
-    bValidType = isSymbol(b);
-    if (aValidType || bValidType) {
-        return a === b;
-    }
-    aValidType = isArray(a);
-    bValidType = isArray(b);
-    if (aValidType || bValidType) {
-        return aValidType && bValidType ? looseCompareArrays(a, b) : false;
-    }
-    aValidType = isObject(a);
-    bValidType = isObject(b);
-    if (aValidType || bValidType) {
-        /* istanbul ignore if: this if will probably never be called */
-        if (!aValidType || !bValidType) {
-            return false;
-        }
-        const aKeysCount = Object.keys(a).length;
-        const bKeysCount = Object.keys(b).length;
-        if (aKeysCount !== bKeysCount) {
-            return false;
-        }
-        for (const key in a) {
-            const aHasKey = a.hasOwnProperty(key);
-            const bHasKey = b.hasOwnProperty(key);
-            if ((aHasKey && !bHasKey) ||
-                (!aHasKey && bHasKey) ||
-                !looseEqual(a[key], b[key])) {
-                return false;
-            }
-        }
-    }
-    return String(a) === String(b);
-}
-function looseIndexOf(arr, val) {
-    return arr.findIndex(item => looseEqual(item, val));
+function looseCompareArrays(a, b) {
+    if (a.length !== b.length)
+        return false;
+    let equal = true;
+    for (let i = 0; equal && i < a.length; i++) {
+        equal = looseEqual(a[i], b[i]);
+    }
+    return equal;
+}
+function looseEqual(a, b) {
+    if (a === b)
+        return true;
+    let aValidType = isDate(a);
+    let bValidType = isDate(b);
+    if (aValidType || bValidType) {
+        return aValidType && bValidType ? a.getTime() === b.getTime() : false;
+    }
+    aValidType = isSymbol(a);
+    bValidType = isSymbol(b);
+    if (aValidType || bValidType) {
+        return a === b;
+    }
+    aValidType = isArray(a);
+    bValidType = isArray(b);
+    if (aValidType || bValidType) {
+        return aValidType && bValidType ? looseCompareArrays(a, b) : false;
+    }
+    aValidType = isObject(a);
+    bValidType = isObject(b);
+    if (aValidType || bValidType) {
+        /* istanbul ignore if: this if will probably never be called */
+        if (!aValidType || !bValidType) {
+            return false;
+        }
+        const aKeysCount = Object.keys(a).length;
+        const bKeysCount = Object.keys(b).length;
+        if (aKeysCount !== bKeysCount) {
+            return false;
+        }
+        for (const key in a) {
+            const aHasKey = a.hasOwnProperty(key);
+            const bHasKey = b.hasOwnProperty(key);
+            if ((aHasKey && !bHasKey) ||
+                (!aHasKey && bHasKey) ||
+                !looseEqual(a[key], b[key])) {
+                return false;
+            }
+        }
+    }
+    return String(a) === String(b);
+}
+function looseIndexOf(arr, val) {
+    return arr.findIndex(item => looseEqual(item, val));
 }
 
-/**
- * For converting {{ interpolation }} values to displayed strings.
- * @private
- */
-const toDisplayString = (val) => {
-    return isString(val)
-        ? val
-        : val == null
-            ? ''
-            : isArray(val) ||
-                (isObject(val) &&
-                    (val.toString === objectToString || !isFunction(val.toString)))
-                ? JSON.stringify(val, replacer, 2)
-                : String(val);
-};
-const replacer = (_key, val) => {
-    // can't use isRef here since @vue/shared has no deps
-    if (val && val.__v_isRef) {
-        return replacer(_key, val.value);
-    }
-    else if (isMap(val)) {
-        return {
-            [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
-                entries[`${key} =>`] = val;
-                return entries;
-            }, {})
-        };
-    }
-    else if (isSet(val)) {
-        return {
-            [`Set(${val.size})`]: [...val.values()]
-        };
-    }
-    else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
-        return String(val);
-    }
-    return val;
+/**
+ * For converting {{ interpolation }} values to displayed strings.
+ * @private
+ */
+const toDisplayString = (val) => {
+    return isString(val)
+        ? val
+        : val == null
+            ? ''
+            : isArray(val) ||
+                (isObject(val) &&
+                    (val.toString === objectToString || !isFunction(val.toString)))
+                ? JSON.stringify(val, replacer, 2)
+                : String(val);
+};
+const replacer = (_key, val) => {
+    // can't use isRef here since @vue/shared has no deps
+    if (val && val.__v_isRef) {
+        return replacer(_key, val.value);
+    }
+    else if (isMap(val)) {
+        return {
+            [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
+                entries[`${key} =>`] = val;
+                return entries;
+            }, {})
+        };
+    }
+    else if (isSet(val)) {
+        return {
+            [`Set(${val.size})`]: [...val.values()]
+        };
+    }
+    else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
+        return String(val);
+    }
+    return val;
 };
 
-const EMPTY_OBJ = (process.env.NODE_ENV !== 'production')
-    ? Object.freeze({})
-    : {};
-const EMPTY_ARR = (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];
-const NOOP = () => { };
-/**
- * Always return false.
- */
-const NO = () => false;
-const onRE = /^on[^a-z]/;
-const isOn = (key) => onRE.test(key);
-const isModelListener = (key) => key.startsWith('onUpdate:');
-const extend = Object.assign;
-const remove = (arr, el) => {
-    const i = arr.indexOf(el);
-    if (i > -1) {
-        arr.splice(i, 1);
-    }
-};
-const hasOwnProperty = Object.prototype.hasOwnProperty;
-const hasOwn = (val, key) => hasOwnProperty.call(val, key);
-const isArray = Array.isArray;
-const isMap = (val) => toTypeString(val) === '[object Map]';
-const isSet = (val) => toTypeString(val) === '[object Set]';
-const isDate = (val) => toTypeString(val) === '[object Date]';
-const isFunction = (val) => typeof val === 'function';
-const isString = (val) => typeof val === 'string';
-const isSymbol = (val) => typeof val === 'symbol';
-const isObject = (val) => val !== null && typeof val === 'object';
-const isPromise = (val) => {
-    return isObject(val) && isFunction(val.then) && isFunction(val.catch);
-};
-const objectToString = Object.prototype.toString;
-const toTypeString = (value) => objectToString.call(value);
-const toRawType = (value) => {
-    // extract "RawType" from strings like "[object RawType]"
-    return toTypeString(value).slice(8, -1);
-};
-const isPlainObject = (val) => toTypeString(val) === '[object Object]';
-const isIntegerKey = (key) => isString(key) &&
-    key !== 'NaN' &&
-    key[0] !== '-' &&
-    '' + parseInt(key, 10) === key;
-const isReservedProp = /*#__PURE__*/ makeMap(
-// the leading comma is intentional so empty string "" is also included
-',key,ref,ref_for,ref_key,' +
-    'onVnodeBeforeMount,onVnodeMounted,' +
-    'onVnodeBeforeUpdate,onVnodeUpdated,' +
-    'onVnodeBeforeUnmount,onVnodeUnmounted');
-const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
-const cacheStringFunction$1 = (fn) => {
-    const cache = Object.create(null);
-    return ((str) => {
-        const hit = cache[str];
-        return hit || (cache[str] = fn(str));
-    });
-};
-const camelizeRE$1 = /-(\w)/g;
-/**
- * @private
- */
-const camelize$1 = cacheStringFunction$1((str) => {
-    return str.replace(camelizeRE$1, (_, c) => (c ? c.toUpperCase() : ''));
-});
-const hyphenateRE = /\B([A-Z])/g;
-/**
- * @private
- */
-const hyphenate = cacheStringFunction$1((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
-/**
- * @private
- */
-const capitalize = cacheStringFunction$1((str) => str.charAt(0).toUpperCase() + str.slice(1));
-/**
- * @private
- */
-const toHandlerKey = cacheStringFunction$1((str) => str ? `on${capitalize(str)}` : ``);
-// compare whether a value has changed, accounting for NaN.
-const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
-const invokeArrayFns = (fns, arg) => {
-    for (let i = 0; i < fns.length; i++) {
-        fns[i](arg);
-    }
-};
-const def = (obj, key, value) => {
-    Object.defineProperty(obj, key, {
-        configurable: true,
-        enumerable: false,
-        value
-    });
-};
-const toNumber = (val) => {
-    const n = parseFloat(val);
-    return isNaN(n) ? val : n;
-};
-let _globalThis;
-const getGlobalThis = () => {
-    return (_globalThis ||
-        (_globalThis =
-            typeof globalThis !== 'undefined'
-                ? globalThis
-                : typeof self !== 'undefined'
-                    ? self
-                    : typeof window !== 'undefined'
-                        ? window
-                        : typeof global !== 'undefined'
-                            ? global
-                            : {}));
-};
-const identRE = /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/;
-function genPropsAccessExp(name) {
-    return identRE.test(name)
-        ? `__props.${name}`
-        : `__props[${JSON.stringify(name)}]`;
+const EMPTY_OBJ = (process.env.NODE_ENV !== 'production')
+    ? Object.freeze({})
+    : {};
+const EMPTY_ARR = (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];
+const NOOP = () => { };
+/**
+ * Always return false.
+ */
+const NO = () => false;
+const onRE = /^on[^a-z]/;
+const isOn = (key) => onRE.test(key);
+const isModelListener = (key) => key.startsWith('onUpdate:');
+const extend = Object.assign;
+const remove = (arr, el) => {
+    const i = arr.indexOf(el);
+    if (i > -1) {
+        arr.splice(i, 1);
+    }
+};
+const hasOwnProperty = Object.prototype.hasOwnProperty;
+const hasOwn = (val, key) => hasOwnProperty.call(val, key);
+const isArray = Array.isArray;
+const isMap = (val) => toTypeString(val) === '[object Map]';
+const isSet = (val) => toTypeString(val) === '[object Set]';
+const isDate = (val) => toTypeString(val) === '[object Date]';
+const isFunction = (val) => typeof val === 'function';
+const isString = (val) => typeof val === 'string';
+const isSymbol = (val) => typeof val === 'symbol';
+const isObject = (val) => val !== null && typeof val === 'object';
+const isPromise = (val) => {
+    return isObject(val) && isFunction(val.then) && isFunction(val.catch);
+};
+const objectToString = Object.prototype.toString;
+const toTypeString = (value) => objectToString.call(value);
+const toRawType = (value) => {
+    // extract "RawType" from strings like "[object RawType]"
+    return toTypeString(value).slice(8, -1);
+};
+const isPlainObject = (val) => toTypeString(val) === '[object Object]';
+const isIntegerKey = (key) => isString(key) &&
+    key !== 'NaN' &&
+    key[0] !== '-' &&
+    '' + parseInt(key, 10) === key;
+const isReservedProp = /*#__PURE__*/ makeMap(
+// the leading comma is intentional so empty string "" is also included
+',key,ref,ref_for,ref_key,' +
+    'onVnodeBeforeMount,onVnodeMounted,' +
+    'onVnodeBeforeUpdate,onVnodeUpdated,' +
+    'onVnodeBeforeUnmount,onVnodeUnmounted');
+const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
+const cacheStringFunction$1 = (fn) => {
+    const cache = Object.create(null);
+    return ((str) => {
+        const hit = cache[str];
+        return hit || (cache[str] = fn(str));
+    });
+};
+const camelizeRE$1 = /-(\w)/g;
+/**
+ * @private
+ */
+const camelize$1 = cacheStringFunction$1((str) => {
+    return str.replace(camelizeRE$1, (_, c) => (c ? c.toUpperCase() : ''));
+});
+const hyphenateRE = /\B([A-Z])/g;
+/**
+ * @private
+ */
+const hyphenate = cacheStringFunction$1((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
+/**
+ * @private
+ */
+const capitalize = cacheStringFunction$1((str) => str.charAt(0).toUpperCase() + str.slice(1));
+/**
+ * @private
+ */
+const toHandlerKey = cacheStringFunction$1((str) => str ? `on${capitalize(str)}` : ``);
+// compare whether a value has changed, accounting for NaN.
+const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
+const invokeArrayFns = (fns, arg) => {
+    for (let i = 0; i < fns.length; i++) {
+        fns[i](arg);
+    }
+};
+const def = (obj, key, value) => {
+    Object.defineProperty(obj, key, {
+        configurable: true,
+        enumerable: false,
+        value
+    });
+};
+const toNumber = (val) => {
+    const n = parseFloat(val);
+    return isNaN(n) ? val : n;
+};
+let _globalThis;
+const getGlobalThis = () => {
+    return (_globalThis ||
+        (_globalThis =
+            typeof globalThis !== 'undefined'
+                ? globalThis
+                : typeof self !== 'undefined'
+                    ? self
+                    : typeof window !== 'undefined'
+                        ? window
+                        : typeof global !== 'undefined'
+                            ? global
+                            : {}));
+};
+const identRE = /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/;
+function genPropsAccessExp(name) {
+    return identRE.test(name)
+        ? `__props.${name}`
+        : `__props[${JSON.stringify(name)}]`;
 }
 
 var shared_esmBundler = {
@@ -682,4855 +682,4855 @@ var shared_esmBundler = {
     toTypeString: toTypeString
 };
 
-function defaultOnError(error) {
-    throw error;
-}
-function defaultOnWarn(msg) {
-    (process.env.NODE_ENV !== 'production') && console.warn(`[Vue warn] ${msg.message}`);
-}
-function createCompilerError(code, loc, messages, additionalMessage) {
-    const msg = (process.env.NODE_ENV !== 'production') || !true
-        ? (messages || errorMessages)[code] + (additionalMessage || ``)
-        : code;
-    const error = new SyntaxError(String(msg));
-    error.code = code;
-    error.loc = loc;
-    return error;
-}
-const errorMessages = {
-    // parse errors
-    [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
-    [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
-    [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
-    [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
-    [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
-    [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
-    [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
-    [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
-    [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
-    [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
-    [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
-    [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
-    [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
-    [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
-    [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
-    [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
-    [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
-    [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
-    [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
-    [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
-    [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
-    [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
-    [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
-    // Vue-specific parse errors
-    [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
-    [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
-    [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
-    [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
-        'Note that dynamic directive argument cannot contain spaces.',
-    [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
-    // transform errors
-    [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
-    [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
-    [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
-    [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
-    [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
-    [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
-    [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
-    [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
-    [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
-    [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
-        `When there are multiple named slots, all slots should use <template> ` +
-        `syntax to avoid scope ambiguity.`,
-    [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
-    [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
-        `default slot. These children will be ignored.`,
-    [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
-    [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
-    [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
-    [43 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
-    [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
-    [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
-    // generic errors
-    [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
-    [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
-    [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
-    [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
-    // just to fulfill types
-    [50 /* __EXTEND_POINT__ */]: ``
+function defaultOnError(error) {
+    throw error;
+}
+function defaultOnWarn(msg) {
+    (process.env.NODE_ENV !== 'production') && console.warn(`[Vue warn] ${msg.message}`);
+}
+function createCompilerError(code, loc, messages, additionalMessage) {
+    const msg = (process.env.NODE_ENV !== 'production') || !true
+        ? (messages || errorMessages)[code] + (additionalMessage || ``)
+        : code;
+    const error = new SyntaxError(String(msg));
+    error.code = code;
+    error.loc = loc;
+    return error;
+}
+const errorMessages = {
+    // parse errors
+    [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
+    [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
+    [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
+    [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
+    [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
+    [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
+    [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
+    [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
+    [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
+    [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
+    [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
+    [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
+    [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
+    [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
+    [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
+    [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
+    [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
+    [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
+    [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
+    [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
+    [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
+    [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
+    [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
+    // Vue-specific parse errors
+    [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
+    [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
+    [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
+    [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
+        'Note that dynamic directive argument cannot contain spaces.',
+    [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
+    // transform errors
+    [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
+    [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
+    [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
+    [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
+    [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
+    [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
+    [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
+    [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
+    [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
+    [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
+        `When there are multiple named slots, all slots should use <template> ` +
+        `syntax to avoid scope ambiguity.`,
+    [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
+    [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
+        `default slot. These children will be ignored.`,
+    [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
+    [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
+    [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
+    [43 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
+    [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
+    [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
+    // generic errors
+    [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
+    [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
+    [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
+    [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
+    // just to fulfill types
+    [50 /* __EXTEND_POINT__ */]: ``
 };
 
-const FRAGMENT = Symbol((process.env.NODE_ENV !== 'production') ? `Fragment` : ``);
-const TELEPORT = Symbol((process.env.NODE_ENV !== 'production') ? `Teleport` : ``);
-const SUSPENSE = Symbol((process.env.NODE_ENV !== 'production') ? `Suspense` : ``);
-const KEEP_ALIVE = Symbol((process.env.NODE_ENV !== 'production') ? `KeepAlive` : ``);
-const BASE_TRANSITION = Symbol((process.env.NODE_ENV !== 'production') ? `BaseTransition` : ``);
-const OPEN_BLOCK = Symbol((process.env.NODE_ENV !== 'production') ? `openBlock` : ``);
-const CREATE_BLOCK = Symbol((process.env.NODE_ENV !== 'production') ? `createBlock` : ``);
-const CREATE_ELEMENT_BLOCK = Symbol((process.env.NODE_ENV !== 'production') ? `createElementBlock` : ``);
-const CREATE_VNODE = Symbol((process.env.NODE_ENV !== 'production') ? `createVNode` : ``);
-const CREATE_ELEMENT_VNODE = Symbol((process.env.NODE_ENV !== 'production') ? `createElementVNode` : ``);
-const CREATE_COMMENT = Symbol((process.env.NODE_ENV !== 'production') ? `createCommentVNode` : ``);
-const CREATE_TEXT = Symbol((process.env.NODE_ENV !== 'production') ? `createTextVNode` : ``);
-const CREATE_STATIC = Symbol((process.env.NODE_ENV !== 'production') ? `createStaticVNode` : ``);
-const RESOLVE_COMPONENT = Symbol((process.env.NODE_ENV !== 'production') ? `resolveComponent` : ``);
-const RESOLVE_DYNAMIC_COMPONENT = Symbol((process.env.NODE_ENV !== 'production') ? `resolveDynamicComponent` : ``);
-const RESOLVE_DIRECTIVE = Symbol((process.env.NODE_ENV !== 'production') ? `resolveDirective` : ``);
-const RESOLVE_FILTER = Symbol((process.env.NODE_ENV !== 'production') ? `resolveFilter` : ``);
-const WITH_DIRECTIVES = Symbol((process.env.NODE_ENV !== 'production') ? `withDirectives` : ``);
-const RENDER_LIST = Symbol((process.env.NODE_ENV !== 'production') ? `renderList` : ``);
-const RENDER_SLOT = Symbol((process.env.NODE_ENV !== 'production') ? `renderSlot` : ``);
-const CREATE_SLOTS = Symbol((process.env.NODE_ENV !== 'production') ? `createSlots` : ``);
-const TO_DISPLAY_STRING = Symbol((process.env.NODE_ENV !== 'production') ? `toDisplayString` : ``);
-const MERGE_PROPS = Symbol((process.env.NODE_ENV !== 'production') ? `mergeProps` : ``);
-const NORMALIZE_CLASS = Symbol((process.env.NODE_ENV !== 'production') ? `normalizeClass` : ``);
-const NORMALIZE_STYLE = Symbol((process.env.NODE_ENV !== 'production') ? `normalizeStyle` : ``);
-const NORMALIZE_PROPS = Symbol((process.env.NODE_ENV !== 'production') ? `normalizeProps` : ``);
-const GUARD_REACTIVE_PROPS = Symbol((process.env.NODE_ENV !== 'production') ? `guardReactiveProps` : ``);
-const TO_HANDLERS = Symbol((process.env.NODE_ENV !== 'production') ? `toHandlers` : ``);
-const CAMELIZE = Symbol((process.env.NODE_ENV !== 'production') ? `camelize` : ``);
-const CAPITALIZE = Symbol((process.env.NODE_ENV !== 'production') ? `capitalize` : ``);
-const TO_HANDLER_KEY = Symbol((process.env.NODE_ENV !== 'production') ? `toHandlerKey` : ``);
-const SET_BLOCK_TRACKING = Symbol((process.env.NODE_ENV !== 'production') ? `setBlockTracking` : ``);
-const PUSH_SCOPE_ID = Symbol((process.env.NODE_ENV !== 'production') ? `pushScopeId` : ``);
-const POP_SCOPE_ID = Symbol((process.env.NODE_ENV !== 'production') ? `popScopeId` : ``);
-const WITH_CTX = Symbol((process.env.NODE_ENV !== 'production') ? `withCtx` : ``);
-const UNREF = Symbol((process.env.NODE_ENV !== 'production') ? `unref` : ``);
-const IS_REF = Symbol((process.env.NODE_ENV !== 'production') ? `isRef` : ``);
-const WITH_MEMO = Symbol((process.env.NODE_ENV !== 'production') ? `withMemo` : ``);
-const IS_MEMO_SAME = Symbol((process.env.NODE_ENV !== 'production') ? `isMemoSame` : ``);
-// Name mapping for runtime helpers that need to be imported from 'vue' in
-// generated code. Make sure these are correctly exported in the runtime!
-// Using `any` here because TS doesn't allow symbols as index type.
-const helperNameMap = {
-    [FRAGMENT]: `Fragment`,
-    [TELEPORT]: `Teleport`,
-    [SUSPENSE]: `Suspense`,
-    [KEEP_ALIVE]: `KeepAlive`,
-    [BASE_TRANSITION]: `BaseTransition`,
-    [OPEN_BLOCK]: `openBlock`,
-    [CREATE_BLOCK]: `createBlock`,
-    [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
-    [CREATE_VNODE]: `createVNode`,
-    [CREATE_ELEMENT_VNODE]: `createElementVNode`,
-    [CREATE_COMMENT]: `createCommentVNode`,
-    [CREATE_TEXT]: `createTextVNode`,
-    [CREATE_STATIC]: `createStaticVNode`,
-    [RESOLVE_COMPONENT]: `resolveComponent`,
-    [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
-    [RESOLVE_DIRECTIVE]: `resolveDirective`,
-    [RESOLVE_FILTER]: `resolveFilter`,
-    [WITH_DIRECTIVES]: `withDirectives`,
-    [RENDER_LIST]: `renderList`,
-    [RENDER_SLOT]: `renderSlot`,
-    [CREATE_SLOTS]: `createSlots`,
-    [TO_DISPLAY_STRING]: `toDisplayString`,
-    [MERGE_PROPS]: `mergeProps`,
-    [NORMALIZE_CLASS]: `normalizeClass`,
-    [NORMALIZE_STYLE]: `normalizeStyle`,
-    [NORMALIZE_PROPS]: `normalizeProps`,
-    [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
-    [TO_HANDLERS]: `toHandlers`,
-    [CAMELIZE]: `camelize`,
-    [CAPITALIZE]: `capitalize`,
-    [TO_HANDLER_KEY]: `toHandlerKey`,
-    [SET_BLOCK_TRACKING]: `setBlockTracking`,
-    [PUSH_SCOPE_ID]: `pushScopeId`,
-    [POP_SCOPE_ID]: `popScopeId`,
-    [WITH_CTX]: `withCtx`,
-    [UNREF]: `unref`,
-    [IS_REF]: `isRef`,
-    [WITH_MEMO]: `withMemo`,
-    [IS_MEMO_SAME]: `isMemoSame`
-};
-function registerRuntimeHelpers(helpers) {
-    Object.getOwnPropertySymbols(helpers).forEach(s => {
-        helperNameMap[s] = helpers[s];
-    });
+const FRAGMENT = Symbol((process.env.NODE_ENV !== 'production') ? `Fragment` : ``);
+const TELEPORT = Symbol((process.env.NODE_ENV !== 'production') ? `Teleport` : ``);
+const SUSPENSE = Symbol((process.env.NODE_ENV !== 'production') ? `Suspense` : ``);
+const KEEP_ALIVE = Symbol((process.env.NODE_ENV !== 'production') ? `KeepAlive` : ``);
+const BASE_TRANSITION = Symbol((process.env.NODE_ENV !== 'production') ? `BaseTransition` : ``);
+const OPEN_BLOCK = Symbol((process.env.NODE_ENV !== 'production') ? `openBlock` : ``);
+const CREATE_BLOCK = Symbol((process.env.NODE_ENV !== 'production') ? `createBlock` : ``);
+const CREATE_ELEMENT_BLOCK = Symbol((process.env.NODE_ENV !== 'production') ? `createElementBlock` : ``);
+const CREATE_VNODE = Symbol((process.env.NODE_ENV !== 'production') ? `createVNode` : ``);
+const CREATE_ELEMENT_VNODE = Symbol((process.env.NODE_ENV !== 'production') ? `createElementVNode` : ``);
+const CREATE_COMMENT = Symbol((process.env.NODE_ENV !== 'production') ? `createCommentVNode` : ``);
+const CREATE_TEXT = Symbol((process.env.NODE_ENV !== 'production') ? `createTextVNode` : ``);
+const CREATE_STATIC = Symbol((process.env.NODE_ENV !== 'production') ? `createStaticVNode` : ``);
+const RESOLVE_COMPONENT = Symbol((process.env.NODE_ENV !== 'production') ? `resolveComponent` : ``);
+const RESOLVE_DYNAMIC_COMPONENT = Symbol((process.env.NODE_ENV !== 'production') ? `resolveDynamicComponent` : ``);
+const RESOLVE_DIRECTIVE = Symbol((process.env.NODE_ENV !== 'production') ? `resolveDirective` : ``);
+const RESOLVE_FILTER = Symbol((process.env.NODE_ENV !== 'production') ? `resolveFilter` : ``);
+const WITH_DIRECTIVES = Symbol((process.env.NODE_ENV !== 'production') ? `withDirectives` : ``);
+const RENDER_LIST = Symbol((process.env.NODE_ENV !== 'production') ? `renderList` : ``);
+const RENDER_SLOT = Symbol((process.env.NODE_ENV !== 'production') ? `renderSlot` : ``);
+const CREATE_SLOTS = Symbol((process.env.NODE_ENV !== 'production') ? `createSlots` : ``);
+const TO_DISPLAY_STRING = Symbol((process.env.NODE_ENV !== 'production') ? `toDisplayString` : ``);
+const MERGE_PROPS = Symbol((process.env.NODE_ENV !== 'production') ? `mergeProps` : ``);
+const NORMALIZE_CLASS = Symbol((process.env.NODE_ENV !== 'production') ? `normalizeClass` : ``);
+const NORMALIZE_STYLE = Symbol((process.env.NODE_ENV !== 'production') ? `normalizeStyle` : ``);
+const NORMALIZE_PROPS = Symbol((process.env.NODE_ENV !== 'production') ? `normalizeProps` : ``);
+const GUARD_REACTIVE_PROPS = Symbol((process.env.NODE_ENV !== 'production') ? `guardReactiveProps` : ``);
+const TO_HANDLERS = Symbol((process.env.NODE_ENV !== 'production') ? `toHandlers` : ``);
+const CAMELIZE = Symbol((process.env.NODE_ENV !== 'production') ? `camelize` : ``);
+const CAPITALIZE = Symbol((process.env.NODE_ENV !== 'production') ? `capitalize` : ``);
+const TO_HANDLER_KEY = Symbol((process.env.NODE_ENV !== 'production') ? `toHandlerKey` : ``);
+const SET_BLOCK_TRACKING = Symbol((process.env.NODE_ENV !== 'production') ? `setBlockTracking` : ``);
+const PUSH_SCOPE_ID = Symbol((process.env.NODE_ENV !== 'production') ? `pushScopeId` : ``);
+const POP_SCOPE_ID = Symbol((process.env.NODE_ENV !== 'production') ? `popScopeId` : ``);
+const WITH_CTX = Symbol((process.env.NODE_ENV !== 'production') ? `withCtx` : ``);
+const UNREF = Symbol((process.env.NODE_ENV !== 'production') ? `unref` : ``);
+const IS_REF = Symbol((process.env.NODE_ENV !== 'production') ? `isRef` : ``);
+const WITH_MEMO = Symbol((process.env.NODE_ENV !== 'production') ? `withMemo` : ``);
+const IS_MEMO_SAME = Symbol((process.env.NODE_ENV !== 'production') ? `isMemoSame` : ``);
+// Name mapping for runtime helpers that need to be imported from 'vue' in
+// generated code. Make sure these are correctly exported in the runtime!
+// Using `any` here because TS doesn't allow symbols as index type.
+const helperNameMap = {
+    [FRAGMENT]: `Fragment`,
+    [TELEPORT]: `Teleport`,
+    [SUSPENSE]: `Suspense`,
+    [KEEP_ALIVE]: `KeepAlive`,
+    [BASE_TRANSITION]: `BaseTransition`,
+    [OPEN_BLOCK]: `openBlock`,
+    [CREATE_BLOCK]: `createBlock`,
+    [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
+    [CREATE_VNODE]: `createVNode`,
+    [CREATE_ELEMENT_VNODE]: `createElementVNode`,
+    [CREATE_COMMENT]: `createCommentVNode`,
+    [CREATE_TEXT]: `createTextVNode`,
+    [CREATE_STATIC]: `createStaticVNode`,
+    [RESOLVE_COMPONENT]: `resolveComponent`,
+    [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
+    [RESOLVE_DIRECTIVE]: `resolveDirective`,
+    [RESOLVE_FILTER]: `resolveFilter`,
+    [WITH_DIRECTIVES]: `withDirectives`,
+    [RENDER_LIST]: `renderList`,
+    [RENDER_SLOT]: `renderSlot`,
+    [CREATE_SLOTS]: `createSlots`,
+    [TO_DISPLAY_STRING]: `toDisplayString`,
+    [MERGE_PROPS]: `mergeProps`,
+    [NORMALIZE_CLASS]: `normalizeClass`,
+    [NORMALIZE_STYLE]: `normalizeStyle`,
+    [NORMALIZE_PROPS]: `normalizeProps`,
+    [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
+    [TO_HANDLERS]: `toHandlers`,
+    [CAMELIZE]: `camelize`,
+    [CAPITALIZE]: `capitalize`,
+    [TO_HANDLER_KEY]: `toHandlerKey`,
+    [SET_BLOCK_TRACKING]: `setBlockTracking`,
+    [PUSH_SCOPE_ID]: `pushScopeId`,
+    [POP_SCOPE_ID]: `popScopeId`,
+    [WITH_CTX]: `withCtx`,
+    [UNREF]: `unref`,
+    [IS_REF]: `isRef`,
+    [WITH_MEMO]: `withMemo`,
+    [IS_MEMO_SAME]: `isMemoSame`
+};
+function registerRuntimeHelpers(helpers) {
+    Object.getOwnPropertySymbols(helpers).forEach(s => {
+        helperNameMap[s] = helpers[s];
+    });
 }
 
-// AST Utilities ---------------------------------------------------------------
-// Some expressions, e.g. sequence and conditional expressions, are never
-// associated with template nodes, so their source locations are just a stub.
-// Container types like CompoundExpression also don't need a real location.
-const locStub = {
-    source: '',
-    start: { line: 1, column: 1, offset: 0 },
-    end: { line: 1, column: 1, offset: 0 }
-};
-function createRoot(children, loc = locStub) {
-    return {
-        type: 0 /* ROOT */,
-        children,
-        helpers: [],
-        components: [],
-        directives: [],
-        hoists: [],
-        imports: [],
-        cached: 0,
-        temps: 0,
-        codegenNode: undefined,
-        loc
-    };
-}
-function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
-    if (context) {
-        if (isBlock) {
-            context.helper(OPEN_BLOCK);
-            context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
-        }
-        else {
-            context.helper(getVNodeHelper(context.inSSR, isComponent));
-        }
-        if (directives) {
-            context.helper(WITH_DIRECTIVES);
-        }
-    }
-    return {
-        type: 13 /* VNODE_CALL */,
-        tag,
-        props,
-        children,
-        patchFlag,
-        dynamicProps,
-        directives,
-        isBlock,
-        disableTracking,
-        isComponent,
-        loc
-    };
-}
-function createArrayExpression(elements, loc = locStub) {
-    return {
-        type: 17 /* JS_ARRAY_EXPRESSION */,
-        loc,
-        elements
-    };
-}
-function createObjectExpression(properties, loc = locStub) {
-    return {
-        type: 15 /* JS_OBJECT_EXPRESSION */,
-        loc,
-        properties
-    };
-}
-function createObjectProperty(key, value) {
-    return {
-        type: 16 /* JS_PROPERTY */,
-        loc: locStub,
-        key: isString(key) ? createSimpleExpression(key, true) : key,
-        value
-    };
-}
-function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
-    return {
-        type: 4 /* SIMPLE_EXPRESSION */,
-        loc,
-        content,
-        isStatic,
-        constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
-    };
-}
-function createInterpolation(content, loc) {
-    return {
-        type: 5 /* INTERPOLATION */,
-        loc,
-        content: isString(content)
-            ? createSimpleExpression(content, false, loc)
-            : content
-    };
-}
-function createCompoundExpression(children, loc = locStub) {
-    return {
-        type: 8 /* COMPOUND_EXPRESSION */,
-        loc,
-        children
-    };
-}
-function createCallExpression(callee, args = [], loc = locStub) {
-    return {
-        type: 14 /* JS_CALL_EXPRESSION */,
-        loc,
-        callee,
-        arguments: args
-    };
-}
-function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
-    return {
-        type: 18 /* JS_FUNCTION_EXPRESSION */,
-        params,
-        returns,
-        newline,
-        isSlot,
-        loc
-    };
-}
-function createConditionalExpression(test, consequent, alternate, newline = true) {
-    return {
-        type: 19 /* JS_CONDITIONAL_EXPRESSION */,
-        test,
-        consequent,
-        alternate,
-        newline,
-        loc: locStub
-    };
-}
-function createCacheExpression(index, value, isVNode = false) {
-    return {
-        type: 20 /* JS_CACHE_EXPRESSION */,
-        index,
-        value,
-        isVNode,
-        loc: locStub
-    };
-}
-function createBlockStatement(body) {
-    return {
-        type: 21 /* JS_BLOCK_STATEMENT */,
-        body,
-        loc: locStub
-    };
-}
-function createTemplateLiteral(elements) {
-    return {
-        type: 22 /* JS_TEMPLATE_LITERAL */,
-        elements,
-        loc: locStub
-    };
-}
-function createIfStatement(test, consequent, alternate) {
-    return {
-        type: 23 /* JS_IF_STATEMENT */,
-        test,
-        consequent,
-        alternate,
-        loc: locStub
-    };
-}
-function createAssignmentExpression(left, right) {
-    return {
-        type: 24 /* JS_ASSIGNMENT_EXPRESSION */,
-        left,
-        right,
-        loc: locStub
-    };
-}
-function createSequenceExpression(expressions) {
-    return {
-        type: 25 /* JS_SEQUENCE_EXPRESSION */,
-        expressions,
-        loc: locStub
-    };
-}
-function createReturnStatement(returns) {
-    return {
-        type: 26 /* JS_RETURN_STATEMENT */,
-        returns,
-        loc: locStub
-    };
+// AST Utilities ---------------------------------------------------------------
+// Some expressions, e.g. sequence and conditional expressions, are never
+// associated with template nodes, so their source locations are just a stub.
+// Container types like CompoundExpression also don't need a real location.
+const locStub = {
+    source: '',
+    start: { line: 1, column: 1, offset: 0 },
+    end: { line: 1, column: 1, offset: 0 }
+};
+function createRoot(children, loc = locStub) {
+    return {
+        type: 0 /* ROOT */,
+        children,
+        helpers: [],
+        components: [],
+        directives: [],
+        hoists: [],
+        imports: [],
+        cached: 0,
+        temps: 0,
+        codegenNode: undefined,
+        loc
+    };
+}
+function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
+    if (context) {
+        if (isBlock) {
+            context.helper(OPEN_BLOCK);
+            context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
+        }
+        else {
+            context.helper(getVNodeHelper(context.inSSR, isComponent));
+        }
+        if (directives) {
+            context.helper(WITH_DIRECTIVES);
+        }
+    }
+    return {
+        type: 13 /* VNODE_CALL */,
+        tag,
+        props,
+        children,
+        patchFlag,
+        dynamicProps,
+        directives,
+        isBlock,
+        disableTracking,
+        isComponent,
+        loc
+    };
+}
+function createArrayExpression(elements, loc = locStub) {
+    return {
+        type: 17 /* JS_ARRAY_EXPRESSION */,
+        loc,
+        elements
+    };
+}
+function createObjectExpression(properties, loc = locStub) {
+    return {
+        type: 15 /* JS_OBJECT_EXPRESSION */,
+        loc,
+        properties
+    };
+}
+function createObjectProperty(key, value) {
+    return {
+        type: 16 /* JS_PROPERTY */,
+        loc: locStub,
+        key: isString(key) ? createSimpleExpression(key, true) : key,
+        value
+    };
+}
+function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
+    return {
+        type: 4 /* SIMPLE_EXPRESSION */,
+        loc,
+        content,
+        isStatic,
+        constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
+    };
+}
+function createInterpolation(content, loc) {
+    return {
+        type: 5 /* INTERPOLATION */,
+        loc,
+        content: isString(content)
+            ? createSimpleExpression(content, false, loc)
+            : content
+    };
+}
+function createCompoundExpression(children, loc = locStub) {
+    return {
+        type: 8 /* COMPOUND_EXPRESSION */,
+        loc,
+        children
+    };
+}
+function createCallExpression(callee, args = [], loc = locStub) {
+    return {
+        type: 14 /* JS_CALL_EXPRESSION */,
+        loc,
+        callee,
+        arguments: args
+    };
+}
+function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
+    return {
+        type: 18 /* JS_FUNCTION_EXPRESSION */,
+        params,
+        returns,
+        newline,
+        isSlot,
+        loc
+    };
+}
+function createConditionalExpression(test, consequent, alternate, newline = true) {
+    return {
+        type: 19 /* JS_CONDITIONAL_EXPRESSION */,
+        test,
+        consequent,
+        alternate,
+        newline,
+        loc: locStub
+    };
+}
+function createCacheExpression(index, value, isVNode = false) {
+    return {
+        type: 20 /* JS_CACHE_EXPRESSION */,
+        index,
+        value,
+        isVNode,
+        loc: locStub
+    };
+}
+function createBlockStatement(body) {
+    return {
+        type: 21 /* JS_BLOCK_STATEMENT */,
+        body,
+        loc: locStub
+    };
+}
+function createTemplateLiteral(elements) {
+    return {
+        type: 22 /* JS_TEMPLATE_LITERAL */,
+        elements,
+        loc: locStub
+    };
+}
+function createIfStatement(test, consequent, alternate) {
+    return {
+        type: 23 /* JS_IF_STATEMENT */,
+        test,
+        consequent,
+        alternate,
+        loc: locStub
+    };
+}
+function createAssignmentExpression(left, right) {
+    return {
+        type: 24 /* JS_ASSIGNMENT_EXPRESSION */,
+        left,
+        right,
+        loc: locStub
+    };
+}
+function createSequenceExpression(expressions) {
+    return {
+        type: 25 /* JS_SEQUENCE_EXPRESSION */,
+        expressions,
+        loc: locStub
+    };
+}
+function createReturnStatement(returns) {
+    return {
+        type: 26 /* JS_RETURN_STATEMENT */,
+        returns,
+        loc: locStub
+    };
 }
 
-const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
-const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
-function isCoreComponent(tag) {
-    if (isBuiltInType(tag, 'Teleport')) {
-        return TELEPORT;
-    }
-    else if (isBuiltInType(tag, 'Suspense')) {
-        return SUSPENSE;
-    }
-    else if (isBuiltInType(tag, 'KeepAlive')) {
-        return KEEP_ALIVE;
-    }
-    else if (isBuiltInType(tag, 'BaseTransition')) {
-        return BASE_TRANSITION;
-    }
-}
-const nonIdentifierRE = /^\d|[^\$\w]/;
-const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
-const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
-const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
-const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
-/**
- * Simple lexer to check if an expression is a member expression. This is
- * lax and only checks validity at the root level (i.e. does not validate exps
- * inside square brackets), but it's ok since these are only used on template
- * expressions and false positives are invalid expressions in the first place.
- */
-const isMemberExpressionBrowser = (path) => {
-    // remove whitespaces around . or [ first
-    path = path.trim().replace(whitespaceRE, s => s.trim());
-    let state = 0 /* inMemberExp */;
-    let stateStack = [];
-    let currentOpenBracketCount = 0;
-    let currentOpenParensCount = 0;
-    let currentStringType = null;
-    for (let i = 0; i < path.length; i++) {
-        const char = path.charAt(i);
-        switch (state) {
-            case 0 /* inMemberExp */:
-                if (char === '[') {
-                    stateStack.push(state);
-                    state = 1 /* inBrackets */;
-                    currentOpenBracketCount++;
-                }
-                else if (char === '(') {
-                    stateStack.push(state);
-                    state = 2 /* inParens */;
-                    currentOpenParensCount++;
-                }
-                else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
-                    return false;
-                }
-                break;
-            case 1 /* inBrackets */:
-                if (char === `'` || char === `"` || char === '`') {
-                    stateStack.push(state);
-                    state = 3 /* inString */;
-                    currentStringType = char;
-                }
-                else if (char === `[`) {
-                    currentOpenBracketCount++;
-                }
-                else if (char === `]`) {
-                    if (!--currentOpenBracketCount) {
-                        state = stateStack.pop();
-                    }
-                }
-                break;
-            case 2 /* inParens */:
-                if (char === `'` || char === `"` || char === '`') {
-                    stateStack.push(state);
-                    state = 3 /* inString */;
-                    currentStringType = char;
-                }
-                else if (char === `(`) {
-                    currentOpenParensCount++;
-                }
-                else if (char === `)`) {
-                    // if the exp ends as a call then it should not be considered valid
-                    if (i === path.length - 1) {
-                        return false;
-                    }
-                    if (!--currentOpenParensCount) {
-                        state = stateStack.pop();
-                    }
-                }
-                break;
-            case 3 /* inString */:
-                if (char === currentStringType) {
-                    state = stateStack.pop();
-                    currentStringType = null;
-                }
-                break;
-        }
-    }
-    return !currentOpenBracketCount && !currentOpenParensCount;
-};
-const isMemberExpressionNode = NOOP
-    ;
-const isMemberExpression = isMemberExpressionBrowser
-    ;
-function getInnerRange(loc, offset, length) {
-    const source = loc.source.slice(offset, offset + length);
-    const newLoc = {
-        source,
-        start: advancePositionWithClone(loc.start, loc.source, offset),
-        end: loc.end
-    };
-    if (length != null) {
-        newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
-    }
-    return newLoc;
-}
-function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
-    return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
-}
-// advance by mutation without cloning (for performance reasons), since this
-// gets called a lot in the parser
-function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
-    let linesCount = 0;
-    let lastNewLinePos = -1;
-    for (let i = 0; i < numberOfCharacters; i++) {
-        if (source.charCodeAt(i) === 10 /* newline char code */) {
-            linesCount++;
-            lastNewLinePos = i;
-        }
-    }
-    pos.offset += numberOfCharacters;
-    pos.line += linesCount;
-    pos.column =
-        lastNewLinePos === -1
-            ? pos.column + numberOfCharacters
-            : numberOfCharacters - lastNewLinePos;
-    return pos;
-}
-function assert(condition, msg) {
-    /* istanbul ignore if */
-    if (!condition) {
-        throw new Error(msg || `unexpected compiler condition`);
-    }
-}
-function findDir(node, name, allowEmpty = false) {
-    for (let i = 0; i < node.props.length; i++) {
-        const p = node.props[i];
-        if (p.type === 7 /* DIRECTIVE */ &&
-            (allowEmpty || p.exp) &&
-            (isString(name) ? p.name === name : name.test(p.name))) {
-            return p;
-        }
-    }
-}
-function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
-    for (let i = 0; i < node.props.length; i++) {
-        const p = node.props[i];
-        if (p.type === 6 /* ATTRIBUTE */) {
-            if (dynamicOnly)
-                continue;
-            if (p.name === name && (p.value || allowEmpty)) {
-                return p;
-            }
-        }
-        else if (p.name === 'bind' &&
-            (p.exp || allowEmpty) &&
-            isStaticArgOf(p.arg, name)) {
-            return p;
-        }
-    }
-}
-function isStaticArgOf(arg, name) {
-    return !!(arg && isStaticExp(arg) && arg.content === name);
-}
-function hasDynamicKeyVBind(node) {
-    return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
-        p.name === 'bind' &&
-        (!p.arg || // v-bind="obj"
-            p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
-            !p.arg.isStatic) // v-bind:[foo]
-    );
-}
-function isText(node) {
-    return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
-}
-function isVSlot(p) {
-    return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
-}
-function isTemplateNode(node) {
-    return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
-}
-function isSlotOutlet(node) {
-    return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
-}
-function getVNodeHelper(ssr, isComponent) {
-    return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
-}
-function getVNodeBlockHelper(ssr, isComponent) {
-    return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
-}
-const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
-function getUnnormalizedProps(props, callPath = []) {
-    if (props &&
-        !isString(props) &&
-        props.type === 14 /* JS_CALL_EXPRESSION */) {
-        const callee = props.callee;
-        if (!isString(callee) && propsHelperSet.has(callee)) {
-            return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
-        }
-    }
-    return [props, callPath];
-}
-function injectProp(node, prop, context) {
-    let propsWithInjection;
-    /**
-     * 1. mergeProps(...)
-     * 2. toHandlers(...)
-     * 3. normalizeProps(...)
-     * 4. normalizeProps(guardReactiveProps(...))
-     *
-     * we need to get the real props before normalization
-     */
-    let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
-    let callPath = [];
-    let parentCall;
-    if (props &&
-        !isString(props) &&
-        props.type === 14 /* JS_CALL_EXPRESSION */) {
-        const ret = getUnnormalizedProps(props);
-        props = ret[0];
-        callPath = ret[1];
-        parentCall = callPath[callPath.length - 1];
-    }
-    if (props == null || isString(props)) {
-        propsWithInjection = createObjectExpression([prop]);
-    }
-    else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
-        // merged props... add ours
-        // only inject key to object literal if it's the first argument so that
-        // if doesn't override user provided keys
-        const first = props.arguments[0];
-        if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
-            first.properties.unshift(prop);
-        }
-        else {
-            if (props.callee === TO_HANDLERS) {
-                // #2366
-                propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
-                    createObjectExpression([prop]),
-                    props
-                ]);
-            }
-            else {
-                props.arguments.unshift(createObjectExpression([prop]));
-            }
-        }
-        !propsWithInjection && (propsWithInjection = props);
-    }
-    else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
-        let alreadyExists = false;
-        // check existing key to avoid overriding user provided keys
-        if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
-            const propKeyName = prop.key.content;
-            alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
-                p.key.content === propKeyName);
-        }
-        if (!alreadyExists) {
-            props.properties.unshift(prop);
-        }
-        propsWithInjection = props;
-    }
-    else {
-        // single v-bind with expression, return a merged replacement
-        propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
-            createObjectExpression([prop]),
-            props
-        ]);
-        // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
-        // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
-        // the `guardReactiveProps` will no longer be needed
-        if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
-            parentCall = callPath[callPath.length - 2];
-        }
-    }
-    if (node.type === 13 /* VNODE_CALL */) {
-        if (parentCall) {
-            parentCall.arguments[0] = propsWithInjection;
-        }
-        else {
-            node.props = propsWithInjection;
-        }
-    }
-    else {
-        if (parentCall) {
-            parentCall.arguments[0] = propsWithInjection;
-        }
-        else {
-            node.arguments[2] = propsWithInjection;
-        }
-    }
-}
-function toValidAssetId(name, type) {
-    // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
-    return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
-        return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
-    })}`;
-}
-// Check if a node contains expressions that reference current context scope ids
-function hasScopeRef(node, ids) {
-    if (!node || Object.keys(ids).length === 0) {
-        return false;
-    }
-    switch (node.type) {
-        case 1 /* ELEMENT */:
-            for (let i = 0; i < node.props.length; i++) {
-                const p = node.props[i];
-                if (p.type === 7 /* DIRECTIVE */ &&
-                    (hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) {
-                    return true;
-                }
-            }
-            return node.children.some(c => hasScopeRef(c, ids));
-        case 11 /* FOR */:
-            if (hasScopeRef(node.source, ids)) {
-                return true;
-            }
-            return node.children.some(c => hasScopeRef(c, ids));
-        case 9 /* IF */:
-            return node.branches.some(b => hasScopeRef(b, ids));
-        case 10 /* IF_BRANCH */:
-            if (hasScopeRef(node.condition, ids)) {
-                return true;
-            }
-            return node.children.some(c => hasScopeRef(c, ids));
-        case 4 /* SIMPLE_EXPRESSION */:
-            return (!node.isStatic &&
-                isSimpleIdentifier(node.content) &&
-                !!ids[node.content]);
-        case 8 /* COMPOUND_EXPRESSION */:
-            return node.children.some(c => isObject(c) && hasScopeRef(c, ids));
-        case 5 /* INTERPOLATION */:
-        case 12 /* TEXT_CALL */:
-            return hasScopeRef(node.content, ids);
-        case 2 /* TEXT */:
-        case 3 /* COMMENT */:
-            return false;
-        default:
-            if ((process.env.NODE_ENV !== 'production')) ;
-            return false;
-    }
-}
-function getMemoedVNodeCall(node) {
-    if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
-        return node.arguments[1].returns;
-    }
-    else {
-        return node;
-    }
-}
-function makeBlock(node, { helper, removeHelper, inSSR }) {
-    if (!node.isBlock) {
-        node.isBlock = true;
-        removeHelper(getVNodeHelper(inSSR, node.isComponent));
-        helper(OPEN_BLOCK);
-        helper(getVNodeBlockHelper(inSSR, node.isComponent));
-    }
+const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
+const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
+function isCoreComponent(tag) {
+    if (isBuiltInType(tag, 'Teleport')) {
+        return TELEPORT;
+    }
+    else if (isBuiltInType(tag, 'Suspense')) {
+        return SUSPENSE;
+    }
+    else if (isBuiltInType(tag, 'KeepAlive')) {
+        return KEEP_ALIVE;
+    }
+    else if (isBuiltInType(tag, 'BaseTransition')) {
+        return BASE_TRANSITION;
+    }
+}
+const nonIdentifierRE = /^\d|[^\$\w]/;
+const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
+const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
+const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
+const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
+/**
+ * Simple lexer to check if an expression is a member expression. This is
+ * lax and only checks validity at the root level (i.e. does not validate exps
+ * inside square brackets), but it's ok since these are only used on template
+ * expressions and false positives are invalid expressions in the first place.
+ */
+const isMemberExpressionBrowser = (path) => {
+    // remove whitespaces around . or [ first
+    path = path.trim().replace(whitespaceRE, s => s.trim());
+    let state = 0 /* inMemberExp */;
+    let stateStack = [];
+    let currentOpenBracketCount = 0;
+    let currentOpenParensCount = 0;
+    let currentStringType = null;
+    for (let i = 0; i < path.length; i++) {
+        const char = path.charAt(i);
+        switch (state) {
+            case 0 /* inMemberExp */:
+                if (char === '[') {
+                    stateStack.push(state);
+                    state = 1 /* inBrackets */;
+                    currentOpenBracketCount++;
+                }
+                else if (char === '(') {
+                    stateStack.push(state);
+                    state = 2 /* inParens */;
+                    currentOpenParensCount++;
+                }
+                else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
+                    return false;
+                }
+                break;
+            case 1 /* inBrackets */:
+                if (char === `'` || char === `"` || char === '`') {
+                    stateStack.push(state);
+                    state = 3 /* inString */;
+                    currentStringType = char;
+                }
+                else if (char === `[`) {
+                    currentOpenBracketCount++;
+                }
+                else if (char === `]`) {
+                    if (!--currentOpenBracketCount) {
+                        state = stateStack.pop();
+                    }
+                }
+                break;
+            case 2 /* inParens */:
+                if (char === `'` || char === `"` || char === '`') {
+                    stateStack.push(state);
+                    state = 3 /* inString */;
+                    currentStringType = char;
+                }
+                else if (char === `(`) {
+                    currentOpenParensCount++;
+                }
+                else if (char === `)`) {
+                    // if the exp ends as a call then it should not be considered valid
+                    if (i === path.length - 1) {
+                        return false;
+                    }
+                    if (!--currentOpenParensCount) {
+                        state = stateStack.pop();
+                    }
+                }
+                break;
+            case 3 /* inString */:
+                if (char === currentStringType) {
+                    state = stateStack.pop();
+                    currentStringType = null;
+                }
+                break;
+        }
+    }
+    return !currentOpenBracketCount && !currentOpenParensCount;
+};
+const isMemberExpressionNode = NOOP
+    ;
+const isMemberExpression = isMemberExpressionBrowser
+    ;
+function getInnerRange(loc, offset, length) {
+    const source = loc.source.slice(offset, offset + length);
+    const newLoc = {
+        source,
+        start: advancePositionWithClone(loc.start, loc.source, offset),
+        end: loc.end
+    };
+    if (length != null) {
+        newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
+    }
+    return newLoc;
+}
+function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
+    return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
+}
+// advance by mutation without cloning (for performance reasons), since this
+// gets called a lot in the parser
+function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
+    let linesCount = 0;
+    let lastNewLinePos = -1;
+    for (let i = 0; i < numberOfCharacters; i++) {
+        if (source.charCodeAt(i) === 10 /* newline char code */) {
+            linesCount++;
+            lastNewLinePos = i;
+        }
+    }
+    pos.offset += numberOfCharacters;
+    pos.line += linesCount;
+    pos.column =
+        lastNewLinePos === -1
+            ? pos.column + numberOfCharacters
+            : numberOfCharacters - lastNewLinePos;
+    return pos;
+}
+function assert(condition, msg) {
+    /* istanbul ignore if */
+    if (!condition) {
+        throw new Error(msg || `unexpected compiler condition`);
+    }
+}
+function findDir(node, name, allowEmpty = false) {
+    for (let i = 0; i < node.props.length; i++) {
+        const p = node.props[i];
+        if (p.type === 7 /* DIRECTIVE */ &&
+            (allowEmpty || p.exp) &&
+            (isString(name) ? p.name === name : name.test(p.name))) {
+            return p;
+        }
+    }
+}
+function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
+    for (let i = 0; i < node.props.length; i++) {
+        const p = node.props[i];
+        if (p.type === 6 /* ATTRIBUTE */) {
+            if (dynamicOnly)
+                continue;
+            if (p.name === name && (p.value || allowEmpty)) {
+                return p;
+            }
+        }
+        else if (p.name === 'bind' &&
+            (p.exp || allowEmpty) &&
+            isStaticArgOf(p.arg, name)) {
+            return p;
+        }
+    }
+}
+function isStaticArgOf(arg, name) {
+    return !!(arg && isStaticExp(arg) && arg.content === name);
+}
+function hasDynamicKeyVBind(node) {
+    return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
+        p.name === 'bind' &&
+        (!p.arg || // v-bind="obj"
+            p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
+            !p.arg.isStatic) // v-bind:[foo]
+    );
+}
+function isText(node) {
+    return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
+}
+function isVSlot(p) {
+    return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
+}
+function isTemplateNode(node) {
+    return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
+}
+function isSlotOutlet(node) {
+    return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
+}
+function getVNodeHelper(ssr, isComponent) {
+    return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
+}
+function getVNodeBlockHelper(ssr, isComponent) {
+    return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
+}
+const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
+function getUnnormalizedProps(props, callPath = []) {
+    if (props &&
+        !isString(props) &&
+        props.type === 14 /* JS_CALL_EXPRESSION */) {
+        const callee = props.callee;
+        if (!isString(callee) && propsHelperSet.has(callee)) {
+            return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
+        }
+    }
+    return [props, callPath];
+}
+function injectProp(node, prop, context) {
+    let propsWithInjection;
+    /**
+     * 1. mergeProps(...)
+     * 2. toHandlers(...)
+     * 3. normalizeProps(...)
+     * 4. normalizeProps(guardReactiveProps(...))
+     *
+     * we need to get the real props before normalization
+     */
+    let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
+    let callPath = [];
+    let parentCall;
+    if (props &&
+        !isString(props) &&
+        props.type === 14 /* JS_CALL_EXPRESSION */) {
+        const ret = getUnnormalizedProps(props);
+        props = ret[0];
+        callPath = ret[1];
+        parentCall = callPath[callPath.length - 1];
+    }
+    if (props == null || isString(props)) {
+        propsWithInjection = createObjectExpression([prop]);
+    }
+    else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
+        // merged props... add ours
+        // only inject key to object literal if it's the first argument so that
+        // if doesn't override user provided keys
+        const first = props.arguments[0];
+        if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
+            first.properties.unshift(prop);
+        }
+        else {
+            if (props.callee === TO_HANDLERS) {
+                // #2366
+                propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
+                    createObjectExpression([prop]),
+                    props
+                ]);
+            }
+            else {
+                props.arguments.unshift(createObjectExpression([prop]));
+            }
+        }
+        !propsWithInjection && (propsWithInjection = props);
+    }
+    else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
+        let alreadyExists = false;
+        // check existing key to avoid overriding user provided keys
+        if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
+            const propKeyName = prop.key.content;
+            alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
+                p.key.content === propKeyName);
+        }
+        if (!alreadyExists) {
+            props.properties.unshift(prop);
+        }
+        propsWithInjection = props;
+    }
+    else {
+        // single v-bind with expression, return a merged replacement
+        propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
+            createObjectExpression([prop]),
+            props
+        ]);
+        // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
+        // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
+        // the `guardReactiveProps` will no longer be needed
+        if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
+            parentCall = callPath[callPath.length - 2];
+        }
+    }
+    if (node.type === 13 /* VNODE_CALL */) {
+        if (parentCall) {
+            parentCall.arguments[0] = propsWithInjection;
+        }
+        else {
+            node.props = propsWithInjection;
+        }
+    }
+    else {
+        if (parentCall) {
+            parentCall.arguments[0] = propsWithInjection;
+        }
+        else {
+            node.arguments[2] = propsWithInjection;
+        }
+    }
+}
+function toValidAssetId(name, type) {
+    // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
+    return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
+        return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
+    })}`;
+}
+// Check if a node contains expressions that reference current context scope ids
+function hasScopeRef(node, ids) {
+    if (!node || Object.keys(ids).length === 0) {
+        return false;
+    }
+    switch (node.type) {
+        case 1 /* ELEMENT */:
+            for (let i = 0; i < node.props.length; i++) {
+                const p = node.props[i];
+                if (p.type === 7 /* DIRECTIVE */ &&
+                    (hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) {
+                    return true;
+                }
+            }
+            return node.children.some(c => hasScopeRef(c, ids));
+        case 11 /* FOR */:
+            if (hasScopeRef(node.source, ids)) {
+                return true;
+            }
+            return node.children.some(c => hasScopeRef(c, ids));
+        case 9 /* IF */:
+            return node.branches.some(b => hasScopeRef(b, ids));
+        case 10 /* IF_BRANCH */:
+            if (hasScopeRef(node.condition, ids)) {
+                return true;
+            }
+            return node.children.some(c => hasScopeRef(c, ids));
+        case 4 /* SIMPLE_EXPRESSION */:
+            return (!node.isStatic &&
+                isSimpleIdentifier(node.content) &&
+                !!ids[node.content]);
+        case 8 /* COMPOUND_EXPRESSION */:
+            return node.children.some(c => isObject(c) && hasScopeRef(c, ids));
+        case 5 /* INTERPOLATION */:
+        case 12 /* TEXT_CALL */:
+            return hasScopeRef(node.content, ids);
+        case 2 /* TEXT */:
+        case 3 /* COMMENT */:
+            return false;
+        default:
+            if ((process.env.NODE_ENV !== 'production')) ;
+            return false;
+    }
+}
+function getMemoedVNodeCall(node) {
+    if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
+        return node.arguments[1].returns;
+    }
+    else {
+        return node;
+    }
+}
+function makeBlock(node, { helper, removeHelper, inSSR }) {
+    if (!node.isBlock) {
+        node.isBlock = true;
+        removeHelper(getVNodeHelper(inSSR, node.isComponent));
+        helper(OPEN_BLOCK);
+        helper(getVNodeBlockHelper(inSSR, node.isComponent));
+    }
 }
 
-const deprecationData = {
-    ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
-        message: `Platform-native elements with "is" prop will no longer be ` +
-            `treated as components in Vue 3 unless the "is" value is explicitly ` +
-            `prefixed with "vue:".`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
-    },
-    ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
-        message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
-            `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
-            `\`v-model:${key}\`.`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
-    },
-    ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
-        message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
-            `Vue 3 will automatically set a binding as DOM property when appropriate.`
-    },
-    ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
-        message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
-            `object spread: it will now overwrite an existing non-mergeable attribute ` +
-            `that appears before v-bind in the case of conflict. ` +
-            `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
-            `You can also suppress this warning if the usage is intended.`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
-    },
-    ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
-        message: `.native modifier for v-on has been removed as is no longer necessary.`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
-    },
-    ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
-        message: `v-if / v-for precedence when used on the same element has changed ` +
-            `in Vue 3: v-if now takes higher precedence and will no longer have ` +
-            `access to v-for scope variables. It is best to avoid the ambiguity ` +
-            `with <template> tags or use a computed property that filters v-for ` +
-            `data source.`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
-    },
-    ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
-        message: `<template> with no special directives will render as a native template ` +
-            `element instead of its inner content in Vue 3.`
-    },
-    ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
-        message: `"inline-template" has been removed in Vue 3.`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
-    },
-    ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
-        message: `filters have been removed in Vue 3. ` +
-            `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
-            `Use method calls or computed properties instead.`,
-        link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
-    }
-};
-function getCompatValue(key, context) {
-    const config = context.options
-        ? context.options.compatConfig
-        : context.compatConfig;
-    const value = config && config[key];
-    if (key === 'MODE') {
-        return value || 3; // compiler defaults to v3 behavior
-    }
-    else {
-        return value;
-    }
-}
-function isCompatEnabled(key, context) {
-    const mode = getCompatValue('MODE', context);
-    const value = getCompatValue(key, context);
-    // in v3 mode, only enable if explicitly set to true
-    // otherwise enable for any non-false value
-    return mode === 3 ? value === true : value !== false;
-}
-function checkCompatEnabled(key, context, loc, ...args) {
-    const enabled = isCompatEnabled(key, context);
-    if ((process.env.NODE_ENV !== 'production') && enabled) {
-        warnDeprecation(key, context, loc, ...args);
-    }
-    return enabled;
-}
-function warnDeprecation(key, context, loc, ...args) {
-    const val = getCompatValue(key, context);
-    if (val === 'suppress-warning') {
-        return;
-    }
-    const { message, link } = deprecationData[key];
-    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;
-    const err = new SyntaxError(msg);
-    err.code = key;
-    if (loc)
-        err.loc = loc;
-    context.onWarn(err);
+const deprecationData = {
+    ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
+        message: `Platform-native elements with "is" prop will no longer be ` +
+            `treated as components in Vue 3 unless the "is" value is explicitly ` +
+            `prefixed with "vue:".`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
+    },
+    ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
+        message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
+            `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
+            `\`v-model:${key}\`.`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
+    },
+    ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
+        message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
+            `Vue 3 will automatically set a binding as DOM property when appropriate.`
+    },
+    ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
+        message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
+            `object spread: it will now overwrite an existing non-mergeable attribute ` +
+            `that appears before v-bind in the case of conflict. ` +
+            `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
+            `You can also suppress this warning if the usage is intended.`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
+    },
+    ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
+        message: `.native modifier for v-on has been removed as is no longer necessary.`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
+    },
+    ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
+        message: `v-if / v-for precedence when used on the same element has changed ` +
+            `in Vue 3: v-if now takes higher precedence and will no longer have ` +
+            `access to v-for scope variables. It is best to avoid the ambiguity ` +
+            `with <template> tags or use a computed property that filters v-for ` +
+            `data source.`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
+    },
+    ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
+        message: `<template> with no special directives will render as a native template ` +
+            `element instead of its inner content in Vue 3.`
+    },
+    ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
+        message: `"inline-template" has been removed in Vue 3.`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
+    },
+    ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
+        message: `filters have been removed in Vue 3. ` +
+            `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
+            `Use method calls or computed properties instead.`,
+        link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
+    }
+};
+function getCompatValue(key, context) {
+    const config = context.options
+        ? context.options.compatConfig
+        : context.compatConfig;
+    const value = config && config[key];
+    if (key === 'MODE') {
+        return value || 3; // compiler defaults to v3 behavior
+    }
+    else {
+        return value;
+    }
+}
+function isCompatEnabled(key, context) {
+    const mode = getCompatValue('MODE', context);
+    const value = getCompatValue(key, context);
+    // in v3 mode, only enable if explicitly set to true
+    // otherwise enable for any non-false value
+    return mode === 3 ? value === true : value !== false;
+}
+function checkCompatEnabled(key, context, loc, ...args) {
+    const enabled = isCompatEnabled(key, context);
+    if ((process.env.NODE_ENV !== 'production') && enabled) {
+        warnDeprecation(key, context, loc, ...args);
+    }
+    return enabled;
+}
+function warnDeprecation(key, context, loc, ...args) {
+    const val = getCompatValue(key, context);
+    if (val === 'suppress-warning') {
+        return;
+    }
+    const { message, link } = deprecationData[key];
+    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;
+    const err = new SyntaxError(msg);
+    err.code = key;
+    if (loc)
+        err.loc = loc;
+    context.onWarn(err);
 }
 
-// The default decoder only provides escapes for characters reserved as part of
-// the template syntax, and is only used if the custom renderer did not provide
-// a platform-specific decoder.
-const decodeRE = /&(gt|lt|amp|apos|quot);/g;
-const decodeMap = {
-    gt: '>',
-    lt: '<',
-    amp: '&',
-    apos: "'",
-    quot: '"'
-};
-const defaultParserOptions = {
-    delimiters: [`{{`, `}}`],
-    getNamespace: () => 0 /* HTML */,
-    getTextMode: () => 0 /* DATA */,
-    isVoidTag: NO,
-    isPreTag: NO,
-    isCustomElement: NO,
-    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
-    onError: defaultOnError,
-    onWarn: defaultOnWarn,
-    comments: (process.env.NODE_ENV !== 'production')
-};
-function baseParse(content, options = {}) {
-    const context = createParserContext(content, options);
-    const start = getCursor(context);
-    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
-}
-function createParserContext(content, rawOptions) {
-    const options = extend({}, defaultParserOptions);
-    let key;
-    for (key in rawOptions) {
-        // @ts-ignore
-        options[key] =
-            rawOptions[key] === undefined
-                ? defaultParserOptions[key]
-                : rawOptions[key];
-    }
-    return {
-        options,
-        column: 1,
-        line: 1,
-        offset: 0,
-        originalSource: content,
-        source: content,
-        inPre: false,
-        inVPre: false,
-        onWarn: options.onWarn
-    };
-}
-function parseChildren(context, mode, ancestors) {
-    const parent = last(ancestors);
-    const ns = parent ? parent.ns : 0 /* HTML */;
-    const nodes = [];
-    while (!isEnd(context, mode, ancestors)) {
-        const s = context.source;
-        let node = undefined;
-        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
-            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
-                // '{{'
-                node = parseInterpolation(context, mode);
-            }
-            else if (mode === 0 /* DATA */ && s[0] === '<') {
-                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
-                if (s.length === 1) {
-                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
-                }
-                else if (s[1] === '!') {
-                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
-                    if (startsWith(s, '<!--')) {
-                        node = parseComment(context);
-                    }
-                    else if (startsWith(s, '<!DOCTYPE')) {
-                        // Ignore DOCTYPE by a limitation.
-                        node = parseBogusComment(context);
-                    }
-                    else if (startsWith(s, '<![CDATA[')) {
-                        if (ns !== 0 /* HTML */) {
-                            node = parseCDATA(context, ancestors);
-                        }
-                        else {
-                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
-                            node = parseBogusComment(context);
-                        }
-                    }
-                    else {
-                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
-                        node = parseBogusComment(context);
-                    }
-                }
-                else if (s[1] === '/') {
-                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
-                    if (s.length === 2) {
-                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
-                    }
-                    else if (s[2] === '>') {
-                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
-                        advanceBy(context, 3);
-                        continue;
-                    }
-                    else if (/[a-z]/i.test(s[2])) {
-                        emitError(context, 23 /* X_INVALID_END_TAG */);
-                        parseTag(context, 1 /* End */, parent);
-                        continue;
-                    }
-                    else {
-                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
-                        node = parseBogusComment(context);
-                    }
-                }
-                else if (/[a-z]/i.test(s[1])) {
-                    node = parseElement(context, ancestors);
-                    // 2.x <template> with no directive compat
-                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&
-                        node &&
-                        node.tag === 'template' &&
-                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
-                            isSpecialTemplateDirective(p.name))) {
-                        (process.env.NODE_ENV !== 'production') &&
-                            warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);
-                        node = node.children;
-                    }
-                }
-                else if (s[1] === '?') {
-                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
-                    node = parseBogusComment(context);
-                }
-                else {
-                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
-                }
-            }
-        }
-        if (!node) {
-            node = parseText(context, mode);
-        }
-        if (isArray(node)) {
-            for (let i = 0; i < node.length; i++) {
-                pushNode(nodes, node[i]);
-            }
-        }
-        else {
-            pushNode(nodes, node);
-        }
-    }
-    // Whitespace handling strategy like v2
-    let removedWhitespace = false;
-    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
-        const shouldCondense = context.options.whitespace !== 'preserve';
-        for (let i = 0; i < nodes.length; i++) {
-            const node = nodes[i];
-            if (!context.inPre && node.type === 2 /* TEXT */) {
-                if (!/[^\t\r\n\f ]/.test(node.content)) {
-                    const prev = nodes[i - 1];
-                    const next = nodes[i + 1];
-                    // Remove if:
-                    // - the whitespace is the first or last node, or:
-                    // - (condense mode) the whitespace is adjacent to a comment, or:
-                    // - (condense mode) the whitespace is between two elements AND contains newline
-                    if (!prev ||
-                        !next ||
-                        (shouldCondense &&
-                            (prev.type === 3 /* COMMENT */ ||
-                                next.type === 3 /* COMMENT */ ||
-                                (prev.type === 1 /* ELEMENT */ &&
-                                    next.type === 1 /* ELEMENT */ &&
-                                    /[\r\n]/.test(node.content))))) {
-                        removedWhitespace = true;
-                        nodes[i] = null;
-                    }
-                    else {
-                        // Otherwise, the whitespace is condensed into a single space
-                        node.content = ' ';
-                    }
-                }
-                else if (shouldCondense) {
-                    // in condense mode, consecutive whitespaces in text are condensed
-                    // down to a single space.
-                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
-                }
-            }
-            // Remove comment nodes if desired by configuration.
-            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
-                removedWhitespace = true;
-                nodes[i] = null;
-            }
-        }
-        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
-            // remove leading newline per html spec
-            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
-            const first = nodes[0];
-            if (first && first.type === 2 /* TEXT */) {
-                first.content = first.content.replace(/^\r?\n/, '');
-            }
-        }
-    }
-    return removedWhitespace ? nodes.filter(Boolean) : nodes;
-}
-function pushNode(nodes, node) {
-    if (node.type === 2 /* TEXT */) {
-        const prev = last(nodes);
-        // Merge if both this and the previous node are text and those are
-        // consecutive. This happens for cases like "a < b".
-        if (prev &&
-            prev.type === 2 /* TEXT */ &&
-            prev.loc.end.offset === node.loc.start.offset) {
-            prev.content += node.content;
-            prev.loc.end = node.loc.end;
-            prev.loc.source += node.loc.source;
-            return;
-        }
-    }
-    nodes.push(node);
-}
-function parseCDATA(context, ancestors) {
-    advanceBy(context, 9);
-    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
-    if (context.source.length === 0) {
-        emitError(context, 6 /* EOF_IN_CDATA */);
-    }
-    else {
-        advanceBy(context, 3);
-    }
-    return nodes;
-}
-function parseComment(context) {
-    const start = getCursor(context);
-    let content;
-    // Regular comment.
-    const match = /--(\!)?>/.exec(context.source);
-    if (!match) {
-        content = context.source.slice(4);
-        advanceBy(context, context.source.length);
-        emitError(context, 7 /* EOF_IN_COMMENT */);
-    }
-    else {
-        if (match.index <= 3) {
-            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
-        }
-        if (match[1]) {
-            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
-        }
-        content = context.source.slice(4, match.index);
-        // Advancing with reporting nested comments.
-        const s = context.source.slice(0, match.index);
-        let prevIndex = 1, nestedIndex = 0;
-        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
-            advanceBy(context, nestedIndex - prevIndex + 1);
-            if (nestedIndex + 4 < s.length) {
-                emitError(context, 16 /* NESTED_COMMENT */);
-            }
-            prevIndex = nestedIndex + 1;
-        }
-        advanceBy(context, match.index + match[0].length - prevIndex + 1);
-    }
-    return {
-        type: 3 /* COMMENT */,
-        content,
-        loc: getSelection(context, start)
-    };
-}
-function parseBogusComment(context) {
-    const start = getCursor(context);
-    const contentStart = context.source[1] === '?' ? 1 : 2;
-    let content;
-    const closeIndex = context.source.indexOf('>');
-    if (closeIndex === -1) {
-        content = context.source.slice(contentStart);
-        advanceBy(context, context.source.length);
-    }
-    else {
-        content = context.source.slice(contentStart, closeIndex);
-        advanceBy(context, closeIndex + 1);
-    }
-    return {
-        type: 3 /* COMMENT */,
-        content,
-        loc: getSelection(context, start)
-    };
-}
-function parseElement(context, ancestors) {
-    // Start tag.
-    const wasInPre = context.inPre;
-    const wasInVPre = context.inVPre;
-    const parent = last(ancestors);
-    const element = parseTag(context, 0 /* Start */, parent);
-    const isPreBoundary = context.inPre && !wasInPre;
-    const isVPreBoundary = context.inVPre && !wasInVPre;
-    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
-        // #4030 self-closing <pre> tag
-        if (isPreBoundary) {
-            context.inPre = false;
-        }
-        if (isVPreBoundary) {
-            context.inVPre = false;
-        }
-        return element;
-    }
-    // Children.
-    ancestors.push(element);
-    const mode = context.options.getTextMode(element, parent);
-    const children = parseChildren(context, mode, ancestors);
-    ancestors.pop();
-    // 2.x inline-template compat
-    {
-        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');
-        if (inlineTemplateProp &&
-            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {
-            const loc = getSelection(context, element.loc.end);
-            inlineTemplateProp.value = {
-                type: 2 /* TEXT */,
-                content: loc.source,
-                loc
-            };
-        }
-    }
-    element.children = children;
-    // End tag.
-    if (startsWithEndTagOpen(context.source, element.tag)) {
-        parseTag(context, 1 /* End */, parent);
-    }
-    else {
-        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
-        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
-            const first = children[0];
-            if (first && startsWith(first.loc.source, '<!--')) {
-                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
-            }
-        }
-    }
-    element.loc = getSelection(context, element.loc.start);
-    if (isPreBoundary) {
-        context.inPre = false;
-    }
-    if (isVPreBoundary) {
-        context.inVPre = false;
-    }
-    return element;
-}
-const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
-function parseTag(context, type, parent) {
-    // Tag open.
-    const start = getCursor(context);
-    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
-    const tag = match[1];
-    const ns = context.options.getNamespace(tag, parent);
-    advanceBy(context, match[0].length);
-    advanceSpaces(context);
-    // save current state in case we need to re-parse attributes with v-pre
-    const cursor = getCursor(context);
-    const currentSource = context.source;
-    // check <pre> tag
-    if (context.options.isPreTag(tag)) {
-        context.inPre = true;
-    }
-    // Attributes.
-    let props = parseAttributes(context, type);
-    // check v-pre
-    if (type === 0 /* Start */ &&
-        !context.inVPre &&
-        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
-        context.inVPre = true;
-        // reset context
-        extend(context, cursor);
-        context.source = currentSource;
-        // re-parse attrs and filter out v-pre itself
-        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
-    }
-    // Tag close.
-    let isSelfClosing = false;
-    if (context.source.length === 0) {
-        emitError(context, 9 /* EOF_IN_TAG */);
-    }
-    else {
-        isSelfClosing = startsWith(context.source, '/>');
-        if (type === 1 /* End */ && isSelfClosing) {
-            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
-        }
-        advanceBy(context, isSelfClosing ? 2 : 1);
-    }
-    if (type === 1 /* End */) {
-        return;
-    }
-    // 2.x deprecation checks
-    if ((process.env.NODE_ENV !== 'production') &&
-        isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {
-        let hasIf = false;
-        let hasFor = false;
-        for (let i = 0; i < props.length; i++) {
-            const p = props[i];
-            if (p.type === 7 /* DIRECTIVE */) {
-                if (p.name === 'if') {
-                    hasIf = true;
-                }
-                else if (p.name === 'for') {
-                    hasFor = true;
-                }
-            }
-            if (hasIf && hasFor) {
-                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));
-                break;
-            }
-        }
-    }
-    let tagType = 0 /* ELEMENT */;
-    if (!context.inVPre) {
-        if (tag === 'slot') {
-            tagType = 2 /* SLOT */;
-        }
-        else if (tag === 'template') {
-            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
-                tagType = 3 /* TEMPLATE */;
-            }
-        }
-        else if (isComponent(tag, props, context)) {
-            tagType = 1 /* COMPONENT */;
-        }
-    }
-    return {
-        type: 1 /* ELEMENT */,
-        ns,
-        tag,
-        tagType,
-        props,
-        isSelfClosing,
-        children: [],
-        loc: getSelection(context, start),
-        codegenNode: undefined // to be created during transform phase
-    };
-}
-function isComponent(tag, props, context) {
-    const options = context.options;
-    if (options.isCustomElement(tag)) {
-        return false;
-    }
-    if (tag === 'component' ||
-        /^[A-Z]/.test(tag) ||
-        isCoreComponent(tag) ||
-        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
-        (options.isNativeTag && !options.isNativeTag(tag))) {
-        return true;
-    }
-    // at this point the tag should be a native tag, but check for potential "is"
-    // casting
-    for (let i = 0; i < props.length; i++) {
-        const p = props[i];
-        if (p.type === 6 /* ATTRIBUTE */) {
-            if (p.name === 'is' && p.value) {
-                if (p.value.content.startsWith('vue:')) {
-                    return true;
-                }
-                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
-                    return true;
-                }
-            }
-        }
-        else {
-            // directive
-            // v-is (TODO Deprecate)
-            if (p.name === 'is') {
-                return true;
-            }
-            else if (
-            // :is on plain element - only treat as component in compat mode
-            p.name === 'bind' &&
-                isStaticArgOf(p.arg, 'is') &&
-                true &&
-                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
-                return true;
-            }
-        }
-    }
-}
-function parseAttributes(context, type) {
-    const props = [];
-    const attributeNames = new Set();
-    while (context.source.length > 0 &&
-        !startsWith(context.source, '>') &&
-        !startsWith(context.source, '/>')) {
-        if (startsWith(context.source, '/')) {
-            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
-            advanceBy(context, 1);
-            advanceSpaces(context);
-            continue;
-        }
-        if (type === 1 /* End */) {
-            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
-        }
-        const attr = parseAttribute(context, attributeNames);
-        // Trim whitespace between class
-        // https://github.com/vuejs/core/issues/4251
-        if (attr.type === 6 /* ATTRIBUTE */ &&
-            attr.value &&
-            attr.name === 'class') {
-            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
-        }
-        if (type === 0 /* Start */) {
-            props.push(attr);
-        }
-        if (/^[^\t\r\n\f />]/.test(context.source)) {
-            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
-        }
-        advanceSpaces(context);
-    }
-    return props;
-}
-function parseAttribute(context, nameSet) {
-    // Name.
-    const start = getCursor(context);
-    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
-    const name = match[0];
-    if (nameSet.has(name)) {
-        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
-    }
-    nameSet.add(name);
-    if (name[0] === '=') {
-        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
-    }
-    {
-        const pattern = /["'<]/g;
-        let m;
-        while ((m = pattern.exec(name))) {
-            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
-        }
-    }
-    advanceBy(context, name.length);
-    // Value
-    let value = undefined;
-    if (/^[\t\r\n\f ]*=/.test(context.source)) {
-        advanceSpaces(context);
-        advanceBy(context, 1);
-        advanceSpaces(context);
-        value = parseAttributeValue(context);
-        if (!value) {
-            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
-        }
-    }
-    const loc = getSelection(context, start);
-    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
-        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
-        let isPropShorthand = startsWith(name, '.');
-        let dirName = match[1] ||
-            (isPropShorthand || startsWith(name, ':')
-                ? 'bind'
-                : startsWith(name, '@')
-                    ? 'on'
-                    : 'slot');
-        let arg;
-        if (match[2]) {
-            const isSlot = dirName === 'slot';
-            const startOffset = name.lastIndexOf(match[2]);
-            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
-            let content = match[2];
-            let isStatic = true;
-            if (content.startsWith('[')) {
-                isStatic = false;
-                if (!content.endsWith(']')) {
-                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
-                    content = content.slice(1);
-                }
-                else {
-                    content = content.slice(1, content.length - 1);
-                }
-            }
-            else if (isSlot) {
-                // #1241 special case for v-slot: vuetify relies extensively on slot
-                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
-                // supports such usage so we are keeping it consistent with 2.x.
-                content += match[3] || '';
-            }
-            arg = {
-                type: 4 /* SIMPLE_EXPRESSION */,
-                content,
-                isStatic,
-                constType: isStatic
-                    ? 3 /* CAN_STRINGIFY */
-                    : 0 /* NOT_CONSTANT */,
-                loc
-            };
-        }
-        if (value && value.isQuoted) {
-            const valueLoc = value.loc;
-            valueLoc.start.offset++;
-            valueLoc.start.column++;
-            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
-            valueLoc.source = valueLoc.source.slice(1, -1);
-        }
-        const modifiers = match[3] ? match[3].slice(1).split('.') : [];
-        if (isPropShorthand)
-            modifiers.push('prop');
-        // 2.x compat v-bind:foo.sync -> v-model:foo
-        if (dirName === 'bind' && arg) {
-            if (modifiers.includes('sync') &&
-                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {
-                dirName = 'model';
-                modifiers.splice(modifiers.indexOf('sync'), 1);
-            }
-            if ((process.env.NODE_ENV !== 'production') && modifiers.includes('prop')) {
-                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);
-            }
-        }
-        return {
-            type: 7 /* DIRECTIVE */,
-            name: dirName,
-            exp: value && {
-                type: 4 /* SIMPLE_EXPRESSION */,
-                content: value.content,
-                isStatic: false,
-                // Treat as non-constant by default. This can be potentially set to
-                // other values by `transformExpression` to make it eligible for hoisting.
-                constType: 0 /* NOT_CONSTANT */,
-                loc: value.loc
-            },
-            arg,
-            modifiers,
-            loc
-        };
-    }
-    // missing directive name or illegal directive name
-    if (!context.inVPre && startsWith(name, 'v-')) {
-        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);
-    }
-    return {
-        type: 6 /* ATTRIBUTE */,
-        name,
-        value: value && {
-            type: 2 /* TEXT */,
-            content: value.content,
-            loc: value.loc
-        },
-        loc
-    };
-}
-function parseAttributeValue(context) {
-    const start = getCursor(context);
-    let content;
-    const quote = context.source[0];
-    const isQuoted = quote === `"` || quote === `'`;
-    if (isQuoted) {
-        // Quoted value.
-        advanceBy(context, 1);
-        const endIndex = context.source.indexOf(quote);
-        if (endIndex === -1) {
-            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
-        }
-        else {
-            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
-            advanceBy(context, 1);
-        }
-    }
-    else {
-        // Unquoted
-        const match = /^[^\t\r\n\f >]+/.exec(context.source);
-        if (!match) {
-            return undefined;
-        }
-        const unexpectedChars = /["'<=`]/g;
-        let m;
-        while ((m = unexpectedChars.exec(match[0]))) {
-            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
-        }
-        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
-    }
-    return { content, isQuoted, loc: getSelection(context, start) };
-}
-function parseInterpolation(context, mode) {
-    const [open, close] = context.options.delimiters;
-    const closeIndex = context.source.indexOf(close, open.length);
-    if (closeIndex === -1) {
-        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
-        return undefined;
-    }
-    const start = getCursor(context);
-    advanceBy(context, open.length);
-    const innerStart = getCursor(context);
-    const innerEnd = getCursor(context);
-    const rawContentLength = closeIndex - open.length;
-    const rawContent = context.source.slice(0, rawContentLength);
-    const preTrimContent = parseTextData(context, rawContentLength, mode);
-    const content = preTrimContent.trim();
-    const startOffset = preTrimContent.indexOf(content);
-    if (startOffset > 0) {
-        advancePositionWithMutation(innerStart, rawContent, startOffset);
-    }
-    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
-    advancePositionWithMutation(innerEnd, rawContent, endOffset);
-    advanceBy(context, close.length);
-    return {
-        type: 5 /* INTERPOLATION */,
-        content: {
-            type: 4 /* SIMPLE_EXPRESSION */,
-            isStatic: false,
-            // Set `isConstant` to false by default and will decide in transformExpression
-            constType: 0 /* NOT_CONSTANT */,
-            content,
-            loc: getSelection(context, innerStart, innerEnd)
-        },
-        loc: getSelection(context, start)
-    };
-}
-function parseText(context, mode) {
-    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
-    let endIndex = context.source.length;
-    for (let i = 0; i < endTokens.length; i++) {
-        const index = context.source.indexOf(endTokens[i], 1);
-        if (index !== -1 && endIndex > index) {
-            endIndex = index;
-        }
-    }
-    const start = getCursor(context);
-    const content = parseTextData(context, endIndex, mode);
-    return {
-        type: 2 /* TEXT */,
-        content,
-        loc: getSelection(context, start)
-    };
-}
-/**
- * Get text data with a given length from the current location.
- * This translates HTML entities in the text data.
- */
-function parseTextData(context, length, mode) {
-    const rawText = context.source.slice(0, length);
-    advanceBy(context, length);
-    if (mode === 2 /* RAWTEXT */ ||
-        mode === 3 /* CDATA */ ||
-        !rawText.includes('&')) {
-        return rawText;
-    }
-    else {
-        // DATA or RCDATA containing "&"". Entity decoding required.
-        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
-    }
-}
-function getCursor(context) {
-    const { column, line, offset } = context;
-    return { column, line, offset };
-}
-function getSelection(context, start, end) {
-    end = end || getCursor(context);
-    return {
-        start,
-        end,
-        source: context.originalSource.slice(start.offset, end.offset)
-    };
-}
-function last(xs) {
-    return xs[xs.length - 1];
-}
-function startsWith(source, searchString) {
-    return source.startsWith(searchString);
-}
-function advanceBy(context, numberOfCharacters) {
-    const { source } = context;
-    advancePositionWithMutation(context, source, numberOfCharacters);
-    context.source = source.slice(numberOfCharacters);
-}
-function advanceSpaces(context) {
-    const match = /^[\t\r\n\f ]+/.exec(context.source);
-    if (match) {
-        advanceBy(context, match[0].length);
-    }
-}
-function getNewPosition(context, start, numberOfCharacters) {
-    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
-}
-function emitError(context, code, offset, loc = getCursor(context)) {
-    if (offset) {
-        loc.offset += offset;
-        loc.column += offset;
-    }
-    context.options.onError(createCompilerError(code, {
-        start: loc,
-        end: loc,
-        source: ''
-    }));
-}
-function isEnd(context, mode, ancestors) {
-    const s = context.source;
-    switch (mode) {
-        case 0 /* DATA */:
-            if (startsWith(s, '</')) {
-                // TODO: probably bad performance
-                for (let i = ancestors.length - 1; i >= 0; --i) {
-                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {
-                        return true;
-                    }
-                }
-            }
-            break;
-        case 1 /* RCDATA */:
-        case 2 /* RAWTEXT */: {
-            const parent = last(ancestors);
-            if (parent && startsWithEndTagOpen(s, parent.tag)) {
-                return true;
-            }
-            break;
-        }
-        case 3 /* CDATA */:
-            if (startsWith(s, ']]>')) {
-                return true;
-            }
-            break;
-    }
-    return !s;
-}
-function startsWithEndTagOpen(source, tag) {
-    return (startsWith(source, '</') &&
-        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
-        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
+// The default decoder only provides escapes for characters reserved as part of
+// the template syntax, and is only used if the custom renderer did not provide
+// a platform-specific decoder.
+const decodeRE = /&(gt|lt|amp|apos|quot);/g;
+const decodeMap = {
+    gt: '>',
+    lt: '<',
+    amp: '&',
+    apos: "'",
+    quot: '"'
+};
+const defaultParserOptions = {
+    delimiters: [`{{`, `}}`],
+    getNamespace: () => 0 /* HTML */,
+    getTextMode: () => 0 /* DATA */,
+    isVoidTag: NO,
+    isPreTag: NO,
+    isCustomElement: NO,
+    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
+    onError: defaultOnError,
+    onWarn: defaultOnWarn,
+    comments: (process.env.NODE_ENV !== 'production')
+};
+function baseParse(content, options = {}) {
+    const context = createParserContext(content, options);
+    const start = getCursor(context);
+    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
+}
+function createParserContext(content, rawOptions) {
+    const options = extend({}, defaultParserOptions);
+    let key;
+    for (key in rawOptions) {
+        // @ts-ignore
+        options[key] =
+            rawOptions[key] === undefined
+                ? defaultParserOptions[key]
+                : rawOptions[key];
+    }
+    return {
+        options,
+        column: 1,
+        line: 1,
+        offset: 0,
+        originalSource: content,
+        source: content,
+        inPre: false,
+        inVPre: false,
+        onWarn: options.onWarn
+    };
+}
+function parseChildren(context, mode, ancestors) {
+    const parent = last(ancestors);
+    const ns = parent ? parent.ns : 0 /* HTML */;
+    const nodes = [];
+    while (!isEnd(context, mode, ancestors)) {
+        const s = context.source;
+        let node = undefined;
+        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
+            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
+                // '{{'
+                node = parseInterpolation(context, mode);
+            }
+            else if (mode === 0 /* DATA */ && s[0] === '<') {
+                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
+                if (s.length === 1) {
+                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
+                }
+                else if (s[1] === '!') {
+                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
+                    if (startsWith(s, '<!--')) {
+                        node = parseComment(context);
+                    }
+                    else if (startsWith(s, '<!DOCTYPE')) {
+                        // Ignore DOCTYPE by a limitation.
+                        node = parseBogusComment(context);
+                    }
+                    else if (startsWith(s, '<![CDATA[')) {
+                        if (ns !== 0 /* HTML */) {
+                            node = parseCDATA(context, ancestors);
+                        }
+                        else {
+                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
+                            node = parseBogusComment(context);
+                        }
+                    }
+                    else {
+                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
+                        node = parseBogusComment(context);
+                    }
+                }
+                else if (s[1] === '/') {
+                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
+                    if (s.length === 2) {
+                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
+                    }
+                    else if (s[2] === '>') {
+                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
+                        advanceBy(context, 3);
+                        continue;
+                    }
+                    else if (/[a-z]/i.test(s[2])) {
+                        emitError(context, 23 /* X_INVALID_END_TAG */);
+                        parseTag(context, 1 /* End */, parent);
+                        continue;
+                    }
+                    else {
+                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
+                        node = parseBogusComment(context);
+                    }
+                }
+                else if (/[a-z]/i.test(s[1])) {
+                    node = parseElement(context, ancestors);
+                    // 2.x <template> with no directive compat
+                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&
+                        node &&
+                        node.tag === 'template' &&
+                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
+                            isSpecialTemplateDirective(p.name))) {
+                        (process.env.NODE_ENV !== 'production') &&
+                            warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);
+                        node = node.children;
+                    }
+                }
+                else if (s[1] === '?') {
+                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
+                    node = parseBogusComment(context);
+                }
+                else {
+                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
+                }
+            }
+        }
+        if (!node) {
+            node = parseText(context, mode);
+        }
+        if (isArray(node)) {
+            for (let i = 0; i < node.length; i++) {
+                pushNode(nodes, node[i]);
+            }
+        }
+        else {
+            pushNode(nodes, node);
+        }
+    }
+    // Whitespace handling strategy like v2
+    let removedWhitespace = false;
+    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
+        const shouldCondense = context.options.whitespace !== 'preserve';
+        for (let i = 0; i < nodes.length; i++) {
+            const node = nodes[i];
+            if (!context.inPre && node.type === 2 /* TEXT */) {
+                if (!/[^\t\r\n\f ]/.test(node.content)) {
+                    const prev = nodes[i - 1];
+                    const next = nodes[i + 1];
+                    // Remove if:
+                    // - the whitespace is the first or last node, or:
+                    // - (condense mode) the whitespace is adjacent to a comment, or:
+                    // - (condense mode) the whitespace is between two elements AND contains newline
+                    if (!prev ||
+                        !next ||
+                        (shouldCondense &&
+                            (prev.type === 3 /* COMMENT */ ||
+                                next.type === 3 /* COMMENT */ ||
+                                (prev.type === 1 /* ELEMENT */ &&
+                                    next.type === 1 /* ELEMENT */ &&
+                                    /[\r\n]/.test(node.content))))) {
+                        removedWhitespace = true;
+                        nodes[i] = null;
+                    }
+                    else {
+                        // Otherwise, the whitespace is condensed into a single space
+                        node.content = ' ';
+                    }
+                }
+                else if (shouldCondense) {
+                    // in condense mode, consecutive whitespaces in text are condensed
+                    // down to a single space.
+                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
+                }
+            }
+            // Remove comment nodes if desired by configuration.
+            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
+                removedWhitespace = true;
+                nodes[i] = null;
+            }
+        }
+        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
+            // remove leading newline per html spec
+            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
+            const first = nodes[0];
+            if (first && first.type === 2 /* TEXT */) {
+                first.content = first.content.replace(/^\r?\n/, '');
+            }
+        }
+    }
+    return removedWhitespace ? nodes.filter(Boolean) : nodes;
+}
+function pushNode(nodes, node) {
+    if (node.type === 2 /* TEXT */) {
+        const prev = last(nodes);
+        // Merge if both this and the previous node are text and those are
+        // consecutive. This happens for cases like "a < b".
+        if (prev &&
+            prev.type === 2 /* TEXT */ &&
+            prev.loc.end.offset === node.loc.start.offset) {
+            prev.content += node.content;
+            prev.loc.end = node.loc.end;
+            prev.loc.source += node.loc.source;
+            return;
+        }
+    }
+    nodes.push(node);
+}
+function parseCDATA(context, ancestors) {
+    advanceBy(context, 9);
+    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
+    if (context.source.length === 0) {
+        emitError(context, 6 /* EOF_IN_CDATA */);
+    }
+    else {
+        advanceBy(context, 3);
+    }
+    return nodes;
+}
+function parseComment(context) {
+    const start = getCursor(context);
+    let content;
+    // Regular comment.
+    const match = /--(\!)?>/.exec(context.source);
+    if (!match) {
+        content = context.source.slice(4);
+        advanceBy(context, context.source.length);
+        emitError(context, 7 /* EOF_IN_COMMENT */);
+    }
+    else {
+        if (match.index <= 3) {
+            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
+        }
+        if (match[1]) {
+            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
+        }
+        content = context.source.slice(4, match.index);
+        // Advancing with reporting nested comments.
+        const s = context.source.slice(0, match.index);
+        let prevIndex = 1, nestedIndex = 0;
+        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
+            advanceBy(context, nestedIndex - prevIndex + 1);
+            if (nestedIndex + 4 < s.length) {
+                emitError(context, 16 /* NESTED_COMMENT */);
+            }
+            prevIndex = nestedIndex + 1;
+        }
+        advanceBy(context, match.index + match[0].length - prevIndex + 1);
+    }
+    return {
+        type: 3 /* COMMENT */,
+        content,
+        loc: getSelection(context, start)
+    };
+}
+function parseBogusComment(context) {
+    const start = getCursor(context);
+    const contentStart = context.source[1] === '?' ? 1 : 2;
+    let content;
+    const closeIndex = context.source.indexOf('>');
+    if (closeIndex === -1) {
+        content = context.source.slice(contentStart);
+        advanceBy(context, context.source.length);
+    }
+    else {
+        content = context.source.slice(contentStart, closeIndex);
+        advanceBy(context, closeIndex + 1);
+    }
+    return {
+        type: 3 /* COMMENT */,
+        content,
+        loc: getSelection(context, start)
+    };
+}
+function parseElement(context, ancestors) {
+    // Start tag.
+    const wasInPre = context.inPre;
+    const wasInVPre = context.inVPre;
+    const parent = last(ancestors);
+    const element = parseTag(context, 0 /* Start */, parent);
+    const isPreBoundary = context.inPre && !wasInPre;
+    const isVPreBoundary = context.inVPre && !wasInVPre;
+    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
+        // #4030 self-closing <pre> tag
+        if (isPreBoundary) {
+            context.inPre = false;
+        }
+        if (isVPreBoundary) {
+            context.inVPre = false;
+        }
+        return element;
+    }
+    // Children.
+    ancestors.push(element);
+    const mode = context.options.getTextMode(element, parent);
+    const children = parseChildren(context, mode, ancestors);
+    ancestors.pop();
+    // 2.x inline-template compat
+    {
+        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');
+        if (inlineTemplateProp &&
+            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {
+            const loc = getSelection(context, element.loc.end);
+            inlineTemplateProp.value = {
+                type: 2 /* TEXT */,
+                content: loc.source,
+                loc
+            };
+        }
+    }
+    element.children = children;
+    // End tag.
+    if (startsWithEndTagOpen(context.source, element.tag)) {
+        parseTag(context, 1 /* End */, parent);
+    }
+    else {
+        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
+        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
+            const first = children[0];
+            if (first && startsWith(first.loc.source, '<!--')) {
+                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
+            }
+        }
+    }
+    element.loc = getSelection(context, element.loc.start);
+    if (isPreBoundary) {
+        context.inPre = false;
+    }
+    if (isVPreBoundary) {
+        context.inVPre = false;
+    }
+    return element;
+}
+const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
+function parseTag(context, type, parent) {
+    // Tag open.
+    const start = getCursor(context);
+    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
+    const tag = match[1];
+    const ns = context.options.getNamespace(tag, parent);
+    advanceBy(context, match[0].length);
+    advanceSpaces(context);
+    // save current state in case we need to re-parse attributes with v-pre
+    const cursor = getCursor(context);
+    const currentSource = context.source;
+    // check <pre> tag
+    if (context.options.isPreTag(tag)) {
+        context.inPre = true;
+    }
+    // Attributes.
+    let props = parseAttributes(context, type);
+    // check v-pre
+    if (type === 0 /* Start */ &&
+        !context.inVPre &&
+        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
+        context.inVPre = true;
+        // reset context
+        extend(context, cursor);
+        context.source = currentSource;
+        // re-parse attrs and filter out v-pre itself
+        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
+    }
+    // Tag close.
+    let isSelfClosing = false;
+    if (context.source.length === 0) {
+        emitError(context, 9 /* EOF_IN_TAG */);
+    }
+    else {
+        isSelfClosing = startsWith(context.source, '/>');
+        if (type === 1 /* End */ && isSelfClosing) {
+            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
+        }
+        advanceBy(context, isSelfClosing ? 2 : 1);
+    }
+    if (type === 1 /* End */) {
+        return;
+    }
+    // 2.x deprecation checks
+    if ((process.env.NODE_ENV !== 'production') &&
+        isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {
+        let hasIf = false;
+        let hasFor = false;
+        for (let i = 0; i < props.length; i++) {
+            const p = props[i];
+            if (p.type === 7 /* DIRECTIVE */) {
+                if (p.name === 'if') {
+                    hasIf = true;
+                }
+                else if (p.name === 'for') {
+                    hasFor = true;
+                }
+            }
+            if (hasIf && hasFor) {
+                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));
+                break;
+            }
+        }
+    }
+    let tagType = 0 /* ELEMENT */;
+    if (!context.inVPre) {
+        if (tag === 'slot') {
+            tagType = 2 /* SLOT */;
+        }
+        else if (tag === 'template') {
+            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
+                tagType = 3 /* TEMPLATE */;
+            }
+        }
+        else if (isComponent(tag, props, context)) {
+            tagType = 1 /* COMPONENT */;
+        }
+    }
+    return {
+        type: 1 /* ELEMENT */,
+        ns,
+        tag,
+        tagType,
+        props,
+        isSelfClosing,
+        children: [],
+        loc: getSelection(context, start),
+        codegenNode: undefined // to be created during transform phase
+    };
+}
+function isComponent(tag, props, context) {
+    const options = context.options;
+    if (options.isCustomElement(tag)) {
+        return false;
+    }
+    if (tag === 'component' ||
+        /^[A-Z]/.test(tag) ||
+        isCoreComponent(tag) ||
+        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
+        (options.isNativeTag && !options.isNativeTag(tag))) {
+        return true;
+    }
+    // at this point the tag should be a native tag, but check for potential "is"
+    // casting
+    for (let i = 0; i < props.length; i++) {
+        const p = props[i];
+        if (p.type === 6 /* ATTRIBUTE */) {
+            if (p.name === 'is' && p.value) {
+                if (p.value.content.startsWith('vue:')) {
+                    return true;
+                }
+                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
+                    return true;
+                }
+            }
+        }
+        else {
+            // directive
+            // v-is (TODO Deprecate)
+            if (p.name === 'is') {
+                return true;
+            }
+            else if (
+            // :is on plain element - only treat as component in compat mode
+            p.name === 'bind' &&
+                isStaticArgOf(p.arg, 'is') &&
+                true &&
+                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
+                return true;
+            }
+        }
+    }
+}
+function parseAttributes(context, type) {
+    const props = [];
+    const attributeNames = new Set();
+    while (context.source.length > 0 &&
+        !startsWith(context.source, '>') &&
+        !startsWith(context.source, '/>')) {
+        if (startsWith(context.source, '/')) {
+            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
+            advanceBy(context, 1);
+            advanceSpaces(context);
+            continue;
+        }
+        if (type === 1 /* End */) {
+            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
+        }
+        const attr = parseAttribute(context, attributeNames);
+        // Trim whitespace between class
+        // https://github.com/vuejs/core/issues/4251
+        if (attr.type === 6 /* ATTRIBUTE */ &&
+            attr.value &&
+            attr.name === 'class') {
+            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
+        }
+        if (type === 0 /* Start */) {
+            props.push(attr);
+        }
+        if (/^[^\t\r\n\f />]/.test(context.source)) {
+            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
+        }
+        advanceSpaces(context);
+    }
+    return props;
+}
+function parseAttribute(context, nameSet) {
+    // Name.
+    const start = getCursor(context);
+    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
+    const name = match[0];
+    if (nameSet.has(name)) {
+        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
+    }
+    nameSet.add(name);
+    if (name[0] === '=') {
+        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
+    }
+    {
+        const pattern = /["'<]/g;
+        let m;
+        while ((m = pattern.exec(name))) {
+            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
+        }
+    }
+    advanceBy(context, name.length);
+    // Value
+    let value = undefined;
+    if (/^[\t\r\n\f ]*=/.test(context.source)) {
+        advanceSpaces(context);
+        advanceBy(context, 1);
+        advanceSpaces(context);
+        value = parseAttributeValue(context);
+        if (!value) {
+            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
+        }
+    }
+    const loc = getSelection(context, start);
+    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
+        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
+        let isPropShorthand = startsWith(name, '.');
+        let dirName = match[1] ||
+            (isPropShorthand || startsWith(name, ':')
+                ? 'bind'
+                : startsWith(name, '@')
+                    ? 'on'
+                    : 'slot');
+        let arg;
+        if (match[2]) {
+            const isSlot = dirName === 'slot';
+            const startOffset = name.lastIndexOf(match[2]);
+            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
+            let content = match[2];
+            let isStatic = true;
+            if (content.startsWith('[')) {
+                isStatic = false;
+                if (!content.endsWith(']')) {
+                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
+                    content = content.slice(1);
+                }
+                else {
+                    content = content.slice(1, content.length - 1);
+                }
+            }
+            else if (isSlot) {
+                // #1241 special case for v-slot: vuetify relies extensively on slot
+                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
+                // supports such usage so we are keeping it consistent with 2.x.
+                content += match[3] || '';
+            }
+            arg = {
+                type: 4 /* SIMPLE_EXPRESSION */,
+                content,
+                isStatic,
+                constType: isStatic
+                    ? 3 /* CAN_STRINGIFY */
+                    : 0 /* NOT_CONSTANT */,
+                loc
+            };
+        }
+        if (value && value.isQuoted) {
+            const valueLoc = value.loc;
+            valueLoc.start.offset++;
+            valueLoc.start.column++;
+            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
+            valueLoc.source = valueLoc.source.slice(1, -1);
+        }
+        const modifiers = match[3] ? match[3].slice(1).split('.') : [];
+        if (isPropShorthand)
+            modifiers.push('prop');
+        // 2.x compat v-bind:foo.sync -> v-model:foo
+        if (dirName === 'bind' && arg) {
+            if (modifiers.includes('sync') &&
+                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {
+                dirName = 'model';
+                modifiers.splice(modifiers.indexOf('sync'), 1);
+            }
+            if ((process.env.NODE_ENV !== 'production') && modifiers.includes('prop')) {
+                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);
+            }
+        }
+        return {
+            type: 7 /* DIRECTIVE */,
+            name: dirName,
+            exp: value && {
+                type: 4 /* SIMPLE_EXPRESSION */,
+                content: value.content,
+                isStatic: false,
+                // Treat as non-constant by default. This can be potentially set to
+                // other values by `transformExpression` to make it eligible for hoisting.
+                constType: 0 /* NOT_CONSTANT */,
+                loc: value.loc
+            },
+            arg,
+            modifiers,
+            loc
+        };
+    }
+    // missing directive name or illegal directive name
+    if (!context.inVPre && startsWith(name, 'v-')) {
+        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);
+    }
+    return {
+        type: 6 /* ATTRIBUTE */,
+        name,
+        value: value && {
+            type: 2 /* TEXT */,
+            content: value.content,
+            loc: value.loc
+        },
+        loc
+    };
+}
+function parseAttributeValue(context) {
+    const start = getCursor(context);
+    let content;
+    const quote = context.source[0];
+    const isQuoted = quote === `"` || quote === `'`;
+    if (isQuoted) {
+        // Quoted value.
+        advanceBy(context, 1);
+        const endIndex = context.source.indexOf(quote);
+        if (endIndex === -1) {
+            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
+        }
+        else {
+            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
+            advanceBy(context, 1);
+        }
+    }
+    else {
+        // Unquoted
+        const match = /^[^\t\r\n\f >]+/.exec(context.source);
+        if (!match) {
+            return undefined;
+        }
+        const unexpectedChars = /["'<=`]/g;
+        let m;
+        while ((m = unexpectedChars.exec(match[0]))) {
+            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
+        }
+        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
+    }
+    return { content, isQuoted, loc: getSelection(context, start) };
+}
+function parseInterpolation(context, mode) {
+    const [open, close] = context.options.delimiters;
+    const closeIndex = context.source.indexOf(close, open.length);
+    if (closeIndex === -1) {
+        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
+        return undefined;
+    }
+    const start = getCursor(context);
+    advanceBy(context, open.length);
+    const innerStart = getCursor(context);
+    const innerEnd = getCursor(context);
+    const rawContentLength = closeIndex - open.length;
+    const rawContent = context.source.slice(0, rawContentLength);
+    const preTrimContent = parseTextData(context, rawContentLength, mode);
+    const content = preTrimContent.trim();
+    const startOffset = preTrimContent.indexOf(content);
+    if (startOffset > 0) {
+        advancePositionWithMutation(innerStart, rawContent, startOffset);
+    }
+    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
+    advancePositionWithMutation(innerEnd, rawContent, endOffset);
+    advanceBy(context, close.length);
+    return {
+        type: 5 /* INTERPOLATION */,
+        content: {
+            type: 4 /* SIMPLE_EXPRESSION */,
+            isStatic: false,
+            // Set `isConstant` to false by default and will decide in transformExpression
+            constType: 0 /* NOT_CONSTANT */,
+            content,
+            loc: getSelection(context, innerStart, innerEnd)
+        },
+        loc: getSelection(context, start)
+    };
+}
+function parseText(context, mode) {
+    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
+    let endIndex = context.source.length;
+    for (let i = 0; i < endTokens.length; i++) {
+        const index = context.source.indexOf(endTokens[i], 1);
+        if (index !== -1 && endIndex > index) {
+            endIndex = index;
+        }
+    }
+    const start = getCursor(context);
+    const content = parseTextData(context, endIndex, mode);
+    return {
+        type: 2 /* TEXT */,
+        content,
+        loc: getSelection(context, start)
+    };
+}
+/**
+ * Get text data with a given length from the current location.
+ * This translates HTML entities in the text data.
+ */
+function parseTextData(context, length, mode) {
+    const rawText = context.source.slice(0, length);
+    advanceBy(context, length);
+    if (mode === 2 /* RAWTEXT */ ||
+        mode === 3 /* CDATA */ ||
+        !rawText.includes('&')) {
+        return rawText;
+    }
+    else {
+        // DATA or RCDATA containing "&"". Entity decoding required.
+        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
+    }
+}
+function getCursor(context) {
+    const { column, line, offset } = context;
+    return { column, line, offset };
+}
+function getSelection(context, start, end) {
+    end = end || getCursor(context);
+    return {
+        start,
+        end,
+        source: context.originalSource.slice(start.offset, end.offset)
+    };
+}
+function last(xs) {
+    return xs[xs.length - 1];
+}
+function startsWith(source, searchString) {
+    return source.startsWith(searchString);
+}
+function advanceBy(context, numberOfCharacters) {
+    const { source } = context;
+    advancePositionWithMutation(context, source, numberOfCharacters);
+    context.source = source.slice(numberOfCharacters);
+}
+function advanceSpaces(context) {
+    const match = /^[\t\r\n\f ]+/.exec(context.source);
+    if (match) {
+        advanceBy(context, match[0].length);
+    }
+}
+function getNewPosition(context, start, numberOfCharacters) {
+    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
+}
+function emitError(context, code, offset, loc = getCursor(context)) {
+    if (offset) {
+        loc.offset += offset;
+        loc.column += offset;
+    }
+    context.options.onError(createCompilerError(code, {
+        start: loc,
+        end: loc,
+        source: ''
+    }));
+}
+function isEnd(context, mode, ancestors) {
+    const s = context.source;
+    switch (mode) {
+        case 0 /* DATA */:
+            if (startsWith(s, '</')) {
+                // TODO: probably bad performance
+                for (let i = ancestors.length - 1; i >= 0; --i) {
+                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {
+                        return true;
+                    }
+                }
+            }
+            break;
+        case 1 /* RCDATA */:
+        case 2 /* RAWTEXT */: {
+            const parent = last(ancestors);
+            if (parent && startsWithEndTagOpen(s, parent.tag)) {
+                return true;
+            }
+            break;
+        }
+        case 3 /* CDATA */:
+            if (startsWith(s, ']]>')) {
+                return true;
+            }
+            break;
+    }
+    return !s;
+}
+function startsWithEndTagOpen(source, tag) {
+    return (startsWith(source, '</') &&
+        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
+        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
 }
 
-function hoistStatic(root, context) {
-    walk(root, context, 
-    // Root node is unfortunately non-hoistable due to potential parent
-    // fallthrough attributes.
-    isSingleElementRoot(root, root.children[0]));
-}
-function isSingleElementRoot(root, child) {
-    const { children } = root;
-    return (children.length === 1 &&
-        child.type === 1 /* ELEMENT */ &&
-        !isSlotOutlet(child));
-}
-function walk(node, context, doNotHoistNode = false) {
-    const { children } = node;
-    const originalCount = children.length;
-    let hoistedCount = 0;
-    for (let i = 0; i < children.length; i++) {
-        const child = children[i];
-        // only plain elements & text calls are eligible for hoisting.
-        if (child.type === 1 /* ELEMENT */ &&
-            child.tagType === 0 /* ELEMENT */) {
-            const constantType = doNotHoistNode
-                ? 0 /* NOT_CONSTANT */
-                : getConstantType(child, context);
-            if (constantType > 0 /* NOT_CONSTANT */) {
-                if (constantType >= 2 /* CAN_HOIST */) {
-                    child.codegenNode.patchFlag =
-                        -1 /* HOISTED */ + ((process.env.NODE_ENV !== 'production') ? ` /* HOISTED */` : ``);
-                    child.codegenNode = context.hoist(child.codegenNode);
-                    hoistedCount++;
-                    continue;
-                }
-            }
-            else {
-                // node may contain dynamic children, but its props may be eligible for
-                // hoisting.
-                const codegenNode = child.codegenNode;
-                if (codegenNode.type === 13 /* VNODE_CALL */) {
-                    const flag = getPatchFlag(codegenNode);
-                    if ((!flag ||
-                        flag === 512 /* NEED_PATCH */ ||
-                        flag === 1 /* TEXT */) &&
-                        getGeneratedPropsConstantType(child, context) >=
-                            2 /* CAN_HOIST */) {
-                        const props = getNodeProps(child);
-                        if (props) {
-                            codegenNode.props = context.hoist(props);
-                        }
-                    }
-                    if (codegenNode.dynamicProps) {
-                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
-                    }
-                }
-            }
-        }
-        else if (child.type === 12 /* TEXT_CALL */ &&
-            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
-            child.codegenNode = context.hoist(child.codegenNode);
-            hoistedCount++;
-        }
-        // walk further
-        if (child.type === 1 /* ELEMENT */) {
-            const isComponent = child.tagType === 1 /* COMPONENT */;
-            if (isComponent) {
-                context.scopes.vSlot++;
-            }
-            walk(child, context);
-            if (isComponent) {
-                context.scopes.vSlot--;
-            }
-        }
-        else if (child.type === 11 /* FOR */) {
-            // Do not hoist v-for single child because it has to be a block
-            walk(child, context, child.children.length === 1);
-        }
-        else if (child.type === 9 /* IF */) {
-            for (let i = 0; i < child.branches.length; i++) {
-                // Do not hoist v-if single child because it has to be a block
-                walk(child.branches[i], context, child.branches[i].children.length === 1);
-            }
-        }
-    }
-    if (hoistedCount && context.transformHoist) {
-        context.transformHoist(children, context, node);
-    }
-    // all children were hoisted - the entire children array is hoistable.
-    if (hoistedCount &&
-        hoistedCount === originalCount &&
-        node.type === 1 /* ELEMENT */ &&
-        node.tagType === 0 /* ELEMENT */ &&
-        node.codegenNode &&
-        node.codegenNode.type === 13 /* VNODE_CALL */ &&
-        isArray(node.codegenNode.children)) {
-        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
-    }
-}
-function getConstantType(node, context) {
-    const { constantCache } = context;
-    switch (node.type) {
-        case 1 /* ELEMENT */:
-            if (node.tagType !== 0 /* ELEMENT */) {
-                return 0 /* NOT_CONSTANT */;
-            }
-            const cached = constantCache.get(node);
-            if (cached !== undefined) {
-                return cached;
-            }
-            const codegenNode = node.codegenNode;
-            if (codegenNode.type !== 13 /* VNODE_CALL */) {
-                return 0 /* NOT_CONSTANT */;
-            }
-            if (codegenNode.isBlock &&
-                node.tag !== 'svg' &&
-                node.tag !== 'foreignObject') {
-                return 0 /* NOT_CONSTANT */;
-            }
-            const flag = getPatchFlag(codegenNode);
-            if (!flag) {
-                let returnType = 3 /* CAN_STRINGIFY */;
-                // Element itself has no patch flag. However we still need to check:
-                // 1. Even for a node with no patch flag, it is possible for it to contain
-                // non-hoistable expressions that refers to scope variables, e.g. compiler
-                // injected keys or cached event handlers. Therefore we need to always
-                // check the codegenNode's props to be sure.
-                const generatedPropsType = getGeneratedPropsConstantType(node, context);
-                if (generatedPropsType === 0 /* NOT_CONSTANT */) {
-                    constantCache.set(node, 0 /* NOT_CONSTANT */);
-                    return 0 /* NOT_CONSTANT */;
-                }
-                if (generatedPropsType < returnType) {
-                    returnType = generatedPropsType;
-                }
-                // 2. its children.
-                for (let i = 0; i < node.children.length; i++) {
-                    const childType = getConstantType(node.children[i], context);
-                    if (childType === 0 /* NOT_CONSTANT */) {
-                        constantCache.set(node, 0 /* NOT_CONSTANT */);
-                        return 0 /* NOT_CONSTANT */;
-                    }
-                    if (childType < returnType) {
-                        returnType = childType;
-                    }
-                }
-                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
-                // type, check if any of the props can cause the type to be lowered
-                // we can skip can_patch because it's guaranteed by the absence of a
-                // patchFlag.
-                if (returnType > 1 /* CAN_SKIP_PATCH */) {
-                    for (let i = 0; i < node.props.length; i++) {
-                        const p = node.props[i];
-                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
-                            const expType = getConstantType(p.exp, context);
-                            if (expType === 0 /* NOT_CONSTANT */) {
-                                constantCache.set(node, 0 /* NOT_CONSTANT */);
-                                return 0 /* NOT_CONSTANT */;
-                            }
-                            if (expType < returnType) {
-                                returnType = expType;
-                            }
-                        }
-                    }
-                }
-                // only svg/foreignObject could be block here, however if they are
-                // static then they don't need to be blocks since there will be no
-                // nested updates.
-                if (codegenNode.isBlock) {
-                    // except set custom directives.
-                    for (let i = 0; i < node.props.length; i++) {
-                        const p = node.props[i];
-                        if (p.type === 7 /* DIRECTIVE */) {
-                            constantCache.set(node, 0 /* NOT_CONSTANT */);
-                            return 0 /* NOT_CONSTANT */;
-                        }
-                    }
-                    context.removeHelper(OPEN_BLOCK);
-                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
-                    codegenNode.isBlock = false;
-                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
-                }
-                constantCache.set(node, returnType);
-                return returnType;
-            }
-            else {
-                constantCache.set(node, 0 /* NOT_CONSTANT */);
-                return 0 /* NOT_CONSTANT */;
-            }
-        case 2 /* TEXT */:
-        case 3 /* COMMENT */:
-            return 3 /* CAN_STRINGIFY */;
-        case 9 /* IF */:
-        case 11 /* FOR */:
-        case 10 /* IF_BRANCH */:
-            return 0 /* NOT_CONSTANT */;
-        case 5 /* INTERPOLATION */:
-        case 12 /* TEXT_CALL */:
-            return getConstantType(node.content, context);
-        case 4 /* SIMPLE_EXPRESSION */:
-            return node.constType;
-        case 8 /* COMPOUND_EXPRESSION */:
-            let returnType = 3 /* CAN_STRINGIFY */;
-            for (let i = 0; i < node.children.length; i++) {
-                const child = node.children[i];
-                if (isString(child) || isSymbol(child)) {
-                    continue;
-                }
-                const childType = getConstantType(child, context);
-                if (childType === 0 /* NOT_CONSTANT */) {
-                    return 0 /* NOT_CONSTANT */;
-                }
-                else if (childType < returnType) {
-                    returnType = childType;
-                }
-            }
-            return returnType;
-        default:
-            if ((process.env.NODE_ENV !== 'production')) ;
-            return 0 /* NOT_CONSTANT */;
-    }
-}
-const allowHoistedHelperSet = new Set([
-    NORMALIZE_CLASS,
-    NORMALIZE_STYLE,
-    NORMALIZE_PROPS,
-    GUARD_REACTIVE_PROPS
-]);
-function getConstantTypeOfHelperCall(value, context) {
-    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
-        !isString(value.callee) &&
-        allowHoistedHelperSet.has(value.callee)) {
-        const arg = value.arguments[0];
-        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
-            return getConstantType(arg, context);
-        }
-        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
-            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
-            return getConstantTypeOfHelperCall(arg, context);
-        }
-    }
-    return 0 /* NOT_CONSTANT */;
-}
-function getGeneratedPropsConstantType(node, context) {
-    let returnType = 3 /* CAN_STRINGIFY */;
-    const props = getNodeProps(node);
-    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
-        const { properties } = props;
-        for (let i = 0; i < properties.length; i++) {
-            const { key, value } = properties[i];
-            const keyType = getConstantType(key, context);
-            if (keyType === 0 /* NOT_CONSTANT */) {
-                return keyType;
-            }
-            if (keyType < returnType) {
-                returnType = keyType;
-            }
-            let valueType;
-            if (value.type === 4 /* SIMPLE_EXPRESSION */) {
-                valueType = getConstantType(value, context);
-            }
-            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
-                // some helper calls can be hoisted,
-                // such as the `normalizeProps` generated by the compiler for pre-normalize class,
-                // in this case we need to respect the ConstantType of the helper's arguments
-                valueType = getConstantTypeOfHelperCall(value, context);
-            }
-            else {
-                valueType = 0 /* NOT_CONSTANT */;
-            }
-            if (valueType === 0 /* NOT_CONSTANT */) {
-                return valueType;
-            }
-            if (valueType < returnType) {
-                returnType = valueType;
-            }
-        }
-    }
-    return returnType;
-}
-function getNodeProps(node) {
-    const codegenNode = node.codegenNode;
-    if (codegenNode.type === 13 /* VNODE_CALL */) {
-        return codegenNode.props;
-    }
-}
-function getPatchFlag(node) {
-    const flag = node.patchFlag;
-    return flag ? parseInt(flag, 10) : undefined;
+function hoistStatic(root, context) {
+    walk(root, context, 
+    // Root node is unfortunately non-hoistable due to potential parent
+    // fallthrough attributes.
+    isSingleElementRoot(root, root.children[0]));
+}
+function isSingleElementRoot(root, child) {
+    const { children } = root;
+    return (children.length === 1 &&
+        child.type === 1 /* ELEMENT */ &&
+        !isSlotOutlet(child));
+}
+function walk(node, context, doNotHoistNode = false) {
+    const { children } = node;
+    const originalCount = children.length;
+    let hoistedCount = 0;
+    for (let i = 0; i < children.length; i++) {
+        const child = children[i];
+        // only plain elements & text calls are eligible for hoisting.
+        if (child.type === 1 /* ELEMENT */ &&
+            child.tagType === 0 /* ELEMENT */) {
+            const constantType = doNotHoistNode
+                ? 0 /* NOT_CONSTANT */
+                : getConstantType(child, context);
+            if (constantType > 0 /* NOT_CONSTANT */) {
+                if (constantType >= 2 /* CAN_HOIST */) {
+                    child.codegenNode.patchFlag =
+                        -1 /* HOISTED */ + ((process.env.NODE_ENV !== 'production') ? ` /* HOISTED */` : ``);
+                    child.codegenNode = context.hoist(child.codegenNode);
+                    hoistedCount++;
+                    continue;
+                }
+            }
+            else {
+                // node may contain dynamic children, but its props may be eligible for
+                // hoisting.
+                const codegenNode = child.codegenNode;
+                if (codegenNode.type === 13 /* VNODE_CALL */) {
+                    const flag = getPatchFlag(codegenNode);
+                    if ((!flag ||
+                        flag === 512 /* NEED_PATCH */ ||
+                        flag === 1 /* TEXT */) &&
+                        getGeneratedPropsConstantType(child, context) >=
+                            2 /* CAN_HOIST */) {
+                        const props = getNodeProps(child);
+                        if (props) {
+                            codegenNode.props = context.hoist(props);
+                        }
+                    }
+                    if (codegenNode.dynamicProps) {
+                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
+                    }
+                }
+            }
+        }
+        else if (child.type === 12 /* TEXT_CALL */ &&
+            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
+            child.codegenNode = context.hoist(child.codegenNode);
+            hoistedCount++;
+        }
+        // walk further
+        if (child.type === 1 /* ELEMENT */) {
+            const isComponent = child.tagType === 1 /* COMPONENT */;
+            if (isComponent) {
+                context.scopes.vSlot++;
+            }
+            walk(child, context);
+            if (isComponent) {
+                context.scopes.vSlot--;
+            }
+        }
+        else if (child.type === 11 /* FOR */) {
+            // Do not hoist v-for single child because it has to be a block
+            walk(child, context, child.children.length === 1);
+        }
+        else if (child.type === 9 /* IF */) {
+            for (let i = 0; i < child.branches.length; i++) {
+                // Do not hoist v-if single child because it has to be a block
+                walk(child.branches[i], context, child.branches[i].children.length === 1);
+            }
+        }
+    }
+    if (hoistedCount && context.transformHoist) {
+        context.transformHoist(children, context, node);
+    }
+    // all children were hoisted - the entire children array is hoistable.
+    if (hoistedCount &&
+        hoistedCount === originalCount &&
+        node.type === 1 /* ELEMENT */ &&
+        node.tagType === 0 /* ELEMENT */ &&
+        node.codegenNode &&
+        node.codegenNode.type === 13 /* VNODE_CALL */ &&
+        isArray(node.codegenNode.children)) {
+        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
+    }
+}
+function getConstantType(node, context) {
+    const { constantCache } = context;
+    switch (node.type) {
+        case 1 /* ELEMENT */:
+            if (node.tagType !== 0 /* ELEMENT */) {
+                return 0 /* NOT_CONSTANT */;
+            }
+            const cached = constantCache.get(node);
+            if (cached !== undefined) {
+                return cached;
+            }
+            const codegenNode = node.codegenNode;
+            if (codegenNode.type !== 13 /* VNODE_CALL */) {
+                return 0 /* NOT_CONSTANT */;
+            }
+            if (codegenNode.isBlock &&
+                node.tag !== 'svg' &&
+                node.tag !== 'foreignObject') {
+                return 0 /* NOT_CONSTANT */;
+            }
+            const flag = getPatchFlag(codegenNode);
+            if (!flag) {
+                let returnType = 3 /* CAN_STRINGIFY */;
+                // Element itself has no patch flag. However we still need to check:
+                // 1. Even for a node with no patch flag, it is possible for it to contain
+                // non-hoistable expressions that refers to scope variables, e.g. compiler
+                // injected keys or cached event handlers. Therefore we need to always
+                // check the codegenNode's props to be sure.
+                const generatedPropsType = getGeneratedPropsConstantType(node, context);
+                if (generatedPropsType === 0 /* NOT_CONSTANT */) {
+                    constantCache.set(node, 0 /* NOT_CONSTANT */);
+                    return 0 /* NOT_CONSTANT */;
+                }
+                if (generatedPropsType < returnType) {
+                    returnType = generatedPropsType;
+                }
+                // 2. its children.
+                for (let i = 0; i < node.children.length; i++) {
+                    const childType = getConstantType(node.children[i], context);
+                    if (childType === 0 /* NOT_CONSTANT */) {
+                        constantCache.set(node, 0 /* NOT_CONSTANT */);
+                        return 0 /* NOT_CONSTANT */;
+                    }
+                    if (childType < returnType) {
+                        returnType = childType;
+                    }
+                }
+                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
+                // type, check if any of the props can cause the type to be lowered
+                // we can skip can_patch because it's guaranteed by the absence of a
+                // patchFlag.
+                if (returnType > 1 /* CAN_SKIP_PATCH */) {
+                    for (let i = 0; i < node.props.length; i++) {
+                        const p = node.props[i];
+                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
+                            const expType = getConstantType(p.exp, context);
+                            if (expType === 0 /* NOT_CONSTANT */) {
+                                constantCache.set(node, 0 /* NOT_CONSTANT */);
+                                return 0 /* NOT_CONSTANT */;
+                            }
+                            if (expType < returnType) {
+                                returnType = expType;
+                            }
+                        }
+                    }
+                }
+                // only svg/foreignObject could be block here, however if they are
+                // static then they don't need to be blocks since there will be no
+                // nested updates.
+                if (codegenNode.isBlock) {
+                    // except set custom directives.
+                    for (let i = 0; i < node.props.length; i++) {
+                        const p = node.props[i];
+                        if (p.type === 7 /* DIRECTIVE */) {
+                            constantCache.set(node, 0 /* NOT_CONSTANT */);
+                            return 0 /* NOT_CONSTANT */;
+                        }
+                    }
+                    context.removeHelper(OPEN_BLOCK);
+                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
+                    codegenNode.isBlock = false;
+                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
+                }
+                constantCache.set(node, returnType);
+                return returnType;
+            }
+            else {
+                constantCache.set(node, 0 /* NOT_CONSTANT */);
+                return 0 /* NOT_CONSTANT */;
+            }
+        case 2 /* TEXT */:
+        case 3 /* COMMENT */:
+            return 3 /* CAN_STRINGIFY */;
+        case 9 /* IF */:
+        case 11 /* FOR */:
+        case 10 /* IF_BRANCH */:
+            return 0 /* NOT_CONSTANT */;
+        case 5 /* INTERPOLATION */:
+        case 12 /* TEXT_CALL */:
+            return getConstantType(node.content, context);
+        case 4 /* SIMPLE_EXPRESSION */:
+            return node.constType;
+        case 8 /* COMPOUND_EXPRESSION */:
+            let returnType = 3 /* CAN_STRINGIFY */;
+            for (let i = 0; i < node.children.length; i++) {
+                const child = node.children[i];
+                if (isString(child) || isSymbol(child)) {
+                    continue;
+                }
+                const childType = getConstantType(child, context);
+                if (childType === 0 /* NOT_CONSTANT */) {
+                    return 0 /* NOT_CONSTANT */;
+                }
+                else if (childType < returnType) {
+                    returnType = childType;
+                }
+            }
+            return returnType;
+        default:
+            if ((process.env.NODE_ENV !== 'production')) ;
+            return 0 /* NOT_CONSTANT */;
+    }
+}
+const allowHoistedHelperSet = new Set([
+    NORMALIZE_CLASS,
+    NORMALIZE_STYLE,
+    NORMALIZE_PROPS,
+    GUARD_REACTIVE_PROPS
+]);
+function getConstantTypeOfHelperCall(value, context) {
+    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
+        !isString(value.callee) &&
+        allowHoistedHelperSet.has(value.callee)) {
+        const arg = value.arguments[0];
+        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
+            return getConstantType(arg, context);
+        }
+        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
+            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
+            return getConstantTypeOfHelperCall(arg, context);
+        }
+    }
+    return 0 /* NOT_CONSTANT */;
+}
+function getGeneratedPropsConstantType(node, context) {
+    let returnType = 3 /* CAN_STRINGIFY */;
+    const props = getNodeProps(node);
+    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
+        const { properties } = props;
+        for (let i = 0; i < properties.length; i++) {
+            const { key, value } = properties[i];
+            const keyType = getConstantType(key, context);
+            if (keyType === 0 /* NOT_CONSTANT */) {
+                return keyType;
+            }
+            if (keyType < returnType) {
+                returnType = keyType;
+            }
+            let valueType;
+            if (value.type === 4 /* SIMPLE_EXPRESSION */) {
+                valueType = getConstantType(value, context);
+            }
+            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
+                // some helper calls can be hoisted,
+                // such as the `normalizeProps` generated by the compiler for pre-normalize class,
+                // in this case we need to respect the ConstantType of the helper's arguments
+                valueType = getConstantTypeOfHelperCall(value, context);
+            }
+            else {
+                valueType = 0 /* NOT_CONSTANT */;
+            }
+            if (valueType === 0 /* NOT_CONSTANT */) {
+                return valueType;
+            }
+            if (valueType < returnType) {
+                returnType = valueType;
+            }
+        }
+    }
+    return returnType;
+}
+function getNodeProps(node) {
+    const codegenNode = node.codegenNode;
+    if (codegenNode.type === 13 /* VNODE_CALL */) {
+        return codegenNode.props;
+    }
+}
+function getPatchFlag(node) {
+    const flag = node.patchFlag;
+    return flag ? parseInt(flag, 10) : undefined;
 }
 
-function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
-    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
-    const context = {
-        // options
-        selfName: nameMatch && capitalize(camelize$1(nameMatch[1])),
-        prefixIdentifiers,
-        hoistStatic,
-        cacheHandlers,
-        nodeTransforms,
-        directiveTransforms,
-        transformHoist,
-        isBuiltInComponent,
-        isCustomElement,
-        expressionPlugins,
-        scopeId,
-        slotted,
-        ssr,
-        inSSR,
-        ssrCssVars,
-        bindingMetadata,
-        inline,
-        isTS,
-        onError,
-        onWarn,
-        compatConfig,
-        // state
-        root,
-        helpers: new Map(),
-        components: new Set(),
-        directives: new Set(),
-        hoists: [],
-        imports: [],
-        constantCache: new Map(),
-        temps: 0,
-        cached: 0,
-        identifiers: Object.create(null),
-        scopes: {
-            vFor: 0,
-            vSlot: 0,
-            vPre: 0,
-            vOnce: 0
-        },
-        parent: null,
-        currentNode: root,
-        childIndex: 0,
-        inVOnce: false,
-        // methods
-        helper(name) {
-            const count = context.helpers.get(name) || 0;
-            context.helpers.set(name, count + 1);
-            return name;
-        },
-        removeHelper(name) {
-            const count = context.helpers.get(name);
-            if (count) {
-                const currentCount = count - 1;
-                if (!currentCount) {
-                    context.helpers.delete(name);
-                }
-                else {
-                    context.helpers.set(name, currentCount);
-                }
-            }
-        },
-        helperString(name) {
-            return `_${helperNameMap[context.helper(name)]}`;
-        },
-        replaceNode(node) {
-            /* istanbul ignore if */
-            if ((process.env.NODE_ENV !== 'production')) {
-                if (!context.currentNode) {
-                    throw new Error(`Node being replaced is already removed.`);
-                }
-                if (!context.parent) {
-                    throw new Error(`Cannot replace root node.`);
-                }
-            }
-            context.parent.children[context.childIndex] = context.currentNode = node;
-        },
-        removeNode(node) {
-            if ((process.env.NODE_ENV !== 'production') && !context.parent) {
-                throw new Error(`Cannot remove root node.`);
-            }
-            const list = context.parent.children;
-            const removalIndex = node
-                ? list.indexOf(node)
-                : context.currentNode
-                    ? context.childIndex
-                    : -1;
-            /* istanbul ignore if */
-            if ((process.env.NODE_ENV !== 'production') && removalIndex < 0) {
-                throw new Error(`node being removed is not a child of current parent`);
-            }
-            if (!node || node === context.currentNode) {
-                // current node removed
-                context.currentNode = null;
-                context.onNodeRemoved();
-            }
-            else {
-                // sibling node removed
-                if (context.childIndex > removalIndex) {
-                    context.childIndex--;
-                    context.onNodeRemoved();
-                }
-            }
-            context.parent.children.splice(removalIndex, 1);
-        },
-        onNodeRemoved: () => { },
-        addIdentifiers(exp) {
-        },
-        removeIdentifiers(exp) {
-        },
-        hoist(exp) {
-            if (isString(exp))
-                exp = createSimpleExpression(exp);
-            context.hoists.push(exp);
-            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
-            identifier.hoisted = exp;
-            return identifier;
-        },
-        cache(exp, isVNode = false) {
-            return createCacheExpression(context.cached++, exp, isVNode);
-        }
-    };
-    {
-        context.filters = new Set();
-    }
-    return context;
-}
-function transform(root, options) {
-    const context = createTransformContext(root, options);
-    traverseNode(root, context);
-    if (options.hoistStatic) {
-        hoistStatic(root, context);
-    }
-    if (!options.ssr) {
-        createRootCodegen(root, context);
-    }
-    // finalize meta information
-    root.helpers = [...context.helpers.keys()];
-    root.components = [...context.components];
-    root.directives = [...context.directives];
-    root.imports = context.imports;
-    root.hoists = context.hoists;
-    root.temps = context.temps;
-    root.cached = context.cached;
-    {
-        root.filters = [...context.filters];
-    }
-}
-function createRootCodegen(root, context) {
-    const { helper } = context;
-    const { children } = root;
-    if (children.length === 1) {
-        const child = children[0];
-        // if the single child is an element, turn it into a block.
-        if (isSingleElementRoot(root, child) && child.codegenNode) {
-            // single element root is never hoisted so codegenNode will never be
-            // SimpleExpressionNode
-            const codegenNode = child.codegenNode;
-            if (codegenNode.type === 13 /* VNODE_CALL */) {
-                makeBlock(codegenNode, context);
-            }
-            root.codegenNode = codegenNode;
-        }
-        else {
-            // - single <slot/>, IfNode, ForNode: already blocks.
-            // - single text node: always patched.
-            // root codegen falls through via genNode()
-            root.codegenNode = child;
-        }
-    }
-    else if (children.length > 1) {
-        // root has multiple nodes - return a fragment block.
-        let patchFlag = 64 /* STABLE_FRAGMENT */;
-        let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
-        // check if the fragment actually contains a single valid child with
-        // the rest being comments
-        if ((process.env.NODE_ENV !== 'production') &&
-            children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
-            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
-            patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
-        }
-        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, undefined, false /* isComponent */);
-    }
-    else ;
-}
-function traverseChildren(parent, context) {
-    let i = 0;
-    const nodeRemoved = () => {
-        i--;
-    };
-    for (; i < parent.children.length; i++) {
-        const child = parent.children[i];
-        if (isString(child))
-            continue;
-        context.parent = parent;
-        context.childIndex = i;
-        context.onNodeRemoved = nodeRemoved;
-        traverseNode(child, context);
-    }
-}
-function traverseNode(node, context) {
-    context.currentNode = node;
-    // apply transform plugins
-    const { nodeTransforms } = context;
-    const exitFns = [];
-    for (let i = 0; i < nodeTransforms.length; i++) {
-        const onExit = nodeTransforms[i](node, context);
-        if (onExit) {
-            if (isArray(onExit)) {
-                exitFns.push(...onExit);
-            }
-            else {
-                exitFns.push(onExit);
-            }
-        }
-        if (!context.currentNode) {
-            // node was removed
-            return;
-        }
-        else {
-            // node may have been replaced
-            node = context.currentNode;
-        }
-    }
-    switch (node.type) {
-        case 3 /* COMMENT */:
-            if (!context.ssr) {
-                // inject import for the Comment symbol, which is needed for creating
-                // comment nodes with `createVNode`
-                context.helper(CREATE_COMMENT);
-            }
-            break;
-        case 5 /* INTERPOLATION */:
-            // no need to traverse, but we need to inject toString helper
-            if (!context.ssr) {
-                context.helper(TO_DISPLAY_STRING);
-            }
-            break;
-        // for container types, further traverse downwards
-        case 9 /* IF */:
-            for (let i = 0; i < node.branches.length; i++) {
-                traverseNode(node.branches[i], context);
-            }
-            break;
-        case 10 /* IF_BRANCH */:
-        case 11 /* FOR */:
-        case 1 /* ELEMENT */:
-        case 0 /* ROOT */:
-            traverseChildren(node, context);
-            break;
-    }
-    // exit transforms
-    context.currentNode = node;
-    let i = exitFns.length;
-    while (i--) {
-        exitFns[i]();
-    }
-}
-function createStructuralDirectiveTransform(name, fn) {
-    const matches = isString(name)
-        ? (n) => n === name
-        : (n) => name.test(n);
-    return (node, context) => {
-        if (node.type === 1 /* ELEMENT */) {
-            const { props } = node;
-            // structural directive transforms are not concerned with slots
-            // as they are handled separately in vSlot.ts
-            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
-                return;
-            }
-            const exitFns = [];
-            for (let i = 0; i < props.length; i++) {
-                const prop = props[i];
-                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
-                    // structural directives are removed to avoid infinite recursion
-                    // also we remove them *before* applying so that it can further
-                    // traverse itself in case it moves the node around
-                    props.splice(i, 1);
-                    i--;
-                    const onExit = fn(node, prop, context);
-                    if (onExit)
-                        exitFns.push(onExit);
-                }
-            }
-            return exitFns;
-        }
-    };
+function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
+    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
+    const context = {
+        // options
+        selfName: nameMatch && capitalize(camelize$1(nameMatch[1])),
+        prefixIdentifiers,
+        hoistStatic,
+        cacheHandlers,
+        nodeTransforms,
+        directiveTransforms,
+        transformHoist,
+        isBuiltInComponent,
+        isCustomElement,
+        expressionPlugins,
+        scopeId,
+        slotted,
+        ssr,
+        inSSR,
+        ssrCssVars,
+        bindingMetadata,
+        inline,
+        isTS,
+        onError,
+        onWarn,
+        compatConfig,
+        // state
+        root,
+        helpers: new Map(),
+        components: new Set(),
+        directives: new Set(),
+        hoists: [],
+        imports: [],
+        constantCache: new Map(),
+        temps: 0,
+        cached: 0,
+        identifiers: Object.create(null),
+        scopes: {
+            vFor: 0,
+            vSlot: 0,
+            vPre: 0,
+            vOnce: 0
+        },
+        parent: null,
+        currentNode: root,
+        childIndex: 0,
+        inVOnce: false,
+        // methods
+        helper(name) {
+            const count = context.helpers.get(name) || 0;
+            context.helpers.set(name, count + 1);
+            return name;
+        },
+        removeHelper(name) {
+            const count = context.helpers.get(name);
+            if (count) {
+                const currentCount = count - 1;
+                if (!currentCount) {
+                    context.helpers.delete(name);
+                }
+                else {
+                    context.helpers.set(name, currentCount);
+                }
+            }
+        },
+        helperString(name) {
+            return `_${helperNameMap[context.helper(name)]}`;
+        },
+        replaceNode(node) {
+            /* istanbul ignore if */
+            if ((process.env.NODE_ENV !== 'production')) {
+                if (!context.currentNode) {
+                    throw new Error(`Node being replaced is already removed.`);
+                }
+                if (!context.parent) {
+                    throw new Error(`Cannot replace root node.`);
+                }
+            }
+            context.parent.children[context.childIndex] = context.currentNode = node;
+        },
+        removeNode(node) {
+            if ((process.env.NODE_ENV !== 'production') && !context.parent) {
+                throw new Error(`Cannot remove root node.`);
+            }
+            const list = context.parent.children;
+            const removalIndex = node
+                ? list.indexOf(node)
+                : context.currentNode
+                    ? context.childIndex
+                    : -1;
+            /* istanbul ignore if */
+            if ((process.env.NODE_ENV !== 'production') && removalIndex < 0) {
+                throw new Error(`node being removed is not a child of current parent`);
+            }
+            if (!node || node === context.currentNode) {
+                // current node removed
+                context.currentNode = null;
+                context.onNodeRemoved();
+            }
+            else {
+                // sibling node removed
+                if (context.childIndex > removalIndex) {
+                    context.childIndex--;
+                    context.onNodeRemoved();
+                }
+            }
+            context.parent.children.splice(removalIndex, 1);
+        },
+        onNodeRemoved: () => { },
+        addIdentifiers(exp) {
+        },
+        removeIdentifiers(exp) {
+        },
+        hoist(exp) {
+            if (isString(exp))
+                exp = createSimpleExpression(exp);
+            context.hoists.push(exp);
+            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
+            identifier.hoisted = exp;
+            return identifier;
+        },
+        cache(exp, isVNode = false) {
+            return createCacheExpression(context.cached++, exp, isVNode);
+        }
+    };
+    {
+        context.filters = new Set();
+    }
+    return context;
+}
+function transform(root, options) {
+    const context = createTransformContext(root, options);
+    traverseNode(root, context);
+    if (options.hoistStatic) {
+        hoistStatic(root, context);
+    }
+    if (!options.ssr) {
+        createRootCodegen(root, context);
+    }
+    // finalize meta information
+    root.helpers = [...context.helpers.keys()];
+    root.components = [...context.components];
+    root.directives = [...context.directives];
+    root.imports = context.imports;
+    root.hoists = context.hoists;
+    root.temps = context.temps;
+    root.cached = context.cached;
+    {
+        root.filters = [...context.filters];
+    }
+}
+function createRootCodegen(root, context) {
+    const { helper } = context;
+    const { children } = root;
+    if (children.length === 1) {
+        const child = children[0];
+        // if the single child is an element, turn it into a block.
+        if (isSingleElementRoot(root, child) && child.codegenNode) {
+            // single element root is never hoisted so codegenNode will never be
+            // SimpleExpressionNode
+            const codegenNode = child.codegenNode;
+            if (codegenNode.type === 13 /* VNODE_CALL */) {
+                makeBlock(codegenNode, context);
+            }
+            root.codegenNode = codegenNode;
+        }
+        else {
+            // - single <slot/>, IfNode, ForNode: already blocks.
+            // - single text node: always patched.
+            // root codegen falls through via genNode()
+            root.codegenNode = child;
+        }
+    }
+    else if (children.length > 1) {
+        // root has multiple nodes - return a fragment block.
+        let patchFlag = 64 /* STABLE_FRAGMENT */;
+        let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
+        // check if the fragment actually contains a single valid child with
+        // the rest being comments
+        if ((process.env.NODE_ENV !== 'production') &&
+            children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
+            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
+            patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
+        }
+        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, undefined, false /* isComponent */);
+    }
+    else ;
+}
+function traverseChildren(parent, context) {
+    let i = 0;
+    const nodeRemoved = () => {
+        i--;
+    };
+    for (; i < parent.children.length; i++) {
+        const child = parent.children[i];
+        if (isString(child))
+            continue;
+        context.parent = parent;
+        context.childIndex = i;
+        context.onNodeRemoved = nodeRemoved;
+        traverseNode(child, context);
+    }
+}
+function traverseNode(node, context) {
+    context.currentNode = node;
+    // apply transform plugins
+    const { nodeTransforms } = context;
+    const exitFns = [];
+    for (let i = 0; i < nodeTransforms.length; i++) {
+        const onExit = nodeTransforms[i](node, context);
+        if (onExit) {
+            if (isArray(onExit)) {
+                exitFns.push(...onExit);
+            }
+            else {
+                exitFns.push(onExit);
+            }
+        }
+        if (!context.currentNode) {
+            // node was removed
+            return;
+        }
+        else {
+            // node may have been replaced
+            node = context.currentNode;
+        }
+    }
+    switch (node.type) {
+        case 3 /* COMMENT */:
+            if (!context.ssr) {
+                // inject import for the Comment symbol, which is needed for creating
+                // comment nodes with `createVNode`
+                context.helper(CREATE_COMMENT);
+            }
+            break;
+        case 5 /* INTERPOLATION */:
+            // no need to traverse, but we need to inject toString helper
+            if (!context.ssr) {
+                context.helper(TO_DISPLAY_STRING);
+            }
+            break;
+        // for container types, further traverse downwards
+        case 9 /* IF */:
+            for (let i = 0; i < node.branches.length; i++) {
+                traverseNode(node.branches[i], context);
+            }
+            break;
+        case 10 /* IF_BRANCH */:
+        case 11 /* FOR */:
+        case 1 /* ELEMENT */:
+        case 0 /* ROOT */:
+            traverseChildren(node, context);
+            break;
+    }
+    // exit transforms
+    context.currentNode = node;
+    let i = exitFns.length;
+    while (i--) {
+        exitFns[i]();
+    }
+}
+function createStructuralDirectiveTransform(name, fn) {
+    const matches = isString(name)
+        ? (n) => n === name
+        : (n) => name.test(n);
+    return (node, context) => {
+        if (node.type === 1 /* ELEMENT */) {
+            const { props } = node;
+            // structural directive transforms are not concerned with slots
+            // as they are handled separately in vSlot.ts
+            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
+                return;
+            }
+            const exitFns = [];
+            for (let i = 0; i < props.length; i++) {
+                const prop = props[i];
+                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
+                    // structural directives are removed to avoid infinite recursion
+                    // also we remove them *before* applying so that it can further
+                    // traverse itself in case it moves the node around
+                    props.splice(i, 1);
+                    i--;
+                    const onExit = fn(node, prop, context);
+                    if (onExit)
+                        exitFns.push(onExit);
+                }
+            }
+            return exitFns;
+        }
+    };
 }
 
-const PURE_ANNOTATION = `/*#__PURE__*/`;
-const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
-function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {
-    const context = {
-        mode,
-        prefixIdentifiers,
-        sourceMap,
-        filename,
-        scopeId,
-        optimizeImports,
-        runtimeGlobalName,
-        runtimeModuleName,
-        ssrRuntimeModuleName,
-        ssr,
-        isTS,
-        inSSR,
-        source: ast.loc.source,
-        code: ``,
-        column: 1,
-        line: 1,
-        offset: 0,
-        indentLevel: 0,
-        pure: false,
-        map: undefined,
-        helper(key) {
-            return `_${helperNameMap[key]}`;
-        },
-        push(code, node) {
-            context.code += code;
-        },
-        indent() {
-            newline(++context.indentLevel);
-        },
-        deindent(withoutNewLine = false) {
-            if (withoutNewLine) {
-                --context.indentLevel;
-            }
-            else {
-                newline(--context.indentLevel);
-            }
-        },
-        newline() {
-            newline(context.indentLevel);
-        }
-    };
-    function newline(n) {
-        context.push('\n' + `  `.repeat(n));
-    }
-    return context;
-}
-function generate(ast, options = {}) {
-    const context = createCodegenContext(ast, options);
-    if (options.onContextCreated)
-        options.onContextCreated(context);
-    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
-    const hasHelpers = ast.helpers.length > 0;
-    const useWithBlock = !prefixIdentifiers && mode !== 'module';
-    // preambles
-    // in setup() inline mode, the preamble is generated in a sub context
-    // and returned separately.
-    const preambleContext = context;
-    {
-        genFunctionPreamble(ast, preambleContext);
-    }
-    // enter render function
-    const functionName = ssr ? `ssrRender` : `render`;
-    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
-    const signature = args.join(', ');
-    {
-        push(`function ${functionName}(${signature}) {`);
-    }
-    indent();
-    if (useWithBlock) {
-        push(`with (_ctx) {`);
-        indent();
-        // function mode const declarations should be inside with block
-        // also they should be renamed to avoid collision with user properties
-        if (hasHelpers) {
-            push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`);
-            push(`\n`);
-            newline();
-        }
-    }
-    // generate asset resolution statements
-    if (ast.components.length) {
-        genAssets(ast.components, 'component', context);
-        if (ast.directives.length || ast.temps > 0) {
-            newline();
-        }
-    }
-    if (ast.directives.length) {
-        genAssets(ast.directives, 'directive', context);
-        if (ast.temps > 0) {
-            newline();
-        }
-    }
-    if (ast.filters && ast.filters.length) {
-        newline();
-        genAssets(ast.filters, 'filter', context);
-        newline();
-    }
-    if (ast.temps > 0) {
-        push(`let `);
-        for (let i = 0; i < ast.temps; i++) {
-            push(`${i > 0 ? `, ` : ``}_temp${i}`);
-        }
-    }
-    if (ast.components.length || ast.directives.length || ast.temps) {
-        push(`\n`);
-        newline();
-    }
-    // generate the VNode tree expression
-    if (!ssr) {
-        push(`return `);
-    }
-    if (ast.codegenNode) {
-        genNode(ast.codegenNode, context);
-    }
-    else {
-        push(`null`);
-    }
-    if (useWithBlock) {
-        deindent();
-        push(`}`);
-    }
-    deindent();
-    push(`}`);
-    return {
-        ast,
-        code: context.code,
-        preamble: ``,
-        // SourceMapGenerator does have toJSON() method but it's not in the types
-        map: context.map ? context.map.toJSON() : undefined
-    };
-}
-function genFunctionPreamble(ast, context) {
-    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
-    const VueBinding = runtimeGlobalName;
-    // Generate const declaration for helpers
-    // In prefix mode, we place the const declaration at top so it's done
-    // only once; But if we not prefixing, we place the declaration inside the
-    // with block so it doesn't incur the `in` check cost for every helper access.
-    if (ast.helpers.length > 0) {
-        {
-            // "with" mode.
-            // save Vue in a separate variable to avoid collision
-            push(`const _Vue = ${VueBinding}\n`);
-            // in "with" mode, helpers are declared inside the with block to avoid
-            // has check cost, but hoists are lifted out of the function - we need
-            // to provide the helper here.
-            if (ast.hoists.length) {
-                const staticHelpers = [
-                    CREATE_VNODE,
-                    CREATE_ELEMENT_VNODE,
-                    CREATE_COMMENT,
-                    CREATE_TEXT,
-                    CREATE_STATIC
-                ]
-                    .filter(helper => ast.helpers.includes(helper))
-                    .map(aliasHelper)
-                    .join(', ');
-                push(`const { ${staticHelpers} } = _Vue\n`);
-            }
-        }
-    }
-    genHoists(ast.hoists, context);
-    newline();
-    push(`return `);
-}
-function genAssets(assets, type, { helper, push, newline, isTS }) {
-    const resolver = helper(type === 'filter'
-        ? RESOLVE_FILTER
-        : type === 'component'
-            ? RESOLVE_COMPONENT
-            : RESOLVE_DIRECTIVE);
-    for (let i = 0; i < assets.length; i++) {
-        let id = assets[i];
-        // potential component implicit self-reference inferred from SFC filename
-        const maybeSelfReference = id.endsWith('__self');
-        if (maybeSelfReference) {
-            id = id.slice(0, -6);
-        }
-        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
-        if (i < assets.length - 1) {
-            newline();
-        }
-    }
-}
-function genHoists(hoists, context) {
-    if (!hoists.length) {
-        return;
-    }
-    context.pure = true;
-    const { push, newline, helper, scopeId, mode } = context;
-    newline();
-    for (let i = 0; i < hoists.length; i++) {
-        const exp = hoists[i];
-        if (exp) {
-            push(`const _hoisted_${i + 1} = ${``}`);
-            genNode(exp, context);
-            newline();
-        }
-    }
-    context.pure = false;
-}
-function isText$1(n) {
-    return (isString(n) ||
-        n.type === 4 /* SIMPLE_EXPRESSION */ ||
-        n.type === 2 /* TEXT */ ||
-        n.type === 5 /* INTERPOLATION */ ||
-        n.type === 8 /* COMPOUND_EXPRESSION */);
-}
-function genNodeListAsArray(nodes, context) {
-    const multilines = nodes.length > 3 ||
-        (((process.env.NODE_ENV !== 'production')) && nodes.some(n => isArray(n) || !isText$1(n)));
-    context.push(`[`);
-    multilines && context.indent();
-    genNodeList(nodes, context, multilines);
-    multilines && context.deindent();
-    context.push(`]`);
-}
-function genNodeList(nodes, context, multilines = false, comma = true) {
-    const { push, newline } = context;
-    for (let i = 0; i < nodes.length; i++) {
-        const node = nodes[i];
-        if (isString(node)) {
-            push(node);
-        }
-        else if (isArray(node)) {
-            genNodeListAsArray(node, context);
-        }
-        else {
-            genNode(node, context);
-        }
-        if (i < nodes.length - 1) {
-            if (multilines) {
-                comma && push(',');
-                newline();
-            }
-            else {
-                comma && push(', ');
-            }
-        }
-    }
-}
-function genNode(node, context) {
-    if (isString(node)) {
-        context.push(node);
-        return;
-    }
-    if (isSymbol(node)) {
-        context.push(context.helper(node));
-        return;
-    }
-    switch (node.type) {
-        case 1 /* ELEMENT */:
-        case 9 /* IF */:
-        case 11 /* FOR */:
-            (process.env.NODE_ENV !== 'production') &&
-                assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
-                    `Apply appropriate transforms first.`);
-            genNode(node.codegenNode, context);
-            break;
-        case 2 /* TEXT */:
-            genText(node, context);
-            break;
-        case 4 /* SIMPLE_EXPRESSION */:
-            genExpression(node, context);
-            break;
-        case 5 /* INTERPOLATION */:
-            genInterpolation(node, context);
-            break;
-        case 12 /* TEXT_CALL */:
-            genNode(node.codegenNode, context);
-            break;
-        case 8 /* COMPOUND_EXPRESSION */:
-            genCompoundExpression(node, context);
-            break;
-        case 3 /* COMMENT */:
-            genComment(node, context);
-            break;
-        case 13 /* VNODE_CALL */:
-            genVNodeCall(node, context);
-            break;
-        case 14 /* JS_CALL_EXPRESSION */:
-            genCallExpression(node, context);
-            break;
-        case 15 /* JS_OBJECT_EXPRESSION */:
-            genObjectExpression(node, context);
-            break;
-        case 17 /* JS_ARRAY_EXPRESSION */:
-            genArrayExpression(node, context);
-            break;
-        case 18 /* JS_FUNCTION_EXPRESSION */:
-            genFunctionExpression(node, context);
-            break;
-        case 19 /* JS_CONDITIONAL_EXPRESSION */:
-            genConditionalExpression(node, context);
-            break;
-        case 20 /* JS_CACHE_EXPRESSION */:
-            genCacheExpression(node, context);
-            break;
-        case 21 /* JS_BLOCK_STATEMENT */:
-            genNodeList(node.body, context, true, false);
-            break;
-        // SSR only types
-        case 22 /* JS_TEMPLATE_LITERAL */:
-            break;
-        case 23 /* JS_IF_STATEMENT */:
-            break;
-        case 24 /* JS_ASSIGNMENT_EXPRESSION */:
-            break;
-        case 25 /* JS_SEQUENCE_EXPRESSION */:
-            break;
-        case 26 /* JS_RETURN_STATEMENT */:
-            break;
-        /* istanbul ignore next */
-        case 10 /* IF_BRANCH */:
-            // noop
-            break;
-        default:
-            if ((process.env.NODE_ENV !== 'production')) {
-                assert(false, `unhandled codegen node type: ${node.type}`);
-                // make sure we exhaust all possible types
-                const exhaustiveCheck = node;
-                return exhaustiveCheck;
-            }
-    }
-}
-function genText(node, context) {
-    context.push(JSON.stringify(node.content), node);
-}
-function genExpression(node, context) {
-    const { content, isStatic } = node;
-    context.push(isStatic ? JSON.stringify(content) : content, node);
-}
-function genInterpolation(node, context) {
-    const { push, helper, pure } = context;
-    if (pure)
-        push(PURE_ANNOTATION);
-    push(`${helper(TO_DISPLAY_STRING)}(`);
-    genNode(node.content, context);
-    push(`)`);
-}
-function genCompoundExpression(node, context) {
-    for (let i = 0; i < node.children.length; i++) {
-        const child = node.children[i];
-        if (isString(child)) {
-            context.push(child);
-        }
-        else {
-            genNode(child, context);
-        }
-    }
-}
-function genExpressionAsPropertyKey(node, context) {
-    const { push } = context;
-    if (node.type === 8 /* COMPOUND_EXPRESSION */) {
-        push(`[`);
-        genCompoundExpression(node, context);
-        push(`]`);
-    }
-    else if (node.isStatic) {
-        // only quote keys if necessary
-        const text = isSimpleIdentifier(node.content)
-            ? node.content
-            : JSON.stringify(node.content);
-        push(text, node);
-    }
-    else {
-        push(`[${node.content}]`, node);
-    }
-}
-function genComment(node, context) {
-    const { push, helper, pure } = context;
-    if (pure) {
-        push(PURE_ANNOTATION);
-    }
-    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
-}
-function genVNodeCall(node, context) {
-    const { push, helper, pure } = context;
-    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
-    if (directives) {
-        push(helper(WITH_DIRECTIVES) + `(`);
-    }
-    if (isBlock) {
-        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
-    }
-    if (pure) {
-        push(PURE_ANNOTATION);
-    }
-    const callHelper = isBlock
-        ? getVNodeBlockHelper(context.inSSR, isComponent)
-        : getVNodeHelper(context.inSSR, isComponent);
-    push(helper(callHelper) + `(`, node);
-    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
-    push(`)`);
-    if (isBlock) {
-        push(`)`);
-    }
-    if (directives) {
-        push(`, `);
-        genNode(directives, context);
-        push(`)`);
-    }
-}
-function genNullableArgs(args) {
-    let i = args.length;
-    while (i--) {
-        if (args[i] != null)
-            break;
-    }
-    return args.slice(0, i + 1).map(arg => arg || `null`);
-}
-// JavaScript
-function genCallExpression(node, context) {
-    const { push, helper, pure } = context;
-    const callee = isString(node.callee) ? node.callee : helper(node.callee);
-    if (pure) {
-        push(PURE_ANNOTATION);
-    }
-    push(callee + `(`, node);
-    genNodeList(node.arguments, context);
-    push(`)`);
-}
-function genObjectExpression(node, context) {
-    const { push, indent, deindent, newline } = context;
-    const { properties } = node;
-    if (!properties.length) {
-        push(`{}`, node);
-        return;
-    }
-    const multilines = properties.length > 1 ||
-        (((process.env.NODE_ENV !== 'production')) &&
-            properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
-    push(multilines ? `{` : `{ `);
-    multilines && indent();
-    for (let i = 0; i < properties.length; i++) {
-        const { key, value } = properties[i];
-        // key
-        genExpressionAsPropertyKey(key, context);
-        push(`: `);
-        // value
-        genNode(value, context);
-        if (i < properties.length - 1) {
-            // will only reach this if it's multilines
-            push(`,`);
-            newline();
-        }
-    }
-    multilines && deindent();
-    push(multilines ? `}` : ` }`);
-}
-function genArrayExpression(node, context) {
-    genNodeListAsArray(node.elements, context);
-}
-function genFunctionExpression(node, context) {
-    const { push, indent, deindent } = context;
-    const { params, returns, body, newline, isSlot } = node;
-    if (isSlot) {
-        // wrap slot functions with owner context
-        push(`_${helperNameMap[WITH_CTX]}(`);
-    }
-    push(`(`, node);
-    if (isArray(params)) {
-        genNodeList(params, context);
-    }
-    else if (params) {
-        genNode(params, context);
-    }
-    push(`) => `);
-    if (newline || body) {
-        push(`{`);
-        indent();
-    }
-    if (returns) {
-        if (newline) {
-            push(`return `);
-        }
-        if (isArray(returns)) {
-            genNodeListAsArray(returns, context);
-        }
-        else {
-            genNode(returns, context);
-        }
-    }
-    else if (body) {
-        genNode(body, context);
-    }
-    if (newline || body) {
-        deindent();
-        push(`}`);
-    }
-    if (isSlot) {
-        if (node.isNonScopedSlot) {
-            push(`, undefined, true`);
-        }
-        push(`)`);
-    }
-}
-function genConditionalExpression(node, context) {
-    const { test, consequent, alternate, newline: needNewline } = node;
-    const { push, indent, deindent, newline } = context;
-    if (test.type === 4 /* SIMPLE_EXPRESSION */) {
-        const needsParens = !isSimpleIdentifier(test.content);
-        needsParens && push(`(`);
-        genExpression(test, context);
-        needsParens && push(`)`);
-    }
-    else {
-        push(`(`);
-        genNode(test, context);
-        push(`)`);
-    }
-    needNewline && indent();
-    context.indentLevel++;
-    needNewline || push(` `);
-    push(`? `);
-    genNode(consequent, context);
-    context.indentLevel--;
-    needNewline && newline();
-    needNewline || push(` `);
-    push(`: `);
-    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
-    if (!isNested) {
-        context.indentLevel++;
-    }
-    genNode(alternate, context);
-    if (!isNested) {
-        context.indentLevel--;
-    }
-    needNewline && deindent(true /* without newline */);
-}
-function genCacheExpression(node, context) {
-    const { push, helper, indent, deindent, newline } = context;
-    push(`_cache[${node.index}] || (`);
-    if (node.isVNode) {
-        indent();
-        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
-        newline();
-    }
-    push(`_cache[${node.index}] = `);
-    genNode(node.value, context);
-    if (node.isVNode) {
-        push(`,`);
-        newline();
-        push(`${helper(SET_BLOCK_TRACKING)}(1),`);
-        newline();
-        push(`_cache[${node.index}]`);
-        deindent();
-    }
-    push(`)`);
+const PURE_ANNOTATION = `/*#__PURE__*/`;
+const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
+function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {
+    const context = {
+        mode,
+        prefixIdentifiers,
+        sourceMap,
+        filename,
+        scopeId,
+        optimizeImports,
+        runtimeGlobalName,
+        runtimeModuleName,
+        ssrRuntimeModuleName,
+        ssr,
+        isTS,
+        inSSR,
+        source: ast.loc.source,
+        code: ``,
+        column: 1,
+        line: 1,
+        offset: 0,
+        indentLevel: 0,
+        pure: false,
+        map: undefined,
+        helper(key) {
+            return `_${helperNameMap[key]}`;
+        },
+        push(code, node) {
+            context.code += code;
+        },
+        indent() {
+            newline(++context.indentLevel);
+        },
+        deindent(withoutNewLine = false) {
+            if (withoutNewLine) {
+                --context.indentLevel;
+            }
+            else {
+                newline(--context.indentLevel);
+            }
+        },
+        newline() {
+            newline(context.indentLevel);
+        }
+    };
+    function newline(n) {
+        context.push('\n' + `  `.repeat(n));
+    }
+    return context;
+}
+function generate(ast, options = {}) {
+    const context = createCodegenContext(ast, options);
+    if (options.onContextCreated)
+        options.onContextCreated(context);
+    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
+    const hasHelpers = ast.helpers.length > 0;
+    const useWithBlock = !prefixIdentifiers && mode !== 'module';
+    // preambles
+    // in setup() inline mode, the preamble is generated in a sub context
+    // and returned separately.
+    const preambleContext = context;
+    {
+        genFunctionPreamble(ast, preambleContext);
+    }
+    // enter render function
+    const functionName = ssr ? `ssrRender` : `render`;
+    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
+    const signature = args.join(', ');
+    {
+        push(`function ${functionName}(${signature}) {`);
+    }
+    indent();
+    if (useWithBlock) {
+        push(`with (_ctx) {`);
+        indent();
+        // function mode const declarations should be inside with block
+        // also they should be renamed to avoid collision with user properties
+        if (hasHelpers) {
+            push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`);
+            push(`\n`);
+            newline();
+        }
+    }
+    // generate asset resolution statements
+    if (ast.components.length) {
+        genAssets(ast.components, 'component', context);
+        if (ast.directives.length || ast.temps > 0) {
+            newline();
+        }
+    }
+    if (ast.directives.length) {
+        genAssets(ast.directives, 'directive', context);
+        if (ast.temps > 0) {
+            newline();
+        }
+    }
+    if (ast.filters && ast.filters.length) {
+        newline();
+        genAssets(ast.filters, 'filter', context);
+        newline();
+    }
+    if (ast.temps > 0) {
+        push(`let `);
+        for (let i = 0; i < ast.temps; i++) {
+            push(`${i > 0 ? `, ` : ``}_temp${i}`);
+        }
+    }
+    if (ast.components.length || ast.directives.length || ast.temps) {
+        push(`\n`);
+        newline();
+    }
+    // generate the VNode tree expression
+    if (!ssr) {
+        push(`return `);
+    }
+    if (ast.codegenNode) {
+        genNode(ast.codegenNode, context);
+    }
+    else {
+        push(`null`);
+    }
+    if (useWithBlock) {
+        deindent();
+        push(`}`);
+    }
+    deindent();
+    push(`}`);
+    return {
+        ast,
+        code: context.code,
+        preamble: ``,
+        // SourceMapGenerator does have toJSON() method but it's not in the types
+        map: context.map ? context.map.toJSON() : undefined
+    };
+}
+function genFunctionPreamble(ast, context) {
+    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
+    const VueBinding = runtimeGlobalName;
+    // Generate const declaration for helpers
+    // In prefix mode, we place the const declaration at top so it's done
+    // only once; But if we not prefixing, we place the declaration inside the
+    // with block so it doesn't incur the `in` check cost for every helper access.
+    if (ast.helpers.length > 0) {
+        {
+            // "with" mode.
+            // save Vue in a separate variable to avoid collision
+            push(`const _Vue = ${VueBinding}\n`);
+            // in "with" mode, helpers are declared inside the with block to avoid
+            // has check cost, but hoists are lifted out of the function - we need
+            // to provide the helper here.
+            if (ast.hoists.length) {
+                const staticHelpers = [
+                    CREATE_VNODE,
+                    CREATE_ELEMENT_VNODE,
+                    CREATE_COMMENT,
+                    CREATE_TEXT,
+                    CREATE_STATIC
+                ]
+                    .filter(helper => ast.helpers.includes(helper))
+                    .map(aliasHelper)
+                    .join(', ');
+                push(`const { ${staticHelpers} } = _Vue\n`);
+            }
+        }
+    }
+    genHoists(ast.hoists, context);
+    newline();
+    push(`return `);
+}
+function genAssets(assets, type, { helper, push, newline, isTS }) {
+    const resolver = helper(type === 'filter'
+        ? RESOLVE_FILTER
+        : type === 'component'
+            ? RESOLVE_COMPONENT
+            : RESOLVE_DIRECTIVE);
+    for (let i = 0; i < assets.length; i++) {
+        let id = assets[i];
+        // potential component implicit self-reference inferred from SFC filename
+        const maybeSelfReference = id.endsWith('__self');
+        if (maybeSelfReference) {
+            id = id.slice(0, -6);
+        }
+        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
+        if (i < assets.length - 1) {
+            newline();
+        }
+    }
+}
+function genHoists(hoists, context) {
+    if (!hoists.length) {
+        return;
+    }
+    context.pure = true;
+    const { push, newline, helper, scopeId, mode } = context;
+    newline();
+    for (let i = 0; i < hoists.length; i++) {
+        const exp = hoists[i];
+        if (exp) {
+            push(`const _hoisted_${i + 1} = ${``}`);
+            genNode(exp, context);
+            newline();
+        }
+    }
+    context.pure = false;
+}
+function isText$1(n) {
+    return (isString(n) ||
+        n.type === 4 /* SIMPLE_EXPRESSION */ ||
+        n.type === 2 /* TEXT */ ||
+        n.type === 5 /* INTERPOLATION */ ||
+        n.type === 8 /* COMPOUND_EXPRESSION */);
+}
+function genNodeListAsArray(nodes, context) {
+    const multilines = nodes.length > 3 ||
+        (((process.env.NODE_ENV !== 'production')) && nodes.some(n => isArray(n) || !isText$1(n)));
+    context.push(`[`);
+    multilines && context.indent();
+    genNodeList(nodes, context, multilines);
+    multilines && context.deindent();
+    context.push(`]`);
+}
+function genNodeList(nodes, context, multilines = false, comma = true) {
+    const { push, newline } = context;
+    for (let i = 0; i < nodes.length; i++) {
+        const node = nodes[i];
+        if (isString(node)) {
+            push(node);
+        }
+        else if (isArray(node)) {
+            genNodeListAsArray(node, context);
+        }
+        else {
+            genNode(node, context);
+        }
+        if (i < nodes.length - 1) {
+            if (multilines) {
+                comma && push(',');
+                newline();
+            }
+            else {
+                comma && push(', ');
+            }
+        }
+    }
+}
+function genNode(node, context) {
+    if (isString(node)) {
+        context.push(node);
+        return;
+    }
+    if (isSymbol(node)) {
+        context.push(context.helper(node));
+        return;
+    }
+    switch (node.type) {
+        case 1 /* ELEMENT */:
+        case 9 /* IF */:
+        case 11 /* FOR */:
+            (process.env.NODE_ENV !== 'production') &&
+                assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
+                    `Apply appropriate transforms first.`);
+            genNode(node.codegenNode, context);
+            break;
+        case 2 /* TEXT */:
+            genText(node, context);
+            break;
+        case 4 /* SIMPLE_EXPRESSION */:
+            genExpression(node, context);
+            break;
+        case 5 /* INTERPOLATION */:
+            genInterpolation(node, context);
+            break;
+        case 12 /* TEXT_CALL */:
+            genNode(node.codegenNode, context);
+            break;
+        case 8 /* COMPOUND_EXPRESSION */:
+            genCompoundExpression(node, context);
+            break;
+        case 3 /* COMMENT */:
+            genComment(node, context);
+            break;
+        case 13 /* VNODE_CALL */:
+            genVNodeCall(node, context);
+            break;
+        case 14 /* JS_CALL_EXPRESSION */:
+            genCallExpression(node, context);
+            break;
+        case 15 /* JS_OBJECT_EXPRESSION */:
+            genObjectExpression(node, context);
+            break;
+        case 17 /* JS_ARRAY_EXPRESSION */:
+            genArrayExpression(node, context);
+            break;
+        case 18 /* JS_FUNCTION_EXPRESSION */:
+            genFunctionExpression(node, context);
+            break;
+        case 19 /* JS_CONDITIONAL_EXPRESSION */:
+            genConditionalExpression(node, context);
+            break;
+        case 20 /* JS_CACHE_EXPRESSION */:
+            genCacheExpression(node, context);
+            break;
+        case 21 /* JS_BLOCK_STATEMENT */:
+            genNodeList(node.body, context, true, false);
+            break;
+        // SSR only types
+        case 22 /* JS_TEMPLATE_LITERAL */:
+            break;
+        case 23 /* JS_IF_STATEMENT */:
+            break;
+        case 24 /* JS_ASSIGNMENT_EXPRESSION */:
+            break;
+        case 25 /* JS_SEQUENCE_EXPRESSION */:
+            break;
+        case 26 /* JS_RETURN_STATEMENT */:
+            break;
+        /* istanbul ignore next */
+        case 10 /* IF_BRANCH */:
+            // noop
+            break;
+        default:
+            if ((process.env.NODE_ENV !== 'production')) {
+                assert(false, `unhandled codegen node type: ${node.type}`);
+                // make sure we exhaust all possible types
+                const exhaustiveCheck = node;
+                return exhaustiveCheck;
+            }
+    }
+}
+function genText(node, context) {
+    context.push(JSON.stringify(node.content), node);
+}
+function genExpression(node, context) {
+    const { content, isStatic } = node;
+    context.push(isStatic ? JSON.stringify(content) : content, node);
+}
+function genInterpolation(node, context) {
+    const { push, helper, pure } = context;
+    if (pure)
+        push(PURE_ANNOTATION);
+    push(`${helper(TO_DISPLAY_STRING)}(`);
+    genNode(node.content, context);
+    push(`)`);
+}
+function genCompoundExpression(node, context) {
+    for (let i = 0; i < node.children.length; i++) {
+        const child = node.children[i];
+        if (isString(child)) {
+            context.push(child);
+        }
+        else {
+            genNode(child, context);
+        }
+    }
+}
+function genExpressionAsPropertyKey(node, context) {
+    const { push } = context;
+    if (node.type === 8 /* COMPOUND_EXPRESSION */) {
+        push(`[`);
+        genCompoundExpression(node, context);
+        push(`]`);
+    }
+    else if (node.isStatic) {
+        // only quote keys if necessary
+        const text = isSimpleIdentifier(node.content)
+            ? node.content
+            : JSON.stringify(node.content);
+        push(text, node);
+    }
+    else {
+        push(`[${node.content}]`, node);
+    }
+}
+function genComment(node, context) {
+    const { push, helper, pure } = context;
+    if (pure) {
+        push(PURE_ANNOTATION);
+    }
+    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
+}
+function genVNodeCall(node, context) {
+    const { push, helper, pure } = context;
+    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
+    if (directives) {
+        push(helper(WITH_DIRECTIVES) + `(`);
+    }
+    if (isBlock) {
+        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
+    }
+    if (pure) {
+        push(PURE_ANNOTATION);
+    }
+    const callHelper = isBlock
+        ? getVNodeBlockHelper(context.inSSR, isComponent)
+        : getVNodeHelper(context.inSSR, isComponent);
+    push(helper(callHelper) + `(`, node);
+    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
+    push(`)`);
+    if (isBlock) {
+        push(`)`);
+    }
+    if (directives) {
+        push(`, `);
+        genNode(directives, context);
+        push(`)`);
+    }
+}
+function genNullableArgs(args) {
+    let i = args.length;
+    while (i--) {
+        if (args[i] != null)
+            break;
+    }
+    return args.slice(0, i + 1).map(arg => arg || `null`);
+}
+// JavaScript
+function genCallExpression(node, context) {
+    const { push, helper, pure } = context;
+    const callee = isString(node.callee) ? node.callee : helper(node.callee);
+    if (pure) {
+        push(PURE_ANNOTATION);
+    }
+    push(callee + `(`, node);
+    genNodeList(node.arguments, context);
+    push(`)`);
+}
+function genObjectExpression(node, context) {
+    const { push, indent, deindent, newline } = context;
+    const { properties } = node;
+    if (!properties.length) {
+        push(`{}`, node);
+        return;
+    }
+    const multilines = properties.length > 1 ||
+        (((process.env.NODE_ENV !== 'production')) &&
+            properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
+    push(multilines ? `{` : `{ `);
+    multilines && indent();
+    for (let i = 0; i < properties.length; i++) {
+        const { key, value } = properties[i];
+        // key
+        genExpressionAsPropertyKey(key, context);
+        push(`: `);
+        // value
+        genNode(value, context);
+        if (i < properties.length - 1) {
+            // will only reach this if it's multilines
+            push(`,`);
+            newline();
+        }
+    }
+    multilines && deindent();
+    push(multilines ? `}` : ` }`);
+}
+function genArrayExpression(node, context) {
+    genNodeListAsArray(node.elements, context);
+}
+function genFunctionExpression(node, context) {
+    const { push, indent, deindent } = context;
+    const { params, returns, body, newline, isSlot } = node;
+    if (isSlot) {
+        // wrap slot functions with owner context
+        push(`_${helperNameMap[WITH_CTX]}(`);
+    }
+    push(`(`, node);
+    if (isArray(params)) {
+        genNodeList(params, context);
+    }
+    else if (params) {
+        genNode(params, context);
+    }
+    push(`) => `);
+    if (newline || body) {
+        push(`{`);
+        indent();
+    }
+    if (returns) {
+        if (newline) {
+            push(`return `);
+        }
+        if (isArray(returns)) {
+            genNodeListAsArray(returns, context);
+        }
+        else {
+            genNode(returns, context);
+        }
+    }
+    else if (body) {
+        genNode(body, context);
+    }
+    if (newline || body) {
+        deindent();
+        push(`}`);
+    }
+    if (isSlot) {
+        if (node.isNonScopedSlot) {
+            push(`, undefined, true`);
+        }
+        push(`)`);
+    }
+}
+function genConditionalExpression(node, context) {
+    const { test, consequent, alternate, newline: needNewline } = node;
+    const { push, indent, deindent, newline } = context;
+    if (test.type === 4 /* SIMPLE_EXPRESSION */) {
+        const needsParens = !isSimpleIdentifier(test.content);
+        needsParens && push(`(`);
+        genExpression(test, context);
+        needsParens && push(`)`);
+    }
+    else {
+        push(`(`);
+        genNode(test, context);
+        push(`)`);
+    }
+    needNewline && indent();
+    context.indentLevel++;
+    needNewline || push(` `);
+    push(`? `);
+    genNode(consequent, context);
+    context.indentLevel--;
+    needNewline && newline();
+    needNewline || push(` `);
+    push(`: `);
+    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
+    if (!isNested) {
+        context.indentLevel++;
+    }
+    genNode(alternate, context);
+    if (!isNested) {
+        context.indentLevel--;
+    }
+    needNewline && deindent(true /* without newline */);
+}
+function genCacheExpression(node, context) {
+    const { push, helper, indent, deindent, newline } = context;
+    push(`_cache[${node.index}] || (`);
+    if (node.isVNode) {
+        indent();
+        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
+        newline();
+    }
+    push(`_cache[${node.index}] = `);
+    genNode(node.value, context);
+    if (node.isVNode) {
+        push(`,`);
+        newline();
+        push(`${helper(SET_BLOCK_TRACKING)}(1),`);
+        newline();
+        push(`_cache[${node.index}]`);
+        deindent();
+    }
+    push(`)`);
 }
 
-function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {
-    {
-        return;
-    }
-}
-function isReferencedIdentifier(id, parent, parentStack) {
-    {
-        return false;
-    }
-}
-function isInDestructureAssignment(parent, parentStack) {
-    if (parent &&
-        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {
-        let i = parentStack.length;
-        while (i--) {
-            const p = parentStack[i];
-            if (p.type === 'AssignmentExpression') {
-                return true;
-            }
-            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
-                break;
-            }
-        }
-    }
-    return false;
-}
-function walkFunctionParams(node, onIdent) {
-    for (const p of node.params) {
-        for (const id of extractIdentifiers(p)) {
-            onIdent(id);
-        }
-    }
-}
-function walkBlockDeclarations(block, onIdent) {
-    for (const stmt of block.body) {
-        if (stmt.type === 'VariableDeclaration') {
-            if (stmt.declare)
-                continue;
-            for (const decl of stmt.declarations) {
-                for (const id of extractIdentifiers(decl.id)) {
-                    onIdent(id);
-                }
-            }
-        }
-        else if (stmt.type === 'FunctionDeclaration' ||
-            stmt.type === 'ClassDeclaration') {
-            if (stmt.declare || !stmt.id)
-                continue;
-            onIdent(stmt.id);
-        }
-    }
-}
-function extractIdentifiers(param, nodes = []) {
-    switch (param.type) {
-        case 'Identifier':
-            nodes.push(param);
-            break;
-        case 'MemberExpression':
-            let object = param;
-            while (object.type === 'MemberExpression') {
-                object = object.object;
-            }
-            nodes.push(object);
-            break;
-        case 'ObjectPattern':
-            for (const prop of param.properties) {
-                if (prop.type === 'RestElement') {
-                    extractIdentifiers(prop.argument, nodes);
-                }
-                else {
-                    extractIdentifiers(prop.value, nodes);
-                }
-            }
-            break;
-        case 'ArrayPattern':
-            param.elements.forEach(element => {
-                if (element)
-                    extractIdentifiers(element, nodes);
-            });
-            break;
-        case 'RestElement':
-            extractIdentifiers(param.argument, nodes);
-            break;
-        case 'AssignmentPattern':
-            extractIdentifiers(param.left, nodes);
-            break;
-    }
-    return nodes;
-}
-const isFunctionType = (node) => {
-    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
-};
-const isStaticProperty = (node) => node &&
-    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
-    !node.computed;
+function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {
+    {
+        return;
+    }
+}
+function isReferencedIdentifier(id, parent, parentStack) {
+    {
+        return false;
+    }
+}
+function isInDestructureAssignment(parent, parentStack) {
+    if (parent &&
+        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {
+        let i = parentStack.length;
+        while (i--) {
+            const p = parentStack[i];
+            if (p.type === 'AssignmentExpression') {
+                return true;
+            }
+            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
+                break;
+            }
+        }
+    }
+    return false;
+}
+function walkFunctionParams(node, onIdent) {
+    for (const p of node.params) {
+        for (const id of extractIdentifiers(p)) {
+            onIdent(id);
+        }
+    }
+}
+function walkBlockDeclarations(block, onIdent) {
+    for (const stmt of block.body) {
+        if (stmt.type === 'VariableDeclaration') {
+            if (stmt.declare)
+                continue;
+            for (const decl of stmt.declarations) {
+                for (const id of extractIdentifiers(decl.id)) {
+                    onIdent(id);
+                }
+            }
+        }
+        else if (stmt.type === 'FunctionDeclaration' ||
+            stmt.type === 'ClassDeclaration') {
+            if (stmt.declare || !stmt.id)
+                continue;
+            onIdent(stmt.id);
+        }
+    }
+}
+function extractIdentifiers(param, nodes = []) {
+    switch (param.type) {
+        case 'Identifier':
+            nodes.push(param);
+            break;
+        case 'MemberExpression':
+            let object = param;
+            while (object.type === 'MemberExpression') {
+                object = object.object;
+            }
+            nodes.push(object);
+            break;
+        case 'ObjectPattern':
+            for (const prop of param.properties) {
+                if (prop.type === 'RestElement') {
+                    extractIdentifiers(prop.argument, nodes);
+                }
+                else {
+                    extractIdentifiers(prop.value, nodes);
+                }
+            }
+            break;
+        case 'ArrayPattern':
+            param.elements.forEach(element => {
+                if (element)
+                    extractIdentifiers(element, nodes);
+            });
+            break;
+        case 'RestElement':
+            extractIdentifiers(param.argument, nodes);
+            break;
+        case 'AssignmentPattern':
+            extractIdentifiers(param.left, nodes);
+            break;
+    }
+    return nodes;
+}
+const isFunctionType = (node) => {
+    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
+};
+const isStaticProperty = (node) => node &&
+    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
+    !node.computed;
 const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;
 
-// these keywords should not appear inside expressions, but operators like
-// typeof, instanceof and in are allowed
-const prohibitedKeywordRE = new RegExp('\\b' +
-    ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
-        'super,throw,while,yield,delete,export,import,return,switch,default,' +
-        'extends,finally,continue,debugger,function,arguments,typeof,void')
-        .split(',')
-        .join('\\b|\\b') +
-    '\\b');
-// strip strings in expressions
-const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
-/**
- * Validate a non-prefixed expression.
- * This is only called when using the in-browser runtime compiler since it
- * doesn't prefix expressions.
- */
-function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
-    const exp = node.content;
-    // empty expressions are validated per-directive since some directives
-    // do allow empty expressions.
-    if (!exp.trim()) {
-        return;
-    }
-    try {
-        new Function(asRawStatements
-            ? ` ${exp} `
-            : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
-    }
-    catch (e) {
-        let message = e.message;
-        const keywordMatch = exp
-            .replace(stripStringRE, '')
-            .match(prohibitedKeywordRE);
-        if (keywordMatch) {
-            message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
-        }
-        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
-    }
+// these keywords should not appear inside expressions, but operators like
+// typeof, instanceof and in are allowed
+const prohibitedKeywordRE = new RegExp('\\b' +
+    ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
+        'super,throw,while,yield,delete,export,import,return,switch,default,' +
+        'extends,finally,continue,debugger,function,arguments,typeof,void')
+        .split(',')
+        .join('\\b|\\b') +
+    '\\b');
+// strip strings in expressions
+const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
+/**
+ * Validate a non-prefixed expression.
+ * This is only called when using the in-browser runtime compiler since it
+ * doesn't prefix expressions.
+ */
+function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
+    const exp = node.content;
+    // empty expressions are validated per-directive since some directives
+    // do allow empty expressions.
+    if (!exp.trim()) {
+        return;
+    }
+    try {
+        new Function(asRawStatements
+            ? ` ${exp} `
+            : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
+    }
+    catch (e) {
+        let message = e.message;
+        const keywordMatch = exp
+            .replace(stripStringRE, '')
+            .match(prohibitedKeywordRE);
+        if (keywordMatch) {
+            message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
+        }
+        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
+    }
 }
 
-const transformExpression = (node, context) => {
-    if (node.type === 5 /* INTERPOLATION */) {
-        node.content = processExpression(node.content, context);
-    }
-    else if (node.type === 1 /* ELEMENT */) {
-        // handle directives on element
-        for (let i = 0; i < node.props.length; i++) {
-            const dir = node.props[i];
-            // do not process for v-on & v-for since they are special handled
-            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
-                const exp = dir.exp;
-                const arg = dir.arg;
-                // do not process exp if this is v-on:arg - we need special handling
-                // for wrapping inline statements.
-                if (exp &&
-                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&
-                    !(dir.name === 'on' && arg)) {
-                    dir.exp = processExpression(exp, context, 
-                    // slot args must be processed as function params
-                    dir.name === 'slot');
-                }
-                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
-                    dir.arg = processExpression(arg, context);
-                }
-            }
-        }
-    }
-};
-// Important: since this function uses Node.js only dependencies, it should
-// always be used with a leading !true check so that it can be
-// tree-shaken from the browser build.
-function processExpression(node, context, 
-// some expressions like v-slot props & v-for aliases should be parsed as
-// function params
-asParams = false, 
-// v-on handler values may contain multiple statements
-asRawStatements = false, localVars = Object.create(context.identifiers)) {
-    {
-        if ((process.env.NODE_ENV !== 'production')) {
-            // simple in-browser validation (same logic in 2.x)
-            validateBrowserExpression(node, context, asParams, asRawStatements);
-        }
-        return node;
-    }
+const transformExpression = (node, context) => {
+    if (node.type === 5 /* INTERPOLATION */) {
+        node.content = processExpression(node.content, context);
+    }
+    else if (node.type === 1 /* ELEMENT */) {
+        // handle directives on element
+        for (let i = 0; i < node.props.length; i++) {
+            const dir = node.props[i];
+            // do not process for v-on & v-for since they are special handled
+            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
+                const exp = dir.exp;
+                const arg = dir.arg;
+                // do not process exp if this is v-on:arg - we need special handling
+                // for wrapping inline statements.
+                if (exp &&
+                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&
+                    !(dir.name === 'on' && arg)) {
+                    dir.exp = processExpression(exp, context, 
+                    // slot args must be processed as function params
+                    dir.name === 'slot');
+                }
+                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
+                    dir.arg = processExpression(arg, context);
+                }
+            }
+        }
+    }
+};
+// Important: since this function uses Node.js only dependencies, it should
+// always be used with a leading !true check so that it can be
+// tree-shaken from the browser build.
+function processExpression(node, context, 
+// some expressions like v-slot props & v-for aliases should be parsed as
+// function params
+asParams = false, 
+// v-on handler values may contain multiple statements
+asRawStatements = false, localVars = Object.create(context.identifiers)) {
+    {
+        if ((process.env.NODE_ENV !== 'production')) {
+            // simple in-browser validation (same logic in 2.x)
+            validateBrowserExpression(node, context, asParams, asRawStatements);
+        }
+        return node;
+    }
 }
 
-const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
-    return processIf(node, dir, context, (ifNode, branch, isRoot) => {
-        // #1587: We need to dynamically increment the key based on the current
-        // node's sibling nodes, since chained v-if/else branches are
-        // rendered at the same depth
-        const siblings = context.parent.children;
-        let i = siblings.indexOf(ifNode);
-        let key = 0;
-        while (i-- >= 0) {
-            const sibling = siblings[i];
-            if (sibling && sibling.type === 9 /* IF */) {
-                key += sibling.branches.length;
-            }
-        }
-        // Exit callback. Complete the codegenNode when all children have been
-        // transformed.
-        return () => {
-            if (isRoot) {
-                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
-            }
-            else {
-                // attach this branch's codegen node to the v-if root.
-                const parentCondition = getParentCondition(ifNode.codegenNode);
-                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
-            }
-        };
-    });
-});
-// target-agnostic transform used for both Client and SSR
-function processIf(node, dir, context, processCodegen) {
-    if (dir.name !== 'else' &&
-        (!dir.exp || !dir.exp.content.trim())) {
-        const loc = dir.exp ? dir.exp.loc : node.loc;
-        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));
-        dir.exp = createSimpleExpression(`true`, false, loc);
-    }
-    if ((process.env.NODE_ENV !== 'production') && true && dir.exp) {
-        validateBrowserExpression(dir.exp, context);
-    }
-    if (dir.name === 'if') {
-        const branch = createIfBranch(node, dir);
-        const ifNode = {
-            type: 9 /* IF */,
-            loc: node.loc,
-            branches: [branch]
-        };
-        context.replaceNode(ifNode);
-        if (processCodegen) {
-            return processCodegen(ifNode, branch, true);
-        }
-    }
-    else {
-        // locate the adjacent v-if
-        const siblings = context.parent.children;
-        const comments = [];
-        let i = siblings.indexOf(node);
-        while (i-- >= -1) {
-            const sibling = siblings[i];
-            if ((process.env.NODE_ENV !== 'production') && sibling && sibling.type === 3 /* COMMENT */) {
-                context.removeNode(sibling);
-                comments.unshift(sibling);
-                continue;
-            }
-            if (sibling &&
-                sibling.type === 2 /* TEXT */ &&
-                !sibling.content.trim().length) {
-                context.removeNode(sibling);
-                continue;
-            }
-            if (sibling && sibling.type === 9 /* IF */) {
-                // Check if v-else was followed by v-else-if
-                if (dir.name === 'else-if' &&
-                    sibling.branches[sibling.branches.length - 1].condition === undefined) {
-                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
-                }
-                // move the node to the if node's branches
-                context.removeNode();
-                const branch = createIfBranch(node, dir);
-                if ((process.env.NODE_ENV !== 'production') &&
-                    comments.length &&
-                    // #3619 ignore comments if the v-if is direct child of <transition>
-                    !(context.parent &&
-                        context.parent.type === 1 /* ELEMENT */ &&
-                        isBuiltInType(context.parent.tag, 'transition'))) {
-                    branch.children = [...comments, ...branch.children];
-                }
-                // check if user is forcing same key on different branches
-                if ((process.env.NODE_ENV !== 'production') || !true) {
-                    const key = branch.userKey;
-                    if (key) {
-                        sibling.branches.forEach(({ userKey }) => {
-                            if (isSameKey(userKey, key)) {
-                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
-                            }
-                        });
-                    }
-                }
-                sibling.branches.push(branch);
-                const onExit = processCodegen && processCodegen(sibling, branch, false);
-                // since the branch was removed, it will not be traversed.
-                // make sure to traverse here.
-                traverseNode(branch, context);
-                // call on exit
-                if (onExit)
-                    onExit();
-                // make sure to reset currentNode after traversal to indicate this
-                // node has been removed.
-                context.currentNode = null;
-            }
-            else {
-                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
-            }
-            break;
-        }
-    }
-}
-function createIfBranch(node, dir) {
-    const isTemplateIf = node.tagType === 3 /* TEMPLATE */;
-    return {
-        type: 10 /* IF_BRANCH */,
-        loc: node.loc,
-        condition: dir.name === 'else' ? undefined : dir.exp,
-        children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
-        userKey: findProp(node, `key`),
-        isTemplateIf
-    };
-}
-function createCodegenNodeForBranch(branch, keyIndex, context) {
-    if (branch.condition) {
-        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 
-        // make sure to pass in asBlock: true so that the comment node call
-        // closes the current block.
-        createCallExpression(context.helper(CREATE_COMMENT), [
-            (process.env.NODE_ENV !== 'production') ? '"v-if"' : '""',
-            'true'
-        ]));
-    }
-    else {
-        return createChildrenCodegenNode(branch, keyIndex, context);
-    }
-}
-function createChildrenCodegenNode(branch, keyIndex, context) {
-    const { helper } = context;
-    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
-    const { children } = branch;
-    const firstChild = children[0];
-    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
-    if (needFragmentWrapper) {
-        if (children.length === 1 && firstChild.type === 11 /* FOR */) {
-            // optimize away nested fragments when child is a ForNode
-            const vnodeCall = firstChild.codegenNode;
-            injectProp(vnodeCall, keyProperty, context);
-            return vnodeCall;
-        }
-        else {
-            let patchFlag = 64 /* STABLE_FRAGMENT */;
-            let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
-            // check if the fragment actually contains a single valid child with
-            // the rest being comments
-            if ((process.env.NODE_ENV !== 'production') &&
-                !branch.isTemplateIf &&
-                children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
-                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
-                patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
-            }
-            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc);
-        }
-    }
-    else {
-        const ret = firstChild.codegenNode;
-        const vnodeCall = getMemoedVNodeCall(ret);
-        // Change createVNode to createBlock.
-        if (vnodeCall.type === 13 /* VNODE_CALL */) {
-            makeBlock(vnodeCall, context);
-        }
-        // inject branch key
-        injectProp(vnodeCall, keyProperty, context);
-        return ret;
-    }
-}
-function isSameKey(a, b) {
-    if (!a || a.type !== b.type) {
-        return false;
-    }
-    if (a.type === 6 /* ATTRIBUTE */) {
-        if (a.value.content !== b.value.content) {
-            return false;
-        }
-    }
-    else {
-        // directive
-        const exp = a.exp;
-        const branchExp = b.exp;
-        if (exp.type !== branchExp.type) {
-            return false;
-        }
-        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
-            exp.isStatic !== branchExp.isStatic ||
-            exp.content !== branchExp.content) {
-            return false;
-        }
-    }
-    return true;
-}
-function getParentCondition(node) {
-    while (true) {
-        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
-            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
-                node = node.alternate;
-            }
-            else {
-                return node;
-            }
-        }
-        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
-            node = node.value;
-        }
-    }
+const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
+    return processIf(node, dir, context, (ifNode, branch, isRoot) => {
+        // #1587: We need to dynamically increment the key based on the current
+        // node's sibling nodes, since chained v-if/else branches are
+        // rendered at the same depth
+        const siblings = context.parent.children;
+        let i = siblings.indexOf(ifNode);
+        let key = 0;
+        while (i-- >= 0) {
+            const sibling = siblings[i];
+            if (sibling && sibling.type === 9 /* IF */) {
+                key += sibling.branches.length;
+            }
+        }
+        // Exit callback. Complete the codegenNode when all children have been
+        // transformed.
+        return () => {
+            if (isRoot) {
+                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
+            }
+            else {
+                // attach this branch's codegen node to the v-if root.
+                const parentCondition = getParentCondition(ifNode.codegenNode);
+                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
+            }
+        };
+    });
+});
+// target-agnostic transform used for both Client and SSR
+function processIf(node, dir, context, processCodegen) {
+    if (dir.name !== 'else' &&
+        (!dir.exp || !dir.exp.content.trim())) {
+        const loc = dir.exp ? dir.exp.loc : node.loc;
+        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));
+        dir.exp = createSimpleExpression(`true`, false, loc);
+    }
+    if ((process.env.NODE_ENV !== 'production') && true && dir.exp) {
+        validateBrowserExpression(dir.exp, context);
+    }
+    if (dir.name === 'if') {
+        const branch = createIfBranch(node, dir);
+        const ifNode = {
+            type: 9 /* IF */,
+            loc: node.loc,
+            branches: [branch]
+        };
+        context.replaceNode(ifNode);
+        if (processCodegen) {
+            return processCodegen(ifNode, branch, true);
+        }
+    }
+    else {
+        // locate the adjacent v-if
+        const siblings = context.parent.children;
+        const comments = [];
+        let i = siblings.indexOf(node);
+        while (i-- >= -1) {
+            const sibling = siblings[i];
+            if ((process.env.NODE_ENV !== 'production') && sibling && sibling.type === 3 /* COMMENT */) {
+                context.removeNode(sibling);
+                comments.unshift(sibling);
+                continue;
+            }
+            if (sibling &&
+                sibling.type === 2 /* TEXT */ &&
+                !sibling.content.trim().length) {
+                context.removeNode(sibling);
+                continue;
+            }
+            if (sibling && sibling.type === 9 /* IF */) {
+                // Check if v-else was followed by v-else-if
+                if (dir.name === 'else-if' &&
+                    sibling.branches[sibling.branches.length - 1].condition === undefined) {
+                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
+                }
+                // move the node to the if node's branches
+                context.removeNode();
+                const branch = createIfBranch(node, dir);
+                if ((process.env.NODE_ENV !== 'production') &&
+                    comments.length &&
+                    // #3619 ignore comments if the v-if is direct child of <transition>
+                    !(context.parent &&
+                        context.parent.type === 1 /* ELEMENT */ &&
+                        isBuiltInType(context.parent.tag, 'transition'))) {
+                    branch.children = [...comments, ...branch.children];
+                }
+                // check if user is forcing same key on different branches
+                if ((process.env.NODE_ENV !== 'production') || !true) {
+                    const key = branch.userKey;
+                    if (key) {
+                        sibling.branches.forEach(({ userKey }) => {
+                            if (isSameKey(userKey, key)) {
+                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
+                            }
+                        });
+                    }
+                }
+                sibling.branches.push(branch);
+                const onExit = processCodegen && processCodegen(sibling, branch, false);
+                // since the branch was removed, it will not be traversed.
+                // make sure to traverse here.
+                traverseNode(branch, context);
+                // call on exit
+                if (onExit)
+                    onExit();
+                // make sure to reset currentNode after traversal to indicate this
+                // node has been removed.
+                context.currentNode = null;
+            }
+            else {
+                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
+            }
+            break;
+        }
+    }
+}
+function createIfBranch(node, dir) {
+    const isTemplateIf = node.tagType === 3 /* TEMPLATE */;
+    return {
+        type: 10 /* IF_BRANCH */,
+        loc: node.loc,
+        condition: dir.name === 'else' ? undefined : dir.exp,
+        children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
+        userKey: findProp(node, `key`),
+        isTemplateIf
+    };
+}
+function createCodegenNodeForBranch(branch, keyIndex, context) {
+    if (branch.condition) {
+        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 
+        // make sure to pass in asBlock: true so that the comment node call
+        // closes the current block.
+        createCallExpression(context.helper(CREATE_COMMENT), [
+            (process.env.NODE_ENV !== 'production') ? '"v-if"' : '""',
+            'true'
+        ]));
+    }
+    else {
+        return createChildrenCodegenNode(branch, keyIndex, context);
+    }
+}
+function createChildrenCodegenNode(branch, keyIndex, context) {
+    const { helper } = context;
+    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
+    const { children } = branch;
+    const firstChild = children[0];
+    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
+    if (needFragmentWrapper) {
+        if (children.length === 1 && firstChild.type === 11 /* FOR */) {
+            // optimize away nested fragments when child is a ForNode
+            const vnodeCall = firstChild.codegenNode;
+            injectProp(vnodeCall, keyProperty, context);
+            return vnodeCall;
+        }
+        else {
+            let patchFlag = 64 /* STABLE_FRAGMENT */;
+            let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
+            // check if the fragment actually contains a single valid child with
+            // the rest being comments
+            if ((process.env.NODE_ENV !== 'production') &&
+                !branch.isTemplateIf &&
+                children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
+                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
+                patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
+            }
+            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc);
+        }
+    }
+    else {
+        const ret = firstChild.codegenNode;
+        const vnodeCall = getMemoedVNodeCall(ret);
+        // Change createVNode to createBlock.
+        if (vnodeCall.type === 13 /* VNODE_CALL */) {
+            makeBlock(vnodeCall, context);
+        }
+        // inject branch key
+        injectProp(vnodeCall, keyProperty, context);
+        return ret;
+    }
+}
+function isSameKey(a, b) {
+    if (!a || a.type !== b.type) {
+        return false;
+    }
+    if (a.type === 6 /* ATTRIBUTE */) {
+        if (a.value.content !== b.value.content) {
+            return false;
+        }
+    }
+    else {
+        // directive
+        const exp = a.exp;
+        const branchExp = b.exp;
+        if (exp.type !== branchExp.type) {
+            return false;
+        }
+        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
+            exp.isStatic !== branchExp.isStatic ||
+            exp.content !== branchExp.content) {
+            return false;
+        }
+    }
+    return true;
+}
+function getParentCondition(node) {
+    while (true) {
+        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
+            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
+                node = node.alternate;
+            }
+            else {
+                return node;
+            }
+        }
+        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
+            node = node.value;
+        }
+    }
 }
 
-const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
-    const { helper, removeHelper } = context;
-    return processFor(node, dir, context, forNode => {
-        // create the loop render function expression now, and add the
-        // iterator on exit after all children have been traversed
-        const renderExp = createCallExpression(helper(RENDER_LIST), [
-            forNode.source
-        ]);
-        const isTemplate = isTemplateNode(node);
-        const memo = findDir(node, 'memo');
-        const keyProp = findProp(node, `key`);
-        const keyExp = keyProp &&
-            (keyProp.type === 6 /* ATTRIBUTE */
-                ? createSimpleExpression(keyProp.value.content, true)
-                : keyProp.exp);
-        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
-        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
-            forNode.source.constType > 0 /* NOT_CONSTANT */;
-        const fragmentFlag = isStableFragment
-            ? 64 /* STABLE_FRAGMENT */
-            : keyProp
-                ? 128 /* KEYED_FRAGMENT */
-                : 256 /* UNKEYED_FRAGMENT */;
-        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
-            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
-        return () => {
-            // finish the codegen now that all children have been traversed
-            let childBlock;
-            const { children } = forNode;
-            // check <template v-for> key placement
-            if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {
-                node.children.some(c => {
-                    if (c.type === 1 /* ELEMENT */) {
-                        const key = findProp(c, 'key');
-                        if (key) {
-                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
-                            return true;
-                        }
-                    }
-                });
-            }
-            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
-            const slotOutlet = isSlotOutlet(node)
-                ? node
-                : isTemplate &&
-                    node.children.length === 1 &&
-                    isSlotOutlet(node.children[0])
-                    ? node.children[0] // api-extractor somehow fails to infer this
-                    : null;
-            if (slotOutlet) {
-                // <slot v-for="..."> or <template v-for="..."><slot/></template>
-                childBlock = slotOutlet.codegenNode;
-                if (isTemplate && keyProperty) {
-                    // <template v-for="..." :key="..."><slot/></template>
-                    // we need to inject the key to the renderSlot() call.
-                    // the props for renderSlot is passed as the 3rd argument.
-                    injectProp(childBlock, keyProperty, context);
-                }
-            }
-            else if (needFragmentWrapper) {
-                // <template v-for="..."> with text or multi-elements
-                // should generate a fragment block for each loop
-                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
-                    ((process.env.NODE_ENV !== 'production')
-                        ? ` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
-                        : ``), undefined, undefined, true, undefined, false /* isComponent */);
-            }
-            else {
-                // Normal element v-for. Directly use the child's codegenNode
-                // but mark it as a block.
-                childBlock = children[0]
-                    .codegenNode;
-                if (isTemplate && keyProperty) {
-                    injectProp(childBlock, keyProperty, context);
-                }
-                if (childBlock.isBlock !== !isStableFragment) {
-                    if (childBlock.isBlock) {
-                        // switch from block to vnode
-                        removeHelper(OPEN_BLOCK);
-                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
-                    }
-                    else {
-                        // switch from vnode to block
-                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
-                    }
-                }
-                childBlock.isBlock = !isStableFragment;
-                if (childBlock.isBlock) {
-                    helper(OPEN_BLOCK);
-                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
-                }
-                else {
-                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
-                }
-            }
-            if (memo) {
-                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
-                    createSimpleExpression(`_cached`)
-                ]));
-                loop.body = createBlockStatement([
-                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
-                    createCompoundExpression([
-                        `if (_cached`,
-                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),
-                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
-                    ]),
-                    createCompoundExpression([`const _item = `, childBlock]),
-                    createSimpleExpression(`_item.memo = _memo`),
-                    createSimpleExpression(`return _item`)
-                ]);
-                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
-            }
-            else {
-                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
-            }
-        };
-    });
-});
-// target-agnostic transform used for both Client and SSR
-function processFor(node, dir, context, processCodegen) {
-    if (!dir.exp) {
-        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
-        return;
-    }
-    const parseResult = parseForExpression(
-    // can only be simple expression because vFor transform is applied
-    // before expression transform.
-    dir.exp, context);
-    if (!parseResult) {
-        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
-        return;
-    }
-    const { addIdentifiers, removeIdentifiers, scopes } = context;
-    const { source, value, key, index } = parseResult;
-    const forNode = {
-        type: 11 /* FOR */,
-        loc: dir.loc,
-        source,
-        valueAlias: value,
-        keyAlias: key,
-        objectIndexAlias: index,
-        parseResult,
-        children: isTemplateNode(node) ? node.children : [node]
-    };
-    context.replaceNode(forNode);
-    // bookkeeping
-    scopes.vFor++;
-    const onExit = processCodegen && processCodegen(forNode);
-    return () => {
-        scopes.vFor--;
-        if (onExit)
-            onExit();
-    };
-}
-const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
-// This regex doesn't cover the case if key or index aliases have destructuring,
-// but those do not make sense in the first place, so this works in practice.
-const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
-const stripParensRE = /^\(|\)$/g;
-function parseForExpression(input, context) {
-    const loc = input.loc;
-    const exp = input.content;
-    const inMatch = exp.match(forAliasRE);
-    if (!inMatch)
-        return;
-    const [, LHS, RHS] = inMatch;
-    const result = {
-        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
-        value: undefined,
-        key: undefined,
-        index: undefined
-    };
-    if ((process.env.NODE_ENV !== 'production') && true) {
-        validateBrowserExpression(result.source, context);
-    }
-    let valueContent = LHS.trim().replace(stripParensRE, '').trim();
-    const trimmedOffset = LHS.indexOf(valueContent);
-    const iteratorMatch = valueContent.match(forIteratorRE);
-    if (iteratorMatch) {
-        valueContent = valueContent.replace(forIteratorRE, '').trim();
-        const keyContent = iteratorMatch[1].trim();
-        let keyOffset;
-        if (keyContent) {
-            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
-            result.key = createAliasExpression(loc, keyContent, keyOffset);
-            if ((process.env.NODE_ENV !== 'production') && true) {
-                validateBrowserExpression(result.key, context, true);
-            }
-        }
-        if (iteratorMatch[2]) {
-            const indexContent = iteratorMatch[2].trim();
-            if (indexContent) {
-                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
-                    ? keyOffset + keyContent.length
-                    : trimmedOffset + valueContent.length));
-                if ((process.env.NODE_ENV !== 'production') && true) {
-                    validateBrowserExpression(result.index, context, true);
-                }
-            }
-        }
-    }
-    if (valueContent) {
-        result.value = createAliasExpression(loc, valueContent, trimmedOffset);
-        if ((process.env.NODE_ENV !== 'production') && true) {
-            validateBrowserExpression(result.value, context, true);
-        }
-    }
-    return result;
-}
-function createAliasExpression(range, content, offset) {
-    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
-}
-function createForLoopParams({ value, key, index }, memoArgs = []) {
-    return createParamsList([value, key, index, ...memoArgs]);
-}
-function createParamsList(args) {
-    let i = args.length;
-    while (i--) {
-        if (args[i])
-            break;
-    }
-    return args
-        .slice(0, i + 1)
-        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
+const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
+    const { helper, removeHelper } = context;
+    return processFor(node, dir, context, forNode => {
+        // create the loop render function expression now, and add the
+        // iterator on exit after all children have been traversed
+        const renderExp = createCallExpression(helper(RENDER_LIST), [
+            forNode.source
+        ]);
+        const isTemplate = isTemplateNode(node);
+        const memo = findDir(node, 'memo');
+        const keyProp = findProp(node, `key`);
+        const keyExp = keyProp &&
+            (keyProp.type === 6 /* ATTRIBUTE */
+                ? createSimpleExpression(keyProp.value.content, true)
+                : keyProp.exp);
+        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
+        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
+            forNode.source.constType > 0 /* NOT_CONSTANT */;
+        const fragmentFlag = isStableFragment
+            ? 64 /* STABLE_FRAGMENT */
+            : keyProp
+                ? 128 /* KEYED_FRAGMENT */
+                : 256 /* UNKEYED_FRAGMENT */;
+        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
+            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
+        return () => {
+            // finish the codegen now that all children have been traversed
+            let childBlock;
+            const { children } = forNode;
+            // check <template v-for> key placement
+            if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {
+                node.children.some(c => {
+                    if (c.type === 1 /* ELEMENT */) {
+                        const key = findProp(c, 'key');
+                        if (key) {
+                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
+                            return true;
+                        }
+                    }
+                });
+            }
+            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
+            const slotOutlet = isSlotOutlet(node)
+                ? node
+                : isTemplate &&
+                    node.children.length === 1 &&
+                    isSlotOutlet(node.children[0])
+                    ? node.children[0] // api-extractor somehow fails to infer this
+                    : null;
+            if (slotOutlet) {
+                // <slot v-for="..."> or <template v-for="..."><slot/></template>
+                childBlock = slotOutlet.codegenNode;
+                if (isTemplate && keyProperty) {
+                    // <template v-for="..." :key="..."><slot/></template>
+                    // we need to inject the key to the renderSlot() call.
+                    // the props for renderSlot is passed as the 3rd argument.
+                    injectProp(childBlock, keyProperty, context);
+                }
+            }
+            else if (needFragmentWrapper) {
+                // <template v-for="..."> with text or multi-elements
+                // should generate a fragment block for each loop
+                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
+                    ((process.env.NODE_ENV !== 'production')
+                        ? ` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
+                        : ``), undefined, undefined, true, undefined, false /* isComponent */);
+            }
+            else {
+                // Normal element v-for. Directly use the child's codegenNode
+                // but mark it as a block.
+                childBlock = children[0]
+                    .codegenNode;
+                if (isTemplate && keyProperty) {
+                    injectProp(childBlock, keyProperty, context);
+                }
+                if (childBlock.isBlock !== !isStableFragment) {
+                    if (childBlock.isBlock) {
+                        // switch from block to vnode
+                        removeHelper(OPEN_BLOCK);
+                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
+                    }
+                    else {
+                        // switch from vnode to block
+                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
+                    }
+                }
+                childBlock.isBlock = !isStableFragment;
+                if (childBlock.isBlock) {
+                    helper(OPEN_BLOCK);
+                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
+                }
+                else {
+                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
+                }
+            }
+            if (memo) {
+                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
+                    createSimpleExpression(`_cached`)
+                ]));
+                loop.body = createBlockStatement([
+                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
+                    createCompoundExpression([
+                        `if (_cached`,
+                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),
+                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
+                    ]),
+                    createCompoundExpression([`const _item = `, childBlock]),
+                    createSimpleExpression(`_item.memo = _memo`),
+                    createSimpleExpression(`return _item`)
+                ]);
+                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
+            }
+            else {
+                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
+            }
+        };
+    });
+});
+// target-agnostic transform used for both Client and SSR
+function processFor(node, dir, context, processCodegen) {
+    if (!dir.exp) {
+        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
+        return;
+    }
+    const parseResult = parseForExpression(
+    // can only be simple expression because vFor transform is applied
+    // before expression transform.
+    dir.exp, context);
+    if (!parseResult) {
+        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
+        return;
+    }
+    const { addIdentifiers, removeIdentifiers, scopes } = context;
+    const { source, value, key, index } = parseResult;
+    const forNode = {
+        type: 11 /* FOR */,
+        loc: dir.loc,
+        source,
+        valueAlias: value,
+        keyAlias: key,
+        objectIndexAlias: index,
+        parseResult,
+        children: isTemplateNode(node) ? node.children : [node]
+    };
+    context.replaceNode(forNode);
+    // bookkeeping
+    scopes.vFor++;
+    const onExit = processCodegen && processCodegen(forNode);
+    return () => {
+        scopes.vFor--;
+        if (onExit)
+            onExit();
+    };
+}
+const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
+// This regex doesn't cover the case if key or index aliases have destructuring,
+// but those do not make sense in the first place, so this works in practice.
+const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
+const stripParensRE = /^\(|\)$/g;
+function parseForExpression(input, context) {
+    const loc = input.loc;
+    const exp = input.content;
+    const inMatch = exp.match(forAliasRE);
+    if (!inMatch)
+        return;
+    const [, LHS, RHS] = inMatch;
+    const result = {
+        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
+        value: undefined,
+        key: undefined,
+        index: undefined
+    };
+    if ((process.env.NODE_ENV !== 'production') && true) {
+        validateBrowserExpression(result.source, context);
+    }
+    let valueContent = LHS.trim().replace(stripParensRE, '').trim();
+    const trimmedOffset = LHS.indexOf(valueContent);
+    const iteratorMatch = valueContent.match(forIteratorRE);
+    if (iteratorMatch) {
+        valueContent = valueContent.replace(forIteratorRE, '').trim();
+        const keyContent = iteratorMatch[1].trim();
+        let keyOffset;
+        if (keyContent) {
+            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
+            result.key = createAliasExpression(loc, keyContent, keyOffset);
+            if ((process.env.NODE_ENV !== 'production') && true) {
+                validateBrowserExpression(result.key, context, true);
+            }
+        }
+        if (iteratorMatch[2]) {
+            const indexContent = iteratorMatch[2].trim();
+            if (indexContent) {
+                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
+                    ? keyOffset + keyContent.length
+                    : trimmedOffset + valueContent.length));
+                if ((process.env.NODE_ENV !== 'production') && true) {
+                    validateBrowserExpression(result.index, context, true);
+                }
+            }
+        }
+    }
+    if (valueContent) {
+        result.value = createAliasExpression(loc, valueContent, trimmedOffset);
+        if ((process.env.NODE_ENV !== 'production') && true) {
+            validateBrowserExpression(result.value, context, true);
+        }
+    }
+    return result;
+}
+function createAliasExpression(range, content, offset) {
+    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
+}
+function createForLoopParams({ value, key, index }, memoArgs = []) {
+    return createParamsList([value, key, index, ...memoArgs]);
+}
+function createParamsList(args) {
+    let i = args.length;
+    while (i--) {
+        if (args[i])
+            break;
+    }
+    return args
+        .slice(0, i + 1)
+        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
 }
 
-const defaultFallback = createSimpleExpression(`undefined`, false);
-// A NodeTransform that:
-// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
-//    by transformExpression. This is only applied in non-browser builds with
-//    { prefixIdentifiers: true }.
-// 2. Track v-slot depths so that we know a slot is inside another slot.
-//    Note the exit callback is executed before buildSlots() on the same node,
-//    so only nested slots see positive numbers.
-const trackSlotScopes = (node, context) => {
-    if (node.type === 1 /* ELEMENT */ &&
-        (node.tagType === 1 /* COMPONENT */ ||
-            node.tagType === 3 /* TEMPLATE */)) {
-        // We are only checking non-empty v-slot here
-        // since we only care about slots that introduce scope variables.
-        const vSlot = findDir(node, 'slot');
-        if (vSlot) {
-            context.scopes.vSlot++;
-            return () => {
-                context.scopes.vSlot--;
-            };
-        }
-    }
-};
-// A NodeTransform that tracks scope identifiers for scoped slots with v-for.
-// This transform is only applied in non-browser builds with { prefixIdentifiers: true }
-const trackVForSlotScopes = (node, context) => {
-    let vFor;
-    if (isTemplateNode(node) &&
-        node.props.some(isVSlot) &&
-        (vFor = findDir(node, 'for'))) {
-        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));
-        if (result) {
-            const { value, key, index } = result;
-            const { addIdentifiers, removeIdentifiers } = context;
-            value && addIdentifiers(value);
-            key && addIdentifiers(key);
-            index && addIdentifiers(index);
-            return () => {
-                value && removeIdentifiers(value);
-                key && removeIdentifiers(key);
-                index && removeIdentifiers(index);
-            };
-        }
-    }
-};
-const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
-// Instead of being a DirectiveTransform, v-slot processing is called during
-// transformElement to build the slots object for a component.
-function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
-    context.helper(WITH_CTX);
-    const { children, loc } = node;
-    const slotsProperties = [];
-    const dynamicSlots = [];
-    // If the slot is inside a v-for or another v-slot, force it to be dynamic
-    // since it likely uses a scope variable.
-    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
-    // 1. Check for slot with slotProps on component itself.
-    //    <Comp v-slot="{ prop }"/>
-    const onComponentSlot = findDir(node, 'slot', true);
-    if (onComponentSlot) {
-        const { arg, exp } = onComponentSlot;
-        if (arg && !isStaticExp(arg)) {
-            hasDynamicSlots = true;
-        }
-        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
-    }
-    // 2. Iterate through children and check for template slots
-    //    <template v-slot:foo="{ prop }">
-    let hasTemplateSlots = false;
-    let hasNamedDefaultSlot = false;
-    const implicitDefaultChildren = [];
-    const seenSlotNames = new Set();
-    for (let i = 0; i < children.length; i++) {
-        const slotElement = children[i];
-        let slotDir;
-        if (!isTemplateNode(slotElement) ||
-            !(slotDir = findDir(slotElement, 'slot', true))) {
-            // not a <template v-slot>, skip.
-            if (slotElement.type !== 3 /* COMMENT */) {
-                implicitDefaultChildren.push(slotElement);
-            }
-            continue;
-        }
-        if (onComponentSlot) {
-            // already has on-component slot - this is incorrect usage.
-            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
-            break;
-        }
-        hasTemplateSlots = true;
-        const { children: slotChildren, loc: slotLoc } = slotElement;
-        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
-        // check if name is dynamic.
-        let staticSlotName;
-        if (isStaticExp(slotName)) {
-            staticSlotName = slotName ? slotName.content : `default`;
-        }
-        else {
-            hasDynamicSlots = true;
-        }
-        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
-        // check if this slot is conditional (v-if/v-for)
-        let vIf;
-        let vElse;
-        let vFor;
-        if ((vIf = findDir(slotElement, 'if'))) {
-            hasDynamicSlots = true;
-            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
-        }
-        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
-            // find adjacent v-if
-            let j = i;
-            let prev;
-            while (j--) {
-                prev = children[j];
-                if (prev.type !== 3 /* COMMENT */) {
-                    break;
-                }
-            }
-            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
-                // remove node
-                children.splice(i, 1);
-                i--;
-                // attach this slot to previous conditional
-                let conditional = dynamicSlots[dynamicSlots.length - 1];
-                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
-                    conditional = conditional.alternate;
-                }
-                conditional.alternate = vElse.exp
-                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
-                    : buildDynamicSlot(slotName, slotFunction);
-            }
-            else {
-                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
-            }
-        }
-        else if ((vFor = findDir(slotElement, 'for'))) {
-            hasDynamicSlots = true;
-            const parseResult = vFor.parseResult ||
-                parseForExpression(vFor.exp, context);
-            if (parseResult) {
-                // Render the dynamic slots as an array and add it to the createSlot()
-                // args. The runtime knows how to handle it appropriately.
-                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
-                    parseResult.source,
-                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
-                ]));
-            }
-            else {
-                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
-            }
-        }
-        else {
-            // check duplicate static names
-            if (staticSlotName) {
-                if (seenSlotNames.has(staticSlotName)) {
-                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
-                    continue;
-                }
-                seenSlotNames.add(staticSlotName);
-                if (staticSlotName === 'default') {
-                    hasNamedDefaultSlot = true;
-                }
-            }
-            slotsProperties.push(createObjectProperty(slotName, slotFunction));
-        }
-    }
-    if (!onComponentSlot) {
-        const buildDefaultSlotProperty = (props, children) => {
-            const fn = buildSlotFn(props, children, loc);
-            if (context.compatConfig) {
-                fn.isNonScopedSlot = true;
-            }
-            return createObjectProperty(`default`, fn);
-        };
-        if (!hasTemplateSlots) {
-            // implicit default slot (on component)
-            slotsProperties.push(buildDefaultSlotProperty(undefined, children));
-        }
-        else if (implicitDefaultChildren.length &&
-            // #3766
-            // with whitespace: 'preserve', whitespaces between slots will end up in
-            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
-            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
-            // implicit default slot (mixed with named slots)
-            if (hasNamedDefaultSlot) {
-                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
-            }
-            else {
-                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
-            }
-        }
-    }
-    const slotFlag = hasDynamicSlots
-        ? 2 /* DYNAMIC */
-        : hasForwardedSlots(node.children)
-            ? 3 /* FORWARDED */
-            : 1 /* STABLE */;
-    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 
-    // 2 = compiled but dynamic = can skip normalization, but must run diff
-    // 1 = compiled and static = can skip normalization AND diff as optimized
-    createSimpleExpression(slotFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${slotFlagsText[slotFlag]} */` : ``), false))), loc);
-    if (dynamicSlots.length) {
-        slots = createCallExpression(context.helper(CREATE_SLOTS), [
-            slots,
-            createArrayExpression(dynamicSlots)
-        ]);
-    }
-    return {
-        slots,
-        hasDynamicSlots
-    };
-}
-function buildDynamicSlot(name, fn) {
-    return createObjectExpression([
-        createObjectProperty(`name`, name),
-        createObjectProperty(`fn`, fn)
-    ]);
-}
-function hasForwardedSlots(children) {
-    for (let i = 0; i < children.length; i++) {
-        const child = children[i];
-        switch (child.type) {
-            case 1 /* ELEMENT */:
-                if (child.tagType === 2 /* SLOT */ ||
-                    hasForwardedSlots(child.children)) {
-                    return true;
-                }
-                break;
-            case 9 /* IF */:
-                if (hasForwardedSlots(child.branches))
-                    return true;
-                break;
-            case 10 /* IF_BRANCH */:
-            case 11 /* FOR */:
-                if (hasForwardedSlots(child.children))
-                    return true;
-                break;
-        }
-    }
-    return false;
-}
-function isNonWhitespaceContent(node) {
-    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
-        return true;
-    return node.type === 2 /* TEXT */
-        ? !!node.content.trim()
-        : isNonWhitespaceContent(node.content);
+const defaultFallback = createSimpleExpression(`undefined`, false);
+// A NodeTransform that:
+// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
+//    by transformExpression. This is only applied in non-browser builds with
+//    { prefixIdentifiers: true }.
+// 2. Track v-slot depths so that we know a slot is inside another slot.
+//    Note the exit callback is executed before buildSlots() on the same node,
+//    so only nested slots see positive numbers.
+const trackSlotScopes = (node, context) => {
+    if (node.type === 1 /* ELEMENT */ &&
+        (node.tagType === 1 /* COMPONENT */ ||
+            node.tagType === 3 /* TEMPLATE */)) {
+        // We are only checking non-empty v-slot here
+        // since we only care about slots that introduce scope variables.
+        const vSlot = findDir(node, 'slot');
+        if (vSlot) {
+            context.scopes.vSlot++;
+            return () => {
+                context.scopes.vSlot--;
+            };
+        }
+    }
+};
+// A NodeTransform that tracks scope identifiers for scoped slots with v-for.
+// This transform is only applied in non-browser builds with { prefixIdentifiers: true }
+const trackVForSlotScopes = (node, context) => {
+    let vFor;
+    if (isTemplateNode(node) &&
+        node.props.some(isVSlot) &&
+        (vFor = findDir(node, 'for'))) {
+        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));
+        if (result) {
+            const { value, key, index } = result;
+            const { addIdentifiers, removeIdentifiers } = context;
+            value && addIdentifiers(value);
+            key && addIdentifiers(key);
+            index && addIdentifiers(index);
+            return () => {
+                value && removeIdentifiers(value);
+                key && removeIdentifiers(key);
+                index && removeIdentifiers(index);
+            };
+        }
+    }
+};
+const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
+// Instead of being a DirectiveTransform, v-slot processing is called during
+// transformElement to build the slots object for a component.
+function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
+    context.helper(WITH_CTX);
+    const { children, loc } = node;
+    const slotsProperties = [];
+    const dynamicSlots = [];
+    // If the slot is inside a v-for or another v-slot, force it to be dynamic
+    // since it likely uses a scope variable.
+    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
+    // 1. Check for slot with slotProps on component itself.
+    //    <Comp v-slot="{ prop }"/>
+    const onComponentSlot = findDir(node, 'slot', true);
+    if (onComponentSlot) {
+        const { arg, exp } = onComponentSlot;
+        if (arg && !isStaticExp(arg)) {
+            hasDynamicSlots = true;
+        }
+        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
+    }
+    // 2. Iterate through children and check for template slots
+    //    <template v-slot:foo="{ prop }">
+    let hasTemplateSlots = false;
+    let hasNamedDefaultSlot = false;
+    const implicitDefaultChildren = [];
+    const seenSlotNames = new Set();
+    for (let i = 0; i < children.length; i++) {
+        const slotElement = children[i];
+        let slotDir;
+        if (!isTemplateNode(slotElement) ||
+            !(slotDir = findDir(slotElement, 'slot', true))) {
+            // not a <template v-slot>, skip.
+            if (slotElement.type !== 3 /* COMMENT */) {
+                implicitDefaultChildren.push(slotElement);
+            }
+            continue;
+        }
+        if (onComponentSlot) {
+            // already has on-component slot - this is incorrect usage.
+            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
+            break;
+        }
+        hasTemplateSlots = true;
+        const { children: slotChildren, loc: slotLoc } = slotElement;
+        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
+        // check if name is dynamic.
+        let staticSlotName;
+        if (isStaticExp(slotName)) {
+            staticSlotName = slotName ? slotName.content : `default`;
+        }
+        else {
+            hasDynamicSlots = true;
+        }
+        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
+        // check if this slot is conditional (v-if/v-for)
+        let vIf;
+        let vElse;
+        let vFor;
+        if ((vIf = findDir(slotElement, 'if'))) {
+            hasDynamicSlots = true;
+            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
+        }
+        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
+            // find adjacent v-if
+            let j = i;
+            let prev;
+            while (j--) {
+                prev = children[j];
+                if (prev.type !== 3 /* COMMENT */) {
+                    break;
+                }
+            }
+            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
+                // remove node
+                children.splice(i, 1);
+                i--;
+                // attach this slot to previous conditional
+                let conditional = dynamicSlots[dynamicSlots.length - 1];
+                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
+                    conditional = conditional.alternate;
+                }
+                conditional.alternate = vElse.exp
+                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
+                    : buildDynamicSlot(slotName, slotFunction);
+            }
+            else {
+                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
+            }
+        }
+        else if ((vFor = findDir(slotElement, 'for'))) {
+            hasDynamicSlots = true;
+            const parseResult = vFor.parseResult ||
+                parseForExpression(vFor.exp, context);
+            if (parseResult) {
+                // Render the dynamic slots as an array and add it to the createSlot()
+                // args. The runtime knows how to handle it appropriately.
+                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
+                    parseResult.source,
+                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
+                ]));
+            }
+            else {
+                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
+            }
+        }
+        else {
+            // check duplicate static names
+            if (staticSlotName) {
+                if (seenSlotNames.has(staticSlotName)) {
+                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
+                    continue;
+                }
+                seenSlotNames.add(staticSlotName);
+                if (staticSlotName === 'default') {
+                    hasNamedDefaultSlot = true;
+                }
+            }
+            slotsProperties.push(createObjectProperty(slotName, slotFunction));
+        }
+    }
+    if (!onComponentSlot) {
+        const buildDefaultSlotProperty = (props, children) => {
+            const fn = buildSlotFn(props, children, loc);
+            if (context.compatConfig) {
+                fn.isNonScopedSlot = true;
+            }
+            return createObjectProperty(`default`, fn);
+        };
+        if (!hasTemplateSlots) {
+            // implicit default slot (on component)
+            slotsProperties.push(buildDefaultSlotProperty(undefined, children));
+        }
+        else if (implicitDefaultChildren.length &&
+            // #3766
+            // with whitespace: 'preserve', whitespaces between slots will end up in
+            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
+            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
+            // implicit default slot (mixed with named slots)
+            if (hasNamedDefaultSlot) {
+                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
+            }
+            else {
+                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
+            }
+        }
+    }
+    const slotFlag = hasDynamicSlots
+        ? 2 /* DYNAMIC */
+        : hasForwardedSlots(node.children)
+            ? 3 /* FORWARDED */
+            : 1 /* STABLE */;
+    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 
+    // 2 = compiled but dynamic = can skip normalization, but must run diff
+    // 1 = compiled and static = can skip normalization AND diff as optimized
+    createSimpleExpression(slotFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${slotFlagsText[slotFlag]} */` : ``), false))), loc);
+    if (dynamicSlots.length) {
+        slots = createCallExpression(context.helper(CREATE_SLOTS), [
+            slots,
+            createArrayExpression(dynamicSlots)
+        ]);
+    }
+    return {
+        slots,
+        hasDynamicSlots
+    };
+}
+function buildDynamicSlot(name, fn) {
+    return createObjectExpression([
+        createObjectProperty(`name`, name),
+        createObjectProperty(`fn`, fn)
+    ]);
+}
+function hasForwardedSlots(children) {
+    for (let i = 0; i < children.length; i++) {
+        const child = children[i];
+        switch (child.type) {
+            case 1 /* ELEMENT */:
+                if (child.tagType === 2 /* SLOT */ ||
+                    hasForwardedSlots(child.children)) {
+                    return true;
+                }
+                break;
+            case 9 /* IF */:
+                if (hasForwardedSlots(child.branches))
+                    return true;
+                break;
+            case 10 /* IF_BRANCH */:
+            case 11 /* FOR */:
+                if (hasForwardedSlots(child.children))
+                    return true;
+                break;
+        }
+    }
+    return false;
+}
+function isNonWhitespaceContent(node) {
+    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
+        return true;
+    return node.type === 2 /* TEXT */
+        ? !!node.content.trim()
+        : isNonWhitespaceContent(node.content);
 }
 
-// some directive transforms (e.g. v-model) may return a symbol for runtime
-// import, which should be used instead of a resolveDirective call.
-const directiveImportMap = new WeakMap();
-// generate a JavaScript AST for this element's codegen
-const transformElement = (node, context) => {
-    // perform the work on exit, after all child expressions have been
-    // processed and merged.
-    return function postTransformElement() {
-        node = context.currentNode;
-        if (!(node.type === 1 /* ELEMENT */ &&
-            (node.tagType === 0 /* ELEMENT */ ||
-                node.tagType === 1 /* COMPONENT */))) {
-            return;
-        }
-        const { tag, props } = node;
-        const isComponent = node.tagType === 1 /* COMPONENT */;
-        // The goal of the transform is to create a codegenNode implementing the
-        // VNodeCall interface.
-        let vnodeTag = isComponent
-            ? resolveComponentType(node, context)
-            : `"${tag}"`;
-        const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
-        let vnodeProps;
-        let vnodeChildren;
-        let vnodePatchFlag;
-        let patchFlag = 0;
-        let vnodeDynamicProps;
-        let dynamicPropNames;
-        let vnodeDirectives;
-        let shouldUseBlock = 
-        // dynamic component may resolve to plain elements
-        isDynamicComponent ||
-            vnodeTag === TELEPORT ||
-            vnodeTag === SUSPENSE ||
-            (!isComponent &&
-                // <svg> and <foreignObject> must be forced into blocks so that block
-                // updates inside get proper isSVG flag at runtime. (#639, #643)
-                // This is technically web-specific, but splitting the logic out of core
-                // leads to too much unnecessary complexity.
-                (tag === 'svg' || tag === 'foreignObject'));
-        // props
-        if (props.length > 0) {
-            const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
-            vnodeProps = propsBuildResult.props;
-            patchFlag = propsBuildResult.patchFlag;
-            dynamicPropNames = propsBuildResult.dynamicPropNames;
-            const directives = propsBuildResult.directives;
-            vnodeDirectives =
-                directives && directives.length
-                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
-                    : undefined;
-            if (propsBuildResult.shouldUseBlock) {
-                shouldUseBlock = true;
-            }
-        }
-        // children
-        if (node.children.length > 0) {
-            if (vnodeTag === KEEP_ALIVE) {
-                // Although a built-in component, we compile KeepAlive with raw children
-                // instead of slot functions so that it can be used inside Transition
-                // or other Transition-wrapping HOCs.
-                // To ensure correct updates with block optimizations, we need to:
-                // 1. Force keep-alive into a block. This avoids its children being
-                //    collected by a parent block.
-                shouldUseBlock = true;
-                // 2. Force keep-alive to always be updated, since it uses raw children.
-                patchFlag |= 1024 /* DYNAMIC_SLOTS */;
-                if ((process.env.NODE_ENV !== 'production') && node.children.length > 1) {
-                    context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
-                        start: node.children[0].loc.start,
-                        end: node.children[node.children.length - 1].loc.end,
-                        source: ''
-                    }));
-                }
-            }
-            const shouldBuildAsSlots = isComponent &&
-                // Teleport is not a real component and has dedicated runtime handling
-                vnodeTag !== TELEPORT &&
-                // explained above.
-                vnodeTag !== KEEP_ALIVE;
-            if (shouldBuildAsSlots) {
-                const { slots, hasDynamicSlots } = buildSlots(node, context);
-                vnodeChildren = slots;
-                if (hasDynamicSlots) {
-                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;
-                }
-            }
-            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
-                const child = node.children[0];
-                const type = child.type;
-                // check for dynamic text children
-                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
-                    type === 8 /* COMPOUND_EXPRESSION */;
-                if (hasDynamicTextChild &&
-                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
-                    patchFlag |= 1 /* TEXT */;
-                }
-                // pass directly if the only child is a text node
-                // (plain / interpolation / expression)
-                if (hasDynamicTextChild || type === 2 /* TEXT */) {
-                    vnodeChildren = child;
-                }
-                else {
-                    vnodeChildren = node.children;
-                }
-            }
-            else {
-                vnodeChildren = node.children;
-            }
-        }
-        // patchFlag & dynamicPropNames
-        if (patchFlag !== 0) {
-            if ((process.env.NODE_ENV !== 'production')) {
-                if (patchFlag < 0) {
-                    // special flags (negative and mutually exclusive)
-                    vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
-                }
-                else {
-                    // bitwise flags
-                    const flagNames = Object.keys(PatchFlagNames)
-                        .map(Number)
-                        .filter(n => n > 0 && patchFlag & n)
-                        .map(n => PatchFlagNames[n])
-                        .join(`, `);
-                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
-                }
-            }
-            else {
-                vnodePatchFlag = String(patchFlag);
-            }
-            if (dynamicPropNames && dynamicPropNames.length) {
-                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
-            }
-        }
-        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
-    };
-};
-function resolveComponentType(node, context, ssr = false) {
-    let { tag } = node;
-    // 1. dynamic component
-    const isExplicitDynamic = isComponentTag(tag);
-    const isProp = findProp(node, 'is');
-    if (isProp) {
-        if (isExplicitDynamic ||
-            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {
-            const exp = isProp.type === 6 /* ATTRIBUTE */
-                ? isProp.value && createSimpleExpression(isProp.value.content, true)
-                : isProp.exp;
-            if (exp) {
-                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
-                    exp
-                ]);
-            }
-        }
-        else if (isProp.type === 6 /* ATTRIBUTE */ &&
-            isProp.value.content.startsWith('vue:')) {
-            // <button is="vue:xxx">
-            // if not <component>, only is value that starts with "vue:" will be
-            // treated as component by the parse phase and reach here, unless it's
-            // compat mode where all is values are considered components
-            tag = isProp.value.content.slice(4);
-        }
-    }
-    // 1.5 v-is (TODO: Deprecate)
-    const isDir = !isExplicitDynamic && findDir(node, 'is');
-    if (isDir && isDir.exp) {
-        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
-            isDir.exp
-        ]);
-    }
-    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
-    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
-    if (builtIn) {
-        // built-ins are simply fallthroughs / have special handling during ssr
-        // so we don't need to import their runtime equivalents
-        if (!ssr)
-            context.helper(builtIn);
-        return builtIn;
-    }
-    // 5. user component (resolve)
-    context.helper(RESOLVE_COMPONENT);
-    context.components.add(tag);
-    return toValidAssetId(tag, `component`);
-}
-function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
-    const { tag, loc: elementLoc, children } = node;
-    let properties = [];
-    const mergeArgs = [];
-    const runtimeDirectives = [];
-    const hasChildren = children.length > 0;
-    let shouldUseBlock = false;
-    // patchFlag analysis
-    let patchFlag = 0;
-    let hasRef = false;
-    let hasClassBinding = false;
-    let hasStyleBinding = false;
-    let hasHydrationEventBinding = false;
-    let hasDynamicKeys = false;
-    let hasVnodeHook = false;
-    const dynamicPropNames = [];
-    const analyzePatchFlag = ({ key, value }) => {
-        if (isStaticExp(key)) {
-            const name = key.content;
-            const isEventHandler = isOn(name);
-            if (isEventHandler &&
-                (!isComponent || isDynamicComponent) &&
-                // omit the flag for click handlers because hydration gives click
-                // dedicated fast path.
-                name.toLowerCase() !== 'onclick' &&
-                // omit v-model handlers
-                name !== 'onUpdate:modelValue' &&
-                // omit onVnodeXXX hooks
-                !isReservedProp(name)) {
-                hasHydrationEventBinding = true;
-            }
-            if (isEventHandler && isReservedProp(name)) {
-                hasVnodeHook = true;
-            }
-            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
-                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
-                    value.type === 8 /* COMPOUND_EXPRESSION */) &&
-                    getConstantType(value, context) > 0)) {
-                // skip if the prop is a cached handler or has constant value
-                return;
-            }
-            if (name === 'ref') {
-                hasRef = true;
-            }
-            else if (name === 'class') {
-                hasClassBinding = true;
-            }
-            else if (name === 'style') {
-                hasStyleBinding = true;
-            }
-            else if (name !== 'key' && !dynamicPropNames.includes(name)) {
-                dynamicPropNames.push(name);
-            }
-            // treat the dynamic class and style binding of the component as dynamic props
-            if (isComponent &&
-                (name === 'class' || name === 'style') &&
-                !dynamicPropNames.includes(name)) {
-                dynamicPropNames.push(name);
-            }
-        }
-        else {
-            hasDynamicKeys = true;
-        }
-    };
-    for (let i = 0; i < props.length; i++) {
-        // static attribute
-        const prop = props[i];
-        if (prop.type === 6 /* ATTRIBUTE */) {
-            const { loc, name, value } = prop;
-            let isStatic = true;
-            if (name === 'ref') {
-                hasRef = true;
-                if (context.scopes.vFor > 0) {
-                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
-                }
-            }
-            // skip is on <component>, or is="vue:xxx"
-            if (name === 'is' &&
-                (isComponentTag(tag) ||
-                    (value && value.content.startsWith('vue:')) ||
-                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
-                continue;
-            }
-            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
-        }
-        else {
-            // directives
-            const { name, arg, exp, loc } = prop;
-            const isVBind = name === 'bind';
-            const isVOn = name === 'on';
-            // skip v-slot - it is handled by its dedicated transform.
-            if (name === 'slot') {
-                if (!isComponent) {
-                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));
-                }
-                continue;
-            }
-            // skip v-once/v-memo - they are handled by dedicated transforms.
-            if (name === 'once' || name === 'memo') {
-                continue;
-            }
-            // skip v-is and :is on <component>
-            if (name === 'is' ||
-                (isVBind &&
-                    isStaticArgOf(arg, 'is') &&
-                    (isComponentTag(tag) ||
-                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
-                continue;
-            }
-            // skip v-on in SSR compilation
-            if (isVOn && ssr) {
-                continue;
-            }
-            if (
-            // #938: elements with dynamic keys should be forced into blocks
-            (isVBind && isStaticArgOf(arg, 'key')) ||
-                // inline before-update hooks need to force block so that it is invoked
-                // before children
-                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
-                shouldUseBlock = true;
-            }
-            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
-                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
-            }
-            // special case for v-bind and v-on with no argument
-            if (!arg && (isVBind || isVOn)) {
-                hasDynamicKeys = true;
-                if (exp) {
-                    if (properties.length) {
-                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
-                        properties = [];
-                    }
-                    if (isVBind) {
-                        {
-                            // 2.x v-bind object order compat
-                            if ((process.env.NODE_ENV !== 'production')) {
-                                const hasOverridableKeys = mergeArgs.some(arg => {
-                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {
-                                        return arg.properties.some(({ key }) => {
-                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||
-                                                !key.isStatic) {
-                                                return true;
-                                            }
-                                            return (key.content !== 'class' &&
-                                                key.content !== 'style' &&
-                                                !isOn(key.content));
-                                        });
-                                    }
-                                    else {
-                                        // dynamic expression
-                                        return true;
-                                    }
-                                });
-                                if (hasOverridableKeys) {
-                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);
-                                }
-                            }
-                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {
-                                mergeArgs.unshift(exp);
-                                continue;
-                            }
-                        }
-                        mergeArgs.push(exp);
-                    }
-                    else {
-                        // v-on="obj" -> toHandlers(obj)
-                        mergeArgs.push({
-                            type: 14 /* JS_CALL_EXPRESSION */,
-                            loc,
-                            callee: context.helper(TO_HANDLERS),
-                            arguments: [exp]
-                        });
-                    }
-                }
-                else {
-                    context.onError(createCompilerError(isVBind
-                        ? 34 /* X_V_BIND_NO_EXPRESSION */
-                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));
-                }
-                continue;
-            }
-            const directiveTransform = context.directiveTransforms[name];
-            if (directiveTransform) {
-                // has built-in directive transform.
-                const { props, needRuntime } = directiveTransform(prop, node, context);
-                !ssr && props.forEach(analyzePatchFlag);
-                properties.push(...props);
-                if (needRuntime) {
-                    runtimeDirectives.push(prop);
-                    if (isSymbol(needRuntime)) {
-                        directiveImportMap.set(prop, needRuntime);
-                    }
-                }
-            }
-            else if (!isBuiltInDirective(name)) {
-                // no built-in transform, this is a user custom directive.
-                runtimeDirectives.push(prop);
-                // custom dirs may use beforeUpdate so they need to force blocks
-                // to ensure before-update gets called before children update
-                if (hasChildren) {
-                    shouldUseBlock = true;
-                }
-            }
-        }
-    }
-    let propsExpression = undefined;
-    // has v-bind="object" or v-on="object", wrap with mergeProps
-    if (mergeArgs.length) {
-        if (properties.length) {
-            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
-        }
-        if (mergeArgs.length > 1) {
-            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
-        }
-        else {
-            // single v-bind with nothing else - no need for a mergeProps call
-            propsExpression = mergeArgs[0];
-        }
-    }
-    else if (properties.length) {
-        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
-    }
-    // patchFlag analysis
-    if (hasDynamicKeys) {
-        patchFlag |= 16 /* FULL_PROPS */;
-    }
-    else {
-        if (hasClassBinding && !isComponent) {
-            patchFlag |= 2 /* CLASS */;
-        }
-        if (hasStyleBinding && !isComponent) {
-            patchFlag |= 4 /* STYLE */;
-        }
-        if (dynamicPropNames.length) {
-            patchFlag |= 8 /* PROPS */;
-        }
-        if (hasHydrationEventBinding) {
-            patchFlag |= 32 /* HYDRATE_EVENTS */;
-        }
-    }
-    if (!shouldUseBlock &&
-        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
-        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
-        patchFlag |= 512 /* NEED_PATCH */;
-    }
-    // pre-normalize props, SSR is skipped for now
-    if (!context.inSSR && propsExpression) {
-        switch (propsExpression.type) {
-            case 15 /* JS_OBJECT_EXPRESSION */:
-                // means that there is no v-bind,
-                // but still need to deal with dynamic key binding
-                let classKeyIndex = -1;
-                let styleKeyIndex = -1;
-                let hasDynamicKey = false;
-                for (let i = 0; i < propsExpression.properties.length; i++) {
-                    const key = propsExpression.properties[i].key;
-                    if (isStaticExp(key)) {
-                        if (key.content === 'class') {
-                            classKeyIndex = i;
-                        }
-                        else if (key.content === 'style') {
-                            styleKeyIndex = i;
-                        }
-                    }
-                    else if (!key.isHandlerKey) {
-                        hasDynamicKey = true;
-                    }
-                }
-                const classProp = propsExpression.properties[classKeyIndex];
-                const styleProp = propsExpression.properties[styleKeyIndex];
-                // no dynamic key
-                if (!hasDynamicKey) {
-                    if (classProp && !isStaticExp(classProp.value)) {
-                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
-                    }
-                    if (styleProp &&
-                        // the static style is compiled into an object,
-                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding
-                        (hasStyleBinding ||
-                            (styleProp.value.type === 4 /* SIMPLE_EXPRESSION */ &&
-                                styleProp.value.content.trim()[0] === `[`) ||
-                            // v-bind:style and style both exist,
-                            // v-bind:style with static literal object
-                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
-                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
-                    }
-                }
-                else {
-                    // dynamic key binding, wrap with `normalizeProps`
-                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
-                }
-                break;
-            case 14 /* JS_CALL_EXPRESSION */:
-                // mergeProps call, do nothing
-                break;
-            default:
-                // single v-bind
-                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
-                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
-                        propsExpression
-                    ])
-                ]);
-                break;
-        }
-    }
-    return {
-        props: propsExpression,
-        directives: runtimeDirectives,
-        patchFlag,
-        dynamicPropNames,
-        shouldUseBlock
-    };
-}
-// Dedupe props in an object literal.
-// Literal duplicated attributes would have been warned during the parse phase,
-// however, it's possible to encounter duplicated `onXXX` handlers with different
-// modifiers. We also need to merge static and dynamic class / style attributes.
-// - onXXX handlers / style: merge into array
-// - class: merge into single expression with concatenation
-function dedupeProperties(properties) {
-    const knownProps = new Map();
-    const deduped = [];
-    for (let i = 0; i < properties.length; i++) {
-        const prop = properties[i];
-        // dynamic keys are always allowed
-        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
-            deduped.push(prop);
-            continue;
-        }
-        const name = prop.key.content;
-        const existing = knownProps.get(name);
-        if (existing) {
-            if (name === 'style' || name === 'class' || isOn(name)) {
-                mergeAsArray(existing, prop);
-            }
-            // unexpected duplicate, should have emitted error during parse
-        }
-        else {
-            knownProps.set(name, prop);
-            deduped.push(prop);
-        }
-    }
-    return deduped;
-}
-function mergeAsArray(existing, incoming) {
-    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
-        existing.value.elements.push(incoming.value);
-    }
-    else {
-        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
-    }
-}
-function buildDirectiveArgs(dir, context) {
-    const dirArgs = [];
-    const runtime = directiveImportMap.get(dir);
-    if (runtime) {
-        // built-in directive with runtime
-        dirArgs.push(context.helperString(runtime));
-    }
-    else {
-        {
-            // inject statement for resolving directive
-            context.helper(RESOLVE_DIRECTIVE);
-            context.directives.add(dir.name);
-            dirArgs.push(toValidAssetId(dir.name, `directive`));
-        }
-    }
-    const { loc } = dir;
-    if (dir.exp)
-        dirArgs.push(dir.exp);
-    if (dir.arg) {
-        if (!dir.exp) {
-            dirArgs.push(`void 0`);
-        }
-        dirArgs.push(dir.arg);
-    }
-    if (Object.keys(dir.modifiers).length) {
-        if (!dir.arg) {
-            if (!dir.exp) {
-                dirArgs.push(`void 0`);
-            }
-            dirArgs.push(`void 0`);
-        }
-        const trueExpression = createSimpleExpression(`true`, false, loc);
-        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
-    }
-    return createArrayExpression(dirArgs, dir.loc);
-}
-function stringifyDynamicPropNames(props) {
-    let propsNamesString = `[`;
-    for (let i = 0, l = props.length; i < l; i++) {
-        propsNamesString += JSON.stringify(props[i]);
-        if (i < l - 1)
-            propsNamesString += ', ';
-    }
-    return propsNamesString + `]`;
-}
-function isComponentTag(tag) {
-    return tag === 'component' || tag === 'Component';
+// some directive transforms (e.g. v-model) may return a symbol for runtime
+// import, which should be used instead of a resolveDirective call.
+const directiveImportMap = new WeakMap();
+// generate a JavaScript AST for this element's codegen
+const transformElement = (node, context) => {
+    // perform the work on exit, after all child expressions have been
+    // processed and merged.
+    return function postTransformElement() {
+        node = context.currentNode;
+        if (!(node.type === 1 /* ELEMENT */ &&
+            (node.tagType === 0 /* ELEMENT */ ||
+                node.tagType === 1 /* COMPONENT */))) {
+            return;
+        }
+        const { tag, props } = node;
+        const isComponent = node.tagType === 1 /* COMPONENT */;
+        // The goal of the transform is to create a codegenNode implementing the
+        // VNodeCall interface.
+        let vnodeTag = isComponent
+            ? resolveComponentType(node, context)
+            : `"${tag}"`;
+        const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
+        let vnodeProps;
+        let vnodeChildren;
+        let vnodePatchFlag;
+        let patchFlag = 0;
+        let vnodeDynamicProps;
+        let dynamicPropNames;
+        let vnodeDirectives;
+        let shouldUseBlock = 
+        // dynamic component may resolve to plain elements
+        isDynamicComponent ||
+            vnodeTag === TELEPORT ||
+            vnodeTag === SUSPENSE ||
+            (!isComponent &&
+                // <svg> and <foreignObject> must be forced into blocks so that block
+                // updates inside get proper isSVG flag at runtime. (#639, #643)
+                // This is technically web-specific, but splitting the logic out of core
+                // leads to too much unnecessary complexity.
+                (tag === 'svg' || tag === 'foreignObject'));
+        // props
+        if (props.length > 0) {
+            const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
+            vnodeProps = propsBuildResult.props;
+            patchFlag = propsBuildResult.patchFlag;
+            dynamicPropNames = propsBuildResult.dynamicPropNames;
+            const directives = propsBuildResult.directives;
+            vnodeDirectives =
+                directives && directives.length
+                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
+                    : undefined;
+            if (propsBuildResult.shouldUseBlock) {
+                shouldUseBlock = true;
+            }
+        }
+        // children
+        if (node.children.length > 0) {
+            if (vnodeTag === KEEP_ALIVE) {
+                // Although a built-in component, we compile KeepAlive with raw children
+                // instead of slot functions so that it can be used inside Transition
+                // or other Transition-wrapping HOCs.
+                // To ensure correct updates with block optimizations, we need to:
+                // 1. Force keep-alive into a block. This avoids its children being
+                //    collected by a parent block.
+                shouldUseBlock = true;
+                // 2. Force keep-alive to always be updated, since it uses raw children.
+                patchFlag |= 1024 /* DYNAMIC_SLOTS */;
+                if ((process.env.NODE_ENV !== 'production') && node.children.length > 1) {
+                    context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
+                        start: node.children[0].loc.start,
+                        end: node.children[node.children.length - 1].loc.end,
+                        source: ''
+                    }));
+                }
+            }
+            const shouldBuildAsSlots = isComponent &&
+                // Teleport is not a real component and has dedicated runtime handling
+                vnodeTag !== TELEPORT &&
+                // explained above.
+                vnodeTag !== KEEP_ALIVE;
+            if (shouldBuildAsSlots) {
+                const { slots, hasDynamicSlots } = buildSlots(node, context);
+                vnodeChildren = slots;
+                if (hasDynamicSlots) {
+                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;
+                }
+            }
+            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
+                const child = node.children[0];
+                const type = child.type;
+                // check for dynamic text children
+                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
+                    type === 8 /* COMPOUND_EXPRESSION */;
+                if (hasDynamicTextChild &&
+                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
+                    patchFlag |= 1 /* TEXT */;
+                }
+                // pass directly if the only child is a text node
+                // (plain / interpolation / expression)
+                if (hasDynamicTextChild || type === 2 /* TEXT */) {
+                    vnodeChildren = child;
+                }
+                else {
+                    vnodeChildren = node.children;
+                }
+            }
+            else {
+                vnodeChildren = node.children;
+            }
+        }
+        // patchFlag & dynamicPropNames
+        if (patchFlag !== 0) {
+            if ((process.env.NODE_ENV !== 'production')) {
+                if (patchFlag < 0) {
+                    // special flags (negative and mutually exclusive)
+                    vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
+                }
+                else {
+                    // bitwise flags
+                    const flagNames = Object.keys(PatchFlagNames)
+                        .map(Number)
+                        .filter(n => n > 0 && patchFlag & n)
+                        .map(n => PatchFlagNames[n])
+                        .join(`, `);
+                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
+                }
+            }
+            else {
+                vnodePatchFlag = String(patchFlag);
+            }
+            if (dynamicPropNames && dynamicPropNames.length) {
+                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
+            }
+        }
+        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
+    };
+};
+function resolveComponentType(node, context, ssr = false) {
+    let { tag } = node;
+    // 1. dynamic component
+    const isExplicitDynamic = isComponentTag(tag);
+    const isProp = findProp(node, 'is');
+    if (isProp) {
+        if (isExplicitDynamic ||
+            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {
+            const exp = isProp.type === 6 /* ATTRIBUTE */
+                ? isProp.value && createSimpleExpression(isProp.value.content, true)
+                : isProp.exp;
+            if (exp) {
+                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
+                    exp
+                ]);
+            }
+        }
+        else if (isProp.type === 6 /* ATTRIBUTE */ &&
+            isProp.value.content.startsWith('vue:')) {
+            // <button is="vue:xxx">
+            // if not <component>, only is value that starts with "vue:" will be
+            // treated as component by the parse phase and reach here, unless it's
+            // compat mode where all is values are considered components
+            tag = isProp.value.content.slice(4);
+        }
+    }
+    // 1.5 v-is (TODO: Deprecate)
+    const isDir = !isExplicitDynamic && findDir(node, 'is');
+    if (isDir && isDir.exp) {
+        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
+            isDir.exp
+        ]);
+    }
+    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
+    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
+    if (builtIn) {
+        // built-ins are simply fallthroughs / have special handling during ssr
+        // so we don't need to import their runtime equivalents
+        if (!ssr)
+            context.helper(builtIn);
+        return builtIn;
+    }
+    // 5. user component (resolve)
+    context.helper(RESOLVE_COMPONENT);
+    context.components.add(tag);
+    return toValidAssetId(tag, `component`);
+}
+function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
+    const { tag, loc: elementLoc, children } = node;
+    let properties = [];
+    const mergeArgs = [];
+    const runtimeDirectives = [];
+    const hasChildren = children.length > 0;
+    let shouldUseBlock = false;
+    // patchFlag analysis
+    let patchFlag = 0;
+    let hasRef = false;
+    let hasClassBinding = false;
+    let hasStyleBinding = false;
+    let hasHydrationEventBinding = false;
+    let hasDynamicKeys = false;
+    let hasVnodeHook = false;
+    const dynamicPropNames = [];
+    const analyzePatchFlag = ({ key, value }) => {
+        if (isStaticExp(key)) {
+            const name = key.content;
+            const isEventHandler = isOn(name);
+            if (isEventHandler &&
+                (!isComponent || isDynamicComponent) &&
+                // omit the flag for click handlers because hydration gives click
+                // dedicated fast path.
+                name.toLowerCase() !== 'onclick' &&
+                // omit v-model handlers
+                name !== 'onUpdate:modelValue' &&
+                // omit onVnodeXXX hooks
+                !isReservedProp(name)) {
+                hasHydrationEventBinding = true;
+            }
+            if (isEventHandler && isReservedProp(name)) {
+                hasVnodeHook = true;
+            }
+            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
+                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
+                    value.type === 8 /* COMPOUND_EXPRESSION */) &&
+                    getConstantType(value, context) > 0)) {
+                // skip if the prop is a cached handler or has constant value
+                return;
+            }
+            if (name === 'ref') {
+                hasRef = true;
+            }
+            else if (name === 'class') {
+                hasClassBinding = true;
+            }
+            else if (name === 'style') {
+                hasStyleBinding = true;
+            }
+            else if (name !== 'key' && !dynamicPropNames.includes(name)) {
+                dynamicPropNames.push(name);
+            }
+            // treat the dynamic class and style binding of the component as dynamic props
+            if (isComponent &&
+                (name === 'class' || name === 'style') &&
+                !dynamicPropNames.includes(name)) {
+                dynamicPropNames.push(name);
+            }
+        }
+        else {
+            hasDynamicKeys = true;
+        }
+    };
+    for (let i = 0; i < props.length; i++) {
+        // static attribute
+        const prop = props[i];
+        if (prop.type === 6 /* ATTRIBUTE */) {
+            const { loc, name, value } = prop;
+            let isStatic = true;
+            if (name === 'ref') {
+                hasRef = true;
+                if (context.scopes.vFor > 0) {
+                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
+                }
+            }
+            // skip is on <component>, or is="vue:xxx"
+            if (name === 'is' &&
+                (isComponentTag(tag) ||
+                    (value && value.content.startsWith('vue:')) ||
+                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
+                continue;
+            }
+            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
+        }
+        else {
+            // directives
+            const { name, arg, exp, loc } = prop;
+            const isVBind = name === 'bind';
+            const isVOn = name === 'on';
+            // skip v-slot - it is handled by its dedicated transform.
+            if (name === 'slot') {
+                if (!isComponent) {
+                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));
+                }
+                continue;
+            }
+            // skip v-once/v-memo - they are handled by dedicated transforms.
+            if (name === 'once' || name === 'memo') {
+                continue;
+            }
+            // skip v-is and :is on <component>
+            if (name === 'is' ||
+                (isVBind &&
+                    isStaticArgOf(arg, 'is') &&
+                    (isComponentTag(tag) ||
+                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
+                continue;
+            }
+            // skip v-on in SSR compilation
+            if (isVOn && ssr) {
+                continue;
+            }
+            if (
+            // #938: elements with dynamic keys should be forced into blocks
+            (isVBind && isStaticArgOf(arg, 'key')) ||
+                // inline before-update hooks need to force block so that it is invoked
+                // before children
+                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
+                shouldUseBlock = true;
+            }
+            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
+                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
+            }
+            // special case for v-bind and v-on with no argument
+            if (!arg && (isVBind || isVOn)) {
+                hasDynamicKeys = true;
+                if (exp) {
+                    if (properties.length) {
+                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
+                        properties = [];
+                    }
+                    if (isVBind) {
+                        {
+                            // 2.x v-bind object order compat
+                            if ((process.env.NODE_ENV !== 'production')) {
+                                const hasOverridableKeys = mergeArgs.some(arg => {
+                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {
+                                        return arg.properties.some(({ key }) => {
+                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||
+                                                !key.isStatic) {
+                                                return true;
+                                            }
+                                            return (key.content !== 'class' &&
+                                                key.content !== 'style' &&
+                                                !isOn(key.content));
+                                        });
+                                    }
+                                    else {
+                                        // dynamic expression
+                                        return true;
+                                    }
+                                });
+                                if (hasOverridableKeys) {
+                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);
+                                }
+                            }
+                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {
+                                mergeArgs.unshift(exp);
+                                continue;
+                            }
+                        }
+                        mergeArgs.push(exp);
+                    }
+                    else {
+                        // v-on="obj" -> toHandlers(obj)
+                        mergeArgs.push({
+                            type: 14 /* JS_CALL_EXPRESSION */,
+                            loc,
+                            callee: context.helper(TO_HANDLERS),
+                            arguments: [exp]
+                        });
+                    }
+                }
+                else {
+                    context.onError(createCompilerError(isVBind
+                        ? 34 /* X_V_BIND_NO_EXPRESSION */
+                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));
+                }
+                continue;
+            }
+            const directiveTransform = context.directiveTransforms[name];
+            if (directiveTransform) {
+                // has built-in directive transform.
+                const { props, needRuntime } = directiveTransform(prop, node, context);
+                !ssr && props.forEach(analyzePatchFlag);
+                properties.push(...props);
+                if (needRuntime) {
+                    runtimeDirectives.push(prop);
+                    if (isSymbol(needRuntime)) {
+                        directiveImportMap.set(prop, needRuntime);
+                    }
+                }
+            }
+            else if (!isBuiltInDirective(name)) {
+                // no built-in transform, this is a user custom directive.
+                runtimeDirectives.push(prop);
+                // custom dirs may use beforeUpdate so they need to force blocks
+                // to ensure before-update gets called before children update
+                if (hasChildren) {
+                    shouldUseBlock = true;
+                }
+            }
+        }
+    }
+    let propsExpression = undefined;
+    // has v-bind="object" or v-on="object", wrap with mergeProps
+    if (mergeArgs.length) {
+        if (properties.length) {
+            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
+        }
+        if (mergeArgs.length > 1) {
+            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
+        }
+        else {
+            // single v-bind with nothing else - no need for a mergeProps call
+            propsExpression = mergeArgs[0];
+        }
+    }
+    else if (properties.length) {
+        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
+    }
+    // patchFlag analysis
+    if (hasDynamicKeys) {
+        patchFlag |= 16 /* FULL_PROPS */;
+    }
+    else {
+        if (hasClassBinding && !isComponent) {
+            patchFlag |= 2 /* CLASS */;
+        }
+        if (hasStyleBinding && !isComponent) {
+            patchFlag |= 4 /* STYLE */;
+        }
+        if (dynamicPropNames.length) {
+            patchFlag |= 8 /* PROPS */;
+        }
+        if (hasHydrationEventBinding) {
+            patchFlag |= 32 /* HYDRATE_EVENTS */;
+        }
+    }
+    if (!shouldUseBlock &&
+        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
+        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
+        patchFlag |= 512 /* NEED_PATCH */;
+    }
+    // pre-normalize props, SSR is skipped for now
+    if (!context.inSSR && propsExpression) {
+        switch (propsExpression.type) {
+            case 15 /* JS_OBJECT_EXPRESSION */:
+                // means that there is no v-bind,
+                // but still need to deal with dynamic key binding
+                let classKeyIndex = -1;
+                let styleKeyIndex = -1;
+                let hasDynamicKey = false;
+                for (let i = 0; i < propsExpression.properties.length; i++) {
+                    const key = propsExpression.properties[i].key;
+                    if (isStaticExp(key)) {
+                        if (key.content === 'class') {
+                            classKeyIndex = i;
+                        }
+                        else if (key.content === 'style') {
+                            styleKeyIndex = i;
+                        }
+                    }
+                    else if (!key.isHandlerKey) {
+                        hasDynamicKey = true;
+                    }
+                }
+                const classProp = propsExpression.properties[classKeyIndex];
+                const styleProp = propsExpression.properties[styleKeyIndex];
+                // no dynamic key
+                if (!hasDynamicKey) {
+                    if (classProp && !isStaticExp(classProp.value)) {
+                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
+                    }
+                    if (styleProp &&
+                        // the static style is compiled into an object,
+                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding
+                        (hasStyleBinding ||
+                            (styleProp.value.type === 4 /* SIMPLE_EXPRESSION */ &&
+                                styleProp.value.content.trim()[0] === `[`) ||
+                            // v-bind:style and style both exist,
+                            // v-bind:style with static literal object
+                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
+                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
+                    }
+                }
+                else {
+                    // dynamic key binding, wrap with `normalizeProps`
+                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
+                }
+                break;
+            case 14 /* JS_CALL_EXPRESSION */:
+                // mergeProps call, do nothing
+                break;
+            default:
+                // single v-bind
+                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
+                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
+                        propsExpression
+                    ])
+                ]);
+                break;
+        }
+    }
+    return {
+        props: propsExpression,
+        directives: runtimeDirectives,
+        patchFlag,
+        dynamicPropNames,
+        shouldUseBlock
+    };
+}
+// Dedupe props in an object literal.
+// Literal duplicated attributes would have been warned during the parse phase,
+// however, it's possible to encounter duplicated `onXXX` handlers with different
+// modifiers. We also need to merge static and dynamic class / style attributes.
+// - onXXX handlers / style: merge into array
+// - class: merge into single expression with concatenation
+function dedupeProperties(properties) {
+    const knownProps = new Map();
+    const deduped = [];
+    for (let i = 0; i < properties.length; i++) {
+        const prop = properties[i];
+        // dynamic keys are always allowed
+        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
+            deduped.push(prop);
+            continue;
+        }
+        const name = prop.key.content;
+        const existing = knownProps.get(name);
+        if (existing) {
+            if (name === 'style' || name === 'class' || isOn(name)) {
+                mergeAsArray(existing, prop);
+            }
+            // unexpected duplicate, should have emitted error during parse
+        }
+        else {
+            knownProps.set(name, prop);
+            deduped.push(prop);
+        }
+    }
+    return deduped;
+}
+function mergeAsArray(existing, incoming) {
+    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
+        existing.value.elements.push(incoming.value);
+    }
+    else {
+        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
+    }
+}
+function buildDirectiveArgs(dir, context) {
+    const dirArgs = [];
+    const runtime = directiveImportMap.get(dir);
+    if (runtime) {
+        // built-in directive with runtime
+        dirArgs.push(context.helperString(runtime));
+    }
+    else {
+        {
+            // inject statement for resolving directive
+            context.helper(RESOLVE_DIRECTIVE);
+            context.directives.add(dir.name);
+            dirArgs.push(toValidAssetId(dir.name, `directive`));
+        }
+    }
+    const { loc } = dir;
+    if (dir.exp)
+        dirArgs.push(dir.exp);
+    if (dir.arg) {
+        if (!dir.exp) {
+            dirArgs.push(`void 0`);
+        }
+        dirArgs.push(dir.arg);
+    }
+    if (Object.keys(dir.modifiers).length) {
+        if (!dir.arg) {
+            if (!dir.exp) {
+                dirArgs.push(`void 0`);
+            }
+            dirArgs.push(`void 0`);
+        }
+        const trueExpression = createSimpleExpression(`true`, false, loc);
+        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
+    }
+    return createArrayExpression(dirArgs, dir.loc);
+}
+function stringifyDynamicPropNames(props) {
+    let propsNamesString = `[`;
+    for (let i = 0, l = props.length; i < l; i++) {
+        propsNamesString += JSON.stringify(props[i]);
+        if (i < l - 1)
+            propsNamesString += ', ';
+    }
+    return propsNamesString + `]`;
+}
+function isComponentTag(tag) {
+    return tag === 'component' || tag === 'Component';
 }
 
-(process.env.NODE_ENV !== 'production')
-    ? Object.freeze({})
-    : {};
-(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];
-const cacheStringFunction = (fn) => {
-    const cache = Object.create(null);
-    return ((str) => {
-        const hit = cache[str];
-        return hit || (cache[str] = fn(str));
-    });
-};
-const camelizeRE = /-(\w)/g;
-/**
- * @private
- */
-const camelize = cacheStringFunction((str) => {
-    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
+(process.env.NODE_ENV !== 'production')
+    ? Object.freeze({})
+    : {};
+(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];
+const cacheStringFunction = (fn) => {
+    const cache = Object.create(null);
+    return ((str) => {
+        const hit = cache[str];
+        return hit || (cache[str] = fn(str));
+    });
+};
+const camelizeRE = /-(\w)/g;
+/**
+ * @private
+ */
+const camelize = cacheStringFunction((str) => {
+    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
 });
 
-const transformSlotOutlet = (node, context) => {
-    if (isSlotOutlet(node)) {
-        const { children, loc } = node;
-        const { slotName, slotProps } = processSlotOutlet(node, context);
-        const slotArgs = [
-            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
-            slotName,
-            '{}',
-            'undefined',
-            'true'
-        ];
-        let expectedLen = 2;
-        if (slotProps) {
-            slotArgs[2] = slotProps;
-            expectedLen = 3;
-        }
-        if (children.length) {
-            slotArgs[3] = createFunctionExpression([], children, false, false, loc);
-            expectedLen = 4;
-        }
-        if (context.scopeId && !context.slotted) {
-            expectedLen = 5;
-        }
-        slotArgs.splice(expectedLen); // remove unused arguments
-        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
-    }
-};
-function processSlotOutlet(node, context) {
-    let slotName = `"default"`;
-    let slotProps = undefined;
-    const nonNameProps = [];
-    for (let i = 0; i < node.props.length; i++) {
-        const p = node.props[i];
-        if (p.type === 6 /* ATTRIBUTE */) {
-            if (p.value) {
-                if (p.name === 'name') {
-                    slotName = JSON.stringify(p.value.content);
-                }
-                else {
-                    p.name = camelize(p.name);
-                    nonNameProps.push(p);
-                }
-            }
-        }
-        else {
-            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
-                if (p.exp)
-                    slotName = p.exp;
-            }
-            else {
-                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
-                    p.arg.content = camelize(p.arg.content);
-                }
-                nonNameProps.push(p);
-            }
-        }
-    }
-    if (nonNameProps.length > 0) {
-        const { props, directives } = buildProps(node, context, nonNameProps, false, false);
-        slotProps = props;
-        if (directives.length) {
-            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
-        }
-    }
-    return {
-        slotName,
-        slotProps
-    };
+const transformSlotOutlet = (node, context) => {
+    if (isSlotOutlet(node)) {
+        const { children, loc } = node;
+        const { slotName, slotProps } = processSlotOutlet(node, context);
+        const slotArgs = [
+            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
+            slotName,
+            '{}',
+            'undefined',
+            'true'
+        ];
+        let expectedLen = 2;
+        if (slotProps) {
+            slotArgs[2] = slotProps;
+            expectedLen = 3;
+        }
+        if (children.length) {
+            slotArgs[3] = createFunctionExpression([], children, false, false, loc);
+            expectedLen = 4;
+        }
+        if (context.scopeId && !context.slotted) {
+            expectedLen = 5;
+        }
+        slotArgs.splice(expectedLen); // remove unused arguments
+        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
+    }
+};
+function processSlotOutlet(node, context) {
+    let slotName = `"default"`;
+    let slotProps = undefined;
+    const nonNameProps = [];
+    for (let i = 0; i < node.props.length; i++) {
+        const p = node.props[i];
+        if (p.type === 6 /* ATTRIBUTE */) {
+            if (p.value) {
+                if (p.name === 'name') {
+                    slotName = JSON.stringify(p.value.content);
+                }
+                else {
+                    p.name = camelize(p.name);
+                    nonNameProps.push(p);
+                }
+            }
+        }
+        else {
+            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
+                if (p.exp)
+                    slotName = p.exp;
+            }
+            else {
+                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
+                    p.arg.content = camelize(p.arg.content);
+                }
+                nonNameProps.push(p);
+            }
+        }
+    }
+    if (nonNameProps.length > 0) {
+        const { props, directives } = buildProps(node, context, nonNameProps, false, false);
+        slotProps = props;
+        if (directives.length) {
+            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
+        }
+    }
+    return {
+        slotName,
+        slotProps
+    };
 }
 
-const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
-const transformOn = (dir, node, context, augmentor) => {
-    const { loc, modifiers, arg } = dir;
-    if (!dir.exp && !modifiers.length) {
-        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));
-    }
-    let eventName;
-    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
-        if (arg.isStatic) {
-            let rawName = arg.content;
-            // TODO deprecate @vnodeXXX usage
-            if (rawName.startsWith('vue:')) {
-                rawName = `vnode-${rawName.slice(4)}`;
-            }
-            // for all event listeners, auto convert it to camelCase. See issue #2249
-            eventName = createSimpleExpression(toHandlerKey(camelize$1(rawName)), true, arg.loc);
-        }
-        else {
-            // #2388
-            eventName = createCompoundExpression([
-                `${context.helperString(TO_HANDLER_KEY)}(`,
-                arg,
-                `)`
-            ]);
-        }
-    }
-    else {
-        // already a compound expression.
-        eventName = arg;
-        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
-        eventName.children.push(`)`);
-    }
-    // handler processing
-    let exp = dir.exp;
-    if (exp && !exp.content.trim()) {
-        exp = undefined;
-    }
-    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
-    if (exp) {
-        const isMemberExp = isMemberExpression(exp.content);
-        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
-        const hasMultipleStatements = exp.content.includes(`;`);
-        if ((process.env.NODE_ENV !== 'production') && true) {
-            validateBrowserExpression(exp, context, false, hasMultipleStatements);
-        }
-        if (isInlineStatement || (shouldCache && isMemberExp)) {
-            // wrap inline statement in a function expression
-            exp = createCompoundExpression([
-                `${isInlineStatement
-                    ? `$event`
-                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
-                exp,
-                hasMultipleStatements ? `}` : `)`
-            ]);
-        }
-    }
-    let ret = {
-        props: [
-            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
-        ]
-    };
-    // apply extended compiler augmentor
-    if (augmentor) {
-        ret = augmentor(ret);
-    }
-    if (shouldCache) {
-        // cache handlers so that it's always the same handler being passed down.
-        // this avoids unnecessary re-renders when users use inline handlers on
-        // components.
-        ret.props[0].value = context.cache(ret.props[0].value);
-    }
-    // mark the key as handler for props normalization check
-    ret.props.forEach(p => (p.key.isHandlerKey = true));
-    return ret;
+const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
+const transformOn = (dir, node, context, augmentor) => {
+    const { loc, modifiers, arg } = dir;
+    if (!dir.exp && !modifiers.length) {
+        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));
+    }
+    let eventName;
+    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
+        if (arg.isStatic) {
+            let rawName = arg.content;
+            // TODO deprecate @vnodeXXX usage
+            if (rawName.startsWith('vue:')) {
+                rawName = `vnode-${rawName.slice(4)}`;
+            }
+            // for all event listeners, auto convert it to camelCase. See issue #2249
+            eventName = createSimpleExpression(toHandlerKey(camelize$1(rawName)), true, arg.loc);
+        }
+        else {
+            // #2388
+            eventName = createCompoundExpression([
+                `${context.helperString(TO_HANDLER_KEY)}(`,
+                arg,
+                `)`
+            ]);
+        }
+    }
+    else {
+        // already a compound expression.
+        eventName = arg;
+        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
+        eventName.children.push(`)`);
+    }
+    // handler processing
+    let exp = dir.exp;
+    if (exp && !exp.content.trim()) {
+        exp = undefined;
+    }
+    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
+    if (exp) {
+        const isMemberExp = isMemberExpression(exp.content);
+        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
+        const hasMultipleStatements = exp.content.includes(`;`);
+        if ((process.env.NODE_ENV !== 'production') && true) {
+            validateBrowserExpression(exp, context, false, hasMultipleStatements);
+        }
+        if (isInlineStatement || (shouldCache && isMemberExp)) {
+            // wrap inline statement in a function expression
+            exp = createCompoundExpression([
+                `${isInlineStatement
+                    ? `$event`
+                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
+                exp,
+                hasMultipleStatements ? `}` : `)`
+            ]);
+        }
+    }
+    let ret = {
+        props: [
+            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
+        ]
+    };
+    // apply extended compiler augmentor
+    if (augmentor) {
+        ret = augmentor(ret);
+    }
+    if (shouldCache) {
+        // cache handlers so that it's always the same handler being passed down.
+        // this avoids unnecessary re-renders when users use inline handlers on
+        // components.
+        ret.props[0].value = context.cache(ret.props[0].value);
+    }
+    // mark the key as handler for props normalization check
+    ret.props.forEach(p => (p.key.isHandlerKey = true));
+    return ret;
 };
 
-// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
-// codegen for the entire props object. This transform here is only for v-bind
-// *with* args.
-const transformBind = (dir, _node, context) => {
-    const { exp, modifiers, loc } = dir;
-    const arg = dir.arg;
-    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
-        arg.children.unshift(`(`);
-        arg.children.push(`) || ""`);
-    }
-    else if (!arg.isStatic) {
-        arg.content = `${arg.content} || ""`;
-    }
-    // .sync is replaced by v-model:arg
-    if (modifiers.includes('camel')) {
-        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
-            if (arg.isStatic) {
-                arg.content = camelize$1(arg.content);
-            }
-            else {
-                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
-            }
-        }
-        else {
-            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
-            arg.children.push(`)`);
-        }
-    }
-    if (!context.inSSR) {
-        if (modifiers.includes('prop')) {
-            injectPrefix(arg, '.');
-        }
-        if (modifiers.includes('attr')) {
-            injectPrefix(arg, '^');
-        }
-    }
-    if (!exp ||
-        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
-        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));
-        return {
-            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
-        };
-    }
-    return {
-        props: [createObjectProperty(arg, exp)]
-    };
-};
-const injectPrefix = (arg, prefix) => {
-    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
-        if (arg.isStatic) {
-            arg.content = prefix + arg.content;
-        }
-        else {
-            arg.content = `\`${prefix}\${${arg.content}}\``;
-        }
-    }
-    else {
-        arg.children.unshift(`'${prefix}' + (`);
-        arg.children.push(`)`);
-    }
+// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
+// codegen for the entire props object. This transform here is only for v-bind
+// *with* args.
+const transformBind = (dir, _node, context) => {
+    const { exp, modifiers, loc } = dir;
+    const arg = dir.arg;
+    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
+        arg.children.unshift(`(`);
+        arg.children.push(`) || ""`);
+    }
+    else if (!arg.isStatic) {
+        arg.content = `${arg.content} || ""`;
+    }
+    // .sync is replaced by v-model:arg
+    if (modifiers.includes('camel')) {
+        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
+            if (arg.isStatic) {
+                arg.content = camelize$1(arg.content);
+            }
+            else {
+                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
+            }
+        }
+        else {
+            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
+            arg.children.push(`)`);
+        }
+    }
+    if (!context.inSSR) {
+        if (modifiers.includes('prop')) {
+            injectPrefix(arg, '.');
+        }
+        if (modifiers.includes('attr')) {
+            injectPrefix(arg, '^');
+        }
+    }
+    if (!exp ||
+        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
+        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));
+        return {
+            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
+        };
+    }
+    return {
+        props: [createObjectProperty(arg, exp)]
+    };
+};
+const injectPrefix = (arg, prefix) => {
+    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
+        if (arg.isStatic) {
+            arg.content = prefix + arg.content;
+        }
+        else {
+            arg.content = `\`${prefix}\${${arg.content}}\``;
+        }
+    }
+    else {
+        arg.children.unshift(`'${prefix}' + (`);
+        arg.children.push(`)`);
+    }
 };
 
-// Merge adjacent text nodes and expressions into a single expression
-// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
-const transformText = (node, context) => {
-    if (node.type === 0 /* ROOT */ ||
-        node.type === 1 /* ELEMENT */ ||
-        node.type === 11 /* FOR */ ||
-        node.type === 10 /* IF_BRANCH */) {
-        // perform the transform on node exit so that all expressions have already
-        // been processed.
-        return () => {
-            const children = node.children;
-            let currentContainer = undefined;
-            let hasText = false;
-            for (let i = 0; i < children.length; i++) {
-                const child = children[i];
-                if (isText(child)) {
-                    hasText = true;
-                    for (let j = i + 1; j < children.length; j++) {
-                        const next = children[j];
-                        if (isText(next)) {
-                            if (!currentContainer) {
-                                currentContainer = children[i] = createCompoundExpression([child], child.loc);
-                            }
-                            // merge adjacent text node into current
-                            currentContainer.children.push(` + `, next);
-                            children.splice(j, 1);
-                            j--;
-                        }
-                        else {
-                            currentContainer = undefined;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (!hasText ||
-                // if this is a plain element with a single text child, leave it
-                // as-is since the runtime has dedicated fast path for this by directly
-                // setting textContent of the element.
-                // for component root it's always normalized anyway.
-                (children.length === 1 &&
-                    (node.type === 0 /* ROOT */ ||
-                        (node.type === 1 /* ELEMENT */ &&
-                            node.tagType === 0 /* ELEMENT */ &&
-                            // #3756
-                            // custom directives can potentially add DOM elements arbitrarily,
-                            // we need to avoid setting textContent of the element at runtime
-                            // to avoid accidentally overwriting the DOM elements added
-                            // by the user through custom directives.
-                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
-                                !context.directiveTransforms[p.name]) &&
-                            // in compat mode, <template> tags with no special directives
-                            // will be rendered as a fragment so its children must be
-                            // converted into vnodes.
-                            !(node.tag === 'template'))))) {
-                return;
-            }
-            // pre-convert text nodes into createTextVNode(text) calls to avoid
-            // runtime normalization.
-            for (let i = 0; i < children.length; i++) {
-                const child = children[i];
-                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
-                    const callArgs = [];
-                    // createTextVNode defaults to single whitespace, so if it is a
-                    // single space the code could be an empty call to save bytes.
-                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
-                        callArgs.push(child);
-                    }
-                    // mark dynamic text with flag so it gets patched inside a block
-                    if (!context.ssr &&
-                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
-                        callArgs.push(1 /* TEXT */ +
-                            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[1 /* TEXT */]} */` : ``));
-                    }
-                    children[i] = {
-                        type: 12 /* TEXT_CALL */,
-                        content: child,
-                        loc: child.loc,
-                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
-                    };
-                }
-            }
-        };
-    }
+// Merge adjacent text nodes and expressions into a single expression
+// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
+const transformText = (node, context) => {
+    if (node.type === 0 /* ROOT */ ||
+        node.type === 1 /* ELEMENT */ ||
+        node.type === 11 /* FOR */ ||
+        node.type === 10 /* IF_BRANCH */) {
+        // perform the transform on node exit so that all expressions have already
+        // been processed.
+        return () => {
+            const children = node.children;
+            let currentContainer = undefined;
+            let hasText = false;
+            for (let i = 0; i < children.length; i++) {
+                const child = children[i];
+                if (isText(child)) {
+                    hasText = true;
+                    for (let j = i + 1; j < children.length; j++) {
+                        const next = children[j];
+                        if (isText(next)) {
+                            if (!currentContainer) {
+                                currentContainer = children[i] = createCompoundExpression([child], child.loc);
+                            }
+                            // merge adjacent text node into current
+                            currentContainer.children.push(` + `, next);
+                            children.splice(j, 1);
+                            j--;
+                        }
+                        else {
+                            currentContainer = undefined;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (!hasText ||
+                // if this is a plain element with a single text child, leave it
+                // as-is since the runtime has dedicated fast path for this by directly
+                // setting textContent of the element.
+                // for component root it's always normalized anyway.
+                (children.length === 1 &&
+                    (node.type === 0 /* ROOT */ ||
+                        (node.type === 1 /* ELEMENT */ &&
+                            node.tagType === 0 /* ELEMENT */ &&
+                            // #3756
+                            // custom directives can potentially add DOM elements arbitrarily,
+                            // we need to avoid setting textContent of the element at runtime
+                            // to avoid accidentally overwriting the DOM elements added
+                            // by the user through custom directives.
+                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
+                                !context.directiveTransforms[p.name]) &&
+                            // in compat mode, <template> tags with no special directives
+                            // will be rendered as a fragment so its children must be
+                            // converted into vnodes.
+                            !(node.tag === 'template'))))) {
+                return;
+            }
+            // pre-convert text nodes into createTextVNode(text) calls to avoid
+            // runtime normalization.
+            for (let i = 0; i < children.length; i++) {
+                const child = children[i];
+                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
+                    const callArgs = [];
+                    // createTextVNode defaults to single whitespace, so if it is a
+                    // single space the code could be an empty call to save bytes.
+                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
+                        callArgs.push(child);
+                    }
+                    // mark dynamic text with flag so it gets patched inside a block
+                    if (!context.ssr &&
+                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
+                        callArgs.push(1 /* TEXT */ +
+                            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[1 /* TEXT */]} */` : ``));
+                    }
+                    children[i] = {
+                        type: 12 /* TEXT_CALL */,
+                        content: child,
+                        loc: child.loc,
+                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
+                    };
+                }
+            }
+        };
+    }
 };
 
-const seen = new WeakSet();
-const transformOnce = (node, context) => {
-    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
-        if (seen.has(node) || context.inVOnce) {
-            return;
-        }
-        seen.add(node);
-        context.inVOnce = true;
-        context.helper(SET_BLOCK_TRACKING);
-        return () => {
-            context.inVOnce = false;
-            const cur = context.currentNode;
-            if (cur.codegenNode) {
-                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
-            }
-        };
-    }
+const seen = new WeakSet();
+const transformOnce = (node, context) => {
+    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
+        if (seen.has(node) || context.inVOnce) {
+            return;
+        }
+        seen.add(node);
+        context.inVOnce = true;
+        context.helper(SET_BLOCK_TRACKING);
+        return () => {
+            context.inVOnce = false;
+            const cur = context.currentNode;
+            if (cur.codegenNode) {
+                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
+            }
+        };
+    }
 };
 
-const transformModel = (dir, node, context) => {
-    const { exp, arg } = dir;
-    if (!exp) {
-        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
-        return createTransformProps();
-    }
-    const rawExp = exp.loc.source;
-    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
-    const maybeRef = !true    /* SETUP_CONST */;
-    if (!expString.trim() ||
-        (!isMemberExpression(expString) && !maybeRef)) {
-        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
-        return createTransformProps();
-    }
-    const propName = arg ? arg : createSimpleExpression('modelValue', true);
-    const eventName = arg
-        ? isStaticExp(arg)
-            ? `onUpdate:${arg.content}`
-            : createCompoundExpression(['"onUpdate:" + ', arg])
-        : `onUpdate:modelValue`;
-    let assignmentExp;
-    const eventArg = context.isTS ? `($event: any)` : `$event`;
-    {
-        assignmentExp = createCompoundExpression([
-            `${eventArg} => ((`,
-            exp,
-            `) = $event)`
-        ]);
-    }
-    const props = [
-        // modelValue: foo
-        createObjectProperty(propName, dir.exp),
-        // "onUpdate:modelValue": $event => (foo = $event)
-        createObjectProperty(eventName, assignmentExp)
-    ];
-    // modelModifiers: { foo: true, "bar-baz": true }
-    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
-        const modifiers = dir.modifiers
-            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
-            .join(`, `);
-        const modifiersKey = arg
-            ? isStaticExp(arg)
-                ? `${arg.content}Modifiers`
-                : createCompoundExpression([arg, ' + "Modifiers"'])
-            : `modelModifiers`;
-        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
-    }
-    return createTransformProps(props);
-};
-function createTransformProps(props = []) {
-    return { props };
+const transformModel = (dir, node, context) => {
+    const { exp, arg } = dir;
+    if (!exp) {
+        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
+        return createTransformProps();
+    }
+    const rawExp = exp.loc.source;
+    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
+    const maybeRef = !true    /* SETUP_CONST */;
+    if (!expString.trim() ||
+        (!isMemberExpression(expString) && !maybeRef)) {
+        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
+        return createTransformProps();
+    }
+    const propName = arg ? arg : createSimpleExpression('modelValue', true);
+    const eventName = arg
+        ? isStaticExp(arg)
+            ? `onUpdate:${arg.content}`
+            : createCompoundExpression(['"onUpdate:" + ', arg])
+        : `onUpdate:modelValue`;
+    let assignmentExp;
+    const eventArg = context.isTS ? `($event: any)` : `$event`;
+    {
+        assignmentExp = createCompoundExpression([
+            `${eventArg} => ((`,
+            exp,
+            `) = $event)`
+        ]);
+    }
+    const props = [
+        // modelValue: foo
+        createObjectProperty(propName, dir.exp),
+        // "onUpdate:modelValue": $event => (foo = $event)
+        createObjectProperty(eventName, assignmentExp)
+    ];
+    // modelModifiers: { foo: true, "bar-baz": true }
+    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
+        const modifiers = dir.modifiers
+            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
+            .join(`, `);
+        const modifiersKey = arg
+            ? isStaticExp(arg)
+                ? `${arg.content}Modifiers`
+                : createCompoundExpression([arg, ' + "Modifiers"'])
+            : `modelModifiers`;
+        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
+    }
+    return createTransformProps(props);
+};
+function createTransformProps(props = []) {
+    return { props };
 }
 
-const validDivisionCharRE = /[\w).+\-_$\]]/;
-const transformFilter = (node, context) => {
-    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {
-        return;
-    }
-    if (node.type === 5 /* INTERPOLATION */) {
-        // filter rewrite is applied before expression transform so only
-        // simple expressions are possible at this stage
-        rewriteFilter(node.content, context);
-    }
-    if (node.type === 1 /* ELEMENT */) {
-        node.props.forEach((prop) => {
-            if (prop.type === 7 /* DIRECTIVE */ &&
-                prop.name !== 'for' &&
-                prop.exp) {
-                rewriteFilter(prop.exp, context);
-            }
-        });
-    }
-};
-function rewriteFilter(node, context) {
-    if (node.type === 4 /* SIMPLE_EXPRESSION */) {
-        parseFilter(node, context);
-    }
-    else {
-        for (let i = 0; i < node.children.length; i++) {
-            const child = node.children[i];
-            if (typeof child !== 'object')
-                continue;
-            if (child.type === 4 /* SIMPLE_EXPRESSION */) {
-                parseFilter(child, context);
-            }
-            else if (child.type === 8 /* COMPOUND_EXPRESSION */) {
-                rewriteFilter(node, context);
-            }
-            else if (child.type === 5 /* INTERPOLATION */) {
-                rewriteFilter(child.content, context);
-            }
-        }
-    }
-}
-function parseFilter(node, context) {
-    const exp = node.content;
-    let inSingle = false;
-    let inDouble = false;
-    let inTemplateString = false;
-    let inRegex = false;
-    let curly = 0;
-    let square = 0;
-    let paren = 0;
-    let lastFilterIndex = 0;
-    let c, prev, i, expression, filters = [];
-    for (i = 0; i < exp.length; i++) {
-        prev = c;
-        c = exp.charCodeAt(i);
-        if (inSingle) {
-            if (c === 0x27 && prev !== 0x5c)
-                inSingle = false;
-        }
-        else if (inDouble) {
-            if (c === 0x22 && prev !== 0x5c)
-                inDouble = false;
-        }
-        else if (inTemplateString) {
-            if (c === 0x60 && prev !== 0x5c)
-                inTemplateString = false;
-        }
-        else if (inRegex) {
-            if (c === 0x2f && prev !== 0x5c)
-                inRegex = false;
-        }
-        else if (c === 0x7c && // pipe
-            exp.charCodeAt(i + 1) !== 0x7c &&
-            exp.charCodeAt(i - 1) !== 0x7c &&
-            !curly &&
-            !square &&
-            !paren) {
-            if (expression === undefined) {
-                // first filter, end of expression
-                lastFilterIndex = i + 1;
-                expression = exp.slice(0, i).trim();
-            }
-            else {
-                pushFilter();
-            }
-        }
-        else {
-            switch (c) {
-                case 0x22:
-                    inDouble = true;
-                    break; // "
-                case 0x27:
-                    inSingle = true;
-                    break; // '
-                case 0x60:
-                    inTemplateString = true;
-                    break; // `
-                case 0x28:
-                    paren++;
-                    break; // (
-                case 0x29:
-                    paren--;
-                    break; // )
-                case 0x5b:
-                    square++;
-                    break; // [
-                case 0x5d:
-                    square--;
-                    break; // ]
-                case 0x7b:
-                    curly++;
-                    break; // {
-                case 0x7d:
-                    curly--;
-                    break; // }
-            }
-            if (c === 0x2f) {
-                // /
-                let j = i - 1;
-                let p;
-                // find first non-whitespace prev char
-                for (; j >= 0; j--) {
-                    p = exp.charAt(j);
-                    if (p !== ' ')
-                        break;
-                }
-                if (!p || !validDivisionCharRE.test(p)) {
-                    inRegex = true;
-                }
-            }
-        }
-    }
-    if (expression === undefined) {
-        expression = exp.slice(0, i).trim();
-    }
-    else if (lastFilterIndex !== 0) {
-        pushFilter();
-    }
-    function pushFilter() {
-        filters.push(exp.slice(lastFilterIndex, i).trim());
-        lastFilterIndex = i + 1;
-    }
-    if (filters.length) {
-        (process.env.NODE_ENV !== 'production') &&
-            warnDeprecation("COMPILER_FILTER" /* COMPILER_FILTERS */, context, node.loc);
-        for (i = 0; i < filters.length; i++) {
-            expression = wrapFilter(expression, filters[i], context);
-        }
-        node.content = expression;
-    }
-}
-function wrapFilter(exp, filter, context) {
-    context.helper(RESOLVE_FILTER);
-    const i = filter.indexOf('(');
-    if (i < 0) {
-        context.filters.add(filter);
-        return `${toValidAssetId(filter, 'filter')}(${exp})`;
-    }
-    else {
-        const name = filter.slice(0, i);
-        const args = filter.slice(i + 1);
-        context.filters.add(name);
-        return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`;
-    }
+const validDivisionCharRE = /[\w).+\-_$\]]/;
+const transformFilter = (node, context) => {
+    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {
+        return;
+    }
+    if (node.type === 5 /* INTERPOLATION */) {
+        // filter rewrite is applied before expression transform so only
+        // simple expressions are possible at this stage
+        rewriteFilter(node.content, context);
+    }
+    if (node.type === 1 /* ELEMENT */) {
+        node.props.forEach((prop) => {
+            if (prop.type === 7 /* DIRECTIVE */ &&
+                prop.name !== 'for' &&
+                prop.exp) {
+                rewriteFilter(prop.exp, context);
+            }
+        });
+    }
+};
+function rewriteFilter(node, context) {
+    if (node.type === 4 /* SIMPLE_EXPRESSION */) {
+        parseFilter(node, context);
+    }
+    else {
+        for (let i = 0; i < node.children.length; i++) {
+            const child = node.children[i];
+            if (typeof child !== 'object')
+                continue;
+            if (child.type === 4 /* SIMPLE_EXPRESSION */) {
+                parseFilter(child, context);
+            }
+            else if (child.type === 8 /* COMPOUND_EXPRESSION */) {
+                rewriteFilter(node, context);
+            }
+            else if (child.type === 5 /* INTERPOLATION */) {
+                rewriteFilter(child.content, context);
+            }
+        }
+    }
+}
+function parseFilter(node, context) {
+    const exp = node.content;
+    let inSingle = false;
+    let inDouble = false;
+    let inTemplateString = false;
+    let inRegex = false;
+    let curly = 0;
+    let square = 0;
+    let paren = 0;
+    let lastFilterIndex = 0;
+    let c, prev, i, expression, filters = [];
+    for (i = 0; i < exp.length; i++) {
+        prev = c;
+        c = exp.charCodeAt(i);
+        if (inSingle) {
+            if (c === 0x27 && prev !== 0x5c)
+                inSingle = false;
+        }
+        else if (inDouble) {
+            if (c === 0x22 && prev !== 0x5c)
+                inDouble = false;
+        }
+        else if (inTemplateString) {
+            if (c === 0x60 && prev !== 0x5c)
+                inTemplateString = false;
+        }
+        else if (inRegex) {
+            if (c === 0x2f && prev !== 0x5c)
+                inRegex = false;
+        }
+        else if (c === 0x7c && // pipe
+            exp.charCodeAt(i + 1) !== 0x7c &&
+            exp.charCodeAt(i - 1) !== 0x7c &&
+            !curly &&
+            !square &&
+            !paren) {
+            if (expression === undefined) {
+                // first filter, end of expression
+                lastFilterIndex = i + 1;
+                expression = exp.slice(0, i).trim();
+            }
+            else {
+                pushFilter();
+            }
+        }
+        else {
+            switch (c) {
+                case 0x22:
+                    inDouble = true;
+                    break; // "
+                case 0x27:
+                    inSingle = true;
+                    break; // '
+                case 0x60:
+                    inTemplateString = true;
+                    break; // `
+                case 0x28:
+                    paren++;
+                    break; // (
+                case 0x29:
+                    paren--;
+                    break; // )
+                case 0x5b:
+                    square++;
+                    break; // [
+                case 0x5d:
+                    square--;
+                    break; // ]
+                case 0x7b:
+                    curly++;
+                    break; // {
+                case 0x7d:
+                    curly--;
+                    break; // }
+            }
+            if (c === 0x2f) {
+                // /
+                let j = i - 1;
+                let p;
+                // find first non-whitespace prev char
+                for (; j >= 0; j--) {
+                    p = exp.charAt(j);
+                    if (p !== ' ')
+                        break;
+                }
+                if (!p || !validDivisionCharRE.test(p)) {
+                    inRegex = true;
+                }
+            }
+        }
+    }
+    if (expression === undefined) {
+        expression = exp.slice(0, i).trim();
+    }
+    else if (lastFilterIndex !== 0) {
+        pushFilter();
+    }
+    function pushFilter() {
+        filters.push(exp.slice(lastFilterIndex, i).trim());
+        lastFilterIndex = i + 1;
+    }
+    if (filters.length) {
+        (process.env.NODE_ENV !== 'production') &&
+            warnDeprecation("COMPILER_FILTER" /* COMPILER_FILTERS */, context, node.loc);
+        for (i = 0; i < filters.length; i++) {
+            expression = wrapFilter(expression, filters[i], context);
+        }
+        node.content = expression;
+    }
+}
+function wrapFilter(exp, filter, context) {
+    context.helper(RESOLVE_FILTER);
+    const i = filter.indexOf('(');
+    if (i < 0) {
+        context.filters.add(filter);
+        return `${toValidAssetId(filter, 'filter')}(${exp})`;
+    }
+    else {
+        const name = filter.slice(0, i);
+        const args = filter.slice(i + 1);
+        context.filters.add(name);
+        return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`;
+    }
 }
 
-const seen$1 = new WeakSet();
-const transformMemo = (node, context) => {
-    if (node.type === 1 /* ELEMENT */) {
-        const dir = findDir(node, 'memo');
-        if (!dir || seen$1.has(node)) {
-            return;
-        }
-        seen$1.add(node);
-        return () => {
-            const codegenNode = node.codegenNode ||
-                context.currentNode.codegenNode;
-            if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
-                // non-component sub tree should be turned into a block
-                if (node.tagType !== 1 /* COMPONENT */) {
-                    makeBlock(codegenNode, context);
-                }
-                node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
-                    dir.exp,
-                    createFunctionExpression(undefined, codegenNode),
-                    `_cache`,
-                    String(context.cached++)
-                ]);
-            }
-        };
-    }
+const seen$1 = new WeakSet();
+const transformMemo = (node, context) => {
+    if (node.type === 1 /* ELEMENT */) {
+        const dir = findDir(node, 'memo');
+        if (!dir || seen$1.has(node)) {
+            return;
+        }
+        seen$1.add(node);
+        return () => {
+            const codegenNode = node.codegenNode ||
+                context.currentNode.codegenNode;
+            if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
+                // non-component sub tree should be turned into a block
+                if (node.tagType !== 1 /* COMPONENT */) {
+                    makeBlock(codegenNode, context);
+                }
+                node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
+                    dir.exp,
+                    createFunctionExpression(undefined, codegenNode),
+                    `_cache`,
+                    String(context.cached++)
+                ]);
+            }
+        };
+    }
 };
 
-function getBaseTransformPreset(prefixIdentifiers) {
-    return [
-        [
-            transformOnce,
-            transformIf,
-            transformMemo,
-            transformFor,
-            ...([transformFilter] ),
-            ...((process.env.NODE_ENV !== 'production')
-                    ? [transformExpression]
-                    : []),
-            transformSlotOutlet,
-            transformElement,
-            trackSlotScopes,
-            transformText
-        ],
-        {
-            on: transformOn,
-            bind: transformBind,
-            model: transformModel
-        }
-    ];
-}
-// we name it `baseCompile` so that higher order compilers like
-// @vue/compiler-dom can export `compile` while re-exporting everything else.
-function baseCompile(template, options = {}) {
-    const onError = options.onError || defaultOnError;
-    const isModuleMode = options.mode === 'module';
-    /* istanbul ignore if */
-    {
-        if (options.prefixIdentifiers === true) {
-            onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));
-        }
-        else if (isModuleMode) {
-            onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));
-        }
-    }
-    const prefixIdentifiers = !true ;
-    if (options.cacheHandlers) {
-        onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
-    }
-    if (options.scopeId && !isModuleMode) {
-        onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));
-    }
-    const ast = isString(template) ? baseParse(template, options) : template;
-    const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
-    transform(ast, extend({}, options, {
-        prefixIdentifiers,
-        nodeTransforms: [
-            ...nodeTransforms,
-            ...(options.nodeTransforms || []) // user transforms
-        ],
-        directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
-        )
-    }));
-    return generate(ast, extend({}, options, {
-        prefixIdentifiers
-    }));
+function getBaseTransformPreset(prefixIdentifiers) {
+    return [
+        [
+            transformOnce,
+            transformIf,
+            transformMemo,
+            transformFor,
+            ...([transformFilter] ),
+            ...((process.env.NODE_ENV !== 'production')
+                    ? [transformExpression]
+                    : []),
+            transformSlotOutlet,
+            transformElement,
+            trackSlotScopes,
+            transformText
+        ],
+        {
+            on: transformOn,
+            bind: transformBind,
+            model: transformModel
+        }
+    ];
+}
+// we name it `baseCompile` so that higher order compilers like
+// @vue/compiler-dom can export `compile` while re-exporting everything else.
+function baseCompile(template, options = {}) {
+    const onError = options.onError || defaultOnError;
+    const isModuleMode = options.mode === 'module';
+    /* istanbul ignore if */
+    {
+        if (options.prefixIdentifiers === true) {
+            onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));
+        }
+        else if (isModuleMode) {
+            onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));
+        }
+    }
+    const prefixIdentifiers = !true ;
+    if (options.cacheHandlers) {
+        onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
+    }
+    if (options.scopeId && !isModuleMode) {
+        onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));
+    }
+    const ast = isString(template) ? baseParse(template, options) : template;
+    const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
+    transform(ast, extend({}, options, {
+        prefixIdentifiers,
+        nodeTransforms: [
+            ...nodeTransforms,
+            ...(options.nodeTransforms || []) // user transforms
+        ],
+        directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
+        )
+    }));
+    return generate(ast, extend({}, options, {
+        prefixIdentifiers
+    }));
 }
 
 const noopDirectiveTransform = () => ({ props: [] });
@@ -5675,27 +5675,27 @@ var require$$1 = /*@__PURE__*/getAugmentedNamespace(shared_esmBundler);
 	var compilerCore = require$$0;
 	var shared = require$$1;
 
-	const V_MODEL_RADIO = Symbol(`vModelRadio` );
-	const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
-	const V_MODEL_TEXT = Symbol(`vModelText` );
-	const V_MODEL_SELECT = Symbol(`vModelSelect` );
-	const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
-	const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
-	const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
-	const V_SHOW = Symbol(`vShow` );
-	const TRANSITION = Symbol(`Transition` );
-	const TRANSITION_GROUP = Symbol(`TransitionGroup` );
-	compilerCore.registerRuntimeHelpers({
-	    [V_MODEL_RADIO]: `vModelRadio`,
-	    [V_MODEL_CHECKBOX]: `vModelCheckbox`,
-	    [V_MODEL_TEXT]: `vModelText`,
-	    [V_MODEL_SELECT]: `vModelSelect`,
-	    [V_MODEL_DYNAMIC]: `vModelDynamic`,
-	    [V_ON_WITH_MODIFIERS]: `withModifiers`,
-	    [V_ON_WITH_KEYS]: `withKeys`,
-	    [V_SHOW]: `vShow`,
-	    [TRANSITION]: `Transition`,
-	    [TRANSITION_GROUP]: `TransitionGroup`
+	const V_MODEL_RADIO = Symbol(`vModelRadio` );
+	const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
+	const V_MODEL_TEXT = Symbol(`vModelText` );
+	const V_MODEL_SELECT = Symbol(`vModelSelect` );
+	const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
+	const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
+	const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
+	const V_SHOW = Symbol(`vShow` );
+	const TRANSITION = Symbol(`Transition` );
+	const TRANSITION_GROUP = Symbol(`TransitionGroup` );
+	compilerCore.registerRuntimeHelpers({
+	    [V_MODEL_RADIO]: `vModelRadio`,
+	    [V_MODEL_CHECKBOX]: `vModelCheckbox`,
+	    [V_MODEL_TEXT]: `vModelText`,
+	    [V_MODEL_SELECT]: `vModelSelect`,
+	    [V_MODEL_DYNAMIC]: `vModelDynamic`,
+	    [V_ON_WITH_MODIFIERS]: `withModifiers`,
+	    [V_ON_WITH_KEYS]: `withKeys`,
+	    [V_SHOW]: `vShow`,
+	    [TRANSITION]: `Transition`,
+	    [TRANSITION_GROUP]: `TransitionGroup`
 	});
 
 	var namedCharacterReferences = {
@@ -7932,856 +7932,856 @@ var require$$1 = /*@__PURE__*/getAugmentedNamespace(shared_esmBundler);
 		"CounterClockwiseContourIntegral;": "∳"
 	};
 
-	// lazy compute this to make this file tree-shakable for browser
-	let maxCRNameLength;
-	const decodeHtml = (rawText, asAttr) => {
-	    let offset = 0;
-	    const end = rawText.length;
-	    let decodedText = '';
-	    function advance(length) {
-	        offset += length;
-	        rawText = rawText.slice(length);
-	    }
-	    while (offset < end) {
-	        const head = /&(?:#x?)?/i.exec(rawText);
-	        if (!head || offset + head.index >= end) {
-	            const remaining = end - offset;
-	            decodedText += rawText.slice(0, remaining);
-	            advance(remaining);
-	            break;
-	        }
-	        // Advance to the "&".
-	        decodedText += rawText.slice(0, head.index);
-	        advance(head.index);
-	        if (head[0] === '&') {
-	            // Named character reference.
-	            let name = '';
-	            let value = undefined;
-	            if (/[0-9a-z]/i.test(rawText[1])) {
-	                if (!maxCRNameLength) {
-	                    maxCRNameLength = Object.keys(namedCharacterReferences).reduce((max, name) => Math.max(max, name.length), 0);
-	                }
-	                for (let length = maxCRNameLength; !value && length > 0; --length) {
-	                    name = rawText.slice(1, 1 + length);
-	                    value = namedCharacterReferences[name];
-	                }
-	                if (value) {
-	                    const semi = name.endsWith(';');
-	                    if (asAttr &&
-	                        !semi &&
-	                        /[=a-z0-9]/i.test(rawText[name.length + 1] || '')) {
-	                        decodedText += '&' + name;
-	                        advance(1 + name.length);
-	                    }
-	                    else {
-	                        decodedText += value;
-	                        advance(1 + name.length);
-	                    }
-	                }
-	                else {
-	                    decodedText += '&' + name;
-	                    advance(1 + name.length);
-	                }
-	            }
-	            else {
-	                decodedText += '&';
-	                advance(1);
-	            }
-	        }
-	        else {
-	            // Numeric character reference.
-	            const hex = head[0] === '&#x';
-	            const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/;
-	            const body = pattern.exec(rawText);
-	            if (!body) {
-	                decodedText += head[0];
-	                advance(head[0].length);
-	            }
-	            else {
-	                // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
-	                let cp = Number.parseInt(body[1], hex ? 16 : 10);
-	                if (cp === 0) {
-	                    cp = 0xfffd;
-	                }
-	                else if (cp > 0x10ffff) {
-	                    cp = 0xfffd;
-	                }
-	                else if (cp >= 0xd800 && cp <= 0xdfff) {
-	                    cp = 0xfffd;
-	                }
-	                else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) ;
-	                else if ((cp >= 0x01 && cp <= 0x08) ||
-	                    cp === 0x0b ||
-	                    (cp >= 0x0d && cp <= 0x1f) ||
-	                    (cp >= 0x7f && cp <= 0x9f)) {
-	                    cp = CCR_REPLACEMENTS[cp] || cp;
-	                }
-	                decodedText += String.fromCodePoint(cp);
-	                advance(body[0].length);
-	            }
-	        }
-	    }
-	    return decodedText;
-	};
-	// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
-	const CCR_REPLACEMENTS = {
-	    0x80: 0x20ac,
-	    0x82: 0x201a,
-	    0x83: 0x0192,
-	    0x84: 0x201e,
-	    0x85: 0x2026,
-	    0x86: 0x2020,
-	    0x87: 0x2021,
-	    0x88: 0x02c6,
-	    0x89: 0x2030,
-	    0x8a: 0x0160,
-	    0x8b: 0x2039,
-	    0x8c: 0x0152,
-	    0x8e: 0x017d,
-	    0x91: 0x2018,
-	    0x92: 0x2019,
-	    0x93: 0x201c,
-	    0x94: 0x201d,
-	    0x95: 0x2022,
-	    0x96: 0x2013,
-	    0x97: 0x2014,
-	    0x98: 0x02dc,
-	    0x99: 0x2122,
-	    0x9a: 0x0161,
-	    0x9b: 0x203a,
-	    0x9c: 0x0153,
-	    0x9e: 0x017e,
-	    0x9f: 0x0178
+	// lazy compute this to make this file tree-shakable for browser
+	let maxCRNameLength;
+	const decodeHtml = (rawText, asAttr) => {
+	    let offset = 0;
+	    const end = rawText.length;
+	    let decodedText = '';
+	    function advance(length) {
+	        offset += length;
+	        rawText = rawText.slice(length);
+	    }
+	    while (offset < end) {
+	        const head = /&(?:#x?)?/i.exec(rawText);
+	        if (!head || offset + head.index >= end) {
+	            const remaining = end - offset;
+	            decodedText += rawText.slice(0, remaining);
+	            advance(remaining);
+	            break;
+	        }
+	        // Advance to the "&".
+	        decodedText += rawText.slice(0, head.index);
+	        advance(head.index);
+	        if (head[0] === '&') {
+	            // Named character reference.
+	            let name = '';
+	            let value = undefined;
+	            if (/[0-9a-z]/i.test(rawText[1])) {
+	                if (!maxCRNameLength) {
+	                    maxCRNameLength = Object.keys(namedCharacterReferences).reduce((max, name) => Math.max(max, name.length), 0);
+	                }
+	                for (let length = maxCRNameLength; !value && length > 0; --length) {
+	                    name = rawText.slice(1, 1 + length);
+	                    value = namedCharacterReferences[name];
+	                }
+	                if (value) {
+	                    const semi = name.endsWith(';');
+	                    if (asAttr &&
+	                        !semi &&
+	                        /[=a-z0-9]/i.test(rawText[name.length + 1] || '')) {
+	                        decodedText += '&' + name;
+	                        advance(1 + name.length);
+	                    }
+	                    else {
+	                        decodedText += value;
+	                        advance(1 + name.length);
+	                    }
+	                }
+	                else {
+	                    decodedText += '&' + name;
+	                    advance(1 + name.length);
+	                }
+	            }
+	            else {
+	                decodedText += '&';
+	                advance(1);
+	            }
+	        }
+	        else {
+	            // Numeric character reference.
+	            const hex = head[0] === '&#x';
+	            const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/;
+	            const body = pattern.exec(rawText);
+	            if (!body) {
+	                decodedText += head[0];
+	                advance(head[0].length);
+	            }
+	            else {
+	                // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
+	                let cp = Number.parseInt(body[1], hex ? 16 : 10);
+	                if (cp === 0) {
+	                    cp = 0xfffd;
+	                }
+	                else if (cp > 0x10ffff) {
+	                    cp = 0xfffd;
+	                }
+	                else if (cp >= 0xd800 && cp <= 0xdfff) {
+	                    cp = 0xfffd;
+	                }
+	                else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) ;
+	                else if ((cp >= 0x01 && cp <= 0x08) ||
+	                    cp === 0x0b ||
+	                    (cp >= 0x0d && cp <= 0x1f) ||
+	                    (cp >= 0x7f && cp <= 0x9f)) {
+	                    cp = CCR_REPLACEMENTS[cp] || cp;
+	                }
+	                decodedText += String.fromCodePoint(cp);
+	                advance(body[0].length);
+	            }
+	        }
+	    }
+	    return decodedText;
+	};
+	// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
+	const CCR_REPLACEMENTS = {
+	    0x80: 0x20ac,
+	    0x82: 0x201a,
+	    0x83: 0x0192,
+	    0x84: 0x201e,
+	    0x85: 0x2026,
+	    0x86: 0x2020,
+	    0x87: 0x2021,
+	    0x88: 0x02c6,
+	    0x89: 0x2030,
+	    0x8a: 0x0160,
+	    0x8b: 0x2039,
+	    0x8c: 0x0152,
+	    0x8e: 0x017d,
+	    0x91: 0x2018,
+	    0x92: 0x2019,
+	    0x93: 0x201c,
+	    0x94: 0x201d,
+	    0x95: 0x2022,
+	    0x96: 0x2013,
+	    0x97: 0x2014,
+	    0x98: 0x02dc,
+	    0x99: 0x2122,
+	    0x9a: 0x0161,
+	    0x9b: 0x203a,
+	    0x9c: 0x0153,
+	    0x9e: 0x017e,
+	    0x9f: 0x0178
 	};
 
-	const isRawTextContainer = /*#__PURE__*/ shared.makeMap('style,iframe,script,noscript', true);
-	const parserOptions = {
-	    isVoidTag: shared.isVoidTag,
-	    isNativeTag: tag => shared.isHTMLTag(tag) || shared.isSVGTag(tag),
-	    isPreTag: tag => tag === 'pre',
-	    decodeEntities: decodeHtml,
-	    isBuiltInComponent: (tag) => {
-	        if (compilerCore.isBuiltInType(tag, `Transition`)) {
-	            return TRANSITION;
-	        }
-	        else if (compilerCore.isBuiltInType(tag, `TransitionGroup`)) {
-	            return TRANSITION_GROUP;
-	        }
-	    },
-	    // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
-	    getNamespace(tag, parent) {
-	        let ns = parent ? parent.ns : 0 /* HTML */;
-	        if (parent && ns === 2 /* MATH_ML */) {
-	            if (parent.tag === 'annotation-xml') {
-	                if (tag === 'svg') {
-	                    return 1 /* SVG */;
-	                }
-	                if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
-	                    a.name === 'encoding' &&
-	                    a.value != null &&
-	                    (a.value.content === 'text/html' ||
-	                        a.value.content === 'application/xhtml+xml'))) {
-	                    ns = 0 /* HTML */;
-	                }
-	            }
-	            else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
-	                tag !== 'mglyph' &&
-	                tag !== 'malignmark') {
-	                ns = 0 /* HTML */;
-	            }
-	        }
-	        else if (parent && ns === 1 /* SVG */) {
-	            if (parent.tag === 'foreignObject' ||
-	                parent.tag === 'desc' ||
-	                parent.tag === 'title') {
-	                ns = 0 /* HTML */;
-	            }
-	        }
-	        if (ns === 0 /* HTML */) {
-	            if (tag === 'svg') {
-	                return 1 /* SVG */;
-	            }
-	            if (tag === 'math') {
-	                return 2 /* MATH_ML */;
-	            }
-	        }
-	        return ns;
-	    },
-	    // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
-	    getTextMode({ tag, ns }) {
-	        if (ns === 0 /* HTML */) {
-	            if (tag === 'textarea' || tag === 'title') {
-	                return 1 /* RCDATA */;
-	            }
-	            if (isRawTextContainer(tag)) {
-	                return 2 /* RAWTEXT */;
-	            }
-	        }
-	        return 0 /* DATA */;
-	    }
+	const isRawTextContainer = /*#__PURE__*/ shared.makeMap('style,iframe,script,noscript', true);
+	const parserOptions = {
+	    isVoidTag: shared.isVoidTag,
+	    isNativeTag: tag => shared.isHTMLTag(tag) || shared.isSVGTag(tag),
+	    isPreTag: tag => tag === 'pre',
+	    decodeEntities: decodeHtml,
+	    isBuiltInComponent: (tag) => {
+	        if (compilerCore.isBuiltInType(tag, `Transition`)) {
+	            return TRANSITION;
+	        }
+	        else if (compilerCore.isBuiltInType(tag, `TransitionGroup`)) {
+	            return TRANSITION_GROUP;
+	        }
+	    },
+	    // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
+	    getNamespace(tag, parent) {
+	        let ns = parent ? parent.ns : 0 /* HTML */;
+	        if (parent && ns === 2 /* MATH_ML */) {
+	            if (parent.tag === 'annotation-xml') {
+	                if (tag === 'svg') {
+	                    return 1 /* SVG */;
+	                }
+	                if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
+	                    a.name === 'encoding' &&
+	                    a.value != null &&
+	                    (a.value.content === 'text/html' ||
+	                        a.value.content === 'application/xhtml+xml'))) {
+	                    ns = 0 /* HTML */;
+	                }
+	            }
+	            else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
+	                tag !== 'mglyph' &&
+	                tag !== 'malignmark') {
+	                ns = 0 /* HTML */;
+	            }
+	        }
+	        else if (parent && ns === 1 /* SVG */) {
+	            if (parent.tag === 'foreignObject' ||
+	                parent.tag === 'desc' ||
+	                parent.tag === 'title') {
+	                ns = 0 /* HTML */;
+	            }
+	        }
+	        if (ns === 0 /* HTML */) {
+	            if (tag === 'svg') {
+	                return 1 /* SVG */;
+	            }
+	            if (tag === 'math') {
+	                return 2 /* MATH_ML */;
+	            }
+	        }
+	        return ns;
+	    },
+	    // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
+	    getTextMode({ tag, ns }) {
+	        if (ns === 0 /* HTML */) {
+	            if (tag === 'textarea' || tag === 'title') {
+	                return 1 /* RCDATA */;
+	            }
+	            if (isRawTextContainer(tag)) {
+	                return 2 /* RAWTEXT */;
+	            }
+	        }
+	        return 0 /* DATA */;
+	    }
 	};
 
-	// Parse inline CSS strings for static style attributes into an object.
-	// This is a NodeTransform since it works on the static `style` attribute and
-	// converts it into a dynamic equivalent:
-	// style="color: red" -> :style='{ "color": "red" }'
-	// It is then processed by `transformElement` and included in the generated
-	// props.
-	const transformStyle = node => {
-	    if (node.type === 1 /* ELEMENT */) {
-	        node.props.forEach((p, i) => {
-	            if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
-	                // replace p with an expression node
-	                node.props[i] = {
-	                    type: 7 /* DIRECTIVE */,
-	                    name: `bind`,
-	                    arg: compilerCore.createSimpleExpression(`style`, true, p.loc),
-	                    exp: parseInlineCSS(p.value.content, p.loc),
-	                    modifiers: [],
-	                    loc: p.loc
-	                };
-	            }
-	        });
-	    }
-	};
-	const parseInlineCSS = (cssText, loc) => {
-	    const normalized = shared.parseStringStyle(cssText);
-	    return compilerCore.createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
+	// Parse inline CSS strings for static style attributes into an object.
+	// This is a NodeTransform since it works on the static `style` attribute and
+	// converts it into a dynamic equivalent:
+	// style="color: red" -> :style='{ "color": "red" }'
+	// It is then processed by `transformElement` and included in the generated
+	// props.
+	const transformStyle = node => {
+	    if (node.type === 1 /* ELEMENT */) {
+	        node.props.forEach((p, i) => {
+	            if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
+	                // replace p with an expression node
+	                node.props[i] = {
+	                    type: 7 /* DIRECTIVE */,
+	                    name: `bind`,
+	                    arg: compilerCore.createSimpleExpression(`style`, true, p.loc),
+	                    exp: parseInlineCSS(p.value.content, p.loc),
+	                    modifiers: [],
+	                    loc: p.loc
+	                };
+	            }
+	        });
+	    }
+	};
+	const parseInlineCSS = (cssText, loc) => {
+	    const normalized = shared.parseStringStyle(cssText);
+	    return compilerCore.createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
 	};
 
-	function createDOMCompilerError(code, loc) {
-	    return compilerCore.createCompilerError(code, loc, DOMErrorMessages );
-	}
-	const DOMErrorMessages = {
-	    [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
-	    [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
-	    [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
-	    [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
-	    [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
-	    [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
-	    [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
-	    [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
-	    [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
-	    [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
-	    [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
+	function createDOMCompilerError(code, loc) {
+	    return compilerCore.createCompilerError(code, loc, DOMErrorMessages );
+	}
+	const DOMErrorMessages = {
+	    [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
+	    [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
+	    [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
+	    [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
+	    [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
+	    [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
+	    [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
+	    [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
+	    [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
+	    [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
+	    [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
 	};
 
-	const transformVHtml = (dir, node, context) => {
-	    const { exp, loc } = dir;
-	    if (!exp) {
-	        context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));
-	    }
-	    if (node.children.length) {
-	        context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));
-	        node.children.length = 0;
-	    }
-	    return {
-	        props: [
-	            compilerCore.createObjectProperty(compilerCore.createSimpleExpression(`innerHTML`, true, loc), exp || compilerCore.createSimpleExpression('', true))
-	        ]
-	    };
+	const transformVHtml = (dir, node, context) => {
+	    const { exp, loc } = dir;
+	    if (!exp) {
+	        context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));
+	    }
+	    if (node.children.length) {
+	        context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));
+	        node.children.length = 0;
+	    }
+	    return {
+	        props: [
+	            compilerCore.createObjectProperty(compilerCore.createSimpleExpression(`innerHTML`, true, loc), exp || compilerCore.createSimpleExpression('', true))
+	        ]
+	    };
 	};
 
-	const transformVText = (dir, node, context) => {
-	    const { exp, loc } = dir;
-	    if (!exp) {
-	        context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));
-	    }
-	    if (node.children.length) {
-	        context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));
-	        node.children.length = 0;
-	    }
-	    return {
-	        props: [
-	            compilerCore.createObjectProperty(compilerCore.createSimpleExpression(`textContent`, true), exp
-	                ? compilerCore.getConstantType(exp, context) > 0
-	                    ? exp
-	                    : compilerCore.createCallExpression(context.helperString(compilerCore.TO_DISPLAY_STRING), [exp], loc)
-	                : compilerCore.createSimpleExpression('', true))
-	        ]
-	    };
+	const transformVText = (dir, node, context) => {
+	    const { exp, loc } = dir;
+	    if (!exp) {
+	        context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));
+	    }
+	    if (node.children.length) {
+	        context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));
+	        node.children.length = 0;
+	    }
+	    return {
+	        props: [
+	            compilerCore.createObjectProperty(compilerCore.createSimpleExpression(`textContent`, true), exp
+	                ? compilerCore.getConstantType(exp, context) > 0
+	                    ? exp
+	                    : compilerCore.createCallExpression(context.helperString(compilerCore.TO_DISPLAY_STRING), [exp], loc)
+	                : compilerCore.createSimpleExpression('', true))
+	        ]
+	    };
 	};
 
-	const transformModel = (dir, node, context) => {
-	    const baseResult = compilerCore.transformModel(dir, node, context);
-	    // base transform has errors OR component v-model (only need props)
-	    if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
-	        return baseResult;
-	    }
-	    if (dir.arg) {
-	        context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
-	    }
-	    function checkDuplicatedValue() {
-	        const value = compilerCore.findProp(node, 'value');
-	        if (value) {
-	            context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
-	        }
-	    }
-	    const { tag } = node;
-	    const isCustomElement = context.isCustomElement(tag);
-	    if (tag === 'input' ||
-	        tag === 'textarea' ||
-	        tag === 'select' ||
-	        isCustomElement) {
-	        let directiveToUse = V_MODEL_TEXT;
-	        let isInvalidType = false;
-	        if (tag === 'input' || isCustomElement) {
-	            const type = compilerCore.findProp(node, `type`);
-	            if (type) {
-	                if (type.type === 7 /* DIRECTIVE */) {
-	                    // :type="foo"
-	                    directiveToUse = V_MODEL_DYNAMIC;
-	                }
-	                else if (type.value) {
-	                    switch (type.value.content) {
-	                        case 'radio':
-	                            directiveToUse = V_MODEL_RADIO;
-	                            break;
-	                        case 'checkbox':
-	                            directiveToUse = V_MODEL_CHECKBOX;
-	                            break;
-	                        case 'file':
-	                            isInvalidType = true;
-	                            context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
-	                            break;
-	                        default:
-	                            // text type
-	                            checkDuplicatedValue();
-	                            break;
-	                    }
-	                }
-	            }
-	            else if (compilerCore.hasDynamicKeyVBind(node)) {
-	                // element has bindings with dynamic keys, which can possibly contain
-	                // "type".
-	                directiveToUse = V_MODEL_DYNAMIC;
-	            }
-	            else {
-	                // text type
-	                checkDuplicatedValue();
-	            }
-	        }
-	        else if (tag === 'select') {
-	            directiveToUse = V_MODEL_SELECT;
-	        }
-	        else {
-	            // textarea
-	            checkDuplicatedValue();
-	        }
-	        // inject runtime directive
-	        // by returning the helper symbol via needRuntime
-	        // the import will replaced a resolveDirective call.
-	        if (!isInvalidType) {
-	            baseResult.needRuntime = context.helper(directiveToUse);
-	        }
-	    }
-	    else {
-	        context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
-	    }
-	    // native vmodel doesn't need the `modelValue` props since they are also
-	    // passed to the runtime as `binding.value`. removing it reduces code size.
-	    baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
-	        p.key.content === 'modelValue'));
-	    return baseResult;
+	const transformModel = (dir, node, context) => {
+	    const baseResult = compilerCore.transformModel(dir, node, context);
+	    // base transform has errors OR component v-model (only need props)
+	    if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
+	        return baseResult;
+	    }
+	    if (dir.arg) {
+	        context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
+	    }
+	    function checkDuplicatedValue() {
+	        const value = compilerCore.findProp(node, 'value');
+	        if (value) {
+	            context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
+	        }
+	    }
+	    const { tag } = node;
+	    const isCustomElement = context.isCustomElement(tag);
+	    if (tag === 'input' ||
+	        tag === 'textarea' ||
+	        tag === 'select' ||
+	        isCustomElement) {
+	        let directiveToUse = V_MODEL_TEXT;
+	        let isInvalidType = false;
+	        if (tag === 'input' || isCustomElement) {
+	            const type = compilerCore.findProp(node, `type`);
+	            if (type) {
+	                if (type.type === 7 /* DIRECTIVE */) {
+	                    // :type="foo"
+	                    directiveToUse = V_MODEL_DYNAMIC;
+	                }
+	                else if (type.value) {
+	                    switch (type.value.content) {
+	                        case 'radio':
+	                            directiveToUse = V_MODEL_RADIO;
+	                            break;
+	                        case 'checkbox':
+	                            directiveToUse = V_MODEL_CHECKBOX;
+	                            break;
+	                        case 'file':
+	                            isInvalidType = true;
+	                            context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
+	                            break;
+	                        default:
+	                            // text type
+	                            checkDuplicatedValue();
+	                            break;
+	                    }
+	                }
+	            }
+	            else if (compilerCore.hasDynamicKeyVBind(node)) {
+	                // element has bindings with dynamic keys, which can possibly contain
+	                // "type".
+	                directiveToUse = V_MODEL_DYNAMIC;
+	            }
+	            else {
+	                // text type
+	                checkDuplicatedValue();
+	            }
+	        }
+	        else if (tag === 'select') {
+	            directiveToUse = V_MODEL_SELECT;
+	        }
+	        else {
+	            // textarea
+	            checkDuplicatedValue();
+	        }
+	        // inject runtime directive
+	        // by returning the helper symbol via needRuntime
+	        // the import will replaced a resolveDirective call.
+	        if (!isInvalidType) {
+	            baseResult.needRuntime = context.helper(directiveToUse);
+	        }
+	    }
+	    else {
+	        context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
+	    }
+	    // native vmodel doesn't need the `modelValue` props since they are also
+	    // passed to the runtime as `binding.value`. removing it reduces code size.
+	    baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
+	        p.key.content === 'modelValue'));
+	    return baseResult;
 	};
 
-	const isEventOptionModifier = /*#__PURE__*/ shared.makeMap(`passive,once,capture`);
-	const isNonKeyModifier = /*#__PURE__*/ shared.makeMap(
-	// event propagation management
-	`stop,prevent,self,` +
-	    // system modifiers + exact
-	    `ctrl,shift,alt,meta,exact,` +
-	    // mouse
-	    `middle`);
-	// left & right could be mouse or key modifiers based on event type
-	const maybeKeyModifier = /*#__PURE__*/ shared.makeMap('left,right');
-	const isKeyboardEvent = /*#__PURE__*/ shared.makeMap(`onkeyup,onkeydown,onkeypress`, true);
-	const resolveModifiers = (key, modifiers, context, loc) => {
-	    const keyModifiers = [];
-	    const nonKeyModifiers = [];
-	    const eventOptionModifiers = [];
-	    for (let i = 0; i < modifiers.length; i++) {
-	        const modifier = modifiers[i];
-	        if (modifier === 'native' &&
-	            compilerCore.checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {
-	            eventOptionModifiers.push(modifier);
-	        }
-	        else if (isEventOptionModifier(modifier)) {
-	            // eventOptionModifiers: modifiers for addEventListener() options,
-	            // e.g. .passive & .capture
-	            eventOptionModifiers.push(modifier);
-	        }
-	        else {
-	            // runtimeModifiers: modifiers that needs runtime guards
-	            if (maybeKeyModifier(modifier)) {
-	                if (compilerCore.isStaticExp(key)) {
-	                    if (isKeyboardEvent(key.content)) {
-	                        keyModifiers.push(modifier);
-	                    }
-	                    else {
-	                        nonKeyModifiers.push(modifier);
-	                    }
-	                }
-	                else {
-	                    keyModifiers.push(modifier);
-	                    nonKeyModifiers.push(modifier);
-	                }
-	            }
-	            else {
-	                if (isNonKeyModifier(modifier)) {
-	                    nonKeyModifiers.push(modifier);
-	                }
-	                else {
-	                    keyModifiers.push(modifier);
-	                }
-	            }
-	        }
-	    }
-	    return {
-	        keyModifiers,
-	        nonKeyModifiers,
-	        eventOptionModifiers
-	    };
-	};
-	const transformClick = (key, event) => {
-	    const isStaticClick = compilerCore.isStaticExp(key) && key.content.toLowerCase() === 'onclick';
-	    return isStaticClick
-	        ? compilerCore.createSimpleExpression(event, true)
-	        : key.type !== 4 /* SIMPLE_EXPRESSION */
-	            ? compilerCore.createCompoundExpression([
-	                `(`,
-	                key,
-	                `) === "onClick" ? "${event}" : (`,
-	                key,
-	                `)`
-	            ])
-	            : key;
-	};
-	const transformOn = (dir, node, context) => {
-	    return compilerCore.transformOn(dir, node, context, baseResult => {
-	        const { modifiers } = dir;
-	        if (!modifiers.length)
-	            return baseResult;
-	        let { key, value: handlerExp } = baseResult.props[0];
-	        const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
-	        // normalize click.right and click.middle since they don't actually fire
-	        if (nonKeyModifiers.includes('right')) {
-	            key = transformClick(key, `onContextmenu`);
-	        }
-	        if (nonKeyModifiers.includes('middle')) {
-	            key = transformClick(key, `onMouseup`);
-	        }
-	        if (nonKeyModifiers.length) {
-	            handlerExp = compilerCore.createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
-	                handlerExp,
-	                JSON.stringify(nonKeyModifiers)
-	            ]);
-	        }
-	        if (keyModifiers.length &&
-	            // if event name is dynamic, always wrap with keys guard
-	            (!compilerCore.isStaticExp(key) || isKeyboardEvent(key.content))) {
-	            handlerExp = compilerCore.createCallExpression(context.helper(V_ON_WITH_KEYS), [
-	                handlerExp,
-	                JSON.stringify(keyModifiers)
-	            ]);
-	        }
-	        if (eventOptionModifiers.length) {
-	            const modifierPostfix = eventOptionModifiers.map(shared.capitalize).join('');
-	            key = compilerCore.isStaticExp(key)
-	                ? compilerCore.createSimpleExpression(`${key.content}${modifierPostfix}`, true)
-	                : compilerCore.createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
-	        }
-	        return {
-	            props: [compilerCore.createObjectProperty(key, handlerExp)]
-	        };
-	    });
+	const isEventOptionModifier = /*#__PURE__*/ shared.makeMap(`passive,once,capture`);
+	const isNonKeyModifier = /*#__PURE__*/ shared.makeMap(
+	// event propagation management
+	`stop,prevent,self,` +
+	    // system modifiers + exact
+	    `ctrl,shift,alt,meta,exact,` +
+	    // mouse
+	    `middle`);
+	// left & right could be mouse or key modifiers based on event type
+	const maybeKeyModifier = /*#__PURE__*/ shared.makeMap('left,right');
+	const isKeyboardEvent = /*#__PURE__*/ shared.makeMap(`onkeyup,onkeydown,onkeypress`, true);
+	const resolveModifiers = (key, modifiers, context, loc) => {
+	    const keyModifiers = [];
+	    const nonKeyModifiers = [];
+	    const eventOptionModifiers = [];
+	    for (let i = 0; i < modifiers.length; i++) {
+	        const modifier = modifiers[i];
+	        if (modifier === 'native' &&
+	            compilerCore.checkCompatEnabled("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {
+	            eventOptionModifiers.push(modifier);
+	        }
+	        else if (isEventOptionModifier(modifier)) {
+	            // eventOptionModifiers: modifiers for addEventListener() options,
+	            // e.g. .passive & .capture
+	            eventOptionModifiers.push(modifier);
+	        }
+	        else {
+	            // runtimeModifiers: modifiers that needs runtime guards
+	            if (maybeKeyModifier(modifier)) {
+	                if (compilerCore.isStaticExp(key)) {
+	                    if (isKeyboardEvent(key.content)) {
+	                        keyModifiers.push(modifier);
+	                    }
+	                    else {
+	                        nonKeyModifiers.push(modifier);
+	                    }
+	                }
+	                else {
+	                    keyModifiers.push(modifier);
+	                    nonKeyModifiers.push(modifier);
+	                }
+	            }
+	            else {
+	                if (isNonKeyModifier(modifier)) {
+	                    nonKeyModifiers.push(modifier);
+	                }
+	                else {
+	                    keyModifiers.push(modifier);
+	                }
+	            }
+	        }
+	    }
+	    return {
+	        keyModifiers,
+	        nonKeyModifiers,
+	        eventOptionModifiers
+	    };
+	};
+	const transformClick = (key, event) => {
+	    const isStaticClick = compilerCore.isStaticExp(key) && key.content.toLowerCase() === 'onclick';
+	    return isStaticClick
+	        ? compilerCore.createSimpleExpression(event, true)
+	        : key.type !== 4 /* SIMPLE_EXPRESSION */
+	            ? compilerCore.createCompoundExpression([
+	                `(`,
+	                key,
+	                `) === "onClick" ? "${event}" : (`,
+	                key,
+	                `)`
+	            ])
+	            : key;
+	};
+	const transformOn = (dir, node, context) => {
+	    return compilerCore.transformOn(dir, node, context, baseResult => {
+	        const { modifiers } = dir;
+	        if (!modifiers.length)
+	            return baseResult;
+	        let { key, value: handlerExp } = baseResult.props[0];
+	        const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
+	        // normalize click.right and click.middle since they don't actually fire
+	        if (nonKeyModifiers.includes('right')) {
+	            key = transformClick(key, `onContextmenu`);
+	        }
+	        if (nonKeyModifiers.includes('middle')) {
+	            key = transformClick(key, `onMouseup`);
+	        }
+	        if (nonKeyModifiers.length) {
+	            handlerExp = compilerCore.createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
+	                handlerExp,
+	                JSON.stringify(nonKeyModifiers)
+	            ]);
+	        }
+	        if (keyModifiers.length &&
+	            // if event name is dynamic, always wrap with keys guard
+	            (!compilerCore.isStaticExp(key) || isKeyboardEvent(key.content))) {
+	            handlerExp = compilerCore.createCallExpression(context.helper(V_ON_WITH_KEYS), [
+	                handlerExp,
+	                JSON.stringify(keyModifiers)
+	            ]);
+	        }
+	        if (eventOptionModifiers.length) {
+	            const modifierPostfix = eventOptionModifiers.map(shared.capitalize).join('');
+	            key = compilerCore.isStaticExp(key)
+	                ? compilerCore.createSimpleExpression(`${key.content}${modifierPostfix}`, true)
+	                : compilerCore.createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
+	        }
+	        return {
+	            props: [compilerCore.createObjectProperty(key, handlerExp)]
+	        };
+	    });
 	};
 
-	const transformShow = (dir, node, context) => {
-	    const { exp, loc } = dir;
-	    if (!exp) {
-	        context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc));
-	    }
-	    return {
-	        props: [],
-	        needRuntime: context.helper(V_SHOW)
-	    };
+	const transformShow = (dir, node, context) => {
+	    const { exp, loc } = dir;
+	    if (!exp) {
+	        context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc));
+	    }
+	    return {
+	        props: [],
+	        needRuntime: context.helper(V_SHOW)
+	    };
 	};
 
-	const transformTransition = (node, context) => {
-	    if (node.type === 1 /* ELEMENT */ &&
-	        node.tagType === 1 /* COMPONENT */) {
-	        const component = context.isBuiltInComponent(node.tag);
-	        if (component === TRANSITION) {
-	            return () => {
-	                if (!node.children.length) {
-	                    return;
-	                }
-	                // warn multiple transition children
-	                if (hasMultipleChildren(node)) {
-	                    context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
-	                        start: node.children[0].loc.start,
-	                        end: node.children[node.children.length - 1].loc.end,
-	                        source: ''
-	                    }));
-	                }
-	                // check if it's s single child w/ v-show
-	                // if yes, inject "persisted: true" to the transition props
-	                const child = node.children[0];
-	                if (child.type === 1 /* ELEMENT */) {
-	                    for (const p of child.props) {
-	                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'show') {
-	                            node.props.push({
-	                                type: 6 /* ATTRIBUTE */,
-	                                name: 'persisted',
-	                                value: undefined,
-	                                loc: node.loc
-	                            });
-	                        }
-	                    }
-	                }
-	            };
-	        }
-	    }
-	};
-	function hasMultipleChildren(node) {
-	    // #1352 filter out potential comment nodes.
-	    const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ &&
-	        !(c.type === 2 /* TEXT */ && !c.content.trim())));
-	    const child = children[0];
-	    return (children.length !== 1 ||
-	        child.type === 11 /* FOR */ ||
-	        (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
+	const transformTransition = (node, context) => {
+	    if (node.type === 1 /* ELEMENT */ &&
+	        node.tagType === 1 /* COMPONENT */) {
+	        const component = context.isBuiltInComponent(node.tag);
+	        if (component === TRANSITION) {
+	            return () => {
+	                if (!node.children.length) {
+	                    return;
+	                }
+	                // warn multiple transition children
+	                if (hasMultipleChildren(node)) {
+	                    context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
+	                        start: node.children[0].loc.start,
+	                        end: node.children[node.children.length - 1].loc.end,
+	                        source: ''
+	                    }));
+	                }
+	                // check if it's s single child w/ v-show
+	                // if yes, inject "persisted: true" to the transition props
+	                const child = node.children[0];
+	                if (child.type === 1 /* ELEMENT */) {
+	                    for (const p of child.props) {
+	                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'show') {
+	                            node.props.push({
+	                                type: 6 /* ATTRIBUTE */,
+	                                name: 'persisted',
+	                                value: undefined,
+	                                loc: node.loc
+	                            });
+	                        }
+	                    }
+	                }
+	            };
+	        }
+	    }
+	};
+	function hasMultipleChildren(node) {
+	    // #1352 filter out potential comment nodes.
+	    const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ &&
+	        !(c.type === 2 /* TEXT */ && !c.content.trim())));
+	    const child = children[0];
+	    return (children.length !== 1 ||
+	        child.type === 11 /* FOR */ ||
+	        (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
 	}
 
-	/**
-	 * This module is Node-only.
-	 */
-	/**
-	 * Regex for replacing placeholders for embedded constant variables
-	 * (e.g. import URL string constants generated by compiler-sfc)
-	 */
-	const expReplaceRE = /__VUE_EXP_START__(.*?)__VUE_EXP_END__/g;
-	/**
-	 * Turn eligible hoisted static trees into stringified static nodes, e.g.
-	 *
-	 * ```js
-	 * const _hoisted_1 = createStaticVNode(`<div class="foo">bar</div>`)
-	 * ```
-	 *
-	 * A single static vnode can contain stringified content for **multiple**
-	 * consecutive nodes (element and plain text), called a "chunk".
-	 * `@vue/runtime-dom` will create the content via innerHTML in a hidden
-	 * container element and insert all the nodes in place. The call must also
-	 * provide the number of nodes contained in the chunk so that during hydration
-	 * we can know how many nodes the static vnode should adopt.
-	 *
-	 * The optimization scans a children list that contains hoisted nodes, and
-	 * tries to find the largest chunk of consecutive hoisted nodes before running
-	 * into a non-hoisted node or the end of the list. A chunk is then converted
-	 * into a single static vnode and replaces the hoisted expression of the first
-	 * node in the chunk. Other nodes in the chunk are considered "merged" and
-	 * therefore removed from both the hoist list and the children array.
-	 *
-	 * This optimization is only performed in Node.js.
-	 */
-	const stringifyStatic = (children, context, parent) => {
-	    // bail stringification for slot content
-	    if (context.scopes.vSlot > 0) {
-	        return;
-	    }
-	    let nc = 0; // current node count
-	    let ec = 0; // current element with binding count
-	    const currentChunk = [];
-	    const stringifyCurrentChunk = (currentIndex) => {
-	        if (nc >= 20 /* NODE_COUNT */ ||
-	            ec >= 5 /* ELEMENT_WITH_BINDING_COUNT */) {
-	            // combine all currently eligible nodes into a single static vnode call
-	            const staticCall = compilerCore.createCallExpression(context.helper(compilerCore.CREATE_STATIC), [
-	                JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')).replace(expReplaceRE, `" + $1 + "`),
-	                // the 2nd argument indicates the number of DOM nodes this static vnode
-	                // will insert / hydrate
-	                String(currentChunk.length)
-	            ]);
-	            // replace the first node's hoisted expression with the static vnode call
-	            replaceHoist(currentChunk[0], staticCall, context);
-	            if (currentChunk.length > 1) {
-	                for (let i = 1; i < currentChunk.length; i++) {
-	                    // for the merged nodes, set their hoisted expression to null
-	                    replaceHoist(currentChunk[i], null, context);
-	                }
-	                // also remove merged nodes from children
-	                const deleteCount = currentChunk.length - 1;
-	                children.splice(currentIndex - currentChunk.length + 1, deleteCount);
-	                return deleteCount;
-	            }
-	        }
-	        return 0;
-	    };
-	    let i = 0;
-	    for (; i < children.length; i++) {
-	        const child = children[i];
-	        const hoisted = getHoistedNode(child);
-	        if (hoisted) {
-	            // presence of hoisted means child must be a stringifiable node
-	            const node = child;
-	            const result = analyzeNode(node);
-	            if (result) {
-	                // node is stringifiable, record state
-	                nc += result[0];
-	                ec += result[1];
-	                currentChunk.push(node);
-	                continue;
-	            }
-	        }
-	        // we only reach here if we ran into a node that is not stringifiable
-	        // check if currently analyzed nodes meet criteria for stringification.
-	        // adjust iteration index
-	        i -= stringifyCurrentChunk(i);
-	        // reset state
-	        nc = 0;
-	        ec = 0;
-	        currentChunk.length = 0;
-	    }
-	    // in case the last node was also stringifiable
-	    stringifyCurrentChunk(i);
-	};
-	const getHoistedNode = (node) => ((node.type === 1 /* ELEMENT */ && node.tagType === 0 /* ELEMENT */) ||
-	    node.type == 12 /* TEXT_CALL */) &&
-	    node.codegenNode &&
-	    node.codegenNode.type === 4 /* SIMPLE_EXPRESSION */ &&
-	    node.codegenNode.hoisted;
-	const dataAriaRE = /^(data|aria)-/;
-	const isStringifiableAttr = (name, ns) => {
-	    return ((ns === 0 /* HTML */
-	        ? shared.isKnownHtmlAttr(name)
-	        : ns === 1 /* SVG */
-	            ? shared.isKnownSvgAttr(name)
-	            : false) || dataAriaRE.test(name));
-	};
-	const replaceHoist = (node, replacement, context) => {
-	    const hoistToReplace = node.codegenNode.hoisted;
-	    context.hoists[context.hoists.indexOf(hoistToReplace)] = replacement;
-	};
-	const isNonStringifiable = /*#__PURE__*/ shared.makeMap(`caption,thead,tr,th,tbody,td,tfoot,colgroup,col`);
-	/**
-	 * for a hoisted node, analyze it and return:
-	 * - false: bailed (contains non-stringifiable props or runtime constant)
-	 * - [nc, ec] where
-	 *   - nc is the number of nodes inside
-	 *   - ec is the number of element with bindings inside
-	 */
-	function analyzeNode(node) {
-	    if (node.type === 1 /* ELEMENT */ && isNonStringifiable(node.tag)) {
-	        return false;
-	    }
-	    if (node.type === 12 /* TEXT_CALL */) {
-	        return [1, 0];
-	    }
-	    let nc = 1; // node count
-	    let ec = node.props.length > 0 ? 1 : 0; // element w/ binding count
-	    let bailed = false;
-	    const bail = () => {
-	        bailed = true;
-	        return false;
-	    };
-	    // TODO: check for cases where using innerHTML will result in different
-	    // output compared to imperative node insertions.
-	    // probably only need to check for most common case
-	    // i.e. non-phrasing-content tags inside `<p>`
-	    function walk(node) {
-	        for (let i = 0; i < node.props.length; i++) {
-	            const p = node.props[i];
-	            // bail on non-attr bindings
-	            if (p.type === 6 /* ATTRIBUTE */ &&
-	                !isStringifiableAttr(p.name, node.ns)) {
-	                return bail();
-	            }
-	            if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
-	                // bail on non-attr bindings
-	                if (p.arg &&
-	                    (p.arg.type === 8 /* COMPOUND_EXPRESSION */ ||
-	                        (p.arg.isStatic && !isStringifiableAttr(p.arg.content, node.ns)))) {
-	                    return bail();
-	                }
-	                if (p.exp &&
-	                    (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||
-	                        p.exp.constType < 3 /* CAN_STRINGIFY */)) {
-	                    return bail();
-	                }
-	            }
-	        }
-	        for (let i = 0; i < node.children.length; i++) {
-	            nc++;
-	            const child = node.children[i];
-	            if (child.type === 1 /* ELEMENT */) {
-	                if (child.props.length > 0) {
-	                    ec++;
-	                }
-	                walk(child);
-	                if (bailed) {
-	                    return false;
-	                }
-	            }
-	        }
-	        return true;
-	    }
-	    return walk(node) ? [nc, ec] : false;
-	}
-	function stringifyNode(node, context) {
-	    if (shared.isString(node)) {
-	        return node;
-	    }
-	    if (shared.isSymbol(node)) {
-	        return ``;
-	    }
-	    switch (node.type) {
-	        case 1 /* ELEMENT */:
-	            return stringifyElement(node, context);
-	        case 2 /* TEXT */:
-	            return shared.escapeHtml(node.content);
-	        case 3 /* COMMENT */:
-	            return `<!--${shared.escapeHtml(node.content)}-->`;
-	        case 5 /* INTERPOLATION */:
-	            return shared.escapeHtml(shared.toDisplayString(evaluateConstant(node.content)));
-	        case 8 /* COMPOUND_EXPRESSION */:
-	            return shared.escapeHtml(evaluateConstant(node));
-	        case 12 /* TEXT_CALL */:
-	            return stringifyNode(node.content, context);
-	        default:
-	            // static trees will not contain if/for nodes
-	            return '';
-	    }
-	}
-	function stringifyElement(node, context) {
-	    let res = `<${node.tag}`;
-	    let innerHTML = '';
-	    for (let i = 0; i < node.props.length; i++) {
-	        const p = node.props[i];
-	        if (p.type === 6 /* ATTRIBUTE */) {
-	            res += ` ${p.name}`;
-	            if (p.value) {
-	                res += `="${shared.escapeHtml(p.value.content)}"`;
-	            }
-	        }
-	        else if (p.type === 7 /* DIRECTIVE */) {
-	            if (p.name === 'bind') {
-	                const exp = p.exp;
-	                if (exp.content[0] === '_') {
-	                    // internally generated string constant references
-	                    // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
-	                    res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
-	                    continue;
-	                }
-	                // constant v-bind, e.g. :foo="1"
-	                let evaluated = evaluateConstant(exp);
-	                if (evaluated != null) {
-	                    const arg = p.arg && p.arg.content;
-	                    if (arg === 'class') {
-	                        evaluated = shared.normalizeClass(evaluated);
-	                    }
-	                    else if (arg === 'style') {
-	                        evaluated = shared.stringifyStyle(shared.normalizeStyle(evaluated));
-	                    }
-	                    res += ` ${p.arg.content}="${shared.escapeHtml(evaluated)}"`;
-	                }
-	            }
-	            else if (p.name === 'html') {
-	                // #5439 v-html with constant value
-	                // not sure why would anyone do this but it can happen
-	                innerHTML = evaluateConstant(p.exp);
-	            }
-	            else if (p.name === 'text') {
-	                innerHTML = shared.escapeHtml(shared.toDisplayString(evaluateConstant(p.exp)));
-	            }
-	        }
-	    }
-	    if (context.scopeId) {
-	        res += ` ${context.scopeId}`;
-	    }
-	    res += `>`;
-	    if (innerHTML) {
-	        res += innerHTML;
-	    }
-	    else {
-	        for (let i = 0; i < node.children.length; i++) {
-	            res += stringifyNode(node.children[i], context);
-	        }
-	    }
-	    if (!shared.isVoidTag(node.tag)) {
-	        res += `</${node.tag}>`;
-	    }
-	    return res;
-	}
-	// __UNSAFE__
-	// Reason: eval.
-	// It's technically safe to eval because only constant expressions are possible
-	// here, e.g. `{{ 1 }}` or `{{ 'foo' }}`
-	// in addition, constant exps bail on presence of parens so you can't even
-	// run JSFuck in here. But we mark it unsafe for security review purposes.
-	// (see compiler-core/src/transforms/transformExpression)
-	function evaluateConstant(exp) {
-	    if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
-	        return new Function(`return ${exp.content}`)();
-	    }
-	    else {
-	        // compound
-	        let res = ``;
-	        exp.children.forEach(c => {
-	            if (shared.isString(c) || shared.isSymbol(c)) {
-	                return;
-	            }
-	            if (c.type === 2 /* TEXT */) {
-	                res += c.content;
-	            }
-	            else if (c.type === 5 /* INTERPOLATION */) {
-	                res += shared.toDisplayString(evaluateConstant(c.content));
-	            }
-	            else {
-	                res += evaluateConstant(c);
-	            }
-	        });
-	        return res;
-	    }
+	/**
+	 * This module is Node-only.
+	 */
+	/**
+	 * Regex for replacing placeholders for embedded constant variables
+	 * (e.g. import URL string constants generated by compiler-sfc)
+	 */
+	const expReplaceRE = /__VUE_EXP_START__(.*?)__VUE_EXP_END__/g;
+	/**
+	 * Turn eligible hoisted static trees into stringified static nodes, e.g.
+	 *
+	 * ```js
+	 * const _hoisted_1 = createStaticVNode(`<div class="foo">bar</div>`)
+	 * ```
+	 *
+	 * A single static vnode can contain stringified content for **multiple**
+	 * consecutive nodes (element and plain text), called a "chunk".
+	 * `@vue/runtime-dom` will create the content via innerHTML in a hidden
+	 * container element and insert all the nodes in place. The call must also
+	 * provide the number of nodes contained in the chunk so that during hydration
+	 * we can know how many nodes the static vnode should adopt.
+	 *
+	 * The optimization scans a children list that contains hoisted nodes, and
+	 * tries to find the largest chunk of consecutive hoisted nodes before running
+	 * into a non-hoisted node or the end of the list. A chunk is then converted
+	 * into a single static vnode and replaces the hoisted expression of the first
+	 * node in the chunk. Other nodes in the chunk are considered "merged" and
+	 * therefore removed from both the hoist list and the children array.
+	 *
+	 * This optimization is only performed in Node.js.
+	 */
+	const stringifyStatic = (children, context, parent) => {
+	    // bail stringification for slot content
+	    if (context.scopes.vSlot > 0) {
+	        return;
+	    }
+	    let nc = 0; // current node count
+	    let ec = 0; // current element with binding count
+	    const currentChunk = [];
+	    const stringifyCurrentChunk = (currentIndex) => {
+	        if (nc >= 20 /* NODE_COUNT */ ||
+	            ec >= 5 /* ELEMENT_WITH_BINDING_COUNT */) {
+	            // combine all currently eligible nodes into a single static vnode call
+	            const staticCall = compilerCore.createCallExpression(context.helper(compilerCore.CREATE_STATIC), [
+	                JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')).replace(expReplaceRE, `" + $1 + "`),
+	                // the 2nd argument indicates the number of DOM nodes this static vnode
+	                // will insert / hydrate
+	                String(currentChunk.length)
+	            ]);
+	            // replace the first node's hoisted expression with the static vnode call
+	            replaceHoist(currentChunk[0], staticCall, context);
+	            if (currentChunk.length > 1) {
+	                for (let i = 1; i < currentChunk.length; i++) {
+	                    // for the merged nodes, set their hoisted expression to null
+	                    replaceHoist(currentChunk[i], null, context);
+	                }
+	                // also remove merged nodes from children
+	                const deleteCount = currentChunk.length - 1;
+	                children.splice(currentIndex - currentChunk.length + 1, deleteCount);
+	                return deleteCount;
+	            }
+	        }
+	        return 0;
+	    };
+	    let i = 0;
+	    for (; i < children.length; i++) {
+	        const child = children[i];
+	        const hoisted = getHoistedNode(child);
+	        if (hoisted) {
+	            // presence of hoisted means child must be a stringifiable node
+	            const node = child;
+	            const result = analyzeNode(node);
+	            if (result) {
+	                // node is stringifiable, record state
+	                nc += result[0];
+	                ec += result[1];
+	                currentChunk.push(node);
+	                continue;
+	            }
+	        }
+	        // we only reach here if we ran into a node that is not stringifiable
+	        // check if currently analyzed nodes meet criteria for stringification.
+	        // adjust iteration index
+	        i -= stringifyCurrentChunk(i);
+	        // reset state
+	        nc = 0;
+	        ec = 0;
+	        currentChunk.length = 0;
+	    }
+	    // in case the last node was also stringifiable
+	    stringifyCurrentChunk(i);
+	};
+	const getHoistedNode = (node) => ((node.type === 1 /* ELEMENT */ && node.tagType === 0 /* ELEMENT */) ||
+	    node.type == 12 /* TEXT_CALL */) &&
+	    node.codegenNode &&
+	    node.codegenNode.type === 4 /* SIMPLE_EXPRESSION */ &&
+	    node.codegenNode.hoisted;
+	const dataAriaRE = /^(data|aria)-/;
+	const isStringifiableAttr = (name, ns) => {
+	    return ((ns === 0 /* HTML */
+	        ? shared.isKnownHtmlAttr(name)
+	        : ns === 1 /* SVG */
+	            ? shared.isKnownSvgAttr(name)
+	            : false) || dataAriaRE.test(name));
+	};
+	const replaceHoist = (node, replacement, context) => {
+	    const hoistToReplace = node.codegenNode.hoisted;
+	    context.hoists[context.hoists.indexOf(hoistToReplace)] = replacement;
+	};
+	const isNonStringifiable = /*#__PURE__*/ shared.makeMap(`caption,thead,tr,th,tbody,td,tfoot,colgroup,col`);
+	/**
+	 * for a hoisted node, analyze it and return:
+	 * - false: bailed (contains non-stringifiable props or runtime constant)
+	 * - [nc, ec] where
+	 *   - nc is the number of nodes inside
+	 *   - ec is the number of element with bindings inside
+	 */
+	function analyzeNode(node) {
+	    if (node.type === 1 /* ELEMENT */ && isNonStringifiable(node.tag)) {
+	        return false;
+	    }
+	    if (node.type === 12 /* TEXT_CALL */) {
+	        return [1, 0];
+	    }
+	    let nc = 1; // node count
+	    let ec = node.props.length > 0 ? 1 : 0; // element w/ binding count
+	    let bailed = false;
+	    const bail = () => {
+	        bailed = true;
+	        return false;
+	    };
+	    // TODO: check for cases where using innerHTML will result in different
+	    // output compared to imperative node insertions.
+	    // probably only need to check for most common case
+	    // i.e. non-phrasing-content tags inside `<p>`
+	    function walk(node) {
+	        for (let i = 0; i < node.props.length; i++) {
+	            const p = node.props[i];
+	            // bail on non-attr bindings
+	            if (p.type === 6 /* ATTRIBUTE */ &&
+	                !isStringifiableAttr(p.name, node.ns)) {
+	                return bail();
+	            }
+	            if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
+	                // bail on non-attr bindings
+	                if (p.arg &&
+	                    (p.arg.type === 8 /* COMPOUND_EXPRESSION */ ||
+	                        (p.arg.isStatic && !isStringifiableAttr(p.arg.content, node.ns)))) {
+	                    return bail();
+	                }
+	                if (p.exp &&
+	                    (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||
+	                        p.exp.constType < 3 /* CAN_STRINGIFY */)) {
+	                    return bail();
+	                }
+	            }
+	        }
+	        for (let i = 0; i < node.children.length; i++) {
+	            nc++;
+	            const child = node.children[i];
+	            if (child.type === 1 /* ELEMENT */) {
+	                if (child.props.length > 0) {
+	                    ec++;
+	                }
+	                walk(child);
+	                if (bailed) {
+	                    return false;
+	                }
+	            }
+	        }
+	        return true;
+	    }
+	    return walk(node) ? [nc, ec] : false;
+	}
+	function stringifyNode(node, context) {
+	    if (shared.isString(node)) {
+	        return node;
+	    }
+	    if (shared.isSymbol(node)) {
+	        return ``;
+	    }
+	    switch (node.type) {
+	        case 1 /* ELEMENT */:
+	            return stringifyElement(node, context);
+	        case 2 /* TEXT */:
+	            return shared.escapeHtml(node.content);
+	        case 3 /* COMMENT */:
+	            return `<!--${shared.escapeHtml(node.content)}-->`;
+	        case 5 /* INTERPOLATION */:
+	            return shared.escapeHtml(shared.toDisplayString(evaluateConstant(node.content)));
+	        case 8 /* COMPOUND_EXPRESSION */:
+	            return shared.escapeHtml(evaluateConstant(node));
+	        case 12 /* TEXT_CALL */:
+	            return stringifyNode(node.content, context);
+	        default:
+	            // static trees will not contain if/for nodes
+	            return '';
+	    }
+	}
+	function stringifyElement(node, context) {
+	    let res = `<${node.tag}`;
+	    let innerHTML = '';
+	    for (let i = 0; i < node.props.length; i++) {
+	        const p = node.props[i];
+	        if (p.type === 6 /* ATTRIBUTE */) {
+	            res += ` ${p.name}`;
+	            if (p.value) {
+	                res += `="${shared.escapeHtml(p.value.content)}"`;
+	            }
+	        }
+	        else if (p.type === 7 /* DIRECTIVE */) {
+	            if (p.name === 'bind') {
+	                const exp = p.exp;
+	                if (exp.content[0] === '_') {
+	                    // internally generated string constant references
+	                    // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
+	                    res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
+	                    continue;
+	                }
+	                // constant v-bind, e.g. :foo="1"
+	                let evaluated = evaluateConstant(exp);
+	                if (evaluated != null) {
+	                    const arg = p.arg && p.arg.content;
+	                    if (arg === 'class') {
+	                        evaluated = shared.normalizeClass(evaluated);
+	                    }
+	                    else if (arg === 'style') {
+	                        evaluated = shared.stringifyStyle(shared.normalizeStyle(evaluated));
+	                    }
+	                    res += ` ${p.arg.content}="${shared.escapeHtml(evaluated)}"`;
+	                }
+	            }
+	            else if (p.name === 'html') {
+	                // #5439 v-html with constant value
+	                // not sure why would anyone do this but it can happen
+	                innerHTML = evaluateConstant(p.exp);
+	            }
+	            else if (p.name === 'text') {
+	                innerHTML = shared.escapeHtml(shared.toDisplayString(evaluateConstant(p.exp)));
+	            }
+	        }
+	    }
+	    if (context.scopeId) {
+	        res += ` ${context.scopeId}`;
+	    }
+	    res += `>`;
+	    if (innerHTML) {
+	        res += innerHTML;
+	    }
+	    else {
+	        for (let i = 0; i < node.children.length; i++) {
+	            res += stringifyNode(node.children[i], context);
+	        }
+	    }
+	    if (!shared.isVoidTag(node.tag)) {
+	        res += `</${node.tag}>`;
+	    }
+	    return res;
+	}
+	// __UNSAFE__
+	// Reason: eval.
+	// It's technically safe to eval because only constant expressions are possible
+	// here, e.g. `{{ 1 }}` or `{{ 'foo' }}`
+	// in addition, constant exps bail on presence of parens so you can't even
+	// run JSFuck in here. But we mark it unsafe for security review purposes.
+	// (see compiler-core/src/transforms/transformExpression)
+	function evaluateConstant(exp) {
+	    if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
+	        return new Function(`return ${exp.content}`)();
+	    }
+	    else {
+	        // compound
+	        let res = ``;
+	        exp.children.forEach(c => {
+	            if (shared.isString(c) || shared.isSymbol(c)) {
+	                return;
+	            }
+	            if (c.type === 2 /* TEXT */) {
+	                res += c.content;
+	            }
+	            else if (c.type === 5 /* INTERPOLATION */) {
+	                res += shared.toDisplayString(evaluateConstant(c.content));
+	            }
+	            else {
+	                res += evaluateConstant(c);
+	            }
+	        });
+	        return res;
+	    }
 	}
 
-	const ignoreSideEffectTags = (node, context) => {
-	    if (node.type === 1 /* ELEMENT */ &&
-	        node.tagType === 0 /* ELEMENT */ &&
-	        (node.tag === 'script' || node.tag === 'style')) {
-	        context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
-	        context.removeNode();
-	    }
+	const ignoreSideEffectTags = (node, context) => {
+	    if (node.type === 1 /* ELEMENT */ &&
+	        node.tagType === 0 /* ELEMENT */ &&
+	        (node.tag === 'script' || node.tag === 'style')) {
+	        context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
+	        context.removeNode();
+	    }
 	};
 
-	const DOMNodeTransforms = [
-	    transformStyle,
-	    ...([transformTransition] )
-	];
-	const DOMDirectiveTransforms = {
-	    cloak: compilerCore.noopDirectiveTransform,
-	    html: transformVHtml,
-	    text: transformVText,
-	    model: transformModel,
-	    on: transformOn,
-	    show: transformShow
-	};
-	function compile(template, options = {}) {
-	    return compilerCore.baseCompile(template, shared.extend({}, parserOptions, options, {
-	        nodeTransforms: [
-	            // ignore <script> and <tag>
-	            // this is not put inside DOMNodeTransforms because that list is used
-	            // by compiler-ssr to generate vnode fallback branches
-	            ignoreSideEffectTags,
-	            ...DOMNodeTransforms,
-	            ...(options.nodeTransforms || [])
-	        ],
-	        directiveTransforms: shared.extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
-	        transformHoist: stringifyStatic
-	    }));
-	}
-	function parse(template, options = {}) {
-	    return compilerCore.baseParse(template, shared.extend({}, parserOptions, options));
+	const DOMNodeTransforms = [
+	    transformStyle,
+	    ...([transformTransition] )
+	];
+	const DOMDirectiveTransforms = {
+	    cloak: compilerCore.noopDirectiveTransform,
+	    html: transformVHtml,
+	    text: transformVText,
+	    model: transformModel,
+	    on: transformOn,
+	    show: transformShow
+	};
+	function compile(template, options = {}) {
+	    return compilerCore.baseCompile(template, shared.extend({}, parserOptions, options, {
+	        nodeTransforms: [
+	            // ignore <script> and <tag>
+	            // this is not put inside DOMNodeTransforms because that list is used
+	            // by compiler-ssr to generate vnode fallback branches
+	            ignoreSideEffectTags,
+	            ...DOMNodeTransforms,
+	            ...(options.nodeTransforms || [])
+	        ],
+	        directiveTransforms: shared.extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
+	        transformHoist: stringifyStatic
+	    }));
+	}
+	function parse(template, options = {}) {
+	    return compilerCore.baseParse(template, shared.extend({}, parserOptions, options));
 	}
 
 	Object.keys(compilerCore).forEach(function (k) {
diff --git a/webui/node_modules/vite/dist/node/index.d.ts b/webui/node_modules/vite/dist/node/index.d.ts
index fbf9b6d..573567e 100644
--- a/webui/node_modules/vite/dist/node/index.d.ts
+++ b/webui/node_modules/vite/dist/node/index.d.ts
@@ -1,3292 +1,3292 @@
-/// <reference types="node" />
-
-import type { Agent } from 'node:http';
-import type { BuildOptions as BuildOptions_2 } from 'esbuild';
-import type { ClientRequest } from 'node:http';
-import type { ClientRequestArgs } from 'node:http';
-import type { CustomPluginOptions } from 'rollup';
-import type { Duplex } from 'node:stream';
-import type { DuplexOptions } from 'node:stream';
-import { TransformOptions as EsbuildTransformOptions } from 'esbuild';
-import { version as esbuildVersion } from 'esbuild';
-import { EventEmitter } from 'node:events';
-import * as events from 'node:events';
-import type { ExistingRawSourceMap } from 'rollup';
-import type * as fs from 'node:fs';
-import type { GetManualChunk } from 'rollup';
-import * as http from 'node:http';
-import type { IncomingMessage } from 'node:http';
-import type { InputOptions } from 'rollup';
-import type { LoadResult } from 'rollup';
-import type { ModuleFormat } from 'rollup';
-import type { ModuleInfo } from 'rollup';
-import type * as net from 'node:net';
-import type { OutgoingHttpHeaders } from 'node:http';
-import type { OutputBundle } from 'rollup';
-import type { OutputChunk } from 'rollup';
-import type { PartialResolvedId } from 'rollup';
-import type { Plugin as Plugin_3 } from 'rollup';
-import type { PluginContext } from 'rollup';
-import type { PluginHooks } from 'rollup';
-import type * as PostCSS from 'postcss';
-import type { ResolveIdResult } from 'rollup';
-import type { RollupError } from 'rollup';
-import type { RollupOptions } from 'rollup';
-import type { RollupOutput } from 'rollup';
-import { VERSION as rollupVersion } from 'rollup';
-import type { RollupWatcher } from 'rollup';
-import type { SecureContextOptions } from 'node:tls';
-import type { Server } from 'node:http';
-import type { Server as Server_2 } from 'node:https';
-import type { ServerOptions as ServerOptions_2 } from 'node:https';
-import type { ServerResponse } from 'node:http';
-import type { SourceDescription } from 'rollup';
-import type { SourceMap } from 'rollup';
-import type * as stream from 'node:stream';
-import type { TransformPluginContext } from 'rollup';
-import type { TransformResult as TransformResult_2 } from 'rollup';
-import type { TransformResult as TransformResult_3 } from 'esbuild';
-import type * as url from 'node:url';
-import type { URL as URL_2 } from 'node:url';
-import type { WatcherOptions } from 'rollup';
-import type { ZlibOptions } from 'node:zlib';
-
-export declare interface Alias {
-    find: string | RegExp
-    replacement: string
-    /**
-     * Instructs the plugin to use an alternative resolving algorithm,
-     * rather than the Rollup's resolver.
-     * @default null
-     */
-    customResolver?: ResolverFunction | ResolverObject | null
-}
-
-/**
- * Specifies an `Object`, or an `Array` of `Object`,
- * which defines aliases used to replace values in `import` or `require` statements.
- * With either format, the order of the entries is important,
- * in that the first defined rules are applied first.
- *
- * This is passed to \@rollup/plugin-alias as the "entries" field
- * https://github.com/rollup/plugins/tree/master/packages/alias#entries
- */
-export declare type AliasOptions = readonly Alias[] | { [find: string]: string }
-
-export declare type AnymatchFn = (testString: string) => boolean
-
-export declare type AnymatchPattern = string | RegExp | AnymatchFn
-
-/**
- * spa: include SPA fallback middleware and configure sirv with `single: true` in preview
- *
- * mpa: only include non-SPA HTML middlewares
- *
- * custom: don't include HTML middlewares
- */
-export declare type AppType = 'spa' | 'mpa' | 'custom';
-
-export declare interface AwaitWriteFinishOptions {
-    /**
-     * Amount of time in milliseconds for a file size to remain constant before emitting its event.
-     */
-    stabilityThreshold?: number
-
-    /**
-     * File size polling interval.
-     */
-    pollInterval?: number
-}
-
-/**
- * Bundles the app for production.
- * Returns a Promise containing the build result.
- */
-export declare function build(inlineConfig?: InlineConfig): Promise<RollupOutput | RollupOutput[] | RollupWatcher>;
-
-export declare interface BuildOptions {
-    /**
-     * Compatibility transform target. The transform is performed with esbuild
-     * and the lowest supported target is es2015/es6. Note this only handles
-     * syntax transformation and does not cover polyfills (except for dynamic
-     * import)
-     *
-     * Default: 'modules' - Similar to `@babel/preset-env`'s targets.esmodules,
-     * transpile targeting browsers that natively support dynamic es module imports.
-     * https://caniuse.com/es6-module-dynamic-import
-     *
-     * Another special value is 'esnext' - which only performs minimal transpiling
-     * (for minification compat) and assumes native dynamic imports support.
-     *
-     * For custom targets, see https://esbuild.github.io/api/#target and
-     * https://esbuild.github.io/content-types/#javascript for more details.
-     */
-    target?: 'modules' | EsbuildTransformOptions['target'] | false;
-    /**
-     * whether to inject module preload polyfill.
-     * Note: does not apply to library mode.
-     * @default true
-     */
-    polyfillModulePreload?: boolean;
-    /**
-     * Directory relative from `root` where build output will be placed. If the
-     * directory exists, it will be removed before the build.
-     * @default 'dist'
-     */
-    outDir?: string;
-    /**
-     * Directory relative from `outDir` where the built js/css/image assets will
-     * be placed.
-     * @default 'assets'
-     */
-    assetsDir?: string;
-    /**
-     * Static asset files smaller than this number (in bytes) will be inlined as
-     * base64 strings. Default limit is `4096` (4kb). Set to `0` to disable.
-     * @default 4096
-     */
-    assetsInlineLimit?: number;
-    /**
-     * Whether to code-split CSS. When enabled, CSS in async chunks will be
-     * inlined as strings in the chunk and inserted via dynamically created
-     * style tags when the chunk is loaded.
-     * @default true
-     */
-    cssCodeSplit?: boolean;
-    /**
-     * An optional separate target for CSS minification.
-     * As esbuild only supports configuring targets to mainstream
-     * browsers, users may need this option when they are targeting
-     * a niche browser that comes with most modern JavaScript features
-     * but has poor CSS support, e.g. Android WeChat WebView, which
-     * doesn't support the #RGBA syntax.
-     */
-    cssTarget?: EsbuildTransformOptions['target'] | false;
-    /**
-     * If `true`, a separate sourcemap file will be created. If 'inline', the
-     * sourcemap will be appended to the resulting output file as data URI.
-     * 'hidden' works like `true` except that the corresponding sourcemap
-     * comments in the bundled files are suppressed.
-     * @default false
-     */
-    sourcemap?: boolean | 'inline' | 'hidden';
-    /**
-     * Set to `false` to disable minification, or specify the minifier to use.
-     * Available options are 'terser' or 'esbuild'.
-     * @default 'esbuild'
-     */
-    minify?: boolean | 'terser' | 'esbuild';
-    /**
-     * Options for terser
-     * https://terser.org/docs/api-reference#minify-options
-     */
-    terserOptions?: Terser.MinifyOptions;
-    /**
-     * Will be merged with internal rollup options.
-     * https://rollupjs.org/guide/en/#big-list-of-options
-     */
-    rollupOptions?: RollupOptions;
-    /**
-     * Options to pass on to `@rollup/plugin-commonjs`
-     */
-    commonjsOptions?: RollupCommonJSOptions;
-    /**
-     * Options to pass on to `@rollup/plugin-dynamic-import-vars`
-     */
-    dynamicImportVarsOptions?: RollupDynamicImportVarsOptions;
-    /**
-     * Whether to write bundle to disk
-     * @default true
-     */
-    write?: boolean;
-    /**
-     * Empty outDir on write.
-     * @default true when outDir is a sub directory of project root
-     */
-    emptyOutDir?: boolean | null;
-    /**
-     * Whether to emit a manifest.json under assets dir to map hash-less filenames
-     * to their hashed versions. Useful when you want to generate your own HTML
-     * instead of using the one generated by Vite.
-     *
-     * Example:
-     *
-     * ```json
-     * {
-     *   "main.js": {
-     *     "file": "main.68fe3fad.js",
-     *     "css": "main.e6b63442.css",
-     *     "imports": [...],
-     *     "dynamicImports": [...]
-     *   }
-     * }
-     * ```
-     * @default false
-     */
-    manifest?: boolean | string;
-    /**
-     * Build in library mode. The value should be the global name of the lib in
-     * UMD mode. This will produce esm + cjs + umd bundle formats with default
-     * configurations that are suitable for distributing libraries.
-     */
-    lib?: LibraryOptions | false;
-    /**
-     * Produce SSR oriented build. Note this requires specifying SSR entry via
-     * `rollupOptions.input`.
-     */
-    ssr?: boolean | string;
-    /**
-     * Generate SSR manifest for determining style links and asset preload
-     * directives in production.
-     */
-    ssrManifest?: boolean | string;
-    /**
-     * Set to false to disable reporting compressed chunk sizes.
-     * Can slightly improve build speed.
-     */
-    reportCompressedSize?: boolean;
-    /**
-     * Adjust chunk size warning limit (in kbs).
-     * @default 500
-     */
-    chunkSizeWarningLimit?: number;
-    /**
-     * Rollup watch options
-     * https://rollupjs.org/guide/en/#watchoptions
-     */
-    watch?: WatcherOptions | null;
-}
-
-export declare interface ChunkMetadata {
-    importedAssets: Set<string>;
-    importedCss: Set<string>;
-}
-
-export declare interface CommonServerOptions {
-    /**
-     * Specify server port. Note if the port is already being used, Vite will
-     * automatically try the next available port so this may not be the actual
-     * port the server ends up listening on.
-     */
-    port?: number;
-    /**
-     * If enabled, vite will exit if specified port is already in use
-     */
-    strictPort?: boolean;
-    /**
-     * Specify which IP addresses the server should listen on.
-     * Set to 0.0.0.0 to listen on all addresses, including LAN and public addresses.
-     */
-    host?: string | boolean;
-    /**
-     * Enable TLS + HTTP/2.
-     * Note: this downgrades to TLS only when the proxy option is also used.
-     */
-    https?: boolean | ServerOptions_2;
-    /**
-     * Open browser window on startup
-     */
-    open?: boolean | string;
-    /**
-     * Configure custom proxy rules for the dev server. Expects an object
-     * of `{ key: options }` pairs.
-     * Uses [`http-proxy`](https://github.com/http-party/node-http-proxy).
-     * Full options [here](https://github.com/http-party/node-http-proxy#options).
-     *
-     * Example `vite.config.js`:
-     * ``` js
-     * module.exports = {
-     *   proxy: {
-     *     // string shorthand
-     *     '/foo': 'http://localhost:4567/foo',
-     *     // with options
-     *     '/api': {
-     *       target: 'http://jsonplaceholder.typicode.com',
-     *       changeOrigin: true,
-     *       rewrite: path => path.replace(/^\/api/, '')
-     *     }
-     *   }
-     * }
-     * ```
-     */
-    proxy?: Record<string, string | ProxyOptions>;
-    /**
-     * Configure CORS for the dev server.
-     * Uses https://github.com/expressjs/cors.
-     * Set to `true` to allow all methods from any origin, or configure separately
-     * using an object.
-     */
-    cors?: CorsOptions | boolean;
-    /**
-     * Specify server response headers.
-     */
-    headers?: OutgoingHttpHeaders;
-}
-
-export declare interface ConfigEnv {
-    command: 'build' | 'serve';
-    mode: string;
-    /**
-     * @experimental
-     */
-    ssrBuild?: boolean;
-}
-
-export declare namespace Connect {
-    export type ServerHandle = HandleFunction | http.Server
-
-    export class IncomingMessage extends http.IncomingMessage {
-        originalUrl?: http.IncomingMessage['url'] | undefined
-    }
-
-    export type NextFunction = (err?: any) => void
-
-    export type SimpleHandleFunction = (
-    req: IncomingMessage,
-    res: http.ServerResponse
-    ) => void
-    export type NextHandleFunction = (
-    req: IncomingMessage,
-    res: http.ServerResponse,
-    next: NextFunction
-    ) => void
-    export type ErrorHandleFunction = (
-    err: any,
-    req: IncomingMessage,
-    res: http.ServerResponse,
-    next: NextFunction
-    ) => void
-    export type HandleFunction =
-    | SimpleHandleFunction
-    | NextHandleFunction
-    | ErrorHandleFunction
-
-    export interface ServerStackItem {
-        route: string
-        handle: ServerHandle
-    }
-
-    export interface Server extends NodeJS.EventEmitter {
-        (req: http.IncomingMessage, res: http.ServerResponse, next?: Function): void
-
-        route: string
-        stack: ServerStackItem[]
-
-        /**
-         * Utilize the given middleware `handle` to the given `route`,
-         * defaulting to _/_. This "route" is the mount-point for the
-         * middleware, when given a value other than _/_ the middleware
-         * is only effective when that segment is present in the request's
-         * pathname.
-         *
-         * For example if we were to mount a function at _/admin_, it would
-         * be invoked on _/admin_, and _/admin/settings_, however it would
-         * not be invoked for _/_, or _/posts_.
-         */
-        use(fn: NextHandleFunction): Server
-        use(fn: HandleFunction): Server
-        use(route: string, fn: NextHandleFunction): Server
-        use(route: string, fn: HandleFunction): Server
-
-        /**
-         * Handle server requests, punting them down
-         * the middleware stack.
-         */
-        handle(
-        req: http.IncomingMessage,
-        res: http.ServerResponse,
-        next: Function
-        ): void
-
-        /**
-         * Listen for connections.
-         *
-         * This method takes the same arguments
-         * as node's `http.Server#listen()`.
-         *
-         * HTTP and HTTPS:
-         *
-         * If you run your application both as HTTP
-         * and HTTPS you may wrap them individually,
-         * since your Connect "server" is really just
-         * a JavaScript `Function`.
-         *
-         *      var connect = require('connect')
-         *        , http = require('http')
-         *        , https = require('https');
-         *
-         *      var app = connect();
-         *
-         *      http.createServer(app).listen(80);
-         *      https.createServer(options, app).listen(443);
-         */
-        listen(
-        port: number,
-        hostname?: string,
-        backlog?: number,
-        callback?: Function
-        ): http.Server
-        listen(port: number, hostname?: string, callback?: Function): http.Server
-        listen(path: string, callback?: Function): http.Server
-        listen(handle: any, listeningListener?: Function): http.Server
-    }
-}
-
-export declare interface ConnectedPayload {
-    type: 'connected'
-}
-
-/**
- * https://github.com/expressjs/cors#configuration-options
- */
-export declare interface CorsOptions {
-    origin?: CorsOrigin | ((origin: string, cb: (err: Error, origins: CorsOrigin) => void) => void);
-    methods?: string | string[];
-    allowedHeaders?: string | string[];
-    exposedHeaders?: string | string[];
-    credentials?: boolean;
-    maxAge?: number;
-    preflightContinue?: boolean;
-    optionsSuccessStatus?: number;
-}
-
-export declare type CorsOrigin = boolean | string | RegExp | (string | RegExp)[];
-
-export declare const createFilter: (include?: FilterPattern | undefined, exclude?: FilterPattern | undefined, options?: {
-    resolve?: string | false | null | undefined;
-} | undefined) => (id: string | unknown) => boolean;
-
-export declare function createLogger(level?: LogLevel, options?: LoggerOptions): Logger;
-
-export declare function createServer(inlineConfig?: InlineConfig): Promise<ViteDevServer>;
-
-export declare interface CSSModulesOptions {
-    getJSON?: (cssFileName: string, json: Record<string, string>, outputFileName: string) => void;
-    scopeBehaviour?: 'global' | 'local';
-    globalModulePaths?: RegExp[];
-    generateScopedName?: string | ((name: string, filename: string, css: string) => string);
-    hashPrefix?: string;
-    /**
-     * default: null
-     */
-    localsConvention?: 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly' | null;
-}
-
-export declare interface CSSOptions {
-    /**
-     * https://github.com/css-modules/postcss-modules
-     */
-    modules?: CSSModulesOptions | false;
-    preprocessorOptions?: Record<string, any>;
-    postcss?: string | (PostCSS.ProcessOptions & {
-        plugins?: PostCSS.AcceptedPlugin[];
-    });
-    /**
-     * Enables css sourcemaps during dev
-     * @default false
-     * @experimental
-     */
-    devSourcemap?: boolean;
-}
-
-export declare interface CustomEventMap {
-    'vite:beforeUpdate': UpdatePayload
-    'vite:beforePrune': PrunePayload
-    'vite:beforeFullReload': FullReloadPayload
-    'vite:error': ErrorPayload
-}
-
-export declare interface CustomPayload {
-    type: 'custom'
-    event: string
-    data?: any
-}
-
-/**
- * Type helper to make it easier to use vite.config.ts
- * accepts a direct {@link UserConfig} object, or a function that returns it.
- * The function receives a {@link ConfigEnv} object that exposes two properties:
- * `command` (either `'build'` or `'serve'`), and `mode`.
- */
-export declare function defineConfig(config: UserConfigExport): UserConfigExport;
-
-export declare interface DepOptimizationConfig {
-    /**
-     * Force optimize listed dependencies (must be resolvable import paths,
-     * cannot be globs).
-     */
-    include?: string[];
-    /**
-     * Do not optimize these dependencies (must be resolvable import paths,
-     * cannot be globs).
-     */
-    exclude?: string[];
-    /**
-     * Force ESM interop when importing for these dependencies. Some legacy
-     * packages advertise themselves as ESM but use `require` internally
-     * @experimental
-     */
-    needsInterop?: string[];
-    /**
-     * Options to pass to esbuild during the dep scanning and optimization
-     *
-     * Certain options are omitted since changing them would not be compatible
-     * with Vite's dep optimization.
-     *
-     * - `external` is also omitted, use Vite's `optimizeDeps.exclude` option
-     * - `plugins` are merged with Vite's dep plugin
-     *
-     * https://esbuild.github.io/api
-     */
-    esbuildOptions?: Omit<BuildOptions_2, 'bundle' | 'entryPoints' | 'external' | 'write' | 'watch' | 'outdir' | 'outfile' | 'outbase' | 'outExtension' | 'metafile'>;
-    /**
-     * List of file extensions that can be optimized. A corresponding esbuild
-     * plugin must exist to handle the specific extension.
-     *
-     * By default, Vite can optimize `.mjs`, `.js`, `.ts`, and `.mts` files. This option
-     * allows specifying additional extensions.
-     *
-     * @experimental
-     */
-    extensions?: string[];
-    /**
-     * Disables dependencies optimizations, true disables the optimizer during
-     * build and dev. Pass 'build' or 'dev' to only disable the optimizer in
-     * one of the modes. Deps optimization is enabled by default in dev only.
-     * @default 'build'
-     * @experimental
-     */
-    disabled?: boolean | 'build' | 'dev';
-}
-
-export declare interface DepOptimizationMetadata {
-    /**
-     * The main hash is determined by user config and dependency lockfiles.
-     * This is checked on server startup to avoid unnecessary re-bundles.
-     */
-    hash: string;
-    /**
-     * The browser hash is determined by the main hash plus additional dependencies
-     * discovered at runtime. This is used to invalidate browser requests to
-     * optimized deps.
-     */
-    browserHash: string;
-    /**
-     * Metadata for each already optimized dependency
-     */
-    optimized: Record<string, OptimizedDepInfo>;
-    /**
-     * Metadata for non-entry optimized chunks and dynamic imports
-     */
-    chunks: Record<string, OptimizedDepInfo>;
-    /**
-     * Metadata for each newly discovered dependency after processing
-     */
-    discovered: Record<string, OptimizedDepInfo>;
-    /**
-     * OptimizedDepInfo list
-     */
-    depInfoList: OptimizedDepInfo[];
-}
-
-export declare type DepOptimizationOptions = DepOptimizationConfig & {
-    /**
-     * By default, Vite will crawl your `index.html` to detect dependencies that
-     * need to be pre-bundled. If `build.rollupOptions.input` is specified, Vite
-     * will crawl those entry points instead.
-     *
-     * If neither of these fit your needs, you can specify custom entries using
-     * this option - the value should be a fast-glob pattern or array of patterns
-     * (https://github.com/mrmlnc/fast-glob#basic-syntax) that are relative from
-     * vite project root. This will overwrite default entries inference.
-     */
-    entries?: string | string[];
-    /**
-     * Force dep pre-optimization regardless of whether deps have changed.
-     * @experimental
-     */
-    force?: boolean;
-};
-
-export declare interface DepOptimizationProcessing {
-    promise: Promise<void>;
-    resolve: () => void;
-}
-
-export declare interface DepOptimizationResult {
-    metadata: DepOptimizationMetadata;
-    /**
-     * When doing a re-run, if there are newly discovered dependencies
-     * the page reload will be delayed until the next rerun so we need
-     * to be able to discard the result
-     */
-    commit: () => Promise<void>;
-    cancel: () => void;
-}
-
-export declare interface DepsOptimizer {
-    metadata: DepOptimizationMetadata;
-    scanProcessing?: Promise<void>;
-    registerMissingImport: (id: string, resolved: string) => OptimizedDepInfo;
-    run: () => void;
-    isOptimizedDepFile: (id: string) => boolean;
-    isOptimizedDepUrl: (url: string) => boolean;
-    getOptimizedDepId: (depInfo: OptimizedDepInfo) => string;
-    delayDepsOptimizerUntil: (id: string, done: () => Promise<any>) => void;
-    registerWorkersSource: (id: string) => void;
-    resetRegisteredIds: () => void;
-    ensureFirstRun: () => void;
-    options: DepOptimizationOptions;
-}
-
-export declare interface ErrorPayload {
-    type: 'error'
-    err: {
-        [name: string]: any
-        message: string
-        stack: string
-        id?: string
-        frame?: string
-        plugin?: string
-        pluginCode?: string
-        loc?: {
-            file?: string
-            line: number
-            column: number
-        }
-    }
-}
-
-export declare interface ESBuildOptions extends EsbuildTransformOptions {
-    include?: string | RegExp | string[] | RegExp[];
-    exclude?: string | RegExp | string[] | RegExp[];
-    jsxInject?: string;
-    /**
-     * This option is not respected. Use `build.minify` instead.
-     */
-    minify?: never;
-}
-
-export { EsbuildTransformOptions }
-
-export declare type ESBuildTransformResult = Omit<TransformResult_3, 'map'> & {
-    map: SourceMap;
-};
-
-export { esbuildVersion }
-
-export declare interface ExperimentalOptions {
-    /**
-     * Append fake `&lang.(ext)` when queries are specified, to preserve the file extension for following plugins to process.
-     *
-     * @experimental
-     * @default false
-     */
-    importGlobRestoreExtension?: boolean;
-    /**
-     * Allow finegrain control over assets and public files paths
-     *
-     * @experimental
-     */
-    renderBuiltUrl?: RenderBuiltAssetUrl;
-    /**
-     * Enables support of HMR partial accept via `import.meta.hot.acceptExports`.
-     *
-     * @experimental
-     * @default false
-     */
-    hmrPartialAccept?: boolean;
-}
-
-export declare type ExportsData = {
-    hasImports: boolean;
-    exports: readonly string[];
-    facade: boolean;
-    hasReExports?: boolean;
-    jsxLoader?: boolean;
-};
-
-export declare interface FileSystemServeOptions {
-    /**
-     * Strictly restrict file accessing outside of allowing paths.
-     *
-     * Set to `false` to disable the warning
-     *
-     * @default true
-     */
-    strict?: boolean;
-    /**
-     * Restrict accessing files outside the allowed directories.
-     *
-     * Accepts absolute path or a path relative to project root.
-     * Will try to search up for workspace root by default.
-     */
-    allow?: string[];
-    /**
-     * Restrict accessing files that matches the patterns.
-     *
-     * This will have higher priority than `allow`.
-     * Glob patterns are supported.
-     *
-     * @default ['.env', '.env.*', '*.crt', '*.pem']
-     */
-    deny?: string[];
-}
-
-/**
- * Inlined to keep `@rollup/pluginutils` in devDependencies
- */
-export declare type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;
-
-export declare function formatPostcssSourceMap(rawMap: ExistingRawSourceMap, file: string): Promise<ExistingRawSourceMap>;
-
-export declare class FSWatcher extends EventEmitter implements fs.FSWatcher {
-    options: WatchOptions
-
-    /**
-     * Constructs a new FSWatcher instance with optional WatchOptions parameter.
-     */
-    constructor(options?: WatchOptions)
-
-    /**
-     * Add files, directories, or glob patterns for tracking. Takes an array of strings or just one
-     * string.
-     */
-    add(paths: string | ReadonlyArray<string>): this
-
-    /**
-     * Stop watching files, directories, or glob patterns. Takes an array of strings or just one
-     * string.
-     */
-    unwatch(paths: string | ReadonlyArray<string>): this
-
-    /**
-     * Returns an object representing all the paths on the file system being watched by this
-     * `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless
-     * the `cwd` option was used), and the values are arrays of the names of the items contained in
-     * each directory.
-     */
-    getWatched(): {
-        [directory: string]: string[]
-    }
-
-    /**
-     * Removes all listeners from watched files.
-     */
-    close(): Promise<void>
-
-    on(
-    event: 'add' | 'addDir' | 'change',
-    listener: (path: string, stats?: fs.Stats) => void
-    ): this
-
-    on(
-    event: 'all',
-    listener: (
-    eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir',
-    path: string,
-    stats?: fs.Stats
-    ) => void
-    ): this
-
-    /**
-     * Error occurred
-     */
-    on(event: 'error', listener: (error: Error) => void): this
-
-    /**
-     * Exposes the native Node `fs.FSWatcher events`
-     */
-    on(
-    event: 'raw',
-    listener: (eventName: string, path: string, details: any) => void
-    ): this
-
-    /**
-     * Fires when the initial scan is complete
-     */
-    on(event: 'ready', listener: () => void): this
-
-    on(event: 'unlink' | 'unlinkDir', listener: (path: string) => void): this
-
-    on(event: string, listener: (...args: any[]) => void): this
-}
-
-export declare interface FullReloadPayload {
-    type: 'full-reload'
-    path?: string
-}
-
-export declare function getDepOptimizationConfig(config: ResolvedConfig, ssr: boolean): DepOptimizationConfig;
-
-export declare interface HmrContext {
-    file: string;
-    timestamp: number;
-    modules: Array<ModuleNode>;
-    read: () => string | Promise<string>;
-    server: ViteDevServer;
-}
-
-export declare interface HmrOptions {
-    protocol?: string;
-    host?: string;
-    port?: number;
-    clientPort?: number;
-    path?: string;
-    timeout?: number;
-    overlay?: boolean;
-    server?: Server;
-}
-
-export declare type HMRPayload =
-| ConnectedPayload
-| UpdatePayload
-| FullReloadPayload
-| CustomPayload
-| ErrorPayload
-| PrunePayload
-
-export declare interface HtmlTagDescriptor {
-    tag: string;
-    attrs?: Record<string, string | boolean | undefined>;
-    children?: string | HtmlTagDescriptor[];
-    /**
-     * default: 'head-prepend'
-     */
-    injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend';
-}
-
-export declare namespace HttpProxy {
-    export type ProxyTarget = ProxyTargetUrl | ProxyTargetDetailed
-
-    export type ProxyTargetUrl = string | Partial<url.Url>
-
-    export interface ProxyTargetDetailed {
-        host: string
-        port: number
-        protocol?: string | undefined
-        hostname?: string | undefined
-        socketPath?: string | undefined
-        key?: string | undefined
-        passphrase?: string | undefined
-        pfx?: Buffer | string | undefined
-        cert?: string | undefined
-        ca?: string | undefined
-        ciphers?: string | undefined
-        secureProtocol?: string | undefined
-    }
-
-    export type ErrorCallback = (
-    err: Error,
-    req: http.IncomingMessage,
-    res: http.ServerResponse,
-    target?: ProxyTargetUrl
-    ) => void
-
-    export class Server extends events.EventEmitter {
-        /**
-         * Creates the proxy server with specified options.
-         * @param options - Config object passed to the proxy
-         */
-        constructor(options?: ServerOptions)
-
-        /**
-         * Used for proxying regular HTTP(S) requests
-         * @param req - Client request.
-         * @param res - Client response.
-         * @param options - Additional options.
-         */
-        web(
-        req: http.IncomingMessage,
-        res: http.ServerResponse,
-        options?: ServerOptions,
-        callback?: ErrorCallback
-        ): void
-
-        /**
-         * Used for proxying regular HTTP(S) requests
-         * @param req - Client request.
-         * @param socket - Client socket.
-         * @param head - Client head.
-         * @param options - Additional options.
-         */
-        ws(
-        req: http.IncomingMessage,
-        socket: unknown,
-        head: unknown,
-        options?: ServerOptions,
-        callback?: ErrorCallback
-        ): void
-
-        /**
-         * A function that wraps the object in a webserver, for your convenience
-         * @param port - Port to listen on
-         */
-        listen(port: number): Server
-
-        /**
-         * A function that closes the inner webserver and stops listening on given port
-         */
-        close(callback?: () => void): void
-
-        /**
-         * Creates the proxy server with specified options.
-         * @param options - Config object passed to the proxy
-         * @returns Proxy object with handlers for `ws` and `web` requests
-         */
-        static createProxyServer(options?: ServerOptions): Server
-
-        /**
-         * Creates the proxy server with specified options.
-         * @param options - Config object passed to the proxy
-         * @returns Proxy object with handlers for `ws` and `web` requests
-         */
-        static createServer(options?: ServerOptions): Server
-
-        /**
-         * Creates the proxy server with specified options.
-         * @param options - Config object passed to the proxy
-         * @returns Proxy object with handlers for `ws` and `web` requests
-         */
-        static createProxy(options?: ServerOptions): Server
-
-        addListener(event: string, listener: () => void): this
-        on(event: string, listener: () => void): this
-        on(event: 'error', listener: ErrorCallback): this
-        on(
-        event: 'start',
-        listener: (
-        req: http.IncomingMessage,
-        res: http.ServerResponse,
-        target: ProxyTargetUrl
-        ) => void
-        ): this
-        on(
-        event: 'proxyReq',
-        listener: (
-        proxyReq: http.ClientRequest,
-        req: http.IncomingMessage,
-        res: http.ServerResponse,
-        options: ServerOptions
-        ) => void
-        ): this
-        on(
-        event: 'proxyRes',
-        listener: (
-        proxyRes: http.IncomingMessage,
-        req: http.IncomingMessage,
-        res: http.ServerResponse
-        ) => void
-        ): this
-        on(
-        event: 'proxyReqWs',
-        listener: (
-        proxyReq: http.ClientRequest,
-        req: http.IncomingMessage,
-        socket: net.Socket,
-        options: ServerOptions,
-        head: any
-        ) => void
-        ): this
-        on(
-        event: 'econnreset',
-        listener: (
-        err: Error,
-        req: http.IncomingMessage,
-        res: http.ServerResponse,
-        target: ProxyTargetUrl
-        ) => void
-        ): this
-        on(
-        event: 'end',
-        listener: (
-        req: http.IncomingMessage,
-        res: http.ServerResponse,
-        proxyRes: http.IncomingMessage
-        ) => void
-        ): this
-        on(
-        event: 'close',
-        listener: (
-        proxyRes: http.IncomingMessage,
-        proxySocket: net.Socket,
-        proxyHead: any
-        ) => void
-        ): this
-
-        once(event: string, listener: () => void): this
-        removeListener(event: string, listener: () => void): this
-        removeAllListeners(event?: string): this
-        getMaxListeners(): number
-        setMaxListeners(n: number): this
-        listeners(event: string): Array<() => void>
-        emit(event: string, ...args: any[]): boolean
-        listenerCount(type: string): number
-    }
-
-    export interface ServerOptions {
-        /** URL string to be parsed with the url module. */
-        target?: ProxyTarget | undefined
-        /** URL string to be parsed with the url module. */
-        forward?: ProxyTargetUrl | undefined
-        /** Object to be passed to http(s).request. */
-        agent?: any
-        /** Object to be passed to https.createServer(). */
-        ssl?: any
-        /** If you want to proxy websockets. */
-        ws?: boolean | undefined
-        /** Adds x- forward headers. */
-        xfwd?: boolean | undefined
-        /** Verify SSL certificate. */
-        secure?: boolean | undefined
-        /** Explicitly specify if we are proxying to another proxy. */
-        toProxy?: boolean | undefined
-        /** Specify whether you want to prepend the target's path to the proxy path. */
-        prependPath?: boolean | undefined
-        /** Specify whether you want to ignore the proxy path of the incoming request. */
-        ignorePath?: boolean | undefined
-        /** Local interface string to bind for outgoing connections. */
-        localAddress?: string | undefined
-        /** Changes the origin of the host header to the target URL. */
-        changeOrigin?: boolean | undefined
-        /** specify whether you want to keep letter case of response header key */
-        preserveHeaderKeyCase?: boolean | undefined
-        /** Basic authentication i.e. 'user:password' to compute an Authorization header. */
-        auth?: string | undefined
-        /** Rewrites the location hostname on (301 / 302 / 307 / 308) redirects, Default: null. */
-        hostRewrite?: string | undefined
-        /** Rewrites the location host/ port on (301 / 302 / 307 / 308) redirects based on requested host/ port.Default: false. */
-        autoRewrite?: boolean | undefined
-        /** Rewrites the location protocol on (301 / 302 / 307 / 308) redirects to 'http' or 'https'.Default: null. */
-        protocolRewrite?: string | undefined
-        /** rewrites domain of set-cookie headers. */
-        cookieDomainRewrite?:
-        | false
-        | string
-        | { [oldDomain: string]: string }
-        | undefined
-        /** rewrites path of set-cookie headers. Default: false */
-        cookiePathRewrite?:
-        | false
-        | string
-        | { [oldPath: string]: string }
-        | undefined
-        /** object with extra headers to be added to target requests. */
-        headers?: { [header: string]: string } | undefined
-        /** Timeout (in milliseconds) when proxy receives no response from target. Default: 120000 (2 minutes) */
-        proxyTimeout?: number | undefined
-        /** Timeout (in milliseconds) for incoming requests */
-        timeout?: number | undefined
-        /** Specify whether you want to follow redirects. Default: false */
-        followRedirects?: boolean | undefined
-        /** If set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event */
-        selfHandleResponse?: boolean | undefined
-        /** Buffer */
-        buffer?: stream.Stream | undefined
-    }
-}
-
-export declare interface ImportGlobEagerFunction {
-    /**
-     * Eagerly import a list of files with a glob pattern.
-     *
-     * Overload 1: No generic provided, infer the type from `as`
-     */
-    <
-    As extends string,
-    T = As extends keyof KnownAsTypeMap ? KnownAsTypeMap[As] : unknown
-    >(
-    glob: string | string[],
-    options?: Omit<ImportGlobOptions<boolean, As>, 'eager'>
-    ): Record<string, T>
-    /**
-     * Eagerly import a list of files with a glob pattern.
-     *
-     * Overload 2: Module generic provided
-     */
-    <M>(
-    glob: string | string[],
-    options?: Omit<ImportGlobOptions<boolean, string>, 'eager'>
-    ): Record<string, M>
-}
-
-export declare interface ImportGlobFunction {
-    /**
-     * Import a list of files with a glob pattern.
-     *
-     * Overload 1: No generic provided, infer the type from `eager` and `as`
-     */
-    <
-    Eager extends boolean,
-    As extends string,
-    T = As extends keyof KnownAsTypeMap ? KnownAsTypeMap[As] : unknown
-    >(
-    glob: string | string[],
-    options?: ImportGlobOptions<Eager, As>
-    ): (Eager extends true ? true : false) extends true
-    ? Record<string, T>
-    : Record<string, () => Promise<T>>
-    /**
-     * Import a list of files with a glob pattern.
-     *
-     * Overload 2: Module generic provided, infer the type from `eager: false`
-     */
-    <M>(
-    glob: string | string[],
-    options?: ImportGlobOptions<false, string>
-    ): Record<string, () => Promise<M>>
-    /**
-     * Import a list of files with a glob pattern.
-     *
-     * Overload 3: Module generic provided, infer the type from `eager: true`
-     */
-    <M>(
-    glob: string | string[],
-    options: ImportGlobOptions<true, string>
-    ): Record<string, M>
-}
-
-export declare interface ImportGlobOptions<
-Eager extends boolean,
-AsType extends string
-> {
-    /**
-     * Import type for the import url.
-     */
-    as?: AsType
-    /**
-     * Import as static or dynamic
-     *
-     * @default false
-     */
-    eager?: Eager
-    /**
-     * Import only the specific named export. Set to `default` to import the default export.
-     */
-    import?: string
-    /**
-     * Custom queries
-     */
-    query?: string | Record<string, string | number | boolean>
-    /**
-     * Search files also inside `node_modules/` and hidden directories (e.g. `.git/`). This might have impact on performance.
-     *
-     * @default false
-     */
-    exhaustive?: boolean
-}
-
-export declare type IndexHtmlTransform = IndexHtmlTransformHook | {
-    enforce?: 'pre' | 'post';
-    transform: IndexHtmlTransformHook;
-};
-
-export declare interface IndexHtmlTransformContext {
-    /**
-     * public path when served
-     */
-    path: string;
-    /**
-     * filename on disk
-     */
-    filename: string;
-    server?: ViteDevServer;
-    bundle?: OutputBundle;
-    chunk?: OutputChunk;
-    originalUrl?: string;
-}
-
-export declare type IndexHtmlTransformHook = (html: string, ctx: IndexHtmlTransformContext) => IndexHtmlTransformResult | void | Promise<IndexHtmlTransformResult | void>;
-
-export declare type IndexHtmlTransformResult = string | HtmlTagDescriptor[] | {
-    html: string;
-    tags: HtmlTagDescriptor[];
-};
-
-export declare type InferCustomEventPayload<T extends string> =
-T extends keyof CustomEventMap ? CustomEventMap[T] : any
-
-export declare interface InlineConfig extends UserConfig {
-    configFile?: string | false;
-    envFile?: false;
-}
-
-export declare interface InternalResolveOptions extends ResolveOptions {
-    root: string;
-    isBuild: boolean;
-    isProduction: boolean;
-    ssrConfig?: SSROptions;
-    packageCache?: PackageCache;
-    /**
-     * src code mode also attempts the following:
-     * - resolving /xxx as URLs
-     * - resolving bare imports from optimized deps
-     */
-    asSrc?: boolean;
-    tryIndex?: boolean;
-    tryPrefix?: string;
-    skipPackageJson?: boolean;
-    preferRelative?: boolean;
-    preserveSymlinks?: boolean;
-    isRequire?: boolean;
-    isFromTsImporter?: boolean;
-    tryEsmOnly?: boolean;
-    scan?: boolean;
-    ssrOptimizeCheck?: boolean;
-    getDepsOptimizer?: (ssr: boolean) => DepsOptimizer | undefined;
-    shouldExternalize?: (id: string) => boolean | undefined;
-}
-
-export declare function isDepsOptimizerEnabled(config: ResolvedConfig, ssr: boolean): boolean;
-
-export declare interface JsonOptions {
-    /**
-     * Generate a named export for every property of the JSON object
-     * @default true
-     */
-    namedExports?: boolean;
-    /**
-     * Generate performant output as JSON.parse("stringified").
-     * Enabling this will disable namedExports.
-     * @default false
-     */
-    stringify?: boolean;
-}
-
-export declare interface KnownAsTypeMap {
-    raw: string
-    url: string
-    worker: Worker
-}
-
-export declare interface LegacyOptions {
-    /**
-     * Revert vite build --ssr to the v2.9 strategy. Use CJS SSR build and v2.9 externalization heuristics
-     *
-     * @experimental
-     * @deprecated
-     * @default false
-     */
-    buildSsrCjsExternalHeuristics?: boolean;
-}
-
-export declare type LibraryFormats = 'es' | 'cjs' | 'umd' | 'iife';
-
-export declare interface LibraryOptions {
-    /**
-     * Path of library entry
-     */
-    entry: string;
-    /**
-     * The name of the exposed global variable. Required when the `formats` option includes
-     * `umd` or `iife`
-     */
-    name?: string;
-    /**
-     * Output bundle formats
-     * @default ['es', 'umd']
-     */
-    formats?: LibraryFormats[];
-    /**
-     * The name of the package file output. The default file name is the name option
-     * of the project package.json. It can also be defined as a function taking the
-     * format as an argument.
-     */
-    fileName?: string | ((format: ModuleFormat) => string);
-}
-
-export declare function loadConfigFromFile(configEnv: ConfigEnv, configFile?: string, configRoot?: string, logLevel?: LogLevel): Promise<{
-    path: string;
-    config: UserConfig;
-    dependencies: string[];
-} | null>;
-
-export declare function loadEnv(mode: string, envDir: string, prefixes?: string | string[]): Record<string, string>;
-
-export declare interface LogErrorOptions extends LogOptions {
-    error?: Error | RollupError | null;
-}
-
-export declare interface Logger {
-    info(msg: string, options?: LogOptions): void;
-    warn(msg: string, options?: LogOptions): void;
-    warnOnce(msg: string, options?: LogOptions): void;
-    error(msg: string, options?: LogErrorOptions): void;
-    clearScreen(type: LogType): void;
-    hasErrorLogged(error: Error | RollupError): boolean;
-    hasWarned: boolean;
-}
-
-export declare interface LoggerOptions {
-    prefix?: string;
-    allowClearScreen?: boolean;
-    customLogger?: Logger;
-}
-
-export declare type LogLevel = LogType | 'silent';
-
-export declare interface LogOptions {
-    clear?: boolean;
-    timestamp?: boolean;
-}
-
-export declare type LogType = 'error' | 'warn' | 'info';
-
-export declare type Manifest = Record<string, ManifestChunk>;
-
-export declare interface ManifestChunk {
-    src?: string;
-    file: string;
-    css?: string[];
-    assets?: string[];
-    isEntry?: boolean;
-    isDynamicEntry?: boolean;
-    imports?: string[];
-    dynamicImports?: string[];
-}
-
-export declare type Matcher = AnymatchPattern | AnymatchPattern[]
-
-export declare function mergeAlias(a?: AliasOptions, b?: AliasOptions): AliasOptions | undefined;
-
-export declare function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot?: boolean): Record<string, any>;
-
-export declare class ModuleGraph {
-    private resolveId;
-    urlToModuleMap: Map<string, ModuleNode>;
-    idToModuleMap: Map<string, ModuleNode>;
-    fileToModulesMap: Map<string, Set<ModuleNode>>;
-    safeModulesPath: Set<string>;
-    constructor(resolveId: (url: string, ssr: boolean) => Promise<PartialResolvedId | null>);
-    getModuleByUrl(rawUrl: string, ssr?: boolean): Promise<ModuleNode | undefined>;
-    getModuleById(id: string): ModuleNode | undefined;
-    getModulesByFile(file: string): Set<ModuleNode> | undefined;
-    onFileChange(file: string): void;
-    invalidateModule(mod: ModuleNode, seen?: Set<ModuleNode>, timestamp?: number): void;
-    invalidateAll(): void;
-    /**
-     * Update the module graph based on a module's updated imports information
-     * If there are dependencies that no longer have any importers, they are
-     * returned as a Set.
-     */
-    updateModuleInfo(mod: ModuleNode, importedModules: Set<string | ModuleNode>, importedBindings: Map<string, Set<string>> | null, acceptedModules: Set<string | ModuleNode>, acceptedExports: Set<string> | null, isSelfAccepting: boolean, ssr?: boolean): Promise<Set<ModuleNode> | undefined>;
-    ensureEntryFromUrl(rawUrl: string, ssr?: boolean, setIsSelfAccepting?: boolean): Promise<ModuleNode>;
-    createFileOnlyEntry(file: string): ModuleNode;
-    resolveUrl(url: string, ssr?: boolean): Promise<ResolvedUrl>;
-}
-
-export declare class ModuleNode {
-    /**
-     * Public served url path, starts with /
-     */
-    url: string;
-    /**
-     * Resolved file system path + query
-     */
-    id: string | null;
-    file: string | null;
-    type: 'js' | 'css';
-    info?: ModuleInfo;
-    meta?: Record<string, any>;
-    importers: Set<ModuleNode>;
-    importedModules: Set<ModuleNode>;
-    acceptedHmrDeps: Set<ModuleNode>;
-    acceptedHmrExports: Set<string> | null;
-    importedBindings: Map<string, Set<string>> | null;
-    isSelfAccepting?: boolean;
-    transformResult: TransformResult | null;
-    ssrTransformResult: TransformResult | null;
-    ssrModule: Record<string, any> | null;
-    ssrError: Error | null;
-    lastHMRTimestamp: number;
-    lastInvalidationTimestamp: number;
-    /**
-     * @param setIsSelfAccepting - set `false` to set `isSelfAccepting` later. e.g. #7870
-     */
-    constructor(url: string, setIsSelfAccepting?: boolean);
-}
-
-export declare function normalizePath(id: string): string;
-
-export declare interface OptimizedDepInfo {
-    id: string;
-    file: string;
-    src?: string;
-    needsInterop?: boolean;
-    browserHash?: string;
-    fileHash?: string;
-    /**
-     * During optimization, ids can still be resolved to their final location
-     * but the bundles may not yet be saved to disk
-     */
-    processing?: Promise<void>;
-    /**
-     * ExportData cache, discovered deps will parse the src entry to get exports
-     * data used both to define if interop is needed and when pre-bundling
-     */
-    exportsData?: Promise<ExportsData>;
-}
-
-/**
- * Scan and optimize dependencies within a project.
- * Used by Vite CLI when running `vite optimize`.
- */
-export declare function optimizeDeps(config: ResolvedConfig, force?: boolean | undefined, asCommand?: boolean): Promise<DepOptimizationMetadata>;
-
-/** Cache for package.json resolution and package.json contents */
-export declare type PackageCache = Map<string, PackageData>;
-
-export declare interface PackageData {
-    dir: string;
-    hasSideEffects: (id: string) => boolean | 'no-treeshake';
-    webResolvedImports: Record<string, string | undefined>;
-    nodeResolvedImports: Record<string, string | undefined>;
-    setResolvedCache: (key: string, entry: string, targetWeb: boolean) => void;
-    getResolvedCache: (key: string, targetWeb: boolean) => string | undefined;
-    data: {
-        [field: string]: any;
-        name: string;
-        type: string;
-        version: string;
-        main: string;
-        module: string;
-        browser: string | Record<string, string | false>;
-        exports: string | Record<string, any> | string[];
-        dependencies: Record<string, string>;
-    };
-}
-
-/**
- * Vite plugins extends the Rollup plugin interface with a few extra
- * vite-specific options. A valid vite plugin is also a valid Rollup plugin.
- * On the contrary, a Rollup plugin may or may NOT be a valid vite universal
- * plugin, since some Rollup features do not make sense in an unbundled
- * dev server context. That said, as long as a rollup plugin doesn't have strong
- * coupling between its bundle phase and output phase hooks then it should
- * just work (that means, most of them).
- *
- * By default, the plugins are run during both serve and build. When a plugin
- * is applied during serve, it will only run **non output plugin hooks** (see
- * rollup type definition of {@link rollup#PluginHooks}). You can think of the
- * dev server as only running `const bundle = rollup.rollup()` but never calling
- * `bundle.generate()`.
- *
- * A plugin that expects to have different behavior depending on serve/build can
- * export a factory function that receives the command being run via options.
- *
- * If a plugin should be applied only for server or build, a function format
- * config file can be used to conditional determine the plugins to use.
- */
-declare interface Plugin_2 extends Plugin_3 {
-    /**
-     * Enforce plugin invocation tier similar to webpack loaders.
-     *
-     * Plugin invocation order:
-     * - alias resolution
-     * - `enforce: 'pre'` plugins
-     * - vite core plugins
-     * - normal plugins
-     * - vite build plugins
-     * - `enforce: 'post'` plugins
-     * - vite build post plugins
-     */
-    enforce?: 'pre' | 'post';
-    /**
-     * Apply the plugin only for serve or build, or on certain conditions.
-     */
-    apply?: 'serve' | 'build' | ((config: UserConfig, env: ConfigEnv) => boolean);
-    /**
-     * Modify vite config before it's resolved. The hook can either mutate the
-     * passed-in config directly, or return a partial config object that will be
-     * deeply merged into existing config.
-     *
-     * Note: User plugins are resolved before running this hook so injecting other
-     * plugins inside  the `config` hook will have no effect.
-     */
-    config?: (config: UserConfig, env: ConfigEnv) => UserConfig | null | void | Promise<UserConfig | null | void>;
-    /**
-     * Use this hook to read and store the final resolved vite config.
-     */
-    configResolved?: (config: ResolvedConfig) => void | Promise<void>;
-    /**
-     * Configure the vite server. The hook receives the {@link ViteDevServer}
-     * instance. This can also be used to store a reference to the server
-     * for use in other hooks.
-     *
-     * The hooks will be called before internal middlewares are applied. A hook
-     * can return a post hook that will be called after internal middlewares
-     * are applied. Hook can be async functions and will be called in series.
-     */
-    configureServer?: ServerHook;
-    /**
-     * Configure the preview server. The hook receives the connect server and
-     * its underlying http server.
-     *
-     * The hooks are called before other middlewares are applied. A hook can
-     * return a post hook that will be called after other middlewares are
-     * applied. Hooks can be async functions and will be called in series.
-     */
-    configurePreviewServer?: PreviewServerHook;
-    /**
-     * Transform index.html.
-     * The hook receives the following arguments:
-     *
-     * - html: string
-     * - ctx?: vite.ServerContext (only present during serve)
-     * - bundle?: rollup.OutputBundle (only present during build)
-     *
-     * It can either return a transformed string, or a list of html tag
-     * descriptors that will be injected into the <head> or <body>.
-     *
-     * By default the transform is applied **after** vite's internal html
-     * transform. If you need to apply the transform before vite, use an object:
-     * `{ enforce: 'pre', transform: hook }`
-     */
-    transformIndexHtml?: IndexHtmlTransform;
-    /**
-     * Perform custom handling of HMR updates.
-     * The handler receives a context containing changed filename, timestamp, a
-     * list of modules affected by the file change, and the dev server instance.
-     *
-     * - The hook can return a filtered list of modules to narrow down the update.
-     *   e.g. for a Vue SFC, we can narrow down the part to update by comparing
-     *   the descriptors.
-     *
-     * - The hook can also return an empty array and then perform custom updates
-     *   by sending a custom hmr payload via server.ws.send().
-     *
-     * - If the hook doesn't return a value, the hmr update will be performed as
-     *   normal.
-     */
-    handleHotUpdate?(ctx: HmrContext): Array<ModuleNode> | void | Promise<Array<ModuleNode> | void>;
-    /**
-     * extend hooks with ssr flag
-     */
-    resolveId?: (this: PluginContext, source: string, importer: string | undefined, options: {
-        custom?: CustomPluginOptions;
-        ssr?: boolean;
-        /* Excluded from this release type: scan */
-        isEntry: boolean;
-    }) => Promise<ResolveIdResult> | ResolveIdResult;
-    load?: (this: PluginContext, id: string, options?: {
-        ssr?: boolean;
-    }) => Promise<LoadResult> | LoadResult;
-    transform?: (this: TransformPluginContext, code: string, id: string, options?: {
-        ssr?: boolean;
-    }) => Promise<TransformResult_2> | TransformResult_2;
-}
-export { Plugin_2 as Plugin }
-
-export declare interface PluginContainer {
-    options: InputOptions;
-    getModuleInfo(id: string): ModuleInfo | null;
-    buildStart(options: InputOptions): Promise<void>;
-    resolveId(id: string, importer?: string, options?: {
-        custom?: CustomPluginOptions;
-        skip?: Set<Plugin_2>;
-        ssr?: boolean;
-        /* Excluded from this release type: scan */
-        isEntry?: boolean;
-    }): Promise<PartialResolvedId | null>;
-    transform(code: string, id: string, options?: {
-        inMap?: SourceDescription['map'];
-        ssr?: boolean;
-    }): Promise<SourceDescription | null>;
-    load(id: string, options?: {
-        ssr?: boolean;
-    }): Promise<LoadResult | null>;
-    close(): Promise<void>;
-}
-
-export declare type PluginOption = Plugin_2 | false | null | undefined | PluginOption[] | Promise<Plugin_2 | false | null | undefined | PluginOption[]>;
-
-/**
- * Starts the Vite server in preview mode, to simulate a production deployment
- */
-export declare function preview(inlineConfig?: InlineConfig): Promise<PreviewServer>;
-
-export declare interface PreviewOptions extends CommonServerOptions {
-}
-
-export declare interface PreviewServer {
-    /**
-     * The resolved vite config object
-     */
-    config: ResolvedConfig;
-    /**
-     * native Node http server instance
-     */
-    httpServer: http.Server;
-    /**
-     * The resolved urls Vite prints on the CLI
-     *
-     * @experimental
-     */
-    resolvedUrls: ResolvedServerUrls;
-    /**
-     * Print server urls
-     */
-    printUrls(): void;
-}
-
-export declare type PreviewServerHook = (server: {
-    middlewares: Connect.Server;
-    httpServer: http.Server;
-}) => (() => void) | void | Promise<(() => void) | void>;
-
-export declare interface ProxyOptions extends HttpProxy.ServerOptions {
-    /**
-     * rewrite path
-     */
-    rewrite?: (path: string) => string;
-    /**
-     * configure the proxy server (e.g. listen to events)
-     */
-    configure?: (proxy: HttpProxy.Server, options: ProxyOptions) => void;
-    /**
-     * webpack-dev-server style bypass function
-     */
-    bypass?: (req: http.IncomingMessage, res: http.ServerResponse, options: ProxyOptions) => void | null | undefined | false | string;
-}
-
-export declare interface PrunePayload {
-    type: 'prune'
-    paths: string[]
-}
-
-export declare type RenderBuiltAssetUrl = (filename: string, type: {
-    type: 'asset' | 'public';
-    hostId: string;
-    hostType: 'js' | 'css' | 'html';
-    ssr: boolean;
-}) => string | {
-    relative?: boolean;
-    runtime?: string;
-} | undefined;
-
-/**
- * Resolve base url. Note that some users use Vite to build for non-web targets like
- * electron or expects to deploy
- */
-export declare function resolveBaseUrl(base: string | undefined, isBuild: boolean, logger: Logger): string;
-
-export declare function resolveConfig(inlineConfig: InlineConfig, command: 'build' | 'serve', defaultMode?: string): Promise<ResolvedConfig>;
-
-export declare type ResolvedBuildOptions = Required<BuildOptions>;
-
-export declare type ResolvedConfig = Readonly<Omit<UserConfig, 'plugins' | 'assetsInclude' | 'optimizeDeps' | 'worker'> & {
-    configFile: string | undefined;
-    configFileDependencies: string[];
-    inlineConfig: InlineConfig;
-    root: string;
-    base: string;
-    publicDir: string;
-    cacheDir: string;
-    command: 'build' | 'serve';
-    mode: string;
-    isWorker: boolean;
-    /* Excluded from this release type: mainConfig */
-    isProduction: boolean;
-    env: Record<string, any>;
-    resolve: ResolveOptions & {
-        alias: Alias[];
-    };
-    plugins: readonly Plugin_2[];
-    server: ResolvedServerOptions;
-    build: ResolvedBuildOptions;
-    preview: ResolvedPreviewOptions;
-    ssr: ResolvedSSROptions;
-    assetsInclude: (file: string) => boolean;
-    logger: Logger;
-    createResolver: (options?: Partial<InternalResolveOptions>) => ResolveFn;
-    optimizeDeps: DepOptimizationOptions;
-    /* Excluded from this release type: packageCache */
-    worker: ResolveWorkerOptions;
-    appType: AppType;
-    experimental: ExperimentalOptions;
-}>;
-
-export declare interface ResolvedPreviewOptions extends PreviewOptions {
-}
-
-export declare interface ResolvedServerOptions extends ServerOptions {
-    fs: Required<FileSystemServeOptions>;
-    middlewareMode: boolean;
-}
-
-export declare interface ResolvedServerUrls {
-    local: string[];
-    network: string[];
-}
-
-export declare interface ResolvedSSROptions extends SSROptions {
-    target: SSRTarget;
-    format: SSRFormat;
-    optimizeDeps: SsrDepOptimizationOptions;
-}
-
-export declare type ResolvedUrl = [
-url: string,
-resolvedId: string,
-meta: object | null | undefined
-];
-
-export declare function resolveEnvPrefix({ envPrefix }: UserConfig): string[];
-
-export declare type ResolveFn = (id: string, importer?: string, aliasOnly?: boolean, ssr?: boolean) => Promise<string | undefined>;
-
-export declare interface ResolveOptions {
-    mainFields?: string[];
-    conditions?: string[];
-    extensions?: string[];
-    dedupe?: string[];
-    preserveSymlinks?: boolean;
-}
-
-export declare function resolvePackageData(id: string, basedir: string, preserveSymlinks?: boolean, packageCache?: PackageCache): PackageData | null;
-
-export declare function resolvePackageEntry(id: string, { dir, data, setResolvedCache, getResolvedCache }: PackageData, targetWeb: boolean, options: InternalResolveOptions): string | undefined;
-
-export declare type ResolverFunction = PluginHooks['resolveId']
-
-export declare interface ResolverObject {
-    buildStart?: PluginHooks['buildStart']
-    resolveId: ResolverFunction
-}
-
-export declare interface ResolveWorkerOptions {
-    format: 'es' | 'iife';
-    plugins: Plugin_2[];
-    rollupOptions: RollupOptions;
-}
-
-/**
- * https://github.com/rollup/plugins/blob/master/packages/commonjs/types/index.d.ts
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file at
- * https://github.com/rollup/plugins/blob/master/LICENSE
- */
-export declare interface RollupCommonJSOptions {
-    /**
-     * A minimatch pattern, or array of patterns, which specifies the files in
-     * the build the plugin should operate on. By default, all files with
-     * extension `".cjs"` or those in `extensions` are included, but you can
-     * narrow this list by only including specific files. These files will be
-     * analyzed and transpiled if either the analysis does not find ES module
-     * specific statements or `transformMixedEsModules` is `true`.
-     * @default undefined
-     */
-    include?: string | RegExp | readonly (string | RegExp)[]
-    /**
-     * A minimatch pattern, or array of patterns, which specifies the files in
-     * the build the plugin should _ignore_. By default, all files with
-     * extensions other than those in `extensions` or `".cjs"` are ignored, but you
-     * can exclude additional files. See also the `include` option.
-     * @default undefined
-     */
-    exclude?: string | RegExp | readonly (string | RegExp)[]
-    /**
-     * For extensionless imports, search for extensions other than .js in the
-     * order specified. Note that you need to make sure that non-JavaScript files
-     * are transpiled by another plugin first.
-     * @default [ '.js' ]
-     */
-    extensions?: ReadonlyArray<string>
-    /**
-     * If true then uses of `global` won't be dealt with by this plugin
-     * @default false
-     */
-    ignoreGlobal?: boolean
-    /**
-     * If false, skips source map generation for CommonJS modules. This will
-     * improve performance.
-     * @default true
-     */
-    sourceMap?: boolean
-    /**
-     * Some `require` calls cannot be resolved statically to be translated to
-     * imports.
-     * When this option is set to `false`, the generated code will either
-     * directly throw an error when such a call is encountered or, when
-     * `dynamicRequireTargets` is used, when such a call cannot be resolved with a
-     * configured dynamic require target.
-     * Setting this option to `true` will instead leave the `require` call in the
-     * code or use it as a fallback for `dynamicRequireTargets`.
-     * @default false
-     */
-    ignoreDynamicRequires?: boolean
-    /**
-     * Instructs the plugin whether to enable mixed module transformations. This
-     * is useful in scenarios with modules that contain a mix of ES `import`
-     * statements and CommonJS `require` expressions. Set to `true` if `require`
-     * calls should be transformed to imports in mixed modules, or `false` if the
-     * `require` expressions should survive the transformation. The latter can be
-     * important if the code contains environment detection, or you are coding
-     * for an environment with special treatment for `require` calls such as
-     * ElectronJS. See also the `ignore` option.
-     * @default false
-     */
-    transformMixedEsModules?: boolean
-    /**
-     * By default, this plugin will try to hoist `require` statements as imports
-     * to the top of each file. While this works well for many code bases and
-     * allows for very efficient ESM output, it does not perfectly capture
-     * CommonJS semantics as the order of side effects like log statements may
-     * change. But it is especially problematic when there are circular `require`
-     * calls between CommonJS modules as those often rely on the lazy execution of
-     * nested `require` calls.
-     *
-     * Setting this option to `true` will wrap all CommonJS files in functions
-     * which are executed when they are required for the first time, preserving
-     * NodeJS semantics. Note that this can have an impact on the size and
-     * performance of the generated code.
-     *
-     * The default value of `"auto"` will only wrap CommonJS files when they are
-     * part of a CommonJS dependency cycle, e.g. an index file that is required by
-     * many of its dependencies. All other CommonJS files are hoisted. This is the
-     * recommended setting for most code bases.
-     *
-     * `false` will entirely prevent wrapping and hoist all files. This may still
-     * work depending on the nature of cyclic dependencies but will often cause
-     * problems.
-     *
-     * You can also provide a minimatch pattern, or array of patterns, to only
-     * specify a subset of files which should be wrapped in functions for proper
-     * `require` semantics.
-     *
-     * `"debug"` works like `"auto"` but after bundling, it will display a warning
-     * containing a list of ids that have been wrapped which can be used as
-     * minimatch pattern for fine-tuning.
-     * @default "auto"
-     */
-    strictRequires?: boolean | string | RegExp | readonly (string | RegExp)[]
-    /**
-     * Sometimes you have to leave require statements unconverted. Pass an array
-     * containing the IDs or a `id => boolean` function.
-     * @default []
-     */
-    ignore?: ReadonlyArray<string> | ((id: string) => boolean)
-    /**
-     * In most cases, where `require` calls are inside a `try-catch` clause,
-     * they should be left unconverted as it requires an optional dependency
-     * that may or may not be installed beside the rolled up package.
-     * Due to the conversion of `require` to a static `import` - the call is
-     * hoisted to the top of the file, outside of the `try-catch` clause.
-     *
-     * - `true`: All `require` calls inside a `try` will be left unconverted.
-     * - `false`: All `require` calls inside a `try` will be converted as if the
-     *   `try-catch` clause is not there.
-     * - `remove`: Remove all `require` calls from inside any `try` block.
-     * - `string[]`: Pass an array containing the IDs to left unconverted.
-     * - `((id: string) => boolean|'remove')`: Pass a function that control
-     *   individual IDs.
-     *
-     * @default false
-     */
-    ignoreTryCatch?:
-    | boolean
-    | 'remove'
-    | ReadonlyArray<string>
-    | ((id: string) => boolean | 'remove')
-    /**
-     * Controls how to render imports from external dependencies. By default,
-     * this plugin assumes that all external dependencies are CommonJS. This
-     * means they are rendered as default imports to be compatible with e.g.
-     * NodeJS where ES modules can only import a default export from a CommonJS
-     * dependency.
-     *
-     * If you set `esmExternals` to `true`, this plugins assumes that all
-     * external dependencies are ES modules and respect the
-     * `requireReturnsDefault` option. If that option is not set, they will be
-     * rendered as namespace imports.
-     *
-     * You can also supply an array of ids to be treated as ES modules, or a
-     * function that will be passed each external id to determine if it is an ES
-     * module.
-     * @default false
-     */
-    esmExternals?: boolean | ReadonlyArray<string> | ((id: string) => boolean)
-    /**
-     * Controls what is returned when requiring an ES module from a CommonJS file.
-     * When using the `esmExternals` option, this will also apply to external
-     * modules. By default, this plugin will render those imports as namespace
-     * imports i.e.
-     *
-     * ```js
-     * // input
-     * const foo = require('foo');
-     *
-     * // output
-     * import * as foo from 'foo';
-     * ```
-     *
-     * However there are some situations where this may not be desired.
-     * For these situations, you can change Rollup's behaviour either globally or
-     * per module. To change it globally, set the `requireReturnsDefault` option
-     * to one of the following values:
-     *
-     * - `false`: This is the default, requiring an ES module returns its
-     *   namespace. This is the only option that will also add a marker
-     *   `__esModule: true` to the namespace to support interop patterns in
-     *   CommonJS modules that are transpiled ES modules.
-     * - `"namespace"`: Like `false`, requiring an ES module returns its
-     *   namespace, but the plugin does not add the `__esModule` marker and thus
-     *   creates more efficient code. For external dependencies when using
-     *   `esmExternals: true`, no additional interop code is generated.
-     * - `"auto"`: This is complementary to how `output.exports: "auto"` works in
-     *   Rollup: If a module has a default export and no named exports, requiring
-     *   that module returns the default export. In all other cases, the namespace
-     *   is returned. For external dependencies when using `esmExternals: true`, a
-     *   corresponding interop helper is added.
-     * - `"preferred"`: If a module has a default export, requiring that module
-     *   always returns the default export, no matter whether additional named
-     *   exports exist. This is similar to how previous versions of this plugin
-     *   worked. Again for external dependencies when using `esmExternals: true`,
-     *   an interop helper is added.
-     * - `true`: This will always try to return the default export on require
-     *   without checking if it actually exists. This can throw at build time if
-     *   there is no default export. This is how external dependencies are handled
-     *   when `esmExternals` is not used. The advantage over the other options is
-     *   that, like `false`, this does not add an interop helper for external
-     *   dependencies, keeping the code lean.
-     *
-     * To change this for individual modules, you can supply a function for
-     * `requireReturnsDefault` instead. This function will then be called once for
-     * each required ES module or external dependency with the corresponding id
-     * and allows you to return different values for different modules.
-     * @default false
-     */
-    requireReturnsDefault?:
-    | boolean
-    | 'auto'
-    | 'preferred'
-    | 'namespace'
-    | ((id: string) => boolean | 'auto' | 'preferred' | 'namespace')
-
-    /**
-     * @default "auto"
-     */
-    defaultIsModuleExports?: boolean | 'auto' | ((id: string) => boolean | 'auto')
-    /**
-     * Some modules contain dynamic `require` calls, or require modules that
-     * contain circular dependencies, which are not handled well by static
-     * imports. Including those modules as `dynamicRequireTargets` will simulate a
-     * CommonJS (NodeJS-like)  environment for them with support for dynamic
-     * dependencies. It also enables `strictRequires` for those modules.
-     *
-     * Note: In extreme cases, this feature may result in some paths being
-     * rendered as absolute in the final bundle. The plugin tries to avoid
-     * exposing paths from the local machine, but if you are `dynamicRequirePaths`
-     * with paths that are far away from your project's folder, that may require
-     * replacing strings like `"/Users/John/Desktop/foo-project/"` -\> `"/"`.
-     */
-    dynamicRequireTargets?: string | ReadonlyArray<string>
-    /**
-     * To avoid long paths when using the `dynamicRequireTargets` option, you can use this option to specify a directory
-     * that is a common parent for all files that use dynamic require statements. Using a directory higher up such as `/`
-     * may lead to unnecessarily long paths in the generated code and may expose directory names on your machine like your
-     * home directory name. By default it uses the current working directory.
-     */
-    dynamicRequireRoot?: string
-}
-
-export declare interface RollupDynamicImportVarsOptions {
-    /**
-     * Files to include in this plugin (default all).
-     * @default []
-     */
-    include?: string | RegExp | (string | RegExp)[]
-    /**
-     * Files to exclude in this plugin (default none).
-     * @default []
-     */
-    exclude?: string | RegExp | (string | RegExp)[]
-    /**
-     * By default, the plugin quits the build process when it encounters an error. If you set this option to true, it will throw a warning instead and leave the code untouched.
-     * @default false
-     */
-    warnOnError?: boolean
-}
-
-export { rollupVersion }
-
-/**
- * Search up for the nearest workspace root
- */
-export declare function searchForWorkspaceRoot(current: string, root?: string): string;
-
-export declare function send(req: IncomingMessage, res: ServerResponse, content: string | Buffer, type: string, options: SendOptions): void;
-
-export declare interface SendOptions {
-    etag?: string;
-    cacheControl?: string;
-    headers?: OutgoingHttpHeaders;
-    map?: SourceMap | null;
-}
-
-export declare type ServerHook = (server: ViteDevServer) => (() => void) | void | Promise<(() => void) | void>;
-
-export declare interface ServerOptions extends CommonServerOptions {
-    /**
-     * Configure HMR-specific options (port, host, path & protocol)
-     */
-    hmr?: HmrOptions | boolean;
-    /**
-     * chokidar watch options
-     * https://github.com/paulmillr/chokidar#api
-     */
-    watch?: WatchOptions;
-    /**
-     * Create Vite dev server to be used as a middleware in an existing server
-     */
-    middlewareMode?: boolean | 'html' | 'ssr';
-    /**
-     * Prepend this folder to http requests, for use when proxying vite as a subfolder
-     * Should start and end with the `/` character
-     */
-    base?: string;
-    /**
-     * Options for files served via '/\@fs/'.
-     */
-    fs?: FileSystemServeOptions;
-    /**
-     * Origin for the generated asset URLs.
-     *
-     * @example `http://127.0.0.1:8080`
-     */
-    origin?: string;
-    /**
-     * Pre-transform known direct imports
-     * @default true
-     */
-    preTransformRequests?: boolean;
-    /**
-     * Force dep pre-optimization regardless of whether deps have changed.
-     *
-     * @deprecated Use optimizeDeps.force instead, this option may be removed
-     * in a future minor version without following semver
-     */
-    force?: boolean;
-}
-
-export declare function sortUserPlugins(plugins: (Plugin_2 | Plugin_2[])[] | undefined): [Plugin_2[], Plugin_2[], Plugin_2[]];
-
-export declare function splitVendorChunk(options?: {
-    cache?: SplitVendorChunkCache;
-}): GetManualChunk;
-
-export declare class SplitVendorChunkCache {
-    cache: Map<string, boolean>;
-    constructor();
-    reset(): void;
-}
-
-export declare function splitVendorChunkPlugin(): Plugin_2;
-
-export declare type SsrDepOptimizationOptions = DepOptimizationConfig;
-
-export declare type SSRFormat = 'esm' | 'cjs';
-
-export declare interface SSROptions {
-    noExternal?: string | RegExp | (string | RegExp)[] | true;
-    external?: string[];
-    /**
-     * Define the target for the ssr build. The browser field in package.json
-     * is ignored for node but used if webworker is the target
-     * Default: 'node'
-     */
-    target?: SSRTarget;
-    /**
-     * Define the format for the ssr build. Since Vite v3 the SSR build generates ESM by default.
-     * `'cjs'` can be selected to generate a CJS build, but it isn't recommended. This option is
-     * left marked as experimental to give users more time to update to ESM. CJS builds requires
-     * complex externalization heuristics that aren't present in the ESM format.
-     * @experimental
-     */
-    format?: SSRFormat;
-    /**
-     * Control over which dependencies are optimized during SSR and esbuild options
-     * During build:
-     *   no external CJS dependencies are optimized by default
-     * During dev:
-     *   explicit no external CJS dependencies are optimized by default
-     * @experimental
-     */
-    optimizeDeps?: SsrDepOptimizationOptions;
-}
-
-export declare type SSRTarget = 'node' | 'webworker';
-
-export declare namespace Terser {
-    export type ECMA = 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020
-
-    export interface ParseOptions {
-        bare_returns?: boolean
-        /** @deprecated legacy option. Currently, all supported EcmaScript is valid to parse. */
-        ecma?: ECMA
-        html5_comments?: boolean
-        shebang?: boolean
-    }
-
-    export interface CompressOptions {
-        arguments?: boolean
-        arrows?: boolean
-        booleans_as_integers?: boolean
-        booleans?: boolean
-        collapse_vars?: boolean
-        comparisons?: boolean
-        computed_props?: boolean
-        conditionals?: boolean
-        dead_code?: boolean
-        defaults?: boolean
-        directives?: boolean
-        drop_console?: boolean
-        drop_debugger?: boolean
-        ecma?: ECMA
-        evaluate?: boolean
-        expression?: boolean
-        global_defs?: object
-        hoist_funs?: boolean
-        hoist_props?: boolean
-        hoist_vars?: boolean
-        ie8?: boolean
-        if_return?: boolean
-        inline?: boolean | InlineFunctions
-        join_vars?: boolean
-        keep_classnames?: boolean | RegExp
-        keep_fargs?: boolean
-        keep_fnames?: boolean | RegExp
-        keep_infinity?: boolean
-        loops?: boolean
-        module?: boolean
-        negate_iife?: boolean
-        passes?: number
-        properties?: boolean
-        pure_funcs?: string[]
-        pure_getters?: boolean | 'strict'
-        reduce_funcs?: boolean
-        reduce_vars?: boolean
-        sequences?: boolean | number
-        side_effects?: boolean
-        switches?: boolean
-        toplevel?: boolean
-        top_retain?: null | string | string[] | RegExp
-        typeofs?: boolean
-        unsafe_arrows?: boolean
-        unsafe?: boolean
-        unsafe_comps?: boolean
-        unsafe_Function?: boolean
-        unsafe_math?: boolean
-        unsafe_symbols?: boolean
-        unsafe_methods?: boolean
-        unsafe_proto?: boolean
-        unsafe_regexp?: boolean
-        unsafe_undefined?: boolean
-        unused?: boolean
-    }
-
-    export enum InlineFunctions {
-        Disabled = 0,
-        SimpleFunctions = 1,
-        WithArguments = 2,
-        WithArgumentsAndVariables = 3
-    }
-
-    export interface MangleOptions {
-        eval?: boolean
-        keep_classnames?: boolean | RegExp
-        keep_fnames?: boolean | RegExp
-        module?: boolean
-        nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler
-        properties?: boolean | ManglePropertiesOptions
-        reserved?: string[]
-        safari10?: boolean
-        toplevel?: boolean
-    }
-
-    /**
-     * An identifier mangler for which the output is invariant with respect to the source code.
-     */
-    export interface SimpleIdentifierMangler {
-        /**
-         * Obtains the nth most favored (usually shortest) identifier to rename a variable to.
-         * The mangler will increment n and retry until the return value is not in use in scope, and is not a reserved word.
-         * This function is expected to be stable; Evaluating get(n) === get(n) should always return true.
-         * @param n - The ordinal of the identifier.
-         */
-        get(n: number): string
-    }
-
-    /**
-     * An identifier mangler that leverages character frequency analysis to determine identifier precedence.
-     */
-    export interface WeightedIdentifierMangler extends SimpleIdentifierMangler {
-        /**
-         * Modifies the internal weighting of the input characters by the specified delta.
-         * Will be invoked on the entire printed AST, and then deduct mangleable identifiers.
-         * @param chars - The characters to modify the weighting of.
-         * @param delta - The numeric weight to add to the characters.
-         */
-        consider(chars: string, delta: number): number
-        /**
-         * Resets character weights.
-         */
-        reset(): void
-        /**
-         * Sorts identifiers by character frequency, in preparation for calls to get(n).
-         */
-        sort(): void
-    }
-
-    export interface ManglePropertiesOptions {
-        builtins?: boolean
-        debug?: boolean
-        keep_quoted?: boolean | 'strict'
-        nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler
-        regex?: RegExp | string
-        reserved?: string[]
-    }
-
-    export interface FormatOptions {
-        ascii_only?: boolean
-        /** @deprecated Not implemented anymore */
-        beautify?: boolean
-        braces?: boolean
-        comments?:
-        | boolean
-        | 'all'
-        | 'some'
-        | RegExp
-        | ((
-        node: any,
-        comment: {
-            value: string
-            type: 'comment1' | 'comment2' | 'comment3' | 'comment4'
-            pos: number
-            line: number
-            col: number
-        }
-        ) => boolean)
-        ecma?: ECMA
-        ie8?: boolean
-        keep_numbers?: boolean
-        indent_level?: number
-        indent_start?: number
-        inline_script?: boolean
-        keep_quoted_props?: boolean
-        max_line_len?: number | false
-        preamble?: string
-        preserve_annotations?: boolean
-        quote_keys?: boolean
-        quote_style?: OutputQuoteStyle
-        safari10?: boolean
-        semicolons?: boolean
-        shebang?: boolean
-        shorthand?: boolean
-        source_map?: SourceMapOptions
-        webkit?: boolean
-        width?: number
-        wrap_iife?: boolean
-        wrap_func_args?: boolean
-    }
-
-    export enum OutputQuoteStyle {
-        PreferDouble = 0,
-        AlwaysSingle = 1,
-        AlwaysDouble = 2,
-        AlwaysOriginal = 3
-    }
-
-    export interface MinifyOptions {
-        compress?: boolean | CompressOptions
-        ecma?: ECMA
-        enclose?: boolean | string
-        ie8?: boolean
-        keep_classnames?: boolean | RegExp
-        keep_fnames?: boolean | RegExp
-        mangle?: boolean | MangleOptions
-        module?: boolean
-        nameCache?: object
-        format?: FormatOptions
-        /** @deprecated deprecated */
-        output?: FormatOptions
-        parse?: ParseOptions
-        safari10?: boolean
-        sourceMap?: boolean | SourceMapOptions
-        toplevel?: boolean
-    }
-
-    export interface MinifyOutput {
-        code?: string
-        map?: object | string
-        decoded_map?: object | null
-    }
-
-    export interface SourceMapOptions {
-        /** Source map object, 'inline' or source map file content */
-        content?: object | string
-        includeSources?: boolean
-        filename?: string
-        root?: string
-        url?: string | 'inline'
-    }
-}
-
-export declare interface TransformOptions {
-    ssr?: boolean;
-    html?: boolean;
-}
-
-export declare interface TransformResult {
-    code: string;
-    map: SourceMap | null;
-    etag?: string;
-    deps?: string[];
-    dynamicDeps?: string[];
-}
-
-export declare function transformWithEsbuild(code: string, filename: string, options?: EsbuildTransformOptions, inMap?: object): Promise<ESBuildTransformResult>;
-
-export declare interface Update {
-    type: 'js-update' | 'css-update'
-    path: string
-    acceptedPath: string
-    timestamp: number
-}
-
-export declare interface UpdatePayload {
-    type: 'update'
-    updates: Update[]
-}
-
-export declare interface UserConfig {
-    /**
-     * Project root directory. Can be an absolute path, or a path relative from
-     * the location of the config file itself.
-     * @default process.cwd()
-     */
-    root?: string;
-    /**
-     * Base public path when served in development or production.
-     * @default '/'
-     */
-    base?: string;
-    /**
-     * Directory to serve as plain static assets. Files in this directory are
-     * served and copied to build dist dir as-is without transform. The value
-     * can be either an absolute file system path or a path relative to <root>.
-     *
-     * Set to `false` or an empty string to disable copied static assets to build dist dir.
-     * @default 'public'
-     */
-    publicDir?: string | false;
-    /**
-     * Directory to save cache files. Files in this directory are pre-bundled
-     * deps or some other cache files that generated by vite, which can improve
-     * the performance. You can use `--force` flag or manually delete the directory
-     * to regenerate the cache files. The value can be either an absolute file
-     * system path or a path relative to <root>.
-     * Default to `.vite` when no `package.json` is detected.
-     * @default 'node_modules/.vite'
-     */
-    cacheDir?: string;
-    /**
-     * Explicitly set a mode to run in. This will override the default mode for
-     * each command, and can be overridden by the command line --mode option.
-     */
-    mode?: string;
-    /**
-     * Define global variable replacements.
-     * Entries will be defined on `window` during dev and replaced during build.
-     */
-    define?: Record<string, any>;
-    /**
-     * Array of vite plugins to use.
-     */
-    plugins?: PluginOption[];
-    /**
-     * Configure resolver
-     */
-    resolve?: ResolveOptions & {
-        alias?: AliasOptions;
-    };
-    /**
-     * CSS related options (preprocessors and CSS modules)
-     */
-    css?: CSSOptions;
-    /**
-     * JSON loading options
-     */
-    json?: JsonOptions;
-    /**
-     * Transform options to pass to esbuild.
-     * Or set to `false` to disable esbuild.
-     */
-    esbuild?: ESBuildOptions | false;
-    /**
-     * Specify additional picomatch patterns to be treated as static assets.
-     */
-    assetsInclude?: string | RegExp | (string | RegExp)[];
-    /**
-     * Server specific options, e.g. host, port, https...
-     */
-    server?: ServerOptions;
-    /**
-     * Build specific options
-     */
-    build?: BuildOptions;
-    /**
-     * Preview specific options, e.g. host, port, https...
-     */
-    preview?: PreviewOptions;
-    /**
-     * Dep optimization options
-     */
-    optimizeDeps?: DepOptimizationOptions;
-    /**
-     * SSR specific options
-     */
-    ssr?: SSROptions;
-    /**
-     * Experimental features
-     *
-     * Features under this field could change in the future and might NOT follow semver.
-     * Please be careful and always pin Vite's version when using them.
-     * @experimental
-     */
-    experimental?: ExperimentalOptions;
-    /**
-     * Legacy options
-     *
-     * Features under this field only follow semver for patches, they could be removed in a
-     * future minor version. Please always pin Vite's version to a minor when using them.
-     */
-    legacy?: LegacyOptions;
-    /**
-     * Log level.
-     * Default: 'info'
-     */
-    logLevel?: LogLevel;
-    /**
-     * Custom logger.
-     */
-    customLogger?: Logger;
-    /**
-     * Default: true
-     */
-    clearScreen?: boolean;
-    /**
-     * Environment files directory. Can be an absolute path, or a path relative from
-     * the location of the config file itself.
-     * @default root
-     */
-    envDir?: string;
-    /**
-     * Env variables starts with `envPrefix` will be exposed to your client source code via import.meta.env.
-     * @default 'VITE_'
-     */
-    envPrefix?: string | string[];
-    /**
-     * Worker bundle options
-     */
-    worker?: {
-        /**
-         * Output format for worker bundle
-         * @default 'iife'
-         */
-        format?: 'es' | 'iife';
-        /**
-         * Vite plugins that apply to worker bundle
-         */
-        plugins?: PluginOption[];
-        /**
-         * Rollup options to build worker bundle
-         */
-        rollupOptions?: Omit<RollupOptions, 'plugins' | 'input' | 'onwarn' | 'preserveEntrySignatures'>;
-    };
-    /**
-     * Whether your application is a Single Page Application (SPA),
-     * a Multi-Page Application (MPA), or Custom Application (SSR
-     * and frameworks with custom HTML handling)
-     * @default 'spa'
-     */
-    appType?: AppType;
-}
-
-export declare type UserConfigExport = UserConfig | Promise<UserConfig> | UserConfigFn;
-
-export declare type UserConfigFn = (env: ConfigEnv) => UserConfig | Promise<UserConfig>;
-
-export declare const version: string;
-
-export declare interface ViteDevServer {
-    /**
-     * The resolved vite config object
-     */
-    config: ResolvedConfig;
-    /**
-     * A connect app instance.
-     * - Can be used to attach custom middlewares to the dev server.
-     * - Can also be used as the handler function of a custom http server
-     *   or as a middleware in any connect-style Node.js frameworks
-     *
-     * https://github.com/senchalabs/connect#use-middleware
-     */
-    middlewares: Connect.Server;
-    /**
-     * native Node http server instance
-     * will be null in middleware mode
-     */
-    httpServer: http.Server | null;
-    /**
-     * chokidar watcher instance
-     * https://github.com/paulmillr/chokidar#api
-     */
-    watcher: FSWatcher;
-    /**
-     * web socket server with `send(payload)` method
-     */
-    ws: WebSocketServer;
-    /**
-     * Rollup plugin container that can run plugin hooks on a given file
-     */
-    pluginContainer: PluginContainer;
-    /**
-     * Module graph that tracks the import relationships, url to file mapping
-     * and hmr state.
-     */
-    moduleGraph: ModuleGraph;
-    /**
-     * The resolved urls Vite prints on the CLI. null in middleware mode or
-     * before `server.listen` is called.
-     *
-     * @experimental
-     */
-    resolvedUrls: ResolvedServerUrls | null;
-    /**
-     * Programmatically resolve, load and transform a URL and get the result
-     * without going through the http request pipeline.
-     */
-    transformRequest(url: string, options?: TransformOptions): Promise<TransformResult | null>;
-    /**
-     * Apply vite built-in HTML transforms and any plugin HTML transforms.
-     */
-    transformIndexHtml(url: string, html: string, originalUrl?: string): Promise<string>;
-    /**
-     * Transform module code into SSR format.
-     */
-    ssrTransform(code: string, inMap: SourceMap | null, url: string): Promise<TransformResult | null>;
-    /**
-     * Load a given URL as an instantiated module for SSR.
-     */
-    ssrLoadModule(url: string, opts?: {
-        fixStacktrace?: boolean;
-    }): Promise<Record<string, any>>;
-    /**
-     * Returns a fixed version of the given stack
-     */
-    ssrRewriteStacktrace(stack: string): string;
-    /**
-     * Mutates the given SSR error by rewriting the stacktrace
-     */
-    ssrFixStacktrace(e: Error): void;
-    /**
-     * Start the server.
-     */
-    listen(port?: number, isRestart?: boolean): Promise<ViteDevServer>;
-    /**
-     * Stop the server.
-     */
-    close(): Promise<void>;
-    /**
-     * Print server urls
-     */
-    printUrls(): void;
-    /**
-     * Restart the server.
-     *
-     * @param forceOptimize - force the optimizer to re-bundle, same as --force cli flag
-     */
-    restart(forceOptimize?: boolean): Promise<void>;
-    /* Excluded from this release type: _importGlobMap */
-    /* Excluded from this release type: _ssrExternals */
-    /* Excluded from this release type: _restartPromise */
-    /* Excluded from this release type: _forceOptimizeOnRestart */
-    /* Excluded from this release type: _pendingRequests */
-}
-
-export declare interface WatchOptions {
-    /**
-     * Indicates whether the process should continue to run as long as files are being watched. If
-     * set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`,
-     * even if the process continues to run.
-     */
-    persistent?: boolean
-
-    /**
-     * ([anymatch](https://github.com/micromatch/anymatch)-compatible definition) Defines files/paths to
-     * be ignored. The whole relative or absolute path is tested, not just filename. If a function
-     * with two arguments is provided, it gets called twice per path - once with a single argument
-     * (the path), second time with two arguments (the path and the
-     * [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path).
-     */
-    ignored?: Matcher
-
-    /**
-     * If set to `false` then `add`/`addDir` events are also emitted for matching paths while
-     * instantiating the watching as chokidar discovers these file paths (before the `ready` event).
-     */
-    ignoreInitial?: boolean
-
-    /**
-     * When `false`, only the symlinks themselves will be watched for changes instead of following
-     * the link references and bubbling events through the link's path.
-     */
-    followSymlinks?: boolean
-
-    /**
-     * The base directory from which watch `paths` are to be derived. Paths emitted with events will
-     * be relative to this.
-     */
-    cwd?: string
-
-    /**
-     * If set to true then the strings passed to .watch() and .add() are treated as literal path
-     * names, even if they look like globs.
-     *
-     * @default false
-     */
-    disableGlobbing?: boolean
-
-    /**
-     * Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU
-     * utilization, consider setting this to `false`. It is typically necessary to **set this to
-     * `true` to successfully watch files over a network**, and it may be necessary to successfully
-     * watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides
-     * the `useFsEvents` default.
-     */
-    usePolling?: boolean
-
-    /**
-     * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly
-     * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on
-     * OS X, `usePolling: true` becomes the default.
-     */
-    useFsEvents?: boolean
-
-    /**
-     * If relying upon the [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object that
-     * may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is
-     * provided even in cases where it wasn't already available from the underlying watch events.
-     */
-    alwaysStat?: boolean
-
-    /**
-     * If set, limits how many levels of subdirectories will be traversed.
-     */
-    depth?: number
-
-    /**
-     * Interval of file system polling.
-     */
-    interval?: number
-
-    /**
-     * Interval of file system polling for binary files. ([see list of binary extensions](https://gi
-     * thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
-     */
-    binaryInterval?: number
-
-    /**
-     *  Indicates whether to watch files that don't have read permissions if possible. If watching
-     *  fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed
-     *  silently.
-     */
-    ignorePermissionErrors?: boolean
-
-    /**
-     * `true` if `useFsEvents` and `usePolling` are `false`). Automatically filters out artifacts
-     * that occur when using editors that use "atomic writes" instead of writing directly to the
-     * source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change`
-     * event rather than `unlink` then `add`. If the default of 100 ms does not work well for you,
-     * you can override it by setting `atomic` to a custom value, in milliseconds.
-     */
-    atomic?: boolean | number
-
-    /**
-     * can be set to an object in order to adjust timing params:
-     */
-    awaitWriteFinish?: AwaitWriteFinishOptions | boolean
-}
-
-declare class WebSocket_2 extends EventEmitter {
-    /** The connection is not yet open. */
-    static readonly CONNECTING: 0
-    /** The connection is open and ready to communicate. */
-    static readonly OPEN: 1
-    /** The connection is in the process of closing. */
-    static readonly CLOSING: 2
-    /** The connection is closed. */
-    static readonly CLOSED: 3
-
-    binaryType: 'nodebuffer' | 'arraybuffer' | 'fragments'
-    readonly bufferedAmount: number
-    readonly extensions: string
-    /** Indicates whether the websocket is paused */
-    readonly isPaused: boolean
-    readonly protocol: string
-    /** The current state of the connection */
-    readonly readyState:
-    | typeof WebSocket_2.CONNECTING
-    | typeof WebSocket_2.OPEN
-    | typeof WebSocket_2.CLOSING
-    | typeof WebSocket_2.CLOSED
-    readonly url: string
-
-    /** The connection is not yet open. */
-    readonly CONNECTING: 0
-    /** The connection is open and ready to communicate. */
-    readonly OPEN: 1
-    /** The connection is in the process of closing. */
-    readonly CLOSING: 2
-    /** The connection is closed. */
-    readonly CLOSED: 3
-
-    onopen: ((event: WebSocket_2.Event) => void) | null
-    onerror: ((event: WebSocket_2.ErrorEvent) => void) | null
-    onclose: ((event: WebSocket_2.CloseEvent) => void) | null
-    onmessage: ((event: WebSocket_2.MessageEvent) => void) | null
-
-    constructor(address: null)
-    constructor(
-    address: string | URL_2,
-    options?: WebSocket_2.ClientOptions | ClientRequestArgs
-    )
-    constructor(
-    address: string | URL_2,
-    protocols?: string | string[],
-    options?: WebSocket_2.ClientOptions | ClientRequestArgs
-    )
-
-    close(code?: number, data?: string | Buffer): void
-    ping(data?: any, mask?: boolean, cb?: (err: Error) => void): void
-    pong(data?: any, mask?: boolean, cb?: (err: Error) => void): void
-    send(data: any, cb?: (err?: Error) => void): void
-    send(
-    data: any,
-    options: {
-        mask?: boolean | undefined
-        binary?: boolean | undefined
-        compress?: boolean | undefined
-        fin?: boolean | undefined
-    },
-    cb?: (err?: Error) => void
-    ): void
-    terminate(): void
-
-    /**
-     * Pause the websocket causing it to stop emitting events. Some events can still be
-     * emitted after this is called, until all buffered data is consumed. This method
-     * is a noop if the ready state is `CONNECTING` or `CLOSED`.
-     */
-    pause(): void
-    /**
-     * Make a paused socket resume emitting events. This method is a noop if the ready
-     * state is `CONNECTING` or `CLOSED`.
-     */
-    resume(): void
-
-    // HTML5 WebSocket events
-    addEventListener(
-    method: 'message',
-    cb: (event: WebSocket_2.MessageEvent) => void,
-    options?: WebSocket_2.EventListenerOptions
-    ): void
-    addEventListener(
-    method: 'close',
-    cb: (event: WebSocket_2.CloseEvent) => void,
-    options?: WebSocket_2.EventListenerOptions
-    ): void
-    addEventListener(
-    method: 'error',
-    cb: (event: WebSocket_2.ErrorEvent) => void,
-    options?: WebSocket_2.EventListenerOptions
-    ): void
-    addEventListener(
-    method: 'open',
-    cb: (event: WebSocket_2.Event) => void,
-    options?: WebSocket_2.EventListenerOptions
-    ): void
-
-    removeEventListener(
-    method: 'message',
-    cb: (event: WebSocket_2.MessageEvent) => void
-    ): void
-    removeEventListener(
-    method: 'close',
-    cb: (event: WebSocket_2.CloseEvent) => void
-    ): void
-    removeEventListener(
-    method: 'error',
-    cb: (event: WebSocket_2.ErrorEvent) => void
-    ): void
-    removeEventListener(
-    method: 'open',
-    cb: (event: WebSocket_2.Event) => void
-    ): void
-
-    // Events
-    on(
-    event: 'close',
-    listener: (this: WebSocket_2, code: number, reason: Buffer) => void
-    ): this
-    on(event: 'error', listener: (this: WebSocket_2, err: Error) => void): this
-    on(
-    event: 'upgrade',
-    listener: (this: WebSocket_2, request: IncomingMessage) => void
-    ): this
-    on(
-    event: 'message',
-    listener: (
-    this: WebSocket_2,
-    data: WebSocket_2.RawData,
-    isBinary: boolean
-    ) => void
-    ): this
-    on(event: 'open', listener: (this: WebSocket_2) => void): this
-    on(
-    event: 'ping' | 'pong',
-    listener: (this: WebSocket_2, data: Buffer) => void
-    ): this
-    on(
-    event: 'unexpected-response',
-    listener: (
-    this: WebSocket_2,
-    request: ClientRequest,
-    response: IncomingMessage
-    ) => void
-    ): this
-    on(
-    event: string | symbol,
-    listener: (this: WebSocket_2, ...args: any[]) => void
-    ): this
-
-    once(
-    event: 'close',
-    listener: (this: WebSocket_2, code: number, reason: Buffer) => void
-    ): this
-    once(event: 'error', listener: (this: WebSocket_2, err: Error) => void): this
-    once(
-    event: 'upgrade',
-    listener: (this: WebSocket_2, request: IncomingMessage) => void
-    ): this
-    once(
-    event: 'message',
-    listener: (
-    this: WebSocket_2,
-    data: WebSocket_2.RawData,
-    isBinary: boolean
-    ) => void
-    ): this
-    once(event: 'open', listener: (this: WebSocket_2) => void): this
-    once(
-    event: 'ping' | 'pong',
-    listener: (this: WebSocket_2, data: Buffer) => void
-    ): this
-    once(
-    event: 'unexpected-response',
-    listener: (
-    this: WebSocket_2,
-    request: ClientRequest,
-    response: IncomingMessage
-    ) => void
-    ): this
-    once(
-    event: string | symbol,
-    listener: (this: WebSocket_2, ...args: any[]) => void
-    ): this
-
-    off(
-    event: 'close',
-    listener: (this: WebSocket_2, code: number, reason: Buffer) => void
-    ): this
-    off(event: 'error', listener: (this: WebSocket_2, err: Error) => void): this
-    off(
-    event: 'upgrade',
-    listener: (this: WebSocket_2, request: IncomingMessage) => void
-    ): this
-    off(
-    event: 'message',
-    listener: (
-    this: WebSocket_2,
-    data: WebSocket_2.RawData,
-    isBinary: boolean
-    ) => void
-    ): this
-    off(event: 'open', listener: (this: WebSocket_2) => void): this
-    off(
-    event: 'ping' | 'pong',
-    listener: (this: WebSocket_2, data: Buffer) => void
-    ): this
-    off(
-    event: 'unexpected-response',
-    listener: (
-    this: WebSocket_2,
-    request: ClientRequest,
-    response: IncomingMessage
-    ) => void
-    ): this
-    off(
-    event: string | symbol,
-    listener: (this: WebSocket_2, ...args: any[]) => void
-    ): this
-
-    addListener(
-    event: 'close',
-    listener: (code: number, reason: Buffer) => void
-    ): this
-    addListener(event: 'error', listener: (err: Error) => void): this
-    addListener(
-    event: 'upgrade',
-    listener: (request: IncomingMessage) => void
-    ): this
-    addListener(
-    event: 'message',
-    listener: (data: WebSocket_2.RawData, isBinary: boolean) => void
-    ): this
-    addListener(event: 'open', listener: () => void): this
-    addListener(event: 'ping' | 'pong', listener: (data: Buffer) => void): this
-    addListener(
-    event: 'unexpected-response',
-    listener: (request: ClientRequest, response: IncomingMessage) => void
-    ): this
-    addListener(event: string | symbol, listener: (...args: any[]) => void): this
-
-    removeListener(
-    event: 'close',
-    listener: (code: number, reason: Buffer) => void
-    ): this
-    removeListener(event: 'error', listener: (err: Error) => void): this
-    removeListener(
-    event: 'upgrade',
-    listener: (request: IncomingMessage) => void
-    ): this
-    removeListener(
-    event: 'message',
-    listener: (data: WebSocket_2.RawData, isBinary: boolean) => void
-    ): this
-    removeListener(event: 'open', listener: () => void): this
-    removeListener(event: 'ping' | 'pong', listener: (data: Buffer) => void): this
-    removeListener(
-    event: 'unexpected-response',
-    listener: (request: ClientRequest, response: IncomingMessage) => void
-    ): this
-    removeListener(
-    event: string | symbol,
-    listener: (...args: any[]) => void
-    ): this
-}
-
-declare namespace WebSocket_2 {
-    /**
-     * Data represents the raw message payload received over the WebSocket.
-     */
-    type RawData = Buffer | ArrayBuffer | Buffer[]
-
-    /**
-     * Data represents the message payload received over the WebSocket.
-     */
-    type Data = string | Buffer | ArrayBuffer | Buffer[]
-
-    /**
-     * CertMeta represents the accepted types for certificate & key data.
-     */
-    type CertMeta = string | string[] | Buffer | Buffer[]
-
-    /**
-     * VerifyClientCallbackSync is a synchronous callback used to inspect the
-     * incoming message. The return value (boolean) of the function determines
-     * whether or not to accept the handshake.
-     */
-    type VerifyClientCallbackSync = (info: {
-        origin: string
-        secure: boolean
-        req: IncomingMessage
-    }) => boolean
-
-    /**
-     * VerifyClientCallbackAsync is an asynchronous callback used to inspect the
-     * incoming message. The return value (boolean) of the function determines
-     * whether or not to accept the handshake.
-     */
-    type VerifyClientCallbackAsync = (
-    info: { origin: string; secure: boolean; req: IncomingMessage },
-    callback: (
-    res: boolean,
-    code?: number,
-    message?: string,
-    headers?: OutgoingHttpHeaders
-    ) => void
-    ) => void
-
-    interface ClientOptions extends SecureContextOptions {
-        protocol?: string | undefined
-        followRedirects?: boolean | undefined
-        generateMask?(mask: Buffer): void
-        handshakeTimeout?: number | undefined
-        maxRedirects?: number | undefined
-        perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined
-        localAddress?: string | undefined
-        protocolVersion?: number | undefined
-        headers?: { [key: string]: string } | undefined
-        origin?: string | undefined
-        agent?: Agent | undefined
-        host?: string | undefined
-        family?: number | undefined
-        checkServerIdentity?(servername: string, cert: CertMeta): boolean
-        rejectUnauthorized?: boolean | undefined
-        maxPayload?: number | undefined
-        skipUTF8Validation?: boolean | undefined
-    }
-
-    interface PerMessageDeflateOptions {
-        serverNoContextTakeover?: boolean | undefined
-        clientNoContextTakeover?: boolean | undefined
-        serverMaxWindowBits?: number | undefined
-        clientMaxWindowBits?: number | undefined
-        zlibDeflateOptions?:
-        | {
-            flush?: number | undefined
-            finishFlush?: number | undefined
-            chunkSize?: number | undefined
-            windowBits?: number | undefined
-            level?: number | undefined
-            memLevel?: number | undefined
-            strategy?: number | undefined
-            dictionary?: Buffer | Buffer[] | DataView | undefined
-            info?: boolean | undefined
-        }
-        | undefined
-        zlibInflateOptions?: ZlibOptions | undefined
-        threshold?: number | undefined
-        concurrencyLimit?: number | undefined
-    }
-
-    interface Event {
-        type: string
-        target: WebSocket
-    }
-
-    interface ErrorEvent {
-        error: any
-        message: string
-        type: string
-        target: WebSocket
-    }
-
-    interface CloseEvent {
-        wasClean: boolean
-        code: number
-        reason: string
-        type: string
-        target: WebSocket
-    }
-
-    interface MessageEvent {
-        data: Data
-        type: string
-        target: WebSocket
-    }
-
-    interface EventListenerOptions {
-        once?: boolean | undefined
-    }
-
-    interface ServerOptions {
-        host?: string | undefined
-        port?: number | undefined
-        backlog?: number | undefined
-        server?: Server | Server_2 | undefined
-        verifyClient?:
-        | VerifyClientCallbackAsync
-        | VerifyClientCallbackSync
-        | undefined
-        handleProtocols?: (
-        protocols: Set<string>,
-        request: IncomingMessage
-        ) => string | false
-        path?: string | undefined
-        noServer?: boolean | undefined
-        clientTracking?: boolean | undefined
-        perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined
-        maxPayload?: number | undefined
-        skipUTF8Validation?: boolean | undefined
-        WebSocket?: typeof WebSocket.WebSocket | undefined
-    }
-
-    interface AddressInfo {
-        address: string
-        family: string
-        port: number
-    }
-
-    // WebSocket Server
-    class Server<T extends WebSocket = WebSocket> extends EventEmitter {
-        options: ServerOptions
-        path: string
-        clients: Set<T>
-
-        constructor(options?: ServerOptions, callback?: () => void)
-
-        address(): AddressInfo | string
-        close(cb?: (err?: Error) => void): void
-        handleUpgrade(
-        request: IncomingMessage,
-        socket: Duplex,
-        upgradeHead: Buffer,
-        callback: (client: T, request: IncomingMessage) => void
-        ): void
-        shouldHandle(request: IncomingMessage): boolean | Promise<boolean>
-
-        // Events
-        on(
-        event: 'connection',
-        cb: (this: Server<T>, socket: T, request: IncomingMessage) => void
-        ): this
-        on(event: 'error', cb: (this: Server<T>, error: Error) => void): this
-        on(
-        event: 'headers',
-        cb: (this: Server<T>, headers: string[], request: IncomingMessage) => void
-        ): this
-        on(event: 'close' | 'listening', cb: (this: Server<T>) => void): this
-        on(
-        event: string | symbol,
-        listener: (this: Server<T>, ...args: any[]) => void
-        ): this
-
-        once(
-        event: 'connection',
-        cb: (this: Server<T>, socket: T, request: IncomingMessage) => void
-        ): this
-        once(event: 'error', cb: (this: Server<T>, error: Error) => void): this
-        once(
-        event: 'headers',
-        cb: (this: Server<T>, headers: string[], request: IncomingMessage) => void
-        ): this
-        once(event: 'close' | 'listening', cb: (this: Server<T>) => void): this
-        once(
-        event: string | symbol,
-        listener: (this: Server<T>, ...args: any[]) => void
-        ): this
-
-        off(
-        event: 'connection',
-        cb: (this: Server<T>, socket: T, request: IncomingMessage) => void
-        ): this
-        off(event: 'error', cb: (this: Server<T>, error: Error) => void): this
-        off(
-        event: 'headers',
-        cb: (this: Server<T>, headers: string[], request: IncomingMessage) => void
-        ): this
-        off(event: 'close' | 'listening', cb: (this: Server<T>) => void): this
-        off(
-        event: string | symbol,
-        listener: (this: Server<T>, ...args: any[]) => void
-        ): this
-
-        addListener(
-        event: 'connection',
-        cb: (client: T, request: IncomingMessage) => void
-        ): this
-        addListener(event: 'error', cb: (err: Error) => void): this
-        addListener(
-        event: 'headers',
-        cb: (headers: string[], request: IncomingMessage) => void
-        ): this
-        addListener(event: 'close' | 'listening', cb: () => void): this
-        addListener(
-        event: string | symbol,
-        listener: (...args: any[]) => void
-        ): this
-
-        removeListener(event: 'connection', cb: (client: T) => void): this
-        removeListener(event: 'error', cb: (err: Error) => void): this
-        removeListener(
-        event: 'headers',
-        cb: (headers: string[], request: IncomingMessage) => void
-        ): this
-        removeListener(event: 'close' | 'listening', cb: () => void): this
-        removeListener(
-        event: string | symbol,
-        listener: (...args: any[]) => void
-        ): this
-    }
-
-    const WebSocketServer: typeof Server
-    interface WebSocketServer extends Server {} // tslint:disable-line no-empty-interface
-    const WebSocket: typeof WebSocketAlias
-    interface WebSocket extends WebSocketAlias {} // tslint:disable-line no-empty-interface
-
-    // WebSocket stream
-    function createWebSocketStream(
-    websocket: WebSocket,
-    options?: DuplexOptions
-    ): Duplex
-}
-export { WebSocket_2 as WebSocket }
-
-export declare const WebSocketAlias: typeof WebSocket_2;
-
-export declare interface WebSocketAlias extends WebSocket_2 {}
-
-export declare interface WebSocketClient {
-    /**
-     * Send event to the client
-     */
-    send(payload: HMRPayload): void;
-    /**
-     * Send custom event
-     */
-    send(event: string, payload?: CustomPayload['data']): void;
-    /**
-     * The raw WebSocket instance
-     * @advanced
-     */
-    socket: WebSocket_2;
-}
-
-export declare type WebSocketCustomListener<T> = (data: T, client: WebSocketClient) => void;
-
-export declare interface WebSocketServer {
-    /**
-     * Get all connected clients.
-     */
-    clients: Set<WebSocketClient>;
-    /**
-     * Broadcast events to all clients
-     */
-    send(payload: HMRPayload): void;
-    /**
-     * Send custom event
-     */
-    send<T extends string>(event: T, payload?: InferCustomEventPayload<T>): void;
-    /**
-     * Disconnect all clients and terminate the server.
-     */
-    close(): Promise<void>;
-    /**
-     * Handle custom event emitted by `import.meta.hot.send`
-     */
-    on: WebSocket_2.Server['on'] & {
-        <T extends string>(event: T, listener: WebSocketCustomListener<InferCustomEventPayload<T>>): void;
-    };
-    /**
-     * Unregister event listener.
-     */
-    off: WebSocket_2.Server['off'] & {
-        (event: string, listener: Function): void;
-    };
-}
-
-export { }
+/// <reference types="node" />
+
+import type { Agent } from 'node:http';
+import type { BuildOptions as BuildOptions_2 } from 'esbuild';
+import type { ClientRequest } from 'node:http';
+import type { ClientRequestArgs } from 'node:http';
+import type { CustomPluginOptions } from 'rollup';
+import type { Duplex } from 'node:stream';
+import type { DuplexOptions } from 'node:stream';
+import { TransformOptions as EsbuildTransformOptions } from 'esbuild';
+import { version as esbuildVersion } from 'esbuild';
+import { EventEmitter } from 'node:events';
+import * as events from 'node:events';
+import type { ExistingRawSourceMap } from 'rollup';
+import type * as fs from 'node:fs';
+import type { GetManualChunk } from 'rollup';
+import * as http from 'node:http';
+import type { IncomingMessage } from 'node:http';
+import type { InputOptions } from 'rollup';
+import type { LoadResult } from 'rollup';
+import type { ModuleFormat } from 'rollup';
+import type { ModuleInfo } from 'rollup';
+import type * as net from 'node:net';
+import type { OutgoingHttpHeaders } from 'node:http';
+import type { OutputBundle } from 'rollup';
+import type { OutputChunk } from 'rollup';
+import type { PartialResolvedId } from 'rollup';
+import type { Plugin as Plugin_3 } from 'rollup';
+import type { PluginContext } from 'rollup';
+import type { PluginHooks } from 'rollup';
+import type * as PostCSS from 'postcss';
+import type { ResolveIdResult } from 'rollup';
+import type { RollupError } from 'rollup';
+import type { RollupOptions } from 'rollup';
+import type { RollupOutput } from 'rollup';
+import { VERSION as rollupVersion } from 'rollup';
+import type { RollupWatcher } from 'rollup';
+import type { SecureContextOptions } from 'node:tls';
+import type { Server } from 'node:http';
+import type { Server as Server_2 } from 'node:https';
+import type { ServerOptions as ServerOptions_2 } from 'node:https';
+import type { ServerResponse } from 'node:http';
+import type { SourceDescription } from 'rollup';
+import type { SourceMap } from 'rollup';
+import type * as stream from 'node:stream';
+import type { TransformPluginContext } from 'rollup';
+import type { TransformResult as TransformResult_2 } from 'rollup';
+import type { TransformResult as TransformResult_3 } from 'esbuild';
+import type * as url from 'node:url';
+import type { URL as URL_2 } from 'node:url';
+import type { WatcherOptions } from 'rollup';
+import type { ZlibOptions } from 'node:zlib';
+
+export declare interface Alias {
+    find: string | RegExp
+    replacement: string
+    /**
+     * Instructs the plugin to use an alternative resolving algorithm,
+     * rather than the Rollup's resolver.
+     * @default null
+     */
+    customResolver?: ResolverFunction | ResolverObject | null
+}
+
+/**
+ * Specifies an `Object`, or an `Array` of `Object`,
+ * which defines aliases used to replace values in `import` or `require` statements.
+ * With either format, the order of the entries is important,
+ * in that the first defined rules are applied first.
+ *
+ * This is passed to \@rollup/plugin-alias as the "entries" field
+ * https://github.com/rollup/plugins/tree/master/packages/alias#entries
+ */
+export declare type AliasOptions = readonly Alias[] | { [find: string]: string }
+
+export declare type AnymatchFn = (testString: string) => boolean
+
+export declare type AnymatchPattern = string | RegExp | AnymatchFn
+
+/**
+ * spa: include SPA fallback middleware and configure sirv with `single: true` in preview
+ *
+ * mpa: only include non-SPA HTML middlewares
+ *
+ * custom: don't include HTML middlewares
+ */
+export declare type AppType = 'spa' | 'mpa' | 'custom';
+
+export declare interface AwaitWriteFinishOptions {
+    /**
+     * Amount of time in milliseconds for a file size to remain constant before emitting its event.
+     */
+    stabilityThreshold?: number
+
+    /**
+     * File size polling interval.
+     */
+    pollInterval?: number
+}
+
+/**
+ * Bundles the app for production.
+ * Returns a Promise containing the build result.
+ */
+export declare function build(inlineConfig?: InlineConfig): Promise<RollupOutput | RollupOutput[] | RollupWatcher>;
+
+export declare interface BuildOptions {
+    /**
+     * Compatibility transform target. The transform is performed with esbuild
+     * and the lowest supported target is es2015/es6. Note this only handles
+     * syntax transformation and does not cover polyfills (except for dynamic
+     * import)
+     *
+     * Default: 'modules' - Similar to `@babel/preset-env`'s targets.esmodules,
+     * transpile targeting browsers that natively support dynamic es module imports.
+     * https://caniuse.com/es6-module-dynamic-import
+     *
+     * Another special value is 'esnext' - which only performs minimal transpiling
+     * (for minification compat) and assumes native dynamic imports support.
+     *
+     * For custom targets, see https://esbuild.github.io/api/#target and
+     * https://esbuild.github.io/content-types/#javascript for more details.
+     */
+    target?: 'modules' | EsbuildTransformOptions['target'] | false;
+    /**
+     * whether to inject module preload polyfill.
+     * Note: does not apply to library mode.
+     * @default true
+     */
+    polyfillModulePreload?: boolean;
+    /**
+     * Directory relative from `root` where build output will be placed. If the
+     * directory exists, it will be removed before the build.
+     * @default 'dist'
+     */
+    outDir?: string;
+    /**
+     * Directory relative from `outDir` where the built js/css/image assets will
+     * be placed.
+     * @default 'assets'
+     */
+    assetsDir?: string;
+    /**
+     * Static asset files smaller than this number (in bytes) will be inlined as
+     * base64 strings. Default limit is `4096` (4kb). Set to `0` to disable.
+     * @default 4096
+     */
+    assetsInlineLimit?: number;
+    /**
+     * Whether to code-split CSS. When enabled, CSS in async chunks will be
+     * inlined as strings in the chunk and inserted via dynamically created
+     * style tags when the chunk is loaded.
+     * @default true
+     */
+    cssCodeSplit?: boolean;
+    /**
+     * An optional separate target for CSS minification.
+     * As esbuild only supports configuring targets to mainstream
+     * browsers, users may need this option when they are targeting
+     * a niche browser that comes with most modern JavaScript features
+     * but has poor CSS support, e.g. Android WeChat WebView, which
+     * doesn't support the #RGBA syntax.
+     */
+    cssTarget?: EsbuildTransformOptions['target'] | false;
+    /**
+     * If `true`, a separate sourcemap file will be created. If 'inline', the
+     * sourcemap will be appended to the resulting output file as data URI.
+     * 'hidden' works like `true` except that the corresponding sourcemap
+     * comments in the bundled files are suppressed.
+     * @default false
+     */
+    sourcemap?: boolean | 'inline' | 'hidden';
+    /**
+     * Set to `false` to disable minification, or specify the minifier to use.
+     * Available options are 'terser' or 'esbuild'.
+     * @default 'esbuild'
+     */
+    minify?: boolean | 'terser' | 'esbuild';
+    /**
+     * Options for terser
+     * https://terser.org/docs/api-reference#minify-options
+     */
+    terserOptions?: Terser.MinifyOptions;
+    /**
+     * Will be merged with internal rollup options.
+     * https://rollupjs.org/guide/en/#big-list-of-options
+     */
+    rollupOptions?: RollupOptions;
+    /**
+     * Options to pass on to `@rollup/plugin-commonjs`
+     */
+    commonjsOptions?: RollupCommonJSOptions;
+    /**
+     * Options to pass on to `@rollup/plugin-dynamic-import-vars`
+     */
+    dynamicImportVarsOptions?: RollupDynamicImportVarsOptions;
+    /**
+     * Whether to write bundle to disk
+     * @default true
+     */
+    write?: boolean;
+    /**
+     * Empty outDir on write.
+     * @default true when outDir is a sub directory of project root
+     */
+    emptyOutDir?: boolean | null;
+    /**
+     * Whether to emit a manifest.json under assets dir to map hash-less filenames
+     * to their hashed versions. Useful when you want to generate your own HTML
+     * instead of using the one generated by Vite.
+     *
+     * Example:
+     *
+     * ```json
+     * {
+     *   "main.js": {
+     *     "file": "main.68fe3fad.js",
+     *     "css": "main.e6b63442.css",
+     *     "imports": [...],
+     *     "dynamicImports": [...]
+     *   }
+     * }
+     * ```
+     * @default false
+     */
+    manifest?: boolean | string;
+    /**
+     * Build in library mode. The value should be the global name of the lib in
+     * UMD mode. This will produce esm + cjs + umd bundle formats with default
+     * configurations that are suitable for distributing libraries.
+     */
+    lib?: LibraryOptions | false;
+    /**
+     * Produce SSR oriented build. Note this requires specifying SSR entry via
+     * `rollupOptions.input`.
+     */
+    ssr?: boolean | string;
+    /**
+     * Generate SSR manifest for determining style links and asset preload
+     * directives in production.
+     */
+    ssrManifest?: boolean | string;
+    /**
+     * Set to false to disable reporting compressed chunk sizes.
+     * Can slightly improve build speed.
+     */
+    reportCompressedSize?: boolean;
+    /**
+     * Adjust chunk size warning limit (in kbs).
+     * @default 500
+     */
+    chunkSizeWarningLimit?: number;
+    /**
+     * Rollup watch options
+     * https://rollupjs.org/guide/en/#watchoptions
+     */
+    watch?: WatcherOptions | null;
+}
+
+export declare interface ChunkMetadata {
+    importedAssets: Set<string>;
+    importedCss: Set<string>;
+}
+
+export declare interface CommonServerOptions {
+    /**
+     * Specify server port. Note if the port is already being used, Vite will
+     * automatically try the next available port so this may not be the actual
+     * port the server ends up listening on.
+     */
+    port?: number;
+    /**
+     * If enabled, vite will exit if specified port is already in use
+     */
+    strictPort?: boolean;
+    /**
+     * Specify which IP addresses the server should listen on.
+     * Set to 0.0.0.0 to listen on all addresses, including LAN and public addresses.
+     */
+    host?: string | boolean;
+    /**
+     * Enable TLS + HTTP/2.
+     * Note: this downgrades to TLS only when the proxy option is also used.
+     */
+    https?: boolean | ServerOptions_2;
+    /**
+     * Open browser window on startup
+     */
+    open?: boolean | string;
+    /**
+     * Configure custom proxy rules for the dev server. Expects an object
+     * of `{ key: options }` pairs.
+     * Uses [`http-proxy`](https://github.com/http-party/node-http-proxy).
+     * Full options [here](https://github.com/http-party/node-http-proxy#options).
+     *
+     * Example `vite.config.js`:
+     * ``` js
+     * module.exports = {
+     *   proxy: {
+     *     // string shorthand
+     *     '/foo': 'http://localhost:4567/foo',
+     *     // with options
+     *     '/api': {
+     *       target: 'http://jsonplaceholder.typicode.com',
+     *       changeOrigin: true,
+     *       rewrite: path => path.replace(/^\/api/, '')
+     *     }
+     *   }
+     * }
+     * ```
+     */
+    proxy?: Record<string, string | ProxyOptions>;
+    /**
+     * Configure CORS for the dev server.
+     * Uses https://github.com/expressjs/cors.
+     * Set to `true` to allow all methods from any origin, or configure separately
+     * using an object.
+     */
+    cors?: CorsOptions | boolean;
+    /**
+     * Specify server response headers.
+     */
+    headers?: OutgoingHttpHeaders;
+}
+
+export declare interface ConfigEnv {
+    command: 'build' | 'serve';
+    mode: string;
+    /**
+     * @experimental
+     */
+    ssrBuild?: boolean;
+}
+
+export declare namespace Connect {
+    export type ServerHandle = HandleFunction | http.Server
+
+    export class IncomingMessage extends http.IncomingMessage {
+        originalUrl?: http.IncomingMessage['url'] | undefined
+    }
+
+    export type NextFunction = (err?: any) => void
+
+    export type SimpleHandleFunction = (
+    req: IncomingMessage,
+    res: http.ServerResponse
+    ) => void
+    export type NextHandleFunction = (
+    req: IncomingMessage,
+    res: http.ServerResponse,
+    next: NextFunction
+    ) => void
+    export type ErrorHandleFunction = (
+    err: any,
+    req: IncomingMessage,
+    res: http.ServerResponse,
+    next: NextFunction
+    ) => void
+    export type HandleFunction =
+    | SimpleHandleFunction
+    | NextHandleFunction
+    | ErrorHandleFunction
+
+    export interface ServerStackItem {
+        route: string
+        handle: ServerHandle
+    }
+
+    export interface Server extends NodeJS.EventEmitter {
+        (req: http.IncomingMessage, res: http.ServerResponse, next?: Function): void
+
+        route: string
+        stack: ServerStackItem[]
+
+        /**
+         * Utilize the given middleware `handle` to the given `route`,
+         * defaulting to _/_. This "route" is the mount-point for the
+         * middleware, when given a value other than _/_ the middleware
+         * is only effective when that segment is present in the request's
+         * pathname.
+         *
+         * For example if we were to mount a function at _/admin_, it would
+         * be invoked on _/admin_, and _/admin/settings_, however it would
+         * not be invoked for _/_, or _/posts_.
+         */
+        use(fn: NextHandleFunction): Server
+        use(fn: HandleFunction): Server
+        use(route: string, fn: NextHandleFunction): Server
+        use(route: string, fn: HandleFunction): Server
+
+        /**
+         * Handle server requests, punting them down
+         * the middleware stack.
+         */
+        handle(
+        req: http.IncomingMessage,
+        res: http.ServerResponse,
+        next: Function
+        ): void
+
+        /**
+         * Listen for connections.
+         *
+         * This method takes the same arguments
+         * as node's `http.Server#listen()`.
+         *
+         * HTTP and HTTPS:
+         *
+         * If you run your application both as HTTP
+         * and HTTPS you may wrap them individually,
+         * since your Connect "server" is really just
+         * a JavaScript `Function`.
+         *
+         *      var connect = require('connect')
+         *        , http = require('http')
+         *        , https = require('https');
+         *
+         *      var app = connect();
+         *
+         *      http.createServer(app).listen(80);
+         *      https.createServer(options, app).listen(443);
+         */
+        listen(
+        port: number,
+        hostname?: string,
+        backlog?: number,
+        callback?: Function
+        ): http.Server
+        listen(port: number, hostname?: string, callback?: Function): http.Server
+        listen(path: string, callback?: Function): http.Server
+        listen(handle: any, listeningListener?: Function): http.Server
+    }
+}
+
+export declare interface ConnectedPayload {
+    type: 'connected'
+}
+
+/**
+ * https://github.com/expressjs/cors#configuration-options
+ */
+export declare interface CorsOptions {
+    origin?: CorsOrigin | ((origin: string, cb: (err: Error, origins: CorsOrigin) => void) => void);
+    methods?: string | string[];
+    allowedHeaders?: string | string[];
+    exposedHeaders?: string | string[];
+    credentials?: boolean;
+    maxAge?: number;
+    preflightContinue?: boolean;
+    optionsSuccessStatus?: number;
+}
+
+export declare type CorsOrigin = boolean | string | RegExp | (string | RegExp)[];
+
+export declare const createFilter: (include?: FilterPattern | undefined, exclude?: FilterPattern | undefined, options?: {
+    resolve?: string | false | null | undefined;
+} | undefined) => (id: string | unknown) => boolean;
+
+export declare function createLogger(level?: LogLevel, options?: LoggerOptions): Logger;
+
+export declare function createServer(inlineConfig?: InlineConfig): Promise<ViteDevServer>;
+
+export declare interface CSSModulesOptions {
+    getJSON?: (cssFileName: string, json: Record<string, string>, outputFileName: string) => void;
+    scopeBehaviour?: 'global' | 'local';
+    globalModulePaths?: RegExp[];
+    generateScopedName?: string | ((name: string, filename: string, css: string) => string);
+    hashPrefix?: string;
+    /**
+     * default: null
+     */
+    localsConvention?: 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly' | null;
+}
+
+export declare interface CSSOptions {
+    /**
+     * https://github.com/css-modules/postcss-modules
+     */
+    modules?: CSSModulesOptions | false;
+    preprocessorOptions?: Record<string, any>;
+    postcss?: string | (PostCSS.ProcessOptions & {
+        plugins?: PostCSS.AcceptedPlugin[];
+    });
+    /**
+     * Enables css sourcemaps during dev
+     * @default false
+     * @experimental
+     */
+    devSourcemap?: boolean;
+}
+
+export declare interface CustomEventMap {
+    'vite:beforeUpdate': UpdatePayload
+    'vite:beforePrune': PrunePayload
+    'vite:beforeFullReload': FullReloadPayload
+    'vite:error': ErrorPayload
+}
+
+export declare interface CustomPayload {
+    type: 'custom'
+    event: string
+    data?: any
+}
+
+/**
+ * Type helper to make it easier to use vite.config.ts
+ * accepts a direct {@link UserConfig} object, or a function that returns it.
+ * The function receives a {@link ConfigEnv} object that exposes two properties:
+ * `command` (either `'build'` or `'serve'`), and `mode`.
+ */
+export declare function defineConfig(config: UserConfigExport): UserConfigExport;
+
+export declare interface DepOptimizationConfig {
+    /**
+     * Force optimize listed dependencies (must be resolvable import paths,
+     * cannot be globs).
+     */
+    include?: string[];
+    /**
+     * Do not optimize these dependencies (must be resolvable import paths,
+     * cannot be globs).
+     */
+    exclude?: string[];
+    /**
+     * Force ESM interop when importing for these dependencies. Some legacy
+     * packages advertise themselves as ESM but use `require` internally
+     * @experimental
+     */
+    needsInterop?: string[];
+    /**
+     * Options to pass to esbuild during the dep scanning and optimization
+     *
+     * Certain options are omitted since changing them would not be compatible
+     * with Vite's dep optimization.
+     *
+     * - `external` is also omitted, use Vite's `optimizeDeps.exclude` option
+     * - `plugins` are merged with Vite's dep plugin
+     *
+     * https://esbuild.github.io/api
+     */
+    esbuildOptions?: Omit<BuildOptions_2, 'bundle' | 'entryPoints' | 'external' | 'write' | 'watch' | 'outdir' | 'outfile' | 'outbase' | 'outExtension' | 'metafile'>;
+    /**
+     * List of file extensions that can be optimized. A corresponding esbuild
+     * plugin must exist to handle the specific extension.
+     *
+     * By default, Vite can optimize `.mjs`, `.js`, `.ts`, and `.mts` files. This option
+     * allows specifying additional extensions.
+     *
+     * @experimental
+     */
+    extensions?: string[];
+    /**
+     * Disables dependencies optimizations, true disables the optimizer during
+     * build and dev. Pass 'build' or 'dev' to only disable the optimizer in
+     * one of the modes. Deps optimization is enabled by default in dev only.
+     * @default 'build'
+     * @experimental
+     */
+    disabled?: boolean | 'build' | 'dev';
+}
+
+export declare interface DepOptimizationMetadata {
+    /**
+     * The main hash is determined by user config and dependency lockfiles.
+     * This is checked on server startup to avoid unnecessary re-bundles.
+     */
+    hash: string;
+    /**
+     * The browser hash is determined by the main hash plus additional dependencies
+     * discovered at runtime. This is used to invalidate browser requests to
+     * optimized deps.
+     */
+    browserHash: string;
+    /**
+     * Metadata for each already optimized dependency
+     */
+    optimized: Record<string, OptimizedDepInfo>;
+    /**
+     * Metadata for non-entry optimized chunks and dynamic imports
+     */
+    chunks: Record<string, OptimizedDepInfo>;
+    /**
+     * Metadata for each newly discovered dependency after processing
+     */
+    discovered: Record<string, OptimizedDepInfo>;
+    /**
+     * OptimizedDepInfo list
+     */
+    depInfoList: OptimizedDepInfo[];
+}
+
+export declare type DepOptimizationOptions = DepOptimizationConfig & {
+    /**
+     * By default, Vite will crawl your `index.html` to detect dependencies that
+     * need to be pre-bundled. If `build.rollupOptions.input` is specified, Vite
+     * will crawl those entry points instead.
+     *
+     * If neither of these fit your needs, you can specify custom entries using
+     * this option - the value should be a fast-glob pattern or array of patterns
+     * (https://github.com/mrmlnc/fast-glob#basic-syntax) that are relative from
+     * vite project root. This will overwrite default entries inference.
+     */
+    entries?: string | string[];
+    /**
+     * Force dep pre-optimization regardless of whether deps have changed.
+     * @experimental
+     */
+    force?: boolean;
+};
+
+export declare interface DepOptimizationProcessing {
+    promise: Promise<void>;
+    resolve: () => void;
+}
+
+export declare interface DepOptimizationResult {
+    metadata: DepOptimizationMetadata;
+    /**
+     * When doing a re-run, if there are newly discovered dependencies
+     * the page reload will be delayed until the next rerun so we need
+     * to be able to discard the result
+     */
+    commit: () => Promise<void>;
+    cancel: () => void;
+}
+
+export declare interface DepsOptimizer {
+    metadata: DepOptimizationMetadata;
+    scanProcessing?: Promise<void>;
+    registerMissingImport: (id: string, resolved: string) => OptimizedDepInfo;
+    run: () => void;
+    isOptimizedDepFile: (id: string) => boolean;
+    isOptimizedDepUrl: (url: string) => boolean;
+    getOptimizedDepId: (depInfo: OptimizedDepInfo) => string;
+    delayDepsOptimizerUntil: (id: string, done: () => Promise<any>) => void;
+    registerWorkersSource: (id: string) => void;
+    resetRegisteredIds: () => void;
+    ensureFirstRun: () => void;
+    options: DepOptimizationOptions;
+}
+
+export declare interface ErrorPayload {
+    type: 'error'
+    err: {
+        [name: string]: any
+        message: string
+        stack: string
+        id?: string
+        frame?: string
+        plugin?: string
+        pluginCode?: string
+        loc?: {
+            file?: string
+            line: number
+            column: number
+        }
+    }
+}
+
+export declare interface ESBuildOptions extends EsbuildTransformOptions {
+    include?: string | RegExp | string[] | RegExp[];
+    exclude?: string | RegExp | string[] | RegExp[];
+    jsxInject?: string;
+    /**
+     * This option is not respected. Use `build.minify` instead.
+     */
+    minify?: never;
+}
+
+export { EsbuildTransformOptions }
+
+export declare type ESBuildTransformResult = Omit<TransformResult_3, 'map'> & {
+    map: SourceMap;
+};
+
+export { esbuildVersion }
+
+export declare interface ExperimentalOptions {
+    /**
+     * Append fake `&lang.(ext)` when queries are specified, to preserve the file extension for following plugins to process.
+     *
+     * @experimental
+     * @default false
+     */
+    importGlobRestoreExtension?: boolean;
+    /**
+     * Allow finegrain control over assets and public files paths
+     *
+     * @experimental
+     */
+    renderBuiltUrl?: RenderBuiltAssetUrl;
+    /**
+     * Enables support of HMR partial accept via `import.meta.hot.acceptExports`.
+     *
+     * @experimental
+     * @default false
+     */
+    hmrPartialAccept?: boolean;
+}
+
+export declare type ExportsData = {
+    hasImports: boolean;
+    exports: readonly string[];
+    facade: boolean;
+    hasReExports?: boolean;
+    jsxLoader?: boolean;
+};
+
+export declare interface FileSystemServeOptions {
+    /**
+     * Strictly restrict file accessing outside of allowing paths.
+     *
+     * Set to `false` to disable the warning
+     *
+     * @default true
+     */
+    strict?: boolean;
+    /**
+     * Restrict accessing files outside the allowed directories.
+     *
+     * Accepts absolute path or a path relative to project root.
+     * Will try to search up for workspace root by default.
+     */
+    allow?: string[];
+    /**
+     * Restrict accessing files that matches the patterns.
+     *
+     * This will have higher priority than `allow`.
+     * Glob patterns are supported.
+     *
+     * @default ['.env', '.env.*', '*.crt', '*.pem']
+     */
+    deny?: string[];
+}
+
+/**
+ * Inlined to keep `@rollup/pluginutils` in devDependencies
+ */
+export declare type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;
+
+export declare function formatPostcssSourceMap(rawMap: ExistingRawSourceMap, file: string): Promise<ExistingRawSourceMap>;
+
+export declare class FSWatcher extends EventEmitter implements fs.FSWatcher {
+    options: WatchOptions
+
+    /**
+     * Constructs a new FSWatcher instance with optional WatchOptions parameter.
+     */
+    constructor(options?: WatchOptions)
+
+    /**
+     * Add files, directories, or glob patterns for tracking. Takes an array of strings or just one
+     * string.
+     */
+    add(paths: string | ReadonlyArray<string>): this
+
+    /**
+     * Stop watching files, directories, or glob patterns. Takes an array of strings or just one
+     * string.
+     */
+    unwatch(paths: string | ReadonlyArray<string>): this
+
+    /**
+     * Returns an object representing all the paths on the file system being watched by this
+     * `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless
+     * the `cwd` option was used), and the values are arrays of the names of the items contained in
+     * each directory.
+     */
+    getWatched(): {
+        [directory: string]: string[]
+    }
+
+    /**
+     * Removes all listeners from watched files.
+     */
+    close(): Promise<void>
+
+    on(
+    event: 'add' | 'addDir' | 'change',
+    listener: (path: string, stats?: fs.Stats) => void
+    ): this
+
+    on(
+    event: 'all',
+    listener: (
+    eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir',
+    path: string,
+    stats?: fs.Stats
+    ) => void
+    ): this
+
+    /**
+     * Error occurred
+     */
+    on(event: 'error', listener: (error: Error) => void): this
+
+    /**
+     * Exposes the native Node `fs.FSWatcher events`
+     */
+    on(
+    event: 'raw',
+    listener: (eventName: string, path: string, details: any) => void
+    ): this
+
+    /**
+     * Fires when the initial scan is complete
+     */
+    on(event: 'ready', listener: () => void): this
+
+    on(event: 'unlink' | 'unlinkDir', listener: (path: string) => void): this
+
+    on(event: string, listener: (...args: any[]) => void): this
+}
+
+export declare interface FullReloadPayload {
+    type: 'full-reload'
+    path?: string
+}
+
+export declare function getDepOptimizationConfig(config: ResolvedConfig, ssr: boolean): DepOptimizationConfig;
+
+export declare interface HmrContext {
+    file: string;
+    timestamp: number;
+    modules: Array<ModuleNode>;
+    read: () => string | Promise<string>;
+    server: ViteDevServer;
+}
+
+export declare interface HmrOptions {
+    protocol?: string;
+    host?: string;
+    port?: number;
+    clientPort?: number;
+    path?: string;
+    timeout?: number;
+    overlay?: boolean;
+    server?: Server;
+}
+
+export declare type HMRPayload =
+| ConnectedPayload
+| UpdatePayload
+| FullReloadPayload
+| CustomPayload
+| ErrorPayload
+| PrunePayload
+
+export declare interface HtmlTagDescriptor {
+    tag: string;
+    attrs?: Record<string, string | boolean | undefined>;
+    children?: string | HtmlTagDescriptor[];
+    /**
+     * default: 'head-prepend'
+     */
+    injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend';
+}
+
+export declare namespace HttpProxy {
+    export type ProxyTarget = ProxyTargetUrl | ProxyTargetDetailed
+
+    export type ProxyTargetUrl = string | Partial<url.Url>
+
+    export interface ProxyTargetDetailed {
+        host: string
+        port: number
+        protocol?: string | undefined
+        hostname?: string | undefined
+        socketPath?: string | undefined
+        key?: string | undefined
+        passphrase?: string | undefined
+        pfx?: Buffer | string | undefined
+        cert?: string | undefined
+        ca?: string | undefined
+        ciphers?: string | undefined
+        secureProtocol?: string | undefined
+    }
+
+    export type ErrorCallback = (
+    err: Error,
+    req: http.IncomingMessage,
+    res: http.ServerResponse,
+    target?: ProxyTargetUrl
+    ) => void
+
+    export class Server extends events.EventEmitter {
+        /**
+         * Creates the proxy server with specified options.
+         * @param options - Config object passed to the proxy
+         */
+        constructor(options?: ServerOptions)
+
+        /**
+         * Used for proxying regular HTTP(S) requests
+         * @param req - Client request.
+         * @param res - Client response.
+         * @param options - Additional options.
+         */
+        web(
+        req: http.IncomingMessage,
+        res: http.ServerResponse,
+        options?: ServerOptions,
+        callback?: ErrorCallback
+        ): void
+
+        /**
+         * Used for proxying regular HTTP(S) requests
+         * @param req - Client request.
+         * @param socket - Client socket.
+         * @param head - Client head.
+         * @param options - Additional options.
+         */
+        ws(
+        req: http.IncomingMessage,
+        socket: unknown,
+        head: unknown,
+        options?: ServerOptions,
+        callback?: ErrorCallback
+        ): void
+
+        /**
+         * A function that wraps the object in a webserver, for your convenience
+         * @param port - Port to listen on
+         */
+        listen(port: number): Server
+
+        /**
+         * A function that closes the inner webserver and stops listening on given port
+         */
+        close(callback?: () => void): void
+
+        /**
+         * Creates the proxy server with specified options.
+         * @param options - Config object passed to the proxy
+         * @returns Proxy object with handlers for `ws` and `web` requests
+         */
+        static createProxyServer(options?: ServerOptions): Server
+
+        /**
+         * Creates the proxy server with specified options.
+         * @param options - Config object passed to the proxy
+         * @returns Proxy object with handlers for `ws` and `web` requests
+         */
+        static createServer(options?: ServerOptions): Server
+
+        /**
+         * Creates the proxy server with specified options.
+         * @param options - Config object passed to the proxy
+         * @returns Proxy object with handlers for `ws` and `web` requests
+         */
+        static createProxy(options?: ServerOptions): Server
+
+        addListener(event: string, listener: () => void): this
+        on(event: string, listener: () => void): this
+        on(event: 'error', listener: ErrorCallback): this
+        on(
+        event: 'start',
+        listener: (
+        req: http.IncomingMessage,
+        res: http.ServerResponse,
+        target: ProxyTargetUrl
+        ) => void
+        ): this
+        on(
+        event: 'proxyReq',
+        listener: (
+        proxyReq: http.ClientRequest,
+        req: http.IncomingMessage,
+        res: http.ServerResponse,
+        options: ServerOptions
+        ) => void
+        ): this
+        on(
+        event: 'proxyRes',
+        listener: (
+        proxyRes: http.IncomingMessage,
+        req: http.IncomingMessage,
+        res: http.ServerResponse
+        ) => void
+        ): this
+        on(
+        event: 'proxyReqWs',
+        listener: (
+        proxyReq: http.ClientRequest,
+        req: http.IncomingMessage,
+        socket: net.Socket,
+        options: ServerOptions,
+        head: any
+        ) => void
+        ): this
+        on(
+        event: 'econnreset',
+        listener: (
+        err: Error,
+        req: http.IncomingMessage,
+        res: http.ServerResponse,
+        target: ProxyTargetUrl
+        ) => void
+        ): this
+        on(
+        event: 'end',
+        listener: (
+        req: http.IncomingMessage,
+        res: http.ServerResponse,
+        proxyRes: http.IncomingMessage
+        ) => void
+        ): this
+        on(
+        event: 'close',
+        listener: (
+        proxyRes: http.IncomingMessage,
+        proxySocket: net.Socket,
+        proxyHead: any
+        ) => void
+        ): this
+
+        once(event: string, listener: () => void): this
+        removeListener(event: string, listener: () => void): this
+        removeAllListeners(event?: string): this
+        getMaxListeners(): number
+        setMaxListeners(n: number): this
+        listeners(event: string): Array<() => void>
+        emit(event: string, ...args: any[]): boolean
+        listenerCount(type: string): number
+    }
+
+    export interface ServerOptions {
+        /** URL string to be parsed with the url module. */
+        target?: ProxyTarget | undefined
+        /** URL string to be parsed with the url module. */
+        forward?: ProxyTargetUrl | undefined
+        /** Object to be passed to http(s).request. */
+        agent?: any
+        /** Object to be passed to https.createServer(). */
+        ssl?: any
+        /** If you want to proxy websockets. */
+        ws?: boolean | undefined
+        /** Adds x- forward headers. */
+        xfwd?: boolean | undefined
+        /** Verify SSL certificate. */
+        secure?: boolean | undefined
+        /** Explicitly specify if we are proxying to another proxy. */
+        toProxy?: boolean | undefined
+        /** Specify whether you want to prepend the target's path to the proxy path. */
+        prependPath?: boolean | undefined
+        /** Specify whether you want to ignore the proxy path of the incoming request. */
+        ignorePath?: boolean | undefined
+        /** Local interface string to bind for outgoing connections. */
+        localAddress?: string | undefined
+        /** Changes the origin of the host header to the target URL. */
+        changeOrigin?: boolean | undefined
+        /** specify whether you want to keep letter case of response header key */
+        preserveHeaderKeyCase?: boolean | undefined
+        /** Basic authentication i.e. 'user:password' to compute an Authorization header. */
+        auth?: string | undefined
+        /** Rewrites the location hostname on (301 / 302 / 307 / 308) redirects, Default: null. */
+        hostRewrite?: string | undefined
+        /** Rewrites the location host/ port on (301 / 302 / 307 / 308) redirects based on requested host/ port.Default: false. */
+        autoRewrite?: boolean | undefined
+        /** Rewrites the location protocol on (301 / 302 / 307 / 308) redirects to 'http' or 'https'.Default: null. */
+        protocolRewrite?: string | undefined
+        /** rewrites domain of set-cookie headers. */
+        cookieDomainRewrite?:
+        | false
+        | string
+        | { [oldDomain: string]: string }
+        | undefined
+        /** rewrites path of set-cookie headers. Default: false */
+        cookiePathRewrite?:
+        | false
+        | string
+        | { [oldPath: string]: string }
+        | undefined
+        /** object with extra headers to be added to target requests. */
+        headers?: { [header: string]: string } | undefined
+        /** Timeout (in milliseconds) when proxy receives no response from target. Default: 120000 (2 minutes) */
+        proxyTimeout?: number | undefined
+        /** Timeout (in milliseconds) for incoming requests */
+        timeout?: number | undefined
+        /** Specify whether you want to follow redirects. Default: false */
+        followRedirects?: boolean | undefined
+        /** If set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event */
+        selfHandleResponse?: boolean | undefined
+        /** Buffer */
+        buffer?: stream.Stream | undefined
+    }
+}
+
+export declare interface ImportGlobEagerFunction {
+    /**
+     * Eagerly import a list of files with a glob pattern.
+     *
+     * Overload 1: No generic provided, infer the type from `as`
+     */
+    <
+    As extends string,
+    T = As extends keyof KnownAsTypeMap ? KnownAsTypeMap[As] : unknown
+    >(
+    glob: string | string[],
+    options?: Omit<ImportGlobOptions<boolean, As>, 'eager'>
+    ): Record<string, T>
+    /**
+     * Eagerly import a list of files with a glob pattern.
+     *
+     * Overload 2: Module generic provided
+     */
+    <M>(
+    glob: string | string[],
+    options?: Omit<ImportGlobOptions<boolean, string>, 'eager'>
+    ): Record<string, M>
+}
+
+export declare interface ImportGlobFunction {
+    /**
+     * Import a list of files with a glob pattern.
+     *
+     * Overload 1: No generic provided, infer the type from `eager` and `as`
+     */
+    <
+    Eager extends boolean,
+    As extends string,
+    T = As extends keyof KnownAsTypeMap ? KnownAsTypeMap[As] : unknown
+    >(
+    glob: string | string[],
+    options?: ImportGlobOptions<Eager, As>
+    ): (Eager extends true ? true : false) extends true
+    ? Record<string, T>
+    : Record<string, () => Promise<T>>
+    /**
+     * Import a list of files with a glob pattern.
+     *
+     * Overload 2: Module generic provided, infer the type from `eager: false`
+     */
+    <M>(
+    glob: string | string[],
+    options?: ImportGlobOptions<false, string>
+    ): Record<string, () => Promise<M>>
+    /**
+     * Import a list of files with a glob pattern.
+     *
+     * Overload 3: Module generic provided, infer the type from `eager: true`
+     */
+    <M>(
+    glob: string | string[],
+    options: ImportGlobOptions<true, string>
+    ): Record<string, M>
+}
+
+export declare interface ImportGlobOptions<
+Eager extends boolean,
+AsType extends string
+> {
+    /**
+     * Import type for the import url.
+     */
+    as?: AsType
+    /**
+     * Import as static or dynamic
+     *
+     * @default false
+     */
+    eager?: Eager
+    /**
+     * Import only the specific named export. Set to `default` to import the default export.
+     */
+    import?: string
+    /**
+     * Custom queries
+     */
+    query?: string | Record<string, string | number | boolean>
+    /**
+     * Search files also inside `node_modules/` and hidden directories (e.g. `.git/`). This might have impact on performance.
+     *
+     * @default false
+     */
+    exhaustive?: boolean
+}
+
+export declare type IndexHtmlTransform = IndexHtmlTransformHook | {
+    enforce?: 'pre' | 'post';
+    transform: IndexHtmlTransformHook;
+};
+
+export declare interface IndexHtmlTransformContext {
+    /**
+     * public path when served
+     */
+    path: string;
+    /**
+     * filename on disk
+     */
+    filename: string;
+    server?: ViteDevServer;
+    bundle?: OutputBundle;
+    chunk?: OutputChunk;
+    originalUrl?: string;
+}
+
+export declare type IndexHtmlTransformHook = (html: string, ctx: IndexHtmlTransformContext) => IndexHtmlTransformResult | void | Promise<IndexHtmlTransformResult | void>;
+
+export declare type IndexHtmlTransformResult = string | HtmlTagDescriptor[] | {
+    html: string;
+    tags: HtmlTagDescriptor[];
+};
+
+export declare type InferCustomEventPayload<T extends string> =
+T extends keyof CustomEventMap ? CustomEventMap[T] : any
+
+export declare interface InlineConfig extends UserConfig {
+    configFile?: string | false;
+    envFile?: false;
+}
+
+export declare interface InternalResolveOptions extends ResolveOptions {
+    root: string;
+    isBuild: boolean;
+    isProduction: boolean;
+    ssrConfig?: SSROptions;
+    packageCache?: PackageCache;
+    /**
+     * src code mode also attempts the following:
+     * - resolving /xxx as URLs
+     * - resolving bare imports from optimized deps
+     */
+    asSrc?: boolean;
+    tryIndex?: boolean;
+    tryPrefix?: string;
+    skipPackageJson?: boolean;
+    preferRelative?: boolean;
+    preserveSymlinks?: boolean;
+    isRequire?: boolean;
+    isFromTsImporter?: boolean;
+    tryEsmOnly?: boolean;
+    scan?: boolean;
+    ssrOptimizeCheck?: boolean;
+    getDepsOptimizer?: (ssr: boolean) => DepsOptimizer | undefined;
+    shouldExternalize?: (id: string) => boolean | undefined;
+}
+
+export declare function isDepsOptimizerEnabled(config: ResolvedConfig, ssr: boolean): boolean;
+
+export declare interface JsonOptions {
+    /**
+     * Generate a named export for every property of the JSON object
+     * @default true
+     */
+    namedExports?: boolean;
+    /**
+     * Generate performant output as JSON.parse("stringified").
+     * Enabling this will disable namedExports.
+     * @default false
+     */
+    stringify?: boolean;
+}
+
+export declare interface KnownAsTypeMap {
+    raw: string
+    url: string
+    worker: Worker
+}
+
+export declare interface LegacyOptions {
+    /**
+     * Revert vite build --ssr to the v2.9 strategy. Use CJS SSR build and v2.9 externalization heuristics
+     *
+     * @experimental
+     * @deprecated
+     * @default false
+     */
+    buildSsrCjsExternalHeuristics?: boolean;
+}
+
+export declare type LibraryFormats = 'es' | 'cjs' | 'umd' | 'iife';
+
+export declare interface LibraryOptions {
+    /**
+     * Path of library entry
+     */
+    entry: string;
+    /**
+     * The name of the exposed global variable. Required when the `formats` option includes
+     * `umd` or `iife`
+     */
+    name?: string;
+    /**
+     * Output bundle formats
+     * @default ['es', 'umd']
+     */
+    formats?: LibraryFormats[];
+    /**
+     * The name of the package file output. The default file name is the name option
+     * of the project package.json. It can also be defined as a function taking the
+     * format as an argument.
+     */
+    fileName?: string | ((format: ModuleFormat) => string);
+}
+
+export declare function loadConfigFromFile(configEnv: ConfigEnv, configFile?: string, configRoot?: string, logLevel?: LogLevel): Promise<{
+    path: string;
+    config: UserConfig;
+    dependencies: string[];
+} | null>;
+
+export declare function loadEnv(mode: string, envDir: string, prefixes?: string | string[]): Record<string, string>;
+
+export declare interface LogErrorOptions extends LogOptions {
+    error?: Error | RollupError | null;
+}
+
+export declare interface Logger {
+    info(msg: string, options?: LogOptions): void;
+    warn(msg: string, options?: LogOptions): void;
+    warnOnce(msg: string, options?: LogOptions): void;
+    error(msg: string, options?: LogErrorOptions): void;
+    clearScreen(type: LogType): void;
+    hasErrorLogged(error: Error | RollupError): boolean;
+    hasWarned: boolean;
+}
+
+export declare interface LoggerOptions {
+    prefix?: string;
+    allowClearScreen?: boolean;
+    customLogger?: Logger;
+}
+
+export declare type LogLevel = LogType | 'silent';
+
+export declare interface LogOptions {
+    clear?: boolean;
+    timestamp?: boolean;
+}
+
+export declare type LogType = 'error' | 'warn' | 'info';
+
+export declare type Manifest = Record<string, ManifestChunk>;
+
+export declare interface ManifestChunk {
+    src?: string;
+    file: string;
+    css?: string[];
+    assets?: string[];
+    isEntry?: boolean;
+    isDynamicEntry?: boolean;
+    imports?: string[];
+    dynamicImports?: string[];
+}
+
+export declare type Matcher = AnymatchPattern | AnymatchPattern[]
+
+export declare function mergeAlias(a?: AliasOptions, b?: AliasOptions): AliasOptions | undefined;
+
+export declare function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot?: boolean): Record<string, any>;
+
+export declare class ModuleGraph {
+    private resolveId;
+    urlToModuleMap: Map<string, ModuleNode>;
+    idToModuleMap: Map<string, ModuleNode>;
+    fileToModulesMap: Map<string, Set<ModuleNode>>;
+    safeModulesPath: Set<string>;
+    constructor(resolveId: (url: string, ssr: boolean) => Promise<PartialResolvedId | null>);
+    getModuleByUrl(rawUrl: string, ssr?: boolean): Promise<ModuleNode | undefined>;
+    getModuleById(id: string): ModuleNode | undefined;
+    getModulesByFile(file: string): Set<ModuleNode> | undefined;
+    onFileChange(file: string): void;
+    invalidateModule(mod: ModuleNode, seen?: Set<ModuleNode>, timestamp?: number): void;
+    invalidateAll(): void;
+    /**
+     * Update the module graph based on a module's updated imports information
+     * If there are dependencies that no longer have any importers, they are
+     * returned as a Set.
+     */
+    updateModuleInfo(mod: ModuleNode, importedModules: Set<string | ModuleNode>, importedBindings: Map<string, Set<string>> | null, acceptedModules: Set<string | ModuleNode>, acceptedExports: Set<string> | null, isSelfAccepting: boolean, ssr?: boolean): Promise<Set<ModuleNode> | undefined>;
+    ensureEntryFromUrl(rawUrl: string, ssr?: boolean, setIsSelfAccepting?: boolean): Promise<ModuleNode>;
+    createFileOnlyEntry(file: string): ModuleNode;
+    resolveUrl(url: string, ssr?: boolean): Promise<ResolvedUrl>;
+}
+
+export declare class ModuleNode {
+    /**
+     * Public served url path, starts with /
+     */
+    url: string;
+    /**
+     * Resolved file system path + query
+     */
+    id: string | null;
+    file: string | null;
+    type: 'js' | 'css';
+    info?: ModuleInfo;
+    meta?: Record<string, any>;
+    importers: Set<ModuleNode>;
+    importedModules: Set<ModuleNode>;
+    acceptedHmrDeps: Set<ModuleNode>;
+    acceptedHmrExports: Set<string> | null;
+    importedBindings: Map<string, Set<string>> | null;
+    isSelfAccepting?: boolean;
+    transformResult: TransformResult | null;
+    ssrTransformResult: TransformResult | null;
+    ssrModule: Record<string, any> | null;
+    ssrError: Error | null;
+    lastHMRTimestamp: number;
+    lastInvalidationTimestamp: number;
+    /**
+     * @param setIsSelfAccepting - set `false` to set `isSelfAccepting` later. e.g. #7870
+     */
+    constructor(url: string, setIsSelfAccepting?: boolean);
+}
+
+export declare function normalizePath(id: string): string;
+
+export declare interface OptimizedDepInfo {
+    id: string;
+    file: string;
+    src?: string;
+    needsInterop?: boolean;
+    browserHash?: string;
+    fileHash?: string;
+    /**
+     * During optimization, ids can still be resolved to their final location
+     * but the bundles may not yet be saved to disk
+     */
+    processing?: Promise<void>;
+    /**
+     * ExportData cache, discovered deps will parse the src entry to get exports
+     * data used both to define if interop is needed and when pre-bundling
+     */
+    exportsData?: Promise<ExportsData>;
+}
+
+/**
+ * Scan and optimize dependencies within a project.
+ * Used by Vite CLI when running `vite optimize`.
+ */
+export declare function optimizeDeps(config: ResolvedConfig, force?: boolean | undefined, asCommand?: boolean): Promise<DepOptimizationMetadata>;
+
+/** Cache for package.json resolution and package.json contents */
+export declare type PackageCache = Map<string, PackageData>;
+
+export declare interface PackageData {
+    dir: string;
+    hasSideEffects: (id: string) => boolean | 'no-treeshake';
+    webResolvedImports: Record<string, string | undefined>;
+    nodeResolvedImports: Record<string, string | undefined>;
+    setResolvedCache: (key: string, entry: string, targetWeb: boolean) => void;
+    getResolvedCache: (key: string, targetWeb: boolean) => string | undefined;
+    data: {
+        [field: string]: any;
+        name: string;
+        type: string;
+        version: string;
+        main: string;
+        module: string;
+        browser: string | Record<string, string | false>;
+        exports: string | Record<string, any> | string[];
+        dependencies: Record<string, string>;
+    };
+}
+
+/**
+ * Vite plugins extends the Rollup plugin interface with a few extra
+ * vite-specific options. A valid vite plugin is also a valid Rollup plugin.
+ * On the contrary, a Rollup plugin may or may NOT be a valid vite universal
+ * plugin, since some Rollup features do not make sense in an unbundled
+ * dev server context. That said, as long as a rollup plugin doesn't have strong
+ * coupling between its bundle phase and output phase hooks then it should
+ * just work (that means, most of them).
+ *
+ * By default, the plugins are run during both serve and build. When a plugin
+ * is applied during serve, it will only run **non output plugin hooks** (see
+ * rollup type definition of {@link rollup#PluginHooks}). You can think of the
+ * dev server as only running `const bundle = rollup.rollup()` but never calling
+ * `bundle.generate()`.
+ *
+ * A plugin that expects to have different behavior depending on serve/build can
+ * export a factory function that receives the command being run via options.
+ *
+ * If a plugin should be applied only for server or build, a function format
+ * config file can be used to conditional determine the plugins to use.
+ */
+declare interface Plugin_2 extends Plugin_3 {
+    /**
+     * Enforce plugin invocation tier similar to webpack loaders.
+     *
+     * Plugin invocation order:
+     * - alias resolution
+     * - `enforce: 'pre'` plugins
+     * - vite core plugins
+     * - normal plugins
+     * - vite build plugins
+     * - `enforce: 'post'` plugins
+     * - vite build post plugins
+     */
+    enforce?: 'pre' | 'post';
+    /**
+     * Apply the plugin only for serve or build, or on certain conditions.
+     */
+    apply?: 'serve' | 'build' | ((config: UserConfig, env: ConfigEnv) => boolean);
+    /**
+     * Modify vite config before it's resolved. The hook can either mutate the
+     * passed-in config directly, or return a partial config object that will be
+     * deeply merged into existing config.
+     *
+     * Note: User plugins are resolved before running this hook so injecting other
+     * plugins inside  the `config` hook will have no effect.
+     */
+    config?: (config: UserConfig, env: ConfigEnv) => UserConfig | null | void | Promise<UserConfig | null | void>;
+    /**
+     * Use this hook to read and store the final resolved vite config.
+     */
+    configResolved?: (config: ResolvedConfig) => void | Promise<void>;
+    /**
+     * Configure the vite server. The hook receives the {@link ViteDevServer}
+     * instance. This can also be used to store a reference to the server
+     * for use in other hooks.
+     *
+     * The hooks will be called before internal middlewares are applied. A hook
+     * can return a post hook that will be called after internal middlewares
+     * are applied. Hook can be async functions and will be called in series.
+     */
+    configureServer?: ServerHook;
+    /**
+     * Configure the preview server. The hook receives the connect server and
+     * its underlying http server.
+     *
+     * The hooks are called before other middlewares are applied. A hook can
+     * return a post hook that will be called after other middlewares are
+     * applied. Hooks can be async functions and will be called in series.
+     */
+    configurePreviewServer?: PreviewServerHook;
+    /**
+     * Transform index.html.
+     * The hook receives the following arguments:
+     *
+     * - html: string
+     * - ctx?: vite.ServerContext (only present during serve)
+     * - bundle?: rollup.OutputBundle (only present during build)
+     *
+     * It can either return a transformed string, or a list of html tag
+     * descriptors that will be injected into the <head> or <body>.
+     *
+     * By default the transform is applied **after** vite's internal html
+     * transform. If you need to apply the transform before vite, use an object:
+     * `{ enforce: 'pre', transform: hook }`
+     */
+    transformIndexHtml?: IndexHtmlTransform;
+    /**
+     * Perform custom handling of HMR updates.
+     * The handler receives a context containing changed filename, timestamp, a
+     * list of modules affected by the file change, and the dev server instance.
+     *
+     * - The hook can return a filtered list of modules to narrow down the update.
+     *   e.g. for a Vue SFC, we can narrow down the part to update by comparing
+     *   the descriptors.
+     *
+     * - The hook can also return an empty array and then perform custom updates
+     *   by sending a custom hmr payload via server.ws.send().
+     *
+     * - If the hook doesn't return a value, the hmr update will be performed as
+     *   normal.
+     */
+    handleHotUpdate?(ctx: HmrContext): Array<ModuleNode> | void | Promise<Array<ModuleNode> | void>;
+    /**
+     * extend hooks with ssr flag
+     */
+    resolveId?: (this: PluginContext, source: string, importer: string | undefined, options: {
+        custom?: CustomPluginOptions;
+        ssr?: boolean;
+        /* Excluded from this release type: scan */
+        isEntry: boolean;
+    }) => Promise<ResolveIdResult> | ResolveIdResult;
+    load?: (this: PluginContext, id: string, options?: {
+        ssr?: boolean;
+    }) => Promise<LoadResult> | LoadResult;
+    transform?: (this: TransformPluginContext, code: string, id: string, options?: {
+        ssr?: boolean;
+    }) => Promise<TransformResult_2> | TransformResult_2;
+}
+export { Plugin_2 as Plugin }
+
+export declare interface PluginContainer {
+    options: InputOptions;
+    getModuleInfo(id: string): ModuleInfo | null;
+    buildStart(options: InputOptions): Promise<void>;
+    resolveId(id: string, importer?: string, options?: {
+        custom?: CustomPluginOptions;
+        skip?: Set<Plugin_2>;
+        ssr?: boolean;
+        /* Excluded from this release type: scan */
+        isEntry?: boolean;
+    }): Promise<PartialResolvedId | null>;
+    transform(code: string, id: string, options?: {
+        inMap?: SourceDescription['map'];
+        ssr?: boolean;
+    }): Promise<SourceDescription | null>;
+    load(id: string, options?: {
+        ssr?: boolean;
+    }): Promise<LoadResult | null>;
+    close(): Promise<void>;
+}
+
+export declare type PluginOption = Plugin_2 | false | null | undefined | PluginOption[] | Promise<Plugin_2 | false | null | undefined | PluginOption[]>;
+
+/**
+ * Starts the Vite server in preview mode, to simulate a production deployment
+ */
+export declare function preview(inlineConfig?: InlineConfig): Promise<PreviewServer>;
+
+export declare interface PreviewOptions extends CommonServerOptions {
+}
+
+export declare interface PreviewServer {
+    /**
+     * The resolved vite config object
+     */
+    config: ResolvedConfig;
+    /**
+     * native Node http server instance
+     */
+    httpServer: http.Server;
+    /**
+     * The resolved urls Vite prints on the CLI
+     *
+     * @experimental
+     */
+    resolvedUrls: ResolvedServerUrls;
+    /**
+     * Print server urls
+     */
+    printUrls(): void;
+}
+
+export declare type PreviewServerHook = (server: {
+    middlewares: Connect.Server;
+    httpServer: http.Server;
+}) => (() => void) | void | Promise<(() => void) | void>;
+
+export declare interface ProxyOptions extends HttpProxy.ServerOptions {
+    /**
+     * rewrite path
+     */
+    rewrite?: (path: string) => string;
+    /**
+     * configure the proxy server (e.g. listen to events)
+     */
+    configure?: (proxy: HttpProxy.Server, options: ProxyOptions) => void;
+    /**
+     * webpack-dev-server style bypass function
+     */
+    bypass?: (req: http.IncomingMessage, res: http.ServerResponse, options: ProxyOptions) => void | null | undefined | false | string;
+}
+
+export declare interface PrunePayload {
+    type: 'prune'
+    paths: string[]
+}
+
+export declare type RenderBuiltAssetUrl = (filename: string, type: {
+    type: 'asset' | 'public';
+    hostId: string;
+    hostType: 'js' | 'css' | 'html';
+    ssr: boolean;
+}) => string | {
+    relative?: boolean;
+    runtime?: string;
+} | undefined;
+
+/**
+ * Resolve base url. Note that some users use Vite to build for non-web targets like
+ * electron or expects to deploy
+ */
+export declare function resolveBaseUrl(base: string | undefined, isBuild: boolean, logger: Logger): string;
+
+export declare function resolveConfig(inlineConfig: InlineConfig, command: 'build' | 'serve', defaultMode?: string): Promise<ResolvedConfig>;
+
+export declare type ResolvedBuildOptions = Required<BuildOptions>;
+
+export declare type ResolvedConfig = Readonly<Omit<UserConfig, 'plugins' | 'assetsInclude' | 'optimizeDeps' | 'worker'> & {
+    configFile: string | undefined;
+    configFileDependencies: string[];
+    inlineConfig: InlineConfig;
+    root: string;
+    base: string;
+    publicDir: string;
+    cacheDir: string;
+    command: 'build' | 'serve';
+    mode: string;
+    isWorker: boolean;
+    /* Excluded from this release type: mainConfig */
+    isProduction: boolean;
+    env: Record<string, any>;
+    resolve: ResolveOptions & {
+        alias: Alias[];
+    };
+    plugins: readonly Plugin_2[];
+    server: ResolvedServerOptions;
+    build: ResolvedBuildOptions;
+    preview: ResolvedPreviewOptions;
+    ssr: ResolvedSSROptions;
+    assetsInclude: (file: string) => boolean;
+    logger: Logger;
+    createResolver: (options?: Partial<InternalResolveOptions>) => ResolveFn;
+    optimizeDeps: DepOptimizationOptions;
+    /* Excluded from this release type: packageCache */
+    worker: ResolveWorkerOptions;
+    appType: AppType;
+    experimental: ExperimentalOptions;
+}>;
+
+export declare interface ResolvedPreviewOptions extends PreviewOptions {
+}
+
+export declare interface ResolvedServerOptions extends ServerOptions {
+    fs: Required<FileSystemServeOptions>;
+    middlewareMode: boolean;
+}
+
+export declare interface ResolvedServerUrls {
+    local: string[];
+    network: string[];
+}
+
+export declare interface ResolvedSSROptions extends SSROptions {
+    target: SSRTarget;
+    format: SSRFormat;
+    optimizeDeps: SsrDepOptimizationOptions;
+}
+
+export declare type ResolvedUrl = [
+url: string,
+resolvedId: string,
+meta: object | null | undefined
+];
+
+export declare function resolveEnvPrefix({ envPrefix }: UserConfig): string[];
+
+export declare type ResolveFn = (id: string, importer?: string, aliasOnly?: boolean, ssr?: boolean) => Promise<string | undefined>;
+
+export declare interface ResolveOptions {
+    mainFields?: string[];
+    conditions?: string[];
+    extensions?: string[];
+    dedupe?: string[];
+    preserveSymlinks?: boolean;
+}
+
+export declare function resolvePackageData(id: string, basedir: string, preserveSymlinks?: boolean, packageCache?: PackageCache): PackageData | null;
+
+export declare function resolvePackageEntry(id: string, { dir, data, setResolvedCache, getResolvedCache }: PackageData, targetWeb: boolean, options: InternalResolveOptions): string | undefined;
+
+export declare type ResolverFunction = PluginHooks['resolveId']
+
+export declare interface ResolverObject {
+    buildStart?: PluginHooks['buildStart']
+    resolveId: ResolverFunction
+}
+
+export declare interface ResolveWorkerOptions {
+    format: 'es' | 'iife';
+    plugins: Plugin_2[];
+    rollupOptions: RollupOptions;
+}
+
+/**
+ * https://github.com/rollup/plugins/blob/master/packages/commonjs/types/index.d.ts
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file at
+ * https://github.com/rollup/plugins/blob/master/LICENSE
+ */
+export declare interface RollupCommonJSOptions {
+    /**
+     * A minimatch pattern, or array of patterns, which specifies the files in
+     * the build the plugin should operate on. By default, all files with
+     * extension `".cjs"` or those in `extensions` are included, but you can
+     * narrow this list by only including specific files. These files will be
+     * analyzed and transpiled if either the analysis does not find ES module
+     * specific statements or `transformMixedEsModules` is `true`.
+     * @default undefined
+     */
+    include?: string | RegExp | readonly (string | RegExp)[]
+    /**
+     * A minimatch pattern, or array of patterns, which specifies the files in
+     * the build the plugin should _ignore_. By default, all files with
+     * extensions other than those in `extensions` or `".cjs"` are ignored, but you
+     * can exclude additional files. See also the `include` option.
+     * @default undefined
+     */
+    exclude?: string | RegExp | readonly (string | RegExp)[]
+    /**
+     * For extensionless imports, search for extensions other than .js in the
+     * order specified. Note that you need to make sure that non-JavaScript files
+     * are transpiled by another plugin first.
+     * @default [ '.js' ]
+     */
+    extensions?: ReadonlyArray<string>
+    /**
+     * If true then uses of `global` won't be dealt with by this plugin
+     * @default false
+     */
+    ignoreGlobal?: boolean
+    /**
+     * If false, skips source map generation for CommonJS modules. This will
+     * improve performance.
+     * @default true
+     */
+    sourceMap?: boolean
+    /**
+     * Some `require` calls cannot be resolved statically to be translated to
+     * imports.
+     * When this option is set to `false`, the generated code will either
+     * directly throw an error when such a call is encountered or, when
+     * `dynamicRequireTargets` is used, when such a call cannot be resolved with a
+     * configured dynamic require target.
+     * Setting this option to `true` will instead leave the `require` call in the
+     * code or use it as a fallback for `dynamicRequireTargets`.
+     * @default false
+     */
+    ignoreDynamicRequires?: boolean
+    /**
+     * Instructs the plugin whether to enable mixed module transformations. This
+     * is useful in scenarios with modules that contain a mix of ES `import`
+     * statements and CommonJS `require` expressions. Set to `true` if `require`
+     * calls should be transformed to imports in mixed modules, or `false` if the
+     * `require` expressions should survive the transformation. The latter can be
+     * important if the code contains environment detection, or you are coding
+     * for an environment with special treatment for `require` calls such as
+     * ElectronJS. See also the `ignore` option.
+     * @default false
+     */
+    transformMixedEsModules?: boolean
+    /**
+     * By default, this plugin will try to hoist `require` statements as imports
+     * to the top of each file. While this works well for many code bases and
+     * allows for very efficient ESM output, it does not perfectly capture
+     * CommonJS semantics as the order of side effects like log statements may
+     * change. But it is especially problematic when there are circular `require`
+     * calls between CommonJS modules as those often rely on the lazy execution of
+     * nested `require` calls.
+     *
+     * Setting this option to `true` will wrap all CommonJS files in functions
+     * which are executed when they are required for the first time, preserving
+     * NodeJS semantics. Note that this can have an impact on the size and
+     * performance of the generated code.
+     *
+     * The default value of `"auto"` will only wrap CommonJS files when they are
+     * part of a CommonJS dependency cycle, e.g. an index file that is required by
+     * many of its dependencies. All other CommonJS files are hoisted. This is the
+     * recommended setting for most code bases.
+     *
+     * `false` will entirely prevent wrapping and hoist all files. This may still
+     * work depending on the nature of cyclic dependencies but will often cause
+     * problems.
+     *
+     * You can also provide a minimatch pattern, or array of patterns, to only
+     * specify a subset of files which should be wrapped in functions for proper
+     * `require` semantics.
+     *
+     * `"debug"` works like `"auto"` but after bundling, it will display a warning
+     * containing a list of ids that have been wrapped which can be used as
+     * minimatch pattern for fine-tuning.
+     * @default "auto"
+     */
+    strictRequires?: boolean | string | RegExp | readonly (string | RegExp)[]
+    /**
+     * Sometimes you have to leave require statements unconverted. Pass an array
+     * containing the IDs or a `id => boolean` function.
+     * @default []
+     */
+    ignore?: ReadonlyArray<string> | ((id: string) => boolean)
+    /**
+     * In most cases, where `require` calls are inside a `try-catch` clause,
+     * they should be left unconverted as it requires an optional dependency
+     * that may or may not be installed beside the rolled up package.
+     * Due to the conversion of `require` to a static `import` - the call is
+     * hoisted to the top of the file, outside of the `try-catch` clause.
+     *
+     * - `true`: All `require` calls inside a `try` will be left unconverted.
+     * - `false`: All `require` calls inside a `try` will be converted as if the
+     *   `try-catch` clause is not there.
+     * - `remove`: Remove all `require` calls from inside any `try` block.
+     * - `string[]`: Pass an array containing the IDs to left unconverted.
+     * - `((id: string) => boolean|'remove')`: Pass a function that control
+     *   individual IDs.
+     *
+     * @default false
+     */
+    ignoreTryCatch?:
+    | boolean
+    | 'remove'
+    | ReadonlyArray<string>
+    | ((id: string) => boolean | 'remove')
+    /**
+     * Controls how to render imports from external dependencies. By default,
+     * this plugin assumes that all external dependencies are CommonJS. This
+     * means they are rendered as default imports to be compatible with e.g.
+     * NodeJS where ES modules can only import a default export from a CommonJS
+     * dependency.
+     *
+     * If you set `esmExternals` to `true`, this plugins assumes that all
+     * external dependencies are ES modules and respect the
+     * `requireReturnsDefault` option. If that option is not set, they will be
+     * rendered as namespace imports.
+     *
+     * You can also supply an array of ids to be treated as ES modules, or a
+     * function that will be passed each external id to determine if it is an ES
+     * module.
+     * @default false
+     */
+    esmExternals?: boolean | ReadonlyArray<string> | ((id: string) => boolean)
+    /**
+     * Controls what is returned when requiring an ES module from a CommonJS file.
+     * When using the `esmExternals` option, this will also apply to external
+     * modules. By default, this plugin will render those imports as namespace
+     * imports i.e.
+     *
+     * ```js
+     * // input
+     * const foo = require('foo');
+     *
+     * // output
+     * import * as foo from 'foo';
+     * ```
+     *
+     * However there are some situations where this may not be desired.
+     * For these situations, you can change Rollup's behaviour either globally or
+     * per module. To change it globally, set the `requireReturnsDefault` option
+     * to one of the following values:
+     *
+     * - `false`: This is the default, requiring an ES module returns its
+     *   namespace. This is the only option that will also add a marker
+     *   `__esModule: true` to the namespace to support interop patterns in
+     *   CommonJS modules that are transpiled ES modules.
+     * - `"namespace"`: Like `false`, requiring an ES module returns its
+     *   namespace, but the plugin does not add the `__esModule` marker and thus
+     *   creates more efficient code. For external dependencies when using
+     *   `esmExternals: true`, no additional interop code is generated.
+     * - `"auto"`: This is complementary to how `output.exports: "auto"` works in
+     *   Rollup: If a module has a default export and no named exports, requiring
+     *   that module returns the default export. In all other cases, the namespace
+     *   is returned. For external dependencies when using `esmExternals: true`, a
+     *   corresponding interop helper is added.
+     * - `"preferred"`: If a module has a default export, requiring that module
+     *   always returns the default export, no matter whether additional named
+     *   exports exist. This is similar to how previous versions of this plugin
+     *   worked. Again for external dependencies when using `esmExternals: true`,
+     *   an interop helper is added.
+     * - `true`: This will always try to return the default export on require
+     *   without checking if it actually exists. This can throw at build time if
+     *   there is no default export. This is how external dependencies are handled
+     *   when `esmExternals` is not used. The advantage over the other options is
+     *   that, like `false`, this does not add an interop helper for external
+     *   dependencies, keeping the code lean.
+     *
+     * To change this for individual modules, you can supply a function for
+     * `requireReturnsDefault` instead. This function will then be called once for
+     * each required ES module or external dependency with the corresponding id
+     * and allows you to return different values for different modules.
+     * @default false
+     */
+    requireReturnsDefault?:
+    | boolean
+    | 'auto'
+    | 'preferred'
+    | 'namespace'
+    | ((id: string) => boolean | 'auto' | 'preferred' | 'namespace')
+
+    /**
+     * @default "auto"
+     */
+    defaultIsModuleExports?: boolean | 'auto' | ((id: string) => boolean | 'auto')
+    /**
+     * Some modules contain dynamic `require` calls, or require modules that
+     * contain circular dependencies, which are not handled well by static
+     * imports. Including those modules as `dynamicRequireTargets` will simulate a
+     * CommonJS (NodeJS-like)  environment for them with support for dynamic
+     * dependencies. It also enables `strictRequires` for those modules.
+     *
+     * Note: In extreme cases, this feature may result in some paths being
+     * rendered as absolute in the final bundle. The plugin tries to avoid
+     * exposing paths from the local machine, but if you are `dynamicRequirePaths`
+     * with paths that are far away from your project's folder, that may require
+     * replacing strings like `"/Users/John/Desktop/foo-project/"` -\> `"/"`.
+     */
+    dynamicRequireTargets?: string | ReadonlyArray<string>
+    /**
+     * To avoid long paths when using the `dynamicRequireTargets` option, you can use this option to specify a directory
+     * that is a common parent for all files that use dynamic require statements. Using a directory higher up such as `/`
+     * may lead to unnecessarily long paths in the generated code and may expose directory names on your machine like your
+     * home directory name. By default it uses the current working directory.
+     */
+    dynamicRequireRoot?: string
+}
+
+export declare interface RollupDynamicImportVarsOptions {
+    /**
+     * Files to include in this plugin (default all).
+     * @default []
+     */
+    include?: string | RegExp | (string | RegExp)[]
+    /**
+     * Files to exclude in this plugin (default none).
+     * @default []
+     */
+    exclude?: string | RegExp | (string | RegExp)[]
+    /**
+     * By default, the plugin quits the build process when it encounters an error. If you set this option to true, it will throw a warning instead and leave the code untouched.
+     * @default false
+     */
+    warnOnError?: boolean
+}
+
+export { rollupVersion }
+
+/**
+ * Search up for the nearest workspace root
+ */
+export declare function searchForWorkspaceRoot(current: string, root?: string): string;
+
+export declare function send(req: IncomingMessage, res: ServerResponse, content: string | Buffer, type: string, options: SendOptions): void;
+
+export declare interface SendOptions {
+    etag?: string;
+    cacheControl?: string;
+    headers?: OutgoingHttpHeaders;
+    map?: SourceMap | null;
+}
+
+export declare type ServerHook = (server: ViteDevServer) => (() => void) | void | Promise<(() => void) | void>;
+
+export declare interface ServerOptions extends CommonServerOptions {
+    /**
+     * Configure HMR-specific options (port, host, path & protocol)
+     */
+    hmr?: HmrOptions | boolean;
+    /**
+     * chokidar watch options
+     * https://github.com/paulmillr/chokidar#api
+     */
+    watch?: WatchOptions;
+    /**
+     * Create Vite dev server to be used as a middleware in an existing server
+     */
+    middlewareMode?: boolean | 'html' | 'ssr';
+    /**
+     * Prepend this folder to http requests, for use when proxying vite as a subfolder
+     * Should start and end with the `/` character
+     */
+    base?: string;
+    /**
+     * Options for files served via '/\@fs/'.
+     */
+    fs?: FileSystemServeOptions;
+    /**
+     * Origin for the generated asset URLs.
+     *
+     * @example `http://127.0.0.1:8080`
+     */
+    origin?: string;
+    /**
+     * Pre-transform known direct imports
+     * @default true
+     */
+    preTransformRequests?: boolean;
+    /**
+     * Force dep pre-optimization regardless of whether deps have changed.
+     *
+     * @deprecated Use optimizeDeps.force instead, this option may be removed
+     * in a future minor version without following semver
+     */
+    force?: boolean;
+}
+
+export declare function sortUserPlugins(plugins: (Plugin_2 | Plugin_2[])[] | undefined): [Plugin_2[], Plugin_2[], Plugin_2[]];
+
+export declare function splitVendorChunk(options?: {
+    cache?: SplitVendorChunkCache;
+}): GetManualChunk;
+
+export declare class SplitVendorChunkCache {
+    cache: Map<string, boolean>;
+    constructor();
+    reset(): void;
+}
+
+export declare function splitVendorChunkPlugin(): Plugin_2;
+
+export declare type SsrDepOptimizationOptions = DepOptimizationConfig;
+
+export declare type SSRFormat = 'esm' | 'cjs';
+
+export declare interface SSROptions {
+    noExternal?: string | RegExp | (string | RegExp)[] | true;
+    external?: string[];
+    /**
+     * Define the target for the ssr build. The browser field in package.json
+     * is ignored for node but used if webworker is the target
+     * Default: 'node'
+     */
+    target?: SSRTarget;
+    /**
+     * Define the format for the ssr build. Since Vite v3 the SSR build generates ESM by default.
+     * `'cjs'` can be selected to generate a CJS build, but it isn't recommended. This option is
+     * left marked as experimental to give users more time to update to ESM. CJS builds requires
+     * complex externalization heuristics that aren't present in the ESM format.
+     * @experimental
+     */
+    format?: SSRFormat;
+    /**
+     * Control over which dependencies are optimized during SSR and esbuild options
+     * During build:
+     *   no external CJS dependencies are optimized by default
+     * During dev:
+     *   explicit no external CJS dependencies are optimized by default
+     * @experimental
+     */
+    optimizeDeps?: SsrDepOptimizationOptions;
+}
+
+export declare type SSRTarget = 'node' | 'webworker';
+
+export declare namespace Terser {
+    export type ECMA = 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020
+
+    export interface ParseOptions {
+        bare_returns?: boolean
+        /** @deprecated legacy option. Currently, all supported EcmaScript is valid to parse. */
+        ecma?: ECMA
+        html5_comments?: boolean
+        shebang?: boolean
+    }
+
+    export interface CompressOptions {
+        arguments?: boolean
+        arrows?: boolean
+        booleans_as_integers?: boolean
+        booleans?: boolean
+        collapse_vars?: boolean
+        comparisons?: boolean
+        computed_props?: boolean
+        conditionals?: boolean
+        dead_code?: boolean
+        defaults?: boolean
+        directives?: boolean
+        drop_console?: boolean
+        drop_debugger?: boolean
+        ecma?: ECMA
+        evaluate?: boolean
+        expression?: boolean
+        global_defs?: object
+        hoist_funs?: boolean
+        hoist_props?: boolean
+        hoist_vars?: boolean
+        ie8?: boolean
+        if_return?: boolean
+        inline?: boolean | InlineFunctions
+        join_vars?: boolean
+        keep_classnames?: boolean | RegExp
+        keep_fargs?: boolean
+        keep_fnames?: boolean | RegExp
+        keep_infinity?: boolean
+        loops?: boolean
+        module?: boolean
+        negate_iife?: boolean
+        passes?: number
+        properties?: boolean
+        pure_funcs?: string[]
+        pure_getters?: boolean | 'strict'
+        reduce_funcs?: boolean
+        reduce_vars?: boolean
+        sequences?: boolean | number
+        side_effects?: boolean
+        switches?: boolean
+        toplevel?: boolean
+        top_retain?: null | string | string[] | RegExp
+        typeofs?: boolean
+        unsafe_arrows?: boolean
+        unsafe?: boolean
+        unsafe_comps?: boolean
+        unsafe_Function?: boolean
+        unsafe_math?: boolean
+        unsafe_symbols?: boolean
+        unsafe_methods?: boolean
+        unsafe_proto?: boolean
+        unsafe_regexp?: boolean
+        unsafe_undefined?: boolean
+        unused?: boolean
+    }
+
+    export enum InlineFunctions {
+        Disabled = 0,
+        SimpleFunctions = 1,
+        WithArguments = 2,
+        WithArgumentsAndVariables = 3
+    }
+
+    export interface MangleOptions {
+        eval?: boolean
+        keep_classnames?: boolean | RegExp
+        keep_fnames?: boolean | RegExp
+        module?: boolean
+        nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler
+        properties?: boolean | ManglePropertiesOptions
+        reserved?: string[]
+        safari10?: boolean
+        toplevel?: boolean
+    }
+
+    /**
+     * An identifier mangler for which the output is invariant with respect to the source code.
+     */
+    export interface SimpleIdentifierMangler {
+        /**
+         * Obtains the nth most favored (usually shortest) identifier to rename a variable to.
+         * The mangler will increment n and retry until the return value is not in use in scope, and is not a reserved word.
+         * This function is expected to be stable; Evaluating get(n) === get(n) should always return true.
+         * @param n - The ordinal of the identifier.
+         */
+        get(n: number): string
+    }
+
+    /**
+     * An identifier mangler that leverages character frequency analysis to determine identifier precedence.
+     */
+    export interface WeightedIdentifierMangler extends SimpleIdentifierMangler {
+        /**
+         * Modifies the internal weighting of the input characters by the specified delta.
+         * Will be invoked on the entire printed AST, and then deduct mangleable identifiers.
+         * @param chars - The characters to modify the weighting of.
+         * @param delta - The numeric weight to add to the characters.
+         */
+        consider(chars: string, delta: number): number
+        /**
+         * Resets character weights.
+         */
+        reset(): void
+        /**
+         * Sorts identifiers by character frequency, in preparation for calls to get(n).
+         */
+        sort(): void
+    }
+
+    export interface ManglePropertiesOptions {
+        builtins?: boolean
+        debug?: boolean
+        keep_quoted?: boolean | 'strict'
+        nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler
+        regex?: RegExp | string
+        reserved?: string[]
+    }
+
+    export interface FormatOptions {
+        ascii_only?: boolean
+        /** @deprecated Not implemented anymore */
+        beautify?: boolean
+        braces?: boolean
+        comments?:
+        | boolean
+        | 'all'
+        | 'some'
+        | RegExp
+        | ((
+        node: any,
+        comment: {
+            value: string
+            type: 'comment1' | 'comment2' | 'comment3' | 'comment4'
+            pos: number
+            line: number
+            col: number
+        }
+        ) => boolean)
+        ecma?: ECMA
+        ie8?: boolean
+        keep_numbers?: boolean
+        indent_level?: number
+        indent_start?: number
+        inline_script?: boolean
+        keep_quoted_props?: boolean
+        max_line_len?: number | false
+        preamble?: string
+        preserve_annotations?: boolean
+        quote_keys?: boolean
+        quote_style?: OutputQuoteStyle
+        safari10?: boolean
+        semicolons?: boolean
+        shebang?: boolean
+        shorthand?: boolean
+        source_map?: SourceMapOptions
+        webkit?: boolean
+        width?: number
+        wrap_iife?: boolean
+        wrap_func_args?: boolean
+    }
+
+    export enum OutputQuoteStyle {
+        PreferDouble = 0,
+        AlwaysSingle = 1,
+        AlwaysDouble = 2,
+        AlwaysOriginal = 3
+    }
+
+    export interface MinifyOptions {
+        compress?: boolean | CompressOptions
+        ecma?: ECMA
+        enclose?: boolean | string
+        ie8?: boolean
+        keep_classnames?: boolean | RegExp
+        keep_fnames?: boolean | RegExp
+        mangle?: boolean | MangleOptions
+        module?: boolean
+        nameCache?: object
+        format?: FormatOptions
+        /** @deprecated deprecated */
+        output?: FormatOptions
+        parse?: ParseOptions
+        safari10?: boolean
+        sourceMap?: boolean | SourceMapOptions
+        toplevel?: boolean
+    }
+
+    export interface MinifyOutput {
+        code?: string
+        map?: object | string
+        decoded_map?: object | null
+    }
+
+    export interface SourceMapOptions {
+        /** Source map object, 'inline' or source map file content */
+        content?: object | string
+        includeSources?: boolean
+        filename?: string
+        root?: string
+        url?: string | 'inline'
+    }
+}
+
+export declare interface TransformOptions {
+    ssr?: boolean;
+    html?: boolean;
+}
+
+export declare interface TransformResult {
+    code: string;
+    map: SourceMap | null;
+    etag?: string;
+    deps?: string[];
+    dynamicDeps?: string[];
+}
+
+export declare function transformWithEsbuild(code: string, filename: string, options?: EsbuildTransformOptions, inMap?: object): Promise<ESBuildTransformResult>;
+
+export declare interface Update {
+    type: 'js-update' | 'css-update'
+    path: string
+    acceptedPath: string
+    timestamp: number
+}
+
+export declare interface UpdatePayload {
+    type: 'update'
+    updates: Update[]
+}
+
+export declare interface UserConfig {
+    /**
+     * Project root directory. Can be an absolute path, or a path relative from
+     * the location of the config file itself.
+     * @default process.cwd()
+     */
+    root?: string;
+    /**
+     * Base public path when served in development or production.
+     * @default '/'
+     */
+    base?: string;
+    /**
+     * Directory to serve as plain static assets. Files in this directory are
+     * served and copied to build dist dir as-is without transform. The value
+     * can be either an absolute file system path or a path relative to <root>.
+     *
+     * Set to `false` or an empty string to disable copied static assets to build dist dir.
+     * @default 'public'
+     */
+    publicDir?: string | false;
+    /**
+     * Directory to save cache files. Files in this directory are pre-bundled
+     * deps or some other cache files that generated by vite, which can improve
+     * the performance. You can use `--force` flag or manually delete the directory
+     * to regenerate the cache files. The value can be either an absolute file
+     * system path or a path relative to <root>.
+     * Default to `.vite` when no `package.json` is detected.
+     * @default 'node_modules/.vite'
+     */
+    cacheDir?: string;
+    /**
+     * Explicitly set a mode to run in. This will override the default mode for
+     * each command, and can be overridden by the command line --mode option.
+     */
+    mode?: string;
+    /**
+     * Define global variable replacements.
+     * Entries will be defined on `window` during dev and replaced during build.
+     */
+    define?: Record<string, any>;
+    /**
+     * Array of vite plugins to use.
+     */
+    plugins?: PluginOption[];
+    /**
+     * Configure resolver
+     */
+    resolve?: ResolveOptions & {
+        alias?: AliasOptions;
+    };
+    /**
+     * CSS related options (preprocessors and CSS modules)
+     */
+    css?: CSSOptions;
+    /**
+     * JSON loading options
+     */
+    json?: JsonOptions;
+    /**
+     * Transform options to pass to esbuild.
+     * Or set to `false` to disable esbuild.
+     */
+    esbuild?: ESBuildOptions | false;
+    /**
+     * Specify additional picomatch patterns to be treated as static assets.
+     */
+    assetsInclude?: string | RegExp | (string | RegExp)[];
+    /**
+     * Server specific options, e.g. host, port, https...
+     */
+    server?: ServerOptions;
+    /**
+     * Build specific options
+     */
+    build?: BuildOptions;
+    /**
+     * Preview specific options, e.g. host, port, https...
+     */
+    preview?: PreviewOptions;
+    /**
+     * Dep optimization options
+     */
+    optimizeDeps?: DepOptimizationOptions;
+    /**
+     * SSR specific options
+     */
+    ssr?: SSROptions;
+    /**
+     * Experimental features
+     *
+     * Features under this field could change in the future and might NOT follow semver.
+     * Please be careful and always pin Vite's version when using them.
+     * @experimental
+     */
+    experimental?: ExperimentalOptions;
+    /**
+     * Legacy options
+     *
+     * Features under this field only follow semver for patches, they could be removed in a
+     * future minor version. Please always pin Vite's version to a minor when using them.
+     */
+    legacy?: LegacyOptions;
+    /**
+     * Log level.
+     * Default: 'info'
+     */
+    logLevel?: LogLevel;
+    /**
+     * Custom logger.
+     */
+    customLogger?: Logger;
+    /**
+     * Default: true
+     */
+    clearScreen?: boolean;
+    /**
+     * Environment files directory. Can be an absolute path, or a path relative from
+     * the location of the config file itself.
+     * @default root
+     */
+    envDir?: string;
+    /**
+     * Env variables starts with `envPrefix` will be exposed to your client source code via import.meta.env.
+     * @default 'VITE_'
+     */
+    envPrefix?: string | string[];
+    /**
+     * Worker bundle options
+     */
+    worker?: {
+        /**
+         * Output format for worker bundle
+         * @default 'iife'
+         */
+        format?: 'es' | 'iife';
+        /**
+         * Vite plugins that apply to worker bundle
+         */
+        plugins?: PluginOption[];
+        /**
+         * Rollup options to build worker bundle
+         */
+        rollupOptions?: Omit<RollupOptions, 'plugins' | 'input' | 'onwarn' | 'preserveEntrySignatures'>;
+    };
+    /**
+     * Whether your application is a Single Page Application (SPA),
+     * a Multi-Page Application (MPA), or Custom Application (SSR
+     * and frameworks with custom HTML handling)
+     * @default 'spa'
+     */
+    appType?: AppType;
+}
+
+export declare type UserConfigExport = UserConfig | Promise<UserConfig> | UserConfigFn;
+
+export declare type UserConfigFn = (env: ConfigEnv) => UserConfig | Promise<UserConfig>;
+
+export declare const version: string;
+
+export declare interface ViteDevServer {
+    /**
+     * The resolved vite config object
+     */
+    config: ResolvedConfig;
+    /**
+     * A connect app instance.
+     * - Can be used to attach custom middlewares to the dev server.
+     * - Can also be used as the handler function of a custom http server
+     *   or as a middleware in any connect-style Node.js frameworks
+     *
+     * https://github.com/senchalabs/connect#use-middleware
+     */
+    middlewares: Connect.Server;
+    /**
+     * native Node http server instance
+     * will be null in middleware mode
+     */
+    httpServer: http.Server | null;
+    /**
+     * chokidar watcher instance
+     * https://github.com/paulmillr/chokidar#api
+     */
+    watcher: FSWatcher;
+    /**
+     * web socket server with `send(payload)` method
+     */
+    ws: WebSocketServer;
+    /**
+     * Rollup plugin container that can run plugin hooks on a given file
+     */
+    pluginContainer: PluginContainer;
+    /**
+     * Module graph that tracks the import relationships, url to file mapping
+     * and hmr state.
+     */
+    moduleGraph: ModuleGraph;
+    /**
+     * The resolved urls Vite prints on the CLI. null in middleware mode or
+     * before `server.listen` is called.
+     *
+     * @experimental
+     */
+    resolvedUrls: ResolvedServerUrls | null;
+    /**
+     * Programmatically resolve, load and transform a URL and get the result
+     * without going through the http request pipeline.
+     */
+    transformRequest(url: string, options?: TransformOptions): Promise<TransformResult | null>;
+    /**
+     * Apply vite built-in HTML transforms and any plugin HTML transforms.
+     */
+    transformIndexHtml(url: string, html: string, originalUrl?: string): Promise<string>;
+    /**
+     * Transform module code into SSR format.
+     */
+    ssrTransform(code: string, inMap: SourceMap | null, url: string): Promise<TransformResult | null>;
+    /**
+     * Load a given URL as an instantiated module for SSR.
+     */
+    ssrLoadModule(url: string, opts?: {
+        fixStacktrace?: boolean;
+    }): Promise<Record<string, any>>;
+    /**
+     * Returns a fixed version of the given stack
+     */
+    ssrRewriteStacktrace(stack: string): string;
+    /**
+     * Mutates the given SSR error by rewriting the stacktrace
+     */
+    ssrFixStacktrace(e: Error): void;
+    /**
+     * Start the server.
+     */
+    listen(port?: number, isRestart?: boolean): Promise<ViteDevServer>;
+    /**
+     * Stop the server.
+     */
+    close(): Promise<void>;
+    /**
+     * Print server urls
+     */
+    printUrls(): void;
+    /**
+     * Restart the server.
+     *
+     * @param forceOptimize - force the optimizer to re-bundle, same as --force cli flag
+     */
+    restart(forceOptimize?: boolean): Promise<void>;
+    /* Excluded from this release type: _importGlobMap */
+    /* Excluded from this release type: _ssrExternals */
+    /* Excluded from this release type: _restartPromise */
+    /* Excluded from this release type: _forceOptimizeOnRestart */
+    /* Excluded from this release type: _pendingRequests */
+}
+
+export declare interface WatchOptions {
+    /**
+     * Indicates whether the process should continue to run as long as files are being watched. If
+     * set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`,
+     * even if the process continues to run.
+     */
+    persistent?: boolean
+
+    /**
+     * ([anymatch](https://github.com/micromatch/anymatch)-compatible definition) Defines files/paths to
+     * be ignored. The whole relative or absolute path is tested, not just filename. If a function
+     * with two arguments is provided, it gets called twice per path - once with a single argument
+     * (the path), second time with two arguments (the path and the
+     * [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path).
+     */
+    ignored?: Matcher
+
+    /**
+     * If set to `false` then `add`/`addDir` events are also emitted for matching paths while
+     * instantiating the watching as chokidar discovers these file paths (before the `ready` event).
+     */
+    ignoreInitial?: boolean
+
+    /**
+     * When `false`, only the symlinks themselves will be watched for changes instead of following
+     * the link references and bubbling events through the link's path.
+     */
+    followSymlinks?: boolean
+
+    /**
+     * The base directory from which watch `paths` are to be derived. Paths emitted with events will
+     * be relative to this.
+     */
+    cwd?: string
+
+    /**
+     * If set to true then the strings passed to .watch() and .add() are treated as literal path
+     * names, even if they look like globs.
+     *
+     * @default false
+     */
+    disableGlobbing?: boolean
+
+    /**
+     * Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU
+     * utilization, consider setting this to `false`. It is typically necessary to **set this to
+     * `true` to successfully watch files over a network**, and it may be necessary to successfully
+     * watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides
+     * the `useFsEvents` default.
+     */
+    usePolling?: boolean
+
+    /**
+     * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly
+     * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on
+     * OS X, `usePolling: true` becomes the default.
+     */
+    useFsEvents?: boolean
+
+    /**
+     * If relying upon the [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object that
+     * may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is
+     * provided even in cases where it wasn't already available from the underlying watch events.
+     */
+    alwaysStat?: boolean
+
+    /**
+     * If set, limits how many levels of subdirectories will be traversed.
+     */
+    depth?: number
+
+    /**
+     * Interval of file system polling.
+     */
+    interval?: number
+
+    /**
+     * Interval of file system polling for binary files. ([see list of binary extensions](https://gi
+     * thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
+     */
+    binaryInterval?: number
+
+    /**
+     *  Indicates whether to watch files that don't have read permissions if possible. If watching
+     *  fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed
+     *  silently.
+     */
+    ignorePermissionErrors?: boolean
+
+    /**
+     * `true` if `useFsEvents` and `usePolling` are `false`). Automatically filters out artifacts
+     * that occur when using editors that use "atomic writes" instead of writing directly to the
+     * source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change`
+     * event rather than `unlink` then `add`. If the default of 100 ms does not work well for you,
+     * you can override it by setting `atomic` to a custom value, in milliseconds.
+     */
+    atomic?: boolean | number
+
+    /**
+     * can be set to an object in order to adjust timing params:
+     */
+    awaitWriteFinish?: AwaitWriteFinishOptions | boolean
+}
+
+declare class WebSocket_2 extends EventEmitter {
+    /** The connection is not yet open. */
+    static readonly CONNECTING: 0
+    /** The connection is open and ready to communicate. */
+    static readonly OPEN: 1
+    /** The connection is in the process of closing. */
+    static readonly CLOSING: 2
+    /** The connection is closed. */
+    static readonly CLOSED: 3
+
+    binaryType: 'nodebuffer' | 'arraybuffer' | 'fragments'
+    readonly bufferedAmount: number
+    readonly extensions: string
+    /** Indicates whether the websocket is paused */
+    readonly isPaused: boolean
+    readonly protocol: string
+    /** The current state of the connection */
+    readonly readyState:
+    | typeof WebSocket_2.CONNECTING
+    | typeof WebSocket_2.OPEN
+    | typeof WebSocket_2.CLOSING
+    | typeof WebSocket_2.CLOSED
+    readonly url: string
+
+    /** The connection is not yet open. */
+    readonly CONNECTING: 0
+    /** The connection is open and ready to communicate. */
+    readonly OPEN: 1
+    /** The connection is in the process of closing. */
+    readonly CLOSING: 2
+    /** The connection is closed. */
+    readonly CLOSED: 3
+
+    onopen: ((event: WebSocket_2.Event) => void) | null
+    onerror: ((event: WebSocket_2.ErrorEvent) => void) | null
+    onclose: ((event: WebSocket_2.CloseEvent) => void) | null
+    onmessage: ((event: WebSocket_2.MessageEvent) => void) | null
+
+    constructor(address: null)
+    constructor(
+    address: string | URL_2,
+    options?: WebSocket_2.ClientOptions | ClientRequestArgs
+    )
+    constructor(
+    address: string | URL_2,
+    protocols?: string | string[],
+    options?: WebSocket_2.ClientOptions | ClientRequestArgs
+    )
+
+    close(code?: number, data?: string | Buffer): void
+    ping(data?: any, mask?: boolean, cb?: (err: Error) => void): void
+    pong(data?: any, mask?: boolean, cb?: (err: Error) => void): void
+    send(data: any, cb?: (err?: Error) => void): void
+    send(
+    data: any,
+    options: {
+        mask?: boolean | undefined
+        binary?: boolean | undefined
+        compress?: boolean | undefined
+        fin?: boolean | undefined
+    },
+    cb?: (err?: Error) => void
+    ): void
+    terminate(): void
+
+    /**
+     * Pause the websocket causing it to stop emitting events. Some events can still be
+     * emitted after this is called, until all buffered data is consumed. This method
+     * is a noop if the ready state is `CONNECTING` or `CLOSED`.
+     */
+    pause(): void
+    /**
+     * Make a paused socket resume emitting events. This method is a noop if the ready
+     * state is `CONNECTING` or `CLOSED`.
+     */
+    resume(): void
+
+    // HTML5 WebSocket events
+    addEventListener(
+    method: 'message',
+    cb: (event: WebSocket_2.MessageEvent) => void,
+    options?: WebSocket_2.EventListenerOptions
+    ): void
+    addEventListener(
+    method: 'close',
+    cb: (event: WebSocket_2.CloseEvent) => void,
+    options?: WebSocket_2.EventListenerOptions
+    ): void
+    addEventListener(
+    method: 'error',
+    cb: (event: WebSocket_2.ErrorEvent) => void,
+    options?: WebSocket_2.EventListenerOptions
+    ): void
+    addEventListener(
+    method: 'open',
+    cb: (event: WebSocket_2.Event) => void,
+    options?: WebSocket_2.EventListenerOptions
+    ): void
+
+    removeEventListener(
+    method: 'message',
+    cb: (event: WebSocket_2.MessageEvent) => void
+    ): void
+    removeEventListener(
+    method: 'close',
+    cb: (event: WebSocket_2.CloseEvent) => void
+    ): void
+    removeEventListener(
+    method: 'error',
+    cb: (event: WebSocket_2.ErrorEvent) => void
+    ): void
+    removeEventListener(
+    method: 'open',
+    cb: (event: WebSocket_2.Event) => void
+    ): void
+
+    // Events
+    on(
+    event: 'close',
+    listener: (this: WebSocket_2, code: number, reason: Buffer) => void
+    ): this
+    on(event: 'error', listener: (this: WebSocket_2, err: Error) => void): this
+    on(
+    event: 'upgrade',
+    listener: (this: WebSocket_2, request: IncomingMessage) => void
+    ): this
+    on(
+    event: 'message',
+    listener: (
+    this: WebSocket_2,
+    data: WebSocket_2.RawData,
+    isBinary: boolean
+    ) => void
+    ): this
+    on(event: 'open', listener: (this: WebSocket_2) => void): this
+    on(
+    event: 'ping' | 'pong',
+    listener: (this: WebSocket_2, data: Buffer) => void
+    ): this
+    on(
+    event: 'unexpected-response',
+    listener: (
+    this: WebSocket_2,
+    request: ClientRequest,
+    response: IncomingMessage
+    ) => void
+    ): this
+    on(
+    event: string | symbol,
+    listener: (this: WebSocket_2, ...args: any[]) => void
+    ): this
+
+    once(
+    event: 'close',
+    listener: (this: WebSocket_2, code: number, reason: Buffer) => void
+    ): this
+    once(event: 'error', listener: (this: WebSocket_2, err: Error) => void): this
+    once(
+    event: 'upgrade',
+    listener: (this: WebSocket_2, request: IncomingMessage) => void
+    ): this
+    once(
+    event: 'message',
+    listener: (
+    this: WebSocket_2,
+    data: WebSocket_2.RawData,
+    isBinary: boolean
+    ) => void
+    ): this
+    once(event: 'open', listener: (this: WebSocket_2) => void): this
+    once(
+    event: 'ping' | 'pong',
+    listener: (this: WebSocket_2, data: Buffer) => void
+    ): this
+    once(
+    event: 'unexpected-response',
+    listener: (
+    this: WebSocket_2,
+    request: ClientRequest,
+    response: IncomingMessage
+    ) => void
+    ): this
+    once(
+    event: string | symbol,
+    listener: (this: WebSocket_2, ...args: any[]) => void
+    ): this
+
+    off(
+    event: 'close',
+    listener: (this: WebSocket_2, code: number, reason: Buffer) => void
+    ): this
+    off(event: 'error', listener: (this: WebSocket_2, err: Error) => void): this
+    off(
+    event: 'upgrade',
+    listener: (this: WebSocket_2, request: IncomingMessage) => void
+    ): this
+    off(
+    event: 'message',
+    listener: (
+    this: WebSocket_2,
+    data: WebSocket_2.RawData,
+    isBinary: boolean
+    ) => void
+    ): this
+    off(event: 'open', listener: (this: WebSocket_2) => void): this
+    off(
+    event: 'ping' | 'pong',
+    listener: (this: WebSocket_2, data: Buffer) => void
+    ): this
+    off(
+    event: 'unexpected-response',
+    listener: (
+    this: WebSocket_2,
+    request: ClientRequest,
+    response: IncomingMessage
+    ) => void
+    ): this
+    off(
+    event: string | symbol,
+    listener: (this: WebSocket_2, ...args: any[]) => void
+    ): this
+
+    addListener(
+    event: 'close',
+    listener: (code: number, reason: Buffer) => void
+    ): this
+    addListener(event: 'error', listener: (err: Error) => void): this
+    addListener(
+    event: 'upgrade',
+    listener: (request: IncomingMessage) => void
+    ): this
+    addListener(
+    event: 'message',
+    listener: (data: WebSocket_2.RawData, isBinary: boolean) => void
+    ): this
+    addListener(event: 'open', listener: () => void): this
+    addListener(event: 'ping' | 'pong', listener: (data: Buffer) => void): this
+    addListener(
+    event: 'unexpected-response',
+    listener: (request: ClientRequest, response: IncomingMessage) => void
+    ): this
+    addListener(event: string | symbol, listener: (...args: any[]) => void): this
+
+    removeListener(
+    event: 'close',
+    listener: (code: number, reason: Buffer) => void
+    ): this
+    removeListener(event: 'error', listener: (err: Error) => void): this
+    removeListener(
+    event: 'upgrade',
+    listener: (request: IncomingMessage) => void
+    ): this
+    removeListener(
+    event: 'message',
+    listener: (data: WebSocket_2.RawData, isBinary: boolean) => void
+    ): this
+    removeListener(event: 'open', listener: () => void): this
+    removeListener(event: 'ping' | 'pong', listener: (data: Buffer) => void): this
+    removeListener(
+    event: 'unexpected-response',
+    listener: (request: ClientRequest, response: IncomingMessage) => void
+    ): this
+    removeListener(
+    event: string | symbol,
+    listener: (...args: any[]) => void
+    ): this
+}
+
+declare namespace WebSocket_2 {
+    /**
+     * Data represents the raw message payload received over the WebSocket.
+     */
+    type RawData = Buffer | ArrayBuffer | Buffer[]
+
+    /**
+     * Data represents the message payload received over the WebSocket.
+     */
+    type Data = string | Buffer | ArrayBuffer | Buffer[]
+
+    /**
+     * CertMeta represents the accepted types for certificate & key data.
+     */
+    type CertMeta = string | string[] | Buffer | Buffer[]
+
+    /**
+     * VerifyClientCallbackSync is a synchronous callback used to inspect the
+     * incoming message. The return value (boolean) of the function determines
+     * whether or not to accept the handshake.
+     */
+    type VerifyClientCallbackSync = (info: {
+        origin: string
+        secure: boolean
+        req: IncomingMessage
+    }) => boolean
+
+    /**
+     * VerifyClientCallbackAsync is an asynchronous callback used to inspect the
+     * incoming message. The return value (boolean) of the function determines
+     * whether or not to accept the handshake.
+     */
+    type VerifyClientCallbackAsync = (
+    info: { origin: string; secure: boolean; req: IncomingMessage },
+    callback: (
+    res: boolean,
+    code?: number,
+    message?: string,
+    headers?: OutgoingHttpHeaders
+    ) => void
+    ) => void
+
+    interface ClientOptions extends SecureContextOptions {
+        protocol?: string | undefined
+        followRedirects?: boolean | undefined
+        generateMask?(mask: Buffer): void
+        handshakeTimeout?: number | undefined
+        maxRedirects?: number | undefined
+        perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined
+        localAddress?: string | undefined
+        protocolVersion?: number | undefined
+        headers?: { [key: string]: string } | undefined
+        origin?: string | undefined
+        agent?: Agent | undefined
+        host?: string | undefined
+        family?: number | undefined
+        checkServerIdentity?(servername: string, cert: CertMeta): boolean
+        rejectUnauthorized?: boolean | undefined
+        maxPayload?: number | undefined
+        skipUTF8Validation?: boolean | undefined
+    }
+
+    interface PerMessageDeflateOptions {
+        serverNoContextTakeover?: boolean | undefined
+        clientNoContextTakeover?: boolean | undefined
+        serverMaxWindowBits?: number | undefined
+        clientMaxWindowBits?: number | undefined
+        zlibDeflateOptions?:
+        | {
+            flush?: number | undefined
+            finishFlush?: number | undefined
+            chunkSize?: number | undefined
+            windowBits?: number | undefined
+            level?: number | undefined
+            memLevel?: number | undefined
+            strategy?: number | undefined
+            dictionary?: Buffer | Buffer[] | DataView | undefined
+            info?: boolean | undefined
+        }
+        | undefined
+        zlibInflateOptions?: ZlibOptions | undefined
+        threshold?: number | undefined
+        concurrencyLimit?: number | undefined
+    }
+
+    interface Event {
+        type: string
+        target: WebSocket
+    }
+
+    interface ErrorEvent {
+        error: any
+        message: string
+        type: string
+        target: WebSocket
+    }
+
+    interface CloseEvent {
+        wasClean: boolean
+        code: number
+        reason: string
+        type: string
+        target: WebSocket
+    }
+
+    interface MessageEvent {
+        data: Data
+        type: string
+        target: WebSocket
+    }
+
+    interface EventListenerOptions {
+        once?: boolean | undefined
+    }
+
+    interface ServerOptions {
+        host?: string | undefined
+        port?: number | undefined
+        backlog?: number | undefined
+        server?: Server | Server_2 | undefined
+        verifyClient?:
+        | VerifyClientCallbackAsync
+        | VerifyClientCallbackSync
+        | undefined
+        handleProtocols?: (
+        protocols: Set<string>,
+        request: IncomingMessage
+        ) => string | false
+        path?: string | undefined
+        noServer?: boolean | undefined
+        clientTracking?: boolean | undefined
+        perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined
+        maxPayload?: number | undefined
+        skipUTF8Validation?: boolean | undefined
+        WebSocket?: typeof WebSocket.WebSocket | undefined
+    }
+
+    interface AddressInfo {
+        address: string
+        family: string
+        port: number
+    }
+
+    // WebSocket Server
+    class Server<T extends WebSocket = WebSocket> extends EventEmitter {
+        options: ServerOptions
+        path: string
+        clients: Set<T>
+
+        constructor(options?: ServerOptions, callback?: () => void)
+
+        address(): AddressInfo | string
+        close(cb?: (err?: Error) => void): void
+        handleUpgrade(
+        request: IncomingMessage,
+        socket: Duplex,
+        upgradeHead: Buffer,
+        callback: (client: T, request: IncomingMessage) => void
+        ): void
+        shouldHandle(request: IncomingMessage): boolean | Promise<boolean>
+
+        // Events
+        on(
+        event: 'connection',
+        cb: (this: Server<T>, socket: T, request: IncomingMessage) => void
+        ): this
+        on(event: 'error', cb: (this: Server<T>, error: Error) => void): this
+        on(
+        event: 'headers',
+        cb: (this: Server<T>, headers: string[], request: IncomingMessage) => void
+        ): this
+        on(event: 'close' | 'listening', cb: (this: Server<T>) => void): this
+        on(
+        event: string | symbol,
+        listener: (this: Server<T>, ...args: any[]) => void
+        ): this
+
+        once(
+        event: 'connection',
+        cb: (this: Server<T>, socket: T, request: IncomingMessage) => void
+        ): this
+        once(event: 'error', cb: (this: Server<T>, error: Error) => void): this
+        once(
+        event: 'headers',
+        cb: (this: Server<T>, headers: string[], request: IncomingMessage) => void
+        ): this
+        once(event: 'close' | 'listening', cb: (this: Server<T>) => void): this
+        once(
+        event: string | symbol,
+        listener: (this: Server<T>, ...args: any[]) => void
+        ): this
+
+        off(
+        event: 'connection',
+        cb: (this: Server<T>, socket: T, request: IncomingMessage) => void
+        ): this
+        off(event: 'error', cb: (this: Server<T>, error: Error) => void): this
+        off(
+        event: 'headers',
+        cb: (this: Server<T>, headers: string[], request: IncomingMessage) => void
+        ): this
+        off(event: 'close' | 'listening', cb: (this: Server<T>) => void): this
+        off(
+        event: string | symbol,
+        listener: (this: Server<T>, ...args: any[]) => void
+        ): this
+
+        addListener(
+        event: 'connection',
+        cb: (client: T, request: IncomingMessage) => void
+        ): this
+        addListener(event: 'error', cb: (err: Error) => void): this
+        addListener(
+        event: 'headers',
+        cb: (headers: string[], request: IncomingMessage) => void
+        ): this
+        addListener(event: 'close' | 'listening', cb: () => void): this
+        addListener(
+        event: string | symbol,
+        listener: (...args: any[]) => void
+        ): this
+
+        removeListener(event: 'connection', cb: (client: T) => void): this
+        removeListener(event: 'error', cb: (err: Error) => void): this
+        removeListener(
+        event: 'headers',
+        cb: (headers: string[], request: IncomingMessage) => void
+        ): this
+        removeListener(event: 'close' | 'listening', cb: () => void): this
+        removeListener(
+        event: string | symbol,
+        listener: (...args: any[]) => void
+        ): this
+    }
+
+    const WebSocketServer: typeof Server
+    interface WebSocketServer extends Server {} // tslint:disable-line no-empty-interface
+    const WebSocket: typeof WebSocketAlias
+    interface WebSocket extends WebSocketAlias {} // tslint:disable-line no-empty-interface
+
+    // WebSocket stream
+    function createWebSocketStream(
+    websocket: WebSocket,
+    options?: DuplexOptions
+    ): Duplex
+}
+export { WebSocket_2 as WebSocket }
+
+export declare const WebSocketAlias: typeof WebSocket_2;
+
+export declare interface WebSocketAlias extends WebSocket_2 {}
+
+export declare interface WebSocketClient {
+    /**
+     * Send event to the client
+     */
+    send(payload: HMRPayload): void;
+    /**
+     * Send custom event
+     */
+    send(event: string, payload?: CustomPayload['data']): void;
+    /**
+     * The raw WebSocket instance
+     * @advanced
+     */
+    socket: WebSocket_2;
+}
+
+export declare type WebSocketCustomListener<T> = (data: T, client: WebSocketClient) => void;
+
+export declare interface WebSocketServer {
+    /**
+     * Get all connected clients.
+     */
+    clients: Set<WebSocketClient>;
+    /**
+     * Broadcast events to all clients
+     */
+    send(payload: HMRPayload): void;
+    /**
+     * Send custom event
+     */
+    send<T extends string>(event: T, payload?: InferCustomEventPayload<T>): void;
+    /**
+     * Disconnect all clients and terminate the server.
+     */
+    close(): Promise<void>;
+    /**
+     * Handle custom event emitted by `import.meta.hot.send`
+     */
+    on: WebSocket_2.Server['on'] & {
+        <T extends string>(event: T, listener: WebSocketCustomListener<InferCustomEventPayload<T>>): void;
+    };
+    /**
+     * Unregister event listener.
+     */
+    off: WebSocket_2.Server['off'] & {
+        (event: string, listener: Function): void;
+    };
+}
+
+export { }