Best JavaScript code snippet using playwright-internal
vendor-node_modules_r.js
Source:vendor-node_modules_r.js  
...796    else {797        return value;798    }799}800function isCompatEnabled(key, context) {801    const mode = getCompatValue('MODE', context);802    const value = getCompatValue(key, context);803    // in v3 mode, only enable if explicitly set to true804    // otherwise enable for any non-false value805    return mode === 3 ? value === true : value !== false;806}807function checkCompatEnabled(key, context, loc, ...args) {808    const enabled = isCompatEnabled(key, context);809    if (( true) && enabled) {810        warnDeprecation(key, context, loc, ...args);811    }812    return enabled;813}814function warnDeprecation(key, context, loc, ...args) {815    const val = getCompatValue(key, context);816    if (val === 'suppress-warning') {817        return;818    }819    const { message, link } = deprecationData[key];820    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;821    const err = new SyntaxError(msg);822    err.code = key;823    if (loc)824        err.loc = loc;825    context.onWarn(err);826}827// The default decoder only provides escapes for characters reserved as part of828// the template syntax, and is only used if the custom renderer did not provide829// a platform-specific decoder.830const decodeRE = /&(gt|lt|amp|apos|quot);/g;831const decodeMap = {832    gt: '>',833    lt: '<',834    amp: '&',835    apos: "'",836    quot: '"'837};838const defaultParserOptions = {839    delimiters: [`{{`, `}}`],840    getNamespace: () => 0 /* HTML */,841    getTextMode: () => 0 /* DATA */,842    isVoidTag: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,843    isPreTag: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,844    isCustomElement: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,845    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),846    onError: defaultOnError,847    onWarn: defaultOnWarn,848    comments: false849};850function baseParse(content, options = {}) {851    const context = createParserContext(content, options);852    const start = getCursor(context);853    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));854}855function createParserContext(content, rawOptions) {856    const options = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, defaultParserOptions);857    for (const key in rawOptions) {858        // @ts-ignore859        options[key] = rawOptions[key] || defaultParserOptions[key];860    }861    return {862        options,863        column: 1,864        line: 1,865        offset: 0,866        originalSource: content,867        source: content,868        inPre: false,869        inVPre: false,870        onWarn: options.onWarn871    };872}873function parseChildren(context, mode, ancestors) {874    const parent = last(ancestors);875    const ns = parent ? parent.ns : 0 /* HTML */;876    const nodes = [];877    while (!isEnd(context, mode, ancestors)) {878        const s = context.source;879        let node = undefined;880        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {881            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {882                // '{{'883                node = parseInterpolation(context, mode);884            }885            else if (mode === 0 /* DATA */ && s[0] === '<') {886                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state887                if (s.length === 1) {888                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);889                }890                else if (s[1] === '!') {891                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state892                    if (startsWith(s, '<!--')) {893                        node = parseComment(context);894                    }895                    else if (startsWith(s, '<!DOCTYPE')) {896                        // Ignore DOCTYPE by a limitation.897                        node = parseBogusComment(context);898                    }899                    else if (startsWith(s, '<![CDATA[')) {900                        if (ns !== 0 /* HTML */) {901                            node = parseCDATA(context, ancestors);902                        }903                        else {904                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);905                            node = parseBogusComment(context);906                        }907                    }908                    else {909                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);910                        node = parseBogusComment(context);911                    }912                }913                else if (s[1] === '/') {914                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state915                    if (s.length === 2) {916                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);917                    }918                    else if (s[2] === '>') {919                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);920                        advanceBy(context, 3);921                        continue;922                    }923                    else if (/[a-z]/i.test(s[2])) {924                        emitError(context, 23 /* X_INVALID_END_TAG */);925                        parseTag(context, 1 /* End */, parent);926                        continue;927                    }928                    else {929                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);930                        node = parseBogusComment(context);931                    }932                }933                else if (/[a-z]/i.test(s[1])) {934                    node = parseElement(context, ancestors);935                    // 2.x <template> with no directive compat936                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&937                        node &&938                        node.tag === 'template' &&939                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&940                            isSpecialTemplateDirective(p.name))) {941                        ( true) &&942                            warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);943                        node = node.children;944                    }945                }946                else if (s[1] === '?') {947                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);948                    node = parseBogusComment(context);949                }950                else {951                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);952                }953            }954        }955        if (!node) {956            node = parseText(context, mode);957        }958        if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node)) {959            for (let i = 0; i < node.length; i++) {960                pushNode(nodes, node[i]);961            }962        }963        else {964            pushNode(nodes, node);965        }966    }967    // Whitespace handling strategy like v2968    let removedWhitespace = false;969    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {970        const preserve = context.options.whitespace === 'preserve';971        for (let i = 0; i < nodes.length; i++) {972            const node = nodes[i];973            if (!context.inPre && node.type === 2 /* TEXT */) {974                if (!/[^\t\r\n\f ]/.test(node.content)) {975                    const prev = nodes[i - 1];976                    const next = nodes[i + 1];977                    // Remove if:978                    // - the whitespace is the first or last node, or:979                    // - (condense mode) the whitespace is adjacent to a comment, or:980                    // - (condense mode) the whitespace is between two elements AND contains newline981                    if (!prev ||982                        !next ||983                        (!preserve &&984                            (prev.type === 3 /* COMMENT */ ||985                                next.type === 3 /* COMMENT */ ||986                                (prev.type === 1 /* ELEMENT */ &&987                                    next.type === 1 /* ELEMENT */ &&988                                    /[\r\n]/.test(node.content))))) {989                        removedWhitespace = true;990                        nodes[i] = null;991                    }992                    else {993                        // Otherwise, the whitespace is condensed into a single space994                        node.content = ' ';995                    }996                }997                else if (!preserve) {998                    // in condense mode, consecutive whitespaces in text are condensed999                    // down to a single space.1000                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1001                }1002            }1003            // also remove comment nodes in prod by default1004            if (false) {}1005        }1006        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1007            // remove leading newline per html spec1008            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1009            const first = nodes[0];1010            if (first && first.type === 2 /* TEXT */) {1011                first.content = first.content.replace(/^\r?\n/, '');1012            }1013        }1014    }1015    return removedWhitespace ? nodes.filter(Boolean) : nodes;1016}1017function pushNode(nodes, node) {1018    if (node.type === 2 /* TEXT */) {1019        const prev = last(nodes);1020        // Merge if both this and the previous node are text and those are1021        // consecutive. This happens for cases like "a < b".1022        if (prev &&1023            prev.type === 2 /* TEXT */ &&1024            prev.loc.end.offset === node.loc.start.offset) {1025            prev.content += node.content;1026            prev.loc.end = node.loc.end;1027            prev.loc.source += node.loc.source;1028            return;1029        }1030    }1031    nodes.push(node);1032}1033function parseCDATA(context, ancestors) {1034    advanceBy(context, 9);1035    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1036    if (context.source.length === 0) {1037        emitError(context, 6 /* EOF_IN_CDATA */);1038    }1039    else {1040        advanceBy(context, 3);1041    }1042    return nodes;1043}1044function parseComment(context) {1045    const start = getCursor(context);1046    let content;1047    // Regular comment.1048    const match = /--(\!)?>/.exec(context.source);1049    if (!match) {1050        content = context.source.slice(4);1051        advanceBy(context, context.source.length);1052        emitError(context, 7 /* EOF_IN_COMMENT */);1053    }1054    else {1055        if (match.index <= 3) {1056            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1057        }1058        if (match[1]) {1059            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1060        }1061        content = context.source.slice(4, match.index);1062        // Advancing with reporting nested comments.1063        const s = context.source.slice(0, match.index);1064        let prevIndex = 1, nestedIndex = 0;1065        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1066            advanceBy(context, nestedIndex - prevIndex + 1);1067            if (nestedIndex + 4 < s.length) {1068                emitError(context, 16 /* NESTED_COMMENT */);1069            }1070            prevIndex = nestedIndex + 1;1071        }1072        advanceBy(context, match.index + match[0].length - prevIndex + 1);1073    }1074    return {1075        type: 3 /* COMMENT */,1076        content,1077        loc: getSelection(context, start)1078    };1079}1080function parseBogusComment(context) {1081    const start = getCursor(context);1082    const contentStart = context.source[1] === '?' ? 1 : 2;1083    let content;1084    const closeIndex = context.source.indexOf('>');1085    if (closeIndex === -1) {1086        content = context.source.slice(contentStart);1087        advanceBy(context, context.source.length);1088    }1089    else {1090        content = context.source.slice(contentStart, closeIndex);1091        advanceBy(context, closeIndex + 1);1092    }1093    return {1094        type: 3 /* COMMENT */,1095        content,1096        loc: getSelection(context, start)1097    };1098}1099function parseElement(context, ancestors) {1100    // Start tag.1101    const wasInPre = context.inPre;1102    const wasInVPre = context.inVPre;1103    const parent = last(ancestors);1104    const element = parseTag(context, 0 /* Start */, parent);1105    const isPreBoundary = context.inPre && !wasInPre;1106    const isVPreBoundary = context.inVPre && !wasInVPre;1107    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1108        // #4030 self-closing <pre> tag1109        if (context.options.isPreTag(element.tag)) {1110            context.inPre = false;1111        }1112        return element;1113    }1114    // Children.1115    ancestors.push(element);1116    const mode = context.options.getTextMode(element, parent);1117    const children = parseChildren(context, mode, ancestors);1118    ancestors.pop();1119    // 2.x inline-template compat1120    {1121        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1122        if (inlineTemplateProp &&1123            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1124            const loc = getSelection(context, element.loc.end);1125            inlineTemplateProp.value = {1126                type: 2 /* TEXT */,1127                content: loc.source,1128                loc1129            };1130        }1131    }1132    element.children = children;1133    // End tag.1134    if (startsWithEndTagOpen(context.source, element.tag)) {1135        parseTag(context, 1 /* End */, parent);1136    }1137    else {1138        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1139        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1140            const first = children[0];1141            if (first && startsWith(first.loc.source, '<!--')) {1142                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1143            }1144        }1145    }1146    element.loc = getSelection(context, element.loc.start);1147    if (isPreBoundary) {1148        context.inPre = false;1149    }1150    if (isVPreBoundary) {1151        context.inVPre = false;1152    }1153    return element;1154}1155const isSpecialTemplateDirective = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.makeMap)(`if,else,else-if,for,slot`);1156function parseTag(context, type, parent) {1157    // Tag open.1158    const start = getCursor(context);1159    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1160    const tag = match[1];1161    const ns = context.options.getNamespace(tag, parent);1162    advanceBy(context, match[0].length);1163    advanceSpaces(context);1164    // save current state in case we need to re-parse attributes with v-pre1165    const cursor = getCursor(context);1166    const currentSource = context.source;1167    // check <pre> tag1168    const isPreTag = context.options.isPreTag(tag);1169    if (isPreTag) {1170        context.inPre = true;1171    }1172    // Attributes.1173    let props = parseAttributes(context, type);1174    // check v-pre1175    if (type === 0 /* Start */ &&1176        !context.inVPre &&1177        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1178        context.inVPre = true;1179        // reset context1180        (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)(context, cursor);1181        context.source = currentSource;1182        // re-parse attrs and filter out v-pre itself1183        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1184    }1185    // Tag close.1186    let isSelfClosing = false;1187    if (context.source.length === 0) {1188        emitError(context, 9 /* EOF_IN_TAG */);1189    }1190    else {1191        isSelfClosing = startsWith(context.source, '/>');1192        if (type === 1 /* End */ && isSelfClosing) {1193            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1194        }1195        advanceBy(context, isSelfClosing ? 2 : 1);1196    }1197    if (type === 1 /* End */) {1198        return;1199    }1200    // 2.x deprecation checks1201    if (( true) &&1202        isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1203        let hasIf = false;1204        let hasFor = false;1205        for (let i = 0; i < props.length; i++) {1206            const p = props[i];1207            if (p.type === 7 /* DIRECTIVE */) {1208                if (p.name === 'if') {1209                    hasIf = true;1210                }1211                else if (p.name === 'for') {1212                    hasFor = true;1213                }1214            }1215            if (hasIf && hasFor) {1216                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1217            }1218        }1219    }1220    let tagType = 0 /* ELEMENT */;1221    if (!context.inVPre) {1222        if (tag === 'slot') {1223            tagType = 2 /* SLOT */;1224        }1225        else if (tag === 'template') {1226            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1227                tagType = 3 /* TEMPLATE */;1228            }1229        }1230        else if (isComponent(tag, props, context)) {1231            tagType = 1 /* COMPONENT */;1232        }1233    }1234    return {1235        type: 1 /* ELEMENT */,1236        ns,1237        tag,1238        tagType,1239        props,1240        isSelfClosing,1241        children: [],1242        loc: getSelection(context, start),1243        codegenNode: undefined // to be created during transform phase1244    };1245}1246function isComponent(tag, props, context) {1247    const options = context.options;1248    if (options.isCustomElement(tag)) {1249        return false;1250    }1251    if (tag === 'component' ||1252        /^[A-Z]/.test(tag) ||1253        isCoreComponent(tag) ||1254        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1255        (options.isNativeTag && !options.isNativeTag(tag))) {1256        return true;1257    }1258    // at this point the tag should be a native tag, but check for potential "is"1259    // casting1260    for (let i = 0; i < props.length; i++) {1261        const p = props[i];1262        if (p.type === 6 /* ATTRIBUTE */) {1263            if (p.name === 'is' && p.value) {1264                if (p.value.content.startsWith('vue:')) {1265                    return true;1266                }1267                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1268                    return true;1269                }1270            }1271        }1272        else {1273            // directive1274            // v-is (TODO Deprecate)1275            if (p.name === 'is') {1276                return true;1277            }1278            else if (1279            // :is on plain element - only treat as component in compat mode1280            p.name === 'bind' &&1281                isBindKey(p.arg, 'is') &&1282                true &&1283                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1284                return true;1285            }1286        }1287    }1288}1289function parseAttributes(context, type) {1290    const props = [];1291    const attributeNames = new Set();1292    while (context.source.length > 0 &&1293        !startsWith(context.source, '>') &&1294        !startsWith(context.source, '/>')) {1295        if (startsWith(context.source, '/')) {1296            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1297            advanceBy(context, 1);1298            advanceSpaces(context);1299            continue;1300        }1301        if (type === 1 /* End */) {1302            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1303        }1304        const attr = parseAttribute(context, attributeNames);1305        if (type === 0 /* Start */) {1306            props.push(attr);1307        }1308        if (/^[^\t\r\n\f />]/.test(context.source)) {1309            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1310        }1311        advanceSpaces(context);1312    }1313    return props;1314}1315function parseAttribute(context, nameSet) {1316    // Name.1317    const start = getCursor(context);1318    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1319    const name = match[0];1320    if (nameSet.has(name)) {1321        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1322    }1323    nameSet.add(name);1324    if (name[0] === '=') {1325        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1326    }1327    {1328        const pattern = /["'<]/g;1329        let m;1330        while ((m = pattern.exec(name))) {1331            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1332        }1333    }1334    advanceBy(context, name.length);1335    // Value1336    let value = undefined;1337    if (/^[\t\r\n\f ]*=/.test(context.source)) {1338        advanceSpaces(context);1339        advanceBy(context, 1);1340        advanceSpaces(context);1341        value = parseAttributeValue(context);1342        if (!value) {1343            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1344        }1345    }1346    const loc = getSelection(context, start);1347    if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {1348        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1349        let dirName = match[1] ||1350            (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');1351        let arg;1352        if (match[2]) {1353            const isSlot = dirName === 'slot';1354            const startOffset = name.lastIndexOf(match[2]);1355            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1356            let content = match[2];1357            let isStatic = true;1358            if (content.startsWith('[')) {1359                isStatic = false;1360                if (!content.endsWith(']')) {1361                    emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1362                }1363                content = content.substr(1, content.length - 2);1364            }1365            else if (isSlot) {1366                // #1241 special case for v-slot: vuetify relies extensively on slot1367                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1368                // supports such usage so we are keeping it consistent with 2.x.1369                content += match[3] || '';1370            }1371            arg = {1372                type: 4 /* SIMPLE_EXPRESSION */,1373                content,1374                isStatic,1375                constType: isStatic1376                    ? 3 /* CAN_STRINGIFY */1377                    : 0 /* NOT_CONSTANT */,1378                loc1379            };1380        }1381        if (value && value.isQuoted) {1382            const valueLoc = value.loc;1383            valueLoc.start.offset++;1384            valueLoc.start.column++;1385            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1386            valueLoc.source = valueLoc.source.slice(1, -1);1387        }1388        const modifiers = match[3] ? match[3].substr(1).split('.') : [];1389        // 2.x compat v-bind:foo.sync -> v-model:foo1390        if (dirName === 'bind' && arg) {1391            if (modifiers.includes('sync') &&1392                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1393                dirName = 'model';1394                modifiers.splice(modifiers.indexOf('sync'), 1);1395            }1396            if (( true) && modifiers.includes('prop')) {1397                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1398            }1399        }1400        return {1401            type: 7 /* DIRECTIVE */,1402            name: dirName,1403            exp: value && {1404                type: 4 /* SIMPLE_EXPRESSION */,1405                content: value.content,1406                isStatic: false,1407                // Treat as non-constant by default. This can be potentially set to1408                // other values by `transformExpression` to make it eligible for hoisting.1409                constType: 0 /* NOT_CONSTANT */,1410                loc: value.loc1411            },1412            arg,1413            modifiers,1414            loc1415        };1416    }1417    return {1418        type: 6 /* ATTRIBUTE */,1419        name,1420        value: value && {1421            type: 2 /* TEXT */,1422            content: value.content,1423            loc: value.loc1424        },1425        loc1426    };1427}1428function parseAttributeValue(context) {1429    const start = getCursor(context);1430    let content;1431    const quote = context.source[0];1432    const isQuoted = quote === `"` || quote === `'`;1433    if (isQuoted) {1434        // Quoted value.1435        advanceBy(context, 1);1436        const endIndex = context.source.indexOf(quote);1437        if (endIndex === -1) {1438            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1439        }1440        else {1441            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1442            advanceBy(context, 1);1443        }1444    }1445    else {1446        // Unquoted1447        const match = /^[^\t\r\n\f >]+/.exec(context.source);1448        if (!match) {1449            return undefined;1450        }1451        const unexpectedChars = /["'<=`]/g;1452        let m;1453        while ((m = unexpectedChars.exec(match[0]))) {1454            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1455        }1456        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1457    }1458    return { content, isQuoted, loc: getSelection(context, start) };1459}1460function parseInterpolation(context, mode) {1461    const [open, close] = context.options.delimiters;1462    const closeIndex = context.source.indexOf(close, open.length);1463    if (closeIndex === -1) {1464        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1465        return undefined;1466    }1467    const start = getCursor(context);1468    advanceBy(context, open.length);1469    const innerStart = getCursor(context);1470    const innerEnd = getCursor(context);1471    const rawContentLength = closeIndex - open.length;1472    const rawContent = context.source.slice(0, rawContentLength);1473    const preTrimContent = parseTextData(context, rawContentLength, mode);1474    const content = preTrimContent.trim();1475    const startOffset = preTrimContent.indexOf(content);1476    if (startOffset > 0) {1477        advancePositionWithMutation(innerStart, rawContent, startOffset);1478    }1479    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1480    advancePositionWithMutation(innerEnd, rawContent, endOffset);1481    advanceBy(context, close.length);1482    return {1483        type: 5 /* INTERPOLATION */,1484        content: {1485            type: 4 /* SIMPLE_EXPRESSION */,1486            isStatic: false,1487            // Set `isConstant` to false by default and will decide in transformExpression1488            constType: 0 /* NOT_CONSTANT */,1489            content,1490            loc: getSelection(context, innerStart, innerEnd)1491        },1492        loc: getSelection(context, start)1493    };1494}1495function parseText(context, mode) {1496    const endTokens = ['<', context.options.delimiters[0]];1497    if (mode === 3 /* CDATA */) {1498        endTokens.push(']]>');1499    }1500    let endIndex = context.source.length;1501    for (let i = 0; i < endTokens.length; i++) {1502        const index = context.source.indexOf(endTokens[i], 1);1503        if (index !== -1 && endIndex > index) {1504            endIndex = index;1505        }1506    }1507    const start = getCursor(context);1508    const content = parseTextData(context, endIndex, mode);1509    return {1510        type: 2 /* TEXT */,1511        content,1512        loc: getSelection(context, start)1513    };1514}1515/**1516 * Get text data with a given length from the current location.1517 * This translates HTML entities in the text data.1518 */1519function parseTextData(context, length, mode) {1520    const rawText = context.source.slice(0, length);1521    advanceBy(context, length);1522    if (mode === 2 /* RAWTEXT */ ||1523        mode === 3 /* CDATA */ ||1524        rawText.indexOf('&') === -1) {1525        return rawText;1526    }1527    else {1528        // DATA or RCDATA containing "&"". Entity decoding required.1529        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1530    }1531}1532function getCursor(context) {1533    const { column, line, offset } = context;1534    return { column, line, offset };1535}1536function getSelection(context, start, end) {1537    end = end || getCursor(context);1538    return {1539        start,1540        end,1541        source: context.originalSource.slice(start.offset, end.offset)1542    };1543}1544function last(xs) {1545    return xs[xs.length - 1];1546}1547function startsWith(source, searchString) {1548    return source.startsWith(searchString);1549}1550function advanceBy(context, numberOfCharacters) {1551    const { source } = context;1552    advancePositionWithMutation(context, source, numberOfCharacters);1553    context.source = source.slice(numberOfCharacters);1554}1555function advanceSpaces(context) {1556    const match = /^[\t\r\n\f ]+/.exec(context.source);1557    if (match) {1558        advanceBy(context, match[0].length);1559    }1560}1561function getNewPosition(context, start, numberOfCharacters) {1562    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1563}1564function emitError(context, code, offset, loc = getCursor(context)) {1565    if (offset) {1566        loc.offset += offset;1567        loc.column += offset;1568    }1569    context.options.onError(createCompilerError(code, {1570        start: loc,1571        end: loc,1572        source: ''1573    }));1574}1575function isEnd(context, mode, ancestors) {1576    const s = context.source;1577    switch (mode) {1578        case 0 /* DATA */:1579            if (startsWith(s, '</')) {1580                // TODO: probably bad performance1581                for (let i = ancestors.length - 1; i >= 0; --i) {1582                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {1583                        return true;1584                    }1585                }1586            }1587            break;1588        case 1 /* RCDATA */:1589        case 2 /* RAWTEXT */: {1590            const parent = last(ancestors);1591            if (parent && startsWithEndTagOpen(s, parent.tag)) {1592                return true;1593            }1594            break;1595        }1596        case 3 /* CDATA */:1597            if (startsWith(s, ']]>')) {1598                return true;1599            }1600            break;1601    }1602    return !s;1603}1604function startsWithEndTagOpen(source, tag) {1605    return (startsWith(source, '</') &&1606        source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&1607        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1608}1609function hoistStatic(root, context) {1610    walk(root, context, 1611    // Root node is unfortunately non-hoistable due to potential parent1612    // fallthrough attributes.1613    isSingleElementRoot(root, root.children[0]));1614}1615function isSingleElementRoot(root, child) {1616    const { children } = root;1617    return (children.length === 1 &&1618        child.type === 1 /* ELEMENT */ &&1619        !isSlotOutlet(child));1620}1621function walk(node, context, doNotHoistNode = false) {1622    let hasHoistedNode = false;1623    // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces1624    // static bindings with expressions. These expressions are guaranteed to be1625    // constant so they are still eligible for hoisting, but they are only1626    // available at runtime and therefore cannot be evaluated ahead of time.1627    // This is only a concern for pre-stringification (via transformHoist by1628    // @vue/compiler-dom), but doing it here allows us to perform only one full1629    // walk of the AST and allow `stringifyStatic` to stop walking as soon as its1630    // stringficiation threshold is met.1631    let canStringify = true;1632    const { children } = node;1633    for (let i = 0; i < children.length; i++) {1634        const child = children[i];1635        // only plain elements & text calls are eligible for hoisting.1636        if (child.type === 1 /* ELEMENT */ &&1637            child.tagType === 0 /* ELEMENT */) {1638            const constantType = doNotHoistNode1639                ? 0 /* NOT_CONSTANT */1640                : getConstantType(child, context);1641            if (constantType > 0 /* NOT_CONSTANT */) {1642                if (constantType < 3 /* CAN_STRINGIFY */) {1643                    canStringify = false;1644                }1645                if (constantType >= 2 /* CAN_HOIST */) {1646                    child.codegenNode.patchFlag =1647                        -1 /* HOISTED */ + (( true) ? ` /* HOISTED */` : 0);1648                    child.codegenNode = context.hoist(child.codegenNode);1649                    hasHoistedNode = true;1650                    continue;1651                }1652            }1653            else {1654                // node may contain dynamic children, but its props may be eligible for1655                // hoisting.1656                const codegenNode = child.codegenNode;1657                if (codegenNode.type === 13 /* VNODE_CALL */) {1658                    const flag = getPatchFlag(codegenNode);1659                    if ((!flag ||1660                        flag === 512 /* NEED_PATCH */ ||1661                        flag === 1 /* TEXT */) &&1662                        getGeneratedPropsConstantType(child, context) >=1663                            2 /* CAN_HOIST */) {1664                        const props = getNodeProps(child);1665                        if (props) {1666                            codegenNode.props = context.hoist(props);1667                        }1668                    }1669                }1670            }1671        }1672        else if (child.type === 12 /* TEXT_CALL */) {1673            const contentType = getConstantType(child.content, context);1674            if (contentType > 0) {1675                if (contentType < 3 /* CAN_STRINGIFY */) {1676                    canStringify = false;1677                }1678                if (contentType >= 2 /* CAN_HOIST */) {1679                    child.codegenNode = context.hoist(child.codegenNode);1680                    hasHoistedNode = true;1681                }1682            }1683        }1684        // walk further1685        if (child.type === 1 /* ELEMENT */) {1686            const isComponent = child.tagType === 1 /* COMPONENT */;1687            if (isComponent) {1688                context.scopes.vSlot++;1689            }1690            walk(child, context);1691            if (isComponent) {1692                context.scopes.vSlot--;1693            }1694        }1695        else if (child.type === 11 /* FOR */) {1696            // Do not hoist v-for single child because it has to be a block1697            walk(child, context, child.children.length === 1);1698        }1699        else if (child.type === 9 /* IF */) {1700            for (let i = 0; i < child.branches.length; i++) {1701                // Do not hoist v-if single child because it has to be a block1702                walk(child.branches[i], context, child.branches[i].children.length === 1);1703            }1704        }1705    }1706    if (canStringify && hasHoistedNode && context.transformHoist) {1707        context.transformHoist(children, context, node);1708    }1709}1710function getConstantType(node, context) {1711    const { constantCache } = context;1712    switch (node.type) {1713        case 1 /* ELEMENT */:1714            if (node.tagType !== 0 /* ELEMENT */) {1715                return 0 /* NOT_CONSTANT */;1716            }1717            const cached = constantCache.get(node);1718            if (cached !== undefined) {1719                return cached;1720            }1721            const codegenNode = node.codegenNode;1722            if (codegenNode.type !== 13 /* VNODE_CALL */) {1723                return 0 /* NOT_CONSTANT */;1724            }1725            const flag = getPatchFlag(codegenNode);1726            if (!flag) {1727                let returnType = 3 /* CAN_STRINGIFY */;1728                // Element itself has no patch flag. However we still need to check:1729                // 1. Even for a node with no patch flag, it is possible for it to contain1730                // non-hoistable expressions that refers to scope variables, e.g. compiler1731                // injected keys or cached event handlers. Therefore we need to always1732                // check the codegenNode's props to be sure.1733                const generatedPropsType = getGeneratedPropsConstantType(node, context);1734                if (generatedPropsType === 0 /* NOT_CONSTANT */) {1735                    constantCache.set(node, 0 /* NOT_CONSTANT */);1736                    return 0 /* NOT_CONSTANT */;1737                }1738                if (generatedPropsType < returnType) {1739                    returnType = generatedPropsType;1740                }1741                // 2. its children.1742                for (let i = 0; i < node.children.length; i++) {1743                    const childType = getConstantType(node.children[i], context);1744                    if (childType === 0 /* NOT_CONSTANT */) {1745                        constantCache.set(node, 0 /* NOT_CONSTANT */);1746                        return 0 /* NOT_CONSTANT */;1747                    }1748                    if (childType < returnType) {1749                        returnType = childType;1750                    }1751                }1752                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01753                // type, check if any of the props can cause the type to be lowered1754                // we can skip can_patch because it's guaranteed by the absence of a1755                // patchFlag.1756                if (returnType > 1 /* CAN_SKIP_PATCH */) {1757                    for (let i = 0; i < node.props.length; i++) {1758                        const p = node.props[i];1759                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1760                            const expType = getConstantType(p.exp, context);1761                            if (expType === 0 /* NOT_CONSTANT */) {1762                                constantCache.set(node, 0 /* NOT_CONSTANT */);1763                                return 0 /* NOT_CONSTANT */;1764                            }1765                            if (expType < returnType) {1766                                returnType = expType;1767                            }1768                        }1769                    }1770                }1771                // only svg/foreignObject could be block here, however if they are1772                // static then they don't need to be blocks since there will be no1773                // nested updates.1774                if (codegenNode.isBlock) {1775                    context.removeHelper(OPEN_BLOCK);1776                    context.removeHelper(CREATE_BLOCK);1777                    codegenNode.isBlock = false;1778                    context.helper(CREATE_VNODE);1779                }1780                constantCache.set(node, returnType);1781                return returnType;1782            }1783            else {1784                constantCache.set(node, 0 /* NOT_CONSTANT */);1785                return 0 /* NOT_CONSTANT */;1786            }1787        case 2 /* TEXT */:1788        case 3 /* COMMENT */:1789            return 3 /* CAN_STRINGIFY */;1790        case 9 /* IF */:1791        case 11 /* FOR */:1792        case 10 /* IF_BRANCH */:1793            return 0 /* NOT_CONSTANT */;1794        case 5 /* INTERPOLATION */:1795        case 12 /* TEXT_CALL */:1796            return getConstantType(node.content, context);1797        case 4 /* SIMPLE_EXPRESSION */:1798            return node.constType;1799        case 8 /* COMPOUND_EXPRESSION */:1800            let returnType = 3 /* CAN_STRINGIFY */;1801            for (let i = 0; i < node.children.length; i++) {1802                const child = node.children[i];1803                if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(child)) {1804                    continue;1805                }1806                const childType = getConstantType(child, context);1807                if (childType === 0 /* NOT_CONSTANT */) {1808                    return 0 /* NOT_CONSTANT */;1809                }1810                else if (childType < returnType) {1811                    returnType = childType;1812                }1813            }1814            return returnType;1815        default:1816            if ((true)) ;1817            return 0 /* NOT_CONSTANT */;1818    }1819}1820function getGeneratedPropsConstantType(node, context) {1821    let returnType = 3 /* CAN_STRINGIFY */;1822    const props = getNodeProps(node);1823    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1824        const { properties } = props;1825        for (let i = 0; i < properties.length; i++) {1826            const { key, value } = properties[i];1827            const keyType = getConstantType(key, context);1828            if (keyType === 0 /* NOT_CONSTANT */) {1829                return keyType;1830            }1831            if (keyType < returnType) {1832                returnType = keyType;1833            }1834            if (value.type !== 4 /* SIMPLE_EXPRESSION */) {1835                return 0 /* NOT_CONSTANT */;1836            }1837            const valueType = getConstantType(value, context);1838            if (valueType === 0 /* NOT_CONSTANT */) {1839                return valueType;1840            }1841            if (valueType < returnType) {1842                returnType = valueType;1843            }1844        }1845    }1846    return returnType;1847}1848function getNodeProps(node) {1849    const codegenNode = node.codegenNode;1850    if (codegenNode.type === 13 /* VNODE_CALL */) {1851        return codegenNode.props;1852    }1853}1854function getPatchFlag(node) {1855    const flag = node.patchFlag;1856    return flag ? parseInt(flag, 10) : undefined;1857}1858function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NOOP, isCustomElement = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, ssrCssVars = ``, bindingMetadata = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {1859    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1860    const context = {1861        // options1862        selfName: nameMatch && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.capitalize)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(nameMatch[1])),1863        prefixIdentifiers,1864        hoistStatic,1865        cacheHandlers,1866        nodeTransforms,1867        directiveTransforms,1868        transformHoist,1869        isBuiltInComponent,1870        isCustomElement,1871        expressionPlugins,1872        scopeId,1873        slotted,1874        ssr,1875        ssrCssVars,1876        bindingMetadata,1877        inline,1878        isTS,1879        onError,1880        onWarn,1881        compatConfig,1882        // state1883        root,1884        helpers: new Map(),1885        components: new Set(),1886        directives: new Set(),1887        hoists: [],1888        imports: [],1889        constantCache: new Map(),1890        temps: 0,1891        cached: 0,1892        identifiers: Object.create(null),1893        scopes: {1894            vFor: 0,1895            vSlot: 0,1896            vPre: 0,1897            vOnce: 01898        },1899        parent: null,1900        currentNode: root,1901        childIndex: 0,1902        // methods1903        helper(name) {1904            const count = context.helpers.get(name) || 0;1905            context.helpers.set(name, count + 1);1906            return name;1907        },1908        removeHelper(name) {1909            const count = context.helpers.get(name);1910            if (count) {1911                const currentCount = count - 1;1912                if (!currentCount) {1913                    context.helpers.delete(name);1914                }1915                else {1916                    context.helpers.set(name, currentCount);1917                }1918            }1919        },1920        helperString(name) {1921            return `_${helperNameMap[context.helper(name)]}`;1922        },1923        replaceNode(node) {1924            /* istanbul ignore if */1925            if ((true)) {1926                if (!context.currentNode) {1927                    throw new Error(`Node being replaced is already removed.`);1928                }1929                if (!context.parent) {1930                    throw new Error(`Cannot replace root node.`);1931                }1932            }1933            context.parent.children[context.childIndex] = context.currentNode = node;1934        },1935        removeNode(node) {1936            if (( true) && !context.parent) {1937                throw new Error(`Cannot remove root node.`);1938            }1939            const list = context.parent.children;1940            const removalIndex = node1941                ? list.indexOf(node)1942                : context.currentNode1943                    ? context.childIndex1944                    : -1;1945            /* istanbul ignore if */1946            if (( true) && removalIndex < 0) {1947                throw new Error(`node being removed is not a child of current parent`);1948            }1949            if (!node || node === context.currentNode) {1950                // current node removed1951                context.currentNode = null;1952                context.onNodeRemoved();1953            }1954            else {1955                // sibling node removed1956                if (context.childIndex > removalIndex) {1957                    context.childIndex--;1958                    context.onNodeRemoved();1959                }1960            }1961            context.parent.children.splice(removalIndex, 1);1962        },1963        onNodeRemoved: () => { },1964        addIdentifiers(exp) {1965        },1966        removeIdentifiers(exp) {1967        },1968        hoist(exp) {1969            context.hoists.push(exp);1970            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);1971            identifier.hoisted = exp;1972            return identifier;1973        },1974        cache(exp, isVNode = false) {1975            return createCacheExpression(++context.cached, exp, isVNode);1976        }1977    };1978    {1979        context.filters = new Set();1980    }1981    return context;1982}1983function transform(root, options) {1984    const context = createTransformContext(root, options);1985    traverseNode(root, context);1986    if (options.hoistStatic) {1987        hoistStatic(root, context);1988    }1989    if (!options.ssr) {1990        createRootCodegen(root, context);1991    }1992    // finalize meta information1993    root.helpers = [...context.helpers.keys()];1994    root.components = [...context.components];1995    root.directives = [...context.directives];1996    root.imports = context.imports;1997    root.hoists = context.hoists;1998    root.temps = context.temps;1999    root.cached = context.cached;2000    {2001        root.filters = [...context.filters];2002    }2003}2004function createRootCodegen(root, context) {2005    const { helper, removeHelper } = context;2006    const { children } = root;2007    if (children.length === 1) {2008        const child = children[0];2009        // if the single child is an element, turn it into a block.2010        if (isSingleElementRoot(root, child) && child.codegenNode) {2011            // single element root is never hoisted so codegenNode will never be2012            // SimpleExpressionNode2013            const codegenNode = child.codegenNode;2014            if (codegenNode.type === 13 /* VNODE_CALL */) {2015                if (!codegenNode.isBlock) {2016                    removeHelper(CREATE_VNODE);2017                    codegenNode.isBlock = true;2018                    helper(OPEN_BLOCK);2019                    helper(CREATE_BLOCK);2020                }2021            }2022            root.codegenNode = codegenNode;2023        }2024        else {2025            // - single <slot/>, IfNode, ForNode: already blocks.2026            // - single text node: always patched.2027            // root codegen falls through via genNode()2028            root.codegenNode = child;2029        }2030    }2031    else if (children.length > 1) {2032        // root has multiple nodes - return a fragment block.2033        let patchFlag = 64 /* STABLE_FRAGMENT */;2034        let patchFlagText = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64];2035        // check if the fragment actually contains a single valid child with2036        // the rest being comments2037        if (( true) &&2038            children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2039            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2040            patchFlagText += `, ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[2048]}`;2041        }2042        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (( true) ? ` /* ${patchFlagText} */` : 0), undefined, undefined, true);2043    }2044    else ;2045}2046function traverseChildren(parent, context) {2047    let i = 0;2048    const nodeRemoved = () => {2049        i--;2050    };2051    for (; i < parent.children.length; i++) {2052        const child = parent.children[i];2053        if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child))2054            continue;2055        context.parent = parent;2056        context.childIndex = i;2057        context.onNodeRemoved = nodeRemoved;2058        traverseNode(child, context);2059    }2060}2061function traverseNode(node, context) {2062    context.currentNode = node;2063    // apply transform plugins2064    const { nodeTransforms } = context;2065    const exitFns = [];2066    for (let i = 0; i < nodeTransforms.length; i++) {2067        const onExit = nodeTransforms[i](node, context);2068        if (onExit) {2069            if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(onExit)) {2070                exitFns.push(...onExit);2071            }2072            else {2073                exitFns.push(onExit);2074            }2075        }2076        if (!context.currentNode) {2077            // node was removed2078            return;2079        }2080        else {2081            // node may have been replaced2082            node = context.currentNode;2083        }2084    }2085    switch (node.type) {2086        case 3 /* COMMENT */:2087            if (!context.ssr) {2088                // inject import for the Comment symbol, which is needed for creating2089                // comment nodes with `createVNode`2090                context.helper(CREATE_COMMENT);2091            }2092            break;2093        case 5 /* INTERPOLATION */:2094            // no need to traverse, but we need to inject toString helper2095            if (!context.ssr) {2096                context.helper(TO_DISPLAY_STRING);2097            }2098            break;2099        // for container types, further traverse downwards2100        case 9 /* IF */:2101            for (let i = 0; i < node.branches.length; i++) {2102                traverseNode(node.branches[i], context);2103            }2104            break;2105        case 10 /* IF_BRANCH */:2106        case 11 /* FOR */:2107        case 1 /* ELEMENT */:2108        case 0 /* ROOT */:2109            traverseChildren(node, context);2110            break;2111    }2112    // exit transforms2113    context.currentNode = node;2114    let i = exitFns.length;2115    while (i--) {2116        exitFns[i]();2117    }2118}2119function createStructuralDirectiveTransform(name, fn) {2120    const matches = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(name)2121        ? (n) => n === name2122        : (n) => name.test(n);2123    return (node, context) => {2124        if (node.type === 1 /* ELEMENT */) {2125            const { props } = node;2126            // structural directive transforms are not concerned with slots2127            // as they are handled separately in vSlot.ts2128            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2129                return;2130            }2131            const exitFns = [];2132            for (let i = 0; i < props.length; i++) {2133                const prop = props[i];2134                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2135                    // structural directives are removed to avoid infinite recursion2136                    // also we remove them *before* applying so that it can further2137                    // traverse itself in case it moves the node around2138                    props.splice(i, 1);2139                    i--;2140                    const onExit = fn(node, prop, context);2141                    if (onExit)2142                        exitFns.push(onExit);2143                }2144            }2145            return exitFns;2146        }2147    };2148}2149const PURE_ANNOTATION = `/*#__PURE__*/`;2150function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false, isTS = false }) {2151    const context = {2152        mode,2153        prefixIdentifiers,2154        sourceMap,2155        filename,2156        scopeId,2157        optimizeImports,2158        runtimeGlobalName,2159        runtimeModuleName,2160        ssr,2161        isTS,2162        source: ast.loc.source,2163        code: ``,2164        column: 1,2165        line: 1,2166        offset: 0,2167        indentLevel: 0,2168        pure: false,2169        map: undefined,2170        helper(key) {2171            return `_${helperNameMap[key]}`;2172        },2173        push(code, node) {2174            context.code += code;2175        },2176        indent() {2177            newline(++context.indentLevel);2178        },2179        deindent(withoutNewLine = false) {2180            if (withoutNewLine) {2181                --context.indentLevel;2182            }2183            else {2184                newline(--context.indentLevel);2185            }2186        },2187        newline() {2188            newline(context.indentLevel);2189        }2190    };2191    function newline(n) {2192        context.push('\n' + `  `.repeat(n));2193    }2194    return context;2195}2196function generate(ast, options = {}) {2197    const context = createCodegenContext(ast, options);2198    if (options.onContextCreated)2199        options.onContextCreated(context);2200    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2201    const hasHelpers = ast.helpers.length > 0;2202    const useWithBlock = !prefixIdentifiers && mode !== 'module';2203    // preambles2204    // in setup() inline mode, the preamble is generated in a sub context2205    // and returned separately.2206    const preambleContext = context;2207    {2208        genFunctionPreamble(ast, preambleContext);2209    }2210    // enter render function2211    const functionName = ssr ? `ssrRender` : `render`;2212    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2213    const signature = args.join(', ');2214    {2215        push(`function ${functionName}(${signature}) {`);2216    }2217    indent();2218    if (useWithBlock) {2219        push(`with (_ctx) {`);2220        indent();2221        // function mode const declarations should be inside with block2222        // also they should be renamed to avoid collision with user properties2223        if (hasHelpers) {2224            push(`const { ${ast.helpers2225                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2226                .join(', ')} } = _Vue`);2227            push(`\n`);2228            newline();2229        }2230    }2231    // generate asset resolution statements2232    if (ast.components.length) {2233        genAssets(ast.components, 'component', context);2234        if (ast.directives.length || ast.temps > 0) {2235            newline();2236        }2237    }2238    if (ast.directives.length) {2239        genAssets(ast.directives, 'directive', context);2240        if (ast.temps > 0) {2241            newline();2242        }2243    }2244    if (ast.filters && ast.filters.length) {2245        newline();2246        genAssets(ast.filters, 'filter', context);2247        newline();2248    }2249    if (ast.temps > 0) {2250        push(`let `);2251        for (let i = 0; i < ast.temps; i++) {2252            push(`${i > 0 ? `, ` : ``}_temp${i}`);2253        }2254    }2255    if (ast.components.length || ast.directives.length || ast.temps) {2256        push(`\n`);2257        newline();2258    }2259    // generate the VNode tree expression2260    if (!ssr) {2261        push(`return `);2262    }2263    if (ast.codegenNode) {2264        genNode(ast.codegenNode, context);2265    }2266    else {2267        push(`null`);2268    }2269    if (useWithBlock) {2270        deindent();2271        push(`}`);2272    }2273    deindent();2274    push(`}`);2275    return {2276        ast,2277        code: context.code,2278        preamble: ``,2279        // SourceMapGenerator does have toJSON() method but it's not in the types2280        map: context.map ? context.map.toJSON() : undefined2281    };2282}2283function genFunctionPreamble(ast, context) {2284    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;2285    const VueBinding = runtimeGlobalName;2286    const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2287    // Generate const declaration for helpers2288    // In prefix mode, we place the const declaration at top so it's done2289    // only once; But if we not prefixing, we place the declaration inside the2290    // with block so it doesn't incur the `in` check cost for every helper access.2291    if (ast.helpers.length > 0) {2292        {2293            // "with" mode.2294            // save Vue in a separate variable to avoid collision2295            push(`const _Vue = ${VueBinding}\n`);2296            // in "with" mode, helpers are declared inside the with block to avoid2297            // has check cost, but hoists are lifted out of the function - we need2298            // to provide the helper here.2299            if (ast.hoists.length) {2300                const staticHelpers = [2301                    CREATE_VNODE,2302                    CREATE_COMMENT,2303                    CREATE_TEXT,2304                    CREATE_STATIC2305                ]2306                    .filter(helper => ast.helpers.includes(helper))2307                    .map(aliasHelper)2308                    .join(', ');2309                push(`const { ${staticHelpers} } = _Vue\n`);2310            }2311        }2312    }2313    genHoists(ast.hoists, context);2314    newline();2315    push(`return `);2316}2317function genAssets(assets, type, { helper, push, newline, isTS }) {2318    const resolver = helper(type === 'filter'2319        ? RESOLVE_FILTER2320        : type === 'component'2321            ? RESOLVE_COMPONENT2322            : RESOLVE_DIRECTIVE);2323    for (let i = 0; i < assets.length; i++) {2324        let id = assets[i];2325        // potential component implicit self-reference inferred from SFC filename2326        const maybeSelfReference = id.endsWith('__self');2327        if (maybeSelfReference) {2328            id = id.slice(0, -6);2329        }2330        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2331        if (i < assets.length - 1) {2332            newline();2333        }2334    }2335}2336function genHoists(hoists, context) {2337    if (!hoists.length) {2338        return;2339    }2340    context.pure = true;2341    const { push, newline, helper, scopeId, mode } = context;2342    newline();2343    hoists.forEach((exp, i) => {2344        if (exp) {2345            push(`const _hoisted_${i + 1} = `);2346            genNode(exp, context);2347            newline();2348        }2349    });2350    context.pure = false;2351}2352function isText$1(n) {2353    return ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(n) ||2354        n.type === 4 /* SIMPLE_EXPRESSION */ ||2355        n.type === 2 /* TEXT */ ||2356        n.type === 5 /* INTERPOLATION */ ||2357        n.type === 8 /* COMPOUND_EXPRESSION */);2358}2359function genNodeListAsArray(nodes, context) {2360    const multilines = nodes.length > 3 ||2361        ((( true)) && nodes.some(n => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(n) || !isText$1(n)));2362    context.push(`[`);2363    multilines && context.indent();2364    genNodeList(nodes, context, multilines);2365    multilines && context.deindent();2366    context.push(`]`);2367}2368function genNodeList(nodes, context, multilines = false, comma = true) {2369    const { push, newline } = context;2370    for (let i = 0; i < nodes.length; i++) {2371        const node = nodes[i];2372        if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node)) {2373            push(node);2374        }2375        else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node)) {2376            genNodeListAsArray(node, context);2377        }2378        else {2379            genNode(node, context);2380        }2381        if (i < nodes.length - 1) {2382            if (multilines) {2383                comma && push(',');2384                newline();2385            }2386            else {2387                comma && push(', ');2388            }2389        }2390    }2391}2392function genNode(node, context) {2393    if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node)) {2394        context.push(node);2395        return;2396    }2397    if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(node)) {2398        context.push(context.helper(node));2399        return;2400    }2401    switch (node.type) {2402        case 1 /* ELEMENT */:2403        case 9 /* IF */:2404        case 11 /* FOR */:2405            ( true) &&2406                assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2407                    `Apply appropriate transforms first.`);2408            genNode(node.codegenNode, context);2409            break;2410        case 2 /* TEXT */:2411            genText(node, context);2412            break;2413        case 4 /* SIMPLE_EXPRESSION */:2414            genExpression(node, context);2415            break;2416        case 5 /* INTERPOLATION */:2417            genInterpolation(node, context);2418            break;2419        case 12 /* TEXT_CALL */:2420            genNode(node.codegenNode, context);2421            break;2422        case 8 /* COMPOUND_EXPRESSION */:2423            genCompoundExpression(node, context);2424            break;2425        case 3 /* COMMENT */:2426            genComment(node, context);2427            break;2428        case 13 /* VNODE_CALL */:2429            genVNodeCall(node, context);2430            break;2431        case 14 /* JS_CALL_EXPRESSION */:2432            genCallExpression(node, context);2433            break;2434        case 15 /* JS_OBJECT_EXPRESSION */:2435            genObjectExpression(node, context);2436            break;2437        case 17 /* JS_ARRAY_EXPRESSION */:2438            genArrayExpression(node, context);2439            break;2440        case 18 /* JS_FUNCTION_EXPRESSION */:2441            genFunctionExpression(node, context);2442            break;2443        case 19 /* JS_CONDITIONAL_EXPRESSION */:2444            genConditionalExpression(node, context);2445            break;2446        case 20 /* JS_CACHE_EXPRESSION */:2447            genCacheExpression(node, context);2448            break;2449        // SSR only types2450        case 21 /* JS_BLOCK_STATEMENT */:2451            break;2452        case 22 /* JS_TEMPLATE_LITERAL */:2453            break;2454        case 23 /* JS_IF_STATEMENT */:2455            break;2456        case 24 /* JS_ASSIGNMENT_EXPRESSION */:2457            break;2458        case 25 /* JS_SEQUENCE_EXPRESSION */:2459            break;2460        case 26 /* JS_RETURN_STATEMENT */:2461            break;2462        /* istanbul ignore next */2463        case 10 /* IF_BRANCH */:2464            // noop2465            break;2466        default:2467            if ((true)) {2468                assert(false, `unhandled codegen node type: ${node.type}`);2469                // make sure we exhaust all possible types2470                const exhaustiveCheck = node;2471                return exhaustiveCheck;2472            }2473    }2474}2475function genText(node, context) {2476    context.push(JSON.stringify(node.content), node);2477}2478function genExpression(node, context) {2479    const { content, isStatic } = node;2480    context.push(isStatic ? JSON.stringify(content) : content, node);2481}2482function genInterpolation(node, context) {2483    const { push, helper, pure } = context;2484    if (pure)2485        push(PURE_ANNOTATION);2486    push(`${helper(TO_DISPLAY_STRING)}(`);2487    genNode(node.content, context);2488    push(`)`);2489}2490function genCompoundExpression(node, context) {2491    for (let i = 0; i < node.children.length; i++) {2492        const child = node.children[i];2493        if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child)) {2494            context.push(child);2495        }2496        else {2497            genNode(child, context);2498        }2499    }2500}2501function genExpressionAsPropertyKey(node, context) {2502    const { push } = context;2503    if (node.type === 8 /* COMPOUND_EXPRESSION */) {2504        push(`[`);2505        genCompoundExpression(node, context);2506        push(`]`);2507    }2508    else if (node.isStatic) {2509        // only quote keys if necessary2510        const text = isSimpleIdentifier(node.content)2511            ? node.content2512            : JSON.stringify(node.content);2513        push(text, node);2514    }2515    else {2516        push(`[${node.content}]`, node);2517    }2518}2519function genComment(node, context) {2520    const { push, helper, pure } = context;2521    if (pure) {2522        push(PURE_ANNOTATION);2523    }2524    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2525}2526function genVNodeCall(node, context) {2527    const { push, helper, pure } = context;2528    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;2529    if (directives) {2530        push(helper(WITH_DIRECTIVES) + `(`);2531    }2532    if (isBlock) {2533        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2534    }2535    if (pure) {2536        push(PURE_ANNOTATION);2537    }2538    push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);2539    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2540    push(`)`);2541    if (isBlock) {2542        push(`)`);2543    }2544    if (directives) {2545        push(`, `);2546        genNode(directives, context);2547        push(`)`);2548    }2549}2550function genNullableArgs(args) {2551    let i = args.length;2552    while (i--) {2553        if (args[i] != null)2554            break;2555    }2556    return args.slice(0, i + 1).map(arg => arg || `null`);2557}2558// JavaScript2559function genCallExpression(node, context) {2560    const { push, helper, pure } = context;2561    const callee = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node.callee) ? node.callee : helper(node.callee);2562    if (pure) {2563        push(PURE_ANNOTATION);2564    }2565    push(callee + `(`, node);2566    genNodeList(node.arguments, context);2567    push(`)`);2568}2569function genObjectExpression(node, context) {2570    const { push, indent, deindent, newline } = context;2571    const { properties } = node;2572    if (!properties.length) {2573        push(`{}`, node);2574        return;2575    }2576    const multilines = properties.length > 1 ||2577        ((( true)) &&2578            properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2579    push(multilines ? `{` : `{ `);2580    multilines && indent();2581    for (let i = 0; i < properties.length; i++) {2582        const { key, value } = properties[i];2583        // key2584        genExpressionAsPropertyKey(key, context);2585        push(`: `);2586        // value2587        genNode(value, context);2588        if (i < properties.length - 1) {2589            // will only reach this if it's multilines2590            push(`,`);2591            newline();2592        }2593    }2594    multilines && deindent();2595    push(multilines ? `}` : ` }`);2596}2597function genArrayExpression(node, context) {2598    genNodeListAsArray(node.elements, context);2599}2600function genFunctionExpression(node, context) {2601    const { push, indent, deindent, scopeId, mode } = context;2602    const { params, returns, body, newline, isSlot } = node;2603    if (isSlot) {2604        // wrap slot functions with owner context2605        push(`_${helperNameMap[WITH_CTX]}(`);2606    }2607    push(`(`, node);2608    if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(params)) {2609        genNodeList(params, context);2610    }2611    else if (params) {2612        genNode(params, context);2613    }2614    push(`) => `);2615    if (newline || body) {2616        push(`{`);2617        indent();2618    }2619    if (returns) {2620        if (newline) {2621            push(`return `);2622        }2623        if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(returns)) {2624            genNodeListAsArray(returns, context);2625        }2626        else {2627            genNode(returns, context);2628        }2629    }2630    else if (body) {2631        genNode(body, context);2632    }2633    if (newline || body) {2634        deindent();2635        push(`}`);2636    }2637    if (isSlot) {2638        if (node.isNonScopedSlot) {2639            push(`, undefined, true`);2640        }2641        push(`)`);2642    }2643}2644function genConditionalExpression(node, context) {2645    const { test, consequent, alternate, newline: needNewline } = node;2646    const { push, indent, deindent, newline } = context;2647    if (test.type === 4 /* SIMPLE_EXPRESSION */) {2648        const needsParens = !isSimpleIdentifier(test.content);2649        needsParens && push(`(`);2650        genExpression(test, context);2651        needsParens && push(`)`);2652    }2653    else {2654        push(`(`);2655        genNode(test, context);2656        push(`)`);2657    }2658    needNewline && indent();2659    context.indentLevel++;2660    needNewline || push(` `);2661    push(`? `);2662    genNode(consequent, context);2663    context.indentLevel--;2664    needNewline && newline();2665    needNewline || push(` `);2666    push(`: `);2667    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2668    if (!isNested) {2669        context.indentLevel++;2670    }2671    genNode(alternate, context);2672    if (!isNested) {2673        context.indentLevel--;2674    }2675    needNewline && deindent(true /* without newline */);2676}2677function genCacheExpression(node, context) {2678    const { push, helper, indent, deindent, newline } = context;2679    push(`_cache[${node.index}] || (`);2680    if (node.isVNode) {2681        indent();2682        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2683        newline();2684    }2685    push(`_cache[${node.index}] = `);2686    genNode(node.value, context);2687    if (node.isVNode) {2688        push(`,`);2689        newline();2690        push(`${helper(SET_BLOCK_TRACKING)}(1),`);2691        newline();2692        push(`_cache[${node.index}]`);2693        deindent();2694    }2695    push(`)`);2696}2697// these keywords should not appear inside expressions, but operators like2698// typeof, instanceof and in are allowed2699const prohibitedKeywordRE = new RegExp('\\b' +2700    ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +2701        'super,throw,while,yield,delete,export,import,return,switch,default,' +2702        'extends,finally,continue,debugger,function,arguments,typeof,void')2703        .split(',')2704        .join('\\b|\\b') +2705    '\\b');2706// strip strings in expressions2707const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;2708/**2709 * Validate a non-prefixed expression.2710 * This is only called when using the in-browser runtime compiler since it2711 * doesn't prefix expressions.2712 */2713function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {2714    const exp = node.content;2715    // empty expressions are validated per-directive since some directives2716    // do allow empty expressions.2717    if (!exp.trim()) {2718        return;2719    }2720    try {2721        new Function(asRawStatements2722            ? ` ${exp} `2723            : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);2724    }2725    catch (e) {2726        let message = e.message;2727        const keywordMatch = exp2728            .replace(stripStringRE, '')2729            .match(prohibitedKeywordRE);2730        if (keywordMatch) {2731            message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;2732        }2733        context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));2734    }2735}2736const transformExpression = (node, context) => {2737    if (node.type === 5 /* INTERPOLATION */) {2738        node.content = processExpression(node.content, context);2739    }2740    else if (node.type === 1 /* ELEMENT */) {2741        // handle directives on element2742        for (let i = 0; i < node.props.length; i++) {2743            const dir = node.props[i];2744            // do not process for v-on & v-for since they are special handled2745            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {2746                const exp = dir.exp;2747                const arg = dir.arg;2748                // do not process exp if this is v-on:arg - we need special handling2749                // for wrapping inline statements.2750                if (exp &&2751                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&2752                    !(dir.name === 'on' && arg)) {2753                    dir.exp = processExpression(exp, context, 2754                    // slot args must be processed as function params2755                    dir.name === 'slot');2756                }2757                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {2758                    dir.arg = processExpression(arg, context);2759                }2760            }2761        }2762    }2763};2764// Important: since this function uses Node.js only dependencies, it should2765// always be used with a leading !true check so that it can be2766// tree-shaken from the browser build.2767function processExpression(node, context, 2768// some expressions like v-slot props & v-for aliases should be parsed as2769// function params2770asParams = false, 2771// v-on handler values may contain multiple statements2772asRawStatements = false) {2773    {2774        if ((true)) {2775            // simple in-browser validation (same logic in 2.x)2776            validateBrowserExpression(node, context, asParams, asRawStatements);2777        }2778        return node;2779    }2780}2781const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {2782    return processIf(node, dir, context, (ifNode, branch, isRoot) => {2783        // #1587: We need to dynamically increment the key based on the current2784        // node's sibling nodes, since chained v-if/else branches are2785        // rendered at the same depth2786        const siblings = context.parent.children;2787        let i = siblings.indexOf(ifNode);2788        let key = 0;2789        while (i-- >= 0) {2790            const sibling = siblings[i];2791            if (sibling && sibling.type === 9 /* IF */) {2792                key += sibling.branches.length;2793            }2794        }2795        // Exit callback. Complete the codegenNode when all children have been2796        // transformed.2797        return () => {2798            if (isRoot) {2799                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);2800            }2801            else {2802                // attach this branch's codegen node to the v-if root.2803                const parentCondition = getParentCondition(ifNode.codegenNode);2804                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);2805            }2806        };2807    });2808});2809// target-agnostic transform used for both Client and SSR2810function processIf(node, dir, context, processCodegen) {2811    if (dir.name !== 'else' &&2812        (!dir.exp || !dir.exp.content.trim())) {2813        const loc = dir.exp ? dir.exp.loc : node.loc;2814        context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));2815        dir.exp = createSimpleExpression(`true`, false, loc);2816    }2817    if ( true && dir.exp) {2818        validateBrowserExpression(dir.exp, context);2819    }2820    if (dir.name === 'if') {2821        const branch = createIfBranch(node, dir);2822        const ifNode = {2823            type: 9 /* IF */,2824            loc: node.loc,2825            branches: [branch]2826        };2827        context.replaceNode(ifNode);2828        if (processCodegen) {2829            return processCodegen(ifNode, branch, true);2830        }2831    }2832    else {2833        // locate the adjacent v-if2834        const siblings = context.parent.children;2835        const comments = [];2836        let i = siblings.indexOf(node);2837        while (i-- >= -1) {2838            const sibling = siblings[i];2839            if (( true) && sibling && sibling.type === 3 /* COMMENT */) {2840                context.removeNode(sibling);2841                comments.unshift(sibling);2842                continue;2843            }2844            if (sibling &&2845                sibling.type === 2 /* TEXT */ &&2846                !sibling.content.trim().length) {2847                context.removeNode(sibling);2848                continue;2849            }2850            if (sibling && sibling.type === 9 /* IF */) {2851                // move the node to the if node's branches2852                context.removeNode();2853                const branch = createIfBranch(node, dir);2854                if (( true) &&2855                    comments.length &&2856                    // #3619 ignore comments if the v-if is direct child of <transition>2857                    !(context.parent &&2858                        context.parent.type === 1 /* ELEMENT */ &&2859                        isBuiltInType(context.parent.tag, 'transition'))) {2860                    branch.children = [...comments, ...branch.children];2861                }2862                // check if user is forcing same key on different branches2863                if (true) {2864                    const key = branch.userKey;2865                    if (key) {2866                        sibling.branches.forEach(({ userKey }) => {2867                            if (isSameKey(userKey, key)) {2868                                context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));2869                            }2870                        });2871                    }2872                }2873                sibling.branches.push(branch);2874                const onExit = processCodegen && processCodegen(sibling, branch, false);2875                // since the branch was removed, it will not be traversed.2876                // make sure to traverse here.2877                traverseNode(branch, context);2878                // call on exit2879                if (onExit)2880                    onExit();2881                // make sure to reset currentNode after traversal to indicate this2882                // node has been removed.2883                context.currentNode = null;2884            }2885            else {2886                context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));2887            }2888            break;2889        }2890    }2891}2892function createIfBranch(node, dir) {2893    return {2894        type: 10 /* IF_BRANCH */,2895        loc: node.loc,2896        condition: dir.name === 'else' ? undefined : dir.exp,2897        children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')2898            ? node.children2899            : [node],2900        userKey: findProp(node, `key`)2901    };2902}2903function createCodegenNodeForBranch(branch, keyIndex, context) {2904    if (branch.condition) {2905        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 2906        // make sure to pass in asBlock: true so that the comment node call2907        // closes the current block.2908        createCallExpression(context.helper(CREATE_COMMENT), [2909            ( true) ? '"v-if"' : 0,2910            'true'2911        ]));2912    }2913    else {2914        return createChildrenCodegenNode(branch, keyIndex, context);2915    }2916}2917function createChildrenCodegenNode(branch, keyIndex, context) {2918    const { helper, removeHelper } = context;2919    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));2920    const { children } = branch;2921    const firstChild = children[0];2922    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;2923    if (needFragmentWrapper) {2924        if (children.length === 1 && firstChild.type === 11 /* FOR */) {2925            // optimize away nested fragments when child is a ForNode2926            const vnodeCall = firstChild.codegenNode;2927            injectProp(vnodeCall, keyProperty, context);2928            return vnodeCall;2929        }2930        else {2931            let patchFlag = 64 /* STABLE_FRAGMENT */;2932            let patchFlagText = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64];2933            // check if the fragment actually contains a single valid child with2934            // the rest being comments2935            if (( true) &&2936                children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2937                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2938                patchFlagText += `, ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[2048]}`;2939            }2940            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (( true) ? ` /* ${patchFlagText} */` : 0), undefined, undefined, true, false, branch.loc);2941        }2942    }2943    else {2944        const vnodeCall = firstChild2945            .codegenNode;2946        // Change createVNode to createBlock.2947        if (vnodeCall.type === 13 /* VNODE_CALL */ && !vnodeCall.isBlock) {2948            removeHelper(CREATE_VNODE);2949            vnodeCall.isBlock = true;2950            helper(OPEN_BLOCK);2951            helper(CREATE_BLOCK);2952        }2953        // inject branch key2954        injectProp(vnodeCall, keyProperty, context);2955        return vnodeCall;2956    }2957}2958function isSameKey(a, b) {2959    if (!a || a.type !== b.type) {2960        return false;2961    }2962    if (a.type === 6 /* ATTRIBUTE */) {2963        if (a.value.content !== b.value.content) {2964            return false;2965        }2966    }2967    else {2968        // directive2969        const exp = a.exp;2970        const branchExp = b.exp;2971        if (exp.type !== branchExp.type) {2972            return false;2973        }2974        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||2975            (exp.isStatic !== branchExp.isStatic ||2976                exp.content !== branchExp.content)) {2977            return false;2978        }2979    }2980    return true;2981}2982function getParentCondition(node) {2983    while (true) {2984        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {2985            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {2986                node = node.alternate;2987            }2988            else {2989                return node;2990            }2991        }2992        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {2993            node = node.value;2994        }2995    }2996}2997const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {2998    const { helper, removeHelper } = context;2999    return processFor(node, dir, context, forNode => {3000        // create the loop render function expression now, and add the3001        // iterator on exit after all children have been traversed3002        const renderExp = createCallExpression(helper(RENDER_LIST), [3003            forNode.source3004        ]);3005        const keyProp = findProp(node, `key`);3006        const keyProperty = keyProp3007            ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */3008                ? createSimpleExpression(keyProp.value.content, true)3009                : keyProp.exp)3010            : null;3011        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3012            forNode.source.constType > 0 /* NOT_CONSTANT */;3013        const fragmentFlag = isStableFragment3014            ? 64 /* STABLE_FRAGMENT */3015            : keyProp3016                ? 128 /* KEYED_FRAGMENT */3017                : 256 /* UNKEYED_FRAGMENT */;3018        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3019            (( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[fragmentFlag]} */` : 0), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);3020        return () => {3021            // finish the codegen now that all children have been traversed3022            let childBlock;3023            const isTemplate = isTemplateNode(node);3024            const { children } = forNode;3025            // check <template v-for> key placement3026            if (( true) && isTemplate) {3027                node.children.some(c => {3028                    if (c.type === 1 /* ELEMENT */) {3029                        const key = findProp(c, 'key');3030                        if (key) {3031                            context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3032                            return true;3033                        }3034                    }3035                });3036            }3037            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3038            const slotOutlet = isSlotOutlet(node)3039                ? node3040                : isTemplate &&3041                    node.children.length === 1 &&3042                    isSlotOutlet(node.children[0])3043                    ? node.children[0] // api-extractor somehow fails to infer this3044                    : null;3045            if (slotOutlet) {3046                // <slot v-for="..."> or <template v-for="..."><slot/></template>3047                childBlock = slotOutlet.codegenNode;3048                if (isTemplate && keyProperty) {3049                    // <template v-for="..." :key="..."><slot/></template>3050                    // we need to inject the key to the renderSlot() call.3051                    // the props for renderSlot is passed as the 3rd argument.3052                    injectProp(childBlock, keyProperty, context);3053                }3054            }3055            else if (needFragmentWrapper) {3056                // <template v-for="..."> with text or multi-elements3057                // should generate a fragment block for each loop3058                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3059                    (( true)3060                        ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64]} */`3061                        : 0), undefined, undefined, true);3062            }3063            else {3064                // Normal element v-for. Directly use the child's codegenNode3065                // but mark it as a block.3066                childBlock = children[0]3067                    .codegenNode;3068                if (isTemplate && keyProperty) {3069                    injectProp(childBlock, keyProperty, context);3070                }3071                if (childBlock.isBlock !== !isStableFragment) {3072                    if (childBlock.isBlock) {3073                        // switch from block to vnode3074                        removeHelper(OPEN_BLOCK);3075                        removeHelper(CREATE_BLOCK);3076                    }3077                    else {3078                        // switch from vnode to block3079                        removeHelper(CREATE_VNODE);3080                    }3081                }3082                childBlock.isBlock = !isStableFragment;3083                if (childBlock.isBlock) {3084                    helper(OPEN_BLOCK);3085                    helper(CREATE_BLOCK);3086                }3087                else {3088                    helper(CREATE_VNODE);3089                }3090            }3091            renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3092        };3093    });3094});3095// target-agnostic transform used for both Client and SSR3096function processFor(node, dir, context, processCodegen) {3097    if (!dir.exp) {3098        context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3099        return;3100    }3101    const parseResult = parseForExpression(3102    // can only be simple expression because vFor transform is applied3103    // before expression transform.3104    dir.exp, context);3105    if (!parseResult) {3106        context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3107        return;3108    }3109    const { addIdentifiers, removeIdentifiers, scopes } = context;3110    const { source, value, key, index } = parseResult;3111    const forNode = {3112        type: 11 /* FOR */,3113        loc: dir.loc,3114        source,3115        valueAlias: value,3116        keyAlias: key,3117        objectIndexAlias: index,3118        parseResult,3119        children: isTemplateNode(node) ? node.children : [node]3120    };3121    context.replaceNode(forNode);3122    // bookkeeping3123    scopes.vFor++;3124    const onExit = processCodegen && processCodegen(forNode);3125    return () => {3126        scopes.vFor--;3127        if (onExit)3128            onExit();3129    };3130}3131const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3132// This regex doesn't cover the case if key or index aliases have destructuring,3133// but those do not make sense in the first place, so this works in practice.3134const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3135const stripParensRE = /^\(|\)$/g;3136function parseForExpression(input, context) {3137    const loc = input.loc;3138    const exp = input.content;3139    const inMatch = exp.match(forAliasRE);3140    if (!inMatch)3141        return;3142    const [, LHS, RHS] = inMatch;3143    const result = {3144        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3145        value: undefined,3146        key: undefined,3147        index: undefined3148    };3149    if (true) {3150        validateBrowserExpression(result.source, context);3151    }3152    let valueContent = LHS.trim()3153        .replace(stripParensRE, '')3154        .trim();3155    const trimmedOffset = LHS.indexOf(valueContent);3156    const iteratorMatch = valueContent.match(forIteratorRE);3157    if (iteratorMatch) {3158        valueContent = valueContent.replace(forIteratorRE, '').trim();3159        const keyContent = iteratorMatch[1].trim();3160        let keyOffset;3161        if (keyContent) {3162            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3163            result.key = createAliasExpression(loc, keyContent, keyOffset);3164            if (true) {3165                validateBrowserExpression(result.key, context, true);3166            }3167        }3168        if (iteratorMatch[2]) {3169            const indexContent = iteratorMatch[2].trim();3170            if (indexContent) {3171                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3172                    ? keyOffset + keyContent.length3173                    : trimmedOffset + valueContent.length));3174                if (true) {3175                    validateBrowserExpression(result.index, context, true);3176                }3177            }3178        }3179    }3180    if (valueContent) {3181        result.value = createAliasExpression(loc, valueContent, trimmedOffset);3182        if (true) {3183            validateBrowserExpression(result.value, context, true);3184        }3185    }3186    return result;3187}3188function createAliasExpression(range, content, offset) {3189    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3190}3191function createForLoopParams({ value, key, index }) {3192    const params = [];3193    if (value) {3194        params.push(value);3195    }3196    if (key) {3197        if (!value) {3198            params.push(createSimpleExpression(`_`, false));3199        }3200        params.push(key);3201    }3202    if (index) {3203        if (!key) {3204            if (!value) {3205                params.push(createSimpleExpression(`_`, false));3206            }3207            params.push(createSimpleExpression(`__`, false));3208        }3209        params.push(index);3210    }3211    return params;3212}3213const defaultFallback = createSimpleExpression(`undefined`, false);3214// A NodeTransform that:3215// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3216//    by transformExpression. This is only applied in non-browser builds with3217//    { prefixIdentifiers: true }.3218// 2. Track v-slot depths so that we know a slot is inside another slot.3219//    Note the exit callback is executed before buildSlots() on the same node,3220//    so only nested slots see positive numbers.3221const trackSlotScopes = (node, context) => {3222    if (node.type === 1 /* ELEMENT */ &&3223        (node.tagType === 1 /* COMPONENT */ ||3224            node.tagType === 3 /* TEMPLATE */)) {3225        // We are only checking non-empty v-slot here3226        // since we only care about slots that introduce scope variables.3227        const vSlot = findDir(node, 'slot');3228        if (vSlot) {3229            vSlot.exp;3230            context.scopes.vSlot++;3231            return () => {3232                context.scopes.vSlot--;3233            };3234        }3235    }3236};3237// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3238// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3239const trackVForSlotScopes = (node, context) => {3240    let vFor;3241    if (isTemplateNode(node) &&3242        node.props.some(isVSlot) &&3243        (vFor = findDir(node, 'for'))) {3244        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3245        if (result) {3246            const { value, key, index } = result;3247            const { addIdentifiers, removeIdentifiers } = context;3248            value && addIdentifiers(value);3249            key && addIdentifiers(key);3250            index && addIdentifiers(index);3251            return () => {3252                value && removeIdentifiers(value);3253                key && removeIdentifiers(key);3254                index && removeIdentifiers(index);3255            };3256        }3257    }3258};3259const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3260// Instead of being a DirectiveTransform, v-slot processing is called during3261// transformElement to build the slots object for a component.3262function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3263    context.helper(WITH_CTX);3264    const { children, loc } = node;3265    const slotsProperties = [];3266    const dynamicSlots = [];3267    // If the slot is inside a v-for or another v-slot, force it to be dynamic3268    // since it likely uses a scope variable.3269    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3270    // 1. Check for slot with slotProps on component itself.3271    //    <Comp v-slot="{ prop }"/>3272    const onComponentSlot = findDir(node, 'slot', true);3273    if (onComponentSlot) {3274        const { arg, exp } = onComponentSlot;3275        if (arg && !isStaticExp(arg)) {3276            hasDynamicSlots = true;3277        }3278        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3279    }3280    // 2. Iterate through children and check for template slots3281    //    <template v-slot:foo="{ prop }">3282    let hasTemplateSlots = false;3283    let hasNamedDefaultSlot = false;3284    const implicitDefaultChildren = [];3285    const seenSlotNames = new Set();3286    for (let i = 0; i < children.length; i++) {3287        const slotElement = children[i];3288        let slotDir;3289        if (!isTemplateNode(slotElement) ||3290            !(slotDir = findDir(slotElement, 'slot', true))) {3291            // not a <template v-slot>, skip.3292            if (slotElement.type !== 3 /* COMMENT */) {3293                implicitDefaultChildren.push(slotElement);3294            }3295            continue;3296        }3297        if (onComponentSlot) {3298            // already has on-component slot - this is incorrect usage.3299            context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3300            break;3301        }3302        hasTemplateSlots = true;3303        const { children: slotChildren, loc: slotLoc } = slotElement;3304        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3305        // check if name is dynamic.3306        let staticSlotName;3307        if (isStaticExp(slotName)) {3308            staticSlotName = slotName ? slotName.content : `default`;3309        }3310        else {3311            hasDynamicSlots = true;3312        }3313        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3314        // check if this slot is conditional (v-if/v-for)3315        let vIf;3316        let vElse;3317        let vFor;3318        if ((vIf = findDir(slotElement, 'if'))) {3319            hasDynamicSlots = true;3320            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3321        }3322        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3323            // find adjacent v-if3324            let j = i;3325            let prev;3326            while (j--) {3327                prev = children[j];3328                if (prev.type !== 3 /* COMMENT */) {3329                    break;3330                }3331            }3332            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3333                // remove node3334                children.splice(i, 1);3335                i--;3336                // attach this slot to previous conditional3337                let conditional = dynamicSlots[dynamicSlots.length - 1];3338                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3339                    conditional = conditional.alternate;3340                }3341                conditional.alternate = vElse.exp3342                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3343                    : buildDynamicSlot(slotName, slotFunction);3344            }3345            else {3346                context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3347            }3348        }3349        else if ((vFor = findDir(slotElement, 'for'))) {3350            hasDynamicSlots = true;3351            const parseResult = vFor.parseResult ||3352                parseForExpression(vFor.exp, context);3353            if (parseResult) {3354                // Render the dynamic slots as an array and add it to the createSlot()3355                // args. The runtime knows how to handle it appropriately.3356                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3357                    parseResult.source,3358                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3359                ]));3360            }3361            else {3362                context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3363            }3364        }3365        else {3366            // check duplicate static names3367            if (staticSlotName) {3368                if (seenSlotNames.has(staticSlotName)) {3369                    context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3370                    continue;3371                }3372                seenSlotNames.add(staticSlotName);3373                if (staticSlotName === 'default') {3374                    hasNamedDefaultSlot = true;3375                }3376            }3377            slotsProperties.push(createObjectProperty(slotName, slotFunction));3378        }3379    }3380    if (!onComponentSlot) {3381        const buildDefaultSlotProperty = (props, children) => {3382            const fn = buildSlotFn(props, children, loc);3383            if (context.compatConfig) {3384                fn.isNonScopedSlot = true;3385            }3386            return createObjectProperty(`default`, fn);3387        };3388        if (!hasTemplateSlots) {3389            // implicit default slot (on component)3390            slotsProperties.push(buildDefaultSlotProperty(undefined, children));3391        }3392        else if (implicitDefaultChildren.length &&3393            // #37663394            // with whitespace: 'preserve', whitespaces between slots will end up in3395            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3396            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3397            // implicit default slot (mixed with named slots)3398            if (hasNamedDefaultSlot) {3399                context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3400            }3401            else {3402                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3403            }3404        }3405    }3406    const slotFlag = hasDynamicSlots3407        ? 2 /* DYNAMIC */3408        : hasForwardedSlots(node.children)3409            ? 3 /* FORWARDED */3410            : 1 /* STABLE */;3411    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3412    // 2 = compiled but dynamic = can skip normalization, but must run diff3413    // 1 = compiled and static = can skip normalization AND diff as optimized3414    createSimpleExpression(slotFlag + (( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.slotFlagsText[slotFlag]} */` : 0), false))), loc);3415    if (dynamicSlots.length) {3416        slots = createCallExpression(context.helper(CREATE_SLOTS), [3417            slots,3418            createArrayExpression(dynamicSlots)3419        ]);3420    }3421    return {3422        slots,3423        hasDynamicSlots3424    };3425}3426function buildDynamicSlot(name, fn) {3427    return createObjectExpression([3428        createObjectProperty(`name`, name),3429        createObjectProperty(`fn`, fn)3430    ]);3431}3432function hasForwardedSlots(children) {3433    for (let i = 0; i < children.length; i++) {3434        const child = children[i];3435        switch (child.type) {3436            case 1 /* ELEMENT */:3437                if (child.tagType === 2 /* SLOT */ ||3438                    ((child.tagType === 0 /* ELEMENT */ ||3439                        child.tagType === 3 /* TEMPLATE */) &&3440                        hasForwardedSlots(child.children))) {3441                    return true;3442                }3443                break;3444            case 9 /* IF */:3445                if (hasForwardedSlots(child.branches))3446                    return true;3447                break;3448            case 10 /* IF_BRANCH */:3449            case 11 /* FOR */:3450                if (hasForwardedSlots(child.children))3451                    return true;3452                break;3453        }3454    }3455    return false;3456}3457function isNonWhitespaceContent(node) {3458    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3459        return true;3460    return node.type === 2 /* TEXT */3461        ? !!node.content.trim()3462        : isNonWhitespaceContent(node.content);3463}3464// some directive transforms (e.g. v-model) may return a symbol for runtime3465// import, which should be used instead of a resolveDirective call.3466const directiveImportMap = new WeakMap();3467// generate a JavaScript AST for this element's codegen3468const transformElement = (node, context) => {3469    // perform the work on exit, after all child expressions have been3470    // processed and merged.3471    return function postTransformElement() {3472        node = context.currentNode;3473        if (!(node.type === 1 /* ELEMENT */ &&3474            (node.tagType === 0 /* ELEMENT */ ||3475                node.tagType === 1 /* COMPONENT */))) {3476            return;3477        }3478        const { tag, props } = node;3479        const isComponent = node.tagType === 1 /* COMPONENT */;3480        // The goal of the transform is to create a codegenNode implementing the3481        // VNodeCall interface.3482        let vnodeTag = isComponent3483            ? resolveComponentType(node, context)3484            : `"${tag}"`;3485        const isDynamicComponent = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3486        let vnodeProps;3487        let vnodeChildren;3488        let vnodePatchFlag;3489        let patchFlag = 0;3490        let vnodeDynamicProps;3491        let dynamicPropNames;3492        let vnodeDirectives;3493        let shouldUseBlock = 3494        // dynamic component may resolve to plain elements3495        isDynamicComponent ||3496            vnodeTag === TELEPORT ||3497            vnodeTag === SUSPENSE ||3498            (!isComponent &&3499                // <svg> and <foreignObject> must be forced into blocks so that block3500                // updates inside get proper isSVG flag at runtime. (#639, #643)3501                // This is technically web-specific, but splitting the logic out of core3502                // leads to too much unnecessary complexity.3503                (tag === 'svg' ||3504                    tag === 'foreignObject' ||3505                    // #938: elements with dynamic keys should be forced into blocks3506                    findProp(node, 'key', true)));3507        // props3508        if (props.length > 0) {3509            const propsBuildResult = buildProps(node, context);3510            vnodeProps = propsBuildResult.props;3511            patchFlag = propsBuildResult.patchFlag;3512            dynamicPropNames = propsBuildResult.dynamicPropNames;3513            const directives = propsBuildResult.directives;3514            vnodeDirectives =3515                directives && directives.length3516                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3517                    : undefined;3518        }3519        // children3520        if (node.children.length > 0) {3521            if (vnodeTag === KEEP_ALIVE) {3522                // Although a built-in component, we compile KeepAlive with raw children3523                // instead of slot functions so that it can be used inside Transition3524                // or other Transition-wrapping HOCs.3525                // To ensure correct updates with block optimizations, we need to:3526                // 1. Force keep-alive into a block. This avoids its children being3527                //    collected by a parent block.3528                shouldUseBlock = true;3529                // 2. Force keep-alive to always be updated, since it uses raw children.3530                patchFlag |= 1024 /* DYNAMIC_SLOTS */;3531                if (( true) && node.children.length > 1) {3532                    context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3533                        start: node.children[0].loc.start,3534                        end: node.children[node.children.length - 1].loc.end,3535                        source: ''3536                    }));3537                }3538            }3539            const shouldBuildAsSlots = isComponent &&3540                // Teleport is not a real component and has dedicated runtime handling3541                vnodeTag !== TELEPORT &&3542                // explained above.3543                vnodeTag !== KEEP_ALIVE;3544            if (shouldBuildAsSlots) {3545                const { slots, hasDynamicSlots } = buildSlots(node, context);3546                vnodeChildren = slots;3547                if (hasDynamicSlots) {3548                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;3549                }3550            }3551            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3552                const child = node.children[0];3553                const type = child.type;3554                // check for dynamic text children3555                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3556                    type === 8 /* COMPOUND_EXPRESSION */;3557                if (hasDynamicTextChild &&3558                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3559                    patchFlag |= 1 /* TEXT */;3560                }3561                // pass directly if the only child is a text node3562                // (plain / interpolation / expression)3563                if (hasDynamicTextChild || type === 2 /* TEXT */) {3564                    vnodeChildren = child;3565                }3566                else {3567                    vnodeChildren = node.children;3568                }3569            }3570            else {3571                vnodeChildren = node.children;3572            }3573        }3574        // patchFlag & dynamicPropNames3575        if (patchFlag !== 0) {3576            if ((true)) {3577                if (patchFlag < 0) {3578                    // special flags (negative and mutually exclusive)3579                    vnodePatchFlag = patchFlag + ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[patchFlag]} */`;3580                }3581                else {3582                    // bitwise flags3583                    const flagNames = Object.keys(_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames)3584                        .map(Number)3585                        .filter(n => n > 0 && patchFlag & n)3586                        .map(n => _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[n])3587                        .join(`, `);3588                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3589                }3590            }3591            else {}3592            if (dynamicPropNames && dynamicPropNames.length) {3593                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3594            }3595        }3596        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);3597    };3598};3599function resolveComponentType(node, context, ssr = false) {3600    let { tag } = node;3601    // 1. dynamic component3602    const isExplicitDynamic = isComponentTag(tag);3603    const isProp = findProp(node, 'is');3604    if (isProp) {3605        if (isExplicitDynamic ||3606            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3607            const exp = isProp.type === 6 /* ATTRIBUTE */3608                ? isProp.value && createSimpleExpression(isProp.value.content, true)3609                : isProp.exp;3610            if (exp) {3611                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3612                    exp3613                ]);3614            }3615        }3616        else if (isProp.type === 6 /* ATTRIBUTE */ &&3617            isProp.value.content.startsWith('vue:')) {3618            // <button is="vue:xxx">3619            // if not <component>, only is value that starts with "vue:" will be3620            // treated as component by the parse phase and reach here, unless it's3621            // compat mode where all is values are considered components3622            tag = isProp.value.content.slice(4);3623        }3624    }3625    // 1.5 v-is (TODO: Deprecate)3626    const isDir = !isExplicitDynamic && findDir(node, 'is');3627    if (isDir && isDir.exp) {3628        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3629            isDir.exp3630        ]);3631    }3632    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3633    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3634    if (builtIn) {3635        // built-ins are simply fallthroughs / have special handling during ssr3636        // so we don't need to import their runtime equivalents3637        if (!ssr)3638            context.helper(builtIn);3639        return builtIn;3640    }3641    // 5. user component (resolve)3642    context.helper(RESOLVE_COMPONENT);3643    context.components.add(tag);3644    return toValidAssetId(tag, `component`);3645}3646function buildProps(node, context, props = node.props, ssr = false) {3647    const { tag, loc: elementLoc } = node;3648    const isComponent = node.tagType === 1 /* COMPONENT */;3649    let properties = [];3650    const mergeArgs = [];3651    const runtimeDirectives = [];3652    // patchFlag analysis3653    let patchFlag = 0;3654    let hasRef = false;3655    let hasClassBinding = false;3656    let hasStyleBinding = false;3657    let hasHydrationEventBinding = false;3658    let hasDynamicKeys = false;3659    let hasVnodeHook = false;3660    const dynamicPropNames = [];3661    const analyzePatchFlag = ({ key, value }) => {3662        if (isStaticExp(key)) {3663            const name = key.content;3664            const isEventHandler = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isOn)(name);3665            if (!isComponent &&3666                isEventHandler &&3667                // omit the flag for click handlers because hydration gives click3668                // dedicated fast path.3669                name.toLowerCase() !== 'onclick' &&3670                // omit v-model handlers3671                name !== 'onUpdate:modelValue' &&3672                // omit onVnodeXXX hooks3673                !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isReservedProp)(name)) {3674                hasHydrationEventBinding = true;3675            }3676            if (isEventHandler && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isReservedProp)(name)) {3677                hasVnodeHook = true;3678            }3679            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||3680                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||3681                    value.type === 8 /* COMPOUND_EXPRESSION */) &&3682                    getConstantType(value, context) > 0)) {3683                // skip if the prop is a cached handler or has constant value3684                return;3685            }3686            if (name === 'ref') {3687                hasRef = true;3688            }3689            else if (name === 'class' && !isComponent) {3690                hasClassBinding = true;3691            }3692            else if (name === 'style' && !isComponent) {3693                hasStyleBinding = true;3694            }3695            else if (name !== 'key' && !dynamicPropNames.includes(name)) {3696                dynamicPropNames.push(name);3697            }3698        }3699        else {3700            hasDynamicKeys = true;3701        }3702    };3703    for (let i = 0; i < props.length; i++) {3704        // static attribute3705        const prop = props[i];3706        if (prop.type === 6 /* ATTRIBUTE */) {3707            const { loc, name, value } = prop;3708            let isStatic = true;3709            if (name === 'ref') {3710                hasRef = true;3711            }3712            // skip is on <component>, or is="vue:xxx"3713            if (name === 'is' &&3714                (isComponentTag(tag) ||3715                    (value && value.content.startsWith('vue:')) ||3716                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {3717                continue;3718            }3719            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));3720        }3721        else {3722            // directives3723            const { name, arg, exp, loc } = prop;3724            const isVBind = name === 'bind';3725            const isVOn = name === 'on';3726            // skip v-slot - it is handled by its dedicated transform.3727            if (name === 'slot') {3728                if (!isComponent) {3729                    context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));3730                }3731                continue;3732            }3733            // skip v-once - it is handled by its dedicated transform.3734            if (name === 'once') {3735                continue;3736            }3737            // skip v-is and :is on <component>3738            if (name === 'is' ||3739                (isVBind &&3740                    isBindKey(arg, 'is') &&3741                    (isComponentTag(tag) ||3742                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {3743                continue;3744            }3745            // skip v-on in SSR compilation3746            if (isVOn && ssr) {3747                continue;3748            }3749            // special case for v-bind and v-on with no argument3750            if (!arg && (isVBind || isVOn)) {3751                hasDynamicKeys = true;3752                if (exp) {3753                    if (properties.length) {3754                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));3755                        properties = [];3756                    }3757                    if (isVBind) {3758                        {3759                            // 2.x v-bind object order compat3760                            if ((true)) {3761                                const hasOverridableKeys = mergeArgs.some(arg => {3762                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {3763                                        return arg.properties.some(({ key }) => {3764                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||3765                                                !key.isStatic) {3766                                                return true;3767                                            }3768                                            return (key.content !== 'class' &&3769                                                key.content !== 'style' &&3770                                                !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isOn)(key.content));3771                                        });3772                                    }3773                                    else {3774                                        // dynamic expression3775                                        return true;3776                                    }3777                                });3778                                if (hasOverridableKeys) {3779                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);3780                                }3781                            }3782                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {3783                                mergeArgs.unshift(exp);3784                                continue;3785                            }3786                        }3787                        mergeArgs.push(exp);3788                    }3789                    else {3790                        // v-on="obj" -> toHandlers(obj)3791                        mergeArgs.push({3792                            type: 14 /* JS_CALL_EXPRESSION */,3793                            loc,3794                            callee: context.helper(TO_HANDLERS),3795                            arguments: [exp]3796                        });3797                    }3798                }3799                else {3800                    context.onError(createCompilerError(isVBind3801                        ? 33 /* X_V_BIND_NO_EXPRESSION */3802                        : 34 /* X_V_ON_NO_EXPRESSION */, loc));3803                }3804                continue;3805            }3806            const directiveTransform = context.directiveTransforms[name];3807            if (directiveTransform) {3808                // has built-in directive transform.3809                const { props, needRuntime } = directiveTransform(prop, node, context);3810                !ssr && props.forEach(analyzePatchFlag);3811                properties.push(...props);3812                if (needRuntime) {3813                    runtimeDirectives.push(prop);3814                    if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(needRuntime)) {3815                        directiveImportMap.set(prop, needRuntime);3816                    }3817                }3818            }3819            else {3820                // no built-in transform, this is a user custom directive.3821                runtimeDirectives.push(prop);3822            }3823        }3824        if (prop.type === 6 /* ATTRIBUTE */ &&3825            prop.name === 'ref' &&3826            context.scopes.vFor > 0 &&3827            checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {3828            properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));3829        }3830    }3831    let propsExpression = undefined;3832    // has v-bind="object" or v-on="object", wrap with mergeProps3833    if (mergeArgs.length) {3834        if (properties.length) {3835            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));3836        }3837        if (mergeArgs.length > 1) {3838            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);3839        }3840        else {3841            // single v-bind with nothing else - no need for a mergeProps call3842            propsExpression = mergeArgs[0];3843        }3844    }3845    else if (properties.length) {3846        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);3847    }3848    // patchFlag analysis3849    if (hasDynamicKeys) {3850        patchFlag |= 16 /* FULL_PROPS */;3851    }3852    else {3853        if (hasClassBinding) {3854            patchFlag |= 2 /* CLASS */;3855        }3856        if (hasStyleBinding) {3857            patchFlag |= 4 /* STYLE */;3858        }3859        if (dynamicPropNames.length) {3860            patchFlag |= 8 /* PROPS */;3861        }3862        if (hasHydrationEventBinding) {3863            patchFlag |= 32 /* HYDRATE_EVENTS */;3864        }3865    }3866    if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&3867        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {3868        patchFlag |= 512 /* NEED_PATCH */;3869    }3870    return {3871        props: propsExpression,3872        directives: runtimeDirectives,3873        patchFlag,3874        dynamicPropNames3875    };3876}3877// Dedupe props in an object literal.3878// Literal duplicated attributes would have been warned during the parse phase,3879// however, it's possible to encounter duplicated `onXXX` handlers with different3880// modifiers. We also need to merge static and dynamic class / style attributes.3881// - onXXX handlers / style: merge into array3882// - class: merge into single expression with concatenation3883function dedupeProperties(properties) {3884    const knownProps = new Map();3885    const deduped = [];3886    for (let i = 0; i < properties.length; i++) {3887        const prop = properties[i];3888        // dynamic keys are always allowed3889        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {3890            deduped.push(prop);3891            continue;3892        }3893        const name = prop.key.content;3894        const existing = knownProps.get(name);3895        if (existing) {3896            if (name === 'style' || name === 'class' || name.startsWith('on')) {3897                mergeAsArray(existing, prop);3898            }3899            // unexpected duplicate, should have emitted error during parse3900        }3901        else {3902            knownProps.set(name, prop);3903            deduped.push(prop);3904        }3905    }3906    return deduped;3907}3908function mergeAsArray(existing, incoming) {3909    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {3910        existing.value.elements.push(incoming.value);3911    }3912    else {3913        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);3914    }3915}3916function buildDirectiveArgs(dir, context) {3917    const dirArgs = [];3918    const runtime = directiveImportMap.get(dir);3919    if (runtime) {3920        // built-in directive with runtime3921        dirArgs.push(context.helperString(runtime));3922    }3923    else {3924        {3925            // inject statement for resolving directive3926            context.helper(RESOLVE_DIRECTIVE);3927            context.directives.add(dir.name);3928            dirArgs.push(toValidAssetId(dir.name, `directive`));3929        }3930    }3931    const { loc } = dir;3932    if (dir.exp)3933        dirArgs.push(dir.exp);3934    if (dir.arg) {3935        if (!dir.exp) {3936            dirArgs.push(`void 0`);3937        }3938        dirArgs.push(dir.arg);3939    }3940    if (Object.keys(dir.modifiers).length) {3941        if (!dir.arg) {3942            if (!dir.exp) {3943                dirArgs.push(`void 0`);3944            }3945            dirArgs.push(`void 0`);3946        }3947        const trueExpression = createSimpleExpression(`true`, false, loc);3948        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));3949    }3950    return createArrayExpression(dirArgs, dir.loc);3951}3952function stringifyDynamicPropNames(props) {3953    let propsNamesString = `[`;3954    for (let i = 0, l = props.length; i < l; i++) {3955        propsNamesString += JSON.stringify(props[i]);3956        if (i < l - 1)3957            propsNamesString += ', ';3958    }3959    return propsNamesString + `]`;3960}3961function isComponentTag(tag) {3962    return tag[0].toLowerCase() + tag.slice(1) === 'component';3963}3964( true)3965    ? Object.freeze({})3966    : 0;3967( true) ? Object.freeze([]) : 0;3968const cacheStringFunction = (fn) => {3969    const cache = Object.create(null);3970    return ((str) => {3971        const hit = cache[str];3972        return hit || (cache[str] = fn(str));3973    });3974};3975const camelizeRE = /-(\w)/g;3976/**3977 * @private3978 */3979const camelize = cacheStringFunction((str) => {3980    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));3981});3982const transformSlotOutlet = (node, context) => {3983    if (isSlotOutlet(node)) {3984        const { children, loc } = node;3985        const { slotName, slotProps } = processSlotOutlet(node, context);3986        const slotArgs = [3987            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,3988            slotName3989        ];3990        if (slotProps) {3991            slotArgs.push(slotProps);3992        }3993        if (children.length) {3994            if (!slotProps) {3995                slotArgs.push(`{}`);3996            }3997            slotArgs.push(createFunctionExpression([], children, false, false, loc));3998        }3999        if (context.scopeId && !context.slotted) {4000            if (!slotProps) {4001                slotArgs.push(`{}`);4002            }4003            if (!children.length) {4004                slotArgs.push(`undefined`);4005            }4006            slotArgs.push(`true`);4007        }4008        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4009    }4010};4011function processSlotOutlet(node, context) {4012    let slotName = `"default"`;4013    let slotProps = undefined;4014    const nonNameProps = [];4015    for (let i = 0; i < node.props.length; i++) {4016        const p = node.props[i];4017        if (p.type === 6 /* ATTRIBUTE */) {4018            if (p.value) {4019                if (p.name === 'name') {4020                    slotName = JSON.stringify(p.value.content);4021                }4022                else {4023                    p.name = camelize(p.name);4024                    nonNameProps.push(p);4025                }4026            }4027        }4028        else {4029            if (p.name === 'bind' && isBindKey(p.arg, 'name')) {4030                if (p.exp)4031                    slotName = p.exp;4032            }4033            else {4034                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4035                    p.arg.content = camelize(p.arg.content);4036                }4037                nonNameProps.push(p);4038            }4039        }4040    }4041    if (nonNameProps.length > 0) {4042        const { props, directives } = buildProps(node, context, nonNameProps);4043        slotProps = props;4044        if (directives.length) {4045            context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4046        }4047    }4048    return {4049        slotName,4050        slotProps4051    };4052}4053const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;4054const transformOn = (dir, node, context, augmentor) => {4055    const { loc, modifiers, arg } = dir;4056    if (!dir.exp && !modifiers.length) {4057        context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));4058    }4059    let eventName;4060    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4061        if (arg.isStatic) {4062            const rawName = arg.content;4063            // for all event listeners, auto convert it to camelCase. See issue #22494064            eventName = createSimpleExpression((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.toHandlerKey)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(rawName)), true, arg.loc);4065        }4066        else {4067            // #23884068            eventName = createCompoundExpression([4069                `${context.helperString(TO_HANDLER_KEY)}(`,4070                arg,4071                `)`4072            ]);4073        }4074    }4075    else {4076        // already a compound expression.4077        eventName = arg;4078        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4079        eventName.children.push(`)`);4080    }4081    // handler processing4082    let exp = dir.exp;4083    if (exp && !exp.content.trim()) {4084        exp = undefined;4085    }4086    let shouldCache = context.cacheHandlers && !exp;4087    if (exp) {4088        const isMemberExp = isMemberExpression(exp.content);4089        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4090        const hasMultipleStatements = exp.content.includes(`;`);4091        if (true) {4092            validateBrowserExpression(exp, context, false, hasMultipleStatements);4093        }4094        if (isInlineStatement || (shouldCache && isMemberExp)) {4095            // wrap inline statement in a function expression4096            exp = createCompoundExpression([4097                `${isInlineStatement4098                    ? `$event`4099                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4100                exp,4101                hasMultipleStatements ? `}` : `)`4102            ]);4103        }4104    }4105    let ret = {4106        props: [4107            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4108        ]4109    };4110    // apply extended compiler augmentor4111    if (augmentor) {4112        ret = augmentor(ret);4113    }4114    if (shouldCache) {4115        // cache handlers so that it's always the same handler being passed down.4116        // this avoids unnecessary re-renders when users use inline handlers on4117        // components.4118        ret.props[0].value = context.cache(ret.props[0].value);4119    }4120    return ret;4121};4122// v-bind without arg is handled directly in ./transformElements.ts due to it affecting4123// codegen for the entire props object. This transform here is only for v-bind4124// *with* args.4125const transformBind = (dir, _node, context) => {4126    const { exp, modifiers, loc } = dir;4127    const arg = dir.arg;4128    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {4129        arg.children.unshift(`(`);4130        arg.children.push(`) || ""`);4131    }4132    else if (!arg.isStatic) {4133        arg.content = `${arg.content} || ""`;4134    }4135    // .prop is no longer necessary due to new patch behavior4136    // .sync is replaced by v-model:arg4137    if (modifiers.includes('camel')) {4138        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4139            if (arg.isStatic) {4140                arg.content = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(arg.content);4141            }4142            else {4143                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;4144            }4145        }4146        else {4147            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);4148            arg.children.push(`)`);4149        }4150    }4151    if (!exp ||4152        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {4153        context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));4154        return {4155            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]4156        };4157    }4158    return {4159        props: [createObjectProperty(arg, exp)]4160    };4161};4162// Merge adjacent text nodes and expressions into a single expression4163// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.4164const transformText = (node, context) => {4165    if (node.type === 0 /* ROOT */ ||4166        node.type === 1 /* ELEMENT */ ||4167        node.type === 11 /* FOR */ ||4168        node.type === 10 /* IF_BRANCH */) {4169        // perform the transform on node exit so that all expressions have already4170        // been processed.4171        return () => {4172            const children = node.children;4173            let currentContainer = undefined;4174            let hasText = false;4175            for (let i = 0; i < children.length; i++) {4176                const child = children[i];4177                if (isText(child)) {4178                    hasText = true;4179                    for (let j = i + 1; j < children.length; j++) {4180                        const next = children[j];4181                        if (isText(next)) {4182                            if (!currentContainer) {4183                                currentContainer = children[i] = {4184                                    type: 8 /* COMPOUND_EXPRESSION */,4185                                    loc: child.loc,4186                                    children: [child]4187                                };4188                            }4189                            // merge adjacent text node into current4190                            currentContainer.children.push(` + `, next);4191                            children.splice(j, 1);4192                            j--;4193                        }4194                        else {4195                            currentContainer = undefined;4196                            break;4197                        }4198                    }4199                }4200            }4201            if (!hasText ||4202                // if this is a plain element with a single text child, leave it4203                // as-is since the runtime has dedicated fast path for this by directly4204                // setting textContent of the element.4205                // for component root it's always normalized anyway.4206                (children.length === 1 &&4207                    (node.type === 0 /* ROOT */ ||4208                        (node.type === 1 /* ELEMENT */ &&4209                            node.tagType === 0 /* ELEMENT */ &&4210                            // #37564211                            // custom directives can potentially add DOM elements arbitrarily,4212                            // we need to avoid setting textContent of the element at runtime4213                            // to avoid accidentally overwriting the DOM elements added4214                            // by the user through custom directives.4215                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&4216                                !context.directiveTransforms[p.name]) &&4217                            // in compat mode, <template> tags with no special directives4218                            // will be rendered as a fragment so its children must be4219                            // converted into vnodes.4220                            !(node.tag === 'template'))))) {4221                return;4222            }4223            // pre-convert text nodes into createTextVNode(text) calls to avoid4224            // runtime normalization.4225            for (let i = 0; i < children.length; i++) {4226                const child = children[i];4227                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {4228                    const callArgs = [];4229                    // createTextVNode defaults to single whitespace, so if it is a4230                    // single space the code could be an empty call to save bytes.4231                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {4232                        callArgs.push(child);4233                    }4234                    // mark dynamic text with flag so it gets patched inside a block4235                    if (!context.ssr &&4236                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4237                        callArgs.push(1 /* TEXT */ +4238                            (( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[1]} */` : 0));4239                    }4240                    children[i] = {4241                        type: 12 /* TEXT_CALL */,4242                        content: child,4243                        loc: child.loc,4244                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)4245                    };4246                }4247            }4248        };4249    }4250};4251const seen = new WeakSet();4252const transformOnce = (node, context) => {4253    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {4254        if (seen.has(node)) {4255            return;4256        }4257        seen.add(node);4258        context.helper(SET_BLOCK_TRACKING);4259        return () => {4260            const cur = context.currentNode;4261            if (cur.codegenNode) {4262                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);4263            }4264        };4265    }4266};4267const transformModel = (dir, node, context) => {4268    const { exp, arg } = dir;4269    if (!exp) {4270        context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));4271        return createTransformProps();4272    }4273    const rawExp = exp.loc.source;4274    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;4275    // im SFC <script setup> inline mode, the exp may have been transformed into4276    // _unref(exp)4277    context.bindingMetadata[rawExp];4278    const maybeRef = !true    /* SETUP_CONST */;4279    if (!expString.trim() || (!isMemberExpression(expString) && !maybeRef)) {4280        context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));4281        return createTransformProps();4282    }4283    const propName = arg ? arg : createSimpleExpression('modelValue', true);4284    const eventName = arg4285        ? isStaticExp(arg)4286            ? `onUpdate:${arg.content}`4287            : createCompoundExpression(['"onUpdate:" + ', arg])4288        : `onUpdate:modelValue`;4289    let assignmentExp;4290    const eventArg = context.isTS ? `($event: any)` : `$event`;4291    {4292        assignmentExp = createCompoundExpression([4293            `${eventArg} => (`,4294            exp,4295            ` = $event)`4296        ]);4297    }4298    const props = [4299        // modelValue: foo4300        createObjectProperty(propName, dir.exp),4301        // "onUpdate:modelValue": $event => (foo = $event)4302        createObjectProperty(eventName, assignmentExp)4303    ];4304    // modelModifiers: { foo: true, "bar-baz": true }4305    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {4306        const modifiers = dir.modifiers4307            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)4308            .join(`, `);4309        const modifiersKey = arg4310            ? isStaticExp(arg)4311                ? `${arg.content}Modifiers`4312                : createCompoundExpression([arg, ' + "Modifiers"'])4313            : `modelModifiers`;4314        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));4315    }4316    return createTransformProps(props);4317};4318function createTransformProps(props = []) {4319    return { props };4320}4321const validDivisionCharRE = /[\w).+\-_$\]]/;4322const transformFilter = (node, context) => {4323    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {4324        return;4325    }4326    if (node.type === 5 /* INTERPOLATION */) {4327        // filter rewrite is applied before expression transform so only4328        // simple expressions are possible at this stage4329        rewriteFilter(node.content, context);4330    }4331    if (node.type === 1 /* ELEMENT */) {4332        node.props.forEach((prop) => {4333            if (prop.type === 7 /* DIRECTIVE */ &&4334                prop.name !== 'for' &&4335                prop.exp) {4336                rewriteFilter(prop.exp, context);4337            }...runtime-dom.esm-browser.js
Source:runtime-dom.esm-browser.js  
...2050    }2051    warnCount[dupKey] = 0;2052    const { message, link } = deprecationData[key];2053    warn(`(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`);2054    if (!isCompatEnabled(key, instance, true)) {2055        console.error(`^ The above deprecation's compat behavior is disabled and will likely ` +2056            `lead to runtime errors.`);2057    }2058}2059const globalCompatConfig = {2060    MODE: 22061};2062function getCompatConfigForKey(key, instance) {2063    const instanceConfig = instance && instance.type.compatConfig;2064    if (instanceConfig && key in instanceConfig) {2065        return instanceConfig[key];2066    }2067    return globalCompatConfig[key];2068}2069function isCompatEnabled(key, instance, enableForBuiltIn = false) {2070    // skip compat for built-in components2071    if (!enableForBuiltIn && instance && instance.type.__isBuiltIn) {2072        return false;2073    }2074    const rawMode = getCompatConfigForKey('MODE', instance) || 2;2075    const val = getCompatConfigForKey(key, instance);2076    const mode = isFunction(rawMode)2077        ? rawMode(instance && instance.type)2078        : rawMode;2079    if (mode === 2) {2080        return val !== false;2081    }2082    else {2083        return val === true || val === 'suppress-warning';2084    }2085}2086function emit(instance, event, ...rawArgs) {2087    const props = instance.vnode.props || EMPTY_OBJ;2088    {2089        const { emitsOptions, propsOptions: [propsOptions] } = instance;2090        if (emitsOptions) {2091            if (!(event in emitsOptions) &&2092                !(false )) {2093                if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {2094                    warn(`Component emitted event "${event}" but it is neither declared in ` +2095                        `the emits option nor as an "${toHandlerKey(event)}" prop.`);2096                }2097            }2098            else {2099                const validator = emitsOptions[event];2100                if (isFunction(validator)) {2101                    const isValid = validator(...rawArgs);2102                    if (!isValid) {2103                        warn(`Invalid event arguments: event validation failed for event "${event}".`);2104                    }2105                }2106            }2107        }2108    }2109    let args = rawArgs;2110    const isModelListener = event.startsWith('update:');2111    // for v-model update:xxx events, apply modifiers on args2112    const modelArg = isModelListener && event.slice(7);2113    if (modelArg && modelArg in props) {2114        const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;2115        const { number, trim } = props[modifiersKey] || EMPTY_OBJ;2116        if (trim) {2117            args = rawArgs.map(a => a.trim());2118        }2119        else if (number) {2120            args = rawArgs.map(toNumber);2121        }2122    }2123    {2124        devtoolsComponentEmit(instance, event, args);2125    }2126    {2127        const lowerCaseEvent = event.toLowerCase();2128        if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {2129            warn(`Event "${lowerCaseEvent}" is emitted in component ` +2130                `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +2131                `Note that HTML attributes are case-insensitive and you cannot use ` +2132                `v-on to listen to camelCase events when using in-DOM templates. ` +2133                `You should probably use "${hyphenate(event)}" instead of "${event}".`);2134        }2135    }2136    let handlerName;2137    let handler = props[(handlerName = toHandlerKey(event))] ||2138        // also try camelCase event handler (#2249)2139        props[(handlerName = toHandlerKey(camelize(event)))];2140    // for v-model update:xxx events, also trigger kebab-case equivalent2141    // for props passed via kebab-case2142    if (!handler && isModelListener) {2143        handler = props[(handlerName = toHandlerKey(hyphenate(event)))];2144    }2145    if (handler) {2146        callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);2147    }2148    const onceHandler = props[handlerName + `Once`];2149    if (onceHandler) {2150        if (!instance.emitted) {2151            instance.emitted = {};2152        }2153        else if (instance.emitted[handlerName]) {2154            return;2155        }2156        instance.emitted[handlerName] = true;2157        callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);2158    }2159}2160function normalizeEmitsOptions(comp, appContext, asMixin = false) {2161    const cache = appContext.emitsCache;2162    const cached = cache.get(comp);2163    if (cached !== undefined) {2164        return cached;2165    }2166    const raw = comp.emits;2167    let normalized = {};2168    // apply mixin/extends props2169    let hasExtends = false;2170    if (!isFunction(comp)) {2171        const extendEmits = (raw) => {2172            const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);2173            if (normalizedFromExtend) {2174                hasExtends = true;2175                extend(normalized, normalizedFromExtend);2176            }2177        };2178        if (!asMixin && appContext.mixins.length) {2179            appContext.mixins.forEach(extendEmits);2180        }2181        if (comp.extends) {2182            extendEmits(comp.extends);2183        }2184        if (comp.mixins) {2185            comp.mixins.forEach(extendEmits);2186        }2187    }2188    if (!raw && !hasExtends) {2189        cache.set(comp, null);2190        return null;2191    }2192    if (isArray(raw)) {2193        raw.forEach(key => (normalized[key] = null));2194    }2195    else {2196        extend(normalized, raw);2197    }2198    cache.set(comp, normalized);2199    return normalized;2200}2201// Check if an incoming prop key is a declared emit event listener.2202// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are2203// both considered matched listeners.2204function isEmitListener(options, key) {2205    if (!options || !isOn(key)) {2206        return false;2207    }2208    key = key.slice(2).replace(/Once$/, '');2209    return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||2210        hasOwn(options, hyphenate(key)) ||2211        hasOwn(options, key));2212}2213/**2214 * mark the current rendering instance for asset resolution (e.g.2215 * resolveComponent, resolveDirective) during render2216 */2217let currentRenderingInstance = null;2218let currentScopeId = null;2219/**2220 * Note: rendering calls maybe nested. The function returns the parent rendering2221 * instance if present, which should be restored after the render is done:2222 *2223 * ```js2224 * const prev = setCurrentRenderingInstance(i)2225 * // ...render2226 * setCurrentRenderingInstance(prev)2227 * ```2228 */2229function setCurrentRenderingInstance(instance) {2230    const prev = currentRenderingInstance;2231    currentRenderingInstance = instance;2232    currentScopeId = (instance && instance.type.__scopeId) || null;2233    return prev;2234}2235/**2236 * Set scope id when creating hoisted vnodes.2237 * @private compiler helper2238 */2239function pushScopeId(id) {2240    currentScopeId = id;2241}2242/**2243 * Technically we no longer need this after 3.0.8 but we need to keep the same2244 * API for backwards compat w/ code generated by compilers.2245 * @private2246 */2247function popScopeId() {2248    currentScopeId = null;2249}2250/**2251 * Only for backwards compat2252 * @private2253 */2254const withScopeId = (_id) => withCtx;2255/**2256 * Wrap a slot function to memoize current rendering instance2257 * @private compiler helper2258 */2259function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only2260) {2261    if (!ctx)2262        return fn;2263    // already normalized2264    if (fn._n) {2265        return fn;2266    }2267    const renderFnWithContext = (...args) => {2268        // If a user calls a compiled slot inside a template expression (#1745), it2269        // can mess up block tracking, so by default we disable block tracking and2270        // force bail out when invoking a compiled slot (indicated by the ._d flag).2271        // This isn't necessary if rendering a compiled `<slot>`, so we flip the2272        // ._d flag off when invoking the wrapped fn inside `renderSlot`.2273        if (renderFnWithContext._d) {2274            setBlockTracking(-1);2275        }2276        const prevInstance = setCurrentRenderingInstance(ctx);2277        const res = fn(...args);2278        setCurrentRenderingInstance(prevInstance);2279        if (renderFnWithContext._d) {2280            setBlockTracking(1);2281        }2282        {2283            devtoolsComponentUpdated(ctx);2284        }2285        return res;2286    };2287    // mark normalized to avoid duplicated wrapping2288    renderFnWithContext._n = true;2289    // mark this as compiled by default2290    // this is used in vnode.ts -> normalizeChildren() to set the slot2291    // rendering flag.2292    renderFnWithContext._c = true;2293    // disable block tracking by default2294    renderFnWithContext._d = true;2295    return renderFnWithContext;2296}2297/**2298 * dev only flag to track whether $attrs was used during render.2299 * If $attrs was used during render then the warning for failed attrs2300 * fallthrough can be suppressed.2301 */2302let accessedAttrs = false;2303function markAttrsAccessed() {2304    accessedAttrs = true;2305}2306function renderComponentRoot(instance) {2307    const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;2308    let result;2309    const prev = setCurrentRenderingInstance(instance);2310    {2311        accessedAttrs = false;2312    }2313    try {2314        let fallthroughAttrs;2315        if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {2316            // withProxy is a proxy with a different `has` trap only for2317            // runtime-compiled render functions using `with` block.2318            const proxyToUse = withProxy || proxy;2319            result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));2320            fallthroughAttrs = attrs;2321        }2322        else {2323            // functional2324            const render = Component;2325            // in dev, mark attrs accessed if optional props (attrs === props)2326            if (true && attrs === props) {2327                markAttrsAccessed();2328            }2329            result = normalizeVNode(render.length > 12330                ? render(props, true2331                    ? {2332                        get attrs() {2333                            markAttrsAccessed();2334                            return attrs;2335                        },2336                        slots,2337                        emit2338                    }2339                    : { attrs, slots, emit })2340                : render(props, null /* we know it doesn't need it */));2341            fallthroughAttrs = Component.props2342                ? attrs2343                : getFunctionalFallthrough(attrs);2344        }2345        // attr merging2346        // in dev mode, comments are preserved, and it's possible for a template2347        // to have comments along side the root element which makes it a fragment2348        let root = result;2349        let setRoot = undefined;2350        if (true &&2351            result.patchFlag > 0 &&2352            result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {2353            ;2354            [root, setRoot] = getChildRoot(result);2355        }2356        if (fallthroughAttrs && inheritAttrs !== false) {2357            const keys = Object.keys(fallthroughAttrs);2358            const { shapeFlag } = root;2359            if (keys.length) {2360                if (shapeFlag & 1 /* ELEMENT */ ||2361                    shapeFlag & 6 /* COMPONENT */) {2362                    if (propsOptions && keys.some(isModelListener)) {2363                        // If a v-model listener (onUpdate:xxx) has a corresponding declared2364                        // prop, it indicates this component expects to handle v-model and2365                        // it should not fallthrough.2366                        // related: #1543, #1643, #19892367                        fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);2368                    }2369                    root = cloneVNode(root, fallthroughAttrs);2370                }2371                else if (true && !accessedAttrs && root.type !== Comment$1) {2372                    const allAttrs = Object.keys(attrs);2373                    const eventAttrs = [];2374                    const extraAttrs = [];2375                    for (let i = 0, l = allAttrs.length; i < l; i++) {2376                        const key = allAttrs[i];2377                        if (isOn(key)) {2378                            // ignore v-model handlers when they fail to fallthrough2379                            if (!isModelListener(key)) {2380                                // remove `on`, lowercase first letter to reflect event casing2381                                // accurately2382                                eventAttrs.push(key[2].toLowerCase() + key.slice(3));2383                            }2384                        }2385                        else {2386                            extraAttrs.push(key);2387                        }2388                    }2389                    if (extraAttrs.length) {2390                        warn(`Extraneous non-props attributes (` +2391                            `${extraAttrs.join(', ')}) ` +2392                            `were passed to component but could not be automatically inherited ` +2393                            `because component renders fragment or text root nodes.`);2394                    }2395                    if (eventAttrs.length) {2396                        warn(`Extraneous non-emits event listeners (` +2397                            `${eventAttrs.join(', ')}) ` +2398                            `were passed to component but could not be automatically inherited ` +2399                            `because component renders fragment or text root nodes. ` +2400                            `If the listener is intended to be a component custom event listener only, ` +2401                            `declare it using the "emits" option.`);2402                    }2403                }2404            }2405        }2406        if (false &&2407            isCompatEnabled("INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */, instance) &&2408            vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */ &&2409            (root.shapeFlag & 1 /* ELEMENT */ ||2410                root.shapeFlag & 6 /* COMPONENT */)) ;2411        // inherit directives2412        if (vnode.dirs) {2413            if (true && !isElementRoot(root)) {2414                warn(`Runtime directive used on component with non-element root node. ` +2415                    `The directives will not function as intended.`);2416            }2417            root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;2418        }2419        // inherit transition data2420        if (vnode.transition) {2421            if (true && !isElementRoot(root)) {...dep-56143c31.js
Source:dep-56143c31.js  
...1419    else {1420        return value;1421    }1422}1423function isCompatEnabled(key, context) {1424    const mode = getCompatValue('MODE', context);1425    const value = getCompatValue(key, context);1426    // in v3 mode, only enable if explicitly set to true1427    // otherwise enable for any non-false value1428    return mode === 3 ? value === true : value !== false;1429}1430function checkCompatEnabled(key, context, loc, ...args) {1431    const enabled = isCompatEnabled(key, context);1432    if ((process.env.NODE_ENV !== 'production') && enabled) {1433        warnDeprecation(key, context, loc, ...args);1434    }1435    return enabled;1436}1437function warnDeprecation(key, context, loc, ...args) {1438    const val = getCompatValue(key, context);1439    if (val === 'suppress-warning') {1440        return;1441    }1442    const { message, link } = deprecationData[key];1443    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;1444    const err = new SyntaxError(msg);1445    err.code = key;1446    if (loc)1447        err.loc = loc;1448    context.onWarn(err);1449}1450// The default decoder only provides escapes for characters reserved as part of1451// the template syntax, and is only used if the custom renderer did not provide1452// a platform-specific decoder.1453const decodeRE = /&(gt|lt|amp|apos|quot);/g;1454const decodeMap = {1455    gt: '>',1456    lt: '<',1457    amp: '&',1458    apos: "'",1459    quot: '"'1460};1461const defaultParserOptions = {1462    delimiters: [`{{`, `}}`],1463    getNamespace: () => 0 /* HTML */,1464    getTextMode: () => 0 /* DATA */,1465    isVoidTag: NO,1466    isPreTag: NO,1467    isCustomElement: NO,1468    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),1469    onError: defaultOnError,1470    onWarn: defaultOnWarn,1471    comments: (process.env.NODE_ENV !== 'production')1472};1473function baseParse(content, options = {}) {1474    const context = createParserContext(content, options);1475    const start = getCursor(context);1476    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));1477}1478function createParserContext(content, rawOptions) {1479    const options = extend({}, defaultParserOptions);1480    let key;1481    for (key in rawOptions) {1482        // @ts-ignore1483        options[key] =1484            rawOptions[key] === undefined1485                ? defaultParserOptions[key]1486                : rawOptions[key];1487    }1488    return {1489        options,1490        column: 1,1491        line: 1,1492        offset: 0,1493        originalSource: content,1494        source: content,1495        inPre: false,1496        inVPre: false,1497        onWarn: options.onWarn1498    };1499}1500function parseChildren(context, mode, ancestors) {1501    const parent = last(ancestors);1502    const ns = parent ? parent.ns : 0 /* HTML */;1503    const nodes = [];1504    while (!isEnd(context, mode, ancestors)) {1505        const s = context.source;1506        let node = undefined;1507        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {1508            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {1509                // '{{'1510                node = parseInterpolation(context, mode);1511            }1512            else if (mode === 0 /* DATA */ && s[0] === '<') {1513                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state1514                if (s.length === 1) {1515                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);1516                }1517                else if (s[1] === '!') {1518                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state1519                    if (startsWith(s, '<!--')) {1520                        node = parseComment(context);1521                    }1522                    else if (startsWith(s, '<!DOCTYPE')) {1523                        // Ignore DOCTYPE by a limitation.1524                        node = parseBogusComment(context);1525                    }1526                    else if (startsWith(s, '<![CDATA[')) {1527                        if (ns !== 0 /* HTML */) {1528                            node = parseCDATA(context, ancestors);1529                        }1530                        else {1531                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);1532                            node = parseBogusComment(context);1533                        }1534                    }1535                    else {1536                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);1537                        node = parseBogusComment(context);1538                    }1539                }1540                else if (s[1] === '/') {1541                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state1542                    if (s.length === 2) {1543                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);1544                    }1545                    else if (s[2] === '>') {1546                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);1547                        advanceBy(context, 3);1548                        continue;1549                    }1550                    else if (/[a-z]/i.test(s[2])) {1551                        emitError(context, 23 /* X_INVALID_END_TAG */);1552                        parseTag(context, 1 /* End */, parent);1553                        continue;1554                    }1555                    else {1556                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);1557                        node = parseBogusComment(context);1558                    }1559                }1560                else if (/[a-z]/i.test(s[1])) {1561                    node = parseElement(context, ancestors);1562                    // 2.x <template> with no directive compat1563                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&1564                        node &&1565                        node.tag === 'template' &&1566                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&1567                            isSpecialTemplateDirective(p.name))) {1568                        (process.env.NODE_ENV !== 'production') &&1569                            warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);1570                        node = node.children;1571                    }1572                }1573                else if (s[1] === '?') {1574                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);1575                    node = parseBogusComment(context);1576                }1577                else {1578                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);1579                }1580            }1581        }1582        if (!node) {1583            node = parseText(context, mode);1584        }1585        if (isArray(node)) {1586            for (let i = 0; i < node.length; i++) {1587                pushNode(nodes, node[i]);1588            }1589        }1590        else {1591            pushNode(nodes, node);1592        }1593    }1594    // Whitespace handling strategy like v21595    let removedWhitespace = false;1596    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {1597        const shouldCondense = context.options.whitespace !== 'preserve';1598        for (let i = 0; i < nodes.length; i++) {1599            const node = nodes[i];1600            if (!context.inPre && node.type === 2 /* TEXT */) {1601                if (!/[^\t\r\n\f ]/.test(node.content)) {1602                    const prev = nodes[i - 1];1603                    const next = nodes[i + 1];1604                    // Remove if:1605                    // - the whitespace is the first or last node, or:1606                    // - (condense mode) the whitespace is adjacent to a comment, or:1607                    // - (condense mode) the whitespace is between two elements AND contains newline1608                    if (!prev ||1609                        !next ||1610                        (shouldCondense &&1611                            (prev.type === 3 /* COMMENT */ ||1612                                next.type === 3 /* COMMENT */ ||1613                                (prev.type === 1 /* ELEMENT */ &&1614                                    next.type === 1 /* ELEMENT */ &&1615                                    /[\r\n]/.test(node.content))))) {1616                        removedWhitespace = true;1617                        nodes[i] = null;1618                    }1619                    else {1620                        // Otherwise, the whitespace is condensed into a single space1621                        node.content = ' ';1622                    }1623                }1624                else if (shouldCondense) {1625                    // in condense mode, consecutive whitespaces in text are condensed1626                    // down to a single space.1627                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1628                }1629            }1630            // Remove comment nodes if desired by configuration.1631            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1632                removedWhitespace = true;1633                nodes[i] = null;1634            }1635        }1636        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1637            // remove leading newline per html spec1638            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1639            const first = nodes[0];1640            if (first && first.type === 2 /* TEXT */) {1641                first.content = first.content.replace(/^\r?\n/, '');1642            }1643        }1644    }1645    return removedWhitespace ? nodes.filter(Boolean) : nodes;1646}1647function pushNode(nodes, node) {1648    if (node.type === 2 /* TEXT */) {1649        const prev = last(nodes);1650        // Merge if both this and the previous node are text and those are1651        // consecutive. This happens for cases like "a < b".1652        if (prev &&1653            prev.type === 2 /* TEXT */ &&1654            prev.loc.end.offset === node.loc.start.offset) {1655            prev.content += node.content;1656            prev.loc.end = node.loc.end;1657            prev.loc.source += node.loc.source;1658            return;1659        }1660    }1661    nodes.push(node);1662}1663function parseCDATA(context, ancestors) {1664    advanceBy(context, 9);1665    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1666    if (context.source.length === 0) {1667        emitError(context, 6 /* EOF_IN_CDATA */);1668    }1669    else {1670        advanceBy(context, 3);1671    }1672    return nodes;1673}1674function parseComment(context) {1675    const start = getCursor(context);1676    let content;1677    // Regular comment.1678    const match = /--(\!)?>/.exec(context.source);1679    if (!match) {1680        content = context.source.slice(4);1681        advanceBy(context, context.source.length);1682        emitError(context, 7 /* EOF_IN_COMMENT */);1683    }1684    else {1685        if (match.index <= 3) {1686            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1687        }1688        if (match[1]) {1689            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1690        }1691        content = context.source.slice(4, match.index);1692        // Advancing with reporting nested comments.1693        const s = context.source.slice(0, match.index);1694        let prevIndex = 1, nestedIndex = 0;1695        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1696            advanceBy(context, nestedIndex - prevIndex + 1);1697            if (nestedIndex + 4 < s.length) {1698                emitError(context, 16 /* NESTED_COMMENT */);1699            }1700            prevIndex = nestedIndex + 1;1701        }1702        advanceBy(context, match.index + match[0].length - prevIndex + 1);1703    }1704    return {1705        type: 3 /* COMMENT */,1706        content,1707        loc: getSelection(context, start)1708    };1709}1710function parseBogusComment(context) {1711    const start = getCursor(context);1712    const contentStart = context.source[1] === '?' ? 1 : 2;1713    let content;1714    const closeIndex = context.source.indexOf('>');1715    if (closeIndex === -1) {1716        content = context.source.slice(contentStart);1717        advanceBy(context, context.source.length);1718    }1719    else {1720        content = context.source.slice(contentStart, closeIndex);1721        advanceBy(context, closeIndex + 1);1722    }1723    return {1724        type: 3 /* COMMENT */,1725        content,1726        loc: getSelection(context, start)1727    };1728}1729function parseElement(context, ancestors) {1730    // Start tag.1731    const wasInPre = context.inPre;1732    const wasInVPre = context.inVPre;1733    const parent = last(ancestors);1734    const element = parseTag(context, 0 /* Start */, parent);1735    const isPreBoundary = context.inPre && !wasInPre;1736    const isVPreBoundary = context.inVPre && !wasInVPre;1737    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1738        // #4030 self-closing <pre> tag1739        if (isPreBoundary) {1740            context.inPre = false;1741        }1742        if (isVPreBoundary) {1743            context.inVPre = false;1744        }1745        return element;1746    }1747    // Children.1748    ancestors.push(element);1749    const mode = context.options.getTextMode(element, parent);1750    const children = parseChildren(context, mode, ancestors);1751    ancestors.pop();1752    // 2.x inline-template compat1753    {1754        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1755        if (inlineTemplateProp &&1756            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1757            const loc = getSelection(context, element.loc.end);1758            inlineTemplateProp.value = {1759                type: 2 /* TEXT */,1760                content: loc.source,1761                loc1762            };1763        }1764    }1765    element.children = children;1766    // End tag.1767    if (startsWithEndTagOpen(context.source, element.tag)) {1768        parseTag(context, 1 /* End */, parent);1769    }1770    else {1771        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1772        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1773            const first = children[0];1774            if (first && startsWith(first.loc.source, '<!--')) {1775                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1776            }1777        }1778    }1779    element.loc = getSelection(context, element.loc.start);1780    if (isPreBoundary) {1781        context.inPre = false;1782    }1783    if (isVPreBoundary) {1784        context.inVPre = false;1785    }1786    return element;1787}1788const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1789function parseTag(context, type, parent) {1790    // Tag open.1791    const start = getCursor(context);1792    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1793    const tag = match[1];1794    const ns = context.options.getNamespace(tag, parent);1795    advanceBy(context, match[0].length);1796    advanceSpaces(context);1797    // save current state in case we need to re-parse attributes with v-pre1798    const cursor = getCursor(context);1799    const currentSource = context.source;1800    // check <pre> tag1801    if (context.options.isPreTag(tag)) {1802        context.inPre = true;1803    }1804    // Attributes.1805    let props = parseAttributes(context, type);1806    // check v-pre1807    if (type === 0 /* Start */ &&1808        !context.inVPre &&1809        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1810        context.inVPre = true;1811        // reset context1812        extend(context, cursor);1813        context.source = currentSource;1814        // re-parse attrs and filter out v-pre itself1815        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1816    }1817    // Tag close.1818    let isSelfClosing = false;1819    if (context.source.length === 0) {1820        emitError(context, 9 /* EOF_IN_TAG */);1821    }1822    else {1823        isSelfClosing = startsWith(context.source, '/>');1824        if (type === 1 /* End */ && isSelfClosing) {1825            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1826        }1827        advanceBy(context, isSelfClosing ? 2 : 1);1828    }1829    if (type === 1 /* End */) {1830        return;1831    }1832    // 2.x deprecation checks1833    if ((process.env.NODE_ENV !== 'production') &&1834        isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1835        let hasIf = false;1836        let hasFor = false;1837        for (let i = 0; i < props.length; i++) {1838            const p = props[i];1839            if (p.type === 7 /* DIRECTIVE */) {1840                if (p.name === 'if') {1841                    hasIf = true;1842                }1843                else if (p.name === 'for') {1844                    hasFor = true;1845                }1846            }1847            if (hasIf && hasFor) {1848                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1849                break;1850            }1851        }1852    }1853    let tagType = 0 /* ELEMENT */;1854    if (!context.inVPre) {1855        if (tag === 'slot') {1856            tagType = 2 /* SLOT */;1857        }1858        else if (tag === 'template') {1859            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1860                tagType = 3 /* TEMPLATE */;1861            }1862        }1863        else if (isComponent(tag, props, context)) {1864            tagType = 1 /* COMPONENT */;1865        }1866    }1867    return {1868        type: 1 /* ELEMENT */,1869        ns,1870        tag,1871        tagType,1872        props,1873        isSelfClosing,1874        children: [],1875        loc: getSelection(context, start),1876        codegenNode: undefined // to be created during transform phase1877    };1878}1879function isComponent(tag, props, context) {1880    const options = context.options;1881    if (options.isCustomElement(tag)) {1882        return false;1883    }1884    if (tag === 'component' ||1885        /^[A-Z]/.test(tag) ||1886        isCoreComponent(tag) ||1887        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1888        (options.isNativeTag && !options.isNativeTag(tag))) {1889        return true;1890    }1891    // at this point the tag should be a native tag, but check for potential "is"1892    // casting1893    for (let i = 0; i < props.length; i++) {1894        const p = props[i];1895        if (p.type === 6 /* ATTRIBUTE */) {1896            if (p.name === 'is' && p.value) {1897                if (p.value.content.startsWith('vue:')) {1898                    return true;1899                }1900                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1901                    return true;1902                }1903            }1904        }1905        else {1906            // directive1907            // v-is (TODO Deprecate)1908            if (p.name === 'is') {1909                return true;1910            }1911            else if (1912            // :is on plain element - only treat as component in compat mode1913            p.name === 'bind' &&1914                isStaticArgOf(p.arg, 'is') &&1915                true &&1916                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1917                return true;1918            }1919        }1920    }1921}1922function parseAttributes(context, type) {1923    const props = [];1924    const attributeNames = new Set();1925    while (context.source.length > 0 &&1926        !startsWith(context.source, '>') &&1927        !startsWith(context.source, '/>')) {1928        if (startsWith(context.source, '/')) {1929            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1930            advanceBy(context, 1);1931            advanceSpaces(context);1932            continue;1933        }1934        if (type === 1 /* End */) {1935            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1936        }1937        const attr = parseAttribute(context, attributeNames);1938        // Trim whitespace between class1939        // https://github.com/vuejs/core/issues/42511940        if (attr.type === 6 /* ATTRIBUTE */ &&1941            attr.value &&1942            attr.name === 'class') {1943            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1944        }1945        if (type === 0 /* Start */) {1946            props.push(attr);1947        }1948        if (/^[^\t\r\n\f />]/.test(context.source)) {1949            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1950        }1951        advanceSpaces(context);1952    }1953    return props;1954}1955function parseAttribute(context, nameSet) {1956    // Name.1957    const start = getCursor(context);1958    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1959    const name = match[0];1960    if (nameSet.has(name)) {1961        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1962    }1963    nameSet.add(name);1964    if (name[0] === '=') {1965        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1966    }1967    {1968        const pattern = /["'<]/g;1969        let m;1970        while ((m = pattern.exec(name))) {1971            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1972        }1973    }1974    advanceBy(context, name.length);1975    // Value1976    let value = undefined;1977    if (/^[\t\r\n\f ]*=/.test(context.source)) {1978        advanceSpaces(context);1979        advanceBy(context, 1);1980        advanceSpaces(context);1981        value = parseAttributeValue(context);1982        if (!value) {1983            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1984        }1985    }1986    const loc = getSelection(context, start);1987    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1988        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1989        let isPropShorthand = startsWith(name, '.');1990        let dirName = match[1] ||1991            (isPropShorthand || startsWith(name, ':')1992                ? 'bind'1993                : startsWith(name, '@')1994                    ? 'on'1995                    : 'slot');1996        let arg;1997        if (match[2]) {1998            const isSlot = dirName === 'slot';1999            const startOffset = name.lastIndexOf(match[2]);2000            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));2001            let content = match[2];2002            let isStatic = true;2003            if (content.startsWith('[')) {2004                isStatic = false;2005                if (!content.endsWith(']')) {2006                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);2007                    content = content.slice(1);2008                }2009                else {2010                    content = content.slice(1, content.length - 1);2011                }2012            }2013            else if (isSlot) {2014                // #1241 special case for v-slot: vuetify relies extensively on slot2015                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x2016                // supports such usage so we are keeping it consistent with 2.x.2017                content += match[3] || '';2018            }2019            arg = {2020                type: 4 /* SIMPLE_EXPRESSION */,2021                content,2022                isStatic,2023                constType: isStatic2024                    ? 3 /* CAN_STRINGIFY */2025                    : 0 /* NOT_CONSTANT */,2026                loc2027            };2028        }2029        if (value && value.isQuoted) {2030            const valueLoc = value.loc;2031            valueLoc.start.offset++;2032            valueLoc.start.column++;2033            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);2034            valueLoc.source = valueLoc.source.slice(1, -1);2035        }2036        const modifiers = match[3] ? match[3].slice(1).split('.') : [];2037        if (isPropShorthand)2038            modifiers.push('prop');2039        // 2.x compat v-bind:foo.sync -> v-model:foo2040        if (dirName === 'bind' && arg) {2041            if (modifiers.includes('sync') &&2042                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {2043                dirName = 'model';2044                modifiers.splice(modifiers.indexOf('sync'), 1);2045            }2046            if ((process.env.NODE_ENV !== 'production') && modifiers.includes('prop')) {2047                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);2048            }2049        }2050        return {2051            type: 7 /* DIRECTIVE */,2052            name: dirName,2053            exp: value && {2054                type: 4 /* SIMPLE_EXPRESSION */,2055                content: value.content,2056                isStatic: false,2057                // Treat as non-constant by default. This can be potentially set to2058                // other values by `transformExpression` to make it eligible for hoisting.2059                constType: 0 /* NOT_CONSTANT */,2060                loc: value.loc2061            },2062            arg,2063            modifiers,2064            loc2065        };2066    }2067    // missing directive name or illegal directive name2068    if (!context.inVPre && startsWith(name, 'v-')) {2069        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);2070    }2071    return {2072        type: 6 /* ATTRIBUTE */,2073        name,2074        value: value && {2075            type: 2 /* TEXT */,2076            content: value.content,2077            loc: value.loc2078        },2079        loc2080    };2081}2082function parseAttributeValue(context) {2083    const start = getCursor(context);2084    let content;2085    const quote = context.source[0];2086    const isQuoted = quote === `"` || quote === `'`;2087    if (isQuoted) {2088        // Quoted value.2089        advanceBy(context, 1);2090        const endIndex = context.source.indexOf(quote);2091        if (endIndex === -1) {2092            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);2093        }2094        else {2095            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);2096            advanceBy(context, 1);2097        }2098    }2099    else {2100        // Unquoted2101        const match = /^[^\t\r\n\f >]+/.exec(context.source);2102        if (!match) {2103            return undefined;2104        }2105        const unexpectedChars = /["'<=`]/g;2106        let m;2107        while ((m = unexpectedChars.exec(match[0]))) {2108            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);2109        }2110        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);2111    }2112    return { content, isQuoted, loc: getSelection(context, start) };2113}2114function parseInterpolation(context, mode) {2115    const [open, close] = context.options.delimiters;2116    const closeIndex = context.source.indexOf(close, open.length);2117    if (closeIndex === -1) {2118        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);2119        return undefined;2120    }2121    const start = getCursor(context);2122    advanceBy(context, open.length);2123    const innerStart = getCursor(context);2124    const innerEnd = getCursor(context);2125    const rawContentLength = closeIndex - open.length;2126    const rawContent = context.source.slice(0, rawContentLength);2127    const preTrimContent = parseTextData(context, rawContentLength, mode);2128    const content = preTrimContent.trim();2129    const startOffset = preTrimContent.indexOf(content);2130    if (startOffset > 0) {2131        advancePositionWithMutation(innerStart, rawContent, startOffset);2132    }2133    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);2134    advancePositionWithMutation(innerEnd, rawContent, endOffset);2135    advanceBy(context, close.length);2136    return {2137        type: 5 /* INTERPOLATION */,2138        content: {2139            type: 4 /* SIMPLE_EXPRESSION */,2140            isStatic: false,2141            // Set `isConstant` to false by default and will decide in transformExpression2142            constType: 0 /* NOT_CONSTANT */,2143            content,2144            loc: getSelection(context, innerStart, innerEnd)2145        },2146        loc: getSelection(context, start)2147    };2148}2149function parseText(context, mode) {2150    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];2151    let endIndex = context.source.length;2152    for (let i = 0; i < endTokens.length; i++) {2153        const index = context.source.indexOf(endTokens[i], 1);2154        if (index !== -1 && endIndex > index) {2155            endIndex = index;2156        }2157    }2158    const start = getCursor(context);2159    const content = parseTextData(context, endIndex, mode);2160    return {2161        type: 2 /* TEXT */,2162        content,2163        loc: getSelection(context, start)2164    };2165}2166/**2167 * Get text data with a given length from the current location.2168 * This translates HTML entities in the text data.2169 */2170function parseTextData(context, length, mode) {2171    const rawText = context.source.slice(0, length);2172    advanceBy(context, length);2173    if (mode === 2 /* RAWTEXT */ ||2174        mode === 3 /* CDATA */ ||2175        !rawText.includes('&')) {2176        return rawText;2177    }2178    else {2179        // DATA or RCDATA containing "&"". Entity decoding required.2180        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);2181    }2182}2183function getCursor(context) {2184    const { column, line, offset } = context;2185    return { column, line, offset };2186}2187function getSelection(context, start, end) {2188    end = end || getCursor(context);2189    return {2190        start,2191        end,2192        source: context.originalSource.slice(start.offset, end.offset)2193    };2194}2195function last(xs) {2196    return xs[xs.length - 1];2197}2198function startsWith(source, searchString) {2199    return source.startsWith(searchString);2200}2201function advanceBy(context, numberOfCharacters) {2202    const { source } = context;2203    advancePositionWithMutation(context, source, numberOfCharacters);2204    context.source = source.slice(numberOfCharacters);2205}2206function advanceSpaces(context) {2207    const match = /^[\t\r\n\f ]+/.exec(context.source);2208    if (match) {2209        advanceBy(context, match[0].length);2210    }2211}2212function getNewPosition(context, start, numberOfCharacters) {2213    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);2214}2215function emitError(context, code, offset, loc = getCursor(context)) {2216    if (offset) {2217        loc.offset += offset;2218        loc.column += offset;2219    }2220    context.options.onError(createCompilerError(code, {2221        start: loc,2222        end: loc,2223        source: ''2224    }));2225}2226function isEnd(context, mode, ancestors) {2227    const s = context.source;2228    switch (mode) {2229        case 0 /* DATA */:2230            if (startsWith(s, '</')) {2231                // TODO: probably bad performance2232                for (let i = ancestors.length - 1; i >= 0; --i) {2233                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {2234                        return true;2235                    }2236                }2237            }2238            break;2239        case 1 /* RCDATA */:2240        case 2 /* RAWTEXT */: {2241            const parent = last(ancestors);2242            if (parent && startsWithEndTagOpen(s, parent.tag)) {2243                return true;2244            }2245            break;2246        }2247        case 3 /* CDATA */:2248            if (startsWith(s, ']]>')) {2249                return true;2250            }2251            break;2252    }2253    return !s;2254}2255function startsWithEndTagOpen(source, tag) {2256    return (startsWith(source, '</') &&2257        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&2258        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));2259}2260function hoistStatic(root, context) {2261    walk(root, context, 2262    // Root node is unfortunately non-hoistable due to potential parent2263    // fallthrough attributes.2264    isSingleElementRoot(root, root.children[0]));2265}2266function isSingleElementRoot(root, child) {2267    const { children } = root;2268    return (children.length === 1 &&2269        child.type === 1 /* ELEMENT */ &&2270        !isSlotOutlet(child));2271}2272function walk(node, context, doNotHoistNode = false) {2273    const { children } = node;2274    const originalCount = children.length;2275    let hoistedCount = 0;2276    for (let i = 0; i < children.length; i++) {2277        const child = children[i];2278        // only plain elements & text calls are eligible for hoisting.2279        if (child.type === 1 /* ELEMENT */ &&2280            child.tagType === 0 /* ELEMENT */) {2281            const constantType = doNotHoistNode2282                ? 0 /* NOT_CONSTANT */2283                : getConstantType(child, context);2284            if (constantType > 0 /* NOT_CONSTANT */) {2285                if (constantType >= 2 /* CAN_HOIST */) {2286                    child.codegenNode.patchFlag =2287                        -1 /* HOISTED */ + ((process.env.NODE_ENV !== 'production') ? ` /* HOISTED */` : ``);2288                    child.codegenNode = context.hoist(child.codegenNode);2289                    hoistedCount++;2290                    continue;2291                }2292            }2293            else {2294                // node may contain dynamic children, but its props may be eligible for2295                // hoisting.2296                const codegenNode = child.codegenNode;2297                if (codegenNode.type === 13 /* VNODE_CALL */) {2298                    const flag = getPatchFlag(codegenNode);2299                    if ((!flag ||2300                        flag === 512 /* NEED_PATCH */ ||2301                        flag === 1 /* TEXT */) &&2302                        getGeneratedPropsConstantType(child, context) >=2303                            2 /* CAN_HOIST */) {2304                        const props = getNodeProps(child);2305                        if (props) {2306                            codegenNode.props = context.hoist(props);2307                        }2308                    }2309                    if (codegenNode.dynamicProps) {2310                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);2311                    }2312                }2313            }2314        }2315        else if (child.type === 12 /* TEXT_CALL */ &&2316            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {2317            child.codegenNode = context.hoist(child.codegenNode);2318            hoistedCount++;2319        }2320        // walk further2321        if (child.type === 1 /* ELEMENT */) {2322            const isComponent = child.tagType === 1 /* COMPONENT */;2323            if (isComponent) {2324                context.scopes.vSlot++;2325            }2326            walk(child, context);2327            if (isComponent) {2328                context.scopes.vSlot--;2329            }2330        }2331        else if (child.type === 11 /* FOR */) {2332            // Do not hoist v-for single child because it has to be a block2333            walk(child, context, child.children.length === 1);2334        }2335        else if (child.type === 9 /* IF */) {2336            for (let i = 0; i < child.branches.length; i++) {2337                // Do not hoist v-if single child because it has to be a block2338                walk(child.branches[i], context, child.branches[i].children.length === 1);2339            }2340        }2341    }2342    if (hoistedCount && context.transformHoist) {2343        context.transformHoist(children, context, node);2344    }2345    // all children were hoisted - the entire children array is hoistable.2346    if (hoistedCount &&2347        hoistedCount === originalCount &&2348        node.type === 1 /* ELEMENT */ &&2349        node.tagType === 0 /* ELEMENT */ &&2350        node.codegenNode &&2351        node.codegenNode.type === 13 /* VNODE_CALL */ &&2352        isArray(node.codegenNode.children)) {2353        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));2354    }2355}2356function getConstantType(node, context) {2357    const { constantCache } = context;2358    switch (node.type) {2359        case 1 /* ELEMENT */:2360            if (node.tagType !== 0 /* ELEMENT */) {2361                return 0 /* NOT_CONSTANT */;2362            }2363            const cached = constantCache.get(node);2364            if (cached !== undefined) {2365                return cached;2366            }2367            const codegenNode = node.codegenNode;2368            if (codegenNode.type !== 13 /* VNODE_CALL */) {2369                return 0 /* NOT_CONSTANT */;2370            }2371            if (codegenNode.isBlock &&2372                node.tag !== 'svg' &&2373                node.tag !== 'foreignObject') {2374                return 0 /* NOT_CONSTANT */;2375            }2376            const flag = getPatchFlag(codegenNode);2377            if (!flag) {2378                let returnType = 3 /* CAN_STRINGIFY */;2379                // Element itself has no patch flag. However we still need to check:2380                // 1. Even for a node with no patch flag, it is possible for it to contain2381                // non-hoistable expressions that refers to scope variables, e.g. compiler2382                // injected keys or cached event handlers. Therefore we need to always2383                // check the codegenNode's props to be sure.2384                const generatedPropsType = getGeneratedPropsConstantType(node, context);2385                if (generatedPropsType === 0 /* NOT_CONSTANT */) {2386                    constantCache.set(node, 0 /* NOT_CONSTANT */);2387                    return 0 /* NOT_CONSTANT */;2388                }2389                if (generatedPropsType < returnType) {2390                    returnType = generatedPropsType;2391                }2392                // 2. its children.2393                for (let i = 0; i < node.children.length; i++) {2394                    const childType = getConstantType(node.children[i], context);2395                    if (childType === 0 /* NOT_CONSTANT */) {2396                        constantCache.set(node, 0 /* NOT_CONSTANT */);2397                        return 0 /* NOT_CONSTANT */;2398                    }2399                    if (childType < returnType) {2400                        returnType = childType;2401                    }2402                }2403                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-02404                // type, check if any of the props can cause the type to be lowered2405                // we can skip can_patch because it's guaranteed by the absence of a2406                // patchFlag.2407                if (returnType > 1 /* CAN_SKIP_PATCH */) {2408                    for (let i = 0; i < node.props.length; i++) {2409                        const p = node.props[i];2410                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {2411                            const expType = getConstantType(p.exp, context);2412                            if (expType === 0 /* NOT_CONSTANT */) {2413                                constantCache.set(node, 0 /* NOT_CONSTANT */);2414                                return 0 /* NOT_CONSTANT */;2415                            }2416                            if (expType < returnType) {2417                                returnType = expType;2418                            }2419                        }2420                    }2421                }2422                // only svg/foreignObject could be block here, however if they are2423                // static then they don't need to be blocks since there will be no2424                // nested updates.2425                if (codegenNode.isBlock) {2426                    context.removeHelper(OPEN_BLOCK);2427                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));2428                    codegenNode.isBlock = false;2429                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));2430                }2431                constantCache.set(node, returnType);2432                return returnType;2433            }2434            else {2435                constantCache.set(node, 0 /* NOT_CONSTANT */);2436                return 0 /* NOT_CONSTANT */;2437            }2438        case 2 /* TEXT */:2439        case 3 /* COMMENT */:2440            return 3 /* CAN_STRINGIFY */;2441        case 9 /* IF */:2442        case 11 /* FOR */:2443        case 10 /* IF_BRANCH */:2444            return 0 /* NOT_CONSTANT */;2445        case 5 /* INTERPOLATION */:2446        case 12 /* TEXT_CALL */:2447            return getConstantType(node.content, context);2448        case 4 /* SIMPLE_EXPRESSION */:2449            return node.constType;2450        case 8 /* COMPOUND_EXPRESSION */:2451            let returnType = 3 /* CAN_STRINGIFY */;2452            for (let i = 0; i < node.children.length; i++) {2453                const child = node.children[i];2454                if (isString(child) || isSymbol(child)) {2455                    continue;2456                }2457                const childType = getConstantType(child, context);2458                if (childType === 0 /* NOT_CONSTANT */) {2459                    return 0 /* NOT_CONSTANT */;2460                }2461                else if (childType < returnType) {2462                    returnType = childType;2463                }2464            }2465            return returnType;2466        default:2467            if ((process.env.NODE_ENV !== 'production')) ;2468            return 0 /* NOT_CONSTANT */;2469    }2470}2471const allowHoistedHelperSet = new Set([2472    NORMALIZE_CLASS,2473    NORMALIZE_STYLE,2474    NORMALIZE_PROPS,2475    GUARD_REACTIVE_PROPS2476]);2477function getConstantTypeOfHelperCall(value, context) {2478    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&2479        !isString(value.callee) &&2480        allowHoistedHelperSet.has(value.callee)) {2481        const arg = value.arguments[0];2482        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2483            return getConstantType(arg, context);2484        }2485        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {2486            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`2487            return getConstantTypeOfHelperCall(arg, context);2488        }2489    }2490    return 0 /* NOT_CONSTANT */;2491}2492function getGeneratedPropsConstantType(node, context) {2493    let returnType = 3 /* CAN_STRINGIFY */;2494    const props = getNodeProps(node);2495    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {2496        const { properties } = props;2497        for (let i = 0; i < properties.length; i++) {2498            const { key, value } = properties[i];2499            const keyType = getConstantType(key, context);2500            if (keyType === 0 /* NOT_CONSTANT */) {2501                return keyType;2502            }2503            if (keyType < returnType) {2504                returnType = keyType;2505            }2506            let valueType;2507            if (value.type === 4 /* SIMPLE_EXPRESSION */) {2508                valueType = getConstantType(value, context);2509            }2510            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {2511                // some helper calls can be hoisted,2512                // such as the `normalizeProps` generated by the compiler for pre-normalize class,2513                // in this case we need to respect the ConstantType of the helper's arguments2514                valueType = getConstantTypeOfHelperCall(value, context);2515            }2516            else {2517                valueType = 0 /* NOT_CONSTANT */;2518            }2519            if (valueType === 0 /* NOT_CONSTANT */) {2520                return valueType;2521            }2522            if (valueType < returnType) {2523                returnType = valueType;2524            }2525        }2526    }2527    return returnType;2528}2529function getNodeProps(node) {2530    const codegenNode = node.codegenNode;2531    if (codegenNode.type === 13 /* VNODE_CALL */) {2532        return codegenNode.props;2533    }2534}2535function getPatchFlag(node) {2536    const flag = node.patchFlag;2537    return flag ? parseInt(flag, 10) : undefined;2538}2539function 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 }) {2540    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);2541    const context = {2542        // options2543        selfName: nameMatch && capitalize(camelize$1(nameMatch[1])),2544        prefixIdentifiers,2545        hoistStatic,2546        cacheHandlers,2547        nodeTransforms,2548        directiveTransforms,2549        transformHoist,2550        isBuiltInComponent,2551        isCustomElement,2552        expressionPlugins,2553        scopeId,2554        slotted,2555        ssr,2556        inSSR,2557        ssrCssVars,2558        bindingMetadata,2559        inline,2560        isTS,2561        onError,2562        onWarn,2563        compatConfig,2564        // state2565        root,2566        helpers: new Map(),2567        components: new Set(),2568        directives: new Set(),2569        hoists: [],2570        imports: [],2571        constantCache: new Map(),2572        temps: 0,2573        cached: 0,2574        identifiers: Object.create(null),2575        scopes: {2576            vFor: 0,2577            vSlot: 0,2578            vPre: 0,2579            vOnce: 02580        },2581        parent: null,2582        currentNode: root,2583        childIndex: 0,2584        inVOnce: false,2585        // methods2586        helper(name) {2587            const count = context.helpers.get(name) || 0;2588            context.helpers.set(name, count + 1);2589            return name;2590        },2591        removeHelper(name) {2592            const count = context.helpers.get(name);2593            if (count) {2594                const currentCount = count - 1;2595                if (!currentCount) {2596                    context.helpers.delete(name);2597                }2598                else {2599                    context.helpers.set(name, currentCount);2600                }2601            }2602        },2603        helperString(name) {2604            return `_${helperNameMap[context.helper(name)]}`;2605        },2606        replaceNode(node) {2607            /* istanbul ignore if */2608            if ((process.env.NODE_ENV !== 'production')) {2609                if (!context.currentNode) {2610                    throw new Error(`Node being replaced is already removed.`);2611                }2612                if (!context.parent) {2613                    throw new Error(`Cannot replace root node.`);2614                }2615            }2616            context.parent.children[context.childIndex] = context.currentNode = node;2617        },2618        removeNode(node) {2619            if ((process.env.NODE_ENV !== 'production') && !context.parent) {2620                throw new Error(`Cannot remove root node.`);2621            }2622            const list = context.parent.children;2623            const removalIndex = node2624                ? list.indexOf(node)2625                : context.currentNode2626                    ? context.childIndex2627                    : -1;2628            /* istanbul ignore if */2629            if ((process.env.NODE_ENV !== 'production') && removalIndex < 0) {2630                throw new Error(`node being removed is not a child of current parent`);2631            }2632            if (!node || node === context.currentNode) {2633                // current node removed2634                context.currentNode = null;2635                context.onNodeRemoved();2636            }2637            else {2638                // sibling node removed2639                if (context.childIndex > removalIndex) {2640                    context.childIndex--;2641                    context.onNodeRemoved();2642                }2643            }2644            context.parent.children.splice(removalIndex, 1);2645        },2646        onNodeRemoved: () => { },2647        addIdentifiers(exp) {2648        },2649        removeIdentifiers(exp) {2650        },2651        hoist(exp) {2652            if (isString(exp))2653                exp = createSimpleExpression(exp);2654            context.hoists.push(exp);2655            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2656            identifier.hoisted = exp;2657            return identifier;2658        },2659        cache(exp, isVNode = false) {2660            return createCacheExpression(context.cached++, exp, isVNode);2661        }2662    };2663    {2664        context.filters = new Set();2665    }2666    return context;2667}2668function transform(root, options) {2669    const context = createTransformContext(root, options);2670    traverseNode(root, context);2671    if (options.hoistStatic) {2672        hoistStatic(root, context);2673    }2674    if (!options.ssr) {2675        createRootCodegen(root, context);2676    }2677    // finalize meta information2678    root.helpers = [...context.helpers.keys()];2679    root.components = [...context.components];2680    root.directives = [...context.directives];2681    root.imports = context.imports;2682    root.hoists = context.hoists;2683    root.temps = context.temps;2684    root.cached = context.cached;2685    {2686        root.filters = [...context.filters];2687    }2688}2689function createRootCodegen(root, context) {2690    const { helper } = context;2691    const { children } = root;2692    if (children.length === 1) {2693        const child = children[0];2694        // if the single child is an element, turn it into a block.2695        if (isSingleElementRoot(root, child) && child.codegenNode) {2696            // single element root is never hoisted so codegenNode will never be2697            // SimpleExpressionNode2698            const codegenNode = child.codegenNode;2699            if (codegenNode.type === 13 /* VNODE_CALL */) {2700                makeBlock(codegenNode, context);2701            }2702            root.codegenNode = codegenNode;2703        }2704        else {2705            // - single <slot/>, IfNode, ForNode: already blocks.2706            // - single text node: always patched.2707            // root codegen falls through via genNode()2708            root.codegenNode = child;2709        }2710    }2711    else if (children.length > 1) {2712        // root has multiple nodes - return a fragment block.2713        let patchFlag = 64 /* STABLE_FRAGMENT */;2714        let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2715        // check if the fragment actually contains a single valid child with2716        // the rest being comments2717        if ((process.env.NODE_ENV !== 'production') &&2718            children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2719            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2720            patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2721        }2722        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, undefined, false /* isComponent */);2723    }2724    else ;2725}2726function traverseChildren(parent, context) {2727    let i = 0;2728    const nodeRemoved = () => {2729        i--;2730    };2731    for (; i < parent.children.length; i++) {2732        const child = parent.children[i];2733        if (isString(child))2734            continue;2735        context.parent = parent;2736        context.childIndex = i;2737        context.onNodeRemoved = nodeRemoved;2738        traverseNode(child, context);2739    }2740}2741function traverseNode(node, context) {2742    context.currentNode = node;2743    // apply transform plugins2744    const { nodeTransforms } = context;2745    const exitFns = [];2746    for (let i = 0; i < nodeTransforms.length; i++) {2747        const onExit = nodeTransforms[i](node, context);2748        if (onExit) {2749            if (isArray(onExit)) {2750                exitFns.push(...onExit);2751            }2752            else {2753                exitFns.push(onExit);2754            }2755        }2756        if (!context.currentNode) {2757            // node was removed2758            return;2759        }2760        else {2761            // node may have been replaced2762            node = context.currentNode;2763        }2764    }2765    switch (node.type) {2766        case 3 /* COMMENT */:2767            if (!context.ssr) {2768                // inject import for the Comment symbol, which is needed for creating2769                // comment nodes with `createVNode`2770                context.helper(CREATE_COMMENT);2771            }2772            break;2773        case 5 /* INTERPOLATION */:2774            // no need to traverse, but we need to inject toString helper2775            if (!context.ssr) {2776                context.helper(TO_DISPLAY_STRING);2777            }2778            break;2779        // for container types, further traverse downwards2780        case 9 /* IF */:2781            for (let i = 0; i < node.branches.length; i++) {2782                traverseNode(node.branches[i], context);2783            }2784            break;2785        case 10 /* IF_BRANCH */:2786        case 11 /* FOR */:2787        case 1 /* ELEMENT */:2788        case 0 /* ROOT */:2789            traverseChildren(node, context);2790            break;2791    }2792    // exit transforms2793    context.currentNode = node;2794    let i = exitFns.length;2795    while (i--) {2796        exitFns[i]();2797    }2798}2799function createStructuralDirectiveTransform(name, fn) {2800    const matches = isString(name)2801        ? (n) => n === name2802        : (n) => name.test(n);2803    return (node, context) => {2804        if (node.type === 1 /* ELEMENT */) {2805            const { props } = node;2806            // structural directive transforms are not concerned with slots2807            // as they are handled separately in vSlot.ts2808            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2809                return;2810            }2811            const exitFns = [];2812            for (let i = 0; i < props.length; i++) {2813                const prop = props[i];2814                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2815                    // structural directives are removed to avoid infinite recursion2816                    // also we remove them *before* applying so that it can further2817                    // traverse itself in case it moves the node around2818                    props.splice(i, 1);2819                    i--;2820                    const onExit = fn(node, prop, context);2821                    if (onExit)2822                        exitFns.push(onExit);2823                }2824            }2825            return exitFns;2826        }2827    };2828}2829const PURE_ANNOTATION = `/*#__PURE__*/`;2830function 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 }) {2831    const context = {2832        mode,2833        prefixIdentifiers,2834        sourceMap,2835        filename,2836        scopeId,2837        optimizeImports,2838        runtimeGlobalName,2839        runtimeModuleName,2840        ssrRuntimeModuleName,2841        ssr,2842        isTS,2843        inSSR,2844        source: ast.loc.source,2845        code: ``,2846        column: 1,2847        line: 1,2848        offset: 0,2849        indentLevel: 0,2850        pure: false,2851        map: undefined,2852        helper(key) {2853            return `_${helperNameMap[key]}`;2854        },2855        push(code, node) {2856            context.code += code;2857        },2858        indent() {2859            newline(++context.indentLevel);2860        },2861        deindent(withoutNewLine = false) {2862            if (withoutNewLine) {2863                --context.indentLevel;2864            }2865            else {2866                newline(--context.indentLevel);2867            }2868        },2869        newline() {2870            newline(context.indentLevel);2871        }2872    };2873    function newline(n) {2874        context.push('\n' + `  `.repeat(n));2875    }2876    return context;2877}2878function generate(ast, options = {}) {2879    const context = createCodegenContext(ast, options);2880    if (options.onContextCreated)2881        options.onContextCreated(context);2882    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2883    const hasHelpers = ast.helpers.length > 0;2884    const useWithBlock = !prefixIdentifiers && mode !== 'module';2885    // preambles2886    // in setup() inline mode, the preamble is generated in a sub context2887    // and returned separately.2888    const preambleContext = context;2889    {2890        genFunctionPreamble(ast, preambleContext);2891    }2892    // enter render function2893    const functionName = ssr ? `ssrRender` : `render`;2894    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2895    const signature = args.join(', ');2896    {2897        push(`function ${functionName}(${signature}) {`);2898    }2899    indent();2900    if (useWithBlock) {2901        push(`with (_ctx) {`);2902        indent();2903        // function mode const declarations should be inside with block2904        // also they should be renamed to avoid collision with user properties2905        if (hasHelpers) {2906            push(`const { ${ast.helpers2907                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2908                .join(', ')} } = _Vue`);2909            push(`\n`);2910            newline();2911        }2912    }2913    // generate asset resolution statements2914    if (ast.components.length) {2915        genAssets(ast.components, 'component', context);2916        if (ast.directives.length || ast.temps > 0) {2917            newline();2918        }2919    }2920    if (ast.directives.length) {2921        genAssets(ast.directives, 'directive', context);2922        if (ast.temps > 0) {2923            newline();2924        }2925    }2926    if (ast.filters && ast.filters.length) {2927        newline();2928        genAssets(ast.filters, 'filter', context);2929        newline();2930    }2931    if (ast.temps > 0) {2932        push(`let `);2933        for (let i = 0; i < ast.temps; i++) {2934            push(`${i > 0 ? `, ` : ``}_temp${i}`);2935        }2936    }2937    if (ast.components.length || ast.directives.length || ast.temps) {2938        push(`\n`);2939        newline();2940    }2941    // generate the VNode tree expression2942    if (!ssr) {2943        push(`return `);2944    }2945    if (ast.codegenNode) {2946        genNode(ast.codegenNode, context);2947    }2948    else {2949        push(`null`);2950    }2951    if (useWithBlock) {2952        deindent();2953        push(`}`);2954    }2955    deindent();2956    push(`}`);2957    return {2958        ast,2959        code: context.code,2960        preamble: ``,2961        // SourceMapGenerator does have toJSON() method but it's not in the types2962        map: context.map ? context.map.toJSON() : undefined2963    };2964}2965function genFunctionPreamble(ast, context) {2966    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2967    const VueBinding = runtimeGlobalName;2968    const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2969    // Generate const declaration for helpers2970    // In prefix mode, we place the const declaration at top so it's done2971    // only once; But if we not prefixing, we place the declaration inside the2972    // with block so it doesn't incur the `in` check cost for every helper access.2973    if (ast.helpers.length > 0) {2974        {2975            // "with" mode.2976            // save Vue in a separate variable to avoid collision2977            push(`const _Vue = ${VueBinding}\n`);2978            // in "with" mode, helpers are declared inside the with block to avoid2979            // has check cost, but hoists are lifted out of the function - we need2980            // to provide the helper here.2981            if (ast.hoists.length) {2982                const staticHelpers = [2983                    CREATE_VNODE,2984                    CREATE_ELEMENT_VNODE,2985                    CREATE_COMMENT,2986                    CREATE_TEXT,2987                    CREATE_STATIC2988                ]2989                    .filter(helper => ast.helpers.includes(helper))2990                    .map(aliasHelper)2991                    .join(', ');2992                push(`const { ${staticHelpers} } = _Vue\n`);2993            }2994        }2995    }2996    genHoists(ast.hoists, context);2997    newline();2998    push(`return `);2999}3000function genAssets(assets, type, { helper, push, newline, isTS }) {3001    const resolver = helper(type === 'filter'3002        ? RESOLVE_FILTER3003        : type === 'component'3004            ? RESOLVE_COMPONENT3005            : RESOLVE_DIRECTIVE);3006    for (let i = 0; i < assets.length; i++) {3007        let id = assets[i];3008        // potential component implicit self-reference inferred from SFC filename3009        const maybeSelfReference = id.endsWith('__self');3010        if (maybeSelfReference) {3011            id = id.slice(0, -6);3012        }3013        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);3014        if (i < assets.length - 1) {3015            newline();3016        }3017    }3018}3019function genHoists(hoists, context) {3020    if (!hoists.length) {3021        return;3022    }3023    context.pure = true;3024    const { push, newline, helper, scopeId, mode } = context;3025    newline();3026    for (let i = 0; i < hoists.length; i++) {3027        const exp = hoists[i];3028        if (exp) {3029            push(`const _hoisted_${i + 1} = ${``}`);3030            genNode(exp, context);3031            newline();3032        }3033    }3034    context.pure = false;3035}3036function isText$1(n) {3037    return (isString(n) ||3038        n.type === 4 /* SIMPLE_EXPRESSION */ ||3039        n.type === 2 /* TEXT */ ||3040        n.type === 5 /* INTERPOLATION */ ||3041        n.type === 8 /* COMPOUND_EXPRESSION */);3042}3043function genNodeListAsArray(nodes, context) {3044    const multilines = nodes.length > 3 ||3045        (((process.env.NODE_ENV !== 'production')) && nodes.some(n => isArray(n) || !isText$1(n)));3046    context.push(`[`);3047    multilines && context.indent();3048    genNodeList(nodes, context, multilines);3049    multilines && context.deindent();3050    context.push(`]`);3051}3052function genNodeList(nodes, context, multilines = false, comma = true) {3053    const { push, newline } = context;3054    for (let i = 0; i < nodes.length; i++) {3055        const node = nodes[i];3056        if (isString(node)) {3057            push(node);3058        }3059        else if (isArray(node)) {3060            genNodeListAsArray(node, context);3061        }3062        else {3063            genNode(node, context);3064        }3065        if (i < nodes.length - 1) {3066            if (multilines) {3067                comma && push(',');3068                newline();3069            }3070            else {3071                comma && push(', ');3072            }3073        }3074    }3075}3076function genNode(node, context) {3077    if (isString(node)) {3078        context.push(node);3079        return;3080    }3081    if (isSymbol(node)) {3082        context.push(context.helper(node));3083        return;3084    }3085    switch (node.type) {3086        case 1 /* ELEMENT */:3087        case 9 /* IF */:3088        case 11 /* FOR */:3089            (process.env.NODE_ENV !== 'production') &&3090                assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +3091                    `Apply appropriate transforms first.`);3092            genNode(node.codegenNode, context);3093            break;3094        case 2 /* TEXT */:3095            genText(node, context);3096            break;3097        case 4 /* SIMPLE_EXPRESSION */:3098            genExpression(node, context);3099            break;3100        case 5 /* INTERPOLATION */:3101            genInterpolation(node, context);3102            break;3103        case 12 /* TEXT_CALL */:3104            genNode(node.codegenNode, context);3105            break;3106        case 8 /* COMPOUND_EXPRESSION */:3107            genCompoundExpression(node, context);3108            break;3109        case 3 /* COMMENT */:3110            genComment(node, context);3111            break;3112        case 13 /* VNODE_CALL */:3113            genVNodeCall(node, context);3114            break;3115        case 14 /* JS_CALL_EXPRESSION */:3116            genCallExpression(node, context);3117            break;3118        case 15 /* JS_OBJECT_EXPRESSION */:3119            genObjectExpression(node, context);3120            break;3121        case 17 /* JS_ARRAY_EXPRESSION */:3122            genArrayExpression(node, context);3123            break;3124        case 18 /* JS_FUNCTION_EXPRESSION */:3125            genFunctionExpression(node, context);3126            break;3127        case 19 /* JS_CONDITIONAL_EXPRESSION */:3128            genConditionalExpression(node, context);3129            break;3130        case 20 /* JS_CACHE_EXPRESSION */:3131            genCacheExpression(node, context);3132            break;3133        case 21 /* JS_BLOCK_STATEMENT */:3134            genNodeList(node.body, context, true, false);3135            break;3136        // SSR only types3137        case 22 /* JS_TEMPLATE_LITERAL */:3138            break;3139        case 23 /* JS_IF_STATEMENT */:3140            break;3141        case 24 /* JS_ASSIGNMENT_EXPRESSION */:3142            break;3143        case 25 /* JS_SEQUENCE_EXPRESSION */:3144            break;3145        case 26 /* JS_RETURN_STATEMENT */:3146            break;3147        /* istanbul ignore next */3148        case 10 /* IF_BRANCH */:3149            // noop3150            break;3151        default:3152            if ((process.env.NODE_ENV !== 'production')) {3153                assert(false, `unhandled codegen node type: ${node.type}`);3154                // make sure we exhaust all possible types3155                const exhaustiveCheck = node;3156                return exhaustiveCheck;3157            }3158    }3159}3160function genText(node, context) {3161    context.push(JSON.stringify(node.content), node);3162}3163function genExpression(node, context) {3164    const { content, isStatic } = node;3165    context.push(isStatic ? JSON.stringify(content) : content, node);3166}3167function genInterpolation(node, context) {3168    const { push, helper, pure } = context;3169    if (pure)3170        push(PURE_ANNOTATION);3171    push(`${helper(TO_DISPLAY_STRING)}(`);3172    genNode(node.content, context);3173    push(`)`);3174}3175function genCompoundExpression(node, context) {3176    for (let i = 0; i < node.children.length; i++) {3177        const child = node.children[i];3178        if (isString(child)) {3179            context.push(child);3180        }3181        else {3182            genNode(child, context);3183        }3184    }3185}3186function genExpressionAsPropertyKey(node, context) {3187    const { push } = context;3188    if (node.type === 8 /* COMPOUND_EXPRESSION */) {3189        push(`[`);3190        genCompoundExpression(node, context);3191        push(`]`);3192    }3193    else if (node.isStatic) {3194        // only quote keys if necessary3195        const text = isSimpleIdentifier(node.content)3196            ? node.content3197            : JSON.stringify(node.content);3198        push(text, node);3199    }3200    else {3201        push(`[${node.content}]`, node);3202    }3203}3204function genComment(node, context) {3205    const { push, helper, pure } = context;3206    if (pure) {3207        push(PURE_ANNOTATION);3208    }3209    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);3210}3211function genVNodeCall(node, context) {3212    const { push, helper, pure } = context;3213    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;3214    if (directives) {3215        push(helper(WITH_DIRECTIVES) + `(`);3216    }3217    if (isBlock) {3218        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);3219    }3220    if (pure) {3221        push(PURE_ANNOTATION);3222    }3223    const callHelper = isBlock3224        ? getVNodeBlockHelper(context.inSSR, isComponent)3225        : getVNodeHelper(context.inSSR, isComponent);3226    push(helper(callHelper) + `(`, node);3227    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);3228    push(`)`);3229    if (isBlock) {3230        push(`)`);3231    }3232    if (directives) {3233        push(`, `);3234        genNode(directives, context);3235        push(`)`);3236    }3237}3238function genNullableArgs(args) {3239    let i = args.length;3240    while (i--) {3241        if (args[i] != null)3242            break;3243    }3244    return args.slice(0, i + 1).map(arg => arg || `null`);3245}3246// JavaScript3247function genCallExpression(node, context) {3248    const { push, helper, pure } = context;3249    const callee = isString(node.callee) ? node.callee : helper(node.callee);3250    if (pure) {3251        push(PURE_ANNOTATION);3252    }3253    push(callee + `(`, node);3254    genNodeList(node.arguments, context);3255    push(`)`);3256}3257function genObjectExpression(node, context) {3258    const { push, indent, deindent, newline } = context;3259    const { properties } = node;3260    if (!properties.length) {3261        push(`{}`, node);3262        return;3263    }3264    const multilines = properties.length > 1 ||3265        (((process.env.NODE_ENV !== 'production')) &&3266            properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));3267    push(multilines ? `{` : `{ `);3268    multilines && indent();3269    for (let i = 0; i < properties.length; i++) {3270        const { key, value } = properties[i];3271        // key3272        genExpressionAsPropertyKey(key, context);3273        push(`: `);3274        // value3275        genNode(value, context);3276        if (i < properties.length - 1) {3277            // will only reach this if it's multilines3278            push(`,`);3279            newline();3280        }3281    }3282    multilines && deindent();3283    push(multilines ? `}` : ` }`);3284}3285function genArrayExpression(node, context) {3286    genNodeListAsArray(node.elements, context);3287}3288function genFunctionExpression(node, context) {3289    const { push, indent, deindent } = context;3290    const { params, returns, body, newline, isSlot } = node;3291    if (isSlot) {3292        // wrap slot functions with owner context3293        push(`_${helperNameMap[WITH_CTX]}(`);3294    }3295    push(`(`, node);3296    if (isArray(params)) {3297        genNodeList(params, context);3298    }3299    else if (params) {3300        genNode(params, context);3301    }3302    push(`) => `);3303    if (newline || body) {3304        push(`{`);3305        indent();3306    }3307    if (returns) {3308        if (newline) {3309            push(`return `);3310        }3311        if (isArray(returns)) {3312            genNodeListAsArray(returns, context);3313        }3314        else {3315            genNode(returns, context);3316        }3317    }3318    else if (body) {3319        genNode(body, context);3320    }3321    if (newline || body) {3322        deindent();3323        push(`}`);3324    }3325    if (isSlot) {3326        if (node.isNonScopedSlot) {3327            push(`, undefined, true`);3328        }3329        push(`)`);3330    }3331}3332function genConditionalExpression(node, context) {3333    const { test, consequent, alternate, newline: needNewline } = node;3334    const { push, indent, deindent, newline } = context;3335    if (test.type === 4 /* SIMPLE_EXPRESSION */) {3336        const needsParens = !isSimpleIdentifier(test.content);3337        needsParens && push(`(`);3338        genExpression(test, context);3339        needsParens && push(`)`);3340    }3341    else {3342        push(`(`);3343        genNode(test, context);3344        push(`)`);3345    }3346    needNewline && indent();3347    context.indentLevel++;3348    needNewline || push(` `);3349    push(`? `);3350    genNode(consequent, context);3351    context.indentLevel--;3352    needNewline && newline();3353    needNewline || push(` `);3354    push(`: `);3355    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;3356    if (!isNested) {3357        context.indentLevel++;3358    }3359    genNode(alternate, context);3360    if (!isNested) {3361        context.indentLevel--;3362    }3363    needNewline && deindent(true /* without newline */);3364}3365function genCacheExpression(node, context) {3366    const { push, helper, indent, deindent, newline } = context;3367    push(`_cache[${node.index}] || (`);3368    if (node.isVNode) {3369        indent();3370        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);3371        newline();3372    }3373    push(`_cache[${node.index}] = `);3374    genNode(node.value, context);3375    if (node.isVNode) {3376        push(`,`);3377        newline();3378        push(`${helper(SET_BLOCK_TRACKING)}(1),`);3379        newline();3380        push(`_cache[${node.index}]`);3381        deindent();3382    }3383    push(`)`);3384}3385function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {3386    {3387        return;3388    }3389}3390function isReferencedIdentifier(id, parent, parentStack) {3391    {3392        return false;3393    }3394}3395function isInDestructureAssignment(parent, parentStack) {3396    if (parent &&3397        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {3398        let i = parentStack.length;3399        while (i--) {3400            const p = parentStack[i];3401            if (p.type === 'AssignmentExpression') {3402                return true;3403            }3404            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {3405                break;3406            }3407        }3408    }3409    return false;3410}3411function walkFunctionParams(node, onIdent) {3412    for (const p of node.params) {3413        for (const id of extractIdentifiers(p)) {3414            onIdent(id);3415        }3416    }3417}3418function walkBlockDeclarations(block, onIdent) {3419    for (const stmt of block.body) {3420        if (stmt.type === 'VariableDeclaration') {3421            if (stmt.declare)3422                continue;3423            for (const decl of stmt.declarations) {3424                for (const id of extractIdentifiers(decl.id)) {3425                    onIdent(id);3426                }3427            }3428        }3429        else if (stmt.type === 'FunctionDeclaration' ||3430            stmt.type === 'ClassDeclaration') {3431            if (stmt.declare || !stmt.id)3432                continue;3433            onIdent(stmt.id);3434        }3435    }3436}3437function extractIdentifiers(param, nodes = []) {3438    switch (param.type) {3439        case 'Identifier':3440            nodes.push(param);3441            break;3442        case 'MemberExpression':3443            let object = param;3444            while (object.type === 'MemberExpression') {3445                object = object.object;3446            }3447            nodes.push(object);3448            break;3449        case 'ObjectPattern':3450            for (const prop of param.properties) {3451                if (prop.type === 'RestElement') {3452                    extractIdentifiers(prop.argument, nodes);3453                }3454                else {3455                    extractIdentifiers(prop.value, nodes);3456                }3457            }3458            break;3459        case 'ArrayPattern':3460            param.elements.forEach(element => {3461                if (element)3462                    extractIdentifiers(element, nodes);3463            });3464            break;3465        case 'RestElement':3466            extractIdentifiers(param.argument, nodes);3467            break;3468        case 'AssignmentPattern':3469            extractIdentifiers(param.left, nodes);3470            break;3471    }3472    return nodes;3473}3474const isFunctionType = (node) => {3475    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3476};3477const isStaticProperty = (node) => node &&3478    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3479    !node.computed;3480const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3481// these keywords should not appear inside expressions, but operators like3482// typeof, instanceof and in are allowed3483const prohibitedKeywordRE = new RegExp('\\b' +3484    ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +3485        'super,throw,while,yield,delete,export,import,return,switch,default,' +3486        'extends,finally,continue,debugger,function,arguments,typeof,void')3487        .split(',')3488        .join('\\b|\\b') +3489    '\\b');3490// strip strings in expressions3491const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;3492/**3493 * Validate a non-prefixed expression.3494 * This is only called when using the in-browser runtime compiler since it3495 * doesn't prefix expressions.3496 */3497function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {3498    const exp = node.content;3499    // empty expressions are validated per-directive since some directives3500    // do allow empty expressions.3501    if (!exp.trim()) {3502        return;3503    }3504    try {3505        new Function(asRawStatements3506            ? ` ${exp} `3507            : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);3508    }3509    catch (e) {3510        let message = e.message;3511        const keywordMatch = exp3512            .replace(stripStringRE, '')3513            .match(prohibitedKeywordRE);3514        if (keywordMatch) {3515            message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;3516        }3517        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));3518    }3519}3520const transformExpression = (node, context) => {3521    if (node.type === 5 /* INTERPOLATION */) {3522        node.content = processExpression(node.content, context);3523    }3524    else if (node.type === 1 /* ELEMENT */) {3525        // handle directives on element3526        for (let i = 0; i < node.props.length; i++) {3527            const dir = node.props[i];3528            // do not process for v-on & v-for since they are special handled3529            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3530                const exp = dir.exp;3531                const arg = dir.arg;3532                // do not process exp if this is v-on:arg - we need special handling3533                // for wrapping inline statements.3534                if (exp &&3535                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&3536                    !(dir.name === 'on' && arg)) {3537                    dir.exp = processExpression(exp, context, 3538                    // slot args must be processed as function params3539                    dir.name === 'slot');3540                }3541                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3542                    dir.arg = processExpression(arg, context);3543                }3544            }3545        }3546    }3547};3548// Important: since this function uses Node.js only dependencies, it should3549// always be used with a leading !true check so that it can be3550// tree-shaken from the browser build.3551function processExpression(node, context, 3552// some expressions like v-slot props & v-for aliases should be parsed as3553// function params3554asParams = false, 3555// v-on handler values may contain multiple statements3556asRawStatements = false, localVars = Object.create(context.identifiers)) {3557    {3558        if ((process.env.NODE_ENV !== 'production')) {3559            // simple in-browser validation (same logic in 2.x)3560            validateBrowserExpression(node, context, asParams, asRawStatements);3561        }3562        return node;3563    }3564}3565const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3566    return processIf(node, dir, context, (ifNode, branch, isRoot) => {3567        // #1587: We need to dynamically increment the key based on the current3568        // node's sibling nodes, since chained v-if/else branches are3569        // rendered at the same depth3570        const siblings = context.parent.children;3571        let i = siblings.indexOf(ifNode);3572        let key = 0;3573        while (i-- >= 0) {3574            const sibling = siblings[i];3575            if (sibling && sibling.type === 9 /* IF */) {3576                key += sibling.branches.length;3577            }3578        }3579        // Exit callback. Complete the codegenNode when all children have been3580        // transformed.3581        return () => {3582            if (isRoot) {3583                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3584            }3585            else {3586                // attach this branch's codegen node to the v-if root.3587                const parentCondition = getParentCondition(ifNode.codegenNode);3588                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3589            }3590        };3591    });3592});3593// target-agnostic transform used for both Client and SSR3594function processIf(node, dir, context, processCodegen) {3595    if (dir.name !== 'else' &&3596        (!dir.exp || !dir.exp.content.trim())) {3597        const loc = dir.exp ? dir.exp.loc : node.loc;3598        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3599        dir.exp = createSimpleExpression(`true`, false, loc);3600    }3601    if ((process.env.NODE_ENV !== 'production') && true && dir.exp) {3602        validateBrowserExpression(dir.exp, context);3603    }3604    if (dir.name === 'if') {3605        const branch = createIfBranch(node, dir);3606        const ifNode = {3607            type: 9 /* IF */,3608            loc: node.loc,3609            branches: [branch]3610        };3611        context.replaceNode(ifNode);3612        if (processCodegen) {3613            return processCodegen(ifNode, branch, true);3614        }3615    }3616    else {3617        // locate the adjacent v-if3618        const siblings = context.parent.children;3619        const comments = [];3620        let i = siblings.indexOf(node);3621        while (i-- >= -1) {3622            const sibling = siblings[i];3623            if ((process.env.NODE_ENV !== 'production') && sibling && sibling.type === 3 /* COMMENT */) {3624                context.removeNode(sibling);3625                comments.unshift(sibling);3626                continue;3627            }3628            if (sibling &&3629                sibling.type === 2 /* TEXT */ &&3630                !sibling.content.trim().length) {3631                context.removeNode(sibling);3632                continue;3633            }3634            if (sibling && sibling.type === 9 /* IF */) {3635                // Check if v-else was followed by v-else-if3636                if (dir.name === 'else-if' &&3637                    sibling.branches[sibling.branches.length - 1].condition === undefined) {3638                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3639                }3640                // move the node to the if node's branches3641                context.removeNode();3642                const branch = createIfBranch(node, dir);3643                if ((process.env.NODE_ENV !== 'production') &&3644                    comments.length &&3645                    // #3619 ignore comments if the v-if is direct child of <transition>3646                    !(context.parent &&3647                        context.parent.type === 1 /* ELEMENT */ &&3648                        isBuiltInType(context.parent.tag, 'transition'))) {3649                    branch.children = [...comments, ...branch.children];3650                }3651                // check if user is forcing same key on different branches3652                if ((process.env.NODE_ENV !== 'production') || !true) {3653                    const key = branch.userKey;3654                    if (key) {3655                        sibling.branches.forEach(({ userKey }) => {3656                            if (isSameKey(userKey, key)) {3657                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3658                            }3659                        });3660                    }3661                }3662                sibling.branches.push(branch);3663                const onExit = processCodegen && processCodegen(sibling, branch, false);3664                // since the branch was removed, it will not be traversed.3665                // make sure to traverse here.3666                traverseNode(branch, context);3667                // call on exit3668                if (onExit)3669                    onExit();3670                // make sure to reset currentNode after traversal to indicate this3671                // node has been removed.3672                context.currentNode = null;3673            }3674            else {3675                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3676            }3677            break;3678        }3679    }3680}3681function createIfBranch(node, dir) {3682    return {3683        type: 10 /* IF_BRANCH */,3684        loc: node.loc,3685        condition: dir.name === 'else' ? undefined : dir.exp,3686        children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3687            ? node.children3688            : [node],3689        userKey: findProp(node, `key`)3690    };3691}3692function createCodegenNodeForBranch(branch, keyIndex, context) {3693    if (branch.condition) {3694        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3695        // make sure to pass in asBlock: true so that the comment node call3696        // closes the current block.3697        createCallExpression(context.helper(CREATE_COMMENT), [3698            (process.env.NODE_ENV !== 'production') ? '"v-if"' : '""',3699            'true'3700        ]));3701    }3702    else {3703        return createChildrenCodegenNode(branch, keyIndex, context);3704    }3705}3706function createChildrenCodegenNode(branch, keyIndex, context) {3707    const { helper } = context;3708    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3709    const { children } = branch;3710    const firstChild = children[0];3711    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3712    if (needFragmentWrapper) {3713        if (children.length === 1 && firstChild.type === 11 /* FOR */) {3714            // optimize away nested fragments when child is a ForNode3715            const vnodeCall = firstChild.codegenNode;3716            injectProp(vnodeCall, keyProperty, context);3717            return vnodeCall;3718        }3719        else {3720            let patchFlag = 64 /* STABLE_FRAGMENT */;3721            let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3722            // check if the fragment actually contains a single valid child with3723            // the rest being comments3724            if ((process.env.NODE_ENV !== 'production') &&3725                children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3726                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3727                patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3728            }3729            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc);3730        }3731    }3732    else {3733        const ret = firstChild.codegenNode;3734        const vnodeCall = getMemoedVNodeCall(ret);3735        // Change createVNode to createBlock.3736        if (vnodeCall.type === 13 /* VNODE_CALL */) {3737            makeBlock(vnodeCall, context);3738        }3739        // inject branch key3740        injectProp(vnodeCall, keyProperty, context);3741        return ret;3742    }3743}3744function isSameKey(a, b) {3745    if (!a || a.type !== b.type) {3746        return false;3747    }3748    if (a.type === 6 /* ATTRIBUTE */) {3749        if (a.value.content !== b.value.content) {3750            return false;3751        }3752    }3753    else {3754        // directive3755        const exp = a.exp;3756        const branchExp = b.exp;3757        if (exp.type !== branchExp.type) {3758            return false;3759        }3760        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3761            exp.isStatic !== branchExp.isStatic ||3762            exp.content !== branchExp.content) {3763            return false;3764        }3765    }3766    return true;3767}3768function getParentCondition(node) {3769    while (true) {3770        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3771            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3772                node = node.alternate;3773            }3774            else {3775                return node;3776            }3777        }3778        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3779            node = node.value;3780        }3781    }3782}3783const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3784    const { helper, removeHelper } = context;3785    return processFor(node, dir, context, forNode => {3786        // create the loop render function expression now, and add the3787        // iterator on exit after all children have been traversed3788        const renderExp = createCallExpression(helper(RENDER_LIST), [3789            forNode.source3790        ]);3791        const isTemplate = isTemplateNode(node);3792        const memo = findDir(node, 'memo');3793        const keyProp = findProp(node, `key`);3794        const keyExp = keyProp &&3795            (keyProp.type === 6 /* ATTRIBUTE */3796                ? createSimpleExpression(keyProp.value.content, true)3797                : keyProp.exp);3798        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3799        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3800            forNode.source.constType > 0 /* NOT_CONSTANT */;3801        const fragmentFlag = isStableFragment3802            ? 64 /* STABLE_FRAGMENT */3803            : keyProp3804                ? 128 /* KEYED_FRAGMENT */3805                : 256 /* UNKEYED_FRAGMENT */;3806        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3807            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3808        return () => {3809            // finish the codegen now that all children have been traversed3810            let childBlock;3811            const { children } = forNode;3812            // check <template v-for> key placement3813            if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {3814                node.children.some(c => {3815                    if (c.type === 1 /* ELEMENT */) {3816                        const key = findProp(c, 'key');3817                        if (key) {3818                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3819                            return true;3820                        }3821                    }3822                });3823            }3824            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3825            const slotOutlet = isSlotOutlet(node)3826                ? node3827                : isTemplate &&3828                    node.children.length === 1 &&3829                    isSlotOutlet(node.children[0])3830                    ? node.children[0] // api-extractor somehow fails to infer this3831                    : null;3832            if (slotOutlet) {3833                // <slot v-for="..."> or <template v-for="..."><slot/></template>3834                childBlock = slotOutlet.codegenNode;3835                if (isTemplate && keyProperty) {3836                    // <template v-for="..." :key="..."><slot/></template>3837                    // we need to inject the key to the renderSlot() call.3838                    // the props for renderSlot is passed as the 3rd argument.3839                    injectProp(childBlock, keyProperty, context);3840                }3841            }3842            else if (needFragmentWrapper) {3843                // <template v-for="..."> with text or multi-elements3844                // should generate a fragment block for each loop3845                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3846                    ((process.env.NODE_ENV !== 'production')3847                        ? ` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3848                        : ``), undefined, undefined, true, undefined, false /* isComponent */);3849            }3850            else {3851                // Normal element v-for. Directly use the child's codegenNode3852                // but mark it as a block.3853                childBlock = children[0]3854                    .codegenNode;3855                if (isTemplate && keyProperty) {3856                    injectProp(childBlock, keyProperty, context);3857                }3858                if (childBlock.isBlock !== !isStableFragment) {3859                    if (childBlock.isBlock) {3860                        // switch from block to vnode3861                        removeHelper(OPEN_BLOCK);3862                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3863                    }3864                    else {3865                        // switch from vnode to block3866                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3867                    }3868                }3869                childBlock.isBlock = !isStableFragment;3870                if (childBlock.isBlock) {3871                    helper(OPEN_BLOCK);3872                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3873                }3874                else {3875                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3876                }3877            }3878            if (memo) {3879                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3880                    createSimpleExpression(`_cached`)3881                ]));3882                loop.body = createBlockStatement([3883                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3884                    createCompoundExpression([3885                        `if (_cached`,3886                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),3887                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3888                    ]),3889                    createCompoundExpression([`const _item = `, childBlock]),3890                    createSimpleExpression(`_item.memo = _memo`),3891                    createSimpleExpression(`return _item`)3892                ]);3893                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3894            }3895            else {3896                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3897            }3898        };3899    });3900});3901// target-agnostic transform used for both Client and SSR3902function processFor(node, dir, context, processCodegen) {3903    if (!dir.exp) {3904        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3905        return;3906    }3907    const parseResult = parseForExpression(3908    // can only be simple expression because vFor transform is applied3909    // before expression transform.3910    dir.exp, context);3911    if (!parseResult) {3912        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3913        return;3914    }3915    const { addIdentifiers, removeIdentifiers, scopes } = context;3916    const { source, value, key, index } = parseResult;3917    const forNode = {3918        type: 11 /* FOR */,3919        loc: dir.loc,3920        source,3921        valueAlias: value,3922        keyAlias: key,3923        objectIndexAlias: index,3924        parseResult,3925        children: isTemplateNode(node) ? node.children : [node]3926    };3927    context.replaceNode(forNode);3928    // bookkeeping3929    scopes.vFor++;3930    const onExit = processCodegen && processCodegen(forNode);3931    return () => {3932        scopes.vFor--;3933        if (onExit)3934            onExit();3935    };3936}3937const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3938// This regex doesn't cover the case if key or index aliases have destructuring,3939// but those do not make sense in the first place, so this works in practice.3940const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3941const stripParensRE = /^\(|\)$/g;3942function parseForExpression(input, context) {3943    const loc = input.loc;3944    const exp = input.content;3945    const inMatch = exp.match(forAliasRE);3946    if (!inMatch)3947        return;3948    const [, LHS, RHS] = inMatch;3949    const result = {3950        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3951        value: undefined,3952        key: undefined,3953        index: undefined3954    };3955    if ((process.env.NODE_ENV !== 'production') && true) {3956        validateBrowserExpression(result.source, context);3957    }3958    let valueContent = LHS.trim().replace(stripParensRE, '').trim();3959    const trimmedOffset = LHS.indexOf(valueContent);3960    const iteratorMatch = valueContent.match(forIteratorRE);3961    if (iteratorMatch) {3962        valueContent = valueContent.replace(forIteratorRE, '').trim();3963        const keyContent = iteratorMatch[1].trim();3964        let keyOffset;3965        if (keyContent) {3966            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3967            result.key = createAliasExpression(loc, keyContent, keyOffset);3968            if ((process.env.NODE_ENV !== 'production') && true) {3969                validateBrowserExpression(result.key, context, true);3970            }3971        }3972        if (iteratorMatch[2]) {3973            const indexContent = iteratorMatch[2].trim();3974            if (indexContent) {3975                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3976                    ? keyOffset + keyContent.length3977                    : trimmedOffset + valueContent.length));3978                if ((process.env.NODE_ENV !== 'production') && true) {3979                    validateBrowserExpression(result.index, context, true);3980                }3981            }3982        }3983    }3984    if (valueContent) {3985        result.value = createAliasExpression(loc, valueContent, trimmedOffset);3986        if ((process.env.NODE_ENV !== 'production') && true) {3987            validateBrowserExpression(result.value, context, true);3988        }3989    }3990    return result;3991}3992function createAliasExpression(range, content, offset) {3993    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3994}3995function createForLoopParams({ value, key, index }, memoArgs = []) {3996    return createParamsList([value, key, index, ...memoArgs]);3997}3998function createParamsList(args) {3999    let i = args.length;4000    while (i--) {4001        if (args[i])4002            break;4003    }4004    return args4005        .slice(0, i + 1)4006        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));4007}4008const defaultFallback = createSimpleExpression(`undefined`, false);4009// A NodeTransform that:4010// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed4011//    by transformExpression. This is only applied in non-browser builds with4012//    { prefixIdentifiers: true }.4013// 2. Track v-slot depths so that we know a slot is inside another slot.4014//    Note the exit callback is executed before buildSlots() on the same node,4015//    so only nested slots see positive numbers.4016const trackSlotScopes = (node, context) => {4017    if (node.type === 1 /* ELEMENT */ &&4018        (node.tagType === 1 /* COMPONENT */ ||4019            node.tagType === 3 /* TEMPLATE */)) {4020        // We are only checking non-empty v-slot here4021        // since we only care about slots that introduce scope variables.4022        const vSlot = findDir(node, 'slot');4023        if (vSlot) {4024            context.scopes.vSlot++;4025            return () => {4026                context.scopes.vSlot--;4027            };4028        }4029    }4030};4031// A NodeTransform that tracks scope identifiers for scoped slots with v-for.4032// This transform is only applied in non-browser builds with { prefixIdentifiers: true }4033const trackVForSlotScopes = (node, context) => {4034    let vFor;4035    if (isTemplateNode(node) &&4036        node.props.some(isVSlot) &&4037        (vFor = findDir(node, 'for'))) {4038        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));4039        if (result) {4040            const { value, key, index } = result;4041            const { addIdentifiers, removeIdentifiers } = context;4042            value && addIdentifiers(value);4043            key && addIdentifiers(key);4044            index && addIdentifiers(index);4045            return () => {4046                value && removeIdentifiers(value);4047                key && removeIdentifiers(key);4048                index && removeIdentifiers(index);4049            };4050        }4051    }4052};4053const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);4054// Instead of being a DirectiveTransform, v-slot processing is called during4055// transformElement to build the slots object for a component.4056function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {4057    context.helper(WITH_CTX);4058    const { children, loc } = node;4059    const slotsProperties = [];4060    const dynamicSlots = [];4061    // If the slot is inside a v-for or another v-slot, force it to be dynamic4062    // since it likely uses a scope variable.4063    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;4064    // 1. Check for slot with slotProps on component itself.4065    //    <Comp v-slot="{ prop }"/>4066    const onComponentSlot = findDir(node, 'slot', true);4067    if (onComponentSlot) {4068        const { arg, exp } = onComponentSlot;4069        if (arg && !isStaticExp(arg)) {4070            hasDynamicSlots = true;4071        }4072        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));4073    }4074    // 2. Iterate through children and check for template slots4075    //    <template v-slot:foo="{ prop }">4076    let hasTemplateSlots = false;4077    let hasNamedDefaultSlot = false;4078    const implicitDefaultChildren = [];4079    const seenSlotNames = new Set();4080    for (let i = 0; i < children.length; i++) {4081        const slotElement = children[i];4082        let slotDir;4083        if (!isTemplateNode(slotElement) ||4084            !(slotDir = findDir(slotElement, 'slot', true))) {4085            // not a <template v-slot>, skip.4086            if (slotElement.type !== 3 /* COMMENT */) {4087                implicitDefaultChildren.push(slotElement);4088            }4089            continue;4090        }4091        if (onComponentSlot) {4092            // already has on-component slot - this is incorrect usage.4093            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));4094            break;4095        }4096        hasTemplateSlots = true;4097        const { children: slotChildren, loc: slotLoc } = slotElement;4098        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;4099        // check if name is dynamic.4100        let staticSlotName;4101        if (isStaticExp(slotName)) {4102            staticSlotName = slotName ? slotName.content : `default`;4103        }4104        else {4105            hasDynamicSlots = true;4106        }4107        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);4108        // check if this slot is conditional (v-if/v-for)4109        let vIf;4110        let vElse;4111        let vFor;4112        if ((vIf = findDir(slotElement, 'if'))) {4113            hasDynamicSlots = true;4114            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));4115        }4116        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {4117            // find adjacent v-if4118            let j = i;4119            let prev;4120            while (j--) {4121                prev = children[j];4122                if (prev.type !== 3 /* COMMENT */) {4123                    break;4124                }4125            }4126            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {4127                // remove node4128                children.splice(i, 1);4129                i--;4130                // attach this slot to previous conditional4131                let conditional = dynamicSlots[dynamicSlots.length - 1];4132                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {4133                    conditional = conditional.alternate;4134                }4135                conditional.alternate = vElse.exp4136                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)4137                    : buildDynamicSlot(slotName, slotFunction);4138            }4139            else {4140                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));4141            }4142        }4143        else if ((vFor = findDir(slotElement, 'for'))) {4144            hasDynamicSlots = true;4145            const parseResult = vFor.parseResult ||4146                parseForExpression(vFor.exp, context);4147            if (parseResult) {4148                // Render the dynamic slots as an array and add it to the createSlot()4149                // args. The runtime knows how to handle it appropriately.4150                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [4151                    parseResult.source,4152                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)4153                ]));4154            }4155            else {4156                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));4157            }4158        }4159        else {4160            // check duplicate static names4161            if (staticSlotName) {4162                if (seenSlotNames.has(staticSlotName)) {4163                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));4164                    continue;4165                }4166                seenSlotNames.add(staticSlotName);4167                if (staticSlotName === 'default') {4168                    hasNamedDefaultSlot = true;4169                }4170            }4171            slotsProperties.push(createObjectProperty(slotName, slotFunction));4172        }4173    }4174    if (!onComponentSlot) {4175        const buildDefaultSlotProperty = (props, children) => {4176            const fn = buildSlotFn(props, children, loc);4177            if (context.compatConfig) {4178                fn.isNonScopedSlot = true;4179            }4180            return createObjectProperty(`default`, fn);4181        };4182        if (!hasTemplateSlots) {4183            // implicit default slot (on component)4184            slotsProperties.push(buildDefaultSlotProperty(undefined, children));4185        }4186        else if (implicitDefaultChildren.length &&4187            // #37664188            // with whitespace: 'preserve', whitespaces between slots will end up in4189            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.4190            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {4191            // implicit default slot (mixed with named slots)4192            if (hasNamedDefaultSlot) {4193                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));4194            }4195            else {4196                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));4197            }4198        }4199    }4200    const slotFlag = hasDynamicSlots4201        ? 2 /* DYNAMIC */4202        : hasForwardedSlots(node.children)4203            ? 3 /* FORWARDED */4204            : 1 /* STABLE */;4205    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 4206    // 2 = compiled but dynamic = can skip normalization, but must run diff4207    // 1 = compiled and static = can skip normalization AND diff as optimized4208    createSimpleExpression(slotFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${slotFlagsText[slotFlag]} */` : ``), false))), loc);4209    if (dynamicSlots.length) {4210        slots = createCallExpression(context.helper(CREATE_SLOTS), [4211            slots,4212            createArrayExpression(dynamicSlots)4213        ]);4214    }4215    return {4216        slots,4217        hasDynamicSlots4218    };4219}4220function buildDynamicSlot(name, fn) {4221    return createObjectExpression([4222        createObjectProperty(`name`, name),4223        createObjectProperty(`fn`, fn)4224    ]);4225}4226function hasForwardedSlots(children) {4227    for (let i = 0; i < children.length; i++) {4228        const child = children[i];4229        switch (child.type) {4230            case 1 /* ELEMENT */:4231                if (child.tagType === 2 /* SLOT */ ||4232                    hasForwardedSlots(child.children)) {4233                    return true;4234                }4235                break;4236            case 9 /* IF */:4237                if (hasForwardedSlots(child.branches))4238                    return true;4239                break;4240            case 10 /* IF_BRANCH */:4241            case 11 /* FOR */:4242                if (hasForwardedSlots(child.children))4243                    return true;4244                break;4245        }4246    }4247    return false;4248}4249function isNonWhitespaceContent(node) {4250    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)4251        return true;4252    return node.type === 2 /* TEXT */4253        ? !!node.content.trim()4254        : isNonWhitespaceContent(node.content);4255}4256// some directive transforms (e.g. v-model) may return a symbol for runtime4257// import, which should be used instead of a resolveDirective call.4258const directiveImportMap = new WeakMap();4259// generate a JavaScript AST for this element's codegen4260const transformElement = (node, context) => {4261    // perform the work on exit, after all child expressions have been4262    // processed and merged.4263    return function postTransformElement() {4264        node = context.currentNode;4265        if (!(node.type === 1 /* ELEMENT */ &&4266            (node.tagType === 0 /* ELEMENT */ ||4267                node.tagType === 1 /* COMPONENT */))) {4268            return;4269        }4270        const { tag, props } = node;4271        const isComponent = node.tagType === 1 /* COMPONENT */;4272        // The goal of the transform is to create a codegenNode implementing the4273        // VNodeCall interface.4274        let vnodeTag = isComponent4275            ? resolveComponentType(node, context)4276            : `"${tag}"`;4277        const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;4278        let vnodeProps;4279        let vnodeChildren;4280        let vnodePatchFlag;4281        let patchFlag = 0;4282        let vnodeDynamicProps;4283        let dynamicPropNames;4284        let vnodeDirectives;4285        let shouldUseBlock = 4286        // dynamic component may resolve to plain elements4287        isDynamicComponent ||4288            vnodeTag === TELEPORT ||4289            vnodeTag === SUSPENSE ||4290            (!isComponent &&4291                // <svg> and <foreignObject> must be forced into blocks so that block4292                // updates inside get proper isSVG flag at runtime. (#639, #643)4293                // This is technically web-specific, but splitting the logic out of core4294                // leads to too much unnecessary complexity.4295                (tag === 'svg' || tag === 'foreignObject'));4296        // props4297        if (props.length > 0) {4298            const propsBuildResult = buildProps(node, context);4299            vnodeProps = propsBuildResult.props;4300            patchFlag = propsBuildResult.patchFlag;4301            dynamicPropNames = propsBuildResult.dynamicPropNames;4302            const directives = propsBuildResult.directives;4303            vnodeDirectives =4304                directives && directives.length4305                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))4306                    : undefined;4307            if (propsBuildResult.shouldUseBlock) {4308                shouldUseBlock = true;4309            }4310        }4311        // children4312        if (node.children.length > 0) {4313            if (vnodeTag === KEEP_ALIVE) {4314                // Although a built-in component, we compile KeepAlive with raw children4315                // instead of slot functions so that it can be used inside Transition4316                // or other Transition-wrapping HOCs.4317                // To ensure correct updates with block optimizations, we need to:4318                // 1. Force keep-alive into a block. This avoids its children being4319                //    collected by a parent block.4320                shouldUseBlock = true;4321                // 2. Force keep-alive to always be updated, since it uses raw children.4322                patchFlag |= 1024 /* DYNAMIC_SLOTS */;4323                if ((process.env.NODE_ENV !== 'production') && node.children.length > 1) {4324                    context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {4325                        start: node.children[0].loc.start,4326                        end: node.children[node.children.length - 1].loc.end,4327                        source: ''4328                    }));4329                }4330            }4331            const shouldBuildAsSlots = isComponent &&4332                // Teleport is not a real component and has dedicated runtime handling4333                vnodeTag !== TELEPORT &&4334                // explained above.4335                vnodeTag !== KEEP_ALIVE;4336            if (shouldBuildAsSlots) {4337                const { slots, hasDynamicSlots } = buildSlots(node, context);4338                vnodeChildren = slots;4339                if (hasDynamicSlots) {4340                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;4341                }4342            }4343            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {4344                const child = node.children[0];4345                const type = child.type;4346                // check for dynamic text children4347                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||4348                    type === 8 /* COMPOUND_EXPRESSION */;4349                if (hasDynamicTextChild &&4350                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4351                    patchFlag |= 1 /* TEXT */;4352                }4353                // pass directly if the only child is a text node4354                // (plain / interpolation / expression)4355                if (hasDynamicTextChild || type === 2 /* TEXT */) {4356                    vnodeChildren = child;4357                }4358                else {4359                    vnodeChildren = node.children;4360                }4361            }4362            else {4363                vnodeChildren = node.children;4364            }4365        }4366        // patchFlag & dynamicPropNames4367        if (patchFlag !== 0) {4368            if ((process.env.NODE_ENV !== 'production')) {4369                if (patchFlag < 0) {4370                    // special flags (negative and mutually exclusive)4371                    vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;4372                }4373                else {4374                    // bitwise flags4375                    const flagNames = Object.keys(PatchFlagNames)4376                        .map(Number)4377                        .filter(n => n > 0 && patchFlag & n)4378                        .map(n => PatchFlagNames[n])4379                        .join(`, `);4380                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;4381                }4382            }4383            else {4384                vnodePatchFlag = String(patchFlag);4385            }4386            if (dynamicPropNames && dynamicPropNames.length) {4387                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);4388            }4389        }4390        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);4391    };4392};4393function resolveComponentType(node, context, ssr = false) {4394    let { tag } = node;4395    // 1. dynamic component4396    const isExplicitDynamic = isComponentTag(tag);4397    const isProp = findProp(node, 'is');4398    if (isProp) {4399        if (isExplicitDynamic ||4400            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {4401            const exp = isProp.type === 6 /* ATTRIBUTE */4402                ? isProp.value && createSimpleExpression(isProp.value.content, true)4403                : isProp.exp;4404            if (exp) {4405                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4406                    exp4407                ]);4408            }4409        }4410        else if (isProp.type === 6 /* ATTRIBUTE */ &&4411            isProp.value.content.startsWith('vue:')) {4412            // <button is="vue:xxx">4413            // if not <component>, only is value that starts with "vue:" will be4414            // treated as component by the parse phase and reach here, unless it's4415            // compat mode where all is values are considered components4416            tag = isProp.value.content.slice(4);4417        }4418    }4419    // 1.5 v-is (TODO: Deprecate)4420    const isDir = !isExplicitDynamic && findDir(node, 'is');4421    if (isDir && isDir.exp) {4422        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4423            isDir.exp4424        ]);4425    }4426    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)4427    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);4428    if (builtIn) {4429        // built-ins are simply fallthroughs / have special handling during ssr4430        // so we don't need to import their runtime equivalents4431        if (!ssr)4432            context.helper(builtIn);4433        return builtIn;4434    }4435    // 5. user component (resolve)4436    context.helper(RESOLVE_COMPONENT);4437    context.components.add(tag);4438    return toValidAssetId(tag, `component`);4439}4440function buildProps(node, context, props = node.props, ssr = false) {4441    const { tag, loc: elementLoc, children } = node;4442    const isComponent = node.tagType === 1 /* COMPONENT */;4443    let properties = [];4444    const mergeArgs = [];4445    const runtimeDirectives = [];4446    const hasChildren = children.length > 0;4447    let shouldUseBlock = false;4448    // patchFlag analysis4449    let patchFlag = 0;4450    let hasRef = false;4451    let hasClassBinding = false;4452    let hasStyleBinding = false;4453    let hasHydrationEventBinding = false;4454    let hasDynamicKeys = false;4455    let hasVnodeHook = false;4456    const dynamicPropNames = [];4457    const analyzePatchFlag = ({ key, value }) => {4458        if (isStaticExp(key)) {4459            const name = key.content;4460            const isEventHandler = isOn(name);4461            if (!isComponent &&4462                isEventHandler &&4463                // omit the flag for click handlers because hydration gives click4464                // dedicated fast path.4465                name.toLowerCase() !== 'onclick' &&4466                // omit v-model handlers4467                name !== 'onUpdate:modelValue' &&4468                // omit onVnodeXXX hooks4469                !isReservedProp(name)) {4470                hasHydrationEventBinding = true;4471            }4472            if (isEventHandler && isReservedProp(name)) {4473                hasVnodeHook = true;4474            }4475            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4476                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4477                    value.type === 8 /* COMPOUND_EXPRESSION */) &&4478                    getConstantType(value, context) > 0)) {4479                // skip if the prop is a cached handler or has constant value4480                return;4481            }4482            if (name === 'ref') {4483                hasRef = true;4484            }4485            else if (name === 'class') {4486                hasClassBinding = true;4487            }4488            else if (name === 'style') {4489                hasStyleBinding = true;4490            }4491            else if (name !== 'key' && !dynamicPropNames.includes(name)) {4492                dynamicPropNames.push(name);4493            }4494            // treat the dynamic class and style binding of the component as dynamic props4495            if (isComponent &&4496                (name === 'class' || name === 'style') &&4497                !dynamicPropNames.includes(name)) {4498                dynamicPropNames.push(name);4499            }4500        }4501        else {4502            hasDynamicKeys = true;4503        }4504    };4505    for (let i = 0; i < props.length; i++) {4506        // static attribute4507        const prop = props[i];4508        if (prop.type === 6 /* ATTRIBUTE */) {4509            const { loc, name, value } = prop;4510            let isStatic = true;4511            if (name === 'ref') {4512                hasRef = true;4513                if (context.scopes.vFor > 0) {4514                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4515                }4516            }4517            // skip is on <component>, or is="vue:xxx"4518            if (name === 'is' &&4519                (isComponentTag(tag) ||4520                    (value && value.content.startsWith('vue:')) ||4521                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4522                continue;4523            }4524            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));4525        }4526        else {4527            // directives4528            const { name, arg, exp, loc } = prop;4529            const isVBind = name === 'bind';4530            const isVOn = name === 'on';4531            // skip v-slot - it is handled by its dedicated transform.4532            if (name === 'slot') {4533                if (!isComponent) {4534                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4535                }4536                continue;4537            }4538            // skip v-once/v-memo - they are handled by dedicated transforms.4539            if (name === 'once' || name === 'memo') {4540                continue;4541            }4542            // skip v-is and :is on <component>4543            if (name === 'is' ||4544                (isVBind &&4545                    isStaticArgOf(arg, 'is') &&4546                    (isComponentTag(tag) ||4547                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4548                continue;4549            }4550            // skip v-on in SSR compilation4551            if (isVOn && ssr) {4552                continue;4553            }4554            if (4555            // #938: elements with dynamic keys should be forced into blocks4556            (isVBind && isStaticArgOf(arg, 'key')) ||4557                // inline before-update hooks need to force block so that it is invoked4558                // before children4559                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {4560                shouldUseBlock = true;4561            }4562            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {4563                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4564            }4565            // special case for v-bind and v-on with no argument4566            if (!arg && (isVBind || isVOn)) {4567                hasDynamicKeys = true;4568                if (exp) {4569                    if (properties.length) {4570                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4571                        properties = [];4572                    }4573                    if (isVBind) {4574                        {4575                            // 2.x v-bind object order compat4576                            if ((process.env.NODE_ENV !== 'production')) {4577                                const hasOverridableKeys = mergeArgs.some(arg => {4578                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4579                                        return arg.properties.some(({ key }) => {4580                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4581                                                !key.isStatic) {4582                                                return true;4583                                            }4584                                            return (key.content !== 'class' &&4585                                                key.content !== 'style' &&4586                                                !isOn(key.content));4587                                        });4588                                    }4589                                    else {4590                                        // dynamic expression4591                                        return true;4592                                    }4593                                });4594                                if (hasOverridableKeys) {4595                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4596                                }4597                            }4598                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4599                                mergeArgs.unshift(exp);4600                                continue;4601                            }4602                        }4603                        mergeArgs.push(exp);4604                    }4605                    else {4606                        // v-on="obj" -> toHandlers(obj)4607                        mergeArgs.push({4608                            type: 14 /* JS_CALL_EXPRESSION */,4609                            loc,4610                            callee: context.helper(TO_HANDLERS),4611                            arguments: [exp]4612                        });4613                    }4614                }4615                else {4616                    context.onError(createCompilerError(isVBind4617                        ? 34 /* X_V_BIND_NO_EXPRESSION */4618                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));4619                }4620                continue;4621            }4622            const directiveTransform = context.directiveTransforms[name];4623            if (directiveTransform) {4624                // has built-in directive transform.4625                const { props, needRuntime } = directiveTransform(prop, node, context);4626                !ssr && props.forEach(analyzePatchFlag);4627                properties.push(...props);4628                if (needRuntime) {4629                    runtimeDirectives.push(prop);4630                    if (isSymbol(needRuntime)) {4631                        directiveImportMap.set(prop, needRuntime);4632                    }4633                }4634            }4635            else if (!isBuiltInDirective(name)) {4636                // no built-in transform, this is a user custom directive.4637                runtimeDirectives.push(prop);4638                // custom dirs may use beforeUpdate so they need to force blocks4639                // to ensure before-update gets called before children update4640                if (hasChildren) {4641                    shouldUseBlock = true;4642                }4643            }4644        }4645    }4646    let propsExpression = undefined;4647    // has v-bind="object" or v-on="object", wrap with mergeProps4648    if (mergeArgs.length) {4649        if (properties.length) {4650            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4651        }4652        if (mergeArgs.length > 1) {4653            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4654        }4655        else {4656            // single v-bind with nothing else - no need for a mergeProps call4657            propsExpression = mergeArgs[0];4658        }4659    }4660    else if (properties.length) {4661        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4662    }4663    // patchFlag analysis4664    if (hasDynamicKeys) {4665        patchFlag |= 16 /* FULL_PROPS */;4666    }4667    else {4668        if (hasClassBinding && !isComponent) {4669            patchFlag |= 2 /* CLASS */;4670        }4671        if (hasStyleBinding && !isComponent) {4672            patchFlag |= 4 /* STYLE */;4673        }4674        if (dynamicPropNames.length) {4675            patchFlag |= 8 /* PROPS */;4676        }4677        if (hasHydrationEventBinding) {4678            patchFlag |= 32 /* HYDRATE_EVENTS */;4679        }4680    }4681    if (!shouldUseBlock &&4682        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4683        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4684        patchFlag |= 512 /* NEED_PATCH */;4685    }4686    // pre-normalize props, SSR is skipped for now4687    if (!context.inSSR && propsExpression) {4688        switch (propsExpression.type) {4689            case 15 /* JS_OBJECT_EXPRESSION */:4690                // means that there is no v-bind,4691                // but still need to deal with dynamic key binding4692                let classKeyIndex = -1;4693                let styleKeyIndex = -1;4694                let hasDynamicKey = false;4695                for (let i = 0; i < propsExpression.properties.length; i++) {4696                    const key = propsExpression.properties[i].key;4697                    if (isStaticExp(key)) {4698                        if (key.content === 'class') {4699                            classKeyIndex = i;4700                        }4701                        else if (key.content === 'style') {4702                            styleKeyIndex = i;4703                        }4704                    }4705                    else if (!key.isHandlerKey) {4706                        hasDynamicKey = true;4707                    }4708                }4709                const classProp = propsExpression.properties[classKeyIndex];4710                const styleProp = propsExpression.properties[styleKeyIndex];4711                // no dynamic key4712                if (!hasDynamicKey) {4713                    if (classProp && !isStaticExp(classProp.value)) {4714                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4715                    }4716                    if (styleProp &&4717                        !isStaticExp(styleProp.value) &&4718                        // the static style is compiled into an object,4719                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding4720                        (hasStyleBinding ||4721                            // v-bind:style and style both exist,4722                            // v-bind:style with static literal object4723                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4724                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4725                    }4726                }4727                else {4728                    // dynamic key binding, wrap with `normalizeProps`4729                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4730                }4731                break;4732            case 14 /* JS_CALL_EXPRESSION */:4733                // mergeProps call, do nothing4734                break;4735            default:4736                // single v-bind4737                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4738                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4739                        propsExpression4740                    ])4741                ]);4742                break;4743        }4744    }4745    return {4746        props: propsExpression,4747        directives: runtimeDirectives,4748        patchFlag,4749        dynamicPropNames,4750        shouldUseBlock4751    };4752}4753// Dedupe props in an object literal.4754// Literal duplicated attributes would have been warned during the parse phase,4755// however, it's possible to encounter duplicated `onXXX` handlers with different4756// modifiers. We also need to merge static and dynamic class / style attributes.4757// - onXXX handlers / style: merge into array4758// - class: merge into single expression with concatenation4759function dedupeProperties(properties) {4760    const knownProps = new Map();4761    const deduped = [];4762    for (let i = 0; i < properties.length; i++) {4763        const prop = properties[i];4764        // dynamic keys are always allowed4765        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4766            deduped.push(prop);4767            continue;4768        }4769        const name = prop.key.content;4770        const existing = knownProps.get(name);4771        if (existing) {4772            if (name === 'style' || name === 'class' || isOn(name)) {4773                mergeAsArray(existing, prop);4774            }4775            // unexpected duplicate, should have emitted error during parse4776        }4777        else {4778            knownProps.set(name, prop);4779            deduped.push(prop);4780        }4781    }4782    return deduped;4783}4784function mergeAsArray(existing, incoming) {4785    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4786        existing.value.elements.push(incoming.value);4787    }4788    else {4789        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4790    }4791}4792function buildDirectiveArgs(dir, context) {4793    const dirArgs = [];4794    const runtime = directiveImportMap.get(dir);4795    if (runtime) {4796        // built-in directive with runtime4797        dirArgs.push(context.helperString(runtime));4798    }4799    else {4800        {4801            // inject statement for resolving directive4802            context.helper(RESOLVE_DIRECTIVE);4803            context.directives.add(dir.name);4804            dirArgs.push(toValidAssetId(dir.name, `directive`));4805        }4806    }4807    const { loc } = dir;4808    if (dir.exp)4809        dirArgs.push(dir.exp);4810    if (dir.arg) {4811        if (!dir.exp) {4812            dirArgs.push(`void 0`);4813        }4814        dirArgs.push(dir.arg);4815    }4816    if (Object.keys(dir.modifiers).length) {4817        if (!dir.arg) {4818            if (!dir.exp) {4819                dirArgs.push(`void 0`);4820            }4821            dirArgs.push(`void 0`);4822        }4823        const trueExpression = createSimpleExpression(`true`, false, loc);4824        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4825    }4826    return createArrayExpression(dirArgs, dir.loc);4827}4828function stringifyDynamicPropNames(props) {4829    let propsNamesString = `[`;4830    for (let i = 0, l = props.length; i < l; i++) {4831        propsNamesString += JSON.stringify(props[i]);4832        if (i < l - 1)4833            propsNamesString += ', ';4834    }4835    return propsNamesString + `]`;4836}4837function isComponentTag(tag) {4838    return tag === 'component' || tag === 'Component';4839}4840(process.env.NODE_ENV !== 'production')4841    ? Object.freeze({})4842    : {};4843(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];4844const cacheStringFunction = (fn) => {4845    const cache = Object.create(null);4846    return ((str) => {4847        const hit = cache[str];4848        return hit || (cache[str] = fn(str));4849    });4850};4851const camelizeRE = /-(\w)/g;4852/**4853 * @private4854 */4855const camelize = cacheStringFunction((str) => {4856    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));4857});4858const transformSlotOutlet = (node, context) => {4859    if (isSlotOutlet(node)) {4860        const { children, loc } = node;4861        const { slotName, slotProps } = processSlotOutlet(node, context);4862        const slotArgs = [4863            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4864            slotName,4865            '{}',4866            'undefined',4867            'true'4868        ];4869        let expectedLen = 2;4870        if (slotProps) {4871            slotArgs[2] = slotProps;4872            expectedLen = 3;4873        }4874        if (children.length) {4875            slotArgs[3] = createFunctionExpression([], children, false, false, loc);4876            expectedLen = 4;4877        }4878        if (context.scopeId && !context.slotted) {4879            expectedLen = 5;4880        }4881        slotArgs.splice(expectedLen); // remove unused arguments4882        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4883    }4884};4885function processSlotOutlet(node, context) {4886    let slotName = `"default"`;4887    let slotProps = undefined;4888    const nonNameProps = [];4889    for (let i = 0; i < node.props.length; i++) {4890        const p = node.props[i];4891        if (p.type === 6 /* ATTRIBUTE */) {4892            if (p.value) {4893                if (p.name === 'name') {4894                    slotName = JSON.stringify(p.value.content);4895                }4896                else {4897                    p.name = camelize(p.name);4898                    nonNameProps.push(p);4899                }4900            }4901        }4902        else {4903            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {4904                if (p.exp)4905                    slotName = p.exp;4906            }4907            else {4908                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4909                    p.arg.content = camelize(p.arg.content);4910                }4911                nonNameProps.push(p);4912            }4913        }4914    }4915    if (nonNameProps.length > 0) {4916        const { props, directives } = buildProps(node, context, nonNameProps);4917        slotProps = props;4918        if (directives.length) {4919            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4920        }4921    }4922    return {4923        slotName,4924        slotProps4925    };4926}4927const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4928const transformOn = (dir, node, context, augmentor) => {4929    const { loc, modifiers, arg } = dir;4930    if (!dir.exp && !modifiers.length) {4931        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4932    }4933    let eventName;4934    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4935        if (arg.isStatic) {4936            let rawName = arg.content;4937            // TODO deprecate @vnodeXXX usage4938            if (rawName.startsWith('vue:')) {4939                rawName = `vnode-${rawName.slice(4)}`;4940            }4941            // for all event listeners, auto convert it to camelCase. See issue #22494942            eventName = createSimpleExpression(toHandlerKey(camelize$1(rawName)), true, arg.loc);4943        }4944        else {4945            // #23884946            eventName = createCompoundExpression([4947                `${context.helperString(TO_HANDLER_KEY)}(`,4948                arg,4949                `)`4950            ]);4951        }4952    }4953    else {4954        // already a compound expression.4955        eventName = arg;4956        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4957        eventName.children.push(`)`);4958    }4959    // handler processing4960    let exp = dir.exp;4961    if (exp && !exp.content.trim()) {4962        exp = undefined;4963    }4964    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4965    if (exp) {4966        const isMemberExp = isMemberExpression(exp.content);4967        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4968        const hasMultipleStatements = exp.content.includes(`;`);4969        if ((process.env.NODE_ENV !== 'production') && true) {4970            validateBrowserExpression(exp, context, false, hasMultipleStatements);4971        }4972        if (isInlineStatement || (shouldCache && isMemberExp)) {4973            // wrap inline statement in a function expression4974            exp = createCompoundExpression([4975                `${isInlineStatement4976                    ? `$event`4977                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4978                exp,4979                hasMultipleStatements ? `}` : `)`4980            ]);4981        }4982    }4983    let ret = {4984        props: [4985            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4986        ]4987    };4988    // apply extended compiler augmentor4989    if (augmentor) {4990        ret = augmentor(ret);4991    }4992    if (shouldCache) {4993        // cache handlers so that it's always the same handler being passed down.4994        // this avoids unnecessary re-renders when users use inline handlers on4995        // components.4996        ret.props[0].value = context.cache(ret.props[0].value);4997    }4998    // mark the key as handler for props normalization check4999    ret.props.forEach(p => (p.key.isHandlerKey = true));5000    return ret;5001};5002// v-bind without arg is handled directly in ./transformElements.ts due to it affecting5003// codegen for the entire props object. This transform here is only for v-bind5004// *with* args.5005const transformBind = (dir, _node, context) => {5006    const { exp, modifiers, loc } = dir;5007    const arg = dir.arg;5008    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {5009        arg.children.unshift(`(`);5010        arg.children.push(`) || ""`);5011    }5012    else if (!arg.isStatic) {5013        arg.content = `${arg.content} || ""`;5014    }5015    // .sync is replaced by v-model:arg5016    if (modifiers.includes('camel')) {5017        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5018            if (arg.isStatic) {5019                arg.content = camelize$1(arg.content);5020            }5021            else {5022                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;5023            }5024        }5025        else {5026            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);5027            arg.children.push(`)`);5028        }5029    }5030    if (!context.inSSR) {5031        if (modifiers.includes('prop')) {5032            injectPrefix(arg, '.');5033        }5034        if (modifiers.includes('attr')) {5035            injectPrefix(arg, '^');5036        }5037    }5038    if (!exp ||5039        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {5040        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));5041        return {5042            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]5043        };5044    }5045    return {5046        props: [createObjectProperty(arg, exp)]5047    };5048};5049const injectPrefix = (arg, prefix) => {5050    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5051        if (arg.isStatic) {5052            arg.content = prefix + arg.content;5053        }5054        else {5055            arg.content = `\`${prefix}\${${arg.content}}\``;5056        }5057    }5058    else {5059        arg.children.unshift(`'${prefix}' + (`);5060        arg.children.push(`)`);5061    }5062};5063// Merge adjacent text nodes and expressions into a single expression5064// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.5065const transformText = (node, context) => {5066    if (node.type === 0 /* ROOT */ ||5067        node.type === 1 /* ELEMENT */ ||5068        node.type === 11 /* FOR */ ||5069        node.type === 10 /* IF_BRANCH */) {5070        // perform the transform on node exit so that all expressions have already5071        // been processed.5072        return () => {5073            const children = node.children;5074            let currentContainer = undefined;5075            let hasText = false;5076            for (let i = 0; i < children.length; i++) {5077                const child = children[i];5078                if (isText(child)) {5079                    hasText = true;5080                    for (let j = i + 1; j < children.length; j++) {5081                        const next = children[j];5082                        if (isText(next)) {5083                            if (!currentContainer) {5084                                currentContainer = children[i] = {5085                                    type: 8 /* COMPOUND_EXPRESSION */,5086                                    loc: child.loc,5087                                    children: [child]5088                                };5089                            }5090                            // merge adjacent text node into current5091                            currentContainer.children.push(` + `, next);5092                            children.splice(j, 1);5093                            j--;5094                        }5095                        else {5096                            currentContainer = undefined;5097                            break;5098                        }5099                    }5100                }5101            }5102            if (!hasText ||5103                // if this is a plain element with a single text child, leave it5104                // as-is since the runtime has dedicated fast path for this by directly5105                // setting textContent of the element.5106                // for component root it's always normalized anyway.5107                (children.length === 1 &&5108                    (node.type === 0 /* ROOT */ ||5109                        (node.type === 1 /* ELEMENT */ &&5110                            node.tagType === 0 /* ELEMENT */ &&5111                            // #37565112                            // custom directives can potentially add DOM elements arbitrarily,5113                            // we need to avoid setting textContent of the element at runtime5114                            // to avoid accidentally overwriting the DOM elements added5115                            // by the user through custom directives.5116                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&5117                                !context.directiveTransforms[p.name]) &&5118                            // in compat mode, <template> tags with no special directives5119                            // will be rendered as a fragment so its children must be5120                            // converted into vnodes.5121                            !(node.tag === 'template'))))) {5122                return;5123            }5124            // pre-convert text nodes into createTextVNode(text) calls to avoid5125            // runtime normalization.5126            for (let i = 0; i < children.length; i++) {5127                const child = children[i];5128                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {5129                    const callArgs = [];5130                    // createTextVNode defaults to single whitespace, so if it is a5131                    // single space the code could be an empty call to save bytes.5132                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {5133                        callArgs.push(child);5134                    }5135                    // mark dynamic text with flag so it gets patched inside a block5136                    if (!context.ssr &&5137                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {5138                        callArgs.push(1 /* TEXT */ +5139                            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[1 /* TEXT */]} */` : ``));5140                    }5141                    children[i] = {5142                        type: 12 /* TEXT_CALL */,5143                        content: child,5144                        loc: child.loc,5145                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)5146                    };5147                }5148            }5149        };5150    }5151};5152const seen = new WeakSet();5153const transformOnce = (node, context) => {5154    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {5155        if (seen.has(node) || context.inVOnce) {5156            return;5157        }5158        seen.add(node);5159        context.inVOnce = true;5160        context.helper(SET_BLOCK_TRACKING);5161        return () => {5162            context.inVOnce = false;5163            const cur = context.currentNode;5164            if (cur.codegenNode) {5165                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);5166            }5167        };5168    }5169};5170const transformModel = (dir, node, context) => {5171    const { exp, arg } = dir;5172    if (!exp) {5173        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));5174        return createTransformProps();5175    }5176    const rawExp = exp.loc.source;5177    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;5178    const maybeRef = !true    /* SETUP_CONST */;5179    if (!expString.trim() ||5180        (!isMemberExpression(expString) && !maybeRef)) {5181        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));5182        return createTransformProps();5183    }5184    const propName = arg ? arg : createSimpleExpression('modelValue', true);5185    const eventName = arg5186        ? isStaticExp(arg)5187            ? `onUpdate:${arg.content}`5188            : createCompoundExpression(['"onUpdate:" + ', arg])5189        : `onUpdate:modelValue`;5190    let assignmentExp;5191    const eventArg = context.isTS ? `($event: any)` : `$event`;5192    {5193        assignmentExp = createCompoundExpression([5194            `${eventArg} => ((`,5195            exp,5196            `) = $event)`5197        ]);5198    }5199    const props = [5200        // modelValue: foo5201        createObjectProperty(propName, dir.exp),5202        // "onUpdate:modelValue": $event => (foo = $event)5203        createObjectProperty(eventName, assignmentExp)5204    ];5205    // modelModifiers: { foo: true, "bar-baz": true }5206    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {5207        const modifiers = dir.modifiers5208            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)5209            .join(`, `);5210        const modifiersKey = arg5211            ? isStaticExp(arg)5212                ? `${arg.content}Modifiers`5213                : createCompoundExpression([arg, ' + "Modifiers"'])5214            : `modelModifiers`;5215        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));5216    }5217    return createTransformProps(props);5218};5219function createTransformProps(props = []) {5220    return { props };5221}5222const validDivisionCharRE = /[\w).+\-_$\]]/;5223const transformFilter = (node, context) => {5224    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {5225        return;5226    }5227    if (node.type === 5 /* INTERPOLATION */) {5228        // filter rewrite is applied before expression transform so only5229        // simple expressions are possible at this stage5230        rewriteFilter(node.content, context);5231    }5232    if (node.type === 1 /* ELEMENT */) {5233        node.props.forEach((prop) => {5234            if (prop.type === 7 /* DIRECTIVE */ &&5235                prop.name !== 'for' &&5236                prop.exp) {5237                rewriteFilter(prop.exp, context);5238            }...compiler-dom.global.js
Source:compiler-dom.global.js  
...941      else {942          return value;943      }944  }945  function isCompatEnabled(key, context) {946      const mode = getCompatValue('MODE', context);947      const value = getCompatValue(key, context);948      // in v3 mode, only enable if explicitly set to true949      // otherwise enable for any non-false value950      return mode === 3 ? value === true : value !== false;951  }952  function checkCompatEnabled(key, context, loc, ...args) {953      const enabled = isCompatEnabled(key, context);954      if (enabled) {955          warnDeprecation(key, context, loc, ...args);956      }957      return enabled;958  }959  function warnDeprecation(key, context, loc, ...args) {960      const val = getCompatValue(key, context);961      if (val === 'suppress-warning') {962          return;963      }964      const { message, link } = deprecationData[key];965      const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;966      const err = new SyntaxError(msg);967      err.code = key;968      if (loc)969          err.loc = loc;970      context.onWarn(err);971  }972  // The default decoder only provides escapes for characters reserved as part of973  // the template syntax, and is only used if the custom renderer did not provide974  // a platform-specific decoder.975  const decodeRE = /&(gt|lt|amp|apos|quot);/g;976  const decodeMap = {977      gt: '>',978      lt: '<',979      amp: '&',980      apos: "'",981      quot: '"'982  };983  const defaultParserOptions = {984      delimiters: [`{{`, `}}`],985      getNamespace: () => 0 /* HTML */,986      getTextMode: () => 0 /* DATA */,987      isVoidTag: NO,988      isPreTag: NO,989      isCustomElement: NO,990      decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),991      onError: defaultOnError,992      onWarn: defaultOnWarn,993      comments: true994  };995  function baseParse(content, options = {}) {996      const context = createParserContext(content, options);997      const start = getCursor(context);998      return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));999  }1000  function createParserContext(content, rawOptions) {1001      const options = extend({}, defaultParserOptions);1002      let key;1003      for (key in rawOptions) {1004          // @ts-ignore1005          options[key] =1006              rawOptions[key] === undefined1007                  ? defaultParserOptions[key]1008                  : rawOptions[key];1009      }1010      return {1011          options,1012          column: 1,1013          line: 1,1014          offset: 0,1015          originalSource: content,1016          source: content,1017          inPre: false,1018          inVPre: false,1019          onWarn: options.onWarn1020      };1021  }1022  function parseChildren(context, mode, ancestors) {1023      const parent = last(ancestors);1024      const ns = parent ? parent.ns : 0 /* HTML */;1025      const nodes = [];1026      while (!isEnd(context, mode, ancestors)) {1027          const s = context.source;1028          let node = undefined;1029          if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {1030              if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {1031                  // '{{'1032                  node = parseInterpolation(context, mode);1033              }1034              else if (mode === 0 /* DATA */ && s[0] === '<') {1035                  // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state1036                  if (s.length === 1) {1037                      emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);1038                  }1039                  else if (s[1] === '!') {1040                      // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state1041                      if (startsWith(s, '<!--')) {1042                          node = parseComment(context);1043                      }1044                      else if (startsWith(s, '<!DOCTYPE')) {1045                          // Ignore DOCTYPE by a limitation.1046                          node = parseBogusComment(context);1047                      }1048                      else if (startsWith(s, '<![CDATA[')) {1049                          if (ns !== 0 /* HTML */) {1050                              node = parseCDATA(context, ancestors);1051                          }1052                          else {1053                              emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);1054                              node = parseBogusComment(context);1055                          }1056                      }1057                      else {1058                          emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);1059                          node = parseBogusComment(context);1060                      }1061                  }1062                  else if (s[1] === '/') {1063                      // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state1064                      if (s.length === 2) {1065                          emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);1066                      }1067                      else if (s[2] === '>') {1068                          emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);1069                          advanceBy(context, 3);1070                          continue;1071                      }1072                      else if (/[a-z]/i.test(s[2])) {1073                          emitError(context, 23 /* X_INVALID_END_TAG */);1074                          parseTag(context, 1 /* End */, parent);1075                          continue;1076                      }1077                      else {1078                          emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);1079                          node = parseBogusComment(context);1080                      }1081                  }1082                  else if (/[a-z]/i.test(s[1])) {1083                      node = parseElement(context, ancestors);1084                      // 2.x <template> with no directive compat1085                      if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&1086                          node &&1087                          node.tag === 'template' &&1088                          !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&1089                              isSpecialTemplateDirective(p.name))) {1090                          warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);1091                          node = node.children;1092                      }1093                  }1094                  else if (s[1] === '?') {1095                      emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);1096                      node = parseBogusComment(context);1097                  }1098                  else {1099                      emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);1100                  }1101              }1102          }1103          if (!node) {1104              node = parseText(context, mode);1105          }1106          if (isArray(node)) {1107              for (let i = 0; i < node.length; i++) {1108                  pushNode(nodes, node[i]);1109              }1110          }1111          else {1112              pushNode(nodes, node);1113          }1114      }1115      // Whitespace handling strategy like v21116      let removedWhitespace = false;1117      if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {1118          const shouldCondense = context.options.whitespace !== 'preserve';1119          for (let i = 0; i < nodes.length; i++) {1120              const node = nodes[i];1121              if (!context.inPre && node.type === 2 /* TEXT */) {1122                  if (!/[^\t\r\n\f ]/.test(node.content)) {1123                      const prev = nodes[i - 1];1124                      const next = nodes[i + 1];1125                      // Remove if:1126                      // - the whitespace is the first or last node, or:1127                      // - (condense mode) the whitespace is adjacent to a comment, or:1128                      // - (condense mode) the whitespace is between two elements AND contains newline1129                      if (!prev ||1130                          !next ||1131                          (shouldCondense &&1132                              (prev.type === 3 /* COMMENT */ ||1133                                  next.type === 3 /* COMMENT */ ||1134                                  (prev.type === 1 /* ELEMENT */ &&1135                                      next.type === 1 /* ELEMENT */ &&1136                                      /[\r\n]/.test(node.content))))) {1137                          removedWhitespace = true;1138                          nodes[i] = null;1139                      }1140                      else {1141                          // Otherwise, the whitespace is condensed into a single space1142                          node.content = ' ';1143                      }1144                  }1145                  else if (shouldCondense) {1146                      // in condense mode, consecutive whitespaces in text are condensed1147                      // down to a single space.1148                      node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1149                  }1150              }1151              // Remove comment nodes if desired by configuration.1152              else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1153                  removedWhitespace = true;1154                  nodes[i] = null;1155              }1156          }1157          if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1158              // remove leading newline per html spec1159              // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1160              const first = nodes[0];1161              if (first && first.type === 2 /* TEXT */) {1162                  first.content = first.content.replace(/^\r?\n/, '');1163              }1164          }1165      }1166      return removedWhitespace ? nodes.filter(Boolean) : nodes;1167  }1168  function pushNode(nodes, node) {1169      if (node.type === 2 /* TEXT */) {1170          const prev = last(nodes);1171          // Merge if both this and the previous node are text and those are1172          // consecutive. This happens for cases like "a < b".1173          if (prev &&1174              prev.type === 2 /* TEXT */ &&1175              prev.loc.end.offset === node.loc.start.offset) {1176              prev.content += node.content;1177              prev.loc.end = node.loc.end;1178              prev.loc.source += node.loc.source;1179              return;1180          }1181      }1182      nodes.push(node);1183  }1184  function parseCDATA(context, ancestors) {1185      advanceBy(context, 9);1186      const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1187      if (context.source.length === 0) {1188          emitError(context, 6 /* EOF_IN_CDATA */);1189      }1190      else {1191          advanceBy(context, 3);1192      }1193      return nodes;1194  }1195  function parseComment(context) {1196      const start = getCursor(context);1197      let content;1198      // Regular comment.1199      const match = /--(\!)?>/.exec(context.source);1200      if (!match) {1201          content = context.source.slice(4);1202          advanceBy(context, context.source.length);1203          emitError(context, 7 /* EOF_IN_COMMENT */);1204      }1205      else {1206          if (match.index <= 3) {1207              emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1208          }1209          if (match[1]) {1210              emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1211          }1212          content = context.source.slice(4, match.index);1213          // Advancing with reporting nested comments.1214          const s = context.source.slice(0, match.index);1215          let prevIndex = 1, nestedIndex = 0;1216          while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1217              advanceBy(context, nestedIndex - prevIndex + 1);1218              if (nestedIndex + 4 < s.length) {1219                  emitError(context, 16 /* NESTED_COMMENT */);1220              }1221              prevIndex = nestedIndex + 1;1222          }1223          advanceBy(context, match.index + match[0].length - prevIndex + 1);1224      }1225      return {1226          type: 3 /* COMMENT */,1227          content,1228          loc: getSelection(context, start)1229      };1230  }1231  function parseBogusComment(context) {1232      const start = getCursor(context);1233      const contentStart = context.source[1] === '?' ? 1 : 2;1234      let content;1235      const closeIndex = context.source.indexOf('>');1236      if (closeIndex === -1) {1237          content = context.source.slice(contentStart);1238          advanceBy(context, context.source.length);1239      }1240      else {1241          content = context.source.slice(contentStart, closeIndex);1242          advanceBy(context, closeIndex + 1);1243      }1244      return {1245          type: 3 /* COMMENT */,1246          content,1247          loc: getSelection(context, start)1248      };1249  }1250  function parseElement(context, ancestors) {1251      // Start tag.1252      const wasInPre = context.inPre;1253      const wasInVPre = context.inVPre;1254      const parent = last(ancestors);1255      const element = parseTag(context, 0 /* Start */, parent);1256      const isPreBoundary = context.inPre && !wasInPre;1257      const isVPreBoundary = context.inVPre && !wasInVPre;1258      if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1259          // #4030 self-closing <pre> tag1260          if (isPreBoundary) {1261              context.inPre = false;1262          }1263          if (isVPreBoundary) {1264              context.inVPre = false;1265          }1266          return element;1267      }1268      // Children.1269      ancestors.push(element);1270      const mode = context.options.getTextMode(element, parent);1271      const children = parseChildren(context, mode, ancestors);1272      ancestors.pop();1273      // 2.x inline-template compat1274      {1275          const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1276          if (inlineTemplateProp &&1277              checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1278              const loc = getSelection(context, element.loc.end);1279              inlineTemplateProp.value = {1280                  type: 2 /* TEXT */,1281                  content: loc.source,1282                  loc1283              };1284          }1285      }1286      element.children = children;1287      // End tag.1288      if (startsWithEndTagOpen(context.source, element.tag)) {1289          parseTag(context, 1 /* End */, parent);1290      }1291      else {1292          emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1293          if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1294              const first = children[0];1295              if (first && startsWith(first.loc.source, '<!--')) {1296                  emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1297              }1298          }1299      }1300      element.loc = getSelection(context, element.loc.start);1301      if (isPreBoundary) {1302          context.inPre = false;1303      }1304      if (isVPreBoundary) {1305          context.inVPre = false;1306      }1307      return element;1308  }1309  const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1310  function parseTag(context, type, parent) {1311      // Tag open.1312      const start = getCursor(context);1313      const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1314      const tag = match[1];1315      const ns = context.options.getNamespace(tag, parent);1316      advanceBy(context, match[0].length);1317      advanceSpaces(context);1318      // save current state in case we need to re-parse attributes with v-pre1319      const cursor = getCursor(context);1320      const currentSource = context.source;1321      // check <pre> tag1322      if (context.options.isPreTag(tag)) {1323          context.inPre = true;1324      }1325      // Attributes.1326      let props = parseAttributes(context, type);1327      // check v-pre1328      if (type === 0 /* Start */ &&1329          !context.inVPre &&1330          props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1331          context.inVPre = true;1332          // reset context1333          extend(context, cursor);1334          context.source = currentSource;1335          // re-parse attrs and filter out v-pre itself1336          props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1337      }1338      // Tag close.1339      let isSelfClosing = false;1340      if (context.source.length === 0) {1341          emitError(context, 9 /* EOF_IN_TAG */);1342      }1343      else {1344          isSelfClosing = startsWith(context.source, '/>');1345          if (type === 1 /* End */ && isSelfClosing) {1346              emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1347          }1348          advanceBy(context, isSelfClosing ? 2 : 1);1349      }1350      if (type === 1 /* End */) {1351          return;1352      }1353      // 2.x deprecation checks1354      if (isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1355          let hasIf = false;1356          let hasFor = false;1357          for (let i = 0; i < props.length; i++) {1358              const p = props[i];1359              if (p.type === 7 /* DIRECTIVE */) {1360                  if (p.name === 'if') {1361                      hasIf = true;1362                  }1363                  else if (p.name === 'for') {1364                      hasFor = true;1365                  }1366              }1367              if (hasIf && hasFor) {1368                  warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1369                  break;1370              }1371          }1372      }1373      let tagType = 0 /* ELEMENT */;1374      if (!context.inVPre) {1375          if (tag === 'slot') {1376              tagType = 2 /* SLOT */;1377          }1378          else if (tag === 'template') {1379              if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1380                  tagType = 3 /* TEMPLATE */;1381              }1382          }1383          else if (isComponent(tag, props, context)) {1384              tagType = 1 /* COMPONENT */;1385          }1386      }1387      return {1388          type: 1 /* ELEMENT */,1389          ns,1390          tag,1391          tagType,1392          props,1393          isSelfClosing,1394          children: [],1395          loc: getSelection(context, start),1396          codegenNode: undefined // to be created during transform phase1397      };1398  }1399  function isComponent(tag, props, context) {1400      const options = context.options;1401      if (options.isCustomElement(tag)) {1402          return false;1403      }1404      if (tag === 'component' ||1405          /^[A-Z]/.test(tag) ||1406          isCoreComponent(tag) ||1407          (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1408          (options.isNativeTag && !options.isNativeTag(tag))) {1409          return true;1410      }1411      // at this point the tag should be a native tag, but check for potential "is"1412      // casting1413      for (let i = 0; i < props.length; i++) {1414          const p = props[i];1415          if (p.type === 6 /* ATTRIBUTE */) {1416              if (p.name === 'is' && p.value) {1417                  if (p.value.content.startsWith('vue:')) {1418                      return true;1419                  }1420                  else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1421                      return true;1422                  }1423              }1424          }1425          else {1426              // directive1427              // v-is (TODO Deprecate)1428              if (p.name === 'is') {1429                  return true;1430              }1431              else if (1432              // :is on plain element - only treat as component in compat mode1433              p.name === 'bind' &&1434                  isStaticArgOf(p.arg, 'is') &&1435                  true &&1436                  checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1437                  return true;1438              }1439          }1440      }1441  }1442  function parseAttributes(context, type) {1443      const props = [];1444      const attributeNames = new Set();1445      while (context.source.length > 0 &&1446          !startsWith(context.source, '>') &&1447          !startsWith(context.source, '/>')) {1448          if (startsWith(context.source, '/')) {1449              emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1450              advanceBy(context, 1);1451              advanceSpaces(context);1452              continue;1453          }1454          if (type === 1 /* End */) {1455              emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1456          }1457          const attr = parseAttribute(context, attributeNames);1458          // Trim whitespace between class1459          // https://github.com/vuejs/vue-next/issues/42511460          if (attr.type === 6 /* ATTRIBUTE */ &&1461              attr.value &&1462              attr.name === 'class') {1463              attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1464          }1465          if (type === 0 /* Start */) {1466              props.push(attr);1467          }1468          if (/^[^\t\r\n\f />]/.test(context.source)) {1469              emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1470          }1471          advanceSpaces(context);1472      }1473      return props;1474  }1475  function parseAttribute(context, nameSet) {1476      // Name.1477      const start = getCursor(context);1478      const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1479      const name = match[0];1480      if (nameSet.has(name)) {1481          emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1482      }1483      nameSet.add(name);1484      if (name[0] === '=') {1485          emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1486      }1487      {1488          const pattern = /["'<]/g;1489          let m;1490          while ((m = pattern.exec(name))) {1491              emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1492          }1493      }1494      advanceBy(context, name.length);1495      // Value1496      let value = undefined;1497      if (/^[\t\r\n\f ]*=/.test(context.source)) {1498          advanceSpaces(context);1499          advanceBy(context, 1);1500          advanceSpaces(context);1501          value = parseAttributeValue(context);1502          if (!value) {1503              emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1504          }1505      }1506      const loc = getSelection(context, start);1507      if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1508          const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1509          let isPropShorthand = startsWith(name, '.');1510          let dirName = match[1] ||1511              (isPropShorthand || startsWith(name, ':')1512                  ? 'bind'1513                  : startsWith(name, '@')1514                      ? 'on'1515                      : 'slot');1516          let arg;1517          if (match[2]) {1518              const isSlot = dirName === 'slot';1519              const startOffset = name.lastIndexOf(match[2]);1520              const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1521              let content = match[2];1522              let isStatic = true;1523              if (content.startsWith('[')) {1524                  isStatic = false;1525                  if (!content.endsWith(']')) {1526                      emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1527                      content = content.slice(1);1528                  }1529                  else {1530                      content = content.slice(1, content.length - 1);1531                  }1532              }1533              else if (isSlot) {1534                  // #1241 special case for v-slot: vuetify relies extensively on slot1535                  // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1536                  // supports such usage so we are keeping it consistent with 2.x.1537                  content += match[3] || '';1538              }1539              arg = {1540                  type: 4 /* SIMPLE_EXPRESSION */,1541                  content,1542                  isStatic,1543                  constType: isStatic1544                      ? 3 /* CAN_STRINGIFY */1545                      : 0 /* NOT_CONSTANT */,1546                  loc1547              };1548          }1549          if (value && value.isQuoted) {1550              const valueLoc = value.loc;1551              valueLoc.start.offset++;1552              valueLoc.start.column++;1553              valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1554              valueLoc.source = valueLoc.source.slice(1, -1);1555          }1556          const modifiers = match[3] ? match[3].slice(1).split('.') : [];1557          if (isPropShorthand)1558              modifiers.push('prop');1559          // 2.x compat v-bind:foo.sync -> v-model:foo1560          if (dirName === 'bind' && arg) {1561              if (modifiers.includes('sync') &&1562                  checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1563                  dirName = 'model';1564                  modifiers.splice(modifiers.indexOf('sync'), 1);1565              }1566              if (modifiers.includes('prop')) {1567                  checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1568              }1569          }1570          return {1571              type: 7 /* DIRECTIVE */,1572              name: dirName,1573              exp: value && {1574                  type: 4 /* SIMPLE_EXPRESSION */,1575                  content: value.content,1576                  isStatic: false,1577                  // Treat as non-constant by default. This can be potentially set to1578                  // other values by `transformExpression` to make it eligible for hoisting.1579                  constType: 0 /* NOT_CONSTANT */,1580                  loc: value.loc1581              },1582              arg,1583              modifiers,1584              loc1585          };1586      }1587      // missing directive name or illegal directive name1588      if (!context.inVPre && startsWith(name, 'v-')) {1589          emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1590      }1591      return {1592          type: 6 /* ATTRIBUTE */,1593          name,1594          value: value && {1595              type: 2 /* TEXT */,1596              content: value.content,1597              loc: value.loc1598          },1599          loc1600      };1601  }1602  function parseAttributeValue(context) {1603      const start = getCursor(context);1604      let content;1605      const quote = context.source[0];1606      const isQuoted = quote === `"` || quote === `'`;1607      if (isQuoted) {1608          // Quoted value.1609          advanceBy(context, 1);1610          const endIndex = context.source.indexOf(quote);1611          if (endIndex === -1) {1612              content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1613          }1614          else {1615              content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1616              advanceBy(context, 1);1617          }1618      }1619      else {1620          // Unquoted1621          const match = /^[^\t\r\n\f >]+/.exec(context.source);1622          if (!match) {1623              return undefined;1624          }1625          const unexpectedChars = /["'<=`]/g;1626          let m;1627          while ((m = unexpectedChars.exec(match[0]))) {1628              emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1629          }1630          content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1631      }1632      return { content, isQuoted, loc: getSelection(context, start) };1633  }1634  function parseInterpolation(context, mode) {1635      const [open, close] = context.options.delimiters;1636      const closeIndex = context.source.indexOf(close, open.length);1637      if (closeIndex === -1) {1638          emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1639          return undefined;1640      }1641      const start = getCursor(context);1642      advanceBy(context, open.length);1643      const innerStart = getCursor(context);1644      const innerEnd = getCursor(context);1645      const rawContentLength = closeIndex - open.length;1646      const rawContent = context.source.slice(0, rawContentLength);1647      const preTrimContent = parseTextData(context, rawContentLength, mode);1648      const content = preTrimContent.trim();1649      const startOffset = preTrimContent.indexOf(content);1650      if (startOffset > 0) {1651          advancePositionWithMutation(innerStart, rawContent, startOffset);1652      }1653      const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1654      advancePositionWithMutation(innerEnd, rawContent, endOffset);1655      advanceBy(context, close.length);1656      return {1657          type: 5 /* INTERPOLATION */,1658          content: {1659              type: 4 /* SIMPLE_EXPRESSION */,1660              isStatic: false,1661              // Set `isConstant` to false by default and will decide in transformExpression1662              constType: 0 /* NOT_CONSTANT */,1663              content,1664              loc: getSelection(context, innerStart, innerEnd)1665          },1666          loc: getSelection(context, start)1667      };1668  }1669  function parseText(context, mode) {1670      const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1671      let endIndex = context.source.length;1672      for (let i = 0; i < endTokens.length; i++) {1673          const index = context.source.indexOf(endTokens[i], 1);1674          if (index !== -1 && endIndex > index) {1675              endIndex = index;1676          }1677      }1678      const start = getCursor(context);1679      const content = parseTextData(context, endIndex, mode);1680      return {1681          type: 2 /* TEXT */,1682          content,1683          loc: getSelection(context, start)1684      };1685  }1686  /**1687   * Get text data with a given length from the current location.1688   * This translates HTML entities in the text data.1689   */1690  function parseTextData(context, length, mode) {1691      const rawText = context.source.slice(0, length);1692      advanceBy(context, length);1693      if (mode === 2 /* RAWTEXT */ ||1694          mode === 3 /* CDATA */ ||1695          rawText.indexOf('&') === -1) {1696          return rawText;1697      }1698      else {1699          // DATA or RCDATA containing "&"". Entity decoding required.1700          return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1701      }1702  }1703  function getCursor(context) {1704      const { column, line, offset } = context;1705      return { column, line, offset };1706  }1707  function getSelection(context, start, end) {1708      end = end || getCursor(context);1709      return {1710          start,1711          end,1712          source: context.originalSource.slice(start.offset, end.offset)1713      };1714  }1715  function last(xs) {1716      return xs[xs.length - 1];1717  }1718  function startsWith(source, searchString) {1719      return source.startsWith(searchString);1720  }1721  function advanceBy(context, numberOfCharacters) {1722      const { source } = context;1723      advancePositionWithMutation(context, source, numberOfCharacters);1724      context.source = source.slice(numberOfCharacters);1725  }1726  function advanceSpaces(context) {1727      const match = /^[\t\r\n\f ]+/.exec(context.source);1728      if (match) {1729          advanceBy(context, match[0].length);1730      }1731  }1732  function getNewPosition(context, start, numberOfCharacters) {1733      return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1734  }1735  function emitError(context, code, offset, loc = getCursor(context)) {1736      if (offset) {1737          loc.offset += offset;1738          loc.column += offset;1739      }1740      context.options.onError(createCompilerError(code, {1741          start: loc,1742          end: loc,1743          source: ''1744      }));1745  }1746  function isEnd(context, mode, ancestors) {1747      const s = context.source;1748      switch (mode) {1749          case 0 /* DATA */:1750              if (startsWith(s, '</')) {1751                  // TODO: probably bad performance1752                  for (let i = ancestors.length - 1; i >= 0; --i) {1753                      if (startsWithEndTagOpen(s, ancestors[i].tag)) {1754                          return true;1755                      }1756                  }1757              }1758              break;1759          case 1 /* RCDATA */:1760          case 2 /* RAWTEXT */: {1761              const parent = last(ancestors);1762              if (parent && startsWithEndTagOpen(s, parent.tag)) {1763                  return true;1764              }1765              break;1766          }1767          case 3 /* CDATA */:1768              if (startsWith(s, ']]>')) {1769                  return true;1770              }1771              break;1772      }1773      return !s;1774  }1775  function startsWithEndTagOpen(source, tag) {1776      return (startsWith(source, '</') &&1777          source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1778          /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1779  }1780  function hoistStatic(root, context) {1781      walk(root, context, 1782      // Root node is unfortunately non-hoistable due to potential parent1783      // fallthrough attributes.1784      isSingleElementRoot(root, root.children[0]));1785  }1786  function isSingleElementRoot(root, child) {1787      const { children } = root;1788      return (children.length === 1 &&1789          child.type === 1 /* ELEMENT */ &&1790          !isSlotOutlet(child));1791  }1792  function walk(node, context, doNotHoistNode = false) {1793      const { children } = node;1794      const originalCount = children.length;1795      let hoistedCount = 0;1796      for (let i = 0; i < children.length; i++) {1797          const child = children[i];1798          // only plain elements & text calls are eligible for hoisting.1799          if (child.type === 1 /* ELEMENT */ &&1800              child.tagType === 0 /* ELEMENT */) {1801              const constantType = doNotHoistNode1802                  ? 0 /* NOT_CONSTANT */1803                  : getConstantType(child, context);1804              if (constantType > 0 /* NOT_CONSTANT */) {1805                  if (constantType >= 2 /* CAN_HOIST */) {1806                      child.codegenNode.patchFlag =1807                          -1 /* HOISTED */ + (` /* HOISTED */` );1808                      child.codegenNode = context.hoist(child.codegenNode);1809                      hoistedCount++;1810                      continue;1811                  }1812              }1813              else {1814                  // node may contain dynamic children, but its props may be eligible for1815                  // hoisting.1816                  const codegenNode = child.codegenNode;1817                  if (codegenNode.type === 13 /* VNODE_CALL */) {1818                      const flag = getPatchFlag(codegenNode);1819                      if ((!flag ||1820                          flag === 512 /* NEED_PATCH */ ||1821                          flag === 1 /* TEXT */) &&1822                          getGeneratedPropsConstantType(child, context) >=1823                              2 /* CAN_HOIST */) {1824                          const props = getNodeProps(child);1825                          if (props) {1826                              codegenNode.props = context.hoist(props);1827                          }1828                      }1829                      if (codegenNode.dynamicProps) {1830                          codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1831                      }1832                  }1833              }1834          }1835          else if (child.type === 12 /* TEXT_CALL */ &&1836              getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {1837              child.codegenNode = context.hoist(child.codegenNode);1838              hoistedCount++;1839          }1840          // walk further1841          if (child.type === 1 /* ELEMENT */) {1842              const isComponent = child.tagType === 1 /* COMPONENT */;1843              if (isComponent) {1844                  context.scopes.vSlot++;1845              }1846              walk(child, context);1847              if (isComponent) {1848                  context.scopes.vSlot--;1849              }1850          }1851          else if (child.type === 11 /* FOR */) {1852              // Do not hoist v-for single child because it has to be a block1853              walk(child, context, child.children.length === 1);1854          }1855          else if (child.type === 9 /* IF */) {1856              for (let i = 0; i < child.branches.length; i++) {1857                  // Do not hoist v-if single child because it has to be a block1858                  walk(child.branches[i], context, child.branches[i].children.length === 1);1859              }1860          }1861      }1862      if (hoistedCount && context.transformHoist) {1863          context.transformHoist(children, context, node);1864      }1865      // all children were hoisted - the entire children array is hoistable.1866      if (hoistedCount &&1867          hoistedCount === originalCount &&1868          node.type === 1 /* ELEMENT */ &&1869          node.tagType === 0 /* ELEMENT */ &&1870          node.codegenNode &&1871          node.codegenNode.type === 13 /* VNODE_CALL */ &&1872          isArray(node.codegenNode.children)) {1873          node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1874      }1875  }1876  function getConstantType(node, context) {1877      const { constantCache } = context;1878      switch (node.type) {1879          case 1 /* ELEMENT */:1880              if (node.tagType !== 0 /* ELEMENT */) {1881                  return 0 /* NOT_CONSTANT */;1882              }1883              const cached = constantCache.get(node);1884              if (cached !== undefined) {1885                  return cached;1886              }1887              const codegenNode = node.codegenNode;1888              if (codegenNode.type !== 13 /* VNODE_CALL */) {1889                  return 0 /* NOT_CONSTANT */;1890              }1891              if (codegenNode.isBlock &&1892                  node.tag !== 'svg' &&1893                  node.tag !== 'foreignObject') {1894                  return 0 /* NOT_CONSTANT */;1895              }1896              const flag = getPatchFlag(codegenNode);1897              if (!flag) {1898                  let returnType = 3 /* CAN_STRINGIFY */;1899                  // Element itself has no patch flag. However we still need to check:1900                  // 1. Even for a node with no patch flag, it is possible for it to contain1901                  // non-hoistable expressions that refers to scope variables, e.g. compiler1902                  // injected keys or cached event handlers. Therefore we need to always1903                  // check the codegenNode's props to be sure.1904                  const generatedPropsType = getGeneratedPropsConstantType(node, context);1905                  if (generatedPropsType === 0 /* NOT_CONSTANT */) {1906                      constantCache.set(node, 0 /* NOT_CONSTANT */);1907                      return 0 /* NOT_CONSTANT */;1908                  }1909                  if (generatedPropsType < returnType) {1910                      returnType = generatedPropsType;1911                  }1912                  // 2. its children.1913                  for (let i = 0; i < node.children.length; i++) {1914                      const childType = getConstantType(node.children[i], context);1915                      if (childType === 0 /* NOT_CONSTANT */) {1916                          constantCache.set(node, 0 /* NOT_CONSTANT */);1917                          return 0 /* NOT_CONSTANT */;1918                      }1919                      if (childType < returnType) {1920                          returnType = childType;1921                      }1922                  }1923                  // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01924                  // type, check if any of the props can cause the type to be lowered1925                  // we can skip can_patch because it's guaranteed by the absence of a1926                  // patchFlag.1927                  if (returnType > 1 /* CAN_SKIP_PATCH */) {1928                      for (let i = 0; i < node.props.length; i++) {1929                          const p = node.props[i];1930                          if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1931                              const expType = getConstantType(p.exp, context);1932                              if (expType === 0 /* NOT_CONSTANT */) {1933                                  constantCache.set(node, 0 /* NOT_CONSTANT */);1934                                  return 0 /* NOT_CONSTANT */;1935                              }1936                              if (expType < returnType) {1937                                  returnType = expType;1938                              }1939                          }1940                      }1941                  }1942                  // only svg/foreignObject could be block here, however if they are1943                  // static then they don't need to be blocks since there will be no1944                  // nested updates.1945                  if (codegenNode.isBlock) {1946                      context.removeHelper(OPEN_BLOCK);1947                      context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1948                      codegenNode.isBlock = false;1949                      context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1950                  }1951                  constantCache.set(node, returnType);1952                  return returnType;1953              }1954              else {1955                  constantCache.set(node, 0 /* NOT_CONSTANT */);1956                  return 0 /* NOT_CONSTANT */;1957              }1958          case 2 /* TEXT */:1959          case 3 /* COMMENT */:1960              return 3 /* CAN_STRINGIFY */;1961          case 9 /* IF */:1962          case 11 /* FOR */:1963          case 10 /* IF_BRANCH */:1964              return 0 /* NOT_CONSTANT */;1965          case 5 /* INTERPOLATION */:1966          case 12 /* TEXT_CALL */:1967              return getConstantType(node.content, context);1968          case 4 /* SIMPLE_EXPRESSION */:1969              return node.constType;1970          case 8 /* COMPOUND_EXPRESSION */:1971              let returnType = 3 /* CAN_STRINGIFY */;1972              for (let i = 0; i < node.children.length; i++) {1973                  const child = node.children[i];1974                  if (isString(child) || isSymbol(child)) {1975                      continue;1976                  }1977                  const childType = getConstantType(child, context);1978                  if (childType === 0 /* NOT_CONSTANT */) {1979                      return 0 /* NOT_CONSTANT */;1980                  }1981                  else if (childType < returnType) {1982                      returnType = childType;1983                  }1984              }1985              return returnType;1986          default:1987              return 0 /* NOT_CONSTANT */;1988      }1989  }1990  const allowHoistedHelperSet = new Set([1991      NORMALIZE_CLASS,1992      NORMALIZE_STYLE,1993      NORMALIZE_PROPS,1994      GUARD_REACTIVE_PROPS1995  ]);1996  function getConstantTypeOfHelperCall(value, context) {1997      if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1998          !isString(value.callee) &&1999          allowHoistedHelperSet.has(value.callee)) {2000          const arg = value.arguments[0];2001          if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2002              return getConstantType(arg, context);2003          }2004          else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {2005              // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`2006              return getConstantTypeOfHelperCall(arg, context);2007          }2008      }2009      return 0 /* NOT_CONSTANT */;2010  }2011  function getGeneratedPropsConstantType(node, context) {2012      let returnType = 3 /* CAN_STRINGIFY */;2013      const props = getNodeProps(node);2014      if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {2015          const { properties } = props;2016          for (let i = 0; i < properties.length; i++) {2017              const { key, value } = properties[i];2018              const keyType = getConstantType(key, context);2019              if (keyType === 0 /* NOT_CONSTANT */) {2020                  return keyType;2021              }2022              if (keyType < returnType) {2023                  returnType = keyType;2024              }2025              let valueType;2026              if (value.type === 4 /* SIMPLE_EXPRESSION */) {2027                  valueType = getConstantType(value, context);2028              }2029              else if (value.type === 14 /* JS_CALL_EXPRESSION */) {2030                  // some helper calls can be hoisted,2031                  // such as the `normalizeProps` generated by the compiler for pre-normalize class,2032                  // in this case we need to respect the ConstantType of the helper's arguments2033                  valueType = getConstantTypeOfHelperCall(value, context);2034              }2035              else {2036                  valueType = 0 /* NOT_CONSTANT */;2037              }2038              if (valueType === 0 /* NOT_CONSTANT */) {2039                  return valueType;2040              }2041              if (valueType < returnType) {2042                  returnType = valueType;2043              }2044          }2045      }2046      return returnType;2047  }2048  function getNodeProps(node) {2049      const codegenNode = node.codegenNode;2050      if (codegenNode.type === 13 /* VNODE_CALL */) {2051          return codegenNode.props;2052      }2053  }2054  function getPatchFlag(node) {2055      const flag = node.patchFlag;2056      return flag ? parseInt(flag, 10) : undefined;2057  }2058  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 }) {2059      const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);2060      const context = {2061          // options2062          selfName: nameMatch && capitalize(camelize(nameMatch[1])),2063          prefixIdentifiers,2064          hoistStatic,2065          cacheHandlers,2066          nodeTransforms,2067          directiveTransforms,2068          transformHoist,2069          isBuiltInComponent,2070          isCustomElement,2071          expressionPlugins,2072          scopeId,2073          slotted,2074          ssr,2075          inSSR,2076          ssrCssVars,2077          bindingMetadata,2078          inline,2079          isTS,2080          onError,2081          onWarn,2082          compatConfig,2083          // state2084          root,2085          helpers: new Map(),2086          components: new Set(),2087          directives: new Set(),2088          hoists: [],2089          imports: [],2090          constantCache: new Map(),2091          temps: 0,2092          cached: 0,2093          identifiers: Object.create(null),2094          scopes: {2095              vFor: 0,2096              vSlot: 0,2097              vPre: 0,2098              vOnce: 02099          },2100          parent: null,2101          currentNode: root,2102          childIndex: 0,2103          inVOnce: false,2104          // methods2105          helper(name) {2106              const count = context.helpers.get(name) || 0;2107              context.helpers.set(name, count + 1);2108              return name;2109          },2110          removeHelper(name) {2111              const count = context.helpers.get(name);2112              if (count) {2113                  const currentCount = count - 1;2114                  if (!currentCount) {2115                      context.helpers.delete(name);2116                  }2117                  else {2118                      context.helpers.set(name, currentCount);2119                  }2120              }2121          },2122          helperString(name) {2123              return `_${helperNameMap[context.helper(name)]}`;2124          },2125          replaceNode(node) {2126              /* istanbul ignore if */2127              {2128                  if (!context.currentNode) {2129                      throw new Error(`Node being replaced is already removed.`);2130                  }2131                  if (!context.parent) {2132                      throw new Error(`Cannot replace root node.`);2133                  }2134              }2135              context.parent.children[context.childIndex] = context.currentNode = node;2136          },2137          removeNode(node) {2138              if (!context.parent) {2139                  throw new Error(`Cannot remove root node.`);2140              }2141              const list = context.parent.children;2142              const removalIndex = node2143                  ? list.indexOf(node)2144                  : context.currentNode2145                      ? context.childIndex2146                      : -1;2147              /* istanbul ignore if */2148              if (removalIndex < 0) {2149                  throw new Error(`node being removed is not a child of current parent`);2150              }2151              if (!node || node === context.currentNode) {2152                  // current node removed2153                  context.currentNode = null;2154                  context.onNodeRemoved();2155              }2156              else {2157                  // sibling node removed2158                  if (context.childIndex > removalIndex) {2159                      context.childIndex--;2160                      context.onNodeRemoved();2161                  }2162              }2163              context.parent.children.splice(removalIndex, 1);2164          },2165          onNodeRemoved: () => { },2166          addIdentifiers(exp) {2167          },2168          removeIdentifiers(exp) {2169          },2170          hoist(exp) {2171              if (isString(exp))2172                  exp = createSimpleExpression(exp);2173              context.hoists.push(exp);2174              const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2175              identifier.hoisted = exp;2176              return identifier;2177          },2178          cache(exp, isVNode = false) {2179              return createCacheExpression(context.cached++, exp, isVNode);2180          }2181      };2182      {2183          context.filters = new Set();2184      }2185      return context;2186  }2187  function transform(root, options) {2188      const context = createTransformContext(root, options);2189      traverseNode(root, context);2190      if (options.hoistStatic) {2191          hoistStatic(root, context);2192      }2193      if (!options.ssr) {2194          createRootCodegen(root, context);2195      }2196      // finalize meta information2197      root.helpers = [...context.helpers.keys()];2198      root.components = [...context.components];2199      root.directives = [...context.directives];2200      root.imports = context.imports;2201      root.hoists = context.hoists;2202      root.temps = context.temps;2203      root.cached = context.cached;2204      {2205          root.filters = [...context.filters];2206      }2207  }2208  function createRootCodegen(root, context) {2209      const { helper } = context;2210      const { children } = root;2211      if (children.length === 1) {2212          const child = children[0];2213          // if the single child is an element, turn it into a block.2214          if (isSingleElementRoot(root, child) && child.codegenNode) {2215              // single element root is never hoisted so codegenNode will never be2216              // SimpleExpressionNode2217              const codegenNode = child.codegenNode;2218              if (codegenNode.type === 13 /* VNODE_CALL */) {2219                  makeBlock(codegenNode, context);2220              }2221              root.codegenNode = codegenNode;2222          }2223          else {2224              // - single <slot/>, IfNode, ForNode: already blocks.2225              // - single text node: always patched.2226              // root codegen falls through via genNode()2227              root.codegenNode = child;2228          }2229      }2230      else if (children.length > 1) {2231          // root has multiple nodes - return a fragment block.2232          let patchFlag = 64 /* STABLE_FRAGMENT */;2233          let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2234          // check if the fragment actually contains a single valid child with2235          // the rest being comments2236          if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2237              patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2238              patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2239          }2240          root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);2241      }2242      else ;2243  }2244  function traverseChildren(parent, context) {2245      let i = 0;2246      const nodeRemoved = () => {2247          i--;2248      };2249      for (; i < parent.children.length; i++) {2250          const child = parent.children[i];2251          if (isString(child))2252              continue;2253          context.parent = parent;2254          context.childIndex = i;2255          context.onNodeRemoved = nodeRemoved;2256          traverseNode(child, context);2257      }2258  }2259  function traverseNode(node, context) {2260      context.currentNode = node;2261      // apply transform plugins2262      const { nodeTransforms } = context;2263      const exitFns = [];2264      for (let i = 0; i < nodeTransforms.length; i++) {2265          const onExit = nodeTransforms[i](node, context);2266          if (onExit) {2267              if (isArray(onExit)) {2268                  exitFns.push(...onExit);2269              }2270              else {2271                  exitFns.push(onExit);2272              }2273          }2274          if (!context.currentNode) {2275              // node was removed2276              return;2277          }2278          else {2279              // node may have been replaced2280              node = context.currentNode;2281          }2282      }2283      switch (node.type) {2284          case 3 /* COMMENT */:2285              if (!context.ssr) {2286                  // inject import for the Comment symbol, which is needed for creating2287                  // comment nodes with `createVNode`2288                  context.helper(CREATE_COMMENT);2289              }2290              break;2291          case 5 /* INTERPOLATION */:2292              // no need to traverse, but we need to inject toString helper2293              if (!context.ssr) {2294                  context.helper(TO_DISPLAY_STRING);2295              }2296              break;2297          // for container types, further traverse downwards2298          case 9 /* IF */:2299              for (let i = 0; i < node.branches.length; i++) {2300                  traverseNode(node.branches[i], context);2301              }2302              break;2303          case 10 /* IF_BRANCH */:2304          case 11 /* FOR */:2305          case 1 /* ELEMENT */:2306          case 0 /* ROOT */:2307              traverseChildren(node, context);2308              break;2309      }2310      // exit transforms2311      context.currentNode = node;2312      let i = exitFns.length;2313      while (i--) {2314          exitFns[i]();2315      }2316  }2317  function createStructuralDirectiveTransform(name, fn) {2318      const matches = isString(name)2319          ? (n) => n === name2320          : (n) => name.test(n);2321      return (node, context) => {2322          if (node.type === 1 /* ELEMENT */) {2323              const { props } = node;2324              // structural directive transforms are not concerned with slots2325              // as they are handled separately in vSlot.ts2326              if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2327                  return;2328              }2329              const exitFns = [];2330              for (let i = 0; i < props.length; i++) {2331                  const prop = props[i];2332                  if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2333                      // structural directives are removed to avoid infinite recursion2334                      // also we remove them *before* applying so that it can further2335                      // traverse itself in case it moves the node around2336                      props.splice(i, 1);2337                      i--;2338                      const onExit = fn(node, prop, context);2339                      if (onExit)2340                          exitFns.push(onExit);2341                  }2342              }2343              return exitFns;2344          }2345      };2346  }2347  const PURE_ANNOTATION = `/*#__PURE__*/`;2348  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 }) {2349      const context = {2350          mode,2351          prefixIdentifiers,2352          sourceMap,2353          filename,2354          scopeId,2355          optimizeImports,2356          runtimeGlobalName,2357          runtimeModuleName,2358          ssrRuntimeModuleName,2359          ssr,2360          isTS,2361          inSSR,2362          source: ast.loc.source,2363          code: ``,2364          column: 1,2365          line: 1,2366          offset: 0,2367          indentLevel: 0,2368          pure: false,2369          map: undefined,2370          helper(key) {2371              return `_${helperNameMap[key]}`;2372          },2373          push(code, node) {2374              context.code += code;2375          },2376          indent() {2377              newline(++context.indentLevel);2378          },2379          deindent(withoutNewLine = false) {2380              if (withoutNewLine) {2381                  --context.indentLevel;2382              }2383              else {2384                  newline(--context.indentLevel);2385              }2386          },2387          newline() {2388              newline(context.indentLevel);2389          }2390      };2391      function newline(n) {2392          context.push('\n' + `  `.repeat(n));2393      }2394      return context;2395  }2396  function generate(ast, options = {}) {2397      const context = createCodegenContext(ast, options);2398      if (options.onContextCreated)2399          options.onContextCreated(context);2400      const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2401      const hasHelpers = ast.helpers.length > 0;2402      const useWithBlock = !prefixIdentifiers && mode !== 'module';2403      // preambles2404      // in setup() inline mode, the preamble is generated in a sub context2405      // and returned separately.2406      const preambleContext = context;2407      {2408          genFunctionPreamble(ast, preambleContext);2409      }2410      // enter render function2411      const functionName = ssr ? `ssrRender` : `render`;2412      const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2413      const signature = args.join(', ');2414      {2415          push(`function ${functionName}(${signature}) {`);2416      }2417      indent();2418      if (useWithBlock) {2419          push(`with (_ctx) {`);2420          indent();2421          // function mode const declarations should be inside with block2422          // also they should be renamed to avoid collision with user properties2423          if (hasHelpers) {2424              push(`const { ${ast.helpers2425                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2426                .join(', ')} } = _Vue`);2427              push(`\n`);2428              newline();2429          }2430      }2431      // generate asset resolution statements2432      if (ast.components.length) {2433          genAssets(ast.components, 'component', context);2434          if (ast.directives.length || ast.temps > 0) {2435              newline();2436          }2437      }2438      if (ast.directives.length) {2439          genAssets(ast.directives, 'directive', context);2440          if (ast.temps > 0) {2441              newline();2442          }2443      }2444      if (ast.filters && ast.filters.length) {2445          newline();2446          genAssets(ast.filters, 'filter', context);2447          newline();2448      }2449      if (ast.temps > 0) {2450          push(`let `);2451          for (let i = 0; i < ast.temps; i++) {2452              push(`${i > 0 ? `, ` : ``}_temp${i}`);2453          }2454      }2455      if (ast.components.length || ast.directives.length || ast.temps) {2456          push(`\n`);2457          newline();2458      }2459      // generate the VNode tree expression2460      if (!ssr) {2461          push(`return `);2462      }2463      if (ast.codegenNode) {2464          genNode(ast.codegenNode, context);2465      }2466      else {2467          push(`null`);2468      }2469      if (useWithBlock) {2470          deindent();2471          push(`}`);2472      }2473      deindent();2474      push(`}`);2475      return {2476          ast,2477          code: context.code,2478          preamble: ``,2479          // SourceMapGenerator does have toJSON() method but it's not in the types2480          map: context.map ? context.map.toJSON() : undefined2481      };2482  }2483  function genFunctionPreamble(ast, context) {2484      const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2485      const VueBinding = runtimeGlobalName;2486      const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2487      // Generate const declaration for helpers2488      // In prefix mode, we place the const declaration at top so it's done2489      // only once; But if we not prefixing, we place the declaration inside the2490      // with block so it doesn't incur the `in` check cost for every helper access.2491      if (ast.helpers.length > 0) {2492          {2493              // "with" mode.2494              // save Vue in a separate variable to avoid collision2495              push(`const _Vue = ${VueBinding}\n`);2496              // in "with" mode, helpers are declared inside the with block to avoid2497              // has check cost, but hoists are lifted out of the function - we need2498              // to provide the helper here.2499              if (ast.hoists.length) {2500                  const staticHelpers = [2501                      CREATE_VNODE,2502                      CREATE_ELEMENT_VNODE,2503                      CREATE_COMMENT,2504                      CREATE_TEXT,2505                      CREATE_STATIC2506                  ]2507                      .filter(helper => ast.helpers.includes(helper))2508                      .map(aliasHelper)2509                      .join(', ');2510                  push(`const { ${staticHelpers} } = _Vue\n`);2511              }2512          }2513      }2514      genHoists(ast.hoists, context);2515      newline();2516      push(`return `);2517  }2518  function genAssets(assets, type, { helper, push, newline, isTS }) {2519      const resolver = helper(type === 'filter'2520          ? RESOLVE_FILTER2521          : type === 'component'2522              ? RESOLVE_COMPONENT2523              : RESOLVE_DIRECTIVE);2524      for (let i = 0; i < assets.length; i++) {2525          let id = assets[i];2526          // potential component implicit self-reference inferred from SFC filename2527          const maybeSelfReference = id.endsWith('__self');2528          if (maybeSelfReference) {2529              id = id.slice(0, -6);2530          }2531          push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2532          if (i < assets.length - 1) {2533              newline();2534          }2535      }2536  }2537  function genHoists(hoists, context) {2538      if (!hoists.length) {2539          return;2540      }2541      context.pure = true;2542      const { push, newline, helper, scopeId, mode } = context;2543      newline();2544      for (let i = 0; i < hoists.length; i++) {2545          const exp = hoists[i];2546          if (exp) {2547              push(`const _hoisted_${i + 1} = ${``}`);2548              genNode(exp, context);2549              newline();2550          }2551      }2552      context.pure = false;2553  }2554  function isText$1(n) {2555      return (isString(n) ||2556          n.type === 4 /* SIMPLE_EXPRESSION */ ||2557          n.type === 2 /* TEXT */ ||2558          n.type === 5 /* INTERPOLATION */ ||2559          n.type === 8 /* COMPOUND_EXPRESSION */);2560  }2561  function genNodeListAsArray(nodes, context) {2562      const multilines = nodes.length > 3 ||2563          (nodes.some(n => isArray(n) || !isText$1(n)));2564      context.push(`[`);2565      multilines && context.indent();2566      genNodeList(nodes, context, multilines);2567      multilines && context.deindent();2568      context.push(`]`);2569  }2570  function genNodeList(nodes, context, multilines = false, comma = true) {2571      const { push, newline } = context;2572      for (let i = 0; i < nodes.length; i++) {2573          const node = nodes[i];2574          if (isString(node)) {2575              push(node);2576          }2577          else if (isArray(node)) {2578              genNodeListAsArray(node, context);2579          }2580          else {2581              genNode(node, context);2582          }2583          if (i < nodes.length - 1) {2584              if (multilines) {2585                  comma && push(',');2586                  newline();2587              }2588              else {2589                  comma && push(', ');2590              }2591          }2592      }2593  }2594  function genNode(node, context) {2595      if (isString(node)) {2596          context.push(node);2597          return;2598      }2599      if (isSymbol(node)) {2600          context.push(context.helper(node));2601          return;2602      }2603      switch (node.type) {2604          case 1 /* ELEMENT */:2605          case 9 /* IF */:2606          case 11 /* FOR */:2607              assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2608                      `Apply appropriate transforms first.`);2609              genNode(node.codegenNode, context);2610              break;2611          case 2 /* TEXT */:2612              genText(node, context);2613              break;2614          case 4 /* SIMPLE_EXPRESSION */:2615              genExpression(node, context);2616              break;2617          case 5 /* INTERPOLATION */:2618              genInterpolation(node, context);2619              break;2620          case 12 /* TEXT_CALL */:2621              genNode(node.codegenNode, context);2622              break;2623          case 8 /* COMPOUND_EXPRESSION */:2624              genCompoundExpression(node, context);2625              break;2626          case 3 /* COMMENT */:2627              genComment(node, context);2628              break;2629          case 13 /* VNODE_CALL */:2630              genVNodeCall(node, context);2631              break;2632          case 14 /* JS_CALL_EXPRESSION */:2633              genCallExpression(node, context);2634              break;2635          case 15 /* JS_OBJECT_EXPRESSION */:2636              genObjectExpression(node, context);2637              break;2638          case 17 /* JS_ARRAY_EXPRESSION */:2639              genArrayExpression(node, context);2640              break;2641          case 18 /* JS_FUNCTION_EXPRESSION */:2642              genFunctionExpression(node, context);2643              break;2644          case 19 /* JS_CONDITIONAL_EXPRESSION */:2645              genConditionalExpression(node, context);2646              break;2647          case 20 /* JS_CACHE_EXPRESSION */:2648              genCacheExpression(node, context);2649              break;2650          case 21 /* JS_BLOCK_STATEMENT */:2651              genNodeList(node.body, context, true, false);2652              break;2653          // SSR only types2654          case 22 /* JS_TEMPLATE_LITERAL */:2655              break;2656          case 23 /* JS_IF_STATEMENT */:2657              break;2658          case 24 /* JS_ASSIGNMENT_EXPRESSION */:2659              break;2660          case 25 /* JS_SEQUENCE_EXPRESSION */:2661              break;2662          case 26 /* JS_RETURN_STATEMENT */:2663              break;2664          /* istanbul ignore next */2665          case 10 /* IF_BRANCH */:2666              // noop2667              break;2668          default:2669              {2670                  assert(false, `unhandled codegen node type: ${node.type}`);2671                  // make sure we exhaust all possible types2672                  const exhaustiveCheck = node;2673                  return exhaustiveCheck;2674              }2675      }2676  }2677  function genText(node, context) {2678      context.push(JSON.stringify(node.content), node);2679  }2680  function genExpression(node, context) {2681      const { content, isStatic } = node;2682      context.push(isStatic ? JSON.stringify(content) : content, node);2683  }2684  function genInterpolation(node, context) {2685      const { push, helper, pure } = context;2686      if (pure)2687          push(PURE_ANNOTATION);2688      push(`${helper(TO_DISPLAY_STRING)}(`);2689      genNode(node.content, context);2690      push(`)`);2691  }2692  function genCompoundExpression(node, context) {2693      for (let i = 0; i < node.children.length; i++) {2694          const child = node.children[i];2695          if (isString(child)) {2696              context.push(child);2697          }2698          else {2699              genNode(child, context);2700          }2701      }2702  }2703  function genExpressionAsPropertyKey(node, context) {2704      const { push } = context;2705      if (node.type === 8 /* COMPOUND_EXPRESSION */) {2706          push(`[`);2707          genCompoundExpression(node, context);2708          push(`]`);2709      }2710      else if (node.isStatic) {2711          // only quote keys if necessary2712          const text = isSimpleIdentifier(node.content)2713              ? node.content2714              : JSON.stringify(node.content);2715          push(text, node);2716      }2717      else {2718          push(`[${node.content}]`, node);2719      }2720  }2721  function genComment(node, context) {2722      const { push, helper, pure } = context;2723      if (pure) {2724          push(PURE_ANNOTATION);2725      }2726      push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2727  }2728  function genVNodeCall(node, context) {2729      const { push, helper, pure } = context;2730      const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2731      if (directives) {2732          push(helper(WITH_DIRECTIVES) + `(`);2733      }2734      if (isBlock) {2735          push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2736      }2737      if (pure) {2738          push(PURE_ANNOTATION);2739      }2740      const callHelper = isBlock2741          ? getVNodeBlockHelper(context.inSSR, isComponent)2742          : getVNodeHelper(context.inSSR, isComponent);2743      push(helper(callHelper) + `(`, node);2744      genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2745      push(`)`);2746      if (isBlock) {2747          push(`)`);2748      }2749      if (directives) {2750          push(`, `);2751          genNode(directives, context);2752          push(`)`);2753      }2754  }2755  function genNullableArgs(args) {2756      let i = args.length;2757      while (i--) {2758          if (args[i] != null)2759              break;2760      }2761      return args.slice(0, i + 1).map(arg => arg || `null`);2762  }2763  // JavaScript2764  function genCallExpression(node, context) {2765      const { push, helper, pure } = context;2766      const callee = isString(node.callee) ? node.callee : helper(node.callee);2767      if (pure) {2768          push(PURE_ANNOTATION);2769      }2770      push(callee + `(`, node);2771      genNodeList(node.arguments, context);2772      push(`)`);2773  }2774  function genObjectExpression(node, context) {2775      const { push, indent, deindent, newline } = context;2776      const { properties } = node;2777      if (!properties.length) {2778          push(`{}`, node);2779          return;2780      }2781      const multilines = properties.length > 1 ||2782          (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2783      push(multilines ? `{` : `{ `);2784      multilines && indent();2785      for (let i = 0; i < properties.length; i++) {2786          const { key, value } = properties[i];2787          // key2788          genExpressionAsPropertyKey(key, context);2789          push(`: `);2790          // value2791          genNode(value, context);2792          if (i < properties.length - 1) {2793              // will only reach this if it's multilines2794              push(`,`);2795              newline();2796          }2797      }2798      multilines && deindent();2799      push(multilines ? `}` : ` }`);2800  }2801  function genArrayExpression(node, context) {2802      genNodeListAsArray(node.elements, context);2803  }2804  function genFunctionExpression(node, context) {2805      const { push, indent, deindent } = context;2806      const { params, returns, body, newline, isSlot } = node;2807      if (isSlot) {2808          // wrap slot functions with owner context2809          push(`_${helperNameMap[WITH_CTX]}(`);2810      }2811      push(`(`, node);2812      if (isArray(params)) {2813          genNodeList(params, context);2814      }2815      else if (params) {2816          genNode(params, context);2817      }2818      push(`) => `);2819      if (newline || body) {2820          push(`{`);2821          indent();2822      }2823      if (returns) {2824          if (newline) {2825              push(`return `);2826          }2827          if (isArray(returns)) {2828              genNodeListAsArray(returns, context);2829          }2830          else {2831              genNode(returns, context);2832          }2833      }2834      else if (body) {2835          genNode(body, context);2836      }2837      if (newline || body) {2838          deindent();2839          push(`}`);2840      }2841      if (isSlot) {2842          if (node.isNonScopedSlot) {2843              push(`, undefined, true`);2844          }2845          push(`)`);2846      }2847  }2848  function genConditionalExpression(node, context) {2849      const { test, consequent, alternate, newline: needNewline } = node;2850      const { push, indent, deindent, newline } = context;2851      if (test.type === 4 /* SIMPLE_EXPRESSION */) {2852          const needsParens = !isSimpleIdentifier(test.content);2853          needsParens && push(`(`);2854          genExpression(test, context);2855          needsParens && push(`)`);2856      }2857      else {2858          push(`(`);2859          genNode(test, context);2860          push(`)`);2861      }2862      needNewline && indent();2863      context.indentLevel++;2864      needNewline || push(` `);2865      push(`? `);2866      genNode(consequent, context);2867      context.indentLevel--;2868      needNewline && newline();2869      needNewline || push(` `);2870      push(`: `);2871      const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2872      if (!isNested) {2873          context.indentLevel++;2874      }2875      genNode(alternate, context);2876      if (!isNested) {2877          context.indentLevel--;2878      }2879      needNewline && deindent(true /* without newline */);2880  }2881  function genCacheExpression(node, context) {2882      const { push, helper, indent, deindent, newline } = context;2883      push(`_cache[${node.index}] || (`);2884      if (node.isVNode) {2885          indent();2886          push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2887          newline();2888      }2889      push(`_cache[${node.index}] = `);2890      genNode(node.value, context);2891      if (node.isVNode) {2892          push(`,`);2893          newline();2894          push(`${helper(SET_BLOCK_TRACKING)}(1),`);2895          newline();2896          push(`_cache[${node.index}]`);2897          deindent();2898      }2899      push(`)`);2900  }2901  function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2902      {2903          return;2904      }2905  }2906  function isReferencedIdentifier(id, parent, parentStack) {2907      {2908          return false;2909      }2910  }2911  function isInDestructureAssignment(parent, parentStack) {2912      if (parent &&2913          (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2914          let i = parentStack.length;2915          while (i--) {2916              const p = parentStack[i];2917              if (p.type === 'AssignmentExpression') {2918                  return true;2919              }2920              else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2921                  break;2922              }2923          }2924      }2925      return false;2926  }2927  function walkFunctionParams(node, onIdent) {2928      for (const p of node.params) {2929          for (const id of extractIdentifiers(p)) {2930              onIdent(id);2931          }2932      }2933  }2934  function walkBlockDeclarations(block, onIdent) {2935      for (const stmt of block.body) {2936          if (stmt.type === 'VariableDeclaration') {2937              if (stmt.declare)2938                  continue;2939              for (const decl of stmt.declarations) {2940                  for (const id of extractIdentifiers(decl.id)) {2941                      onIdent(id);2942                  }2943              }2944          }2945          else if (stmt.type === 'FunctionDeclaration' ||2946              stmt.type === 'ClassDeclaration') {2947              if (stmt.declare || !stmt.id)2948                  continue;2949              onIdent(stmt.id);2950          }2951      }2952  }2953  function extractIdentifiers(param, nodes = []) {2954      switch (param.type) {2955          case 'Identifier':2956              nodes.push(param);2957              break;2958          case 'MemberExpression':2959              let object = param;2960              while (object.type === 'MemberExpression') {2961                  object = object.object;2962              }2963              nodes.push(object);2964              break;2965          case 'ObjectPattern':2966              for (const prop of param.properties) {2967                  if (prop.type === 'RestElement') {2968                      extractIdentifiers(prop.argument, nodes);2969                  }2970                  else {2971                      extractIdentifiers(prop.value, nodes);2972                  }2973              }2974              break;2975          case 'ArrayPattern':2976              param.elements.forEach(element => {2977                  if (element)2978                      extractIdentifiers(element, nodes);2979              });2980              break;2981          case 'RestElement':2982              extractIdentifiers(param.argument, nodes);2983              break;2984          case 'AssignmentPattern':2985              extractIdentifiers(param.left, nodes);2986              break;2987      }2988      return nodes;2989  }2990  const isFunctionType = (node) => {2991      return /Function(?:Expression|Declaration)$|Method$/.test(node.type);2992  };2993  const isStaticProperty = (node) => node &&2994      (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&2995      !node.computed;2996  const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;2997  // these keywords should not appear inside expressions, but operators like2998  // typeof, instanceof and in are allowed2999  const prohibitedKeywordRE = new RegExp('\\b' +3000      ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +3001          'super,throw,while,yield,delete,export,import,return,switch,default,' +3002          'extends,finally,continue,debugger,function,arguments,typeof,void')3003          .split(',')3004          .join('\\b|\\b') +3005      '\\b');3006  // strip strings in expressions3007  const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;3008  /**3009   * Validate a non-prefixed expression.3010   * This is only called when using the in-browser runtime compiler since it3011   * doesn't prefix expressions.3012   */3013  function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {3014      const exp = node.content;3015      // empty expressions are validated per-directive since some directives3016      // do allow empty expressions.3017      if (!exp.trim()) {3018          return;3019      }3020      try {3021          new Function(asRawStatements3022              ? ` ${exp} `3023              : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);3024      }3025      catch (e) {3026          let message = e.message;3027          const keywordMatch = exp3028              .replace(stripStringRE, '')3029              .match(prohibitedKeywordRE);3030          if (keywordMatch) {3031              message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;3032          }3033          context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));3034      }3035  }3036  const transformExpression = (node, context) => {3037      if (node.type === 5 /* INTERPOLATION */) {3038          node.content = processExpression(node.content, context);3039      }3040      else if (node.type === 1 /* ELEMENT */) {3041          // handle directives on element3042          for (let i = 0; i < node.props.length; i++) {3043              const dir = node.props[i];3044              // do not process for v-on & v-for since they are special handled3045              if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3046                  const exp = dir.exp;3047                  const arg = dir.arg;3048                  // do not process exp if this is v-on:arg - we need special handling3049                  // for wrapping inline statements.3050                  if (exp &&3051                      exp.type === 4 /* SIMPLE_EXPRESSION */ &&3052                      !(dir.name === 'on' && arg)) {3053                      dir.exp = processExpression(exp, context, 3054                      // slot args must be processed as function params3055                      dir.name === 'slot');3056                  }3057                  if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3058                      dir.arg = processExpression(arg, context);3059                  }3060              }3061          }3062      }3063  };3064  // Important: since this function uses Node.js only dependencies, it should3065  // always be used with a leading !true check so that it can be3066  // tree-shaken from the browser build.3067  function processExpression(node, context, 3068  // some expressions like v-slot props & v-for aliases should be parsed as3069  // function params3070  asParams = false, 3071  // v-on handler values may contain multiple statements3072  asRawStatements = false, localVars = Object.create(context.identifiers)) {3073      {3074          {3075              // simple in-browser validation (same logic in 2.x)3076              validateBrowserExpression(node, context, asParams, asRawStatements);3077          }3078          return node;3079      }3080  }3081  const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3082      return processIf(node, dir, context, (ifNode, branch, isRoot) => {3083          // #1587: We need to dynamically increment the key based on the current3084          // node's sibling nodes, since chained v-if/else branches are3085          // rendered at the same depth3086          const siblings = context.parent.children;3087          let i = siblings.indexOf(ifNode);3088          let key = 0;3089          while (i-- >= 0) {3090              const sibling = siblings[i];3091              if (sibling && sibling.type === 9 /* IF */) {3092                  key += sibling.branches.length;3093              }3094          }3095          // Exit callback. Complete the codegenNode when all children have been3096          // transformed.3097          return () => {3098              if (isRoot) {3099                  ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3100              }3101              else {3102                  // attach this branch's codegen node to the v-if root.3103                  const parentCondition = getParentCondition(ifNode.codegenNode);3104                  parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3105              }3106          };3107      });3108  });3109  // target-agnostic transform used for both Client and SSR3110  function processIf(node, dir, context, processCodegen) {3111      if (dir.name !== 'else' &&3112          (!dir.exp || !dir.exp.content.trim())) {3113          const loc = dir.exp ? dir.exp.loc : node.loc;3114          context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3115          dir.exp = createSimpleExpression(`true`, false, loc);3116      }3117      if (dir.exp) {3118          validateBrowserExpression(dir.exp, context);3119      }3120      if (dir.name === 'if') {3121          const branch = createIfBranch(node, dir);3122          const ifNode = {3123              type: 9 /* IF */,3124              loc: node.loc,3125              branches: [branch]3126          };3127          context.replaceNode(ifNode);3128          if (processCodegen) {3129              return processCodegen(ifNode, branch, true);3130          }3131      }3132      else {3133          // locate the adjacent v-if3134          const siblings = context.parent.children;3135          const comments = [];3136          let i = siblings.indexOf(node);3137          while (i-- >= -1) {3138              const sibling = siblings[i];3139              if (sibling && sibling.type === 3 /* COMMENT */) {3140                  context.removeNode(sibling);3141                  comments.unshift(sibling);3142                  continue;3143              }3144              if (sibling &&3145                  sibling.type === 2 /* TEXT */ &&3146                  !sibling.content.trim().length) {3147                  context.removeNode(sibling);3148                  continue;3149              }3150              if (sibling && sibling.type === 9 /* IF */) {3151                  // Check if v-else was followed by v-else-if3152                  if (dir.name === 'else-if' &&3153                      sibling.branches[sibling.branches.length - 1].condition === undefined) {3154                      context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3155                  }3156                  // move the node to the if node's branches3157                  context.removeNode();3158                  const branch = createIfBranch(node, dir);3159                  if (comments.length &&3160                      // #3619 ignore comments if the v-if is direct child of <transition>3161                      !(context.parent &&3162                          context.parent.type === 1 /* ELEMENT */ &&3163                          isBuiltInType(context.parent.tag, 'transition'))) {3164                      branch.children = [...comments, ...branch.children];3165                  }3166                  // check if user is forcing same key on different branches3167                  {3168                      const key = branch.userKey;3169                      if (key) {3170                          sibling.branches.forEach(({ userKey }) => {3171                              if (isSameKey(userKey, key)) {3172                                  context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3173                              }3174                          });3175                      }3176                  }3177                  sibling.branches.push(branch);3178                  const onExit = processCodegen && processCodegen(sibling, branch, false);3179                  // since the branch was removed, it will not be traversed.3180                  // make sure to traverse here.3181                  traverseNode(branch, context);3182                  // call on exit3183                  if (onExit)3184                      onExit();3185                  // make sure to reset currentNode after traversal to indicate this3186                  // node has been removed.3187                  context.currentNode = null;3188              }3189              else {3190                  context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3191              }3192              break;3193          }3194      }3195  }3196  function createIfBranch(node, dir) {3197      return {3198          type: 10 /* IF_BRANCH */,3199          loc: node.loc,3200          condition: dir.name === 'else' ? undefined : dir.exp,3201          children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3202              ? node.children3203              : [node],3204          userKey: findProp(node, `key`)3205      };3206  }3207  function createCodegenNodeForBranch(branch, keyIndex, context) {3208      if (branch.condition) {3209          return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3210          // make sure to pass in asBlock: true so that the comment node call3211          // closes the current block.3212          createCallExpression(context.helper(CREATE_COMMENT), [3213              '"v-if"' ,3214              'true'3215          ]));3216      }3217      else {3218          return createChildrenCodegenNode(branch, keyIndex, context);3219      }3220  }3221  function createChildrenCodegenNode(branch, keyIndex, context) {3222      const { helper } = context;3223      const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3224      const { children } = branch;3225      const firstChild = children[0];3226      const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3227      if (needFragmentWrapper) {3228          if (children.length === 1 && firstChild.type === 11 /* FOR */) {3229              // optimize away nested fragments when child is a ForNode3230              const vnodeCall = firstChild.codegenNode;3231              injectProp(vnodeCall, keyProperty, context);3232              return vnodeCall;3233          }3234          else {3235              let patchFlag = 64 /* STABLE_FRAGMENT */;3236              let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3237              // check if the fragment actually contains a single valid child with3238              // the rest being comments3239              if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3240                  patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3241                  patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3242              }3243              return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);3244          }3245      }3246      else {3247          const ret = firstChild.codegenNode;3248          const vnodeCall = getMemoedVNodeCall(ret);3249          // Change createVNode to createBlock.3250          if (vnodeCall.type === 13 /* VNODE_CALL */) {3251              makeBlock(vnodeCall, context);3252          }3253          // inject branch key3254          injectProp(vnodeCall, keyProperty, context);3255          return ret;3256      }3257  }3258  function isSameKey(a, b) {3259      if (!a || a.type !== b.type) {3260          return false;3261      }3262      if (a.type === 6 /* ATTRIBUTE */) {3263          if (a.value.content !== b.value.content) {3264              return false;3265          }3266      }3267      else {3268          // directive3269          const exp = a.exp;3270          const branchExp = b.exp;3271          if (exp.type !== branchExp.type) {3272              return false;3273          }3274          if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3275              exp.isStatic !== branchExp.isStatic ||3276              exp.content !== branchExp.content) {3277              return false;3278          }3279      }3280      return true;3281  }3282  function getParentCondition(node) {3283      while (true) {3284          if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3285              if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3286                  node = node.alternate;3287              }3288              else {3289                  return node;3290              }3291          }3292          else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3293              node = node.value;3294          }3295      }3296  }3297  const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3298      const { helper, removeHelper } = context;3299      return processFor(node, dir, context, forNode => {3300          // create the loop render function expression now, and add the3301          // iterator on exit after all children have been traversed3302          const renderExp = createCallExpression(helper(RENDER_LIST), [3303              forNode.source3304          ]);3305          const memo = findDir(node, 'memo');3306          const keyProp = findProp(node, `key`);3307          const keyExp = keyProp &&3308              (keyProp.type === 6 /* ATTRIBUTE */3309                  ? createSimpleExpression(keyProp.value.content, true)3310                  : keyProp.exp);3311          const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3312          const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3313              forNode.source.constType > 0 /* NOT_CONSTANT */;3314          const fragmentFlag = isStableFragment3315              ? 64 /* STABLE_FRAGMENT */3316              : keyProp3317                  ? 128 /* KEYED_FRAGMENT */3318                  : 256 /* UNKEYED_FRAGMENT */;3319          forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3320              (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3321          return () => {3322              // finish the codegen now that all children have been traversed3323              let childBlock;3324              const isTemplate = isTemplateNode(node);3325              const { children } = forNode;3326              // check <template v-for> key placement3327              if (isTemplate) {3328                  node.children.some(c => {3329                      if (c.type === 1 /* ELEMENT */) {3330                          const key = findProp(c, 'key');3331                          if (key) {3332                              context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3333                              return true;3334                          }3335                      }3336                  });3337              }3338              const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3339              const slotOutlet = isSlotOutlet(node)3340                  ? node3341                  : isTemplate &&3342                      node.children.length === 1 &&3343                      isSlotOutlet(node.children[0])3344                      ? node.children[0] // api-extractor somehow fails to infer this3345                      : null;3346              if (slotOutlet) {3347                  // <slot v-for="..."> or <template v-for="..."><slot/></template>3348                  childBlock = slotOutlet.codegenNode;3349                  if (isTemplate && keyProperty) {3350                      // <template v-for="..." :key="..."><slot/></template>3351                      // we need to inject the key to the renderSlot() call.3352                      // the props for renderSlot is passed as the 3rd argument.3353                      injectProp(childBlock, keyProperty, context);3354                  }3355              }3356              else if (needFragmentWrapper) {3357                  // <template v-for="..."> with text or multi-elements3358                  // should generate a fragment block for each loop3359                  childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3360                      (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3361                          ), undefined, undefined, true, undefined, false /* isComponent */);3362              }3363              else {3364                  // Normal element v-for. Directly use the child's codegenNode3365                  // but mark it as a block.3366                  childBlock = children[0]3367                      .codegenNode;3368                  if (isTemplate && keyProperty) {3369                      injectProp(childBlock, keyProperty, context);3370                  }3371                  if (childBlock.isBlock !== !isStableFragment) {3372                      if (childBlock.isBlock) {3373                          // switch from block to vnode3374                          removeHelper(OPEN_BLOCK);3375                          removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3376                      }3377                      else {3378                          // switch from vnode to block3379                          removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3380                      }3381                  }3382                  childBlock.isBlock = !isStableFragment;3383                  if (childBlock.isBlock) {3384                      helper(OPEN_BLOCK);3385                      helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3386                  }3387                  else {3388                      helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3389                  }3390              }3391              if (memo) {3392                  const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3393                      createSimpleExpression(`_cached`)3394                  ]));3395                  loop.body = createBlockStatement([3396                      createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3397                      createCompoundExpression([3398                          `if (_cached`,3399                          ...(keyExp ? [` && _cached.key === `, keyExp] : []),3400                          ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3401                      ]),3402                      createCompoundExpression([`const _item = `, childBlock]),3403                      createSimpleExpression(`_item.memo = _memo`),3404                      createSimpleExpression(`return _item`)3405                  ]);3406                  renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3407              }3408              else {3409                  renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3410              }3411          };3412      });3413  });3414  // target-agnostic transform used for both Client and SSR3415  function processFor(node, dir, context, processCodegen) {3416      if (!dir.exp) {3417          context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3418          return;3419      }3420      const parseResult = parseForExpression(3421      // can only be simple expression because vFor transform is applied3422      // before expression transform.3423      dir.exp, context);3424      if (!parseResult) {3425          context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3426          return;3427      }3428      const { addIdentifiers, removeIdentifiers, scopes } = context;3429      const { source, value, key, index } = parseResult;3430      const forNode = {3431          type: 11 /* FOR */,3432          loc: dir.loc,3433          source,3434          valueAlias: value,3435          keyAlias: key,3436          objectIndexAlias: index,3437          parseResult,3438          children: isTemplateNode(node) ? node.children : [node]3439      };3440      context.replaceNode(forNode);3441      // bookkeeping3442      scopes.vFor++;3443      const onExit = processCodegen && processCodegen(forNode);3444      return () => {3445          scopes.vFor--;3446          if (onExit)3447              onExit();3448      };3449  }3450  const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3451  // This regex doesn't cover the case if key or index aliases have destructuring,3452  // but those do not make sense in the first place, so this works in practice.3453  const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3454  const stripParensRE = /^\(|\)$/g;3455  function parseForExpression(input, context) {3456      const loc = input.loc;3457      const exp = input.content;3458      const inMatch = exp.match(forAliasRE);3459      if (!inMatch)3460          return;3461      const [, LHS, RHS] = inMatch;3462      const result = {3463          source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3464          value: undefined,3465          key: undefined,3466          index: undefined3467      };3468      {3469          validateBrowserExpression(result.source, context);3470      }3471      let valueContent = LHS.trim().replace(stripParensRE, '').trim();3472      const trimmedOffset = LHS.indexOf(valueContent);3473      const iteratorMatch = valueContent.match(forIteratorRE);3474      if (iteratorMatch) {3475          valueContent = valueContent.replace(forIteratorRE, '').trim();3476          const keyContent = iteratorMatch[1].trim();3477          let keyOffset;3478          if (keyContent) {3479              keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3480              result.key = createAliasExpression(loc, keyContent, keyOffset);3481              {3482                  validateBrowserExpression(result.key, context, true);3483              }3484          }3485          if (iteratorMatch[2]) {3486              const indexContent = iteratorMatch[2].trim();3487              if (indexContent) {3488                  result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3489                      ? keyOffset + keyContent.length3490                      : trimmedOffset + valueContent.length));3491                  {3492                      validateBrowserExpression(result.index, context, true);3493                  }3494              }3495          }3496      }3497      if (valueContent) {3498          result.value = createAliasExpression(loc, valueContent, trimmedOffset);3499          {3500              validateBrowserExpression(result.value, context, true);3501          }3502      }3503      return result;3504  }3505  function createAliasExpression(range, content, offset) {3506      return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3507  }3508  function createForLoopParams({ value, key, index }, memoArgs = []) {3509      return createParamsList([value, key, index, ...memoArgs]);3510  }3511  function createParamsList(args) {3512      let i = args.length;3513      while (i--) {3514          if (args[i])3515              break;3516      }3517      return args3518          .slice(0, i + 1)3519          .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3520  }3521  const defaultFallback = createSimpleExpression(`undefined`, false);3522  // A NodeTransform that:3523  // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3524  //    by transformExpression. This is only applied in non-browser builds with3525  //    { prefixIdentifiers: true }.3526  // 2. Track v-slot depths so that we know a slot is inside another slot.3527  //    Note the exit callback is executed before buildSlots() on the same node,3528  //    so only nested slots see positive numbers.3529  const trackSlotScopes = (node, context) => {3530      if (node.type === 1 /* ELEMENT */ &&3531          (node.tagType === 1 /* COMPONENT */ ||3532              node.tagType === 3 /* TEMPLATE */)) {3533          // We are only checking non-empty v-slot here3534          // since we only care about slots that introduce scope variables.3535          const vSlot = findDir(node, 'slot');3536          if (vSlot) {3537              vSlot.exp;3538              context.scopes.vSlot++;3539              return () => {3540                  context.scopes.vSlot--;3541              };3542          }3543      }3544  };3545  // A NodeTransform that tracks scope identifiers for scoped slots with v-for.3546  // This transform is only applied in non-browser builds with { prefixIdentifiers: true }3547  const trackVForSlotScopes = (node, context) => {3548      let vFor;3549      if (isTemplateNode(node) &&3550          node.props.some(isVSlot) &&3551          (vFor = findDir(node, 'for'))) {3552          const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3553          if (result) {3554              const { value, key, index } = result;3555              const { addIdentifiers, removeIdentifiers } = context;3556              value && addIdentifiers(value);3557              key && addIdentifiers(key);3558              index && addIdentifiers(index);3559              return () => {3560                  value && removeIdentifiers(value);3561                  key && removeIdentifiers(key);3562                  index && removeIdentifiers(index);3563              };3564          }3565      }3566  };3567  const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3568  // Instead of being a DirectiveTransform, v-slot processing is called during3569  // transformElement to build the slots object for a component.3570  function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3571      context.helper(WITH_CTX);3572      const { children, loc } = node;3573      const slotsProperties = [];3574      const dynamicSlots = [];3575      // If the slot is inside a v-for or another v-slot, force it to be dynamic3576      // since it likely uses a scope variable.3577      let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3578      // 1. Check for slot with slotProps on component itself.3579      //    <Comp v-slot="{ prop }"/>3580      const onComponentSlot = findDir(node, 'slot', true);3581      if (onComponentSlot) {3582          const { arg, exp } = onComponentSlot;3583          if (arg && !isStaticExp(arg)) {3584              hasDynamicSlots = true;3585          }3586          slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3587      }3588      // 2. Iterate through children and check for template slots3589      //    <template v-slot:foo="{ prop }">3590      let hasTemplateSlots = false;3591      let hasNamedDefaultSlot = false;3592      const implicitDefaultChildren = [];3593      const seenSlotNames = new Set();3594      for (let i = 0; i < children.length; i++) {3595          const slotElement = children[i];3596          let slotDir;3597          if (!isTemplateNode(slotElement) ||3598              !(slotDir = findDir(slotElement, 'slot', true))) {3599              // not a <template v-slot>, skip.3600              if (slotElement.type !== 3 /* COMMENT */) {3601                  implicitDefaultChildren.push(slotElement);3602              }3603              continue;3604          }3605          if (onComponentSlot) {3606              // already has on-component slot - this is incorrect usage.3607              context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3608              break;3609          }3610          hasTemplateSlots = true;3611          const { children: slotChildren, loc: slotLoc } = slotElement;3612          const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3613          // check if name is dynamic.3614          let staticSlotName;3615          if (isStaticExp(slotName)) {3616              staticSlotName = slotName ? slotName.content : `default`;3617          }3618          else {3619              hasDynamicSlots = true;3620          }3621          const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3622          // check if this slot is conditional (v-if/v-for)3623          let vIf;3624          let vElse;3625          let vFor;3626          if ((vIf = findDir(slotElement, 'if'))) {3627              hasDynamicSlots = true;3628              dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3629          }3630          else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3631              // find adjacent v-if3632              let j = i;3633              let prev;3634              while (j--) {3635                  prev = children[j];3636                  if (prev.type !== 3 /* COMMENT */) {3637                      break;3638                  }3639              }3640              if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3641                  // remove node3642                  children.splice(i, 1);3643                  i--;3644                  // attach this slot to previous conditional3645                  let conditional = dynamicSlots[dynamicSlots.length - 1];3646                  while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3647                      conditional = conditional.alternate;3648                  }3649                  conditional.alternate = vElse.exp3650                      ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3651                      : buildDynamicSlot(slotName, slotFunction);3652              }3653              else {3654                  context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3655              }3656          }3657          else if ((vFor = findDir(slotElement, 'for'))) {3658              hasDynamicSlots = true;3659              const parseResult = vFor.parseResult ||3660                  parseForExpression(vFor.exp, context);3661              if (parseResult) {3662                  // Render the dynamic slots as an array and add it to the createSlot()3663                  // args. The runtime knows how to handle it appropriately.3664                  dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3665                      parseResult.source,3666                      createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3667                  ]));3668              }3669              else {3670                  context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3671              }3672          }3673          else {3674              // check duplicate static names3675              if (staticSlotName) {3676                  if (seenSlotNames.has(staticSlotName)) {3677                      context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3678                      continue;3679                  }3680                  seenSlotNames.add(staticSlotName);3681                  if (staticSlotName === 'default') {3682                      hasNamedDefaultSlot = true;3683                  }3684              }3685              slotsProperties.push(createObjectProperty(slotName, slotFunction));3686          }3687      }3688      if (!onComponentSlot) {3689          const buildDefaultSlotProperty = (props, children) => {3690              const fn = buildSlotFn(props, children, loc);3691              if (context.compatConfig) {3692                  fn.isNonScopedSlot = true;3693              }3694              return createObjectProperty(`default`, fn);3695          };3696          if (!hasTemplateSlots) {3697              // implicit default slot (on component)3698              slotsProperties.push(buildDefaultSlotProperty(undefined, children));3699          }3700          else if (implicitDefaultChildren.length &&3701              // #37663702              // with whitespace: 'preserve', whitespaces between slots will end up in3703              // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3704              implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3705              // implicit default slot (mixed with named slots)3706              if (hasNamedDefaultSlot) {3707                  context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3708              }3709              else {3710                  slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3711              }3712          }3713      }3714      const slotFlag = hasDynamicSlots3715          ? 2 /* DYNAMIC */3716          : hasForwardedSlots(node.children)3717              ? 3 /* FORWARDED */3718              : 1 /* STABLE */;3719      let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3720      // 2 = compiled but dynamic = can skip normalization, but must run diff3721      // 1 = compiled and static = can skip normalization AND diff as optimized3722      createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);3723      if (dynamicSlots.length) {3724          slots = createCallExpression(context.helper(CREATE_SLOTS), [3725              slots,3726              createArrayExpression(dynamicSlots)3727          ]);3728      }3729      return {3730          slots,3731          hasDynamicSlots3732      };3733  }3734  function buildDynamicSlot(name, fn) {3735      return createObjectExpression([3736          createObjectProperty(`name`, name),3737          createObjectProperty(`fn`, fn)3738      ]);3739  }3740  function hasForwardedSlots(children) {3741      for (let i = 0; i < children.length; i++) {3742          const child = children[i];3743          switch (child.type) {3744              case 1 /* ELEMENT */:3745                  if (child.tagType === 2 /* SLOT */ ||3746                      hasForwardedSlots(child.children)) {3747                      return true;3748                  }3749                  break;3750              case 9 /* IF */:3751                  if (hasForwardedSlots(child.branches))3752                      return true;3753                  break;3754              case 10 /* IF_BRANCH */:3755              case 11 /* FOR */:3756                  if (hasForwardedSlots(child.children))3757                      return true;3758                  break;3759          }3760      }3761      return false;3762  }3763  function isNonWhitespaceContent(node) {3764      if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3765          return true;3766      return node.type === 2 /* TEXT */3767          ? !!node.content.trim()3768          : isNonWhitespaceContent(node.content);3769  }3770  // some directive transforms (e.g. v-model) may return a symbol for runtime3771  // import, which should be used instead of a resolveDirective call.3772  const directiveImportMap = new WeakMap();3773  // generate a JavaScript AST for this element's codegen3774  const transformElement = (node, context) => {3775      // perform the work on exit, after all child expressions have been3776      // processed and merged.3777      return function postTransformElement() {3778          node = context.currentNode;3779          if (!(node.type === 1 /* ELEMENT */ &&3780              (node.tagType === 0 /* ELEMENT */ ||3781                  node.tagType === 1 /* COMPONENT */))) {3782              return;3783          }3784          const { tag, props } = node;3785          const isComponent = node.tagType === 1 /* COMPONENT */;3786          // The goal of the transform is to create a codegenNode implementing the3787          // VNodeCall interface.3788          let vnodeTag = isComponent3789              ? resolveComponentType(node, context)3790              : `"${tag}"`;3791          const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3792          let vnodeProps;3793          let vnodeChildren;3794          let vnodePatchFlag;3795          let patchFlag = 0;3796          let vnodeDynamicProps;3797          let dynamicPropNames;3798          let vnodeDirectives;3799          let shouldUseBlock = 3800          // dynamic component may resolve to plain elements3801          isDynamicComponent ||3802              vnodeTag === TELEPORT ||3803              vnodeTag === SUSPENSE ||3804              (!isComponent &&3805                  // <svg> and <foreignObject> must be forced into blocks so that block3806                  // updates inside get proper isSVG flag at runtime. (#639, #643)3807                  // This is technically web-specific, but splitting the logic out of core3808                  // leads to too much unnecessary complexity.3809                  (tag === 'svg' || tag === 'foreignObject'));3810          // props3811          if (props.length > 0) {3812              const propsBuildResult = buildProps(node, context);3813              vnodeProps = propsBuildResult.props;3814              patchFlag = propsBuildResult.patchFlag;3815              dynamicPropNames = propsBuildResult.dynamicPropNames;3816              const directives = propsBuildResult.directives;3817              vnodeDirectives =3818                  directives && directives.length3819                      ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3820                      : undefined;3821              if (propsBuildResult.shouldUseBlock) {3822                  shouldUseBlock = true;3823              }3824          }3825          // children3826          if (node.children.length > 0) {3827              if (vnodeTag === KEEP_ALIVE) {3828                  // Although a built-in component, we compile KeepAlive with raw children3829                  // instead of slot functions so that it can be used inside Transition3830                  // or other Transition-wrapping HOCs.3831                  // To ensure correct updates with block optimizations, we need to:3832                  // 1. Force keep-alive into a block. This avoids its children being3833                  //    collected by a parent block.3834                  shouldUseBlock = true;3835                  // 2. Force keep-alive to always be updated, since it uses raw children.3836                  patchFlag |= 1024 /* DYNAMIC_SLOTS */;3837                  if (node.children.length > 1) {3838                      context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3839                          start: node.children[0].loc.start,3840                          end: node.children[node.children.length - 1].loc.end,3841                          source: ''3842                      }));3843                  }3844              }3845              const shouldBuildAsSlots = isComponent &&3846                  // Teleport is not a real component and has dedicated runtime handling3847                  vnodeTag !== TELEPORT &&3848                  // explained above.3849                  vnodeTag !== KEEP_ALIVE;3850              if (shouldBuildAsSlots) {3851                  const { slots, hasDynamicSlots } = buildSlots(node, context);3852                  vnodeChildren = slots;3853                  if (hasDynamicSlots) {3854                      patchFlag |= 1024 /* DYNAMIC_SLOTS */;3855                  }3856              }3857              else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3858                  const child = node.children[0];3859                  const type = child.type;3860                  // check for dynamic text children3861                  const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3862                      type === 8 /* COMPOUND_EXPRESSION */;3863                  if (hasDynamicTextChild &&3864                      getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3865                      patchFlag |= 1 /* TEXT */;3866                  }3867                  // pass directly if the only child is a text node3868                  // (plain / interpolation / expression)3869                  if (hasDynamicTextChild || type === 2 /* TEXT */) {3870                      vnodeChildren = child;3871                  }3872                  else {3873                      vnodeChildren = node.children;3874                  }3875              }3876              else {3877                  vnodeChildren = node.children;3878              }3879          }3880          // patchFlag & dynamicPropNames3881          if (patchFlag !== 0) {3882              {3883                  if (patchFlag < 0) {3884                      // special flags (negative and mutually exclusive)3885                      vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;3886                  }3887                  else {3888                      // bitwise flags3889                      const flagNames = Object.keys(PatchFlagNames)3890                          .map(Number)3891                          .filter(n => n > 0 && patchFlag & n)3892                          .map(n => PatchFlagNames[n])3893                          .join(`, `);3894                      vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3895                  }3896              }3897              if (dynamicPropNames && dynamicPropNames.length) {3898                  vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3899              }3900          }3901          node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);3902      };3903  };3904  function resolveComponentType(node, context, ssr = false) {3905      let { tag } = node;3906      // 1. dynamic component3907      const isExplicitDynamic = isComponentTag(tag);3908      const isProp = findProp(node, 'is');3909      if (isProp) {3910          if (isExplicitDynamic ||3911              (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3912              const exp = isProp.type === 6 /* ATTRIBUTE */3913                  ? isProp.value && createSimpleExpression(isProp.value.content, true)3914                  : isProp.exp;3915              if (exp) {3916                  return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3917                      exp3918                  ]);3919              }3920          }3921          else if (isProp.type === 6 /* ATTRIBUTE */ &&3922              isProp.value.content.startsWith('vue:')) {3923              // <button is="vue:xxx">3924              // if not <component>, only is value that starts with "vue:" will be3925              // treated as component by the parse phase and reach here, unless it's3926              // compat mode where all is values are considered components3927              tag = isProp.value.content.slice(4);3928          }3929      }3930      // 1.5 v-is (TODO: Deprecate)3931      const isDir = !isExplicitDynamic && findDir(node, 'is');3932      if (isDir && isDir.exp) {3933          return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3934              isDir.exp3935          ]);3936      }3937      // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3938      const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3939      if (builtIn) {3940          // built-ins are simply fallthroughs / have special handling during ssr3941          // so we don't need to import their runtime equivalents3942          if (!ssr)3943              context.helper(builtIn);3944          return builtIn;3945      }3946      // 5. user component (resolve)3947      context.helper(RESOLVE_COMPONENT);3948      context.components.add(tag);3949      return toValidAssetId(tag, `component`);3950  }3951  function buildProps(node, context, props = node.props, ssr = false) {3952      const { tag, loc: elementLoc, children } = node;3953      const isComponent = node.tagType === 1 /* COMPONENT */;3954      let properties = [];3955      const mergeArgs = [];3956      const runtimeDirectives = [];3957      const hasChildren = children.length > 0;3958      let shouldUseBlock = false;3959      // patchFlag analysis3960      let patchFlag = 0;3961      let hasRef = false;3962      let hasClassBinding = false;3963      let hasStyleBinding = false;3964      let hasHydrationEventBinding = false;3965      let hasDynamicKeys = false;3966      let hasVnodeHook = false;3967      const dynamicPropNames = [];3968      const analyzePatchFlag = ({ key, value }) => {3969          if (isStaticExp(key)) {3970              const name = key.content;3971              const isEventHandler = isOn(name);3972              if (!isComponent &&3973                  isEventHandler &&3974                  // omit the flag for click handlers because hydration gives click3975                  // dedicated fast path.3976                  name.toLowerCase() !== 'onclick' &&3977                  // omit v-model handlers3978                  name !== 'onUpdate:modelValue' &&3979                  // omit onVnodeXXX hooks3980                  !isReservedProp(name)) {3981                  hasHydrationEventBinding = true;3982              }3983              if (isEventHandler && isReservedProp(name)) {3984                  hasVnodeHook = true;3985              }3986              if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||3987                  ((value.type === 4 /* SIMPLE_EXPRESSION */ ||3988                      value.type === 8 /* COMPOUND_EXPRESSION */) &&3989                      getConstantType(value, context) > 0)) {3990                  // skip if the prop is a cached handler or has constant value3991                  return;3992              }3993              if (name === 'ref') {3994                  hasRef = true;3995              }3996              else if (name === 'class') {3997                  hasClassBinding = true;3998              }3999              else if (name === 'style') {4000                  hasStyleBinding = true;4001              }4002              else if (name !== 'key' && !dynamicPropNames.includes(name)) {4003                  dynamicPropNames.push(name);4004              }4005              // treat the dynamic class and style binding of the component as dynamic props4006              if (isComponent &&4007                  (name === 'class' || name === 'style') &&4008                  !dynamicPropNames.includes(name)) {4009                  dynamicPropNames.push(name);4010              }4011          }4012          else {4013              hasDynamicKeys = true;4014          }4015      };4016      for (let i = 0; i < props.length; i++) {4017          // static attribute4018          const prop = props[i];4019          if (prop.type === 6 /* ATTRIBUTE */) {4020              const { loc, name, value } = prop;4021              let isStatic = true;4022              if (name === 'ref') {4023                  hasRef = true;4024                  if (context.scopes.vFor > 0) {4025                      properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4026                  }4027              }4028              // skip is on <component>, or is="vue:xxx"4029              if (name === 'is' &&4030                  (isComponentTag(tag) ||4031                      (value && value.content.startsWith('vue:')) ||4032                      (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4033                  continue;4034              }4035              properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));4036          }4037          else {4038              // directives4039              const { name, arg, exp, loc } = prop;4040              const isVBind = name === 'bind';4041              const isVOn = name === 'on';4042              // skip v-slot - it is handled by its dedicated transform.4043              if (name === 'slot') {4044                  if (!isComponent) {4045                      context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4046                  }4047                  continue;4048              }4049              // skip v-once/v-memo - they are handled by dedicated transforms.4050              if (name === 'once' || name === 'memo') {4051                  continue;4052              }4053              // skip v-is and :is on <component>4054              if (name === 'is' ||4055                  (isVBind &&4056                      isStaticArgOf(arg, 'is') &&4057                      (isComponentTag(tag) ||4058                          (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4059                  continue;4060              }4061              // skip v-on in SSR compilation4062              if (isVOn && ssr) {4063                  continue;4064              }4065              if (4066              // #938: elements with dynamic keys should be forced into blocks4067              (isVBind && isStaticArgOf(arg, 'key')) ||4068                  // inline before-update hooks need to force block so that it is invoked4069                  // before children4070                  (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {4071                  shouldUseBlock = true;4072              }4073              if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {4074                  properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4075              }4076              // special case for v-bind and v-on with no argument4077              if (!arg && (isVBind || isVOn)) {4078                  hasDynamicKeys = true;4079                  if (exp) {4080                      if (properties.length) {4081                          mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4082                          properties = [];4083                      }4084                      if (isVBind) {4085                          {4086                              // 2.x v-bind object order compat4087                              {4088                                  const hasOverridableKeys = mergeArgs.some(arg => {4089                                      if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4090                                          return arg.properties.some(({ key }) => {4091                                              if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4092                                                  !key.isStatic) {4093                                                  return true;4094                                              }4095                                              return (key.content !== 'class' &&4096                                                  key.content !== 'style' &&4097                                                  !isOn(key.content));4098                                          });4099                                      }4100                                      else {4101                                          // dynamic expression4102                                          return true;4103                                      }4104                                  });4105                                  if (hasOverridableKeys) {4106                                      checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4107                                  }4108                              }4109                              if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4110                                  mergeArgs.unshift(exp);4111                                  continue;4112                              }4113                          }4114                          mergeArgs.push(exp);4115                      }4116                      else {4117                          // v-on="obj" -> toHandlers(obj)4118                          mergeArgs.push({4119                              type: 14 /* JS_CALL_EXPRESSION */,4120                              loc,4121                              callee: context.helper(TO_HANDLERS),4122                              arguments: [exp]4123                          });4124                      }4125                  }4126                  else {4127                      context.onError(createCompilerError(isVBind4128                          ? 34 /* X_V_BIND_NO_EXPRESSION */4129                          : 35 /* X_V_ON_NO_EXPRESSION */, loc));4130                  }4131                  continue;4132              }4133              const directiveTransform = context.directiveTransforms[name];4134              if (directiveTransform) {4135                  // has built-in directive transform.4136                  const { props, needRuntime } = directiveTransform(prop, node, context);4137                  !ssr && props.forEach(analyzePatchFlag);4138                  properties.push(...props);4139                  if (needRuntime) {4140                      runtimeDirectives.push(prop);4141                      if (isSymbol(needRuntime)) {4142                          directiveImportMap.set(prop, needRuntime);4143                      }4144                  }4145              }4146              else {4147                  // no built-in transform, this is a user custom directive.4148                  runtimeDirectives.push(prop);4149                  // custom dirs may use beforeUpdate so they need to force blocks4150                  // to ensure before-update gets called before children update4151                  if (hasChildren) {4152                      shouldUseBlock = true;4153                  }4154              }4155          }4156      }4157      let propsExpression = undefined;4158      // has v-bind="object" or v-on="object", wrap with mergeProps4159      if (mergeArgs.length) {4160          if (properties.length) {4161              mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4162          }4163          if (mergeArgs.length > 1) {4164              propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4165          }4166          else {4167              // single v-bind with nothing else - no need for a mergeProps call4168              propsExpression = mergeArgs[0];4169          }4170      }4171      else if (properties.length) {4172          propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4173      }4174      // patchFlag analysis4175      if (hasDynamicKeys) {4176          patchFlag |= 16 /* FULL_PROPS */;4177      }4178      else {4179          if (hasClassBinding && !isComponent) {4180              patchFlag |= 2 /* CLASS */;4181          }4182          if (hasStyleBinding && !isComponent) {4183              patchFlag |= 4 /* STYLE */;4184          }4185          if (dynamicPropNames.length) {4186              patchFlag |= 8 /* PROPS */;4187          }4188          if (hasHydrationEventBinding) {4189              patchFlag |= 32 /* HYDRATE_EVENTS */;4190          }4191      }4192      if (!shouldUseBlock &&4193          (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4194          (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4195          patchFlag |= 512 /* NEED_PATCH */;4196      }4197      // pre-normalize props, SSR is skipped for now4198      if (!context.inSSR && propsExpression) {4199          switch (propsExpression.type) {4200              case 15 /* JS_OBJECT_EXPRESSION */:4201                  // means that there is no v-bind,4202                  // but still need to deal with dynamic key binding4203                  let classKeyIndex = -1;4204                  let styleKeyIndex = -1;4205                  let hasDynamicKey = false;4206                  for (let i = 0; i < propsExpression.properties.length; i++) {4207                      const key = propsExpression.properties[i].key;4208                      if (isStaticExp(key)) {4209                          if (key.content === 'class') {4210                              classKeyIndex = i;4211                          }4212                          else if (key.content === 'style') {4213                              styleKeyIndex = i;4214                          }4215                      }4216                      else if (!key.isHandlerKey) {4217                          hasDynamicKey = true;4218                      }4219                  }4220                  const classProp = propsExpression.properties[classKeyIndex];4221                  const styleProp = propsExpression.properties[styleKeyIndex];4222                  // no dynamic key4223                  if (!hasDynamicKey) {4224                      if (classProp && !isStaticExp(classProp.value)) {4225                          classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4226                      }4227                      if (styleProp &&4228                          !isStaticExp(styleProp.value) &&4229                          // the static style is compiled into an object,4230                          // so use `hasStyleBinding` to ensure that it is a dynamic style binding4231                          (hasStyleBinding ||4232                              // v-bind:style and style both exist,4233                              // v-bind:style with static literal object4234                              styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4235                          styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4236                      }4237                  }4238                  else {4239                      // dynamic key binding, wrap with `normalizeProps`4240                      propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4241                  }4242                  break;4243              case 14 /* JS_CALL_EXPRESSION */:4244                  // mergeProps call, do nothing4245                  break;4246              default:4247                  // single v-bind4248                  propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4249                      createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4250                          propsExpression4251                      ])4252                  ]);4253                  break;4254          }4255      }4256      return {4257          props: propsExpression,4258          directives: runtimeDirectives,4259          patchFlag,4260          dynamicPropNames,4261          shouldUseBlock4262      };4263  }4264  // Dedupe props in an object literal.4265  // Literal duplicated attributes would have been warned during the parse phase,4266  // however, it's possible to encounter duplicated `onXXX` handlers with different4267  // modifiers. We also need to merge static and dynamic class / style attributes.4268  // - onXXX handlers / style: merge into array4269  // - class: merge into single expression with concatenation4270  function dedupeProperties(properties) {4271      const knownProps = new Map();4272      const deduped = [];4273      for (let i = 0; i < properties.length; i++) {4274          const prop = properties[i];4275          // dynamic keys are always allowed4276          if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4277              deduped.push(prop);4278              continue;4279          }4280          const name = prop.key.content;4281          const existing = knownProps.get(name);4282          if (existing) {4283              if (name === 'style' || name === 'class' || isOn(name)) {4284                  mergeAsArray(existing, prop);4285              }4286              // unexpected duplicate, should have emitted error during parse4287          }4288          else {4289              knownProps.set(name, prop);4290              deduped.push(prop);4291          }4292      }4293      return deduped;4294  }4295  function mergeAsArray(existing, incoming) {4296      if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4297          existing.value.elements.push(incoming.value);4298      }4299      else {4300          existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4301      }4302  }4303  function buildDirectiveArgs(dir, context) {4304      const dirArgs = [];4305      const runtime = directiveImportMap.get(dir);4306      if (runtime) {4307          // built-in directive with runtime4308          dirArgs.push(context.helperString(runtime));4309      }4310      else {4311          {4312              // inject statement for resolving directive4313              context.helper(RESOLVE_DIRECTIVE);4314              context.directives.add(dir.name);4315              dirArgs.push(toValidAssetId(dir.name, `directive`));4316          }4317      }4318      const { loc } = dir;4319      if (dir.exp)4320          dirArgs.push(dir.exp);4321      if (dir.arg) {4322          if (!dir.exp) {4323              dirArgs.push(`void 0`);4324          }4325          dirArgs.push(dir.arg);4326      }4327      if (Object.keys(dir.modifiers).length) {4328          if (!dir.arg) {4329              if (!dir.exp) {4330                  dirArgs.push(`void 0`);4331              }4332              dirArgs.push(`void 0`);4333          }4334          const trueExpression = createSimpleExpression(`true`, false, loc);4335          dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4336      }4337      return createArrayExpression(dirArgs, dir.loc);4338  }4339  function stringifyDynamicPropNames(props) {4340      let propsNamesString = `[`;4341      for (let i = 0, l = props.length; i < l; i++) {4342          propsNamesString += JSON.stringify(props[i]);4343          if (i < l - 1)4344              propsNamesString += ', ';4345      }4346      return propsNamesString + `]`;4347  }4348  function isComponentTag(tag) {4349      return tag === 'component' || tag === 'Component';4350  }4351  const transformSlotOutlet = (node, context) => {4352      if (isSlotOutlet(node)) {4353          const { children, loc } = node;4354          const { slotName, slotProps } = processSlotOutlet(node, context);4355          const slotArgs = [4356              context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4357              slotName,4358              '{}',4359              'undefined',4360              'true'4361          ];4362          let expectedLen = 2;4363          if (slotProps) {4364              slotArgs[2] = slotProps;4365              expectedLen = 3;4366          }4367          if (children.length) {4368              slotArgs[3] = createFunctionExpression([], children, false, false, loc);4369              expectedLen = 4;4370          }4371          if (context.scopeId && !context.slotted) {4372              expectedLen = 5;4373          }4374          slotArgs.splice(expectedLen); // remove unused arguments4375          node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4376      }4377  };4378  function processSlotOutlet(node, context) {4379      let slotName = `"default"`;4380      let slotProps = undefined;4381      const nonNameProps = [];4382      for (let i = 0; i < node.props.length; i++) {4383          const p = node.props[i];4384          if (p.type === 6 /* ATTRIBUTE */) {4385              if (p.value) {4386                  if (p.name === 'name') {4387                      slotName = JSON.stringify(p.value.content);4388                  }4389                  else {4390                      p.name = camelize(p.name);4391                      nonNameProps.push(p);4392                  }4393              }4394          }4395          else {4396              if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {4397                  if (p.exp)4398                      slotName = p.exp;4399              }4400              else {4401                  if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4402                      p.arg.content = camelize(p.arg.content);4403                  }4404                  nonNameProps.push(p);4405              }4406          }4407      }4408      if (nonNameProps.length > 0) {4409          const { props, directives } = buildProps(node, context, nonNameProps);4410          slotProps = props;4411          if (directives.length) {4412              context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4413          }4414      }4415      return {4416          slotName,4417          slotProps4418      };4419  }4420  const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4421  const transformOn = (dir, node, context, augmentor) => {4422      const { loc, modifiers, arg } = dir;4423      if (!dir.exp && !modifiers.length) {4424          context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4425      }4426      let eventName;4427      if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4428          if (arg.isStatic) {4429              let rawName = arg.content;4430              // TODO deprecate @vnodeXXX usage4431              if (rawName.startsWith('vue:')) {4432                  rawName = `vnode-${rawName.slice(4)}`;4433              }4434              // for all event listeners, auto convert it to camelCase. See issue #22494435              eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);4436          }4437          else {4438              // #23884439              eventName = createCompoundExpression([4440                  `${context.helperString(TO_HANDLER_KEY)}(`,4441                  arg,4442                  `)`4443              ]);4444          }4445      }4446      else {4447          // already a compound expression.4448          eventName = arg;4449          eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4450          eventName.children.push(`)`);4451      }4452      // handler processing4453      let exp = dir.exp;4454      if (exp && !exp.content.trim()) {4455          exp = undefined;4456      }4457      let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4458      if (exp) {4459          const isMemberExp = isMemberExpression(exp.content);4460          const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4461          const hasMultipleStatements = exp.content.includes(`;`);4462          {4463              validateBrowserExpression(exp, context, false, hasMultipleStatements);4464          }4465          if (isInlineStatement || (shouldCache && isMemberExp)) {4466              // wrap inline statement in a function expression4467              exp = createCompoundExpression([4468                  `${isInlineStatement4469                    ? `$event`4470                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4471                  exp,4472                  hasMultipleStatements ? `}` : `)`4473              ]);4474          }4475      }4476      let ret = {4477          props: [4478              createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4479          ]4480      };4481      // apply extended compiler augmentor4482      if (augmentor) {4483          ret = augmentor(ret);4484      }4485      if (shouldCache) {4486          // cache handlers so that it's always the same handler being passed down.4487          // this avoids unnecessary re-renders when users use inline handlers on4488          // components.4489          ret.props[0].value = context.cache(ret.props[0].value);4490      }4491      // mark the key as handler for props normalization check4492      ret.props.forEach(p => (p.key.isHandlerKey = true));4493      return ret;4494  };4495  // v-bind without arg is handled directly in ./transformElements.ts due to it affecting4496  // codegen for the entire props object. This transform here is only for v-bind4497  // *with* args.4498  const transformBind = (dir, _node, context) => {4499      const { exp, modifiers, loc } = dir;4500      const arg = dir.arg;4501      if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {4502          arg.children.unshift(`(`);4503          arg.children.push(`) || ""`);4504      }4505      else if (!arg.isStatic) {4506          arg.content = `${arg.content} || ""`;4507      }4508      // .sync is replaced by v-model:arg4509      if (modifiers.includes('camel')) {4510          if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4511              if (arg.isStatic) {4512                  arg.content = camelize(arg.content);4513              }4514              else {4515                  arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;4516              }4517          }4518          else {4519              arg.children.unshift(`${context.helperString(CAMELIZE)}(`);4520              arg.children.push(`)`);4521          }4522      }4523      if (!context.inSSR) {4524          if (modifiers.includes('prop')) {4525              injectPrefix(arg, '.');4526          }4527          if (modifiers.includes('attr')) {4528              injectPrefix(arg, '^');4529          }4530      }4531      if (!exp ||4532          (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {4533          context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));4534          return {4535              props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]4536          };4537      }4538      return {4539          props: [createObjectProperty(arg, exp)]4540      };4541  };4542  const injectPrefix = (arg, prefix) => {4543      if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4544          if (arg.isStatic) {4545              arg.content = prefix + arg.content;4546          }4547          else {4548              arg.content = `\`${prefix}\${${arg.content}}\``;4549          }4550      }4551      else {4552          arg.children.unshift(`'${prefix}' + (`);4553          arg.children.push(`)`);4554      }4555  };4556  // Merge adjacent text nodes and expressions into a single expression4557  // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.4558  const transformText = (node, context) => {4559      if (node.type === 0 /* ROOT */ ||4560          node.type === 1 /* ELEMENT */ ||4561          node.type === 11 /* FOR */ ||4562          node.type === 10 /* IF_BRANCH */) {4563          // perform the transform on node exit so that all expressions have already4564          // been processed.4565          return () => {4566              const children = node.children;4567              let currentContainer = undefined;4568              let hasText = false;4569              for (let i = 0; i < children.length; i++) {4570                  const child = children[i];4571                  if (isText(child)) {4572                      hasText = true;4573                      for (let j = i + 1; j < children.length; j++) {4574                          const next = children[j];4575                          if (isText(next)) {4576                              if (!currentContainer) {4577                                  currentContainer = children[i] = {4578                                      type: 8 /* COMPOUND_EXPRESSION */,4579                                      loc: child.loc,4580                                      children: [child]4581                                  };4582                              }4583                              // merge adjacent text node into current4584                              currentContainer.children.push(` + `, next);4585                              children.splice(j, 1);4586                              j--;4587                          }4588                          else {4589                              currentContainer = undefined;4590                              break;4591                          }4592                      }4593                  }4594              }4595              if (!hasText ||4596                  // if this is a plain element with a single text child, leave it4597                  // as-is since the runtime has dedicated fast path for this by directly4598                  // setting textContent of the element.4599                  // for component root it's always normalized anyway.4600                  (children.length === 1 &&4601                      (node.type === 0 /* ROOT */ ||4602                          (node.type === 1 /* ELEMENT */ &&4603                              node.tagType === 0 /* ELEMENT */ &&4604                              // #37564605                              // custom directives can potentially add DOM elements arbitrarily,4606                              // we need to avoid setting textContent of the element at runtime4607                              // to avoid accidentally overwriting the DOM elements added4608                              // by the user through custom directives.4609                              !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&4610                                  !context.directiveTransforms[p.name]) &&4611                              // in compat mode, <template> tags with no special directives4612                              // will be rendered as a fragment so its children must be4613                              // converted into vnodes.4614                              !(node.tag === 'template'))))) {4615                  return;4616              }4617              // pre-convert text nodes into createTextVNode(text) calls to avoid4618              // runtime normalization.4619              for (let i = 0; i < children.length; i++) {4620                  const child = children[i];4621                  if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {4622                      const callArgs = [];4623                      // createTextVNode defaults to single whitespace, so if it is a4624                      // single space the code could be an empty call to save bytes.4625                      if (child.type !== 2 /* TEXT */ || child.content !== ' ') {4626                          callArgs.push(child);4627                      }4628                      // mark dynamic text with flag so it gets patched inside a block4629                      if (!context.ssr &&4630                          getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4631                          callArgs.push(1 /* TEXT */ +4632                              (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));4633                      }4634                      children[i] = {4635                          type: 12 /* TEXT_CALL */,4636                          content: child,4637                          loc: child.loc,4638                          codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)4639                      };4640                  }4641              }4642          };4643      }4644  };4645  const seen = new WeakSet();4646  const transformOnce = (node, context) => {4647      if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {4648          if (seen.has(node) || context.inVOnce) {4649              return;4650          }4651          seen.add(node);4652          context.inVOnce = true;4653          context.helper(SET_BLOCK_TRACKING);4654          return () => {4655              context.inVOnce = false;4656              const cur = context.currentNode;4657              if (cur.codegenNode) {4658                  cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);4659              }4660          };4661      }4662  };4663  const transformModel = (dir, node, context) => {4664      const { exp, arg } = dir;4665      if (!exp) {4666          context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));4667          return createTransformProps();4668      }4669      const rawExp = exp.loc.source;4670      const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;4671      // im SFC <script setup> inline mode, the exp may have been transformed into4672      // _unref(exp)4673      context.bindingMetadata[rawExp];4674      const maybeRef = !true    /* SETUP_CONST */;4675      if (!expString.trim() ||4676          (!isMemberExpression(expString) && !maybeRef)) {4677          context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));4678          return createTransformProps();4679      }4680      const propName = arg ? arg : createSimpleExpression('modelValue', true);4681      const eventName = arg4682          ? isStaticExp(arg)4683              ? `onUpdate:${arg.content}`4684              : createCompoundExpression(['"onUpdate:" + ', arg])4685          : `onUpdate:modelValue`;4686      let assignmentExp;4687      const eventArg = context.isTS ? `($event: any)` : `$event`;4688      {4689          assignmentExp = createCompoundExpression([4690              `${eventArg} => ((`,4691              exp,4692              `) = $event)`4693          ]);4694      }4695      const props = [4696          // modelValue: foo4697          createObjectProperty(propName, dir.exp),4698          // "onUpdate:modelValue": $event => (foo = $event)4699          createObjectProperty(eventName, assignmentExp)4700      ];4701      // modelModifiers: { foo: true, "bar-baz": true }4702      if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {4703          const modifiers = dir.modifiers4704              .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)4705              .join(`, `);4706          const modifiersKey = arg4707              ? isStaticExp(arg)4708                  ? `${arg.content}Modifiers`4709                  : createCompoundExpression([arg, ' + "Modifiers"'])4710              : `modelModifiers`;4711          props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));4712      }4713      return createTransformProps(props);4714  };4715  function createTransformProps(props = []) {4716      return { props };4717  }4718  const validDivisionCharRE = /[\w).+\-_$\]]/;4719  const transformFilter = (node, context) => {4720      if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {4721          return;4722      }4723      if (node.type === 5 /* INTERPOLATION */) {4724          // filter rewrite is applied before expression transform so only4725          // simple expressions are possible at this stage4726          rewriteFilter(node.content, context);4727      }4728      if (node.type === 1 /* ELEMENT */) {4729          node.props.forEach((prop) => {4730              if (prop.type === 7 /* DIRECTIVE */ &&4731                  prop.name !== 'for' &&4732                  prop.exp) {4733                  rewriteFilter(prop.exp, context);4734              }...compiler-core.cjs.js
Source:compiler-core.cjs.js  
...787    else {788        return value;789    }790}791function isCompatEnabled(key, context) {792    const mode = getCompatValue('MODE', context);793    const value = getCompatValue(key, context);794    // in v3 mode, only enable if explicitly set to true795    // otherwise enable for any non-false value796    return mode === 3 ? value === true : value !== false;797}798function checkCompatEnabled(key, context, loc, ...args) {799    const enabled = isCompatEnabled(key, context);800    if (enabled) {801        warnDeprecation(key, context, loc, ...args);802    }803    return enabled;804}805function warnDeprecation(key, context, loc, ...args) {806    const val = getCompatValue(key, context);807    if (val === 'suppress-warning') {808        return;809    }810    const { message, link } = deprecationData[key];811    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;812    const err = new SyntaxError(msg);813    err.code = key;814    if (loc)815        err.loc = loc;816    context.onWarn(err);817}818// The default decoder only provides escapes for characters reserved as part of819// the template syntax, and is only used if the custom renderer did not provide820// a platform-specific decoder.821const decodeRE = /&(gt|lt|amp|apos|quot);/g;822const decodeMap = {823    gt: '>',824    lt: '<',825    amp: '&',826    apos: "'",827    quot: '"'828};829const defaultParserOptions = {830    delimiters: [`{{`, `}}`],831    getNamespace: () => 0 /* HTML */,832    getTextMode: () => 0 /* DATA */,833    isVoidTag: shared.NO,834    isPreTag: shared.NO,835    isCustomElement: shared.NO,836    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),837    onError: defaultOnError,838    onWarn: defaultOnWarn,839    comments: true840};841function baseParse(content, options = {}) {842    const context = createParserContext(content, options);843    const start = getCursor(context);844    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));845}846function createParserContext(content, rawOptions) {847    const options = shared.extend({}, defaultParserOptions);848    let key;849    for (key in rawOptions) {850        // @ts-ignore851        options[key] =852            rawOptions[key] === undefined853                ? defaultParserOptions[key]854                : rawOptions[key];855    }856    return {857        options,858        column: 1,859        line: 1,860        offset: 0,861        originalSource: content,862        source: content,863        inPre: false,864        inVPre: false,865        onWarn: options.onWarn866    };867}868function parseChildren(context, mode, ancestors) {869    const parent = last(ancestors);870    const ns = parent ? parent.ns : 0 /* HTML */;871    const nodes = [];872    while (!isEnd(context, mode, ancestors)) {873        const s = context.source;874        let node = undefined;875        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {876            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {877                // '{{'878                node = parseInterpolation(context, mode);879            }880            else if (mode === 0 /* DATA */ && s[0] === '<') {881                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state882                if (s.length === 1) {883                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);884                }885                else if (s[1] === '!') {886                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state887                    if (startsWith(s, '<!--')) {888                        node = parseComment(context);889                    }890                    else if (startsWith(s, '<!DOCTYPE')) {891                        // Ignore DOCTYPE by a limitation.892                        node = parseBogusComment(context);893                    }894                    else if (startsWith(s, '<![CDATA[')) {895                        if (ns !== 0 /* HTML */) {896                            node = parseCDATA(context, ancestors);897                        }898                        else {899                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);900                            node = parseBogusComment(context);901                        }902                    }903                    else {904                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);905                        node = parseBogusComment(context);906                    }907                }908                else if (s[1] === '/') {909                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state910                    if (s.length === 2) {911                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);912                    }913                    else if (s[2] === '>') {914                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);915                        advanceBy(context, 3);916                        continue;917                    }918                    else if (/[a-z]/i.test(s[2])) {919                        emitError(context, 23 /* X_INVALID_END_TAG */);920                        parseTag(context, 1 /* End */, parent);921                        continue;922                    }923                    else {924                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);925                        node = parseBogusComment(context);926                    }927                }928                else if (/[a-z]/i.test(s[1])) {929                    node = parseElement(context, ancestors);930                    // 2.x <template> with no directive compat931                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&932                        node &&933                        node.tag === 'template' &&934                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&935                            isSpecialTemplateDirective(p.name))) {936                        warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);937                        node = node.children;938                    }939                }940                else if (s[1] === '?') {941                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);942                    node = parseBogusComment(context);943                }944                else {945                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);946                }947            }948        }949        if (!node) {950            node = parseText(context, mode);951        }952        if (shared.isArray(node)) {953            for (let i = 0; i < node.length; i++) {954                pushNode(nodes, node[i]);955            }956        }957        else {958            pushNode(nodes, node);959        }960    }961    // Whitespace handling strategy like v2962    let removedWhitespace = false;963    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {964        const shouldCondense = context.options.whitespace !== 'preserve';965        for (let i = 0; i < nodes.length; i++) {966            const node = nodes[i];967            if (!context.inPre && node.type === 2 /* TEXT */) {968                if (!/[^\t\r\n\f ]/.test(node.content)) {969                    const prev = nodes[i - 1];970                    const next = nodes[i + 1];971                    // Remove if:972                    // - the whitespace is the first or last node, or:973                    // - (condense mode) the whitespace is adjacent to a comment, or:974                    // - (condense mode) the whitespace is between two elements AND contains newline975                    if (!prev ||976                        !next ||977                        (shouldCondense &&978                            (prev.type === 3 /* COMMENT */ ||979                                next.type === 3 /* COMMENT */ ||980                                (prev.type === 1 /* ELEMENT */ &&981                                    next.type === 1 /* ELEMENT */ &&982                                    /[\r\n]/.test(node.content))))) {983                        removedWhitespace = true;984                        nodes[i] = null;985                    }986                    else {987                        // Otherwise, the whitespace is condensed into a single space988                        node.content = ' ';989                    }990                }991                else if (shouldCondense) {992                    // in condense mode, consecutive whitespaces in text are condensed993                    // down to a single space.994                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');995                }996            }997            // Remove comment nodes if desired by configuration.998            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {999                removedWhitespace = true;1000                nodes[i] = null;1001            }1002        }1003        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1004            // remove leading newline per html spec1005            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1006            const first = nodes[0];1007            if (first && first.type === 2 /* TEXT */) {1008                first.content = first.content.replace(/^\r?\n/, '');1009            }1010        }1011    }1012    return removedWhitespace ? nodes.filter(Boolean) : nodes;1013}1014function pushNode(nodes, node) {1015    if (node.type === 2 /* TEXT */) {1016        const prev = last(nodes);1017        // Merge if both this and the previous node are text and those are1018        // consecutive. This happens for cases like "a < b".1019        if (prev &&1020            prev.type === 2 /* TEXT */ &&1021            prev.loc.end.offset === node.loc.start.offset) {1022            prev.content += node.content;1023            prev.loc.end = node.loc.end;1024            prev.loc.source += node.loc.source;1025            return;1026        }1027    }1028    nodes.push(node);1029}1030function parseCDATA(context, ancestors) {1031    advanceBy(context, 9);1032    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1033    if (context.source.length === 0) {1034        emitError(context, 6 /* EOF_IN_CDATA */);1035    }1036    else {1037        advanceBy(context, 3);1038    }1039    return nodes;1040}1041function parseComment(context) {1042    const start = getCursor(context);1043    let content;1044    // Regular comment.1045    const match = /--(\!)?>/.exec(context.source);1046    if (!match) {1047        content = context.source.slice(4);1048        advanceBy(context, context.source.length);1049        emitError(context, 7 /* EOF_IN_COMMENT */);1050    }1051    else {1052        if (match.index <= 3) {1053            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1054        }1055        if (match[1]) {1056            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1057        }1058        content = context.source.slice(4, match.index);1059        // Advancing with reporting nested comments.1060        const s = context.source.slice(0, match.index);1061        let prevIndex = 1, nestedIndex = 0;1062        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1063            advanceBy(context, nestedIndex - prevIndex + 1);1064            if (nestedIndex + 4 < s.length) {1065                emitError(context, 16 /* NESTED_COMMENT */);1066            }1067            prevIndex = nestedIndex + 1;1068        }1069        advanceBy(context, match.index + match[0].length - prevIndex + 1);1070    }1071    return {1072        type: 3 /* COMMENT */,1073        content,1074        loc: getSelection(context, start)1075    };1076}1077function parseBogusComment(context) {1078    const start = getCursor(context);1079    const contentStart = context.source[1] === '?' ? 1 : 2;1080    let content;1081    const closeIndex = context.source.indexOf('>');1082    if (closeIndex === -1) {1083        content = context.source.slice(contentStart);1084        advanceBy(context, context.source.length);1085    }1086    else {1087        content = context.source.slice(contentStart, closeIndex);1088        advanceBy(context, closeIndex + 1);1089    }1090    return {1091        type: 3 /* COMMENT */,1092        content,1093        loc: getSelection(context, start)1094    };1095}1096function parseElement(context, ancestors) {1097    // Start tag.1098    const wasInPre = context.inPre;1099    const wasInVPre = context.inVPre;1100    const parent = last(ancestors);1101    const element = parseTag(context, 0 /* Start */, parent);1102    const isPreBoundary = context.inPre && !wasInPre;1103    const isVPreBoundary = context.inVPre && !wasInVPre;1104    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1105        // #4030 self-closing <pre> tag1106        if (isPreBoundary) {1107            context.inPre = false;1108        }1109        if (isVPreBoundary) {1110            context.inVPre = false;1111        }1112        return element;1113    }1114    // Children.1115    ancestors.push(element);1116    const mode = context.options.getTextMode(element, parent);1117    const children = parseChildren(context, mode, ancestors);1118    ancestors.pop();1119    // 2.x inline-template compat1120    {1121        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1122        if (inlineTemplateProp &&1123            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1124            const loc = getSelection(context, element.loc.end);1125            inlineTemplateProp.value = {1126                type: 2 /* TEXT */,1127                content: loc.source,1128                loc1129            };1130        }1131    }1132    element.children = children;1133    // End tag.1134    if (startsWithEndTagOpen(context.source, element.tag)) {1135        parseTag(context, 1 /* End */, parent);1136    }1137    else {1138        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1139        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1140            const first = children[0];1141            if (first && startsWith(first.loc.source, '<!--')) {1142                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1143            }1144        }1145    }1146    element.loc = getSelection(context, element.loc.start);1147    if (isPreBoundary) {1148        context.inPre = false;1149    }1150    if (isVPreBoundary) {1151        context.inVPre = false;1152    }1153    return element;1154}1155const isSpecialTemplateDirective = /*#__PURE__*/ shared.makeMap(`if,else,else-if,for,slot`);1156function parseTag(context, type, parent) {1157    // Tag open.1158    const start = getCursor(context);1159    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1160    const tag = match[1];1161    const ns = context.options.getNamespace(tag, parent);1162    advanceBy(context, match[0].length);1163    advanceSpaces(context);1164    // save current state in case we need to re-parse attributes with v-pre1165    const cursor = getCursor(context);1166    const currentSource = context.source;1167    // check <pre> tag1168    if (context.options.isPreTag(tag)) {1169        context.inPre = true;1170    }1171    // Attributes.1172    let props = parseAttributes(context, type);1173    // check v-pre1174    if (type === 0 /* Start */ &&1175        !context.inVPre &&1176        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1177        context.inVPre = true;1178        // reset context1179        shared.extend(context, cursor);1180        context.source = currentSource;1181        // re-parse attrs and filter out v-pre itself1182        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1183    }1184    // Tag close.1185    let isSelfClosing = false;1186    if (context.source.length === 0) {1187        emitError(context, 9 /* EOF_IN_TAG */);1188    }1189    else {1190        isSelfClosing = startsWith(context.source, '/>');1191        if (type === 1 /* End */ && isSelfClosing) {1192            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1193        }1194        advanceBy(context, isSelfClosing ? 2 : 1);1195    }1196    if (type === 1 /* End */) {1197        return;1198    }1199    // 2.x deprecation checks1200    if (isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1201        let hasIf = false;1202        let hasFor = false;1203        for (let i = 0; i < props.length; i++) {1204            const p = props[i];1205            if (p.type === 7 /* DIRECTIVE */) {1206                if (p.name === 'if') {1207                    hasIf = true;1208                }1209                else if (p.name === 'for') {1210                    hasFor = true;1211                }1212            }1213            if (hasIf && hasFor) {1214                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1215                break;1216            }1217        }1218    }1219    let tagType = 0 /* ELEMENT */;1220    if (!context.inVPre) {1221        if (tag === 'slot') {1222            tagType = 2 /* SLOT */;1223        }1224        else if (tag === 'template') {1225            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1226                tagType = 3 /* TEMPLATE */;1227            }1228        }1229        else if (isComponent(tag, props, context)) {1230            tagType = 1 /* COMPONENT */;1231        }1232    }1233    return {1234        type: 1 /* ELEMENT */,1235        ns,1236        tag,1237        tagType,1238        props,1239        isSelfClosing,1240        children: [],1241        loc: getSelection(context, start),1242        codegenNode: undefined // to be created during transform phase1243    };1244}1245function isComponent(tag, props, context) {1246    const options = context.options;1247    if (options.isCustomElement(tag)) {1248        return false;1249    }1250    if (tag === 'component' ||1251        /^[A-Z]/.test(tag) ||1252        isCoreComponent(tag) ||1253        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1254        (options.isNativeTag && !options.isNativeTag(tag))) {1255        return true;1256    }1257    // at this point the tag should be a native tag, but check for potential "is"1258    // casting1259    for (let i = 0; i < props.length; i++) {1260        const p = props[i];1261        if (p.type === 6 /* ATTRIBUTE */) {1262            if (p.name === 'is' && p.value) {1263                if (p.value.content.startsWith('vue:')) {1264                    return true;1265                }1266                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1267                    return true;1268                }1269            }1270        }1271        else {1272            // directive1273            // v-is (TODO Deprecate)1274            if (p.name === 'is') {1275                return true;1276            }1277            else if (1278            // :is on plain element - only treat as component in compat mode1279            p.name === 'bind' &&1280                isStaticArgOf(p.arg, 'is') &&1281                true &&1282                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1283                return true;1284            }1285        }1286    }1287}1288function parseAttributes(context, type) {1289    const props = [];1290    const attributeNames = new Set();1291    while (context.source.length > 0 &&1292        !startsWith(context.source, '>') &&1293        !startsWith(context.source, '/>')) {1294        if (startsWith(context.source, '/')) {1295            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1296            advanceBy(context, 1);1297            advanceSpaces(context);1298            continue;1299        }1300        if (type === 1 /* End */) {1301            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1302        }1303        const attr = parseAttribute(context, attributeNames);1304        // Trim whitespace between class1305        // https://github.com/vuejs/vue-next/issues/42511306        if (attr.type === 6 /* ATTRIBUTE */ &&1307            attr.value &&1308            attr.name === 'class') {1309            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1310        }1311        if (type === 0 /* Start */) {1312            props.push(attr);1313        }1314        if (/^[^\t\r\n\f />]/.test(context.source)) {1315            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1316        }1317        advanceSpaces(context);1318    }1319    return props;1320}1321function parseAttribute(context, nameSet) {1322    // Name.1323    const start = getCursor(context);1324    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1325    const name = match[0];1326    if (nameSet.has(name)) {1327        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1328    }1329    nameSet.add(name);1330    if (name[0] === '=') {1331        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1332    }1333    {1334        const pattern = /["'<]/g;1335        let m;1336        while ((m = pattern.exec(name))) {1337            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1338        }1339    }1340    advanceBy(context, name.length);1341    // Value1342    let value = undefined;1343    if (/^[\t\r\n\f ]*=/.test(context.source)) {1344        advanceSpaces(context);1345        advanceBy(context, 1);1346        advanceSpaces(context);1347        value = parseAttributeValue(context);1348        if (!value) {1349            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1350        }1351    }1352    const loc = getSelection(context, start);1353    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1354        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1355        let isPropShorthand = startsWith(name, '.');1356        let dirName = match[1] ||1357            (isPropShorthand || startsWith(name, ':')1358                ? 'bind'1359                : startsWith(name, '@')1360                    ? 'on'1361                    : 'slot');1362        let arg;1363        if (match[2]) {1364            const isSlot = dirName === 'slot';1365            const startOffset = name.lastIndexOf(match[2]);1366            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1367            let content = match[2];1368            let isStatic = true;1369            if (content.startsWith('[')) {1370                isStatic = false;1371                if (!content.endsWith(']')) {1372                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1373                    content = content.slice(1);1374                }1375                else {1376                    content = content.slice(1, content.length - 1);1377                }1378            }1379            else if (isSlot) {1380                // #1241 special case for v-slot: vuetify relies extensively on slot1381                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1382                // supports such usage so we are keeping it consistent with 2.x.1383                content += match[3] || '';1384            }1385            arg = {1386                type: 4 /* SIMPLE_EXPRESSION */,1387                content,1388                isStatic,1389                constType: isStatic1390                    ? 3 /* CAN_STRINGIFY */1391                    : 0 /* NOT_CONSTANT */,1392                loc1393            };1394        }1395        if (value && value.isQuoted) {1396            const valueLoc = value.loc;1397            valueLoc.start.offset++;1398            valueLoc.start.column++;1399            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1400            valueLoc.source = valueLoc.source.slice(1, -1);1401        }1402        const modifiers = match[3] ? match[3].slice(1).split('.') : [];1403        if (isPropShorthand)1404            modifiers.push('prop');1405        // 2.x compat v-bind:foo.sync -> v-model:foo1406        if (dirName === 'bind' && arg) {1407            if (modifiers.includes('sync') &&1408                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1409                dirName = 'model';1410                modifiers.splice(modifiers.indexOf('sync'), 1);1411            }1412            if (modifiers.includes('prop')) {1413                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1414            }1415        }1416        return {1417            type: 7 /* DIRECTIVE */,1418            name: dirName,1419            exp: value && {1420                type: 4 /* SIMPLE_EXPRESSION */,1421                content: value.content,1422                isStatic: false,1423                // Treat as non-constant by default. This can be potentially set to1424                // other values by `transformExpression` to make it eligible for hoisting.1425                constType: 0 /* NOT_CONSTANT */,1426                loc: value.loc1427            },1428            arg,1429            modifiers,1430            loc1431        };1432    }1433    // missing directive name or illegal directive name1434    if (!context.inVPre && startsWith(name, 'v-')) {1435        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1436    }1437    return {1438        type: 6 /* ATTRIBUTE */,1439        name,1440        value: value && {1441            type: 2 /* TEXT */,1442            content: value.content,1443            loc: value.loc1444        },1445        loc1446    };1447}1448function parseAttributeValue(context) {1449    const start = getCursor(context);1450    let content;1451    const quote = context.source[0];1452    const isQuoted = quote === `"` || quote === `'`;1453    if (isQuoted) {1454        // Quoted value.1455        advanceBy(context, 1);1456        const endIndex = context.source.indexOf(quote);1457        if (endIndex === -1) {1458            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1459        }1460        else {1461            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1462            advanceBy(context, 1);1463        }1464    }1465    else {1466        // Unquoted1467        const match = /^[^\t\r\n\f >]+/.exec(context.source);1468        if (!match) {1469            return undefined;1470        }1471        const unexpectedChars = /["'<=`]/g;1472        let m;1473        while ((m = unexpectedChars.exec(match[0]))) {1474            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1475        }1476        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1477    }1478    return { content, isQuoted, loc: getSelection(context, start) };1479}1480function parseInterpolation(context, mode) {1481    const [open, close] = context.options.delimiters;1482    const closeIndex = context.source.indexOf(close, open.length);1483    if (closeIndex === -1) {1484        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1485        return undefined;1486    }1487    const start = getCursor(context);1488    advanceBy(context, open.length);1489    const innerStart = getCursor(context);1490    const innerEnd = getCursor(context);1491    const rawContentLength = closeIndex - open.length;1492    const rawContent = context.source.slice(0, rawContentLength);1493    const preTrimContent = parseTextData(context, rawContentLength, mode);1494    const content = preTrimContent.trim();1495    const startOffset = preTrimContent.indexOf(content);1496    if (startOffset > 0) {1497        advancePositionWithMutation(innerStart, rawContent, startOffset);1498    }1499    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1500    advancePositionWithMutation(innerEnd, rawContent, endOffset);1501    advanceBy(context, close.length);1502    return {1503        type: 5 /* INTERPOLATION */,1504        content: {1505            type: 4 /* SIMPLE_EXPRESSION */,1506            isStatic: false,1507            // Set `isConstant` to false by default and will decide in transformExpression1508            constType: 0 /* NOT_CONSTANT */,1509            content,1510            loc: getSelection(context, innerStart, innerEnd)1511        },1512        loc: getSelection(context, start)1513    };1514}1515function parseText(context, mode) {1516    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1517    let endIndex = context.source.length;1518    for (let i = 0; i < endTokens.length; i++) {1519        const index = context.source.indexOf(endTokens[i], 1);1520        if (index !== -1 && endIndex > index) {1521            endIndex = index;1522        }1523    }1524    const start = getCursor(context);1525    const content = parseTextData(context, endIndex, mode);1526    return {1527        type: 2 /* TEXT */,1528        content,1529        loc: getSelection(context, start)1530    };1531}1532/**1533 * Get text data with a given length from the current location.1534 * This translates HTML entities in the text data.1535 */1536function parseTextData(context, length, mode) {1537    const rawText = context.source.slice(0, length);1538    advanceBy(context, length);1539    if (mode === 2 /* RAWTEXT */ ||1540        mode === 3 /* CDATA */ ||1541        rawText.indexOf('&') === -1) {1542        return rawText;1543    }1544    else {1545        // DATA or RCDATA containing "&"". Entity decoding required.1546        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1547    }1548}1549function getCursor(context) {1550    const { column, line, offset } = context;1551    return { column, line, offset };1552}1553function getSelection(context, start, end) {1554    end = end || getCursor(context);1555    return {1556        start,1557        end,1558        source: context.originalSource.slice(start.offset, end.offset)1559    };1560}1561function last(xs) {1562    return xs[xs.length - 1];1563}1564function startsWith(source, searchString) {1565    return source.startsWith(searchString);1566}1567function advanceBy(context, numberOfCharacters) {1568    const { source } = context;1569    advancePositionWithMutation(context, source, numberOfCharacters);1570    context.source = source.slice(numberOfCharacters);1571}1572function advanceSpaces(context) {1573    const match = /^[\t\r\n\f ]+/.exec(context.source);1574    if (match) {1575        advanceBy(context, match[0].length);1576    }1577}1578function getNewPosition(context, start, numberOfCharacters) {1579    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1580}1581function emitError(context, code, offset, loc = getCursor(context)) {1582    if (offset) {1583        loc.offset += offset;1584        loc.column += offset;1585    }1586    context.options.onError(createCompilerError(code, {1587        start: loc,1588        end: loc,1589        source: ''1590    }));1591}1592function isEnd(context, mode, ancestors) {1593    const s = context.source;1594    switch (mode) {1595        case 0 /* DATA */:1596            if (startsWith(s, '</')) {1597                // TODO: probably bad performance1598                for (let i = ancestors.length - 1; i >= 0; --i) {1599                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {1600                        return true;1601                    }1602                }1603            }1604            break;1605        case 1 /* RCDATA */:1606        case 2 /* RAWTEXT */: {1607            const parent = last(ancestors);1608            if (parent && startsWithEndTagOpen(s, parent.tag)) {1609                return true;1610            }1611            break;1612        }1613        case 3 /* CDATA */:1614            if (startsWith(s, ']]>')) {1615                return true;1616            }1617            break;1618    }1619    return !s;1620}1621function startsWithEndTagOpen(source, tag) {1622    return (startsWith(source, '</') &&1623        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1624        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1625}1626function hoistStatic(root, context) {1627    walk(root, context, 1628    // Root node is unfortunately non-hoistable due to potential parent1629    // fallthrough attributes.1630    isSingleElementRoot(root, root.children[0]));1631}1632function isSingleElementRoot(root, child) {1633    const { children } = root;1634    return (children.length === 1 &&1635        child.type === 1 /* ELEMENT */ &&1636        !isSlotOutlet(child));1637}1638function walk(node, context, doNotHoistNode = false) {1639    const { children } = node;1640    const originalCount = children.length;1641    let hoistedCount = 0;1642    for (let i = 0; i < children.length; i++) {1643        const child = children[i];1644        // only plain elements & text calls are eligible for hoisting.1645        if (child.type === 1 /* ELEMENT */ &&1646            child.tagType === 0 /* ELEMENT */) {1647            const constantType = doNotHoistNode1648                ? 0 /* NOT_CONSTANT */1649                : getConstantType(child, context);1650            if (constantType > 0 /* NOT_CONSTANT */) {1651                if (constantType >= 2 /* CAN_HOIST */) {1652                    child.codegenNode.patchFlag =1653                        -1 /* HOISTED */ + (` /* HOISTED */` );1654                    child.codegenNode = context.hoist(child.codegenNode);1655                    hoistedCount++;1656                    continue;1657                }1658            }1659            else {1660                // node may contain dynamic children, but its props may be eligible for1661                // hoisting.1662                const codegenNode = child.codegenNode;1663                if (codegenNode.type === 13 /* VNODE_CALL */) {1664                    const flag = getPatchFlag(codegenNode);1665                    if ((!flag ||1666                        flag === 512 /* NEED_PATCH */ ||1667                        flag === 1 /* TEXT */) &&1668                        getGeneratedPropsConstantType(child, context) >=1669                            2 /* CAN_HOIST */) {1670                        const props = getNodeProps(child);1671                        if (props) {1672                            codegenNode.props = context.hoist(props);1673                        }1674                    }1675                    if (codegenNode.dynamicProps) {1676                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1677                    }1678                }1679            }1680        }1681        else if (child.type === 12 /* TEXT_CALL */ &&1682            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {1683            child.codegenNode = context.hoist(child.codegenNode);1684            hoistedCount++;1685        }1686        // walk further1687        if (child.type === 1 /* ELEMENT */) {1688            const isComponent = child.tagType === 1 /* COMPONENT */;1689            if (isComponent) {1690                context.scopes.vSlot++;1691            }1692            walk(child, context);1693            if (isComponent) {1694                context.scopes.vSlot--;1695            }1696        }1697        else if (child.type === 11 /* FOR */) {1698            // Do not hoist v-for single child because it has to be a block1699            walk(child, context, child.children.length === 1);1700        }1701        else if (child.type === 9 /* IF */) {1702            for (let i = 0; i < child.branches.length; i++) {1703                // Do not hoist v-if single child because it has to be a block1704                walk(child.branches[i], context, child.branches[i].children.length === 1);1705            }1706        }1707    }1708    if (hoistedCount && context.transformHoist) {1709        context.transformHoist(children, context, node);1710    }1711    // all children were hoisted - the entire children array is hoistable.1712    if (hoistedCount &&1713        hoistedCount === originalCount &&1714        node.type === 1 /* ELEMENT */ &&1715        node.tagType === 0 /* ELEMENT */ &&1716        node.codegenNode &&1717        node.codegenNode.type === 13 /* VNODE_CALL */ &&1718        shared.isArray(node.codegenNode.children)) {1719        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1720    }1721}1722function getConstantType(node, context) {1723    const { constantCache } = context;1724    switch (node.type) {1725        case 1 /* ELEMENT */:1726            if (node.tagType !== 0 /* ELEMENT */) {1727                return 0 /* NOT_CONSTANT */;1728            }1729            const cached = constantCache.get(node);1730            if (cached !== undefined) {1731                return cached;1732            }1733            const codegenNode = node.codegenNode;1734            if (codegenNode.type !== 13 /* VNODE_CALL */) {1735                return 0 /* NOT_CONSTANT */;1736            }1737            if (codegenNode.isBlock &&1738                node.tag !== 'svg' &&1739                node.tag !== 'foreignObject') {1740                return 0 /* NOT_CONSTANT */;1741            }1742            const flag = getPatchFlag(codegenNode);1743            if (!flag) {1744                let returnType = 3 /* CAN_STRINGIFY */;1745                // Element itself has no patch flag. However we still need to check:1746                // 1. Even for a node with no patch flag, it is possible for it to contain1747                // non-hoistable expressions that refers to scope variables, e.g. compiler1748                // injected keys or cached event handlers. Therefore we need to always1749                // check the codegenNode's props to be sure.1750                const generatedPropsType = getGeneratedPropsConstantType(node, context);1751                if (generatedPropsType === 0 /* NOT_CONSTANT */) {1752                    constantCache.set(node, 0 /* NOT_CONSTANT */);1753                    return 0 /* NOT_CONSTANT */;1754                }1755                if (generatedPropsType < returnType) {1756                    returnType = generatedPropsType;1757                }1758                // 2. its children.1759                for (let i = 0; i < node.children.length; i++) {1760                    const childType = getConstantType(node.children[i], context);1761                    if (childType === 0 /* NOT_CONSTANT */) {1762                        constantCache.set(node, 0 /* NOT_CONSTANT */);1763                        return 0 /* NOT_CONSTANT */;1764                    }1765                    if (childType < returnType) {1766                        returnType = childType;1767                    }1768                }1769                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01770                // type, check if any of the props can cause the type to be lowered1771                // we can skip can_patch because it's guaranteed by the absence of a1772                // patchFlag.1773                if (returnType > 1 /* CAN_SKIP_PATCH */) {1774                    for (let i = 0; i < node.props.length; i++) {1775                        const p = node.props[i];1776                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1777                            const expType = getConstantType(p.exp, context);1778                            if (expType === 0 /* NOT_CONSTANT */) {1779                                constantCache.set(node, 0 /* NOT_CONSTANT */);1780                                return 0 /* NOT_CONSTANT */;1781                            }1782                            if (expType < returnType) {1783                                returnType = expType;1784                            }1785                        }1786                    }1787                }1788                // only svg/foreignObject could be block here, however if they are1789                // static then they don't need to be blocks since there will be no1790                // nested updates.1791                if (codegenNode.isBlock) {1792                    context.removeHelper(OPEN_BLOCK);1793                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1794                    codegenNode.isBlock = false;1795                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1796                }1797                constantCache.set(node, returnType);1798                return returnType;1799            }1800            else {1801                constantCache.set(node, 0 /* NOT_CONSTANT */);1802                return 0 /* NOT_CONSTANT */;1803            }1804        case 2 /* TEXT */:1805        case 3 /* COMMENT */:1806            return 3 /* CAN_STRINGIFY */;1807        case 9 /* IF */:1808        case 11 /* FOR */:1809        case 10 /* IF_BRANCH */:1810            return 0 /* NOT_CONSTANT */;1811        case 5 /* INTERPOLATION */:1812        case 12 /* TEXT_CALL */:1813            return getConstantType(node.content, context);1814        case 4 /* SIMPLE_EXPRESSION */:1815            return node.constType;1816        case 8 /* COMPOUND_EXPRESSION */:1817            let returnType = 3 /* CAN_STRINGIFY */;1818            for (let i = 0; i < node.children.length; i++) {1819                const child = node.children[i];1820                if (shared.isString(child) || shared.isSymbol(child)) {1821                    continue;1822                }1823                const childType = getConstantType(child, context);1824                if (childType === 0 /* NOT_CONSTANT */) {1825                    return 0 /* NOT_CONSTANT */;1826                }1827                else if (childType < returnType) {1828                    returnType = childType;1829                }1830            }1831            return returnType;1832        default:1833            return 0 /* NOT_CONSTANT */;1834    }1835}1836const allowHoistedHelperSet = new Set([1837    NORMALIZE_CLASS,1838    NORMALIZE_STYLE,1839    NORMALIZE_PROPS,1840    GUARD_REACTIVE_PROPS1841]);1842function getConstantTypeOfHelperCall(value, context) {1843    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1844        !shared.isString(value.callee) &&1845        allowHoistedHelperSet.has(value.callee)) {1846        const arg = value.arguments[0];1847        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {1848            return getConstantType(arg, context);1849        }1850        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {1851            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`1852            return getConstantTypeOfHelperCall(arg, context);1853        }1854    }1855    return 0 /* NOT_CONSTANT */;1856}1857function getGeneratedPropsConstantType(node, context) {1858    let returnType = 3 /* CAN_STRINGIFY */;1859    const props = getNodeProps(node);1860    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1861        const { properties } = props;1862        for (let i = 0; i < properties.length; i++) {1863            const { key, value } = properties[i];1864            const keyType = getConstantType(key, context);1865            if (keyType === 0 /* NOT_CONSTANT */) {1866                return keyType;1867            }1868            if (keyType < returnType) {1869                returnType = keyType;1870            }1871            let valueType;1872            if (value.type === 4 /* SIMPLE_EXPRESSION */) {1873                valueType = getConstantType(value, context);1874            }1875            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {1876                // some helper calls can be hoisted,1877                // such as the `normalizeProps` generated by the compiler for pre-normalize class,1878                // in this case we need to respect the ConstantType of the helper's arguments1879                valueType = getConstantTypeOfHelperCall(value, context);1880            }1881            else {1882                valueType = 0 /* NOT_CONSTANT */;1883            }1884            if (valueType === 0 /* NOT_CONSTANT */) {1885                return valueType;1886            }1887            if (valueType < returnType) {1888                returnType = valueType;1889            }1890        }1891    }1892    return returnType;1893}1894function getNodeProps(node) {1895    const codegenNode = node.codegenNode;1896    if (codegenNode.type === 13 /* VNODE_CALL */) {1897        return codegenNode.props;1898    }1899}1900function getPatchFlag(node) {1901    const flag = node.patchFlag;1902    return flag ? parseInt(flag, 10) : undefined;1903}1904function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = shared.NOOP, isCustomElement = shared.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = shared.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {1905    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1906    const context = {1907        // options1908        selfName: nameMatch && shared.capitalize(shared.camelize(nameMatch[1])),1909        prefixIdentifiers,1910        hoistStatic,1911        cacheHandlers,1912        nodeTransforms,1913        directiveTransforms,1914        transformHoist,1915        isBuiltInComponent,1916        isCustomElement,1917        expressionPlugins,1918        scopeId,1919        slotted,1920        ssr,1921        inSSR,1922        ssrCssVars,1923        bindingMetadata,1924        inline,1925        isTS,1926        onError,1927        onWarn,1928        compatConfig,1929        // state1930        root,1931        helpers: new Map(),1932        components: new Set(),1933        directives: new Set(),1934        hoists: [],1935        imports: [],1936        constantCache: new Map(),1937        temps: 0,1938        cached: 0,1939        identifiers: Object.create(null),1940        scopes: {1941            vFor: 0,1942            vSlot: 0,1943            vPre: 0,1944            vOnce: 01945        },1946        parent: null,1947        currentNode: root,1948        childIndex: 0,1949        inVOnce: false,1950        // methods1951        helper(name) {1952            const count = context.helpers.get(name) || 0;1953            context.helpers.set(name, count + 1);1954            return name;1955        },1956        removeHelper(name) {1957            const count = context.helpers.get(name);1958            if (count) {1959                const currentCount = count - 1;1960                if (!currentCount) {1961                    context.helpers.delete(name);1962                }1963                else {1964                    context.helpers.set(name, currentCount);1965                }1966            }1967        },1968        helperString(name) {1969            return `_${helperNameMap[context.helper(name)]}`;1970        },1971        replaceNode(node) {1972            /* istanbul ignore if */1973            {1974                if (!context.currentNode) {1975                    throw new Error(`Node being replaced is already removed.`);1976                }1977                if (!context.parent) {1978                    throw new Error(`Cannot replace root node.`);1979                }1980            }1981            context.parent.children[context.childIndex] = context.currentNode = node;1982        },1983        removeNode(node) {1984            if (!context.parent) {1985                throw new Error(`Cannot remove root node.`);1986            }1987            const list = context.parent.children;1988            const removalIndex = node1989                ? list.indexOf(node)1990                : context.currentNode1991                    ? context.childIndex1992                    : -1;1993            /* istanbul ignore if */1994            if (removalIndex < 0) {1995                throw new Error(`node being removed is not a child of current parent`);1996            }1997            if (!node || node === context.currentNode) {1998                // current node removed1999                context.currentNode = null;2000                context.onNodeRemoved();2001            }2002            else {2003                // sibling node removed2004                if (context.childIndex > removalIndex) {2005                    context.childIndex--;2006                    context.onNodeRemoved();2007                }2008            }2009            context.parent.children.splice(removalIndex, 1);2010        },2011        onNodeRemoved: () => { },2012        addIdentifiers(exp) {2013            // identifier tracking only happens in non-browser builds.2014            {2015                if (shared.isString(exp)) {2016                    addId(exp);2017                }2018                else if (exp.identifiers) {2019                    exp.identifiers.forEach(addId);2020                }2021                else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {2022                    addId(exp.content);2023                }2024            }2025        },2026        removeIdentifiers(exp) {2027            {2028                if (shared.isString(exp)) {2029                    removeId(exp);2030                }2031                else if (exp.identifiers) {2032                    exp.identifiers.forEach(removeId);2033                }2034                else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {2035                    removeId(exp.content);2036                }2037            }2038        },2039        hoist(exp) {2040            if (shared.isString(exp))2041                exp = createSimpleExpression(exp);2042            context.hoists.push(exp);2043            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2044            identifier.hoisted = exp;2045            return identifier;2046        },2047        cache(exp, isVNode = false) {2048            return createCacheExpression(context.cached++, exp, isVNode);2049        }2050    };2051    {2052        context.filters = new Set();2053    }2054    function addId(id) {2055        const { identifiers } = context;2056        if (identifiers[id] === undefined) {2057            identifiers[id] = 0;2058        }2059        identifiers[id]++;2060    }2061    function removeId(id) {2062        context.identifiers[id]--;2063    }2064    return context;2065}2066function transform(root, options) {2067    const context = createTransformContext(root, options);2068    traverseNode(root, context);2069    if (options.hoistStatic) {2070        hoistStatic(root, context);2071    }2072    if (!options.ssr) {2073        createRootCodegen(root, context);2074    }2075    // finalize meta information2076    root.helpers = [...context.helpers.keys()];2077    root.components = [...context.components];2078    root.directives = [...context.directives];2079    root.imports = context.imports;2080    root.hoists = context.hoists;2081    root.temps = context.temps;2082    root.cached = context.cached;2083    {2084        root.filters = [...context.filters];2085    }2086}2087function createRootCodegen(root, context) {2088    const { helper } = context;2089    const { children } = root;2090    if (children.length === 1) {2091        const child = children[0];2092        // if the single child is an element, turn it into a block.2093        if (isSingleElementRoot(root, child) && child.codegenNode) {2094            // single element root is never hoisted so codegenNode will never be2095            // SimpleExpressionNode2096            const codegenNode = child.codegenNode;2097            if (codegenNode.type === 13 /* VNODE_CALL */) {2098                makeBlock(codegenNode, context);2099            }2100            root.codegenNode = codegenNode;2101        }2102        else {2103            // - single <slot/>, IfNode, ForNode: already blocks.2104            // - single text node: always patched.2105            // root codegen falls through via genNode()2106            root.codegenNode = child;2107        }2108    }2109    else if (children.length > 1) {2110        // root has multiple nodes - return a fragment block.2111        let patchFlag = 64 /* STABLE_FRAGMENT */;2112        let patchFlagText = shared.PatchFlagNames[64 /* STABLE_FRAGMENT */];2113        // check if the fragment actually contains a single valid child with2114        // the rest being comments2115        if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2116            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2117            patchFlagText += `, ${shared.PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2118        }2119        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);2120    }2121    else ;2122}2123function traverseChildren(parent, context) {2124    let i = 0;2125    const nodeRemoved = () => {2126        i--;2127    };2128    for (; i < parent.children.length; i++) {2129        const child = parent.children[i];2130        if (shared.isString(child))2131            continue;2132        context.parent = parent;2133        context.childIndex = i;2134        context.onNodeRemoved = nodeRemoved;2135        traverseNode(child, context);2136    }2137}2138function traverseNode(node, context) {2139    context.currentNode = node;2140    // apply transform plugins2141    const { nodeTransforms } = context;2142    const exitFns = [];2143    for (let i = 0; i < nodeTransforms.length; i++) {2144        const onExit = nodeTransforms[i](node, context);2145        if (onExit) {2146            if (shared.isArray(onExit)) {2147                exitFns.push(...onExit);2148            }2149            else {2150                exitFns.push(onExit);2151            }2152        }2153        if (!context.currentNode) {2154            // node was removed2155            return;2156        }2157        else {2158            // node may have been replaced2159            node = context.currentNode;2160        }2161    }2162    switch (node.type) {2163        case 3 /* COMMENT */:2164            if (!context.ssr) {2165                // inject import for the Comment symbol, which is needed for creating2166                // comment nodes with `createVNode`2167                context.helper(CREATE_COMMENT);2168            }2169            break;2170        case 5 /* INTERPOLATION */:2171            // no need to traverse, but we need to inject toString helper2172            if (!context.ssr) {2173                context.helper(TO_DISPLAY_STRING);2174            }2175            break;2176        // for container types, further traverse downwards2177        case 9 /* IF */:2178            for (let i = 0; i < node.branches.length; i++) {2179                traverseNode(node.branches[i], context);2180            }2181            break;2182        case 10 /* IF_BRANCH */:2183        case 11 /* FOR */:2184        case 1 /* ELEMENT */:2185        case 0 /* ROOT */:2186            traverseChildren(node, context);2187            break;2188    }2189    // exit transforms2190    context.currentNode = node;2191    let i = exitFns.length;2192    while (i--) {2193        exitFns[i]();2194    }2195}2196function createStructuralDirectiveTransform(name, fn) {2197    const matches = shared.isString(name)2198        ? (n) => n === name2199        : (n) => name.test(n);2200    return (node, context) => {2201        if (node.type === 1 /* ELEMENT */) {2202            const { props } = node;2203            // structural directive transforms are not concerned with slots2204            // as they are handled separately in vSlot.ts2205            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2206                return;2207            }2208            const exitFns = [];2209            for (let i = 0; i < props.length; i++) {2210                const prop = props[i];2211                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2212                    // structural directives are removed to avoid infinite recursion2213                    // also we remove them *before* applying so that it can further2214                    // traverse itself in case it moves the node around2215                    props.splice(i, 1);2216                    i--;2217                    const onExit = fn(node, prop, context);2218                    if (onExit)2219                        exitFns.push(onExit);2220                }2221            }2222            return exitFns;2223        }2224    };2225}2226const PURE_ANNOTATION = `/*#__PURE__*/`;2227function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap: sourceMap$1 = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2228    const context = {2229        mode,2230        prefixIdentifiers,2231        sourceMap: sourceMap$1,2232        filename,2233        scopeId,2234        optimizeImports,2235        runtimeGlobalName,2236        runtimeModuleName,2237        ssrRuntimeModuleName,2238        ssr,2239        isTS,2240        inSSR,2241        source: ast.loc.source,2242        code: ``,2243        column: 1,2244        line: 1,2245        offset: 0,2246        indentLevel: 0,2247        pure: false,2248        map: undefined,2249        helper(key) {2250            return `_${helperNameMap[key]}`;2251        },2252        push(code, node) {2253            context.code += code;2254            if (context.map) {2255                if (node) {2256                    let name;2257                    if (node.type === 4 /* SIMPLE_EXPRESSION */ && !node.isStatic) {2258                        const content = node.content.replace(/^_ctx\./, '');2259                        if (content !== node.content && isSimpleIdentifier(content)) {2260                            name = content;2261                        }2262                    }2263                    addMapping(node.loc.start, name);2264                }2265                advancePositionWithMutation(context, code);2266                if (node && node.loc !== locStub) {2267                    addMapping(node.loc.end);2268                }2269            }2270        },2271        indent() {2272            newline(++context.indentLevel);2273        },2274        deindent(withoutNewLine = false) {2275            if (withoutNewLine) {2276                --context.indentLevel;2277            }2278            else {2279                newline(--context.indentLevel);2280            }2281        },2282        newline() {2283            newline(context.indentLevel);2284        }2285    };2286    function newline(n) {2287        context.push('\n' + `  `.repeat(n));2288    }2289    function addMapping(loc, name) {2290        context.map.addMapping({2291            name,2292            source: context.filename,2293            original: {2294                line: loc.line,2295                column: loc.column - 1 // source-map column is 0 based2296            },2297            generated: {2298                line: context.line,2299                column: context.column - 12300            }2301        });2302    }2303    if (sourceMap$1) {2304        // lazy require source-map implementation, only in non-browser builds2305        context.map = new sourceMap.SourceMapGenerator();2306        context.map.setSourceContent(filename, context.source);2307    }2308    return context;2309}2310function generate(ast, options = {}) {2311    const context = createCodegenContext(ast, options);2312    if (options.onContextCreated)2313        options.onContextCreated(context);2314    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2315    const hasHelpers = ast.helpers.length > 0;2316    const useWithBlock = !prefixIdentifiers && mode !== 'module';2317    const genScopeId = scopeId != null && mode === 'module';2318    const isSetupInlined = !!options.inline;2319    // preambles2320    // in setup() inline mode, the preamble is generated in a sub context2321    // and returned separately.2322    const preambleContext = isSetupInlined2323        ? createCodegenContext(ast, options)2324        : context;2325    if (mode === 'module') {2326        genModulePreamble(ast, preambleContext, genScopeId, isSetupInlined);2327    }2328    else {2329        genFunctionPreamble(ast, preambleContext);2330    }2331    // enter render function2332    const functionName = ssr ? `ssrRender` : `render`;2333    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2334    if (options.bindingMetadata && !options.inline) {2335        // binding optimization args2336        args.push('$props', '$setup', '$data', '$options');2337    }2338    const signature = options.isTS2339        ? args.map(arg => `${arg}: any`).join(',')2340        : args.join(', ');2341    if (isSetupInlined) {2342        push(`(${signature}) => {`);2343    }2344    else {2345        push(`function ${functionName}(${signature}) {`);2346    }2347    indent();2348    if (useWithBlock) {2349        push(`with (_ctx) {`);2350        indent();2351        // function mode const declarations should be inside with block2352        // also they should be renamed to avoid collision with user properties2353        if (hasHelpers) {2354            push(`const { ${ast.helpers2355                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2356                .join(', ')} } = _Vue`);2357            push(`\n`);2358            newline();2359        }2360    }2361    // generate asset resolution statements2362    if (ast.components.length) {2363        genAssets(ast.components, 'component', context);2364        if (ast.directives.length || ast.temps > 0) {2365            newline();2366        }2367    }2368    if (ast.directives.length) {2369        genAssets(ast.directives, 'directive', context);2370        if (ast.temps > 0) {2371            newline();2372        }2373    }2374    if (ast.filters && ast.filters.length) {2375        newline();2376        genAssets(ast.filters, 'filter', context);2377        newline();2378    }2379    if (ast.temps > 0) {2380        push(`let `);2381        for (let i = 0; i < ast.temps; i++) {2382            push(`${i > 0 ? `, ` : ``}_temp${i}`);2383        }2384    }2385    if (ast.components.length || ast.directives.length || ast.temps) {2386        push(`\n`);2387        newline();2388    }2389    // generate the VNode tree expression2390    if (!ssr) {2391        push(`return `);2392    }2393    if (ast.codegenNode) {2394        genNode(ast.codegenNode, context);2395    }2396    else {2397        push(`null`);2398    }2399    if (useWithBlock) {2400        deindent();2401        push(`}`);2402    }2403    deindent();2404    push(`}`);2405    return {2406        ast,2407        code: context.code,2408        preamble: isSetupInlined ? preambleContext.code : ``,2409        // SourceMapGenerator does have toJSON() method but it's not in the types2410        map: context.map ? context.map.toJSON() : undefined2411    };2412}2413function genFunctionPreamble(ast, context) {2414    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2415    const VueBinding = ssr2416        ? `require(${JSON.stringify(runtimeModuleName)})`2417        : runtimeGlobalName;2418    const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2419    // Generate const declaration for helpers2420    // In prefix mode, we place the const declaration at top so it's done2421    // only once; But if we not prefixing, we place the declaration inside the2422    // with block so it doesn't incur the `in` check cost for every helper access.2423    if (ast.helpers.length > 0) {2424        if (prefixIdentifiers) {2425            push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`);2426        }2427        else {2428            // "with" mode.2429            // save Vue in a separate variable to avoid collision2430            push(`const _Vue = ${VueBinding}\n`);2431            // in "with" mode, helpers are declared inside the with block to avoid2432            // has check cost, but hoists are lifted out of the function - we need2433            // to provide the helper here.2434            if (ast.hoists.length) {2435                const staticHelpers = [2436                    CREATE_VNODE,2437                    CREATE_ELEMENT_VNODE,2438                    CREATE_COMMENT,2439                    CREATE_TEXT,2440                    CREATE_STATIC2441                ]2442                    .filter(helper => ast.helpers.includes(helper))2443                    .map(aliasHelper)2444                    .join(', ');2445                push(`const { ${staticHelpers} } = _Vue\n`);2446            }2447        }2448    }2449    // generate variables for ssr helpers2450    if (ast.ssrHelpers && ast.ssrHelpers.length) {2451        // ssr guarantees prefixIdentifier: true2452        push(`const { ${ast.ssrHelpers2453            .map(aliasHelper)2454            .join(', ')} } = require("${ssrRuntimeModuleName}")\n`);2455    }2456    genHoists(ast.hoists, context);2457    newline();2458    push(`return `);2459}2460function genModulePreamble(ast, context, genScopeId, inline) {2461    const { push, newline, optimizeImports, runtimeModuleName, ssrRuntimeModuleName } = context;2462    if (genScopeId && ast.hoists.length) {2463        ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID);2464    }2465    // generate import statements for helpers2466    if (ast.helpers.length) {2467        if (optimizeImports) {2468            // when bundled with webpack with code-split, calling an import binding2469            // as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,2470            // incurring both payload size increase and potential perf overhead.2471            // therefore we assign the imports to variables (which is a constant ~50b2472            // cost per-component instead of scaling with template size)2473            push(`import { ${ast.helpers2474                .map(s => helperNameMap[s])2475                .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);2476            push(`\n// Binding optimization for webpack code-split\nconst ${ast.helpers2477                .map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)2478                .join(', ')}\n`);2479        }2480        else {2481            push(`import { ${ast.helpers2482                .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)2483                .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);2484        }2485    }2486    if (ast.ssrHelpers && ast.ssrHelpers.length) {2487        push(`import { ${ast.ssrHelpers2488            .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)2489            .join(', ')} } from "${ssrRuntimeModuleName}"\n`);2490    }2491    if (ast.imports.length) {2492        genImports(ast.imports, context);2493        newline();2494    }2495    genHoists(ast.hoists, context);2496    newline();2497    if (!inline) {2498        push(`export `);2499    }2500}2501function genAssets(assets, type, { helper, push, newline, isTS }) {2502    const resolver = helper(type === 'filter'2503        ? RESOLVE_FILTER2504        : type === 'component'2505            ? RESOLVE_COMPONENT2506            : RESOLVE_DIRECTIVE);2507    for (let i = 0; i < assets.length; i++) {2508        let id = assets[i];2509        // potential component implicit self-reference inferred from SFC filename2510        const maybeSelfReference = id.endsWith('__self');2511        if (maybeSelfReference) {2512            id = id.slice(0, -6);2513        }2514        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2515        if (i < assets.length - 1) {2516            newline();2517        }2518    }2519}2520function genHoists(hoists, context) {2521    if (!hoists.length) {2522        return;2523    }2524    context.pure = true;2525    const { push, newline, helper, scopeId, mode } = context;2526    const genScopeId = scopeId != null && mode !== 'function';2527    newline();2528    // generate inlined withScopeId helper2529    if (genScopeId) {2530        push(`const _withScopeId = n => (${helper(PUSH_SCOPE_ID)}("${scopeId}"),n=n(),${helper(POP_SCOPE_ID)}(),n)`);2531        newline();2532    }2533    for (let i = 0; i < hoists.length; i++) {2534        const exp = hoists[i];2535        if (exp) {2536            const needScopeIdWrapper = genScopeId && exp.type === 13 /* VNODE_CALL */;2537            push(`const _hoisted_${i + 1} = ${needScopeIdWrapper ? `${PURE_ANNOTATION} _withScopeId(() => ` : ``}`);2538            genNode(exp, context);2539            if (needScopeIdWrapper) {2540                push(`)`);2541            }2542            newline();2543        }2544    }2545    context.pure = false;2546}2547function genImports(importsOptions, context) {2548    if (!importsOptions.length) {2549        return;2550    }2551    importsOptions.forEach(imports => {2552        context.push(`import `);2553        genNode(imports.exp, context);2554        context.push(` from '${imports.path}'`);2555        context.newline();2556    });2557}2558function isText$1(n) {2559    return (shared.isString(n) ||2560        n.type === 4 /* SIMPLE_EXPRESSION */ ||2561        n.type === 2 /* TEXT */ ||2562        n.type === 5 /* INTERPOLATION */ ||2563        n.type === 8 /* COMPOUND_EXPRESSION */);2564}2565function genNodeListAsArray(nodes, context) {2566    const multilines = nodes.length > 3 ||2567        (nodes.some(n => shared.isArray(n) || !isText$1(n)));2568    context.push(`[`);2569    multilines && context.indent();2570    genNodeList(nodes, context, multilines);2571    multilines && context.deindent();2572    context.push(`]`);2573}2574function genNodeList(nodes, context, multilines = false, comma = true) {2575    const { push, newline } = context;2576    for (let i = 0; i < nodes.length; i++) {2577        const node = nodes[i];2578        if (shared.isString(node)) {2579            push(node);2580        }2581        else if (shared.isArray(node)) {2582            genNodeListAsArray(node, context);2583        }2584        else {2585            genNode(node, context);2586        }2587        if (i < nodes.length - 1) {2588            if (multilines) {2589                comma && push(',');2590                newline();2591            }2592            else {2593                comma && push(', ');2594            }2595        }2596    }2597}2598function genNode(node, context) {2599    if (shared.isString(node)) {2600        context.push(node);2601        return;2602    }2603    if (shared.isSymbol(node)) {2604        context.push(context.helper(node));2605        return;2606    }2607    switch (node.type) {2608        case 1 /* ELEMENT */:2609        case 9 /* IF */:2610        case 11 /* FOR */:2611            assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2612                    `Apply appropriate transforms first.`);2613            genNode(node.codegenNode, context);2614            break;2615        case 2 /* TEXT */:2616            genText(node, context);2617            break;2618        case 4 /* SIMPLE_EXPRESSION */:2619            genExpression(node, context);2620            break;2621        case 5 /* INTERPOLATION */:2622            genInterpolation(node, context);2623            break;2624        case 12 /* TEXT_CALL */:2625            genNode(node.codegenNode, context);2626            break;2627        case 8 /* COMPOUND_EXPRESSION */:2628            genCompoundExpression(node, context);2629            break;2630        case 3 /* COMMENT */:2631            genComment(node, context);2632            break;2633        case 13 /* VNODE_CALL */:2634            genVNodeCall(node, context);2635            break;2636        case 14 /* JS_CALL_EXPRESSION */:2637            genCallExpression(node, context);2638            break;2639        case 15 /* JS_OBJECT_EXPRESSION */:2640            genObjectExpression(node, context);2641            break;2642        case 17 /* JS_ARRAY_EXPRESSION */:2643            genArrayExpression(node, context);2644            break;2645        case 18 /* JS_FUNCTION_EXPRESSION */:2646            genFunctionExpression(node, context);2647            break;2648        case 19 /* JS_CONDITIONAL_EXPRESSION */:2649            genConditionalExpression(node, context);2650            break;2651        case 20 /* JS_CACHE_EXPRESSION */:2652            genCacheExpression(node, context);2653            break;2654        case 21 /* JS_BLOCK_STATEMENT */:2655            genNodeList(node.body, context, true, false);2656            break;2657        // SSR only types2658        case 22 /* JS_TEMPLATE_LITERAL */:2659            genTemplateLiteral(node, context);2660            break;2661        case 23 /* JS_IF_STATEMENT */:2662            genIfStatement(node, context);2663            break;2664        case 24 /* JS_ASSIGNMENT_EXPRESSION */:2665            genAssignmentExpression(node, context);2666            break;2667        case 25 /* JS_SEQUENCE_EXPRESSION */:2668            genSequenceExpression(node, context);2669            break;2670        case 26 /* JS_RETURN_STATEMENT */:2671            genReturnStatement(node, context);2672            break;2673        /* istanbul ignore next */2674        case 10 /* IF_BRANCH */:2675            // noop2676            break;2677        default:2678            {2679                assert(false, `unhandled codegen node type: ${node.type}`);2680                // make sure we exhaust all possible types2681                const exhaustiveCheck = node;2682                return exhaustiveCheck;2683            }2684    }2685}2686function genText(node, context) {2687    context.push(JSON.stringify(node.content), node);2688}2689function genExpression(node, context) {2690    const { content, isStatic } = node;2691    context.push(isStatic ? JSON.stringify(content) : content, node);2692}2693function genInterpolation(node, context) {2694    const { push, helper, pure } = context;2695    if (pure)2696        push(PURE_ANNOTATION);2697    push(`${helper(TO_DISPLAY_STRING)}(`);2698    genNode(node.content, context);2699    push(`)`);2700}2701function genCompoundExpression(node, context) {2702    for (let i = 0; i < node.children.length; i++) {2703        const child = node.children[i];2704        if (shared.isString(child)) {2705            context.push(child);2706        }2707        else {2708            genNode(child, context);2709        }2710    }2711}2712function genExpressionAsPropertyKey(node, context) {2713    const { push } = context;2714    if (node.type === 8 /* COMPOUND_EXPRESSION */) {2715        push(`[`);2716        genCompoundExpression(node, context);2717        push(`]`);2718    }2719    else if (node.isStatic) {2720        // only quote keys if necessary2721        const text = isSimpleIdentifier(node.content)2722            ? node.content2723            : JSON.stringify(node.content);2724        push(text, node);2725    }2726    else {2727        push(`[${node.content}]`, node);2728    }2729}2730function genComment(node, context) {2731    const { push, helper, pure } = context;2732    if (pure) {2733        push(PURE_ANNOTATION);2734    }2735    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2736}2737function genVNodeCall(node, context) {2738    const { push, helper, pure } = context;2739    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2740    if (directives) {2741        push(helper(WITH_DIRECTIVES) + `(`);2742    }2743    if (isBlock) {2744        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2745    }2746    if (pure) {2747        push(PURE_ANNOTATION);2748    }2749    const callHelper = isBlock2750        ? getVNodeBlockHelper(context.inSSR, isComponent)2751        : getVNodeHelper(context.inSSR, isComponent);2752    push(helper(callHelper) + `(`, node);2753    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2754    push(`)`);2755    if (isBlock) {2756        push(`)`);2757    }2758    if (directives) {2759        push(`, `);2760        genNode(directives, context);2761        push(`)`);2762    }2763}2764function genNullableArgs(args) {2765    let i = args.length;2766    while (i--) {2767        if (args[i] != null)2768            break;2769    }2770    return args.slice(0, i + 1).map(arg => arg || `null`);2771}2772// JavaScript2773function genCallExpression(node, context) {2774    const { push, helper, pure } = context;2775    const callee = shared.isString(node.callee) ? node.callee : helper(node.callee);2776    if (pure) {2777        push(PURE_ANNOTATION);2778    }2779    push(callee + `(`, node);2780    genNodeList(node.arguments, context);2781    push(`)`);2782}2783function genObjectExpression(node, context) {2784    const { push, indent, deindent, newline } = context;2785    const { properties } = node;2786    if (!properties.length) {2787        push(`{}`, node);2788        return;2789    }2790    const multilines = properties.length > 1 ||2791        (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2792    push(multilines ? `{` : `{ `);2793    multilines && indent();2794    for (let i = 0; i < properties.length; i++) {2795        const { key, value } = properties[i];2796        // key2797        genExpressionAsPropertyKey(key, context);2798        push(`: `);2799        // value2800        genNode(value, context);2801        if (i < properties.length - 1) {2802            // will only reach this if it's multilines2803            push(`,`);2804            newline();2805        }2806    }2807    multilines && deindent();2808    push(multilines ? `}` : ` }`);2809}2810function genArrayExpression(node, context) {2811    genNodeListAsArray(node.elements, context);2812}2813function genFunctionExpression(node, context) {2814    const { push, indent, deindent } = context;2815    const { params, returns, body, newline, isSlot } = node;2816    if (isSlot) {2817        // wrap slot functions with owner context2818        push(`_${helperNameMap[WITH_CTX]}(`);2819    }2820    push(`(`, node);2821    if (shared.isArray(params)) {2822        genNodeList(params, context);2823    }2824    else if (params) {2825        genNode(params, context);2826    }2827    push(`) => `);2828    if (newline || body) {2829        push(`{`);2830        indent();2831    }2832    if (returns) {2833        if (newline) {2834            push(`return `);2835        }2836        if (shared.isArray(returns)) {2837            genNodeListAsArray(returns, context);2838        }2839        else {2840            genNode(returns, context);2841        }2842    }2843    else if (body) {2844        genNode(body, context);2845    }2846    if (newline || body) {2847        deindent();2848        push(`}`);2849    }2850    if (isSlot) {2851        if (node.isNonScopedSlot) {2852            push(`, undefined, true`);2853        }2854        push(`)`);2855    }2856}2857function genConditionalExpression(node, context) {2858    const { test, consequent, alternate, newline: needNewline } = node;2859    const { push, indent, deindent, newline } = context;2860    if (test.type === 4 /* SIMPLE_EXPRESSION */) {2861        const needsParens = !isSimpleIdentifier(test.content);2862        needsParens && push(`(`);2863        genExpression(test, context);2864        needsParens && push(`)`);2865    }2866    else {2867        push(`(`);2868        genNode(test, context);2869        push(`)`);2870    }2871    needNewline && indent();2872    context.indentLevel++;2873    needNewline || push(` `);2874    push(`? `);2875    genNode(consequent, context);2876    context.indentLevel--;2877    needNewline && newline();2878    needNewline || push(` `);2879    push(`: `);2880    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2881    if (!isNested) {2882        context.indentLevel++;2883    }2884    genNode(alternate, context);2885    if (!isNested) {2886        context.indentLevel--;2887    }2888    needNewline && deindent(true /* without newline */);2889}2890function genCacheExpression(node, context) {2891    const { push, helper, indent, deindent, newline } = context;2892    push(`_cache[${node.index}] || (`);2893    if (node.isVNode) {2894        indent();2895        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2896        newline();2897    }2898    push(`_cache[${node.index}] = `);2899    genNode(node.value, context);2900    if (node.isVNode) {2901        push(`,`);2902        newline();2903        push(`${helper(SET_BLOCK_TRACKING)}(1),`);2904        newline();2905        push(`_cache[${node.index}]`);2906        deindent();2907    }2908    push(`)`);2909}2910function genTemplateLiteral(node, context) {2911    const { push, indent, deindent } = context;2912    push('`');2913    const l = node.elements.length;2914    const multilines = l > 3;2915    for (let i = 0; i < l; i++) {2916        const e = node.elements[i];2917        if (shared.isString(e)) {2918            push(e.replace(/(`|\$|\\)/g, '\\$1'));2919        }2920        else {2921            push('${');2922            if (multilines)2923                indent();2924            genNode(e, context);2925            if (multilines)2926                deindent();2927            push('}');2928        }2929    }2930    push('`');2931}2932function genIfStatement(node, context) {2933    const { push, indent, deindent } = context;2934    const { test, consequent, alternate } = node;2935    push(`if (`);2936    genNode(test, context);2937    push(`) {`);2938    indent();2939    genNode(consequent, context);2940    deindent();2941    push(`}`);2942    if (alternate) {2943        push(` else `);2944        if (alternate.type === 23 /* JS_IF_STATEMENT */) {2945            genIfStatement(alternate, context);2946        }2947        else {2948            push(`{`);2949            indent();2950            genNode(alternate, context);2951            deindent();2952            push(`}`);2953        }2954    }2955}2956function genAssignmentExpression(node, context) {2957    genNode(node.left, context);2958    context.push(` = `);2959    genNode(node.right, context);2960}2961function genSequenceExpression(node, context) {2962    context.push(`(`);2963    genNodeList(node.expressions, context);2964    context.push(`)`);2965}2966function genReturnStatement({ returns }, context) {2967    context.push(`return `);2968    if (shared.isArray(returns)) {2969        genNodeListAsArray(returns, context);2970    }2971    else {2972        genNode(returns, context);2973    }2974}2975function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2976    const rootExp = root.type === 'Program' &&2977        root.body[0].type === 'ExpressionStatement' &&2978        root.body[0].expression;2979    estreeWalker.walk(root, {2980        enter(node, parent) {2981            parent && parentStack.push(parent);2982            if (parent &&2983                parent.type.startsWith('TS') &&2984                parent.type !== 'TSAsExpression' &&2985                parent.type !== 'TSNonNullExpression' &&2986                parent.type !== 'TSTypeAssertion') {2987                return this.skip();2988            }2989            if (node.type === 'Identifier') {2990                const isLocal = !!knownIds[node.name];2991                const isRefed = isReferencedIdentifier(node, parent, parentStack);2992                if (includeAll || (isRefed && !isLocal)) {2993                    onIdentifier(node, parent, parentStack, isRefed, isLocal);2994                }2995            }2996            else if (node.type === 'ObjectProperty' &&2997                parent.type === 'ObjectPattern') {2998                node.inPattern = true;2999            }3000            else if (isFunctionType(node)) {3001                // walk function expressions and add its arguments to known identifiers3002                // so that we don't prefix them3003                walkFunctionParams(node, id => markScopeIdentifier(node, id, knownIds));3004            }3005            else if (node.type === 'BlockStatement') {3006                // #3445 record block-level local variables3007                walkBlockDeclarations(node, id => markScopeIdentifier(node, id, knownIds));3008            }3009        },3010        leave(node, parent) {3011            parent && parentStack.pop();3012            if (node !== rootExp && node.scopeIds) {3013                for (const id of node.scopeIds) {3014                    knownIds[id]--;3015                    if (knownIds[id] === 0) {3016                        delete knownIds[id];3017                    }3018                }3019            }3020        }3021    });3022}3023function isReferencedIdentifier(id, parent, parentStack) {3024    if (!parent) {3025        return true;3026    }3027    // is a special keyword but parsed as identifier3028    if (id.name === 'arguments') {3029        return false;3030    }3031    if (isReferenced(id, parent)) {3032        return true;3033    }3034    // babel's isReferenced check returns false for ids being assigned to, so we3035    // need to cover those cases here3036    switch (parent.type) {3037        case 'AssignmentExpression':3038        case 'AssignmentPattern':3039            return true;3040        case 'ObjectPattern':3041        case 'ArrayPattern':3042            return isInDestructureAssignment(parent, parentStack);3043    }3044    return false;3045}3046function isInDestructureAssignment(parent, parentStack) {3047    if (parent &&3048        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {3049        let i = parentStack.length;3050        while (i--) {3051            const p = parentStack[i];3052            if (p.type === 'AssignmentExpression') {3053                return true;3054            }3055            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {3056                break;3057            }3058        }3059    }3060    return false;3061}3062function walkFunctionParams(node, onIdent) {3063    for (const p of node.params) {3064        for (const id of extractIdentifiers(p)) {3065            onIdent(id);3066        }3067    }3068}3069function walkBlockDeclarations(block, onIdent) {3070    for (const stmt of block.body) {3071        if (stmt.type === 'VariableDeclaration') {3072            if (stmt.declare)3073                continue;3074            for (const decl of stmt.declarations) {3075                for (const id of extractIdentifiers(decl.id)) {3076                    onIdent(id);3077                }3078            }3079        }3080        else if (stmt.type === 'FunctionDeclaration' ||3081            stmt.type === 'ClassDeclaration') {3082            if (stmt.declare || !stmt.id)3083                continue;3084            onIdent(stmt.id);3085        }3086    }3087}3088function extractIdentifiers(param, nodes = []) {3089    switch (param.type) {3090        case 'Identifier':3091            nodes.push(param);3092            break;3093        case 'MemberExpression':3094            let object = param;3095            while (object.type === 'MemberExpression') {3096                object = object.object;3097            }3098            nodes.push(object);3099            break;3100        case 'ObjectPattern':3101            for (const prop of param.properties) {3102                if (prop.type === 'RestElement') {3103                    extractIdentifiers(prop.argument, nodes);3104                }3105                else {3106                    extractIdentifiers(prop.value, nodes);3107                }3108            }3109            break;3110        case 'ArrayPattern':3111            param.elements.forEach(element => {3112                if (element)3113                    extractIdentifiers(element, nodes);3114            });3115            break;3116        case 'RestElement':3117            extractIdentifiers(param.argument, nodes);3118            break;3119        case 'AssignmentPattern':3120            extractIdentifiers(param.left, nodes);3121            break;3122    }3123    return nodes;3124}3125function markScopeIdentifier(node, child, knownIds) {3126    const { name } = child;3127    if (node.scopeIds && node.scopeIds.has(name)) {3128        return;3129    }3130    if (name in knownIds) {3131        knownIds[name]++;3132    }3133    else {3134        knownIds[name] = 1;3135    }3136    (node.scopeIds || (node.scopeIds = new Set())).add(name);3137}3138const isFunctionType = (node) => {3139    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3140};3141const isStaticProperty = (node) => node &&3142    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3143    !node.computed;3144const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3145/**3146 * Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts3147 * To avoid runtime dependency on @babel/types (which includes process references)3148 * This file should not change very often in babel but we may need to keep it3149 * up-to-date from time to time.3150 *3151 * https://github.com/babel/babel/blob/main/LICENSE3152 *3153 */3154function isReferenced(node, parent, grandparent) {3155    switch (parent.type) {3156        // yes: PARENT[NODE]3157        // yes: NODE.child3158        // no: parent.NODE3159        case 'MemberExpression':3160        case 'OptionalMemberExpression':3161            if (parent.property === node) {3162                return !!parent.computed;3163            }3164            return parent.object === node;3165        case 'JSXMemberExpression':3166            return parent.object === node;3167        // no: let NODE = init;3168        // yes: let id = NODE;3169        case 'VariableDeclarator':3170            return parent.init === node;3171        // yes: () => NODE3172        // no: (NODE) => {}3173        case 'ArrowFunctionExpression':3174            return parent.body === node;3175        // no: class { #NODE; }3176        // no: class { get #NODE() {} }3177        // no: class { #NODE() {} }3178        // no: class { fn() { return this.#NODE; } }3179        case 'PrivateName':3180            return false;3181        // no: class { NODE() {} }3182        // yes: class { [NODE]() {} }3183        // no: class { foo(NODE) {} }3184        case 'ClassMethod':3185        case 'ClassPrivateMethod':3186        case 'ObjectMethod':3187            if (parent.key === node) {3188                return !!parent.computed;3189            }3190            return false;3191        // yes: { [NODE]: "" }3192        // no: { NODE: "" }3193        // depends: { NODE }3194        // depends: { key: NODE }3195        case 'ObjectProperty':3196            if (parent.key === node) {3197                return !!parent.computed;3198            }3199            // parent.value === node3200            return !grandparent || grandparent.type !== 'ObjectPattern';3201        // no: class { NODE = value; }3202        // yes: class { [NODE] = value; }3203        // yes: class { key = NODE; }3204        case 'ClassProperty':3205            if (parent.key === node) {3206                return !!parent.computed;3207            }3208            return true;3209        case 'ClassPrivateProperty':3210            return parent.key !== node;3211        // no: class NODE {}3212        // yes: class Foo extends NODE {}3213        case 'ClassDeclaration':3214        case 'ClassExpression':3215            return parent.superClass === node;3216        // yes: left = NODE;3217        // no: NODE = right;3218        case 'AssignmentExpression':3219            return parent.right === node;3220        // no: [NODE = foo] = [];3221        // yes: [foo = NODE] = [];3222        case 'AssignmentPattern':3223            return parent.right === node;3224        // no: NODE: for (;;) {}3225        case 'LabeledStatement':3226            return false;3227        // no: try {} catch (NODE) {}3228        case 'CatchClause':3229            return false;3230        // no: function foo(...NODE) {}3231        case 'RestElement':3232            return false;3233        case 'BreakStatement':3234        case 'ContinueStatement':3235            return false;3236        // no: function NODE() {}3237        // no: function foo(NODE) {}3238        case 'FunctionDeclaration':3239        case 'FunctionExpression':3240            return false;3241        // no: export NODE from "foo";3242        // no: export * as NODE from "foo";3243        case 'ExportNamespaceSpecifier':3244        case 'ExportDefaultSpecifier':3245            return false;3246        // no: export { foo as NODE };3247        // yes: export { NODE as foo };3248        // no: export { NODE as foo } from "foo";3249        case 'ExportSpecifier':3250            // @ts-expect-error3251            if (grandparent === null || grandparent === void 0 ? void 0 : grandparent.source) {3252                return false;3253            }3254            return parent.local === node;3255        // no: import NODE from "foo";3256        // no: import * as NODE from "foo";3257        // no: import { NODE as foo } from "foo";3258        // no: import { foo as NODE } from "foo";3259        // no: import NODE from "bar";3260        case 'ImportDefaultSpecifier':3261        case 'ImportNamespaceSpecifier':3262        case 'ImportSpecifier':3263            return false;3264        // no: import "foo" assert { NODE: "json" }3265        case 'ImportAttribute':3266            return false;3267        // no: <div NODE="foo" />3268        case 'JSXAttribute':3269            return false;3270        // no: [NODE] = [];3271        // no: ({ NODE }) = [];3272        case 'ObjectPattern':3273        case 'ArrayPattern':3274            return false;3275        // no: new.NODE3276        // no: NODE.target3277        case 'MetaProperty':3278            return false;3279        // yes: type X = { somePropert: NODE }3280        // no: type X = { NODE: OtherType }3281        case 'ObjectTypeProperty':3282            return parent.key !== node;3283        // yes: enum X { Foo = NODE }3284        // no: enum X { NODE }3285        case 'TSEnumMember':3286            return parent.id !== node;3287        // yes: { [NODE]: value }3288        // no: { NODE: value }3289        case 'TSPropertySignature':3290            if (parent.key === node) {3291                return !!parent.computed;3292            }3293            return true;3294    }3295    return true;3296}3297const isLiteralWhitelisted = /*#__PURE__*/ shared.makeMap('true,false,null,this');3298const transformExpression = (node, context) => {3299    if (node.type === 5 /* INTERPOLATION */) {3300        node.content = processExpression(node.content, context);3301    }3302    else if (node.type === 1 /* ELEMENT */) {3303        // handle directives on element3304        for (let i = 0; i < node.props.length; i++) {3305            const dir = node.props[i];3306            // do not process for v-on & v-for since they are special handled3307            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3308                const exp = dir.exp;3309                const arg = dir.arg;3310                // do not process exp if this is v-on:arg - we need special handling3311                // for wrapping inline statements.3312                if (exp &&3313                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&3314                    !(dir.name === 'on' && arg)) {3315                    dir.exp = processExpression(exp, context, 3316                    // slot args must be processed as function params3317                    dir.name === 'slot');3318                }3319                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3320                    dir.arg = processExpression(arg, context);3321                }3322            }3323        }3324    }3325};3326// Important: since this function uses Node.js only dependencies, it should3327// always be used with a leading !false check so that it can be3328// tree-shaken from the browser build.3329function processExpression(node, context, 3330// some expressions like v-slot props & v-for aliases should be parsed as3331// function params3332asParams = false, 3333// v-on handler values may contain multiple statements3334asRawStatements = false, localVars = Object.create(context.identifiers)) {3335    if (!context.prefixIdentifiers || !node.content.trim()) {3336        return node;3337    }3338    const { inline, bindingMetadata } = context;3339    const rewriteIdentifier = (raw, parent, id) => {3340        const type = shared.hasOwn(bindingMetadata, raw) && bindingMetadata[raw];3341        if (inline) {3342            // x = y3343            const isAssignmentLVal = parent && parent.type === 'AssignmentExpression' && parent.left === id;3344            // x++3345            const isUpdateArg = parent && parent.type === 'UpdateExpression' && parent.argument === id;3346            // ({ x } = y)3347            const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack);3348            if (type === "setup-const" /* SETUP_CONST */ || localVars[raw]) {3349                return raw;3350            }3351            else if (type === "setup-ref" /* SETUP_REF */) {3352                return `${raw}.value`;3353            }3354            else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {3355                // const binding that may or may not be ref3356                // if it's not a ref, then assignments don't make sense -3357                // so we ignore the non-ref assignment case and generate code3358                // that assumes the value to be a ref for more efficiency3359                return isAssignmentLVal || isUpdateArg || isDestructureAssignment3360                    ? `${raw}.value`3361                    : `${context.helperString(UNREF)}(${raw})`;3362            }3363            else if (type === "setup-let" /* SETUP_LET */) {3364                if (isAssignmentLVal) {3365                    // let binding.3366                    // this is a bit more tricky as we need to cover the case where3367                    // let is a local non-ref value, and we need to replicate the3368                    // right hand side value.3369                    // x = y --> isRef(x) ? x.value = y : x = y3370                    const { right: rVal, operator } = parent;3371                    const rExp = rawExp.slice(rVal.start - 1, rVal.end - 1);3372                    const rExpString = stringifyExpression(processExpression(createSimpleExpression(rExp, false), context, false, false, knownIds));3373                    return `${context.helperString(IS_REF)}(${raw})${context.isTS ? ` //@ts-ignore\n` : ``} ? ${raw}.value ${operator} ${rExpString} : ${raw}`;3374                }3375                else if (isUpdateArg) {3376                    // make id replace parent in the code range so the raw update operator3377                    // is removed3378                    id.start = parent.start;3379                    id.end = parent.end;3380                    const { prefix: isPrefix, operator } = parent;3381                    const prefix = isPrefix ? operator : ``;3382                    const postfix = isPrefix ? `` : operator;3383                    // let binding.3384                    // x++ --> isRef(a) ? a.value++ : a++3385                    return `${context.helperString(IS_REF)}(${raw})${context.isTS ? ` //@ts-ignore\n` : ``} ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}`;3386                }3387                else if (isDestructureAssignment) {3388                    // TODO3389                    // let binding in a destructure assignment - it's very tricky to3390                    // handle both possible cases here without altering the original3391                    // structure of the code, so we just assume it's not a ref here3392                    // for now3393                    return raw;3394                }3395                else {3396                    return `${context.helperString(UNREF)}(${raw})`;3397                }3398            }3399            else if (type === "props" /* PROPS */) {3400                // use __props which is generated by compileScript so in ts mode3401                // it gets correct type3402                return `__props.${raw}`;3403            }3404            else if (type === "props-aliased" /* PROPS_ALIASED */) {3405                // prop with a different local alias (from defineProps() destructure)3406                return `__props.${bindingMetadata.__propsAliases[raw]}`;3407            }3408        }3409        else {3410            if (type && type.startsWith('setup')) {3411                // setup bindings in non-inline mode3412                return `$setup.${raw}`;3413            }3414            else if (type === "props-aliased" /* PROPS_ALIASED */) {3415                return `$props.${bindingMetadata.__propsAliases[raw]}`;3416            }3417            else if (type) {3418                return `$${type}.${raw}`;3419            }3420        }3421        // fallback to ctx3422        return `_ctx.${raw}`;3423    };3424    // fast path if expression is a simple identifier.3425    const rawExp = node.content;3426    // bail constant on parens (function invocation) and dot (member access)3427    const bailConstant = rawExp.indexOf(`(`) > -1 || rawExp.indexOf('.') > 0;3428    if (isSimpleIdentifier(rawExp)) {3429        const isScopeVarReference = context.identifiers[rawExp];3430        const isAllowedGlobal = shared.isGloballyWhitelisted(rawExp);3431        const isLiteral = isLiteralWhitelisted(rawExp);3432        if (!asParams && !isScopeVarReference && !isAllowedGlobal && !isLiteral) {3433            // const bindings exposed from setup can be skipped for patching but3434            // cannot be hoisted to module scope3435            if (bindingMetadata[node.content] === "setup-const" /* SETUP_CONST */) {3436                node.constType = 1 /* CAN_SKIP_PATCH */;3437            }3438            node.content = rewriteIdentifier(rawExp);3439        }3440        else if (!isScopeVarReference) {3441            if (isLiteral) {3442                node.constType = 3 /* CAN_STRINGIFY */;3443            }3444            else {3445                node.constType = 2 /* CAN_HOIST */;3446            }3447        }3448        return node;3449    }3450    let ast;3451    // exp needs to be parsed differently:3452    // 1. Multiple inline statements (v-on, with presence of `;`): parse as raw3453    //    exp, but make sure to pad with spaces for consistent ranges3454    // 2. Expressions: wrap with parens (for e.g. object expressions)3455    // 3. Function arguments (v-for, v-slot): place in a function argument position3456    const source = asRawStatements3457        ? ` ${rawExp} `3458        : `(${rawExp})${asParams ? `=>{}` : ``}`;3459    try {3460        ast = parser.parse(source, {3461            plugins: context.expressionPlugins3462        }).program;3463    }3464    catch (e) {3465        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, e.message));3466        return node;3467    }3468    const ids = [];3469    const parentStack = [];3470    const knownIds = Object.create(context.identifiers);3471    walkIdentifiers(ast, (node, parent, _, isReferenced, isLocal) => {3472        if (isStaticPropertyKey(node, parent)) {3473            return;3474        }3475        // v2 wrapped filter call3476        if (node.name.startsWith('_filter_')) {3477            return;3478        }3479        const needPrefix = isReferenced && canPrefix(node);3480        if (needPrefix && !isLocal) {3481            if (isStaticProperty(parent) && parent.shorthand) {3482                node.prefix = `${node.name}: `;3483            }3484            node.name = rewriteIdentifier(node.name, parent, node);3485            ids.push(node);3486        }3487        else {3488            // The identifier is considered constant unless it's pointing to a3489            // local scope variable (a v-for alias, or a v-slot prop)3490            if (!(needPrefix && isLocal) && !bailConstant) {3491                node.isConstant = true;3492            }3493            // also generate sub-expressions for other identifiers for better3494            // source map support. (except for property keys which are static)3495            ids.push(node);3496        }3497    }, true, // invoke on ALL identifiers3498    parentStack, knownIds);3499    // We break up the compound expression into an array of strings and sub3500    // expressions (for identifiers that have been prefixed). In codegen, if3501    // an ExpressionNode has the `.children` property, it will be used instead of3502    // `.content`.3503    const children = [];3504    ids.sort((a, b) => a.start - b.start);3505    ids.forEach((id, i) => {3506        // range is offset by -1 due to the wrapping parens when parsed3507        const start = id.start - 1;3508        const end = id.end - 1;3509        const last = ids[i - 1];3510        const leadingText = rawExp.slice(last ? last.end - 1 : 0, start);3511        if (leadingText.length || id.prefix) {3512            children.push(leadingText + (id.prefix || ``));3513        }3514        const source = rawExp.slice(start, end);3515        children.push(createSimpleExpression(id.name, false, {3516            source,3517            start: advancePositionWithClone(node.loc.start, source, start),3518            end: advancePositionWithClone(node.loc.start, source, end)3519        }, id.isConstant ? 3 /* CAN_STRINGIFY */ : 0 /* NOT_CONSTANT */));3520        if (i === ids.length - 1 && end < rawExp.length) {3521            children.push(rawExp.slice(end));3522        }3523    });3524    let ret;3525    if (children.length) {3526        ret = createCompoundExpression(children, node.loc);3527    }3528    else {3529        ret = node;3530        ret.constType = bailConstant3531            ? 0 /* NOT_CONSTANT */3532            : 3 /* CAN_STRINGIFY */;3533    }3534    ret.identifiers = Object.keys(knownIds);3535    return ret;3536}3537function canPrefix(id) {3538    // skip whitelisted globals3539    if (shared.isGloballyWhitelisted(id.name)) {3540        return false;3541    }3542    // special case for webpack compilation3543    if (id.name === 'require') {3544        return false;3545    }3546    return true;3547}3548function stringifyExpression(exp) {3549    if (shared.isString(exp)) {3550        return exp;3551    }3552    else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {3553        return exp.content;3554    }3555    else {3556        return exp.children3557            .map(stringifyExpression)3558            .join('');3559    }3560}3561const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3562    return processIf(node, dir, context, (ifNode, branch, isRoot) => {3563        // #1587: We need to dynamically increment the key based on the current3564        // node's sibling nodes, since chained v-if/else branches are3565        // rendered at the same depth3566        const siblings = context.parent.children;3567        let i = siblings.indexOf(ifNode);3568        let key = 0;3569        while (i-- >= 0) {3570            const sibling = siblings[i];3571            if (sibling && sibling.type === 9 /* IF */) {3572                key += sibling.branches.length;3573            }3574        }3575        // Exit callback. Complete the codegenNode when all children have been3576        // transformed.3577        return () => {3578            if (isRoot) {3579                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3580            }3581            else {3582                // attach this branch's codegen node to the v-if root.3583                const parentCondition = getParentCondition(ifNode.codegenNode);3584                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3585            }3586        };3587    });3588});3589// target-agnostic transform used for both Client and SSR3590function processIf(node, dir, context, processCodegen) {3591    if (dir.name !== 'else' &&3592        (!dir.exp || !dir.exp.content.trim())) {3593        const loc = dir.exp ? dir.exp.loc : node.loc;3594        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3595        dir.exp = createSimpleExpression(`true`, false, loc);3596    }3597    if (context.prefixIdentifiers && dir.exp) {3598        // dir.exp can only be simple expression because vIf transform is applied3599        // before expression transform.3600        dir.exp = processExpression(dir.exp, context);3601    }3602    if (dir.name === 'if') {3603        const branch = createIfBranch(node, dir);3604        const ifNode = {3605            type: 9 /* IF */,3606            loc: node.loc,3607            branches: [branch]3608        };3609        context.replaceNode(ifNode);3610        if (processCodegen) {3611            return processCodegen(ifNode, branch, true);3612        }3613    }3614    else {3615        // locate the adjacent v-if3616        const siblings = context.parent.children;3617        const comments = [];3618        let i = siblings.indexOf(node);3619        while (i-- >= -1) {3620            const sibling = siblings[i];3621            if (sibling && sibling.type === 3 /* COMMENT */) {3622                context.removeNode(sibling);3623                comments.unshift(sibling);3624                continue;3625            }3626            if (sibling &&3627                sibling.type === 2 /* TEXT */ &&3628                !sibling.content.trim().length) {3629                context.removeNode(sibling);3630                continue;3631            }3632            if (sibling && sibling.type === 9 /* IF */) {3633                // Check if v-else was followed by v-else-if3634                if (dir.name === 'else-if' &&3635                    sibling.branches[sibling.branches.length - 1].condition === undefined) {3636                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3637                }3638                // move the node to the if node's branches3639                context.removeNode();3640                const branch = createIfBranch(node, dir);3641                if (comments.length &&3642                    // #3619 ignore comments if the v-if is direct child of <transition>3643                    !(context.parent &&3644                        context.parent.type === 1 /* ELEMENT */ &&3645                        isBuiltInType(context.parent.tag, 'transition'))) {3646                    branch.children = [...comments, ...branch.children];3647                }3648                // check if user is forcing same key on different branches3649                {3650                    const key = branch.userKey;3651                    if (key) {3652                        sibling.branches.forEach(({ userKey }) => {3653                            if (isSameKey(userKey, key)) {3654                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3655                            }3656                        });3657                    }3658                }3659                sibling.branches.push(branch);3660                const onExit = processCodegen && processCodegen(sibling, branch, false);3661                // since the branch was removed, it will not be traversed.3662                // make sure to traverse here.3663                traverseNode(branch, context);3664                // call on exit3665                if (onExit)3666                    onExit();3667                // make sure to reset currentNode after traversal to indicate this3668                // node has been removed.3669                context.currentNode = null;3670            }3671            else {3672                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3673            }3674            break;3675        }3676    }3677}3678function createIfBranch(node, dir) {3679    return {3680        type: 10 /* IF_BRANCH */,3681        loc: node.loc,3682        condition: dir.name === 'else' ? undefined : dir.exp,3683        children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3684            ? node.children3685            : [node],3686        userKey: findProp(node, `key`)3687    };3688}3689function createCodegenNodeForBranch(branch, keyIndex, context) {3690    if (branch.condition) {3691        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3692        // make sure to pass in asBlock: true so that the comment node call3693        // closes the current block.3694        createCallExpression(context.helper(CREATE_COMMENT), [3695            '"v-if"' ,3696            'true'3697        ]));3698    }3699    else {3700        return createChildrenCodegenNode(branch, keyIndex, context);3701    }3702}3703function createChildrenCodegenNode(branch, keyIndex, context) {3704    const { helper } = context;3705    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3706    const { children } = branch;3707    const firstChild = children[0];3708    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3709    if (needFragmentWrapper) {3710        if (children.length === 1 && firstChild.type === 11 /* FOR */) {3711            // optimize away nested fragments when child is a ForNode3712            const vnodeCall = firstChild.codegenNode;3713            injectProp(vnodeCall, keyProperty, context);3714            return vnodeCall;3715        }3716        else {3717            let patchFlag = 64 /* STABLE_FRAGMENT */;3718            let patchFlagText = shared.PatchFlagNames[64 /* STABLE_FRAGMENT */];3719            // check if the fragment actually contains a single valid child with3720            // the rest being comments3721            if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3722                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3723                patchFlagText += `, ${shared.PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3724            }3725            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);3726        }3727    }3728    else {3729        const ret = firstChild.codegenNode;3730        const vnodeCall = getMemoedVNodeCall(ret);3731        // Change createVNode to createBlock.3732        if (vnodeCall.type === 13 /* VNODE_CALL */) {3733            makeBlock(vnodeCall, context);3734        }3735        // inject branch key3736        injectProp(vnodeCall, keyProperty, context);3737        return ret;3738    }3739}3740function isSameKey(a, b) {3741    if (!a || a.type !== b.type) {3742        return false;3743    }3744    if (a.type === 6 /* ATTRIBUTE */) {3745        if (a.value.content !== b.value.content) {3746            return false;3747        }3748    }3749    else {3750        // directive3751        const exp = a.exp;3752        const branchExp = b.exp;3753        if (exp.type !== branchExp.type) {3754            return false;3755        }3756        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3757            exp.isStatic !== branchExp.isStatic ||3758            exp.content !== branchExp.content) {3759            return false;3760        }3761    }3762    return true;3763}3764function getParentCondition(node) {3765    while (true) {3766        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3767            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3768                node = node.alternate;3769            }3770            else {3771                return node;3772            }3773        }3774        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3775            node = node.value;3776        }3777    }3778}3779const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3780    const { helper, removeHelper } = context;3781    return processFor(node, dir, context, forNode => {3782        // create the loop render function expression now, and add the3783        // iterator on exit after all children have been traversed3784        const renderExp = createCallExpression(helper(RENDER_LIST), [3785            forNode.source3786        ]);3787        const memo = findDir(node, 'memo');3788        const keyProp = findProp(node, `key`);3789        const keyExp = keyProp &&3790            (keyProp.type === 6 /* ATTRIBUTE */3791                ? createSimpleExpression(keyProp.value.content, true)3792                : keyProp.exp);3793        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3794        if (context.prefixIdentifiers &&3795            keyProperty &&3796            keyProp.type !== 6 /* ATTRIBUTE */) {3797            // #2085 process :key expression needs to be processed in order for it3798            // to behave consistently for <template v-for> and <div v-for>.3799            // In the case of `<template v-for>`, the node is discarded and never3800            // traversed so its key expression won't be processed by the normal3801            // transforms.3802            keyProperty.value = processExpression(keyProperty.value, context);3803        }3804        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3805            forNode.source.constType > 0 /* NOT_CONSTANT */;3806        const fragmentFlag = isStableFragment3807            ? 64 /* STABLE_FRAGMENT */3808            : keyProp3809                ? 128 /* KEYED_FRAGMENT */3810                : 256 /* UNKEYED_FRAGMENT */;3811        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3812            (` /* ${shared.PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3813        return () => {3814            // finish the codegen now that all children have been traversed3815            let childBlock;3816            const isTemplate = isTemplateNode(node);3817            const { children } = forNode;3818            // check <template v-for> key placement3819            if (isTemplate) {3820                node.children.some(c => {3821                    if (c.type === 1 /* ELEMENT */) {3822                        const key = findProp(c, 'key');3823                        if (key) {3824                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3825                            return true;3826                        }3827                    }3828                });3829            }3830            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3831            const slotOutlet = isSlotOutlet(node)3832                ? node3833                : isTemplate &&3834                    node.children.length === 1 &&3835                    isSlotOutlet(node.children[0])3836                    ? node.children[0] // api-extractor somehow fails to infer this3837                    : null;3838            if (slotOutlet) {3839                // <slot v-for="..."> or <template v-for="..."><slot/></template>3840                childBlock = slotOutlet.codegenNode;3841                if (isTemplate && keyProperty) {3842                    // <template v-for="..." :key="..."><slot/></template>3843                    // we need to inject the key to the renderSlot() call.3844                    // the props for renderSlot is passed as the 3rd argument.3845                    injectProp(childBlock, keyProperty, context);3846                }3847            }3848            else if (needFragmentWrapper) {3849                // <template v-for="..."> with text or multi-elements3850                // should generate a fragment block for each loop3851                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3852                    (` /* ${shared.PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3853                        ), undefined, undefined, true, undefined, false /* isComponent */);3854            }3855            else {3856                // Normal element v-for. Directly use the child's codegenNode3857                // but mark it as a block.3858                childBlock = children[0]3859                    .codegenNode;3860                if (isTemplate && keyProperty) {3861                    injectProp(childBlock, keyProperty, context);3862                }3863                if (childBlock.isBlock !== !isStableFragment) {3864                    if (childBlock.isBlock) {3865                        // switch from block to vnode3866                        removeHelper(OPEN_BLOCK);3867                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3868                    }3869                    else {3870                        // switch from vnode to block3871                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3872                    }3873                }3874                childBlock.isBlock = !isStableFragment;3875                if (childBlock.isBlock) {3876                    helper(OPEN_BLOCK);3877                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3878                }3879                else {3880                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3881                }3882            }3883            if (memo) {3884                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3885                    createSimpleExpression(`_cached`)3886                ]));3887                loop.body = createBlockStatement([3888                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3889                    createCompoundExpression([3890                        `if (_cached`,3891                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),3892                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3893                    ]),3894                    createCompoundExpression([`const _item = `, childBlock]),3895                    createSimpleExpression(`_item.memo = _memo`),3896                    createSimpleExpression(`return _item`)3897                ]);3898                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3899            }3900            else {3901                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3902            }3903        };3904    });3905});3906// target-agnostic transform used for both Client and SSR3907function processFor(node, dir, context, processCodegen) {3908    if (!dir.exp) {3909        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3910        return;3911    }3912    const parseResult = parseForExpression(3913    // can only be simple expression because vFor transform is applied3914    // before expression transform.3915    dir.exp, context);3916    if (!parseResult) {3917        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3918        return;3919    }3920    const { addIdentifiers, removeIdentifiers, scopes } = context;3921    const { source, value, key, index } = parseResult;3922    const forNode = {3923        type: 11 /* FOR */,3924        loc: dir.loc,3925        source,3926        valueAlias: value,3927        keyAlias: key,3928        objectIndexAlias: index,3929        parseResult,3930        children: isTemplateNode(node) ? node.children : [node]3931    };3932    context.replaceNode(forNode);3933    // bookkeeping3934    scopes.vFor++;3935    if (context.prefixIdentifiers) {3936        // scope management3937        // inject identifiers to context3938        value && addIdentifiers(value);3939        key && addIdentifiers(key);3940        index && addIdentifiers(index);3941    }3942    const onExit = processCodegen && processCodegen(forNode);3943    return () => {3944        scopes.vFor--;3945        if (context.prefixIdentifiers) {3946            value && removeIdentifiers(value);3947            key && removeIdentifiers(key);3948            index && removeIdentifiers(index);3949        }3950        if (onExit)3951            onExit();3952    };3953}3954const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3955// This regex doesn't cover the case if key or index aliases have destructuring,3956// but those do not make sense in the first place, so this works in practice.3957const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3958const stripParensRE = /^\(|\)$/g;3959function parseForExpression(input, context) {3960    const loc = input.loc;3961    const exp = input.content;3962    const inMatch = exp.match(forAliasRE);3963    if (!inMatch)3964        return;3965    const [, LHS, RHS] = inMatch;3966    const result = {3967        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3968        value: undefined,3969        key: undefined,3970        index: undefined3971    };3972    if (context.prefixIdentifiers) {3973        result.source = processExpression(result.source, context);3974    }3975    let valueContent = LHS.trim().replace(stripParensRE, '').trim();3976    const trimmedOffset = LHS.indexOf(valueContent);3977    const iteratorMatch = valueContent.match(forIteratorRE);3978    if (iteratorMatch) {3979        valueContent = valueContent.replace(forIteratorRE, '').trim();3980        const keyContent = iteratorMatch[1].trim();3981        let keyOffset;3982        if (keyContent) {3983            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3984            result.key = createAliasExpression(loc, keyContent, keyOffset);3985            if (context.prefixIdentifiers) {3986                result.key = processExpression(result.key, context, true);3987            }3988        }3989        if (iteratorMatch[2]) {3990            const indexContent = iteratorMatch[2].trim();3991            if (indexContent) {3992                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3993                    ? keyOffset + keyContent.length3994                    : trimmedOffset + valueContent.length));3995                if (context.prefixIdentifiers) {3996                    result.index = processExpression(result.index, context, true);3997                }3998            }3999        }4000    }4001    if (valueContent) {4002        result.value = createAliasExpression(loc, valueContent, trimmedOffset);4003        if (context.prefixIdentifiers) {4004            result.value = processExpression(result.value, context, true);4005        }4006    }4007    return result;4008}4009function createAliasExpression(range, content, offset) {4010    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));4011}4012function createForLoopParams({ value, key, index }, memoArgs = []) {4013    return createParamsList([value, key, index, ...memoArgs]);4014}4015function createParamsList(args) {4016    let i = args.length;4017    while (i--) {4018        if (args[i])4019            break;4020    }4021    return args4022        .slice(0, i + 1)4023        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));4024}4025const defaultFallback = createSimpleExpression(`undefined`, false);4026// A NodeTransform that:4027// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed4028//    by transformExpression. This is only applied in non-browser builds with4029//    { prefixIdentifiers: true }.4030// 2. Track v-slot depths so that we know a slot is inside another slot.4031//    Note the exit callback is executed before buildSlots() on the same node,4032//    so only nested slots see positive numbers.4033const trackSlotScopes = (node, context) => {4034    if (node.type === 1 /* ELEMENT */ &&4035        (node.tagType === 1 /* COMPONENT */ ||4036            node.tagType === 3 /* TEMPLATE */)) {4037        // We are only checking non-empty v-slot here4038        // since we only care about slots that introduce scope variables.4039        const vSlot = findDir(node, 'slot');4040        if (vSlot) {4041            const slotProps = vSlot.exp;4042            if (context.prefixIdentifiers) {4043                slotProps && context.addIdentifiers(slotProps);4044            }4045            context.scopes.vSlot++;4046            return () => {4047                if (context.prefixIdentifiers) {4048                    slotProps && context.removeIdentifiers(slotProps);4049                }4050                context.scopes.vSlot--;4051            };4052        }4053    }4054};4055// A NodeTransform that tracks scope identifiers for scoped slots with v-for.4056// This transform is only applied in non-browser builds with { prefixIdentifiers: true }4057const trackVForSlotScopes = (node, context) => {4058    let vFor;4059    if (isTemplateNode(node) &&4060        node.props.some(isVSlot) &&4061        (vFor = findDir(node, 'for'))) {4062        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));4063        if (result) {4064            const { value, key, index } = result;4065            const { addIdentifiers, removeIdentifiers } = context;4066            value && addIdentifiers(value);4067            key && addIdentifiers(key);4068            index && addIdentifiers(index);4069            return () => {4070                value && removeIdentifiers(value);4071                key && removeIdentifiers(key);4072                index && removeIdentifiers(index);4073            };4074        }4075    }4076};4077const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);4078// Instead of being a DirectiveTransform, v-slot processing is called during4079// transformElement to build the slots object for a component.4080function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {4081    context.helper(WITH_CTX);4082    const { children, loc } = node;4083    const slotsProperties = [];4084    const dynamicSlots = [];4085    // If the slot is inside a v-for or another v-slot, force it to be dynamic4086    // since it likely uses a scope variable.4087    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;4088    // with `prefixIdentifiers: true`, this can be further optimized to make4089    // it dynamic only when the slot actually uses the scope variables.4090    if (!context.ssr && context.prefixIdentifiers) {4091        hasDynamicSlots = hasScopeRef(node, context.identifiers);4092    }4093    // 1. Check for slot with slotProps on component itself.4094    //    <Comp v-slot="{ prop }"/>4095    const onComponentSlot = findDir(node, 'slot', true);4096    if (onComponentSlot) {4097        const { arg, exp } = onComponentSlot;4098        if (arg && !isStaticExp(arg)) {4099            hasDynamicSlots = true;4100        }4101        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));4102    }4103    // 2. Iterate through children and check for template slots4104    //    <template v-slot:foo="{ prop }">4105    let hasTemplateSlots = false;4106    let hasNamedDefaultSlot = false;4107    const implicitDefaultChildren = [];4108    const seenSlotNames = new Set();4109    for (let i = 0; i < children.length; i++) {4110        const slotElement = children[i];4111        let slotDir;4112        if (!isTemplateNode(slotElement) ||4113            !(slotDir = findDir(slotElement, 'slot', true))) {4114            // not a <template v-slot>, skip.4115            if (slotElement.type !== 3 /* COMMENT */) {4116                implicitDefaultChildren.push(slotElement);4117            }4118            continue;4119        }4120        if (onComponentSlot) {4121            // already has on-component slot - this is incorrect usage.4122            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));4123            break;4124        }4125        hasTemplateSlots = true;4126        const { children: slotChildren, loc: slotLoc } = slotElement;4127        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;4128        // check if name is dynamic.4129        let staticSlotName;4130        if (isStaticExp(slotName)) {4131            staticSlotName = slotName ? slotName.content : `default`;4132        }4133        else {4134            hasDynamicSlots = true;4135        }4136        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);4137        // check if this slot is conditional (v-if/v-for)4138        let vIf;4139        let vElse;4140        let vFor;4141        if ((vIf = findDir(slotElement, 'if'))) {4142            hasDynamicSlots = true;4143            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));4144        }4145        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {4146            // find adjacent v-if4147            let j = i;4148            let prev;4149            while (j--) {4150                prev = children[j];4151                if (prev.type !== 3 /* COMMENT */) {4152                    break;4153                }4154            }4155            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {4156                // remove node4157                children.splice(i, 1);4158                i--;4159                // attach this slot to previous conditional4160                let conditional = dynamicSlots[dynamicSlots.length - 1];4161                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {4162                    conditional = conditional.alternate;4163                }4164                conditional.alternate = vElse.exp4165                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)4166                    : buildDynamicSlot(slotName, slotFunction);4167            }4168            else {4169                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));4170            }4171        }4172        else if ((vFor = findDir(slotElement, 'for'))) {4173            hasDynamicSlots = true;4174            const parseResult = vFor.parseResult ||4175                parseForExpression(vFor.exp, context);4176            if (parseResult) {4177                // Render the dynamic slots as an array and add it to the createSlot()4178                // args. The runtime knows how to handle it appropriately.4179                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [4180                    parseResult.source,4181                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)4182                ]));4183            }4184            else {4185                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));4186            }4187        }4188        else {4189            // check duplicate static names4190            if (staticSlotName) {4191                if (seenSlotNames.has(staticSlotName)) {4192                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));4193                    continue;4194                }4195                seenSlotNames.add(staticSlotName);4196                if (staticSlotName === 'default') {4197                    hasNamedDefaultSlot = true;4198                }4199            }4200            slotsProperties.push(createObjectProperty(slotName, slotFunction));4201        }4202    }4203    if (!onComponentSlot) {4204        const buildDefaultSlotProperty = (props, children) => {4205            const fn = buildSlotFn(props, children, loc);4206            if (context.compatConfig) {4207                fn.isNonScopedSlot = true;4208            }4209            return createObjectProperty(`default`, fn);4210        };4211        if (!hasTemplateSlots) {4212            // implicit default slot (on component)4213            slotsProperties.push(buildDefaultSlotProperty(undefined, children));4214        }4215        else if (implicitDefaultChildren.length &&4216            // #37664217            // with whitespace: 'preserve', whitespaces between slots will end up in4218            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.4219            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {4220            // implicit default slot (mixed with named slots)4221            if (hasNamedDefaultSlot) {4222                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));4223            }4224            else {4225                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));4226            }4227        }4228    }4229    const slotFlag = hasDynamicSlots4230        ? 2 /* DYNAMIC */4231        : hasForwardedSlots(node.children)4232            ? 3 /* FORWARDED */4233            : 1 /* STABLE */;4234    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 4235    // 2 = compiled but dynamic = can skip normalization, but must run diff4236    // 1 = compiled and static = can skip normalization AND diff as optimized4237    createSimpleExpression(slotFlag + (` /* ${shared.slotFlagsText[slotFlag]} */` ), false))), loc);4238    if (dynamicSlots.length) {4239        slots = createCallExpression(context.helper(CREATE_SLOTS), [4240            slots,4241            createArrayExpression(dynamicSlots)4242        ]);4243    }4244    return {4245        slots,4246        hasDynamicSlots4247    };4248}4249function buildDynamicSlot(name, fn) {4250    return createObjectExpression([4251        createObjectProperty(`name`, name),4252        createObjectProperty(`fn`, fn)4253    ]);4254}4255function hasForwardedSlots(children) {4256    for (let i = 0; i < children.length; i++) {4257        const child = children[i];4258        switch (child.type) {4259            case 1 /* ELEMENT */:4260                if (child.tagType === 2 /* SLOT */ ||4261                    hasForwardedSlots(child.children)) {4262                    return true;4263                }4264                break;4265            case 9 /* IF */:4266                if (hasForwardedSlots(child.branches))4267                    return true;4268                break;4269            case 10 /* IF_BRANCH */:4270            case 11 /* FOR */:4271                if (hasForwardedSlots(child.children))4272                    return true;4273                break;4274        }4275    }4276    return false;4277}4278function isNonWhitespaceContent(node) {4279    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)4280        return true;4281    return node.type === 2 /* TEXT */4282        ? !!node.content.trim()4283        : isNonWhitespaceContent(node.content);4284}4285// some directive transforms (e.g. v-model) may return a symbol for runtime4286// import, which should be used instead of a resolveDirective call.4287const directiveImportMap = new WeakMap();4288// generate a JavaScript AST for this element's codegen4289const transformElement = (node, context) => {4290    // perform the work on exit, after all child expressions have been4291    // processed and merged.4292    return function postTransformElement() {4293        node = context.currentNode;4294        if (!(node.type === 1 /* ELEMENT */ &&4295            (node.tagType === 0 /* ELEMENT */ ||4296                node.tagType === 1 /* COMPONENT */))) {4297            return;4298        }4299        const { tag, props } = node;4300        const isComponent = node.tagType === 1 /* COMPONENT */;4301        // The goal of the transform is to create a codegenNode implementing the4302        // VNodeCall interface.4303        let vnodeTag = isComponent4304            ? resolveComponentType(node, context)4305            : `"${tag}"`;4306        const isDynamicComponent = shared.isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;4307        let vnodeProps;4308        let vnodeChildren;4309        let vnodePatchFlag;4310        let patchFlag = 0;4311        let vnodeDynamicProps;4312        let dynamicPropNames;4313        let vnodeDirectives;4314        let shouldUseBlock = 4315        // dynamic component may resolve to plain elements4316        isDynamicComponent ||4317            vnodeTag === TELEPORT ||4318            vnodeTag === SUSPENSE ||4319            (!isComponent &&4320                // <svg> and <foreignObject> must be forced into blocks so that block4321                // updates inside get proper isSVG flag at runtime. (#639, #643)4322                // This is technically web-specific, but splitting the logic out of core4323                // leads to too much unnecessary complexity.4324                (tag === 'svg' || tag === 'foreignObject'));4325        // props4326        if (props.length > 0) {4327            const propsBuildResult = buildProps(node, context);4328            vnodeProps = propsBuildResult.props;4329            patchFlag = propsBuildResult.patchFlag;4330            dynamicPropNames = propsBuildResult.dynamicPropNames;4331            const directives = propsBuildResult.directives;4332            vnodeDirectives =4333                directives && directives.length4334                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))4335                    : undefined;4336            if (propsBuildResult.shouldUseBlock) {4337                shouldUseBlock = true;4338            }4339        }4340        // children4341        if (node.children.length > 0) {4342            if (vnodeTag === KEEP_ALIVE) {4343                // Although a built-in component, we compile KeepAlive with raw children4344                // instead of slot functions so that it can be used inside Transition4345                // or other Transition-wrapping HOCs.4346                // To ensure correct updates with block optimizations, we need to:4347                // 1. Force keep-alive into a block. This avoids its children being4348                //    collected by a parent block.4349                shouldUseBlock = true;4350                // 2. Force keep-alive to always be updated, since it uses raw children.4351                patchFlag |= 1024 /* DYNAMIC_SLOTS */;4352                if (node.children.length > 1) {4353                    context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {4354                        start: node.children[0].loc.start,4355                        end: node.children[node.children.length - 1].loc.end,4356                        source: ''4357                    }));4358                }4359            }4360            const shouldBuildAsSlots = isComponent &&4361                // Teleport is not a real component and has dedicated runtime handling4362                vnodeTag !== TELEPORT &&4363                // explained above.4364                vnodeTag !== KEEP_ALIVE;4365            if (shouldBuildAsSlots) {4366                const { slots, hasDynamicSlots } = buildSlots(node, context);4367                vnodeChildren = slots;4368                if (hasDynamicSlots) {4369                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;4370                }4371            }4372            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {4373                const child = node.children[0];4374                const type = child.type;4375                // check for dynamic text children4376                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||4377                    type === 8 /* COMPOUND_EXPRESSION */;4378                if (hasDynamicTextChild &&4379                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4380                    patchFlag |= 1 /* TEXT */;4381                }4382                // pass directly if the only child is a text node4383                // (plain / interpolation / expression)4384                if (hasDynamicTextChild || type === 2 /* TEXT */) {4385                    vnodeChildren = child;4386                }4387                else {4388                    vnodeChildren = node.children;4389                }4390            }4391            else {4392                vnodeChildren = node.children;4393            }4394        }4395        // patchFlag & dynamicPropNames4396        if (patchFlag !== 0) {4397            {4398                if (patchFlag < 0) {4399                    // special flags (negative and mutually exclusive)4400                    vnodePatchFlag = patchFlag + ` /* ${shared.PatchFlagNames[patchFlag]} */`;4401                }4402                else {4403                    // bitwise flags4404                    const flagNames = Object.keys(shared.PatchFlagNames)4405                        .map(Number)4406                        .filter(n => n > 0 && patchFlag & n)4407                        .map(n => shared.PatchFlagNames[n])4408                        .join(`, `);4409                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;4410                }4411            }4412            if (dynamicPropNames && dynamicPropNames.length) {4413                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);4414            }4415        }4416        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);4417    };4418};4419function resolveComponentType(node, context, ssr = false) {4420    let { tag } = node;4421    // 1. dynamic component4422    const isExplicitDynamic = isComponentTag(tag);4423    const isProp = findProp(node, 'is');4424    if (isProp) {4425        if (isExplicitDynamic ||4426            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {4427            const exp = isProp.type === 6 /* ATTRIBUTE */4428                ? isProp.value && createSimpleExpression(isProp.value.content, true)4429                : isProp.exp;4430            if (exp) {4431                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4432                    exp4433                ]);4434            }4435        }4436        else if (isProp.type === 6 /* ATTRIBUTE */ &&4437            isProp.value.content.startsWith('vue:')) {4438            // <button is="vue:xxx">4439            // if not <component>, only is value that starts with "vue:" will be4440            // treated as component by the parse phase and reach here, unless it's4441            // compat mode where all is values are considered components4442            tag = isProp.value.content.slice(4);4443        }4444    }4445    // 1.5 v-is (TODO: Deprecate)4446    const isDir = !isExplicitDynamic && findDir(node, 'is');4447    if (isDir && isDir.exp) {4448        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4449            isDir.exp4450        ]);4451    }4452    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)4453    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);4454    if (builtIn) {4455        // built-ins are simply fallthroughs / have special handling during ssr4456        // so we don't need to import their runtime equivalents4457        if (!ssr)4458            context.helper(builtIn);4459        return builtIn;4460    }4461    // 3. user component (from setup bindings)4462    // this is skipped in browser build since browser builds do not perform4463    // binding analysis.4464    {4465        const fromSetup = resolveSetupReference(tag, context);4466        if (fromSetup) {4467            return fromSetup;4468        }4469        const dotIndex = tag.indexOf('.');4470        if (dotIndex > 0) {4471            const ns = resolveSetupReference(tag.slice(0, dotIndex), context);4472            if (ns) {4473                return ns + tag.slice(dotIndex);4474            }4475        }4476    }4477    // 4. Self referencing component (inferred from filename)4478    if (context.selfName &&4479        shared.capitalize(shared.camelize(tag)) === context.selfName) {4480        context.helper(RESOLVE_COMPONENT);4481        // codegen.ts has special check for __self postfix when generating4482        // component imports, which will pass additional `maybeSelfReference` flag4483        // to `resolveComponent`.4484        context.components.add(tag + `__self`);4485        return toValidAssetId(tag, `component`);4486    }4487    // 5. user component (resolve)4488    context.helper(RESOLVE_COMPONENT);4489    context.components.add(tag);4490    return toValidAssetId(tag, `component`);4491}4492function resolveSetupReference(name, context) {4493    const bindings = context.bindingMetadata;4494    if (!bindings || bindings.__isScriptSetup === false) {4495        return;4496    }4497    const camelName = shared.camelize(name);4498    const PascalName = shared.capitalize(camelName);4499    const checkType = (type) => {4500        if (bindings[name] === type) {4501            return name;4502        }4503        if (bindings[camelName] === type) {4504            return camelName;4505        }4506        if (bindings[PascalName] === type) {4507            return PascalName;4508        }4509    };4510    const fromConst = checkType("setup-const" /* SETUP_CONST */);4511    if (fromConst) {4512        return context.inline4513            ? // in inline mode, const setup bindings (e.g. imports) can be used as-is4514                fromConst4515            : `$setup[${JSON.stringify(fromConst)}]`;4516    }4517    const fromMaybeRef = checkType("setup-let" /* SETUP_LET */) ||4518        checkType("setup-ref" /* SETUP_REF */) ||4519        checkType("setup-maybe-ref" /* SETUP_MAYBE_REF */);4520    if (fromMaybeRef) {4521        return context.inline4522            ? // setup scope bindings that may be refs need to be unrefed4523                `${context.helperString(UNREF)}(${fromMaybeRef})`4524            : `$setup[${JSON.stringify(fromMaybeRef)}]`;4525    }4526}4527function buildProps(node, context, props = node.props, ssr = false) {4528    const { tag, loc: elementLoc, children } = node;4529    const isComponent = node.tagType === 1 /* COMPONENT */;4530    let properties = [];4531    const mergeArgs = [];4532    const runtimeDirectives = [];4533    const hasChildren = children.length > 0;4534    let shouldUseBlock = false;4535    // patchFlag analysis4536    let patchFlag = 0;4537    let hasRef = false;4538    let hasClassBinding = false;4539    let hasStyleBinding = false;4540    let hasHydrationEventBinding = false;4541    let hasDynamicKeys = false;4542    let hasVnodeHook = false;4543    const dynamicPropNames = [];4544    const analyzePatchFlag = ({ key, value }) => {4545        if (isStaticExp(key)) {4546            const name = key.content;4547            const isEventHandler = shared.isOn(name);4548            if (!isComponent &&4549                isEventHandler &&4550                // omit the flag for click handlers because hydration gives click4551                // dedicated fast path.4552                name.toLowerCase() !== 'onclick' &&4553                // omit v-model handlers4554                name !== 'onUpdate:modelValue' &&4555                // omit onVnodeXXX hooks4556                !shared.isReservedProp(name)) {4557                hasHydrationEventBinding = true;4558            }4559            if (isEventHandler && shared.isReservedProp(name)) {4560                hasVnodeHook = true;4561            }4562            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4563                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4564                    value.type === 8 /* COMPOUND_EXPRESSION */) &&4565                    getConstantType(value, context) > 0)) {4566                // skip if the prop is a cached handler or has constant value4567                return;4568            }4569            if (name === 'ref') {4570                hasRef = true;4571            }4572            else if (name === 'class') {4573                hasClassBinding = true;4574            }4575            else if (name === 'style') {4576                hasStyleBinding = true;4577            }4578            else if (name !== 'key' && !dynamicPropNames.includes(name)) {4579                dynamicPropNames.push(name);4580            }4581            // treat the dynamic class and style binding of the component as dynamic props4582            if (isComponent &&4583                (name === 'class' || name === 'style') &&4584                !dynamicPropNames.includes(name)) {4585                dynamicPropNames.push(name);4586            }4587        }4588        else {4589            hasDynamicKeys = true;4590        }4591    };4592    for (let i = 0; i < props.length; i++) {4593        // static attribute4594        const prop = props[i];4595        if (prop.type === 6 /* ATTRIBUTE */) {4596            const { loc, name, value } = prop;4597            let isStatic = true;4598            if (name === 'ref') {4599                hasRef = true;4600                if (context.scopes.vFor > 0) {4601                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4602                }4603                // in inline mode there is no setupState object, so we can't use string4604                // keys to set the ref. Instead, we need to transform it to pass the4605                // actual ref instead.4606                if (value &&4607                    context.inline &&4608                    context.bindingMetadata[value.content]) {4609                    isStatic = false;4610                    properties.push(createObjectProperty(createSimpleExpression('ref_key', true), createSimpleExpression(value.content, true, value.loc)));4611                }4612            }4613            // skip is on <component>, or is="vue:xxx"4614            if (name === 'is' &&4615                (isComponentTag(tag) ||4616                    (value && value.content.startsWith('vue:')) ||4617                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4618                continue;4619            }4620            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));4621        }4622        else {4623            // directives4624            const { name, arg, exp, loc } = prop;4625            const isVBind = name === 'bind';4626            const isVOn = name === 'on';4627            // skip v-slot - it is handled by its dedicated transform.4628            if (name === 'slot') {4629                if (!isComponent) {4630                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4631                }4632                continue;4633            }4634            // skip v-once/v-memo - they are handled by dedicated transforms.4635            if (name === 'once' || name === 'memo') {4636                continue;4637            }4638            // skip v-is and :is on <component>4639            if (name === 'is' ||4640                (isVBind &&4641                    isStaticArgOf(arg, 'is') &&4642                    (isComponentTag(tag) ||4643                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4644                continue;4645            }4646            // skip v-on in SSR compilation4647            if (isVOn && ssr) {4648                continue;4649            }4650            if (4651            // #938: elements with dynamic keys should be forced into blocks4652            (isVBind && isStaticArgOf(arg, 'key')) ||4653                // inline before-update hooks need to force block so that it is invoked4654                // before children4655                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {4656                shouldUseBlock = true;4657            }4658            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {4659                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4660            }4661            // special case for v-bind and v-on with no argument4662            if (!arg && (isVBind || isVOn)) {4663                hasDynamicKeys = true;4664                if (exp) {4665                    if (properties.length) {4666                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4667                        properties = [];4668                    }4669                    if (isVBind) {4670                        {4671                            // 2.x v-bind object order compat4672                            {4673                                const hasOverridableKeys = mergeArgs.some(arg => {4674                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4675                                        return arg.properties.some(({ key }) => {4676                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4677                                                !key.isStatic) {4678                                                return true;4679                                            }4680                                            return (key.content !== 'class' &&4681                                                key.content !== 'style' &&4682                                                !shared.isOn(key.content));4683                                        });4684                                    }4685                                    else {4686                                        // dynamic expression4687                                        return true;4688                                    }4689                                });4690                                if (hasOverridableKeys) {4691                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4692                                }4693                            }4694                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4695                                mergeArgs.unshift(exp);4696                                continue;4697                            }4698                        }4699                        mergeArgs.push(exp);4700                    }4701                    else {4702                        // v-on="obj" -> toHandlers(obj)4703                        mergeArgs.push({4704                            type: 14 /* JS_CALL_EXPRESSION */,4705                            loc,4706                            callee: context.helper(TO_HANDLERS),4707                            arguments: [exp]4708                        });4709                    }4710                }4711                else {4712                    context.onError(createCompilerError(isVBind4713                        ? 34 /* X_V_BIND_NO_EXPRESSION */4714                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));4715                }4716                continue;4717            }4718            const directiveTransform = context.directiveTransforms[name];4719            if (directiveTransform) {4720                // has built-in directive transform.4721                const { props, needRuntime } = directiveTransform(prop, node, context);4722                !ssr && props.forEach(analyzePatchFlag);4723                properties.push(...props);4724                if (needRuntime) {4725                    runtimeDirectives.push(prop);4726                    if (shared.isSymbol(needRuntime)) {4727                        directiveImportMap.set(prop, needRuntime);4728                    }4729                }4730            }4731            else {4732                // no built-in transform, this is a user custom directive.4733                runtimeDirectives.push(prop);4734                // custom dirs may use beforeUpdate so they need to force blocks4735                // to ensure before-update gets called before children update4736                if (hasChildren) {4737                    shouldUseBlock = true;4738                }4739            }4740        }4741    }4742    let propsExpression = undefined;4743    // has v-bind="object" or v-on="object", wrap with mergeProps4744    if (mergeArgs.length) {4745        if (properties.length) {4746            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4747        }4748        if (mergeArgs.length > 1) {4749            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4750        }4751        else {4752            // single v-bind with nothing else - no need for a mergeProps call4753            propsExpression = mergeArgs[0];4754        }4755    }4756    else if (properties.length) {4757        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4758    }4759    // patchFlag analysis4760    if (hasDynamicKeys) {4761        patchFlag |= 16 /* FULL_PROPS */;4762    }4763    else {4764        if (hasClassBinding && !isComponent) {4765            patchFlag |= 2 /* CLASS */;4766        }4767        if (hasStyleBinding && !isComponent) {4768            patchFlag |= 4 /* STYLE */;4769        }4770        if (dynamicPropNames.length) {4771            patchFlag |= 8 /* PROPS */;4772        }4773        if (hasHydrationEventBinding) {4774            patchFlag |= 32 /* HYDRATE_EVENTS */;4775        }4776    }4777    if (!shouldUseBlock &&4778        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4779        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4780        patchFlag |= 512 /* NEED_PATCH */;4781    }4782    // pre-normalize props, SSR is skipped for now4783    if (!context.inSSR && propsExpression) {4784        switch (propsExpression.type) {4785            case 15 /* JS_OBJECT_EXPRESSION */:4786                // means that there is no v-bind,4787                // but still need to deal with dynamic key binding4788                let classKeyIndex = -1;4789                let styleKeyIndex = -1;4790                let hasDynamicKey = false;4791                for (let i = 0; i < propsExpression.properties.length; i++) {4792                    const key = propsExpression.properties[i].key;4793                    if (isStaticExp(key)) {4794                        if (key.content === 'class') {4795                            classKeyIndex = i;4796                        }4797                        else if (key.content === 'style') {4798                            styleKeyIndex = i;4799                        }4800                    }4801                    else if (!key.isHandlerKey) {4802                        hasDynamicKey = true;4803                    }4804                }4805                const classProp = propsExpression.properties[classKeyIndex];4806                const styleProp = propsExpression.properties[styleKeyIndex];4807                // no dynamic key4808                if (!hasDynamicKey) {4809                    if (classProp && !isStaticExp(classProp.value)) {4810                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4811                    }4812                    if (styleProp &&4813                        !isStaticExp(styleProp.value) &&4814                        // the static style is compiled into an object,4815                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding4816                        (hasStyleBinding ||4817                            // v-bind:style and style both exist,4818                            // v-bind:style with static literal object4819                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4820                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4821                    }4822                }4823                else {4824                    // dynamic key binding, wrap with `normalizeProps`4825                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4826                }4827                break;4828            case 14 /* JS_CALL_EXPRESSION */:4829                // mergeProps call, do nothing4830                break;4831            default:4832                // single v-bind4833                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4834                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4835                        propsExpression4836                    ])4837                ]);4838                break;4839        }4840    }4841    return {4842        props: propsExpression,4843        directives: runtimeDirectives,4844        patchFlag,4845        dynamicPropNames,4846        shouldUseBlock4847    };4848}4849// Dedupe props in an object literal.4850// Literal duplicated attributes would have been warned during the parse phase,4851// however, it's possible to encounter duplicated `onXXX` handlers with different4852// modifiers. We also need to merge static and dynamic class / style attributes.4853// - onXXX handlers / style: merge into array4854// - class: merge into single expression with concatenation4855function dedupeProperties(properties) {4856    const knownProps = new Map();4857    const deduped = [];4858    for (let i = 0; i < properties.length; i++) {4859        const prop = properties[i];4860        // dynamic keys are always allowed4861        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4862            deduped.push(prop);4863            continue;4864        }4865        const name = prop.key.content;4866        const existing = knownProps.get(name);4867        if (existing) {4868            if (name === 'style' || name === 'class' || shared.isOn(name)) {4869                mergeAsArray(existing, prop);4870            }4871            // unexpected duplicate, should have emitted error during parse4872        }4873        else {4874            knownProps.set(name, prop);4875            deduped.push(prop);4876        }4877    }4878    return deduped;4879}4880function mergeAsArray(existing, incoming) {4881    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4882        existing.value.elements.push(incoming.value);4883    }4884    else {4885        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4886    }4887}4888function buildDirectiveArgs(dir, context) {4889    const dirArgs = [];4890    const runtime = directiveImportMap.get(dir);4891    if (runtime) {4892        // built-in directive with runtime4893        dirArgs.push(context.helperString(runtime));4894    }4895    else {4896        // user directive.4897        // see if we have directives exposed via <script setup>4898        const fromSetup = resolveSetupReference('v-' + dir.name, context);4899        if (fromSetup) {4900            dirArgs.push(fromSetup);4901        }4902        else {4903            // inject statement for resolving directive4904            context.helper(RESOLVE_DIRECTIVE);4905            context.directives.add(dir.name);4906            dirArgs.push(toValidAssetId(dir.name, `directive`));4907        }4908    }4909    const { loc } = dir;4910    if (dir.exp)4911        dirArgs.push(dir.exp);4912    if (dir.arg) {4913        if (!dir.exp) {4914            dirArgs.push(`void 0`);4915        }4916        dirArgs.push(dir.arg);4917    }4918    if (Object.keys(dir.modifiers).length) {4919        if (!dir.arg) {4920            if (!dir.exp) {4921                dirArgs.push(`void 0`);4922            }4923            dirArgs.push(`void 0`);4924        }4925        const trueExpression = createSimpleExpression(`true`, false, loc);4926        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4927    }4928    return createArrayExpression(dirArgs, dir.loc);4929}4930function stringifyDynamicPropNames(props) {4931    let propsNamesString = `[`;4932    for (let i = 0, l = props.length; i < l; i++) {4933        propsNamesString += JSON.stringify(props[i]);4934        if (i < l - 1)4935            propsNamesString += ', ';4936    }4937    return propsNamesString + `]`;4938}4939function isComponentTag(tag) {4940    return tag === 'component' || tag === 'Component';4941}4942Object.freeze({})4943    ;4944Object.freeze([]) ;4945const cacheStringFunction = (fn) => {4946    const cache = Object.create(null);4947    return ((str) => {4948        const hit = cache[str];4949        return hit || (cache[str] = fn(str));4950    });4951};4952const camelizeRE = /-(\w)/g;4953/**4954 * @private4955 */4956const camelize = cacheStringFunction((str) => {4957    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));4958});4959const transformSlotOutlet = (node, context) => {4960    if (isSlotOutlet(node)) {4961        const { children, loc } = node;4962        const { slotName, slotProps } = processSlotOutlet(node, context);4963        const slotArgs = [4964            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4965            slotName,4966            '{}',4967            'undefined',4968            'true'4969        ];4970        let expectedLen = 2;4971        if (slotProps) {4972            slotArgs[2] = slotProps;4973            expectedLen = 3;4974        }4975        if (children.length) {4976            slotArgs[3] = createFunctionExpression([], children, false, false, loc);4977            expectedLen = 4;4978        }4979        if (context.scopeId && !context.slotted) {4980            expectedLen = 5;4981        }4982        slotArgs.splice(expectedLen); // remove unused arguments4983        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4984    }4985};4986function processSlotOutlet(node, context) {4987    let slotName = `"default"`;4988    let slotProps = undefined;4989    const nonNameProps = [];4990    for (let i = 0; i < node.props.length; i++) {4991        const p = node.props[i];4992        if (p.type === 6 /* ATTRIBUTE */) {4993            if (p.value) {4994                if (p.name === 'name') {4995                    slotName = JSON.stringify(p.value.content);4996                }4997                else {4998                    p.name = camelize(p.name);4999                    nonNameProps.push(p);5000                }5001            }5002        }5003        else {5004            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {5005                if (p.exp)5006                    slotName = p.exp;5007            }5008            else {5009                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {5010                    p.arg.content = camelize(p.arg.content);5011                }5012                nonNameProps.push(p);5013            }5014        }5015    }5016    if (nonNameProps.length > 0) {5017        const { props, directives } = buildProps(node, context, nonNameProps);5018        slotProps = props;5019        if (directives.length) {5020            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));5021        }5022    }5023    return {5024        slotName,5025        slotProps5026    };5027}5028const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;5029const transformOn = (dir, node, context, augmentor) => {5030    const { loc, modifiers, arg } = dir;5031    if (!dir.exp && !modifiers.length) {5032        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));5033    }5034    let eventName;5035    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5036        if (arg.isStatic) {5037            let rawName = arg.content;5038            // TODO deprecate @vnodeXXX usage5039            if (rawName.startsWith('vue:')) {5040                rawName = `vnode-${rawName.slice(4)}`;5041            }5042            // for all event listeners, auto convert it to camelCase. See issue #22495043            eventName = createSimpleExpression(shared.toHandlerKey(shared.camelize(rawName)), true, arg.loc);5044        }5045        else {5046            // #23885047            eventName = createCompoundExpression([5048                `${context.helperString(TO_HANDLER_KEY)}(`,5049                arg,5050                `)`5051            ]);5052        }5053    }5054    else {5055        // already a compound expression.5056        eventName = arg;5057        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);5058        eventName.children.push(`)`);5059    }5060    // handler processing5061    let exp = dir.exp;5062    if (exp && !exp.content.trim()) {5063        exp = undefined;5064    }5065    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;5066    if (exp) {5067        const isMemberExp = isMemberExpression(exp.content, context);5068        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));5069        const hasMultipleStatements = exp.content.includes(`;`);5070        // process the expression since it's been skipped5071        if (context.prefixIdentifiers) {5072            isInlineStatement && context.addIdentifiers(`$event`);5073            exp = dir.exp = processExpression(exp, context, false, hasMultipleStatements);5074            isInlineStatement && context.removeIdentifiers(`$event`);5075            // with scope analysis, the function is hoistable if it has no reference5076            // to scope variables.5077            shouldCache =5078                context.cacheHandlers &&5079                    // unnecessary to cache inside v-once5080                    !context.inVOnce &&5081                    // runtime constants don't need to be cached5082                    // (this is analyzed by compileScript in SFC <script setup>)5083                    !(exp.type === 4 /* SIMPLE_EXPRESSION */ && exp.constType > 0) &&5084                    // #1541 bail if this is a member exp handler passed to a component -5085                    // we need to use the original function to preserve arity,5086                    // e.g. <transition> relies on checking cb.length to determine5087                    // transition end handling. Inline function is ok since its arity5088                    // is preserved even when cached.5089                    !(isMemberExp && node.tagType === 1 /* COMPONENT */) &&5090                    // bail if the function references closure variables (v-for, v-slot)5091                    // it must be passed fresh to avoid stale values.5092                    !hasScopeRef(exp, context.identifiers);5093            // If the expression is optimizable and is a member expression pointing5094            // to a function, turn it into invocation (and wrap in an arrow function5095            // below) so that it always accesses the latest value when called - thus5096            // avoiding the need to be patched.5097            if (shouldCache && isMemberExp) {5098                if (exp.type === 4 /* SIMPLE_EXPRESSION */) {5099                    exp.content = `${exp.content} && ${exp.content}(...args)`;5100                }5101                else {5102                    exp.children = [...exp.children, ` && `, ...exp.children, `(...args)`];5103                }5104            }5105        }5106        if (isInlineStatement || (shouldCache && isMemberExp)) {5107            // wrap inline statement in a function expression5108            exp = createCompoundExpression([5109                `${isInlineStatement5110                    ? context.isTS5111                        ? `($event: any)`5112                        : `$event`5113                    : `${context.isTS ? `\n//@ts-ignore\n` : ``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,5114                exp,5115                hasMultipleStatements ? `}` : `)`5116            ]);5117        }5118    }5119    let ret = {5120        props: [5121            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))5122        ]5123    };5124    // apply extended compiler augmentor5125    if (augmentor) {5126        ret = augmentor(ret);5127    }5128    if (shouldCache) {5129        // cache handlers so that it's always the same handler being passed down.5130        // this avoids unnecessary re-renders when users use inline handlers on5131        // components.5132        ret.props[0].value = context.cache(ret.props[0].value);5133    }5134    // mark the key as handler for props normalization check5135    ret.props.forEach(p => (p.key.isHandlerKey = true));5136    return ret;5137};5138// v-bind without arg is handled directly in ./transformElements.ts due to it affecting5139// codegen for the entire props object. This transform here is only for v-bind5140// *with* args.5141const transformBind = (dir, _node, context) => {5142    const { exp, modifiers, loc } = dir;5143    const arg = dir.arg;5144    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {5145        arg.children.unshift(`(`);5146        arg.children.push(`) || ""`);5147    }5148    else if (!arg.isStatic) {5149        arg.content = `${arg.content} || ""`;5150    }5151    // .sync is replaced by v-model:arg5152    if (modifiers.includes('camel')) {5153        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5154            if (arg.isStatic) {5155                arg.content = shared.camelize(arg.content);5156            }5157            else {5158                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;5159            }5160        }5161        else {5162            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);5163            arg.children.push(`)`);5164        }5165    }5166    if (!context.inSSR) {5167        if (modifiers.includes('prop')) {5168            injectPrefix(arg, '.');5169        }5170        if (modifiers.includes('attr')) {5171            injectPrefix(arg, '^');5172        }5173    }5174    if (!exp ||5175        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {5176        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));5177        return {5178            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]5179        };5180    }5181    return {5182        props: [createObjectProperty(arg, exp)]5183    };5184};5185const injectPrefix = (arg, prefix) => {5186    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5187        if (arg.isStatic) {5188            arg.content = prefix + arg.content;5189        }5190        else {5191            arg.content = `\`${prefix}\${${arg.content}}\``;5192        }5193    }5194    else {5195        arg.children.unshift(`'${prefix}' + (`);5196        arg.children.push(`)`);5197    }5198};5199// Merge adjacent text nodes and expressions into a single expression5200// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.5201const transformText = (node, context) => {5202    if (node.type === 0 /* ROOT */ ||5203        node.type === 1 /* ELEMENT */ ||5204        node.type === 11 /* FOR */ ||5205        node.type === 10 /* IF_BRANCH */) {5206        // perform the transform on node exit so that all expressions have already5207        // been processed.5208        return () => {5209            const children = node.children;5210            let currentContainer = undefined;5211            let hasText = false;5212            for (let i = 0; i < children.length; i++) {5213                const child = children[i];5214                if (isText(child)) {5215                    hasText = true;5216                    for (let j = i + 1; j < children.length; j++) {5217                        const next = children[j];5218                        if (isText(next)) {5219                            if (!currentContainer) {5220                                currentContainer = children[i] = {5221                                    type: 8 /* COMPOUND_EXPRESSION */,5222                                    loc: child.loc,5223                                    children: [child]5224                                };5225                            }5226                            // merge adjacent text node into current5227                            currentContainer.children.push(` + `, next);5228                            children.splice(j, 1);5229                            j--;5230                        }5231                        else {5232                            currentContainer = undefined;5233                            break;5234                        }5235                    }5236                }5237            }5238            if (!hasText ||5239                // if this is a plain element with a single text child, leave it5240                // as-is since the runtime has dedicated fast path for this by directly5241                // setting textContent of the element.5242                // for component root it's always normalized anyway.5243                (children.length === 1 &&5244                    (node.type === 0 /* ROOT */ ||5245                        (node.type === 1 /* ELEMENT */ &&5246                            node.tagType === 0 /* ELEMENT */ &&5247                            // #37565248                            // custom directives can potentially add DOM elements arbitrarily,5249                            // we need to avoid setting textContent of the element at runtime5250                            // to avoid accidentally overwriting the DOM elements added5251                            // by the user through custom directives.5252                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&5253                                !context.directiveTransforms[p.name]) &&5254                            // in compat mode, <template> tags with no special directives5255                            // will be rendered as a fragment so its children must be5256                            // converted into vnodes.5257                            !(node.tag === 'template'))))) {5258                return;5259            }5260            // pre-convert text nodes into createTextVNode(text) calls to avoid5261            // runtime normalization.5262            for (let i = 0; i < children.length; i++) {5263                const child = children[i];5264                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {5265                    const callArgs = [];5266                    // createTextVNode defaults to single whitespace, so if it is a5267                    // single space the code could be an empty call to save bytes.5268                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {5269                        callArgs.push(child);5270                    }5271                    // mark dynamic text with flag so it gets patched inside a block5272                    if (!context.ssr &&5273                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {5274                        callArgs.push(1 /* TEXT */ +5275                            (` /* ${shared.PatchFlagNames[1 /* TEXT */]} */` ));5276                    }5277                    children[i] = {5278                        type: 12 /* TEXT_CALL */,5279                        content: child,5280                        loc: child.loc,5281                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)5282                    };5283                }5284            }5285        };5286    }5287};5288const seen = new WeakSet();5289const transformOnce = (node, context) => {5290    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {5291        if (seen.has(node) || context.inVOnce) {5292            return;5293        }5294        seen.add(node);5295        context.inVOnce = true;5296        context.helper(SET_BLOCK_TRACKING);5297        return () => {5298            context.inVOnce = false;5299            const cur = context.currentNode;5300            if (cur.codegenNode) {5301                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);5302            }5303        };5304    }5305};5306const transformModel = (dir, node, context) => {5307    const { exp, arg } = dir;5308    if (!exp) {5309        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));5310        return createTransformProps();5311    }5312    const rawExp = exp.loc.source;5313    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;5314    // im SFC <script setup> inline mode, the exp may have been transformed into5315    // _unref(exp)5316    const bindingType = context.bindingMetadata[rawExp];5317    const maybeRef = context.inline &&5318        bindingType &&5319        bindingType !== "setup-const" /* SETUP_CONST */;5320    if (!expString.trim() ||5321        (!isMemberExpression(expString, context) && !maybeRef)) {5322        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));5323        return createTransformProps();5324    }5325    if (context.prefixIdentifiers &&5326        isSimpleIdentifier(expString) &&5327        context.identifiers[expString]) {5328        context.onError(createCompilerError(43 /* X_V_MODEL_ON_SCOPE_VARIABLE */, exp.loc));5329        return createTransformProps();5330    }5331    const propName = arg ? arg : createSimpleExpression('modelValue', true);5332    const eventName = arg5333        ? isStaticExp(arg)5334            ? `onUpdate:${arg.content}`5335            : createCompoundExpression(['"onUpdate:" + ', arg])5336        : `onUpdate:modelValue`;5337    let assignmentExp;5338    const eventArg = context.isTS ? `($event: any)` : `$event`;5339    if (maybeRef) {5340        if (bindingType === "setup-ref" /* SETUP_REF */) {5341            // v-model used on known ref.5342            assignmentExp = createCompoundExpression([5343                `${eventArg} => ((`,5344                createSimpleExpression(rawExp, false, exp.loc),5345                `).value = $event)`5346            ]);5347        }5348        else {5349            // v-model used on a potentially ref binding in <script setup> inline mode.5350            // the assignment needs to check whether the binding is actually a ref.5351            const altAssignment = bindingType === "setup-let" /* SETUP_LET */ ? `${rawExp} = $event` : `null`;5352            assignmentExp = createCompoundExpression([5353                `${eventArg} => (${context.helperString(IS_REF)}(${rawExp}) ? (`,5354                createSimpleExpression(rawExp, false, exp.loc),5355                `).value = $event : ${altAssignment})`5356            ]);5357        }5358    }5359    else {5360        assignmentExp = createCompoundExpression([5361            `${eventArg} => ((`,5362            exp,5363            `) = $event)`5364        ]);5365    }5366    const props = [5367        // modelValue: foo5368        createObjectProperty(propName, dir.exp),5369        // "onUpdate:modelValue": $event => (foo = $event)5370        createObjectProperty(eventName, assignmentExp)5371    ];5372    // cache v-model handler if applicable (when it doesn't refer any scope vars)5373    if (context.prefixIdentifiers &&5374        !context.inVOnce &&5375        context.cacheHandlers &&5376        !hasScopeRef(exp, context.identifiers)) {5377        props[1].value = context.cache(props[1].value);5378    }5379    // modelModifiers: { foo: true, "bar-baz": true }5380    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {5381        const modifiers = dir.modifiers5382            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)5383            .join(`, `);5384        const modifiersKey = arg5385            ? isStaticExp(arg)5386                ? `${arg.content}Modifiers`5387                : createCompoundExpression([arg, ' + "Modifiers"'])5388            : `modelModifiers`;5389        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));5390    }5391    return createTransformProps(props);5392};5393function createTransformProps(props = []) {5394    return { props };5395}5396const validDivisionCharRE = /[\w).+\-_$\]]/;5397const transformFilter = (node, context) => {5398    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {5399        return;5400    }5401    if (node.type === 5 /* INTERPOLATION */) {5402        // filter rewrite is applied before expression transform so only5403        // simple expressions are possible at this stage5404        rewriteFilter(node.content, context);5405    }5406    if (node.type === 1 /* ELEMENT */) {5407        node.props.forEach((prop) => {5408            if (prop.type === 7 /* DIRECTIVE */ &&5409                prop.name !== 'for' &&5410                prop.exp) {5411                rewriteFilter(prop.exp, context);5412            }...compiler-core.cjs.prod.js
Source:compiler-core.cjs.prod.js  
...786    else {787        return value;788    }789}790function isCompatEnabled(key, context) {791    const mode = getCompatValue('MODE', context);792    const value = getCompatValue(key, context);793    // in v3 mode, only enable if explicitly set to true794    // otherwise enable for any non-false value795    return mode === 3 ? value === true : value !== false;796}797function checkCompatEnabled(key, context, loc, ...args) {798    const enabled = isCompatEnabled(key, context);799    return enabled;800}801function warnDeprecation(key, context, loc, ...args) {802    const val = getCompatValue(key, context);803    if (val === 'suppress-warning') {804        return;805    }806    const { message, link } = deprecationData[key];807    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;808    const err = new SyntaxError(msg);809    err.code = key;810    if (loc)811        err.loc = loc;812    context.onWarn(err);813}814// The default decoder only provides escapes for characters reserved as part of815// the template syntax, and is only used if the custom renderer did not provide816// a platform-specific decoder.817const decodeRE = /&(gt|lt|amp|apos|quot);/g;818const decodeMap = {819    gt: '>',820    lt: '<',821    amp: '&',822    apos: "'",823    quot: '"'824};825const defaultParserOptions = {826    delimiters: [`{{`, `}}`],827    getNamespace: () => 0 /* HTML */,828    getTextMode: () => 0 /* DATA */,829    isVoidTag: shared.NO,830    isPreTag: shared.NO,831    isCustomElement: shared.NO,832    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),833    onError: defaultOnError,834    onWarn: defaultOnWarn,835    comments: false836};837function baseParse(content, options = {}) {838    const context = createParserContext(content, options);839    const start = getCursor(context);840    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));841}842function createParserContext(content, rawOptions) {843    const options = shared.extend({}, defaultParserOptions);844    let key;845    for (key in rawOptions) {846        // @ts-ignore847        options[key] =848            rawOptions[key] === undefined849                ? defaultParserOptions[key]850                : rawOptions[key];851    }852    return {853        options,854        column: 1,855        line: 1,856        offset: 0,857        originalSource: content,858        source: content,859        inPre: false,860        inVPre: false,861        onWarn: options.onWarn862    };863}864function parseChildren(context, mode, ancestors) {865    const parent = last(ancestors);866    const ns = parent ? parent.ns : 0 /* HTML */;867    const nodes = [];868    while (!isEnd(context, mode, ancestors)) {869        const s = context.source;870        let node = undefined;871        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {872            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {873                // '{{'874                node = parseInterpolation(context, mode);875            }876            else if (mode === 0 /* DATA */ && s[0] === '<') {877                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state878                if (s.length === 1) {879                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);880                }881                else if (s[1] === '!') {882                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state883                    if (startsWith(s, '<!--')) {884                        node = parseComment(context);885                    }886                    else if (startsWith(s, '<!DOCTYPE')) {887                        // Ignore DOCTYPE by a limitation.888                        node = parseBogusComment(context);889                    }890                    else if (startsWith(s, '<![CDATA[')) {891                        if (ns !== 0 /* HTML */) {892                            node = parseCDATA(context, ancestors);893                        }894                        else {895                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);896                            node = parseBogusComment(context);897                        }898                    }899                    else {900                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);901                        node = parseBogusComment(context);902                    }903                }904                else if (s[1] === '/') {905                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state906                    if (s.length === 2) {907                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);908                    }909                    else if (s[2] === '>') {910                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);911                        advanceBy(context, 3);912                        continue;913                    }914                    else if (/[a-z]/i.test(s[2])) {915                        emitError(context, 23 /* X_INVALID_END_TAG */);916                        parseTag(context, 1 /* End */, parent);917                        continue;918                    }919                    else {920                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);921                        node = parseBogusComment(context);922                    }923                }924                else if (/[a-z]/i.test(s[1])) {925                    node = parseElement(context, ancestors);926                    // 2.x <template> with no directive compat927                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&928                        node &&929                        node.tag === 'template' &&930                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&931                            isSpecialTemplateDirective(p.name))) {932                        node = node.children;933                    }934                }935                else if (s[1] === '?') {936                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);937                    node = parseBogusComment(context);938                }939                else {940                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);941                }942            }943        }944        if (!node) {945            node = parseText(context, mode);946        }947        if (shared.isArray(node)) {948            for (let i = 0; i < node.length; i++) {949                pushNode(nodes, node[i]);950            }951        }952        else {953            pushNode(nodes, node);954        }955    }956    // Whitespace handling strategy like v2957    let removedWhitespace = false;958    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {959        const shouldCondense = context.options.whitespace !== 'preserve';960        for (let i = 0; i < nodes.length; i++) {961            const node = nodes[i];962            if (!context.inPre && node.type === 2 /* TEXT */) {963                if (!/[^\t\r\n\f ]/.test(node.content)) {964                    const prev = nodes[i - 1];965                    const next = nodes[i + 1];966                    // Remove if:967                    // - the whitespace is the first or last node, or:968                    // - (condense mode) the whitespace is adjacent to a comment, or:969                    // - (condense mode) the whitespace is between two elements AND contains newline970                    if (!prev ||971                        !next ||972                        (shouldCondense &&973                            (prev.type === 3 /* COMMENT */ ||974                                next.type === 3 /* COMMENT */ ||975                                (prev.type === 1 /* ELEMENT */ &&976                                    next.type === 1 /* ELEMENT */ &&977                                    /[\r\n]/.test(node.content))))) {978                        removedWhitespace = true;979                        nodes[i] = null;980                    }981                    else {982                        // Otherwise, the whitespace is condensed into a single space983                        node.content = ' ';984                    }985                }986                else if (shouldCondense) {987                    // in condense mode, consecutive whitespaces in text are condensed988                    // down to a single space.989                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');990                }991            }992            // Remove comment nodes if desired by configuration.993            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {994                removedWhitespace = true;995                nodes[i] = null;996            }997        }998        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {999            // remove leading newline per html spec1000            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1001            const first = nodes[0];1002            if (first && first.type === 2 /* TEXT */) {1003                first.content = first.content.replace(/^\r?\n/, '');1004            }1005        }1006    }1007    return removedWhitespace ? nodes.filter(Boolean) : nodes;1008}1009function pushNode(nodes, node) {1010    if (node.type === 2 /* TEXT */) {1011        const prev = last(nodes);1012        // Merge if both this and the previous node are text and those are1013        // consecutive. This happens for cases like "a < b".1014        if (prev &&1015            prev.type === 2 /* TEXT */ &&1016            prev.loc.end.offset === node.loc.start.offset) {1017            prev.content += node.content;1018            prev.loc.end = node.loc.end;1019            prev.loc.source += node.loc.source;1020            return;1021        }1022    }1023    nodes.push(node);1024}1025function parseCDATA(context, ancestors) {1026    advanceBy(context, 9);1027    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1028    if (context.source.length === 0) {1029        emitError(context, 6 /* EOF_IN_CDATA */);1030    }1031    else {1032        advanceBy(context, 3);1033    }1034    return nodes;1035}1036function parseComment(context) {1037    const start = getCursor(context);1038    let content;1039    // Regular comment.1040    const match = /--(\!)?>/.exec(context.source);1041    if (!match) {1042        content = context.source.slice(4);1043        advanceBy(context, context.source.length);1044        emitError(context, 7 /* EOF_IN_COMMENT */);1045    }1046    else {1047        if (match.index <= 3) {1048            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1049        }1050        if (match[1]) {1051            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1052        }1053        content = context.source.slice(4, match.index);1054        // Advancing with reporting nested comments.1055        const s = context.source.slice(0, match.index);1056        let prevIndex = 1, nestedIndex = 0;1057        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1058            advanceBy(context, nestedIndex - prevIndex + 1);1059            if (nestedIndex + 4 < s.length) {1060                emitError(context, 16 /* NESTED_COMMENT */);1061            }1062            prevIndex = nestedIndex + 1;1063        }1064        advanceBy(context, match.index + match[0].length - prevIndex + 1);1065    }1066    return {1067        type: 3 /* COMMENT */,1068        content,1069        loc: getSelection(context, start)1070    };1071}1072function parseBogusComment(context) {1073    const start = getCursor(context);1074    const contentStart = context.source[1] === '?' ? 1 : 2;1075    let content;1076    const closeIndex = context.source.indexOf('>');1077    if (closeIndex === -1) {1078        content = context.source.slice(contentStart);1079        advanceBy(context, context.source.length);1080    }1081    else {1082        content = context.source.slice(contentStart, closeIndex);1083        advanceBy(context, closeIndex + 1);1084    }1085    return {1086        type: 3 /* COMMENT */,1087        content,1088        loc: getSelection(context, start)1089    };1090}1091function parseElement(context, ancestors) {1092    // Start tag.1093    const wasInPre = context.inPre;1094    const wasInVPre = context.inVPre;1095    const parent = last(ancestors);1096    const element = parseTag(context, 0 /* Start */, parent);1097    const isPreBoundary = context.inPre && !wasInPre;1098    const isVPreBoundary = context.inVPre && !wasInVPre;1099    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1100        // #4030 self-closing <pre> tag1101        if (isPreBoundary) {1102            context.inPre = false;1103        }1104        if (isVPreBoundary) {1105            context.inVPre = false;1106        }1107        return element;1108    }1109    // Children.1110    ancestors.push(element);1111    const mode = context.options.getTextMode(element, parent);1112    const children = parseChildren(context, mode, ancestors);1113    ancestors.pop();1114    // 2.x inline-template compat1115    {1116        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1117        if (inlineTemplateProp &&1118            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1119            const loc = getSelection(context, element.loc.end);1120            inlineTemplateProp.value = {1121                type: 2 /* TEXT */,1122                content: loc.source,1123                loc1124            };1125        }1126    }1127    element.children = children;1128    // End tag.1129    if (startsWithEndTagOpen(context.source, element.tag)) {1130        parseTag(context, 1 /* End */, parent);1131    }1132    else {1133        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1134        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1135            const first = children[0];1136            if (first && startsWith(first.loc.source, '<!--')) {1137                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1138            }1139        }1140    }1141    element.loc = getSelection(context, element.loc.start);1142    if (isPreBoundary) {1143        context.inPre = false;1144    }1145    if (isVPreBoundary) {1146        context.inVPre = false;1147    }1148    return element;1149}1150const isSpecialTemplateDirective = /*#__PURE__*/ shared.makeMap(`if,else,else-if,for,slot`);1151function parseTag(context, type, parent) {1152    // Tag open.1153    const start = getCursor(context);1154    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1155    const tag = match[1];1156    const ns = context.options.getNamespace(tag, parent);1157    advanceBy(context, match[0].length);1158    advanceSpaces(context);1159    // save current state in case we need to re-parse attributes with v-pre1160    const cursor = getCursor(context);1161    const currentSource = context.source;1162    // check <pre> tag1163    if (context.options.isPreTag(tag)) {1164        context.inPre = true;1165    }1166    // Attributes.1167    let props = parseAttributes(context, type);1168    // check v-pre1169    if (type === 0 /* Start */ &&1170        !context.inVPre &&1171        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1172        context.inVPre = true;1173        // reset context1174        shared.extend(context, cursor);1175        context.source = currentSource;1176        // re-parse attrs and filter out v-pre itself1177        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1178    }1179    // Tag close.1180    let isSelfClosing = false;1181    if (context.source.length === 0) {1182        emitError(context, 9 /* EOF_IN_TAG */);1183    }1184    else {1185        isSelfClosing = startsWith(context.source, '/>');1186        if (type === 1 /* End */ && isSelfClosing) {1187            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1188        }1189        advanceBy(context, isSelfClosing ? 2 : 1);1190    }1191    if (type === 1 /* End */) {1192        return;1193    }1194    let tagType = 0 /* ELEMENT */;1195    if (!context.inVPre) {1196        if (tag === 'slot') {1197            tagType = 2 /* SLOT */;1198        }1199        else if (tag === 'template') {1200            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1201                tagType = 3 /* TEMPLATE */;1202            }1203        }1204        else if (isComponent(tag, props, context)) {1205            tagType = 1 /* COMPONENT */;1206        }1207    }1208    return {1209        type: 1 /* ELEMENT */,1210        ns,1211        tag,1212        tagType,1213        props,1214        isSelfClosing,1215        children: [],1216        loc: getSelection(context, start),1217        codegenNode: undefined // to be created during transform phase1218    };1219}1220function isComponent(tag, props, context) {1221    const options = context.options;1222    if (options.isCustomElement(tag)) {1223        return false;1224    }1225    if (tag === 'component' ||1226        /^[A-Z]/.test(tag) ||1227        isCoreComponent(tag) ||1228        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1229        (options.isNativeTag && !options.isNativeTag(tag))) {1230        return true;1231    }1232    // at this point the tag should be a native tag, but check for potential "is"1233    // casting1234    for (let i = 0; i < props.length; i++) {1235        const p = props[i];1236        if (p.type === 6 /* ATTRIBUTE */) {1237            if (p.name === 'is' && p.value) {1238                if (p.value.content.startsWith('vue:')) {1239                    return true;1240                }1241                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1242                    return true;1243                }1244            }1245        }1246        else {1247            // directive1248            // v-is (TODO Deprecate)1249            if (p.name === 'is') {1250                return true;1251            }1252            else if (1253            // :is on plain element - only treat as component in compat mode1254            p.name === 'bind' &&1255                isStaticArgOf(p.arg, 'is') &&1256                true &&1257                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1258                return true;1259            }1260        }1261    }1262}1263function parseAttributes(context, type) {1264    const props = [];1265    const attributeNames = new Set();1266    while (context.source.length > 0 &&1267        !startsWith(context.source, '>') &&1268        !startsWith(context.source, '/>')) {1269        if (startsWith(context.source, '/')) {1270            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1271            advanceBy(context, 1);1272            advanceSpaces(context);1273            continue;1274        }1275        if (type === 1 /* End */) {1276            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1277        }1278        const attr = parseAttribute(context, attributeNames);1279        // Trim whitespace between class1280        // https://github.com/vuejs/vue-next/issues/42511281        if (attr.type === 6 /* ATTRIBUTE */ &&1282            attr.value &&1283            attr.name === 'class') {1284            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1285        }1286        if (type === 0 /* Start */) {1287            props.push(attr);1288        }1289        if (/^[^\t\r\n\f />]/.test(context.source)) {1290            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1291        }1292        advanceSpaces(context);1293    }1294    return props;1295}1296function parseAttribute(context, nameSet) {1297    // Name.1298    const start = getCursor(context);1299    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1300    const name = match[0];1301    if (nameSet.has(name)) {1302        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1303    }1304    nameSet.add(name);1305    if (name[0] === '=') {1306        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1307    }1308    {1309        const pattern = /["'<]/g;1310        let m;1311        while ((m = pattern.exec(name))) {1312            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1313        }1314    }1315    advanceBy(context, name.length);1316    // Value1317    let value = undefined;1318    if (/^[\t\r\n\f ]*=/.test(context.source)) {1319        advanceSpaces(context);1320        advanceBy(context, 1);1321        advanceSpaces(context);1322        value = parseAttributeValue(context);1323        if (!value) {1324            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1325        }1326    }1327    const loc = getSelection(context, start);1328    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1329        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1330        let isPropShorthand = startsWith(name, '.');1331        let dirName = match[1] ||1332            (isPropShorthand || startsWith(name, ':')1333                ? 'bind'1334                : startsWith(name, '@')1335                    ? 'on'1336                    : 'slot');1337        let arg;1338        if (match[2]) {1339            const isSlot = dirName === 'slot';1340            const startOffset = name.lastIndexOf(match[2]);1341            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1342            let content = match[2];1343            let isStatic = true;1344            if (content.startsWith('[')) {1345                isStatic = false;1346                if (!content.endsWith(']')) {1347                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1348                    content = content.slice(1);1349                }1350                else {1351                    content = content.slice(1, content.length - 1);1352                }1353            }1354            else if (isSlot) {1355                // #1241 special case for v-slot: vuetify relies extensively on slot1356                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1357                // supports such usage so we are keeping it consistent with 2.x.1358                content += match[3] || '';1359            }1360            arg = {1361                type: 4 /* SIMPLE_EXPRESSION */,1362                content,1363                isStatic,1364                constType: isStatic1365                    ? 3 /* CAN_STRINGIFY */1366                    : 0 /* NOT_CONSTANT */,1367                loc1368            };1369        }1370        if (value && value.isQuoted) {1371            const valueLoc = value.loc;1372            valueLoc.start.offset++;1373            valueLoc.start.column++;1374            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1375            valueLoc.source = valueLoc.source.slice(1, -1);1376        }1377        const modifiers = match[3] ? match[3].slice(1).split('.') : [];1378        if (isPropShorthand)1379            modifiers.push('prop');1380        // 2.x compat v-bind:foo.sync -> v-model:foo1381        if (dirName === 'bind' && arg) {1382            if (modifiers.includes('sync') &&1383                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1384                dirName = 'model';1385                modifiers.splice(modifiers.indexOf('sync'), 1);1386            }1387        }1388        return {1389            type: 7 /* DIRECTIVE */,1390            name: dirName,1391            exp: value && {1392                type: 4 /* SIMPLE_EXPRESSION */,1393                content: value.content,1394                isStatic: false,1395                // Treat as non-constant by default. This can be potentially set to1396                // other values by `transformExpression` to make it eligible for hoisting.1397                constType: 0 /* NOT_CONSTANT */,1398                loc: value.loc1399            },1400            arg,1401            modifiers,1402            loc1403        };1404    }1405    // missing directive name or illegal directive name1406    if (!context.inVPre && startsWith(name, 'v-')) {1407        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1408    }1409    return {1410        type: 6 /* ATTRIBUTE */,1411        name,1412        value: value && {1413            type: 2 /* TEXT */,1414            content: value.content,1415            loc: value.loc1416        },1417        loc1418    };1419}1420function parseAttributeValue(context) {1421    const start = getCursor(context);1422    let content;1423    const quote = context.source[0];1424    const isQuoted = quote === `"` || quote === `'`;1425    if (isQuoted) {1426        // Quoted value.1427        advanceBy(context, 1);1428        const endIndex = context.source.indexOf(quote);1429        if (endIndex === -1) {1430            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1431        }1432        else {1433            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1434            advanceBy(context, 1);1435        }1436    }1437    else {1438        // Unquoted1439        const match = /^[^\t\r\n\f >]+/.exec(context.source);1440        if (!match) {1441            return undefined;1442        }1443        const unexpectedChars = /["'<=`]/g;1444        let m;1445        while ((m = unexpectedChars.exec(match[0]))) {1446            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1447        }1448        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1449    }1450    return { content, isQuoted, loc: getSelection(context, start) };1451}1452function parseInterpolation(context, mode) {1453    const [open, close] = context.options.delimiters;1454    const closeIndex = context.source.indexOf(close, open.length);1455    if (closeIndex === -1) {1456        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1457        return undefined;1458    }1459    const start = getCursor(context);1460    advanceBy(context, open.length);1461    const innerStart = getCursor(context);1462    const innerEnd = getCursor(context);1463    const rawContentLength = closeIndex - open.length;1464    const rawContent = context.source.slice(0, rawContentLength);1465    const preTrimContent = parseTextData(context, rawContentLength, mode);1466    const content = preTrimContent.trim();1467    const startOffset = preTrimContent.indexOf(content);1468    if (startOffset > 0) {1469        advancePositionWithMutation(innerStart, rawContent, startOffset);1470    }1471    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1472    advancePositionWithMutation(innerEnd, rawContent, endOffset);1473    advanceBy(context, close.length);1474    return {1475        type: 5 /* INTERPOLATION */,1476        content: {1477            type: 4 /* SIMPLE_EXPRESSION */,1478            isStatic: false,1479            // Set `isConstant` to false by default and will decide in transformExpression1480            constType: 0 /* NOT_CONSTANT */,1481            content,1482            loc: getSelection(context, innerStart, innerEnd)1483        },1484        loc: getSelection(context, start)1485    };1486}1487function parseText(context, mode) {1488    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1489    let endIndex = context.source.length;1490    for (let i = 0; i < endTokens.length; i++) {1491        const index = context.source.indexOf(endTokens[i], 1);1492        if (index !== -1 && endIndex > index) {1493            endIndex = index;1494        }1495    }1496    const start = getCursor(context);1497    const content = parseTextData(context, endIndex, mode);1498    return {1499        type: 2 /* TEXT */,1500        content,1501        loc: getSelection(context, start)1502    };1503}1504/**1505 * Get text data with a given length from the current location.1506 * This translates HTML entities in the text data.1507 */1508function parseTextData(context, length, mode) {1509    const rawText = context.source.slice(0, length);1510    advanceBy(context, length);1511    if (mode === 2 /* RAWTEXT */ ||1512        mode === 3 /* CDATA */ ||1513        rawText.indexOf('&') === -1) {1514        return rawText;1515    }1516    else {1517        // DATA or RCDATA containing "&"". Entity decoding required.1518        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1519    }1520}1521function getCursor(context) {1522    const { column, line, offset } = context;1523    return { column, line, offset };1524}1525function getSelection(context, start, end) {1526    end = end || getCursor(context);1527    return {1528        start,1529        end,1530        source: context.originalSource.slice(start.offset, end.offset)1531    };1532}1533function last(xs) {1534    return xs[xs.length - 1];1535}1536function startsWith(source, searchString) {1537    return source.startsWith(searchString);1538}1539function advanceBy(context, numberOfCharacters) {1540    const { source } = context;1541    advancePositionWithMutation(context, source, numberOfCharacters);1542    context.source = source.slice(numberOfCharacters);1543}1544function advanceSpaces(context) {1545    const match = /^[\t\r\n\f ]+/.exec(context.source);1546    if (match) {1547        advanceBy(context, match[0].length);1548    }1549}1550function getNewPosition(context, start, numberOfCharacters) {1551    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1552}1553function emitError(context, code, offset, loc = getCursor(context)) {1554    if (offset) {1555        loc.offset += offset;1556        loc.column += offset;1557    }1558    context.options.onError(createCompilerError(code, {1559        start: loc,1560        end: loc,1561        source: ''1562    }));1563}1564function isEnd(context, mode, ancestors) {1565    const s = context.source;1566    switch (mode) {1567        case 0 /* DATA */:1568            if (startsWith(s, '</')) {1569                // TODO: probably bad performance1570                for (let i = ancestors.length - 1; i >= 0; --i) {1571                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {1572                        return true;1573                    }1574                }1575            }1576            break;1577        case 1 /* RCDATA */:1578        case 2 /* RAWTEXT */: {1579            const parent = last(ancestors);1580            if (parent && startsWithEndTagOpen(s, parent.tag)) {1581                return true;1582            }1583            break;1584        }1585        case 3 /* CDATA */:1586            if (startsWith(s, ']]>')) {1587                return true;1588            }1589            break;1590    }1591    return !s;1592}1593function startsWithEndTagOpen(source, tag) {1594    return (startsWith(source, '</') &&1595        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1596        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1597}1598function hoistStatic(root, context) {1599    walk(root, context, 1600    // Root node is unfortunately non-hoistable due to potential parent1601    // fallthrough attributes.1602    isSingleElementRoot(root, root.children[0]));1603}1604function isSingleElementRoot(root, child) {1605    const { children } = root;1606    return (children.length === 1 &&1607        child.type === 1 /* ELEMENT */ &&1608        !isSlotOutlet(child));1609}1610function walk(node, context, doNotHoistNode = false) {1611    const { children } = node;1612    const originalCount = children.length;1613    let hoistedCount = 0;1614    for (let i = 0; i < children.length; i++) {1615        const child = children[i];1616        // only plain elements & text calls are eligible for hoisting.1617        if (child.type === 1 /* ELEMENT */ &&1618            child.tagType === 0 /* ELEMENT */) {1619            const constantType = doNotHoistNode1620                ? 0 /* NOT_CONSTANT */1621                : getConstantType(child, context);1622            if (constantType > 0 /* NOT_CONSTANT */) {1623                if (constantType >= 2 /* CAN_HOIST */) {1624                    child.codegenNode.patchFlag =1625                        -1 /* HOISTED */ + (``);1626                    child.codegenNode = context.hoist(child.codegenNode);1627                    hoistedCount++;1628                    continue;1629                }1630            }1631            else {1632                // node may contain dynamic children, but its props may be eligible for1633                // hoisting.1634                const codegenNode = child.codegenNode;1635                if (codegenNode.type === 13 /* VNODE_CALL */) {1636                    const flag = getPatchFlag(codegenNode);1637                    if ((!flag ||1638                        flag === 512 /* NEED_PATCH */ ||1639                        flag === 1 /* TEXT */) &&1640                        getGeneratedPropsConstantType(child, context) >=1641                            2 /* CAN_HOIST */) {1642                        const props = getNodeProps(child);1643                        if (props) {1644                            codegenNode.props = context.hoist(props);1645                        }1646                    }1647                    if (codegenNode.dynamicProps) {1648                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1649                    }1650                }1651            }1652        }1653        else if (child.type === 12 /* TEXT_CALL */ &&1654            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {1655            child.codegenNode = context.hoist(child.codegenNode);1656            hoistedCount++;1657        }1658        // walk further1659        if (child.type === 1 /* ELEMENT */) {1660            const isComponent = child.tagType === 1 /* COMPONENT */;1661            if (isComponent) {1662                context.scopes.vSlot++;1663            }1664            walk(child, context);1665            if (isComponent) {1666                context.scopes.vSlot--;1667            }1668        }1669        else if (child.type === 11 /* FOR */) {1670            // Do not hoist v-for single child because it has to be a block1671            walk(child, context, child.children.length === 1);1672        }1673        else if (child.type === 9 /* IF */) {1674            for (let i = 0; i < child.branches.length; i++) {1675                // Do not hoist v-if single child because it has to be a block1676                walk(child.branches[i], context, child.branches[i].children.length === 1);1677            }1678        }1679    }1680    if (hoistedCount && context.transformHoist) {1681        context.transformHoist(children, context, node);1682    }1683    // all children were hoisted - the entire children array is hoistable.1684    if (hoistedCount &&1685        hoistedCount === originalCount &&1686        node.type === 1 /* ELEMENT */ &&1687        node.tagType === 0 /* ELEMENT */ &&1688        node.codegenNode &&1689        node.codegenNode.type === 13 /* VNODE_CALL */ &&1690        shared.isArray(node.codegenNode.children)) {1691        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1692    }1693}1694function getConstantType(node, context) {1695    const { constantCache } = context;1696    switch (node.type) {1697        case 1 /* ELEMENT */:1698            if (node.tagType !== 0 /* ELEMENT */) {1699                return 0 /* NOT_CONSTANT */;1700            }1701            const cached = constantCache.get(node);1702            if (cached !== undefined) {1703                return cached;1704            }1705            const codegenNode = node.codegenNode;1706            if (codegenNode.type !== 13 /* VNODE_CALL */) {1707                return 0 /* NOT_CONSTANT */;1708            }1709            if (codegenNode.isBlock &&1710                node.tag !== 'svg' &&1711                node.tag !== 'foreignObject') {1712                return 0 /* NOT_CONSTANT */;1713            }1714            const flag = getPatchFlag(codegenNode);1715            if (!flag) {1716                let returnType = 3 /* CAN_STRINGIFY */;1717                // Element itself has no patch flag. However we still need to check:1718                // 1. Even for a node with no patch flag, it is possible for it to contain1719                // non-hoistable expressions that refers to scope variables, e.g. compiler1720                // injected keys or cached event handlers. Therefore we need to always1721                // check the codegenNode's props to be sure.1722                const generatedPropsType = getGeneratedPropsConstantType(node, context);1723                if (generatedPropsType === 0 /* NOT_CONSTANT */) {1724                    constantCache.set(node, 0 /* NOT_CONSTANT */);1725                    return 0 /* NOT_CONSTANT */;1726                }1727                if (generatedPropsType < returnType) {1728                    returnType = generatedPropsType;1729                }1730                // 2. its children.1731                for (let i = 0; i < node.children.length; i++) {1732                    const childType = getConstantType(node.children[i], context);1733                    if (childType === 0 /* NOT_CONSTANT */) {1734                        constantCache.set(node, 0 /* NOT_CONSTANT */);1735                        return 0 /* NOT_CONSTANT */;1736                    }1737                    if (childType < returnType) {1738                        returnType = childType;1739                    }1740                }1741                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01742                // type, check if any of the props can cause the type to be lowered1743                // we can skip can_patch because it's guaranteed by the absence of a1744                // patchFlag.1745                if (returnType > 1 /* CAN_SKIP_PATCH */) {1746                    for (let i = 0; i < node.props.length; i++) {1747                        const p = node.props[i];1748                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1749                            const expType = getConstantType(p.exp, context);1750                            if (expType === 0 /* NOT_CONSTANT */) {1751                                constantCache.set(node, 0 /* NOT_CONSTANT */);1752                                return 0 /* NOT_CONSTANT */;1753                            }1754                            if (expType < returnType) {1755                                returnType = expType;1756                            }1757                        }1758                    }1759                }1760                // only svg/foreignObject could be block here, however if they are1761                // static then they don't need to be blocks since there will be no1762                // nested updates.1763                if (codegenNode.isBlock) {1764                    context.removeHelper(OPEN_BLOCK);1765                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1766                    codegenNode.isBlock = false;1767                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1768                }1769                constantCache.set(node, returnType);1770                return returnType;1771            }1772            else {1773                constantCache.set(node, 0 /* NOT_CONSTANT */);1774                return 0 /* NOT_CONSTANT */;1775            }1776        case 2 /* TEXT */:1777        case 3 /* COMMENT */:1778            return 3 /* CAN_STRINGIFY */;1779        case 9 /* IF */:1780        case 11 /* FOR */:1781        case 10 /* IF_BRANCH */:1782            return 0 /* NOT_CONSTANT */;1783        case 5 /* INTERPOLATION */:1784        case 12 /* TEXT_CALL */:1785            return getConstantType(node.content, context);1786        case 4 /* SIMPLE_EXPRESSION */:1787            return node.constType;1788        case 8 /* COMPOUND_EXPRESSION */:1789            let returnType = 3 /* CAN_STRINGIFY */;1790            for (let i = 0; i < node.children.length; i++) {1791                const child = node.children[i];1792                if (shared.isString(child) || shared.isSymbol(child)) {1793                    continue;1794                }1795                const childType = getConstantType(child, context);1796                if (childType === 0 /* NOT_CONSTANT */) {1797                    return 0 /* NOT_CONSTANT */;1798                }1799                else if (childType < returnType) {1800                    returnType = childType;1801                }1802            }1803            return returnType;1804        default:1805            return 0 /* NOT_CONSTANT */;1806    }1807}1808const allowHoistedHelperSet = new Set([1809    NORMALIZE_CLASS,1810    NORMALIZE_STYLE,1811    NORMALIZE_PROPS,1812    GUARD_REACTIVE_PROPS1813]);1814function getConstantTypeOfHelperCall(value, context) {1815    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1816        !shared.isString(value.callee) &&1817        allowHoistedHelperSet.has(value.callee)) {1818        const arg = value.arguments[0];1819        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {1820            return getConstantType(arg, context);1821        }1822        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {1823            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`1824            return getConstantTypeOfHelperCall(arg, context);1825        }1826    }1827    return 0 /* NOT_CONSTANT */;1828}1829function getGeneratedPropsConstantType(node, context) {1830    let returnType = 3 /* CAN_STRINGIFY */;1831    const props = getNodeProps(node);1832    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1833        const { properties } = props;1834        for (let i = 0; i < properties.length; i++) {1835            const { key, value } = properties[i];1836            const keyType = getConstantType(key, context);1837            if (keyType === 0 /* NOT_CONSTANT */) {1838                return keyType;1839            }1840            if (keyType < returnType) {1841                returnType = keyType;1842            }1843            let valueType;1844            if (value.type === 4 /* SIMPLE_EXPRESSION */) {1845                valueType = getConstantType(value, context);1846            }1847            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {1848                // some helper calls can be hoisted,1849                // such as the `normalizeProps` generated by the compiler for pre-normalize class,1850                // in this case we need to respect the ConstantType of the helper's arguments1851                valueType = getConstantTypeOfHelperCall(value, context);1852            }1853            else {1854                valueType = 0 /* NOT_CONSTANT */;1855            }1856            if (valueType === 0 /* NOT_CONSTANT */) {1857                return valueType;1858            }1859            if (valueType < returnType) {1860                returnType = valueType;1861            }1862        }1863    }1864    return returnType;1865}1866function getNodeProps(node) {1867    const codegenNode = node.codegenNode;1868    if (codegenNode.type === 13 /* VNODE_CALL */) {1869        return codegenNode.props;1870    }1871}1872function getPatchFlag(node) {1873    const flag = node.patchFlag;1874    return flag ? parseInt(flag, 10) : undefined;1875}1876function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = shared.NOOP, isCustomElement = shared.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = shared.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {1877    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1878    const context = {1879        // options1880        selfName: nameMatch && shared.capitalize(shared.camelize(nameMatch[1])),1881        prefixIdentifiers,1882        hoistStatic,1883        cacheHandlers,1884        nodeTransforms,1885        directiveTransforms,1886        transformHoist,1887        isBuiltInComponent,1888        isCustomElement,1889        expressionPlugins,1890        scopeId,1891        slotted,1892        ssr,1893        inSSR,1894        ssrCssVars,1895        bindingMetadata,1896        inline,1897        isTS,1898        onError,1899        onWarn,1900        compatConfig,1901        // state1902        root,1903        helpers: new Map(),1904        components: new Set(),1905        directives: new Set(),1906        hoists: [],1907        imports: [],1908        constantCache: new Map(),1909        temps: 0,1910        cached: 0,1911        identifiers: Object.create(null),1912        scopes: {1913            vFor: 0,1914            vSlot: 0,1915            vPre: 0,1916            vOnce: 01917        },1918        parent: null,1919        currentNode: root,1920        childIndex: 0,1921        inVOnce: false,1922        // methods1923        helper(name) {1924            const count = context.helpers.get(name) || 0;1925            context.helpers.set(name, count + 1);1926            return name;1927        },1928        removeHelper(name) {1929            const count = context.helpers.get(name);1930            if (count) {1931                const currentCount = count - 1;1932                if (!currentCount) {1933                    context.helpers.delete(name);1934                }1935                else {1936                    context.helpers.set(name, currentCount);1937                }1938            }1939        },1940        helperString(name) {1941            return `_${helperNameMap[context.helper(name)]}`;1942        },1943        replaceNode(node) {1944            context.parent.children[context.childIndex] = context.currentNode = node;1945        },1946        removeNode(node) {1947            const list = context.parent.children;1948            const removalIndex = node1949                ? list.indexOf(node)1950                : context.currentNode1951                    ? context.childIndex1952                    : -1;1953            if (!node || node === context.currentNode) {1954                // current node removed1955                context.currentNode = null;1956                context.onNodeRemoved();1957            }1958            else {1959                // sibling node removed1960                if (context.childIndex > removalIndex) {1961                    context.childIndex--;1962                    context.onNodeRemoved();1963                }1964            }1965            context.parent.children.splice(removalIndex, 1);1966        },1967        onNodeRemoved: () => { },1968        addIdentifiers(exp) {1969            // identifier tracking only happens in non-browser builds.1970            {1971                if (shared.isString(exp)) {1972                    addId(exp);1973                }1974                else if (exp.identifiers) {1975                    exp.identifiers.forEach(addId);1976                }1977                else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {1978                    addId(exp.content);1979                }1980            }1981        },1982        removeIdentifiers(exp) {1983            {1984                if (shared.isString(exp)) {1985                    removeId(exp);1986                }1987                else if (exp.identifiers) {1988                    exp.identifiers.forEach(removeId);1989                }1990                else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {1991                    removeId(exp.content);1992                }1993            }1994        },1995        hoist(exp) {1996            if (shared.isString(exp))1997                exp = createSimpleExpression(exp);1998            context.hoists.push(exp);1999            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2000            identifier.hoisted = exp;2001            return identifier;2002        },2003        cache(exp, isVNode = false) {2004            return createCacheExpression(context.cached++, exp, isVNode);2005        }2006    };2007    {2008        context.filters = new Set();2009    }2010    function addId(id) {2011        const { identifiers } = context;2012        if (identifiers[id] === undefined) {2013            identifiers[id] = 0;2014        }2015        identifiers[id]++;2016    }2017    function removeId(id) {2018        context.identifiers[id]--;2019    }2020    return context;2021}2022function transform(root, options) {2023    const context = createTransformContext(root, options);2024    traverseNode(root, context);2025    if (options.hoistStatic) {2026        hoistStatic(root, context);2027    }2028    if (!options.ssr) {2029        createRootCodegen(root, context);2030    }2031    // finalize meta information2032    root.helpers = [...context.helpers.keys()];2033    root.components = [...context.components];2034    root.directives = [...context.directives];2035    root.imports = context.imports;2036    root.hoists = context.hoists;2037    root.temps = context.temps;2038    root.cached = context.cached;2039    {2040        root.filters = [...context.filters];2041    }2042}2043function createRootCodegen(root, context) {2044    const { helper } = context;2045    const { children } = root;2046    if (children.length === 1) {2047        const child = children[0];2048        // if the single child is an element, turn it into a block.2049        if (isSingleElementRoot(root, child) && child.codegenNode) {2050            // single element root is never hoisted so codegenNode will never be2051            // SimpleExpressionNode2052            const codegenNode = child.codegenNode;2053            if (codegenNode.type === 13 /* VNODE_CALL */) {2054                makeBlock(codegenNode, context);2055            }2056            root.codegenNode = codegenNode;2057        }2058        else {2059            // - single <slot/>, IfNode, ForNode: already blocks.2060            // - single text node: always patched.2061            // root codegen falls through via genNode()2062            root.codegenNode = child;2063        }2064    }2065    else if (children.length > 1) {2066        // root has multiple nodes - return a fragment block.2067        let patchFlag = 64 /* STABLE_FRAGMENT */;2068        shared.PatchFlagNames[64 /* STABLE_FRAGMENT */];2069        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (``), undefined, undefined, true, undefined, false /* isComponent */);2070    }2071    else ;2072}2073function traverseChildren(parent, context) {2074    let i = 0;2075    const nodeRemoved = () => {2076        i--;2077    };2078    for (; i < parent.children.length; i++) {2079        const child = parent.children[i];2080        if (shared.isString(child))2081            continue;2082        context.parent = parent;2083        context.childIndex = i;2084        context.onNodeRemoved = nodeRemoved;2085        traverseNode(child, context);2086    }2087}2088function traverseNode(node, context) {2089    context.currentNode = node;2090    // apply transform plugins2091    const { nodeTransforms } = context;2092    const exitFns = [];2093    for (let i = 0; i < nodeTransforms.length; i++) {2094        const onExit = nodeTransforms[i](node, context);2095        if (onExit) {2096            if (shared.isArray(onExit)) {2097                exitFns.push(...onExit);2098            }2099            else {2100                exitFns.push(onExit);2101            }2102        }2103        if (!context.currentNode) {2104            // node was removed2105            return;2106        }2107        else {2108            // node may have been replaced2109            node = context.currentNode;2110        }2111    }2112    switch (node.type) {2113        case 3 /* COMMENT */:2114            if (!context.ssr) {2115                // inject import for the Comment symbol, which is needed for creating2116                // comment nodes with `createVNode`2117                context.helper(CREATE_COMMENT);2118            }2119            break;2120        case 5 /* INTERPOLATION */:2121            // no need to traverse, but we need to inject toString helper2122            if (!context.ssr) {2123                context.helper(TO_DISPLAY_STRING);2124            }2125            break;2126        // for container types, further traverse downwards2127        case 9 /* IF */:2128            for (let i = 0; i < node.branches.length; i++) {2129                traverseNode(node.branches[i], context);2130            }2131            break;2132        case 10 /* IF_BRANCH */:2133        case 11 /* FOR */:2134        case 1 /* ELEMENT */:2135        case 0 /* ROOT */:2136            traverseChildren(node, context);2137            break;2138    }2139    // exit transforms2140    context.currentNode = node;2141    let i = exitFns.length;2142    while (i--) {2143        exitFns[i]();2144    }2145}2146function createStructuralDirectiveTransform(name, fn) {2147    const matches = shared.isString(name)2148        ? (n) => n === name2149        : (n) => name.test(n);2150    return (node, context) => {2151        if (node.type === 1 /* ELEMENT */) {2152            const { props } = node;2153            // structural directive transforms are not concerned with slots2154            // as they are handled separately in vSlot.ts2155            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2156                return;2157            }2158            const exitFns = [];2159            for (let i = 0; i < props.length; i++) {2160                const prop = props[i];2161                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2162                    // structural directives are removed to avoid infinite recursion2163                    // also we remove them *before* applying so that it can further2164                    // traverse itself in case it moves the node around2165                    props.splice(i, 1);2166                    i--;2167                    const onExit = fn(node, prop, context);2168                    if (onExit)2169                        exitFns.push(onExit);2170                }2171            }2172            return exitFns;2173        }2174    };2175}2176const PURE_ANNOTATION = `/*#__PURE__*/`;2177function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap: sourceMap$1 = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {2178    const context = {2179        mode,2180        prefixIdentifiers,2181        sourceMap: sourceMap$1,2182        filename,2183        scopeId,2184        optimizeImports,2185        runtimeGlobalName,2186        runtimeModuleName,2187        ssrRuntimeModuleName,2188        ssr,2189        isTS,2190        inSSR,2191        source: ast.loc.source,2192        code: ``,2193        column: 1,2194        line: 1,2195        offset: 0,2196        indentLevel: 0,2197        pure: false,2198        map: undefined,2199        helper(key) {2200            return `_${helperNameMap[key]}`;2201        },2202        push(code, node) {2203            context.code += code;2204            if (context.map) {2205                if (node) {2206                    let name;2207                    if (node.type === 4 /* SIMPLE_EXPRESSION */ && !node.isStatic) {2208                        const content = node.content.replace(/^_ctx\./, '');2209                        if (content !== node.content && isSimpleIdentifier(content)) {2210                            name = content;2211                        }2212                    }2213                    addMapping(node.loc.start, name);2214                }2215                advancePositionWithMutation(context, code);2216                if (node && node.loc !== locStub) {2217                    addMapping(node.loc.end);2218                }2219            }2220        },2221        indent() {2222            newline(++context.indentLevel);2223        },2224        deindent(withoutNewLine = false) {2225            if (withoutNewLine) {2226                --context.indentLevel;2227            }2228            else {2229                newline(--context.indentLevel);2230            }2231        },2232        newline() {2233            newline(context.indentLevel);2234        }2235    };2236    function newline(n) {2237        context.push('\n' + `  `.repeat(n));2238    }2239    function addMapping(loc, name) {2240        context.map.addMapping({2241            name,2242            source: context.filename,2243            original: {2244                line: loc.line,2245                column: loc.column - 1 // source-map column is 0 based2246            },2247            generated: {2248                line: context.line,2249                column: context.column - 12250            }2251        });2252    }2253    if (sourceMap$1) {2254        // lazy require source-map implementation, only in non-browser builds2255        context.map = new sourceMap.SourceMapGenerator();2256        context.map.setSourceContent(filename, context.source);2257    }2258    return context;2259}2260function generate(ast, options = {}) {2261    const context = createCodegenContext(ast, options);2262    if (options.onContextCreated)2263        options.onContextCreated(context);2264    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2265    const hasHelpers = ast.helpers.length > 0;2266    const useWithBlock = !prefixIdentifiers && mode !== 'module';2267    const genScopeId = scopeId != null && mode === 'module';2268    const isSetupInlined = !!options.inline;2269    // preambles2270    // in setup() inline mode, the preamble is generated in a sub context2271    // and returned separately.2272    const preambleContext = isSetupInlined2273        ? createCodegenContext(ast, options)2274        : context;2275    if (mode === 'module') {2276        genModulePreamble(ast, preambleContext, genScopeId, isSetupInlined);2277    }2278    else {2279        genFunctionPreamble(ast, preambleContext);2280    }2281    // enter render function2282    const functionName = ssr ? `ssrRender` : `render`;2283    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2284    if (options.bindingMetadata && !options.inline) {2285        // binding optimization args2286        args.push('$props', '$setup', '$data', '$options');2287    }2288    const signature = options.isTS2289        ? args.map(arg => `${arg}: any`).join(',')2290        : args.join(', ');2291    if (isSetupInlined) {2292        push(`(${signature}) => {`);2293    }2294    else {2295        push(`function ${functionName}(${signature}) {`);2296    }2297    indent();2298    if (useWithBlock) {2299        push(`with (_ctx) {`);2300        indent();2301        // function mode const declarations should be inside with block2302        // also they should be renamed to avoid collision with user properties2303        if (hasHelpers) {2304            push(`const { ${ast.helpers2305                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2306                .join(', ')} } = _Vue`);2307            push(`\n`);2308            newline();2309        }2310    }2311    // generate asset resolution statements2312    if (ast.components.length) {2313        genAssets(ast.components, 'component', context);2314        if (ast.directives.length || ast.temps > 0) {2315            newline();2316        }2317    }2318    if (ast.directives.length) {2319        genAssets(ast.directives, 'directive', context);2320        if (ast.temps > 0) {2321            newline();2322        }2323    }2324    if (ast.filters && ast.filters.length) {2325        newline();2326        genAssets(ast.filters, 'filter', context);2327        newline();2328    }2329    if (ast.temps > 0) {2330        push(`let `);2331        for (let i = 0; i < ast.temps; i++) {2332            push(`${i > 0 ? `, ` : ``}_temp${i}`);2333        }2334    }2335    if (ast.components.length || ast.directives.length || ast.temps) {2336        push(`\n`);2337        newline();2338    }2339    // generate the VNode tree expression2340    if (!ssr) {2341        push(`return `);2342    }2343    if (ast.codegenNode) {2344        genNode(ast.codegenNode, context);2345    }2346    else {2347        push(`null`);2348    }2349    if (useWithBlock) {2350        deindent();2351        push(`}`);2352    }2353    deindent();2354    push(`}`);2355    return {2356        ast,2357        code: context.code,2358        preamble: isSetupInlined ? preambleContext.code : ``,2359        // SourceMapGenerator does have toJSON() method but it's not in the types2360        map: context.map ? context.map.toJSON() : undefined2361    };2362}2363function genFunctionPreamble(ast, context) {2364    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2365    const VueBinding = ssr2366        ? `require(${JSON.stringify(runtimeModuleName)})`2367        : runtimeGlobalName;2368    const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2369    // Generate const declaration for helpers2370    // In prefix mode, we place the const declaration at top so it's done2371    // only once; But if we not prefixing, we place the declaration inside the2372    // with block so it doesn't incur the `in` check cost for every helper access.2373    if (ast.helpers.length > 0) {2374        if (prefixIdentifiers) {2375            push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`);2376        }2377        else {2378            // "with" mode.2379            // save Vue in a separate variable to avoid collision2380            push(`const _Vue = ${VueBinding}\n`);2381            // in "with" mode, helpers are declared inside the with block to avoid2382            // has check cost, but hoists are lifted out of the function - we need2383            // to provide the helper here.2384            if (ast.hoists.length) {2385                const staticHelpers = [2386                    CREATE_VNODE,2387                    CREATE_ELEMENT_VNODE,2388                    CREATE_COMMENT,2389                    CREATE_TEXT,2390                    CREATE_STATIC2391                ]2392                    .filter(helper => ast.helpers.includes(helper))2393                    .map(aliasHelper)2394                    .join(', ');2395                push(`const { ${staticHelpers} } = _Vue\n`);2396            }2397        }2398    }2399    // generate variables for ssr helpers2400    if (ast.ssrHelpers && ast.ssrHelpers.length) {2401        // ssr guarantees prefixIdentifier: true2402        push(`const { ${ast.ssrHelpers2403            .map(aliasHelper)2404            .join(', ')} } = require("${ssrRuntimeModuleName}")\n`);2405    }2406    genHoists(ast.hoists, context);2407    newline();2408    push(`return `);2409}2410function genModulePreamble(ast, context, genScopeId, inline) {2411    const { push, newline, optimizeImports, runtimeModuleName, ssrRuntimeModuleName } = context;2412    if (genScopeId && ast.hoists.length) {2413        ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID);2414    }2415    // generate import statements for helpers2416    if (ast.helpers.length) {2417        if (optimizeImports) {2418            // when bundled with webpack with code-split, calling an import binding2419            // as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,2420            // incurring both payload size increase and potential perf overhead.2421            // therefore we assign the imports to variables (which is a constant ~50b2422            // cost per-component instead of scaling with template size)2423            push(`import { ${ast.helpers2424                .map(s => helperNameMap[s])2425                .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);2426            push(`\n// Binding optimization for webpack code-split\nconst ${ast.helpers2427                .map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)2428                .join(', ')}\n`);2429        }2430        else {2431            push(`import { ${ast.helpers2432                .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)2433                .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);2434        }2435    }2436    if (ast.ssrHelpers && ast.ssrHelpers.length) {2437        push(`import { ${ast.ssrHelpers2438            .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)2439            .join(', ')} } from "${ssrRuntimeModuleName}"\n`);2440    }2441    if (ast.imports.length) {2442        genImports(ast.imports, context);2443        newline();2444    }2445    genHoists(ast.hoists, context);2446    newline();2447    if (!inline) {2448        push(`export `);2449    }2450}2451function genAssets(assets, type, { helper, push, newline, isTS }) {2452    const resolver = helper(type === 'filter'2453        ? RESOLVE_FILTER2454        : type === 'component'2455            ? RESOLVE_COMPONENT2456            : RESOLVE_DIRECTIVE);2457    for (let i = 0; i < assets.length; i++) {2458        let id = assets[i];2459        // potential component implicit self-reference inferred from SFC filename2460        const maybeSelfReference = id.endsWith('__self');2461        if (maybeSelfReference) {2462            id = id.slice(0, -6);2463        }2464        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2465        if (i < assets.length - 1) {2466            newline();2467        }2468    }2469}2470function genHoists(hoists, context) {2471    if (!hoists.length) {2472        return;2473    }2474    context.pure = true;2475    const { push, newline, helper, scopeId, mode } = context;2476    const genScopeId = scopeId != null && mode !== 'function';2477    newline();2478    // generate inlined withScopeId helper2479    if (genScopeId) {2480        push(`const _withScopeId = n => (${helper(PUSH_SCOPE_ID)}("${scopeId}"),n=n(),${helper(POP_SCOPE_ID)}(),n)`);2481        newline();2482    }2483    for (let i = 0; i < hoists.length; i++) {2484        const exp = hoists[i];2485        if (exp) {2486            const needScopeIdWrapper = genScopeId && exp.type === 13 /* VNODE_CALL */;2487            push(`const _hoisted_${i + 1} = ${needScopeIdWrapper ? `${PURE_ANNOTATION} _withScopeId(() => ` : ``}`);2488            genNode(exp, context);2489            if (needScopeIdWrapper) {2490                push(`)`);2491            }2492            newline();2493        }2494    }2495    context.pure = false;2496}2497function genImports(importsOptions, context) {2498    if (!importsOptions.length) {2499        return;2500    }2501    importsOptions.forEach(imports => {2502        context.push(`import `);2503        genNode(imports.exp, context);2504        context.push(` from '${imports.path}'`);2505        context.newline();2506    });2507}2508function isText$1(n) {2509    return (shared.isString(n) ||2510        n.type === 4 /* SIMPLE_EXPRESSION */ ||2511        n.type === 2 /* TEXT */ ||2512        n.type === 5 /* INTERPOLATION */ ||2513        n.type === 8 /* COMPOUND_EXPRESSION */);2514}2515function genNodeListAsArray(nodes, context) {2516    const multilines = nodes.length > 3 ||2517        (nodes.some(n => shared.isArray(n) || !isText$1(n)));2518    context.push(`[`);2519    multilines && context.indent();2520    genNodeList(nodes, context, multilines);2521    multilines && context.deindent();2522    context.push(`]`);2523}2524function genNodeList(nodes, context, multilines = false, comma = true) {2525    const { push, newline } = context;2526    for (let i = 0; i < nodes.length; i++) {2527        const node = nodes[i];2528        if (shared.isString(node)) {2529            push(node);2530        }2531        else if (shared.isArray(node)) {2532            genNodeListAsArray(node, context);2533        }2534        else {2535            genNode(node, context);2536        }2537        if (i < nodes.length - 1) {2538            if (multilines) {2539                comma && push(',');2540                newline();2541            }2542            else {2543                comma && push(', ');2544            }2545        }2546    }2547}2548function genNode(node, context) {2549    if (shared.isString(node)) {2550        context.push(node);2551        return;2552    }2553    if (shared.isSymbol(node)) {2554        context.push(context.helper(node));2555        return;2556    }2557    switch (node.type) {2558        case 1 /* ELEMENT */:2559        case 9 /* IF */:2560        case 11 /* FOR */:2561            genNode(node.codegenNode, context);2562            break;2563        case 2 /* TEXT */:2564            genText(node, context);2565            break;2566        case 4 /* SIMPLE_EXPRESSION */:2567            genExpression(node, context);2568            break;2569        case 5 /* INTERPOLATION */:2570            genInterpolation(node, context);2571            break;2572        case 12 /* TEXT_CALL */:2573            genNode(node.codegenNode, context);2574            break;2575        case 8 /* COMPOUND_EXPRESSION */:2576            genCompoundExpression(node, context);2577            break;2578        case 3 /* COMMENT */:2579            genComment(node, context);2580            break;2581        case 13 /* VNODE_CALL */:2582            genVNodeCall(node, context);2583            break;2584        case 14 /* JS_CALL_EXPRESSION */:2585            genCallExpression(node, context);2586            break;2587        case 15 /* JS_OBJECT_EXPRESSION */:2588            genObjectExpression(node, context);2589            break;2590        case 17 /* JS_ARRAY_EXPRESSION */:2591            genArrayExpression(node, context);2592            break;2593        case 18 /* JS_FUNCTION_EXPRESSION */:2594            genFunctionExpression(node, context);2595            break;2596        case 19 /* JS_CONDITIONAL_EXPRESSION */:2597            genConditionalExpression(node, context);2598            break;2599        case 20 /* JS_CACHE_EXPRESSION */:2600            genCacheExpression(node, context);2601            break;2602        case 21 /* JS_BLOCK_STATEMENT */:2603            genNodeList(node.body, context, true, false);2604            break;2605        // SSR only types2606        case 22 /* JS_TEMPLATE_LITERAL */:2607            genTemplateLiteral(node, context);2608            break;2609        case 23 /* JS_IF_STATEMENT */:2610            genIfStatement(node, context);2611            break;2612        case 24 /* JS_ASSIGNMENT_EXPRESSION */:2613            genAssignmentExpression(node, context);2614            break;2615        case 25 /* JS_SEQUENCE_EXPRESSION */:2616            genSequenceExpression(node, context);2617            break;2618        case 26 /* JS_RETURN_STATEMENT */:2619            genReturnStatement(node, context);2620            break;2621    }2622}2623function genText(node, context) {2624    context.push(JSON.stringify(node.content), node);2625}2626function genExpression(node, context) {2627    const { content, isStatic } = node;2628    context.push(isStatic ? JSON.stringify(content) : content, node);2629}2630function genInterpolation(node, context) {2631    const { push, helper, pure } = context;2632    if (pure)2633        push(PURE_ANNOTATION);2634    push(`${helper(TO_DISPLAY_STRING)}(`);2635    genNode(node.content, context);2636    push(`)`);2637}2638function genCompoundExpression(node, context) {2639    for (let i = 0; i < node.children.length; i++) {2640        const child = node.children[i];2641        if (shared.isString(child)) {2642            context.push(child);2643        }2644        else {2645            genNode(child, context);2646        }2647    }2648}2649function genExpressionAsPropertyKey(node, context) {2650    const { push } = context;2651    if (node.type === 8 /* COMPOUND_EXPRESSION */) {2652        push(`[`);2653        genCompoundExpression(node, context);2654        push(`]`);2655    }2656    else if (node.isStatic) {2657        // only quote keys if necessary2658        const text = isSimpleIdentifier(node.content)2659            ? node.content2660            : JSON.stringify(node.content);2661        push(text, node);2662    }2663    else {2664        push(`[${node.content}]`, node);2665    }2666}2667function genComment(node, context) {2668    const { push, helper, pure } = context;2669    if (pure) {2670        push(PURE_ANNOTATION);2671    }2672    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2673}2674function genVNodeCall(node, context) {2675    const { push, helper, pure } = context;2676    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2677    if (directives) {2678        push(helper(WITH_DIRECTIVES) + `(`);2679    }2680    if (isBlock) {2681        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2682    }2683    if (pure) {2684        push(PURE_ANNOTATION);2685    }2686    const callHelper = isBlock2687        ? getVNodeBlockHelper(context.inSSR, isComponent)2688        : getVNodeHelper(context.inSSR, isComponent);2689    push(helper(callHelper) + `(`, node);2690    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2691    push(`)`);2692    if (isBlock) {2693        push(`)`);2694    }2695    if (directives) {2696        push(`, `);2697        genNode(directives, context);2698        push(`)`);2699    }2700}2701function genNullableArgs(args) {2702    let i = args.length;2703    while (i--) {2704        if (args[i] != null)2705            break;2706    }2707    return args.slice(0, i + 1).map(arg => arg || `null`);2708}2709// JavaScript2710function genCallExpression(node, context) {2711    const { push, helper, pure } = context;2712    const callee = shared.isString(node.callee) ? node.callee : helper(node.callee);2713    if (pure) {2714        push(PURE_ANNOTATION);2715    }2716    push(callee + `(`, node);2717    genNodeList(node.arguments, context);2718    push(`)`);2719}2720function genObjectExpression(node, context) {2721    const { push, indent, deindent, newline } = context;2722    const { properties } = node;2723    if (!properties.length) {2724        push(`{}`, node);2725        return;2726    }2727    const multilines = properties.length > 1 ||2728        (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2729    push(multilines ? `{` : `{ `);2730    multilines && indent();2731    for (let i = 0; i < properties.length; i++) {2732        const { key, value } = properties[i];2733        // key2734        genExpressionAsPropertyKey(key, context);2735        push(`: `);2736        // value2737        genNode(value, context);2738        if (i < properties.length - 1) {2739            // will only reach this if it's multilines2740            push(`,`);2741            newline();2742        }2743    }2744    multilines && deindent();2745    push(multilines ? `}` : ` }`);2746}2747function genArrayExpression(node, context) {2748    genNodeListAsArray(node.elements, context);2749}2750function genFunctionExpression(node, context) {2751    const { push, indent, deindent } = context;2752    const { params, returns, body, newline, isSlot } = node;2753    if (isSlot) {2754        // wrap slot functions with owner context2755        push(`_${helperNameMap[WITH_CTX]}(`);2756    }2757    push(`(`, node);2758    if (shared.isArray(params)) {2759        genNodeList(params, context);2760    }2761    else if (params) {2762        genNode(params, context);2763    }2764    push(`) => `);2765    if (newline || body) {2766        push(`{`);2767        indent();2768    }2769    if (returns) {2770        if (newline) {2771            push(`return `);2772        }2773        if (shared.isArray(returns)) {2774            genNodeListAsArray(returns, context);2775        }2776        else {2777            genNode(returns, context);2778        }2779    }2780    else if (body) {2781        genNode(body, context);2782    }2783    if (newline || body) {2784        deindent();2785        push(`}`);2786    }2787    if (isSlot) {2788        if (node.isNonScopedSlot) {2789            push(`, undefined, true`);2790        }2791        push(`)`);2792    }2793}2794function genConditionalExpression(node, context) {2795    const { test, consequent, alternate, newline: needNewline } = node;2796    const { push, indent, deindent, newline } = context;2797    if (test.type === 4 /* SIMPLE_EXPRESSION */) {2798        const needsParens = !isSimpleIdentifier(test.content);2799        needsParens && push(`(`);2800        genExpression(test, context);2801        needsParens && push(`)`);2802    }2803    else {2804        push(`(`);2805        genNode(test, context);2806        push(`)`);2807    }2808    needNewline && indent();2809    context.indentLevel++;2810    needNewline || push(` `);2811    push(`? `);2812    genNode(consequent, context);2813    context.indentLevel--;2814    needNewline && newline();2815    needNewline || push(` `);2816    push(`: `);2817    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2818    if (!isNested) {2819        context.indentLevel++;2820    }2821    genNode(alternate, context);2822    if (!isNested) {2823        context.indentLevel--;2824    }2825    needNewline && deindent(true /* without newline */);2826}2827function genCacheExpression(node, context) {2828    const { push, helper, indent, deindent, newline } = context;2829    push(`_cache[${node.index}] || (`);2830    if (node.isVNode) {2831        indent();2832        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2833        newline();2834    }2835    push(`_cache[${node.index}] = `);2836    genNode(node.value, context);2837    if (node.isVNode) {2838        push(`,`);2839        newline();2840        push(`${helper(SET_BLOCK_TRACKING)}(1),`);2841        newline();2842        push(`_cache[${node.index}]`);2843        deindent();2844    }2845    push(`)`);2846}2847function genTemplateLiteral(node, context) {2848    const { push, indent, deindent } = context;2849    push('`');2850    const l = node.elements.length;2851    const multilines = l > 3;2852    for (let i = 0; i < l; i++) {2853        const e = node.elements[i];2854        if (shared.isString(e)) {2855            push(e.replace(/(`|\$|\\)/g, '\\$1'));2856        }2857        else {2858            push('${');2859            if (multilines)2860                indent();2861            genNode(e, context);2862            if (multilines)2863                deindent();2864            push('}');2865        }2866    }2867    push('`');2868}2869function genIfStatement(node, context) {2870    const { push, indent, deindent } = context;2871    const { test, consequent, alternate } = node;2872    push(`if (`);2873    genNode(test, context);2874    push(`) {`);2875    indent();2876    genNode(consequent, context);2877    deindent();2878    push(`}`);2879    if (alternate) {2880        push(` else `);2881        if (alternate.type === 23 /* JS_IF_STATEMENT */) {2882            genIfStatement(alternate, context);2883        }2884        else {2885            push(`{`);2886            indent();2887            genNode(alternate, context);2888            deindent();2889            push(`}`);2890        }2891    }2892}2893function genAssignmentExpression(node, context) {2894    genNode(node.left, context);2895    context.push(` = `);2896    genNode(node.right, context);2897}2898function genSequenceExpression(node, context) {2899    context.push(`(`);2900    genNodeList(node.expressions, context);2901    context.push(`)`);2902}2903function genReturnStatement({ returns }, context) {2904    context.push(`return `);2905    if (shared.isArray(returns)) {2906        genNodeListAsArray(returns, context);2907    }2908    else {2909        genNode(returns, context);2910    }2911}2912function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2913    const rootExp = root.type === 'Program' &&2914        root.body[0].type === 'ExpressionStatement' &&2915        root.body[0].expression;2916    estreeWalker.walk(root, {2917        enter(node, parent) {2918            parent && parentStack.push(parent);2919            if (parent &&2920                parent.type.startsWith('TS') &&2921                parent.type !== 'TSAsExpression' &&2922                parent.type !== 'TSNonNullExpression' &&2923                parent.type !== 'TSTypeAssertion') {2924                return this.skip();2925            }2926            if (node.type === 'Identifier') {2927                const isLocal = !!knownIds[node.name];2928                const isRefed = isReferencedIdentifier(node, parent, parentStack);2929                if (includeAll || (isRefed && !isLocal)) {2930                    onIdentifier(node, parent, parentStack, isRefed, isLocal);2931                }2932            }2933            else if (node.type === 'ObjectProperty' &&2934                parent.type === 'ObjectPattern') {2935                node.inPattern = true;2936            }2937            else if (isFunctionType(node)) {2938                // walk function expressions and add its arguments to known identifiers2939                // so that we don't prefix them2940                walkFunctionParams(node, id => markScopeIdentifier(node, id, knownIds));2941            }2942            else if (node.type === 'BlockStatement') {2943                // #3445 record block-level local variables2944                walkBlockDeclarations(node, id => markScopeIdentifier(node, id, knownIds));2945            }2946        },2947        leave(node, parent) {2948            parent && parentStack.pop();2949            if (node !== rootExp && node.scopeIds) {2950                for (const id of node.scopeIds) {2951                    knownIds[id]--;2952                    if (knownIds[id] === 0) {2953                        delete knownIds[id];2954                    }2955                }2956            }2957        }2958    });2959}2960function isReferencedIdentifier(id, parent, parentStack) {2961    if (!parent) {2962        return true;2963    }2964    // is a special keyword but parsed as identifier2965    if (id.name === 'arguments') {2966        return false;2967    }2968    if (isReferenced(id, parent)) {2969        return true;2970    }2971    // babel's isReferenced check returns false for ids being assigned to, so we2972    // need to cover those cases here2973    switch (parent.type) {2974        case 'AssignmentExpression':2975        case 'AssignmentPattern':2976            return true;2977        case 'ObjectPattern':2978        case 'ArrayPattern':2979            return isInDestructureAssignment(parent, parentStack);2980    }2981    return false;2982}2983function isInDestructureAssignment(parent, parentStack) {2984    if (parent &&2985        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2986        let i = parentStack.length;2987        while (i--) {2988            const p = parentStack[i];2989            if (p.type === 'AssignmentExpression') {2990                return true;2991            }2992            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2993                break;2994            }2995        }2996    }2997    return false;2998}2999function walkFunctionParams(node, onIdent) {3000    for (const p of node.params) {3001        for (const id of extractIdentifiers(p)) {3002            onIdent(id);3003        }3004    }3005}3006function walkBlockDeclarations(block, onIdent) {3007    for (const stmt of block.body) {3008        if (stmt.type === 'VariableDeclaration') {3009            if (stmt.declare)3010                continue;3011            for (const decl of stmt.declarations) {3012                for (const id of extractIdentifiers(decl.id)) {3013                    onIdent(id);3014                }3015            }3016        }3017        else if (stmt.type === 'FunctionDeclaration' ||3018            stmt.type === 'ClassDeclaration') {3019            if (stmt.declare || !stmt.id)3020                continue;3021            onIdent(stmt.id);3022        }3023    }3024}3025function extractIdentifiers(param, nodes = []) {3026    switch (param.type) {3027        case 'Identifier':3028            nodes.push(param);3029            break;3030        case 'MemberExpression':3031            let object = param;3032            while (object.type === 'MemberExpression') {3033                object = object.object;3034            }3035            nodes.push(object);3036            break;3037        case 'ObjectPattern':3038            for (const prop of param.properties) {3039                if (prop.type === 'RestElement') {3040                    extractIdentifiers(prop.argument, nodes);3041                }3042                else {3043                    extractIdentifiers(prop.value, nodes);3044                }3045            }3046            break;3047        case 'ArrayPattern':3048            param.elements.forEach(element => {3049                if (element)3050                    extractIdentifiers(element, nodes);3051            });3052            break;3053        case 'RestElement':3054            extractIdentifiers(param.argument, nodes);3055            break;3056        case 'AssignmentPattern':3057            extractIdentifiers(param.left, nodes);3058            break;3059    }3060    return nodes;3061}3062function markScopeIdentifier(node, child, knownIds) {3063    const { name } = child;3064    if (node.scopeIds && node.scopeIds.has(name)) {3065        return;3066    }3067    if (name in knownIds) {3068        knownIds[name]++;3069    }3070    else {3071        knownIds[name] = 1;3072    }3073    (node.scopeIds || (node.scopeIds = new Set())).add(name);3074}3075const isFunctionType = (node) => {3076    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);3077};3078const isStaticProperty = (node) => node &&3079    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&3080    !node.computed;3081const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;3082/**3083 * Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts3084 * To avoid runtime dependency on @babel/types (which includes process references)3085 * This file should not change very often in babel but we may need to keep it3086 * up-to-date from time to time.3087 *3088 * https://github.com/babel/babel/blob/main/LICENSE3089 *3090 */3091function isReferenced(node, parent, grandparent) {3092    switch (parent.type) {3093        // yes: PARENT[NODE]3094        // yes: NODE.child3095        // no: parent.NODE3096        case 'MemberExpression':3097        case 'OptionalMemberExpression':3098            if (parent.property === node) {3099                return !!parent.computed;3100            }3101            return parent.object === node;3102        case 'JSXMemberExpression':3103            return parent.object === node;3104        // no: let NODE = init;3105        // yes: let id = NODE;3106        case 'VariableDeclarator':3107            return parent.init === node;3108        // yes: () => NODE3109        // no: (NODE) => {}3110        case 'ArrowFunctionExpression':3111            return parent.body === node;3112        // no: class { #NODE; }3113        // no: class { get #NODE() {} }3114        // no: class { #NODE() {} }3115        // no: class { fn() { return this.#NODE; } }3116        case 'PrivateName':3117            return false;3118        // no: class { NODE() {} }3119        // yes: class { [NODE]() {} }3120        // no: class { foo(NODE) {} }3121        case 'ClassMethod':3122        case 'ClassPrivateMethod':3123        case 'ObjectMethod':3124            if (parent.key === node) {3125                return !!parent.computed;3126            }3127            return false;3128        // yes: { [NODE]: "" }3129        // no: { NODE: "" }3130        // depends: { NODE }3131        // depends: { key: NODE }3132        case 'ObjectProperty':3133            if (parent.key === node) {3134                return !!parent.computed;3135            }3136            // parent.value === node3137            return !grandparent || grandparent.type !== 'ObjectPattern';3138        // no: class { NODE = value; }3139        // yes: class { [NODE] = value; }3140        // yes: class { key = NODE; }3141        case 'ClassProperty':3142            if (parent.key === node) {3143                return !!parent.computed;3144            }3145            return true;3146        case 'ClassPrivateProperty':3147            return parent.key !== node;3148        // no: class NODE {}3149        // yes: class Foo extends NODE {}3150        case 'ClassDeclaration':3151        case 'ClassExpression':3152            return parent.superClass === node;3153        // yes: left = NODE;3154        // no: NODE = right;3155        case 'AssignmentExpression':3156            return parent.right === node;3157        // no: [NODE = foo] = [];3158        // yes: [foo = NODE] = [];3159        case 'AssignmentPattern':3160            return parent.right === node;3161        // no: NODE: for (;;) {}3162        case 'LabeledStatement':3163            return false;3164        // no: try {} catch (NODE) {}3165        case 'CatchClause':3166            return false;3167        // no: function foo(...NODE) {}3168        case 'RestElement':3169            return false;3170        case 'BreakStatement':3171        case 'ContinueStatement':3172            return false;3173        // no: function NODE() {}3174        // no: function foo(NODE) {}3175        case 'FunctionDeclaration':3176        case 'FunctionExpression':3177            return false;3178        // no: export NODE from "foo";3179        // no: export * as NODE from "foo";3180        case 'ExportNamespaceSpecifier':3181        case 'ExportDefaultSpecifier':3182            return false;3183        // no: export { foo as NODE };3184        // yes: export { NODE as foo };3185        // no: export { NODE as foo } from "foo";3186        case 'ExportSpecifier':3187            // @ts-expect-error3188            if (grandparent === null || grandparent === void 0 ? void 0 : grandparent.source) {3189                return false;3190            }3191            return parent.local === node;3192        // no: import NODE from "foo";3193        // no: import * as NODE from "foo";3194        // no: import { NODE as foo } from "foo";3195        // no: import { foo as NODE } from "foo";3196        // no: import NODE from "bar";3197        case 'ImportDefaultSpecifier':3198        case 'ImportNamespaceSpecifier':3199        case 'ImportSpecifier':3200            return false;3201        // no: import "foo" assert { NODE: "json" }3202        case 'ImportAttribute':3203            return false;3204        // no: <div NODE="foo" />3205        case 'JSXAttribute':3206            return false;3207        // no: [NODE] = [];3208        // no: ({ NODE }) = [];3209        case 'ObjectPattern':3210        case 'ArrayPattern':3211            return false;3212        // no: new.NODE3213        // no: NODE.target3214        case 'MetaProperty':3215            return false;3216        // yes: type X = { somePropert: NODE }3217        // no: type X = { NODE: OtherType }3218        case 'ObjectTypeProperty':3219            return parent.key !== node;3220        // yes: enum X { Foo = NODE }3221        // no: enum X { NODE }3222        case 'TSEnumMember':3223            return parent.id !== node;3224        // yes: { [NODE]: value }3225        // no: { NODE: value }3226        case 'TSPropertySignature':3227            if (parent.key === node) {3228                return !!parent.computed;3229            }3230            return true;3231    }3232    return true;3233}3234const isLiteralWhitelisted = /*#__PURE__*/ shared.makeMap('true,false,null,this');3235const transformExpression = (node, context) => {3236    if (node.type === 5 /* INTERPOLATION */) {3237        node.content = processExpression(node.content, context);3238    }3239    else if (node.type === 1 /* ELEMENT */) {3240        // handle directives on element3241        for (let i = 0; i < node.props.length; i++) {3242            const dir = node.props[i];3243            // do not process for v-on & v-for since they are special handled3244            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3245                const exp = dir.exp;3246                const arg = dir.arg;3247                // do not process exp if this is v-on:arg - we need special handling3248                // for wrapping inline statements.3249                if (exp &&3250                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&3251                    !(dir.name === 'on' && arg)) {3252                    dir.exp = processExpression(exp, context, 3253                    // slot args must be processed as function params3254                    dir.name === 'slot');3255                }3256                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3257                    dir.arg = processExpression(arg, context);3258                }3259            }3260        }3261    }3262};3263// Important: since this function uses Node.js only dependencies, it should3264// always be used with a leading !false check so that it can be3265// tree-shaken from the browser build.3266function processExpression(node, context, 3267// some expressions like v-slot props & v-for aliases should be parsed as3268// function params3269asParams = false, 3270// v-on handler values may contain multiple statements3271asRawStatements = false, localVars = Object.create(context.identifiers)) {3272    if (!context.prefixIdentifiers || !node.content.trim()) {3273        return node;3274    }3275    const { inline, bindingMetadata } = context;3276    const rewriteIdentifier = (raw, parent, id) => {3277        const type = shared.hasOwn(bindingMetadata, raw) && bindingMetadata[raw];3278        if (inline) {3279            // x = y3280            const isAssignmentLVal = parent && parent.type === 'AssignmentExpression' && parent.left === id;3281            // x++3282            const isUpdateArg = parent && parent.type === 'UpdateExpression' && parent.argument === id;3283            // ({ x } = y)3284            const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack);3285            if (type === "setup-const" /* SETUP_CONST */ || localVars[raw]) {3286                return raw;3287            }3288            else if (type === "setup-ref" /* SETUP_REF */) {3289                return `${raw}.value`;3290            }3291            else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {3292                // const binding that may or may not be ref3293                // if it's not a ref, then assignments don't make sense -3294                // so we ignore the non-ref assignment case and generate code3295                // that assumes the value to be a ref for more efficiency3296                return isAssignmentLVal || isUpdateArg || isDestructureAssignment3297                    ? `${raw}.value`3298                    : `${context.helperString(UNREF)}(${raw})`;3299            }3300            else if (type === "setup-let" /* SETUP_LET */) {3301                if (isAssignmentLVal) {3302                    // let binding.3303                    // this is a bit more tricky as we need to cover the case where3304                    // let is a local non-ref value, and we need to replicate the3305                    // right hand side value.3306                    // x = y --> isRef(x) ? x.value = y : x = y3307                    const { right: rVal, operator } = parent;3308                    const rExp = rawExp.slice(rVal.start - 1, rVal.end - 1);3309                    const rExpString = stringifyExpression(processExpression(createSimpleExpression(rExp, false), context, false, false, knownIds));3310                    return `${context.helperString(IS_REF)}(${raw})${context.isTS ? ` //@ts-ignore\n` : ``} ? ${raw}.value ${operator} ${rExpString} : ${raw}`;3311                }3312                else if (isUpdateArg) {3313                    // make id replace parent in the code range so the raw update operator3314                    // is removed3315                    id.start = parent.start;3316                    id.end = parent.end;3317                    const { prefix: isPrefix, operator } = parent;3318                    const prefix = isPrefix ? operator : ``;3319                    const postfix = isPrefix ? `` : operator;3320                    // let binding.3321                    // x++ --> isRef(a) ? a.value++ : a++3322                    return `${context.helperString(IS_REF)}(${raw})${context.isTS ? ` //@ts-ignore\n` : ``} ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}`;3323                }3324                else if (isDestructureAssignment) {3325                    // TODO3326                    // let binding in a destructure assignment - it's very tricky to3327                    // handle both possible cases here without altering the original3328                    // structure of the code, so we just assume it's not a ref here3329                    // for now3330                    return raw;3331                }3332                else {3333                    return `${context.helperString(UNREF)}(${raw})`;3334                }3335            }3336            else if (type === "props" /* PROPS */) {3337                // use __props which is generated by compileScript so in ts mode3338                // it gets correct type3339                return `__props.${raw}`;3340            }3341            else if (type === "props-aliased" /* PROPS_ALIASED */) {3342                // prop with a different local alias (from defineProps() destructure)3343                return `__props.${bindingMetadata.__propsAliases[raw]}`;3344            }3345        }3346        else {3347            if (type && type.startsWith('setup')) {3348                // setup bindings in non-inline mode3349                return `$setup.${raw}`;3350            }3351            else if (type === "props-aliased" /* PROPS_ALIASED */) {3352                return `$props.${bindingMetadata.__propsAliases[raw]}`;3353            }3354            else if (type) {3355                return `$${type}.${raw}`;3356            }3357        }3358        // fallback to ctx3359        return `_ctx.${raw}`;3360    };3361    // fast path if expression is a simple identifier.3362    const rawExp = node.content;3363    // bail constant on parens (function invocation) and dot (member access)3364    const bailConstant = rawExp.indexOf(`(`) > -1 || rawExp.indexOf('.') > 0;3365    if (isSimpleIdentifier(rawExp)) {3366        const isScopeVarReference = context.identifiers[rawExp];3367        const isAllowedGlobal = shared.isGloballyWhitelisted(rawExp);3368        const isLiteral = isLiteralWhitelisted(rawExp);3369        if (!asParams && !isScopeVarReference && !isAllowedGlobal && !isLiteral) {3370            // const bindings exposed from setup can be skipped for patching but3371            // cannot be hoisted to module scope3372            if (bindingMetadata[node.content] === "setup-const" /* SETUP_CONST */) {3373                node.constType = 1 /* CAN_SKIP_PATCH */;3374            }3375            node.content = rewriteIdentifier(rawExp);3376        }3377        else if (!isScopeVarReference) {3378            if (isLiteral) {3379                node.constType = 3 /* CAN_STRINGIFY */;3380            }3381            else {3382                node.constType = 2 /* CAN_HOIST */;3383            }3384        }3385        return node;3386    }3387    let ast;3388    // exp needs to be parsed differently:3389    // 1. Multiple inline statements (v-on, with presence of `;`): parse as raw3390    //    exp, but make sure to pad with spaces for consistent ranges3391    // 2. Expressions: wrap with parens (for e.g. object expressions)3392    // 3. Function arguments (v-for, v-slot): place in a function argument position3393    const source = asRawStatements3394        ? ` ${rawExp} `3395        : `(${rawExp})${asParams ? `=>{}` : ``}`;3396    try {3397        ast = parser.parse(source, {3398            plugins: context.expressionPlugins3399        }).program;3400    }3401    catch (e) {3402        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, e.message));3403        return node;3404    }3405    const ids = [];3406    const parentStack = [];3407    const knownIds = Object.create(context.identifiers);3408    walkIdentifiers(ast, (node, parent, _, isReferenced, isLocal) => {3409        if (isStaticPropertyKey(node, parent)) {3410            return;3411        }3412        // v2 wrapped filter call3413        if (node.name.startsWith('_filter_')) {3414            return;3415        }3416        const needPrefix = isReferenced && canPrefix(node);3417        if (needPrefix && !isLocal) {3418            if (isStaticProperty(parent) && parent.shorthand) {3419                node.prefix = `${node.name}: `;3420            }3421            node.name = rewriteIdentifier(node.name, parent, node);3422            ids.push(node);3423        }3424        else {3425            // The identifier is considered constant unless it's pointing to a3426            // local scope variable (a v-for alias, or a v-slot prop)3427            if (!(needPrefix && isLocal) && !bailConstant) {3428                node.isConstant = true;3429            }3430            // also generate sub-expressions for other identifiers for better3431            // source map support. (except for property keys which are static)3432            ids.push(node);3433        }3434    }, true, // invoke on ALL identifiers3435    parentStack, knownIds);3436    // We break up the compound expression into an array of strings and sub3437    // expressions (for identifiers that have been prefixed). In codegen, if3438    // an ExpressionNode has the `.children` property, it will be used instead of3439    // `.content`.3440    const children = [];3441    ids.sort((a, b) => a.start - b.start);3442    ids.forEach((id, i) => {3443        // range is offset by -1 due to the wrapping parens when parsed3444        const start = id.start - 1;3445        const end = id.end - 1;3446        const last = ids[i - 1];3447        const leadingText = rawExp.slice(last ? last.end - 1 : 0, start);3448        if (leadingText.length || id.prefix) {3449            children.push(leadingText + (id.prefix || ``));3450        }3451        const source = rawExp.slice(start, end);3452        children.push(createSimpleExpression(id.name, false, {3453            source,3454            start: advancePositionWithClone(node.loc.start, source, start),3455            end: advancePositionWithClone(node.loc.start, source, end)3456        }, id.isConstant ? 3 /* CAN_STRINGIFY */ : 0 /* NOT_CONSTANT */));3457        if (i === ids.length - 1 && end < rawExp.length) {3458            children.push(rawExp.slice(end));3459        }3460    });3461    let ret;3462    if (children.length) {3463        ret = createCompoundExpression(children, node.loc);3464    }3465    else {3466        ret = node;3467        ret.constType = bailConstant3468            ? 0 /* NOT_CONSTANT */3469            : 3 /* CAN_STRINGIFY */;3470    }3471    ret.identifiers = Object.keys(knownIds);3472    return ret;3473}3474function canPrefix(id) {3475    // skip whitelisted globals3476    if (shared.isGloballyWhitelisted(id.name)) {3477        return false;3478    }3479    // special case for webpack compilation3480    if (id.name === 'require') {3481        return false;3482    }3483    return true;3484}3485function stringifyExpression(exp) {3486    if (shared.isString(exp)) {3487        return exp;3488    }3489    else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {3490        return exp.content;3491    }3492    else {3493        return exp.children3494            .map(stringifyExpression)3495            .join('');3496    }3497}3498const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3499    return processIf(node, dir, context, (ifNode, branch, isRoot) => {3500        // #1587: We need to dynamically increment the key based on the current3501        // node's sibling nodes, since chained v-if/else branches are3502        // rendered at the same depth3503        const siblings = context.parent.children;3504        let i = siblings.indexOf(ifNode);3505        let key = 0;3506        while (i-- >= 0) {3507            const sibling = siblings[i];3508            if (sibling && sibling.type === 9 /* IF */) {3509                key += sibling.branches.length;3510            }3511        }3512        // Exit callback. Complete the codegenNode when all children have been3513        // transformed.3514        return () => {3515            if (isRoot) {3516                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3517            }3518            else {3519                // attach this branch's codegen node to the v-if root.3520                const parentCondition = getParentCondition(ifNode.codegenNode);3521                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3522            }3523        };3524    });3525});3526// target-agnostic transform used for both Client and SSR3527function processIf(node, dir, context, processCodegen) {3528    if (dir.name !== 'else' &&3529        (!dir.exp || !dir.exp.content.trim())) {3530        const loc = dir.exp ? dir.exp.loc : node.loc;3531        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3532        dir.exp = createSimpleExpression(`true`, false, loc);3533    }3534    if (context.prefixIdentifiers && dir.exp) {3535        // dir.exp can only be simple expression because vIf transform is applied3536        // before expression transform.3537        dir.exp = processExpression(dir.exp, context);3538    }3539    if (dir.name === 'if') {3540        const branch = createIfBranch(node, dir);3541        const ifNode = {3542            type: 9 /* IF */,3543            loc: node.loc,3544            branches: [branch]3545        };3546        context.replaceNode(ifNode);3547        if (processCodegen) {3548            return processCodegen(ifNode, branch, true);3549        }3550    }3551    else {3552        // locate the adjacent v-if3553        const siblings = context.parent.children;3554        let i = siblings.indexOf(node);3555        while (i-- >= -1) {3556            const sibling = siblings[i];3557            if (sibling &&3558                sibling.type === 2 /* TEXT */ &&3559                !sibling.content.trim().length) {3560                context.removeNode(sibling);3561                continue;3562            }3563            if (sibling && sibling.type === 9 /* IF */) {3564                // Check if v-else was followed by v-else-if3565                if (dir.name === 'else-if' &&3566                    sibling.branches[sibling.branches.length - 1].condition === undefined) {3567                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3568                }3569                // move the node to the if node's branches3570                context.removeNode();3571                const branch = createIfBranch(node, dir);3572                // check if user is forcing same key on different branches3573                {3574                    const key = branch.userKey;3575                    if (key) {3576                        sibling.branches.forEach(({ userKey }) => {3577                            if (isSameKey(userKey, key)) {3578                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3579                            }3580                        });3581                    }3582                }3583                sibling.branches.push(branch);3584                const onExit = processCodegen && processCodegen(sibling, branch, false);3585                // since the branch was removed, it will not be traversed.3586                // make sure to traverse here.3587                traverseNode(branch, context);3588                // call on exit3589                if (onExit)3590                    onExit();3591                // make sure to reset currentNode after traversal to indicate this3592                // node has been removed.3593                context.currentNode = null;3594            }3595            else {3596                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3597            }3598            break;3599        }3600    }3601}3602function createIfBranch(node, dir) {3603    return {3604        type: 10 /* IF_BRANCH */,3605        loc: node.loc,3606        condition: dir.name === 'else' ? undefined : dir.exp,3607        children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3608            ? node.children3609            : [node],3610        userKey: findProp(node, `key`)3611    };3612}3613function createCodegenNodeForBranch(branch, keyIndex, context) {3614    if (branch.condition) {3615        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3616        // make sure to pass in asBlock: true so that the comment node call3617        // closes the current block.3618        createCallExpression(context.helper(CREATE_COMMENT), [3619            '""',3620            'true'3621        ]));3622    }3623    else {3624        return createChildrenCodegenNode(branch, keyIndex, context);3625    }3626}3627function createChildrenCodegenNode(branch, keyIndex, context) {3628    const { helper } = context;3629    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3630    const { children } = branch;3631    const firstChild = children[0];3632    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3633    if (needFragmentWrapper) {3634        if (children.length === 1 && firstChild.type === 11 /* FOR */) {3635            // optimize away nested fragments when child is a ForNode3636            const vnodeCall = firstChild.codegenNode;3637            injectProp(vnodeCall, keyProperty, context);3638            return vnodeCall;3639        }3640        else {3641            let patchFlag = 64 /* STABLE_FRAGMENT */;3642            shared.PatchFlagNames[64 /* STABLE_FRAGMENT */];3643            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (``), undefined, undefined, true, false, false /* isComponent */, branch.loc);3644        }3645    }3646    else {3647        const ret = firstChild.codegenNode;3648        const vnodeCall = getMemoedVNodeCall(ret);3649        // Change createVNode to createBlock.3650        if (vnodeCall.type === 13 /* VNODE_CALL */) {3651            makeBlock(vnodeCall, context);3652        }3653        // inject branch key3654        injectProp(vnodeCall, keyProperty, context);3655        return ret;3656    }3657}3658function isSameKey(a, b) {3659    if (!a || a.type !== b.type) {3660        return false;3661    }3662    if (a.type === 6 /* ATTRIBUTE */) {3663        if (a.value.content !== b.value.content) {3664            return false;3665        }3666    }3667    else {3668        // directive3669        const exp = a.exp;3670        const branchExp = b.exp;3671        if (exp.type !== branchExp.type) {3672            return false;3673        }3674        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3675            exp.isStatic !== branchExp.isStatic ||3676            exp.content !== branchExp.content) {3677            return false;3678        }3679    }3680    return true;3681}3682function getParentCondition(node) {3683    while (true) {3684        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3685            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3686                node = node.alternate;3687            }3688            else {3689                return node;3690            }3691        }3692        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3693            node = node.value;3694        }3695    }3696}3697const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3698    const { helper, removeHelper } = context;3699    return processFor(node, dir, context, forNode => {3700        // create the loop render function expression now, and add the3701        // iterator on exit after all children have been traversed3702        const renderExp = createCallExpression(helper(RENDER_LIST), [3703            forNode.source3704        ]);3705        const memo = findDir(node, 'memo');3706        const keyProp = findProp(node, `key`);3707        const keyExp = keyProp &&3708            (keyProp.type === 6 /* ATTRIBUTE */3709                ? createSimpleExpression(keyProp.value.content, true)3710                : keyProp.exp);3711        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3712        if (context.prefixIdentifiers &&3713            keyProperty &&3714            keyProp.type !== 6 /* ATTRIBUTE */) {3715            // #2085 process :key expression needs to be processed in order for it3716            // to behave consistently for <template v-for> and <div v-for>.3717            // In the case of `<template v-for>`, the node is discarded and never3718            // traversed so its key expression won't be processed by the normal3719            // transforms.3720            keyProperty.value = processExpression(keyProperty.value, context);3721        }3722        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3723            forNode.source.constType > 0 /* NOT_CONSTANT */;3724        const fragmentFlag = isStableFragment3725            ? 64 /* STABLE_FRAGMENT */3726            : keyProp3727                ? 128 /* KEYED_FRAGMENT */3728                : 256 /* UNKEYED_FRAGMENT */;3729        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3730            (``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3731        return () => {3732            // finish the codegen now that all children have been traversed3733            let childBlock;3734            const isTemplate = isTemplateNode(node);3735            const { children } = forNode;3736            // check <template v-for> key placement3737            if (isTemplate) {3738                node.children.some(c => {3739                    if (c.type === 1 /* ELEMENT */) {3740                        const key = findProp(c, 'key');3741                        if (key) {3742                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3743                            return true;3744                        }3745                    }3746                });3747            }3748            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3749            const slotOutlet = isSlotOutlet(node)3750                ? node3751                : isTemplate &&3752                    node.children.length === 1 &&3753                    isSlotOutlet(node.children[0])3754                    ? node.children[0] // api-extractor somehow fails to infer this3755                    : null;3756            if (slotOutlet) {3757                // <slot v-for="..."> or <template v-for="..."><slot/></template>3758                childBlock = slotOutlet.codegenNode;3759                if (isTemplate && keyProperty) {3760                    // <template v-for="..." :key="..."><slot/></template>3761                    // we need to inject the key to the renderSlot() call.3762                    // the props for renderSlot is passed as the 3rd argument.3763                    injectProp(childBlock, keyProperty, context);3764                }3765            }3766            else if (needFragmentWrapper) {3767                // <template v-for="..."> with text or multi-elements3768                // should generate a fragment block for each loop3769                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3770                    (``), undefined, undefined, true, undefined, false /* isComponent */);3771            }3772            else {3773                // Normal element v-for. Directly use the child's codegenNode3774                // but mark it as a block.3775                childBlock = children[0]3776                    .codegenNode;3777                if (isTemplate && keyProperty) {3778                    injectProp(childBlock, keyProperty, context);3779                }3780                if (childBlock.isBlock !== !isStableFragment) {3781                    if (childBlock.isBlock) {3782                        // switch from block to vnode3783                        removeHelper(OPEN_BLOCK);3784                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3785                    }3786                    else {3787                        // switch from vnode to block3788                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3789                    }3790                }3791                childBlock.isBlock = !isStableFragment;3792                if (childBlock.isBlock) {3793                    helper(OPEN_BLOCK);3794                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3795                }3796                else {3797                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3798                }3799            }3800            if (memo) {3801                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3802                    createSimpleExpression(`_cached`)3803                ]));3804                loop.body = createBlockStatement([3805                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3806                    createCompoundExpression([3807                        `if (_cached`,3808                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),3809                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3810                    ]),3811                    createCompoundExpression([`const _item = `, childBlock]),3812                    createSimpleExpression(`_item.memo = _memo`),3813                    createSimpleExpression(`return _item`)3814                ]);3815                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3816            }3817            else {3818                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3819            }3820        };3821    });3822});3823// target-agnostic transform used for both Client and SSR3824function processFor(node, dir, context, processCodegen) {3825    if (!dir.exp) {3826        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3827        return;3828    }3829    const parseResult = parseForExpression(3830    // can only be simple expression because vFor transform is applied3831    // before expression transform.3832    dir.exp, context);3833    if (!parseResult) {3834        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3835        return;3836    }3837    const { addIdentifiers, removeIdentifiers, scopes } = context;3838    const { source, value, key, index } = parseResult;3839    const forNode = {3840        type: 11 /* FOR */,3841        loc: dir.loc,3842        source,3843        valueAlias: value,3844        keyAlias: key,3845        objectIndexAlias: index,3846        parseResult,3847        children: isTemplateNode(node) ? node.children : [node]3848    };3849    context.replaceNode(forNode);3850    // bookkeeping3851    scopes.vFor++;3852    if (context.prefixIdentifiers) {3853        // scope management3854        // inject identifiers to context3855        value && addIdentifiers(value);3856        key && addIdentifiers(key);3857        index && addIdentifiers(index);3858    }3859    const onExit = processCodegen && processCodegen(forNode);3860    return () => {3861        scopes.vFor--;3862        if (context.prefixIdentifiers) {3863            value && removeIdentifiers(value);3864            key && removeIdentifiers(key);3865            index && removeIdentifiers(index);3866        }3867        if (onExit)3868            onExit();3869    };3870}3871const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3872// This regex doesn't cover the case if key or index aliases have destructuring,3873// but those do not make sense in the first place, so this works in practice.3874const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3875const stripParensRE = /^\(|\)$/g;3876function parseForExpression(input, context) {3877    const loc = input.loc;3878    const exp = input.content;3879    const inMatch = exp.match(forAliasRE);3880    if (!inMatch)3881        return;3882    const [, LHS, RHS] = inMatch;3883    const result = {3884        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3885        value: undefined,3886        key: undefined,3887        index: undefined3888    };3889    if (context.prefixIdentifiers) {3890        result.source = processExpression(result.source, context);3891    }3892    let valueContent = LHS.trim().replace(stripParensRE, '').trim();3893    const trimmedOffset = LHS.indexOf(valueContent);3894    const iteratorMatch = valueContent.match(forIteratorRE);3895    if (iteratorMatch) {3896        valueContent = valueContent.replace(forIteratorRE, '').trim();3897        const keyContent = iteratorMatch[1].trim();3898        let keyOffset;3899        if (keyContent) {3900            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3901            result.key = createAliasExpression(loc, keyContent, keyOffset);3902            if (context.prefixIdentifiers) {3903                result.key = processExpression(result.key, context, true);3904            }3905        }3906        if (iteratorMatch[2]) {3907            const indexContent = iteratorMatch[2].trim();3908            if (indexContent) {3909                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3910                    ? keyOffset + keyContent.length3911                    : trimmedOffset + valueContent.length));3912                if (context.prefixIdentifiers) {3913                    result.index = processExpression(result.index, context, true);3914                }3915            }3916        }3917    }3918    if (valueContent) {3919        result.value = createAliasExpression(loc, valueContent, trimmedOffset);3920        if (context.prefixIdentifiers) {3921            result.value = processExpression(result.value, context, true);3922        }3923    }3924    return result;3925}3926function createAliasExpression(range, content, offset) {3927    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3928}3929function createForLoopParams({ value, key, index }, memoArgs = []) {3930    return createParamsList([value, key, index, ...memoArgs]);3931}3932function createParamsList(args) {3933    let i = args.length;3934    while (i--) {3935        if (args[i])3936            break;3937    }3938    return args3939        .slice(0, i + 1)3940        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3941}3942const defaultFallback = createSimpleExpression(`undefined`, false);3943// A NodeTransform that:3944// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3945//    by transformExpression. This is only applied in non-browser builds with3946//    { prefixIdentifiers: true }.3947// 2. Track v-slot depths so that we know a slot is inside another slot.3948//    Note the exit callback is executed before buildSlots() on the same node,3949//    so only nested slots see positive numbers.3950const trackSlotScopes = (node, context) => {3951    if (node.type === 1 /* ELEMENT */ &&3952        (node.tagType === 1 /* COMPONENT */ ||3953            node.tagType === 3 /* TEMPLATE */)) {3954        // We are only checking non-empty v-slot here3955        // since we only care about slots that introduce scope variables.3956        const vSlot = findDir(node, 'slot');3957        if (vSlot) {3958            const slotProps = vSlot.exp;3959            if (context.prefixIdentifiers) {3960                slotProps && context.addIdentifiers(slotProps);3961            }3962            context.scopes.vSlot++;3963            return () => {3964                if (context.prefixIdentifiers) {3965                    slotProps && context.removeIdentifiers(slotProps);3966                }3967                context.scopes.vSlot--;3968            };3969        }3970    }3971};3972// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3973// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3974const trackVForSlotScopes = (node, context) => {3975    let vFor;3976    if (isTemplateNode(node) &&3977        node.props.some(isVSlot) &&3978        (vFor = findDir(node, 'for'))) {3979        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3980        if (result) {3981            const { value, key, index } = result;3982            const { addIdentifiers, removeIdentifiers } = context;3983            value && addIdentifiers(value);3984            key && addIdentifiers(key);3985            index && addIdentifiers(index);3986            return () => {3987                value && removeIdentifiers(value);3988                key && removeIdentifiers(key);3989                index && removeIdentifiers(index);3990            };3991        }3992    }3993};3994const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3995// Instead of being a DirectiveTransform, v-slot processing is called during3996// transformElement to build the slots object for a component.3997function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3998    context.helper(WITH_CTX);3999    const { children, loc } = node;4000    const slotsProperties = [];4001    const dynamicSlots = [];4002    // If the slot is inside a v-for or another v-slot, force it to be dynamic4003    // since it likely uses a scope variable.4004    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;4005    // with `prefixIdentifiers: true`, this can be further optimized to make4006    // it dynamic only when the slot actually uses the scope variables.4007    if (!context.ssr && context.prefixIdentifiers) {4008        hasDynamicSlots = hasScopeRef(node, context.identifiers);4009    }4010    // 1. Check for slot with slotProps on component itself.4011    //    <Comp v-slot="{ prop }"/>4012    const onComponentSlot = findDir(node, 'slot', true);4013    if (onComponentSlot) {4014        const { arg, exp } = onComponentSlot;4015        if (arg && !isStaticExp(arg)) {4016            hasDynamicSlots = true;4017        }4018        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));4019    }4020    // 2. Iterate through children and check for template slots4021    //    <template v-slot:foo="{ prop }">4022    let hasTemplateSlots = false;4023    let hasNamedDefaultSlot = false;4024    const implicitDefaultChildren = [];4025    const seenSlotNames = new Set();4026    for (let i = 0; i < children.length; i++) {4027        const slotElement = children[i];4028        let slotDir;4029        if (!isTemplateNode(slotElement) ||4030            !(slotDir = findDir(slotElement, 'slot', true))) {4031            // not a <template v-slot>, skip.4032            if (slotElement.type !== 3 /* COMMENT */) {4033                implicitDefaultChildren.push(slotElement);4034            }4035            continue;4036        }4037        if (onComponentSlot) {4038            // already has on-component slot - this is incorrect usage.4039            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));4040            break;4041        }4042        hasTemplateSlots = true;4043        const { children: slotChildren, loc: slotLoc } = slotElement;4044        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;4045        // check if name is dynamic.4046        let staticSlotName;4047        if (isStaticExp(slotName)) {4048            staticSlotName = slotName ? slotName.content : `default`;4049        }4050        else {4051            hasDynamicSlots = true;4052        }4053        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);4054        // check if this slot is conditional (v-if/v-for)4055        let vIf;4056        let vElse;4057        let vFor;4058        if ((vIf = findDir(slotElement, 'if'))) {4059            hasDynamicSlots = true;4060            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));4061        }4062        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {4063            // find adjacent v-if4064            let j = i;4065            let prev;4066            while (j--) {4067                prev = children[j];4068                if (prev.type !== 3 /* COMMENT */) {4069                    break;4070                }4071            }4072            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {4073                // remove node4074                children.splice(i, 1);4075                i--;4076                // attach this slot to previous conditional4077                let conditional = dynamicSlots[dynamicSlots.length - 1];4078                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {4079                    conditional = conditional.alternate;4080                }4081                conditional.alternate = vElse.exp4082                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)4083                    : buildDynamicSlot(slotName, slotFunction);4084            }4085            else {4086                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));4087            }4088        }4089        else if ((vFor = findDir(slotElement, 'for'))) {4090            hasDynamicSlots = true;4091            const parseResult = vFor.parseResult ||4092                parseForExpression(vFor.exp, context);4093            if (parseResult) {4094                // Render the dynamic slots as an array and add it to the createSlot()4095                // args. The runtime knows how to handle it appropriately.4096                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [4097                    parseResult.source,4098                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)4099                ]));4100            }4101            else {4102                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));4103            }4104        }4105        else {4106            // check duplicate static names4107            if (staticSlotName) {4108                if (seenSlotNames.has(staticSlotName)) {4109                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));4110                    continue;4111                }4112                seenSlotNames.add(staticSlotName);4113                if (staticSlotName === 'default') {4114                    hasNamedDefaultSlot = true;4115                }4116            }4117            slotsProperties.push(createObjectProperty(slotName, slotFunction));4118        }4119    }4120    if (!onComponentSlot) {4121        const buildDefaultSlotProperty = (props, children) => {4122            const fn = buildSlotFn(props, children, loc);4123            if (context.compatConfig) {4124                fn.isNonScopedSlot = true;4125            }4126            return createObjectProperty(`default`, fn);4127        };4128        if (!hasTemplateSlots) {4129            // implicit default slot (on component)4130            slotsProperties.push(buildDefaultSlotProperty(undefined, children));4131        }4132        else if (implicitDefaultChildren.length &&4133            // #37664134            // with whitespace: 'preserve', whitespaces between slots will end up in4135            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.4136            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {4137            // implicit default slot (mixed with named slots)4138            if (hasNamedDefaultSlot) {4139                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));4140            }4141            else {4142                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));4143            }4144        }4145    }4146    const slotFlag = hasDynamicSlots4147        ? 2 /* DYNAMIC */4148        : hasForwardedSlots(node.children)4149            ? 3 /* FORWARDED */4150            : 1 /* STABLE */;4151    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 4152    // 2 = compiled but dynamic = can skip normalization, but must run diff4153    // 1 = compiled and static = can skip normalization AND diff as optimized4154    createSimpleExpression(slotFlag + (``), false))), loc);4155    if (dynamicSlots.length) {4156        slots = createCallExpression(context.helper(CREATE_SLOTS), [4157            slots,4158            createArrayExpression(dynamicSlots)4159        ]);4160    }4161    return {4162        slots,4163        hasDynamicSlots4164    };4165}4166function buildDynamicSlot(name, fn) {4167    return createObjectExpression([4168        createObjectProperty(`name`, name),4169        createObjectProperty(`fn`, fn)4170    ]);4171}4172function hasForwardedSlots(children) {4173    for (let i = 0; i < children.length; i++) {4174        const child = children[i];4175        switch (child.type) {4176            case 1 /* ELEMENT */:4177                if (child.tagType === 2 /* SLOT */ ||4178                    hasForwardedSlots(child.children)) {4179                    return true;4180                }4181                break;4182            case 9 /* IF */:4183                if (hasForwardedSlots(child.branches))4184                    return true;4185                break;4186            case 10 /* IF_BRANCH */:4187            case 11 /* FOR */:4188                if (hasForwardedSlots(child.children))4189                    return true;4190                break;4191        }4192    }4193    return false;4194}4195function isNonWhitespaceContent(node) {4196    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)4197        return true;4198    return node.type === 2 /* TEXT */4199        ? !!node.content.trim()4200        : isNonWhitespaceContent(node.content);4201}4202// some directive transforms (e.g. v-model) may return a symbol for runtime4203// import, which should be used instead of a resolveDirective call.4204const directiveImportMap = new WeakMap();4205// generate a JavaScript AST for this element's codegen4206const transformElement = (node, context) => {4207    // perform the work on exit, after all child expressions have been4208    // processed and merged.4209    return function postTransformElement() {4210        node = context.currentNode;4211        if (!(node.type === 1 /* ELEMENT */ &&4212            (node.tagType === 0 /* ELEMENT */ ||4213                node.tagType === 1 /* COMPONENT */))) {4214            return;4215        }4216        const { tag, props } = node;4217        const isComponent = node.tagType === 1 /* COMPONENT */;4218        // The goal of the transform is to create a codegenNode implementing the4219        // VNodeCall interface.4220        let vnodeTag = isComponent4221            ? resolveComponentType(node, context)4222            : `"${tag}"`;4223        const isDynamicComponent = shared.isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;4224        let vnodeProps;4225        let vnodeChildren;4226        let vnodePatchFlag;4227        let patchFlag = 0;4228        let vnodeDynamicProps;4229        let dynamicPropNames;4230        let vnodeDirectives;4231        let shouldUseBlock = 4232        // dynamic component may resolve to plain elements4233        isDynamicComponent ||4234            vnodeTag === TELEPORT ||4235            vnodeTag === SUSPENSE ||4236            (!isComponent &&4237                // <svg> and <foreignObject> must be forced into blocks so that block4238                // updates inside get proper isSVG flag at runtime. (#639, #643)4239                // This is technically web-specific, but splitting the logic out of core4240                // leads to too much unnecessary complexity.4241                (tag === 'svg' || tag === 'foreignObject'));4242        // props4243        if (props.length > 0) {4244            const propsBuildResult = buildProps(node, context);4245            vnodeProps = propsBuildResult.props;4246            patchFlag = propsBuildResult.patchFlag;4247            dynamicPropNames = propsBuildResult.dynamicPropNames;4248            const directives = propsBuildResult.directives;4249            vnodeDirectives =4250                directives && directives.length4251                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))4252                    : undefined;4253            if (propsBuildResult.shouldUseBlock) {4254                shouldUseBlock = true;4255            }4256        }4257        // children4258        if (node.children.length > 0) {4259            if (vnodeTag === KEEP_ALIVE) {4260                // Although a built-in component, we compile KeepAlive with raw children4261                // instead of slot functions so that it can be used inside Transition4262                // or other Transition-wrapping HOCs.4263                // To ensure correct updates with block optimizations, we need to:4264                // 1. Force keep-alive into a block. This avoids its children being4265                //    collected by a parent block.4266                shouldUseBlock = true;4267                // 2. Force keep-alive to always be updated, since it uses raw children.4268                patchFlag |= 1024 /* DYNAMIC_SLOTS */;4269            }4270            const shouldBuildAsSlots = isComponent &&4271                // Teleport is not a real component and has dedicated runtime handling4272                vnodeTag !== TELEPORT &&4273                // explained above.4274                vnodeTag !== KEEP_ALIVE;4275            if (shouldBuildAsSlots) {4276                const { slots, hasDynamicSlots } = buildSlots(node, context);4277                vnodeChildren = slots;4278                if (hasDynamicSlots) {4279                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;4280                }4281            }4282            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {4283                const child = node.children[0];4284                const type = child.type;4285                // check for dynamic text children4286                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||4287                    type === 8 /* COMPOUND_EXPRESSION */;4288                if (hasDynamicTextChild &&4289                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4290                    patchFlag |= 1 /* TEXT */;4291                }4292                // pass directly if the only child is a text node4293                // (plain / interpolation / expression)4294                if (hasDynamicTextChild || type === 2 /* TEXT */) {4295                    vnodeChildren = child;4296                }4297                else {4298                    vnodeChildren = node.children;4299                }4300            }4301            else {4302                vnodeChildren = node.children;4303            }4304        }4305        // patchFlag & dynamicPropNames4306        if (patchFlag !== 0) {4307            {4308                vnodePatchFlag = String(patchFlag);4309            }4310            if (dynamicPropNames && dynamicPropNames.length) {4311                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);4312            }4313        }4314        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);4315    };4316};4317function resolveComponentType(node, context, ssr = false) {4318    let { tag } = node;4319    // 1. dynamic component4320    const isExplicitDynamic = isComponentTag(tag);4321    const isProp = findProp(node, 'is');4322    if (isProp) {4323        if (isExplicitDynamic ||4324            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {4325            const exp = isProp.type === 6 /* ATTRIBUTE */4326                ? isProp.value && createSimpleExpression(isProp.value.content, true)4327                : isProp.exp;4328            if (exp) {4329                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4330                    exp4331                ]);4332            }4333        }4334        else if (isProp.type === 6 /* ATTRIBUTE */ &&4335            isProp.value.content.startsWith('vue:')) {4336            // <button is="vue:xxx">4337            // if not <component>, only is value that starts with "vue:" will be4338            // treated as component by the parse phase and reach here, unless it's4339            // compat mode where all is values are considered components4340            tag = isProp.value.content.slice(4);4341        }4342    }4343    // 1.5 v-is (TODO: Deprecate)4344    const isDir = !isExplicitDynamic && findDir(node, 'is');4345    if (isDir && isDir.exp) {4346        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [4347            isDir.exp4348        ]);4349    }4350    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)4351    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);4352    if (builtIn) {4353        // built-ins are simply fallthroughs / have special handling during ssr4354        // so we don't need to import their runtime equivalents4355        if (!ssr)4356            context.helper(builtIn);4357        return builtIn;4358    }4359    // 3. user component (from setup bindings)4360    // this is skipped in browser build since browser builds do not perform4361    // binding analysis.4362    {4363        const fromSetup = resolveSetupReference(tag, context);4364        if (fromSetup) {4365            return fromSetup;4366        }4367        const dotIndex = tag.indexOf('.');4368        if (dotIndex > 0) {4369            const ns = resolveSetupReference(tag.slice(0, dotIndex), context);4370            if (ns) {4371                return ns + tag.slice(dotIndex);4372            }4373        }4374    }4375    // 4. Self referencing component (inferred from filename)4376    if (context.selfName &&4377        shared.capitalize(shared.camelize(tag)) === context.selfName) {4378        context.helper(RESOLVE_COMPONENT);4379        // codegen.ts has special check for __self postfix when generating4380        // component imports, which will pass additional `maybeSelfReference` flag4381        // to `resolveComponent`.4382        context.components.add(tag + `__self`);4383        return toValidAssetId(tag, `component`);4384    }4385    // 5. user component (resolve)4386    context.helper(RESOLVE_COMPONENT);4387    context.components.add(tag);4388    return toValidAssetId(tag, `component`);4389}4390function resolveSetupReference(name, context) {4391    const bindings = context.bindingMetadata;4392    if (!bindings || bindings.__isScriptSetup === false) {4393        return;4394    }4395    const camelName = shared.camelize(name);4396    const PascalName = shared.capitalize(camelName);4397    const checkType = (type) => {4398        if (bindings[name] === type) {4399            return name;4400        }4401        if (bindings[camelName] === type) {4402            return camelName;4403        }4404        if (bindings[PascalName] === type) {4405            return PascalName;4406        }4407    };4408    const fromConst = checkType("setup-const" /* SETUP_CONST */);4409    if (fromConst) {4410        return context.inline4411            ? // in inline mode, const setup bindings (e.g. imports) can be used as-is4412                fromConst4413            : `$setup[${JSON.stringify(fromConst)}]`;4414    }4415    const fromMaybeRef = checkType("setup-let" /* SETUP_LET */) ||4416        checkType("setup-ref" /* SETUP_REF */) ||4417        checkType("setup-maybe-ref" /* SETUP_MAYBE_REF */);4418    if (fromMaybeRef) {4419        return context.inline4420            ? // setup scope bindings that may be refs need to be unrefed4421                `${context.helperString(UNREF)}(${fromMaybeRef})`4422            : `$setup[${JSON.stringify(fromMaybeRef)}]`;4423    }4424}4425function buildProps(node, context, props = node.props, ssr = false) {4426    const { tag, loc: elementLoc, children } = node;4427    const isComponent = node.tagType === 1 /* COMPONENT */;4428    let properties = [];4429    const mergeArgs = [];4430    const runtimeDirectives = [];4431    const hasChildren = children.length > 0;4432    let shouldUseBlock = false;4433    // patchFlag analysis4434    let patchFlag = 0;4435    let hasRef = false;4436    let hasClassBinding = false;4437    let hasStyleBinding = false;4438    let hasHydrationEventBinding = false;4439    let hasDynamicKeys = false;4440    let hasVnodeHook = false;4441    const dynamicPropNames = [];4442    const analyzePatchFlag = ({ key, value }) => {4443        if (isStaticExp(key)) {4444            const name = key.content;4445            const isEventHandler = shared.isOn(name);4446            if (!isComponent &&4447                isEventHandler &&4448                // omit the flag for click handlers because hydration gives click4449                // dedicated fast path.4450                name.toLowerCase() !== 'onclick' &&4451                // omit v-model handlers4452                name !== 'onUpdate:modelValue' &&4453                // omit onVnodeXXX hooks4454                !shared.isReservedProp(name)) {4455                hasHydrationEventBinding = true;4456            }4457            if (isEventHandler && shared.isReservedProp(name)) {4458                hasVnodeHook = true;4459            }4460            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||4461                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||4462                    value.type === 8 /* COMPOUND_EXPRESSION */) &&4463                    getConstantType(value, context) > 0)) {4464                // skip if the prop is a cached handler or has constant value4465                return;4466            }4467            if (name === 'ref') {4468                hasRef = true;4469            }4470            else if (name === 'class') {4471                hasClassBinding = true;4472            }4473            else if (name === 'style') {4474                hasStyleBinding = true;4475            }4476            else if (name !== 'key' && !dynamicPropNames.includes(name)) {4477                dynamicPropNames.push(name);4478            }4479            // treat the dynamic class and style binding of the component as dynamic props4480            if (isComponent &&4481                (name === 'class' || name === 'style') &&4482                !dynamicPropNames.includes(name)) {4483                dynamicPropNames.push(name);4484            }4485        }4486        else {4487            hasDynamicKeys = true;4488        }4489    };4490    for (let i = 0; i < props.length; i++) {4491        // static attribute4492        const prop = props[i];4493        if (prop.type === 6 /* ATTRIBUTE */) {4494            const { loc, name, value } = prop;4495            let isStatic = true;4496            if (name === 'ref') {4497                hasRef = true;4498                if (context.scopes.vFor > 0) {4499                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4500                }4501                // in inline mode there is no setupState object, so we can't use string4502                // keys to set the ref. Instead, we need to transform it to pass the4503                // actual ref instead.4504                if (value &&4505                    context.inline &&4506                    context.bindingMetadata[value.content]) {4507                    isStatic = false;4508                    properties.push(createObjectProperty(createSimpleExpression('ref_key', true), createSimpleExpression(value.content, true, value.loc)));4509                }4510            }4511            // skip is on <component>, or is="vue:xxx"4512            if (name === 'is' &&4513                (isComponentTag(tag) ||4514                    (value && value.content.startsWith('vue:')) ||4515                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4516                continue;4517            }4518            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));4519        }4520        else {4521            // directives4522            const { name, arg, exp, loc } = prop;4523            const isVBind = name === 'bind';4524            const isVOn = name === 'on';4525            // skip v-slot - it is handled by its dedicated transform.4526            if (name === 'slot') {4527                if (!isComponent) {4528                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4529                }4530                continue;4531            }4532            // skip v-once/v-memo - they are handled by dedicated transforms.4533            if (name === 'once' || name === 'memo') {4534                continue;4535            }4536            // skip v-is and :is on <component>4537            if (name === 'is' ||4538                (isVBind &&4539                    isStaticArgOf(arg, 'is') &&4540                    (isComponentTag(tag) ||4541                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4542                continue;4543            }4544            // skip v-on in SSR compilation4545            if (isVOn && ssr) {4546                continue;4547            }4548            if (4549            // #938: elements with dynamic keys should be forced into blocks4550            (isVBind && isStaticArgOf(arg, 'key')) ||4551                // inline before-update hooks need to force block so that it is invoked4552                // before children4553                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {4554                shouldUseBlock = true;4555            }4556            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {4557                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4558            }4559            // special case for v-bind and v-on with no argument4560            if (!arg && (isVBind || isVOn)) {4561                hasDynamicKeys = true;4562                if (exp) {4563                    if (properties.length) {4564                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4565                        properties = [];4566                    }4567                    if (isVBind) {4568                        {4569                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4570                                mergeArgs.unshift(exp);4571                                continue;4572                            }4573                        }4574                        mergeArgs.push(exp);4575                    }4576                    else {4577                        // v-on="obj" -> toHandlers(obj)4578                        mergeArgs.push({4579                            type: 14 /* JS_CALL_EXPRESSION */,4580                            loc,4581                            callee: context.helper(TO_HANDLERS),4582                            arguments: [exp]4583                        });4584                    }4585                }4586                else {4587                    context.onError(createCompilerError(isVBind4588                        ? 34 /* X_V_BIND_NO_EXPRESSION */4589                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));4590                }4591                continue;4592            }4593            const directiveTransform = context.directiveTransforms[name];4594            if (directiveTransform) {4595                // has built-in directive transform.4596                const { props, needRuntime } = directiveTransform(prop, node, context);4597                !ssr && props.forEach(analyzePatchFlag);4598                properties.push(...props);4599                if (needRuntime) {4600                    runtimeDirectives.push(prop);4601                    if (shared.isSymbol(needRuntime)) {4602                        directiveImportMap.set(prop, needRuntime);4603                    }4604                }4605            }4606            else {4607                // no built-in transform, this is a user custom directive.4608                runtimeDirectives.push(prop);4609                // custom dirs may use beforeUpdate so they need to force blocks4610                // to ensure before-update gets called before children update4611                if (hasChildren) {4612                    shouldUseBlock = true;4613                }4614            }4615        }4616    }4617    let propsExpression = undefined;4618    // has v-bind="object" or v-on="object", wrap with mergeProps4619    if (mergeArgs.length) {4620        if (properties.length) {4621            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4622        }4623        if (mergeArgs.length > 1) {4624            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4625        }4626        else {4627            // single v-bind with nothing else - no need for a mergeProps call4628            propsExpression = mergeArgs[0];4629        }4630    }4631    else if (properties.length) {4632        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4633    }4634    // patchFlag analysis4635    if (hasDynamicKeys) {4636        patchFlag |= 16 /* FULL_PROPS */;4637    }4638    else {4639        if (hasClassBinding && !isComponent) {4640            patchFlag |= 2 /* CLASS */;4641        }4642        if (hasStyleBinding && !isComponent) {4643            patchFlag |= 4 /* STYLE */;4644        }4645        if (dynamicPropNames.length) {4646            patchFlag |= 8 /* PROPS */;4647        }4648        if (hasHydrationEventBinding) {4649            patchFlag |= 32 /* HYDRATE_EVENTS */;4650        }4651    }4652    if (!shouldUseBlock &&4653        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4654        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4655        patchFlag |= 512 /* NEED_PATCH */;4656    }4657    // pre-normalize props, SSR is skipped for now4658    if (!context.inSSR && propsExpression) {4659        switch (propsExpression.type) {4660            case 15 /* JS_OBJECT_EXPRESSION */:4661                // means that there is no v-bind,4662                // but still need to deal with dynamic key binding4663                let classKeyIndex = -1;4664                let styleKeyIndex = -1;4665                let hasDynamicKey = false;4666                for (let i = 0; i < propsExpression.properties.length; i++) {4667                    const key = propsExpression.properties[i].key;4668                    if (isStaticExp(key)) {4669                        if (key.content === 'class') {4670                            classKeyIndex = i;4671                        }4672                        else if (key.content === 'style') {4673                            styleKeyIndex = i;4674                        }4675                    }4676                    else if (!key.isHandlerKey) {4677                        hasDynamicKey = true;4678                    }4679                }4680                const classProp = propsExpression.properties[classKeyIndex];4681                const styleProp = propsExpression.properties[styleKeyIndex];4682                // no dynamic key4683                if (!hasDynamicKey) {4684                    if (classProp && !isStaticExp(classProp.value)) {4685                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4686                    }4687                    if (styleProp &&4688                        !isStaticExp(styleProp.value) &&4689                        // the static style is compiled into an object,4690                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding4691                        (hasStyleBinding ||4692                            // v-bind:style and style both exist,4693                            // v-bind:style with static literal object4694                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4695                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4696                    }4697                }4698                else {4699                    // dynamic key binding, wrap with `normalizeProps`4700                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4701                }4702                break;4703            case 14 /* JS_CALL_EXPRESSION */:4704                // mergeProps call, do nothing4705                break;4706            default:4707                // single v-bind4708                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4709                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4710                        propsExpression4711                    ])4712                ]);4713                break;4714        }4715    }4716    return {4717        props: propsExpression,4718        directives: runtimeDirectives,4719        patchFlag,4720        dynamicPropNames,4721        shouldUseBlock4722    };4723}4724// Dedupe props in an object literal.4725// Literal duplicated attributes would have been warned during the parse phase,4726// however, it's possible to encounter duplicated `onXXX` handlers with different4727// modifiers. We also need to merge static and dynamic class / style attributes.4728// - onXXX handlers / style: merge into array4729// - class: merge into single expression with concatenation4730function dedupeProperties(properties) {4731    const knownProps = new Map();4732    const deduped = [];4733    for (let i = 0; i < properties.length; i++) {4734        const prop = properties[i];4735        // dynamic keys are always allowed4736        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4737            deduped.push(prop);4738            continue;4739        }4740        const name = prop.key.content;4741        const existing = knownProps.get(name);4742        if (existing) {4743            if (name === 'style' || name === 'class' || shared.isOn(name)) {4744                mergeAsArray(existing, prop);4745            }4746            // unexpected duplicate, should have emitted error during parse4747        }4748        else {4749            knownProps.set(name, prop);4750            deduped.push(prop);4751        }4752    }4753    return deduped;4754}4755function mergeAsArray(existing, incoming) {4756    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4757        existing.value.elements.push(incoming.value);4758    }4759    else {4760        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4761    }4762}4763function buildDirectiveArgs(dir, context) {4764    const dirArgs = [];4765    const runtime = directiveImportMap.get(dir);4766    if (runtime) {4767        // built-in directive with runtime4768        dirArgs.push(context.helperString(runtime));4769    }4770    else {4771        // user directive.4772        // see if we have directives exposed via <script setup>4773        const fromSetup = resolveSetupReference('v-' + dir.name, context);4774        if (fromSetup) {4775            dirArgs.push(fromSetup);4776        }4777        else {4778            // inject statement for resolving directive4779            context.helper(RESOLVE_DIRECTIVE);4780            context.directives.add(dir.name);4781            dirArgs.push(toValidAssetId(dir.name, `directive`));4782        }4783    }4784    const { loc } = dir;4785    if (dir.exp)4786        dirArgs.push(dir.exp);4787    if (dir.arg) {4788        if (!dir.exp) {4789            dirArgs.push(`void 0`);4790        }4791        dirArgs.push(dir.arg);4792    }4793    if (Object.keys(dir.modifiers).length) {4794        if (!dir.arg) {4795            if (!dir.exp) {4796                dirArgs.push(`void 0`);4797            }4798            dirArgs.push(`void 0`);4799        }4800        const trueExpression = createSimpleExpression(`true`, false, loc);4801        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4802    }4803    return createArrayExpression(dirArgs, dir.loc);4804}4805function stringifyDynamicPropNames(props) {4806    let propsNamesString = `[`;4807    for (let i = 0, l = props.length; i < l; i++) {4808        propsNamesString += JSON.stringify(props[i]);4809        if (i < l - 1)4810            propsNamesString += ', ';4811    }4812    return propsNamesString + `]`;4813}4814function isComponentTag(tag) {4815    return tag === 'component' || tag === 'Component';4816}4817const cacheStringFunction = (fn) => {4818    const cache = Object.create(null);4819    return ((str) => {4820        const hit = cache[str];4821        return hit || (cache[str] = fn(str));4822    });4823};4824const camelizeRE = /-(\w)/g;4825/**4826 * @private4827 */4828const camelize = cacheStringFunction((str) => {4829    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));4830});4831const transformSlotOutlet = (node, context) => {4832    if (isSlotOutlet(node)) {4833        const { children, loc } = node;4834        const { slotName, slotProps } = processSlotOutlet(node, context);4835        const slotArgs = [4836            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4837            slotName,4838            '{}',4839            'undefined',4840            'true'4841        ];4842        let expectedLen = 2;4843        if (slotProps) {4844            slotArgs[2] = slotProps;4845            expectedLen = 3;4846        }4847        if (children.length) {4848            slotArgs[3] = createFunctionExpression([], children, false, false, loc);4849            expectedLen = 4;4850        }4851        if (context.scopeId && !context.slotted) {4852            expectedLen = 5;4853        }4854        slotArgs.splice(expectedLen); // remove unused arguments4855        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4856    }4857};4858function processSlotOutlet(node, context) {4859    let slotName = `"default"`;4860    let slotProps = undefined;4861    const nonNameProps = [];4862    for (let i = 0; i < node.props.length; i++) {4863        const p = node.props[i];4864        if (p.type === 6 /* ATTRIBUTE */) {4865            if (p.value) {4866                if (p.name === 'name') {4867                    slotName = JSON.stringify(p.value.content);4868                }4869                else {4870                    p.name = camelize(p.name);4871                    nonNameProps.push(p);4872                }4873            }4874        }4875        else {4876            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {4877                if (p.exp)4878                    slotName = p.exp;4879            }4880            else {4881                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4882                    p.arg.content = camelize(p.arg.content);4883                }4884                nonNameProps.push(p);4885            }4886        }4887    }4888    if (nonNameProps.length > 0) {4889        const { props, directives } = buildProps(node, context, nonNameProps);4890        slotProps = props;4891        if (directives.length) {4892            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4893        }4894    }4895    return {4896        slotName,4897        slotProps4898    };4899}4900const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4901const transformOn = (dir, node, context, augmentor) => {4902    const { loc, modifiers, arg } = dir;4903    if (!dir.exp && !modifiers.length) {4904        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4905    }4906    let eventName;4907    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4908        if (arg.isStatic) {4909            let rawName = arg.content;4910            // TODO deprecate @vnodeXXX usage4911            if (rawName.startsWith('vue:')) {4912                rawName = `vnode-${rawName.slice(4)}`;4913            }4914            // for all event listeners, auto convert it to camelCase. See issue #22494915            eventName = createSimpleExpression(shared.toHandlerKey(shared.camelize(rawName)), true, arg.loc);4916        }4917        else {4918            // #23884919            eventName = createCompoundExpression([4920                `${context.helperString(TO_HANDLER_KEY)}(`,4921                arg,4922                `)`4923            ]);4924        }4925    }4926    else {4927        // already a compound expression.4928        eventName = arg;4929        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4930        eventName.children.push(`)`);4931    }4932    // handler processing4933    let exp = dir.exp;4934    if (exp && !exp.content.trim()) {4935        exp = undefined;4936    }4937    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4938    if (exp) {4939        const isMemberExp = isMemberExpression(exp.content, context);4940        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4941        const hasMultipleStatements = exp.content.includes(`;`);4942        // process the expression since it's been skipped4943        if (context.prefixIdentifiers) {4944            isInlineStatement && context.addIdentifiers(`$event`);4945            exp = dir.exp = processExpression(exp, context, false, hasMultipleStatements);4946            isInlineStatement && context.removeIdentifiers(`$event`);4947            // with scope analysis, the function is hoistable if it has no reference4948            // to scope variables.4949            shouldCache =4950                context.cacheHandlers &&4951                    // unnecessary to cache inside v-once4952                    !context.inVOnce &&4953                    // runtime constants don't need to be cached4954                    // (this is analyzed by compileScript in SFC <script setup>)4955                    !(exp.type === 4 /* SIMPLE_EXPRESSION */ && exp.constType > 0) &&4956                    // #1541 bail if this is a member exp handler passed to a component -4957                    // we need to use the original function to preserve arity,4958                    // e.g. <transition> relies on checking cb.length to determine4959                    // transition end handling. Inline function is ok since its arity4960                    // is preserved even when cached.4961                    !(isMemberExp && node.tagType === 1 /* COMPONENT */) &&4962                    // bail if the function references closure variables (v-for, v-slot)4963                    // it must be passed fresh to avoid stale values.4964                    !hasScopeRef(exp, context.identifiers);4965            // If the expression is optimizable and is a member expression pointing4966            // to a function, turn it into invocation (and wrap in an arrow function4967            // below) so that it always accesses the latest value when called - thus4968            // avoiding the need to be patched.4969            if (shouldCache && isMemberExp) {4970                if (exp.type === 4 /* SIMPLE_EXPRESSION */) {4971                    exp.content = `${exp.content} && ${exp.content}(...args)`;4972                }4973                else {4974                    exp.children = [...exp.children, ` && `, ...exp.children, `(...args)`];4975                }4976            }4977        }4978        if (isInlineStatement || (shouldCache && isMemberExp)) {4979            // wrap inline statement in a function expression4980            exp = createCompoundExpression([4981                `${isInlineStatement4982                    ? context.isTS4983                        ? `($event: any)`4984                        : `$event`4985                    : `${context.isTS ? `\n//@ts-ignore\n` : ``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4986                exp,4987                hasMultipleStatements ? `}` : `)`4988            ]);4989        }4990    }4991    let ret = {4992        props: [4993            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4994        ]4995    };4996    // apply extended compiler augmentor4997    if (augmentor) {4998        ret = augmentor(ret);4999    }5000    if (shouldCache) {5001        // cache handlers so that it's always the same handler being passed down.5002        // this avoids unnecessary re-renders when users use inline handlers on5003        // components.5004        ret.props[0].value = context.cache(ret.props[0].value);5005    }5006    // mark the key as handler for props normalization check5007    ret.props.forEach(p => (p.key.isHandlerKey = true));5008    return ret;5009};5010// v-bind without arg is handled directly in ./transformElements.ts due to it affecting5011// codegen for the entire props object. This transform here is only for v-bind5012// *with* args.5013const transformBind = (dir, _node, context) => {5014    const { exp, modifiers, loc } = dir;5015    const arg = dir.arg;5016    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {5017        arg.children.unshift(`(`);5018        arg.children.push(`) || ""`);5019    }5020    else if (!arg.isStatic) {5021        arg.content = `${arg.content} || ""`;5022    }5023    // .sync is replaced by v-model:arg5024    if (modifiers.includes('camel')) {5025        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5026            if (arg.isStatic) {5027                arg.content = shared.camelize(arg.content);5028            }5029            else {5030                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;5031            }5032        }5033        else {5034            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);5035            arg.children.push(`)`);5036        }5037    }5038    if (!context.inSSR) {5039        if (modifiers.includes('prop')) {5040            injectPrefix(arg, '.');5041        }5042        if (modifiers.includes('attr')) {5043            injectPrefix(arg, '^');5044        }5045    }5046    if (!exp ||5047        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {5048        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));5049        return {5050            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]5051        };5052    }5053    return {5054        props: [createObjectProperty(arg, exp)]5055    };5056};5057const injectPrefix = (arg, prefix) => {5058    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {5059        if (arg.isStatic) {5060            arg.content = prefix + arg.content;5061        }5062        else {5063            arg.content = `\`${prefix}\${${arg.content}}\``;5064        }5065    }5066    else {5067        arg.children.unshift(`'${prefix}' + (`);5068        arg.children.push(`)`);5069    }5070};5071// Merge adjacent text nodes and expressions into a single expression5072// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.5073const transformText = (node, context) => {5074    if (node.type === 0 /* ROOT */ ||5075        node.type === 1 /* ELEMENT */ ||5076        node.type === 11 /* FOR */ ||5077        node.type === 10 /* IF_BRANCH */) {5078        // perform the transform on node exit so that all expressions have already5079        // been processed.5080        return () => {5081            const children = node.children;5082            let currentContainer = undefined;5083            let hasText = false;5084            for (let i = 0; i < children.length; i++) {5085                const child = children[i];5086                if (isText(child)) {5087                    hasText = true;5088                    for (let j = i + 1; j < children.length; j++) {5089                        const next = children[j];5090                        if (isText(next)) {5091                            if (!currentContainer) {5092                                currentContainer = children[i] = {5093                                    type: 8 /* COMPOUND_EXPRESSION */,5094                                    loc: child.loc,5095                                    children: [child]5096                                };5097                            }5098                            // merge adjacent text node into current5099                            currentContainer.children.push(` + `, next);5100                            children.splice(j, 1);5101                            j--;5102                        }5103                        else {5104                            currentContainer = undefined;5105                            break;5106                        }5107                    }5108                }5109            }5110            if (!hasText ||5111                // if this is a plain element with a single text child, leave it5112                // as-is since the runtime has dedicated fast path for this by directly5113                // setting textContent of the element.5114                // for component root it's always normalized anyway.5115                (children.length === 1 &&5116                    (node.type === 0 /* ROOT */ ||5117                        (node.type === 1 /* ELEMENT */ &&5118                            node.tagType === 0 /* ELEMENT */ &&5119                            // #37565120                            // custom directives can potentially add DOM elements arbitrarily,5121                            // we need to avoid setting textContent of the element at runtime5122                            // to avoid accidentally overwriting the DOM elements added5123                            // by the user through custom directives.5124                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&5125                                !context.directiveTransforms[p.name]) &&5126                            // in compat mode, <template> tags with no special directives5127                            // will be rendered as a fragment so its children must be5128                            // converted into vnodes.5129                            !(node.tag === 'template'))))) {5130                return;5131            }5132            // pre-convert text nodes into createTextVNode(text) calls to avoid5133            // runtime normalization.5134            for (let i = 0; i < children.length; i++) {5135                const child = children[i];5136                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {5137                    const callArgs = [];5138                    // createTextVNode defaults to single whitespace, so if it is a5139                    // single space the code could be an empty call to save bytes.5140                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {5141                        callArgs.push(child);5142                    }5143                    // mark dynamic text with flag so it gets patched inside a block5144                    if (!context.ssr &&5145                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {5146                        callArgs.push(1 /* TEXT */ +5147                            (``));5148                    }5149                    children[i] = {5150                        type: 12 /* TEXT_CALL */,5151                        content: child,5152                        loc: child.loc,5153                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)5154                    };5155                }5156            }5157        };5158    }5159};5160const seen = new WeakSet();5161const transformOnce = (node, context) => {5162    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {5163        if (seen.has(node) || context.inVOnce) {5164            return;5165        }5166        seen.add(node);5167        context.inVOnce = true;5168        context.helper(SET_BLOCK_TRACKING);5169        return () => {5170            context.inVOnce = false;5171            const cur = context.currentNode;5172            if (cur.codegenNode) {5173                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);5174            }5175        };5176    }5177};5178const transformModel = (dir, node, context) => {5179    const { exp, arg } = dir;5180    if (!exp) {5181        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));5182        return createTransformProps();5183    }5184    const rawExp = exp.loc.source;5185    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;5186    // im SFC <script setup> inline mode, the exp may have been transformed into5187    // _unref(exp)5188    const bindingType = context.bindingMetadata[rawExp];5189    const maybeRef = context.inline &&5190        bindingType &&5191        bindingType !== "setup-const" /* SETUP_CONST */;5192    if (!expString.trim() ||5193        (!isMemberExpression(expString, context) && !maybeRef)) {5194        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));5195        return createTransformProps();5196    }5197    if (context.prefixIdentifiers &&5198        isSimpleIdentifier(expString) &&5199        context.identifiers[expString]) {5200        context.onError(createCompilerError(43 /* X_V_MODEL_ON_SCOPE_VARIABLE */, exp.loc));5201        return createTransformProps();5202    }5203    const propName = arg ? arg : createSimpleExpression('modelValue', true);5204    const eventName = arg5205        ? isStaticExp(arg)5206            ? `onUpdate:${arg.content}`5207            : createCompoundExpression(['"onUpdate:" + ', arg])5208        : `onUpdate:modelValue`;5209    let assignmentExp;5210    const eventArg = context.isTS ? `($event: any)` : `$event`;5211    if (maybeRef) {5212        if (bindingType === "setup-ref" /* SETUP_REF */) {5213            // v-model used on known ref.5214            assignmentExp = createCompoundExpression([5215                `${eventArg} => ((`,5216                createSimpleExpression(rawExp, false, exp.loc),5217                `).value = $event)`5218            ]);5219        }5220        else {5221            // v-model used on a potentially ref binding in <script setup> inline mode.5222            // the assignment needs to check whether the binding is actually a ref.5223            const altAssignment = bindingType === "setup-let" /* SETUP_LET */ ? `${rawExp} = $event` : `null`;5224            assignmentExp = createCompoundExpression([5225                `${eventArg} => (${context.helperString(IS_REF)}(${rawExp}) ? (`,5226                createSimpleExpression(rawExp, false, exp.loc),5227                `).value = $event : ${altAssignment})`5228            ]);5229        }5230    }5231    else {5232        assignmentExp = createCompoundExpression([5233            `${eventArg} => ((`,5234            exp,5235            `) = $event)`5236        ]);5237    }5238    const props = [5239        // modelValue: foo5240        createObjectProperty(propName, dir.exp),5241        // "onUpdate:modelValue": $event => (foo = $event)5242        createObjectProperty(eventName, assignmentExp)5243    ];5244    // cache v-model handler if applicable (when it doesn't refer any scope vars)5245    if (context.prefixIdentifiers &&5246        !context.inVOnce &&5247        context.cacheHandlers &&5248        !hasScopeRef(exp, context.identifiers)) {5249        props[1].value = context.cache(props[1].value);5250    }5251    // modelModifiers: { foo: true, "bar-baz": true }5252    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {5253        const modifiers = dir.modifiers5254            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)5255            .join(`, `);5256        const modifiersKey = arg5257            ? isStaticExp(arg)5258                ? `${arg.content}Modifiers`5259                : createCompoundExpression([arg, ' + "Modifiers"'])5260            : `modelModifiers`;5261        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));5262    }5263    return createTransformProps(props);5264};5265function createTransformProps(props = []) {5266    return { props };5267}5268const validDivisionCharRE = /[\w).+\-_$\]]/;5269const transformFilter = (node, context) => {5270    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {5271        return;5272    }5273    if (node.type === 5 /* INTERPOLATION */) {5274        // filter rewrite is applied before expression transform so only5275        // simple expressions are possible at this stage5276        rewriteFilter(node.content, context);5277    }5278    if (node.type === 1 /* ELEMENT */) {5279        node.props.forEach((prop) => {5280            if (prop.type === 7 /* DIRECTIVE */ &&5281                prop.name !== 'for' &&5282                prop.exp) {5283                rewriteFilter(prop.exp, context);5284            }...compiler-dom.esm-browser.js
Source:compiler-dom.esm-browser.js  
...939    else {940        return value;941    }942}943function isCompatEnabled(key, context) {944    const mode = getCompatValue('MODE', context);945    const value = getCompatValue(key, context);946    // in v3 mode, only enable if explicitly set to true947    // otherwise enable for any non-false value948    return mode === 3 ? value === true : value !== false;949}950function checkCompatEnabled(key, context, loc, ...args) {951    const enabled = isCompatEnabled(key, context);952    if (enabled) {953        warnDeprecation(key, context, loc, ...args);954    }955    return enabled;956}957function warnDeprecation(key, context, loc, ...args) {958    const val = getCompatValue(key, context);959    if (val === 'suppress-warning') {960        return;961    }962    const { message, link } = deprecationData[key];963    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;964    const err = new SyntaxError(msg);965    err.code = key;966    if (loc)967        err.loc = loc;968    context.onWarn(err);969}970// The default decoder only provides escapes for characters reserved as part of971// the template syntax, and is only used if the custom renderer did not provide972// a platform-specific decoder.973const decodeRE = /&(gt|lt|amp|apos|quot);/g;974const decodeMap = {975    gt: '>',976    lt: '<',977    amp: '&',978    apos: "'",979    quot: '"'980};981const defaultParserOptions = {982    delimiters: [`{{`, `}}`],983    getNamespace: () => 0 /* HTML */,984    getTextMode: () => 0 /* DATA */,985    isVoidTag: NO,986    isPreTag: NO,987    isCustomElement: NO,988    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),989    onError: defaultOnError,990    onWarn: defaultOnWarn,991    comments: true992};993function baseParse(content, options = {}) {994    const context = createParserContext(content, options);995    const start = getCursor(context);996    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));997}998function createParserContext(content, rawOptions) {999    const options = extend({}, defaultParserOptions);1000    let key;1001    for (key in rawOptions) {1002        // @ts-ignore1003        options[key] =1004            rawOptions[key] === undefined1005                ? defaultParserOptions[key]1006                : rawOptions[key];1007    }1008    return {1009        options,1010        column: 1,1011        line: 1,1012        offset: 0,1013        originalSource: content,1014        source: content,1015        inPre: false,1016        inVPre: false,1017        onWarn: options.onWarn1018    };1019}1020function parseChildren(context, mode, ancestors) {1021    const parent = last(ancestors);1022    const ns = parent ? parent.ns : 0 /* HTML */;1023    const nodes = [];1024    while (!isEnd(context, mode, ancestors)) {1025        const s = context.source;1026        let node = undefined;1027        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {1028            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {1029                // '{{'1030                node = parseInterpolation(context, mode);1031            }1032            else if (mode === 0 /* DATA */ && s[0] === '<') {1033                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state1034                if (s.length === 1) {1035                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);1036                }1037                else if (s[1] === '!') {1038                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state1039                    if (startsWith(s, '<!--')) {1040                        node = parseComment(context);1041                    }1042                    else if (startsWith(s, '<!DOCTYPE')) {1043                        // Ignore DOCTYPE by a limitation.1044                        node = parseBogusComment(context);1045                    }1046                    else if (startsWith(s, '<![CDATA[')) {1047                        if (ns !== 0 /* HTML */) {1048                            node = parseCDATA(context, ancestors);1049                        }1050                        else {1051                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);1052                            node = parseBogusComment(context);1053                        }1054                    }1055                    else {1056                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);1057                        node = parseBogusComment(context);1058                    }1059                }1060                else if (s[1] === '/') {1061                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state1062                    if (s.length === 2) {1063                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);1064                    }1065                    else if (s[2] === '>') {1066                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);1067                        advanceBy(context, 3);1068                        continue;1069                    }1070                    else if (/[a-z]/i.test(s[2])) {1071                        emitError(context, 23 /* X_INVALID_END_TAG */);1072                        parseTag(context, 1 /* End */, parent);1073                        continue;1074                    }1075                    else {1076                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);1077                        node = parseBogusComment(context);1078                    }1079                }1080                else if (/[a-z]/i.test(s[1])) {1081                    node = parseElement(context, ancestors);1082                    // 2.x <template> with no directive compat1083                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&1084                        node &&1085                        node.tag === 'template' &&1086                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&1087                            isSpecialTemplateDirective(p.name))) {1088                        warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);1089                        node = node.children;1090                    }1091                }1092                else if (s[1] === '?') {1093                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);1094                    node = parseBogusComment(context);1095                }1096                else {1097                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);1098                }1099            }1100        }1101        if (!node) {1102            node = parseText(context, mode);1103        }1104        if (isArray(node)) {1105            for (let i = 0; i < node.length; i++) {1106                pushNode(nodes, node[i]);1107            }1108        }1109        else {1110            pushNode(nodes, node);1111        }1112    }1113    // Whitespace handling strategy like v21114    let removedWhitespace = false;1115    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {1116        const shouldCondense = context.options.whitespace !== 'preserve';1117        for (let i = 0; i < nodes.length; i++) {1118            const node = nodes[i];1119            if (!context.inPre && node.type === 2 /* TEXT */) {1120                if (!/[^\t\r\n\f ]/.test(node.content)) {1121                    const prev = nodes[i - 1];1122                    const next = nodes[i + 1];1123                    // Remove if:1124                    // - the whitespace is the first or last node, or:1125                    // - (condense mode) the whitespace is adjacent to a comment, or:1126                    // - (condense mode) the whitespace is between two elements AND contains newline1127                    if (!prev ||1128                        !next ||1129                        (shouldCondense &&1130                            (prev.type === 3 /* COMMENT */ ||1131                                next.type === 3 /* COMMENT */ ||1132                                (prev.type === 1 /* ELEMENT */ &&1133                                    next.type === 1 /* ELEMENT */ &&1134                                    /[\r\n]/.test(node.content))))) {1135                        removedWhitespace = true;1136                        nodes[i] = null;1137                    }1138                    else {1139                        // Otherwise, the whitespace is condensed into a single space1140                        node.content = ' ';1141                    }1142                }1143                else if (shouldCondense) {1144                    // in condense mode, consecutive whitespaces in text are condensed1145                    // down to a single space.1146                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');1147                }1148            }1149            // Remove comment nodes if desired by configuration.1150            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {1151                removedWhitespace = true;1152                nodes[i] = null;1153            }1154        }1155        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {1156            // remove leading newline per html spec1157            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element1158            const first = nodes[0];1159            if (first && first.type === 2 /* TEXT */) {1160                first.content = first.content.replace(/^\r?\n/, '');1161            }1162        }1163    }1164    return removedWhitespace ? nodes.filter(Boolean) : nodes;1165}1166function pushNode(nodes, node) {1167    if (node.type === 2 /* TEXT */) {1168        const prev = last(nodes);1169        // Merge if both this and the previous node are text and those are1170        // consecutive. This happens for cases like "a < b".1171        if (prev &&1172            prev.type === 2 /* TEXT */ &&1173            prev.loc.end.offset === node.loc.start.offset) {1174            prev.content += node.content;1175            prev.loc.end = node.loc.end;1176            prev.loc.source += node.loc.source;1177            return;1178        }1179    }1180    nodes.push(node);1181}1182function parseCDATA(context, ancestors) {1183    advanceBy(context, 9);1184    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1185    if (context.source.length === 0) {1186        emitError(context, 6 /* EOF_IN_CDATA */);1187    }1188    else {1189        advanceBy(context, 3);1190    }1191    return nodes;1192}1193function parseComment(context) {1194    const start = getCursor(context);1195    let content;1196    // Regular comment.1197    const match = /--(\!)?>/.exec(context.source);1198    if (!match) {1199        content = context.source.slice(4);1200        advanceBy(context, context.source.length);1201        emitError(context, 7 /* EOF_IN_COMMENT */);1202    }1203    else {1204        if (match.index <= 3) {1205            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1206        }1207        if (match[1]) {1208            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1209        }1210        content = context.source.slice(4, match.index);1211        // Advancing with reporting nested comments.1212        const s = context.source.slice(0, match.index);1213        let prevIndex = 1, nestedIndex = 0;1214        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1215            advanceBy(context, nestedIndex - prevIndex + 1);1216            if (nestedIndex + 4 < s.length) {1217                emitError(context, 16 /* NESTED_COMMENT */);1218            }1219            prevIndex = nestedIndex + 1;1220        }1221        advanceBy(context, match.index + match[0].length - prevIndex + 1);1222    }1223    return {1224        type: 3 /* COMMENT */,1225        content,1226        loc: getSelection(context, start)1227    };1228}1229function parseBogusComment(context) {1230    const start = getCursor(context);1231    const contentStart = context.source[1] === '?' ? 1 : 2;1232    let content;1233    const closeIndex = context.source.indexOf('>');1234    if (closeIndex === -1) {1235        content = context.source.slice(contentStart);1236        advanceBy(context, context.source.length);1237    }1238    else {1239        content = context.source.slice(contentStart, closeIndex);1240        advanceBy(context, closeIndex + 1);1241    }1242    return {1243        type: 3 /* COMMENT */,1244        content,1245        loc: getSelection(context, start)1246    };1247}1248function parseElement(context, ancestors) {1249    // Start tag.1250    const wasInPre = context.inPre;1251    const wasInVPre = context.inVPre;1252    const parent = last(ancestors);1253    const element = parseTag(context, 0 /* Start */, parent);1254    const isPreBoundary = context.inPre && !wasInPre;1255    const isVPreBoundary = context.inVPre && !wasInVPre;1256    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1257        // #4030 self-closing <pre> tag1258        if (isPreBoundary) {1259            context.inPre = false;1260        }1261        if (isVPreBoundary) {1262            context.inVPre = false;1263        }1264        return element;1265    }1266    // Children.1267    ancestors.push(element);1268    const mode = context.options.getTextMode(element, parent);1269    const children = parseChildren(context, mode, ancestors);1270    ancestors.pop();1271    // 2.x inline-template compat1272    {1273        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1274        if (inlineTemplateProp &&1275            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1276            const loc = getSelection(context, element.loc.end);1277            inlineTemplateProp.value = {1278                type: 2 /* TEXT */,1279                content: loc.source,1280                loc1281            };1282        }1283    }1284    element.children = children;1285    // End tag.1286    if (startsWithEndTagOpen(context.source, element.tag)) {1287        parseTag(context, 1 /* End */, parent);1288    }1289    else {1290        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1291        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1292            const first = children[0];1293            if (first && startsWith(first.loc.source, '<!--')) {1294                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1295            }1296        }1297    }1298    element.loc = getSelection(context, element.loc.start);1299    if (isPreBoundary) {1300        context.inPre = false;1301    }1302    if (isVPreBoundary) {1303        context.inVPre = false;1304    }1305    return element;1306}1307const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1308function parseTag(context, type, parent) {1309    // Tag open.1310    const start = getCursor(context);1311    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1312    const tag = match[1];1313    const ns = context.options.getNamespace(tag, parent);1314    advanceBy(context, match[0].length);1315    advanceSpaces(context);1316    // save current state in case we need to re-parse attributes with v-pre1317    const cursor = getCursor(context);1318    const currentSource = context.source;1319    // check <pre> tag1320    if (context.options.isPreTag(tag)) {1321        context.inPre = true;1322    }1323    // Attributes.1324    let props = parseAttributes(context, type);1325    // check v-pre1326    if (type === 0 /* Start */ &&1327        !context.inVPre &&1328        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1329        context.inVPre = true;1330        // reset context1331        extend(context, cursor);1332        context.source = currentSource;1333        // re-parse attrs and filter out v-pre itself1334        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1335    }1336    // Tag close.1337    let isSelfClosing = false;1338    if (context.source.length === 0) {1339        emitError(context, 9 /* EOF_IN_TAG */);1340    }1341    else {1342        isSelfClosing = startsWith(context.source, '/>');1343        if (type === 1 /* End */ && isSelfClosing) {1344            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1345        }1346        advanceBy(context, isSelfClosing ? 2 : 1);1347    }1348    if (type === 1 /* End */) {1349        return;1350    }1351    // 2.x deprecation checks1352    if (isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1353        let hasIf = false;1354        let hasFor = false;1355        for (let i = 0; i < props.length; i++) {1356            const p = props[i];1357            if (p.type === 7 /* DIRECTIVE */) {1358                if (p.name === 'if') {1359                    hasIf = true;1360                }1361                else if (p.name === 'for') {1362                    hasFor = true;1363                }1364            }1365            if (hasIf && hasFor) {1366                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1367                break;1368            }1369        }1370    }1371    let tagType = 0 /* ELEMENT */;1372    if (!context.inVPre) {1373        if (tag === 'slot') {1374            tagType = 2 /* SLOT */;1375        }1376        else if (tag === 'template') {1377            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1378                tagType = 3 /* TEMPLATE */;1379            }1380        }1381        else if (isComponent(tag, props, context)) {1382            tagType = 1 /* COMPONENT */;1383        }1384    }1385    return {1386        type: 1 /* ELEMENT */,1387        ns,1388        tag,1389        tagType,1390        props,1391        isSelfClosing,1392        children: [],1393        loc: getSelection(context, start),1394        codegenNode: undefined // to be created during transform phase1395    };1396}1397function isComponent(tag, props, context) {1398    const options = context.options;1399    if (options.isCustomElement(tag)) {1400        return false;1401    }1402    if (tag === 'component' ||1403        /^[A-Z]/.test(tag) ||1404        isCoreComponent(tag) ||1405        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1406        (options.isNativeTag && !options.isNativeTag(tag))) {1407        return true;1408    }1409    // at this point the tag should be a native tag, but check for potential "is"1410    // casting1411    for (let i = 0; i < props.length; i++) {1412        const p = props[i];1413        if (p.type === 6 /* ATTRIBUTE */) {1414            if (p.name === 'is' && p.value) {1415                if (p.value.content.startsWith('vue:')) {1416                    return true;1417                }1418                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1419                    return true;1420                }1421            }1422        }1423        else {1424            // directive1425            // v-is (TODO Deprecate)1426            if (p.name === 'is') {1427                return true;1428            }1429            else if (1430            // :is on plain element - only treat as component in compat mode1431            p.name === 'bind' &&1432                isStaticArgOf(p.arg, 'is') &&1433                true &&1434                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1435                return true;1436            }1437        }1438    }1439}1440function parseAttributes(context, type) {1441    const props = [];1442    const attributeNames = new Set();1443    while (context.source.length > 0 &&1444        !startsWith(context.source, '>') &&1445        !startsWith(context.source, '/>')) {1446        if (startsWith(context.source, '/')) {1447            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1448            advanceBy(context, 1);1449            advanceSpaces(context);1450            continue;1451        }1452        if (type === 1 /* End */) {1453            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1454        }1455        const attr = parseAttribute(context, attributeNames);1456        // Trim whitespace between class1457        // https://github.com/vuejs/vue-next/issues/42511458        if (attr.type === 6 /* ATTRIBUTE */ &&1459            attr.value &&1460            attr.name === 'class') {1461            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1462        }1463        if (type === 0 /* Start */) {1464            props.push(attr);1465        }1466        if (/^[^\t\r\n\f />]/.test(context.source)) {1467            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1468        }1469        advanceSpaces(context);1470    }1471    return props;1472}1473function parseAttribute(context, nameSet) {1474    // Name.1475    const start = getCursor(context);1476    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1477    const name = match[0];1478    if (nameSet.has(name)) {1479        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1480    }1481    nameSet.add(name);1482    if (name[0] === '=') {1483        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1484    }1485    {1486        const pattern = /["'<]/g;1487        let m;1488        while ((m = pattern.exec(name))) {1489            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1490        }1491    }1492    advanceBy(context, name.length);1493    // Value1494    let value = undefined;1495    if (/^[\t\r\n\f ]*=/.test(context.source)) {1496        advanceSpaces(context);1497        advanceBy(context, 1);1498        advanceSpaces(context);1499        value = parseAttributeValue(context);1500        if (!value) {1501            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1502        }1503    }1504    const loc = getSelection(context, start);1505    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1506        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1507        let isPropShorthand = startsWith(name, '.');1508        let dirName = match[1] ||1509            (isPropShorthand || startsWith(name, ':')1510                ? 'bind'1511                : startsWith(name, '@')1512                    ? 'on'1513                    : 'slot');1514        let arg;1515        if (match[2]) {1516            const isSlot = dirName === 'slot';1517            const startOffset = name.lastIndexOf(match[2]);1518            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1519            let content = match[2];1520            let isStatic = true;1521            if (content.startsWith('[')) {1522                isStatic = false;1523                if (!content.endsWith(']')) {1524                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1525                    content = content.slice(1);1526                }1527                else {1528                    content = content.slice(1, content.length - 1);1529                }1530            }1531            else if (isSlot) {1532                // #1241 special case for v-slot: vuetify relies extensively on slot1533                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1534                // supports such usage so we are keeping it consistent with 2.x.1535                content += match[3] || '';1536            }1537            arg = {1538                type: 4 /* SIMPLE_EXPRESSION */,1539                content,1540                isStatic,1541                constType: isStatic1542                    ? 3 /* CAN_STRINGIFY */1543                    : 0 /* NOT_CONSTANT */,1544                loc1545            };1546        }1547        if (value && value.isQuoted) {1548            const valueLoc = value.loc;1549            valueLoc.start.offset++;1550            valueLoc.start.column++;1551            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1552            valueLoc.source = valueLoc.source.slice(1, -1);1553        }1554        const modifiers = match[3] ? match[3].slice(1).split('.') : [];1555        if (isPropShorthand)1556            modifiers.push('prop');1557        // 2.x compat v-bind:foo.sync -> v-model:foo1558        if (dirName === 'bind' && arg) {1559            if (modifiers.includes('sync') &&1560                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1561                dirName = 'model';1562                modifiers.splice(modifiers.indexOf('sync'), 1);1563            }1564            if (modifiers.includes('prop')) {1565                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1566            }1567        }1568        return {1569            type: 7 /* DIRECTIVE */,1570            name: dirName,1571            exp: value && {1572                type: 4 /* SIMPLE_EXPRESSION */,1573                content: value.content,1574                isStatic: false,1575                // Treat as non-constant by default. This can be potentially set to1576                // other values by `transformExpression` to make it eligible for hoisting.1577                constType: 0 /* NOT_CONSTANT */,1578                loc: value.loc1579            },1580            arg,1581            modifiers,1582            loc1583        };1584    }1585    // missing directive name or illegal directive name1586    if (!context.inVPre && startsWith(name, 'v-')) {1587        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1588    }1589    return {1590        type: 6 /* ATTRIBUTE */,1591        name,1592        value: value && {1593            type: 2 /* TEXT */,1594            content: value.content,1595            loc: value.loc1596        },1597        loc1598    };1599}1600function parseAttributeValue(context) {1601    const start = getCursor(context);1602    let content;1603    const quote = context.source[0];1604    const isQuoted = quote === `"` || quote === `'`;1605    if (isQuoted) {1606        // Quoted value.1607        advanceBy(context, 1);1608        const endIndex = context.source.indexOf(quote);1609        if (endIndex === -1) {1610            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1611        }1612        else {1613            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1614            advanceBy(context, 1);1615        }1616    }1617    else {1618        // Unquoted1619        const match = /^[^\t\r\n\f >]+/.exec(context.source);1620        if (!match) {1621            return undefined;1622        }1623        const unexpectedChars = /["'<=`]/g;1624        let m;1625        while ((m = unexpectedChars.exec(match[0]))) {1626            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1627        }1628        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1629    }1630    return { content, isQuoted, loc: getSelection(context, start) };1631}1632function parseInterpolation(context, mode) {1633    const [open, close] = context.options.delimiters;1634    const closeIndex = context.source.indexOf(close, open.length);1635    if (closeIndex === -1) {1636        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1637        return undefined;1638    }1639    const start = getCursor(context);1640    advanceBy(context, open.length);1641    const innerStart = getCursor(context);1642    const innerEnd = getCursor(context);1643    const rawContentLength = closeIndex - open.length;1644    const rawContent = context.source.slice(0, rawContentLength);1645    const preTrimContent = parseTextData(context, rawContentLength, mode);1646    const content = preTrimContent.trim();1647    const startOffset = preTrimContent.indexOf(content);1648    if (startOffset > 0) {1649        advancePositionWithMutation(innerStart, rawContent, startOffset);1650    }1651    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1652    advancePositionWithMutation(innerEnd, rawContent, endOffset);1653    advanceBy(context, close.length);1654    return {1655        type: 5 /* INTERPOLATION */,1656        content: {1657            type: 4 /* SIMPLE_EXPRESSION */,1658            isStatic: false,1659            // Set `isConstant` to false by default and will decide in transformExpression1660            constType: 0 /* NOT_CONSTANT */,1661            content,1662            loc: getSelection(context, innerStart, innerEnd)1663        },1664        loc: getSelection(context, start)1665    };1666}1667function parseText(context, mode) {1668    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1669    let endIndex = context.source.length;1670    for (let i = 0; i < endTokens.length; i++) {1671        const index = context.source.indexOf(endTokens[i], 1);1672        if (index !== -1 && endIndex > index) {1673            endIndex = index;1674        }1675    }1676    const start = getCursor(context);1677    const content = parseTextData(context, endIndex, mode);1678    return {1679        type: 2 /* TEXT */,1680        content,1681        loc: getSelection(context, start)1682    };1683}1684/**1685 * Get text data with a given length from the current location.1686 * This translates HTML entities in the text data.1687 */1688function parseTextData(context, length, mode) {1689    const rawText = context.source.slice(0, length);1690    advanceBy(context, length);1691    if (mode === 2 /* RAWTEXT */ ||1692        mode === 3 /* CDATA */ ||1693        rawText.indexOf('&') === -1) {1694        return rawText;1695    }1696    else {1697        // DATA or RCDATA containing "&"". Entity decoding required.1698        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1699    }1700}1701function getCursor(context) {1702    const { column, line, offset } = context;1703    return { column, line, offset };1704}1705function getSelection(context, start, end) {1706    end = end || getCursor(context);1707    return {1708        start,1709        end,1710        source: context.originalSource.slice(start.offset, end.offset)1711    };1712}1713function last(xs) {1714    return xs[xs.length - 1];1715}1716function startsWith(source, searchString) {1717    return source.startsWith(searchString);1718}1719function advanceBy(context, numberOfCharacters) {1720    const { source } = context;1721    advancePositionWithMutation(context, source, numberOfCharacters);1722    context.source = source.slice(numberOfCharacters);1723}1724function advanceSpaces(context) {1725    const match = /^[\t\r\n\f ]+/.exec(context.source);1726    if (match) {1727        advanceBy(context, match[0].length);1728    }1729}1730function getNewPosition(context, start, numberOfCharacters) {1731    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1732}1733function emitError(context, code, offset, loc = getCursor(context)) {1734    if (offset) {1735        loc.offset += offset;1736        loc.column += offset;1737    }1738    context.options.onError(createCompilerError(code, {1739        start: loc,1740        end: loc,1741        source: ''1742    }));1743}1744function isEnd(context, mode, ancestors) {1745    const s = context.source;1746    switch (mode) {1747        case 0 /* DATA */:1748            if (startsWith(s, '</')) {1749                // TODO: probably bad performance1750                for (let i = ancestors.length - 1; i >= 0; --i) {1751                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {1752                        return true;1753                    }1754                }1755            }1756            break;1757        case 1 /* RCDATA */:1758        case 2 /* RAWTEXT */: {1759            const parent = last(ancestors);1760            if (parent && startsWithEndTagOpen(s, parent.tag)) {1761                return true;1762            }1763            break;1764        }1765        case 3 /* CDATA */:1766            if (startsWith(s, ']]>')) {1767                return true;1768            }1769            break;1770    }1771    return !s;1772}1773function startsWithEndTagOpen(source, tag) {1774    return (startsWith(source, '</') &&1775        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1776        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1777}1778function hoistStatic(root, context) {1779    walk(root, context, 1780    // Root node is unfortunately non-hoistable due to potential parent1781    // fallthrough attributes.1782    isSingleElementRoot(root, root.children[0]));1783}1784function isSingleElementRoot(root, child) {1785    const { children } = root;1786    return (children.length === 1 &&1787        child.type === 1 /* ELEMENT */ &&1788        !isSlotOutlet(child));1789}1790function walk(node, context, doNotHoistNode = false) {1791    const { children } = node;1792    const originalCount = children.length;1793    let hoistedCount = 0;1794    for (let i = 0; i < children.length; i++) {1795        const child = children[i];1796        // only plain elements & text calls are eligible for hoisting.1797        if (child.type === 1 /* ELEMENT */ &&1798            child.tagType === 0 /* ELEMENT */) {1799            const constantType = doNotHoistNode1800                ? 0 /* NOT_CONSTANT */1801                : getConstantType(child, context);1802            if (constantType > 0 /* NOT_CONSTANT */) {1803                if (constantType >= 2 /* CAN_HOIST */) {1804                    child.codegenNode.patchFlag =1805                        -1 /* HOISTED */ + (` /* HOISTED */` );1806                    child.codegenNode = context.hoist(child.codegenNode);1807                    hoistedCount++;1808                    continue;1809                }1810            }1811            else {1812                // node may contain dynamic children, but its props may be eligible for1813                // hoisting.1814                const codegenNode = child.codegenNode;1815                if (codegenNode.type === 13 /* VNODE_CALL */) {1816                    const flag = getPatchFlag(codegenNode);1817                    if ((!flag ||1818                        flag === 512 /* NEED_PATCH */ ||1819                        flag === 1 /* TEXT */) &&1820                        getGeneratedPropsConstantType(child, context) >=1821                            2 /* CAN_HOIST */) {1822                        const props = getNodeProps(child);1823                        if (props) {1824                            codegenNode.props = context.hoist(props);1825                        }1826                    }1827                    if (codegenNode.dynamicProps) {1828                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1829                    }1830                }1831            }1832        }1833        else if (child.type === 12 /* TEXT_CALL */ &&1834            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {1835            child.codegenNode = context.hoist(child.codegenNode);1836            hoistedCount++;1837        }1838        // walk further1839        if (child.type === 1 /* ELEMENT */) {1840            const isComponent = child.tagType === 1 /* COMPONENT */;1841            if (isComponent) {1842                context.scopes.vSlot++;1843            }1844            walk(child, context);1845            if (isComponent) {1846                context.scopes.vSlot--;1847            }1848        }1849        else if (child.type === 11 /* FOR */) {1850            // Do not hoist v-for single child because it has to be a block1851            walk(child, context, child.children.length === 1);1852        }1853        else if (child.type === 9 /* IF */) {1854            for (let i = 0; i < child.branches.length; i++) {1855                // Do not hoist v-if single child because it has to be a block1856                walk(child.branches[i], context, child.branches[i].children.length === 1);1857            }1858        }1859    }1860    if (hoistedCount && context.transformHoist) {1861        context.transformHoist(children, context, node);1862    }1863    // all children were hoisted - the entire children array is hoistable.1864    if (hoistedCount &&1865        hoistedCount === originalCount &&1866        node.type === 1 /* ELEMENT */ &&1867        node.tagType === 0 /* ELEMENT */ &&1868        node.codegenNode &&1869        node.codegenNode.type === 13 /* VNODE_CALL */ &&1870        isArray(node.codegenNode.children)) {1871        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1872    }1873}1874function getConstantType(node, context) {1875    const { constantCache } = context;1876    switch (node.type) {1877        case 1 /* ELEMENT */:1878            if (node.tagType !== 0 /* ELEMENT */) {1879                return 0 /* NOT_CONSTANT */;1880            }1881            const cached = constantCache.get(node);1882            if (cached !== undefined) {1883                return cached;1884            }1885            const codegenNode = node.codegenNode;1886            if (codegenNode.type !== 13 /* VNODE_CALL */) {1887                return 0 /* NOT_CONSTANT */;1888            }1889            if (codegenNode.isBlock &&1890                node.tag !== 'svg' &&1891                node.tag !== 'foreignObject') {1892                return 0 /* NOT_CONSTANT */;1893            }1894            const flag = getPatchFlag(codegenNode);1895            if (!flag) {1896                let returnType = 3 /* CAN_STRINGIFY */;1897                // Element itself has no patch flag. However we still need to check:1898                // 1. Even for a node with no patch flag, it is possible for it to contain1899                // non-hoistable expressions that refers to scope variables, e.g. compiler1900                // injected keys or cached event handlers. Therefore we need to always1901                // check the codegenNode's props to be sure.1902                const generatedPropsType = getGeneratedPropsConstantType(node, context);1903                if (generatedPropsType === 0 /* NOT_CONSTANT */) {1904                    constantCache.set(node, 0 /* NOT_CONSTANT */);1905                    return 0 /* NOT_CONSTANT */;1906                }1907                if (generatedPropsType < returnType) {1908                    returnType = generatedPropsType;1909                }1910                // 2. its children.1911                for (let i = 0; i < node.children.length; i++) {1912                    const childType = getConstantType(node.children[i], context);1913                    if (childType === 0 /* NOT_CONSTANT */) {1914                        constantCache.set(node, 0 /* NOT_CONSTANT */);1915                        return 0 /* NOT_CONSTANT */;1916                    }1917                    if (childType < returnType) {1918                        returnType = childType;1919                    }1920                }1921                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01922                // type, check if any of the props can cause the type to be lowered1923                // we can skip can_patch because it's guaranteed by the absence of a1924                // patchFlag.1925                if (returnType > 1 /* CAN_SKIP_PATCH */) {1926                    for (let i = 0; i < node.props.length; i++) {1927                        const p = node.props[i];1928                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1929                            const expType = getConstantType(p.exp, context);1930                            if (expType === 0 /* NOT_CONSTANT */) {1931                                constantCache.set(node, 0 /* NOT_CONSTANT */);1932                                return 0 /* NOT_CONSTANT */;1933                            }1934                            if (expType < returnType) {1935                                returnType = expType;1936                            }1937                        }1938                    }1939                }1940                // only svg/foreignObject could be block here, however if they are1941                // static then they don't need to be blocks since there will be no1942                // nested updates.1943                if (codegenNode.isBlock) {1944                    context.removeHelper(OPEN_BLOCK);1945                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1946                    codegenNode.isBlock = false;1947                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1948                }1949                constantCache.set(node, returnType);1950                return returnType;1951            }1952            else {1953                constantCache.set(node, 0 /* NOT_CONSTANT */);1954                return 0 /* NOT_CONSTANT */;1955            }1956        case 2 /* TEXT */:1957        case 3 /* COMMENT */:1958            return 3 /* CAN_STRINGIFY */;1959        case 9 /* IF */:1960        case 11 /* FOR */:1961        case 10 /* IF_BRANCH */:1962            return 0 /* NOT_CONSTANT */;1963        case 5 /* INTERPOLATION */:1964        case 12 /* TEXT_CALL */:1965            return getConstantType(node.content, context);1966        case 4 /* SIMPLE_EXPRESSION */:1967            return node.constType;1968        case 8 /* COMPOUND_EXPRESSION */:1969            let returnType = 3 /* CAN_STRINGIFY */;1970            for (let i = 0; i < node.children.length; i++) {1971                const child = node.children[i];1972                if (isString(child) || isSymbol(child)) {1973                    continue;1974                }1975                const childType = getConstantType(child, context);1976                if (childType === 0 /* NOT_CONSTANT */) {1977                    return 0 /* NOT_CONSTANT */;1978                }1979                else if (childType < returnType) {1980                    returnType = childType;1981                }1982            }1983            return returnType;1984        default:1985            return 0 /* NOT_CONSTANT */;1986    }1987}1988const allowHoistedHelperSet = new Set([1989    NORMALIZE_CLASS,1990    NORMALIZE_STYLE,1991    NORMALIZE_PROPS,1992    GUARD_REACTIVE_PROPS1993]);1994function getConstantTypeOfHelperCall(value, context) {1995    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1996        !isString(value.callee) &&1997        allowHoistedHelperSet.has(value.callee)) {1998        const arg = value.arguments[0];1999        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {2000            return getConstantType(arg, context);2001        }2002        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {2003            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`2004            return getConstantTypeOfHelperCall(arg, context);2005        }2006    }2007    return 0 /* NOT_CONSTANT */;2008}2009function getGeneratedPropsConstantType(node, context) {2010    let returnType = 3 /* CAN_STRINGIFY */;2011    const props = getNodeProps(node);2012    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {2013        const { properties } = props;2014        for (let i = 0; i < properties.length; i++) {2015            const { key, value } = properties[i];2016            const keyType = getConstantType(key, context);2017            if (keyType === 0 /* NOT_CONSTANT */) {2018                return keyType;2019            }2020            if (keyType < returnType) {2021                returnType = keyType;2022            }2023            let valueType;2024            if (value.type === 4 /* SIMPLE_EXPRESSION */) {2025                valueType = getConstantType(value, context);2026            }2027            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {2028                // some helper calls can be hoisted,2029                // such as the `normalizeProps` generated by the compiler for pre-normalize class,2030                // in this case we need to respect the ConstantType of the helper's arguments2031                valueType = getConstantTypeOfHelperCall(value, context);2032            }2033            else {2034                valueType = 0 /* NOT_CONSTANT */;2035            }2036            if (valueType === 0 /* NOT_CONSTANT */) {2037                return valueType;2038            }2039            if (valueType < returnType) {2040                returnType = valueType;2041            }2042        }2043    }2044    return returnType;2045}2046function getNodeProps(node) {2047    const codegenNode = node.codegenNode;2048    if (codegenNode.type === 13 /* VNODE_CALL */) {2049        return codegenNode.props;2050    }2051}2052function getPatchFlag(node) {2053    const flag = node.patchFlag;2054    return flag ? parseInt(flag, 10) : undefined;2055}2056function 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 }) {2057    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);2058    const context = {2059        // options2060        selfName: nameMatch && capitalize(camelize(nameMatch[1])),2061        prefixIdentifiers,2062        hoistStatic,2063        cacheHandlers,2064        nodeTransforms,2065        directiveTransforms,2066        transformHoist,2067        isBuiltInComponent,2068        isCustomElement,2069        expressionPlugins,2070        scopeId,2071        slotted,2072        ssr,2073        inSSR,2074        ssrCssVars,2075        bindingMetadata,2076        inline,2077        isTS,2078        onError,2079        onWarn,2080        compatConfig,2081        // state2082        root,2083        helpers: new Map(),2084        components: new Set(),2085        directives: new Set(),2086        hoists: [],2087        imports: [],2088        constantCache: new Map(),2089        temps: 0,2090        cached: 0,2091        identifiers: Object.create(null),2092        scopes: {2093            vFor: 0,2094            vSlot: 0,2095            vPre: 0,2096            vOnce: 02097        },2098        parent: null,2099        currentNode: root,2100        childIndex: 0,2101        inVOnce: false,2102        // methods2103        helper(name) {2104            const count = context.helpers.get(name) || 0;2105            context.helpers.set(name, count + 1);2106            return name;2107        },2108        removeHelper(name) {2109            const count = context.helpers.get(name);2110            if (count) {2111                const currentCount = count - 1;2112                if (!currentCount) {2113                    context.helpers.delete(name);2114                }2115                else {2116                    context.helpers.set(name, currentCount);2117                }2118            }2119        },2120        helperString(name) {2121            return `_${helperNameMap[context.helper(name)]}`;2122        },2123        replaceNode(node) {2124            /* istanbul ignore if */2125            {2126                if (!context.currentNode) {2127                    throw new Error(`Node being replaced is already removed.`);2128                }2129                if (!context.parent) {2130                    throw new Error(`Cannot replace root node.`);2131                }2132            }2133            context.parent.children[context.childIndex] = context.currentNode = node;2134        },2135        removeNode(node) {2136            if (!context.parent) {2137                throw new Error(`Cannot remove root node.`);2138            }2139            const list = context.parent.children;2140            const removalIndex = node2141                ? list.indexOf(node)2142                : context.currentNode2143                    ? context.childIndex2144                    : -1;2145            /* istanbul ignore if */2146            if (removalIndex < 0) {2147                throw new Error(`node being removed is not a child of current parent`);2148            }2149            if (!node || node === context.currentNode) {2150                // current node removed2151                context.currentNode = null;2152                context.onNodeRemoved();2153            }2154            else {2155                // sibling node removed2156                if (context.childIndex > removalIndex) {2157                    context.childIndex--;2158                    context.onNodeRemoved();2159                }2160            }2161            context.parent.children.splice(removalIndex, 1);2162        },2163        onNodeRemoved: () => { },2164        addIdentifiers(exp) {2165        },2166        removeIdentifiers(exp) {2167        },2168        hoist(exp) {2169            if (isString(exp))2170                exp = createSimpleExpression(exp);2171            context.hoists.push(exp);2172            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2173            identifier.hoisted = exp;2174            return identifier;2175        },2176        cache(exp, isVNode = false) {2177            return createCacheExpression(context.cached++, exp, isVNode);2178        }2179    };2180    {2181        context.filters = new Set();2182    }2183    return context;2184}2185function transform(root, options) {2186    const context = createTransformContext(root, options);2187    traverseNode(root, context);2188    if (options.hoistStatic) {2189        hoistStatic(root, context);2190    }2191    if (!options.ssr) {2192        createRootCodegen(root, context);2193    }2194    // finalize meta information2195    root.helpers = [...context.helpers.keys()];2196    root.components = [...context.components];2197    root.directives = [...context.directives];2198    root.imports = context.imports;2199    root.hoists = context.hoists;2200    root.temps = context.temps;2201    root.cached = context.cached;2202    {2203        root.filters = [...context.filters];2204    }2205}2206function createRootCodegen(root, context) {2207    const { helper } = context;2208    const { children } = root;2209    if (children.length === 1) {2210        const child = children[0];2211        // if the single child is an element, turn it into a block.2212        if (isSingleElementRoot(root, child) && child.codegenNode) {2213            // single element root is never hoisted so codegenNode will never be2214            // SimpleExpressionNode2215            const codegenNode = child.codegenNode;2216            if (codegenNode.type === 13 /* VNODE_CALL */) {2217                makeBlock(codegenNode, context);2218            }2219            root.codegenNode = codegenNode;2220        }2221        else {2222            // - single <slot/>, IfNode, ForNode: already blocks.2223            // - single text node: always patched.2224            // root codegen falls through via genNode()2225            root.codegenNode = child;2226        }2227    }2228    else if (children.length > 1) {2229        // root has multiple nodes - return a fragment block.2230        let patchFlag = 64 /* STABLE_FRAGMENT */;2231        let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2232        // check if the fragment actually contains a single valid child with2233        // the rest being comments2234        if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2235            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2236            patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2237        }2238        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);2239    }2240    else ;2241}2242function traverseChildren(parent, context) {2243    let i = 0;2244    const nodeRemoved = () => {2245        i--;2246    };2247    for (; i < parent.children.length; i++) {2248        const child = parent.children[i];2249        if (isString(child))2250            continue;2251        context.parent = parent;2252        context.childIndex = i;2253        context.onNodeRemoved = nodeRemoved;2254        traverseNode(child, context);2255    }2256}2257function traverseNode(node, context) {2258    context.currentNode = node;2259    // apply transform plugins2260    const { nodeTransforms } = context;2261    const exitFns = [];2262    for (let i = 0; i < nodeTransforms.length; i++) {2263        const onExit = nodeTransforms[i](node, context);2264        if (onExit) {2265            if (isArray(onExit)) {2266                exitFns.push(...onExit);2267            }2268            else {2269                exitFns.push(onExit);2270            }2271        }2272        if (!context.currentNode) {2273            // node was removed2274            return;2275        }2276        else {2277            // node may have been replaced2278            node = context.currentNode;2279        }2280    }2281    switch (node.type) {2282        case 3 /* COMMENT */:2283            if (!context.ssr) {2284                // inject import for the Comment symbol, which is needed for creating2285                // comment nodes with `createVNode`2286                context.helper(CREATE_COMMENT);2287            }2288            break;2289        case 5 /* INTERPOLATION */:2290            // no need to traverse, but we need to inject toString helper2291            if (!context.ssr) {2292                context.helper(TO_DISPLAY_STRING);2293            }2294            break;2295        // for container types, further traverse downwards2296        case 9 /* IF */:2297            for (let i = 0; i < node.branches.length; i++) {2298                traverseNode(node.branches[i], context);2299            }2300            break;2301        case 10 /* IF_BRANCH */:2302        case 11 /* FOR */:2303        case 1 /* ELEMENT */:2304        case 0 /* ROOT */:2305            traverseChildren(node, context);2306            break;2307    }2308    // exit transforms2309    context.currentNode = node;2310    let i = exitFns.length;2311    while (i--) {2312        exitFns[i]();2313    }2314}2315function createStructuralDirectiveTransform(name, fn) {2316    const matches = isString(name)2317        ? (n) => n === name2318        : (n) => name.test(n);2319    return (node, context) => {2320        if (node.type === 1 /* ELEMENT */) {2321            const { props } = node;2322            // structural directive transforms are not concerned with slots2323            // as they are handled separately in vSlot.ts2324            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2325                return;2326            }2327            const exitFns = [];2328            for (let i = 0; i < props.length; i++) {2329                const prop = props[i];2330                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2331                    // structural directives are removed to avoid infinite recursion2332                    // also we remove them *before* applying so that it can further2333                    // traverse itself in case it moves the node around2334                    props.splice(i, 1);2335                    i--;2336                    const onExit = fn(node, prop, context);2337                    if (onExit)2338                        exitFns.push(onExit);2339                }2340            }2341            return exitFns;2342        }2343    };2344}2345const PURE_ANNOTATION = `/*#__PURE__*/`;2346function 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 }) {2347    const context = {2348        mode,2349        prefixIdentifiers,2350        sourceMap,2351        filename,2352        scopeId,2353        optimizeImports,2354        runtimeGlobalName,2355        runtimeModuleName,2356        ssrRuntimeModuleName,2357        ssr,2358        isTS,2359        inSSR,2360        source: ast.loc.source,2361        code: ``,2362        column: 1,2363        line: 1,2364        offset: 0,2365        indentLevel: 0,2366        pure: false,2367        map: undefined,2368        helper(key) {2369            return `_${helperNameMap[key]}`;2370        },2371        push(code, node) {2372            context.code += code;2373        },2374        indent() {2375            newline(++context.indentLevel);2376        },2377        deindent(withoutNewLine = false) {2378            if (withoutNewLine) {2379                --context.indentLevel;2380            }2381            else {2382                newline(--context.indentLevel);2383            }2384        },2385        newline() {2386            newline(context.indentLevel);2387        }2388    };2389    function newline(n) {2390        context.push('\n' + `  `.repeat(n));2391    }2392    return context;2393}2394function generate(ast, options = {}) {2395    const context = createCodegenContext(ast, options);2396    if (options.onContextCreated)2397        options.onContextCreated(context);2398    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2399    const hasHelpers = ast.helpers.length > 0;2400    const useWithBlock = !prefixIdentifiers && mode !== 'module';2401    // preambles2402    // in setup() inline mode, the preamble is generated in a sub context2403    // and returned separately.2404    const preambleContext = context;2405    {2406        genFunctionPreamble(ast, preambleContext);2407    }2408    // enter render function2409    const functionName = ssr ? `ssrRender` : `render`;2410    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2411    const signature = args.join(', ');2412    {2413        push(`function ${functionName}(${signature}) {`);2414    }2415    indent();2416    if (useWithBlock) {2417        push(`with (_ctx) {`);2418        indent();2419        // function mode const declarations should be inside with block2420        // also they should be renamed to avoid collision with user properties2421        if (hasHelpers) {2422            push(`const { ${ast.helpers2423                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2424                .join(', ')} } = _Vue`);2425            push(`\n`);2426            newline();2427        }2428    }2429    // generate asset resolution statements2430    if (ast.components.length) {2431        genAssets(ast.components, 'component', context);2432        if (ast.directives.length || ast.temps > 0) {2433            newline();2434        }2435    }2436    if (ast.directives.length) {2437        genAssets(ast.directives, 'directive', context);2438        if (ast.temps > 0) {2439            newline();2440        }2441    }2442    if (ast.filters && ast.filters.length) {2443        newline();2444        genAssets(ast.filters, 'filter', context);2445        newline();2446    }2447    if (ast.temps > 0) {2448        push(`let `);2449        for (let i = 0; i < ast.temps; i++) {2450            push(`${i > 0 ? `, ` : ``}_temp${i}`);2451        }2452    }2453    if (ast.components.length || ast.directives.length || ast.temps) {2454        push(`\n`);2455        newline();2456    }2457    // generate the VNode tree expression2458    if (!ssr) {2459        push(`return `);2460    }2461    if (ast.codegenNode) {2462        genNode(ast.codegenNode, context);2463    }2464    else {2465        push(`null`);2466    }2467    if (useWithBlock) {2468        deindent();2469        push(`}`);2470    }2471    deindent();2472    push(`}`);2473    return {2474        ast,2475        code: context.code,2476        preamble: ``,2477        // SourceMapGenerator does have toJSON() method but it's not in the types2478        map: context.map ? context.map.toJSON() : undefined2479    };2480}2481function genFunctionPreamble(ast, context) {2482    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2483    const VueBinding = runtimeGlobalName;2484    const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2485    // Generate const declaration for helpers2486    // In prefix mode, we place the const declaration at top so it's done2487    // only once; But if we not prefixing, we place the declaration inside the2488    // with block so it doesn't incur the `in` check cost for every helper access.2489    if (ast.helpers.length > 0) {2490        {2491            // "with" mode.2492            // save Vue in a separate variable to avoid collision2493            push(`const _Vue = ${VueBinding}\n`);2494            // in "with" mode, helpers are declared inside the with block to avoid2495            // has check cost, but hoists are lifted out of the function - we need2496            // to provide the helper here.2497            if (ast.hoists.length) {2498                const staticHelpers = [2499                    CREATE_VNODE,2500                    CREATE_ELEMENT_VNODE,2501                    CREATE_COMMENT,2502                    CREATE_TEXT,2503                    CREATE_STATIC2504                ]2505                    .filter(helper => ast.helpers.includes(helper))2506                    .map(aliasHelper)2507                    .join(', ');2508                push(`const { ${staticHelpers} } = _Vue\n`);2509            }2510        }2511    }2512    genHoists(ast.hoists, context);2513    newline();2514    push(`return `);2515}2516function genAssets(assets, type, { helper, push, newline, isTS }) {2517    const resolver = helper(type === 'filter'2518        ? RESOLVE_FILTER2519        : type === 'component'2520            ? RESOLVE_COMPONENT2521            : RESOLVE_DIRECTIVE);2522    for (let i = 0; i < assets.length; i++) {2523        let id = assets[i];2524        // potential component implicit self-reference inferred from SFC filename2525        const maybeSelfReference = id.endsWith('__self');2526        if (maybeSelfReference) {2527            id = id.slice(0, -6);2528        }2529        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2530        if (i < assets.length - 1) {2531            newline();2532        }2533    }2534}2535function genHoists(hoists, context) {2536    if (!hoists.length) {2537        return;2538    }2539    context.pure = true;2540    const { push, newline, helper, scopeId, mode } = context;2541    newline();2542    for (let i = 0; i < hoists.length; i++) {2543        const exp = hoists[i];2544        if (exp) {2545            push(`const _hoisted_${i + 1} = ${``}`);2546            genNode(exp, context);2547            newline();2548        }2549    }2550    context.pure = false;2551}2552function isText$1(n) {2553    return (isString(n) ||2554        n.type === 4 /* SIMPLE_EXPRESSION */ ||2555        n.type === 2 /* TEXT */ ||2556        n.type === 5 /* INTERPOLATION */ ||2557        n.type === 8 /* COMPOUND_EXPRESSION */);2558}2559function genNodeListAsArray(nodes, context) {2560    const multilines = nodes.length > 3 ||2561        (nodes.some(n => isArray(n) || !isText$1(n)));2562    context.push(`[`);2563    multilines && context.indent();2564    genNodeList(nodes, context, multilines);2565    multilines && context.deindent();2566    context.push(`]`);2567}2568function genNodeList(nodes, context, multilines = false, comma = true) {2569    const { push, newline } = context;2570    for (let i = 0; i < nodes.length; i++) {2571        const node = nodes[i];2572        if (isString(node)) {2573            push(node);2574        }2575        else if (isArray(node)) {2576            genNodeListAsArray(node, context);2577        }2578        else {2579            genNode(node, context);2580        }2581        if (i < nodes.length - 1) {2582            if (multilines) {2583                comma && push(',');2584                newline();2585            }2586            else {2587                comma && push(', ');2588            }2589        }2590    }2591}2592function genNode(node, context) {2593    if (isString(node)) {2594        context.push(node);2595        return;2596    }2597    if (isSymbol(node)) {2598        context.push(context.helper(node));2599        return;2600    }2601    switch (node.type) {2602        case 1 /* ELEMENT */:2603        case 9 /* IF */:2604        case 11 /* FOR */:2605            assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2606                    `Apply appropriate transforms first.`);2607            genNode(node.codegenNode, context);2608            break;2609        case 2 /* TEXT */:2610            genText(node, context);2611            break;2612        case 4 /* SIMPLE_EXPRESSION */:2613            genExpression(node, context);2614            break;2615        case 5 /* INTERPOLATION */:2616            genInterpolation(node, context);2617            break;2618        case 12 /* TEXT_CALL */:2619            genNode(node.codegenNode, context);2620            break;2621        case 8 /* COMPOUND_EXPRESSION */:2622            genCompoundExpression(node, context);2623            break;2624        case 3 /* COMMENT */:2625            genComment(node, context);2626            break;2627        case 13 /* VNODE_CALL */:2628            genVNodeCall(node, context);2629            break;2630        case 14 /* JS_CALL_EXPRESSION */:2631            genCallExpression(node, context);2632            break;2633        case 15 /* JS_OBJECT_EXPRESSION */:2634            genObjectExpression(node, context);2635            break;2636        case 17 /* JS_ARRAY_EXPRESSION */:2637            genArrayExpression(node, context);2638            break;2639        case 18 /* JS_FUNCTION_EXPRESSION */:2640            genFunctionExpression(node, context);2641            break;2642        case 19 /* JS_CONDITIONAL_EXPRESSION */:2643            genConditionalExpression(node, context);2644            break;2645        case 20 /* JS_CACHE_EXPRESSION */:2646            genCacheExpression(node, context);2647            break;2648        case 21 /* JS_BLOCK_STATEMENT */:2649            genNodeList(node.body, context, true, false);2650            break;2651        // SSR only types2652        case 22 /* JS_TEMPLATE_LITERAL */:2653            break;2654        case 23 /* JS_IF_STATEMENT */:2655            break;2656        case 24 /* JS_ASSIGNMENT_EXPRESSION */:2657            break;2658        case 25 /* JS_SEQUENCE_EXPRESSION */:2659            break;2660        case 26 /* JS_RETURN_STATEMENT */:2661            break;2662        /* istanbul ignore next */2663        case 10 /* IF_BRANCH */:2664            // noop2665            break;2666        default:2667            {2668                assert(false, `unhandled codegen node type: ${node.type}`);2669                // make sure we exhaust all possible types2670                const exhaustiveCheck = node;2671                return exhaustiveCheck;2672            }2673    }2674}2675function genText(node, context) {2676    context.push(JSON.stringify(node.content), node);2677}2678function genExpression(node, context) {2679    const { content, isStatic } = node;2680    context.push(isStatic ? JSON.stringify(content) : content, node);2681}2682function genInterpolation(node, context) {2683    const { push, helper, pure } = context;2684    if (pure)2685        push(PURE_ANNOTATION);2686    push(`${helper(TO_DISPLAY_STRING)}(`);2687    genNode(node.content, context);2688    push(`)`);2689}2690function genCompoundExpression(node, context) {2691    for (let i = 0; i < node.children.length; i++) {2692        const child = node.children[i];2693        if (isString(child)) {2694            context.push(child);2695        }2696        else {2697            genNode(child, context);2698        }2699    }2700}2701function genExpressionAsPropertyKey(node, context) {2702    const { push } = context;2703    if (node.type === 8 /* COMPOUND_EXPRESSION */) {2704        push(`[`);2705        genCompoundExpression(node, context);2706        push(`]`);2707    }2708    else if (node.isStatic) {2709        // only quote keys if necessary2710        const text = isSimpleIdentifier(node.content)2711            ? node.content2712            : JSON.stringify(node.content);2713        push(text, node);2714    }2715    else {2716        push(`[${node.content}]`, node);2717    }2718}2719function genComment(node, context) {2720    const { push, helper, pure } = context;2721    if (pure) {2722        push(PURE_ANNOTATION);2723    }2724    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2725}2726function genVNodeCall(node, context) {2727    const { push, helper, pure } = context;2728    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2729    if (directives) {2730        push(helper(WITH_DIRECTIVES) + `(`);2731    }2732    if (isBlock) {2733        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2734    }2735    if (pure) {2736        push(PURE_ANNOTATION);2737    }2738    const callHelper = isBlock2739        ? getVNodeBlockHelper(context.inSSR, isComponent)2740        : getVNodeHelper(context.inSSR, isComponent);2741    push(helper(callHelper) + `(`, node);2742    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2743    push(`)`);2744    if (isBlock) {2745        push(`)`);2746    }2747    if (directives) {2748        push(`, `);2749        genNode(directives, context);2750        push(`)`);2751    }2752}2753function genNullableArgs(args) {2754    let i = args.length;2755    while (i--) {2756        if (args[i] != null)2757            break;2758    }2759    return args.slice(0, i + 1).map(arg => arg || `null`);2760}2761// JavaScript2762function genCallExpression(node, context) {2763    const { push, helper, pure } = context;2764    const callee = isString(node.callee) ? node.callee : helper(node.callee);2765    if (pure) {2766        push(PURE_ANNOTATION);2767    }2768    push(callee + `(`, node);2769    genNodeList(node.arguments, context);2770    push(`)`);2771}2772function genObjectExpression(node, context) {2773    const { push, indent, deindent, newline } = context;2774    const { properties } = node;2775    if (!properties.length) {2776        push(`{}`, node);2777        return;2778    }2779    const multilines = properties.length > 1 ||2780        (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2781    push(multilines ? `{` : `{ `);2782    multilines && indent();2783    for (let i = 0; i < properties.length; i++) {2784        const { key, value } = properties[i];2785        // key2786        genExpressionAsPropertyKey(key, context);2787        push(`: `);2788        // value2789        genNode(value, context);2790        if (i < properties.length - 1) {2791            // will only reach this if it's multilines2792            push(`,`);2793            newline();2794        }2795    }2796    multilines && deindent();2797    push(multilines ? `}` : ` }`);2798}2799function genArrayExpression(node, context) {2800    genNodeListAsArray(node.elements, context);2801}2802function genFunctionExpression(node, context) {2803    const { push, indent, deindent } = context;2804    const { params, returns, body, newline, isSlot } = node;2805    if (isSlot) {2806        // wrap slot functions with owner context2807        push(`_${helperNameMap[WITH_CTX]}(`);2808    }2809    push(`(`, node);2810    if (isArray(params)) {2811        genNodeList(params, context);2812    }2813    else if (params) {2814        genNode(params, context);2815    }2816    push(`) => `);2817    if (newline || body) {2818        push(`{`);2819        indent();2820    }2821    if (returns) {2822        if (newline) {2823            push(`return `);2824        }2825        if (isArray(returns)) {2826            genNodeListAsArray(returns, context);2827        }2828        else {2829            genNode(returns, context);2830        }2831    }2832    else if (body) {2833        genNode(body, context);2834    }2835    if (newline || body) {2836        deindent();2837        push(`}`);2838    }2839    if (isSlot) {2840        if (node.isNonScopedSlot) {2841            push(`, undefined, true`);2842        }2843        push(`)`);2844    }2845}2846function genConditionalExpression(node, context) {2847    const { test, consequent, alternate, newline: needNewline } = node;2848    const { push, indent, deindent, newline } = context;2849    if (test.type === 4 /* SIMPLE_EXPRESSION */) {2850        const needsParens = !isSimpleIdentifier(test.content);2851        needsParens && push(`(`);2852        genExpression(test, context);2853        needsParens && push(`)`);2854    }2855    else {2856        push(`(`);2857        genNode(test, context);2858        push(`)`);2859    }2860    needNewline && indent();2861    context.indentLevel++;2862    needNewline || push(` `);2863    push(`? `);2864    genNode(consequent, context);2865    context.indentLevel--;2866    needNewline && newline();2867    needNewline || push(` `);2868    push(`: `);2869    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2870    if (!isNested) {2871        context.indentLevel++;2872    }2873    genNode(alternate, context);2874    if (!isNested) {2875        context.indentLevel--;2876    }2877    needNewline && deindent(true /* without newline */);2878}2879function genCacheExpression(node, context) {2880    const { push, helper, indent, deindent, newline } = context;2881    push(`_cache[${node.index}] || (`);2882    if (node.isVNode) {2883        indent();2884        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2885        newline();2886    }2887    push(`_cache[${node.index}] = `);2888    genNode(node.value, context);2889    if (node.isVNode) {2890        push(`,`);2891        newline();2892        push(`${helper(SET_BLOCK_TRACKING)}(1),`);2893        newline();2894        push(`_cache[${node.index}]`);2895        deindent();2896    }2897    push(`)`);2898}2899function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2900    {2901        return;2902    }2903}2904function isReferencedIdentifier(id, parent, parentStack) {2905    {2906        return false;2907    }2908}2909function isInDestructureAssignment(parent, parentStack) {2910    if (parent &&2911        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2912        let i = parentStack.length;2913        while (i--) {2914            const p = parentStack[i];2915            if (p.type === 'AssignmentExpression') {2916                return true;2917            }2918            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2919                break;2920            }2921        }2922    }2923    return false;2924}2925function walkFunctionParams(node, onIdent) {2926    for (const p of node.params) {2927        for (const id of extractIdentifiers(p)) {2928            onIdent(id);2929        }2930    }2931}2932function walkBlockDeclarations(block, onIdent) {2933    for (const stmt of block.body) {2934        if (stmt.type === 'VariableDeclaration') {2935            if (stmt.declare)2936                continue;2937            for (const decl of stmt.declarations) {2938                for (const id of extractIdentifiers(decl.id)) {2939                    onIdent(id);2940                }2941            }2942        }2943        else if (stmt.type === 'FunctionDeclaration' ||2944            stmt.type === 'ClassDeclaration') {2945            if (stmt.declare || !stmt.id)2946                continue;2947            onIdent(stmt.id);2948        }2949    }2950}2951function extractIdentifiers(param, nodes = []) {2952    switch (param.type) {2953        case 'Identifier':2954            nodes.push(param);2955            break;2956        case 'MemberExpression':2957            let object = param;2958            while (object.type === 'MemberExpression') {2959                object = object.object;2960            }2961            nodes.push(object);2962            break;2963        case 'ObjectPattern':2964            for (const prop of param.properties) {2965                if (prop.type === 'RestElement') {2966                    extractIdentifiers(prop.argument, nodes);2967                }2968                else {2969                    extractIdentifiers(prop.value, nodes);2970                }2971            }2972            break;2973        case 'ArrayPattern':2974            param.elements.forEach(element => {2975                if (element)2976                    extractIdentifiers(element, nodes);2977            });2978            break;2979        case 'RestElement':2980            extractIdentifiers(param.argument, nodes);2981            break;2982        case 'AssignmentPattern':2983            extractIdentifiers(param.left, nodes);2984            break;2985    }2986    return nodes;2987}2988const isFunctionType = (node) => {2989    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);2990};2991const isStaticProperty = (node) => node &&2992    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&2993    !node.computed;2994const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;2995// these keywords should not appear inside expressions, but operators like2996// typeof, instanceof and in are allowed2997const prohibitedKeywordRE = new RegExp('\\b' +2998    ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +2999        'super,throw,while,yield,delete,export,import,return,switch,default,' +3000        'extends,finally,continue,debugger,function,arguments,typeof,void')3001        .split(',')3002        .join('\\b|\\b') +3003    '\\b');3004// strip strings in expressions3005const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;3006/**3007 * Validate a non-prefixed expression.3008 * This is only called when using the in-browser runtime compiler since it3009 * doesn't prefix expressions.3010 */3011function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {3012    const exp = node.content;3013    // empty expressions are validated per-directive since some directives3014    // do allow empty expressions.3015    if (!exp.trim()) {3016        return;3017    }3018    try {3019        new Function(asRawStatements3020            ? ` ${exp} `3021            : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);3022    }3023    catch (e) {3024        let message = e.message;3025        const keywordMatch = exp3026            .replace(stripStringRE, '')3027            .match(prohibitedKeywordRE);3028        if (keywordMatch) {3029            message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;3030        }3031        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));3032    }3033}3034const transformExpression = (node, context) => {3035    if (node.type === 5 /* INTERPOLATION */) {3036        node.content = processExpression(node.content, context);3037    }3038    else if (node.type === 1 /* ELEMENT */) {3039        // handle directives on element3040        for (let i = 0; i < node.props.length; i++) {3041            const dir = node.props[i];3042            // do not process for v-on & v-for since they are special handled3043            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {3044                const exp = dir.exp;3045                const arg = dir.arg;3046                // do not process exp if this is v-on:arg - we need special handling3047                // for wrapping inline statements.3048                if (exp &&3049                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&3050                    !(dir.name === 'on' && arg)) {3051                    dir.exp = processExpression(exp, context, 3052                    // slot args must be processed as function params3053                    dir.name === 'slot');3054                }3055                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {3056                    dir.arg = processExpression(arg, context);3057                }3058            }3059        }3060    }3061};3062// Important: since this function uses Node.js only dependencies, it should3063// always be used with a leading !true check so that it can be3064// tree-shaken from the browser build.3065function processExpression(node, context, 3066// some expressions like v-slot props & v-for aliases should be parsed as3067// function params3068asParams = false, 3069// v-on handler values may contain multiple statements3070asRawStatements = false, localVars = Object.create(context.identifiers)) {3071    {3072        {3073            // simple in-browser validation (same logic in 2.x)3074            validateBrowserExpression(node, context, asParams, asRawStatements);3075        }3076        return node;3077    }3078}3079const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {3080    return processIf(node, dir, context, (ifNode, branch, isRoot) => {3081        // #1587: We need to dynamically increment the key based on the current3082        // node's sibling nodes, since chained v-if/else branches are3083        // rendered at the same depth3084        const siblings = context.parent.children;3085        let i = siblings.indexOf(ifNode);3086        let key = 0;3087        while (i-- >= 0) {3088            const sibling = siblings[i];3089            if (sibling && sibling.type === 9 /* IF */) {3090                key += sibling.branches.length;3091            }3092        }3093        // Exit callback. Complete the codegenNode when all children have been3094        // transformed.3095        return () => {3096            if (isRoot) {3097                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);3098            }3099            else {3100                // attach this branch's codegen node to the v-if root.3101                const parentCondition = getParentCondition(ifNode.codegenNode);3102                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);3103            }3104        };3105    });3106});3107// target-agnostic transform used for both Client and SSR3108function processIf(node, dir, context, processCodegen) {3109    if (dir.name !== 'else' &&3110        (!dir.exp || !dir.exp.content.trim())) {3111        const loc = dir.exp ? dir.exp.loc : node.loc;3112        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));3113        dir.exp = createSimpleExpression(`true`, false, loc);3114    }3115    if (dir.exp) {3116        validateBrowserExpression(dir.exp, context);3117    }3118    if (dir.name === 'if') {3119        const branch = createIfBranch(node, dir);3120        const ifNode = {3121            type: 9 /* IF */,3122            loc: node.loc,3123            branches: [branch]3124        };3125        context.replaceNode(ifNode);3126        if (processCodegen) {3127            return processCodegen(ifNode, branch, true);3128        }3129    }3130    else {3131        // locate the adjacent v-if3132        const siblings = context.parent.children;3133        const comments = [];3134        let i = siblings.indexOf(node);3135        while (i-- >= -1) {3136            const sibling = siblings[i];3137            if (sibling && sibling.type === 3 /* COMMENT */) {3138                context.removeNode(sibling);3139                comments.unshift(sibling);3140                continue;3141            }3142            if (sibling &&3143                sibling.type === 2 /* TEXT */ &&3144                !sibling.content.trim().length) {3145                context.removeNode(sibling);3146                continue;3147            }3148            if (sibling && sibling.type === 9 /* IF */) {3149                // Check if v-else was followed by v-else-if3150                if (dir.name === 'else-if' &&3151                    sibling.branches[sibling.branches.length - 1].condition === undefined) {3152                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3153                }3154                // move the node to the if node's branches3155                context.removeNode();3156                const branch = createIfBranch(node, dir);3157                if (comments.length &&3158                    // #3619 ignore comments if the v-if is direct child of <transition>3159                    !(context.parent &&3160                        context.parent.type === 1 /* ELEMENT */ &&3161                        isBuiltInType(context.parent.tag, 'transition'))) {3162                    branch.children = [...comments, ...branch.children];3163                }3164                // check if user is forcing same key on different branches3165                {3166                    const key = branch.userKey;3167                    if (key) {3168                        sibling.branches.forEach(({ userKey }) => {3169                            if (isSameKey(userKey, key)) {3170                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3171                            }3172                        });3173                    }3174                }3175                sibling.branches.push(branch);3176                const onExit = processCodegen && processCodegen(sibling, branch, false);3177                // since the branch was removed, it will not be traversed.3178                // make sure to traverse here.3179                traverseNode(branch, context);3180                // call on exit3181                if (onExit)3182                    onExit();3183                // make sure to reset currentNode after traversal to indicate this3184                // node has been removed.3185                context.currentNode = null;3186            }3187            else {3188                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3189            }3190            break;3191        }3192    }3193}3194function createIfBranch(node, dir) {3195    return {3196        type: 10 /* IF_BRANCH */,3197        loc: node.loc,3198        condition: dir.name === 'else' ? undefined : dir.exp,3199        children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3200            ? node.children3201            : [node],3202        userKey: findProp(node, `key`)3203    };3204}3205function createCodegenNodeForBranch(branch, keyIndex, context) {3206    if (branch.condition) {3207        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3208        // make sure to pass in asBlock: true so that the comment node call3209        // closes the current block.3210        createCallExpression(context.helper(CREATE_COMMENT), [3211            '"v-if"' ,3212            'true'3213        ]));3214    }3215    else {3216        return createChildrenCodegenNode(branch, keyIndex, context);3217    }3218}3219function createChildrenCodegenNode(branch, keyIndex, context) {3220    const { helper } = context;3221    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3222    const { children } = branch;3223    const firstChild = children[0];3224    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3225    if (needFragmentWrapper) {3226        if (children.length === 1 && firstChild.type === 11 /* FOR */) {3227            // optimize away nested fragments when child is a ForNode3228            const vnodeCall = firstChild.codegenNode;3229            injectProp(vnodeCall, keyProperty, context);3230            return vnodeCall;3231        }3232        else {3233            let patchFlag = 64 /* STABLE_FRAGMENT */;3234            let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3235            // check if the fragment actually contains a single valid child with3236            // the rest being comments3237            if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3238                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3239                patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3240            }3241            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);3242        }3243    }3244    else {3245        const ret = firstChild.codegenNode;3246        const vnodeCall = getMemoedVNodeCall(ret);3247        // Change createVNode to createBlock.3248        if (vnodeCall.type === 13 /* VNODE_CALL */) {3249            makeBlock(vnodeCall, context);3250        }3251        // inject branch key3252        injectProp(vnodeCall, keyProperty, context);3253        return ret;3254    }3255}3256function isSameKey(a, b) {3257    if (!a || a.type !== b.type) {3258        return false;3259    }3260    if (a.type === 6 /* ATTRIBUTE */) {3261        if (a.value.content !== b.value.content) {3262            return false;3263        }3264    }3265    else {3266        // directive3267        const exp = a.exp;3268        const branchExp = b.exp;3269        if (exp.type !== branchExp.type) {3270            return false;3271        }3272        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3273            exp.isStatic !== branchExp.isStatic ||3274            exp.content !== branchExp.content) {3275            return false;3276        }3277    }3278    return true;3279}3280function getParentCondition(node) {3281    while (true) {3282        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3283            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3284                node = node.alternate;3285            }3286            else {3287                return node;3288            }3289        }3290        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3291            node = node.value;3292        }3293    }3294}3295const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3296    const { helper, removeHelper } = context;3297    return processFor(node, dir, context, forNode => {3298        // create the loop render function expression now, and add the3299        // iterator on exit after all children have been traversed3300        const renderExp = createCallExpression(helper(RENDER_LIST), [3301            forNode.source3302        ]);3303        const memo = findDir(node, 'memo');3304        const keyProp = findProp(node, `key`);3305        const keyExp = keyProp &&3306            (keyProp.type === 6 /* ATTRIBUTE */3307                ? createSimpleExpression(keyProp.value.content, true)3308                : keyProp.exp);3309        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3310        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3311            forNode.source.constType > 0 /* NOT_CONSTANT */;3312        const fragmentFlag = isStableFragment3313            ? 64 /* STABLE_FRAGMENT */3314            : keyProp3315                ? 128 /* KEYED_FRAGMENT */3316                : 256 /* UNKEYED_FRAGMENT */;3317        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3318            (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3319        return () => {3320            // finish the codegen now that all children have been traversed3321            let childBlock;3322            const isTemplate = isTemplateNode(node);3323            const { children } = forNode;3324            // check <template v-for> key placement3325            if (isTemplate) {3326                node.children.some(c => {3327                    if (c.type === 1 /* ELEMENT */) {3328                        const key = findProp(c, 'key');3329                        if (key) {3330                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3331                            return true;3332                        }3333                    }3334                });3335            }3336            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3337            const slotOutlet = isSlotOutlet(node)3338                ? node3339                : isTemplate &&3340                    node.children.length === 1 &&3341                    isSlotOutlet(node.children[0])3342                    ? node.children[0] // api-extractor somehow fails to infer this3343                    : null;3344            if (slotOutlet) {3345                // <slot v-for="..."> or <template v-for="..."><slot/></template>3346                childBlock = slotOutlet.codegenNode;3347                if (isTemplate && keyProperty) {3348                    // <template v-for="..." :key="..."><slot/></template>3349                    // we need to inject the key to the renderSlot() call.3350                    // the props for renderSlot is passed as the 3rd argument.3351                    injectProp(childBlock, keyProperty, context);3352                }3353            }3354            else if (needFragmentWrapper) {3355                // <template v-for="..."> with text or multi-elements3356                // should generate a fragment block for each loop3357                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3358                    (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3359                        ), undefined, undefined, true, undefined, false /* isComponent */);3360            }3361            else {3362                // Normal element v-for. Directly use the child's codegenNode3363                // but mark it as a block.3364                childBlock = children[0]3365                    .codegenNode;3366                if (isTemplate && keyProperty) {3367                    injectProp(childBlock, keyProperty, context);3368                }3369                if (childBlock.isBlock !== !isStableFragment) {3370                    if (childBlock.isBlock) {3371                        // switch from block to vnode3372                        removeHelper(OPEN_BLOCK);3373                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3374                    }3375                    else {3376                        // switch from vnode to block3377                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3378                    }3379                }3380                childBlock.isBlock = !isStableFragment;3381                if (childBlock.isBlock) {3382                    helper(OPEN_BLOCK);3383                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3384                }3385                else {3386                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3387                }3388            }3389            if (memo) {3390                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3391                    createSimpleExpression(`_cached`)3392                ]));3393                loop.body = createBlockStatement([3394                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3395                    createCompoundExpression([3396                        `if (_cached`,3397                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),3398                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3399                    ]),3400                    createCompoundExpression([`const _item = `, childBlock]),3401                    createSimpleExpression(`_item.memo = _memo`),3402                    createSimpleExpression(`return _item`)3403                ]);3404                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3405            }3406            else {3407                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3408            }3409        };3410    });3411});3412// target-agnostic transform used for both Client and SSR3413function processFor(node, dir, context, processCodegen) {3414    if (!dir.exp) {3415        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3416        return;3417    }3418    const parseResult = parseForExpression(3419    // can only be simple expression because vFor transform is applied3420    // before expression transform.3421    dir.exp, context);3422    if (!parseResult) {3423        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3424        return;3425    }3426    const { addIdentifiers, removeIdentifiers, scopes } = context;3427    const { source, value, key, index } = parseResult;3428    const forNode = {3429        type: 11 /* FOR */,3430        loc: dir.loc,3431        source,3432        valueAlias: value,3433        keyAlias: key,3434        objectIndexAlias: index,3435        parseResult,3436        children: isTemplateNode(node) ? node.children : [node]3437    };3438    context.replaceNode(forNode);3439    // bookkeeping3440    scopes.vFor++;3441    const onExit = processCodegen && processCodegen(forNode);3442    return () => {3443        scopes.vFor--;3444        if (onExit)3445            onExit();3446    };3447}3448const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3449// This regex doesn't cover the case if key or index aliases have destructuring,3450// but those do not make sense in the first place, so this works in practice.3451const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3452const stripParensRE = /^\(|\)$/g;3453function parseForExpression(input, context) {3454    const loc = input.loc;3455    const exp = input.content;3456    const inMatch = exp.match(forAliasRE);3457    if (!inMatch)3458        return;3459    const [, LHS, RHS] = inMatch;3460    const result = {3461        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3462        value: undefined,3463        key: undefined,3464        index: undefined3465    };3466    {3467        validateBrowserExpression(result.source, context);3468    }3469    let valueContent = LHS.trim().replace(stripParensRE, '').trim();3470    const trimmedOffset = LHS.indexOf(valueContent);3471    const iteratorMatch = valueContent.match(forIteratorRE);3472    if (iteratorMatch) {3473        valueContent = valueContent.replace(forIteratorRE, '').trim();3474        const keyContent = iteratorMatch[1].trim();3475        let keyOffset;3476        if (keyContent) {3477            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3478            result.key = createAliasExpression(loc, keyContent, keyOffset);3479            {3480                validateBrowserExpression(result.key, context, true);3481            }3482        }3483        if (iteratorMatch[2]) {3484            const indexContent = iteratorMatch[2].trim();3485            if (indexContent) {3486                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3487                    ? keyOffset + keyContent.length3488                    : trimmedOffset + valueContent.length));3489                {3490                    validateBrowserExpression(result.index, context, true);3491                }3492            }3493        }3494    }3495    if (valueContent) {3496        result.value = createAliasExpression(loc, valueContent, trimmedOffset);3497        {3498            validateBrowserExpression(result.value, context, true);3499        }3500    }3501    return result;3502}3503function createAliasExpression(range, content, offset) {3504    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3505}3506function createForLoopParams({ value, key, index }, memoArgs = []) {3507    return createParamsList([value, key, index, ...memoArgs]);3508}3509function createParamsList(args) {3510    let i = args.length;3511    while (i--) {3512        if (args[i])3513            break;3514    }3515    return args3516        .slice(0, i + 1)3517        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3518}3519const defaultFallback = createSimpleExpression(`undefined`, false);3520// A NodeTransform that:3521// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3522//    by transformExpression. This is only applied in non-browser builds with3523//    { prefixIdentifiers: true }.3524// 2. Track v-slot depths so that we know a slot is inside another slot.3525//    Note the exit callback is executed before buildSlots() on the same node,3526//    so only nested slots see positive numbers.3527const trackSlotScopes = (node, context) => {3528    if (node.type === 1 /* ELEMENT */ &&3529        (node.tagType === 1 /* COMPONENT */ ||3530            node.tagType === 3 /* TEMPLATE */)) {3531        // We are only checking non-empty v-slot here3532        // since we only care about slots that introduce scope variables.3533        const vSlot = findDir(node, 'slot');3534        if (vSlot) {3535            vSlot.exp;3536            context.scopes.vSlot++;3537            return () => {3538                context.scopes.vSlot--;3539            };3540        }3541    }3542};3543// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3544// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3545const trackVForSlotScopes = (node, context) => {3546    let vFor;3547    if (isTemplateNode(node) &&3548        node.props.some(isVSlot) &&3549        (vFor = findDir(node, 'for'))) {3550        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3551        if (result) {3552            const { value, key, index } = result;3553            const { addIdentifiers, removeIdentifiers } = context;3554            value && addIdentifiers(value);3555            key && addIdentifiers(key);3556            index && addIdentifiers(index);3557            return () => {3558                value && removeIdentifiers(value);3559                key && removeIdentifiers(key);3560                index && removeIdentifiers(index);3561            };3562        }3563    }3564};3565const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3566// Instead of being a DirectiveTransform, v-slot processing is called during3567// transformElement to build the slots object for a component.3568function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3569    context.helper(WITH_CTX);3570    const { children, loc } = node;3571    const slotsProperties = [];3572    const dynamicSlots = [];3573    // If the slot is inside a v-for or another v-slot, force it to be dynamic3574    // since it likely uses a scope variable.3575    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3576    // 1. Check for slot with slotProps on component itself.3577    //    <Comp v-slot="{ prop }"/>3578    const onComponentSlot = findDir(node, 'slot', true);3579    if (onComponentSlot) {3580        const { arg, exp } = onComponentSlot;3581        if (arg && !isStaticExp(arg)) {3582            hasDynamicSlots = true;3583        }3584        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3585    }3586    // 2. Iterate through children and check for template slots3587    //    <template v-slot:foo="{ prop }">3588    let hasTemplateSlots = false;3589    let hasNamedDefaultSlot = false;3590    const implicitDefaultChildren = [];3591    const seenSlotNames = new Set();3592    for (let i = 0; i < children.length; i++) {3593        const slotElement = children[i];3594        let slotDir;3595        if (!isTemplateNode(slotElement) ||3596            !(slotDir = findDir(slotElement, 'slot', true))) {3597            // not a <template v-slot>, skip.3598            if (slotElement.type !== 3 /* COMMENT */) {3599                implicitDefaultChildren.push(slotElement);3600            }3601            continue;3602        }3603        if (onComponentSlot) {3604            // already has on-component slot - this is incorrect usage.3605            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3606            break;3607        }3608        hasTemplateSlots = true;3609        const { children: slotChildren, loc: slotLoc } = slotElement;3610        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3611        // check if name is dynamic.3612        let staticSlotName;3613        if (isStaticExp(slotName)) {3614            staticSlotName = slotName ? slotName.content : `default`;3615        }3616        else {3617            hasDynamicSlots = true;3618        }3619        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3620        // check if this slot is conditional (v-if/v-for)3621        let vIf;3622        let vElse;3623        let vFor;3624        if ((vIf = findDir(slotElement, 'if'))) {3625            hasDynamicSlots = true;3626            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3627        }3628        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3629            // find adjacent v-if3630            let j = i;3631            let prev;3632            while (j--) {3633                prev = children[j];3634                if (prev.type !== 3 /* COMMENT */) {3635                    break;3636                }3637            }3638            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3639                // remove node3640                children.splice(i, 1);3641                i--;3642                // attach this slot to previous conditional3643                let conditional = dynamicSlots[dynamicSlots.length - 1];3644                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3645                    conditional = conditional.alternate;3646                }3647                conditional.alternate = vElse.exp3648                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3649                    : buildDynamicSlot(slotName, slotFunction);3650            }3651            else {3652                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3653            }3654        }3655        else if ((vFor = findDir(slotElement, 'for'))) {3656            hasDynamicSlots = true;3657            const parseResult = vFor.parseResult ||3658                parseForExpression(vFor.exp, context);3659            if (parseResult) {3660                // Render the dynamic slots as an array and add it to the createSlot()3661                // args. The runtime knows how to handle it appropriately.3662                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3663                    parseResult.source,3664                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3665                ]));3666            }3667            else {3668                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3669            }3670        }3671        else {3672            // check duplicate static names3673            if (staticSlotName) {3674                if (seenSlotNames.has(staticSlotName)) {3675                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3676                    continue;3677                }3678                seenSlotNames.add(staticSlotName);3679                if (staticSlotName === 'default') {3680                    hasNamedDefaultSlot = true;3681                }3682            }3683            slotsProperties.push(createObjectProperty(slotName, slotFunction));3684        }3685    }3686    if (!onComponentSlot) {3687        const buildDefaultSlotProperty = (props, children) => {3688            const fn = buildSlotFn(props, children, loc);3689            if (context.compatConfig) {3690                fn.isNonScopedSlot = true;3691            }3692            return createObjectProperty(`default`, fn);3693        };3694        if (!hasTemplateSlots) {3695            // implicit default slot (on component)3696            slotsProperties.push(buildDefaultSlotProperty(undefined, children));3697        }3698        else if (implicitDefaultChildren.length &&3699            // #37663700            // with whitespace: 'preserve', whitespaces between slots will end up in3701            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3702            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3703            // implicit default slot (mixed with named slots)3704            if (hasNamedDefaultSlot) {3705                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3706            }3707            else {3708                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3709            }3710        }3711    }3712    const slotFlag = hasDynamicSlots3713        ? 2 /* DYNAMIC */3714        : hasForwardedSlots(node.children)3715            ? 3 /* FORWARDED */3716            : 1 /* STABLE */;3717    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3718    // 2 = compiled but dynamic = can skip normalization, but must run diff3719    // 1 = compiled and static = can skip normalization AND diff as optimized3720    createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);3721    if (dynamicSlots.length) {3722        slots = createCallExpression(context.helper(CREATE_SLOTS), [3723            slots,3724            createArrayExpression(dynamicSlots)3725        ]);3726    }3727    return {3728        slots,3729        hasDynamicSlots3730    };3731}3732function buildDynamicSlot(name, fn) {3733    return createObjectExpression([3734        createObjectProperty(`name`, name),3735        createObjectProperty(`fn`, fn)3736    ]);3737}3738function hasForwardedSlots(children) {3739    for (let i = 0; i < children.length; i++) {3740        const child = children[i];3741        switch (child.type) {3742            case 1 /* ELEMENT */:3743                if (child.tagType === 2 /* SLOT */ ||3744                    hasForwardedSlots(child.children)) {3745                    return true;3746                }3747                break;3748            case 9 /* IF */:3749                if (hasForwardedSlots(child.branches))3750                    return true;3751                break;3752            case 10 /* IF_BRANCH */:3753            case 11 /* FOR */:3754                if (hasForwardedSlots(child.children))3755                    return true;3756                break;3757        }3758    }3759    return false;3760}3761function isNonWhitespaceContent(node) {3762    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3763        return true;3764    return node.type === 2 /* TEXT */3765        ? !!node.content.trim()3766        : isNonWhitespaceContent(node.content);3767}3768// some directive transforms (e.g. v-model) may return a symbol for runtime3769// import, which should be used instead of a resolveDirective call.3770const directiveImportMap = new WeakMap();3771// generate a JavaScript AST for this element's codegen3772const transformElement = (node, context) => {3773    // perform the work on exit, after all child expressions have been3774    // processed and merged.3775    return function postTransformElement() {3776        node = context.currentNode;3777        if (!(node.type === 1 /* ELEMENT */ &&3778            (node.tagType === 0 /* ELEMENT */ ||3779                node.tagType === 1 /* COMPONENT */))) {3780            return;3781        }3782        const { tag, props } = node;3783        const isComponent = node.tagType === 1 /* COMPONENT */;3784        // The goal of the transform is to create a codegenNode implementing the3785        // VNodeCall interface.3786        let vnodeTag = isComponent3787            ? resolveComponentType(node, context)3788            : `"${tag}"`;3789        const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3790        let vnodeProps;3791        let vnodeChildren;3792        let vnodePatchFlag;3793        let patchFlag = 0;3794        let vnodeDynamicProps;3795        let dynamicPropNames;3796        let vnodeDirectives;3797        let shouldUseBlock = 3798        // dynamic component may resolve to plain elements3799        isDynamicComponent ||3800            vnodeTag === TELEPORT ||3801            vnodeTag === SUSPENSE ||3802            (!isComponent &&3803                // <svg> and <foreignObject> must be forced into blocks so that block3804                // updates inside get proper isSVG flag at runtime. (#639, #643)3805                // This is technically web-specific, but splitting the logic out of core3806                // leads to too much unnecessary complexity.3807                (tag === 'svg' || tag === 'foreignObject'));3808        // props3809        if (props.length > 0) {3810            const propsBuildResult = buildProps(node, context);3811            vnodeProps = propsBuildResult.props;3812            patchFlag = propsBuildResult.patchFlag;3813            dynamicPropNames = propsBuildResult.dynamicPropNames;3814            const directives = propsBuildResult.directives;3815            vnodeDirectives =3816                directives && directives.length3817                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3818                    : undefined;3819            if (propsBuildResult.shouldUseBlock) {3820                shouldUseBlock = true;3821            }3822        }3823        // children3824        if (node.children.length > 0) {3825            if (vnodeTag === KEEP_ALIVE) {3826                // Although a built-in component, we compile KeepAlive with raw children3827                // instead of slot functions so that it can be used inside Transition3828                // or other Transition-wrapping HOCs.3829                // To ensure correct updates with block optimizations, we need to:3830                // 1. Force keep-alive into a block. This avoids its children being3831                //    collected by a parent block.3832                shouldUseBlock = true;3833                // 2. Force keep-alive to always be updated, since it uses raw children.3834                patchFlag |= 1024 /* DYNAMIC_SLOTS */;3835                if (node.children.length > 1) {3836                    context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3837                        start: node.children[0].loc.start,3838                        end: node.children[node.children.length - 1].loc.end,3839                        source: ''3840                    }));3841                }3842            }3843            const shouldBuildAsSlots = isComponent &&3844                // Teleport is not a real component and has dedicated runtime handling3845                vnodeTag !== TELEPORT &&3846                // explained above.3847                vnodeTag !== KEEP_ALIVE;3848            if (shouldBuildAsSlots) {3849                const { slots, hasDynamicSlots } = buildSlots(node, context);3850                vnodeChildren = slots;3851                if (hasDynamicSlots) {3852                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;3853                }3854            }3855            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3856                const child = node.children[0];3857                const type = child.type;3858                // check for dynamic text children3859                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3860                    type === 8 /* COMPOUND_EXPRESSION */;3861                if (hasDynamicTextChild &&3862                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3863                    patchFlag |= 1 /* TEXT */;3864                }3865                // pass directly if the only child is a text node3866                // (plain / interpolation / expression)3867                if (hasDynamicTextChild || type === 2 /* TEXT */) {3868                    vnodeChildren = child;3869                }3870                else {3871                    vnodeChildren = node.children;3872                }3873            }3874            else {3875                vnodeChildren = node.children;3876            }3877        }3878        // patchFlag & dynamicPropNames3879        if (patchFlag !== 0) {3880            {3881                if (patchFlag < 0) {3882                    // special flags (negative and mutually exclusive)3883                    vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;3884                }3885                else {3886                    // bitwise flags3887                    const flagNames = Object.keys(PatchFlagNames)3888                        .map(Number)3889                        .filter(n => n > 0 && patchFlag & n)3890                        .map(n => PatchFlagNames[n])3891                        .join(`, `);3892                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3893                }3894            }3895            if (dynamicPropNames && dynamicPropNames.length) {3896                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3897            }3898        }3899        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);3900    };3901};3902function resolveComponentType(node, context, ssr = false) {3903    let { tag } = node;3904    // 1. dynamic component3905    const isExplicitDynamic = isComponentTag(tag);3906    const isProp = findProp(node, 'is');3907    if (isProp) {3908        if (isExplicitDynamic ||3909            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3910            const exp = isProp.type === 6 /* ATTRIBUTE */3911                ? isProp.value && createSimpleExpression(isProp.value.content, true)3912                : isProp.exp;3913            if (exp) {3914                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3915                    exp3916                ]);3917            }3918        }3919        else if (isProp.type === 6 /* ATTRIBUTE */ &&3920            isProp.value.content.startsWith('vue:')) {3921            // <button is="vue:xxx">3922            // if not <component>, only is value that starts with "vue:" will be3923            // treated as component by the parse phase and reach here, unless it's3924            // compat mode where all is values are considered components3925            tag = isProp.value.content.slice(4);3926        }3927    }3928    // 1.5 v-is (TODO: Deprecate)3929    const isDir = !isExplicitDynamic && findDir(node, 'is');3930    if (isDir && isDir.exp) {3931        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3932            isDir.exp3933        ]);3934    }3935    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3936    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3937    if (builtIn) {3938        // built-ins are simply fallthroughs / have special handling during ssr3939        // so we don't need to import their runtime equivalents3940        if (!ssr)3941            context.helper(builtIn);3942        return builtIn;3943    }3944    // 5. user component (resolve)3945    context.helper(RESOLVE_COMPONENT);3946    context.components.add(tag);3947    return toValidAssetId(tag, `component`);3948}3949function buildProps(node, context, props = node.props, ssr = false) {3950    const { tag, loc: elementLoc, children } = node;3951    const isComponent = node.tagType === 1 /* COMPONENT */;3952    let properties = [];3953    const mergeArgs = [];3954    const runtimeDirectives = [];3955    const hasChildren = children.length > 0;3956    let shouldUseBlock = false;3957    // patchFlag analysis3958    let patchFlag = 0;3959    let hasRef = false;3960    let hasClassBinding = false;3961    let hasStyleBinding = false;3962    let hasHydrationEventBinding = false;3963    let hasDynamicKeys = false;3964    let hasVnodeHook = false;3965    const dynamicPropNames = [];3966    const analyzePatchFlag = ({ key, value }) => {3967        if (isStaticExp(key)) {3968            const name = key.content;3969            const isEventHandler = isOn(name);3970            if (!isComponent &&3971                isEventHandler &&3972                // omit the flag for click handlers because hydration gives click3973                // dedicated fast path.3974                name.toLowerCase() !== 'onclick' &&3975                // omit v-model handlers3976                name !== 'onUpdate:modelValue' &&3977                // omit onVnodeXXX hooks3978                !isReservedProp(name)) {3979                hasHydrationEventBinding = true;3980            }3981            if (isEventHandler && isReservedProp(name)) {3982                hasVnodeHook = true;3983            }3984            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||3985                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||3986                    value.type === 8 /* COMPOUND_EXPRESSION */) &&3987                    getConstantType(value, context) > 0)) {3988                // skip if the prop is a cached handler or has constant value3989                return;3990            }3991            if (name === 'ref') {3992                hasRef = true;3993            }3994            else if (name === 'class') {3995                hasClassBinding = true;3996            }3997            else if (name === 'style') {3998                hasStyleBinding = true;3999            }4000            else if (name !== 'key' && !dynamicPropNames.includes(name)) {4001                dynamicPropNames.push(name);4002            }4003            // treat the dynamic class and style binding of the component as dynamic props4004            if (isComponent &&4005                (name === 'class' || name === 'style') &&4006                !dynamicPropNames.includes(name)) {4007                dynamicPropNames.push(name);4008            }4009        }4010        else {4011            hasDynamicKeys = true;4012        }4013    };4014    for (let i = 0; i < props.length; i++) {4015        // static attribute4016        const prop = props[i];4017        if (prop.type === 6 /* ATTRIBUTE */) {4018            const { loc, name, value } = prop;4019            let isStatic = true;4020            if (name === 'ref') {4021                hasRef = true;4022                if (context.scopes.vFor > 0) {4023                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4024                }4025            }4026            // skip is on <component>, or is="vue:xxx"4027            if (name === 'is' &&4028                (isComponentTag(tag) ||4029                    (value && value.content.startsWith('vue:')) ||4030                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {4031                continue;4032            }4033            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));4034        }4035        else {4036            // directives4037            const { name, arg, exp, loc } = prop;4038            const isVBind = name === 'bind';4039            const isVOn = name === 'on';4040            // skip v-slot - it is handled by its dedicated transform.4041            if (name === 'slot') {4042                if (!isComponent) {4043                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));4044                }4045                continue;4046            }4047            // skip v-once/v-memo - they are handled by dedicated transforms.4048            if (name === 'once' || name === 'memo') {4049                continue;4050            }4051            // skip v-is and :is on <component>4052            if (name === 'is' ||4053                (isVBind &&4054                    isStaticArgOf(arg, 'is') &&4055                    (isComponentTag(tag) ||4056                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {4057                continue;4058            }4059            // skip v-on in SSR compilation4060            if (isVOn && ssr) {4061                continue;4062            }4063            if (4064            // #938: elements with dynamic keys should be forced into blocks4065            (isVBind && isStaticArgOf(arg, 'key')) ||4066                // inline before-update hooks need to force block so that it is invoked4067                // before children4068                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {4069                shouldUseBlock = true;4070            }4071            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {4072                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));4073            }4074            // special case for v-bind and v-on with no argument4075            if (!arg && (isVBind || isVOn)) {4076                hasDynamicKeys = true;4077                if (exp) {4078                    if (properties.length) {4079                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4080                        properties = [];4081                    }4082                    if (isVBind) {4083                        {4084                            // 2.x v-bind object order compat4085                            {4086                                const hasOverridableKeys = mergeArgs.some(arg => {4087                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {4088                                        return arg.properties.some(({ key }) => {4089                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||4090                                                !key.isStatic) {4091                                                return true;4092                                            }4093                                            return (key.content !== 'class' &&4094                                                key.content !== 'style' &&4095                                                !isOn(key.content));4096                                        });4097                                    }4098                                    else {4099                                        // dynamic expression4100                                        return true;4101                                    }4102                                });4103                                if (hasOverridableKeys) {4104                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);4105                                }4106                            }4107                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {4108                                mergeArgs.unshift(exp);4109                                continue;4110                            }4111                        }4112                        mergeArgs.push(exp);4113                    }4114                    else {4115                        // v-on="obj" -> toHandlers(obj)4116                        mergeArgs.push({4117                            type: 14 /* JS_CALL_EXPRESSION */,4118                            loc,4119                            callee: context.helper(TO_HANDLERS),4120                            arguments: [exp]4121                        });4122                    }4123                }4124                else {4125                    context.onError(createCompilerError(isVBind4126                        ? 34 /* X_V_BIND_NO_EXPRESSION */4127                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));4128                }4129                continue;4130            }4131            const directiveTransform = context.directiveTransforms[name];4132            if (directiveTransform) {4133                // has built-in directive transform.4134                const { props, needRuntime } = directiveTransform(prop, node, context);4135                !ssr && props.forEach(analyzePatchFlag);4136                properties.push(...props);4137                if (needRuntime) {4138                    runtimeDirectives.push(prop);4139                    if (isSymbol(needRuntime)) {4140                        directiveImportMap.set(prop, needRuntime);4141                    }4142                }4143            }4144            else {4145                // no built-in transform, this is a user custom directive.4146                runtimeDirectives.push(prop);4147                // custom dirs may use beforeUpdate so they need to force blocks4148                // to ensure before-update gets called before children update4149                if (hasChildren) {4150                    shouldUseBlock = true;4151                }4152            }4153        }4154    }4155    let propsExpression = undefined;4156    // has v-bind="object" or v-on="object", wrap with mergeProps4157    if (mergeArgs.length) {4158        if (properties.length) {4159            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4160        }4161        if (mergeArgs.length > 1) {4162            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4163        }4164        else {4165            // single v-bind with nothing else - no need for a mergeProps call4166            propsExpression = mergeArgs[0];4167        }4168    }4169    else if (properties.length) {4170        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4171    }4172    // patchFlag analysis4173    if (hasDynamicKeys) {4174        patchFlag |= 16 /* FULL_PROPS */;4175    }4176    else {4177        if (hasClassBinding && !isComponent) {4178            patchFlag |= 2 /* CLASS */;4179        }4180        if (hasStyleBinding && !isComponent) {4181            patchFlag |= 4 /* STYLE */;4182        }4183        if (dynamicPropNames.length) {4184            patchFlag |= 8 /* PROPS */;4185        }4186        if (hasHydrationEventBinding) {4187            patchFlag |= 32 /* HYDRATE_EVENTS */;4188        }4189    }4190    if (!shouldUseBlock &&4191        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4192        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4193        patchFlag |= 512 /* NEED_PATCH */;4194    }4195    // pre-normalize props, SSR is skipped for now4196    if (!context.inSSR && propsExpression) {4197        switch (propsExpression.type) {4198            case 15 /* JS_OBJECT_EXPRESSION */:4199                // means that there is no v-bind,4200                // but still need to deal with dynamic key binding4201                let classKeyIndex = -1;4202                let styleKeyIndex = -1;4203                let hasDynamicKey = false;4204                for (let i = 0; i < propsExpression.properties.length; i++) {4205                    const key = propsExpression.properties[i].key;4206                    if (isStaticExp(key)) {4207                        if (key.content === 'class') {4208                            classKeyIndex = i;4209                        }4210                        else if (key.content === 'style') {4211                            styleKeyIndex = i;4212                        }4213                    }4214                    else if (!key.isHandlerKey) {4215                        hasDynamicKey = true;4216                    }4217                }4218                const classProp = propsExpression.properties[classKeyIndex];4219                const styleProp = propsExpression.properties[styleKeyIndex];4220                // no dynamic key4221                if (!hasDynamicKey) {4222                    if (classProp && !isStaticExp(classProp.value)) {4223                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4224                    }4225                    if (styleProp &&4226                        !isStaticExp(styleProp.value) &&4227                        // the static style is compiled into an object,4228                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding4229                        (hasStyleBinding ||4230                            // v-bind:style and style both exist,4231                            // v-bind:style with static literal object4232                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4233                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4234                    }4235                }4236                else {4237                    // dynamic key binding, wrap with `normalizeProps`4238                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4239                }4240                break;4241            case 14 /* JS_CALL_EXPRESSION */:4242                // mergeProps call, do nothing4243                break;4244            default:4245                // single v-bind4246                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4247                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4248                        propsExpression4249                    ])4250                ]);4251                break;4252        }4253    }4254    return {4255        props: propsExpression,4256        directives: runtimeDirectives,4257        patchFlag,4258        dynamicPropNames,4259        shouldUseBlock4260    };4261}4262// Dedupe props in an object literal.4263// Literal duplicated attributes would have been warned during the parse phase,4264// however, it's possible to encounter duplicated `onXXX` handlers with different4265// modifiers. We also need to merge static and dynamic class / style attributes.4266// - onXXX handlers / style: merge into array4267// - class: merge into single expression with concatenation4268function dedupeProperties(properties) {4269    const knownProps = new Map();4270    const deduped = [];4271    for (let i = 0; i < properties.length; i++) {4272        const prop = properties[i];4273        // dynamic keys are always allowed4274        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4275            deduped.push(prop);4276            continue;4277        }4278        const name = prop.key.content;4279        const existing = knownProps.get(name);4280        if (existing) {4281            if (name === 'style' || name === 'class' || isOn(name)) {4282                mergeAsArray(existing, prop);4283            }4284            // unexpected duplicate, should have emitted error during parse4285        }4286        else {4287            knownProps.set(name, prop);4288            deduped.push(prop);4289        }4290    }4291    return deduped;4292}4293function mergeAsArray(existing, incoming) {4294    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4295        existing.value.elements.push(incoming.value);4296    }4297    else {4298        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4299    }4300}4301function buildDirectiveArgs(dir, context) {4302    const dirArgs = [];4303    const runtime = directiveImportMap.get(dir);4304    if (runtime) {4305        // built-in directive with runtime4306        dirArgs.push(context.helperString(runtime));4307    }4308    else {4309        {4310            // inject statement for resolving directive4311            context.helper(RESOLVE_DIRECTIVE);4312            context.directives.add(dir.name);4313            dirArgs.push(toValidAssetId(dir.name, `directive`));4314        }4315    }4316    const { loc } = dir;4317    if (dir.exp)4318        dirArgs.push(dir.exp);4319    if (dir.arg) {4320        if (!dir.exp) {4321            dirArgs.push(`void 0`);4322        }4323        dirArgs.push(dir.arg);4324    }4325    if (Object.keys(dir.modifiers).length) {4326        if (!dir.arg) {4327            if (!dir.exp) {4328                dirArgs.push(`void 0`);4329            }4330            dirArgs.push(`void 0`);4331        }4332        const trueExpression = createSimpleExpression(`true`, false, loc);4333        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4334    }4335    return createArrayExpression(dirArgs, dir.loc);4336}4337function stringifyDynamicPropNames(props) {4338    let propsNamesString = `[`;4339    for (let i = 0, l = props.length; i < l; i++) {4340        propsNamesString += JSON.stringify(props[i]);4341        if (i < l - 1)4342            propsNamesString += ', ';4343    }4344    return propsNamesString + `]`;4345}4346function isComponentTag(tag) {4347    return tag === 'component' || tag === 'Component';4348}4349const transformSlotOutlet = (node, context) => {4350    if (isSlotOutlet(node)) {4351        const { children, loc } = node;4352        const { slotName, slotProps } = processSlotOutlet(node, context);4353        const slotArgs = [4354            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4355            slotName,4356            '{}',4357            'undefined',4358            'true'4359        ];4360        let expectedLen = 2;4361        if (slotProps) {4362            slotArgs[2] = slotProps;4363            expectedLen = 3;4364        }4365        if (children.length) {4366            slotArgs[3] = createFunctionExpression([], children, false, false, loc);4367            expectedLen = 4;4368        }4369        if (context.scopeId && !context.slotted) {4370            expectedLen = 5;4371        }4372        slotArgs.splice(expectedLen); // remove unused arguments4373        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4374    }4375};4376function processSlotOutlet(node, context) {4377    let slotName = `"default"`;4378    let slotProps = undefined;4379    const nonNameProps = [];4380    for (let i = 0; i < node.props.length; i++) {4381        const p = node.props[i];4382        if (p.type === 6 /* ATTRIBUTE */) {4383            if (p.value) {4384                if (p.name === 'name') {4385                    slotName = JSON.stringify(p.value.content);4386                }4387                else {4388                    p.name = camelize(p.name);4389                    nonNameProps.push(p);4390                }4391            }4392        }4393        else {4394            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {4395                if (p.exp)4396                    slotName = p.exp;4397            }4398            else {4399                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4400                    p.arg.content = camelize(p.arg.content);4401                }4402                nonNameProps.push(p);4403            }4404        }4405    }4406    if (nonNameProps.length > 0) {4407        const { props, directives } = buildProps(node, context, nonNameProps);4408        slotProps = props;4409        if (directives.length) {4410            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4411        }4412    }4413    return {4414        slotName,4415        slotProps4416    };4417}4418const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4419const transformOn = (dir, node, context, augmentor) => {4420    const { loc, modifiers, arg } = dir;4421    if (!dir.exp && !modifiers.length) {4422        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4423    }4424    let eventName;4425    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4426        if (arg.isStatic) {4427            let rawName = arg.content;4428            // TODO deprecate @vnodeXXX usage4429            if (rawName.startsWith('vue:')) {4430                rawName = `vnode-${rawName.slice(4)}`;4431            }4432            // for all event listeners, auto convert it to camelCase. See issue #22494433            eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);4434        }4435        else {4436            // #23884437            eventName = createCompoundExpression([4438                `${context.helperString(TO_HANDLER_KEY)}(`,4439                arg,4440                `)`4441            ]);4442        }4443    }4444    else {4445        // already a compound expression.4446        eventName = arg;4447        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4448        eventName.children.push(`)`);4449    }4450    // handler processing4451    let exp = dir.exp;4452    if (exp && !exp.content.trim()) {4453        exp = undefined;4454    }4455    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4456    if (exp) {4457        const isMemberExp = isMemberExpression(exp.content);4458        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4459        const hasMultipleStatements = exp.content.includes(`;`);4460        {4461            validateBrowserExpression(exp, context, false, hasMultipleStatements);4462        }4463        if (isInlineStatement || (shouldCache && isMemberExp)) {4464            // wrap inline statement in a function expression4465            exp = createCompoundExpression([4466                `${isInlineStatement4467                    ? `$event`4468                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4469                exp,4470                hasMultipleStatements ? `}` : `)`4471            ]);4472        }4473    }4474    let ret = {4475        props: [4476            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4477        ]4478    };4479    // apply extended compiler augmentor4480    if (augmentor) {4481        ret = augmentor(ret);4482    }4483    if (shouldCache) {4484        // cache handlers so that it's always the same handler being passed down.4485        // this avoids unnecessary re-renders when users use inline handlers on4486        // components.4487        ret.props[0].value = context.cache(ret.props[0].value);4488    }4489    // mark the key as handler for props normalization check4490    ret.props.forEach(p => (p.key.isHandlerKey = true));4491    return ret;4492};4493// v-bind without arg is handled directly in ./transformElements.ts due to it affecting4494// codegen for the entire props object. This transform here is only for v-bind4495// *with* args.4496const transformBind = (dir, _node, context) => {4497    const { exp, modifiers, loc } = dir;4498    const arg = dir.arg;4499    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {4500        arg.children.unshift(`(`);4501        arg.children.push(`) || ""`);4502    }4503    else if (!arg.isStatic) {4504        arg.content = `${arg.content} || ""`;4505    }4506    // .sync is replaced by v-model:arg4507    if (modifiers.includes('camel')) {4508        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4509            if (arg.isStatic) {4510                arg.content = camelize(arg.content);4511            }4512            else {4513                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;4514            }4515        }4516        else {4517            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);4518            arg.children.push(`)`);4519        }4520    }4521    if (!context.inSSR) {4522        if (modifiers.includes('prop')) {4523            injectPrefix(arg, '.');4524        }4525        if (modifiers.includes('attr')) {4526            injectPrefix(arg, '^');4527        }4528    }4529    if (!exp ||4530        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {4531        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));4532        return {4533            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]4534        };4535    }4536    return {4537        props: [createObjectProperty(arg, exp)]4538    };4539};4540const injectPrefix = (arg, prefix) => {4541    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4542        if (arg.isStatic) {4543            arg.content = prefix + arg.content;4544        }4545        else {4546            arg.content = `\`${prefix}\${${arg.content}}\``;4547        }4548    }4549    else {4550        arg.children.unshift(`'${prefix}' + (`);4551        arg.children.push(`)`);4552    }4553};4554// Merge adjacent text nodes and expressions into a single expression4555// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.4556const transformText = (node, context) => {4557    if (node.type === 0 /* ROOT */ ||4558        node.type === 1 /* ELEMENT */ ||4559        node.type === 11 /* FOR */ ||4560        node.type === 10 /* IF_BRANCH */) {4561        // perform the transform on node exit so that all expressions have already4562        // been processed.4563        return () => {4564            const children = node.children;4565            let currentContainer = undefined;4566            let hasText = false;4567            for (let i = 0; i < children.length; i++) {4568                const child = children[i];4569                if (isText(child)) {4570                    hasText = true;4571                    for (let j = i + 1; j < children.length; j++) {4572                        const next = children[j];4573                        if (isText(next)) {4574                            if (!currentContainer) {4575                                currentContainer = children[i] = {4576                                    type: 8 /* COMPOUND_EXPRESSION */,4577                                    loc: child.loc,4578                                    children: [child]4579                                };4580                            }4581                            // merge adjacent text node into current4582                            currentContainer.children.push(` + `, next);4583                            children.splice(j, 1);4584                            j--;4585                        }4586                        else {4587                            currentContainer = undefined;4588                            break;4589                        }4590                    }4591                }4592            }4593            if (!hasText ||4594                // if this is a plain element with a single text child, leave it4595                // as-is since the runtime has dedicated fast path for this by directly4596                // setting textContent of the element.4597                // for component root it's always normalized anyway.4598                (children.length === 1 &&4599                    (node.type === 0 /* ROOT */ ||4600                        (node.type === 1 /* ELEMENT */ &&4601                            node.tagType === 0 /* ELEMENT */ &&4602                            // #37564603                            // custom directives can potentially add DOM elements arbitrarily,4604                            // we need to avoid setting textContent of the element at runtime4605                            // to avoid accidentally overwriting the DOM elements added4606                            // by the user through custom directives.4607                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&4608                                !context.directiveTransforms[p.name]) &&4609                            // in compat mode, <template> tags with no special directives4610                            // will be rendered as a fragment so its children must be4611                            // converted into vnodes.4612                            !(node.tag === 'template'))))) {4613                return;4614            }4615            // pre-convert text nodes into createTextVNode(text) calls to avoid4616            // runtime normalization.4617            for (let i = 0; i < children.length; i++) {4618                const child = children[i];4619                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {4620                    const callArgs = [];4621                    // createTextVNode defaults to single whitespace, so if it is a4622                    // single space the code could be an empty call to save bytes.4623                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {4624                        callArgs.push(child);4625                    }4626                    // mark dynamic text with flag so it gets patched inside a block4627                    if (!context.ssr &&4628                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4629                        callArgs.push(1 /* TEXT */ +4630                            (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));4631                    }4632                    children[i] = {4633                        type: 12 /* TEXT_CALL */,4634                        content: child,4635                        loc: child.loc,4636                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)4637                    };4638                }4639            }4640        };4641    }4642};4643const seen = new WeakSet();4644const transformOnce = (node, context) => {4645    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {4646        if (seen.has(node) || context.inVOnce) {4647            return;4648        }4649        seen.add(node);4650        context.inVOnce = true;4651        context.helper(SET_BLOCK_TRACKING);4652        return () => {4653            context.inVOnce = false;4654            const cur = context.currentNode;4655            if (cur.codegenNode) {4656                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);4657            }4658        };4659    }4660};4661const transformModel = (dir, node, context) => {4662    const { exp, arg } = dir;4663    if (!exp) {4664        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));4665        return createTransformProps();4666    }4667    const rawExp = exp.loc.source;4668    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;4669    // im SFC <script setup> inline mode, the exp may have been transformed into4670    // _unref(exp)4671    context.bindingMetadata[rawExp];4672    const maybeRef = !true    /* SETUP_CONST */;4673    if (!expString.trim() ||4674        (!isMemberExpression(expString) && !maybeRef)) {4675        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));4676        return createTransformProps();4677    }4678    const propName = arg ? arg : createSimpleExpression('modelValue', true);4679    const eventName = arg4680        ? isStaticExp(arg)4681            ? `onUpdate:${arg.content}`4682            : createCompoundExpression(['"onUpdate:" + ', arg])4683        : `onUpdate:modelValue`;4684    let assignmentExp;4685    const eventArg = context.isTS ? `($event: any)` : `$event`;4686    {4687        assignmentExp = createCompoundExpression([4688            `${eventArg} => ((`,4689            exp,4690            `) = $event)`4691        ]);4692    }4693    const props = [4694        // modelValue: foo4695        createObjectProperty(propName, dir.exp),4696        // "onUpdate:modelValue": $event => (foo = $event)4697        createObjectProperty(eventName, assignmentExp)4698    ];4699    // modelModifiers: { foo: true, "bar-baz": true }4700    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {4701        const modifiers = dir.modifiers4702            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)4703            .join(`, `);4704        const modifiersKey = arg4705            ? isStaticExp(arg)4706                ? `${arg.content}Modifiers`4707                : createCompoundExpression([arg, ' + "Modifiers"'])4708            : `modelModifiers`;4709        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));4710    }4711    return createTransformProps(props);4712};4713function createTransformProps(props = []) {4714    return { props };4715}4716const validDivisionCharRE = /[\w).+\-_$\]]/;4717const transformFilter = (node, context) => {4718    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {4719        return;4720    }4721    if (node.type === 5 /* INTERPOLATION */) {4722        // filter rewrite is applied before expression transform so only4723        // simple expressions are possible at this stage4724        rewriteFilter(node.content, context);4725    }4726    if (node.type === 1 /* ELEMENT */) {4727        node.props.forEach((prop) => {4728            if (prop.type === 7 /* DIRECTIVE */ &&4729                prop.name !== 'for' &&4730                prop.exp) {4731                rewriteFilter(prop.exp, context);4732            }...compiler-core.esm-bundler.js
Source:compiler-core.esm-bundler.js  
...772    else {773        return value;774    }775}776function isCompatEnabled(key, context) {777    const mode = getCompatValue('MODE', context);778    const value = getCompatValue(key, context);779    // in v3 mode, only enable if explicitly set to true780    // otherwise enable for any non-false value781    return mode === 3 ? value === true : value !== false;782}783function checkCompatEnabled(key, context, loc, ...args) {784    const enabled = isCompatEnabled(key, context);785    if ((process.env.NODE_ENV !== 'production') && enabled) {786        warnDeprecation(key, context, loc, ...args);787    }788    return enabled;789}790function warnDeprecation(key, context, loc, ...args) {791    const val = getCompatValue(key, context);792    if (val === 'suppress-warning') {793        return;794    }795    const { message, link } = deprecationData[key];796    const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n  Details: ${link}` : ``}`;797    const err = new SyntaxError(msg);798    err.code = key;799    if (loc)800        err.loc = loc;801    context.onWarn(err);802}803// The default decoder only provides escapes for characters reserved as part of804// the template syntax, and is only used if the custom renderer did not provide805// a platform-specific decoder.806const decodeRE = /&(gt|lt|amp|apos|quot);/g;807const decodeMap = {808    gt: '>',809    lt: '<',810    amp: '&',811    apos: "'",812    quot: '"'813};814const defaultParserOptions = {815    delimiters: [`{{`, `}}`],816    getNamespace: () => 0 /* HTML */,817    getTextMode: () => 0 /* DATA */,818    isVoidTag: NO,819    isPreTag: NO,820    isCustomElement: NO,821    decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),822    onError: defaultOnError,823    onWarn: defaultOnWarn,824    comments: (process.env.NODE_ENV !== 'production')825};826function baseParse(content, options = {}) {827    const context = createParserContext(content, options);828    const start = getCursor(context);829    return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));830}831function createParserContext(content, rawOptions) {832    const options = extend({}, defaultParserOptions);833    let key;834    for (key in rawOptions) {835        // @ts-ignore836        options[key] =837            rawOptions[key] === undefined838                ? defaultParserOptions[key]839                : rawOptions[key];840    }841    return {842        options,843        column: 1,844        line: 1,845        offset: 0,846        originalSource: content,847        source: content,848        inPre: false,849        inVPre: false,850        onWarn: options.onWarn851    };852}853function parseChildren(context, mode, ancestors) {854    const parent = last(ancestors);855    const ns = parent ? parent.ns : 0 /* HTML */;856    const nodes = [];857    while (!isEnd(context, mode, ancestors)) {858        const s = context.source;859        let node = undefined;860        if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {861            if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {862                // '{{'863                node = parseInterpolation(context, mode);864            }865            else if (mode === 0 /* DATA */ && s[0] === '<') {866                // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state867                if (s.length === 1) {868                    emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);869                }870                else if (s[1] === '!') {871                    // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state872                    if (startsWith(s, '<!--')) {873                        node = parseComment(context);874                    }875                    else if (startsWith(s, '<!DOCTYPE')) {876                        // Ignore DOCTYPE by a limitation.877                        node = parseBogusComment(context);878                    }879                    else if (startsWith(s, '<![CDATA[')) {880                        if (ns !== 0 /* HTML */) {881                            node = parseCDATA(context, ancestors);882                        }883                        else {884                            emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);885                            node = parseBogusComment(context);886                        }887                    }888                    else {889                        emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);890                        node = parseBogusComment(context);891                    }892                }893                else if (s[1] === '/') {894                    // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state895                    if (s.length === 2) {896                        emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);897                    }898                    else if (s[2] === '>') {899                        emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);900                        advanceBy(context, 3);901                        continue;902                    }903                    else if (/[a-z]/i.test(s[2])) {904                        emitError(context, 23 /* X_INVALID_END_TAG */);905                        parseTag(context, 1 /* End */, parent);906                        continue;907                    }908                    else {909                        emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);910                        node = parseBogusComment(context);911                    }912                }913                else if (/[a-z]/i.test(s[1])) {914                    node = parseElement(context, ancestors);915                    // 2.x <template> with no directive compat916                    if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&917                        node &&918                        node.tag === 'template' &&919                        !node.props.some(p => p.type === 7 /* DIRECTIVE */ &&920                            isSpecialTemplateDirective(p.name))) {921                        (process.env.NODE_ENV !== 'production') &&922                            warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);923                        node = node.children;924                    }925                }926                else if (s[1] === '?') {927                    emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);928                    node = parseBogusComment(context);929                }930                else {931                    emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);932                }933            }934        }935        if (!node) {936            node = parseText(context, mode);937        }938        if (isArray(node)) {939            for (let i = 0; i < node.length; i++) {940                pushNode(nodes, node[i]);941            }942        }943        else {944            pushNode(nodes, node);945        }946    }947    // Whitespace handling strategy like v2948    let removedWhitespace = false;949    if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {950        const shouldCondense = context.options.whitespace !== 'preserve';951        for (let i = 0; i < nodes.length; i++) {952            const node = nodes[i];953            if (!context.inPre && node.type === 2 /* TEXT */) {954                if (!/[^\t\r\n\f ]/.test(node.content)) {955                    const prev = nodes[i - 1];956                    const next = nodes[i + 1];957                    // Remove if:958                    // - the whitespace is the first or last node, or:959                    // - (condense mode) the whitespace is adjacent to a comment, or:960                    // - (condense mode) the whitespace is between two elements AND contains newline961                    if (!prev ||962                        !next ||963                        (shouldCondense &&964                            (prev.type === 3 /* COMMENT */ ||965                                next.type === 3 /* COMMENT */ ||966                                (prev.type === 1 /* ELEMENT */ &&967                                    next.type === 1 /* ELEMENT */ &&968                                    /[\r\n]/.test(node.content))))) {969                        removedWhitespace = true;970                        nodes[i] = null;971                    }972                    else {973                        // Otherwise, the whitespace is condensed into a single space974                        node.content = ' ';975                    }976                }977                else if (shouldCondense) {978                    // in condense mode, consecutive whitespaces in text are condensed979                    // down to a single space.980                    node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');981                }982            }983            // Remove comment nodes if desired by configuration.984            else if (node.type === 3 /* COMMENT */ && !context.options.comments) {985                removedWhitespace = true;986                nodes[i] = null;987            }988        }989        if (context.inPre && parent && context.options.isPreTag(parent.tag)) {990            // remove leading newline per html spec991            // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element992            const first = nodes[0];993            if (first && first.type === 2 /* TEXT */) {994                first.content = first.content.replace(/^\r?\n/, '');995            }996        }997    }998    return removedWhitespace ? nodes.filter(Boolean) : nodes;999}1000function pushNode(nodes, node) {1001    if (node.type === 2 /* TEXT */) {1002        const prev = last(nodes);1003        // Merge if both this and the previous node are text and those are1004        // consecutive. This happens for cases like "a < b".1005        if (prev &&1006            prev.type === 2 /* TEXT */ &&1007            prev.loc.end.offset === node.loc.start.offset) {1008            prev.content += node.content;1009            prev.loc.end = node.loc.end;1010            prev.loc.source += node.loc.source;1011            return;1012        }1013    }1014    nodes.push(node);1015}1016function parseCDATA(context, ancestors) {1017    advanceBy(context, 9);1018    const nodes = parseChildren(context, 3 /* CDATA */, ancestors);1019    if (context.source.length === 0) {1020        emitError(context, 6 /* EOF_IN_CDATA */);1021    }1022    else {1023        advanceBy(context, 3);1024    }1025    return nodes;1026}1027function parseComment(context) {1028    const start = getCursor(context);1029    let content;1030    // Regular comment.1031    const match = /--(\!)?>/.exec(context.source);1032    if (!match) {1033        content = context.source.slice(4);1034        advanceBy(context, context.source.length);1035        emitError(context, 7 /* EOF_IN_COMMENT */);1036    }1037    else {1038        if (match.index <= 3) {1039            emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);1040        }1041        if (match[1]) {1042            emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);1043        }1044        content = context.source.slice(4, match.index);1045        // Advancing with reporting nested comments.1046        const s = context.source.slice(0, match.index);1047        let prevIndex = 1, nestedIndex = 0;1048        while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {1049            advanceBy(context, nestedIndex - prevIndex + 1);1050            if (nestedIndex + 4 < s.length) {1051                emitError(context, 16 /* NESTED_COMMENT */);1052            }1053            prevIndex = nestedIndex + 1;1054        }1055        advanceBy(context, match.index + match[0].length - prevIndex + 1);1056    }1057    return {1058        type: 3 /* COMMENT */,1059        content,1060        loc: getSelection(context, start)1061    };1062}1063function parseBogusComment(context) {1064    const start = getCursor(context);1065    const contentStart = context.source[1] === '?' ? 1 : 2;1066    let content;1067    const closeIndex = context.source.indexOf('>');1068    if (closeIndex === -1) {1069        content = context.source.slice(contentStart);1070        advanceBy(context, context.source.length);1071    }1072    else {1073        content = context.source.slice(contentStart, closeIndex);1074        advanceBy(context, closeIndex + 1);1075    }1076    return {1077        type: 3 /* COMMENT */,1078        content,1079        loc: getSelection(context, start)1080    };1081}1082function parseElement(context, ancestors) {1083    // Start tag.1084    const wasInPre = context.inPre;1085    const wasInVPre = context.inVPre;1086    const parent = last(ancestors);1087    const element = parseTag(context, 0 /* Start */, parent);1088    const isPreBoundary = context.inPre && !wasInPre;1089    const isVPreBoundary = context.inVPre && !wasInVPre;1090    if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {1091        // #4030 self-closing <pre> tag1092        if (isPreBoundary) {1093            context.inPre = false;1094        }1095        if (isVPreBoundary) {1096            context.inVPre = false;1097        }1098        return element;1099    }1100    // Children.1101    ancestors.push(element);1102    const mode = context.options.getTextMode(element, parent);1103    const children = parseChildren(context, mode, ancestors);1104    ancestors.pop();1105    // 2.x inline-template compat1106    {1107        const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');1108        if (inlineTemplateProp &&1109            checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {1110            const loc = getSelection(context, element.loc.end);1111            inlineTemplateProp.value = {1112                type: 2 /* TEXT */,1113                content: loc.source,1114                loc1115            };1116        }1117    }1118    element.children = children;1119    // End tag.1120    if (startsWithEndTagOpen(context.source, element.tag)) {1121        parseTag(context, 1 /* End */, parent);1122    }1123    else {1124        emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);1125        if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {1126            const first = children[0];1127            if (first && startsWith(first.loc.source, '<!--')) {1128                emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);1129            }1130        }1131    }1132    element.loc = getSelection(context, element.loc.start);1133    if (isPreBoundary) {1134        context.inPre = false;1135    }1136    if (isVPreBoundary) {1137        context.inVPre = false;1138    }1139    return element;1140}1141const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);1142function parseTag(context, type, parent) {1143    // Tag open.1144    const start = getCursor(context);1145    const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);1146    const tag = match[1];1147    const ns = context.options.getNamespace(tag, parent);1148    advanceBy(context, match[0].length);1149    advanceSpaces(context);1150    // save current state in case we need to re-parse attributes with v-pre1151    const cursor = getCursor(context);1152    const currentSource = context.source;1153    // check <pre> tag1154    if (context.options.isPreTag(tag)) {1155        context.inPre = true;1156    }1157    // Attributes.1158    let props = parseAttributes(context, type);1159    // check v-pre1160    if (type === 0 /* Start */ &&1161        !context.inVPre &&1162        props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {1163        context.inVPre = true;1164        // reset context1165        extend(context, cursor);1166        context.source = currentSource;1167        // re-parse attrs and filter out v-pre itself1168        props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');1169    }1170    // Tag close.1171    let isSelfClosing = false;1172    if (context.source.length === 0) {1173        emitError(context, 9 /* EOF_IN_TAG */);1174    }1175    else {1176        isSelfClosing = startsWith(context.source, '/>');1177        if (type === 1 /* End */ && isSelfClosing) {1178            emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);1179        }1180        advanceBy(context, isSelfClosing ? 2 : 1);1181    }1182    if (type === 1 /* End */) {1183        return;1184    }1185    // 2.x deprecation checks1186    if ((process.env.NODE_ENV !== 'production') &&1187        isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {1188        let hasIf = false;1189        let hasFor = false;1190        for (let i = 0; i < props.length; i++) {1191            const p = props[i];1192            if (p.type === 7 /* DIRECTIVE */) {1193                if (p.name === 'if') {1194                    hasIf = true;1195                }1196                else if (p.name === 'for') {1197                    hasFor = true;1198                }1199            }1200            if (hasIf && hasFor) {1201                warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));1202                break;1203            }1204        }1205    }1206    let tagType = 0 /* ELEMENT */;1207    if (!context.inVPre) {1208        if (tag === 'slot') {1209            tagType = 2 /* SLOT */;1210        }1211        else if (tag === 'template') {1212            if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {1213                tagType = 3 /* TEMPLATE */;1214            }1215        }1216        else if (isComponent(tag, props, context)) {1217            tagType = 1 /* COMPONENT */;1218        }1219    }1220    return {1221        type: 1 /* ELEMENT */,1222        ns,1223        tag,1224        tagType,1225        props,1226        isSelfClosing,1227        children: [],1228        loc: getSelection(context, start),1229        codegenNode: undefined // to be created during transform phase1230    };1231}1232function isComponent(tag, props, context) {1233    const options = context.options;1234    if (options.isCustomElement(tag)) {1235        return false;1236    }1237    if (tag === 'component' ||1238        /^[A-Z]/.test(tag) ||1239        isCoreComponent(tag) ||1240        (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||1241        (options.isNativeTag && !options.isNativeTag(tag))) {1242        return true;1243    }1244    // at this point the tag should be a native tag, but check for potential "is"1245    // casting1246    for (let i = 0; i < props.length; i++) {1247        const p = props[i];1248        if (p.type === 6 /* ATTRIBUTE */) {1249            if (p.name === 'is' && p.value) {1250                if (p.value.content.startsWith('vue:')) {1251                    return true;1252                }1253                else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1254                    return true;1255                }1256            }1257        }1258        else {1259            // directive1260            // v-is (TODO Deprecate)1261            if (p.name === 'is') {1262                return true;1263            }1264            else if (1265            // :is on plain element - only treat as component in compat mode1266            p.name === 'bind' &&1267                isStaticArgOf(p.arg, 'is') &&1268                true &&1269                checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {1270                return true;1271            }1272        }1273    }1274}1275function parseAttributes(context, type) {1276    const props = [];1277    const attributeNames = new Set();1278    while (context.source.length > 0 &&1279        !startsWith(context.source, '>') &&1280        !startsWith(context.source, '/>')) {1281        if (startsWith(context.source, '/')) {1282            emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);1283            advanceBy(context, 1);1284            advanceSpaces(context);1285            continue;1286        }1287        if (type === 1 /* End */) {1288            emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);1289        }1290        const attr = parseAttribute(context, attributeNames);1291        // Trim whitespace between class1292        // https://github.com/vuejs/vue-next/issues/42511293        if (attr.type === 6 /* ATTRIBUTE */ &&1294            attr.value &&1295            attr.name === 'class') {1296            attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();1297        }1298        if (type === 0 /* Start */) {1299            props.push(attr);1300        }1301        if (/^[^\t\r\n\f />]/.test(context.source)) {1302            emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);1303        }1304        advanceSpaces(context);1305    }1306    return props;1307}1308function parseAttribute(context, nameSet) {1309    // Name.1310    const start = getCursor(context);1311    const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);1312    const name = match[0];1313    if (nameSet.has(name)) {1314        emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);1315    }1316    nameSet.add(name);1317    if (name[0] === '=') {1318        emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);1319    }1320    {1321        const pattern = /["'<]/g;1322        let m;1323        while ((m = pattern.exec(name))) {1324            emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);1325        }1326    }1327    advanceBy(context, name.length);1328    // Value1329    let value = undefined;1330    if (/^[\t\r\n\f ]*=/.test(context.source)) {1331        advanceSpaces(context);1332        advanceBy(context, 1);1333        advanceSpaces(context);1334        value = parseAttributeValue(context);1335        if (!value) {1336            emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);1337        }1338    }1339    const loc = getSelection(context, start);1340    if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {1341        const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);1342        let isPropShorthand = startsWith(name, '.');1343        let dirName = match[1] ||1344            (isPropShorthand || startsWith(name, ':')1345                ? 'bind'1346                : startsWith(name, '@')1347                    ? 'on'1348                    : 'slot');1349        let arg;1350        if (match[2]) {1351            const isSlot = dirName === 'slot';1352            const startOffset = name.lastIndexOf(match[2]);1353            const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));1354            let content = match[2];1355            let isStatic = true;1356            if (content.startsWith('[')) {1357                isStatic = false;1358                if (!content.endsWith(']')) {1359                    emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);1360                    content = content.slice(1);1361                }1362                else {1363                    content = content.slice(1, content.length - 1);1364                }1365            }1366            else if (isSlot) {1367                // #1241 special case for v-slot: vuetify relies extensively on slot1368                // names containing dots. v-slot doesn't have any modifiers and Vue 2.x1369                // supports such usage so we are keeping it consistent with 2.x.1370                content += match[3] || '';1371            }1372            arg = {1373                type: 4 /* SIMPLE_EXPRESSION */,1374                content,1375                isStatic,1376                constType: isStatic1377                    ? 3 /* CAN_STRINGIFY */1378                    : 0 /* NOT_CONSTANT */,1379                loc1380            };1381        }1382        if (value && value.isQuoted) {1383            const valueLoc = value.loc;1384            valueLoc.start.offset++;1385            valueLoc.start.column++;1386            valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);1387            valueLoc.source = valueLoc.source.slice(1, -1);1388        }1389        const modifiers = match[3] ? match[3].slice(1).split('.') : [];1390        if (isPropShorthand)1391            modifiers.push('prop');1392        // 2.x compat v-bind:foo.sync -> v-model:foo1393        if (dirName === 'bind' && arg) {1394            if (modifiers.includes('sync') &&1395                checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {1396                dirName = 'model';1397                modifiers.splice(modifiers.indexOf('sync'), 1);1398            }1399            if ((process.env.NODE_ENV !== 'production') && modifiers.includes('prop')) {1400                checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);1401            }1402        }1403        return {1404            type: 7 /* DIRECTIVE */,1405            name: dirName,1406            exp: value && {1407                type: 4 /* SIMPLE_EXPRESSION */,1408                content: value.content,1409                isStatic: false,1410                // Treat as non-constant by default. This can be potentially set to1411                // other values by `transformExpression` to make it eligible for hoisting.1412                constType: 0 /* NOT_CONSTANT */,1413                loc: value.loc1414            },1415            arg,1416            modifiers,1417            loc1418        };1419    }1420    // missing directive name or illegal directive name1421    if (!context.inVPre && startsWith(name, 'v-')) {1422        emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);1423    }1424    return {1425        type: 6 /* ATTRIBUTE */,1426        name,1427        value: value && {1428            type: 2 /* TEXT */,1429            content: value.content,1430            loc: value.loc1431        },1432        loc1433    };1434}1435function parseAttributeValue(context) {1436    const start = getCursor(context);1437    let content;1438    const quote = context.source[0];1439    const isQuoted = quote === `"` || quote === `'`;1440    if (isQuoted) {1441        // Quoted value.1442        advanceBy(context, 1);1443        const endIndex = context.source.indexOf(quote);1444        if (endIndex === -1) {1445            content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);1446        }1447        else {1448            content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);1449            advanceBy(context, 1);1450        }1451    }1452    else {1453        // Unquoted1454        const match = /^[^\t\r\n\f >]+/.exec(context.source);1455        if (!match) {1456            return undefined;1457        }1458        const unexpectedChars = /["'<=`]/g;1459        let m;1460        while ((m = unexpectedChars.exec(match[0]))) {1461            emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);1462        }1463        content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);1464    }1465    return { content, isQuoted, loc: getSelection(context, start) };1466}1467function parseInterpolation(context, mode) {1468    const [open, close] = context.options.delimiters;1469    const closeIndex = context.source.indexOf(close, open.length);1470    if (closeIndex === -1) {1471        emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);1472        return undefined;1473    }1474    const start = getCursor(context);1475    advanceBy(context, open.length);1476    const innerStart = getCursor(context);1477    const innerEnd = getCursor(context);1478    const rawContentLength = closeIndex - open.length;1479    const rawContent = context.source.slice(0, rawContentLength);1480    const preTrimContent = parseTextData(context, rawContentLength, mode);1481    const content = preTrimContent.trim();1482    const startOffset = preTrimContent.indexOf(content);1483    if (startOffset > 0) {1484        advancePositionWithMutation(innerStart, rawContent, startOffset);1485    }1486    const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);1487    advancePositionWithMutation(innerEnd, rawContent, endOffset);1488    advanceBy(context, close.length);1489    return {1490        type: 5 /* INTERPOLATION */,1491        content: {1492            type: 4 /* SIMPLE_EXPRESSION */,1493            isStatic: false,1494            // Set `isConstant` to false by default and will decide in transformExpression1495            constType: 0 /* NOT_CONSTANT */,1496            content,1497            loc: getSelection(context, innerStart, innerEnd)1498        },1499        loc: getSelection(context, start)1500    };1501}1502function parseText(context, mode) {1503    const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];1504    let endIndex = context.source.length;1505    for (let i = 0; i < endTokens.length; i++) {1506        const index = context.source.indexOf(endTokens[i], 1);1507        if (index !== -1 && endIndex > index) {1508            endIndex = index;1509        }1510    }1511    const start = getCursor(context);1512    const content = parseTextData(context, endIndex, mode);1513    return {1514        type: 2 /* TEXT */,1515        content,1516        loc: getSelection(context, start)1517    };1518}1519/**1520 * Get text data with a given length from the current location.1521 * This translates HTML entities in the text data.1522 */1523function parseTextData(context, length, mode) {1524    const rawText = context.source.slice(0, length);1525    advanceBy(context, length);1526    if (mode === 2 /* RAWTEXT */ ||1527        mode === 3 /* CDATA */ ||1528        rawText.indexOf('&') === -1) {1529        return rawText;1530    }1531    else {1532        // DATA or RCDATA containing "&"". Entity decoding required.1533        return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);1534    }1535}1536function getCursor(context) {1537    const { column, line, offset } = context;1538    return { column, line, offset };1539}1540function getSelection(context, start, end) {1541    end = end || getCursor(context);1542    return {1543        start,1544        end,1545        source: context.originalSource.slice(start.offset, end.offset)1546    };1547}1548function last(xs) {1549    return xs[xs.length - 1];1550}1551function startsWith(source, searchString) {1552    return source.startsWith(searchString);1553}1554function advanceBy(context, numberOfCharacters) {1555    const { source } = context;1556    advancePositionWithMutation(context, source, numberOfCharacters);1557    context.source = source.slice(numberOfCharacters);1558}1559function advanceSpaces(context) {1560    const match = /^[\t\r\n\f ]+/.exec(context.source);1561    if (match) {1562        advanceBy(context, match[0].length);1563    }1564}1565function getNewPosition(context, start, numberOfCharacters) {1566    return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);1567}1568function emitError(context, code, offset, loc = getCursor(context)) {1569    if (offset) {1570        loc.offset += offset;1571        loc.column += offset;1572    }1573    context.options.onError(createCompilerError(code, {1574        start: loc,1575        end: loc,1576        source: ''1577    }));1578}1579function isEnd(context, mode, ancestors) {1580    const s = context.source;1581    switch (mode) {1582        case 0 /* DATA */:1583            if (startsWith(s, '</')) {1584                // TODO: probably bad performance1585                for (let i = ancestors.length - 1; i >= 0; --i) {1586                    if (startsWithEndTagOpen(s, ancestors[i].tag)) {1587                        return true;1588                    }1589                }1590            }1591            break;1592        case 1 /* RCDATA */:1593        case 2 /* RAWTEXT */: {1594            const parent = last(ancestors);1595            if (parent && startsWithEndTagOpen(s, parent.tag)) {1596                return true;1597            }1598            break;1599        }1600        case 3 /* CDATA */:1601            if (startsWith(s, ']]>')) {1602                return true;1603            }1604            break;1605    }1606    return !s;1607}1608function startsWithEndTagOpen(source, tag) {1609    return (startsWith(source, '</') &&1610        source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&1611        /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));1612}1613function hoistStatic(root, context) {1614    walk(root, context, 1615    // Root node is unfortunately non-hoistable due to potential parent1616    // fallthrough attributes.1617    isSingleElementRoot(root, root.children[0]));1618}1619function isSingleElementRoot(root, child) {1620    const { children } = root;1621    return (children.length === 1 &&1622        child.type === 1 /* ELEMENT */ &&1623        !isSlotOutlet(child));1624}1625function walk(node, context, doNotHoistNode = false) {1626    const { children } = node;1627    const originalCount = children.length;1628    let hoistedCount = 0;1629    for (let i = 0; i < children.length; i++) {1630        const child = children[i];1631        // only plain elements & text calls are eligible for hoisting.1632        if (child.type === 1 /* ELEMENT */ &&1633            child.tagType === 0 /* ELEMENT */) {1634            const constantType = doNotHoistNode1635                ? 0 /* NOT_CONSTANT */1636                : getConstantType(child, context);1637            if (constantType > 0 /* NOT_CONSTANT */) {1638                if (constantType >= 2 /* CAN_HOIST */) {1639                    child.codegenNode.patchFlag =1640                        -1 /* HOISTED */ + ((process.env.NODE_ENV !== 'production') ? ` /* HOISTED */` : ``);1641                    child.codegenNode = context.hoist(child.codegenNode);1642                    hoistedCount++;1643                    continue;1644                }1645            }1646            else {1647                // node may contain dynamic children, but its props may be eligible for1648                // hoisting.1649                const codegenNode = child.codegenNode;1650                if (codegenNode.type === 13 /* VNODE_CALL */) {1651                    const flag = getPatchFlag(codegenNode);1652                    if ((!flag ||1653                        flag === 512 /* NEED_PATCH */ ||1654                        flag === 1 /* TEXT */) &&1655                        getGeneratedPropsConstantType(child, context) >=1656                            2 /* CAN_HOIST */) {1657                        const props = getNodeProps(child);1658                        if (props) {1659                            codegenNode.props = context.hoist(props);1660                        }1661                    }1662                    if (codegenNode.dynamicProps) {1663                        codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);1664                    }1665                }1666            }1667        }1668        else if (child.type === 12 /* TEXT_CALL */ &&1669            getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {1670            child.codegenNode = context.hoist(child.codegenNode);1671            hoistedCount++;1672        }1673        // walk further1674        if (child.type === 1 /* ELEMENT */) {1675            const isComponent = child.tagType === 1 /* COMPONENT */;1676            if (isComponent) {1677                context.scopes.vSlot++;1678            }1679            walk(child, context);1680            if (isComponent) {1681                context.scopes.vSlot--;1682            }1683        }1684        else if (child.type === 11 /* FOR */) {1685            // Do not hoist v-for single child because it has to be a block1686            walk(child, context, child.children.length === 1);1687        }1688        else if (child.type === 9 /* IF */) {1689            for (let i = 0; i < child.branches.length; i++) {1690                // Do not hoist v-if single child because it has to be a block1691                walk(child.branches[i], context, child.branches[i].children.length === 1);1692            }1693        }1694    }1695    if (hoistedCount && context.transformHoist) {1696        context.transformHoist(children, context, node);1697    }1698    // all children were hoisted - the entire children array is hoistable.1699    if (hoistedCount &&1700        hoistedCount === originalCount &&1701        node.type === 1 /* ELEMENT */ &&1702        node.tagType === 0 /* ELEMENT */ &&1703        node.codegenNode &&1704        node.codegenNode.type === 13 /* VNODE_CALL */ &&1705        isArray(node.codegenNode.children)) {1706        node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));1707    }1708}1709function getConstantType(node, context) {1710    const { constantCache } = context;1711    switch (node.type) {1712        case 1 /* ELEMENT */:1713            if (node.tagType !== 0 /* ELEMENT */) {1714                return 0 /* NOT_CONSTANT */;1715            }1716            const cached = constantCache.get(node);1717            if (cached !== undefined) {1718                return cached;1719            }1720            const codegenNode = node.codegenNode;1721            if (codegenNode.type !== 13 /* VNODE_CALL */) {1722                return 0 /* NOT_CONSTANT */;1723            }1724            if (codegenNode.isBlock &&1725                node.tag !== 'svg' &&1726                node.tag !== 'foreignObject') {1727                return 0 /* NOT_CONSTANT */;1728            }1729            const flag = getPatchFlag(codegenNode);1730            if (!flag) {1731                let returnType = 3 /* CAN_STRINGIFY */;1732                // Element itself has no patch flag. However we still need to check:1733                // 1. Even for a node with no patch flag, it is possible for it to contain1734                // non-hoistable expressions that refers to scope variables, e.g. compiler1735                // injected keys or cached event handlers. Therefore we need to always1736                // check the codegenNode's props to be sure.1737                const generatedPropsType = getGeneratedPropsConstantType(node, context);1738                if (generatedPropsType === 0 /* NOT_CONSTANT */) {1739                    constantCache.set(node, 0 /* NOT_CONSTANT */);1740                    return 0 /* NOT_CONSTANT */;1741                }1742                if (generatedPropsType < returnType) {1743                    returnType = generatedPropsType;1744                }1745                // 2. its children.1746                for (let i = 0; i < node.children.length; i++) {1747                    const childType = getConstantType(node.children[i], context);1748                    if (childType === 0 /* NOT_CONSTANT */) {1749                        constantCache.set(node, 0 /* NOT_CONSTANT */);1750                        return 0 /* NOT_CONSTANT */;1751                    }1752                    if (childType < returnType) {1753                        returnType = childType;1754                    }1755                }1756                // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-01757                // type, check if any of the props can cause the type to be lowered1758                // we can skip can_patch because it's guaranteed by the absence of a1759                // patchFlag.1760                if (returnType > 1 /* CAN_SKIP_PATCH */) {1761                    for (let i = 0; i < node.props.length; i++) {1762                        const p = node.props[i];1763                        if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {1764                            const expType = getConstantType(p.exp, context);1765                            if (expType === 0 /* NOT_CONSTANT */) {1766                                constantCache.set(node, 0 /* NOT_CONSTANT */);1767                                return 0 /* NOT_CONSTANT */;1768                            }1769                            if (expType < returnType) {1770                                returnType = expType;1771                            }1772                        }1773                    }1774                }1775                // only svg/foreignObject could be block here, however if they are1776                // static then they don't need to be blocks since there will be no1777                // nested updates.1778                if (codegenNode.isBlock) {1779                    context.removeHelper(OPEN_BLOCK);1780                    context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));1781                    codegenNode.isBlock = false;1782                    context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));1783                }1784                constantCache.set(node, returnType);1785                return returnType;1786            }1787            else {1788                constantCache.set(node, 0 /* NOT_CONSTANT */);1789                return 0 /* NOT_CONSTANT */;1790            }1791        case 2 /* TEXT */:1792        case 3 /* COMMENT */:1793            return 3 /* CAN_STRINGIFY */;1794        case 9 /* IF */:1795        case 11 /* FOR */:1796        case 10 /* IF_BRANCH */:1797            return 0 /* NOT_CONSTANT */;1798        case 5 /* INTERPOLATION */:1799        case 12 /* TEXT_CALL */:1800            return getConstantType(node.content, context);1801        case 4 /* SIMPLE_EXPRESSION */:1802            return node.constType;1803        case 8 /* COMPOUND_EXPRESSION */:1804            let returnType = 3 /* CAN_STRINGIFY */;1805            for (let i = 0; i < node.children.length; i++) {1806                const child = node.children[i];1807                if (isString(child) || isSymbol(child)) {1808                    continue;1809                }1810                const childType = getConstantType(child, context);1811                if (childType === 0 /* NOT_CONSTANT */) {1812                    return 0 /* NOT_CONSTANT */;1813                }1814                else if (childType < returnType) {1815                    returnType = childType;1816                }1817            }1818            return returnType;1819        default:1820            if ((process.env.NODE_ENV !== 'production')) ;1821            return 0 /* NOT_CONSTANT */;1822    }1823}1824const allowHoistedHelperSet = new Set([1825    NORMALIZE_CLASS,1826    NORMALIZE_STYLE,1827    NORMALIZE_PROPS,1828    GUARD_REACTIVE_PROPS1829]);1830function getConstantTypeOfHelperCall(value, context) {1831    if (value.type === 14 /* JS_CALL_EXPRESSION */ &&1832        !isString(value.callee) &&1833        allowHoistedHelperSet.has(value.callee)) {1834        const arg = value.arguments[0];1835        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {1836            return getConstantType(arg, context);1837        }1838        else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {1839            // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`1840            return getConstantTypeOfHelperCall(arg, context);1841        }1842    }1843    return 0 /* NOT_CONSTANT */;1844}1845function getGeneratedPropsConstantType(node, context) {1846    let returnType = 3 /* CAN_STRINGIFY */;1847    const props = getNodeProps(node);1848    if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {1849        const { properties } = props;1850        for (let i = 0; i < properties.length; i++) {1851            const { key, value } = properties[i];1852            const keyType = getConstantType(key, context);1853            if (keyType === 0 /* NOT_CONSTANT */) {1854                return keyType;1855            }1856            if (keyType < returnType) {1857                returnType = keyType;1858            }1859            let valueType;1860            if (value.type === 4 /* SIMPLE_EXPRESSION */) {1861                valueType = getConstantType(value, context);1862            }1863            else if (value.type === 14 /* JS_CALL_EXPRESSION */) {1864                // some helper calls can be hoisted,1865                // such as the `normalizeProps` generated by the compiler for pre-normalize class,1866                // in this case we need to respect the ConstantType of the helper's arguments1867                valueType = getConstantTypeOfHelperCall(value, context);1868            }1869            else {1870                valueType = 0 /* NOT_CONSTANT */;1871            }1872            if (valueType === 0 /* NOT_CONSTANT */) {1873                return valueType;1874            }1875            if (valueType < returnType) {1876                returnType = valueType;1877            }1878        }1879    }1880    return returnType;1881}1882function getNodeProps(node) {1883    const codegenNode = node.codegenNode;1884    if (codegenNode.type === 13 /* VNODE_CALL */) {1885        return codegenNode.props;1886    }1887}1888function getPatchFlag(node) {1889    const flag = node.patchFlag;1890    return flag ? parseInt(flag, 10) : undefined;1891}1892function 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 }) {1893    const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);1894    const context = {1895        // options1896        selfName: nameMatch && capitalize(camelize$1(nameMatch[1])),1897        prefixIdentifiers,1898        hoistStatic,1899        cacheHandlers,1900        nodeTransforms,1901        directiveTransforms,1902        transformHoist,1903        isBuiltInComponent,1904        isCustomElement,1905        expressionPlugins,1906        scopeId,1907        slotted,1908        ssr,1909        inSSR,1910        ssrCssVars,1911        bindingMetadata,1912        inline,1913        isTS,1914        onError,1915        onWarn,1916        compatConfig,1917        // state1918        root,1919        helpers: new Map(),1920        components: new Set(),1921        directives: new Set(),1922        hoists: [],1923        imports: [],1924        constantCache: new Map(),1925        temps: 0,1926        cached: 0,1927        identifiers: Object.create(null),1928        scopes: {1929            vFor: 0,1930            vSlot: 0,1931            vPre: 0,1932            vOnce: 01933        },1934        parent: null,1935        currentNode: root,1936        childIndex: 0,1937        inVOnce: false,1938        // methods1939        helper(name) {1940            const count = context.helpers.get(name) || 0;1941            context.helpers.set(name, count + 1);1942            return name;1943        },1944        removeHelper(name) {1945            const count = context.helpers.get(name);1946            if (count) {1947                const currentCount = count - 1;1948                if (!currentCount) {1949                    context.helpers.delete(name);1950                }1951                else {1952                    context.helpers.set(name, currentCount);1953                }1954            }1955        },1956        helperString(name) {1957            return `_${helperNameMap[context.helper(name)]}`;1958        },1959        replaceNode(node) {1960            /* istanbul ignore if */1961            if ((process.env.NODE_ENV !== 'production')) {1962                if (!context.currentNode) {1963                    throw new Error(`Node being replaced is already removed.`);1964                }1965                if (!context.parent) {1966                    throw new Error(`Cannot replace root node.`);1967                }1968            }1969            context.parent.children[context.childIndex] = context.currentNode = node;1970        },1971        removeNode(node) {1972            if ((process.env.NODE_ENV !== 'production') && !context.parent) {1973                throw new Error(`Cannot remove root node.`);1974            }1975            const list = context.parent.children;1976            const removalIndex = node1977                ? list.indexOf(node)1978                : context.currentNode1979                    ? context.childIndex1980                    : -1;1981            /* istanbul ignore if */1982            if ((process.env.NODE_ENV !== 'production') && removalIndex < 0) {1983                throw new Error(`node being removed is not a child of current parent`);1984            }1985            if (!node || node === context.currentNode) {1986                // current node removed1987                context.currentNode = null;1988                context.onNodeRemoved();1989            }1990            else {1991                // sibling node removed1992                if (context.childIndex > removalIndex) {1993                    context.childIndex--;1994                    context.onNodeRemoved();1995                }1996            }1997            context.parent.children.splice(removalIndex, 1);1998        },1999        onNodeRemoved: () => { },2000        addIdentifiers(exp) {2001        },2002        removeIdentifiers(exp) {2003        },2004        hoist(exp) {2005            if (isString(exp))2006                exp = createSimpleExpression(exp);2007            context.hoists.push(exp);2008            const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);2009            identifier.hoisted = exp;2010            return identifier;2011        },2012        cache(exp, isVNode = false) {2013            return createCacheExpression(context.cached++, exp, isVNode);2014        }2015    };2016    {2017        context.filters = new Set();2018    }2019    return context;2020}2021function transform(root, options) {2022    const context = createTransformContext(root, options);2023    traverseNode(root, context);2024    if (options.hoistStatic) {2025        hoistStatic(root, context);2026    }2027    if (!options.ssr) {2028        createRootCodegen(root, context);2029    }2030    // finalize meta information2031    root.helpers = [...context.helpers.keys()];2032    root.components = [...context.components];2033    root.directives = [...context.directives];2034    root.imports = context.imports;2035    root.hoists = context.hoists;2036    root.temps = context.temps;2037    root.cached = context.cached;2038    {2039        root.filters = [...context.filters];2040    }2041}2042function createRootCodegen(root, context) {2043    const { helper } = context;2044    const { children } = root;2045    if (children.length === 1) {2046        const child = children[0];2047        // if the single child is an element, turn it into a block.2048        if (isSingleElementRoot(root, child) && child.codegenNode) {2049            // single element root is never hoisted so codegenNode will never be2050            // SimpleExpressionNode2051            const codegenNode = child.codegenNode;2052            if (codegenNode.type === 13 /* VNODE_CALL */) {2053                makeBlock(codegenNode, context);2054            }2055            root.codegenNode = codegenNode;2056        }2057        else {2058            // - single <slot/>, IfNode, ForNode: already blocks.2059            // - single text node: always patched.2060            // root codegen falls through via genNode()2061            root.codegenNode = child;2062        }2063    }2064    else if (children.length > 1) {2065        // root has multiple nodes - return a fragment block.2066        let patchFlag = 64 /* STABLE_FRAGMENT */;2067        let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];2068        // check if the fragment actually contains a single valid child with2069        // the rest being comments2070        if ((process.env.NODE_ENV !== 'production') &&2071            children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {2072            patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;2073            patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;2074        }2075        root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, undefined, false /* isComponent */);2076    }2077    else ;2078}2079function traverseChildren(parent, context) {2080    let i = 0;2081    const nodeRemoved = () => {2082        i--;2083    };2084    for (; i < parent.children.length; i++) {2085        const child = parent.children[i];2086        if (isString(child))2087            continue;2088        context.parent = parent;2089        context.childIndex = i;2090        context.onNodeRemoved = nodeRemoved;2091        traverseNode(child, context);2092    }2093}2094function traverseNode(node, context) {2095    context.currentNode = node;2096    // apply transform plugins2097    const { nodeTransforms } = context;2098    const exitFns = [];2099    for (let i = 0; i < nodeTransforms.length; i++) {2100        const onExit = nodeTransforms[i](node, context);2101        if (onExit) {2102            if (isArray(onExit)) {2103                exitFns.push(...onExit);2104            }2105            else {2106                exitFns.push(onExit);2107            }2108        }2109        if (!context.currentNode) {2110            // node was removed2111            return;2112        }2113        else {2114            // node may have been replaced2115            node = context.currentNode;2116        }2117    }2118    switch (node.type) {2119        case 3 /* COMMENT */:2120            if (!context.ssr) {2121                // inject import for the Comment symbol, which is needed for creating2122                // comment nodes with `createVNode`2123                context.helper(CREATE_COMMENT);2124            }2125            break;2126        case 5 /* INTERPOLATION */:2127            // no need to traverse, but we need to inject toString helper2128            if (!context.ssr) {2129                context.helper(TO_DISPLAY_STRING);2130            }2131            break;2132        // for container types, further traverse downwards2133        case 9 /* IF */:2134            for (let i = 0; i < node.branches.length; i++) {2135                traverseNode(node.branches[i], context);2136            }2137            break;2138        case 10 /* IF_BRANCH */:2139        case 11 /* FOR */:2140        case 1 /* ELEMENT */:2141        case 0 /* ROOT */:2142            traverseChildren(node, context);2143            break;2144    }2145    // exit transforms2146    context.currentNode = node;2147    let i = exitFns.length;2148    while (i--) {2149        exitFns[i]();2150    }2151}2152function createStructuralDirectiveTransform(name, fn) {2153    const matches = isString(name)2154        ? (n) => n === name2155        : (n) => name.test(n);2156    return (node, context) => {2157        if (node.type === 1 /* ELEMENT */) {2158            const { props } = node;2159            // structural directive transforms are not concerned with slots2160            // as they are handled separately in vSlot.ts2161            if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {2162                return;2163            }2164            const exitFns = [];2165            for (let i = 0; i < props.length; i++) {2166                const prop = props[i];2167                if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {2168                    // structural directives are removed to avoid infinite recursion2169                    // also we remove them *before* applying so that it can further2170                    // traverse itself in case it moves the node around2171                    props.splice(i, 1);2172                    i--;2173                    const onExit = fn(node, prop, context);2174                    if (onExit)2175                        exitFns.push(onExit);2176                }2177            }2178            return exitFns;2179        }2180    };2181}2182const PURE_ANNOTATION = `/*#__PURE__*/`;2183function 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 }) {2184    const context = {2185        mode,2186        prefixIdentifiers,2187        sourceMap,2188        filename,2189        scopeId,2190        optimizeImports,2191        runtimeGlobalName,2192        runtimeModuleName,2193        ssrRuntimeModuleName,2194        ssr,2195        isTS,2196        inSSR,2197        source: ast.loc.source,2198        code: ``,2199        column: 1,2200        line: 1,2201        offset: 0,2202        indentLevel: 0,2203        pure: false,2204        map: undefined,2205        helper(key) {2206            return `_${helperNameMap[key]}`;2207        },2208        push(code, node) {2209            context.code += code;2210        },2211        indent() {2212            newline(++context.indentLevel);2213        },2214        deindent(withoutNewLine = false) {2215            if (withoutNewLine) {2216                --context.indentLevel;2217            }2218            else {2219                newline(--context.indentLevel);2220            }2221        },2222        newline() {2223            newline(context.indentLevel);2224        }2225    };2226    function newline(n) {2227        context.push('\n' + `  `.repeat(n));2228    }2229    return context;2230}2231function generate(ast, options = {}) {2232    const context = createCodegenContext(ast, options);2233    if (options.onContextCreated)2234        options.onContextCreated(context);2235    const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;2236    const hasHelpers = ast.helpers.length > 0;2237    const useWithBlock = !prefixIdentifiers && mode !== 'module';2238    // preambles2239    // in setup() inline mode, the preamble is generated in a sub context2240    // and returned separately.2241    const preambleContext = context;2242    {2243        genFunctionPreamble(ast, preambleContext);2244    }2245    // enter render function2246    const functionName = ssr ? `ssrRender` : `render`;2247    const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];2248    const signature = args.join(', ');2249    {2250        push(`function ${functionName}(${signature}) {`);2251    }2252    indent();2253    if (useWithBlock) {2254        push(`with (_ctx) {`);2255        indent();2256        // function mode const declarations should be inside with block2257        // also they should be renamed to avoid collision with user properties2258        if (hasHelpers) {2259            push(`const { ${ast.helpers2260                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)2261                .join(', ')} } = _Vue`);2262            push(`\n`);2263            newline();2264        }2265    }2266    // generate asset resolution statements2267    if (ast.components.length) {2268        genAssets(ast.components, 'component', context);2269        if (ast.directives.length || ast.temps > 0) {2270            newline();2271        }2272    }2273    if (ast.directives.length) {2274        genAssets(ast.directives, 'directive', context);2275        if (ast.temps > 0) {2276            newline();2277        }2278    }2279    if (ast.filters && ast.filters.length) {2280        newline();2281        genAssets(ast.filters, 'filter', context);2282        newline();2283    }2284    if (ast.temps > 0) {2285        push(`let `);2286        for (let i = 0; i < ast.temps; i++) {2287            push(`${i > 0 ? `, ` : ``}_temp${i}`);2288        }2289    }2290    if (ast.components.length || ast.directives.length || ast.temps) {2291        push(`\n`);2292        newline();2293    }2294    // generate the VNode tree expression2295    if (!ssr) {2296        push(`return `);2297    }2298    if (ast.codegenNode) {2299        genNode(ast.codegenNode, context);2300    }2301    else {2302        push(`null`);2303    }2304    if (useWithBlock) {2305        deindent();2306        push(`}`);2307    }2308    deindent();2309    push(`}`);2310    return {2311        ast,2312        code: context.code,2313        preamble: ``,2314        // SourceMapGenerator does have toJSON() method but it's not in the types2315        map: context.map ? context.map.toJSON() : undefined2316    };2317}2318function genFunctionPreamble(ast, context) {2319    const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;2320    const VueBinding = runtimeGlobalName;2321    const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;2322    // Generate const declaration for helpers2323    // In prefix mode, we place the const declaration at top so it's done2324    // only once; But if we not prefixing, we place the declaration inside the2325    // with block so it doesn't incur the `in` check cost for every helper access.2326    if (ast.helpers.length > 0) {2327        {2328            // "with" mode.2329            // save Vue in a separate variable to avoid collision2330            push(`const _Vue = ${VueBinding}\n`);2331            // in "with" mode, helpers are declared inside the with block to avoid2332            // has check cost, but hoists are lifted out of the function - we need2333            // to provide the helper here.2334            if (ast.hoists.length) {2335                const staticHelpers = [2336                    CREATE_VNODE,2337                    CREATE_ELEMENT_VNODE,2338                    CREATE_COMMENT,2339                    CREATE_TEXT,2340                    CREATE_STATIC2341                ]2342                    .filter(helper => ast.helpers.includes(helper))2343                    .map(aliasHelper)2344                    .join(', ');2345                push(`const { ${staticHelpers} } = _Vue\n`);2346            }2347        }2348    }2349    genHoists(ast.hoists, context);2350    newline();2351    push(`return `);2352}2353function genAssets(assets, type, { helper, push, newline, isTS }) {2354    const resolver = helper(type === 'filter'2355        ? RESOLVE_FILTER2356        : type === 'component'2357            ? RESOLVE_COMPONENT2358            : RESOLVE_DIRECTIVE);2359    for (let i = 0; i < assets.length; i++) {2360        let id = assets[i];2361        // potential component implicit self-reference inferred from SFC filename2362        const maybeSelfReference = id.endsWith('__self');2363        if (maybeSelfReference) {2364            id = id.slice(0, -6);2365        }2366        push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);2367        if (i < assets.length - 1) {2368            newline();2369        }2370    }2371}2372function genHoists(hoists, context) {2373    if (!hoists.length) {2374        return;2375    }2376    context.pure = true;2377    const { push, newline, helper, scopeId, mode } = context;2378    newline();2379    for (let i = 0; i < hoists.length; i++) {2380        const exp = hoists[i];2381        if (exp) {2382            push(`const _hoisted_${i + 1} = ${``}`);2383            genNode(exp, context);2384            newline();2385        }2386    }2387    context.pure = false;2388}2389function isText$1(n) {2390    return (isString(n) ||2391        n.type === 4 /* SIMPLE_EXPRESSION */ ||2392        n.type === 2 /* TEXT */ ||2393        n.type === 5 /* INTERPOLATION */ ||2394        n.type === 8 /* COMPOUND_EXPRESSION */);2395}2396function genNodeListAsArray(nodes, context) {2397    const multilines = nodes.length > 3 ||2398        (((process.env.NODE_ENV !== 'production')) && nodes.some(n => isArray(n) || !isText$1(n)));2399    context.push(`[`);2400    multilines && context.indent();2401    genNodeList(nodes, context, multilines);2402    multilines && context.deindent();2403    context.push(`]`);2404}2405function genNodeList(nodes, context, multilines = false, comma = true) {2406    const { push, newline } = context;2407    for (let i = 0; i < nodes.length; i++) {2408        const node = nodes[i];2409        if (isString(node)) {2410            push(node);2411        }2412        else if (isArray(node)) {2413            genNodeListAsArray(node, context);2414        }2415        else {2416            genNode(node, context);2417        }2418        if (i < nodes.length - 1) {2419            if (multilines) {2420                comma && push(',');2421                newline();2422            }2423            else {2424                comma && push(', ');2425            }2426        }2427    }2428}2429function genNode(node, context) {2430    if (isString(node)) {2431        context.push(node);2432        return;2433    }2434    if (isSymbol(node)) {2435        context.push(context.helper(node));2436        return;2437    }2438    switch (node.type) {2439        case 1 /* ELEMENT */:2440        case 9 /* IF */:2441        case 11 /* FOR */:2442            (process.env.NODE_ENV !== 'production') &&2443                assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +2444                    `Apply appropriate transforms first.`);2445            genNode(node.codegenNode, context);2446            break;2447        case 2 /* TEXT */:2448            genText(node, context);2449            break;2450        case 4 /* SIMPLE_EXPRESSION */:2451            genExpression(node, context);2452            break;2453        case 5 /* INTERPOLATION */:2454            genInterpolation(node, context);2455            break;2456        case 12 /* TEXT_CALL */:2457            genNode(node.codegenNode, context);2458            break;2459        case 8 /* COMPOUND_EXPRESSION */:2460            genCompoundExpression(node, context);2461            break;2462        case 3 /* COMMENT */:2463            genComment(node, context);2464            break;2465        case 13 /* VNODE_CALL */:2466            genVNodeCall(node, context);2467            break;2468        case 14 /* JS_CALL_EXPRESSION */:2469            genCallExpression(node, context);2470            break;2471        case 15 /* JS_OBJECT_EXPRESSION */:2472            genObjectExpression(node, context);2473            break;2474        case 17 /* JS_ARRAY_EXPRESSION */:2475            genArrayExpression(node, context);2476            break;2477        case 18 /* JS_FUNCTION_EXPRESSION */:2478            genFunctionExpression(node, context);2479            break;2480        case 19 /* JS_CONDITIONAL_EXPRESSION */:2481            genConditionalExpression(node, context);2482            break;2483        case 20 /* JS_CACHE_EXPRESSION */:2484            genCacheExpression(node, context);2485            break;2486        case 21 /* JS_BLOCK_STATEMENT */:2487            genNodeList(node.body, context, true, false);2488            break;2489        // SSR only types2490        case 22 /* JS_TEMPLATE_LITERAL */:2491            break;2492        case 23 /* JS_IF_STATEMENT */:2493            break;2494        case 24 /* JS_ASSIGNMENT_EXPRESSION */:2495            break;2496        case 25 /* JS_SEQUENCE_EXPRESSION */:2497            break;2498        case 26 /* JS_RETURN_STATEMENT */:2499            break;2500        /* istanbul ignore next */2501        case 10 /* IF_BRANCH */:2502            // noop2503            break;2504        default:2505            if ((process.env.NODE_ENV !== 'production')) {2506                assert(false, `unhandled codegen node type: ${node.type}`);2507                // make sure we exhaust all possible types2508                const exhaustiveCheck = node;2509                return exhaustiveCheck;2510            }2511    }2512}2513function genText(node, context) {2514    context.push(JSON.stringify(node.content), node);2515}2516function genExpression(node, context) {2517    const { content, isStatic } = node;2518    context.push(isStatic ? JSON.stringify(content) : content, node);2519}2520function genInterpolation(node, context) {2521    const { push, helper, pure } = context;2522    if (pure)2523        push(PURE_ANNOTATION);2524    push(`${helper(TO_DISPLAY_STRING)}(`);2525    genNode(node.content, context);2526    push(`)`);2527}2528function genCompoundExpression(node, context) {2529    for (let i = 0; i < node.children.length; i++) {2530        const child = node.children[i];2531        if (isString(child)) {2532            context.push(child);2533        }2534        else {2535            genNode(child, context);2536        }2537    }2538}2539function genExpressionAsPropertyKey(node, context) {2540    const { push } = context;2541    if (node.type === 8 /* COMPOUND_EXPRESSION */) {2542        push(`[`);2543        genCompoundExpression(node, context);2544        push(`]`);2545    }2546    else if (node.isStatic) {2547        // only quote keys if necessary2548        const text = isSimpleIdentifier(node.content)2549            ? node.content2550            : JSON.stringify(node.content);2551        push(text, node);2552    }2553    else {2554        push(`[${node.content}]`, node);2555    }2556}2557function genComment(node, context) {2558    const { push, helper, pure } = context;2559    if (pure) {2560        push(PURE_ANNOTATION);2561    }2562    push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);2563}2564function genVNodeCall(node, context) {2565    const { push, helper, pure } = context;2566    const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;2567    if (directives) {2568        push(helper(WITH_DIRECTIVES) + `(`);2569    }2570    if (isBlock) {2571        push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);2572    }2573    if (pure) {2574        push(PURE_ANNOTATION);2575    }2576    const callHelper = isBlock2577        ? getVNodeBlockHelper(context.inSSR, isComponent)2578        : getVNodeHelper(context.inSSR, isComponent);2579    push(helper(callHelper) + `(`, node);2580    genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);2581    push(`)`);2582    if (isBlock) {2583        push(`)`);2584    }2585    if (directives) {2586        push(`, `);2587        genNode(directives, context);2588        push(`)`);2589    }2590}2591function genNullableArgs(args) {2592    let i = args.length;2593    while (i--) {2594        if (args[i] != null)2595            break;2596    }2597    return args.slice(0, i + 1).map(arg => arg || `null`);2598}2599// JavaScript2600function genCallExpression(node, context) {2601    const { push, helper, pure } = context;2602    const callee = isString(node.callee) ? node.callee : helper(node.callee);2603    if (pure) {2604        push(PURE_ANNOTATION);2605    }2606    push(callee + `(`, node);2607    genNodeList(node.arguments, context);2608    push(`)`);2609}2610function genObjectExpression(node, context) {2611    const { push, indent, deindent, newline } = context;2612    const { properties } = node;2613    if (!properties.length) {2614        push(`{}`, node);2615        return;2616    }2617    const multilines = properties.length > 1 ||2618        (((process.env.NODE_ENV !== 'production')) &&2619            properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));2620    push(multilines ? `{` : `{ `);2621    multilines && indent();2622    for (let i = 0; i < properties.length; i++) {2623        const { key, value } = properties[i];2624        // key2625        genExpressionAsPropertyKey(key, context);2626        push(`: `);2627        // value2628        genNode(value, context);2629        if (i < properties.length - 1) {2630            // will only reach this if it's multilines2631            push(`,`);2632            newline();2633        }2634    }2635    multilines && deindent();2636    push(multilines ? `}` : ` }`);2637}2638function genArrayExpression(node, context) {2639    genNodeListAsArray(node.elements, context);2640}2641function genFunctionExpression(node, context) {2642    const { push, indent, deindent } = context;2643    const { params, returns, body, newline, isSlot } = node;2644    if (isSlot) {2645        // wrap slot functions with owner context2646        push(`_${helperNameMap[WITH_CTX]}(`);2647    }2648    push(`(`, node);2649    if (isArray(params)) {2650        genNodeList(params, context);2651    }2652    else if (params) {2653        genNode(params, context);2654    }2655    push(`) => `);2656    if (newline || body) {2657        push(`{`);2658        indent();2659    }2660    if (returns) {2661        if (newline) {2662            push(`return `);2663        }2664        if (isArray(returns)) {2665            genNodeListAsArray(returns, context);2666        }2667        else {2668            genNode(returns, context);2669        }2670    }2671    else if (body) {2672        genNode(body, context);2673    }2674    if (newline || body) {2675        deindent();2676        push(`}`);2677    }2678    if (isSlot) {2679        if (node.isNonScopedSlot) {2680            push(`, undefined, true`);2681        }2682        push(`)`);2683    }2684}2685function genConditionalExpression(node, context) {2686    const { test, consequent, alternate, newline: needNewline } = node;2687    const { push, indent, deindent, newline } = context;2688    if (test.type === 4 /* SIMPLE_EXPRESSION */) {2689        const needsParens = !isSimpleIdentifier(test.content);2690        needsParens && push(`(`);2691        genExpression(test, context);2692        needsParens && push(`)`);2693    }2694    else {2695        push(`(`);2696        genNode(test, context);2697        push(`)`);2698    }2699    needNewline && indent();2700    context.indentLevel++;2701    needNewline || push(` `);2702    push(`? `);2703    genNode(consequent, context);2704    context.indentLevel--;2705    needNewline && newline();2706    needNewline || push(` `);2707    push(`: `);2708    const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;2709    if (!isNested) {2710        context.indentLevel++;2711    }2712    genNode(alternate, context);2713    if (!isNested) {2714        context.indentLevel--;2715    }2716    needNewline && deindent(true /* without newline */);2717}2718function genCacheExpression(node, context) {2719    const { push, helper, indent, deindent, newline } = context;2720    push(`_cache[${node.index}] || (`);2721    if (node.isVNode) {2722        indent();2723        push(`${helper(SET_BLOCK_TRACKING)}(-1),`);2724        newline();2725    }2726    push(`_cache[${node.index}] = `);2727    genNode(node.value, context);2728    if (node.isVNode) {2729        push(`,`);2730        newline();2731        push(`${helper(SET_BLOCK_TRACKING)}(1),`);2732        newline();2733        push(`_cache[${node.index}]`);2734        deindent();2735    }2736    push(`)`);2737}2738function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {2739    {2740        return;2741    }2742}2743function isReferencedIdentifier(id, parent, parentStack) {2744    {2745        return false;2746    }2747}2748function isInDestructureAssignment(parent, parentStack) {2749    if (parent &&2750        (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {2751        let i = parentStack.length;2752        while (i--) {2753            const p = parentStack[i];2754            if (p.type === 'AssignmentExpression') {2755                return true;2756            }2757            else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {2758                break;2759            }2760        }2761    }2762    return false;2763}2764function walkFunctionParams(node, onIdent) {2765    for (const p of node.params) {2766        for (const id of extractIdentifiers(p)) {2767            onIdent(id);2768        }2769    }2770}2771function walkBlockDeclarations(block, onIdent) {2772    for (const stmt of block.body) {2773        if (stmt.type === 'VariableDeclaration') {2774            if (stmt.declare)2775                continue;2776            for (const decl of stmt.declarations) {2777                for (const id of extractIdentifiers(decl.id)) {2778                    onIdent(id);2779                }2780            }2781        }2782        else if (stmt.type === 'FunctionDeclaration' ||2783            stmt.type === 'ClassDeclaration') {2784            if (stmt.declare || !stmt.id)2785                continue;2786            onIdent(stmt.id);2787        }2788    }2789}2790function extractIdentifiers(param, nodes = []) {2791    switch (param.type) {2792        case 'Identifier':2793            nodes.push(param);2794            break;2795        case 'MemberExpression':2796            let object = param;2797            while (object.type === 'MemberExpression') {2798                object = object.object;2799            }2800            nodes.push(object);2801            break;2802        case 'ObjectPattern':2803            for (const prop of param.properties) {2804                if (prop.type === 'RestElement') {2805                    extractIdentifiers(prop.argument, nodes);2806                }2807                else {2808                    extractIdentifiers(prop.value, nodes);2809                }2810            }2811            break;2812        case 'ArrayPattern':2813            param.elements.forEach(element => {2814                if (element)2815                    extractIdentifiers(element, nodes);2816            });2817            break;2818        case 'RestElement':2819            extractIdentifiers(param.argument, nodes);2820            break;2821        case 'AssignmentPattern':2822            extractIdentifiers(param.left, nodes);2823            break;2824    }2825    return nodes;2826}2827const isFunctionType = (node) => {2828    return /Function(?:Expression|Declaration)$|Method$/.test(node.type);2829};2830const isStaticProperty = (node) => node &&2831    (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&2832    !node.computed;2833const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;2834// these keywords should not appear inside expressions, but operators like2835// typeof, instanceof and in are allowed2836const prohibitedKeywordRE = new RegExp('\\b' +2837    ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +2838        'super,throw,while,yield,delete,export,import,return,switch,default,' +2839        'extends,finally,continue,debugger,function,arguments,typeof,void')2840        .split(',')2841        .join('\\b|\\b') +2842    '\\b');2843// strip strings in expressions2844const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;2845/**2846 * Validate a non-prefixed expression.2847 * This is only called when using the in-browser runtime compiler since it2848 * doesn't prefix expressions.2849 */2850function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {2851    const exp = node.content;2852    // empty expressions are validated per-directive since some directives2853    // do allow empty expressions.2854    if (!exp.trim()) {2855        return;2856    }2857    try {2858        new Function(asRawStatements2859            ? ` ${exp} `2860            : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);2861    }2862    catch (e) {2863        let message = e.message;2864        const keywordMatch = exp2865            .replace(stripStringRE, '')2866            .match(prohibitedKeywordRE);2867        if (keywordMatch) {2868            message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;2869        }2870        context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));2871    }2872}2873const transformExpression = (node, context) => {2874    if (node.type === 5 /* INTERPOLATION */) {2875        node.content = processExpression(node.content, context);2876    }2877    else if (node.type === 1 /* ELEMENT */) {2878        // handle directives on element2879        for (let i = 0; i < node.props.length; i++) {2880            const dir = node.props[i];2881            // do not process for v-on & v-for since they are special handled2882            if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {2883                const exp = dir.exp;2884                const arg = dir.arg;2885                // do not process exp if this is v-on:arg - we need special handling2886                // for wrapping inline statements.2887                if (exp &&2888                    exp.type === 4 /* SIMPLE_EXPRESSION */ &&2889                    !(dir.name === 'on' && arg)) {2890                    dir.exp = processExpression(exp, context, 2891                    // slot args must be processed as function params2892                    dir.name === 'slot');2893                }2894                if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {2895                    dir.arg = processExpression(arg, context);2896                }2897            }2898        }2899    }2900};2901// Important: since this function uses Node.js only dependencies, it should2902// always be used with a leading !true check so that it can be2903// tree-shaken from the browser build.2904function processExpression(node, context, 2905// some expressions like v-slot props & v-for aliases should be parsed as2906// function params2907asParams = false, 2908// v-on handler values may contain multiple statements2909asRawStatements = false, localVars = Object.create(context.identifiers)) {2910    {2911        if ((process.env.NODE_ENV !== 'production')) {2912            // simple in-browser validation (same logic in 2.x)2913            validateBrowserExpression(node, context, asParams, asRawStatements);2914        }2915        return node;2916    }2917}2918const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {2919    return processIf(node, dir, context, (ifNode, branch, isRoot) => {2920        // #1587: We need to dynamically increment the key based on the current2921        // node's sibling nodes, since chained v-if/else branches are2922        // rendered at the same depth2923        const siblings = context.parent.children;2924        let i = siblings.indexOf(ifNode);2925        let key = 0;2926        while (i-- >= 0) {2927            const sibling = siblings[i];2928            if (sibling && sibling.type === 9 /* IF */) {2929                key += sibling.branches.length;2930            }2931        }2932        // Exit callback. Complete the codegenNode when all children have been2933        // transformed.2934        return () => {2935            if (isRoot) {2936                ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);2937            }2938            else {2939                // attach this branch's codegen node to the v-if root.2940                const parentCondition = getParentCondition(ifNode.codegenNode);2941                parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);2942            }2943        };2944    });2945});2946// target-agnostic transform used for both Client and SSR2947function processIf(node, dir, context, processCodegen) {2948    if (dir.name !== 'else' &&2949        (!dir.exp || !dir.exp.content.trim())) {2950        const loc = dir.exp ? dir.exp.loc : node.loc;2951        context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));2952        dir.exp = createSimpleExpression(`true`, false, loc);2953    }2954    if ((process.env.NODE_ENV !== 'production') && true && dir.exp) {2955        validateBrowserExpression(dir.exp, context);2956    }2957    if (dir.name === 'if') {2958        const branch = createIfBranch(node, dir);2959        const ifNode = {2960            type: 9 /* IF */,2961            loc: node.loc,2962            branches: [branch]2963        };2964        context.replaceNode(ifNode);2965        if (processCodegen) {2966            return processCodegen(ifNode, branch, true);2967        }2968    }2969    else {2970        // locate the adjacent v-if2971        const siblings = context.parent.children;2972        const comments = [];2973        let i = siblings.indexOf(node);2974        while (i-- >= -1) {2975            const sibling = siblings[i];2976            if ((process.env.NODE_ENV !== 'production') && sibling && sibling.type === 3 /* COMMENT */) {2977                context.removeNode(sibling);2978                comments.unshift(sibling);2979                continue;2980            }2981            if (sibling &&2982                sibling.type === 2 /* TEXT */ &&2983                !sibling.content.trim().length) {2984                context.removeNode(sibling);2985                continue;2986            }2987            if (sibling && sibling.type === 9 /* IF */) {2988                // Check if v-else was followed by v-else-if2989                if (dir.name === 'else-if' &&2990                    sibling.branches[sibling.branches.length - 1].condition === undefined) {2991                    context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));2992                }2993                // move the node to the if node's branches2994                context.removeNode();2995                const branch = createIfBranch(node, dir);2996                if ((process.env.NODE_ENV !== 'production') &&2997                    comments.length &&2998                    // #3619 ignore comments if the v-if is direct child of <transition>2999                    !(context.parent &&3000                        context.parent.type === 1 /* ELEMENT */ &&3001                        isBuiltInType(context.parent.tag, 'transition'))) {3002                    branch.children = [...comments, ...branch.children];3003                }3004                // check if user is forcing same key on different branches3005                if ((process.env.NODE_ENV !== 'production') || !true) {3006                    const key = branch.userKey;3007                    if (key) {3008                        sibling.branches.forEach(({ userKey }) => {3009                            if (isSameKey(userKey, key)) {3010                                context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));3011                            }3012                        });3013                    }3014                }3015                sibling.branches.push(branch);3016                const onExit = processCodegen && processCodegen(sibling, branch, false);3017                // since the branch was removed, it will not be traversed.3018                // make sure to traverse here.3019                traverseNode(branch, context);3020                // call on exit3021                if (onExit)3022                    onExit();3023                // make sure to reset currentNode after traversal to indicate this3024                // node has been removed.3025                context.currentNode = null;3026            }3027            else {3028                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));3029            }3030            break;3031        }3032    }3033}3034function createIfBranch(node, dir) {3035    return {3036        type: 10 /* IF_BRANCH */,3037        loc: node.loc,3038        condition: dir.name === 'else' ? undefined : dir.exp,3039        children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')3040            ? node.children3041            : [node],3042        userKey: findProp(node, `key`)3043    };3044}3045function createCodegenNodeForBranch(branch, keyIndex, context) {3046    if (branch.condition) {3047        return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 3048        // make sure to pass in asBlock: true so that the comment node call3049        // closes the current block.3050        createCallExpression(context.helper(CREATE_COMMENT), [3051            (process.env.NODE_ENV !== 'production') ? '"v-if"' : '""',3052            'true'3053        ]));3054    }3055    else {3056        return createChildrenCodegenNode(branch, keyIndex, context);3057    }3058}3059function createChildrenCodegenNode(branch, keyIndex, context) {3060    const { helper } = context;3061    const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));3062    const { children } = branch;3063    const firstChild = children[0];3064    const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;3065    if (needFragmentWrapper) {3066        if (children.length === 1 && firstChild.type === 11 /* FOR */) {3067            // optimize away nested fragments when child is a ForNode3068            const vnodeCall = firstChild.codegenNode;3069            injectProp(vnodeCall, keyProperty, context);3070            return vnodeCall;3071        }3072        else {3073            let patchFlag = 64 /* STABLE_FRAGMENT */;3074            let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];3075            // check if the fragment actually contains a single valid child with3076            // the rest being comments3077            if ((process.env.NODE_ENV !== 'production') &&3078                children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {3079                patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;3080                patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;3081            }3082            return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${patchFlagText} */` : ``), undefined, undefined, true, false, false /* isComponent */, branch.loc);3083        }3084    }3085    else {3086        const ret = firstChild.codegenNode;3087        const vnodeCall = getMemoedVNodeCall(ret);3088        // Change createVNode to createBlock.3089        if (vnodeCall.type === 13 /* VNODE_CALL */) {3090            makeBlock(vnodeCall, context);3091        }3092        // inject branch key3093        injectProp(vnodeCall, keyProperty, context);3094        return ret;3095    }3096}3097function isSameKey(a, b) {3098    if (!a || a.type !== b.type) {3099        return false;3100    }3101    if (a.type === 6 /* ATTRIBUTE */) {3102        if (a.value.content !== b.value.content) {3103            return false;3104        }3105    }3106    else {3107        // directive3108        const exp = a.exp;3109        const branchExp = b.exp;3110        if (exp.type !== branchExp.type) {3111            return false;3112        }3113        if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||3114            exp.isStatic !== branchExp.isStatic ||3115            exp.content !== branchExp.content) {3116            return false;3117        }3118    }3119    return true;3120}3121function getParentCondition(node) {3122    while (true) {3123        if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3124            if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3125                node = node.alternate;3126            }3127            else {3128                return node;3129            }3130        }3131        else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {3132            node = node.value;3133        }3134    }3135}3136const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {3137    const { helper, removeHelper } = context;3138    return processFor(node, dir, context, forNode => {3139        // create the loop render function expression now, and add the3140        // iterator on exit after all children have been traversed3141        const renderExp = createCallExpression(helper(RENDER_LIST), [3142            forNode.source3143        ]);3144        const memo = findDir(node, 'memo');3145        const keyProp = findProp(node, `key`);3146        const keyExp = keyProp &&3147            (keyProp.type === 6 /* ATTRIBUTE */3148                ? createSimpleExpression(keyProp.value.content, true)3149                : keyProp.exp);3150        const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;3151        const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&3152            forNode.source.constType > 0 /* NOT_CONSTANT */;3153        const fragmentFlag = isStableFragment3154            ? 64 /* STABLE_FRAGMENT */3155            : keyProp3156                ? 128 /* KEYED_FRAGMENT */3157                : 256 /* UNKEYED_FRAGMENT */;3158        forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +3159            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);3160        return () => {3161            // finish the codegen now that all children have been traversed3162            let childBlock;3163            const isTemplate = isTemplateNode(node);3164            const { children } = forNode;3165            // check <template v-for> key placement3166            if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {3167                node.children.some(c => {3168                    if (c.type === 1 /* ELEMENT */) {3169                        const key = findProp(c, 'key');3170                        if (key) {3171                            context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));3172                            return true;3173                        }3174                    }3175                });3176            }3177            const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;3178            const slotOutlet = isSlotOutlet(node)3179                ? node3180                : isTemplate &&3181                    node.children.length === 1 &&3182                    isSlotOutlet(node.children[0])3183                    ? node.children[0] // api-extractor somehow fails to infer this3184                    : null;3185            if (slotOutlet) {3186                // <slot v-for="..."> or <template v-for="..."><slot/></template>3187                childBlock = slotOutlet.codegenNode;3188                if (isTemplate && keyProperty) {3189                    // <template v-for="..." :key="..."><slot/></template>3190                    // we need to inject the key to the renderSlot() call.3191                    // the props for renderSlot is passed as the 3rd argument.3192                    injectProp(childBlock, keyProperty, context);3193                }3194            }3195            else if (needFragmentWrapper) {3196                // <template v-for="..."> with text or multi-elements3197                // should generate a fragment block for each loop3198                childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +3199                    ((process.env.NODE_ENV !== 'production')3200                        ? ` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`3201                        : ``), undefined, undefined, true, undefined, false /* isComponent */);3202            }3203            else {3204                // Normal element v-for. Directly use the child's codegenNode3205                // but mark it as a block.3206                childBlock = children[0]3207                    .codegenNode;3208                if (isTemplate && keyProperty) {3209                    injectProp(childBlock, keyProperty, context);3210                }3211                if (childBlock.isBlock !== !isStableFragment) {3212                    if (childBlock.isBlock) {3213                        // switch from block to vnode3214                        removeHelper(OPEN_BLOCK);3215                        removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3216                    }3217                    else {3218                        // switch from vnode to block3219                        removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));3220                    }3221                }3222                childBlock.isBlock = !isStableFragment;3223                if (childBlock.isBlock) {3224                    helper(OPEN_BLOCK);3225                    helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));3226                }3227                else {3228                    helper(getVNodeHelper(context.inSSR, childBlock.isComponent));3229                }3230            }3231            if (memo) {3232                const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [3233                    createSimpleExpression(`_cached`)3234                ]));3235                loop.body = createBlockStatement([3236                    createCompoundExpression([`const _memo = (`, memo.exp, `)`]),3237                    createCompoundExpression([3238                        `if (_cached`,3239                        ...(keyExp ? [` && _cached.key === `, keyExp] : []),3240                        ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`3241                    ]),3242                    createCompoundExpression([`const _item = `, childBlock]),3243                    createSimpleExpression(`_item.memo = _memo`),3244                    createSimpleExpression(`return _item`)3245                ]);3246                renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));3247            }3248            else {3249                renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));3250            }3251        };3252    });3253});3254// target-agnostic transform used for both Client and SSR3255function processFor(node, dir, context, processCodegen) {3256    if (!dir.exp) {3257        context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));3258        return;3259    }3260    const parseResult = parseForExpression(3261    // can only be simple expression because vFor transform is applied3262    // before expression transform.3263    dir.exp, context);3264    if (!parseResult) {3265        context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));3266        return;3267    }3268    const { addIdentifiers, removeIdentifiers, scopes } = context;3269    const { source, value, key, index } = parseResult;3270    const forNode = {3271        type: 11 /* FOR */,3272        loc: dir.loc,3273        source,3274        valueAlias: value,3275        keyAlias: key,3276        objectIndexAlias: index,3277        parseResult,3278        children: isTemplateNode(node) ? node.children : [node]3279    };3280    context.replaceNode(forNode);3281    // bookkeeping3282    scopes.vFor++;3283    const onExit = processCodegen && processCodegen(forNode);3284    return () => {3285        scopes.vFor--;3286        if (onExit)3287            onExit();3288    };3289}3290const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;3291// This regex doesn't cover the case if key or index aliases have destructuring,3292// but those do not make sense in the first place, so this works in practice.3293const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;3294const stripParensRE = /^\(|\)$/g;3295function parseForExpression(input, context) {3296    const loc = input.loc;3297    const exp = input.content;3298    const inMatch = exp.match(forAliasRE);3299    if (!inMatch)3300        return;3301    const [, LHS, RHS] = inMatch;3302    const result = {3303        source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),3304        value: undefined,3305        key: undefined,3306        index: undefined3307    };3308    if ((process.env.NODE_ENV !== 'production') && true) {3309        validateBrowserExpression(result.source, context);3310    }3311    let valueContent = LHS.trim().replace(stripParensRE, '').trim();3312    const trimmedOffset = LHS.indexOf(valueContent);3313    const iteratorMatch = valueContent.match(forIteratorRE);3314    if (iteratorMatch) {3315        valueContent = valueContent.replace(forIteratorRE, '').trim();3316        const keyContent = iteratorMatch[1].trim();3317        let keyOffset;3318        if (keyContent) {3319            keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);3320            result.key = createAliasExpression(loc, keyContent, keyOffset);3321            if ((process.env.NODE_ENV !== 'production') && true) {3322                validateBrowserExpression(result.key, context, true);3323            }3324        }3325        if (iteratorMatch[2]) {3326            const indexContent = iteratorMatch[2].trim();3327            if (indexContent) {3328                result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key3329                    ? keyOffset + keyContent.length3330                    : trimmedOffset + valueContent.length));3331                if ((process.env.NODE_ENV !== 'production') && true) {3332                    validateBrowserExpression(result.index, context, true);3333                }3334            }3335        }3336    }3337    if (valueContent) {3338        result.value = createAliasExpression(loc, valueContent, trimmedOffset);3339        if ((process.env.NODE_ENV !== 'production') && true) {3340            validateBrowserExpression(result.value, context, true);3341        }3342    }3343    return result;3344}3345function createAliasExpression(range, content, offset) {3346    return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));3347}3348function createForLoopParams({ value, key, index }, memoArgs = []) {3349    return createParamsList([value, key, index, ...memoArgs]);3350}3351function createParamsList(args) {3352    let i = args.length;3353    while (i--) {3354        if (args[i])3355            break;3356    }3357    return args3358        .slice(0, i + 1)3359        .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));3360}3361const defaultFallback = createSimpleExpression(`undefined`, false);3362// A NodeTransform that:3363// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed3364//    by transformExpression. This is only applied in non-browser builds with3365//    { prefixIdentifiers: true }.3366// 2. Track v-slot depths so that we know a slot is inside another slot.3367//    Note the exit callback is executed before buildSlots() on the same node,3368//    so only nested slots see positive numbers.3369const trackSlotScopes = (node, context) => {3370    if (node.type === 1 /* ELEMENT */ &&3371        (node.tagType === 1 /* COMPONENT */ ||3372            node.tagType === 3 /* TEMPLATE */)) {3373        // We are only checking non-empty v-slot here3374        // since we only care about slots that introduce scope variables.3375        const vSlot = findDir(node, 'slot');3376        if (vSlot) {3377            vSlot.exp;3378            context.scopes.vSlot++;3379            return () => {3380                context.scopes.vSlot--;3381            };3382        }3383    }3384};3385// A NodeTransform that tracks scope identifiers for scoped slots with v-for.3386// This transform is only applied in non-browser builds with { prefixIdentifiers: true }3387const trackVForSlotScopes = (node, context) => {3388    let vFor;3389    if (isTemplateNode(node) &&3390        node.props.some(isVSlot) &&3391        (vFor = findDir(node, 'for'))) {3392        const result = (vFor.parseResult = parseForExpression(vFor.exp, context));3393        if (result) {3394            const { value, key, index } = result;3395            const { addIdentifiers, removeIdentifiers } = context;3396            value && addIdentifiers(value);3397            key && addIdentifiers(key);3398            index && addIdentifiers(index);3399            return () => {3400                value && removeIdentifiers(value);3401                key && removeIdentifiers(key);3402                index && removeIdentifiers(index);3403            };3404        }3405    }3406};3407const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);3408// Instead of being a DirectiveTransform, v-slot processing is called during3409// transformElement to build the slots object for a component.3410function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {3411    context.helper(WITH_CTX);3412    const { children, loc } = node;3413    const slotsProperties = [];3414    const dynamicSlots = [];3415    // If the slot is inside a v-for or another v-slot, force it to be dynamic3416    // since it likely uses a scope variable.3417    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;3418    // 1. Check for slot with slotProps on component itself.3419    //    <Comp v-slot="{ prop }"/>3420    const onComponentSlot = findDir(node, 'slot', true);3421    if (onComponentSlot) {3422        const { arg, exp } = onComponentSlot;3423        if (arg && !isStaticExp(arg)) {3424            hasDynamicSlots = true;3425        }3426        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));3427    }3428    // 2. Iterate through children and check for template slots3429    //    <template v-slot:foo="{ prop }">3430    let hasTemplateSlots = false;3431    let hasNamedDefaultSlot = false;3432    const implicitDefaultChildren = [];3433    const seenSlotNames = new Set();3434    for (let i = 0; i < children.length; i++) {3435        const slotElement = children[i];3436        let slotDir;3437        if (!isTemplateNode(slotElement) ||3438            !(slotDir = findDir(slotElement, 'slot', true))) {3439            // not a <template v-slot>, skip.3440            if (slotElement.type !== 3 /* COMMENT */) {3441                implicitDefaultChildren.push(slotElement);3442            }3443            continue;3444        }3445        if (onComponentSlot) {3446            // already has on-component slot - this is incorrect usage.3447            context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));3448            break;3449        }3450        hasTemplateSlots = true;3451        const { children: slotChildren, loc: slotLoc } = slotElement;3452        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;3453        // check if name is dynamic.3454        let staticSlotName;3455        if (isStaticExp(slotName)) {3456            staticSlotName = slotName ? slotName.content : `default`;3457        }3458        else {3459            hasDynamicSlots = true;3460        }3461        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);3462        // check if this slot is conditional (v-if/v-for)3463        let vIf;3464        let vElse;3465        let vFor;3466        if ((vIf = findDir(slotElement, 'if'))) {3467            hasDynamicSlots = true;3468            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));3469        }3470        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {3471            // find adjacent v-if3472            let j = i;3473            let prev;3474            while (j--) {3475                prev = children[j];3476                if (prev.type !== 3 /* COMMENT */) {3477                    break;3478                }3479            }3480            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {3481                // remove node3482                children.splice(i, 1);3483                i--;3484                // attach this slot to previous conditional3485                let conditional = dynamicSlots[dynamicSlots.length - 1];3486                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {3487                    conditional = conditional.alternate;3488                }3489                conditional.alternate = vElse.exp3490                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)3491                    : buildDynamicSlot(slotName, slotFunction);3492            }3493            else {3494                context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));3495            }3496        }3497        else if ((vFor = findDir(slotElement, 'for'))) {3498            hasDynamicSlots = true;3499            const parseResult = vFor.parseResult ||3500                parseForExpression(vFor.exp, context);3501            if (parseResult) {3502                // Render the dynamic slots as an array and add it to the createSlot()3503                // args. The runtime knows how to handle it appropriately.3504                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [3505                    parseResult.source,3506                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)3507                ]));3508            }3509            else {3510                context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));3511            }3512        }3513        else {3514            // check duplicate static names3515            if (staticSlotName) {3516                if (seenSlotNames.has(staticSlotName)) {3517                    context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));3518                    continue;3519                }3520                seenSlotNames.add(staticSlotName);3521                if (staticSlotName === 'default') {3522                    hasNamedDefaultSlot = true;3523                }3524            }3525            slotsProperties.push(createObjectProperty(slotName, slotFunction));3526        }3527    }3528    if (!onComponentSlot) {3529        const buildDefaultSlotProperty = (props, children) => {3530            const fn = buildSlotFn(props, children, loc);3531            if (context.compatConfig) {3532                fn.isNonScopedSlot = true;3533            }3534            return createObjectProperty(`default`, fn);3535        };3536        if (!hasTemplateSlots) {3537            // implicit default slot (on component)3538            slotsProperties.push(buildDefaultSlotProperty(undefined, children));3539        }3540        else if (implicitDefaultChildren.length &&3541            // #37663542            // with whitespace: 'preserve', whitespaces between slots will end up in3543            // implicitDefaultChildren. Ignore if all implicit children are whitespaces.3544            implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {3545            // implicit default slot (mixed with named slots)3546            if (hasNamedDefaultSlot) {3547                context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));3548            }3549            else {3550                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));3551            }3552        }3553    }3554    const slotFlag = hasDynamicSlots3555        ? 2 /* DYNAMIC */3556        : hasForwardedSlots(node.children)3557            ? 3 /* FORWARDED */3558            : 1 /* STABLE */;3559    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 3560    // 2 = compiled but dynamic = can skip normalization, but must run diff3561    // 1 = compiled and static = can skip normalization AND diff as optimized3562    createSimpleExpression(slotFlag + ((process.env.NODE_ENV !== 'production') ? ` /* ${slotFlagsText[slotFlag]} */` : ``), false))), loc);3563    if (dynamicSlots.length) {3564        slots = createCallExpression(context.helper(CREATE_SLOTS), [3565            slots,3566            createArrayExpression(dynamicSlots)3567        ]);3568    }3569    return {3570        slots,3571        hasDynamicSlots3572    };3573}3574function buildDynamicSlot(name, fn) {3575    return createObjectExpression([3576        createObjectProperty(`name`, name),3577        createObjectProperty(`fn`, fn)3578    ]);3579}3580function hasForwardedSlots(children) {3581    for (let i = 0; i < children.length; i++) {3582        const child = children[i];3583        switch (child.type) {3584            case 1 /* ELEMENT */:3585                if (child.tagType === 2 /* SLOT */ ||3586                    hasForwardedSlots(child.children)) {3587                    return true;3588                }3589                break;3590            case 9 /* IF */:3591                if (hasForwardedSlots(child.branches))3592                    return true;3593                break;3594            case 10 /* IF_BRANCH */:3595            case 11 /* FOR */:3596                if (hasForwardedSlots(child.children))3597                    return true;3598                break;3599        }3600    }3601    return false;3602}3603function isNonWhitespaceContent(node) {3604    if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)3605        return true;3606    return node.type === 2 /* TEXT */3607        ? !!node.content.trim()3608        : isNonWhitespaceContent(node.content);3609}3610// some directive transforms (e.g. v-model) may return a symbol for runtime3611// import, which should be used instead of a resolveDirective call.3612const directiveImportMap = new WeakMap();3613// generate a JavaScript AST for this element's codegen3614const transformElement = (node, context) => {3615    // perform the work on exit, after all child expressions have been3616    // processed and merged.3617    return function postTransformElement() {3618        node = context.currentNode;3619        if (!(node.type === 1 /* ELEMENT */ &&3620            (node.tagType === 0 /* ELEMENT */ ||3621                node.tagType === 1 /* COMPONENT */))) {3622            return;3623        }3624        const { tag, props } = node;3625        const isComponent = node.tagType === 1 /* COMPONENT */;3626        // The goal of the transform is to create a codegenNode implementing the3627        // VNodeCall interface.3628        let vnodeTag = isComponent3629            ? resolveComponentType(node, context)3630            : `"${tag}"`;3631        const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;3632        let vnodeProps;3633        let vnodeChildren;3634        let vnodePatchFlag;3635        let patchFlag = 0;3636        let vnodeDynamicProps;3637        let dynamicPropNames;3638        let vnodeDirectives;3639        let shouldUseBlock = 3640        // dynamic component may resolve to plain elements3641        isDynamicComponent ||3642            vnodeTag === TELEPORT ||3643            vnodeTag === SUSPENSE ||3644            (!isComponent &&3645                // <svg> and <foreignObject> must be forced into blocks so that block3646                // updates inside get proper isSVG flag at runtime. (#639, #643)3647                // This is technically web-specific, but splitting the logic out of core3648                // leads to too much unnecessary complexity.3649                (tag === 'svg' || tag === 'foreignObject'));3650        // props3651        if (props.length > 0) {3652            const propsBuildResult = buildProps(node, context);3653            vnodeProps = propsBuildResult.props;3654            patchFlag = propsBuildResult.patchFlag;3655            dynamicPropNames = propsBuildResult.dynamicPropNames;3656            const directives = propsBuildResult.directives;3657            vnodeDirectives =3658                directives && directives.length3659                    ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))3660                    : undefined;3661            if (propsBuildResult.shouldUseBlock) {3662                shouldUseBlock = true;3663            }3664        }3665        // children3666        if (node.children.length > 0) {3667            if (vnodeTag === KEEP_ALIVE) {3668                // Although a built-in component, we compile KeepAlive with raw children3669                // instead of slot functions so that it can be used inside Transition3670                // or other Transition-wrapping HOCs.3671                // To ensure correct updates with block optimizations, we need to:3672                // 1. Force keep-alive into a block. This avoids its children being3673                //    collected by a parent block.3674                shouldUseBlock = true;3675                // 2. Force keep-alive to always be updated, since it uses raw children.3676                patchFlag |= 1024 /* DYNAMIC_SLOTS */;3677                if ((process.env.NODE_ENV !== 'production') && node.children.length > 1) {3678                    context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {3679                        start: node.children[0].loc.start,3680                        end: node.children[node.children.length - 1].loc.end,3681                        source: ''3682                    }));3683                }3684            }3685            const shouldBuildAsSlots = isComponent &&3686                // Teleport is not a real component and has dedicated runtime handling3687                vnodeTag !== TELEPORT &&3688                // explained above.3689                vnodeTag !== KEEP_ALIVE;3690            if (shouldBuildAsSlots) {3691                const { slots, hasDynamicSlots } = buildSlots(node, context);3692                vnodeChildren = slots;3693                if (hasDynamicSlots) {3694                    patchFlag |= 1024 /* DYNAMIC_SLOTS */;3695                }3696            }3697            else if (node.children.length === 1 && vnodeTag !== TELEPORT) {3698                const child = node.children[0];3699                const type = child.type;3700                // check for dynamic text children3701                const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||3702                    type === 8 /* COMPOUND_EXPRESSION */;3703                if (hasDynamicTextChild &&3704                    getConstantType(child, context) === 0 /* NOT_CONSTANT */) {3705                    patchFlag |= 1 /* TEXT */;3706                }3707                // pass directly if the only child is a text node3708                // (plain / interpolation / expression)3709                if (hasDynamicTextChild || type === 2 /* TEXT */) {3710                    vnodeChildren = child;3711                }3712                else {3713                    vnodeChildren = node.children;3714                }3715            }3716            else {3717                vnodeChildren = node.children;3718            }3719        }3720        // patchFlag & dynamicPropNames3721        if (patchFlag !== 0) {3722            if ((process.env.NODE_ENV !== 'production')) {3723                if (patchFlag < 0) {3724                    // special flags (negative and mutually exclusive)3725                    vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;3726                }3727                else {3728                    // bitwise flags3729                    const flagNames = Object.keys(PatchFlagNames)3730                        .map(Number)3731                        .filter(n => n > 0 && patchFlag & n)3732                        .map(n => PatchFlagNames[n])3733                        .join(`, `);3734                    vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;3735                }3736            }3737            else {3738                vnodePatchFlag = String(patchFlag);3739            }3740            if (dynamicPropNames && dynamicPropNames.length) {3741                vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);3742            }3743        }3744        node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);3745    };3746};3747function resolveComponentType(node, context, ssr = false) {3748    let { tag } = node;3749    // 1. dynamic component3750    const isExplicitDynamic = isComponentTag(tag);3751    const isProp = findProp(node, 'is');3752    if (isProp) {3753        if (isExplicitDynamic ||3754            (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {3755            const exp = isProp.type === 6 /* ATTRIBUTE */3756                ? isProp.value && createSimpleExpression(isProp.value.content, true)3757                : isProp.exp;3758            if (exp) {3759                return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3760                    exp3761                ]);3762            }3763        }3764        else if (isProp.type === 6 /* ATTRIBUTE */ &&3765            isProp.value.content.startsWith('vue:')) {3766            // <button is="vue:xxx">3767            // if not <component>, only is value that starts with "vue:" will be3768            // treated as component by the parse phase and reach here, unless it's3769            // compat mode where all is values are considered components3770            tag = isProp.value.content.slice(4);3771        }3772    }3773    // 1.5 v-is (TODO: Deprecate)3774    const isDir = !isExplicitDynamic && findDir(node, 'is');3775    if (isDir && isDir.exp) {3776        return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [3777            isDir.exp3778        ]);3779    }3780    // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)3781    const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);3782    if (builtIn) {3783        // built-ins are simply fallthroughs / have special handling during ssr3784        // so we don't need to import their runtime equivalents3785        if (!ssr)3786            context.helper(builtIn);3787        return builtIn;3788    }3789    // 5. user component (resolve)3790    context.helper(RESOLVE_COMPONENT);3791    context.components.add(tag);3792    return toValidAssetId(tag, `component`);3793}3794function buildProps(node, context, props = node.props, ssr = false) {3795    const { tag, loc: elementLoc, children } = node;3796    const isComponent = node.tagType === 1 /* COMPONENT */;3797    let properties = [];3798    const mergeArgs = [];3799    const runtimeDirectives = [];3800    const hasChildren = children.length > 0;3801    let shouldUseBlock = false;3802    // patchFlag analysis3803    let patchFlag = 0;3804    let hasRef = false;3805    let hasClassBinding = false;3806    let hasStyleBinding = false;3807    let hasHydrationEventBinding = false;3808    let hasDynamicKeys = false;3809    let hasVnodeHook = false;3810    const dynamicPropNames = [];3811    const analyzePatchFlag = ({ key, value }) => {3812        if (isStaticExp(key)) {3813            const name = key.content;3814            const isEventHandler = isOn(name);3815            if (!isComponent &&3816                isEventHandler &&3817                // omit the flag for click handlers because hydration gives click3818                // dedicated fast path.3819                name.toLowerCase() !== 'onclick' &&3820                // omit v-model handlers3821                name !== 'onUpdate:modelValue' &&3822                // omit onVnodeXXX hooks3823                !isReservedProp(name)) {3824                hasHydrationEventBinding = true;3825            }3826            if (isEventHandler && isReservedProp(name)) {3827                hasVnodeHook = true;3828            }3829            if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||3830                ((value.type === 4 /* SIMPLE_EXPRESSION */ ||3831                    value.type === 8 /* COMPOUND_EXPRESSION */) &&3832                    getConstantType(value, context) > 0)) {3833                // skip if the prop is a cached handler or has constant value3834                return;3835            }3836            if (name === 'ref') {3837                hasRef = true;3838            }3839            else if (name === 'class') {3840                hasClassBinding = true;3841            }3842            else if (name === 'style') {3843                hasStyleBinding = true;3844            }3845            else if (name !== 'key' && !dynamicPropNames.includes(name)) {3846                dynamicPropNames.push(name);3847            }3848            // treat the dynamic class and style binding of the component as dynamic props3849            if (isComponent &&3850                (name === 'class' || name === 'style') &&3851                !dynamicPropNames.includes(name)) {3852                dynamicPropNames.push(name);3853            }3854        }3855        else {3856            hasDynamicKeys = true;3857        }3858    };3859    for (let i = 0; i < props.length; i++) {3860        // static attribute3861        const prop = props[i];3862        if (prop.type === 6 /* ATTRIBUTE */) {3863            const { loc, name, value } = prop;3864            let isStatic = true;3865            if (name === 'ref') {3866                hasRef = true;3867                if (context.scopes.vFor > 0) {3868                    properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));3869                }3870            }3871            // skip is on <component>, or is="vue:xxx"3872            if (name === 'is' &&3873                (isComponentTag(tag) ||3874                    (value && value.content.startsWith('vue:')) ||3875                    (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {3876                continue;3877            }3878            properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));3879        }3880        else {3881            // directives3882            const { name, arg, exp, loc } = prop;3883            const isVBind = name === 'bind';3884            const isVOn = name === 'on';3885            // skip v-slot - it is handled by its dedicated transform.3886            if (name === 'slot') {3887                if (!isComponent) {3888                    context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));3889                }3890                continue;3891            }3892            // skip v-once/v-memo - they are handled by dedicated transforms.3893            if (name === 'once' || name === 'memo') {3894                continue;3895            }3896            // skip v-is and :is on <component>3897            if (name === 'is' ||3898                (isVBind &&3899                    isStaticArgOf(arg, 'is') &&3900                    (isComponentTag(tag) ||3901                        (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {3902                continue;3903            }3904            // skip v-on in SSR compilation3905            if (isVOn && ssr) {3906                continue;3907            }3908            if (3909            // #938: elements with dynamic keys should be forced into blocks3910            (isVBind && isStaticArgOf(arg, 'key')) ||3911                // inline before-update hooks need to force block so that it is invoked3912                // before children3913                (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {3914                shouldUseBlock = true;3915            }3916            if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {3917                properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));3918            }3919            // special case for v-bind and v-on with no argument3920            if (!arg && (isVBind || isVOn)) {3921                hasDynamicKeys = true;3922                if (exp) {3923                    if (properties.length) {3924                        mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));3925                        properties = [];3926                    }3927                    if (isVBind) {3928                        {3929                            // 2.x v-bind object order compat3930                            if ((process.env.NODE_ENV !== 'production')) {3931                                const hasOverridableKeys = mergeArgs.some(arg => {3932                                    if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {3933                                        return arg.properties.some(({ key }) => {3934                                            if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||3935                                                !key.isStatic) {3936                                                return true;3937                                            }3938                                            return (key.content !== 'class' &&3939                                                key.content !== 'style' &&3940                                                !isOn(key.content));3941                                        });3942                                    }3943                                    else {3944                                        // dynamic expression3945                                        return true;3946                                    }3947                                });3948                                if (hasOverridableKeys) {3949                                    checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);3950                                }3951                            }3952                            if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {3953                                mergeArgs.unshift(exp);3954                                continue;3955                            }3956                        }3957                        mergeArgs.push(exp);3958                    }3959                    else {3960                        // v-on="obj" -> toHandlers(obj)3961                        mergeArgs.push({3962                            type: 14 /* JS_CALL_EXPRESSION */,3963                            loc,3964                            callee: context.helper(TO_HANDLERS),3965                            arguments: [exp]3966                        });3967                    }3968                }3969                else {3970                    context.onError(createCompilerError(isVBind3971                        ? 34 /* X_V_BIND_NO_EXPRESSION */3972                        : 35 /* X_V_ON_NO_EXPRESSION */, loc));3973                }3974                continue;3975            }3976            const directiveTransform = context.directiveTransforms[name];3977            if (directiveTransform) {3978                // has built-in directive transform.3979                const { props, needRuntime } = directiveTransform(prop, node, context);3980                !ssr && props.forEach(analyzePatchFlag);3981                properties.push(...props);3982                if (needRuntime) {3983                    runtimeDirectives.push(prop);3984                    if (isSymbol(needRuntime)) {3985                        directiveImportMap.set(prop, needRuntime);3986                    }3987                }3988            }3989            else {3990                // no built-in transform, this is a user custom directive.3991                runtimeDirectives.push(prop);3992                // custom dirs may use beforeUpdate so they need to force blocks3993                // to ensure before-update gets called before children update3994                if (hasChildren) {3995                    shouldUseBlock = true;3996                }3997            }3998        }3999    }4000    let propsExpression = undefined;4001    // has v-bind="object" or v-on="object", wrap with mergeProps4002    if (mergeArgs.length) {4003        if (properties.length) {4004            mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));4005        }4006        if (mergeArgs.length > 1) {4007            propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);4008        }4009        else {4010            // single v-bind with nothing else - no need for a mergeProps call4011            propsExpression = mergeArgs[0];4012        }4013    }4014    else if (properties.length) {4015        propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);4016    }4017    // patchFlag analysis4018    if (hasDynamicKeys) {4019        patchFlag |= 16 /* FULL_PROPS */;4020    }4021    else {4022        if (hasClassBinding && !isComponent) {4023            patchFlag |= 2 /* CLASS */;4024        }4025        if (hasStyleBinding && !isComponent) {4026            patchFlag |= 4 /* STYLE */;4027        }4028        if (dynamicPropNames.length) {4029            patchFlag |= 8 /* PROPS */;4030        }4031        if (hasHydrationEventBinding) {4032            patchFlag |= 32 /* HYDRATE_EVENTS */;4033        }4034    }4035    if (!shouldUseBlock &&4036        (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&4037        (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {4038        patchFlag |= 512 /* NEED_PATCH */;4039    }4040    // pre-normalize props, SSR is skipped for now4041    if (!context.inSSR && propsExpression) {4042        switch (propsExpression.type) {4043            case 15 /* JS_OBJECT_EXPRESSION */:4044                // means that there is no v-bind,4045                // but still need to deal with dynamic key binding4046                let classKeyIndex = -1;4047                let styleKeyIndex = -1;4048                let hasDynamicKey = false;4049                for (let i = 0; i < propsExpression.properties.length; i++) {4050                    const key = propsExpression.properties[i].key;4051                    if (isStaticExp(key)) {4052                        if (key.content === 'class') {4053                            classKeyIndex = i;4054                        }4055                        else if (key.content === 'style') {4056                            styleKeyIndex = i;4057                        }4058                    }4059                    else if (!key.isHandlerKey) {4060                        hasDynamicKey = true;4061                    }4062                }4063                const classProp = propsExpression.properties[classKeyIndex];4064                const styleProp = propsExpression.properties[styleKeyIndex];4065                // no dynamic key4066                if (!hasDynamicKey) {4067                    if (classProp && !isStaticExp(classProp.value)) {4068                        classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);4069                    }4070                    if (styleProp &&4071                        !isStaticExp(styleProp.value) &&4072                        // the static style is compiled into an object,4073                        // so use `hasStyleBinding` to ensure that it is a dynamic style binding4074                        (hasStyleBinding ||4075                            // v-bind:style and style both exist,4076                            // v-bind:style with static literal object4077                            styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {4078                        styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);4079                    }4080                }4081                else {4082                    // dynamic key binding, wrap with `normalizeProps`4083                    propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);4084                }4085                break;4086            case 14 /* JS_CALL_EXPRESSION */:4087                // mergeProps call, do nothing4088                break;4089            default:4090                // single v-bind4091                propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [4092                    createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [4093                        propsExpression4094                    ])4095                ]);4096                break;4097        }4098    }4099    return {4100        props: propsExpression,4101        directives: runtimeDirectives,4102        patchFlag,4103        dynamicPropNames,4104        shouldUseBlock4105    };4106}4107// Dedupe props in an object literal.4108// Literal duplicated attributes would have been warned during the parse phase,4109// however, it's possible to encounter duplicated `onXXX` handlers with different4110// modifiers. We also need to merge static and dynamic class / style attributes.4111// - onXXX handlers / style: merge into array4112// - class: merge into single expression with concatenation4113function dedupeProperties(properties) {4114    const knownProps = new Map();4115    const deduped = [];4116    for (let i = 0; i < properties.length; i++) {4117        const prop = properties[i];4118        // dynamic keys are always allowed4119        if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {4120            deduped.push(prop);4121            continue;4122        }4123        const name = prop.key.content;4124        const existing = knownProps.get(name);4125        if (existing) {4126            if (name === 'style' || name === 'class' || isOn(name)) {4127                mergeAsArray(existing, prop);4128            }4129            // unexpected duplicate, should have emitted error during parse4130        }4131        else {4132            knownProps.set(name, prop);4133            deduped.push(prop);4134        }4135    }4136    return deduped;4137}4138function mergeAsArray(existing, incoming) {4139    if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {4140        existing.value.elements.push(incoming.value);4141    }4142    else {4143        existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);4144    }4145}4146function buildDirectiveArgs(dir, context) {4147    const dirArgs = [];4148    const runtime = directiveImportMap.get(dir);4149    if (runtime) {4150        // built-in directive with runtime4151        dirArgs.push(context.helperString(runtime));4152    }4153    else {4154        {4155            // inject statement for resolving directive4156            context.helper(RESOLVE_DIRECTIVE);4157            context.directives.add(dir.name);4158            dirArgs.push(toValidAssetId(dir.name, `directive`));4159        }4160    }4161    const { loc } = dir;4162    if (dir.exp)4163        dirArgs.push(dir.exp);4164    if (dir.arg) {4165        if (!dir.exp) {4166            dirArgs.push(`void 0`);4167        }4168        dirArgs.push(dir.arg);4169    }4170    if (Object.keys(dir.modifiers).length) {4171        if (!dir.arg) {4172            if (!dir.exp) {4173                dirArgs.push(`void 0`);4174            }4175            dirArgs.push(`void 0`);4176        }4177        const trueExpression = createSimpleExpression(`true`, false, loc);4178        dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));4179    }4180    return createArrayExpression(dirArgs, dir.loc);4181}4182function stringifyDynamicPropNames(props) {4183    let propsNamesString = `[`;4184    for (let i = 0, l = props.length; i < l; i++) {4185        propsNamesString += JSON.stringify(props[i]);4186        if (i < l - 1)4187            propsNamesString += ', ';4188    }4189    return propsNamesString + `]`;4190}4191function isComponentTag(tag) {4192    return tag === 'component' || tag === 'Component';4193}4194(process.env.NODE_ENV !== 'production')4195    ? Object.freeze({})4196    : {};4197(process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];4198const cacheStringFunction = (fn) => {4199    const cache = Object.create(null);4200    return ((str) => {4201        const hit = cache[str];4202        return hit || (cache[str] = fn(str));4203    });4204};4205const camelizeRE = /-(\w)/g;4206/**4207 * @private4208 */4209const camelize = cacheStringFunction((str) => {4210    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));4211});4212const transformSlotOutlet = (node, context) => {4213    if (isSlotOutlet(node)) {4214        const { children, loc } = node;4215        const { slotName, slotProps } = processSlotOutlet(node, context);4216        const slotArgs = [4217            context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,4218            slotName,4219            '{}',4220            'undefined',4221            'true'4222        ];4223        let expectedLen = 2;4224        if (slotProps) {4225            slotArgs[2] = slotProps;4226            expectedLen = 3;4227        }4228        if (children.length) {4229            slotArgs[3] = createFunctionExpression([], children, false, false, loc);4230            expectedLen = 4;4231        }4232        if (context.scopeId && !context.slotted) {4233            expectedLen = 5;4234        }4235        slotArgs.splice(expectedLen); // remove unused arguments4236        node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);4237    }4238};4239function processSlotOutlet(node, context) {4240    let slotName = `"default"`;4241    let slotProps = undefined;4242    const nonNameProps = [];4243    for (let i = 0; i < node.props.length; i++) {4244        const p = node.props[i];4245        if (p.type === 6 /* ATTRIBUTE */) {4246            if (p.value) {4247                if (p.name === 'name') {4248                    slotName = JSON.stringify(p.value.content);4249                }4250                else {4251                    p.name = camelize(p.name);4252                    nonNameProps.push(p);4253                }4254            }4255        }4256        else {4257            if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {4258                if (p.exp)4259                    slotName = p.exp;4260            }4261            else {4262                if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {4263                    p.arg.content = camelize(p.arg.content);4264                }4265                nonNameProps.push(p);4266            }4267        }4268    }4269    if (nonNameProps.length > 0) {4270        const { props, directives } = buildProps(node, context, nonNameProps);4271        slotProps = props;4272        if (directives.length) {4273            context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));4274        }4275    }4276    return {4277        slotName,4278        slotProps4279    };4280}4281const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;4282const transformOn = (dir, node, context, augmentor) => {4283    const { loc, modifiers, arg } = dir;4284    if (!dir.exp && !modifiers.length) {4285        context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));4286    }4287    let eventName;4288    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4289        if (arg.isStatic) {4290            let rawName = arg.content;4291            // TODO deprecate @vnodeXXX usage4292            if (rawName.startsWith('vue:')) {4293                rawName = `vnode-${rawName.slice(4)}`;4294            }4295            // for all event listeners, auto convert it to camelCase. See issue #22494296            eventName = createSimpleExpression(toHandlerKey(camelize$1(rawName)), true, arg.loc);4297        }4298        else {4299            // #23884300            eventName = createCompoundExpression([4301                `${context.helperString(TO_HANDLER_KEY)}(`,4302                arg,4303                `)`4304            ]);4305        }4306    }4307    else {4308        // already a compound expression.4309        eventName = arg;4310        eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);4311        eventName.children.push(`)`);4312    }4313    // handler processing4314    let exp = dir.exp;4315    if (exp && !exp.content.trim()) {4316        exp = undefined;4317    }4318    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;4319    if (exp) {4320        const isMemberExp = isMemberExpression(exp.content);4321        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));4322        const hasMultipleStatements = exp.content.includes(`;`);4323        if ((process.env.NODE_ENV !== 'production') && true) {4324            validateBrowserExpression(exp, context, false, hasMultipleStatements);4325        }4326        if (isInlineStatement || (shouldCache && isMemberExp)) {4327            // wrap inline statement in a function expression4328            exp = createCompoundExpression([4329                `${isInlineStatement4330                    ? `$event`4331                    : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,4332                exp,4333                hasMultipleStatements ? `}` : `)`4334            ]);4335        }4336    }4337    let ret = {4338        props: [4339            createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))4340        ]4341    };4342    // apply extended compiler augmentor4343    if (augmentor) {4344        ret = augmentor(ret);4345    }4346    if (shouldCache) {4347        // cache handlers so that it's always the same handler being passed down.4348        // this avoids unnecessary re-renders when users use inline handlers on4349        // components.4350        ret.props[0].value = context.cache(ret.props[0].value);4351    }4352    // mark the key as handler for props normalization check4353    ret.props.forEach(p => (p.key.isHandlerKey = true));4354    return ret;4355};4356// v-bind without arg is handled directly in ./transformElements.ts due to it affecting4357// codegen for the entire props object. This transform here is only for v-bind4358// *with* args.4359const transformBind = (dir, _node, context) => {4360    const { exp, modifiers, loc } = dir;4361    const arg = dir.arg;4362    if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {4363        arg.children.unshift(`(`);4364        arg.children.push(`) || ""`);4365    }4366    else if (!arg.isStatic) {4367        arg.content = `${arg.content} || ""`;4368    }4369    // .sync is replaced by v-model:arg4370    if (modifiers.includes('camel')) {4371        if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4372            if (arg.isStatic) {4373                arg.content = camelize$1(arg.content);4374            }4375            else {4376                arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;4377            }4378        }4379        else {4380            arg.children.unshift(`${context.helperString(CAMELIZE)}(`);4381            arg.children.push(`)`);4382        }4383    }4384    if (!context.inSSR) {4385        if (modifiers.includes('prop')) {4386            injectPrefix(arg, '.');4387        }4388        if (modifiers.includes('attr')) {4389            injectPrefix(arg, '^');4390        }4391    }4392    if (!exp ||4393        (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {4394        context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));4395        return {4396            props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]4397        };4398    }4399    return {4400        props: [createObjectProperty(arg, exp)]4401    };4402};4403const injectPrefix = (arg, prefix) => {4404    if (arg.type === 4 /* SIMPLE_EXPRESSION */) {4405        if (arg.isStatic) {4406            arg.content = prefix + arg.content;4407        }4408        else {4409            arg.content = `\`${prefix}\${${arg.content}}\``;4410        }4411    }4412    else {4413        arg.children.unshift(`'${prefix}' + (`);4414        arg.children.push(`)`);4415    }4416};4417// Merge adjacent text nodes and expressions into a single expression4418// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.4419const transformText = (node, context) => {4420    if (node.type === 0 /* ROOT */ ||4421        node.type === 1 /* ELEMENT */ ||4422        node.type === 11 /* FOR */ ||4423        node.type === 10 /* IF_BRANCH */) {4424        // perform the transform on node exit so that all expressions have already4425        // been processed.4426        return () => {4427            const children = node.children;4428            let currentContainer = undefined;4429            let hasText = false;4430            for (let i = 0; i < children.length; i++) {4431                const child = children[i];4432                if (isText(child)) {4433                    hasText = true;4434                    for (let j = i + 1; j < children.length; j++) {4435                        const next = children[j];4436                        if (isText(next)) {4437                            if (!currentContainer) {4438                                currentContainer = children[i] = {4439                                    type: 8 /* COMPOUND_EXPRESSION */,4440                                    loc: child.loc,4441                                    children: [child]4442                                };4443                            }4444                            // merge adjacent text node into current4445                            currentContainer.children.push(` + `, next);4446                            children.splice(j, 1);4447                            j--;4448                        }4449                        else {4450                            currentContainer = undefined;4451                            break;4452                        }4453                    }4454                }4455            }4456            if (!hasText ||4457                // if this is a plain element with a single text child, leave it4458                // as-is since the runtime has dedicated fast path for this by directly4459                // setting textContent of the element.4460                // for component root it's always normalized anyway.4461                (children.length === 1 &&4462                    (node.type === 0 /* ROOT */ ||4463                        (node.type === 1 /* ELEMENT */ &&4464                            node.tagType === 0 /* ELEMENT */ &&4465                            // #37564466                            // custom directives can potentially add DOM elements arbitrarily,4467                            // we need to avoid setting textContent of the element at runtime4468                            // to avoid accidentally overwriting the DOM elements added4469                            // by the user through custom directives.4470                            !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&4471                                !context.directiveTransforms[p.name]) &&4472                            // in compat mode, <template> tags with no special directives4473                            // will be rendered as a fragment so its children must be4474                            // converted into vnodes.4475                            !(node.tag === 'template'))))) {4476                return;4477            }4478            // pre-convert text nodes into createTextVNode(text) calls to avoid4479            // runtime normalization.4480            for (let i = 0; i < children.length; i++) {4481                const child = children[i];4482                if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {4483                    const callArgs = [];4484                    // createTextVNode defaults to single whitespace, so if it is a4485                    // single space the code could be an empty call to save bytes.4486                    if (child.type !== 2 /* TEXT */ || child.content !== ' ') {4487                        callArgs.push(child);4488                    }4489                    // mark dynamic text with flag so it gets patched inside a block4490                    if (!context.ssr &&4491                        getConstantType(child, context) === 0 /* NOT_CONSTANT */) {4492                        callArgs.push(1 /* TEXT */ +4493                            ((process.env.NODE_ENV !== 'production') ? ` /* ${PatchFlagNames[1 /* TEXT */]} */` : ``));4494                    }4495                    children[i] = {4496                        type: 12 /* TEXT_CALL */,4497                        content: child,4498                        loc: child.loc,4499                        codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)4500                    };4501                }4502            }4503        };4504    }4505};4506const seen = new WeakSet();4507const transformOnce = (node, context) => {4508    if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {4509        if (seen.has(node) || context.inVOnce) {4510            return;4511        }4512        seen.add(node);4513        context.inVOnce = true;4514        context.helper(SET_BLOCK_TRACKING);4515        return () => {4516            context.inVOnce = false;4517            const cur = context.currentNode;4518            if (cur.codegenNode) {4519                cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);4520            }4521        };4522    }4523};4524const transformModel = (dir, node, context) => {4525    const { exp, arg } = dir;4526    if (!exp) {4527        context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));4528        return createTransformProps();4529    }4530    const rawExp = exp.loc.source;4531    const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;4532    // im SFC <script setup> inline mode, the exp may have been transformed into4533    // _unref(exp)4534    context.bindingMetadata[rawExp];4535    const maybeRef = !true    /* SETUP_CONST */;4536    if (!expString.trim() ||4537        (!isMemberExpression(expString) && !maybeRef)) {4538        context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));4539        return createTransformProps();4540    }4541    const propName = arg ? arg : createSimpleExpression('modelValue', true);4542    const eventName = arg4543        ? isStaticExp(arg)4544            ? `onUpdate:${arg.content}`4545            : createCompoundExpression(['"onUpdate:" + ', arg])4546        : `onUpdate:modelValue`;4547    let assignmentExp;4548    const eventArg = context.isTS ? `($event: any)` : `$event`;4549    {4550        assignmentExp = createCompoundExpression([4551            `${eventArg} => ((`,4552            exp,4553            `) = $event)`4554        ]);4555    }4556    const props = [4557        // modelValue: foo4558        createObjectProperty(propName, dir.exp),4559        // "onUpdate:modelValue": $event => (foo = $event)4560        createObjectProperty(eventName, assignmentExp)4561    ];4562    // modelModifiers: { foo: true, "bar-baz": true }4563    if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {4564        const modifiers = dir.modifiers4565            .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)4566            .join(`, `);4567        const modifiersKey = arg4568            ? isStaticExp(arg)4569                ? `${arg.content}Modifiers`4570                : createCompoundExpression([arg, ' + "Modifiers"'])4571            : `modelModifiers`;4572        props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));4573    }4574    return createTransformProps(props);4575};4576function createTransformProps(props = []) {4577    return { props };4578}4579const validDivisionCharRE = /[\w).+\-_$\]]/;4580const transformFilter = (node, context) => {4581    if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {4582        return;4583    }4584    if (node.type === 5 /* INTERPOLATION */) {4585        // filter rewrite is applied before expression transform so only4586        // simple expressions are possible at this stage4587        rewriteFilter(node.content, context);4588    }4589    if (node.type === 1 /* ELEMENT */) {4590        node.props.forEach((prop) => {4591            if (prop.type === 7 /* DIRECTIVE */ &&4592                prop.name !== 'for' &&4593                prop.exp) {4594                rewriteFilter(prop.exp, context);4595            }...Using AI Code Generation
1const { isCompatEnabled } = require('playwright-core/lib/server/browserContext');2const { chromium } = require('playwright-core');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  console.log(isCompatEnabled(context));8  await browser.close();9})();10[MIT](LICENSE)Using AI Code Generation
1const { devices } = require('playwright');2const iPhone = devices['iPhone 11 Pro'];3const { chromium } = require('playwright');4(async () => {5  const browser = await chromium.launch();6  const context = await browser.newContext({7    geolocation: { longitude: 12.492507, latitude: 41.889938 },8  });9  const page = await context.newPage();10  await page.click('text="Your location"');11  await page.waitForSelector('text="Your device"');12  await page.click('text="Your device"');13  await page.evaluate(() => console.log(navigator.permissions.query));14  await browser.close();15})();16const { devices } = require('playwright');17const iPhone = devices['iPhone 11 Pro'];18const { chromium } = require('playwright');19(async () => {20  const browser = await chromium.launch();21  const context = await browser.newContext({22    geolocation: { longitude: 12.492507, latitude: 41.889938 },23  });24  const page = await context.newPage();25  await page.click('text="Your location"');26  await page.waitForSelector('text="Your device"');27  await page.click('text="Your device"');28  await page.evaluate(() => console.log(navigator.userAgent));29  await browser.close();30})();Using AI Code Generation
1const { isCompatEnabled } = require('playwright/lib/server/chromium/crBrowser');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const page = await browser.newPage();6  console.log(isCompatEnabled(page));7  await browser.close();8})();9We welcome contributions to Playwright! Please read the [contributing guide](Using AI Code Generation
1const { isCompatEnabled } = require('@playwright/test/lib/server/compat');2const { isCompatEnabled } = require('@playwright/test/lib/server/compat');3const { test, expect } = require('@playwright/test');4test('Test', async ({ page }) => {5  const isCompat = isCompatEnabled(page);6  expect(isCompat).toBe(false);7});8const { test, expect } = require('@playwright/test');9test('Test', async ({ page }) => {10  const isCompat = page.isCompatEnabled();11  expect(isCompat).toBe(true);12});13### `isCompatEnabled(page: Page): boolean`14### `page.isCompatEnabled(): boolean`15- [Playwright](Using AI Code Generation
1const { isCompatEnabled } = require('@playwright/test/lib/server/compat');2const { isCompatEnabled } = require('@playwright/test/lib/server/compat');3const { test, expect } = require('@playwright/test');4test('test', async ({ page }) => {5  await page.click('text=Get started');6  await page.click('text=Docs');7  await page.click('text=API');8  await page.click('text=Using AI Code Generation
1const { isCompatEnabled } = require('playwright/lib/server/chromium/crBrowser');2const browser = await chromium.launch();3const page = await browser.newPage();4const isCompat = isCompatEnabled(page);5await browser.close();6const { chromium } = require('playwright');7(async () => {8  const browser = await chromium.launch();9  const context = await browser.newContext();10  const page = await context.newPage();11  await context.close();12})();13-   **geolocation** <[Object]> An object which specifies `latitude` (required) and `longitude` (required),Using AI Code Generation
1const { isCompatEnabled } = require("playwright/lib/server/browserContext");2console.log(isCompatEnabled());3const { isCompatEnabled } = require("playwright/lib/server/browserContext");4console.log(isCompatEnabled());5const { isCompatEnabled } = require("playwright/lib/server/browserContext");6console.log(isCompatEnabled());7const { isCompatEnabled } = require("playwright/lib/server/browserContext");8console.log(isCompatEnabled());9const { isCompatEnabled } = require("playwright/lib/server/browserContext");10console.log(isCompatEnabled());11const { isCompatEnabled } = require("playwright/lib/server/browserContext");12console.log(isCompatEnabled());13const { isCompatEnabled } = require("playwright/lib/server/browserContext");14console.log(isCompatEnabled());LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
