HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/node_modules/@vue/compiler-sfc/dist/compiler-sfc.global.js
var VueCompilerSFC = (function (exports, postcss) {
  'use strict';

  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e['default'] : e; }

  var postcss__default = /*#__PURE__*/_interopDefaultLegacy(postcss);

  /**
   * Make a map and return a function for checking if a key
   * is in that map.
   * IMPORTANT: all calls of this function must be prefixed with
   * \/\*#\_\_PURE\_\_\*\/
   * So that rollup can tree-shake them if necessary.
   */
  function makeMap(str, expectsLowerCase) {
      const map = Object.create(null);
      const list = str.split(',');
      for (let i = 0; i < list.length; i++) {
          map[list[i]] = true;
      }
      return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
  }

  // Patch flags are optimization hints generated by the compiler.
  // when a block with dynamicChildren is encountered during diff, the algorithm
  // enters "optimized mode". In this mode, we know that the vdom is produced by
  // a render function generated by the compiler, so the algorithm only needs to
  // handle updates explicitly marked by these patch flags.
  // dev only flag -> name mapping
  const PatchFlagNames = {
      [1 /* TEXT */]: `TEXT`,
      [2 /* CLASS */]: `CLASS`,
      [4 /* STYLE */]: `STYLE`,
      [8 /* PROPS */]: `PROPS`,
      [16 /* FULL_PROPS */]: `FULL_PROPS`,
      [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
      [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
      [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
      [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
      [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
      [512 /* NEED_PATCH */]: `NEED_PATCH`,
      [-1 /* HOISTED */]: `HOISTED`,
      [-2 /* BAIL */]: `BAIL`
  };

  const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
      'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
      'Object,Boolean,String,RegExp,Map,Set,JSON,Intl';
  const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);

  const range = 2;
  function generateCodeFrame(source, start = 0, end = source.length) {
      const lines = source.split(/\r?\n/);
      let count = 0;
      const res = [];
      for (let i = 0; i < lines.length; i++) {
          count += lines[i].length + 1;
          if (count >= start) {
              for (let j = i - range; j <= i + range || end > count; j++) {
                  if (j < 0 || j >= lines.length)
                      continue;
                  const line = j + 1;
                  res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}|  ${lines[j]}`);
                  const lineLength = lines[j].length;
                  if (j === i) {
                      // push underline
                      const pad = start - (count - lineLength) + 1;
                      const length = Math.max(1, end > count ? lineLength - pad : end - start);
                      res.push(`   |  ` + ' '.repeat(pad) + '^'.repeat(length));
                  }
                  else if (j > i) {
                      if (end > count) {
                          const length = Math.max(Math.min(end - count, lineLength), 1);
                          res.push(`   |  ` + '^'.repeat(length));
                      }
                      count += lineLength + 1;
                  }
              }
              break;
          }
      }
      return res.join('\n');
  }

  /**
   * On the client we only need to offer special cases for boolean attributes that
   * have different names from their corresponding dom properties:
   * - itemscope -> N/A
   * - allowfullscreen -> allowFullscreen
   * - formnovalidate -> formNoValidate
   * - ismap -> isMap
   * - nomodule -> noModule
   * - novalidate -> noValidate
   * - readonly -> readOnly
   */
  const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
  /**
   * The full list is needed during SSR to produce the correct initial markup.
   */
  const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs +
      `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` +
      `loop,open,required,reversed,scoped,seamless,` +
      `checked,muted,multiple,selected`);
  const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/;
  const attrValidationCache = {};
  function isSSRSafeAttrName(name) {
      if (attrValidationCache.hasOwnProperty(name)) {
          return attrValidationCache[name];
      }
      const isUnsafe = unsafeAttrCharRE.test(name);
      if (isUnsafe) {
          console.error(`unsafe attribute name: ${name}`);
      }
      return (attrValidationCache[name] = !isUnsafe);
  }
  const propsToAttrMap = {
      acceptCharset: 'accept-charset',
      className: 'class',
      htmlFor: 'for',
      httpEquiv: 'http-equiv'
  };
  /**
   * CSS properties that accept plain numbers
   */
  const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` +
      `border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` +
      `columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` +
      `grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` +
      `grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` +
      `line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` +
      // SVG
      `fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` +
      `stroke-miterlimit,stroke-opacity,stroke-width`);
  /**
   * Known attributes, this is used for stringification of runtime static nodes
   * so that we don't stringify bindings that cannot be set from HTML.
   * Don't also forget to allow `data-*` and `aria-*`!
   * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
   */
  const isKnownAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` +
      `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` +
      `border,buffered,capture,challenge,charset,checked,cite,class,code,` +
      `codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` +
      `coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` +
      `disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` +
      `formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` +
      `height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` +
      `ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` +
      `manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` +
      `open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` +
      `referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` +
      `selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` +
      `start,step,style,summary,tabindex,target,title,translate,type,usemap,` +
      `value,width,wrap`);

  function normalizeStyle(value) {
      if (isArray(value)) {
          const res = {};
          for (let i = 0; i < value.length; i++) {
              const item = value[i];
              const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item);
              if (normalized) {
                  for (const key in normalized) {
                      res[key] = normalized[key];
                  }
              }
          }
          return res;
      }
      else if (isObject(value)) {
          return value;
      }
  }
  const listDelimiterRE = /;(?![^(]*\))/g;
  const propertyDelimiterRE = /:(.+)/;
  function parseStringStyle(cssText) {
      const ret = {};
      cssText.split(listDelimiterRE).forEach(item => {
          if (item) {
              const tmp = item.split(propertyDelimiterRE);
              tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
          }
      });
      return ret;
  }
  function stringifyStyle(styles) {
      let ret = '';
      if (!styles) {
          return ret;
      }
      for (const key in styles) {
          const value = styles[key];
          const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key);
          if (isString(value) ||
              (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) {
              // only render valid values
              ret += `${normalizedKey}:${value};`;
          }
      }
      return ret;
  }
  function normalizeClass(value) {
      let res = '';
      if (isString(value)) {
          res = value;
      }
      else if (isArray(value)) {
          for (let i = 0; i < value.length; i++) {
              res += normalizeClass(value[i]) + ' ';
          }
      }
      else if (isObject(value)) {
          for (const name in value) {
              if (value[name]) {
                  res += name + ' ';
              }
          }
      }
      return res.trim();
  }

  // These tag configs are shared between compiler-dom and runtime-dom, so they
  // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
  const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
      'header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,' +
      'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
      'data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,' +
      'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
      'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
      'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
      'option,output,progress,select,textarea,details,dialog,menu,' +
      'summary,template,blockquote,iframe,tfoot';
  // https://developer.mozilla.org/en-US/docs/Web/SVG/Element
  const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
      'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
      'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
      'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
      'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
      'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
      'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
      'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
      'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
      'text,textPath,title,tspan,unknown,use,view';
  const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
  const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
  const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
  const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);

  const escapeRE = /["'&<>]/;
  function escapeHtml(string) {
      const str = '' + string;
      const match = escapeRE.exec(str);
      if (!match) {
          return str;
      }
      let html = '';
      let escaped;
      let index;
      let lastIndex = 0;
      for (index = match.index; index < str.length; index++) {
          switch (str.charCodeAt(index)) {
              case 34: // "
                  escaped = '&quot;';
                  break;
              case 38: // &
                  escaped = '&amp;';
                  break;
              case 39: // '
                  escaped = '&#39;';
                  break;
              case 60: // <
                  escaped = '&lt;';
                  break;
              case 62: // >
                  escaped = '&gt;';
                  break;
              default:
                  continue;
          }
          if (lastIndex !== index) {
              html += str.substring(lastIndex, index);
          }
          lastIndex = index + 1;
          html += escaped;
      }
      return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
  }

  /**
   * For converting {{ interpolation }} values to displayed strings.
   * @private
   */
  const toDisplayString = (val) => {
      return val == null
          ? ''
          : isObject(val)
              ? JSON.stringify(val, replacer, 2)
              : String(val);
  };
  const replacer = (_key, val) => {
      if (isMap(val)) {
          return {
              [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
                  entries[`${key} =>`] = val;
                  return entries;
              }, {})
          };
      }
      else if (isSet(val)) {
          return {
              [`Set(${val.size})`]: [...val.values()]
          };
      }
      else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
          return String(val);
      }
      return val;
  };

  /**
   * List of @babel/parser plugins that are used for template expression
   * transforms and SFC script transforms. By default we enable proposals slated
   * for ES2020. This will need to be updated as the spec moves forward.
   * Full list at https://babeljs.io/docs/en/next/babel-parser#plugins
   */
  const babelParserDefaultPlugins = [
      'bigInt',
      'optionalChaining',
      'nullishCoalescingOperator'
  ];
  const EMPTY_OBJ =  Object.freeze({})
      ;
  const NOOP = () => { };
  /**
   * Always return false.
   */
  const NO = () => false;
  const onRE = /^on[^a-z]/;
  const isOn = (key) => onRE.test(key);
  const extend = Object.assign;
  const hasOwnProperty = Object.prototype.hasOwnProperty;
  const hasOwn = (val, key) => hasOwnProperty.call(val, key);
  const isArray = Array.isArray;
  const isMap = (val) => toTypeString(val) === '[object Map]';
  const isSet = (val) => toTypeString(val) === '[object Set]';
  const isFunction = (val) => typeof val === 'function';
  const isString = (val) => typeof val === 'string';
  const isSymbol = (val) => typeof val === 'symbol';
  const isObject = (val) => val !== null && typeof val === 'object';
  const objectToString = Object.prototype.toString;
  const toTypeString = (value) => objectToString.call(value);
  const isPlainObject = (val) => toTypeString(val) === '[object Object]';
  const isReservedProp = /*#__PURE__*/ makeMap('key,ref,' +
      'onVnodeBeforeMount,onVnodeMounted,' +
      'onVnodeBeforeUpdate,onVnodeUpdated,' +
      'onVnodeBeforeUnmount,onVnodeUnmounted');
  const cacheStringFunction = (fn) => {
      const cache = Object.create(null);
      return ((str) => {
          const hit = cache[str];
          return hit || (cache[str] = fn(str));
      });
  };
  const camelizeRE = /-(\w)/g;
  /**
   * @private
   */
  const camelize = cacheStringFunction((str) => {
      return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
  });
  const hyphenateRE = /\B([A-Z])/g;
  /**
   * @private
   */
  const hyphenate = cacheStringFunction((str) => {
      return str.replace(hyphenateRE, '-$1').toLowerCase();
  });
  /**
   * @private
   */
  const capitalize = cacheStringFunction((str) => {
      return str.charAt(0).toUpperCase() + str.slice(1);
  });

  function defaultOnError(error) {
      throw error;
  }
  function createCompilerError(code, loc, messages, additionalMessage) {
      const msg =  (messages || errorMessages)[code] + (additionalMessage || ``)
          ;
      const error = new SyntaxError(String(msg));
      error.code = code;
      error.loc = loc;
      return error;
  }
  const errorMessages = {
      // parse errors
      [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
      [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
      [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
      [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
      [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
      [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
      [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
      [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
      [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
      [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
      [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
      [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
      [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
      [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
      [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
      [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
      [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
      [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
      [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
      [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
      [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
      [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
      // Vue-specific parse errors
      [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
      [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
      [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
      [26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
          'Note that dynamic directive argument cannot contain spaces.',
      // transform errors
      [27 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
      [28 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
      [29 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if.`,
      [30 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
      [31 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
      [32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
      [33 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
      [34 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
      [35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
      [36 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
          `When there are multiple named slots, all slots should use <template> ` +
          `syntax to avoid scope ambiguity.`,
      [37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
      [38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
          `default slot. These children will be ignored.`,
      [39 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
      [40 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
      [41 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
      [42 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
      [43 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
      [44 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
      // generic errors
      [45 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
      [46 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
      [47 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
      [48 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`
  };

  const FRAGMENT = Symbol( `Fragment` );
  const TELEPORT = Symbol( `Teleport` );
  const SUSPENSE = Symbol( `Suspense` );
  const KEEP_ALIVE = Symbol( `KeepAlive` );
  const BASE_TRANSITION = Symbol( `BaseTransition` );
  const OPEN_BLOCK = Symbol( `openBlock` );
  const CREATE_BLOCK = Symbol( `createBlock` );
  const CREATE_VNODE = Symbol( `createVNode` );
  const CREATE_COMMENT = Symbol( `createCommentVNode` );
  const CREATE_TEXT = Symbol( `createTextVNode` );
  const CREATE_STATIC = Symbol( `createStaticVNode` );
  const RESOLVE_COMPONENT = Symbol( `resolveComponent` );
  const RESOLVE_DYNAMIC_COMPONENT = Symbol( `resolveDynamicComponent` );
  const RESOLVE_DIRECTIVE = Symbol( `resolveDirective` );
  const WITH_DIRECTIVES = Symbol( `withDirectives` );
  const RENDER_LIST = Symbol( `renderList` );
  const RENDER_SLOT = Symbol( `renderSlot` );
  const CREATE_SLOTS = Symbol( `createSlots` );
  const TO_DISPLAY_STRING = Symbol( `toDisplayString` );
  const MERGE_PROPS = Symbol( `mergeProps` );
  const TO_HANDLERS = Symbol( `toHandlers` );
  const CAMELIZE = Symbol( `camelize` );
  const CAPITALIZE = Symbol( `capitalize` );
  const SET_BLOCK_TRACKING = Symbol( `setBlockTracking` );
  const PUSH_SCOPE_ID = Symbol( `pushScopeId` );
  const POP_SCOPE_ID = Symbol( `popScopeId` );
  const WITH_SCOPE_ID = Symbol( `withScopeId` );
  const WITH_CTX = Symbol( `withCtx` );
  // Name mapping for runtime helpers that need to be imported from 'vue' in
  // generated code. Make sure these are correctly exported in the runtime!
  // Using `any` here because TS doesn't allow symbols as index type.
  const helperNameMap = {
      [FRAGMENT]: `Fragment`,
      [TELEPORT]: `Teleport`,
      [SUSPENSE]: `Suspense`,
      [KEEP_ALIVE]: `KeepAlive`,
      [BASE_TRANSITION]: `BaseTransition`,
      [OPEN_BLOCK]: `openBlock`,
      [CREATE_BLOCK]: `createBlock`,
      [CREATE_VNODE]: `createVNode`,
      [CREATE_COMMENT]: `createCommentVNode`,
      [CREATE_TEXT]: `createTextVNode`,
      [CREATE_STATIC]: `createStaticVNode`,
      [RESOLVE_COMPONENT]: `resolveComponent`,
      [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
      [RESOLVE_DIRECTIVE]: `resolveDirective`,
      [WITH_DIRECTIVES]: `withDirectives`,
      [RENDER_LIST]: `renderList`,
      [RENDER_SLOT]: `renderSlot`,
      [CREATE_SLOTS]: `createSlots`,
      [TO_DISPLAY_STRING]: `toDisplayString`,
      [MERGE_PROPS]: `mergeProps`,
      [TO_HANDLERS]: `toHandlers`,
      [CAMELIZE]: `camelize`,
      [CAPITALIZE]: `capitalize`,
      [SET_BLOCK_TRACKING]: `setBlockTracking`,
      [PUSH_SCOPE_ID]: `pushScopeId`,
      [POP_SCOPE_ID]: `popScopeId`,
      [WITH_SCOPE_ID]: `withScopeId`,
      [WITH_CTX]: `withCtx`
  };
  function registerRuntimeHelpers(helpers) {
      Object.getOwnPropertySymbols(helpers).forEach(s => {
          helperNameMap[s] = helpers[s];
      });
  }

  // AST Utilities ---------------------------------------------------------------
  // Some expressions, e.g. sequence and conditional expressions, are never
  // associated with template nodes, so their source locations are just a stub.
  // Container types like CompoundExpression also don't need a real location.
  const locStub = {
      source: '',
      start: { line: 1, column: 1, offset: 0 },
      end: { line: 1, column: 1, offset: 0 }
  };
  function createRoot(children, loc = locStub) {
      return {
          type: 0 /* ROOT */,
          children,
          helpers: [],
          components: [],
          directives: [],
          hoists: [],
          imports: [],
          cached: 0,
          temps: 0,
          codegenNode: undefined,
          loc
      };
  }
  function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) {
      if (context) {
          if (isBlock) {
              context.helper(OPEN_BLOCK);
              context.helper(CREATE_BLOCK);
          }
          else {
              context.helper(CREATE_VNODE);
          }
          if (directives) {
              context.helper(WITH_DIRECTIVES);
          }
      }
      return {
          type: 13 /* VNODE_CALL */,
          tag,
          props,
          children,
          patchFlag,
          dynamicProps,
          directives,
          isBlock,
          disableTracking,
          loc
      };
  }
  function createArrayExpression(elements, loc = locStub) {
      return {
          type: 17 /* JS_ARRAY_EXPRESSION */,
          loc,
          elements
      };
  }
  function createObjectExpression(properties, loc = locStub) {
      return {
          type: 15 /* JS_OBJECT_EXPRESSION */,
          loc,
          properties
      };
  }
  function createObjectProperty(key, value) {
      return {
          type: 16 /* JS_PROPERTY */,
          loc: locStub,
          key: isString(key) ? createSimpleExpression(key, true) : key,
          value
      };
  }
  function createSimpleExpression(content, isStatic, loc = locStub, isConstant = false) {
      return {
          type: 4 /* SIMPLE_EXPRESSION */,
          loc,
          isConstant,
          content,
          isStatic
      };
  }
  function createInterpolation(content, loc) {
      return {
          type: 5 /* INTERPOLATION */,
          loc,
          content: isString(content)
              ? createSimpleExpression(content, false, loc)
              : content
      };
  }
  function createCompoundExpression(children, loc = locStub) {
      return {
          type: 8 /* COMPOUND_EXPRESSION */,
          loc,
          children
      };
  }
  function createCallExpression(callee, args = [], loc = locStub) {
      return {
          type: 14 /* JS_CALL_EXPRESSION */,
          loc,
          callee,
          arguments: args
      };
  }
  function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
      return {
          type: 18 /* JS_FUNCTION_EXPRESSION */,
          params,
          returns,
          newline,
          isSlot,
          loc
      };
  }
  function createConditionalExpression(test, consequent, alternate, newline = true) {
      return {
          type: 19 /* JS_CONDITIONAL_EXPRESSION */,
          test,
          consequent,
          alternate,
          newline,
          loc: locStub
      };
  }
  function createCacheExpression(index, value, isVNode = false) {
      return {
          type: 20 /* JS_CACHE_EXPRESSION */,
          index,
          value,
          isVNode,
          loc: locStub
      };
  }
  function createBlockStatement(body) {
      return {
          type: 21 /* JS_BLOCK_STATEMENT */,
          body,
          loc: locStub
      };
  }
  function createTemplateLiteral(elements) {
      return {
          type: 22 /* JS_TEMPLATE_LITERAL */,
          elements,
          loc: locStub
      };
  }
  function createIfStatement(test, consequent, alternate) {
      return {
          type: 23 /* JS_IF_STATEMENT */,
          test,
          consequent,
          alternate,
          loc: locStub
      };
  }
  function createAssignmentExpression(left, right) {
      return {
          type: 24 /* JS_ASSIGNMENT_EXPRESSION */,
          left,
          right,
          loc: locStub
      };
  }
  function createSequenceExpression(expressions) {
      return {
          type: 25 /* JS_SEQUENCE_EXPRESSION */,
          expressions,
          loc: locStub
      };
  }
  function createReturnStatement(returns) {
      return {
          type: 26 /* JS_RETURN_STATEMENT */,
          returns,
          loc: locStub
      };
  }

  const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
  const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
  function isCoreComponent(tag) {
      if (isBuiltInType(tag, 'Teleport')) {
          return TELEPORT;
      }
      else if (isBuiltInType(tag, 'Suspense')) {
          return SUSPENSE;
      }
      else if (isBuiltInType(tag, 'KeepAlive')) {
          return KEEP_ALIVE;
      }
      else if (isBuiltInType(tag, 'BaseTransition')) {
          return BASE_TRANSITION;
      }
  }
  const nonIdentifierRE = /^\d|[^\$\w]/;
  const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
  const memberExpRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\[[^\]]+\])*$/;
  const isMemberExpression = (path) => {
      if (!path)
          return false;
      return memberExpRE.test(path.trim());
  };
  function getInnerRange(loc, offset, length) {
      const source = loc.source.substr(offset, length);
      const newLoc = {
          source,
          start: advancePositionWithClone(loc.start, loc.source, offset),
          end: loc.end
      };
      if (length != null) {
          newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
      }
      return newLoc;
  }
  function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
      return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
  }
  // advance by mutation without cloning (for performance reasons), since this
  // gets called a lot in the parser
  function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
      let linesCount = 0;
      let lastNewLinePos = -1;
      for (let i = 0; i < numberOfCharacters; i++) {
          if (source.charCodeAt(i) === 10 /* newline char code */) {
              linesCount++;
              lastNewLinePos = i;
          }
      }
      pos.offset += numberOfCharacters;
      pos.line += linesCount;
      pos.column =
          lastNewLinePos === -1
              ? pos.column + numberOfCharacters
              : numberOfCharacters - lastNewLinePos;
      return pos;
  }
  function assert(condition, msg) {
      /* istanbul ignore if */
      if (!condition) {
          throw new Error(msg || `unexpected compiler condition`);
      }
  }
  function findDir(node, name, allowEmpty = false) {
      for (let i = 0; i < node.props.length; i++) {
          const p = node.props[i];
          if (p.type === 7 /* DIRECTIVE */ &&
              (allowEmpty || p.exp) &&
              (isString(name) ? p.name === name : name.test(p.name))) {
              return p;
          }
      }
  }
  function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
      for (let i = 0; i < node.props.length; i++) {
          const p = node.props[i];
          if (p.type === 6 /* ATTRIBUTE */) {
              if (dynamicOnly)
                  continue;
              if (p.name === name && (p.value || allowEmpty)) {
                  return p;
              }
          }
          else if (p.name === 'bind' &&
              (p.exp || allowEmpty) &&
              isBindKey(p.arg, name)) {
              return p;
          }
      }
  }
  function isBindKey(arg, name) {
      return !!(arg && isStaticExp(arg) && arg.content === name);
  }
  function hasDynamicKeyVBind(node) {
      return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
          p.name === 'bind' &&
          (!p.arg || // v-bind="obj"
              p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
              !p.arg.isStatic) // v-bind:[foo]
      );
  }
  function isText(node) {
      return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
  }
  function isVSlot(p) {
      return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
  }
  function isTemplateNode(node) {
      return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
  }
  function isSlotOutlet(node) {
      return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
  }
  function injectProp(node, prop, context) {
      let propsWithInjection;
      const props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
      if (props == null || isString(props)) {
          propsWithInjection = createObjectExpression([prop]);
      }
      else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
          // merged props... add ours
          // only inject key to object literal if it's the first argument so that
          // if doesn't override user provided keys
          const first = props.arguments[0];
          if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
              first.properties.unshift(prop);
          }
          else {
              props.arguments.unshift(createObjectExpression([prop]));
          }
          propsWithInjection = props;
      }
      else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
          let alreadyExists = false;
          // check existing key to avoid overriding user provided keys
          if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
              const propKeyName = prop.key.content;
              alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
                  p.key.content === propKeyName);
          }
          if (!alreadyExists) {
              props.properties.unshift(prop);
          }
          propsWithInjection = props;
      }
      else {
          // single v-bind with expression, return a merged replacement
          propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
              createObjectExpression([prop]),
              props
          ]);
      }
      if (node.type === 13 /* VNODE_CALL */) {
          node.props = propsWithInjection;
      }
      else {
          node.arguments[2] = propsWithInjection;
      }
  }
  function toValidAssetId(name, type) {
      return `_${type}_${name.replace(/[^\w]/g, '_')}`;
  }
  // Check if a node contains expressions that reference current context scope ids
  function hasScopeRef(node, ids) {
      if (!node || Object.keys(ids).length === 0) {
          return false;
      }
      switch (node.type) {
          case 1 /* ELEMENT */:
              for (let i = 0; i < node.props.length; i++) {
                  const p = node.props[i];
                  if (p.type === 7 /* DIRECTIVE */ &&
                      (hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) {
                      return true;
                  }
              }
              return node.children.some(c => hasScopeRef(c, ids));
          case 11 /* FOR */:
              if (hasScopeRef(node.source, ids)) {
                  return true;
              }
              return node.children.some(c => hasScopeRef(c, ids));
          case 9 /* IF */:
              return node.branches.some(b => hasScopeRef(b, ids));
          case 10 /* IF_BRANCH */:
              if (hasScopeRef(node.condition, ids)) {
                  return true;
              }
              return node.children.some(c => hasScopeRef(c, ids));
          case 4 /* SIMPLE_EXPRESSION */:
              return (!node.isStatic &&
                  isSimpleIdentifier(node.content) &&
                  !!ids[node.content]);
          case 8 /* COMPOUND_EXPRESSION */:
              return node.children.some(c => isObject(c) && hasScopeRef(c, ids));
          case 5 /* INTERPOLATION */:
          case 12 /* TEXT_CALL */:
              return hasScopeRef(node.content, ids);
          case 2 /* TEXT */:
          case 3 /* COMMENT */:
              return false;
          default:
              return false;
      }
  }

  // The default decoder only provides escapes for characters reserved as part of
  // the template syntax, and is only used if the custom renderer did not provide
  // a platform-specific decoder.
  const decodeRE = /&(gt|lt|amp|apos|quot);/g;
  const decodeMap = {
      gt: '>',
      lt: '<',
      amp: '&',
      apos: "'",
      quot: '"'
  };
  const defaultParserOptions = {
      delimiters: [`{{`, `}}`],
      getNamespace: () => 0 /* HTML */,
      getTextMode: () => 0 /* DATA */,
      isVoidTag: NO,
      isPreTag: NO,
      isCustomElement: NO,
      decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
      onError: defaultOnError,
      comments: false
  };
  function baseParse(content, options = {}) {
      const context = createParserContext(content, options);
      const start = getCursor(context);
      return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
  }
  function createParserContext(content, rawOptions) {
      const options = extend({}, defaultParserOptions);
      for (const key in rawOptions) {
          // @ts-ignore
          options[key] = rawOptions[key] || defaultParserOptions[key];
      }
      return {
          options,
          column: 1,
          line: 1,
          offset: 0,
          originalSource: content,
          source: content,
          inPre: false,
          inVPre: false
      };
  }
  function parseChildren(context, mode, ancestors) {
      const parent = last(ancestors);
      const ns = parent ? parent.ns : 0 /* HTML */;
      const nodes = [];
      while (!isEnd(context, mode, ancestors)) {
          const s = context.source;
          let node = undefined;
          if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
              if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
                  // '{{'
                  node = parseInterpolation(context, mode);
              }
              else if (mode === 0 /* DATA */ && s[0] === '<') {
                  // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
                  if (s.length === 1) {
                      emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
                  }
                  else if (s[1] === '!') {
                      // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
                      if (startsWith(s, '<!--')) {
                          node = parseComment(context);
                      }
                      else if (startsWith(s, '<!DOCTYPE')) {
                          // Ignore DOCTYPE by a limitation.
                          node = parseBogusComment(context);
                      }
                      else if (startsWith(s, '<![CDATA[')) {
                          if (ns !== 0 /* HTML */) {
                              node = parseCDATA(context, ancestors);
                          }
                          else {
                              emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
                              node = parseBogusComment(context);
                          }
                      }
                      else {
                          emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
                          node = parseBogusComment(context);
                      }
                  }
                  else if (s[1] === '/') {
                      // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
                      if (s.length === 2) {
                          emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
                      }
                      else if (s[2] === '>') {
                          emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
                          advanceBy(context, 3);
                          continue;
                      }
                      else if (/[a-z]/i.test(s[2])) {
                          emitError(context, 23 /* X_INVALID_END_TAG */);
                          parseTag(context, 1 /* End */, parent);
                          continue;
                      }
                      else {
                          emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
                          node = parseBogusComment(context);
                      }
                  }
                  else if (/[a-z]/i.test(s[1])) {
                      node = parseElement(context, ancestors);
                  }
                  else if (s[1] === '?') {
                      emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
                      node = parseBogusComment(context);
                  }
                  else {
                      emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
                  }
              }
          }
          if (!node) {
              node = parseText(context, mode);
          }
          if (isArray(node)) {
              for (let i = 0; i < node.length; i++) {
                  pushNode(nodes, node[i]);
              }
          }
          else {
              pushNode(nodes, node);
          }
      }
      // Whitespace management for more efficient output
      // (same as v2 whitespace: 'condense')
      let removedWhitespace = false;
      if (mode !== 2 /* RAWTEXT */) {
          if (!context.inPre) {
              for (let i = 0; i < nodes.length; i++) {
                  const node = nodes[i];
                  if (node.type === 2 /* TEXT */) {
                      if (!/[^\t\r\n\f ]/.test(node.content)) {
                          const prev = nodes[i - 1];
                          const next = nodes[i + 1];
                          // If:
                          // - the whitespace is the first or last node, or:
                          // - the whitespace is adjacent to a comment, or:
                          // - the whitespace is between two elements AND contains newline
                          // Then the whitespace is ignored.
                          if (!prev ||
                              !next ||
                              prev.type === 3 /* COMMENT */ ||
                              next.type === 3 /* COMMENT */ ||
                              (prev.type === 1 /* ELEMENT */ &&
                                  next.type === 1 /* ELEMENT */ &&
                                  /[\r\n]/.test(node.content))) {
                              removedWhitespace = true;
                              nodes[i] = null;
                          }
                          else {
                              // Otherwise, condensed consecutive whitespace inside the text
                              // down to a single space
                              node.content = ' ';
                          }
                      }
                      else {
                          node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
                      }
                  }
              }
          }
          else if (parent && context.options.isPreTag(parent.tag)) {
              // remove leading newline per html spec
              // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
              const first = nodes[0];
              if (first && first.type === 2 /* TEXT */) {
                  first.content = first.content.replace(/^\r?\n/, '');
              }
          }
      }
      return removedWhitespace ? nodes.filter(Boolean) : nodes;
  }
  function pushNode(nodes, node) {
      if (node.type === 2 /* TEXT */) {
          const prev = last(nodes);
          // Merge if both this and the previous node are text and those are
          // consecutive. This happens for cases like "a < b".
          if (prev &&
              prev.type === 2 /* TEXT */ &&
              prev.loc.end.offset === node.loc.start.offset) {
              prev.content += node.content;
              prev.loc.end = node.loc.end;
              prev.loc.source += node.loc.source;
              return;
          }
      }
      nodes.push(node);
  }
  function parseCDATA(context, ancestors) {
      advanceBy(context, 9);
      const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
      if (context.source.length === 0) {
          emitError(context, 6 /* EOF_IN_CDATA */);
      }
      else {
          advanceBy(context, 3);
      }
      return nodes;
  }
  function parseComment(context) {
      const start = getCursor(context);
      let content;
      // Regular comment.
      const match = /--(\!)?>/.exec(context.source);
      if (!match) {
          content = context.source.slice(4);
          advanceBy(context, context.source.length);
          emitError(context, 7 /* EOF_IN_COMMENT */);
      }
      else {
          if (match.index <= 3) {
              emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
          }
          if (match[1]) {
              emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
          }
          content = context.source.slice(4, match.index);
          // Advancing with reporting nested comments.
          const s = context.source.slice(0, match.index);
          let prevIndex = 1, nestedIndex = 0;
          while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
              advanceBy(context, nestedIndex - prevIndex + 1);
              if (nestedIndex + 4 < s.length) {
                  emitError(context, 16 /* NESTED_COMMENT */);
              }
              prevIndex = nestedIndex + 1;
          }
          advanceBy(context, match.index + match[0].length - prevIndex + 1);
      }
      return {
          type: 3 /* COMMENT */,
          content,
          loc: getSelection(context, start)
      };
  }
  function parseBogusComment(context) {
      const start = getCursor(context);
      const contentStart = context.source[1] === '?' ? 1 : 2;
      let content;
      const closeIndex = context.source.indexOf('>');
      if (closeIndex === -1) {
          content = context.source.slice(contentStart);
          advanceBy(context, context.source.length);
      }
      else {
          content = context.source.slice(contentStart, closeIndex);
          advanceBy(context, closeIndex + 1);
      }
      return {
          type: 3 /* COMMENT */,
          content,
          loc: getSelection(context, start)
      };
  }
  function parseElement(context, ancestors) {
      // Start tag.
      const wasInPre = context.inPre;
      const wasInVPre = context.inVPre;
      const parent = last(ancestors);
      const element = parseTag(context, 0 /* Start */, parent);
      const isPreBoundary = context.inPre && !wasInPre;
      const isVPreBoundary = context.inVPre && !wasInVPre;
      if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
          return element;
      }
      // Children.
      ancestors.push(element);
      const mode = context.options.getTextMode(element, parent);
      const children = parseChildren(context, mode, ancestors);
      ancestors.pop();
      element.children = children;
      // End tag.
      if (startsWithEndTagOpen(context.source, element.tag)) {
          parseTag(context, 1 /* End */, parent);
      }
      else {
          emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
          if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
              const first = children[0];
              if (first && startsWith(first.loc.source, '<!--')) {
                  emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
              }
          }
      }
      element.loc = getSelection(context, element.loc.start);
      if (isPreBoundary) {
          context.inPre = false;
      }
      if (isVPreBoundary) {
          context.inVPre = false;
      }
      return element;
  }
  const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
  /**
   * Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
   */
  function parseTag(context, type, parent) {
      // Tag open.
      const start = getCursor(context);
      const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
      const tag = match[1];
      const ns = context.options.getNamespace(tag, parent);
      advanceBy(context, match[0].length);
      advanceSpaces(context);
      // save current state in case we need to re-parse attributes with v-pre
      const cursor = getCursor(context);
      const currentSource = context.source;
      // Attributes.
      let props = parseAttributes(context, type);
      // check <pre> tag
      if (context.options.isPreTag(tag)) {
          context.inPre = true;
      }
      // check v-pre
      if (!context.inVPre &&
          props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
          context.inVPre = true;
          // reset context
          extend(context, cursor);
          context.source = currentSource;
          // re-parse attrs and filter out v-pre itself
          props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
      }
      // Tag close.
      let isSelfClosing = false;
      if (context.source.length === 0) {
          emitError(context, 9 /* EOF_IN_TAG */);
      }
      else {
          isSelfClosing = startsWith(context.source, '/>');
          if (type === 1 /* End */ && isSelfClosing) {
              emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
          }
          advanceBy(context, isSelfClosing ? 2 : 1);
      }
      let tagType = 0 /* ELEMENT */;
      const options = context.options;
      if (!context.inVPre && !options.isCustomElement(tag)) {
          const hasVIs = props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'is');
          if (options.isNativeTag && !hasVIs) {
              if (!options.isNativeTag(tag))
                  tagType = 1 /* COMPONENT */;
          }
          else if (hasVIs ||
              isCoreComponent(tag) ||
              (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
              /^[A-Z]/.test(tag) ||
              tag === 'component') {
              tagType = 1 /* COMPONENT */;
          }
          if (tag === 'slot') {
              tagType = 2 /* SLOT */;
          }
          else if (tag === 'template' &&
              props.some(p => {
                  return (p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name));
              })) {
              tagType = 3 /* TEMPLATE */;
          }
      }
      return {
          type: 1 /* ELEMENT */,
          ns,
          tag,
          tagType,
          props,
          isSelfClosing,
          children: [],
          loc: getSelection(context, start),
          codegenNode: undefined // to be created during transform phase
      };
  }
  function parseAttributes(context, type) {
      const props = [];
      const attributeNames = new Set();
      while (context.source.length > 0 &&
          !startsWith(context.source, '>') &&
          !startsWith(context.source, '/>')) {
          if (startsWith(context.source, '/')) {
              emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
              advanceBy(context, 1);
              advanceSpaces(context);
              continue;
          }
          if (type === 1 /* End */) {
              emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
          }
          const attr = parseAttribute(context, attributeNames);
          if (type === 0 /* Start */) {
              props.push(attr);
          }
          if (/^[^\t\r\n\f />]/.test(context.source)) {
              emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
          }
          advanceSpaces(context);
      }
      return props;
  }
  function parseAttribute(context, nameSet) {
      // Name.
      const start = getCursor(context);
      const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
      const name = match[0];
      if (nameSet.has(name)) {
          emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
      }
      nameSet.add(name);
      if (name[0] === '=') {
          emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
      }
      {
          const pattern = /["'<]/g;
          let m;
          while ((m = pattern.exec(name))) {
              emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
          }
      }
      advanceBy(context, name.length);
      // Value
      let value = undefined;
      if (/^[\t\r\n\f ]*=/.test(context.source)) {
          advanceSpaces(context);
          advanceBy(context, 1);
          advanceSpaces(context);
          value = parseAttributeValue(context);
          if (!value) {
              emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
          }
      }
      const loc = getSelection(context, start);
      if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {
          const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
          const dirName = match[1] ||
              (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');
          let arg;
          if (match[2]) {
              const isSlot = dirName === 'slot';
              const startOffset = name.indexOf(match[2]);
              const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
              let content = match[2];
              let isStatic = true;
              if (content.startsWith('[')) {
                  isStatic = false;
                  if (!content.endsWith(']')) {
                      emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
                  }
                  content = content.substr(1, content.length - 2);
              }
              else if (isSlot) {
                  // #1241 special case for v-slot: vuetify relies extensively on slot
                  // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
                  // supports such usage so we are keeping it consistent with 2.x.
                  content += match[3] || '';
              }
              arg = {
                  type: 4 /* SIMPLE_EXPRESSION */,
                  content,
                  isStatic,
                  isConstant: isStatic,
                  loc
              };
          }
          if (value && value.isQuoted) {
              const valueLoc = value.loc;
              valueLoc.start.offset++;
              valueLoc.start.column++;
              valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
              valueLoc.source = valueLoc.source.slice(1, -1);
          }
          return {
              type: 7 /* DIRECTIVE */,
              name: dirName,
              exp: value && {
                  type: 4 /* SIMPLE_EXPRESSION */,
                  content: value.content,
                  isStatic: false,
                  // Treat as non-constant by default. This can be potentially set to
                  // true by `transformExpression` to make it eligible for hoisting.
                  isConstant: false,
                  loc: value.loc
              },
              arg,
              modifiers: match[3] ? match[3].substr(1).split('.') : [],
              loc
          };
      }
      return {
          type: 6 /* ATTRIBUTE */,
          name,
          value: value && {
              type: 2 /* TEXT */,
              content: value.content,
              loc: value.loc
          },
          loc
      };
  }
  function parseAttributeValue(context) {
      const start = getCursor(context);
      let content;
      const quote = context.source[0];
      const isQuoted = quote === `"` || quote === `'`;
      if (isQuoted) {
          // Quoted value.
          advanceBy(context, 1);
          const endIndex = context.source.indexOf(quote);
          if (endIndex === -1) {
              content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
          }
          else {
              content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
              advanceBy(context, 1);
          }
      }
      else {
          // Unquoted
          const match = /^[^\t\r\n\f >]+/.exec(context.source);
          if (!match) {
              return undefined;
          }
          const unexpectedChars = /["'<=`]/g;
          let m;
          while ((m = unexpectedChars.exec(match[0]))) {
              emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
          }
          content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
      }
      return { content, isQuoted, loc: getSelection(context, start) };
  }
  function parseInterpolation(context, mode) {
      const [open, close] = context.options.delimiters;
      const closeIndex = context.source.indexOf(close, open.length);
      if (closeIndex === -1) {
          emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
          return undefined;
      }
      const start = getCursor(context);
      advanceBy(context, open.length);
      const innerStart = getCursor(context);
      const innerEnd = getCursor(context);
      const rawContentLength = closeIndex - open.length;
      const rawContent = context.source.slice(0, rawContentLength);
      const preTrimContent = parseTextData(context, rawContentLength, mode);
      const content = preTrimContent.trim();
      const startOffset = preTrimContent.indexOf(content);
      if (startOffset > 0) {
          advancePositionWithMutation(innerStart, rawContent, startOffset);
      }
      const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
      advancePositionWithMutation(innerEnd, rawContent, endOffset);
      advanceBy(context, close.length);
      return {
          type: 5 /* INTERPOLATION */,
          content: {
              type: 4 /* SIMPLE_EXPRESSION */,
              isStatic: false,
              // Set `isConstant` to false by default and will decide in transformExpression
              isConstant: false,
              content,
              loc: getSelection(context, innerStart, innerEnd)
          },
          loc: getSelection(context, start)
      };
  }
  function parseText(context, mode) {
      const endTokens = ['<', context.options.delimiters[0]];
      if (mode === 3 /* CDATA */) {
          endTokens.push(']]>');
      }
      let endIndex = context.source.length;
      for (let i = 0; i < endTokens.length; i++) {
          const index = context.source.indexOf(endTokens[i], 1);
          if (index !== -1 && endIndex > index) {
              endIndex = index;
          }
      }
      const start = getCursor(context);
      const content = parseTextData(context, endIndex, mode);
      return {
          type: 2 /* TEXT */,
          content,
          loc: getSelection(context, start)
      };
  }
  /**
   * Get text data with a given length from the current location.
   * This translates HTML entities in the text data.
   */
  function parseTextData(context, length, mode) {
      const rawText = context.source.slice(0, length);
      advanceBy(context, length);
      if (mode === 2 /* RAWTEXT */ ||
          mode === 3 /* CDATA */ ||
          rawText.indexOf('&') === -1) {
          return rawText;
      }
      else {
          // DATA or RCDATA containing "&"". Entity decoding required.
          return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
      }
  }
  function getCursor(context) {
      const { column, line, offset } = context;
      return { column, line, offset };
  }
  function getSelection(context, start, end) {
      end = end || getCursor(context);
      return {
          start,
          end,
          source: context.originalSource.slice(start.offset, end.offset)
      };
  }
  function last(xs) {
      return xs[xs.length - 1];
  }
  function startsWith(source, searchString) {
      return source.startsWith(searchString);
  }
  function advanceBy(context, numberOfCharacters) {
      const { source } = context;
      advancePositionWithMutation(context, source, numberOfCharacters);
      context.source = source.slice(numberOfCharacters);
  }
  function advanceSpaces(context) {
      const match = /^[\t\r\n\f ]+/.exec(context.source);
      if (match) {
          advanceBy(context, match[0].length);
      }
  }
  function getNewPosition(context, start, numberOfCharacters) {
      return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
  }
  function emitError(context, code, offset, loc = getCursor(context)) {
      if (offset) {
          loc.offset += offset;
          loc.column += offset;
      }
      context.options.onError(createCompilerError(code, {
          start: loc,
          end: loc,
          source: ''
      }));
  }
  function isEnd(context, mode, ancestors) {
      const s = context.source;
      switch (mode) {
          case 0 /* DATA */:
              if (startsWith(s, '</')) {
                  //TODO: probably bad performance
                  for (let i = ancestors.length - 1; i >= 0; --i) {
                      if (startsWithEndTagOpen(s, ancestors[i].tag)) {
                          return true;
                      }
                  }
              }
              break;
          case 1 /* RCDATA */:
          case 2 /* RAWTEXT */: {
              const parent = last(ancestors);
              if (parent && startsWithEndTagOpen(s, parent.tag)) {
                  return true;
              }
              break;
          }
          case 3 /* CDATA */:
              if (startsWith(s, ']]>')) {
                  return true;
              }
              break;
      }
      return !s;
  }
  function startsWithEndTagOpen(source, tag) {
      return (startsWith(source, '</') &&
          source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
          /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
  }

  function hoistStatic(root, context) {
      walk(root, context, new Map(), 
      // Root node is unfortunately non-hoistable due to potential parent
      // fallthrough attributes.
      isSingleElementRoot(root, root.children[0]));
  }
  function isSingleElementRoot(root, child) {
      const { children } = root;
      return (children.length === 1 &&
          child.type === 1 /* ELEMENT */ &&
          !isSlotOutlet(child));
  }
  function walk(node, context, resultCache, doNotHoistNode = false) {
      let hasHoistedNode = false;
      // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
      // static bindings with expressions. These expressions are guaranteed to be
      // constant so they are still eligible for hoisting, but they are only
      // available at runtime and therefore cannot be evaluated ahead of time.
      // This is only a concern for pre-stringification (via transformHoist by
      // @vue/compiler-dom), but doing it here allows us to perform only one full
      // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
      // stringficiation threshold is met.
      let hasRuntimeConstant = false;
      const { children } = node;
      for (let i = 0; i < children.length; i++) {
          const child = children[i];
          // only plain elements & text calls are eligible for hoisting.
          if (child.type === 1 /* ELEMENT */ &&
              child.tagType === 0 /* ELEMENT */) {
              let staticType;
              if (!doNotHoistNode &&
                  (staticType = getStaticType(child, resultCache)) > 0) {
                  if (staticType === 2 /* HAS_RUNTIME_CONSTANT */) {
                      hasRuntimeConstant = true;
                  }
                  child.codegenNode.patchFlag =
                      -1 /* HOISTED */ + ( ` /* HOISTED */` );
                  child.codegenNode = context.hoist(child.codegenNode);
                  hasHoistedNode = true;
                  continue;
              }
              else {
                  // node may contain dynamic children, but its props may be eligible for
                  // hoisting.
                  const codegenNode = child.codegenNode;
                  if (codegenNode.type === 13 /* VNODE_CALL */) {
                      const flag = getPatchFlag(codegenNode);
                      if ((!flag ||
                          flag === 512 /* NEED_PATCH */ ||
                          flag === 1 /* TEXT */) &&
                          !hasNonHoistableProps(child)) {
                          const props = getNodeProps(child);
                          if (props) {
                              codegenNode.props = context.hoist(props);
                          }
                      }
                  }
              }
          }
          else if (child.type === 12 /* TEXT_CALL */) {
              const staticType = getStaticType(child.content, resultCache);
              if (staticType > 0) {
                  if (staticType === 2 /* HAS_RUNTIME_CONSTANT */) {
                      hasRuntimeConstant = true;
                  }
                  child.codegenNode = context.hoist(child.codegenNode);
                  hasHoistedNode = true;
              }
          }
          // walk further
          if (child.type === 1 /* ELEMENT */) {
              walk(child, context, resultCache);
          }
          else if (child.type === 11 /* FOR */) {
              // Do not hoist v-for single child because it has to be a block
              walk(child, context, resultCache, child.children.length === 1);
          }
          else if (child.type === 9 /* IF */) {
              for (let i = 0; i < child.branches.length; i++) {
                  // Do not hoist v-if single child because it has to be a block
                  walk(child.branches[i], context, resultCache, child.branches[i].children.length === 1);
              }
          }
      }
      if (!hasRuntimeConstant && hasHoistedNode && context.transformHoist) {
          context.transformHoist(children, context, node);
      }
  }
  function getStaticType(node, resultCache = new Map()) {
      switch (node.type) {
          case 1 /* ELEMENT */:
              if (node.tagType !== 0 /* ELEMENT */) {
                  return 0 /* NOT_STATIC */;
              }
              const cached = resultCache.get(node);
              if (cached !== undefined) {
                  return cached;
              }
              const codegenNode = node.codegenNode;
              if (codegenNode.type !== 13 /* VNODE_CALL */) {
                  return 0 /* NOT_STATIC */;
              }
              const flag = getPatchFlag(codegenNode);
              if (!flag && !hasNonHoistableProps(node)) {
                  // element self is static. check its children.
                  let returnType = 1 /* FULL_STATIC */;
                  for (let i = 0; i < node.children.length; i++) {
                      const childType = getStaticType(node.children[i], resultCache);
                      if (childType === 0 /* NOT_STATIC */) {
                          resultCache.set(node, 0 /* NOT_STATIC */);
                          return 0 /* NOT_STATIC */;
                      }
                      else if (childType === 2 /* HAS_RUNTIME_CONSTANT */) {
                          returnType = 2 /* HAS_RUNTIME_CONSTANT */;
                      }
                  }
                  // check if any of the props contain runtime constants
                  if (returnType !== 2 /* HAS_RUNTIME_CONSTANT */) {
                      for (let i = 0; i < node.props.length; i++) {
                          const p = node.props[i];
                          if (p.type === 7 /* DIRECTIVE */ &&
                              p.name === 'bind' &&
                              p.exp &&
                              (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||
                                  p.exp.isRuntimeConstant)) {
                              returnType = 2 /* HAS_RUNTIME_CONSTANT */;
                          }
                      }
                  }
                  // only svg/foreignObject could be block here, however if they are
                  // stati then they don't need to be blocks since there will be no
                  // nested updates.
                  if (codegenNode.isBlock) {
                      codegenNode.isBlock = false;
                  }
                  resultCache.set(node, returnType);
                  return returnType;
              }
              else {
                  resultCache.set(node, 0 /* NOT_STATIC */);
                  return 0 /* NOT_STATIC */;
              }
          case 2 /* TEXT */:
          case 3 /* COMMENT */:
              return 1 /* FULL_STATIC */;
          case 9 /* IF */:
          case 11 /* FOR */:
          case 10 /* IF_BRANCH */:
              return 0 /* NOT_STATIC */;
          case 5 /* INTERPOLATION */:
          case 12 /* TEXT_CALL */:
              return getStaticType(node.content, resultCache);
          case 4 /* SIMPLE_EXPRESSION */:
              return node.isConstant
                  ? node.isRuntimeConstant
                      ? 2 /* HAS_RUNTIME_CONSTANT */
                      : 1 /* FULL_STATIC */
                  : 0 /* NOT_STATIC */;
          case 8 /* COMPOUND_EXPRESSION */:
              let returnType = 1 /* FULL_STATIC */;
              for (let i = 0; i < node.children.length; i++) {
                  const child = node.children[i];
                  if (isString(child) || isSymbol(child)) {
                      continue;
                  }
                  const childType = getStaticType(child, resultCache);
                  if (childType === 0 /* NOT_STATIC */) {
                      return 0 /* NOT_STATIC */;
                  }
                  else if (childType === 2 /* HAS_RUNTIME_CONSTANT */) {
                      returnType = 2 /* HAS_RUNTIME_CONSTANT */;
                  }
              }
              return returnType;
          default:
              return 0 /* NOT_STATIC */;
      }
  }
  /**
   * Even for a node with no patch flag, it is possible for it to contain
   * non-hoistable expressions that refers to scope variables, e.g. compiler
   * injected keys or cached event handlers. Therefore we need to always check the
   * codegenNode's props to be sure.
   */
  function hasNonHoistableProps(node) {
      const props = getNodeProps(node);
      if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
          const { properties } = props;
          for (let i = 0; i < properties.length; i++) {
              const { key, value } = properties[i];
              if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||
                  !key.isStatic ||
                  (value.type !== 4 /* SIMPLE_EXPRESSION */ ||
                      (!value.isStatic && !value.isConstant))) {
                  return true;
              }
          }
      }
      return false;
  }
  function getNodeProps(node) {
      const codegenNode = node.codegenNode;
      if (codegenNode.type === 13 /* VNODE_CALL */) {
          return codegenNode.props;
      }
  }
  function getPatchFlag(node) {
      const flag = node.patchFlag;
      return flag ? parseInt(flag, 10) : undefined;
  }

  function createTransformContext(root, { prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, ssr = false, ssrCssVars = ``, bindingMetadata = {}, onError = defaultOnError }) {
      const context = {
          // options
          prefixIdentifiers,
          hoistStatic,
          cacheHandlers,
          nodeTransforms,
          directiveTransforms,
          transformHoist,
          isBuiltInComponent,
          isCustomElement,
          expressionPlugins,
          scopeId,
          ssr,
          ssrCssVars,
          bindingMetadata,
          onError,
          // state
          root,
          helpers: new Set(),
          components: new Set(),
          directives: new Set(),
          hoists: [],
          imports: new Set(),
          temps: 0,
          cached: 0,
          identifiers: Object.create(null),
          scopes: {
              vFor: 0,
              vSlot: 0,
              vPre: 0,
              vOnce: 0
          },
          parent: null,
          currentNode: root,
          childIndex: 0,
          // methods
          helper(name) {
              context.helpers.add(name);
              return name;
          },
          helperString(name) {
              return `_${helperNameMap[context.helper(name)]}`;
          },
          replaceNode(node) {
              /* istanbul ignore if */
              {
                  if (!context.currentNode) {
                      throw new Error(`Node being replaced is already removed.`);
                  }
                  if (!context.parent) {
                      throw new Error(`Cannot replace root node.`);
                  }
              }
              context.parent.children[context.childIndex] = context.currentNode = node;
          },
          removeNode(node) {
              if ( !context.parent) {
                  throw new Error(`Cannot remove root node.`);
              }
              const list = context.parent.children;
              const removalIndex = node
                  ? list.indexOf(node)
                  : context.currentNode
                      ? context.childIndex
                      : -1;
              /* istanbul ignore if */
              if ( removalIndex < 0) {
                  throw new Error(`node being removed is not a child of current parent`);
              }
              if (!node || node === context.currentNode) {
                  // current node removed
                  context.currentNode = null;
                  context.onNodeRemoved();
              }
              else {
                  // sibling node removed
                  if (context.childIndex > removalIndex) {
                      context.childIndex--;
                      context.onNodeRemoved();
                  }
              }
              context.parent.children.splice(removalIndex, 1);
          },
          onNodeRemoved: () => { },
          addIdentifiers(exp) {
              // identifier tracking only happens in non-browser builds.
              {
                  if (isString(exp)) {
                      addId(exp);
                  }
                  else if (exp.identifiers) {
                      exp.identifiers.forEach(addId);
                  }
                  else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
                      addId(exp.content);
                  }
              }
          },
          removeIdentifiers(exp) {
              {
                  if (isString(exp)) {
                      removeId(exp);
                  }
                  else if (exp.identifiers) {
                      exp.identifiers.forEach(removeId);
                  }
                  else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
                      removeId(exp.content);
                  }
              }
          },
          hoist(exp) {
              context.hoists.push(exp);
              const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, true);
              identifier.hoisted = exp;
              return identifier;
          },
          cache(exp, isVNode = false) {
              return createCacheExpression(++context.cached, exp, isVNode);
          }
      };
      function addId(id) {
          const { identifiers } = context;
          if (identifiers[id] === undefined) {
              identifiers[id] = 0;
          }
          identifiers[id]++;
      }
      function removeId(id) {
          context.identifiers[id]--;
      }
      return context;
  }
  function transform(root, options) {
      const context = createTransformContext(root, options);
      traverseNode(root, context);
      if (options.hoistStatic) {
          hoistStatic(root, context);
      }
      if (!options.ssr) {
          createRootCodegen(root, context);
      }
      // finalize meta information
      root.helpers = [...context.helpers];
      root.components = [...context.components];
      root.directives = [...context.directives];
      root.imports = [...context.imports];
      root.hoists = context.hoists;
      root.temps = context.temps;
      root.cached = context.cached;
  }
  function createRootCodegen(root, context) {
      const { helper } = context;
      const { children } = root;
      if (children.length === 1) {
          const child = children[0];
          // if the single child is an element, turn it into a block.
          if (isSingleElementRoot(root, child) && child.codegenNode) {
              // single element root is never hoisted so codegenNode will never be
              // SimpleExpressionNode
              const codegenNode = child.codegenNode;
              if (codegenNode.type === 13 /* VNODE_CALL */) {
                  codegenNode.isBlock = true;
                  helper(OPEN_BLOCK);
                  helper(CREATE_BLOCK);
              }
              root.codegenNode = codegenNode;
          }
          else {
              // - single <slot/>, IfNode, ForNode: already blocks.
              // - single text node: always patched.
              // root codegen falls through via genNode()
              root.codegenNode = child;
          }
      }
      else if (children.length > 1) {
          // root has multiple nodes - return a fragment block.
          root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, `${64 /* STABLE_FRAGMENT */} /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`, undefined, undefined, true);
      }
      else ;
  }
  function traverseChildren(parent, context) {
      let i = 0;
      const nodeRemoved = () => {
          i--;
      };
      for (; i < parent.children.length; i++) {
          const child = parent.children[i];
          if (isString(child))
              continue;
          context.parent = parent;
          context.childIndex = i;
          context.onNodeRemoved = nodeRemoved;
          traverseNode(child, context);
      }
  }
  function traverseNode(node, context) {
      context.currentNode = node;
      // apply transform plugins
      const { nodeTransforms } = context;
      const exitFns = [];
      for (let i = 0; i < nodeTransforms.length; i++) {
          const onExit = nodeTransforms[i](node, context);
          if (onExit) {
              if (isArray(onExit)) {
                  exitFns.push(...onExit);
              }
              else {
                  exitFns.push(onExit);
              }
          }
          if (!context.currentNode) {
              // node was removed
              return;
          }
          else {
              // node may have been replaced
              node = context.currentNode;
          }
      }
      switch (node.type) {
          case 3 /* COMMENT */:
              if (!context.ssr) {
                  // inject import for the Comment symbol, which is needed for creating
                  // comment nodes with `createVNode`
                  context.helper(CREATE_COMMENT);
              }
              break;
          case 5 /* INTERPOLATION */:
              // no need to traverse, but we need to inject toString helper
              if (!context.ssr) {
                  context.helper(TO_DISPLAY_STRING);
              }
              break;
          // for container types, further traverse downwards
          case 9 /* IF */:
              for (let i = 0; i < node.branches.length; i++) {
                  traverseNode(node.branches[i], context);
              }
              break;
          case 10 /* IF_BRANCH */:
          case 11 /* FOR */:
          case 1 /* ELEMENT */:
          case 0 /* ROOT */:
              traverseChildren(node, context);
              break;
      }
      // exit transforms
      context.currentNode = node;
      let i = exitFns.length;
      while (i--) {
          exitFns[i]();
      }
  }
  function createStructuralDirectiveTransform(name, fn) {
      const matches = isString(name)
          ? (n) => n === name
          : (n) => name.test(n);
      return (node, context) => {
          if (node.type === 1 /* ELEMENT */) {
              const { props } = node;
              // structural directive transforms are not concerned with slots
              // as they are handled separately in vSlot.ts
              if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
                  return;
              }
              const exitFns = [];
              for (let i = 0; i < props.length; i++) {
                  const prop = props[i];
                  if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
                      // structural directives are removed to avoid infinite recursion
                      // also we remove them *before* applying so that it can further
                      // traverse itself in case it moves the node around
                      props.splice(i, 1);
                      i--;
                      const onExit = fn(node, prop, context);
                      if (onExit)
                          exitFns.push(onExit);
                  }
              }
              return exitFns;
          }
      };
  }

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */

  var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');

  /**
   * Encode an integer in the range of 0 to 63 to a single base 64 digit.
   */
  var encode = function (number) {
    if (0 <= number && number < intToCharMap.length) {
      return intToCharMap[number];
    }
    throw new TypeError("Must be between 0 and 63: " + number);
  };

  /**
   * Decode a single base 64 character code digit to an integer. Returns -1 on
   * failure.
   */
  var decode = function (charCode) {
    var bigA = 65;     // 'A'
    var bigZ = 90;     // 'Z'

    var littleA = 97;  // 'a'
    var littleZ = 122; // 'z'

    var zero = 48;     // '0'
    var nine = 57;     // '9'

    var plus = 43;     // '+'
    var slash = 47;    // '/'

    var littleOffset = 26;
    var numberOffset = 52;

    // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
    if (bigA <= charCode && charCode <= bigZ) {
      return (charCode - bigA);
    }

    // 26 - 51: abcdefghijklmnopqrstuvwxyz
    if (littleA <= charCode && charCode <= littleZ) {
      return (charCode - littleA + littleOffset);
    }

    // 52 - 61: 0123456789
    if (zero <= charCode && charCode <= nine) {
      return (charCode - zero + numberOffset);
    }

    // 62: +
    if (charCode == plus) {
      return 62;
    }

    // 63: /
    if (charCode == slash) {
      return 63;
    }

    // Invalid base64 digit.
    return -1;
  };

  var base64 = {
  	encode: encode,
  	decode: decode
  };

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   *
   * Based on the Base 64 VLQ implementation in Closure Compiler:
   * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
   *
   * Copyright 2011 The Closure Compiler Authors. All rights reserved.
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are
   * met:
   *
   *  * Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *  * Redistributions in binary form must reproduce the above
   *    copyright notice, this list of conditions and the following
   *    disclaimer in the documentation and/or other materials provided
   *    with the distribution.
   *  * Neither the name of Google Inc. nor the names of its
   *    contributors may be used to endorse or promote products derived
   *    from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */



  // A single base 64 digit can contain 6 bits of data. For the base 64 variable
  // length quantities we use in the source map spec, the first bit is the sign,
  // the next four bits are the actual value, and the 6th bit is the
  // continuation bit. The continuation bit tells us whether there are more
  // digits in this value following this digit.
  //
  //   Continuation
  //   |    Sign
  //   |    |
  //   V    V
  //   101011

  var VLQ_BASE_SHIFT = 5;

  // binary: 100000
  var VLQ_BASE = 1 << VLQ_BASE_SHIFT;

  // binary: 011111
  var VLQ_BASE_MASK = VLQ_BASE - 1;

  // binary: 100000
  var VLQ_CONTINUATION_BIT = VLQ_BASE;

  /**
   * Converts from a two-complement value to a value where the sign bit is
   * placed in the least significant bit.  For example, as decimals:
   *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
   *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
   */
  function toVLQSigned(aValue) {
    return aValue < 0
      ? ((-aValue) << 1) + 1
      : (aValue << 1) + 0;
  }

  /**
   * Converts to a two-complement value from a value where the sign bit is
   * placed in the least significant bit.  For example, as decimals:
   *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
   *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
   */
  function fromVLQSigned(aValue) {
    var isNegative = (aValue & 1) === 1;
    var shifted = aValue >> 1;
    return isNegative
      ? -shifted
      : shifted;
  }

  /**
   * Returns the base 64 VLQ encoded value.
   */
  var encode$1 = function base64VLQ_encode(aValue) {
    var encoded = "";
    var digit;

    var vlq = toVLQSigned(aValue);

    do {
      digit = vlq & VLQ_BASE_MASK;
      vlq >>>= VLQ_BASE_SHIFT;
      if (vlq > 0) {
        // There are still more digits in this value, so we must make sure the
        // continuation bit is marked.
        digit |= VLQ_CONTINUATION_BIT;
      }
      encoded += base64.encode(digit);
    } while (vlq > 0);

    return encoded;
  };

  /**
   * Decodes the next base 64 VLQ value from the given string and returns the
   * value and the rest of the string via the out parameter.
   */
  var decode$1 = function base64VLQ_decode(aStr, aIndex, aOutParam) {
    var strLen = aStr.length;
    var result = 0;
    var shift = 0;
    var continuation, digit;

    do {
      if (aIndex >= strLen) {
        throw new Error("Expected more digits in base 64 VLQ value.");
      }

      digit = base64.decode(aStr.charCodeAt(aIndex++));
      if (digit === -1) {
        throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
      }

      continuation = !!(digit & VLQ_CONTINUATION_BIT);
      digit &= VLQ_BASE_MASK;
      result = result + (digit << shift);
      shift += VLQ_BASE_SHIFT;
    } while (continuation);

    aOutParam.value = fromVLQSigned(result);
    aOutParam.rest = aIndex;
  };

  var base64Vlq = {
  	encode: encode$1,
  	decode: decode$1
  };

  function getDefaultExportFromCjs (x) {
  	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  }

  function createCommonjsModule(fn, basedir, module) {
  	return module = {
  	  path: basedir,
  	  exports: {},
  	  require: function (path, base) {
        return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
      }
  	}, fn(module, module.exports), module.exports;
  }

  function commonjsRequire () {
  	throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
  }

  var util = createCommonjsModule(function (module, exports) {
  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */

  /**
   * This is a helper function for getting values from parameter/options
   * objects.
   *
   * @param args The object we are extracting values from
   * @param name The name of the property we are getting.
   * @param defaultValue An optional value to return if the property is missing
   * from the object. If this is not specified and the property is missing, an
   * error will be thrown.
   */
  function getArg(aArgs, aName, aDefaultValue) {
    if (aName in aArgs) {
      return aArgs[aName];
    } else if (arguments.length === 3) {
      return aDefaultValue;
    } else {
      throw new Error('"' + aName + '" is a required argument.');
    }
  }
  exports.getArg = getArg;

  var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
  var dataUrlRegexp = /^data:.+\,.+$/;

  function urlParse(aUrl) {
    var match = aUrl.match(urlRegexp);
    if (!match) {
      return null;
    }
    return {
      scheme: match[1],
      auth: match[2],
      host: match[3],
      port: match[4],
      path: match[5]
    };
  }
  exports.urlParse = urlParse;

  function urlGenerate(aParsedUrl) {
    var url = '';
    if (aParsedUrl.scheme) {
      url += aParsedUrl.scheme + ':';
    }
    url += '//';
    if (aParsedUrl.auth) {
      url += aParsedUrl.auth + '@';
    }
    if (aParsedUrl.host) {
      url += aParsedUrl.host;
    }
    if (aParsedUrl.port) {
      url += ":" + aParsedUrl.port;
    }
    if (aParsedUrl.path) {
      url += aParsedUrl.path;
    }
    return url;
  }
  exports.urlGenerate = urlGenerate;

  /**
   * Normalizes a path, or the path portion of a URL:
   *
   * - Replaces consecutive slashes with one slash.
   * - Removes unnecessary '.' parts.
   * - Removes unnecessary '<dir>/..' parts.
   *
   * Based on code in the Node.js 'path' core module.
   *
   * @param aPath The path or url to normalize.
   */
  function normalize(aPath) {
    var path = aPath;
    var url = urlParse(aPath);
    if (url) {
      if (!url.path) {
        return aPath;
      }
      path = url.path;
    }
    var isAbsolute = exports.isAbsolute(path);

    var parts = path.split(/\/+/);
    for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
      part = parts[i];
      if (part === '.') {
        parts.splice(i, 1);
      } else if (part === '..') {
        up++;
      } else if (up > 0) {
        if (part === '') {
          // The first part is blank if the path is absolute. Trying to go
          // above the root is a no-op. Therefore we can remove all '..' parts
          // directly after the root.
          parts.splice(i + 1, up);
          up = 0;
        } else {
          parts.splice(i, 2);
          up--;
        }
      }
    }
    path = parts.join('/');

    if (path === '') {
      path = isAbsolute ? '/' : '.';
    }

    if (url) {
      url.path = path;
      return urlGenerate(url);
    }
    return path;
  }
  exports.normalize = normalize;

  /**
   * Joins two paths/URLs.
   *
   * @param aRoot The root path or URL.
   * @param aPath The path or URL to be joined with the root.
   *
   * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
   *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended
   *   first.
   * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
   *   is updated with the result and aRoot is returned. Otherwise the result
   *   is returned.
   *   - If aPath is absolute, the result is aPath.
   *   - Otherwise the two paths are joined with a slash.
   * - Joining for example 'http://' and 'www.example.com' is also supported.
   */
  function join(aRoot, aPath) {
    if (aRoot === "") {
      aRoot = ".";
    }
    if (aPath === "") {
      aPath = ".";
    }
    var aPathUrl = urlParse(aPath);
    var aRootUrl = urlParse(aRoot);
    if (aRootUrl) {
      aRoot = aRootUrl.path || '/';
    }

    // `join(foo, '//www.example.org')`
    if (aPathUrl && !aPathUrl.scheme) {
      if (aRootUrl) {
        aPathUrl.scheme = aRootUrl.scheme;
      }
      return urlGenerate(aPathUrl);
    }

    if (aPathUrl || aPath.match(dataUrlRegexp)) {
      return aPath;
    }

    // `join('http://', 'www.example.com')`
    if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
      aRootUrl.host = aPath;
      return urlGenerate(aRootUrl);
    }

    var joined = aPath.charAt(0) === '/'
      ? aPath
      : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);

    if (aRootUrl) {
      aRootUrl.path = joined;
      return urlGenerate(aRootUrl);
    }
    return joined;
  }
  exports.join = join;

  exports.isAbsolute = function (aPath) {
    return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
  };

  /**
   * Make a path relative to a URL or another path.
   *
   * @param aRoot The root path or URL.
   * @param aPath The path or URL to be made relative to aRoot.
   */
  function relative(aRoot, aPath) {
    if (aRoot === "") {
      aRoot = ".";
    }

    aRoot = aRoot.replace(/\/$/, '');

    // It is possible for the path to be above the root. In this case, simply
    // checking whether the root is a prefix of the path won't work. Instead, we
    // need to remove components from the root one by one, until either we find
    // a prefix that fits, or we run out of components to remove.
    var level = 0;
    while (aPath.indexOf(aRoot + '/') !== 0) {
      var index = aRoot.lastIndexOf("/");
      if (index < 0) {
        return aPath;
      }

      // If the only part of the root that is left is the scheme (i.e. http://,
      // file:///, etc.), one or more slashes (/), or simply nothing at all, we
      // have exhausted all components, so the path is not relative to the root.
      aRoot = aRoot.slice(0, index);
      if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
        return aPath;
      }

      ++level;
    }

    // Make sure we add a "../" for each component we removed from the root.
    return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
  }
  exports.relative = relative;

  var supportsNullProto = (function () {
    var obj = Object.create(null);
    return !('__proto__' in obj);
  }());

  function identity (s) {
    return s;
  }

  /**
   * Because behavior goes wacky when you set `__proto__` on objects, we
   * have to prefix all the strings in our set with an arbitrary character.
   *
   * See https://github.com/mozilla/source-map/pull/31 and
   * https://github.com/mozilla/source-map/issues/30
   *
   * @param String aStr
   */
  function toSetString(aStr) {
    if (isProtoString(aStr)) {
      return '$' + aStr;
    }

    return aStr;
  }
  exports.toSetString = supportsNullProto ? identity : toSetString;

  function fromSetString(aStr) {
    if (isProtoString(aStr)) {
      return aStr.slice(1);
    }

    return aStr;
  }
  exports.fromSetString = supportsNullProto ? identity : fromSetString;

  function isProtoString(s) {
    if (!s) {
      return false;
    }

    var length = s.length;

    if (length < 9 /* "__proto__".length */) {
      return false;
    }

    if (s.charCodeAt(length - 1) !== 95  /* '_' */ ||
        s.charCodeAt(length - 2) !== 95  /* '_' */ ||
        s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
        s.charCodeAt(length - 4) !== 116 /* 't' */ ||
        s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
        s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
        s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
        s.charCodeAt(length - 8) !== 95  /* '_' */ ||
        s.charCodeAt(length - 9) !== 95  /* '_' */) {
      return false;
    }

    for (var i = length - 10; i >= 0; i--) {
      if (s.charCodeAt(i) !== 36 /* '$' */) {
        return false;
      }
    }

    return true;
  }

  /**
   * Comparator between two mappings where the original positions are compared.
   *
   * Optionally pass in `true` as `onlyCompareGenerated` to consider two
   * mappings with the same original source/line/column, but different generated
   * line and column the same. Useful when searching for a mapping with a
   * stubbed out mapping.
   */
  function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
    var cmp = strcmp(mappingA.source, mappingB.source);
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.originalLine - mappingB.originalLine;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.originalColumn - mappingB.originalColumn;
    if (cmp !== 0 || onlyCompareOriginal) {
      return cmp;
    }

    cmp = mappingA.generatedColumn - mappingB.generatedColumn;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.generatedLine - mappingB.generatedLine;
    if (cmp !== 0) {
      return cmp;
    }

    return strcmp(mappingA.name, mappingB.name);
  }
  exports.compareByOriginalPositions = compareByOriginalPositions;

  /**
   * Comparator between two mappings with deflated source and name indices where
   * the generated positions are compared.
   *
   * Optionally pass in `true` as `onlyCompareGenerated` to consider two
   * mappings with the same generated line and column, but different
   * source/name/original line and column the same. Useful when searching for a
   * mapping with a stubbed out mapping.
   */
  function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
    var cmp = mappingA.generatedLine - mappingB.generatedLine;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.generatedColumn - mappingB.generatedColumn;
    if (cmp !== 0 || onlyCompareGenerated) {
      return cmp;
    }

    cmp = strcmp(mappingA.source, mappingB.source);
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.originalLine - mappingB.originalLine;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.originalColumn - mappingB.originalColumn;
    if (cmp !== 0) {
      return cmp;
    }

    return strcmp(mappingA.name, mappingB.name);
  }
  exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;

  function strcmp(aStr1, aStr2) {
    if (aStr1 === aStr2) {
      return 0;
    }

    if (aStr1 === null) {
      return 1; // aStr2 !== null
    }

    if (aStr2 === null) {
      return -1; // aStr1 !== null
    }

    if (aStr1 > aStr2) {
      return 1;
    }

    return -1;
  }

  /**
   * Comparator between two mappings with inflated source and name strings where
   * the generated positions are compared.
   */
  function compareByGeneratedPositionsInflated(mappingA, mappingB) {
    var cmp = mappingA.generatedLine - mappingB.generatedLine;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.generatedColumn - mappingB.generatedColumn;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = strcmp(mappingA.source, mappingB.source);
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.originalLine - mappingB.originalLine;
    if (cmp !== 0) {
      return cmp;
    }

    cmp = mappingA.originalColumn - mappingB.originalColumn;
    if (cmp !== 0) {
      return cmp;
    }

    return strcmp(mappingA.name, mappingB.name);
  }
  exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;

  /**
   * Strip any JSON XSSI avoidance prefix from the string (as documented
   * in the source maps specification), and then parse the string as
   * JSON.
   */
  function parseSourceMapInput(str) {
    return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
  }
  exports.parseSourceMapInput = parseSourceMapInput;

  /**
   * Compute the URL of a source given the the source root, the source's
   * URL, and the source map's URL.
   */
  function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
    sourceURL = sourceURL || '';

    if (sourceRoot) {
      // This follows what Chrome does.
      if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
        sourceRoot += '/';
      }
      // The spec says:
      //   Line 4: An optional source root, useful for relocating source
      //   files on a server or removing repeated values in the
      //   “sources” entry.  This value is prepended to the individual
      //   entries in the “source” field.
      sourceURL = sourceRoot + sourceURL;
    }

    // Historically, SourceMapConsumer did not take the sourceMapURL as
    // a parameter.  This mode is still somewhat supported, which is why
    // this code block is conditional.  However, it's preferable to pass
    // the source map URL to SourceMapConsumer, so that this function
    // can implement the source URL resolution algorithm as outlined in
    // the spec.  This block is basically the equivalent of:
    //    new URL(sourceURL, sourceMapURL).toString()
    // ... except it avoids using URL, which wasn't available in the
    // older releases of node still supported by this library.
    //
    // The spec says:
    //   If the sources are not absolute URLs after prepending of the
    //   “sourceRoot”, the sources are resolved relative to the
    //   SourceMap (like resolving script src in a html document).
    if (sourceMapURL) {
      var parsed = urlParse(sourceMapURL);
      if (!parsed) {
        throw new Error("sourceMapURL could not be parsed");
      }
      if (parsed.path) {
        // Strip the last path component, but keep the "/".
        var index = parsed.path.lastIndexOf('/');
        if (index >= 0) {
          parsed.path = parsed.path.substring(0, index + 1);
        }
      }
      sourceURL = join(urlGenerate(parsed), sourceURL);
    }

    return normalize(sourceURL);
  }
  exports.computeSourceURL = computeSourceURL;
  });

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */


  var has = Object.prototype.hasOwnProperty;
  var hasNativeMap = typeof Map !== "undefined";

  /**
   * A data structure which is a combination of an array and a set. Adding a new
   * member is O(1), testing for membership is O(1), and finding the index of an
   * element is O(1). Removing elements from the set is not supported. Only
   * strings are supported for membership.
   */
  function ArraySet() {
    this._array = [];
    this._set = hasNativeMap ? new Map() : Object.create(null);
  }

  /**
   * Static method for creating ArraySet instances from an existing array.
   */
  ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
    var set = new ArraySet();
    for (var i = 0, len = aArray.length; i < len; i++) {
      set.add(aArray[i], aAllowDuplicates);
    }
    return set;
  };

  /**
   * Return how many unique items are in this ArraySet. If duplicates have been
   * added, than those do not count towards the size.
   *
   * @returns Number
   */
  ArraySet.prototype.size = function ArraySet_size() {
    return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
  };

  /**
   * Add the given string to this set.
   *
   * @param String aStr
   */
  ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
    var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
    var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
    var idx = this._array.length;
    if (!isDuplicate || aAllowDuplicates) {
      this._array.push(aStr);
    }
    if (!isDuplicate) {
      if (hasNativeMap) {
        this._set.set(aStr, idx);
      } else {
        this._set[sStr] = idx;
      }
    }
  };

  /**
   * Is the given string a member of this set?
   *
   * @param String aStr
   */
  ArraySet.prototype.has = function ArraySet_has(aStr) {
    if (hasNativeMap) {
      return this._set.has(aStr);
    } else {
      var sStr = util.toSetString(aStr);
      return has.call(this._set, sStr);
    }
  };

  /**
   * What is the index of the given string in the array?
   *
   * @param String aStr
   */
  ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
    if (hasNativeMap) {
      var idx = this._set.get(aStr);
      if (idx >= 0) {
          return idx;
      }
    } else {
      var sStr = util.toSetString(aStr);
      if (has.call(this._set, sStr)) {
        return this._set[sStr];
      }
    }

    throw new Error('"' + aStr + '" is not in the set.');
  };

  /**
   * What is the element at the given index?
   *
   * @param Number aIdx
   */
  ArraySet.prototype.at = function ArraySet_at(aIdx) {
    if (aIdx >= 0 && aIdx < this._array.length) {
      return this._array[aIdx];
    }
    throw new Error('No element indexed by ' + aIdx);
  };

  /**
   * Returns the array representation of this set (which has the proper indices
   * indicated by indexOf). Note that this is a copy of the internal array used
   * for storing the members so that no one can mess with internal state.
   */
  ArraySet.prototype.toArray = function ArraySet_toArray() {
    return this._array.slice();
  };

  var ArraySet_1 = ArraySet;

  var arraySet = {
  	ArraySet: ArraySet_1
  };

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2014 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */



  /**
   * Determine whether mappingB is after mappingA with respect to generated
   * position.
   */
  function generatedPositionAfter(mappingA, mappingB) {
    // Optimized for most common case
    var lineA = mappingA.generatedLine;
    var lineB = mappingB.generatedLine;
    var columnA = mappingA.generatedColumn;
    var columnB = mappingB.generatedColumn;
    return lineB > lineA || lineB == lineA && columnB >= columnA ||
           util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
  }

  /**
   * A data structure to provide a sorted view of accumulated mappings in a
   * performance conscious manner. It trades a neglibable overhead in general
   * case for a large speedup in case of mappings being added in order.
   */
  function MappingList() {
    this._array = [];
    this._sorted = true;
    // Serves as infimum
    this._last = {generatedLine: -1, generatedColumn: 0};
  }

  /**
   * Iterate through internal items. This method takes the same arguments that
   * `Array.prototype.forEach` takes.
   *
   * NOTE: The order of the mappings is NOT guaranteed.
   */
  MappingList.prototype.unsortedForEach =
    function MappingList_forEach(aCallback, aThisArg) {
      this._array.forEach(aCallback, aThisArg);
    };

  /**
   * Add the given source mapping.
   *
   * @param Object aMapping
   */
  MappingList.prototype.add = function MappingList_add(aMapping) {
    if (generatedPositionAfter(this._last, aMapping)) {
      this._last = aMapping;
      this._array.push(aMapping);
    } else {
      this._sorted = false;
      this._array.push(aMapping);
    }
  };

  /**
   * Returns the flat, sorted array of mappings. The mappings are sorted by
   * generated position.
   *
   * WARNING: This method returns internal data without copying, for
   * performance. The return value must NOT be mutated, and should be treated as
   * an immutable borrow. If you want to take ownership, you must make your own
   * copy.
   */
  MappingList.prototype.toArray = function MappingList_toArray() {
    if (!this._sorted) {
      this._array.sort(util.compareByGeneratedPositionsInflated);
      this._sorted = true;
    }
    return this._array;
  };

  var MappingList_1 = MappingList;

  var mappingList = {
  	MappingList: MappingList_1
  };

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */



  var ArraySet$1 = arraySet.ArraySet;
  var MappingList$1 = mappingList.MappingList;

  /**
   * An instance of the SourceMapGenerator represents a source map which is
   * being built incrementally. You may pass an object with the following
   * properties:
   *
   *   - file: The filename of the generated source.
   *   - sourceRoot: A root for all relative URLs in this source map.
   */
  function SourceMapGenerator(aArgs) {
    if (!aArgs) {
      aArgs = {};
    }
    this._file = util.getArg(aArgs, 'file', null);
    this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
    this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
    this._sources = new ArraySet$1();
    this._names = new ArraySet$1();
    this._mappings = new MappingList$1();
    this._sourcesContents = null;
  }

  SourceMapGenerator.prototype._version = 3;

  /**
   * Creates a new SourceMapGenerator based on a SourceMapConsumer
   *
   * @param aSourceMapConsumer The SourceMap.
   */
  SourceMapGenerator.fromSourceMap =
    function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
      var sourceRoot = aSourceMapConsumer.sourceRoot;
      var generator = new SourceMapGenerator({
        file: aSourceMapConsumer.file,
        sourceRoot: sourceRoot
      });
      aSourceMapConsumer.eachMapping(function (mapping) {
        var newMapping = {
          generated: {
            line: mapping.generatedLine,
            column: mapping.generatedColumn
          }
        };

        if (mapping.source != null) {
          newMapping.source = mapping.source;
          if (sourceRoot != null) {
            newMapping.source = util.relative(sourceRoot, newMapping.source);
          }

          newMapping.original = {
            line: mapping.originalLine,
            column: mapping.originalColumn
          };

          if (mapping.name != null) {
            newMapping.name = mapping.name;
          }
        }

        generator.addMapping(newMapping);
      });
      aSourceMapConsumer.sources.forEach(function (sourceFile) {
        var sourceRelative = sourceFile;
        if (sourceRoot !== null) {
          sourceRelative = util.relative(sourceRoot, sourceFile);
        }

        if (!generator._sources.has(sourceRelative)) {
          generator._sources.add(sourceRelative);
        }

        var content = aSourceMapConsumer.sourceContentFor(sourceFile);
        if (content != null) {
          generator.setSourceContent(sourceFile, content);
        }
      });
      return generator;
    };

  /**
   * Add a single mapping from original source line and column to the generated
   * source's line and column for this source map being created. The mapping
   * object should have the following properties:
   *
   *   - generated: An object with the generated line and column positions.
   *   - original: An object with the original line and column positions.
   *   - source: The original source file (relative to the sourceRoot).
   *   - name: An optional original token name for this mapping.
   */
  SourceMapGenerator.prototype.addMapping =
    function SourceMapGenerator_addMapping(aArgs) {
      var generated = util.getArg(aArgs, 'generated');
      var original = util.getArg(aArgs, 'original', null);
      var source = util.getArg(aArgs, 'source', null);
      var name = util.getArg(aArgs, 'name', null);

      if (!this._skipValidation) {
        this._validateMapping(generated, original, source, name);
      }

      if (source != null) {
        source = String(source);
        if (!this._sources.has(source)) {
          this._sources.add(source);
        }
      }

      if (name != null) {
        name = String(name);
        if (!this._names.has(name)) {
          this._names.add(name);
        }
      }

      this._mappings.add({
        generatedLine: generated.line,
        generatedColumn: generated.column,
        originalLine: original != null && original.line,
        originalColumn: original != null && original.column,
        source: source,
        name: name
      });
    };

  /**
   * Set the source content for a source file.
   */
  SourceMapGenerator.prototype.setSourceContent =
    function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
      var source = aSourceFile;
      if (this._sourceRoot != null) {
        source = util.relative(this._sourceRoot, source);
      }

      if (aSourceContent != null) {
        // Add the source content to the _sourcesContents map.
        // Create a new _sourcesContents map if the property is null.
        if (!this._sourcesContents) {
          this._sourcesContents = Object.create(null);
        }
        this._sourcesContents[util.toSetString(source)] = aSourceContent;
      } else if (this._sourcesContents) {
        // Remove the source file from the _sourcesContents map.
        // If the _sourcesContents map is empty, set the property to null.
        delete this._sourcesContents[util.toSetString(source)];
        if (Object.keys(this._sourcesContents).length === 0) {
          this._sourcesContents = null;
        }
      }
    };

  /**
   * Applies the mappings of a sub-source-map for a specific source file to the
   * source map being generated. Each mapping to the supplied source file is
   * rewritten using the supplied source map. Note: The resolution for the
   * resulting mappings is the minimium of this map and the supplied map.
   *
   * @param aSourceMapConsumer The source map to be applied.
   * @param aSourceFile Optional. The filename of the source file.
   *        If omitted, SourceMapConsumer's file property will be used.
   * @param aSourceMapPath Optional. The dirname of the path to the source map
   *        to be applied. If relative, it is relative to the SourceMapConsumer.
   *        This parameter is needed when the two source maps aren't in the same
   *        directory, and the source map to be applied contains relative source
   *        paths. If so, those relative source paths need to be rewritten
   *        relative to the SourceMapGenerator.
   */
  SourceMapGenerator.prototype.applySourceMap =
    function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
      var sourceFile = aSourceFile;
      // If aSourceFile is omitted, we will use the file property of the SourceMap
      if (aSourceFile == null) {
        if (aSourceMapConsumer.file == null) {
          throw new Error(
            'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
            'or the source map\'s "file" property. Both were omitted.'
          );
        }
        sourceFile = aSourceMapConsumer.file;
      }
      var sourceRoot = this._sourceRoot;
      // Make "sourceFile" relative if an absolute Url is passed.
      if (sourceRoot != null) {
        sourceFile = util.relative(sourceRoot, sourceFile);
      }
      // Applying the SourceMap can add and remove items from the sources and
      // the names array.
      var newSources = new ArraySet$1();
      var newNames = new ArraySet$1();

      // Find mappings for the "sourceFile"
      this._mappings.unsortedForEach(function (mapping) {
        if (mapping.source === sourceFile && mapping.originalLine != null) {
          // Check if it can be mapped by the source map, then update the mapping.
          var original = aSourceMapConsumer.originalPositionFor({
            line: mapping.originalLine,
            column: mapping.originalColumn
          });
          if (original.source != null) {
            // Copy mapping
            mapping.source = original.source;
            if (aSourceMapPath != null) {
              mapping.source = util.join(aSourceMapPath, mapping.source);
            }
            if (sourceRoot != null) {
              mapping.source = util.relative(sourceRoot, mapping.source);
            }
            mapping.originalLine = original.line;
            mapping.originalColumn = original.column;
            if (original.name != null) {
              mapping.name = original.name;
            }
          }
        }

        var source = mapping.source;
        if (source != null && !newSources.has(source)) {
          newSources.add(source);
        }

        var name = mapping.name;
        if (name != null && !newNames.has(name)) {
          newNames.add(name);
        }

      }, this);
      this._sources = newSources;
      this._names = newNames;

      // Copy sourcesContents of applied map.
      aSourceMapConsumer.sources.forEach(function (sourceFile) {
        var content = aSourceMapConsumer.sourceContentFor(sourceFile);
        if (content != null) {
          if (aSourceMapPath != null) {
            sourceFile = util.join(aSourceMapPath, sourceFile);
          }
          if (sourceRoot != null) {
            sourceFile = util.relative(sourceRoot, sourceFile);
          }
          this.setSourceContent(sourceFile, content);
        }
      }, this);
    };

  /**
   * A mapping can have one of the three levels of data:
   *
   *   1. Just the generated position.
   *   2. The Generated position, original position, and original source.
   *   3. Generated and original position, original source, as well as a name
   *      token.
   *
   * To maintain consistency, we validate that any new mapping being added falls
   * in to one of these categories.
   */
  SourceMapGenerator.prototype._validateMapping =
    function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
                                                aName) {
      // When aOriginal is truthy but has empty values for .line and .column,
      // it is most likely a programmer error. In this case we throw a very
      // specific error message to try to guide them the right way.
      // For example: https://github.com/Polymer/polymer-bundler/pull/519
      if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
          throw new Error(
              'original.line and original.column are not numbers -- you probably meant to omit ' +
              'the original mapping entirely and only map the generated position. If so, pass ' +
              'null for the original mapping instead of an object with empty or null values.'
          );
      }

      if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
          && aGenerated.line > 0 && aGenerated.column >= 0
          && !aOriginal && !aSource && !aName) {
        // Case 1.
        return;
      }
      else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
               && aOriginal && 'line' in aOriginal && 'column' in aOriginal
               && aGenerated.line > 0 && aGenerated.column >= 0
               && aOriginal.line > 0 && aOriginal.column >= 0
               && aSource) {
        // Cases 2 and 3.
        return;
      }
      else {
        throw new Error('Invalid mapping: ' + JSON.stringify({
          generated: aGenerated,
          source: aSource,
          original: aOriginal,
          name: aName
        }));
      }
    };

  /**
   * Serialize the accumulated mappings in to the stream of base 64 VLQs
   * specified by the source map format.
   */
  SourceMapGenerator.prototype._serializeMappings =
    function SourceMapGenerator_serializeMappings() {
      var previousGeneratedColumn = 0;
      var previousGeneratedLine = 1;
      var previousOriginalColumn = 0;
      var previousOriginalLine = 0;
      var previousName = 0;
      var previousSource = 0;
      var result = '';
      var next;
      var mapping;
      var nameIdx;
      var sourceIdx;

      var mappings = this._mappings.toArray();
      for (var i = 0, len = mappings.length; i < len; i++) {
        mapping = mappings[i];
        next = '';

        if (mapping.generatedLine !== previousGeneratedLine) {
          previousGeneratedColumn = 0;
          while (mapping.generatedLine !== previousGeneratedLine) {
            next += ';';
            previousGeneratedLine++;
          }
        }
        else {
          if (i > 0) {
            if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
              continue;
            }
            next += ',';
          }
        }

        next += base64Vlq.encode(mapping.generatedColumn
                                   - previousGeneratedColumn);
        previousGeneratedColumn = mapping.generatedColumn;

        if (mapping.source != null) {
          sourceIdx = this._sources.indexOf(mapping.source);
          next += base64Vlq.encode(sourceIdx - previousSource);
          previousSource = sourceIdx;

          // lines are stored 0-based in SourceMap spec version 3
          next += base64Vlq.encode(mapping.originalLine - 1
                                     - previousOriginalLine);
          previousOriginalLine = mapping.originalLine - 1;

          next += base64Vlq.encode(mapping.originalColumn
                                     - previousOriginalColumn);
          previousOriginalColumn = mapping.originalColumn;

          if (mapping.name != null) {
            nameIdx = this._names.indexOf(mapping.name);
            next += base64Vlq.encode(nameIdx - previousName);
            previousName = nameIdx;
          }
        }

        result += next;
      }

      return result;
    };

  SourceMapGenerator.prototype._generateSourcesContent =
    function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
      return aSources.map(function (source) {
        if (!this._sourcesContents) {
          return null;
        }
        if (aSourceRoot != null) {
          source = util.relative(aSourceRoot, source);
        }
        var key = util.toSetString(source);
        return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
          ? this._sourcesContents[key]
          : null;
      }, this);
    };

  /**
   * Externalize the source map.
   */
  SourceMapGenerator.prototype.toJSON =
    function SourceMapGenerator_toJSON() {
      var map = {
        version: this._version,
        sources: this._sources.toArray(),
        names: this._names.toArray(),
        mappings: this._serializeMappings()
      };
      if (this._file != null) {
        map.file = this._file;
      }
      if (this._sourceRoot != null) {
        map.sourceRoot = this._sourceRoot;
      }
      if (this._sourcesContents) {
        map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
      }

      return map;
    };

  /**
   * Render the source map being generated to a string.
   */
  SourceMapGenerator.prototype.toString =
    function SourceMapGenerator_toString() {
      return JSON.stringify(this.toJSON());
    };

  var SourceMapGenerator_1 = SourceMapGenerator;

  var sourceMapGenerator = {
  	SourceMapGenerator: SourceMapGenerator_1
  };

  var binarySearch = createCommonjsModule(function (module, exports) {
  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */

  exports.GREATEST_LOWER_BOUND = 1;
  exports.LEAST_UPPER_BOUND = 2;

  /**
   * Recursive implementation of binary search.
   *
   * @param aLow Indices here and lower do not contain the needle.
   * @param aHigh Indices here and higher do not contain the needle.
   * @param aNeedle The element being searched for.
   * @param aHaystack The non-empty array being searched.
   * @param aCompare Function which takes two elements and returns -1, 0, or 1.
   * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
   *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
   *     closest element that is smaller than or greater than the one we are
   *     searching for, respectively, if the exact element cannot be found.
   */
  function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
    // This function terminates when one of the following is true:
    //
    //   1. We find the exact element we are looking for.
    //
    //   2. We did not find the exact element, but we can return the index of
    //      the next-closest element.
    //
    //   3. We did not find the exact element, and there is no next-closest
    //      element than the one we are searching for, so we return -1.
    var mid = Math.floor((aHigh - aLow) / 2) + aLow;
    var cmp = aCompare(aNeedle, aHaystack[mid], true);
    if (cmp === 0) {
      // Found the element we are looking for.
      return mid;
    }
    else if (cmp > 0) {
      // Our needle is greater than aHaystack[mid].
      if (aHigh - mid > 1) {
        // The element is in the upper half.
        return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
      }

      // The exact needle element was not found in this haystack. Determine if
      // we are in termination case (3) or (2) and return the appropriate thing.
      if (aBias == exports.LEAST_UPPER_BOUND) {
        return aHigh < aHaystack.length ? aHigh : -1;
      } else {
        return mid;
      }
    }
    else {
      // Our needle is less than aHaystack[mid].
      if (mid - aLow > 1) {
        // The element is in the lower half.
        return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
      }

      // we are in termination case (3) or (2) and return the appropriate thing.
      if (aBias == exports.LEAST_UPPER_BOUND) {
        return mid;
      } else {
        return aLow < 0 ? -1 : aLow;
      }
    }
  }

  /**
   * This is an implementation of binary search which will always try and return
   * the index of the closest element if there is no exact hit. This is because
   * mappings between original and generated line/col pairs are single points,
   * and there is an implicit region between each of them, so a miss just means
   * that you aren't on the very start of a region.
   *
   * @param aNeedle The element you are looking for.
   * @param aHaystack The array that is being searched.
   * @param aCompare A function which takes the needle and an element in the
   *     array and returns -1, 0, or 1 depending on whether the needle is less
   *     than, equal to, or greater than the element, respectively.
   * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
   *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
   *     closest element that is smaller than or greater than the one we are
   *     searching for, respectively, if the exact element cannot be found.
   *     Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
   */
  exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
    if (aHaystack.length === 0) {
      return -1;
    }

    var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
                                aCompare, aBias || exports.GREATEST_LOWER_BOUND);
    if (index < 0) {
      return -1;
    }

    // We have found either the exact element, or the next-closest element than
    // the one we are searching for. However, there may be more than one such
    // element. Make sure we always return the smallest of these.
    while (index - 1 >= 0) {
      if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
        break;
      }
      --index;
    }

    return index;
  };
  });

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */

  // It turns out that some (most?) JavaScript engines don't self-host
  // `Array.prototype.sort`. This makes sense because C++ will likely remain
  // faster than JS when doing raw CPU-intensive sorting. However, when using a
  // custom comparator function, calling back and forth between the VM's C++ and
  // JIT'd JS is rather slow *and* loses JIT type information, resulting in
  // worse generated code for the comparator function than would be optimal. In
  // fact, when sorting with a comparator, these costs outweigh the benefits of
  // sorting in C++. By using our own JS-implemented Quick Sort (below), we get
  // a ~3500ms mean speed-up in `bench/bench.html`.

  /**
   * Swap the elements indexed by `x` and `y` in the array `ary`.
   *
   * @param {Array} ary
   *        The array.
   * @param {Number} x
   *        The index of the first item.
   * @param {Number} y
   *        The index of the second item.
   */
  function swap(ary, x, y) {
    var temp = ary[x];
    ary[x] = ary[y];
    ary[y] = temp;
  }

  /**
   * Returns a random integer within the range `low .. high` inclusive.
   *
   * @param {Number} low
   *        The lower bound on the range.
   * @param {Number} high
   *        The upper bound on the range.
   */
  function randomIntInRange(low, high) {
    return Math.round(low + (Math.random() * (high - low)));
  }

  /**
   * The Quick Sort algorithm.
   *
   * @param {Array} ary
   *        An array to sort.
   * @param {function} comparator
   *        Function to use to compare two items.
   * @param {Number} p
   *        Start index of the array
   * @param {Number} r
   *        End index of the array
   */
  function doQuickSort(ary, comparator, p, r) {
    // If our lower bound is less than our upper bound, we (1) partition the
    // array into two pieces and (2) recurse on each half. If it is not, this is
    // the empty array and our base case.

    if (p < r) {
      // (1) Partitioning.
      //
      // The partitioning chooses a pivot between `p` and `r` and moves all
      // elements that are less than or equal to the pivot to the before it, and
      // all the elements that are greater than it after it. The effect is that
      // once partition is done, the pivot is in the exact place it will be when
      // the array is put in sorted order, and it will not need to be moved
      // again. This runs in O(n) time.

      // Always choose a random pivot so that an input array which is reverse
      // sorted does not cause O(n^2) running time.
      var pivotIndex = randomIntInRange(p, r);
      var i = p - 1;

      swap(ary, pivotIndex, r);
      var pivot = ary[r];

      // Immediately after `j` is incremented in this loop, the following hold
      // true:
      //
      //   * Every element in `ary[p .. i]` is less than or equal to the pivot.
      //
      //   * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
      for (var j = p; j < r; j++) {
        if (comparator(ary[j], pivot) <= 0) {
          i += 1;
          swap(ary, i, j);
        }
      }

      swap(ary, i + 1, j);
      var q = i + 1;

      // (2) Recurse on each half.

      doQuickSort(ary, comparator, p, q - 1);
      doQuickSort(ary, comparator, q + 1, r);
    }
  }

  /**
   * Sort the given array in-place with the given comparator function.
   *
   * @param {Array} ary
   *        An array to sort.
   * @param {function} comparator
   *        Function to use to compare two items.
   */
  var quickSort_1 = function (ary, comparator) {
    doQuickSort(ary, comparator, 0, ary.length - 1);
  };

  var quickSort = {
  	quickSort: quickSort_1
  };

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */



  var ArraySet$2 = arraySet.ArraySet;

  var quickSort$1 = quickSort.quickSort;

  function SourceMapConsumer(aSourceMap, aSourceMapURL) {
    var sourceMap = aSourceMap;
    if (typeof aSourceMap === 'string') {
      sourceMap = util.parseSourceMapInput(aSourceMap);
    }

    return sourceMap.sections != null
      ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
      : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
  }

  SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {
    return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);
  };

  /**
   * The version of the source mapping spec that we are consuming.
   */
  SourceMapConsumer.prototype._version = 3;

  // `__generatedMappings` and `__originalMappings` are arrays that hold the
  // parsed mapping coordinates from the source map's "mappings" attribute. They
  // are lazily instantiated, accessed via the `_generatedMappings` and
  // `_originalMappings` getters respectively, and we only parse the mappings
  // and create these arrays once queried for a source location. We jump through
  // these hoops because there can be many thousands of mappings, and parsing
  // them is expensive, so we only want to do it if we must.
  //
  // Each object in the arrays is of the form:
  //
  //     {
  //       generatedLine: The line number in the generated code,
  //       generatedColumn: The column number in the generated code,
  //       source: The path to the original source file that generated this
  //               chunk of code,
  //       originalLine: The line number in the original source that
  //                     corresponds to this chunk of generated code,
  //       originalColumn: The column number in the original source that
  //                       corresponds to this chunk of generated code,
  //       name: The name of the original symbol which generated this chunk of
  //             code.
  //     }
  //
  // All properties except for `generatedLine` and `generatedColumn` can be
  // `null`.
  //
  // `_generatedMappings` is ordered by the generated positions.
  //
  // `_originalMappings` is ordered by the original positions.

  SourceMapConsumer.prototype.__generatedMappings = null;
  Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
    configurable: true,
    enumerable: true,
    get: function () {
      if (!this.__generatedMappings) {
        this._parseMappings(this._mappings, this.sourceRoot);
      }

      return this.__generatedMappings;
    }
  });

  SourceMapConsumer.prototype.__originalMappings = null;
  Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
    configurable: true,
    enumerable: true,
    get: function () {
      if (!this.__originalMappings) {
        this._parseMappings(this._mappings, this.sourceRoot);
      }

      return this.__originalMappings;
    }
  });

  SourceMapConsumer.prototype._charIsMappingSeparator =
    function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
      var c = aStr.charAt(index);
      return c === ";" || c === ",";
    };

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (the ordered arrays in the `this.__generatedMappings` and
   * `this.__originalMappings` properties).
   */
  SourceMapConsumer.prototype._parseMappings =
    function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
      throw new Error("Subclasses must implement _parseMappings");
    };

  SourceMapConsumer.GENERATED_ORDER = 1;
  SourceMapConsumer.ORIGINAL_ORDER = 2;

  SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
  SourceMapConsumer.LEAST_UPPER_BOUND = 2;

  /**
   * Iterate over each mapping between an original source/line/column and a
   * generated line/column in this source map.
   *
   * @param Function aCallback
   *        The function that is called with each mapping.
   * @param Object aContext
   *        Optional. If specified, this object will be the value of `this` every
   *        time that `aCallback` is called.
   * @param aOrder
   *        Either `SourceMapConsumer.GENERATED_ORDER` or
   *        `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
   *        iterate over the mappings sorted by the generated file's line/column
   *        order or the original's source/line/column order, respectively. Defaults to
   *        `SourceMapConsumer.GENERATED_ORDER`.
   */
  SourceMapConsumer.prototype.eachMapping =
    function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
      var context = aContext || null;
      var order = aOrder || SourceMapConsumer.GENERATED_ORDER;

      var mappings;
      switch (order) {
      case SourceMapConsumer.GENERATED_ORDER:
        mappings = this._generatedMappings;
        break;
      case SourceMapConsumer.ORIGINAL_ORDER:
        mappings = this._originalMappings;
        break;
      default:
        throw new Error("Unknown order of iteration.");
      }

      var sourceRoot = this.sourceRoot;
      mappings.map(function (mapping) {
        var source = mapping.source === null ? null : this._sources.at(mapping.source);
        source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
        return {
          source: source,
          generatedLine: mapping.generatedLine,
          generatedColumn: mapping.generatedColumn,
          originalLine: mapping.originalLine,
          originalColumn: mapping.originalColumn,
          name: mapping.name === null ? null : this._names.at(mapping.name)
        };
      }, this).forEach(aCallback, context);
    };

  /**
   * Returns all generated line and column information for the original source,
   * line, and column provided. If no column is provided, returns all mappings
   * corresponding to a either the line we are searching for or the next
   * closest line that has any mappings. Otherwise, returns all mappings
   * corresponding to the given line and either the column we are searching for
   * or the next closest column that has any offsets.
   *
   * The only argument is an object with the following properties:
   *
   *   - source: The filename of the original source.
   *   - line: The line number in the original source.  The line number is 1-based.
   *   - column: Optional. the column number in the original source.
   *    The column number is 0-based.
   *
   * and an array of objects is returned, each with the following properties:
   *
   *   - line: The line number in the generated source, or null.  The
   *    line number is 1-based.
   *   - column: The column number in the generated source, or null.
   *    The column number is 0-based.
   */
  SourceMapConsumer.prototype.allGeneratedPositionsFor =
    function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
      var line = util.getArg(aArgs, 'line');

      // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
      // returns the index of the closest mapping less than the needle. By
      // setting needle.originalColumn to 0, we thus find the last mapping for
      // the given line, provided such a mapping exists.
      var needle = {
        source: util.getArg(aArgs, 'source'),
        originalLine: line,
        originalColumn: util.getArg(aArgs, 'column', 0)
      };

      needle.source = this._findSourceIndex(needle.source);
      if (needle.source < 0) {
        return [];
      }

      var mappings = [];

      var index = this._findMapping(needle,
                                    this._originalMappings,
                                    "originalLine",
                                    "originalColumn",
                                    util.compareByOriginalPositions,
                                    binarySearch.LEAST_UPPER_BOUND);
      if (index >= 0) {
        var mapping = this._originalMappings[index];

        if (aArgs.column === undefined) {
          var originalLine = mapping.originalLine;

          // Iterate until either we run out of mappings, or we run into
          // a mapping for a different line than the one we found. Since
          // mappings are sorted, this is guaranteed to find all mappings for
          // the line we found.
          while (mapping && mapping.originalLine === originalLine) {
            mappings.push({
              line: util.getArg(mapping, 'generatedLine', null),
              column: util.getArg(mapping, 'generatedColumn', null),
              lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
            });

            mapping = this._originalMappings[++index];
          }
        } else {
          var originalColumn = mapping.originalColumn;

          // Iterate until either we run out of mappings, or we run into
          // a mapping for a different line than the one we were searching for.
          // Since mappings are sorted, this is guaranteed to find all mappings for
          // the line we are searching for.
          while (mapping &&
                 mapping.originalLine === line &&
                 mapping.originalColumn == originalColumn) {
            mappings.push({
              line: util.getArg(mapping, 'generatedLine', null),
              column: util.getArg(mapping, 'generatedColumn', null),
              lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
            });

            mapping = this._originalMappings[++index];
          }
        }
      }

      return mappings;
    };

  var SourceMapConsumer_1 = SourceMapConsumer;

  /**
   * A BasicSourceMapConsumer instance represents a parsed source map which we can
   * query for information about the original file positions by giving it a file
   * position in the generated source.
   *
   * The first parameter is the raw source map (either as a JSON string, or
   * already parsed to an object). According to the spec, source maps have the
   * following attributes:
   *
   *   - version: Which version of the source map spec this map is following.
   *   - sources: An array of URLs to the original source files.
   *   - names: An array of identifiers which can be referrenced by individual mappings.
   *   - sourceRoot: Optional. The URL root from which all sources are relative.
   *   - sourcesContent: Optional. An array of contents of the original source files.
   *   - mappings: A string of base64 VLQs which contain the actual mappings.
   *   - file: Optional. The generated file this source map is associated with.
   *
   * Here is an example source map, taken from the source map spec[0]:
   *
   *     {
   *       version : 3,
   *       file: "out.js",
   *       sourceRoot : "",
   *       sources: ["foo.js", "bar.js"],
   *       names: ["src", "maps", "are", "fun"],
   *       mappings: "AA,AB;;ABCDE;"
   *     }
   *
   * The second parameter, if given, is a string whose value is the URL
   * at which the source map was found.  This URL is used to compute the
   * sources array.
   *
   * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
   */
  function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
    var sourceMap = aSourceMap;
    if (typeof aSourceMap === 'string') {
      sourceMap = util.parseSourceMapInput(aSourceMap);
    }

    var version = util.getArg(sourceMap, 'version');
    var sources = util.getArg(sourceMap, 'sources');
    // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
    // requires the array) to play nice here.
    var names = util.getArg(sourceMap, 'names', []);
    var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
    var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
    var mappings = util.getArg(sourceMap, 'mappings');
    var file = util.getArg(sourceMap, 'file', null);

    // Once again, Sass deviates from the spec and supplies the version as a
    // string rather than a number, so we use loose equality checking here.
    if (version != this._version) {
      throw new Error('Unsupported version: ' + version);
    }

    if (sourceRoot) {
      sourceRoot = util.normalize(sourceRoot);
    }

    sources = sources
      .map(String)
      // Some source maps produce relative source paths like "./foo.js" instead of
      // "foo.js".  Normalize these first so that future comparisons will succeed.
      // See bugzil.la/1090768.
      .map(util.normalize)
      // Always ensure that absolute sources are internally stored relative to
      // the source root, if the source root is absolute. Not doing this would
      // be particularly problematic when the source root is a prefix of the
      // source (valid, but why??). See github issue #199 and bugzil.la/1188982.
      .map(function (source) {
        return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
          ? util.relative(sourceRoot, source)
          : source;
      });

    // Pass `true` below to allow duplicate names and sources. While source maps
    // are intended to be compressed and deduplicated, the TypeScript compiler
    // sometimes generates source maps with duplicates in them. See Github issue
    // #72 and bugzil.la/889492.
    this._names = ArraySet$2.fromArray(names.map(String), true);
    this._sources = ArraySet$2.fromArray(sources, true);

    this._absoluteSources = this._sources.toArray().map(function (s) {
      return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
    });

    this.sourceRoot = sourceRoot;
    this.sourcesContent = sourcesContent;
    this._mappings = mappings;
    this._sourceMapURL = aSourceMapURL;
    this.file = file;
  }

  BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
  BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;

  /**
   * Utility function to find the index of a source.  Returns -1 if not
   * found.
   */
  BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {
    var relativeSource = aSource;
    if (this.sourceRoot != null) {
      relativeSource = util.relative(this.sourceRoot, relativeSource);
    }

    if (this._sources.has(relativeSource)) {
      return this._sources.indexOf(relativeSource);
    }

    // Maybe aSource is an absolute URL as returned by |sources|.  In
    // this case we can't simply undo the transform.
    var i;
    for (i = 0; i < this._absoluteSources.length; ++i) {
      if (this._absoluteSources[i] == aSource) {
        return i;
      }
    }

    return -1;
  };

  /**
   * Create a BasicSourceMapConsumer from a SourceMapGenerator.
   *
   * @param SourceMapGenerator aSourceMap
   *        The source map that will be consumed.
   * @param String aSourceMapURL
   *        The URL at which the source map can be found (optional)
   * @returns BasicSourceMapConsumer
   */
  BasicSourceMapConsumer.fromSourceMap =
    function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
      var smc = Object.create(BasicSourceMapConsumer.prototype);

      var names = smc._names = ArraySet$2.fromArray(aSourceMap._names.toArray(), true);
      var sources = smc._sources = ArraySet$2.fromArray(aSourceMap._sources.toArray(), true);
      smc.sourceRoot = aSourceMap._sourceRoot;
      smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
                                                              smc.sourceRoot);
      smc.file = aSourceMap._file;
      smc._sourceMapURL = aSourceMapURL;
      smc._absoluteSources = smc._sources.toArray().map(function (s) {
        return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);
      });

      // Because we are modifying the entries (by converting string sources and
      // names to indices into the sources and names ArraySets), we have to make
      // a copy of the entry or else bad things happen. Shared mutable state
      // strikes again! See github issue #191.

      var generatedMappings = aSourceMap._mappings.toArray().slice();
      var destGeneratedMappings = smc.__generatedMappings = [];
      var destOriginalMappings = smc.__originalMappings = [];

      for (var i = 0, length = generatedMappings.length; i < length; i++) {
        var srcMapping = generatedMappings[i];
        var destMapping = new Mapping;
        destMapping.generatedLine = srcMapping.generatedLine;
        destMapping.generatedColumn = srcMapping.generatedColumn;

        if (srcMapping.source) {
          destMapping.source = sources.indexOf(srcMapping.source);
          destMapping.originalLine = srcMapping.originalLine;
          destMapping.originalColumn = srcMapping.originalColumn;

          if (srcMapping.name) {
            destMapping.name = names.indexOf(srcMapping.name);
          }

          destOriginalMappings.push(destMapping);
        }

        destGeneratedMappings.push(destMapping);
      }

      quickSort$1(smc.__originalMappings, util.compareByOriginalPositions);

      return smc;
    };

  /**
   * The version of the source mapping spec that we are consuming.
   */
  BasicSourceMapConsumer.prototype._version = 3;

  /**
   * The list of original sources.
   */
  Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
    get: function () {
      return this._absoluteSources.slice();
    }
  });

  /**
   * Provide the JIT with a nice shape / hidden class.
   */
  function Mapping() {
    this.generatedLine = 0;
    this.generatedColumn = 0;
    this.source = null;
    this.originalLine = null;
    this.originalColumn = null;
    this.name = null;
  }

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (the ordered arrays in the `this.__generatedMappings` and
   * `this.__originalMappings` properties).
   */
  BasicSourceMapConsumer.prototype._parseMappings =
    function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
      var generatedLine = 1;
      var previousGeneratedColumn = 0;
      var previousOriginalLine = 0;
      var previousOriginalColumn = 0;
      var previousSource = 0;
      var previousName = 0;
      var length = aStr.length;
      var index = 0;
      var cachedSegments = {};
      var temp = {};
      var originalMappings = [];
      var generatedMappings = [];
      var mapping, str, segment, end, value;

      while (index < length) {
        if (aStr.charAt(index) === ';') {
          generatedLine++;
          index++;
          previousGeneratedColumn = 0;
        }
        else if (aStr.charAt(index) === ',') {
          index++;
        }
        else {
          mapping = new Mapping();
          mapping.generatedLine = generatedLine;

          // Because each offset is encoded relative to the previous one,
          // many segments often have the same encoding. We can exploit this
          // fact by caching the parsed variable length fields of each segment,
          // allowing us to avoid a second parse if we encounter the same
          // segment again.
          for (end = index; end < length; end++) {
            if (this._charIsMappingSeparator(aStr, end)) {
              break;
            }
          }
          str = aStr.slice(index, end);

          segment = cachedSegments[str];
          if (segment) {
            index += str.length;
          } else {
            segment = [];
            while (index < end) {
              base64Vlq.decode(aStr, index, temp);
              value = temp.value;
              index = temp.rest;
              segment.push(value);
            }

            if (segment.length === 2) {
              throw new Error('Found a source, but no line and column');
            }

            if (segment.length === 3) {
              throw new Error('Found a source and line, but no column');
            }

            cachedSegments[str] = segment;
          }

          // Generated column.
          mapping.generatedColumn = previousGeneratedColumn + segment[0];
          previousGeneratedColumn = mapping.generatedColumn;

          if (segment.length > 1) {
            // Original source.
            mapping.source = previousSource + segment[1];
            previousSource += segment[1];

            // Original line.
            mapping.originalLine = previousOriginalLine + segment[2];
            previousOriginalLine = mapping.originalLine;
            // Lines are stored 0-based
            mapping.originalLine += 1;

            // Original column.
            mapping.originalColumn = previousOriginalColumn + segment[3];
            previousOriginalColumn = mapping.originalColumn;

            if (segment.length > 4) {
              // Original name.
              mapping.name = previousName + segment[4];
              previousName += segment[4];
            }
          }

          generatedMappings.push(mapping);
          if (typeof mapping.originalLine === 'number') {
            originalMappings.push(mapping);
          }
        }
      }

      quickSort$1(generatedMappings, util.compareByGeneratedPositionsDeflated);
      this.__generatedMappings = generatedMappings;

      quickSort$1(originalMappings, util.compareByOriginalPositions);
      this.__originalMappings = originalMappings;
    };

  /**
   * Find the mapping that best matches the hypothetical "needle" mapping that
   * we are searching for in the given "haystack" of mappings.
   */
  BasicSourceMapConsumer.prototype._findMapping =
    function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
                                           aColumnName, aComparator, aBias) {
      // To return the position we are searching for, we must first find the
      // mapping for the given position and then return the opposite position it
      // points to. Because the mappings are sorted, we can use binary search to
      // find the best mapping.

      if (aNeedle[aLineName] <= 0) {
        throw new TypeError('Line must be greater than or equal to 1, got '
                            + aNeedle[aLineName]);
      }
      if (aNeedle[aColumnName] < 0) {
        throw new TypeError('Column must be greater than or equal to 0, got '
                            + aNeedle[aColumnName]);
      }

      return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
    };

  /**
   * Compute the last column for each generated mapping. The last column is
   * inclusive.
   */
  BasicSourceMapConsumer.prototype.computeColumnSpans =
    function SourceMapConsumer_computeColumnSpans() {
      for (var index = 0; index < this._generatedMappings.length; ++index) {
        var mapping = this._generatedMappings[index];

        // Mappings do not contain a field for the last generated columnt. We
        // can come up with an optimistic estimate, however, by assuming that
        // mappings are contiguous (i.e. given two consecutive mappings, the
        // first mapping ends where the second one starts).
        if (index + 1 < this._generatedMappings.length) {
          var nextMapping = this._generatedMappings[index + 1];

          if (mapping.generatedLine === nextMapping.generatedLine) {
            mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
            continue;
          }
        }

        // The last mapping for each line spans the entire line.
        mapping.lastGeneratedColumn = Infinity;
      }
    };

  /**
   * Returns the original source, line, and column information for the generated
   * source's line and column positions provided. The only argument is an object
   * with the following properties:
   *
   *   - line: The line number in the generated source.  The line number
   *     is 1-based.
   *   - column: The column number in the generated source.  The column
   *     number is 0-based.
   *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
   *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
   *     closest element that is smaller than or greater than the one we are
   *     searching for, respectively, if the exact element cannot be found.
   *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
   *
   * and an object is returned with the following properties:
   *
   *   - source: The original source file, or null.
   *   - line: The line number in the original source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the original source, or null.  The
   *     column number is 0-based.
   *   - name: The original identifier, or null.
   */
  BasicSourceMapConsumer.prototype.originalPositionFor =
    function SourceMapConsumer_originalPositionFor(aArgs) {
      var needle = {
        generatedLine: util.getArg(aArgs, 'line'),
        generatedColumn: util.getArg(aArgs, 'column')
      };

      var index = this._findMapping(
        needle,
        this._generatedMappings,
        "generatedLine",
        "generatedColumn",
        util.compareByGeneratedPositionsDeflated,
        util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
      );

      if (index >= 0) {
        var mapping = this._generatedMappings[index];

        if (mapping.generatedLine === needle.generatedLine) {
          var source = util.getArg(mapping, 'source', null);
          if (source !== null) {
            source = this._sources.at(source);
            source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
          }
          var name = util.getArg(mapping, 'name', null);
          if (name !== null) {
            name = this._names.at(name);
          }
          return {
            source: source,
            line: util.getArg(mapping, 'originalLine', null),
            column: util.getArg(mapping, 'originalColumn', null),
            name: name
          };
        }
      }

      return {
        source: null,
        line: null,
        column: null,
        name: null
      };
    };

  /**
   * Return true if we have the source content for every source in the source
   * map, false otherwise.
   */
  BasicSourceMapConsumer.prototype.hasContentsOfAllSources =
    function BasicSourceMapConsumer_hasContentsOfAllSources() {
      if (!this.sourcesContent) {
        return false;
      }
      return this.sourcesContent.length >= this._sources.size() &&
        !this.sourcesContent.some(function (sc) { return sc == null; });
    };

  /**
   * Returns the original source content. The only argument is the url of the
   * original source file. Returns null if no original source content is
   * available.
   */
  BasicSourceMapConsumer.prototype.sourceContentFor =
    function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
      if (!this.sourcesContent) {
        return null;
      }

      var index = this._findSourceIndex(aSource);
      if (index >= 0) {
        return this.sourcesContent[index];
      }

      var relativeSource = aSource;
      if (this.sourceRoot != null) {
        relativeSource = util.relative(this.sourceRoot, relativeSource);
      }

      var url;
      if (this.sourceRoot != null
          && (url = util.urlParse(this.sourceRoot))) {
        // XXX: file:// URIs and absolute paths lead to unexpected behavior for
        // many users. We can help them out when they expect file:// URIs to
        // behave like it would if they were running a local HTTP server. See
        // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
        var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
        if (url.scheme == "file"
            && this._sources.has(fileUriAbsPath)) {
          return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
        }

        if ((!url.path || url.path == "/")
            && this._sources.has("/" + relativeSource)) {
          return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
        }
      }

      // This function is used recursively from
      // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
      // don't want to throw if we can't find the source - we just want to
      // return null, so we provide a flag to exit gracefully.
      if (nullOnMissing) {
        return null;
      }
      else {
        throw new Error('"' + relativeSource + '" is not in the SourceMap.');
      }
    };

  /**
   * Returns the generated line and column information for the original source,
   * line, and column positions provided. The only argument is an object with
   * the following properties:
   *
   *   - source: The filename of the original source.
   *   - line: The line number in the original source.  The line number
   *     is 1-based.
   *   - column: The column number in the original source.  The column
   *     number is 0-based.
   *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
   *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
   *     closest element that is smaller than or greater than the one we are
   *     searching for, respectively, if the exact element cannot be found.
   *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
   *
   * and an object is returned with the following properties:
   *
   *   - line: The line number in the generated source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the generated source, or null.
   *     The column number is 0-based.
   */
  BasicSourceMapConsumer.prototype.generatedPositionFor =
    function SourceMapConsumer_generatedPositionFor(aArgs) {
      var source = util.getArg(aArgs, 'source');
      source = this._findSourceIndex(source);
      if (source < 0) {
        return {
          line: null,
          column: null,
          lastColumn: null
        };
      }

      var needle = {
        source: source,
        originalLine: util.getArg(aArgs, 'line'),
        originalColumn: util.getArg(aArgs, 'column')
      };

      var index = this._findMapping(
        needle,
        this._originalMappings,
        "originalLine",
        "originalColumn",
        util.compareByOriginalPositions,
        util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
      );

      if (index >= 0) {
        var mapping = this._originalMappings[index];

        if (mapping.source === needle.source) {
          return {
            line: util.getArg(mapping, 'generatedLine', null),
            column: util.getArg(mapping, 'generatedColumn', null),
            lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
          };
        }
      }

      return {
        line: null,
        column: null,
        lastColumn: null
      };
    };

  var BasicSourceMapConsumer_1 = BasicSourceMapConsumer;

  /**
   * An IndexedSourceMapConsumer instance represents a parsed source map which
   * we can query for information. It differs from BasicSourceMapConsumer in
   * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
   * input.
   *
   * The first parameter is a raw source map (either as a JSON string, or already
   * parsed to an object). According to the spec for indexed source maps, they
   * have the following attributes:
   *
   *   - version: Which version of the source map spec this map is following.
   *   - file: Optional. The generated file this source map is associated with.
   *   - sections: A list of section definitions.
   *
   * Each value under the "sections" field has two fields:
   *   - offset: The offset into the original specified at which this section
   *       begins to apply, defined as an object with a "line" and "column"
   *       field.
   *   - map: A source map definition. This source map could also be indexed,
   *       but doesn't have to be.
   *
   * Instead of the "map" field, it's also possible to have a "url" field
   * specifying a URL to retrieve a source map from, but that's currently
   * unsupported.
   *
   * Here's an example source map, taken from the source map spec[0], but
   * modified to omit a section which uses the "url" field.
   *
   *  {
   *    version : 3,
   *    file: "app.js",
   *    sections: [{
   *      offset: {line:100, column:10},
   *      map: {
   *        version : 3,
   *        file: "section.js",
   *        sources: ["foo.js", "bar.js"],
   *        names: ["src", "maps", "are", "fun"],
   *        mappings: "AAAA,E;;ABCDE;"
   *      }
   *    }],
   *  }
   *
   * The second parameter, if given, is a string whose value is the URL
   * at which the source map was found.  This URL is used to compute the
   * sources array.
   *
   * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
   */
  function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
    var sourceMap = aSourceMap;
    if (typeof aSourceMap === 'string') {
      sourceMap = util.parseSourceMapInput(aSourceMap);
    }

    var version = util.getArg(sourceMap, 'version');
    var sections = util.getArg(sourceMap, 'sections');

    if (version != this._version) {
      throw new Error('Unsupported version: ' + version);
    }

    this._sources = new ArraySet$2();
    this._names = new ArraySet$2();

    var lastOffset = {
      line: -1,
      column: 0
    };
    this._sections = sections.map(function (s) {
      if (s.url) {
        // The url field will require support for asynchronicity.
        // See https://github.com/mozilla/source-map/issues/16
        throw new Error('Support for url field in sections not implemented.');
      }
      var offset = util.getArg(s, 'offset');
      var offsetLine = util.getArg(offset, 'line');
      var offsetColumn = util.getArg(offset, 'column');

      if (offsetLine < lastOffset.line ||
          (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
        throw new Error('Section offsets must be ordered and non-overlapping.');
      }
      lastOffset = offset;

      return {
        generatedOffset: {
          // The offset fields are 0-based, but we use 1-based indices when
          // encoding/decoding from VLQ.
          generatedLine: offsetLine + 1,
          generatedColumn: offsetColumn + 1
        },
        consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
      }
    });
  }

  IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
  IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;

  /**
   * The version of the source mapping spec that we are consuming.
   */
  IndexedSourceMapConsumer.prototype._version = 3;

  /**
   * The list of original sources.
   */
  Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
    get: function () {
      var sources = [];
      for (var i = 0; i < this._sections.length; i++) {
        for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
          sources.push(this._sections[i].consumer.sources[j]);
        }
      }
      return sources;
    }
  });

  /**
   * Returns the original source, line, and column information for the generated
   * source's line and column positions provided. The only argument is an object
   * with the following properties:
   *
   *   - line: The line number in the generated source.  The line number
   *     is 1-based.
   *   - column: The column number in the generated source.  The column
   *     number is 0-based.
   *
   * and an object is returned with the following properties:
   *
   *   - source: The original source file, or null.
   *   - line: The line number in the original source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the original source, or null.  The
   *     column number is 0-based.
   *   - name: The original identifier, or null.
   */
  IndexedSourceMapConsumer.prototype.originalPositionFor =
    function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
      var needle = {
        generatedLine: util.getArg(aArgs, 'line'),
        generatedColumn: util.getArg(aArgs, 'column')
      };

      // Find the section containing the generated position we're trying to map
      // to an original position.
      var sectionIndex = binarySearch.search(needle, this._sections,
        function(needle, section) {
          var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
          if (cmp) {
            return cmp;
          }

          return (needle.generatedColumn -
                  section.generatedOffset.generatedColumn);
        });
      var section = this._sections[sectionIndex];

      if (!section) {
        return {
          source: null,
          line: null,
          column: null,
          name: null
        };
      }

      return section.consumer.originalPositionFor({
        line: needle.generatedLine -
          (section.generatedOffset.generatedLine - 1),
        column: needle.generatedColumn -
          (section.generatedOffset.generatedLine === needle.generatedLine
           ? section.generatedOffset.generatedColumn - 1
           : 0),
        bias: aArgs.bias
      });
    };

  /**
   * Return true if we have the source content for every source in the source
   * map, false otherwise.
   */
  IndexedSourceMapConsumer.prototype.hasContentsOfAllSources =
    function IndexedSourceMapConsumer_hasContentsOfAllSources() {
      return this._sections.every(function (s) {
        return s.consumer.hasContentsOfAllSources();
      });
    };

  /**
   * Returns the original source content. The only argument is the url of the
   * original source file. Returns null if no original source content is
   * available.
   */
  IndexedSourceMapConsumer.prototype.sourceContentFor =
    function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
      for (var i = 0; i < this._sections.length; i++) {
        var section = this._sections[i];

        var content = section.consumer.sourceContentFor(aSource, true);
        if (content) {
          return content;
        }
      }
      if (nullOnMissing) {
        return null;
      }
      else {
        throw new Error('"' + aSource + '" is not in the SourceMap.');
      }
    };

  /**
   * Returns the generated line and column information for the original source,
   * line, and column positions provided. The only argument is an object with
   * the following properties:
   *
   *   - source: The filename of the original source.
   *   - line: The line number in the original source.  The line number
   *     is 1-based.
   *   - column: The column number in the original source.  The column
   *     number is 0-based.
   *
   * and an object is returned with the following properties:
   *
   *   - line: The line number in the generated source, or null.  The
   *     line number is 1-based. 
   *   - column: The column number in the generated source, or null.
   *     The column number is 0-based.
   */
  IndexedSourceMapConsumer.prototype.generatedPositionFor =
    function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
      for (var i = 0; i < this._sections.length; i++) {
        var section = this._sections[i];

        // Only consider this section if the requested source is in the list of
        // sources of the consumer.
        if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) {
          continue;
        }
        var generatedPosition = section.consumer.generatedPositionFor(aArgs);
        if (generatedPosition) {
          var ret = {
            line: generatedPosition.line +
              (section.generatedOffset.generatedLine - 1),
            column: generatedPosition.column +
              (section.generatedOffset.generatedLine === generatedPosition.line
               ? section.generatedOffset.generatedColumn - 1
               : 0)
          };
          return ret;
        }
      }

      return {
        line: null,
        column: null
      };
    };

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (the ordered arrays in the `this.__generatedMappings` and
   * `this.__originalMappings` properties).
   */
  IndexedSourceMapConsumer.prototype._parseMappings =
    function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
      this.__generatedMappings = [];
      this.__originalMappings = [];
      for (var i = 0; i < this._sections.length; i++) {
        var section = this._sections[i];
        var sectionMappings = section.consumer._generatedMappings;
        for (var j = 0; j < sectionMappings.length; j++) {
          var mapping = sectionMappings[j];

          var source = section.consumer._sources.at(mapping.source);
          source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
          this._sources.add(source);
          source = this._sources.indexOf(source);

          var name = null;
          if (mapping.name) {
            name = section.consumer._names.at(mapping.name);
            this._names.add(name);
            name = this._names.indexOf(name);
          }

          // The mappings coming from the consumer for the section have
          // generated positions relative to the start of the section, so we
          // need to offset them to be relative to the start of the concatenated
          // generated file.
          var adjustedMapping = {
            source: source,
            generatedLine: mapping.generatedLine +
              (section.generatedOffset.generatedLine - 1),
            generatedColumn: mapping.generatedColumn +
              (section.generatedOffset.generatedLine === mapping.generatedLine
              ? section.generatedOffset.generatedColumn - 1
              : 0),
            originalLine: mapping.originalLine,
            originalColumn: mapping.originalColumn,
            name: name
          };

          this.__generatedMappings.push(adjustedMapping);
          if (typeof adjustedMapping.originalLine === 'number') {
            this.__originalMappings.push(adjustedMapping);
          }
        }
      }

      quickSort$1(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
      quickSort$1(this.__originalMappings, util.compareByOriginalPositions);
    };

  var IndexedSourceMapConsumer_1 = IndexedSourceMapConsumer;

  var sourceMapConsumer = {
  	SourceMapConsumer: SourceMapConsumer_1,
  	BasicSourceMapConsumer: BasicSourceMapConsumer_1,
  	IndexedSourceMapConsumer: IndexedSourceMapConsumer_1
  };

  /* -*- Mode: js; js-indent-level: 2; -*- */
  /*
   * Copyright 2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE or:
   * http://opensource.org/licenses/BSD-3-Clause
   */

  var SourceMapGenerator$1 = sourceMapGenerator.SourceMapGenerator;


  // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
  // operating systems these days (capturing the result).
  var REGEX_NEWLINE = /(\r?\n)/;

  // Newline character code for charCodeAt() comparisons
  var NEWLINE_CODE = 10;

  // Private symbol for identifying `SourceNode`s when multiple versions of
  // the source-map library are loaded. This MUST NOT CHANGE across
  // versions!
  var isSourceNode = "$$$isSourceNode$$$";

  /**
   * SourceNodes provide a way to abstract over interpolating/concatenating
   * snippets of generated JavaScript source code while maintaining the line and
   * column information associated with the original source code.
   *
   * @param aLine The original line number.
   * @param aColumn The original column number.
   * @param aSource The original source's filename.
   * @param aChunks Optional. An array of strings which are snippets of
   *        generated JS, or other SourceNodes.
   * @param aName The original identifier.
   */
  function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
    this.children = [];
    this.sourceContents = {};
    this.line = aLine == null ? null : aLine;
    this.column = aColumn == null ? null : aColumn;
    this.source = aSource == null ? null : aSource;
    this.name = aName == null ? null : aName;
    this[isSourceNode] = true;
    if (aChunks != null) this.add(aChunks);
  }

  /**
   * Creates a SourceNode from generated code and a SourceMapConsumer.
   *
   * @param aGeneratedCode The generated code
   * @param aSourceMapConsumer The SourceMap for the generated code
   * @param aRelativePath Optional. The path that relative sources in the
   *        SourceMapConsumer should be relative to.
   */
  SourceNode.fromStringWithSourceMap =
    function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
      // The SourceNode we want to fill with the generated code
      // and the SourceMap
      var node = new SourceNode();

      // All even indices of this array are one line of the generated code,
      // while all odd indices are the newlines between two adjacent lines
      // (since `REGEX_NEWLINE` captures its match).
      // Processed fragments are accessed by calling `shiftNextLine`.
      var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
      var remainingLinesIndex = 0;
      var shiftNextLine = function() {
        var lineContents = getNextLine();
        // The last line of a file might not have a newline.
        var newLine = getNextLine() || "";
        return lineContents + newLine;

        function getNextLine() {
          return remainingLinesIndex < remainingLines.length ?
              remainingLines[remainingLinesIndex++] : undefined;
        }
      };

      // We need to remember the position of "remainingLines"
      var lastGeneratedLine = 1, lastGeneratedColumn = 0;

      // The generate SourceNodes we need a code range.
      // To extract it current and last mapping is used.
      // Here we store the last mapping.
      var lastMapping = null;

      aSourceMapConsumer.eachMapping(function (mapping) {
        if (lastMapping !== null) {
          // We add the code from "lastMapping" to "mapping":
          // First check if there is a new line in between.
          if (lastGeneratedLine < mapping.generatedLine) {
            // Associate first line with "lastMapping"
            addMappingWithCode(lastMapping, shiftNextLine());
            lastGeneratedLine++;
            lastGeneratedColumn = 0;
            // The remaining code is added without mapping
          } else {
            // There is no new line in between.
            // Associate the code between "lastGeneratedColumn" and
            // "mapping.generatedColumn" with "lastMapping"
            var nextLine = remainingLines[remainingLinesIndex] || '';
            var code = nextLine.substr(0, mapping.generatedColumn -
                                          lastGeneratedColumn);
            remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
                                                lastGeneratedColumn);
            lastGeneratedColumn = mapping.generatedColumn;
            addMappingWithCode(lastMapping, code);
            // No more remaining code, continue
            lastMapping = mapping;
            return;
          }
        }
        // We add the generated code until the first mapping
        // to the SourceNode without any mapping.
        // Each line is added as separate string.
        while (lastGeneratedLine < mapping.generatedLine) {
          node.add(shiftNextLine());
          lastGeneratedLine++;
        }
        if (lastGeneratedColumn < mapping.generatedColumn) {
          var nextLine = remainingLines[remainingLinesIndex] || '';
          node.add(nextLine.substr(0, mapping.generatedColumn));
          remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
          lastGeneratedColumn = mapping.generatedColumn;
        }
        lastMapping = mapping;
      }, this);
      // We have processed all mappings.
      if (remainingLinesIndex < remainingLines.length) {
        if (lastMapping) {
          // Associate the remaining code in the current line with "lastMapping"
          addMappingWithCode(lastMapping, shiftNextLine());
        }
        // and add the remaining lines without any mapping
        node.add(remainingLines.splice(remainingLinesIndex).join(""));
      }

      // Copy sourcesContent into SourceNode
      aSourceMapConsumer.sources.forEach(function (sourceFile) {
        var content = aSourceMapConsumer.sourceContentFor(sourceFile);
        if (content != null) {
          if (aRelativePath != null) {
            sourceFile = util.join(aRelativePath, sourceFile);
          }
          node.setSourceContent(sourceFile, content);
        }
      });

      return node;

      function addMappingWithCode(mapping, code) {
        if (mapping === null || mapping.source === undefined) {
          node.add(code);
        } else {
          var source = aRelativePath
            ? util.join(aRelativePath, mapping.source)
            : mapping.source;
          node.add(new SourceNode(mapping.originalLine,
                                  mapping.originalColumn,
                                  source,
                                  code,
                                  mapping.name));
        }
      }
    };

  /**
   * Add a chunk of generated JS to this source node.
   *
   * @param aChunk A string snippet of generated JS code, another instance of
   *        SourceNode, or an array where each member is one of those things.
   */
  SourceNode.prototype.add = function SourceNode_add(aChunk) {
    if (Array.isArray(aChunk)) {
      aChunk.forEach(function (chunk) {
        this.add(chunk);
      }, this);
    }
    else if (aChunk[isSourceNode] || typeof aChunk === "string") {
      if (aChunk) {
        this.children.push(aChunk);
      }
    }
    else {
      throw new TypeError(
        "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
      );
    }
    return this;
  };

  /**
   * Add a chunk of generated JS to the beginning of this source node.
   *
   * @param aChunk A string snippet of generated JS code, another instance of
   *        SourceNode, or an array where each member is one of those things.
   */
  SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
    if (Array.isArray(aChunk)) {
      for (var i = aChunk.length-1; i >= 0; i--) {
        this.prepend(aChunk[i]);
      }
    }
    else if (aChunk[isSourceNode] || typeof aChunk === "string") {
      this.children.unshift(aChunk);
    }
    else {
      throw new TypeError(
        "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
      );
    }
    return this;
  };

  /**
   * Walk over the tree of JS snippets in this node and its children. The
   * walking function is called once for each snippet of JS and is passed that
   * snippet and the its original associated source's line/column location.
   *
   * @param aFn The traversal function.
   */
  SourceNode.prototype.walk = function SourceNode_walk(aFn) {
    var chunk;
    for (var i = 0, len = this.children.length; i < len; i++) {
      chunk = this.children[i];
      if (chunk[isSourceNode]) {
        chunk.walk(aFn);
      }
      else {
        if (chunk !== '') {
          aFn(chunk, { source: this.source,
                       line: this.line,
                       column: this.column,
                       name: this.name });
        }
      }
    }
  };

  /**
   * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
   * each of `this.children`.
   *
   * @param aSep The separator.
   */
  SourceNode.prototype.join = function SourceNode_join(aSep) {
    var newChildren;
    var i;
    var len = this.children.length;
    if (len > 0) {
      newChildren = [];
      for (i = 0; i < len-1; i++) {
        newChildren.push(this.children[i]);
        newChildren.push(aSep);
      }
      newChildren.push(this.children[i]);
      this.children = newChildren;
    }
    return this;
  };

  /**
   * Call String.prototype.replace on the very right-most source snippet. Useful
   * for trimming whitespace from the end of a source node, etc.
   *
   * @param aPattern The pattern to replace.
   * @param aReplacement The thing to replace the pattern with.
   */
  SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
    var lastChild = this.children[this.children.length - 1];
    if (lastChild[isSourceNode]) {
      lastChild.replaceRight(aPattern, aReplacement);
    }
    else if (typeof lastChild === 'string') {
      this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
    }
    else {
      this.children.push(''.replace(aPattern, aReplacement));
    }
    return this;
  };

  /**
   * Set the source content for a source file. This will be added to the SourceMapGenerator
   * in the sourcesContent field.
   *
   * @param aSourceFile The filename of the source file
   * @param aSourceContent The content of the source file
   */
  SourceNode.prototype.setSourceContent =
    function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
      this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
    };

  /**
   * Walk over the tree of SourceNodes. The walking function is called for each
   * source file content and is passed the filename and source content.
   *
   * @param aFn The traversal function.
   */
  SourceNode.prototype.walkSourceContents =
    function SourceNode_walkSourceContents(aFn) {
      for (var i = 0, len = this.children.length; i < len; i++) {
        if (this.children[i][isSourceNode]) {
          this.children[i].walkSourceContents(aFn);
        }
      }

      var sources = Object.keys(this.sourceContents);
      for (var i = 0, len = sources.length; i < len; i++) {
        aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
      }
    };

  /**
   * Return the string representation of this source node. Walks over the tree
   * and concatenates all the various snippets together to one string.
   */
  SourceNode.prototype.toString = function SourceNode_toString() {
    var str = "";
    this.walk(function (chunk) {
      str += chunk;
    });
    return str;
  };

  /**
   * Returns the string representation of this source node along with a source
   * map.
   */
  SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
    var generated = {
      code: "",
      line: 1,
      column: 0
    };
    var map = new SourceMapGenerator$1(aArgs);
    var sourceMappingActive = false;
    var lastOriginalSource = null;
    var lastOriginalLine = null;
    var lastOriginalColumn = null;
    var lastOriginalName = null;
    this.walk(function (chunk, original) {
      generated.code += chunk;
      if (original.source !== null
          && original.line !== null
          && original.column !== null) {
        if(lastOriginalSource !== original.source
           || lastOriginalLine !== original.line
           || lastOriginalColumn !== original.column
           || lastOriginalName !== original.name) {
          map.addMapping({
            source: original.source,
            original: {
              line: original.line,
              column: original.column
            },
            generated: {
              line: generated.line,
              column: generated.column
            },
            name: original.name
          });
        }
        lastOriginalSource = original.source;
        lastOriginalLine = original.line;
        lastOriginalColumn = original.column;
        lastOriginalName = original.name;
        sourceMappingActive = true;
      } else if (sourceMappingActive) {
        map.addMapping({
          generated: {
            line: generated.line,
            column: generated.column
          }
        });
        lastOriginalSource = null;
        sourceMappingActive = false;
      }
      for (var idx = 0, length = chunk.length; idx < length; idx++) {
        if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
          generated.line++;
          generated.column = 0;
          // Mappings end at eol
          if (idx + 1 === length) {
            lastOriginalSource = null;
            sourceMappingActive = false;
          } else if (sourceMappingActive) {
            map.addMapping({
              source: original.source,
              original: {
                line: original.line,
                column: original.column
              },
              generated: {
                line: generated.line,
                column: generated.column
              },
              name: original.name
            });
          }
        } else {
          generated.column++;
        }
      }
    });
    this.walkSourceContents(function (sourceFile, sourceContent) {
      map.setSourceContent(sourceFile, sourceContent);
    });

    return { code: generated.code, map: map };
  };

  var SourceNode_1 = SourceNode;

  var sourceNode = {
  	SourceNode: SourceNode_1
  };

  /*
   * Copyright 2009-2011 Mozilla Foundation and contributors
   * Licensed under the New BSD license. See LICENSE.txt or:
   * http://opensource.org/licenses/BSD-3-Clause
   */
  var SourceMapGenerator$2 = sourceMapGenerator.SourceMapGenerator;
  var SourceMapConsumer$1 = sourceMapConsumer.SourceMapConsumer;
  var SourceNode$1 = sourceNode.SourceNode;

  var sourceMap = {
  	SourceMapGenerator: SourceMapGenerator$2,
  	SourceMapConsumer: SourceMapConsumer$1,
  	SourceNode: SourceNode$1
  };

  const PURE_ANNOTATION = `/*#__PURE__*/`;
  function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
      const context = {
          mode,
          prefixIdentifiers,
          sourceMap,
          filename,
          scopeId,
          optimizeImports,
          runtimeGlobalName,
          runtimeModuleName,
          ssr,
          source: ast.loc.source,
          code: ``,
          column: 1,
          line: 1,
          offset: 0,
          indentLevel: 0,
          pure: false,
          map: undefined,
          helper(key) {
              return `_${helperNameMap[key]}`;
          },
          push(code, node) {
              context.code += code;
              if ( context.map) {
                  if (node) {
                      let name;
                      if (node.type === 4 /* SIMPLE_EXPRESSION */ && !node.isStatic) {
                          const content = node.content.replace(/^_ctx\./, '');
                          if (content !== node.content && isSimpleIdentifier(content)) {
                              name = content;
                          }
                      }
                      addMapping(node.loc.start, name);
                  }
                  advancePositionWithMutation(context, code);
                  if (node && node.loc !== locStub) {
                      addMapping(node.loc.end);
                  }
              }
          },
          indent() {
              newline(++context.indentLevel);
          },
          deindent(withoutNewLine = false) {
              if (withoutNewLine) {
                  --context.indentLevel;
              }
              else {
                  newline(--context.indentLevel);
              }
          },
          newline() {
              newline(context.indentLevel);
          }
      };
      function newline(n) {
          context.push('\n' + `  `.repeat(n));
      }
      function addMapping(loc, name) {
          context.map.addMapping({
              name,
              source: context.filename,
              original: {
                  line: loc.line,
                  column: loc.column - 1 // source-map column is 0 based
              },
              generated: {
                  line: context.line,
                  column: context.column - 1
              }
          });
      }
      if ( sourceMap) {
          // lazy require source-map implementation, only in non-browser builds
          context.map = new SourceMapGenerator$2();
          context.map.setSourceContent(filename, context.source);
      }
      return context;
  }
  function generate(ast, options = {}) {
      const context = createCodegenContext(ast, options);
      if (options.onContextCreated)
          options.onContextCreated(context);
      const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
      const hasHelpers = ast.helpers.length > 0;
      const useWithBlock = !prefixIdentifiers && mode !== 'module';
      const genScopeId =  scopeId != null && mode === 'module';
      // preambles
      if ( mode === 'module') {
          genModulePreamble(ast, context, genScopeId);
      }
      else {
          genFunctionPreamble(ast, context);
      }
      // binding optimizations
      const optimizeSources = options.bindingMetadata
          ? `, $props, $setup, $data, $options`
          : ``;
      // enter render function
      if (!ssr) {
          if (genScopeId) {
              push(`const render = ${PURE_ANNOTATION}_withId(`);
          }
          push(`function render(_ctx, _cache${optimizeSources}) {`);
      }
      else {
          if (genScopeId) {
              push(`const ssrRender = ${PURE_ANNOTATION}_withId(`);
          }
          push(`function ssrRender(_ctx, _push, _parent, _attrs${optimizeSources}) {`);
      }
      indent();
      if (useWithBlock) {
          push(`with (_ctx) {`);
          indent();
          // function mode const declarations should be inside with block
          // also they should be renamed to avoid collision with user properties
          if (hasHelpers) {
              push(`const { ${ast.helpers
                .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
                .join(', ')} } = _Vue`);
              push(`\n`);
              newline();
          }
      }
      // generate asset resolution statements
      if (ast.components.length) {
          genAssets(ast.components, 'component', context);
          if (ast.directives.length || ast.temps > 0) {
              newline();
          }
      }
      if (ast.directives.length) {
          genAssets(ast.directives, 'directive', context);
          if (ast.temps > 0) {
              newline();
          }
      }
      if (ast.temps > 0) {
          push(`let `);
          for (let i = 0; i < ast.temps; i++) {
              push(`${i > 0 ? `, ` : ``}_temp${i}`);
          }
      }
      if (ast.components.length || ast.directives.length || ast.temps) {
          push(`\n`);
          newline();
      }
      // generate the VNode tree expression
      if (!ssr) {
          push(`return `);
      }
      if (ast.codegenNode) {
          genNode(ast.codegenNode, context);
      }
      else {
          push(`null`);
      }
      if (useWithBlock) {
          deindent();
          push(`}`);
      }
      deindent();
      push(`}`);
      if (genScopeId) {
          push(`)`);
      }
      return {
          ast,
          code: context.code,
          // SourceMapGenerator does have toJSON() method but it's not in the types
          map: context.map ? context.map.toJSON() : undefined
      };
  }
  function genFunctionPreamble(ast, context) {
      const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;
      const VueBinding =  ssr
          ? `require(${JSON.stringify(runtimeModuleName)})`
          : runtimeGlobalName;
      const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
      // Generate const declaration for helpers
      // In prefix mode, we place the const declaration at top so it's done
      // only once; But if we not prefixing, we place the declaration inside the
      // with block so it doesn't incur the `in` check cost for every helper access.
      if (ast.helpers.length > 0) {
          if ( prefixIdentifiers) {
              push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`);
          }
          else {
              // "with" mode.
              // save Vue in a separate variable to avoid collision
              push(`const _Vue = ${VueBinding}\n`);
              // in "with" mode, helpers are declared inside the with block to avoid
              // has check cost, but hoists are lifted out of the function - we need
              // to provide the helper here.
              if (ast.hoists.length) {
                  const staticHelpers = [
                      CREATE_VNODE,
                      CREATE_COMMENT,
                      CREATE_TEXT,
                      CREATE_STATIC
                  ]
                      .filter(helper => ast.helpers.includes(helper))
                      .map(aliasHelper)
                      .join(', ');
                  push(`const { ${staticHelpers} } = _Vue\n`);
              }
          }
      }
      // generate variables for ssr helpers
      if ( ast.ssrHelpers && ast.ssrHelpers.length) {
          // ssr guarantees prefixIdentifier: true
          push(`const { ${ast.ssrHelpers
            .map(aliasHelper)
            .join(', ')} } = require("@vue/server-renderer")\n`);
      }
      genHoists(ast.hoists, context);
      newline();
      push(`return `);
  }
  function genModulePreamble(ast, context, genScopeId) {
      const { push, helper, newline, scopeId, optimizeImports, runtimeModuleName } = context;
      if (genScopeId) {
          ast.helpers.push(WITH_SCOPE_ID);
          if (ast.hoists.length) {
              ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID);
          }
      }
      // generate import statements for helpers
      if (ast.helpers.length) {
          if (optimizeImports) {
              // when bundled with webpack with code-split, calling an import binding
              // as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,
              // incurring both payload size increase and potential perf overhead.
              // therefore we assign the imports to variables (which is a constant ~50b
              // cost per-component instead of scaling with template size)
              push(`import { ${ast.helpers
                .map(s => helperNameMap[s])
                .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);
              push(`\n// Binding optimization for webpack code-split\nconst ${ast.helpers
                .map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)
                .join(', ')}\n`);
          }
          else {
              push(`import { ${ast.helpers
                .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
                .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`);
          }
      }
      if (ast.ssrHelpers && ast.ssrHelpers.length) {
          push(`import { ${ast.ssrHelpers
            .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
            .join(', ')} } from "@vue/server-renderer"\n`);
      }
      if (ast.imports.length) {
          genImports(ast.imports, context);
          newline();
      }
      if (genScopeId) {
          push(`const _withId = ${PURE_ANNOTATION}${helper(WITH_SCOPE_ID)}("${scopeId}")`);
          newline();
      }
      genHoists(ast.hoists, context);
      newline();
      push(`export `);
  }
  function genAssets(assets, type, { helper, push, newline }) {
      const resolver = helper(type === 'component' ? RESOLVE_COMPONENT : RESOLVE_DIRECTIVE);
      for (let i = 0; i < assets.length; i++) {
          const id = assets[i];
          push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)})`);
          if (i < assets.length - 1) {
              newline();
          }
      }
  }
  function genHoists(hoists, context) {
      if (!hoists.length) {
          return;
      }
      context.pure = true;
      const { push, newline, helper, scopeId, mode } = context;
      const genScopeId =  scopeId != null && mode !== 'function';
      newline();
      // push scope Id before initializing hoisted vnodes so that these vnodes
      // get the proper scopeId as well.
      if (genScopeId) {
          push(`${helper(PUSH_SCOPE_ID)}("${scopeId}")`);
          newline();
      }
      hoists.forEach((exp, i) => {
          if (exp) {
              push(`const _hoisted_${i + 1} = `);
              genNode(exp, context);
              newline();
          }
      });
      if (genScopeId) {
          push(`${helper(POP_SCOPE_ID)}()`);
          newline();
      }
      context.pure = false;
  }
  function genImports(importsOptions, context) {
      if (!importsOptions.length) {
          return;
      }
      importsOptions.forEach(imports => {
          context.push(`import `);
          genNode(imports.exp, context);
          context.push(` from '${imports.path}'`);
          context.newline();
      });
  }
  function isText$1(n) {
      return (isString(n) ||
          n.type === 4 /* SIMPLE_EXPRESSION */ ||
          n.type === 2 /* TEXT */ ||
          n.type === 5 /* INTERPOLATION */ ||
          n.type === 8 /* COMPOUND_EXPRESSION */);
  }
  function genNodeListAsArray(nodes, context) {
      const multilines = nodes.length > 3 ||
          ( nodes.some(n => isArray(n) || !isText$1(n)));
      context.push(`[`);
      multilines && context.indent();
      genNodeList(nodes, context, multilines);
      multilines && context.deindent();
      context.push(`]`);
  }
  function genNodeList(nodes, context, multilines = false, comma = true) {
      const { push, newline } = context;
      for (let i = 0; i < nodes.length; i++) {
          const node = nodes[i];
          if (isString(node)) {
              push(node);
          }
          else if (isArray(node)) {
              genNodeListAsArray(node, context);
          }
          else {
              genNode(node, context);
          }
          if (i < nodes.length - 1) {
              if (multilines) {
                  comma && push(',');
                  newline();
              }
              else {
                  comma && push(', ');
              }
          }
      }
  }
  function genNode(node, context) {
      if (isString(node)) {
          context.push(node);
          return;
      }
      if (isSymbol(node)) {
          context.push(context.helper(node));
          return;
      }
      switch (node.type) {
          case 1 /* ELEMENT */:
          case 9 /* IF */:
          case 11 /* FOR */:
              
                  assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
                      `Apply appropriate transforms first.`);
              genNode(node.codegenNode, context);
              break;
          case 2 /* TEXT */:
              genText(node, context);
              break;
          case 4 /* SIMPLE_EXPRESSION */:
              genExpression(node, context);
              break;
          case 5 /* INTERPOLATION */:
              genInterpolation(node, context);
              break;
          case 12 /* TEXT_CALL */:
              genNode(node.codegenNode, context);
              break;
          case 8 /* COMPOUND_EXPRESSION */:
              genCompoundExpression(node, context);
              break;
          case 3 /* COMMENT */:
              genComment(node, context);
              break;
          case 13 /* VNODE_CALL */:
              genVNodeCall(node, context);
              break;
          case 14 /* JS_CALL_EXPRESSION */:
              genCallExpression(node, context);
              break;
          case 15 /* JS_OBJECT_EXPRESSION */:
              genObjectExpression(node, context);
              break;
          case 17 /* JS_ARRAY_EXPRESSION */:
              genArrayExpression(node, context);
              break;
          case 18 /* JS_FUNCTION_EXPRESSION */:
              genFunctionExpression(node, context);
              break;
          case 19 /* JS_CONDITIONAL_EXPRESSION */:
              genConditionalExpression(node, context);
              break;
          case 20 /* JS_CACHE_EXPRESSION */:
              genCacheExpression(node, context);
              break;
          // SSR only types
          case 21 /* JS_BLOCK_STATEMENT */:
               genNodeList(node.body, context, true, false);
              break;
          case 22 /* JS_TEMPLATE_LITERAL */:
               genTemplateLiteral(node, context);
              break;
          case 23 /* JS_IF_STATEMENT */:
               genIfStatement(node, context);
              break;
          case 24 /* JS_ASSIGNMENT_EXPRESSION */:
               genAssignmentExpression(node, context);
              break;
          case 25 /* JS_SEQUENCE_EXPRESSION */:
               genSequenceExpression(node, context);
              break;
          case 26 /* JS_RETURN_STATEMENT */:
               genReturnStatement(node, context);
              break;
          /* istanbul ignore next */
          case 10 /* IF_BRANCH */:
              // noop
              break;
          default:
              {
                  assert(false, `unhandled codegen node type: ${node.type}`);
                  // make sure we exhaust all possible types
                  const exhaustiveCheck = node;
                  return exhaustiveCheck;
              }
      }
  }
  function genText(node, context) {
      context.push(JSON.stringify(node.content), node);
  }
  function genExpression(node, context) {
      const { content, isStatic } = node;
      context.push(isStatic ? JSON.stringify(content) : content, node);
  }
  function genInterpolation(node, context) {
      const { push, helper, pure } = context;
      if (pure)
          push(PURE_ANNOTATION);
      push(`${helper(TO_DISPLAY_STRING)}(`);
      genNode(node.content, context);
      push(`)`);
  }
  function genCompoundExpression(node, context) {
      for (let i = 0; i < node.children.length; i++) {
          const child = node.children[i];
          if (isString(child)) {
              context.push(child);
          }
          else {
              genNode(child, context);
          }
      }
  }
  function genExpressionAsPropertyKey(node, context) {
      const { push } = context;
      if (node.type === 8 /* COMPOUND_EXPRESSION */) {
          push(`[`);
          genCompoundExpression(node, context);
          push(`]`);
      }
      else if (node.isStatic) {
          // only quote keys if necessary
          const text = isSimpleIdentifier(node.content)
              ? node.content
              : JSON.stringify(node.content);
          push(text, node);
      }
      else {
          push(`[${node.content}]`, node);
      }
  }
  function genComment(node, context) {
      {
          const { push, helper, pure } = context;
          if (pure) {
              push(PURE_ANNOTATION);
          }
          push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
      }
  }
  function genVNodeCall(node, context) {
      const { push, helper, pure } = context;
      const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;
      if (directives) {
          push(helper(WITH_DIRECTIVES) + `(`);
      }
      if (isBlock) {
          push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
      }
      if (pure) {
          push(PURE_ANNOTATION);
      }
      push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);
      genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
      push(`)`);
      if (isBlock) {
          push(`)`);
      }
      if (directives) {
          push(`, `);
          genNode(directives, context);
          push(`)`);
      }
  }
  function genNullableArgs(args) {
      let i = args.length;
      while (i--) {
          if (args[i] != null)
              break;
      }
      return args.slice(0, i + 1).map(arg => arg || `null`);
  }
  // JavaScript
  function genCallExpression(node, context) {
      const { push, helper, pure } = context;
      const callee = isString(node.callee) ? node.callee : helper(node.callee);
      if (pure) {
          push(PURE_ANNOTATION);
      }
      push(callee + `(`, node);
      genNodeList(node.arguments, context);
      push(`)`);
  }
  function genObjectExpression(node, context) {
      const { push, indent, deindent, newline } = context;
      const { properties } = node;
      if (!properties.length) {
          push(`{}`, node);
          return;
      }
      const multilines = properties.length > 1 ||
          (
              properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
      push(multilines ? `{` : `{ `);
      multilines && indent();
      for (let i = 0; i < properties.length; i++) {
          const { key, value } = properties[i];
          // key
          genExpressionAsPropertyKey(key, context);
          push(`: `);
          // value
          genNode(value, context);
          if (i < properties.length - 1) {
              // will only reach this if it's multilines
              push(`,`);
              newline();
          }
      }
      multilines && deindent();
      push(multilines ? `}` : ` }`);
  }
  function genArrayExpression(node, context) {
      genNodeListAsArray(node.elements, context);
  }
  function genFunctionExpression(node, context) {
      const { push, indent, deindent, scopeId, mode } = context;
      const { params, returns, body, newline, isSlot } = node;
      // slot functions also need to push scopeId before rendering its content
      const genScopeId =  isSlot && scopeId != null && mode !== 'function';
      if (genScopeId) {
          push(`_withId(`);
      }
      else if (isSlot) {
          push(`_${helperNameMap[WITH_CTX]}(`);
      }
      push(`(`, node);
      if (isArray(params)) {
          genNodeList(params, context);
      }
      else if (params) {
          genNode(params, context);
      }
      push(`) => `);
      if (newline || body) {
          push(`{`);
          indent();
      }
      if (returns) {
          if (newline) {
              push(`return `);
          }
          if (isArray(returns)) {
              genNodeListAsArray(returns, context);
          }
          else {
              genNode(returns, context);
          }
      }
      else if (body) {
          genNode(body, context);
      }
      if (newline || body) {
          deindent();
          push(`}`);
      }
      if (genScopeId || isSlot) {
          push(`)`);
      }
  }
  function genConditionalExpression(node, context) {
      const { test, consequent, alternate, newline: needNewline } = node;
      const { push, indent, deindent, newline } = context;
      if (test.type === 4 /* SIMPLE_EXPRESSION */) {
          const needsParens = !isSimpleIdentifier(test.content);
          needsParens && push(`(`);
          genExpression(test, context);
          needsParens && push(`)`);
      }
      else {
          push(`(`);
          genNode(test, context);
          push(`)`);
      }
      needNewline && indent();
      context.indentLevel++;
      needNewline || push(` `);
      push(`? `);
      genNode(consequent, context);
      context.indentLevel--;
      needNewline && newline();
      needNewline || push(` `);
      push(`: `);
      const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
      if (!isNested) {
          context.indentLevel++;
      }
      genNode(alternate, context);
      if (!isNested) {
          context.indentLevel--;
      }
      needNewline && deindent(true /* without newline */);
  }
  function genCacheExpression(node, context) {
      const { push, helper, indent, deindent, newline } = context;
      push(`_cache[${node.index}] || (`);
      if (node.isVNode) {
          indent();
          push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
          newline();
      }
      push(`_cache[${node.index}] = `);
      genNode(node.value, context);
      if (node.isVNode) {
          push(`,`);
          newline();
          push(`${helper(SET_BLOCK_TRACKING)}(1),`);
          newline();
          push(`_cache[${node.index}]`);
          deindent();
      }
      push(`)`);
  }
  function genTemplateLiteral(node, context) {
      const { push, indent, deindent } = context;
      push('`');
      const l = node.elements.length;
      const multilines = l > 3;
      for (let i = 0; i < l; i++) {
          const e = node.elements[i];
          if (isString(e)) {
              push(e.replace(/(`|\$|\\)/g, '\\$1'));
          }
          else {
              push('${');
              if (multilines)
                  indent();
              genNode(e, context);
              if (multilines)
                  deindent();
              push('}');
          }
      }
      push('`');
  }
  function genIfStatement(node, context) {
      const { push, indent, deindent } = context;
      const { test, consequent, alternate } = node;
      push(`if (`);
      genNode(test, context);
      push(`) {`);
      indent();
      genNode(consequent, context);
      deindent();
      push(`}`);
      if (alternate) {
          push(` else `);
          if (alternate.type === 23 /* JS_IF_STATEMENT */) {
              genIfStatement(alternate, context);
          }
          else {
              push(`{`);
              indent();
              genNode(alternate, context);
              deindent();
              push(`}`);
          }
      }
  }
  function genAssignmentExpression(node, context) {
      genNode(node.left, context);
      context.push(` = `);
      genNode(node.right, context);
  }
  function genSequenceExpression(node, context) {
      context.push(`(`);
      genNodeList(node.expressions, context);
      context.push(`)`);
  }
  function genReturnStatement({ returns }, context) {
      context.push(`return `);
      if (isArray(returns)) {
          genNodeListAsArray(returns, context);
      }
      else {
          genNode(returns, context);
      }
  }

  var lib = createCommonjsModule(function (module, exports) {

  Object.defineProperty(exports, '__esModule', { value: true });

  const beforeExpr = true;
  const startsExpr = true;
  const isLoop = true;
  const isAssign = true;
  const prefix = true;
  const postfix = true;
  class TokenType {
    constructor(label, conf = {}) {
      this.label = label;
      this.keyword = conf.keyword;
      this.beforeExpr = !!conf.beforeExpr;
      this.startsExpr = !!conf.startsExpr;
      this.rightAssociative = !!conf.rightAssociative;
      this.isLoop = !!conf.isLoop;
      this.isAssign = !!conf.isAssign;
      this.prefix = !!conf.prefix;
      this.postfix = !!conf.postfix;
      this.binop = conf.binop != null ? conf.binop : null;
      this.updateContext = null;
    }

  }
  const keywords = new Map();

  function createKeyword(name, options = {}) {
    options.keyword = name;
    const token = new TokenType(name, options);
    keywords.set(name, token);
    return token;
  }

  function createBinop(name, binop) {
    return new TokenType(name, {
      beforeExpr,
      binop
    });
  }

  const types = {
    num: new TokenType("num", {
      startsExpr
    }),
    bigint: new TokenType("bigint", {
      startsExpr
    }),
    decimal: new TokenType("decimal", {
      startsExpr
    }),
    regexp: new TokenType("regexp", {
      startsExpr
    }),
    string: new TokenType("string", {
      startsExpr
    }),
    name: new TokenType("name", {
      startsExpr
    }),
    eof: new TokenType("eof"),
    bracketL: new TokenType("[", {
      beforeExpr,
      startsExpr
    }),
    bracketHashL: new TokenType("#[", {
      beforeExpr,
      startsExpr
    }),
    bracketBarL: new TokenType("[|", {
      beforeExpr,
      startsExpr
    }),
    bracketR: new TokenType("]"),
    bracketBarR: new TokenType("|]"),
    braceL: new TokenType("{", {
      beforeExpr,
      startsExpr
    }),
    braceBarL: new TokenType("{|", {
      beforeExpr,
      startsExpr
    }),
    braceHashL: new TokenType("#{", {
      beforeExpr,
      startsExpr
    }),
    braceR: new TokenType("}"),
    braceBarR: new TokenType("|}"),
    parenL: new TokenType("(", {
      beforeExpr,
      startsExpr
    }),
    parenR: new TokenType(")"),
    comma: new TokenType(",", {
      beforeExpr
    }),
    semi: new TokenType(";", {
      beforeExpr
    }),
    colon: new TokenType(":", {
      beforeExpr
    }),
    doubleColon: new TokenType("::", {
      beforeExpr
    }),
    dot: new TokenType("."),
    question: new TokenType("?", {
      beforeExpr
    }),
    questionDot: new TokenType("?."),
    arrow: new TokenType("=>", {
      beforeExpr
    }),
    template: new TokenType("template"),
    ellipsis: new TokenType("...", {
      beforeExpr
    }),
    backQuote: new TokenType("`", {
      startsExpr
    }),
    dollarBraceL: new TokenType("${", {
      beforeExpr,
      startsExpr
    }),
    at: new TokenType("@"),
    hash: new TokenType("#", {
      startsExpr
    }),
    interpreterDirective: new TokenType("#!..."),
    eq: new TokenType("=", {
      beforeExpr,
      isAssign
    }),
    assign: new TokenType("_=", {
      beforeExpr,
      isAssign
    }),
    incDec: new TokenType("++/--", {
      prefix,
      postfix,
      startsExpr
    }),
    bang: new TokenType("!", {
      beforeExpr,
      prefix,
      startsExpr
    }),
    tilde: new TokenType("~", {
      beforeExpr,
      prefix,
      startsExpr
    }),
    pipeline: createBinop("|>", 0),
    nullishCoalescing: createBinop("??", 1),
    logicalOR: createBinop("||", 1),
    logicalAND: createBinop("&&", 2),
    bitwiseOR: createBinop("|", 3),
    bitwiseXOR: createBinop("^", 4),
    bitwiseAND: createBinop("&", 5),
    equality: createBinop("==/!=/===/!==", 6),
    relational: createBinop("</>/<=/>=", 7),
    bitShift: createBinop("<</>>/>>>", 8),
    plusMin: new TokenType("+/-", {
      beforeExpr,
      binop: 9,
      prefix,
      startsExpr
    }),
    modulo: new TokenType("%", {
      beforeExpr,
      binop: 10,
      startsExpr
    }),
    star: new TokenType("*", {
      binop: 10
    }),
    slash: createBinop("/", 10),
    exponent: new TokenType("**", {
      beforeExpr,
      binop: 11,
      rightAssociative: true
    }),
    _break: createKeyword("break"),
    _case: createKeyword("case", {
      beforeExpr
    }),
    _catch: createKeyword("catch"),
    _continue: createKeyword("continue"),
    _debugger: createKeyword("debugger"),
    _default: createKeyword("default", {
      beforeExpr
    }),
    _do: createKeyword("do", {
      isLoop,
      beforeExpr
    }),
    _else: createKeyword("else", {
      beforeExpr
    }),
    _finally: createKeyword("finally"),
    _for: createKeyword("for", {
      isLoop
    }),
    _function: createKeyword("function", {
      startsExpr
    }),
    _if: createKeyword("if"),
    _return: createKeyword("return", {
      beforeExpr
    }),
    _switch: createKeyword("switch"),
    _throw: createKeyword("throw", {
      beforeExpr,
      prefix,
      startsExpr
    }),
    _try: createKeyword("try"),
    _var: createKeyword("var"),
    _const: createKeyword("const"),
    _while: createKeyword("while", {
      isLoop
    }),
    _with: createKeyword("with"),
    _new: createKeyword("new", {
      beforeExpr,
      startsExpr
    }),
    _this: createKeyword("this", {
      startsExpr
    }),
    _super: createKeyword("super", {
      startsExpr
    }),
    _class: createKeyword("class", {
      startsExpr
    }),
    _extends: createKeyword("extends", {
      beforeExpr
    }),
    _export: createKeyword("export"),
    _import: createKeyword("import", {
      startsExpr
    }),
    _null: createKeyword("null", {
      startsExpr
    }),
    _true: createKeyword("true", {
      startsExpr
    }),
    _false: createKeyword("false", {
      startsExpr
    }),
    _in: createKeyword("in", {
      beforeExpr,
      binop: 7
    }),
    _instanceof: createKeyword("instanceof", {
      beforeExpr,
      binop: 7
    }),
    _typeof: createKeyword("typeof", {
      beforeExpr,
      prefix,
      startsExpr
    }),
    _void: createKeyword("void", {
      beforeExpr,
      prefix,
      startsExpr
    }),
    _delete: createKeyword("delete", {
      beforeExpr,
      prefix,
      startsExpr
    })
  };

  const SCOPE_OTHER = 0b00000000,
        SCOPE_PROGRAM = 0b00000001,
        SCOPE_FUNCTION = 0b00000010,
        SCOPE_ARROW = 0b00000100,
        SCOPE_SIMPLE_CATCH = 0b00001000,
        SCOPE_SUPER = 0b00010000,
        SCOPE_DIRECT_SUPER = 0b00100000,
        SCOPE_CLASS = 0b01000000,
        SCOPE_TS_MODULE = 0b10000000,
        SCOPE_VAR = SCOPE_PROGRAM | SCOPE_FUNCTION | SCOPE_TS_MODULE;
  const BIND_KIND_VALUE = 0b00000000001,
        BIND_KIND_TYPE = 0b00000000010,
        BIND_SCOPE_VAR = 0b00000000100,
        BIND_SCOPE_LEXICAL = 0b00000001000,
        BIND_SCOPE_FUNCTION = 0b00000010000,
        BIND_FLAGS_NONE = 0b00001000000,
        BIND_FLAGS_CLASS = 0b00010000000,
        BIND_FLAGS_TS_ENUM = 0b00100000000,
        BIND_FLAGS_TS_CONST_ENUM = 0b01000000000,
        BIND_FLAGS_TS_EXPORT_ONLY = 0b10000000000;
  const BIND_CLASS = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_CLASS,
        BIND_LEXICAL = BIND_KIND_VALUE | 0 | BIND_SCOPE_LEXICAL | 0,
        BIND_VAR = BIND_KIND_VALUE | 0 | BIND_SCOPE_VAR | 0,
        BIND_FUNCTION = BIND_KIND_VALUE | 0 | BIND_SCOPE_FUNCTION | 0,
        BIND_TS_INTERFACE = 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_CLASS,
        BIND_TS_TYPE = 0 | BIND_KIND_TYPE | 0 | 0,
        BIND_TS_ENUM = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_TS_ENUM,
        BIND_TS_AMBIENT = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY,
        BIND_NONE = 0 | 0 | 0 | BIND_FLAGS_NONE,
        BIND_OUTSIDE = BIND_KIND_VALUE | 0 | 0 | BIND_FLAGS_NONE,
        BIND_TS_CONST_ENUM = BIND_TS_ENUM | BIND_FLAGS_TS_CONST_ENUM,
        BIND_TS_NAMESPACE = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY;
  const CLASS_ELEMENT_FLAG_STATIC = 0b100,
        CLASS_ELEMENT_KIND_GETTER = 0b010,
        CLASS_ELEMENT_KIND_SETTER = 0b001,
        CLASS_ELEMENT_KIND_ACCESSOR = CLASS_ELEMENT_KIND_GETTER | CLASS_ELEMENT_KIND_SETTER;
  const CLASS_ELEMENT_STATIC_GETTER = CLASS_ELEMENT_KIND_GETTER | CLASS_ELEMENT_FLAG_STATIC,
        CLASS_ELEMENT_STATIC_SETTER = CLASS_ELEMENT_KIND_SETTER | CLASS_ELEMENT_FLAG_STATIC,
        CLASS_ELEMENT_INSTANCE_GETTER = CLASS_ELEMENT_KIND_GETTER,
        CLASS_ELEMENT_INSTANCE_SETTER = CLASS_ELEMENT_KIND_SETTER,
        CLASS_ELEMENT_OTHER = 0;

  const lineBreak = /\r\n?|[\n\u2028\u2029]/;
  const lineBreakG = new RegExp(lineBreak.source, "g");
  function isNewLine(code) {
    switch (code) {
      case 10:
      case 13:
      case 8232:
      case 8233:
        return true;

      default:
        return false;
    }
  }
  const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
  function isWhitespace(code) {
    switch (code) {
      case 0x0009:
      case 0x000b:
      case 0x000c:
      case 32:
      case 160:
      case 5760:
      case 0x2000:
      case 0x2001:
      case 0x2002:
      case 0x2003:
      case 0x2004:
      case 0x2005:
      case 0x2006:
      case 0x2007:
      case 0x2008:
      case 0x2009:
      case 0x200a:
      case 0x202f:
      case 0x205f:
      case 0x3000:
      case 0xfeff:
        return true;

      default:
        return false;
    }
  }

  class Position {
    constructor(line, col) {
      this.line = line;
      this.column = col;
    }

  }
  class SourceLocation {
    constructor(start, end) {
      this.start = start;
      this.end = end;
    }

  }
  function getLineInfo(input, offset) {
    let line = 1;
    let lineStart = 0;
    let match;
    lineBreakG.lastIndex = 0;

    while ((match = lineBreakG.exec(input)) && match.index < offset) {
      line++;
      lineStart = lineBreakG.lastIndex;
    }

    return new Position(line, offset - lineStart);
  }

  class BaseParser {
    constructor() {
      this.sawUnambiguousESM = false;
      this.ambiguousScriptDifferentAst = false;
    }

    hasPlugin(name) {
      return this.plugins.has(name);
    }

    getPluginOption(plugin, name) {
      if (this.hasPlugin(plugin)) return this.plugins.get(plugin)[name];
    }

  }

  function last(stack) {
    return stack[stack.length - 1];
  }

  class CommentsParser extends BaseParser {
    addComment(comment) {
      if (this.filename) comment.loc.filename = this.filename;
      this.state.trailingComments.push(comment);
      this.state.leadingComments.push(comment);
    }

    adjustCommentsAfterTrailingComma(node, elements, takeAllComments) {
      if (this.state.leadingComments.length === 0) {
        return;
      }

      let lastElement = null;
      let i = elements.length;

      while (lastElement === null && i > 0) {
        lastElement = elements[--i];
      }

      if (lastElement === null) {
        return;
      }

      for (let j = 0; j < this.state.leadingComments.length; j++) {
        if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) {
          this.state.leadingComments.splice(j, 1);
          j--;
        }
      }

      const newTrailingComments = [];

      for (let i = 0; i < this.state.leadingComments.length; i++) {
        const leadingComment = this.state.leadingComments[i];

        if (leadingComment.end < node.end) {
          newTrailingComments.push(leadingComment);

          if (!takeAllComments) {
            this.state.leadingComments.splice(i, 1);
            i--;
          }
        } else {
          if (node.trailingComments === undefined) {
            node.trailingComments = [];
          }

          node.trailingComments.push(leadingComment);
        }
      }

      if (takeAllComments) this.state.leadingComments = [];

      if (newTrailingComments.length > 0) {
        lastElement.trailingComments = newTrailingComments;
      } else if (lastElement.trailingComments !== undefined) {
        lastElement.trailingComments = [];
      }
    }

    processComment(node) {
      if (node.type === "Program" && node.body.length > 0) return;
      const stack = this.state.commentStack;
      let firstChild, lastChild, trailingComments, i, j;

      if (this.state.trailingComments.length > 0) {
        if (this.state.trailingComments[0].start >= node.end) {
          trailingComments = this.state.trailingComments;
          this.state.trailingComments = [];
        } else {
          this.state.trailingComments.length = 0;
        }
      } else if (stack.length > 0) {
        const lastInStack = last(stack);

        if (lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) {
          trailingComments = lastInStack.trailingComments;
          delete lastInStack.trailingComments;
        }
      }

      if (stack.length > 0 && last(stack).start >= node.start) {
        firstChild = stack.pop();
      }

      while (stack.length > 0 && last(stack).start >= node.start) {
        lastChild = stack.pop();
      }

      if (!lastChild && firstChild) lastChild = firstChild;

      if (firstChild) {
        switch (node.type) {
          case "ObjectExpression":
            this.adjustCommentsAfterTrailingComma(node, node.properties);
            break;

          case "ObjectPattern":
            this.adjustCommentsAfterTrailingComma(node, node.properties, true);
            break;

          case "CallExpression":
            this.adjustCommentsAfterTrailingComma(node, node.arguments);
            break;

          case "ArrayExpression":
            this.adjustCommentsAfterTrailingComma(node, node.elements);
            break;

          case "ArrayPattern":
            this.adjustCommentsAfterTrailingComma(node, node.elements, true);
            break;
        }
      } else if (this.state.commentPreviousNode && (this.state.commentPreviousNode.type === "ImportSpecifier" && node.type !== "ImportSpecifier" || this.state.commentPreviousNode.type === "ExportSpecifier" && node.type !== "ExportSpecifier")) {
        this.adjustCommentsAfterTrailingComma(node, [this.state.commentPreviousNode]);
      }

      if (lastChild) {
        if (lastChild.leadingComments) {
          if (lastChild !== node && lastChild.leadingComments.length > 0 && last(lastChild.leadingComments).end <= node.start) {
            node.leadingComments = lastChild.leadingComments;
            delete lastChild.leadingComments;
          } else {
            for (i = lastChild.leadingComments.length - 2; i >= 0; --i) {
              if (lastChild.leadingComments[i].end <= node.start) {
                node.leadingComments = lastChild.leadingComments.splice(0, i + 1);
                break;
              }
            }
          }
        }
      } else if (this.state.leadingComments.length > 0) {
        if (last(this.state.leadingComments).end <= node.start) {
          if (this.state.commentPreviousNode) {
            for (j = 0; j < this.state.leadingComments.length; j++) {
              if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) {
                this.state.leadingComments.splice(j, 1);
                j--;
              }
            }
          }

          if (this.state.leadingComments.length > 0) {
            node.leadingComments = this.state.leadingComments;
            this.state.leadingComments = [];
          }
        } else {
          for (i = 0; i < this.state.leadingComments.length; i++) {
            if (this.state.leadingComments[i].end > node.start) {
              break;
            }
          }

          const leadingComments = this.state.leadingComments.slice(0, i);

          if (leadingComments.length) {
            node.leadingComments = leadingComments;
          }

          trailingComments = this.state.leadingComments.slice(i);

          if (trailingComments.length === 0) {
            trailingComments = null;
          }
        }
      }

      this.state.commentPreviousNode = node;

      if (trailingComments) {
        if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) {
          node.innerComments = trailingComments;
        } else {
          const firstTrailingCommentIndex = trailingComments.findIndex(comment => comment.end >= node.end);

          if (firstTrailingCommentIndex > 0) {
            node.innerComments = trailingComments.slice(0, firstTrailingCommentIndex);
            node.trailingComments = trailingComments.slice(firstTrailingCommentIndex);
          } else {
            node.trailingComments = trailingComments;
          }
        }
      }

      stack.push(node);
    }

  }

  const ErrorMessages = Object.freeze({
    AccessorIsGenerator: "A %0ter cannot be a generator",
    ArgumentsDisallowedInInitializer: "'arguments' is not allowed in class field initializer",
    AsyncFunctionInSingleStatementContext: "Async functions can only be declared at the top level or inside a block",
    AwaitBindingIdentifier: "Can not use 'await' as identifier inside an async function",
    AwaitExpressionFormalParameter: "await is not allowed in async function parameters",
    AwaitNotInAsyncFunction: "Can not use keyword 'await' outside an async function",
    BadGetterArity: "getter must not have any formal parameters",
    BadSetterArity: "setter must have exactly one formal parameter",
    BadSetterRestParameter: "setter function argument must not be a rest parameter",
    ConstructorClassField: "Classes may not have a field named 'constructor'",
    ConstructorClassPrivateField: "Classes may not have a private field named '#constructor'",
    ConstructorIsAccessor: "Class constructor may not be an accessor",
    ConstructorIsAsync: "Constructor can't be an async function",
    ConstructorIsGenerator: "Constructor can't be a generator",
    DeclarationMissingInitializer: "%0 require an initialization value",
    DecoratorBeforeExport: "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax",
    DecoratorConstructor: "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?",
    DecoratorExportClass: "Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.",
    DecoratorSemicolon: "Decorators must not be followed by a semicolon",
    DeletePrivateField: "Deleting a private field is not allowed",
    DestructureNamedImport: "ES2015 named imports do not destructure. Use another statement for destructuring after the import.",
    DuplicateConstructor: "Duplicate constructor in the same class",
    DuplicateDefaultExport: "Only one default export allowed per module.",
    DuplicateExport: "`%0` has already been exported. Exported identifiers must be unique.",
    DuplicateProto: "Redefinition of __proto__ property",
    DuplicateRegExpFlags: "Duplicate regular expression flag",
    ElementAfterRest: "Rest element must be last element",
    EscapedCharNotAnIdentifier: "Invalid Unicode escape",
    ExportDefaultFromAsIdentifier: "'from' is not allowed as an identifier after 'export default'",
    ForInOfLoopInitializer: "%0 loop variable declaration may not have an initializer",
    GeneratorInSingleStatementContext: "Generators can only be declared at the top level or inside a block",
    IllegalBreakContinue: "Unsyntactic %0",
    IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list",
    IllegalReturn: "'return' outside of function",
    ImportCallArgumentTrailingComma: "Trailing comma is disallowed inside import(...) arguments",
    ImportCallArity: "import() requires exactly %0",
    ImportCallNotNewExpression: "Cannot use new with import(...)",
    ImportCallSpreadArgument: "... is not allowed in import()",
    ImportMetaOutsideModule: `import.meta may appear only with 'sourceType: "module"'`,
    ImportOutsideModule: `'import' and 'export' may appear only with 'sourceType: "module"'`,
    InvalidBigIntLiteral: "Invalid BigIntLiteral",
    InvalidCodePoint: "Code point out of bounds",
    InvalidDecimal: "Invalid decimal",
    InvalidDigit: "Expected number in radix %0",
    InvalidEscapeSequence: "Bad character escape sequence",
    InvalidEscapeSequenceTemplate: "Invalid escape sequence in template",
    InvalidEscapedReservedWord: "Escape sequence in keyword %0",
    InvalidIdentifier: "Invalid identifier %0",
    InvalidLhs: "Invalid left-hand side in %0",
    InvalidLhsBinding: "Binding invalid left-hand side in %0",
    InvalidNumber: "Invalid number",
    InvalidOrUnexpectedToken: "Unexpected character '%0'",
    InvalidParenthesizedAssignment: "Invalid parenthesized assignment pattern",
    InvalidPrivateFieldResolution: "Private name #%0 is not defined",
    InvalidPropertyBindingPattern: "Binding member expression",
    InvalidRecordProperty: "Only properties and spread elements are allowed in record definitions",
    InvalidRestAssignmentPattern: "Invalid rest operator's argument",
    LabelRedeclaration: "Label '%0' is already declared",
    LetInLexicalBinding: "'let' is not allowed to be used as a name in 'let' or 'const' declarations.",
    LineTerminatorBeforeArrow: "No line break is allowed before '=>'",
    MalformedRegExpFlags: "Invalid regular expression flag",
    MissingClassName: "A class name is required",
    MissingEqInAssignment: "Only '=' operator can be used for specifying default value.",
    MissingUnicodeEscape: "Expecting Unicode escape sequence \\uXXXX",
    MixingCoalesceWithLogical: "Nullish coalescing operator(??) requires parens when mixing with logical operators",
    ModuleAttributeDifferentFromType: "The only accepted module attribute is `type`",
    ModuleAttributeInvalidValue: "Only string literals are allowed as module attribute values",
    ModuleAttributesWithDuplicateKeys: 'Duplicate key "%0" is not allowed in module attributes',
    ModuleExportUndefined: "Export '%0' is not defined",
    MultipleDefaultsInSwitch: "Multiple default clauses",
    NewlineAfterThrow: "Illegal newline after throw",
    NoCatchOrFinally: "Missing catch or finally clause",
    NumberIdentifier: "Identifier directly after number",
    NumericSeparatorInEscapeSequence: "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences",
    ObsoleteAwaitStar: "await* has been removed from the async functions proposal. Use Promise.all() instead.",
    OptionalChainingNoNew: "constructors in/after an Optional Chain are not allowed",
    OptionalChainingNoTemplate: "Tagged Template Literals are not allowed in optionalChain",
    ParamDupe: "Argument name clash",
    PatternHasAccessor: "Object pattern can't contain getter or setter",
    PatternHasMethod: "Object pattern can't contain methods",
    PipelineBodyNoArrow: 'Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized',
    PipelineBodySequenceExpression: "Pipeline body may not be a comma-separated sequence expression",
    PipelineHeadSequenceExpression: "Pipeline head should not be a comma-separated sequence expression",
    PipelineTopicUnused: "Pipeline is in topic style but does not use topic reference",
    PrimaryTopicNotAllowed: "Topic reference was used in a lexical context without topic binding",
    PrimaryTopicRequiresSmartPipeline: "Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' option.",
    PrivateInExpectedIn: "Private names are only allowed in property accesses (`obj.#%0`) or in `in` expressions (`#%0 in obj`)",
    PrivateNameRedeclaration: "Duplicate private name #%0",
    RecordExpressionBarIncorrectEndSyntaxType: "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'",
    RecordExpressionBarIncorrectStartSyntaxType: "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'",
    RecordExpressionHashIncorrectStartSyntaxType: "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'",
    RecordNoProto: "'__proto__' is not allowed in Record expressions",
    RestTrailingComma: "Unexpected trailing comma after rest element",
    SloppyFunction: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement",
    StaticPrototype: "Classes may not have static property named prototype",
    StrictDelete: "Deleting local variable in strict mode",
    StrictEvalArguments: "Assigning to '%0' in strict mode",
    StrictEvalArgumentsBinding: "Binding '%0' in strict mode",
    StrictFunction: "In strict mode code, functions can only be declared at top level or inside a block",
    StrictNumericEscape: "The only valid numeric escape in strict mode is '\\0'",
    StrictOctalLiteral: "Legacy octal literals are not allowed in strict mode",
    StrictWith: "'with' in strict mode",
    SuperNotAllowed: "super() is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class?",
    SuperPrivateField: "Private fields can't be accessed on super",
    TrailingDecorator: "Decorators must be attached to a class element",
    TupleExpressionBarIncorrectEndSyntaxType: "Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'",
    TupleExpressionBarIncorrectStartSyntaxType: "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'",
    TupleExpressionHashIncorrectStartSyntaxType: "Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'",
    UnexpectedArgumentPlaceholder: "Unexpected argument placeholder",
    UnexpectedAwaitAfterPipelineBody: 'Unexpected "await" after pipeline body; await must have parentheses in minimal proposal',
    UnexpectedDigitAfterHash: "Unexpected digit after hash token",
    UnexpectedImportExport: "'import' and 'export' may only appear at the top level",
    UnexpectedKeyword: "Unexpected keyword '%0'",
    UnexpectedLeadingDecorator: "Leading decorators must be attached to a class declaration",
    UnexpectedLexicalDeclaration: "Lexical declaration cannot appear in a single-statement context",
    UnexpectedNewTarget: "new.target can only be used in functions",
    UnexpectedNumericSeparator: "A numeric separator is only allowed between two digits",
    UnexpectedPrivateField: "Private names can only be used as the name of a class element (i.e. class C { #p = 42; #m() {} } )\n or a property of member expression (i.e. this.#p).",
    UnexpectedReservedWord: "Unexpected reserved word '%0'",
    UnexpectedSuper: "super is only allowed in object methods and classes",
    UnexpectedToken: "Unexpected token '%0'",
    UnexpectedTokenUnaryExponentiation: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.",
    UnsupportedBind: "Binding should be performed on object property.",
    UnsupportedDecoratorExport: "A decorated export must export a class declaration",
    UnsupportedDefaultExport: "Only expressions, functions or classes are allowed as the `default` export.",
    UnsupportedImport: "import can only be used in import() or import.meta",
    UnsupportedMetaProperty: "The only valid meta property for %0 is %0.%1",
    UnsupportedParameterDecorator: "Decorators cannot be used to decorate parameters",
    UnsupportedPropertyDecorator: "Decorators cannot be used to decorate object literal properties",
    UnsupportedSuper: "super can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop])",
    UnterminatedComment: "Unterminated comment",
    UnterminatedRegExp: "Unterminated regular expression",
    UnterminatedString: "Unterminated string constant",
    UnterminatedTemplate: "Unterminated template",
    VarRedeclaration: "Identifier '%0' has already been declared",
    YieldBindingIdentifier: "Can not use 'yield' as identifier inside a generator",
    YieldInParameter: "yield is not allowed in generator parameters",
    ZeroDigitNumericSeparator: "Numeric separator can not be used after leading 0"
  });

  class ParserError extends CommentsParser {
    getLocationForPosition(pos) {
      let loc;
      if (pos === this.state.start) loc = this.state.startLoc;else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc;else if (pos === this.state.end) loc = this.state.endLoc;else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc;else loc = getLineInfo(this.input, pos);
      return loc;
    }

    raise(pos, errorTemplate, ...params) {
      return this.raiseWithData(pos, undefined, errorTemplate, ...params);
    }

    raiseWithData(pos, data, errorTemplate, ...params) {
      const loc = this.getLocationForPosition(pos);
      const message = errorTemplate.replace(/%(\d+)/g, (_, i) => params[i]) + ` (${loc.line}:${loc.column})`;
      return this._raise(Object.assign({
        loc,
        pos
      }, data), message);
    }

    _raise(errorContext, message) {
      const err = new SyntaxError(message);
      Object.assign(err, errorContext);

      if (this.options.errorRecovery) {
        if (!this.isLookahead) this.state.errors.push(err);
        return err;
      } else {
        throw err;
      }
    }

  }

  function isSimpleProperty(node) {
    return node != null && node.type === "Property" && node.kind === "init" && node.method === false;
  }

  var estree = (superClass => class extends superClass {
    estreeParseRegExpLiteral({
      pattern,
      flags
    }) {
      let regex = null;

      try {
        regex = new RegExp(pattern, flags);
      } catch (e) {}

      const node = this.estreeParseLiteral(regex);
      node.regex = {
        pattern,
        flags
      };
      return node;
    }

    estreeParseBigIntLiteral(value) {
      const bigInt = typeof BigInt !== "undefined" ? BigInt(value) : null;
      const node = this.estreeParseLiteral(bigInt);
      node.bigint = String(node.value || value);
      return node;
    }

    estreeParseDecimalLiteral(value) {
      const decimal = null;
      const node = this.estreeParseLiteral(decimal);
      node.decimal = String(node.value || value);
      return node;
    }

    estreeParseLiteral(value) {
      return this.parseLiteral(value, "Literal");
    }

    directiveToStmt(directive) {
      const directiveLiteral = directive.value;
      const stmt = this.startNodeAt(directive.start, directive.loc.start);
      const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start);
      expression.value = directiveLiteral.value;
      expression.raw = directiveLiteral.extra.raw;
      stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end);
      stmt.directive = directiveLiteral.extra.raw.slice(1, -1);
      return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end);
    }

    initFunction(node, isAsync) {
      super.initFunction(node, isAsync);
      node.expression = false;
    }

    checkDeclaration(node) {
      if (isSimpleProperty(node)) {
        this.checkDeclaration(node.value);
      } else {
        super.checkDeclaration(node);
      }
    }

    checkGetterSetterParams(method) {
      const prop = method;
      const paramCount = prop.kind === "get" ? 0 : 1;
      const start = prop.start;

      if (prop.value.params.length !== paramCount) {
        if (method.kind === "get") {
          this.raise(start, ErrorMessages.BadGetterArity);
        } else {
          this.raise(start, ErrorMessages.BadSetterArity);
        }
      } else if (prop.kind === "set" && prop.value.params[0].type === "RestElement") {
        this.raise(start, ErrorMessages.BadSetterRestParameter);
      }
    }

    checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription, disallowLetBinding) {
      switch (expr.type) {
        case "ObjectPattern":
          expr.properties.forEach(prop => {
            this.checkLVal(prop.type === "Property" ? prop.value : prop, bindingType, checkClashes, "object destructuring pattern", disallowLetBinding);
          });
          break;

        default:
          super.checkLVal(expr, bindingType, checkClashes, contextDescription, disallowLetBinding);
      }
    }

    checkProto(prop, isRecord, protoRef, refExpressionErrors) {
      if (prop.method) {
        return;
      }

      super.checkProto(prop, isRecord, protoRef, refExpressionErrors);
    }

    isValidDirective(stmt) {
      var _stmt$expression$extr;

      return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && !((_stmt$expression$extr = stmt.expression.extra) == null ? void 0 : _stmt$expression$extr.parenthesized);
    }

    stmtToDirective(stmt) {
      const directive = super.stmtToDirective(stmt);
      const value = stmt.expression.value;
      directive.value.value = value;
      return directive;
    }

    parseBlockBody(node, allowDirectives, topLevel, end) {
      super.parseBlockBody(node, allowDirectives, topLevel, end);
      const directiveStatements = node.directives.map(d => this.directiveToStmt(d));
      node.body = directiveStatements.concat(node.body);
      delete node.directives;
    }

    pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
      this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true);

      if (method.typeParameters) {
        method.value.typeParameters = method.typeParameters;
        delete method.typeParameters;
      }

      classBody.body.push(method);
    }

    parseExprAtom(refExpressionErrors) {
      switch (this.state.type) {
        case types.num:
        case types.string:
          return this.estreeParseLiteral(this.state.value);

        case types.regexp:
          return this.estreeParseRegExpLiteral(this.state.value);

        case types.bigint:
          return this.estreeParseBigIntLiteral(this.state.value);

        case types.decimal:
          return this.estreeParseDecimalLiteral(this.state.value);

        case types._null:
          return this.estreeParseLiteral(null);

        case types._true:
          return this.estreeParseLiteral(true);

        case types._false:
          return this.estreeParseLiteral(false);

        default:
          return super.parseExprAtom(refExpressionErrors);
      }
    }

    parseLiteral(value, type, startPos, startLoc) {
      const node = super.parseLiteral(value, type, startPos, startLoc);
      node.raw = node.extra.raw;
      delete node.extra;
      return node;
    }

    parseFunctionBody(node, allowExpression, isMethod = false) {
      super.parseFunctionBody(node, allowExpression, isMethod);
      node.expression = node.body.type !== "BlockStatement";
    }

    parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) {
      let funcNode = this.startNode();
      funcNode.kind = node.kind;
      funcNode = super.parseMethod(funcNode, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope);
      funcNode.type = "FunctionExpression";
      delete funcNode.kind;
      node.value = funcNode;
      type = type === "ClassMethod" ? "MethodDefinition" : type;
      return this.finishNode(node, type);
    }

    parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) {
      const node = super.parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor);

      if (node) {
        node.type = "Property";
        if (node.kind === "method") node.kind = "init";
        node.shorthand = false;
      }

      return node;
    }

    parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors) {
      const node = super.parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors);

      if (node) {
        node.kind = "init";
        node.type = "Property";
      }

      return node;
    }

    toAssignable(node) {
      if (isSimpleProperty(node)) {
        this.toAssignable(node.value);
        return node;
      }

      return super.toAssignable(node);
    }

    toAssignableObjectExpressionProp(prop, isLast) {
      if (prop.kind === "get" || prop.kind === "set") {
        throw this.raise(prop.key.start, ErrorMessages.PatternHasAccessor);
      } else if (prop.method) {
        throw this.raise(prop.key.start, ErrorMessages.PatternHasMethod);
      } else {
        super.toAssignableObjectExpressionProp(prop, isLast);
      }
    }

    finishCallExpression(node, optional) {
      super.finishCallExpression(node, optional);

      if (node.callee.type === "Import") {
        node.type = "ImportExpression";
        node.source = node.arguments[0];
        delete node.arguments;
        delete node.callee;
      }

      return node;
    }

    toReferencedListDeep(exprList, isParenthesizedExpr) {
      if (!exprList) {
        return;
      }

      super.toReferencedListDeep(exprList, isParenthesizedExpr);
    }

    parseExport(node) {
      super.parseExport(node);

      switch (node.type) {
        case "ExportAllDeclaration":
          node.exported = null;
          break;

        case "ExportNamedDeclaration":
          if (node.specifiers.length === 1 && node.specifiers[0].type === "ExportNamespaceSpecifier") {
            node.type = "ExportAllDeclaration";
            node.exported = node.specifiers[0].exported;
            delete node.specifiers;
          }

          break;
      }

      return node;
    }

    parseSubscript(base, startPos, startLoc, noCalls, state) {
      const node = super.parseSubscript(base, startPos, startLoc, noCalls, state);

      if (state.optionalChainMember) {
        if (node.type === "OptionalMemberExpression" || node.type === "OptionalCallExpression") {
          node.type = node.type.substring(8);
        }

        if (state.stop) {
          const chain = this.startNodeAtNode(node);
          chain.expression = node;
          return this.finishNode(chain, "ChainExpression");
        }
      } else if (node.type === "MemberExpression" || node.type === "CallExpression") {
        node.optional = false;
      }

      return node;
    }

  });

  class TokContext {
    constructor(token, isExpr, preserveSpace, override) {
      this.token = token;
      this.isExpr = !!isExpr;
      this.preserveSpace = !!preserveSpace;
      this.override = override;
    }

  }
  const types$1 = {
    braceStatement: new TokContext("{", false),
    braceExpression: new TokContext("{", true),
    recordExpression: new TokContext("#{", true),
    templateQuasi: new TokContext("${", false),
    parenStatement: new TokContext("(", false),
    parenExpression: new TokContext("(", true),
    template: new TokContext("`", true, true, p => p.readTmplToken()),
    functionExpression: new TokContext("function", true),
    functionStatement: new TokContext("function", false)
  };

  types.parenR.updateContext = types.braceR.updateContext = function () {
    if (this.state.context.length === 1) {
      this.state.exprAllowed = true;
      return;
    }

    let out = this.state.context.pop();

    if (out === types$1.braceStatement && this.curContext().token === "function") {
      out = this.state.context.pop();
    }

    this.state.exprAllowed = !out.isExpr;
  };

  types.name.updateContext = function (prevType) {
    let allowed = false;

    if (prevType !== types.dot) {
      if (this.state.value === "of" && !this.state.exprAllowed && prevType !== types._function && prevType !== types._class || this.state.value === "yield" && this.prodParam.hasYield) {
        allowed = true;
      }
    }

    this.state.exprAllowed = allowed;

    if (this.state.isIterator) {
      this.state.isIterator = false;
    }
  };

  types.braceL.updateContext = function (prevType) {
    this.state.context.push(this.braceIsBlock(prevType) ? types$1.braceStatement : types$1.braceExpression);
    this.state.exprAllowed = true;
  };

  types.dollarBraceL.updateContext = function () {
    this.state.context.push(types$1.templateQuasi);
    this.state.exprAllowed = true;
  };

  types.parenL.updateContext = function (prevType) {
    const statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
    this.state.context.push(statementParens ? types$1.parenStatement : types$1.parenExpression);
    this.state.exprAllowed = true;
  };

  types.incDec.updateContext = function () {};

  types._function.updateContext = types._class.updateContext = function (prevType) {
    if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && !(prevType === types._return && this.hasPrecedingLineBreak()) && !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) {
      this.state.context.push(types$1.functionExpression);
    } else {
      this.state.context.push(types$1.functionStatement);
    }

    this.state.exprAllowed = false;
  };

  types.backQuote.updateContext = function () {
    if (this.curContext() === types$1.template) {
      this.state.context.pop();
    } else {
      this.state.context.push(types$1.template);
    }

    this.state.exprAllowed = false;
  };

  types.braceHashL.updateContext = function () {
    this.state.context.push(types$1.recordExpression);
    this.state.exprAllowed = true;
  };

  let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
  let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
  const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
  const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
  nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
  const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938];
  const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];

  function isInAstralSet(code, set) {
    let pos = 0x10000;

    for (let i = 0, length = set.length; i < length; i += 2) {
      pos += set[i];
      if (pos > code) return false;
      pos += set[i + 1];
      if (pos >= code) return true;
    }

    return false;
  }

  function isIdentifierStart(code) {
    if (code < 65) return code === 36;
    if (code <= 90) return true;
    if (code < 97) return code === 95;
    if (code <= 122) return true;

    if (code <= 0xffff) {
      return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
    }

    return isInAstralSet(code, astralIdentifierStartCodes);
  }
  function isIdentifierChar(code) {
    if (code < 48) return code === 36;
    if (code < 58) return true;
    if (code < 65) return false;
    if (code <= 90) return true;
    if (code < 97) return code === 95;
    if (code <= 122) return true;

    if (code <= 0xffff) {
      return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
    }

    return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
  }

  const reservedWords = {
    keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"],
    strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"],
    strictBind: ["eval", "arguments"]
  };
  const keywords$1 = new Set(reservedWords.keyword);
  const reservedWordsStrictSet = new Set(reservedWords.strict);
  const reservedWordsStrictBindSet = new Set(reservedWords.strictBind);
  function isReservedWord(word, inModule) {
    return inModule && word === "await" || word === "enum";
  }
  function isStrictReservedWord(word, inModule) {
    return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
  }
  function isStrictBindOnlyReservedWord(word) {
    return reservedWordsStrictBindSet.has(word);
  }
  function isStrictBindReservedWord(word, inModule) {
    return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word);
  }
  function isKeyword(word) {
    return keywords$1.has(word);
  }

  const keywordRelationalOperator = /^in(stanceof)?$/;
  function isIteratorStart(current, next) {
    return current === 64 && next === 64;
  }

  const reservedTypes = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]);
  const FlowErrors = Object.freeze({
    AmbiguousConditionalArrow: "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.",
    AmbiguousDeclareModuleKind: "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module",
    AssignReservedType: "Cannot overwrite reserved type %0",
    DeclareClassElement: "The `declare` modifier can only appear on class fields.",
    DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.",
    DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement",
    EnumBooleanMemberNotInitialized: "Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.",
    EnumDuplicateMemberName: "Enum member names need to be unique, but the name `%0` has already been used before in enum `%1`.",
    EnumInconsistentMemberValues: "Enum `%0` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.",
    EnumInvalidExplicitType: "Enum type `%1` is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.",
    EnumInvalidExplicitTypeUnknownSupplied: "Supplied enum type is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.",
    EnumInvalidMemberInitializerPrimaryType: "Enum `%0` has type `%2`, so the initializer of `%1` needs to be a %2 literal.",
    EnumInvalidMemberInitializerSymbolType: "Symbol enum members cannot be initialized. Use `%1,` in enum `%0`.",
    EnumInvalidMemberInitializerUnknownType: "The enum member initializer for `%1` needs to be a literal (either a boolean, number, or string) in enum `%0`.",
    EnumInvalidMemberName: "Enum member names cannot start with lowercase 'a' through 'z'. Instead of using `%0`, consider using `%1`, in enum `%2`.",
    EnumNumberMemberNotInitialized: "Number enum members need to be initialized, e.g. `%1 = 1` in enum `%0`.",
    EnumStringMemberInconsistentlyInitailized: "String enum members need to consistently either all use initializers, or use no initializers, in enum `%0`.",
    ImportTypeShorthandOnlyInPureImport: "The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements",
    InexactInsideExact: "Explicit inexact syntax cannot appear inside an explicit exact object type",
    InexactInsideNonObject: "Explicit inexact syntax cannot appear in class or interface definitions",
    InexactVariance: "Explicit inexact syntax cannot have variance",
    InvalidNonTypeImportInDeclareModule: "Imports within a `declare module` body must always be `import type` or `import typeof`",
    MissingTypeParamDefault: "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.",
    NestedDeclareModule: "`declare module` cannot be used inside another `declare module`",
    NestedFlowComment: "Cannot have a flow comment inside another flow comment",
    OptionalBindingPattern: "A binding pattern parameter cannot be optional in an implementation signature.",
    SpreadVariance: "Spread properties cannot have variance",
    TypeBeforeInitializer: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`",
    TypeCastInPattern: "The type cast expression is expected to be wrapped with parenthesis",
    UnexpectedExplicitInexactInObject: "Explicit inexact syntax must appear at the end of an inexact object",
    UnexpectedReservedType: "Unexpected reserved type %0",
    UnexpectedReservedUnderscore: "`_` is only allowed as a type argument to call or new",
    UnexpectedSpaceBetweenModuloChecks: "Spaces between `%` and `checks` are not allowed here.",
    UnexpectedSpreadType: "Spread operator cannot appear in class or interface definitions",
    UnexpectedSubtractionOperand: 'Unexpected token, expected "number" or "bigint"',
    UnexpectedTokenAfterTypeParameter: "Expected an arrow function after this type parameter declaration",
    UnexpectedTypeParameterBeforeAsyncArrowFunction: "Type parameters must come after the async keyword, e.g. instead of `<T> async () => {}`, use `async <T>() => {}`",
    UnsupportedDeclareExportKind: "`declare export %0` is not supported. Use `%1` instead",
    UnsupportedStatementInDeclareModule: "Only declares and type imports are allowed inside declare module",
    UnterminatedFlowComment: "Unterminated flow-comment"
  });

  function isEsModuleType(bodyElement) {
    return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration");
  }

  function hasTypeImportKind(node) {
    return node.importKind === "type" || node.importKind === "typeof";
  }

  function isMaybeDefaultImport(state) {
    return (state.type === types.name || !!state.type.keyword) && state.value !== "from";
  }

  const exportSuggestions = {
    const: "declare export var",
    let: "declare export var",
    type: "export type",
    interface: "export interface"
  };

  function partition(list, test) {
    const list1 = [];
    const list2 = [];

    for (let i = 0; i < list.length; i++) {
      (test(list[i], i, list) ? list1 : list2).push(list[i]);
    }

    return [list1, list2];
  }

  const FLOW_PRAGMA_REGEX = /\*?\s*@((?:no)?flow)\b/;
  var flow = (superClass => class extends superClass {
    constructor(options, input) {
      super(options, input);
      this.flowPragma = undefined;
    }

    shouldParseTypes() {
      return this.getPluginOption("flow", "all") || this.flowPragma === "flow";
    }

    shouldParseEnums() {
      return !!this.getPluginOption("flow", "enums");
    }

    finishToken(type, val) {
      if (type !== types.string && type !== types.semi && type !== types.interpreterDirective) {
        if (this.flowPragma === undefined) {
          this.flowPragma = null;
        }
      }

      return super.finishToken(type, val);
    }

    addComment(comment) {
      if (this.flowPragma === undefined) {
        const matches = FLOW_PRAGMA_REGEX.exec(comment.value);

        if (!matches) ; else if (matches[1] === "flow") {
          this.flowPragma = "flow";
        } else if (matches[1] === "noflow") {
          this.flowPragma = "noflow";
        } else {
          throw new Error("Unexpected flow pragma");
        }
      }

      return super.addComment(comment);
    }

    flowParseTypeInitialiser(tok) {
      const oldInType = this.state.inType;
      this.state.inType = true;
      this.expect(tok || types.colon);
      const type = this.flowParseType();
      this.state.inType = oldInType;
      return type;
    }

    flowParsePredicate() {
      const node = this.startNode();
      const moduloLoc = this.state.startLoc;
      const moduloPos = this.state.start;
      this.expect(types.modulo);
      const checksLoc = this.state.startLoc;
      this.expectContextual("checks");

      if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) {
        this.raise(moduloPos, FlowErrors.UnexpectedSpaceBetweenModuloChecks);
      }

      if (this.eat(types.parenL)) {
        node.value = this.parseExpression();
        this.expect(types.parenR);
        return this.finishNode(node, "DeclaredPredicate");
      } else {
        return this.finishNode(node, "InferredPredicate");
      }
    }

    flowParseTypeAndPredicateInitialiser() {
      const oldInType = this.state.inType;
      this.state.inType = true;
      this.expect(types.colon);
      let type = null;
      let predicate = null;

      if (this.match(types.modulo)) {
        this.state.inType = oldInType;
        predicate = this.flowParsePredicate();
      } else {
        type = this.flowParseType();
        this.state.inType = oldInType;

        if (this.match(types.modulo)) {
          predicate = this.flowParsePredicate();
        }
      }

      return [type, predicate];
    }

    flowParseDeclareClass(node) {
      this.next();
      this.flowParseInterfaceish(node, true);
      return this.finishNode(node, "DeclareClass");
    }

    flowParseDeclareFunction(node) {
      this.next();
      const id = node.id = this.parseIdentifier();
      const typeNode = this.startNode();
      const typeContainer = this.startNode();

      if (this.isRelational("<")) {
        typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
      } else {
        typeNode.typeParameters = null;
      }

      this.expect(types.parenL);
      const tmp = this.flowParseFunctionTypeParams();
      typeNode.params = tmp.params;
      typeNode.rest = tmp.rest;
      this.expect(types.parenR);
      [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
      typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
      id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
      this.resetEndLocation(id);
      this.semicolon();
      return this.finishNode(node, "DeclareFunction");
    }

    flowParseDeclare(node, insideModule) {
      if (this.match(types._class)) {
        return this.flowParseDeclareClass(node);
      } else if (this.match(types._function)) {
        return this.flowParseDeclareFunction(node);
      } else if (this.match(types._var)) {
        return this.flowParseDeclareVariable(node);
      } else if (this.eatContextual("module")) {
        if (this.match(types.dot)) {
          return this.flowParseDeclareModuleExports(node);
        } else {
          if (insideModule) {
            this.raise(this.state.lastTokStart, FlowErrors.NestedDeclareModule);
          }

          return this.flowParseDeclareModule(node);
        }
      } else if (this.isContextual("type")) {
        return this.flowParseDeclareTypeAlias(node);
      } else if (this.isContextual("opaque")) {
        return this.flowParseDeclareOpaqueType(node);
      } else if (this.isContextual("interface")) {
        return this.flowParseDeclareInterface(node);
      } else if (this.match(types._export)) {
        return this.flowParseDeclareExportDeclaration(node, insideModule);
      } else {
        throw this.unexpected();
      }
    }

    flowParseDeclareVariable(node) {
      this.next();
      node.id = this.flowParseTypeAnnotatableIdentifier(true);
      this.scope.declareName(node.id.name, BIND_VAR, node.id.start);
      this.semicolon();
      return this.finishNode(node, "DeclareVariable");
    }

    flowParseDeclareModule(node) {
      this.scope.enter(SCOPE_OTHER);

      if (this.match(types.string)) {
        node.id = this.parseExprAtom();
      } else {
        node.id = this.parseIdentifier();
      }

      const bodyNode = node.body = this.startNode();
      const body = bodyNode.body = [];
      this.expect(types.braceL);

      while (!this.match(types.braceR)) {
        let bodyNode = this.startNode();

        if (this.match(types._import)) {
          this.next();

          if (!this.isContextual("type") && !this.match(types._typeof)) {
            this.raise(this.state.lastTokStart, FlowErrors.InvalidNonTypeImportInDeclareModule);
          }

          this.parseImport(bodyNode);
        } else {
          this.expectContextual("declare", FlowErrors.UnsupportedStatementInDeclareModule);
          bodyNode = this.flowParseDeclare(bodyNode, true);
        }

        body.push(bodyNode);
      }

      this.scope.exit();
      this.expect(types.braceR);
      this.finishNode(bodyNode, "BlockStatement");
      let kind = null;
      let hasModuleExport = false;
      body.forEach(bodyElement => {
        if (isEsModuleType(bodyElement)) {
          if (kind === "CommonJS") {
            this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind);
          }

          kind = "ES";
        } else if (bodyElement.type === "DeclareModuleExports") {
          if (hasModuleExport) {
            this.raise(bodyElement.start, FlowErrors.DuplicateDeclareModuleExports);
          }

          if (kind === "ES") {
            this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind);
          }

          kind = "CommonJS";
          hasModuleExport = true;
        }
      });
      node.kind = kind || "CommonJS";
      return this.finishNode(node, "DeclareModule");
    }

    flowParseDeclareExportDeclaration(node, insideModule) {
      this.expect(types._export);

      if (this.eat(types._default)) {
        if (this.match(types._function) || this.match(types._class)) {
          node.declaration = this.flowParseDeclare(this.startNode());
        } else {
          node.declaration = this.flowParseType();
          this.semicolon();
        }

        node.default = true;
        return this.finishNode(node, "DeclareExportDeclaration");
      } else {
        if (this.match(types._const) || this.isLet() || (this.isContextual("type") || this.isContextual("interface")) && !insideModule) {
          const label = this.state.value;
          const suggestion = exportSuggestions[label];
          throw this.raise(this.state.start, FlowErrors.UnsupportedDeclareExportKind, label, suggestion);
        }

        if (this.match(types._var) || this.match(types._function) || this.match(types._class) || this.isContextual("opaque")) {
            node.declaration = this.flowParseDeclare(this.startNode());
            node.default = false;
            return this.finishNode(node, "DeclareExportDeclaration");
          } else if (this.match(types.star) || this.match(types.braceL) || this.isContextual("interface") || this.isContextual("type") || this.isContextual("opaque")) {
            node = this.parseExport(node);

            if (node.type === "ExportNamedDeclaration") {
              node.type = "ExportDeclaration";
              node.default = false;
              delete node.exportKind;
            }

            node.type = "Declare" + node.type;
            return node;
          }
      }

      throw this.unexpected();
    }

    flowParseDeclareModuleExports(node) {
      this.next();
      this.expectContextual("exports");
      node.typeAnnotation = this.flowParseTypeAnnotation();
      this.semicolon();
      return this.finishNode(node, "DeclareModuleExports");
    }

    flowParseDeclareTypeAlias(node) {
      this.next();
      this.flowParseTypeAlias(node);
      node.type = "DeclareTypeAlias";
      return node;
    }

    flowParseDeclareOpaqueType(node) {
      this.next();
      this.flowParseOpaqueType(node, true);
      node.type = "DeclareOpaqueType";
      return node;
    }

    flowParseDeclareInterface(node) {
      this.next();
      this.flowParseInterfaceish(node);
      return this.finishNode(node, "DeclareInterface");
    }

    flowParseInterfaceish(node, isClass = false) {
      node.id = this.flowParseRestrictedIdentifier(!isClass, true);
      this.scope.declareName(node.id.name, isClass ? BIND_FUNCTION : BIND_LEXICAL, node.id.start);

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterDeclaration();
      } else {
        node.typeParameters = null;
      }

      node.extends = [];
      node.implements = [];
      node.mixins = [];

      if (this.eat(types._extends)) {
        do {
          node.extends.push(this.flowParseInterfaceExtends());
        } while (!isClass && this.eat(types.comma));
      }

      if (this.isContextual("mixins")) {
        this.next();

        do {
          node.mixins.push(this.flowParseInterfaceExtends());
        } while (this.eat(types.comma));
      }

      if (this.isContextual("implements")) {
        this.next();

        do {
          node.implements.push(this.flowParseInterfaceExtends());
        } while (this.eat(types.comma));
      }

      node.body = this.flowParseObjectType({
        allowStatic: isClass,
        allowExact: false,
        allowSpread: false,
        allowProto: isClass,
        allowInexact: false
      });
    }

    flowParseInterfaceExtends() {
      const node = this.startNode();
      node.id = this.flowParseQualifiedTypeIdentifier();

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterInstantiation();
      } else {
        node.typeParameters = null;
      }

      return this.finishNode(node, "InterfaceExtends");
    }

    flowParseInterface(node) {
      this.flowParseInterfaceish(node);
      return this.finishNode(node, "InterfaceDeclaration");
    }

    checkNotUnderscore(word) {
      if (word === "_") {
        this.raise(this.state.start, FlowErrors.UnexpectedReservedUnderscore);
      }
    }

    checkReservedType(word, startLoc, declaration) {
      if (!reservedTypes.has(word)) return;
      this.raise(startLoc, declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, word);
    }

    flowParseRestrictedIdentifier(liberal, declaration) {
      this.checkReservedType(this.state.value, this.state.start, declaration);
      return this.parseIdentifier(liberal);
    }

    flowParseTypeAlias(node) {
      node.id = this.flowParseRestrictedIdentifier(false, true);
      this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start);

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterDeclaration();
      } else {
        node.typeParameters = null;
      }

      node.right = this.flowParseTypeInitialiser(types.eq);
      this.semicolon();
      return this.finishNode(node, "TypeAlias");
    }

    flowParseOpaqueType(node, declare) {
      this.expectContextual("type");
      node.id = this.flowParseRestrictedIdentifier(true, true);
      this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start);

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterDeclaration();
      } else {
        node.typeParameters = null;
      }

      node.supertype = null;

      if (this.match(types.colon)) {
        node.supertype = this.flowParseTypeInitialiser(types.colon);
      }

      node.impltype = null;

      if (!declare) {
        node.impltype = this.flowParseTypeInitialiser(types.eq);
      }

      this.semicolon();
      return this.finishNode(node, "OpaqueType");
    }

    flowParseTypeParameter(requireDefault = false) {
      const nodeStart = this.state.start;
      const node = this.startNode();
      const variance = this.flowParseVariance();
      const ident = this.flowParseTypeAnnotatableIdentifier();
      node.name = ident.name;
      node.variance = variance;
      node.bound = ident.typeAnnotation;

      if (this.match(types.eq)) {
        this.eat(types.eq);
        node.default = this.flowParseType();
      } else {
        if (requireDefault) {
          this.raise(nodeStart, FlowErrors.MissingTypeParamDefault);
        }
      }

      return this.finishNode(node, "TypeParameter");
    }

    flowParseTypeParameterDeclaration() {
      const oldInType = this.state.inType;
      const node = this.startNode();
      node.params = [];
      this.state.inType = true;

      if (this.isRelational("<") || this.match(types.jsxTagStart)) {
        this.next();
      } else {
        this.unexpected();
      }

      let defaultRequired = false;

      do {
        const typeParameter = this.flowParseTypeParameter(defaultRequired);
        node.params.push(typeParameter);

        if (typeParameter.default) {
          defaultRequired = true;
        }

        if (!this.isRelational(">")) {
          this.expect(types.comma);
        }
      } while (!this.isRelational(">"));

      this.expectRelational(">");
      this.state.inType = oldInType;
      return this.finishNode(node, "TypeParameterDeclaration");
    }

    flowParseTypeParameterInstantiation() {
      const node = this.startNode();
      const oldInType = this.state.inType;
      node.params = [];
      this.state.inType = true;
      this.expectRelational("<");
      const oldNoAnonFunctionType = this.state.noAnonFunctionType;
      this.state.noAnonFunctionType = false;

      while (!this.isRelational(">")) {
        node.params.push(this.flowParseType());

        if (!this.isRelational(">")) {
          this.expect(types.comma);
        }
      }

      this.state.noAnonFunctionType = oldNoAnonFunctionType;
      this.expectRelational(">");
      this.state.inType = oldInType;
      return this.finishNode(node, "TypeParameterInstantiation");
    }

    flowParseTypeParameterInstantiationCallOrNew() {
      const node = this.startNode();
      const oldInType = this.state.inType;
      node.params = [];
      this.state.inType = true;
      this.expectRelational("<");

      while (!this.isRelational(">")) {
        node.params.push(this.flowParseTypeOrImplicitInstantiation());

        if (!this.isRelational(">")) {
          this.expect(types.comma);
        }
      }

      this.expectRelational(">");
      this.state.inType = oldInType;
      return this.finishNode(node, "TypeParameterInstantiation");
    }

    flowParseInterfaceType() {
      const node = this.startNode();
      this.expectContextual("interface");
      node.extends = [];

      if (this.eat(types._extends)) {
        do {
          node.extends.push(this.flowParseInterfaceExtends());
        } while (this.eat(types.comma));
      }

      node.body = this.flowParseObjectType({
        allowStatic: false,
        allowExact: false,
        allowSpread: false,
        allowProto: false,
        allowInexact: false
      });
      return this.finishNode(node, "InterfaceTypeAnnotation");
    }

    flowParseObjectPropertyKey() {
      return this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true);
    }

    flowParseObjectTypeIndexer(node, isStatic, variance) {
      node.static = isStatic;

      if (this.lookahead().type === types.colon) {
        node.id = this.flowParseObjectPropertyKey();
        node.key = this.flowParseTypeInitialiser();
      } else {
        node.id = null;
        node.key = this.flowParseType();
      }

      this.expect(types.bracketR);
      node.value = this.flowParseTypeInitialiser();
      node.variance = variance;
      return this.finishNode(node, "ObjectTypeIndexer");
    }

    flowParseObjectTypeInternalSlot(node, isStatic) {
      node.static = isStatic;
      node.id = this.flowParseObjectPropertyKey();
      this.expect(types.bracketR);
      this.expect(types.bracketR);

      if (this.isRelational("<") || this.match(types.parenL)) {
        node.method = true;
        node.optional = false;
        node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start));
      } else {
        node.method = false;

        if (this.eat(types.question)) {
          node.optional = true;
        }

        node.value = this.flowParseTypeInitialiser();
      }

      return this.finishNode(node, "ObjectTypeInternalSlot");
    }

    flowParseObjectTypeMethodish(node) {
      node.params = [];
      node.rest = null;
      node.typeParameters = null;

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterDeclaration();
      }

      this.expect(types.parenL);

      while (!this.match(types.parenR) && !this.match(types.ellipsis)) {
        node.params.push(this.flowParseFunctionTypeParam());

        if (!this.match(types.parenR)) {
          this.expect(types.comma);
        }
      }

      if (this.eat(types.ellipsis)) {
        node.rest = this.flowParseFunctionTypeParam();
      }

      this.expect(types.parenR);
      node.returnType = this.flowParseTypeInitialiser();
      return this.finishNode(node, "FunctionTypeAnnotation");
    }

    flowParseObjectTypeCallProperty(node, isStatic) {
      const valueNode = this.startNode();
      node.static = isStatic;
      node.value = this.flowParseObjectTypeMethodish(valueNode);
      return this.finishNode(node, "ObjectTypeCallProperty");
    }

    flowParseObjectType({
      allowStatic,
      allowExact,
      allowSpread,
      allowProto,
      allowInexact
    }) {
      const oldInType = this.state.inType;
      this.state.inType = true;
      const nodeStart = this.startNode();
      nodeStart.callProperties = [];
      nodeStart.properties = [];
      nodeStart.indexers = [];
      nodeStart.internalSlots = [];
      let endDelim;
      let exact;
      let inexact = false;

      if (allowExact && this.match(types.braceBarL)) {
        this.expect(types.braceBarL);
        endDelim = types.braceBarR;
        exact = true;
      } else {
        this.expect(types.braceL);
        endDelim = types.braceR;
        exact = false;
      }

      nodeStart.exact = exact;

      while (!this.match(endDelim)) {
        let isStatic = false;
        let protoStart = null;
        let inexactStart = null;
        const node = this.startNode();

        if (allowProto && this.isContextual("proto")) {
          const lookahead = this.lookahead();

          if (lookahead.type !== types.colon && lookahead.type !== types.question) {
            this.next();
            protoStart = this.state.start;
            allowStatic = false;
          }
        }

        if (allowStatic && this.isContextual("static")) {
          const lookahead = this.lookahead();

          if (lookahead.type !== types.colon && lookahead.type !== types.question) {
            this.next();
            isStatic = true;
          }
        }

        const variance = this.flowParseVariance();

        if (this.eat(types.bracketL)) {
          if (protoStart != null) {
            this.unexpected(protoStart);
          }

          if (this.eat(types.bracketL)) {
            if (variance) {
              this.unexpected(variance.start);
            }

            nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic));
          } else {
            nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance));
          }
        } else if (this.match(types.parenL) || this.isRelational("<")) {
          if (protoStart != null) {
            this.unexpected(protoStart);
          }

          if (variance) {
            this.unexpected(variance.start);
          }

          nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic));
        } else {
          let kind = "init";

          if (this.isContextual("get") || this.isContextual("set")) {
            const lookahead = this.lookahead();

            if (lookahead.type === types.name || lookahead.type === types.string || lookahead.type === types.num) {
              kind = this.state.value;
              this.next();
            }
          }

          const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact);

          if (propOrInexact === null) {
            inexact = true;
            inexactStart = this.state.lastTokStart;
          } else {
            nodeStart.properties.push(propOrInexact);
          }
        }

        this.flowObjectTypeSemicolon();

        if (inexactStart && !this.match(types.braceR) && !this.match(types.braceBarR)) {
          this.raise(inexactStart, FlowErrors.UnexpectedExplicitInexactInObject);
        }
      }

      this.expect(endDelim);

      if (allowSpread) {
        nodeStart.inexact = inexact;
      }

      const out = this.finishNode(nodeStart, "ObjectTypeAnnotation");
      this.state.inType = oldInType;
      return out;
    }

    flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact) {
      if (this.eat(types.ellipsis)) {
        const isInexactToken = this.match(types.comma) || this.match(types.semi) || this.match(types.braceR) || this.match(types.braceBarR);

        if (isInexactToken) {
          if (!allowSpread) {
            this.raise(this.state.lastTokStart, FlowErrors.InexactInsideNonObject);
          } else if (!allowInexact) {
            this.raise(this.state.lastTokStart, FlowErrors.InexactInsideExact);
          }

          if (variance) {
            this.raise(variance.start, FlowErrors.InexactVariance);
          }

          return null;
        }

        if (!allowSpread) {
          this.raise(this.state.lastTokStart, FlowErrors.UnexpectedSpreadType);
        }

        if (protoStart != null) {
          this.unexpected(protoStart);
        }

        if (variance) {
          this.raise(variance.start, FlowErrors.SpreadVariance);
        }

        node.argument = this.flowParseType();
        return this.finishNode(node, "ObjectTypeSpreadProperty");
      } else {
        node.key = this.flowParseObjectPropertyKey();
        node.static = isStatic;
        node.proto = protoStart != null;
        node.kind = kind;
        let optional = false;

        if (this.isRelational("<") || this.match(types.parenL)) {
          node.method = true;

          if (protoStart != null) {
            this.unexpected(protoStart);
          }

          if (variance) {
            this.unexpected(variance.start);
          }

          node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start));

          if (kind === "get" || kind === "set") {
            this.flowCheckGetterSetterParams(node);
          }
        } else {
          if (kind !== "init") this.unexpected();
          node.method = false;

          if (this.eat(types.question)) {
            optional = true;
          }

          node.value = this.flowParseTypeInitialiser();
          node.variance = variance;
        }

        node.optional = optional;
        return this.finishNode(node, "ObjectTypeProperty");
      }
    }

    flowCheckGetterSetterParams(property) {
      const paramCount = property.kind === "get" ? 0 : 1;
      const start = property.start;
      const length = property.value.params.length + (property.value.rest ? 1 : 0);

      if (length !== paramCount) {
        if (property.kind === "get") {
          this.raise(start, ErrorMessages.BadGetterArity);
        } else {
          this.raise(start, ErrorMessages.BadSetterArity);
        }
      }

      if (property.kind === "set" && property.value.rest) {
        this.raise(start, ErrorMessages.BadSetterRestParameter);
      }
    }

    flowObjectTypeSemicolon() {
      if (!this.eat(types.semi) && !this.eat(types.comma) && !this.match(types.braceR) && !this.match(types.braceBarR)) {
        this.unexpected();
      }
    }

    flowParseQualifiedTypeIdentifier(startPos, startLoc, id) {
      startPos = startPos || this.state.start;
      startLoc = startLoc || this.state.startLoc;
      let node = id || this.flowParseRestrictedIdentifier(true);

      while (this.eat(types.dot)) {
        const node2 = this.startNodeAt(startPos, startLoc);
        node2.qualification = node;
        node2.id = this.flowParseRestrictedIdentifier(true);
        node = this.finishNode(node2, "QualifiedTypeIdentifier");
      }

      return node;
    }

    flowParseGenericType(startPos, startLoc, id) {
      const node = this.startNodeAt(startPos, startLoc);
      node.typeParameters = null;
      node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id);

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterInstantiation();
      }

      return this.finishNode(node, "GenericTypeAnnotation");
    }

    flowParseTypeofType() {
      const node = this.startNode();
      this.expect(types._typeof);
      node.argument = this.flowParsePrimaryType();
      return this.finishNode(node, "TypeofTypeAnnotation");
    }

    flowParseTupleType() {
      const node = this.startNode();
      node.types = [];
      this.expect(types.bracketL);

      while (this.state.pos < this.length && !this.match(types.bracketR)) {
        node.types.push(this.flowParseType());
        if (this.match(types.bracketR)) break;
        this.expect(types.comma);
      }

      this.expect(types.bracketR);
      return this.finishNode(node, "TupleTypeAnnotation");
    }

    flowParseFunctionTypeParam() {
      let name = null;
      let optional = false;
      let typeAnnotation = null;
      const node = this.startNode();
      const lh = this.lookahead();

      if (lh.type === types.colon || lh.type === types.question) {
        name = this.parseIdentifier();

        if (this.eat(types.question)) {
          optional = true;
        }

        typeAnnotation = this.flowParseTypeInitialiser();
      } else {
        typeAnnotation = this.flowParseType();
      }

      node.name = name;
      node.optional = optional;
      node.typeAnnotation = typeAnnotation;
      return this.finishNode(node, "FunctionTypeParam");
    }

    reinterpretTypeAsFunctionTypeParam(type) {
      const node = this.startNodeAt(type.start, type.loc.start);
      node.name = null;
      node.optional = false;
      node.typeAnnotation = type;
      return this.finishNode(node, "FunctionTypeParam");
    }

    flowParseFunctionTypeParams(params = []) {
      let rest = null;

      while (!this.match(types.parenR) && !this.match(types.ellipsis)) {
        params.push(this.flowParseFunctionTypeParam());

        if (!this.match(types.parenR)) {
          this.expect(types.comma);
        }
      }

      if (this.eat(types.ellipsis)) {
        rest = this.flowParseFunctionTypeParam();
      }

      return {
        params,
        rest
      };
    }

    flowIdentToTypeAnnotation(startPos, startLoc, node, id) {
      switch (id.name) {
        case "any":
          return this.finishNode(node, "AnyTypeAnnotation");

        case "bool":
        case "boolean":
          return this.finishNode(node, "BooleanTypeAnnotation");

        case "mixed":
          return this.finishNode(node, "MixedTypeAnnotation");

        case "empty":
          return this.finishNode(node, "EmptyTypeAnnotation");

        case "number":
          return this.finishNode(node, "NumberTypeAnnotation");

        case "string":
          return this.finishNode(node, "StringTypeAnnotation");

        case "symbol":
          return this.finishNode(node, "SymbolTypeAnnotation");

        default:
          this.checkNotUnderscore(id.name);
          return this.flowParseGenericType(startPos, startLoc, id);
      }
    }

    flowParsePrimaryType() {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const node = this.startNode();
      let tmp;
      let type;
      let isGroupedType = false;
      const oldNoAnonFunctionType = this.state.noAnonFunctionType;

      switch (this.state.type) {
        case types.name:
          if (this.isContextual("interface")) {
            return this.flowParseInterfaceType();
          }

          return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier());

        case types.braceL:
          return this.flowParseObjectType({
            allowStatic: false,
            allowExact: false,
            allowSpread: true,
            allowProto: false,
            allowInexact: true
          });

        case types.braceBarL:
          return this.flowParseObjectType({
            allowStatic: false,
            allowExact: true,
            allowSpread: true,
            allowProto: false,
            allowInexact: false
          });

        case types.bracketL:
          this.state.noAnonFunctionType = false;
          type = this.flowParseTupleType();
          this.state.noAnonFunctionType = oldNoAnonFunctionType;
          return type;

        case types.relational:
          if (this.state.value === "<") {
            node.typeParameters = this.flowParseTypeParameterDeclaration();
            this.expect(types.parenL);
            tmp = this.flowParseFunctionTypeParams();
            node.params = tmp.params;
            node.rest = tmp.rest;
            this.expect(types.parenR);
            this.expect(types.arrow);
            node.returnType = this.flowParseType();
            return this.finishNode(node, "FunctionTypeAnnotation");
          }

          break;

        case types.parenL:
          this.next();

          if (!this.match(types.parenR) && !this.match(types.ellipsis)) {
            if (this.match(types.name)) {
              const token = this.lookahead().type;
              isGroupedType = token !== types.question && token !== types.colon;
            } else {
              isGroupedType = true;
            }
          }

          if (isGroupedType) {
            this.state.noAnonFunctionType = false;
            type = this.flowParseType();
            this.state.noAnonFunctionType = oldNoAnonFunctionType;

            if (this.state.noAnonFunctionType || !(this.match(types.comma) || this.match(types.parenR) && this.lookahead().type === types.arrow)) {
              this.expect(types.parenR);
              return type;
            } else {
              this.eat(types.comma);
            }
          }

          if (type) {
            tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]);
          } else {
            tmp = this.flowParseFunctionTypeParams();
          }

          node.params = tmp.params;
          node.rest = tmp.rest;
          this.expect(types.parenR);
          this.expect(types.arrow);
          node.returnType = this.flowParseType();
          node.typeParameters = null;
          return this.finishNode(node, "FunctionTypeAnnotation");

        case types.string:
          return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation");

        case types._true:
        case types._false:
          node.value = this.match(types._true);
          this.next();
          return this.finishNode(node, "BooleanLiteralTypeAnnotation");

        case types.plusMin:
          if (this.state.value === "-") {
            this.next();

            if (this.match(types.num)) {
              return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start);
            }

            if (this.match(types.bigint)) {
              return this.parseLiteral(-this.state.value, "BigIntLiteralTypeAnnotation", node.start, node.loc.start);
            }

            throw this.raise(this.state.start, FlowErrors.UnexpectedSubtractionOperand);
          }

          throw this.unexpected();

        case types.num:
          return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation");

        case types.bigint:
          return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation");

        case types._void:
          this.next();
          return this.finishNode(node, "VoidTypeAnnotation");

        case types._null:
          this.next();
          return this.finishNode(node, "NullLiteralTypeAnnotation");

        case types._this:
          this.next();
          return this.finishNode(node, "ThisTypeAnnotation");

        case types.star:
          this.next();
          return this.finishNode(node, "ExistsTypeAnnotation");

        default:
          if (this.state.type.keyword === "typeof") {
            return this.flowParseTypeofType();
          } else if (this.state.type.keyword) {
            const label = this.state.type.label;
            this.next();
            return super.createIdentifier(node, label);
          }

      }

      throw this.unexpected();
    }

    flowParsePostfixType() {
      const startPos = this.state.start,
            startLoc = this.state.startLoc;
      let type = this.flowParsePrimaryType();

      while (this.match(types.bracketL) && !this.canInsertSemicolon()) {
        const node = this.startNodeAt(startPos, startLoc);
        node.elementType = type;
        this.expect(types.bracketL);
        this.expect(types.bracketR);
        type = this.finishNode(node, "ArrayTypeAnnotation");
      }

      return type;
    }

    flowParsePrefixType() {
      const node = this.startNode();

      if (this.eat(types.question)) {
        node.typeAnnotation = this.flowParsePrefixType();
        return this.finishNode(node, "NullableTypeAnnotation");
      } else {
        return this.flowParsePostfixType();
      }
    }

    flowParseAnonFunctionWithoutParens() {
      const param = this.flowParsePrefixType();

      if (!this.state.noAnonFunctionType && this.eat(types.arrow)) {
        const node = this.startNodeAt(param.start, param.loc.start);
        node.params = [this.reinterpretTypeAsFunctionTypeParam(param)];
        node.rest = null;
        node.returnType = this.flowParseType();
        node.typeParameters = null;
        return this.finishNode(node, "FunctionTypeAnnotation");
      }

      return param;
    }

    flowParseIntersectionType() {
      const node = this.startNode();
      this.eat(types.bitwiseAND);
      const type = this.flowParseAnonFunctionWithoutParens();
      node.types = [type];

      while (this.eat(types.bitwiseAND)) {
        node.types.push(this.flowParseAnonFunctionWithoutParens());
      }

      return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
    }

    flowParseUnionType() {
      const node = this.startNode();
      this.eat(types.bitwiseOR);
      const type = this.flowParseIntersectionType();
      node.types = [type];

      while (this.eat(types.bitwiseOR)) {
        node.types.push(this.flowParseIntersectionType());
      }

      return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
    }

    flowParseType() {
      const oldInType = this.state.inType;
      this.state.inType = true;
      const type = this.flowParseUnionType();
      this.state.inType = oldInType;
      this.state.exprAllowed = this.state.exprAllowed || this.state.noAnonFunctionType;
      return type;
    }

    flowParseTypeOrImplicitInstantiation() {
      if (this.state.type === types.name && this.state.value === "_") {
        const startPos = this.state.start;
        const startLoc = this.state.startLoc;
        const node = this.parseIdentifier();
        return this.flowParseGenericType(startPos, startLoc, node);
      } else {
        return this.flowParseType();
      }
    }

    flowParseTypeAnnotation() {
      const node = this.startNode();
      node.typeAnnotation = this.flowParseTypeInitialiser();
      return this.finishNode(node, "TypeAnnotation");
    }

    flowParseTypeAnnotatableIdentifier(allowPrimitiveOverride) {
      const ident = allowPrimitiveOverride ? this.parseIdentifier() : this.flowParseRestrictedIdentifier();

      if (this.match(types.colon)) {
        ident.typeAnnotation = this.flowParseTypeAnnotation();
        this.resetEndLocation(ident);
      }

      return ident;
    }

    typeCastToParameter(node) {
      node.expression.typeAnnotation = node.typeAnnotation;
      this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end);
      return node.expression;
    }

    flowParseVariance() {
      let variance = null;

      if (this.match(types.plusMin)) {
        variance = this.startNode();

        if (this.state.value === "+") {
          variance.kind = "plus";
        } else {
          variance.kind = "minus";
        }

        this.next();
        this.finishNode(variance, "Variance");
      }

      return variance;
    }

    parseFunctionBody(node, allowExpressionBody, isMethod = false) {
      if (allowExpressionBody) {
        return this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod));
      }

      return super.parseFunctionBody(node, false, isMethod);
    }

    parseFunctionBodyAndFinish(node, type, isMethod = false) {
      if (this.match(types.colon)) {
        const typeNode = this.startNode();
        [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
        node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null;
      }

      super.parseFunctionBodyAndFinish(node, type, isMethod);
    }

    parseStatement(context, topLevel) {
      if (this.state.strict && this.match(types.name) && this.state.value === "interface") {
        const node = this.startNode();
        this.next();
        return this.flowParseInterface(node);
      } else if (this.shouldParseEnums() && this.isContextual("enum")) {
        const node = this.startNode();
        this.next();
        return this.flowParseEnumDeclaration(node);
      } else {
        const stmt = super.parseStatement(context, topLevel);

        if (this.flowPragma === undefined && !this.isValidDirective(stmt)) {
          this.flowPragma = null;
        }

        return stmt;
      }
    }

    parseExpressionStatement(node, expr) {
      if (expr.type === "Identifier") {
        if (expr.name === "declare") {
          if (this.match(types._class) || this.match(types.name) || this.match(types._function) || this.match(types._var) || this.match(types._export)) {
            return this.flowParseDeclare(node);
          }
        } else if (this.match(types.name)) {
          if (expr.name === "interface") {
            return this.flowParseInterface(node);
          } else if (expr.name === "type") {
            return this.flowParseTypeAlias(node);
          } else if (expr.name === "opaque") {
            return this.flowParseOpaqueType(node, false);
          }
        }
      }

      return super.parseExpressionStatement(node, expr);
    }

    shouldParseExportDeclaration() {
      return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || this.shouldParseEnums() && this.isContextual("enum") || super.shouldParseExportDeclaration();
    }

    isExportDefaultSpecifier() {
      if (this.match(types.name) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque" || this.shouldParseEnums() && this.state.value === "enum")) {
        return false;
      }

      return super.isExportDefaultSpecifier();
    }

    parseExportDefaultExpression() {
      if (this.shouldParseEnums() && this.isContextual("enum")) {
        const node = this.startNode();
        this.next();
        return this.flowParseEnumDeclaration(node);
      }

      return super.parseExportDefaultExpression();
    }

    parseConditional(expr, startPos, startLoc, refNeedsArrowPos) {
      if (!this.match(types.question)) return expr;

      if (refNeedsArrowPos) {
        const result = this.tryParse(() => super.parseConditional(expr, startPos, startLoc));

        if (!result.node) {
          refNeedsArrowPos.start = result.error.pos || this.state.start;
          return expr;
        }

        if (result.error) this.state = result.failState;
        return result.node;
      }

      this.expect(types.question);
      const state = this.state.clone();
      const originalNoArrowAt = this.state.noArrowAt;
      const node = this.startNodeAt(startPos, startLoc);
      let {
        consequent,
        failed
      } = this.tryParseConditionalConsequent();
      let [valid, invalid] = this.getArrowLikeExpressions(consequent);

      if (failed || invalid.length > 0) {
        const noArrowAt = [...originalNoArrowAt];

        if (invalid.length > 0) {
          this.state = state;
          this.state.noArrowAt = noArrowAt;

          for (let i = 0; i < invalid.length; i++) {
            noArrowAt.push(invalid[i].start);
          }

          ({
            consequent,
            failed
          } = this.tryParseConditionalConsequent());
          [valid, invalid] = this.getArrowLikeExpressions(consequent);
        }

        if (failed && valid.length > 1) {
          this.raise(state.start, FlowErrors.AmbiguousConditionalArrow);
        }

        if (failed && valid.length === 1) {
          this.state = state;
          this.state.noArrowAt = noArrowAt.concat(valid[0].start);
          ({
            consequent,
            failed
          } = this.tryParseConditionalConsequent());
        }
      }

      this.getArrowLikeExpressions(consequent, true);
      this.state.noArrowAt = originalNoArrowAt;
      this.expect(types.colon);
      node.test = expr;
      node.consequent = consequent;
      node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(undefined, undefined, undefined));
      return this.finishNode(node, "ConditionalExpression");
    }

    tryParseConditionalConsequent() {
      this.state.noArrowParamsConversionAt.push(this.state.start);
      const consequent = this.parseMaybeAssignAllowIn();
      const failed = !this.match(types.colon);
      this.state.noArrowParamsConversionAt.pop();
      return {
        consequent,
        failed
      };
    }

    getArrowLikeExpressions(node, disallowInvalid) {
      const stack = [node];
      const arrows = [];

      while (stack.length !== 0) {
        const node = stack.pop();

        if (node.type === "ArrowFunctionExpression") {
          if (node.typeParameters || !node.returnType) {
            this.finishArrowValidation(node);
          } else {
            arrows.push(node);
          }

          stack.push(node.body);
        } else if (node.type === "ConditionalExpression") {
          stack.push(node.consequent);
          stack.push(node.alternate);
        }
      }

      if (disallowInvalid) {
        arrows.forEach(node => this.finishArrowValidation(node));
        return [arrows, []];
      }

      return partition(arrows, node => node.params.every(param => this.isAssignable(param, true)));
    }

    finishArrowValidation(node) {
      var _node$extra;

      this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingComma);
      this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW);
      super.checkParams(node, false, true);
      this.scope.exit();
    }

    forwardNoArrowParamsConversionAt(node, parse) {
      let result;

      if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
        this.state.noArrowParamsConversionAt.push(this.state.start);
        result = parse();
        this.state.noArrowParamsConversionAt.pop();
      } else {
        result = parse();
      }

      return result;
    }

    parseParenItem(node, startPos, startLoc) {
      node = super.parseParenItem(node, startPos, startLoc);

      if (this.eat(types.question)) {
        node.optional = true;
        this.resetEndLocation(node);
      }

      if (this.match(types.colon)) {
        const typeCastNode = this.startNodeAt(startPos, startLoc);
        typeCastNode.expression = node;
        typeCastNode.typeAnnotation = this.flowParseTypeAnnotation();
        return this.finishNode(typeCastNode, "TypeCastExpression");
      }

      return node;
    }

    assertModuleNodeAllowed(node) {
      if (node.type === "ImportDeclaration" && (node.importKind === "type" || node.importKind === "typeof") || node.type === "ExportNamedDeclaration" && node.exportKind === "type" || node.type === "ExportAllDeclaration" && node.exportKind === "type") {
        return;
      }

      super.assertModuleNodeAllowed(node);
    }

    parseExport(node) {
      const decl = super.parseExport(node);

      if (decl.type === "ExportNamedDeclaration" || decl.type === "ExportAllDeclaration") {
        decl.exportKind = decl.exportKind || "value";
      }

      return decl;
    }

    parseExportDeclaration(node) {
      if (this.isContextual("type")) {
        node.exportKind = "type";
        const declarationNode = this.startNode();
        this.next();

        if (this.match(types.braceL)) {
          node.specifiers = this.parseExportSpecifiers();
          this.parseExportFrom(node);
          return null;
        } else {
          return this.flowParseTypeAlias(declarationNode);
        }
      } else if (this.isContextual("opaque")) {
        node.exportKind = "type";
        const declarationNode = this.startNode();
        this.next();
        return this.flowParseOpaqueType(declarationNode, false);
      } else if (this.isContextual("interface")) {
        node.exportKind = "type";
        const declarationNode = this.startNode();
        this.next();
        return this.flowParseInterface(declarationNode);
      } else if (this.shouldParseEnums() && this.isContextual("enum")) {
        node.exportKind = "value";
        const declarationNode = this.startNode();
        this.next();
        return this.flowParseEnumDeclaration(declarationNode);
      } else {
        return super.parseExportDeclaration(node);
      }
    }

    eatExportStar(node) {
      if (super.eatExportStar(...arguments)) return true;

      if (this.isContextual("type") && this.lookahead().type === types.star) {
        node.exportKind = "type";
        this.next();
        this.next();
        return true;
      }

      return false;
    }

    maybeParseExportNamespaceSpecifier(node) {
      const pos = this.state.start;
      const hasNamespace = super.maybeParseExportNamespaceSpecifier(node);

      if (hasNamespace && node.exportKind === "type") {
        this.unexpected(pos);
      }

      return hasNamespace;
    }

    parseClassId(node, isStatement, optionalId) {
      super.parseClassId(node, isStatement, optionalId);

      if (this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterDeclaration();
      }
    }

    parseClassMember(classBody, member, state, constructorAllowsSuper) {
      const pos = this.state.start;

      if (this.isContextual("declare")) {
        if (this.parseClassMemberFromModifier(classBody, member)) {
          return;
        }

        member.declare = true;
      }

      super.parseClassMember(classBody, member, state, constructorAllowsSuper);

      if (member.declare) {
        if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty") {
          this.raise(pos, FlowErrors.DeclareClassElement);
        } else if (member.value) {
          this.raise(member.value.start, FlowErrors.DeclareClassFieldInitializer);
        }
      }
    }

    getTokenFromCode(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (code === 123 && next === 124) {
        return this.finishOp(types.braceBarL, 2);
      } else if (this.state.inType && (code === 62 || code === 60)) {
        return this.finishOp(types.relational, 1);
      } else if (this.state.inType && code === 63) {
        return this.finishOp(types.question, 1);
      } else if (isIteratorStart(code, next)) {
        this.state.isIterator = true;
        return super.readWord();
      } else {
        return super.getTokenFromCode(code);
      }
    }

    isAssignable(node, isBinding) {
      switch (node.type) {
        case "Identifier":
        case "ObjectPattern":
        case "ArrayPattern":
        case "AssignmentPattern":
          return true;

        case "ObjectExpression":
          {
            const last = node.properties.length - 1;
            return node.properties.every((prop, i) => {
              return prop.type !== "ObjectMethod" && (i === last || prop.type === "SpreadElement") && this.isAssignable(prop);
            });
          }

        case "ObjectProperty":
          return this.isAssignable(node.value);

        case "SpreadElement":
          return this.isAssignable(node.argument);

        case "ArrayExpression":
          return node.elements.every(element => this.isAssignable(element));

        case "AssignmentExpression":
          return node.operator === "=";

        case "ParenthesizedExpression":
        case "TypeCastExpression":
          return this.isAssignable(node.expression);

        case "MemberExpression":
        case "OptionalMemberExpression":
          return !isBinding;

        default:
          return false;
      }
    }

    toAssignable(node) {
      if (node.type === "TypeCastExpression") {
        return super.toAssignable(this.typeCastToParameter(node));
      } else {
        return super.toAssignable(node);
      }
    }

    toAssignableList(exprList, trailingCommaPos) {
      for (let i = 0; i < exprList.length; i++) {
        const expr = exprList[i];

        if ((expr == null ? void 0 : expr.type) === "TypeCastExpression") {
          exprList[i] = this.typeCastToParameter(expr);
        }
      }

      return super.toAssignableList(exprList, trailingCommaPos);
    }

    toReferencedList(exprList, isParenthesizedExpr) {
      for (let i = 0; i < exprList.length; i++) {
        var _expr$extra;

        const expr = exprList[i];

        if (expr && expr.type === "TypeCastExpression" && !((_expr$extra = expr.extra) == null ? void 0 : _expr$extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) {
          this.raise(expr.typeAnnotation.start, FlowErrors.TypeCastInPattern);
        }
      }

      return exprList;
    }

    checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription) {
      if (expr.type !== "TypeCastExpression") {
        return super.checkLVal(expr, bindingType, checkClashes, contextDescription);
      }
    }

    parseClassProperty(node) {
      if (this.match(types.colon)) {
        node.typeAnnotation = this.flowParseTypeAnnotation();
      }

      return super.parseClassProperty(node);
    }

    parseClassPrivateProperty(node) {
      if (this.match(types.colon)) {
        node.typeAnnotation = this.flowParseTypeAnnotation();
      }

      return super.parseClassPrivateProperty(node);
    }

    isClassMethod() {
      return this.isRelational("<") || super.isClassMethod();
    }

    isClassProperty() {
      return this.match(types.colon) || super.isClassProperty();
    }

    isNonstaticConstructor(method) {
      return !this.match(types.colon) && super.isNonstaticConstructor(method);
    }

    pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
      if (method.variance) {
        this.unexpected(method.variance.start);
      }

      delete method.variance;

      if (this.isRelational("<")) {
        method.typeParameters = this.flowParseTypeParameterDeclaration();
      }

      super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper);
    }

    pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
      if (method.variance) {
        this.unexpected(method.variance.start);
      }

      delete method.variance;

      if (this.isRelational("<")) {
        method.typeParameters = this.flowParseTypeParameterDeclaration();
      }

      super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync);
    }

    parseClassSuper(node) {
      super.parseClassSuper(node);

      if (node.superClass && this.isRelational("<")) {
        node.superTypeParameters = this.flowParseTypeParameterInstantiation();
      }

      if (this.isContextual("implements")) {
        this.next();
        const implemented = node.implements = [];

        do {
          const node = this.startNode();
          node.id = this.flowParseRestrictedIdentifier(true);

          if (this.isRelational("<")) {
            node.typeParameters = this.flowParseTypeParameterInstantiation();
          } else {
            node.typeParameters = null;
          }

          implemented.push(this.finishNode(node, "ClassImplements"));
        } while (this.eat(types.comma));
      }
    }

    parsePropertyName(node, isPrivateNameAllowed) {
      const variance = this.flowParseVariance();
      const key = super.parsePropertyName(node, isPrivateNameAllowed);
      node.variance = variance;
      return key;
    }

    parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
      if (prop.variance) {
        this.unexpected(prop.variance.start);
      }

      delete prop.variance;
      let typeParameters;

      if (this.isRelational("<") && !isAccessor) {
        typeParameters = this.flowParseTypeParameterDeclaration();
        if (!this.match(types.parenL)) this.unexpected();
      }

      super.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors);

      if (typeParameters) {
        (prop.value || prop).typeParameters = typeParameters;
      }
    }

    parseAssignableListItemTypes(param) {
      if (this.eat(types.question)) {
        if (param.type !== "Identifier") {
          this.raise(param.start, FlowErrors.OptionalBindingPattern);
        }

        param.optional = true;
      }

      if (this.match(types.colon)) {
        param.typeAnnotation = this.flowParseTypeAnnotation();
      }

      this.resetEndLocation(param);
      return param;
    }

    parseMaybeDefault(startPos, startLoc, left) {
      const node = super.parseMaybeDefault(startPos, startLoc, left);

      if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
        this.raise(node.typeAnnotation.start, FlowErrors.TypeBeforeInitializer);
      }

      return node;
    }

    shouldParseDefaultImport(node) {
      if (!hasTypeImportKind(node)) {
        return super.shouldParseDefaultImport(node);
      }

      return isMaybeDefaultImport(this.state);
    }

    parseImportSpecifierLocal(node, specifier, type, contextDescription) {
      specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier();
      this.checkLVal(specifier.local, BIND_LEXICAL, undefined, contextDescription);
      node.specifiers.push(this.finishNode(specifier, type));
    }

    maybeParseDefaultImportSpecifier(node) {
      node.importKind = "value";
      let kind = null;

      if (this.match(types._typeof)) {
        kind = "typeof";
      } else if (this.isContextual("type")) {
        kind = "type";
      }

      if (kind) {
        const lh = this.lookahead();

        if (kind === "type" && lh.type === types.star) {
          this.unexpected(lh.start);
        }

        if (isMaybeDefaultImport(lh) || lh.type === types.braceL || lh.type === types.star) {
          this.next();
          node.importKind = kind;
        }
      }

      return super.maybeParseDefaultImportSpecifier(node);
    }

    parseImportSpecifier(node) {
      const specifier = this.startNode();
      const firstIdentLoc = this.state.start;
      const firstIdent = this.parseIdentifier(true);
      let specifierTypeKind = null;

      if (firstIdent.name === "type") {
        specifierTypeKind = "type";
      } else if (firstIdent.name === "typeof") {
        specifierTypeKind = "typeof";
      }

      let isBinding = false;

      if (this.isContextual("as") && !this.isLookaheadContextual("as")) {
        const as_ident = this.parseIdentifier(true);

        if (specifierTypeKind !== null && !this.match(types.name) && !this.state.type.keyword) {
          specifier.imported = as_ident;
          specifier.importKind = specifierTypeKind;
          specifier.local = as_ident.__clone();
        } else {
          specifier.imported = firstIdent;
          specifier.importKind = null;
          specifier.local = this.parseIdentifier();
        }
      } else if (specifierTypeKind !== null && (this.match(types.name) || this.state.type.keyword)) {
        specifier.imported = this.parseIdentifier(true);
        specifier.importKind = specifierTypeKind;

        if (this.eatContextual("as")) {
          specifier.local = this.parseIdentifier();
        } else {
          isBinding = true;
          specifier.local = specifier.imported.__clone();
        }
      } else {
        isBinding = true;
        specifier.imported = firstIdent;
        specifier.importKind = null;
        specifier.local = specifier.imported.__clone();
      }

      const nodeIsTypeImport = hasTypeImportKind(node);
      const specifierIsTypeImport = hasTypeImportKind(specifier);

      if (nodeIsTypeImport && specifierIsTypeImport) {
        this.raise(firstIdentLoc, FlowErrors.ImportTypeShorthandOnlyInPureImport);
      }

      if (nodeIsTypeImport || specifierIsTypeImport) {
        this.checkReservedType(specifier.local.name, specifier.local.start, true);
      }

      if (isBinding && !nodeIsTypeImport && !specifierIsTypeImport) {
        this.checkReservedWord(specifier.local.name, specifier.start, true, true);
      }

      this.checkLVal(specifier.local, BIND_LEXICAL, undefined, "import specifier");
      node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
    }

    parseFunctionParams(node, allowModifiers) {
      const kind = node.kind;

      if (kind !== "get" && kind !== "set" && this.isRelational("<")) {
        node.typeParameters = this.flowParseTypeParameterDeclaration();
      }

      super.parseFunctionParams(node, allowModifiers);
    }

    parseVarId(decl, kind) {
      super.parseVarId(decl, kind);

      if (this.match(types.colon)) {
        decl.id.typeAnnotation = this.flowParseTypeAnnotation();
        this.resetEndLocation(decl.id);
      }
    }

    parseAsyncArrowFromCallExpression(node, call) {
      if (this.match(types.colon)) {
        const oldNoAnonFunctionType = this.state.noAnonFunctionType;
        this.state.noAnonFunctionType = true;
        node.returnType = this.flowParseTypeAnnotation();
        this.state.noAnonFunctionType = oldNoAnonFunctionType;
      }

      return super.parseAsyncArrowFromCallExpression(node, call);
    }

    shouldParseAsyncArrow() {
      return this.match(types.colon) || super.shouldParseAsyncArrow();
    }

    parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos) {
      var _jsx;

      let state = null;
      let jsx;

      if (this.hasPlugin("jsx") && (this.match(types.jsxTagStart) || this.isRelational("<"))) {
        state = this.state.clone();
        jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos), state);
        if (!jsx.error) return jsx.node;
        const {
          context
        } = this.state;

        if (context[context.length - 1] === types$1.j_oTag) {
          context.length -= 2;
        } else if (context[context.length - 1] === types$1.j_expr) {
          context.length -= 1;
        }
      }

      if (((_jsx = jsx) == null ? void 0 : _jsx.error) || this.isRelational("<")) {
        var _jsx2, _jsx3;

        state = state || this.state.clone();
        let typeParameters;
        const arrow = this.tryParse(abort => {
          var _arrowExpression$extr;

          typeParameters = this.flowParseTypeParameterDeclaration();
          const arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => {
            const result = super.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos);
            this.resetStartLocationFromNode(result, typeParameters);
            return result;
          });

          if (arrowExpression.type !== "ArrowFunctionExpression" && ((_arrowExpression$extr = arrowExpression.extra) == null ? void 0 : _arrowExpression$extr.parenthesized)) {
            abort();
          }

          const expr = this.maybeUnwrapTypeCastExpression(arrowExpression);
          expr.typeParameters = typeParameters;
          this.resetStartLocationFromNode(expr, typeParameters);
          return arrowExpression;
        }, state);
        let arrowExpression = null;

        if (arrow.node && this.maybeUnwrapTypeCastExpression(arrow.node).type === "ArrowFunctionExpression") {
          if (!arrow.error && !arrow.aborted) {
            if (arrow.node.async) {
              this.raise(typeParameters.start, FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction);
            }

            return arrow.node;
          }

          arrowExpression = arrow.node;
        }

        if ((_jsx2 = jsx) == null ? void 0 : _jsx2.node) {
          this.state = jsx.failState;
          return jsx.node;
        }

        if (arrowExpression) {
          this.state = arrow.failState;
          return arrowExpression;
        }

        if ((_jsx3 = jsx) == null ? void 0 : _jsx3.thrown) throw jsx.error;
        if (arrow.thrown) throw arrow.error;
        throw this.raise(typeParameters.start, FlowErrors.UnexpectedTokenAfterTypeParameter);
      }

      return super.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos);
    }

    parseArrow(node) {
      if (this.match(types.colon)) {
        const result = this.tryParse(() => {
          const oldNoAnonFunctionType = this.state.noAnonFunctionType;
          this.state.noAnonFunctionType = true;
          const typeNode = this.startNode();
          [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
          this.state.noAnonFunctionType = oldNoAnonFunctionType;
          if (this.canInsertSemicolon()) this.unexpected();
          if (!this.match(types.arrow)) this.unexpected();
          return typeNode;
        });
        if (result.thrown) return null;
        if (result.error) this.state = result.failState;
        node.returnType = result.node.typeAnnotation ? this.finishNode(result.node, "TypeAnnotation") : null;
      }

      return super.parseArrow(node);
    }

    shouldParseArrow() {
      return this.match(types.colon) || super.shouldParseArrow();
    }

    setArrowFunctionParameters(node, params) {
      if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
        node.params = params;
      } else {
        super.setArrowFunctionParameters(node, params);
      }
    }

    checkParams(node, allowDuplicates, isArrowFunction) {
      if (isArrowFunction && this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) {
        return;
      }

      return super.checkParams(...arguments);
    }

    parseParenAndDistinguishExpression(canBeArrow) {
      return super.parseParenAndDistinguishExpression(canBeArrow && this.state.noArrowAt.indexOf(this.state.start) === -1);
    }

    parseSubscripts(base, startPos, startLoc, noCalls) {
      if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.indexOf(startPos) !== -1) {
        this.next();
        const node = this.startNodeAt(startPos, startLoc);
        node.callee = base;
        node.arguments = this.parseCallExpressionArguments(types.parenR, false);
        base = this.finishNode(node, "CallExpression");
      } else if (base.type === "Identifier" && base.name === "async" && this.isRelational("<")) {
        const state = this.state.clone();
        const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startPos, startLoc) || abort(), state);
        if (!arrow.error && !arrow.aborted) return arrow.node;
        const result = this.tryParse(() => super.parseSubscripts(base, startPos, startLoc, noCalls), state);
        if (result.node && !result.error) return result.node;

        if (arrow.node) {
          this.state = arrow.failState;
          return arrow.node;
        }

        if (result.node) {
          this.state = result.failState;
          return result.node;
        }

        throw arrow.error || result.error;
      }

      return super.parseSubscripts(base, startPos, startLoc, noCalls);
    }

    parseSubscript(base, startPos, startLoc, noCalls, subscriptState) {
      if (this.match(types.questionDot) && this.isLookaheadToken_lt()) {
        subscriptState.optionalChainMember = true;

        if (noCalls) {
          subscriptState.stop = true;
          return base;
        }

        this.next();
        const node = this.startNodeAt(startPos, startLoc);
        node.callee = base;
        node.typeArguments = this.flowParseTypeParameterInstantiation();
        this.expect(types.parenL);
        node.arguments = this.parseCallExpressionArguments(types.parenR, false);
        node.optional = true;
        return this.finishCallExpression(node, true);
      } else if (!noCalls && this.shouldParseTypes() && this.isRelational("<")) {
        const node = this.startNodeAt(startPos, startLoc);
        node.callee = base;
        const result = this.tryParse(() => {
          node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew();
          this.expect(types.parenL);
          node.arguments = this.parseCallExpressionArguments(types.parenR, false);
          if (subscriptState.optionalChainMember) node.optional = false;
          return this.finishCallExpression(node, subscriptState.optionalChainMember);
        });

        if (result.node) {
          if (result.error) this.state = result.failState;
          return result.node;
        }
      }

      return super.parseSubscript(base, startPos, startLoc, noCalls, subscriptState);
    }

    parseNewArguments(node) {
      let targs = null;

      if (this.shouldParseTypes() && this.isRelational("<")) {
        targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node;
      }

      node.typeArguments = targs;
      super.parseNewArguments(node);
    }

    parseAsyncArrowWithTypeParameters(startPos, startLoc) {
      const node = this.startNodeAt(startPos, startLoc);
      this.parseFunctionParams(node);
      if (!this.parseArrow(node)) return;
      return this.parseArrowExpression(node, undefined, true);
    }

    readToken_mult_modulo(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (code === 42 && next === 47 && this.state.hasFlowComment) {
        this.state.hasFlowComment = false;
        this.state.pos += 2;
        this.nextToken();
        return;
      }

      super.readToken_mult_modulo(code);
    }

    readToken_pipe_amp(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (code === 124 && next === 125) {
        this.finishOp(types.braceBarR, 2);
        return;
      }

      super.readToken_pipe_amp(code);
    }

    parseTopLevel(file, program) {
      const fileNode = super.parseTopLevel(file, program);

      if (this.state.hasFlowComment) {
        this.raise(this.state.pos, FlowErrors.UnterminatedFlowComment);
      }

      return fileNode;
    }

    skipBlockComment() {
      if (this.hasPlugin("flowComments") && this.skipFlowComment()) {
        if (this.state.hasFlowComment) {
          this.unexpected(null, FlowErrors.NestedFlowComment);
        }

        this.hasFlowCommentCompletion();
        this.state.pos += this.skipFlowComment();
        this.state.hasFlowComment = true;
        return;
      }

      if (this.state.hasFlowComment) {
        const end = this.input.indexOf("*-/", this.state.pos += 2);

        if (end === -1) {
          throw this.raise(this.state.pos - 2, ErrorMessages.UnterminatedComment);
        }

        this.state.pos = end + 3;
        return;
      }

      super.skipBlockComment();
    }

    skipFlowComment() {
      const {
        pos
      } = this.state;
      let shiftToFirstNonWhiteSpace = 2;

      while ([32, 9].includes(this.input.charCodeAt(pos + shiftToFirstNonWhiteSpace))) {
        shiftToFirstNonWhiteSpace++;
      }

      const ch2 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos);
      const ch3 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos + 1);

      if (ch2 === 58 && ch3 === 58) {
        return shiftToFirstNonWhiteSpace + 2;
      }

      if (this.input.slice(shiftToFirstNonWhiteSpace + pos, shiftToFirstNonWhiteSpace + pos + 12) === "flow-include") {
        return shiftToFirstNonWhiteSpace + 12;
      }

      if (ch2 === 58 && ch3 !== 58) {
        return shiftToFirstNonWhiteSpace;
      }

      return false;
    }

    hasFlowCommentCompletion() {
      const end = this.input.indexOf("*/", this.state.pos);

      if (end === -1) {
        throw this.raise(this.state.pos, ErrorMessages.UnterminatedComment);
      }
    }

    flowEnumErrorBooleanMemberNotInitialized(pos, {
      enumName,
      memberName
    }) {
      this.raise(pos, FlowErrors.EnumBooleanMemberNotInitialized, memberName, enumName);
    }

    flowEnumErrorInvalidMemberName(pos, {
      enumName,
      memberName
    }) {
      const suggestion = memberName[0].toUpperCase() + memberName.slice(1);
      this.raise(pos, FlowErrors.EnumInvalidMemberName, memberName, suggestion, enumName);
    }

    flowEnumErrorDuplicateMemberName(pos, {
      enumName,
      memberName
    }) {
      this.raise(pos, FlowErrors.EnumDuplicateMemberName, memberName, enumName);
    }

    flowEnumErrorInconsistentMemberValues(pos, {
      enumName
    }) {
      this.raise(pos, FlowErrors.EnumInconsistentMemberValues, enumName);
    }

    flowEnumErrorInvalidExplicitType(pos, {
      enumName,
      suppliedType
    }) {
      return this.raise(pos, suppliedType === null ? FlowErrors.EnumInvalidExplicitTypeUnknownSupplied : FlowErrors.EnumInvalidExplicitType, enumName, suppliedType);
    }

    flowEnumErrorInvalidMemberInitializer(pos, {
      enumName,
      explicitType,
      memberName
    }) {
      let message = null;

      switch (explicitType) {
        case "boolean":
        case "number":
        case "string":
          message = FlowErrors.EnumInvalidMemberInitializerPrimaryType;
          break;

        case "symbol":
          message = FlowErrors.EnumInvalidMemberInitializerSymbolType;
          break;

        default:
          message = FlowErrors.EnumInvalidMemberInitializerUnknownType;
      }

      return this.raise(pos, message, enumName, memberName, explicitType);
    }

    flowEnumErrorNumberMemberNotInitialized(pos, {
      enumName,
      memberName
    }) {
      this.raise(pos, FlowErrors.EnumNumberMemberNotInitialized, enumName, memberName);
    }

    flowEnumErrorStringMemberInconsistentlyInitailized(pos, {
      enumName
    }) {
      this.raise(pos, FlowErrors.EnumStringMemberInconsistentlyInitailized, enumName);
    }

    flowEnumMemberInit() {
      const startPos = this.state.start;

      const endOfInit = () => this.match(types.comma) || this.match(types.braceR);

      switch (this.state.type) {
        case types.num:
          {
            const literal = this.parseLiteral(this.state.value, "NumericLiteral");

            if (endOfInit()) {
              return {
                type: "number",
                pos: literal.start,
                value: literal
              };
            }

            return {
              type: "invalid",
              pos: startPos
            };
          }

        case types.string:
          {
            const literal = this.parseLiteral(this.state.value, "StringLiteral");

            if (endOfInit()) {
              return {
                type: "string",
                pos: literal.start,
                value: literal
              };
            }

            return {
              type: "invalid",
              pos: startPos
            };
          }

        case types._true:
        case types._false:
          {
            const literal = this.parseBooleanLiteral();

            if (endOfInit()) {
              return {
                type: "boolean",
                pos: literal.start,
                value: literal
              };
            }

            return {
              type: "invalid",
              pos: startPos
            };
          }

        default:
          return {
            type: "invalid",
            pos: startPos
          };
      }
    }

    flowEnumMemberRaw() {
      const pos = this.state.start;
      const id = this.parseIdentifier(true);
      const init = this.eat(types.eq) ? this.flowEnumMemberInit() : {
        type: "none",
        pos
      };
      return {
        id,
        init
      };
    }

    flowEnumCheckExplicitTypeMismatch(pos, context, expectedType) {
      const {
        explicitType
      } = context;

      if (explicitType === null) {
        return;
      }

      if (explicitType !== expectedType) {
        this.flowEnumErrorInvalidMemberInitializer(pos, context);
      }
    }

    flowEnumMembers({
      enumName,
      explicitType
    }) {
      const seenNames = new Set();
      const members = {
        booleanMembers: [],
        numberMembers: [],
        stringMembers: [],
        defaultedMembers: []
      };

      while (!this.match(types.braceR)) {
        const memberNode = this.startNode();
        const {
          id,
          init
        } = this.flowEnumMemberRaw();
        const memberName = id.name;

        if (memberName === "") {
          continue;
        }

        if (/^[a-z]/.test(memberName)) {
          this.flowEnumErrorInvalidMemberName(id.start, {
            enumName,
            memberName
          });
        }

        if (seenNames.has(memberName)) {
          this.flowEnumErrorDuplicateMemberName(id.start, {
            enumName,
            memberName
          });
        }

        seenNames.add(memberName);
        const context = {
          enumName,
          explicitType,
          memberName
        };
        memberNode.id = id;

        switch (init.type) {
          case "boolean":
            {
              this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "boolean");
              memberNode.init = init.value;
              members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember"));
              break;
            }

          case "number":
            {
              this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "number");
              memberNode.init = init.value;
              members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember"));
              break;
            }

          case "string":
            {
              this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "string");
              memberNode.init = init.value;
              members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember"));
              break;
            }

          case "invalid":
            {
              throw this.flowEnumErrorInvalidMemberInitializer(init.pos, context);
            }

          case "none":
            {
              switch (explicitType) {
                case "boolean":
                  this.flowEnumErrorBooleanMemberNotInitialized(init.pos, context);
                  break;

                case "number":
                  this.flowEnumErrorNumberMemberNotInitialized(init.pos, context);
                  break;

                default:
                  members.defaultedMembers.push(this.finishNode(memberNode, "EnumDefaultedMember"));
              }
            }
        }

        if (!this.match(types.braceR)) {
          this.expect(types.comma);
        }
      }

      return members;
    }

    flowEnumStringMembers(initializedMembers, defaultedMembers, {
      enumName
    }) {
      if (initializedMembers.length === 0) {
        return defaultedMembers;
      } else if (defaultedMembers.length === 0) {
        return initializedMembers;
      } else if (defaultedMembers.length > initializedMembers.length) {
        for (let _i = 0; _i < initializedMembers.length; _i++) {
          const member = initializedMembers[_i];
          this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, {
            enumName
          });
        }

        return defaultedMembers;
      } else {
        for (let _i2 = 0; _i2 < defaultedMembers.length; _i2++) {
          const member = defaultedMembers[_i2];
          this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, {
            enumName
          });
        }

        return initializedMembers;
      }
    }

    flowEnumParseExplicitType({
      enumName
    }) {
      if (this.eatContextual("of")) {
        if (!this.match(types.name)) {
          throw this.flowEnumErrorInvalidExplicitType(this.state.start, {
            enumName,
            suppliedType: null
          });
        }

        const {
          value
        } = this.state;
        this.next();

        if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") {
          this.flowEnumErrorInvalidExplicitType(this.state.start, {
            enumName,
            suppliedType: value
          });
        }

        return value;
      }

      return null;
    }

    flowEnumBody(node, {
      enumName,
      nameLoc
    }) {
      const explicitType = this.flowEnumParseExplicitType({
        enumName
      });
      this.expect(types.braceL);
      const members = this.flowEnumMembers({
        enumName,
        explicitType
      });

      switch (explicitType) {
        case "boolean":
          node.explicitType = true;
          node.members = members.booleanMembers;
          this.expect(types.braceR);
          return this.finishNode(node, "EnumBooleanBody");

        case "number":
          node.explicitType = true;
          node.members = members.numberMembers;
          this.expect(types.braceR);
          return this.finishNode(node, "EnumNumberBody");

        case "string":
          node.explicitType = true;
          node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
            enumName
          });
          this.expect(types.braceR);
          return this.finishNode(node, "EnumStringBody");

        case "symbol":
          node.members = members.defaultedMembers;
          this.expect(types.braceR);
          return this.finishNode(node, "EnumSymbolBody");

        default:
          {
            const empty = () => {
              node.members = [];
              this.expect(types.braceR);
              return this.finishNode(node, "EnumStringBody");
            };

            node.explicitType = false;
            const boolsLen = members.booleanMembers.length;
            const numsLen = members.numberMembers.length;
            const strsLen = members.stringMembers.length;
            const defaultedLen = members.defaultedMembers.length;

            if (!boolsLen && !numsLen && !strsLen && !defaultedLen) {
              return empty();
            } else if (!boolsLen && !numsLen) {
              node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
                enumName
              });
              this.expect(types.braceR);
              return this.finishNode(node, "EnumStringBody");
            } else if (!numsLen && !strsLen && boolsLen >= defaultedLen) {
              for (let _i3 = 0, _members$defaultedMem = members.defaultedMembers; _i3 < _members$defaultedMem.length; _i3++) {
                const member = _members$defaultedMem[_i3];
                this.flowEnumErrorBooleanMemberNotInitialized(member.start, {
                  enumName,
                  memberName: member.id.name
                });
              }

              node.members = members.booleanMembers;
              this.expect(types.braceR);
              return this.finishNode(node, "EnumBooleanBody");
            } else if (!boolsLen && !strsLen && numsLen >= defaultedLen) {
              for (let _i4 = 0, _members$defaultedMem2 = members.defaultedMembers; _i4 < _members$defaultedMem2.length; _i4++) {
                const member = _members$defaultedMem2[_i4];
                this.flowEnumErrorNumberMemberNotInitialized(member.start, {
                  enumName,
                  memberName: member.id.name
                });
              }

              node.members = members.numberMembers;
              this.expect(types.braceR);
              return this.finishNode(node, "EnumNumberBody");
            } else {
              this.flowEnumErrorInconsistentMemberValues(nameLoc, {
                enumName
              });
              return empty();
            }
          }
      }
    }

    flowParseEnumDeclaration(node) {
      const id = this.parseIdentifier();
      node.id = id;
      node.body = this.flowEnumBody(this.startNode(), {
        enumName: id.name,
        nameLoc: id.start
      });
      return this.finishNode(node, "EnumDeclaration");
    }

    updateContext(prevType) {
      if (this.match(types.name) && this.state.value === "of" && prevType === types.name && this.input.slice(this.state.lastTokStart, this.state.lastTokEnd) === "interface") {
        this.state.exprAllowed = false;
      } else {
        super.updateContext(prevType);
      }
    }

    isLookaheadToken_lt() {
      const next = this.nextTokenStart();

      if (this.input.charCodeAt(next) === 60) {
        const afterNext = this.input.charCodeAt(next + 1);
        return afterNext !== 60 && afterNext !== 61;
      }

      return false;
    }

    maybeUnwrapTypeCastExpression(node) {
      return node.type === "TypeCastExpression" ? node.expression : node;
    }

  });

  const entities = {
    quot: "\u0022",
    amp: "&",
    apos: "\u0027",
    lt: "<",
    gt: ">",
    nbsp: "\u00A0",
    iexcl: "\u00A1",
    cent: "\u00A2",
    pound: "\u00A3",
    curren: "\u00A4",
    yen: "\u00A5",
    brvbar: "\u00A6",
    sect: "\u00A7",
    uml: "\u00A8",
    copy: "\u00A9",
    ordf: "\u00AA",
    laquo: "\u00AB",
    not: "\u00AC",
    shy: "\u00AD",
    reg: "\u00AE",
    macr: "\u00AF",
    deg: "\u00B0",
    plusmn: "\u00B1",
    sup2: "\u00B2",
    sup3: "\u00B3",
    acute: "\u00B4",
    micro: "\u00B5",
    para: "\u00B6",
    middot: "\u00B7",
    cedil: "\u00B8",
    sup1: "\u00B9",
    ordm: "\u00BA",
    raquo: "\u00BB",
    frac14: "\u00BC",
    frac12: "\u00BD",
    frac34: "\u00BE",
    iquest: "\u00BF",
    Agrave: "\u00C0",
    Aacute: "\u00C1",
    Acirc: "\u00C2",
    Atilde: "\u00C3",
    Auml: "\u00C4",
    Aring: "\u00C5",
    AElig: "\u00C6",
    Ccedil: "\u00C7",
    Egrave: "\u00C8",
    Eacute: "\u00C9",
    Ecirc: "\u00CA",
    Euml: "\u00CB",
    Igrave: "\u00CC",
    Iacute: "\u00CD",
    Icirc: "\u00CE",
    Iuml: "\u00CF",
    ETH: "\u00D0",
    Ntilde: "\u00D1",
    Ograve: "\u00D2",
    Oacute: "\u00D3",
    Ocirc: "\u00D4",
    Otilde: "\u00D5",
    Ouml: "\u00D6",
    times: "\u00D7",
    Oslash: "\u00D8",
    Ugrave: "\u00D9",
    Uacute: "\u00DA",
    Ucirc: "\u00DB",
    Uuml: "\u00DC",
    Yacute: "\u00DD",
    THORN: "\u00DE",
    szlig: "\u00DF",
    agrave: "\u00E0",
    aacute: "\u00E1",
    acirc: "\u00E2",
    atilde: "\u00E3",
    auml: "\u00E4",
    aring: "\u00E5",
    aelig: "\u00E6",
    ccedil: "\u00E7",
    egrave: "\u00E8",
    eacute: "\u00E9",
    ecirc: "\u00EA",
    euml: "\u00EB",
    igrave: "\u00EC",
    iacute: "\u00ED",
    icirc: "\u00EE",
    iuml: "\u00EF",
    eth: "\u00F0",
    ntilde: "\u00F1",
    ograve: "\u00F2",
    oacute: "\u00F3",
    ocirc: "\u00F4",
    otilde: "\u00F5",
    ouml: "\u00F6",
    divide: "\u00F7",
    oslash: "\u00F8",
    ugrave: "\u00F9",
    uacute: "\u00FA",
    ucirc: "\u00FB",
    uuml: "\u00FC",
    yacute: "\u00FD",
    thorn: "\u00FE",
    yuml: "\u00FF",
    OElig: "\u0152",
    oelig: "\u0153",
    Scaron: "\u0160",
    scaron: "\u0161",
    Yuml: "\u0178",
    fnof: "\u0192",
    circ: "\u02C6",
    tilde: "\u02DC",
    Alpha: "\u0391",
    Beta: "\u0392",
    Gamma: "\u0393",
    Delta: "\u0394",
    Epsilon: "\u0395",
    Zeta: "\u0396",
    Eta: "\u0397",
    Theta: "\u0398",
    Iota: "\u0399",
    Kappa: "\u039A",
    Lambda: "\u039B",
    Mu: "\u039C",
    Nu: "\u039D",
    Xi: "\u039E",
    Omicron: "\u039F",
    Pi: "\u03A0",
    Rho: "\u03A1",
    Sigma: "\u03A3",
    Tau: "\u03A4",
    Upsilon: "\u03A5",
    Phi: "\u03A6",
    Chi: "\u03A7",
    Psi: "\u03A8",
    Omega: "\u03A9",
    alpha: "\u03B1",
    beta: "\u03B2",
    gamma: "\u03B3",
    delta: "\u03B4",
    epsilon: "\u03B5",
    zeta: "\u03B6",
    eta: "\u03B7",
    theta: "\u03B8",
    iota: "\u03B9",
    kappa: "\u03BA",
    lambda: "\u03BB",
    mu: "\u03BC",
    nu: "\u03BD",
    xi: "\u03BE",
    omicron: "\u03BF",
    pi: "\u03C0",
    rho: "\u03C1",
    sigmaf: "\u03C2",
    sigma: "\u03C3",
    tau: "\u03C4",
    upsilon: "\u03C5",
    phi: "\u03C6",
    chi: "\u03C7",
    psi: "\u03C8",
    omega: "\u03C9",
    thetasym: "\u03D1",
    upsih: "\u03D2",
    piv: "\u03D6",
    ensp: "\u2002",
    emsp: "\u2003",
    thinsp: "\u2009",
    zwnj: "\u200C",
    zwj: "\u200D",
    lrm: "\u200E",
    rlm: "\u200F",
    ndash: "\u2013",
    mdash: "\u2014",
    lsquo: "\u2018",
    rsquo: "\u2019",
    sbquo: "\u201A",
    ldquo: "\u201C",
    rdquo: "\u201D",
    bdquo: "\u201E",
    dagger: "\u2020",
    Dagger: "\u2021",
    bull: "\u2022",
    hellip: "\u2026",
    permil: "\u2030",
    prime: "\u2032",
    Prime: "\u2033",
    lsaquo: "\u2039",
    rsaquo: "\u203A",
    oline: "\u203E",
    frasl: "\u2044",
    euro: "\u20AC",
    image: "\u2111",
    weierp: "\u2118",
    real: "\u211C",
    trade: "\u2122",
    alefsym: "\u2135",
    larr: "\u2190",
    uarr: "\u2191",
    rarr: "\u2192",
    darr: "\u2193",
    harr: "\u2194",
    crarr: "\u21B5",
    lArr: "\u21D0",
    uArr: "\u21D1",
    rArr: "\u21D2",
    dArr: "\u21D3",
    hArr: "\u21D4",
    forall: "\u2200",
    part: "\u2202",
    exist: "\u2203",
    empty: "\u2205",
    nabla: "\u2207",
    isin: "\u2208",
    notin: "\u2209",
    ni: "\u220B",
    prod: "\u220F",
    sum: "\u2211",
    minus: "\u2212",
    lowast: "\u2217",
    radic: "\u221A",
    prop: "\u221D",
    infin: "\u221E",
    ang: "\u2220",
    and: "\u2227",
    or: "\u2228",
    cap: "\u2229",
    cup: "\u222A",
    int: "\u222B",
    there4: "\u2234",
    sim: "\u223C",
    cong: "\u2245",
    asymp: "\u2248",
    ne: "\u2260",
    equiv: "\u2261",
    le: "\u2264",
    ge: "\u2265",
    sub: "\u2282",
    sup: "\u2283",
    nsub: "\u2284",
    sube: "\u2286",
    supe: "\u2287",
    oplus: "\u2295",
    otimes: "\u2297",
    perp: "\u22A5",
    sdot: "\u22C5",
    lceil: "\u2308",
    rceil: "\u2309",
    lfloor: "\u230A",
    rfloor: "\u230B",
    lang: "\u2329",
    rang: "\u232A",
    loz: "\u25CA",
    spades: "\u2660",
    clubs: "\u2663",
    hearts: "\u2665",
    diams: "\u2666"
  };

  const HEX_NUMBER = /^[\da-fA-F]+$/;
  const DECIMAL_NUMBER = /^\d+$/;
  const JsxErrors = Object.freeze({
    AttributeIsEmpty: "JSX attributes must only be assigned a non-empty expression",
    MissingClosingTagFragment: "Expected corresponding JSX closing tag for <>",
    MissingClosingTagElement: "Expected corresponding JSX closing tag for <%0>",
    UnsupportedJsxValue: "JSX value should be either an expression or a quoted JSX text",
    UnterminatedJsxContent: "Unterminated JSX contents",
    UnwrappedAdjacentJSXElements: "Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?"
  });
  types$1.j_oTag = new TokContext("<tag", false);
  types$1.j_cTag = new TokContext("</tag", false);
  types$1.j_expr = new TokContext("<tag>...</tag>", true, true);
  types.jsxName = new TokenType("jsxName");
  types.jsxText = new TokenType("jsxText", {
    beforeExpr: true
  });
  types.jsxTagStart = new TokenType("jsxTagStart", {
    startsExpr: true
  });
  types.jsxTagEnd = new TokenType("jsxTagEnd");

  types.jsxTagStart.updateContext = function () {
    this.state.context.push(types$1.j_expr);
    this.state.context.push(types$1.j_oTag);
    this.state.exprAllowed = false;
  };

  types.jsxTagEnd.updateContext = function (prevType) {
    const out = this.state.context.pop();

    if (out === types$1.j_oTag && prevType === types.slash || out === types$1.j_cTag) {
      this.state.context.pop();
      this.state.exprAllowed = this.curContext() === types$1.j_expr;
    } else {
      this.state.exprAllowed = true;
    }
  };

  function isFragment(object) {
    return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" : false;
  }

  function getQualifiedJSXName(object) {
    if (object.type === "JSXIdentifier") {
      return object.name;
    }

    if (object.type === "JSXNamespacedName") {
      return object.namespace.name + ":" + object.name.name;
    }

    if (object.type === "JSXMemberExpression") {
      return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property);
    }

    throw new Error("Node had unexpected type: " + object.type);
  }

  var jsx = (superClass => class extends superClass {
    jsxReadToken() {
      let out = "";
      let chunkStart = this.state.pos;

      for (;;) {
        if (this.state.pos >= this.length) {
          throw this.raise(this.state.start, JsxErrors.UnterminatedJsxContent);
        }

        const ch = this.input.charCodeAt(this.state.pos);

        switch (ch) {
          case 60:
          case 123:
            if (this.state.pos === this.state.start) {
              if (ch === 60 && this.state.exprAllowed) {
                ++this.state.pos;
                return this.finishToken(types.jsxTagStart);
              }

              return super.getTokenFromCode(ch);
            }

            out += this.input.slice(chunkStart, this.state.pos);
            return this.finishToken(types.jsxText, out);

          case 38:
            out += this.input.slice(chunkStart, this.state.pos);
            out += this.jsxReadEntity();
            chunkStart = this.state.pos;
            break;

          default:
            if (isNewLine(ch)) {
              out += this.input.slice(chunkStart, this.state.pos);
              out += this.jsxReadNewLine(true);
              chunkStart = this.state.pos;
            } else {
              ++this.state.pos;
            }

        }
      }
    }

    jsxReadNewLine(normalizeCRLF) {
      const ch = this.input.charCodeAt(this.state.pos);
      let out;
      ++this.state.pos;

      if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) {
        ++this.state.pos;
        out = normalizeCRLF ? "\n" : "\r\n";
      } else {
        out = String.fromCharCode(ch);
      }

      ++this.state.curLine;
      this.state.lineStart = this.state.pos;
      return out;
    }

    jsxReadString(quote) {
      let out = "";
      let chunkStart = ++this.state.pos;

      for (;;) {
        if (this.state.pos >= this.length) {
          throw this.raise(this.state.start, ErrorMessages.UnterminatedString);
        }

        const ch = this.input.charCodeAt(this.state.pos);
        if (ch === quote) break;

        if (ch === 38) {
          out += this.input.slice(chunkStart, this.state.pos);
          out += this.jsxReadEntity();
          chunkStart = this.state.pos;
        } else if (isNewLine(ch)) {
          out += this.input.slice(chunkStart, this.state.pos);
          out += this.jsxReadNewLine(false);
          chunkStart = this.state.pos;
        } else {
          ++this.state.pos;
        }
      }

      out += this.input.slice(chunkStart, this.state.pos++);
      return this.finishToken(types.string, out);
    }

    jsxReadEntity() {
      let str = "";
      let count = 0;
      let entity;
      let ch = this.input[this.state.pos];
      const startPos = ++this.state.pos;

      while (this.state.pos < this.length && count++ < 10) {
        ch = this.input[this.state.pos++];

        if (ch === ";") {
          if (str[0] === "#") {
            if (str[1] === "x") {
              str = str.substr(2);

              if (HEX_NUMBER.test(str)) {
                entity = String.fromCodePoint(parseInt(str, 16));
              }
            } else {
              str = str.substr(1);

              if (DECIMAL_NUMBER.test(str)) {
                entity = String.fromCodePoint(parseInt(str, 10));
              }
            }
          } else {
            entity = entities[str];
          }

          break;
        }

        str += ch;
      }

      if (!entity) {
        this.state.pos = startPos;
        return "&";
      }

      return entity;
    }

    jsxReadWord() {
      let ch;
      const start = this.state.pos;

      do {
        ch = this.input.charCodeAt(++this.state.pos);
      } while (isIdentifierChar(ch) || ch === 45);

      return this.finishToken(types.jsxName, this.input.slice(start, this.state.pos));
    }

    jsxParseIdentifier() {
      const node = this.startNode();

      if (this.match(types.jsxName)) {
        node.name = this.state.value;
      } else if (this.state.type.keyword) {
        node.name = this.state.type.keyword;
      } else {
        this.unexpected();
      }

      this.next();
      return this.finishNode(node, "JSXIdentifier");
    }

    jsxParseNamespacedName() {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const name = this.jsxParseIdentifier();
      if (!this.eat(types.colon)) return name;
      const node = this.startNodeAt(startPos, startLoc);
      node.namespace = name;
      node.name = this.jsxParseIdentifier();
      return this.finishNode(node, "JSXNamespacedName");
    }

    jsxParseElementName() {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      let node = this.jsxParseNamespacedName();

      if (node.type === "JSXNamespacedName") {
        return node;
      }

      while (this.eat(types.dot)) {
        const newNode = this.startNodeAt(startPos, startLoc);
        newNode.object = node;
        newNode.property = this.jsxParseIdentifier();
        node = this.finishNode(newNode, "JSXMemberExpression");
      }

      return node;
    }

    jsxParseAttributeValue() {
      let node;

      switch (this.state.type) {
        case types.braceL:
          node = this.startNode();
          this.next();
          node = this.jsxParseExpressionContainer(node);

          if (node.expression.type === "JSXEmptyExpression") {
            this.raise(node.start, JsxErrors.AttributeIsEmpty);
          }

          return node;

        case types.jsxTagStart:
        case types.string:
          return this.parseExprAtom();

        default:
          throw this.raise(this.state.start, JsxErrors.UnsupportedJsxValue);
      }
    }

    jsxParseEmptyExpression() {
      const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc);
      return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc);
    }

    jsxParseSpreadChild(node) {
      this.next();
      node.expression = this.parseExpression();
      this.expect(types.braceR);
      return this.finishNode(node, "JSXSpreadChild");
    }

    jsxParseExpressionContainer(node) {
      if (this.match(types.braceR)) {
        node.expression = this.jsxParseEmptyExpression();
      } else {
        node.expression = this.parseExpression();
      }

      this.expect(types.braceR);
      return this.finishNode(node, "JSXExpressionContainer");
    }

    jsxParseAttribute() {
      const node = this.startNode();

      if (this.eat(types.braceL)) {
        this.expect(types.ellipsis);
        node.argument = this.parseMaybeAssignAllowIn();
        this.expect(types.braceR);
        return this.finishNode(node, "JSXSpreadAttribute");
      }

      node.name = this.jsxParseNamespacedName();
      node.value = this.eat(types.eq) ? this.jsxParseAttributeValue() : null;
      return this.finishNode(node, "JSXAttribute");
    }

    jsxParseOpeningElementAt(startPos, startLoc) {
      const node = this.startNodeAt(startPos, startLoc);

      if (this.match(types.jsxTagEnd)) {
        this.expect(types.jsxTagEnd);
        return this.finishNode(node, "JSXOpeningFragment");
      }

      node.name = this.jsxParseElementName();
      return this.jsxParseOpeningElementAfterName(node);
    }

    jsxParseOpeningElementAfterName(node) {
      const attributes = [];

      while (!this.match(types.slash) && !this.match(types.jsxTagEnd)) {
        attributes.push(this.jsxParseAttribute());
      }

      node.attributes = attributes;
      node.selfClosing = this.eat(types.slash);
      this.expect(types.jsxTagEnd);
      return this.finishNode(node, "JSXOpeningElement");
    }

    jsxParseClosingElementAt(startPos, startLoc) {
      const node = this.startNodeAt(startPos, startLoc);

      if (this.match(types.jsxTagEnd)) {
        this.expect(types.jsxTagEnd);
        return this.finishNode(node, "JSXClosingFragment");
      }

      node.name = this.jsxParseElementName();
      this.expect(types.jsxTagEnd);
      return this.finishNode(node, "JSXClosingElement");
    }

    jsxParseElementAt(startPos, startLoc) {
      const node = this.startNodeAt(startPos, startLoc);
      const children = [];
      const openingElement = this.jsxParseOpeningElementAt(startPos, startLoc);
      let closingElement = null;

      if (!openingElement.selfClosing) {
        contents: for (;;) {
          switch (this.state.type) {
            case types.jsxTagStart:
              startPos = this.state.start;
              startLoc = this.state.startLoc;
              this.next();

              if (this.eat(types.slash)) {
                closingElement = this.jsxParseClosingElementAt(startPos, startLoc);
                break contents;
              }

              children.push(this.jsxParseElementAt(startPos, startLoc));
              break;

            case types.jsxText:
              children.push(this.parseExprAtom());
              break;

            case types.braceL:
              {
                const node = this.startNode();
                this.next();

                if (this.match(types.ellipsis)) {
                  children.push(this.jsxParseSpreadChild(node));
                } else {
                  children.push(this.jsxParseExpressionContainer(node));
                }

                break;
              }

            default:
              throw this.unexpected();
          }
        }

        if (isFragment(openingElement) && !isFragment(closingElement)) {
          this.raise(closingElement.start, JsxErrors.MissingClosingTagFragment);
        } else if (!isFragment(openingElement) && isFragment(closingElement)) {
          this.raise(closingElement.start, JsxErrors.MissingClosingTagElement, getQualifiedJSXName(openingElement.name));
        } else if (!isFragment(openingElement) && !isFragment(closingElement)) {
          if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
            this.raise(closingElement.start, JsxErrors.MissingClosingTagElement, getQualifiedJSXName(openingElement.name));
          }
        }
      }

      if (isFragment(openingElement)) {
        node.openingFragment = openingElement;
        node.closingFragment = closingElement;
      } else {
        node.openingElement = openingElement;
        node.closingElement = closingElement;
      }

      node.children = children;

      if (this.isRelational("<")) {
        throw this.raise(this.state.start, JsxErrors.UnwrappedAdjacentJSXElements);
      }

      return isFragment(openingElement) ? this.finishNode(node, "JSXFragment") : this.finishNode(node, "JSXElement");
    }

    jsxParseElement() {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      this.next();
      return this.jsxParseElementAt(startPos, startLoc);
    }

    parseExprAtom(refExpressionErrors) {
      if (this.match(types.jsxText)) {
        return this.parseLiteral(this.state.value, "JSXText");
      } else if (this.match(types.jsxTagStart)) {
        return this.jsxParseElement();
      } else if (this.isRelational("<") && this.input.charCodeAt(this.state.pos) !== 33) {
        this.finishToken(types.jsxTagStart);
        return this.jsxParseElement();
      } else {
        return super.parseExprAtom(refExpressionErrors);
      }
    }

    getTokenFromCode(code) {
      if (this.state.inPropertyName) return super.getTokenFromCode(code);
      const context = this.curContext();

      if (context === types$1.j_expr) {
        return this.jsxReadToken();
      }

      if (context === types$1.j_oTag || context === types$1.j_cTag) {
        if (isIdentifierStart(code)) {
          return this.jsxReadWord();
        }

        if (code === 62) {
          ++this.state.pos;
          return this.finishToken(types.jsxTagEnd);
        }

        if ((code === 34 || code === 39) && context === types$1.j_oTag) {
          return this.jsxReadString(code);
        }
      }

      if (code === 60 && this.state.exprAllowed && this.input.charCodeAt(this.state.pos + 1) !== 33) {
        ++this.state.pos;
        return this.finishToken(types.jsxTagStart);
      }

      return super.getTokenFromCode(code);
    }

    updateContext(prevType) {
      if (this.match(types.braceL)) {
        const curContext = this.curContext();

        if (curContext === types$1.j_oTag) {
          this.state.context.push(types$1.braceExpression);
        } else if (curContext === types$1.j_expr) {
          this.state.context.push(types$1.templateQuasi);
        } else {
          super.updateContext(prevType);
        }

        this.state.exprAllowed = true;
      } else if (this.match(types.slash) && prevType === types.jsxTagStart) {
        this.state.context.length -= 2;
        this.state.context.push(types$1.j_cTag);
        this.state.exprAllowed = false;
      } else {
        return super.updateContext(prevType);
      }
    }

  });

  class Scope {
    constructor(flags) {
      this.var = [];
      this.lexical = [];
      this.functions = [];
      this.flags = flags;
    }

  }
  class ScopeHandler {
    constructor(raise, inModule) {
      this.scopeStack = [];
      this.undefinedExports = new Map();
      this.undefinedPrivateNames = new Map();
      this.raise = raise;
      this.inModule = inModule;
    }

    get inFunction() {
      return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0;
    }

    get allowSuper() {
      return (this.currentThisScope().flags & SCOPE_SUPER) > 0;
    }

    get allowDirectSuper() {
      return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0;
    }

    get inClass() {
      return (this.currentThisScope().flags & SCOPE_CLASS) > 0;
    }

    get inNonArrowFunction() {
      return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0;
    }

    get treatFunctionsAsVar() {
      return this.treatFunctionsAsVarInScope(this.currentScope());
    }

    createScope(flags) {
      return new Scope(flags);
    }

    enter(flags) {
      this.scopeStack.push(this.createScope(flags));
    }

    exit() {
      this.scopeStack.pop();
    }

    treatFunctionsAsVarInScope(scope) {
      return !!(scope.flags & SCOPE_FUNCTION || !this.inModule && scope.flags & SCOPE_PROGRAM);
    }

    declareName(name, bindingType, pos) {
      let scope = this.currentScope();

      if (bindingType & BIND_SCOPE_LEXICAL || bindingType & BIND_SCOPE_FUNCTION) {
        this.checkRedeclarationInScope(scope, name, bindingType, pos);

        if (bindingType & BIND_SCOPE_FUNCTION) {
          scope.functions.push(name);
        } else {
          scope.lexical.push(name);
        }

        if (bindingType & BIND_SCOPE_LEXICAL) {
          this.maybeExportDefined(scope, name);
        }
      } else if (bindingType & BIND_SCOPE_VAR) {
        for (let i = this.scopeStack.length - 1; i >= 0; --i) {
          scope = this.scopeStack[i];
          this.checkRedeclarationInScope(scope, name, bindingType, pos);
          scope.var.push(name);
          this.maybeExportDefined(scope, name);
          if (scope.flags & SCOPE_VAR) break;
        }
      }

      if (this.inModule && scope.flags & SCOPE_PROGRAM) {
        this.undefinedExports.delete(name);
      }
    }

    maybeExportDefined(scope, name) {
      if (this.inModule && scope.flags & SCOPE_PROGRAM) {
        this.undefinedExports.delete(name);
      }
    }

    checkRedeclarationInScope(scope, name, bindingType, pos) {
      if (this.isRedeclaredInScope(scope, name, bindingType)) {
        this.raise(pos, ErrorMessages.VarRedeclaration, name);
      }
    }

    isRedeclaredInScope(scope, name, bindingType) {
      if (!(bindingType & BIND_KIND_VALUE)) return false;

      if (bindingType & BIND_SCOPE_LEXICAL) {
        return scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
      }

      if (bindingType & BIND_SCOPE_FUNCTION) {
        return scope.lexical.indexOf(name) > -1 || !this.treatFunctionsAsVarInScope(scope) && scope.var.indexOf(name) > -1;
      }

      return scope.lexical.indexOf(name) > -1 && !(scope.flags & SCOPE_SIMPLE_CATCH && scope.lexical[0] === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.indexOf(name) > -1;
    }

    checkLocalExport(id) {
      if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && this.scopeStack[0].var.indexOf(id.name) === -1 && this.scopeStack[0].functions.indexOf(id.name) === -1) {
        this.undefinedExports.set(id.name, id.start);
      }
    }

    currentScope() {
      return this.scopeStack[this.scopeStack.length - 1];
    }

    currentVarScope() {
      for (let i = this.scopeStack.length - 1;; i--) {
        const scope = this.scopeStack[i];

        if (scope.flags & SCOPE_VAR) {
          return scope;
        }
      }
    }

    currentThisScope() {
      for (let i = this.scopeStack.length - 1;; i--) {
        const scope = this.scopeStack[i];

        if ((scope.flags & SCOPE_VAR || scope.flags & SCOPE_CLASS) && !(scope.flags & SCOPE_ARROW)) {
          return scope;
        }
      }
    }

  }

  class TypeScriptScope extends Scope {
    constructor(...args) {
      super(...args);
      this.types = [];
      this.enums = [];
      this.constEnums = [];
      this.classes = [];
      this.exportOnlyBindings = [];
    }

  }

  class TypeScriptScopeHandler extends ScopeHandler {
    createScope(flags) {
      return new TypeScriptScope(flags);
    }

    declareName(name, bindingType, pos) {
      const scope = this.currentScope();

      if (bindingType & BIND_FLAGS_TS_EXPORT_ONLY) {
        this.maybeExportDefined(scope, name);
        scope.exportOnlyBindings.push(name);
        return;
      }

      super.declareName(...arguments);

      if (bindingType & BIND_KIND_TYPE) {
        if (!(bindingType & BIND_KIND_VALUE)) {
          this.checkRedeclarationInScope(scope, name, bindingType, pos);
          this.maybeExportDefined(scope, name);
        }

        scope.types.push(name);
      }

      if (bindingType & BIND_FLAGS_TS_ENUM) scope.enums.push(name);
      if (bindingType & BIND_FLAGS_TS_CONST_ENUM) scope.constEnums.push(name);
      if (bindingType & BIND_FLAGS_CLASS) scope.classes.push(name);
    }

    isRedeclaredInScope(scope, name, bindingType) {
      if (scope.enums.indexOf(name) > -1) {
        if (bindingType & BIND_FLAGS_TS_ENUM) {
          const isConst = !!(bindingType & BIND_FLAGS_TS_CONST_ENUM);
          const wasConst = scope.constEnums.indexOf(name) > -1;
          return isConst !== wasConst;
        }

        return true;
      }

      if (bindingType & BIND_FLAGS_CLASS && scope.classes.indexOf(name) > -1) {
        if (scope.lexical.indexOf(name) > -1) {
          return !!(bindingType & BIND_KIND_VALUE);
        } else {
          return false;
        }
      }

      if (bindingType & BIND_KIND_TYPE && scope.types.indexOf(name) > -1) {
        return true;
      }

      return super.isRedeclaredInScope(...arguments);
    }

    checkLocalExport(id) {
      if (this.scopeStack[0].types.indexOf(id.name) === -1 && this.scopeStack[0].exportOnlyBindings.indexOf(id.name) === -1) {
        super.checkLocalExport(id);
      }
    }

  }

  const PARAM = 0b0000,
        PARAM_YIELD = 0b0001,
        PARAM_AWAIT = 0b0010,
        PARAM_RETURN = 0b0100,
        PARAM_IN = 0b1000;
  class ProductionParameterHandler {
    constructor() {
      this.stacks = [];
    }

    enter(flags) {
      this.stacks.push(flags);
    }

    exit() {
      this.stacks.pop();
    }

    currentFlags() {
      return this.stacks[this.stacks.length - 1];
    }

    get hasAwait() {
      return (this.currentFlags() & PARAM_AWAIT) > 0;
    }

    get hasYield() {
      return (this.currentFlags() & PARAM_YIELD) > 0;
    }

    get hasReturn() {
      return (this.currentFlags() & PARAM_RETURN) > 0;
    }

    get hasIn() {
      return (this.currentFlags() & PARAM_IN) > 0;
    }

  }
  function functionFlags(isAsync, isGenerator) {
    return (isAsync ? PARAM_AWAIT : 0) | (isGenerator ? PARAM_YIELD : 0);
  }

  function nonNull(x) {
    if (x == null) {
      throw new Error(`Unexpected ${x} value.`);
    }

    return x;
  }

  function assert(x) {
    if (!x) {
      throw new Error("Assert fail");
    }
  }

  const TSErrors = Object.freeze({
    ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier",
    ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier",
    DeclareClassFieldHasInitializer: "'declare' class fields cannot have an initializer",
    DuplicateModifier: "Duplicate modifier: '%0'",
    EmptyHeritageClauseType: "'%0' list cannot be empty.",
    IndexSignatureHasAbstract: "Index signatures cannot have the 'abstract' modifier",
    IndexSignatureHasAccessibility: "Index signatures cannot have an accessibility modifier ('%0')",
    IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier",
    InvalidTupleMemberLabel: "Tuple members must be labeled with a simple identifier.",
    MixedLabeledAndUnlabeledElements: "Tuple members must all have names or all not have names.",
    OptionalTypeBeforeRequired: "A required element cannot follow an optional element.",
    PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.",
    PrivateElementHasAbstract: "Private elements cannot have the 'abstract' modifier.",
    PrivateElementHasAccessibility: "Private elements cannot have an accessibility modifier ('%0')",
    TemplateTypeHasSubstitution: "Template literal types cannot have any substitution",
    TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`",
    UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.",
    UnexpectedTypeAnnotation: "Did not expect a type annotation here.",
    UnexpectedTypeCastInParameter: "Unexpected type cast in parameter position.",
    UnsupportedImportTypeArgument: "Argument in a type import must be a string literal",
    UnsupportedParameterPropertyKind: "A parameter property may not be declared using a binding pattern.",
    UnsupportedSignatureParameterKind: "Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got %0"
  });

  function keywordTypeFromName(value) {
    switch (value) {
      case "any":
        return "TSAnyKeyword";

      case "boolean":
        return "TSBooleanKeyword";

      case "bigint":
        return "TSBigIntKeyword";

      case "never":
        return "TSNeverKeyword";

      case "number":
        return "TSNumberKeyword";

      case "object":
        return "TSObjectKeyword";

      case "string":
        return "TSStringKeyword";

      case "symbol":
        return "TSSymbolKeyword";

      case "undefined":
        return "TSUndefinedKeyword";

      case "unknown":
        return "TSUnknownKeyword";

      default:
        return undefined;
    }
  }

  var typescript = (superClass => class extends superClass {
    getScopeHandler() {
      return TypeScriptScopeHandler;
    }

    tsIsIdentifier() {
      return this.match(types.name);
    }

    tsNextTokenCanFollowModifier() {
      this.next();
      return !this.hasPrecedingLineBreak() && !this.match(types.parenL) && !this.match(types.parenR) && !this.match(types.colon) && !this.match(types.eq) && !this.match(types.question) && !this.match(types.bang);
    }

    tsParseModifier(allowedModifiers) {
      if (!this.match(types.name)) {
        return undefined;
      }

      const modifier = this.state.value;

      if (allowedModifiers.indexOf(modifier) !== -1 && this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) {
        return modifier;
      }

      return undefined;
    }

    tsParseModifiers(modified, allowedModifiers) {
      for (;;) {
        const startPos = this.state.start;
        const modifier = this.tsParseModifier(allowedModifiers);
        if (!modifier) break;

        if (Object.hasOwnProperty.call(modified, modifier)) {
          this.raise(startPos, TSErrors.DuplicateModifier, modifier);
        }

        modified[modifier] = true;
      }
    }

    tsIsListTerminator(kind) {
      switch (kind) {
        case "EnumMembers":
        case "TypeMembers":
          return this.match(types.braceR);

        case "HeritageClauseElement":
          return this.match(types.braceL);

        case "TupleElementTypes":
          return this.match(types.bracketR);

        case "TypeParametersOrArguments":
          return this.isRelational(">");
      }

      throw new Error("Unreachable");
    }

    tsParseList(kind, parseElement) {
      const result = [];

      while (!this.tsIsListTerminator(kind)) {
        result.push(parseElement());
      }

      return result;
    }

    tsParseDelimitedList(kind, parseElement) {
      return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true));
    }

    tsParseDelimitedListWorker(kind, parseElement, expectSuccess) {
      const result = [];

      for (;;) {
        if (this.tsIsListTerminator(kind)) {
          break;
        }

        const element = parseElement();

        if (element == null) {
          return undefined;
        }

        result.push(element);

        if (this.eat(types.comma)) {
          continue;
        }

        if (this.tsIsListTerminator(kind)) {
          break;
        }

        if (expectSuccess) {
          this.expect(types.comma);
        }

        return undefined;
      }

      return result;
    }

    tsParseBracketedList(kind, parseElement, bracket, skipFirstToken) {
      if (!skipFirstToken) {
        if (bracket) {
          this.expect(types.bracketL);
        } else {
          this.expectRelational("<");
        }
      }

      const result = this.tsParseDelimitedList(kind, parseElement);

      if (bracket) {
        this.expect(types.bracketR);
      } else {
        this.expectRelational(">");
      }

      return result;
    }

    tsParseImportType() {
      const node = this.startNode();
      this.expect(types._import);
      this.expect(types.parenL);

      if (!this.match(types.string)) {
        this.raise(this.state.start, TSErrors.UnsupportedImportTypeArgument);
      }

      node.argument = this.parseExprAtom();
      this.expect(types.parenR);

      if (this.eat(types.dot)) {
        node.qualifier = this.tsParseEntityName(true);
      }

      if (this.isRelational("<")) {
        node.typeParameters = this.tsParseTypeArguments();
      }

      return this.finishNode(node, "TSImportType");
    }

    tsParseEntityName(allowReservedWords) {
      let entity = this.parseIdentifier();

      while (this.eat(types.dot)) {
        const node = this.startNodeAtNode(entity);
        node.left = entity;
        node.right = this.parseIdentifier(allowReservedWords);
        entity = this.finishNode(node, "TSQualifiedName");
      }

      return entity;
    }

    tsParseTypeReference() {
      const node = this.startNode();
      node.typeName = this.tsParseEntityName(false);

      if (!this.hasPrecedingLineBreak() && this.isRelational("<")) {
        node.typeParameters = this.tsParseTypeArguments();
      }

      return this.finishNode(node, "TSTypeReference");
    }

    tsParseThisTypePredicate(lhs) {
      this.next();
      const node = this.startNodeAtNode(lhs);
      node.parameterName = lhs;
      node.typeAnnotation = this.tsParseTypeAnnotation(false);
      return this.finishNode(node, "TSTypePredicate");
    }

    tsParseThisTypeNode() {
      const node = this.startNode();
      this.next();
      return this.finishNode(node, "TSThisType");
    }

    tsParseTypeQuery() {
      const node = this.startNode();
      this.expect(types._typeof);

      if (this.match(types._import)) {
        node.exprName = this.tsParseImportType();
      } else {
        node.exprName = this.tsParseEntityName(true);
      }

      return this.finishNode(node, "TSTypeQuery");
    }

    tsParseTypeParameter() {
      const node = this.startNode();
      node.name = this.parseIdentifierName(node.start);
      node.constraint = this.tsEatThenParseType(types._extends);
      node.default = this.tsEatThenParseType(types.eq);
      return this.finishNode(node, "TSTypeParameter");
    }

    tsTryParseTypeParameters() {
      if (this.isRelational("<")) {
        return this.tsParseTypeParameters();
      }
    }

    tsParseTypeParameters() {
      const node = this.startNode();

      if (this.isRelational("<") || this.match(types.jsxTagStart)) {
        this.next();
      } else {
        this.unexpected();
      }

      node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this), false, true);
      return this.finishNode(node, "TSTypeParameterDeclaration");
    }

    tsTryNextParseConstantContext() {
      if (this.lookahead().type === types._const) {
        this.next();
        return this.tsParseTypeReference();
      }

      return null;
    }

    tsFillSignature(returnToken, signature) {
      const returnTokenRequired = returnToken === types.arrow;
      signature.typeParameters = this.tsTryParseTypeParameters();
      this.expect(types.parenL);
      signature.parameters = this.tsParseBindingListForSignature();

      if (returnTokenRequired) {
        signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken);
      } else if (this.match(returnToken)) {
        signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken);
      }
    }

    tsParseBindingListForSignature() {
      return this.parseBindingList(types.parenR, 41).map(pattern => {
        if (pattern.type !== "Identifier" && pattern.type !== "RestElement" && pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") {
          this.raise(pattern.start, TSErrors.UnsupportedSignatureParameterKind, pattern.type);
        }

        return pattern;
      });
    }

    tsParseTypeMemberSemicolon() {
      if (!this.eat(types.comma)) {
        this.semicolon();
      }
    }

    tsParseSignatureMember(kind, node) {
      this.tsFillSignature(types.colon, node);
      this.tsParseTypeMemberSemicolon();
      return this.finishNode(node, kind);
    }

    tsIsUnambiguouslyIndexSignature() {
      this.next();
      return this.eat(types.name) && this.match(types.colon);
    }

    tsTryParseIndexSignature(node) {
      if (!(this.match(types.bracketL) && this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))) {
        return undefined;
      }

      this.expect(types.bracketL);
      const id = this.parseIdentifier();
      id.typeAnnotation = this.tsParseTypeAnnotation();
      this.resetEndLocation(id);
      this.expect(types.bracketR);
      node.parameters = [id];
      const type = this.tsTryParseTypeAnnotation();
      if (type) node.typeAnnotation = type;
      this.tsParseTypeMemberSemicolon();
      return this.finishNode(node, "TSIndexSignature");
    }

    tsParsePropertyOrMethodSignature(node, readonly) {
      if (this.eat(types.question)) node.optional = true;
      const nodeAny = node;

      if (!readonly && (this.match(types.parenL) || this.isRelational("<"))) {
        const method = nodeAny;
        this.tsFillSignature(types.colon, method);
        this.tsParseTypeMemberSemicolon();
        return this.finishNode(method, "TSMethodSignature");
      } else {
        const property = nodeAny;
        if (readonly) property.readonly = true;
        const type = this.tsTryParseTypeAnnotation();
        if (type) property.typeAnnotation = type;
        this.tsParseTypeMemberSemicolon();
        return this.finishNode(property, "TSPropertySignature");
      }
    }

    tsParseTypeMember() {
      const node = this.startNode();

      if (this.match(types.parenL) || this.isRelational("<")) {
        return this.tsParseSignatureMember("TSCallSignatureDeclaration", node);
      }

      if (this.match(types._new)) {
        const id = this.startNode();
        this.next();

        if (this.match(types.parenL) || this.isRelational("<")) {
          return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node);
        } else {
          node.key = this.createIdentifier(id, "new");
          return this.tsParsePropertyOrMethodSignature(node, false);
        }
      }

      const readonly = !!this.tsParseModifier(["readonly"]);
      const idx = this.tsTryParseIndexSignature(node);

      if (idx) {
        if (readonly) node.readonly = true;
        return idx;
      }

      this.parsePropertyName(node, false);
      return this.tsParsePropertyOrMethodSignature(node, readonly);
    }

    tsParseTypeLiteral() {
      const node = this.startNode();
      node.members = this.tsParseObjectTypeMembers();
      return this.finishNode(node, "TSTypeLiteral");
    }

    tsParseObjectTypeMembers() {
      this.expect(types.braceL);
      const members = this.tsParseList("TypeMembers", this.tsParseTypeMember.bind(this));
      this.expect(types.braceR);
      return members;
    }

    tsIsStartOfMappedType() {
      this.next();

      if (this.eat(types.plusMin)) {
        return this.isContextual("readonly");
      }

      if (this.isContextual("readonly")) {
        this.next();
      }

      if (!this.match(types.bracketL)) {
        return false;
      }

      this.next();

      if (!this.tsIsIdentifier()) {
        return false;
      }

      this.next();
      return this.match(types._in);
    }

    tsParseMappedTypeParameter() {
      const node = this.startNode();
      node.name = this.parseIdentifierName(node.start);
      node.constraint = this.tsExpectThenParseType(types._in);
      return this.finishNode(node, "TSTypeParameter");
    }

    tsParseMappedType() {
      const node = this.startNode();
      this.expect(types.braceL);

      if (this.match(types.plusMin)) {
        node.readonly = this.state.value;
        this.next();
        this.expectContextual("readonly");
      } else if (this.eatContextual("readonly")) {
        node.readonly = true;
      }

      this.expect(types.bracketL);
      node.typeParameter = this.tsParseMappedTypeParameter();
      this.expect(types.bracketR);

      if (this.match(types.plusMin)) {
        node.optional = this.state.value;
        this.next();
        this.expect(types.question);
      } else if (this.eat(types.question)) {
        node.optional = true;
      }

      node.typeAnnotation = this.tsTryParseType();
      this.semicolon();
      this.expect(types.braceR);
      return this.finishNode(node, "TSMappedType");
    }

    tsParseTupleType() {
      const node = this.startNode();
      node.elementTypes = this.tsParseBracketedList("TupleElementTypes", this.tsParseTupleElementType.bind(this), true, false);
      let seenOptionalElement = false;
      let labeledElements = null;
      node.elementTypes.forEach(elementNode => {
        var _labeledElements;

        let {
          type
        } = elementNode;

        if (seenOptionalElement && type !== "TSRestType" && type !== "TSOptionalType" && !(type === "TSNamedTupleMember" && elementNode.optional)) {
          this.raise(elementNode.start, TSErrors.OptionalTypeBeforeRequired);
        }

        seenOptionalElement = seenOptionalElement || type === "TSNamedTupleMember" && elementNode.optional || type === "TSOptionalType";

        if (type === "TSRestType") {
          elementNode = elementNode.typeAnnotation;
          type = elementNode.type;
        }

        const isLabeled = type === "TSNamedTupleMember";
        labeledElements = (_labeledElements = labeledElements) != null ? _labeledElements : isLabeled;

        if (labeledElements !== isLabeled) {
          this.raise(elementNode.start, TSErrors.MixedLabeledAndUnlabeledElements);
        }
      });
      return this.finishNode(node, "TSTupleType");
    }

    tsParseTupleElementType() {
      const {
        start: startPos,
        startLoc
      } = this.state;
      const rest = this.eat(types.ellipsis);
      let type = this.tsParseType();
      const optional = this.eat(types.question);
      const labeled = this.eat(types.colon);

      if (labeled) {
        const labeledNode = this.startNodeAtNode(type);
        labeledNode.optional = optional;

        if (type.type === "TSTypeReference" && !type.typeParameters && type.typeName.type === "Identifier") {
          labeledNode.label = type.typeName;
        } else {
          this.raise(type.start, TSErrors.InvalidTupleMemberLabel);
          labeledNode.label = type;
        }

        labeledNode.elementType = this.tsParseType();
        type = this.finishNode(labeledNode, "TSNamedTupleMember");
      } else if (optional) {
        const optionalTypeNode = this.startNodeAtNode(type);
        optionalTypeNode.typeAnnotation = type;
        type = this.finishNode(optionalTypeNode, "TSOptionalType");
      }

      if (rest) {
        const restNode = this.startNodeAt(startPos, startLoc);
        restNode.typeAnnotation = type;
        type = this.finishNode(restNode, "TSRestType");
      }

      return type;
    }

    tsParseParenthesizedType() {
      const node = this.startNode();
      this.expect(types.parenL);
      node.typeAnnotation = this.tsParseType();
      this.expect(types.parenR);
      return this.finishNode(node, "TSParenthesizedType");
    }

    tsParseFunctionOrConstructorType(type) {
      const node = this.startNode();

      if (type === "TSConstructorType") {
        this.expect(types._new);
      }

      this.tsFillSignature(types.arrow, node);
      return this.finishNode(node, type);
    }

    tsParseLiteralTypeNode() {
      const node = this.startNode();

      node.literal = (() => {
        switch (this.state.type) {
          case types.num:
          case types.bigint:
          case types.string:
          case types._true:
          case types._false:
            return this.parseExprAtom();

          default:
            throw this.unexpected();
        }
      })();

      return this.finishNode(node, "TSLiteralType");
    }

    tsParseTemplateLiteralType() {
      const node = this.startNode();
      const templateNode = this.parseTemplate(false);

      if (templateNode.expressions.length > 0) {
        this.raise(templateNode.expressions[0].start, TSErrors.TemplateTypeHasSubstitution);
      }

      node.literal = templateNode;
      return this.finishNode(node, "TSLiteralType");
    }

    tsParseThisTypeOrThisTypePredicate() {
      const thisKeyword = this.tsParseThisTypeNode();

      if (this.isContextual("is") && !this.hasPrecedingLineBreak()) {
        return this.tsParseThisTypePredicate(thisKeyword);
      } else {
        return thisKeyword;
      }
    }

    tsParseNonArrayType() {
      switch (this.state.type) {
        case types.name:
        case types._void:
        case types._null:
          {
            const type = this.match(types._void) ? "TSVoidKeyword" : this.match(types._null) ? "TSNullKeyword" : keywordTypeFromName(this.state.value);

            if (type !== undefined && this.lookaheadCharCode() !== 46) {
              const node = this.startNode();
              this.next();
              return this.finishNode(node, type);
            }

            return this.tsParseTypeReference();
          }

        case types.string:
        case types.num:
        case types.bigint:
        case types._true:
        case types._false:
          return this.tsParseLiteralTypeNode();

        case types.plusMin:
          if (this.state.value === "-") {
            const node = this.startNode();
            const nextToken = this.lookahead();

            if (nextToken.type !== types.num && nextToken.type !== types.bigint) {
              throw this.unexpected();
            }

            node.literal = this.parseMaybeUnary();
            return this.finishNode(node, "TSLiteralType");
          }

          break;

        case types._this:
          return this.tsParseThisTypeOrThisTypePredicate();

        case types._typeof:
          return this.tsParseTypeQuery();

        case types._import:
          return this.tsParseImportType();

        case types.braceL:
          return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this)) ? this.tsParseMappedType() : this.tsParseTypeLiteral();

        case types.bracketL:
          return this.tsParseTupleType();

        case types.parenL:
          return this.tsParseParenthesizedType();

        case types.backQuote:
          return this.tsParseTemplateLiteralType();
      }

      throw this.unexpected();
    }

    tsParseArrayTypeOrHigher() {
      let type = this.tsParseNonArrayType();

      while (!this.hasPrecedingLineBreak() && this.eat(types.bracketL)) {
        if (this.match(types.bracketR)) {
          const node = this.startNodeAtNode(type);
          node.elementType = type;
          this.expect(types.bracketR);
          type = this.finishNode(node, "TSArrayType");
        } else {
          const node = this.startNodeAtNode(type);
          node.objectType = type;
          node.indexType = this.tsParseType();
          this.expect(types.bracketR);
          type = this.finishNode(node, "TSIndexedAccessType");
        }
      }

      return type;
    }

    tsParseTypeOperator(operator) {
      const node = this.startNode();
      this.expectContextual(operator);
      node.operator = operator;
      node.typeAnnotation = this.tsParseTypeOperatorOrHigher();

      if (operator === "readonly") {
        this.tsCheckTypeAnnotationForReadOnly(node);
      }

      return this.finishNode(node, "TSTypeOperator");
    }

    tsCheckTypeAnnotationForReadOnly(node) {
      switch (node.typeAnnotation.type) {
        case "TSTupleType":
        case "TSArrayType":
          return;

        default:
          this.raise(node.start, TSErrors.UnexpectedReadonly);
      }
    }

    tsParseInferType() {
      const node = this.startNode();
      this.expectContextual("infer");
      const typeParameter = this.startNode();
      typeParameter.name = this.parseIdentifierName(typeParameter.start);
      node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter");
      return this.finishNode(node, "TSInferType");
    }

    tsParseTypeOperatorOrHigher() {
      const operator = ["keyof", "unique", "readonly"].find(kw => this.isContextual(kw));
      return operator ? this.tsParseTypeOperator(operator) : this.isContextual("infer") ? this.tsParseInferType() : this.tsParseArrayTypeOrHigher();
    }

    tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) {
      this.eat(operator);
      let type = parseConstituentType();

      if (this.match(operator)) {
        const types = [type];

        while (this.eat(operator)) {
          types.push(parseConstituentType());
        }

        const node = this.startNodeAtNode(type);
        node.types = types;
        type = this.finishNode(node, kind);
      }

      return type;
    }

    tsParseIntersectionTypeOrHigher() {
      return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), types.bitwiseAND);
    }

    tsParseUnionTypeOrHigher() {
      return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), types.bitwiseOR);
    }

    tsIsStartOfFunctionType() {
      if (this.isRelational("<")) {
        return true;
      }

      return this.match(types.parenL) && this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this));
    }

    tsSkipParameterStart() {
      if (this.match(types.name) || this.match(types._this)) {
        this.next();
        return true;
      }

      if (this.match(types.braceL)) {
        let braceStackCounter = 1;
        this.next();

        while (braceStackCounter > 0) {
          if (this.match(types.braceL)) {
            ++braceStackCounter;
          } else if (this.match(types.braceR)) {
            --braceStackCounter;
          }

          this.next();
        }

        return true;
      }

      if (this.match(types.bracketL)) {
        let braceStackCounter = 1;
        this.next();

        while (braceStackCounter > 0) {
          if (this.match(types.bracketL)) {
            ++braceStackCounter;
          } else if (this.match(types.bracketR)) {
            --braceStackCounter;
          }

          this.next();
        }

        return true;
      }

      return false;
    }

    tsIsUnambiguouslyStartOfFunctionType() {
      this.next();

      if (this.match(types.parenR) || this.match(types.ellipsis)) {
        return true;
      }

      if (this.tsSkipParameterStart()) {
        if (this.match(types.colon) || this.match(types.comma) || this.match(types.question) || this.match(types.eq)) {
          return true;
        }

        if (this.match(types.parenR)) {
          this.next();

          if (this.match(types.arrow)) {
            return true;
          }
        }
      }

      return false;
    }

    tsParseTypeOrTypePredicateAnnotation(returnToken) {
      return this.tsInType(() => {
        const t = this.startNode();
        this.expect(returnToken);
        const asserts = this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this));

        if (asserts && this.match(types._this)) {
          let thisTypePredicate = this.tsParseThisTypeOrThisTypePredicate();

          if (thisTypePredicate.type === "TSThisType") {
            const node = this.startNodeAtNode(t);
            node.parameterName = thisTypePredicate;
            node.asserts = true;
            thisTypePredicate = this.finishNode(node, "TSTypePredicate");
          } else {
            thisTypePredicate.asserts = true;
          }

          t.typeAnnotation = thisTypePredicate;
          return this.finishNode(t, "TSTypeAnnotation");
        }

        const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this));

        if (!typePredicateVariable) {
          if (!asserts) {
            return this.tsParseTypeAnnotation(false, t);
          }

          const node = this.startNodeAtNode(t);
          node.parameterName = this.parseIdentifier();
          node.asserts = asserts;
          t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
          return this.finishNode(t, "TSTypeAnnotation");
        }

        const type = this.tsParseTypeAnnotation(false);
        const node = this.startNodeAtNode(t);
        node.parameterName = typePredicateVariable;
        node.typeAnnotation = type;
        node.asserts = asserts;
        t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
        return this.finishNode(t, "TSTypeAnnotation");
      });
    }

    tsTryParseTypeOrTypePredicateAnnotation() {
      return this.match(types.colon) ? this.tsParseTypeOrTypePredicateAnnotation(types.colon) : undefined;
    }

    tsTryParseTypeAnnotation() {
      return this.match(types.colon) ? this.tsParseTypeAnnotation() : undefined;
    }

    tsTryParseType() {
      return this.tsEatThenParseType(types.colon);
    }

    tsParseTypePredicatePrefix() {
      const id = this.parseIdentifier();

      if (this.isContextual("is") && !this.hasPrecedingLineBreak()) {
        this.next();
        return id;
      }
    }

    tsParseTypePredicateAsserts() {
      if (!this.match(types.name) || this.state.value !== "asserts" || this.hasPrecedingLineBreak()) {
        return false;
      }

      const containsEsc = this.state.containsEsc;
      this.next();

      if (!this.match(types.name) && !this.match(types._this)) {
        return false;
      }

      if (containsEsc) {
        this.raise(this.state.lastTokStart, ErrorMessages.InvalidEscapedReservedWord, "asserts");
      }

      return true;
    }

    tsParseTypeAnnotation(eatColon = true, t = this.startNode()) {
      this.tsInType(() => {
        if (eatColon) this.expect(types.colon);
        t.typeAnnotation = this.tsParseType();
      });
      return this.finishNode(t, "TSTypeAnnotation");
    }

    tsParseType() {
      assert(this.state.inType);
      const type = this.tsParseNonConditionalType();

      if (this.hasPrecedingLineBreak() || !this.eat(types._extends)) {
        return type;
      }

      const node = this.startNodeAtNode(type);
      node.checkType = type;
      node.extendsType = this.tsParseNonConditionalType();
      this.expect(types.question);
      node.trueType = this.tsParseType();
      this.expect(types.colon);
      node.falseType = this.tsParseType();
      return this.finishNode(node, "TSConditionalType");
    }

    tsParseNonConditionalType() {
      if (this.tsIsStartOfFunctionType()) {
        return this.tsParseFunctionOrConstructorType("TSFunctionType");
      }

      if (this.match(types._new)) {
        return this.tsParseFunctionOrConstructorType("TSConstructorType");
      }

      return this.tsParseUnionTypeOrHigher();
    }

    tsParseTypeAssertion() {
      const node = this.startNode();

      const _const = this.tsTryNextParseConstantContext();

      node.typeAnnotation = _const || this.tsNextThenParseType();
      this.expectRelational(">");
      node.expression = this.parseMaybeUnary();
      return this.finishNode(node, "TSTypeAssertion");
    }

    tsParseHeritageClause(descriptor) {
      const originalStart = this.state.start;
      const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", this.tsParseExpressionWithTypeArguments.bind(this));

      if (!delimitedList.length) {
        this.raise(originalStart, TSErrors.EmptyHeritageClauseType, descriptor);
      }

      return delimitedList;
    }

    tsParseExpressionWithTypeArguments() {
      const node = this.startNode();
      node.expression = this.tsParseEntityName(false);

      if (this.isRelational("<")) {
        node.typeParameters = this.tsParseTypeArguments();
      }

      return this.finishNode(node, "TSExpressionWithTypeArguments");
    }

    tsParseInterfaceDeclaration(node) {
      node.id = this.parseIdentifier();
      this.checkLVal(node.id, BIND_TS_INTERFACE, undefined, "typescript interface declaration");
      node.typeParameters = this.tsTryParseTypeParameters();

      if (this.eat(types._extends)) {
        node.extends = this.tsParseHeritageClause("extends");
      }

      const body = this.startNode();
      body.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this));
      node.body = this.finishNode(body, "TSInterfaceBody");
      return this.finishNode(node, "TSInterfaceDeclaration");
    }

    tsParseTypeAliasDeclaration(node) {
      node.id = this.parseIdentifier();
      this.checkLVal(node.id, BIND_TS_TYPE, undefined, "typescript type alias");
      node.typeParameters = this.tsTryParseTypeParameters();
      node.typeAnnotation = this.tsExpectThenParseType(types.eq);
      this.semicolon();
      return this.finishNode(node, "TSTypeAliasDeclaration");
    }

    tsInNoContext(cb) {
      const oldContext = this.state.context;
      this.state.context = [oldContext[0]];

      try {
        return cb();
      } finally {
        this.state.context = oldContext;
      }
    }

    tsInType(cb) {
      const oldInType = this.state.inType;
      this.state.inType = true;

      try {
        return cb();
      } finally {
        this.state.inType = oldInType;
      }
    }

    tsEatThenParseType(token) {
      return !this.match(token) ? undefined : this.tsNextThenParseType();
    }

    tsExpectThenParseType(token) {
      return this.tsDoThenParseType(() => this.expect(token));
    }

    tsNextThenParseType() {
      return this.tsDoThenParseType(() => this.next());
    }

    tsDoThenParseType(cb) {
      return this.tsInType(() => {
        cb();
        return this.tsParseType();
      });
    }

    tsParseEnumMember() {
      const node = this.startNode();
      node.id = this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true);

      if (this.eat(types.eq)) {
        node.initializer = this.parseMaybeAssignAllowIn();
      }

      return this.finishNode(node, "TSEnumMember");
    }

    tsParseEnumDeclaration(node, isConst) {
      if (isConst) node.const = true;
      node.id = this.parseIdentifier();
      this.checkLVal(node.id, isConst ? BIND_TS_CONST_ENUM : BIND_TS_ENUM, undefined, "typescript enum declaration");
      this.expect(types.braceL);
      node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this));
      this.expect(types.braceR);
      return this.finishNode(node, "TSEnumDeclaration");
    }

    tsParseModuleBlock() {
      const node = this.startNode();
      this.scope.enter(SCOPE_OTHER);
      this.expect(types.braceL);
      this.parseBlockOrModuleBlockBody(node.body = [], undefined, true, types.braceR);
      this.scope.exit();
      return this.finishNode(node, "TSModuleBlock");
    }

    tsParseModuleOrNamespaceDeclaration(node, nested = false) {
      node.id = this.parseIdentifier();

      if (!nested) {
        this.checkLVal(node.id, BIND_TS_NAMESPACE, null, "module or namespace declaration");
      }

      if (this.eat(types.dot)) {
        const inner = this.startNode();
        this.tsParseModuleOrNamespaceDeclaration(inner, true);
        node.body = inner;
      } else {
        this.scope.enter(SCOPE_TS_MODULE);
        this.prodParam.enter(PARAM);
        node.body = this.tsParseModuleBlock();
        this.prodParam.exit();
        this.scope.exit();
      }

      return this.finishNode(node, "TSModuleDeclaration");
    }

    tsParseAmbientExternalModuleDeclaration(node) {
      if (this.isContextual("global")) {
        node.global = true;
        node.id = this.parseIdentifier();
      } else if (this.match(types.string)) {
        node.id = this.parseExprAtom();
      } else {
        this.unexpected();
      }

      if (this.match(types.braceL)) {
        this.scope.enter(SCOPE_TS_MODULE);
        this.prodParam.enter(PARAM);
        node.body = this.tsParseModuleBlock();
        this.prodParam.exit();
        this.scope.exit();
      } else {
        this.semicolon();
      }

      return this.finishNode(node, "TSModuleDeclaration");
    }

    tsParseImportEqualsDeclaration(node, isExport) {
      node.isExport = isExport || false;
      node.id = this.parseIdentifier();
      this.checkLVal(node.id, BIND_LEXICAL, undefined, "import equals declaration");
      this.expect(types.eq);
      node.moduleReference = this.tsParseModuleReference();
      this.semicolon();
      return this.finishNode(node, "TSImportEqualsDeclaration");
    }

    tsIsExternalModuleReference() {
      return this.isContextual("require") && this.lookaheadCharCode() === 40;
    }

    tsParseModuleReference() {
      return this.tsIsExternalModuleReference() ? this.tsParseExternalModuleReference() : this.tsParseEntityName(false);
    }

    tsParseExternalModuleReference() {
      const node = this.startNode();
      this.expectContextual("require");
      this.expect(types.parenL);

      if (!this.match(types.string)) {
        throw this.unexpected();
      }

      node.expression = this.parseExprAtom();
      this.expect(types.parenR);
      return this.finishNode(node, "TSExternalModuleReference");
    }

    tsLookAhead(f) {
      const state = this.state.clone();
      const res = f();
      this.state = state;
      return res;
    }

    tsTryParseAndCatch(f) {
      const result = this.tryParse(abort => f() || abort());
      if (result.aborted || !result.node) return undefined;
      if (result.error) this.state = result.failState;
      return result.node;
    }

    tsTryParse(f) {
      const state = this.state.clone();
      const result = f();

      if (result !== undefined && result !== false) {
        return result;
      } else {
        this.state = state;
        return undefined;
      }
    }

    tsTryParseDeclare(nany) {
      if (this.isLineTerminator()) {
        return;
      }

      let starttype = this.state.type;
      let kind;

      if (this.isContextual("let")) {
        starttype = types._var;
        kind = "let";
      }

      switch (starttype) {
        case types._function:
          return this.parseFunctionStatement(nany, false, true);

        case types._class:
          nany.declare = true;
          return this.parseClass(nany, true, false);

        case types._const:
          if (this.match(types._const) && this.isLookaheadContextual("enum")) {
            this.expect(types._const);
            this.expectContextual("enum");
            return this.tsParseEnumDeclaration(nany, true);
          }

        case types._var:
          kind = kind || this.state.value;
          return this.parseVarStatement(nany, kind);

        case types.name:
          {
            const value = this.state.value;

            if (value === "global") {
              return this.tsParseAmbientExternalModuleDeclaration(nany);
            } else {
              return this.tsParseDeclaration(nany, value, true);
            }
          }
      }
    }

    tsTryParseExportDeclaration() {
      return this.tsParseDeclaration(this.startNode(), this.state.value, true);
    }

    tsParseExpressionStatement(node, expr) {
      switch (expr.name) {
        case "declare":
          {
            const declaration = this.tsTryParseDeclare(node);

            if (declaration) {
              declaration.declare = true;
              return declaration;
            }

            break;
          }

        case "global":
          if (this.match(types.braceL)) {
            this.scope.enter(SCOPE_TS_MODULE);
            this.prodParam.enter(PARAM);
            const mod = node;
            mod.global = true;
            mod.id = expr;
            mod.body = this.tsParseModuleBlock();
            this.scope.exit();
            this.prodParam.exit();
            return this.finishNode(mod, "TSModuleDeclaration");
          }

          break;

        default:
          return this.tsParseDeclaration(node, expr.name, false);
      }
    }

    tsParseDeclaration(node, value, next) {
      switch (value) {
        case "abstract":
          if (this.tsCheckLineTerminatorAndMatch(types._class, next)) {
            const cls = node;
            cls.abstract = true;

            if (next) {
              this.next();

              if (!this.match(types._class)) {
                this.unexpected(null, types._class);
              }
            }

            return this.parseClass(cls, true, false);
          }

          break;

        case "enum":
          if (next || this.match(types.name)) {
            if (next) this.next();
            return this.tsParseEnumDeclaration(node, false);
          }

          break;

        case "interface":
          if (this.tsCheckLineTerminatorAndMatch(types.name, next)) {
            if (next) this.next();
            return this.tsParseInterfaceDeclaration(node);
          }

          break;

        case "module":
          if (next) this.next();

          if (this.match(types.string)) {
            return this.tsParseAmbientExternalModuleDeclaration(node);
          } else if (this.tsCheckLineTerminatorAndMatch(types.name, next)) {
            return this.tsParseModuleOrNamespaceDeclaration(node);
          }

          break;

        case "namespace":
          if (this.tsCheckLineTerminatorAndMatch(types.name, next)) {
            if (next) this.next();
            return this.tsParseModuleOrNamespaceDeclaration(node);
          }

          break;

        case "type":
          if (this.tsCheckLineTerminatorAndMatch(types.name, next)) {
            if (next) this.next();
            return this.tsParseTypeAliasDeclaration(node);
          }

          break;
      }
    }

    tsCheckLineTerminatorAndMatch(tokenType, next) {
      return (next || this.match(tokenType)) && !this.isLineTerminator();
    }

    tsTryParseGenericAsyncArrowFunction(startPos, startLoc) {
      if (!this.isRelational("<")) {
        return undefined;
      }

      const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;
      this.state.maybeInArrowParameters = true;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      const res = this.tsTryParseAndCatch(() => {
        const node = this.startNodeAt(startPos, startLoc);
        node.typeParameters = this.tsParseTypeParameters();
        super.parseFunctionParams(node);
        node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation();
        this.expect(types.arrow);
        return node;
      });
      this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
      this.state.yieldPos = oldYieldPos;
      this.state.awaitPos = oldAwaitPos;

      if (!res) {
        return undefined;
      }

      return this.parseArrowExpression(res, null, true);
    }

    tsParseTypeArguments() {
      const node = this.startNode();
      node.params = this.tsInType(() => this.tsInNoContext(() => {
        this.expectRelational("<");
        return this.tsParseDelimitedList("TypeParametersOrArguments", this.tsParseType.bind(this));
      }));
      this.state.exprAllowed = false;
      this.expectRelational(">");
      return this.finishNode(node, "TSTypeParameterInstantiation");
    }

    tsIsDeclarationStart() {
      if (this.match(types.name)) {
        switch (this.state.value) {
          case "abstract":
          case "declare":
          case "enum":
          case "interface":
          case "module":
          case "namespace":
          case "type":
            return true;
        }
      }

      return false;
    }

    isExportDefaultSpecifier() {
      if (this.tsIsDeclarationStart()) return false;
      return super.isExportDefaultSpecifier();
    }

    parseAssignableListItem(allowModifiers, decorators) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      let accessibility;
      let readonly = false;

      if (allowModifiers) {
        accessibility = this.parseAccessModifier();
        readonly = !!this.tsParseModifier(["readonly"]);
      }

      const left = this.parseMaybeDefault();
      this.parseAssignableListItemTypes(left);
      const elt = this.parseMaybeDefault(left.start, left.loc.start, left);

      if (accessibility || readonly) {
        const pp = this.startNodeAt(startPos, startLoc);

        if (decorators.length) {
          pp.decorators = decorators;
        }

        if (accessibility) pp.accessibility = accessibility;
        if (readonly) pp.readonly = readonly;

        if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") {
          this.raise(pp.start, TSErrors.UnsupportedParameterPropertyKind);
        }

        pp.parameter = elt;
        return this.finishNode(pp, "TSParameterProperty");
      }

      if (decorators.length) {
        left.decorators = decorators;
      }

      return elt;
    }

    parseFunctionBodyAndFinish(node, type, isMethod = false) {
      if (this.match(types.colon)) {
        node.returnType = this.tsParseTypeOrTypePredicateAnnotation(types.colon);
      }

      const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" ? "TSDeclareMethod" : undefined;

      if (bodilessType && !this.match(types.braceL) && this.isLineTerminator()) {
        this.finishNode(node, bodilessType);
        return;
      }

      super.parseFunctionBodyAndFinish(node, type, isMethod);
    }

    registerFunctionStatementId(node) {
      if (!node.body && node.id) {
        this.checkLVal(node.id, BIND_TS_AMBIENT, null, "function name");
      } else {
        super.registerFunctionStatementId(...arguments);
      }
    }

    parseSubscript(base, startPos, startLoc, noCalls, state) {
      if (!this.hasPrecedingLineBreak() && this.match(types.bang)) {
        this.state.exprAllowed = false;
        this.next();
        const nonNullExpression = this.startNodeAt(startPos, startLoc);
        nonNullExpression.expression = base;
        return this.finishNode(nonNullExpression, "TSNonNullExpression");
      }

      if (this.isRelational("<")) {
        const result = this.tsTryParseAndCatch(() => {
          if (!noCalls && this.atPossibleAsyncArrow(base)) {
            const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(startPos, startLoc);

            if (asyncArrowFn) {
              return asyncArrowFn;
            }
          }

          const node = this.startNodeAt(startPos, startLoc);
          node.callee = base;
          const typeArguments = this.tsParseTypeArguments();

          if (typeArguments) {
            if (!noCalls && this.eat(types.parenL)) {
              node.arguments = this.parseCallExpressionArguments(types.parenR, false);
              node.typeParameters = typeArguments;
              return this.finishCallExpression(node, state.optionalChainMember);
            } else if (this.match(types.backQuote)) {
              const result = this.parseTaggedTemplateExpression(base, startPos, startLoc, state);
              result.typeParameters = typeArguments;
              return result;
            }
          }

          this.unexpected();
        });
        if (result) return result;
      }

      return super.parseSubscript(base, startPos, startLoc, noCalls, state);
    }

    parseNewArguments(node) {
      if (this.isRelational("<")) {
        const typeParameters = this.tsTryParseAndCatch(() => {
          const args = this.tsParseTypeArguments();
          if (!this.match(types.parenL)) this.unexpected();
          return args;
        });

        if (typeParameters) {
          node.typeParameters = typeParameters;
        }
      }

      super.parseNewArguments(node);
    }

    parseExprOp(left, leftStartPos, leftStartLoc, minPrec) {
      if (nonNull(types._in.binop) > minPrec && !this.hasPrecedingLineBreak() && this.isContextual("as")) {
        const node = this.startNodeAt(leftStartPos, leftStartLoc);
        node.expression = left;

        const _const = this.tsTryNextParseConstantContext();

        if (_const) {
          node.typeAnnotation = _const;
        } else {
          node.typeAnnotation = this.tsNextThenParseType();
        }

        this.finishNode(node, "TSAsExpression");
        this.reScan_lt_gt();
        return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec);
      }

      return super.parseExprOp(left, leftStartPos, leftStartLoc, minPrec);
    }

    checkReservedWord(word, startLoc, checkKeywords, isBinding) {}

    checkDuplicateExports() {}

    parseImport(node) {
      if (this.match(types.name) || this.match(types.star) || this.match(types.braceL)) {
        const ahead = this.lookahead();

        if (this.match(types.name) && ahead.type === types.eq) {
          return this.tsParseImportEqualsDeclaration(node);
        }

        if (this.isContextual("type") && ahead.type !== types.comma && !(ahead.type === types.name && ahead.value === "from")) {
          node.importKind = "type";
          this.next();
        } else {
          node.importKind = "value";
        }
      }

      const importNode = super.parseImport(node);

      if (importNode.importKind === "type" && importNode.specifiers.length > 1 && importNode.specifiers[0].type === "ImportDefaultSpecifier") {
        this.raise(importNode.start, "A type-only import can specify a default import or named bindings, but not both.");
      }

      return importNode;
    }

    parseExport(node) {
      if (this.match(types._import)) {
        this.expect(types._import);
        return this.tsParseImportEqualsDeclaration(node, true);
      } else if (this.eat(types.eq)) {
        const assign = node;
        assign.expression = this.parseExpression();
        this.semicolon();
        return this.finishNode(assign, "TSExportAssignment");
      } else if (this.eatContextual("as")) {
        const decl = node;
        this.expectContextual("namespace");
        decl.id = this.parseIdentifier();
        this.semicolon();
        return this.finishNode(decl, "TSNamespaceExportDeclaration");
      } else {
        if (this.isContextual("type") && this.lookahead().type === types.braceL) {
          this.next();
          node.exportKind = "type";
        } else {
          node.exportKind = "value";
        }

        return super.parseExport(node);
      }
    }

    isAbstractClass() {
      return this.isContextual("abstract") && this.lookahead().type === types._class;
    }

    parseExportDefaultExpression() {
      if (this.isAbstractClass()) {
        const cls = this.startNode();
        this.next();
        this.parseClass(cls, true, true);
        cls.abstract = true;
        return cls;
      }

      if (this.state.value === "interface") {
        const result = this.tsParseDeclaration(this.startNode(), this.state.value, true);
        if (result) return result;
      }

      return super.parseExportDefaultExpression();
    }

    parseStatementContent(context, topLevel) {
      if (this.state.type === types._const) {
        const ahead = this.lookahead();

        if (ahead.type === types.name && ahead.value === "enum") {
          const node = this.startNode();
          this.expect(types._const);
          this.expectContextual("enum");
          return this.tsParseEnumDeclaration(node, true);
        }
      }

      return super.parseStatementContent(context, topLevel);
    }

    parseAccessModifier() {
      return this.tsParseModifier(["public", "protected", "private"]);
    }

    parseClassMember(classBody, member, state, constructorAllowsSuper) {
      this.tsParseModifiers(member, ["declare"]);
      const accessibility = this.parseAccessModifier();
      if (accessibility) member.accessibility = accessibility;
      this.tsParseModifiers(member, ["declare"]);
      super.parseClassMember(classBody, member, state, constructorAllowsSuper);
    }

    parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper) {
      this.tsParseModifiers(member, ["abstract", "readonly", "declare"]);
      const idx = this.tsTryParseIndexSignature(member);

      if (idx) {
        classBody.body.push(idx);

        if (member.abstract) {
          this.raise(member.start, TSErrors.IndexSignatureHasAbstract);
        }

        if (isStatic) {
          this.raise(member.start, TSErrors.IndexSignatureHasStatic);
        }

        if (member.accessibility) {
          this.raise(member.start, TSErrors.IndexSignatureHasAccessibility, member.accessibility);
        }

        return;
      }

      super.parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper);
    }

    parsePostMemberNameModifiers(methodOrProp) {
      const optional = this.eat(types.question);
      if (optional) methodOrProp.optional = true;

      if (methodOrProp.readonly && this.match(types.parenL)) {
        this.raise(methodOrProp.start, TSErrors.ClassMethodHasReadonly);
      }

      if (methodOrProp.declare && this.match(types.parenL)) {
        this.raise(methodOrProp.start, TSErrors.ClassMethodHasDeclare);
      }
    }

    parseExpressionStatement(node, expr) {
      const decl = expr.type === "Identifier" ? this.tsParseExpressionStatement(node, expr) : undefined;
      return decl || super.parseExpressionStatement(node, expr);
    }

    shouldParseExportDeclaration() {
      if (this.tsIsDeclarationStart()) return true;
      return super.shouldParseExportDeclaration();
    }

    parseConditional(expr, startPos, startLoc, refNeedsArrowPos) {
      if (!refNeedsArrowPos || !this.match(types.question)) {
        return super.parseConditional(expr, startPos, startLoc, refNeedsArrowPos);
      }

      const result = this.tryParse(() => super.parseConditional(expr, startPos, startLoc));

      if (!result.node) {
        refNeedsArrowPos.start = result.error.pos || this.state.start;
        return expr;
      }

      if (result.error) this.state = result.failState;
      return result.node;
    }

    parseParenItem(node, startPos, startLoc) {
      node = super.parseParenItem(node, startPos, startLoc);

      if (this.eat(types.question)) {
        node.optional = true;
        this.resetEndLocation(node);
      }

      if (this.match(types.colon)) {
        const typeCastNode = this.startNodeAt(startPos, startLoc);
        typeCastNode.expression = node;
        typeCastNode.typeAnnotation = this.tsParseTypeAnnotation();
        return this.finishNode(typeCastNode, "TSTypeCastExpression");
      }

      return node;
    }

    parseExportDeclaration(node) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const isDeclare = this.eatContextual("declare");
      let declaration;

      if (this.match(types.name)) {
        declaration = this.tsTryParseExportDeclaration();
      }

      if (!declaration) {
        declaration = super.parseExportDeclaration(node);
      }

      if (declaration && (declaration.type === "TSInterfaceDeclaration" || declaration.type === "TSTypeAliasDeclaration" || isDeclare)) {
        node.exportKind = "type";
      }

      if (declaration && isDeclare) {
        this.resetStartLocation(declaration, startPos, startLoc);
        declaration.declare = true;
      }

      return declaration;
    }

    parseClassId(node, isStatement, optionalId) {
      if ((!isStatement || optionalId) && this.isContextual("implements")) {
        return;
      }

      super.parseClassId(node, isStatement, optionalId, node.declare ? BIND_TS_AMBIENT : BIND_CLASS);
      const typeParameters = this.tsTryParseTypeParameters();
      if (typeParameters) node.typeParameters = typeParameters;
    }

    parseClassPropertyAnnotation(node) {
      if (!node.optional && this.eat(types.bang)) {
        node.definite = true;
      }

      const type = this.tsTryParseTypeAnnotation();
      if (type) node.typeAnnotation = type;
    }

    parseClassProperty(node) {
      this.parseClassPropertyAnnotation(node);

      if (node.declare && this.match(types.equal)) {
        this.raise(this.state.start, TSErrors.DeclareClassFieldHasInitializer);
      }

      return super.parseClassProperty(node);
    }

    parseClassPrivateProperty(node) {
      if (node.abstract) {
        this.raise(node.start, TSErrors.PrivateElementHasAbstract);
      }

      if (node.accessibility) {
        this.raise(node.start, TSErrors.PrivateElementHasAccessibility, node.accessibility);
      }

      this.parseClassPropertyAnnotation(node);
      return super.parseClassPrivateProperty(node);
    }

    pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
      const typeParameters = this.tsTryParseTypeParameters();
      if (typeParameters) method.typeParameters = typeParameters;
      super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper);
    }

    pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
      const typeParameters = this.tsTryParseTypeParameters();
      if (typeParameters) method.typeParameters = typeParameters;
      super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync);
    }

    parseClassSuper(node) {
      super.parseClassSuper(node);

      if (node.superClass && this.isRelational("<")) {
        node.superTypeParameters = this.tsParseTypeArguments();
      }

      if (this.eatContextual("implements")) {
        node.implements = this.tsParseHeritageClause("implements");
      }
    }

    parseObjPropValue(prop, ...args) {
      const typeParameters = this.tsTryParseTypeParameters();
      if (typeParameters) prop.typeParameters = typeParameters;
      super.parseObjPropValue(prop, ...args);
    }

    parseFunctionParams(node, allowModifiers) {
      const typeParameters = this.tsTryParseTypeParameters();
      if (typeParameters) node.typeParameters = typeParameters;
      super.parseFunctionParams(node, allowModifiers);
    }

    parseVarId(decl, kind) {
      super.parseVarId(decl, kind);

      if (decl.id.type === "Identifier" && this.eat(types.bang)) {
        decl.definite = true;
      }

      const type = this.tsTryParseTypeAnnotation();

      if (type) {
        decl.id.typeAnnotation = type;
        this.resetEndLocation(decl.id);
      }
    }

    parseAsyncArrowFromCallExpression(node, call) {
      if (this.match(types.colon)) {
        node.returnType = this.tsParseTypeAnnotation();
      }

      return super.parseAsyncArrowFromCallExpression(node, call);
    }

    parseMaybeAssign(...args) {
      var _jsx, _jsx2, _typeCast, _jsx3, _typeCast2, _jsx4, _typeCast3;

      let state;
      let jsx;
      let typeCast;

      if (this.match(types.jsxTagStart)) {
        state = this.state.clone();
        jsx = this.tryParse(() => super.parseMaybeAssign(...args), state);
        if (!jsx.error) return jsx.node;
        const {
          context
        } = this.state;

        if (context[context.length - 1] === types$1.j_oTag) {
          context.length -= 2;
        } else if (context[context.length - 1] === types$1.j_expr) {
          context.length -= 1;
        }
      }

      if (!((_jsx = jsx) == null ? void 0 : _jsx.error) && !this.isRelational("<")) {
        return super.parseMaybeAssign(...args);
      }

      let typeParameters;
      state = state || this.state.clone();
      const arrow = this.tryParse(abort => {
        var _typeParameters;

        typeParameters = this.tsParseTypeParameters();
        const expr = super.parseMaybeAssign(...args);

        if (expr.type !== "ArrowFunctionExpression" || expr.extra && expr.extra.parenthesized) {
          abort();
        }

        if (((_typeParameters = typeParameters) == null ? void 0 : _typeParameters.params.length) !== 0) {
          this.resetStartLocationFromNode(expr, typeParameters);
        }

        expr.typeParameters = typeParameters;
        return expr;
      }, state);
      if (!arrow.error && !arrow.aborted) return arrow.node;

      if (!jsx) {
        assert(!this.hasPlugin("jsx"));
        typeCast = this.tryParse(() => super.parseMaybeAssign(...args), state);
        if (!typeCast.error) return typeCast.node;
      }

      if ((_jsx2 = jsx) == null ? void 0 : _jsx2.node) {
        this.state = jsx.failState;
        return jsx.node;
      }

      if (arrow.node) {
        this.state = arrow.failState;
        return arrow.node;
      }

      if ((_typeCast = typeCast) == null ? void 0 : _typeCast.node) {
        this.state = typeCast.failState;
        return typeCast.node;
      }

      if ((_jsx3 = jsx) == null ? void 0 : _jsx3.thrown) throw jsx.error;
      if (arrow.thrown) throw arrow.error;
      if ((_typeCast2 = typeCast) == null ? void 0 : _typeCast2.thrown) throw typeCast.error;
      throw ((_jsx4 = jsx) == null ? void 0 : _jsx4.error) || arrow.error || ((_typeCast3 = typeCast) == null ? void 0 : _typeCast3.error);
    }

    parseMaybeUnary(refExpressionErrors) {
      if (!this.hasPlugin("jsx") && this.isRelational("<")) {
        return this.tsParseTypeAssertion();
      } else {
        return super.parseMaybeUnary(refExpressionErrors);
      }
    }

    parseArrow(node) {
      if (this.match(types.colon)) {
        const result = this.tryParse(abort => {
          const returnType = this.tsParseTypeOrTypePredicateAnnotation(types.colon);
          if (this.canInsertSemicolon() || !this.match(types.arrow)) abort();
          return returnType;
        });
        if (result.aborted) return;

        if (!result.thrown) {
          if (result.error) this.state = result.failState;
          node.returnType = result.node;
        }
      }

      return super.parseArrow(node);
    }

    parseAssignableListItemTypes(param) {
      if (this.eat(types.question)) {
        if (param.type !== "Identifier") {
          this.raise(param.start, TSErrors.PatternIsOptional);
        }

        param.optional = true;
      }

      const type = this.tsTryParseTypeAnnotation();
      if (type) param.typeAnnotation = type;
      this.resetEndLocation(param);
      return param;
    }

    toAssignable(node) {
      switch (node.type) {
        case "TSTypeCastExpression":
          return super.toAssignable(this.typeCastToParameter(node));

        case "TSParameterProperty":
          return super.toAssignable(node);

        case "TSAsExpression":
        case "TSNonNullExpression":
        case "TSTypeAssertion":
          node.expression = this.toAssignable(node.expression);
          return node;

        default:
          return super.toAssignable(node);
      }
    }

    checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription) {
      switch (expr.type) {
        case "TSTypeCastExpression":
          return;

        case "TSParameterProperty":
          this.checkLVal(expr.parameter, bindingType, checkClashes, "parameter property");
          return;

        case "TSAsExpression":
        case "TSNonNullExpression":
        case "TSTypeAssertion":
          this.checkLVal(expr.expression, bindingType, checkClashes, contextDescription);
          return;

        default:
          super.checkLVal(expr, bindingType, checkClashes, contextDescription);
          return;
      }
    }

    parseBindingAtom() {
      switch (this.state.type) {
        case types._this:
          return this.parseIdentifier(true);

        default:
          return super.parseBindingAtom();
      }
    }

    parseMaybeDecoratorArguments(expr) {
      if (this.isRelational("<")) {
        const typeArguments = this.tsParseTypeArguments();

        if (this.match(types.parenL)) {
          const call = super.parseMaybeDecoratorArguments(expr);
          call.typeParameters = typeArguments;
          return call;
        }

        this.unexpected(this.state.start, types.parenL);
      }

      return super.parseMaybeDecoratorArguments(expr);
    }

    isClassMethod() {
      return this.isRelational("<") || super.isClassMethod();
    }

    isClassProperty() {
      return this.match(types.bang) || this.match(types.colon) || super.isClassProperty();
    }

    parseMaybeDefault(...args) {
      const node = super.parseMaybeDefault(...args);

      if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
        this.raise(node.typeAnnotation.start, TSErrors.TypeAnnotationAfterAssign);
      }

      return node;
    }

    getTokenFromCode(code) {
      if (this.state.inType && (code === 62 || code === 60)) {
        return this.finishOp(types.relational, 1);
      } else {
        return super.getTokenFromCode(code);
      }
    }

    reScan_lt_gt() {
      if (this.match(types.relational)) {
        const code = this.input.charCodeAt(this.state.start);

        if (code === 60 || code === 62) {
          this.state.pos -= 1;
          this.readToken_lt_gt(code);
        }
      }
    }

    toAssignableList(exprList) {
      for (let i = 0; i < exprList.length; i++) {
        const expr = exprList[i];
        if (!expr) continue;

        switch (expr.type) {
          case "TSTypeCastExpression":
            exprList[i] = this.typeCastToParameter(expr);
            break;

          case "TSAsExpression":
          case "TSTypeAssertion":
            if (!this.state.maybeInArrowParameters) {
              exprList[i] = this.typeCastToParameter(expr);
            } else {
              this.raise(expr.start, TSErrors.UnexpectedTypeCastInParameter);
            }

            break;
        }
      }

      return super.toAssignableList(...arguments);
    }

    typeCastToParameter(node) {
      node.expression.typeAnnotation = node.typeAnnotation;
      this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end);
      return node.expression;
    }

    toReferencedList(exprList, isInParens) {
      for (let i = 0; i < exprList.length; i++) {
        const expr = exprList[i];

        if ((expr == null ? void 0 : expr.type) === "TSTypeCastExpression") {
          this.raise(expr.start, TSErrors.UnexpectedTypeAnnotation);
        }
      }

      return exprList;
    }

    shouldParseArrow() {
      return this.match(types.colon) || super.shouldParseArrow();
    }

    shouldParseAsyncArrow() {
      return this.match(types.colon) || super.shouldParseAsyncArrow();
    }

    canHaveLeadingDecorator() {
      return super.canHaveLeadingDecorator() || this.isAbstractClass();
    }

    jsxParseOpeningElementAfterName(node) {
      if (this.isRelational("<")) {
        const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArguments());
        if (typeArguments) node.typeParameters = typeArguments;
      }

      return super.jsxParseOpeningElementAfterName(node);
    }

    getGetterSetterExpectedParamCount(method) {
      const baseCount = super.getGetterSetterExpectedParamCount(method);
      const firstParam = method.params[0];
      const hasContextParam = firstParam && firstParam.type === "Identifier" && firstParam.name === "this";
      return hasContextParam ? baseCount + 1 : baseCount;
    }

    parseCatchClauseParam() {
      const param = super.parseCatchClauseParam();
      const type = this.tsTryParseTypeAnnotation();

      if (type) {
        param.typeAnnotation = type;
        this.resetEndLocation(param);
      }

      return param;
    }

  });

  types.placeholder = new TokenType("%%", {
    startsExpr: true
  });
  var placeholders = (superClass => class extends superClass {
    parsePlaceholder(expectedNode) {
      if (this.match(types.placeholder)) {
        const node = this.startNode();
        this.next();
        this.assertNoSpace("Unexpected space in placeholder.");
        node.name = super.parseIdentifier(true);
        this.assertNoSpace("Unexpected space in placeholder.");
        this.expect(types.placeholder);
        return this.finishPlaceholder(node, expectedNode);
      }
    }

    finishPlaceholder(node, expectedNode) {
      const isFinished = !!(node.expectedNode && node.type === "Placeholder");
      node.expectedNode = expectedNode;
      return isFinished ? node : this.finishNode(node, "Placeholder");
    }

    getTokenFromCode(code) {
      if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) {
        return this.finishOp(types.placeholder, 2);
      }

      return super.getTokenFromCode(...arguments);
    }

    parseExprAtom() {
      return this.parsePlaceholder("Expression") || super.parseExprAtom(...arguments);
    }

    parseIdentifier() {
      return this.parsePlaceholder("Identifier") || super.parseIdentifier(...arguments);
    }

    checkReservedWord(word) {
      if (word !== undefined) super.checkReservedWord(...arguments);
    }

    parseBindingAtom() {
      return this.parsePlaceholder("Pattern") || super.parseBindingAtom(...arguments);
    }

    checkLVal(expr) {
      if (expr.type !== "Placeholder") super.checkLVal(...arguments);
    }

    toAssignable(node) {
      if (node && node.type === "Placeholder" && node.expectedNode === "Expression") {
        node.expectedNode = "Pattern";
        return node;
      }

      return super.toAssignable(...arguments);
    }

    verifyBreakContinue(node) {
      if (node.label && node.label.type === "Placeholder") return;
      super.verifyBreakContinue(...arguments);
    }

    parseExpressionStatement(node, expr) {
      if (expr.type !== "Placeholder" || expr.extra && expr.extra.parenthesized) {
        return super.parseExpressionStatement(...arguments);
      }

      if (this.match(types.colon)) {
        const stmt = node;
        stmt.label = this.finishPlaceholder(expr, "Identifier");
        this.next();
        stmt.body = this.parseStatement("label");
        return this.finishNode(stmt, "LabeledStatement");
      }

      this.semicolon();
      node.name = expr.name;
      return this.finishPlaceholder(node, "Statement");
    }

    parseBlock() {
      return this.parsePlaceholder("BlockStatement") || super.parseBlock(...arguments);
    }

    parseFunctionId() {
      return this.parsePlaceholder("Identifier") || super.parseFunctionId(...arguments);
    }

    parseClass(node, isStatement, optionalId) {
      const type = isStatement ? "ClassDeclaration" : "ClassExpression";
      this.next();
      this.takeDecorators(node);
      const oldStrict = this.state.strict;
      const placeholder = this.parsePlaceholder("Identifier");

      if (placeholder) {
        if (this.match(types._extends) || this.match(types.placeholder) || this.match(types.braceL)) {
          node.id = placeholder;
        } else if (optionalId || !isStatement) {
          node.id = null;
          node.body = this.finishPlaceholder(placeholder, "ClassBody");
          return this.finishNode(node, type);
        } else {
          this.unexpected(null, "A class name is required");
        }
      } else {
        this.parseClassId(node, isStatement, optionalId);
      }

      this.parseClassSuper(node);
      node.body = this.parsePlaceholder("ClassBody") || this.parseClassBody(!!node.superClass, oldStrict);
      return this.finishNode(node, type);
    }

    parseExport(node) {
      const placeholder = this.parsePlaceholder("Identifier");
      if (!placeholder) return super.parseExport(...arguments);

      if (!this.isContextual("from") && !this.match(types.comma)) {
        node.specifiers = [];
        node.source = null;
        node.declaration = this.finishPlaceholder(placeholder, "Declaration");
        return this.finishNode(node, "ExportNamedDeclaration");
      }

      this.expectPlugin("exportDefaultFrom");
      const specifier = this.startNode();
      specifier.exported = placeholder;
      node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
      return super.parseExport(node);
    }

    isExportDefaultSpecifier() {
      if (this.match(types._default)) {
        const next = this.nextTokenStart();

        if (this.isUnparsedContextual(next, "from")) {
          if (this.input.startsWith(types.placeholder.label, this.nextTokenStartSince(next + 4))) {
            return true;
          }
        }
      }

      return super.isExportDefaultSpecifier();
    }

    maybeParseExportDefaultSpecifier(node) {
      if (node.specifiers && node.specifiers.length > 0) {
        return true;
      }

      return super.maybeParseExportDefaultSpecifier(...arguments);
    }

    checkExport(node) {
      const {
        specifiers
      } = node;

      if (specifiers == null ? void 0 : specifiers.length) {
        node.specifiers = specifiers.filter(node => node.exported.type === "Placeholder");
      }

      super.checkExport(node);
      node.specifiers = specifiers;
    }

    parseImport(node) {
      const placeholder = this.parsePlaceholder("Identifier");
      if (!placeholder) return super.parseImport(...arguments);
      node.specifiers = [];

      if (!this.isContextual("from") && !this.match(types.comma)) {
        node.source = this.finishPlaceholder(placeholder, "StringLiteral");
        this.semicolon();
        return this.finishNode(node, "ImportDeclaration");
      }

      const specifier = this.startNodeAtNode(placeholder);
      specifier.local = placeholder;
      this.finishNode(specifier, "ImportDefaultSpecifier");
      node.specifiers.push(specifier);

      if (this.eat(types.comma)) {
        const hasStarImport = this.maybeParseStarImportSpecifier(node);
        if (!hasStarImport) this.parseNamedImportSpecifiers(node);
      }

      this.expectContextual("from");
      node.source = this.parseImportSource();
      this.semicolon();
      return this.finishNode(node, "ImportDeclaration");
    }

    parseImportSource() {
      return this.parsePlaceholder("StringLiteral") || super.parseImportSource(...arguments);
    }

  });

  var v8intrinsic = (superClass => class extends superClass {
    parseV8Intrinsic() {
      if (this.match(types.modulo)) {
        const v8IntrinsicStart = this.state.start;
        const node = this.startNode();
        this.eat(types.modulo);

        if (this.match(types.name)) {
          const name = this.parseIdentifierName(this.state.start);
          const identifier = this.createIdentifier(node, name);
          identifier.type = "V8IntrinsicIdentifier";

          if (this.match(types.parenL)) {
            return identifier;
          }
        }

        this.unexpected(v8IntrinsicStart);
      }
    }

    parseExprAtom() {
      return this.parseV8Intrinsic() || super.parseExprAtom(...arguments);
    }

  });

  function hasPlugin(plugins, name) {
    return plugins.some(plugin => {
      if (Array.isArray(plugin)) {
        return plugin[0] === name;
      } else {
        return plugin === name;
      }
    });
  }
  function getPluginOption(plugins, name, option) {
    const plugin = plugins.find(plugin => {
      if (Array.isArray(plugin)) {
        return plugin[0] === name;
      } else {
        return plugin === name;
      }
    });

    if (plugin && Array.isArray(plugin)) {
      return plugin[1][option];
    }

    return null;
  }
  const PIPELINE_PROPOSALS = ["minimal", "smart", "fsharp"];
  const RECORD_AND_TUPLE_SYNTAX_TYPES = ["hash", "bar"];
  function validatePlugins(plugins) {
    if (hasPlugin(plugins, "decorators")) {
      if (hasPlugin(plugins, "decorators-legacy")) {
        throw new Error("Cannot use the decorators and decorators-legacy plugin together");
      }

      const decoratorsBeforeExport = getPluginOption(plugins, "decorators", "decoratorsBeforeExport");

      if (decoratorsBeforeExport == null) {
        throw new Error("The 'decorators' plugin requires a 'decoratorsBeforeExport' option," + " whose value must be a boolean. If you are migrating from" + " Babylon/Babel 6 or want to use the old decorators proposal, you" + " should use the 'decorators-legacy' plugin instead of 'decorators'.");
      } else if (typeof decoratorsBeforeExport !== "boolean") {
        throw new Error("'decoratorsBeforeExport' must be a boolean.");
      }
    }

    if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) {
      throw new Error("Cannot combine flow and typescript plugins.");
    }

    if (hasPlugin(plugins, "placeholders") && hasPlugin(plugins, "v8intrinsic")) {
      throw new Error("Cannot combine placeholders and v8intrinsic plugins.");
    }

    if (hasPlugin(plugins, "pipelineOperator") && !PIPELINE_PROPOSALS.includes(getPluginOption(plugins, "pipelineOperator", "proposal"))) {
      throw new Error("'pipelineOperator' requires 'proposal' option whose value should be one of: " + PIPELINE_PROPOSALS.map(p => `'${p}'`).join(", "));
    }

    if (hasPlugin(plugins, "moduleAttributes")) {
      const moduleAttributesVerionPluginOption = getPluginOption(plugins, "moduleAttributes", "version");

      if (moduleAttributesVerionPluginOption !== "may-2020") {
        throw new Error("The 'moduleAttributes' plugin requires a 'version' option," + " representing the last proposal update. Currently, the" + " only supported value is 'may-2020'.");
      }
    }

    if (hasPlugin(plugins, "recordAndTuple") && !RECORD_AND_TUPLE_SYNTAX_TYPES.includes(getPluginOption(plugins, "recordAndTuple", "syntaxType"))) {
      throw new Error("'recordAndTuple' requires 'syntaxType' option whose value should be one of: " + RECORD_AND_TUPLE_SYNTAX_TYPES.map(p => `'${p}'`).join(", "));
    }
  }
  const mixinPlugins = {
    estree,
    jsx,
    flow,
    typescript,
    v8intrinsic,
    placeholders
  };
  const mixinPluginNames = Object.keys(mixinPlugins);

  const defaultOptions = {
    sourceType: "script",
    sourceFilename: undefined,
    startLine: 1,
    allowAwaitOutsideFunction: false,
    allowReturnOutsideFunction: false,
    allowImportExportEverywhere: false,
    allowSuperOutsideMethod: false,
    allowUndeclaredExports: false,
    plugins: [],
    strictMode: null,
    ranges: false,
    tokens: false,
    createParenthesizedExpressions: false,
    errorRecovery: false
  };
  function getOptions(opts) {
    const options = {};

    for (let _i = 0, _Object$keys = Object.keys(defaultOptions); _i < _Object$keys.length; _i++) {
      const key = _Object$keys[_i];
      options[key] = opts && opts[key] != null ? opts[key] : defaultOptions[key];
    }

    return options;
  }

  class State {
    constructor() {
      this.errors = [];
      this.potentialArrowAt = -1;
      this.noArrowAt = [];
      this.noArrowParamsConversionAt = [];
      this.inParameters = false;
      this.maybeInArrowParameters = false;
      this.maybeInAsyncArrowHead = false;
      this.inPipeline = false;
      this.inType = false;
      this.noAnonFunctionType = false;
      this.inPropertyName = false;
      this.hasFlowComment = false;
      this.isIterator = false;
      this.topicContext = {
        maxNumOfResolvableTopics: 0,
        maxTopicIndex: null
      };
      this.soloAwait = false;
      this.inFSharpPipelineDirectBody = false;
      this.labels = [];
      this.decoratorStack = [[]];
      this.yieldPos = -1;
      this.awaitPos = -1;
      this.comments = [];
      this.trailingComments = [];
      this.leadingComments = [];
      this.commentStack = [];
      this.commentPreviousNode = null;
      this.pos = 0;
      this.lineStart = 0;
      this.type = types.eof;
      this.value = null;
      this.start = 0;
      this.end = 0;
      this.lastTokEndLoc = null;
      this.lastTokStartLoc = null;
      this.lastTokStart = 0;
      this.lastTokEnd = 0;
      this.context = [types$1.braceStatement];
      this.exprAllowed = true;
      this.containsEsc = false;
      this.octalPositions = [];
      this.exportedIdentifiers = [];
      this.tokensLength = 0;
    }

    init(options) {
      this.strict = options.strictMode === false ? false : options.sourceType === "module";
      this.curLine = options.startLine;
      this.startLoc = this.endLoc = this.curPosition();
    }

    curPosition() {
      return new Position(this.curLine, this.pos - this.lineStart);
    }

    clone(skipArrays) {
      const state = new State();
      const keys = Object.keys(this);

      for (let i = 0, length = keys.length; i < length; i++) {
        const key = keys[i];
        let val = this[key];

        if (!skipArrays && Array.isArray(val)) {
          val = val.slice();
        }

        state[key] = val;
      }

      return state;
    }

  }

  var _isDigit = function isDigit(code) {
    return code >= 48 && code <= 57;
  };
  const VALID_REGEX_FLAGS = new Set(["g", "m", "s", "i", "y", "u"]);
  const forbiddenNumericSeparatorSiblings = {
    decBinOct: [46, 66, 69, 79, 95, 98, 101, 111],
    hex: [46, 88, 95, 120]
  };
  const allowedNumericSeparatorSiblings = {};
  allowedNumericSeparatorSiblings.bin = [48, 49];
  allowedNumericSeparatorSiblings.oct = [...allowedNumericSeparatorSiblings.bin, 50, 51, 52, 53, 54, 55];
  allowedNumericSeparatorSiblings.dec = [...allowedNumericSeparatorSiblings.oct, 56, 57];
  allowedNumericSeparatorSiblings.hex = [...allowedNumericSeparatorSiblings.dec, 65, 66, 67, 68, 69, 70, 97, 98, 99, 100, 101, 102];
  class Token {
    constructor(state) {
      this.type = state.type;
      this.value = state.value;
      this.start = state.start;
      this.end = state.end;
      this.loc = new SourceLocation(state.startLoc, state.endLoc);
    }

  }
  class Tokenizer extends ParserError {
    constructor(options, input) {
      super();
      this.tokens = [];
      this.state = new State();
      this.state.init(options);
      this.input = input;
      this.length = input.length;
      this.isLookahead = false;
    }

    pushToken(token) {
      this.tokens.length = this.state.tokensLength;
      this.tokens.push(token);
      ++this.state.tokensLength;
    }

    next() {
      if (!this.isLookahead) {
        this.checkKeywordEscapes();

        if (this.options.tokens) {
          this.pushToken(new Token(this.state));
        }
      }

      this.state.lastTokEnd = this.state.end;
      this.state.lastTokStart = this.state.start;
      this.state.lastTokEndLoc = this.state.endLoc;
      this.state.lastTokStartLoc = this.state.startLoc;
      this.nextToken();
    }

    eat(type) {
      if (this.match(type)) {
        this.next();
        return true;
      } else {
        return false;
      }
    }

    match(type) {
      return this.state.type === type;
    }

    lookahead() {
      const old = this.state;
      this.state = old.clone(true);
      this.isLookahead = true;
      this.next();
      this.isLookahead = false;
      const curr = this.state;
      this.state = old;
      return curr;
    }

    nextTokenStart() {
      return this.nextTokenStartSince(this.state.pos);
    }

    nextTokenStartSince(pos) {
      skipWhiteSpace.lastIndex = pos;
      const skip = skipWhiteSpace.exec(this.input);
      return pos + skip[0].length;
    }

    lookaheadCharCode() {
      return this.input.charCodeAt(this.nextTokenStart());
    }

    setStrict(strict) {
      this.state.strict = strict;
      if (!this.match(types.num) && !this.match(types.string)) return;
      this.state.pos = this.state.start;

      while (this.state.pos < this.state.lineStart) {
        this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1;
        --this.state.curLine;
      }

      this.nextToken();
    }

    curContext() {
      return this.state.context[this.state.context.length - 1];
    }

    nextToken() {
      const curContext = this.curContext();
      if (!(curContext == null ? void 0 : curContext.preserveSpace)) this.skipSpace();
      this.state.octalPositions = [];
      this.state.start = this.state.pos;
      this.state.startLoc = this.state.curPosition();

      if (this.state.pos >= this.length) {
        this.finishToken(types.eof);
        return;
      }

      const override = curContext == null ? void 0 : curContext.override;

      if (override) {
        override(this);
      } else {
        this.getTokenFromCode(this.input.codePointAt(this.state.pos));
      }
    }

    pushComment(block, text, start, end, startLoc, endLoc) {
      const comment = {
        type: block ? "CommentBlock" : "CommentLine",
        value: text,
        start: start,
        end: end,
        loc: new SourceLocation(startLoc, endLoc)
      };
      if (this.options.tokens) this.pushToken(comment);
      this.state.comments.push(comment);
      this.addComment(comment);
    }

    skipBlockComment() {
      const startLoc = this.state.curPosition();
      const start = this.state.pos;
      const end = this.input.indexOf("*/", this.state.pos + 2);
      if (end === -1) throw this.raise(start, ErrorMessages.UnterminatedComment);
      this.state.pos = end + 2;
      lineBreakG.lastIndex = start;
      let match;

      while ((match = lineBreakG.exec(this.input)) && match.index < this.state.pos) {
        ++this.state.curLine;
        this.state.lineStart = match.index + match[0].length;
      }

      if (this.isLookahead) return;
      this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition());
    }

    skipLineComment(startSkip) {
      const start = this.state.pos;
      const startLoc = this.state.curPosition();
      let ch = this.input.charCodeAt(this.state.pos += startSkip);

      if (this.state.pos < this.length) {
        while (!isNewLine(ch) && ++this.state.pos < this.length) {
          ch = this.input.charCodeAt(this.state.pos);
        }
      }

      if (this.isLookahead) return;
      this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition());
    }

    skipSpace() {
      loop: while (this.state.pos < this.length) {
        const ch = this.input.charCodeAt(this.state.pos);

        switch (ch) {
          case 32:
          case 160:
          case 9:
            ++this.state.pos;
            break;

          case 13:
            if (this.input.charCodeAt(this.state.pos + 1) === 10) {
              ++this.state.pos;
            }

          case 10:
          case 8232:
          case 8233:
            ++this.state.pos;
            ++this.state.curLine;
            this.state.lineStart = this.state.pos;
            break;

          case 47:
            switch (this.input.charCodeAt(this.state.pos + 1)) {
              case 42:
                this.skipBlockComment();
                break;

              case 47:
                this.skipLineComment(2);
                break;

              default:
                break loop;
            }

            break;

          default:
            if (isWhitespace(ch)) {
              ++this.state.pos;
            } else {
              break loop;
            }

        }
      }
    }

    finishToken(type, val) {
      this.state.end = this.state.pos;
      this.state.endLoc = this.state.curPosition();
      const prevType = this.state.type;
      this.state.type = type;
      this.state.value = val;
      if (!this.isLookahead) this.updateContext(prevType);
    }

    readToken_numberSign() {
      if (this.state.pos === 0 && this.readToken_interpreter()) {
        return;
      }

      const nextPos = this.state.pos + 1;
      const next = this.input.charCodeAt(nextPos);

      if (next >= 48 && next <= 57) {
        throw this.raise(this.state.pos, ErrorMessages.UnexpectedDigitAfterHash);
      }

      if (next === 123 || next === 91 && this.hasPlugin("recordAndTuple")) {
        this.expectPlugin("recordAndTuple");

        if (this.getPluginOption("recordAndTuple", "syntaxType") !== "hash") {
          throw this.raise(this.state.pos, next === 123 ? ErrorMessages.RecordExpressionHashIncorrectStartSyntaxType : ErrorMessages.TupleExpressionHashIncorrectStartSyntaxType);
        }

        if (next === 123) {
          this.finishToken(types.braceHashL);
        } else {
          this.finishToken(types.bracketHashL);
        }

        this.state.pos += 2;
      } else {
        this.finishOp(types.hash, 1);
      }
    }

    readToken_dot() {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (next >= 48 && next <= 57) {
        this.readNumber(true);
        return;
      }

      if (next === 46 && this.input.charCodeAt(this.state.pos + 2) === 46) {
        this.state.pos += 3;
        this.finishToken(types.ellipsis);
      } else {
        ++this.state.pos;
        this.finishToken(types.dot);
      }
    }

    readToken_slash() {
      if (this.state.exprAllowed && !this.state.inType) {
        ++this.state.pos;
        this.readRegexp();
        return;
      }

      const next = this.input.charCodeAt(this.state.pos + 1);

      if (next === 61) {
        this.finishOp(types.assign, 2);
      } else {
        this.finishOp(types.slash, 1);
      }
    }

    readToken_interpreter() {
      if (this.state.pos !== 0 || this.length < 2) return false;
      let ch = this.input.charCodeAt(this.state.pos + 1);
      if (ch !== 33) return false;
      const start = this.state.pos;
      this.state.pos += 1;

      while (!isNewLine(ch) && ++this.state.pos < this.length) {
        ch = this.input.charCodeAt(this.state.pos);
      }

      const value = this.input.slice(start + 2, this.state.pos);
      this.finishToken(types.interpreterDirective, value);
      return true;
    }

    readToken_mult_modulo(code) {
      let type = code === 42 ? types.star : types.modulo;
      let width = 1;
      let next = this.input.charCodeAt(this.state.pos + 1);
      const exprAllowed = this.state.exprAllowed;

      if (code === 42 && next === 42) {
        width++;
        next = this.input.charCodeAt(this.state.pos + 2);
        type = types.exponent;
      }

      if (next === 61 && !exprAllowed) {
        width++;
        type = types.assign;
      }

      this.finishOp(type, width);
    }

    readToken_pipe_amp(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (next === code) {
        if (this.input.charCodeAt(this.state.pos + 2) === 61) {
          this.finishOp(types.assign, 3);
        } else {
          this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2);
        }

        return;
      }

      if (code === 124) {
        if (next === 62) {
          this.finishOp(types.pipeline, 2);
          return;
        }

        if (this.hasPlugin("recordAndTuple") && next === 125) {
          if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
            throw this.raise(this.state.pos, ErrorMessages.RecordExpressionBarIncorrectEndSyntaxType);
          }

          this.finishOp(types.braceBarR, 2);
          return;
        }

        if (this.hasPlugin("recordAndTuple") && next === 93) {
          if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
            throw this.raise(this.state.pos, ErrorMessages.TupleExpressionBarIncorrectEndSyntaxType);
          }

          this.finishOp(types.bracketBarR, 2);
          return;
        }
      }

      if (next === 61) {
        this.finishOp(types.assign, 2);
        return;
      }

      this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1);
    }

    readToken_caret() {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (next === 61) {
        this.finishOp(types.assign, 2);
      } else {
        this.finishOp(types.bitwiseXOR, 1);
      }
    }

    readToken_plus_min(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (next === code) {
        if (next === 45 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 62 && (this.state.lastTokEnd === 0 || this.hasPrecedingLineBreak())) {
          this.skipLineComment(3);
          this.skipSpace();
          this.nextToken();
          return;
        }

        this.finishOp(types.incDec, 2);
        return;
      }

      if (next === 61) {
        this.finishOp(types.assign, 2);
      } else {
        this.finishOp(types.plusMin, 1);
      }
    }

    readToken_lt_gt(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);
      let size = 1;

      if (next === code) {
        size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2;

        if (this.input.charCodeAt(this.state.pos + size) === 61) {
          this.finishOp(types.assign, size + 1);
          return;
        }

        this.finishOp(types.bitShift, size);
        return;
      }

      if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) {
        this.skipLineComment(4);
        this.skipSpace();
        this.nextToken();
        return;
      }

      if (next === 61) {
        size = 2;
      }

      this.finishOp(types.relational, size);
    }

    readToken_eq_excl(code) {
      const next = this.input.charCodeAt(this.state.pos + 1);

      if (next === 61) {
        this.finishOp(types.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2);
        return;
      }

      if (code === 61 && next === 62) {
        this.state.pos += 2;
        this.finishToken(types.arrow);
        return;
      }

      this.finishOp(code === 61 ? types.eq : types.bang, 1);
    }

    readToken_question() {
      const next = this.input.charCodeAt(this.state.pos + 1);
      const next2 = this.input.charCodeAt(this.state.pos + 2);

      if (next === 63) {
        if (next2 === 61) {
          this.finishOp(types.assign, 3);
        } else {
          this.finishOp(types.nullishCoalescing, 2);
        }
      } else if (next === 46 && !(next2 >= 48 && next2 <= 57)) {
        this.state.pos += 2;
        this.finishToken(types.questionDot);
      } else {
        ++this.state.pos;
        this.finishToken(types.question);
      }
    }

    getTokenFromCode(code) {
      switch (code) {
        case 46:
          this.readToken_dot();
          return;

        case 40:
          ++this.state.pos;
          this.finishToken(types.parenL);
          return;

        case 41:
          ++this.state.pos;
          this.finishToken(types.parenR);
          return;

        case 59:
          ++this.state.pos;
          this.finishToken(types.semi);
          return;

        case 44:
          ++this.state.pos;
          this.finishToken(types.comma);
          return;

        case 91:
          if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) {
            if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
              throw this.raise(this.state.pos, ErrorMessages.TupleExpressionBarIncorrectStartSyntaxType);
            }

            this.finishToken(types.bracketBarL);
            this.state.pos += 2;
          } else {
            ++this.state.pos;
            this.finishToken(types.bracketL);
          }

          return;

        case 93:
          ++this.state.pos;
          this.finishToken(types.bracketR);
          return;

        case 123:
          if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) {
            if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
              throw this.raise(this.state.pos, ErrorMessages.RecordExpressionBarIncorrectStartSyntaxType);
            }

            this.finishToken(types.braceBarL);
            this.state.pos += 2;
          } else {
            ++this.state.pos;
            this.finishToken(types.braceL);
          }

          return;

        case 125:
          ++this.state.pos;
          this.finishToken(types.braceR);
          return;

        case 58:
          if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) {
            this.finishOp(types.doubleColon, 2);
          } else {
            ++this.state.pos;
            this.finishToken(types.colon);
          }

          return;

        case 63:
          this.readToken_question();
          return;

        case 96:
          ++this.state.pos;
          this.finishToken(types.backQuote);
          return;

        case 48:
          {
            const next = this.input.charCodeAt(this.state.pos + 1);

            if (next === 120 || next === 88) {
              this.readRadixNumber(16);
              return;
            }

            if (next === 111 || next === 79) {
              this.readRadixNumber(8);
              return;
            }

            if (next === 98 || next === 66) {
              this.readRadixNumber(2);
              return;
            }
          }

        case 49:
        case 50:
        case 51:
        case 52:
        case 53:
        case 54:
        case 55:
        case 56:
        case 57:
          this.readNumber(false);
          return;

        case 34:
        case 39:
          this.readString(code);
          return;

        case 47:
          this.readToken_slash();
          return;

        case 37:
        case 42:
          this.readToken_mult_modulo(code);
          return;

        case 124:
        case 38:
          this.readToken_pipe_amp(code);
          return;

        case 94:
          this.readToken_caret();
          return;

        case 43:
        case 45:
          this.readToken_plus_min(code);
          return;

        case 60:
        case 62:
          this.readToken_lt_gt(code);
          return;

        case 61:
        case 33:
          this.readToken_eq_excl(code);
          return;

        case 126:
          this.finishOp(types.tilde, 1);
          return;

        case 64:
          ++this.state.pos;
          this.finishToken(types.at);
          return;

        case 35:
          this.readToken_numberSign();
          return;

        case 92:
          this.readWord();
          return;

        default:
          if (isIdentifierStart(code)) {
            this.readWord();
            return;
          }

      }

      throw this.raise(this.state.pos, ErrorMessages.InvalidOrUnexpectedToken, String.fromCodePoint(code));
    }

    finishOp(type, size) {
      const str = this.input.slice(this.state.pos, this.state.pos + size);
      this.state.pos += size;
      this.finishToken(type, str);
    }

    readRegexp() {
      const start = this.state.pos;
      let escaped, inClass;

      for (;;) {
        if (this.state.pos >= this.length) {
          throw this.raise(start, ErrorMessages.UnterminatedRegExp);
        }

        const ch = this.input.charAt(this.state.pos);

        if (lineBreak.test(ch)) {
          throw this.raise(start, ErrorMessages.UnterminatedRegExp);
        }

        if (escaped) {
          escaped = false;
        } else {
          if (ch === "[") {
            inClass = true;
          } else if (ch === "]" && inClass) {
            inClass = false;
          } else if (ch === "/" && !inClass) {
            break;
          }

          escaped = ch === "\\";
        }

        ++this.state.pos;
      }

      const content = this.input.slice(start, this.state.pos);
      ++this.state.pos;
      let mods = "";

      while (this.state.pos < this.length) {
        const char = this.input[this.state.pos];
        const charCode = this.input.codePointAt(this.state.pos);

        if (VALID_REGEX_FLAGS.has(char)) {
          if (mods.indexOf(char) > -1) {
            this.raise(this.state.pos + 1, ErrorMessages.DuplicateRegExpFlags);
          }
        } else if (isIdentifierChar(charCode) || charCode === 92) {
          this.raise(this.state.pos + 1, ErrorMessages.MalformedRegExpFlags);
        } else {
          break;
        }

        ++this.state.pos;
        mods += char;
      }

      this.finishToken(types.regexp, {
        pattern: content,
        flags: mods
      });
    }

    readInt(radix, len, forceLen, allowNumSeparator = true) {
      const start = this.state.pos;
      const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct;
      const allowedSiblings = radix === 16 ? allowedNumericSeparatorSiblings.hex : radix === 10 ? allowedNumericSeparatorSiblings.dec : radix === 8 ? allowedNumericSeparatorSiblings.oct : allowedNumericSeparatorSiblings.bin;
      let invalid = false;
      let total = 0;

      for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) {
        const code = this.input.charCodeAt(this.state.pos);
        let val;

        if (code === 95) {
          const prev = this.input.charCodeAt(this.state.pos - 1);
          const next = this.input.charCodeAt(this.state.pos + 1);

          if (allowedSiblings.indexOf(next) === -1) {
            this.raise(this.state.pos, ErrorMessages.UnexpectedNumericSeparator);
          } else if (forbiddenSiblings.indexOf(prev) > -1 || forbiddenSiblings.indexOf(next) > -1 || Number.isNaN(next)) {
            this.raise(this.state.pos, ErrorMessages.UnexpectedNumericSeparator);
          }

          if (!allowNumSeparator) {
            this.raise(this.state.pos, ErrorMessages.NumericSeparatorInEscapeSequence);
          }

          ++this.state.pos;
          continue;
        }

        if (code >= 97) {
          val = code - 97 + 10;
        } else if (code >= 65) {
          val = code - 65 + 10;
        } else if (_isDigit(code)) {
          val = code - 48;
        } else {
          val = Infinity;
        }

        if (val >= radix) {
          if (this.options.errorRecovery && val <= 9) {
            val = 0;
            this.raise(this.state.start + i + 2, ErrorMessages.InvalidDigit, radix);
          } else if (forceLen) {
            val = 0;
            invalid = true;
          } else {
            break;
          }
        }

        ++this.state.pos;
        total = total * radix + val;
      }

      if (this.state.pos === start || len != null && this.state.pos - start !== len || invalid) {
        return null;
      }

      return total;
    }

    readRadixNumber(radix) {
      const start = this.state.pos;
      let isBigInt = false;
      this.state.pos += 2;
      const val = this.readInt(radix);

      if (val == null) {
        this.raise(this.state.start + 2, ErrorMessages.InvalidDigit, radix);
      }

      const next = this.input.charCodeAt(this.state.pos);

      if (next === 110) {
        ++this.state.pos;
        isBigInt = true;
      } else if (next === 109) {
        throw this.raise(start, ErrorMessages.InvalidDecimal);
      }

      if (isIdentifierStart(this.input.codePointAt(this.state.pos))) {
        throw this.raise(this.state.pos, ErrorMessages.NumberIdentifier);
      }

      if (isBigInt) {
        const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, "");
        this.finishToken(types.bigint, str);
        return;
      }

      this.finishToken(types.num, val);
    }

    readNumber(startsWithDot) {
      const start = this.state.pos;
      let isFloat = false;
      let isBigInt = false;
      let isDecimal = false;
      let hasExponent = false;
      let isOctal = false;

      if (!startsWithDot && this.readInt(10) === null) {
        this.raise(start, ErrorMessages.InvalidNumber);
      }

      const hasLeadingZero = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48;

      if (hasLeadingZero) {
        const integer = this.input.slice(start, this.state.pos);

        if (this.state.strict) {
          this.raise(start, ErrorMessages.StrictOctalLiteral);
        } else {
          const underscorePos = integer.indexOf("_");

          if (underscorePos > 0) {
            this.raise(underscorePos + start, ErrorMessages.ZeroDigitNumericSeparator);
          }
        }

        isOctal = hasLeadingZero && !/[89]/.test(integer);
      }

      let next = this.input.charCodeAt(this.state.pos);

      if (next === 46 && !isOctal) {
        ++this.state.pos;
        this.readInt(10);
        isFloat = true;
        next = this.input.charCodeAt(this.state.pos);
      }

      if ((next === 69 || next === 101) && !isOctal) {
        next = this.input.charCodeAt(++this.state.pos);

        if (next === 43 || next === 45) {
          ++this.state.pos;
        }

        if (this.readInt(10) === null) this.raise(start, ErrorMessages.InvalidNumber);
        isFloat = true;
        hasExponent = true;
        next = this.input.charCodeAt(this.state.pos);
      }

      if (next === 110) {
        if (isFloat || hasLeadingZero) {
          this.raise(start, ErrorMessages.InvalidBigIntLiteral);
        }

        ++this.state.pos;
        isBigInt = true;
      }

      if (next === 109) {
        this.expectPlugin("decimal", this.state.pos);

        if (hasExponent || hasLeadingZero) {
          this.raise(start, ErrorMessages.InvalidDecimal);
        }

        ++this.state.pos;
        isDecimal = true;
      }

      if (isIdentifierStart(this.input.codePointAt(this.state.pos))) {
        throw this.raise(this.state.pos, ErrorMessages.NumberIdentifier);
      }

      const str = this.input.slice(start, this.state.pos).replace(/[_mn]/g, "");

      if (isBigInt) {
        this.finishToken(types.bigint, str);
        return;
      }

      if (isDecimal) {
        this.finishToken(types.decimal, str);
        return;
      }

      const val = isOctal ? parseInt(str, 8) : parseFloat(str);
      this.finishToken(types.num, val);
    }

    readCodePoint(throwOnInvalid) {
      const ch = this.input.charCodeAt(this.state.pos);
      let code;

      if (ch === 123) {
        const codePos = ++this.state.pos;
        code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, true, throwOnInvalid);
        ++this.state.pos;

        if (code !== null && code > 0x10ffff) {
          if (throwOnInvalid) {
            this.raise(codePos, ErrorMessages.InvalidCodePoint);
          } else {
            return null;
          }
        }
      } else {
        code = this.readHexChar(4, false, throwOnInvalid);
      }

      return code;
    }

    readString(quote) {
      let out = "",
          chunkStart = ++this.state.pos;

      for (;;) {
        if (this.state.pos >= this.length) {
          throw this.raise(this.state.start, ErrorMessages.UnterminatedString);
        }

        const ch = this.input.charCodeAt(this.state.pos);
        if (ch === quote) break;

        if (ch === 92) {
          out += this.input.slice(chunkStart, this.state.pos);
          out += this.readEscapedChar(false);
          chunkStart = this.state.pos;
        } else if (ch === 8232 || ch === 8233) {
          ++this.state.pos;
          ++this.state.curLine;
          this.state.lineStart = this.state.pos;
        } else if (isNewLine(ch)) {
          throw this.raise(this.state.start, ErrorMessages.UnterminatedString);
        } else {
          ++this.state.pos;
        }
      }

      out += this.input.slice(chunkStart, this.state.pos++);
      this.finishToken(types.string, out);
    }

    readTmplToken() {
      let out = "",
          chunkStart = this.state.pos,
          containsInvalid = false;

      for (;;) {
        if (this.state.pos >= this.length) {
          throw this.raise(this.state.start, ErrorMessages.UnterminatedTemplate);
        }

        const ch = this.input.charCodeAt(this.state.pos);

        if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) {
          if (this.state.pos === this.state.start && this.match(types.template)) {
            if (ch === 36) {
              this.state.pos += 2;
              this.finishToken(types.dollarBraceL);
              return;
            } else {
              ++this.state.pos;
              this.finishToken(types.backQuote);
              return;
            }
          }

          out += this.input.slice(chunkStart, this.state.pos);
          this.finishToken(types.template, containsInvalid ? null : out);
          return;
        }

        if (ch === 92) {
          out += this.input.slice(chunkStart, this.state.pos);
          const escaped = this.readEscapedChar(true);

          if (escaped === null) {
            containsInvalid = true;
          } else {
            out += escaped;
          }

          chunkStart = this.state.pos;
        } else if (isNewLine(ch)) {
          out += this.input.slice(chunkStart, this.state.pos);
          ++this.state.pos;

          switch (ch) {
            case 13:
              if (this.input.charCodeAt(this.state.pos) === 10) {
                ++this.state.pos;
              }

            case 10:
              out += "\n";
              break;

            default:
              out += String.fromCharCode(ch);
              break;
          }

          ++this.state.curLine;
          this.state.lineStart = this.state.pos;
          chunkStart = this.state.pos;
        } else {
          ++this.state.pos;
        }
      }
    }

    readEscapedChar(inTemplate) {
      const throwOnInvalid = !inTemplate;
      const ch = this.input.charCodeAt(++this.state.pos);
      ++this.state.pos;

      switch (ch) {
        case 110:
          return "\n";

        case 114:
          return "\r";

        case 120:
          {
            const code = this.readHexChar(2, false, throwOnInvalid);
            return code === null ? null : String.fromCharCode(code);
          }

        case 117:
          {
            const code = this.readCodePoint(throwOnInvalid);
            return code === null ? null : String.fromCodePoint(code);
          }

        case 116:
          return "\t";

        case 98:
          return "\b";

        case 118:
          return "\u000b";

        case 102:
          return "\f";

        case 13:
          if (this.input.charCodeAt(this.state.pos) === 10) {
            ++this.state.pos;
          }

        case 10:
          this.state.lineStart = this.state.pos;
          ++this.state.curLine;

        case 8232:
        case 8233:
          return "";

        case 56:
        case 57:
          if (inTemplate) {
            return null;
          } else if (this.state.strict) {
            this.raise(this.state.pos - 1, ErrorMessages.StrictNumericEscape);
          }

        default:
          if (ch >= 48 && ch <= 55) {
            const codePos = this.state.pos - 1;
            const match = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/);
            let octalStr = match[0];
            let octal = parseInt(octalStr, 8);

            if (octal > 255) {
              octalStr = octalStr.slice(0, -1);
              octal = parseInt(octalStr, 8);
            }

            this.state.pos += octalStr.length - 1;
            const next = this.input.charCodeAt(this.state.pos);

            if (octalStr !== "0" || next === 56 || next === 57) {
              if (inTemplate) {
                return null;
              } else if (this.state.strict) {
                this.raise(codePos, ErrorMessages.StrictNumericEscape);
              } else {
                this.state.octalPositions.push(codePos);
              }
            }

            return String.fromCharCode(octal);
          }

          return String.fromCharCode(ch);
      }
    }

    readHexChar(len, forceLen, throwOnInvalid) {
      const codePos = this.state.pos;
      const n = this.readInt(16, len, forceLen, false);

      if (n === null) {
        if (throwOnInvalid) {
          this.raise(codePos, ErrorMessages.InvalidEscapeSequence);
        } else {
          this.state.pos = codePos - 1;
        }
      }

      return n;
    }

    readWord1() {
      let word = "";
      this.state.containsEsc = false;
      const start = this.state.pos;
      let chunkStart = this.state.pos;

      while (this.state.pos < this.length) {
        const ch = this.input.codePointAt(this.state.pos);

        if (isIdentifierChar(ch)) {
          this.state.pos += ch <= 0xffff ? 1 : 2;
        } else if (this.state.isIterator && ch === 64) {
          ++this.state.pos;
        } else if (ch === 92) {
          this.state.containsEsc = true;
          word += this.input.slice(chunkStart, this.state.pos);
          const escStart = this.state.pos;
          const identifierCheck = this.state.pos === start ? isIdentifierStart : isIdentifierChar;

          if (this.input.charCodeAt(++this.state.pos) !== 117) {
            this.raise(this.state.pos, ErrorMessages.MissingUnicodeEscape);
            continue;
          }

          ++this.state.pos;
          const esc = this.readCodePoint(true);

          if (esc !== null) {
            if (!identifierCheck(esc)) {
              this.raise(escStart, ErrorMessages.EscapedCharNotAnIdentifier);
            }

            word += String.fromCodePoint(esc);
          }

          chunkStart = this.state.pos;
        } else {
          break;
        }
      }

      return word + this.input.slice(chunkStart, this.state.pos);
    }

    isIterator(word) {
      return word === "@@iterator" || word === "@@asyncIterator";
    }

    readWord() {
      const word = this.readWord1();
      const type = keywords.get(word) || types.name;

      if (this.state.isIterator && (!this.isIterator(word) || !this.state.inType)) {
        this.raise(this.state.pos, ErrorMessages.InvalidIdentifier, word);
      }

      this.finishToken(type, word);
    }

    checkKeywordEscapes() {
      const kw = this.state.type.keyword;

      if (kw && this.state.containsEsc) {
        this.raise(this.state.start, ErrorMessages.InvalidEscapedReservedWord, kw);
      }
    }

    braceIsBlock(prevType) {
      const parent = this.curContext();

      if (parent === types$1.functionExpression || parent === types$1.functionStatement) {
        return true;
      }

      if (prevType === types.colon && (parent === types$1.braceStatement || parent === types$1.braceExpression)) {
        return !parent.isExpr;
      }

      if (prevType === types._return || prevType === types.name && this.state.exprAllowed) {
        return this.hasPrecedingLineBreak();
      }

      if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) {
        return true;
      }

      if (prevType === types.braceL) {
        return parent === types$1.braceStatement;
      }

      if (prevType === types._var || prevType === types._const || prevType === types.name) {
        return false;
      }

      if (prevType === types.relational) {
        return true;
      }

      return !this.state.exprAllowed;
    }

    updateContext(prevType) {
      const type = this.state.type;
      let update;

      if (type.keyword && (prevType === types.dot || prevType === types.questionDot)) {
        this.state.exprAllowed = false;
      } else if (update = type.updateContext) {
        update.call(this, prevType);
      } else {
        this.state.exprAllowed = type.beforeExpr;
      }
    }

  }

  class UtilParser extends Tokenizer {
    addExtra(node, key, val) {
      if (!node) return;
      const extra = node.extra = node.extra || {};
      extra[key] = val;
    }

    isRelational(op) {
      return this.match(types.relational) && this.state.value === op;
    }

    expectRelational(op) {
      if (this.isRelational(op)) {
        this.next();
      } else {
        this.unexpected(null, types.relational);
      }
    }

    isContextual(name) {
      return this.match(types.name) && this.state.value === name && !this.state.containsEsc;
    }

    isUnparsedContextual(nameStart, name) {
      const nameEnd = nameStart + name.length;
      return this.input.slice(nameStart, nameEnd) === name && (nameEnd === this.input.length || !isIdentifierChar(this.input.charCodeAt(nameEnd)));
    }

    isLookaheadContextual(name) {
      const next = this.nextTokenStart();
      return this.isUnparsedContextual(next, name);
    }

    eatContextual(name) {
      return this.isContextual(name) && this.eat(types.name);
    }

    expectContextual(name, message) {
      if (!this.eatContextual(name)) this.unexpected(null, message);
    }

    canInsertSemicolon() {
      return this.match(types.eof) || this.match(types.braceR) || this.hasPrecedingLineBreak();
    }

    hasPrecedingLineBreak() {
      return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
    }

    isLineTerminator() {
      return this.eat(types.semi) || this.canInsertSemicolon();
    }

    semicolon() {
      if (!this.isLineTerminator()) this.unexpected(null, types.semi);
    }

    expect(type, pos) {
      this.eat(type) || this.unexpected(pos, type);
    }

    assertNoSpace(message = "Unexpected space.") {
      if (this.state.start > this.state.lastTokEnd) {
        this.raise(this.state.lastTokEnd, message);
      }
    }

    unexpected(pos, messageOrType = "Unexpected token") {
      if (typeof messageOrType !== "string") {
        messageOrType = `Unexpected token, expected "${messageOrType.label}"`;
      }

      throw this.raise(pos != null ? pos : this.state.start, messageOrType);
    }

    expectPlugin(name, pos) {
      if (!this.hasPlugin(name)) {
        throw this.raiseWithData(pos != null ? pos : this.state.start, {
          missingPlugin: [name]
        }, `This experimental syntax requires enabling the parser plugin: '${name}'`);
      }

      return true;
    }

    expectOnePlugin(names, pos) {
      if (!names.some(n => this.hasPlugin(n))) {
        throw this.raiseWithData(pos != null ? pos : this.state.start, {
          missingPlugin: names
        }, `This experimental syntax requires enabling one of the following parser plugin(s): '${names.join(", ")}'`);
      }
    }

    checkYieldAwaitInDefaultParams() {
      if (this.state.yieldPos !== -1 && (this.state.awaitPos === -1 || this.state.yieldPos < this.state.awaitPos)) {
        this.raise(this.state.yieldPos, ErrorMessages.YieldBindingIdentifier);
      }

      if (this.state.awaitPos !== -1) {
        this.raise(this.state.awaitPos, ErrorMessages.AwaitBindingIdentifier);
      }
    }

    tryParse(fn, oldState = this.state.clone()) {
      const abortSignal = {
        node: null
      };

      try {
        const node = fn((node = null) => {
          abortSignal.node = node;
          throw abortSignal;
        });

        if (this.state.errors.length > oldState.errors.length) {
          const failState = this.state;
          this.state = oldState;
          return {
            node,
            error: failState.errors[oldState.errors.length],
            thrown: false,
            aborted: false,
            failState
          };
        }

        return {
          node,
          error: null,
          thrown: false,
          aborted: false,
          failState: null
        };
      } catch (error) {
        const failState = this.state;
        this.state = oldState;

        if (error instanceof SyntaxError) {
          return {
            node: null,
            error,
            thrown: true,
            aborted: false,
            failState
          };
        }

        if (error === abortSignal) {
          return {
            node: abortSignal.node,
            error: null,
            thrown: false,
            aborted: true,
            failState
          };
        }

        throw error;
      }
    }

    checkExpressionErrors(refExpressionErrors, andThrow) {
      if (!refExpressionErrors) return false;
      const {
        shorthandAssign,
        doubleProto
      } = refExpressionErrors;
      if (!andThrow) return shorthandAssign >= 0 || doubleProto >= 0;

      if (shorthandAssign >= 0) {
        this.unexpected(shorthandAssign);
      }

      if (doubleProto >= 0) {
        this.raise(doubleProto, ErrorMessages.DuplicateProto);
      }
    }

    isLiteralPropertyName() {
      return this.match(types.name) || !!this.state.type.keyword || this.match(types.string) || this.match(types.num) || this.match(types.bigint) || this.match(types.decimal);
    }

  }
  class ExpressionErrors {
    constructor() {
      this.shorthandAssign = -1;
      this.doubleProto = -1;
    }

  }

  class Node {
    constructor(parser, pos, loc) {
      this.type = "";
      this.start = pos;
      this.end = 0;
      this.loc = new SourceLocation(loc);
      if (parser == null ? void 0 : parser.options.ranges) this.range = [pos, 0];
      if (parser == null ? void 0 : parser.filename) this.loc.filename = parser.filename;
    }

    __clone() {
      const newNode = new Node();
      const keys = Object.keys(this);

      for (let i = 0, length = keys.length; i < length; i++) {
        const key = keys[i];

        if (key !== "leadingComments" && key !== "trailingComments" && key !== "innerComments") {
          newNode[key] = this[key];
        }
      }

      return newNode;
    }

  }

  class NodeUtils extends UtilParser {
    startNode() {
      return new Node(this, this.state.start, this.state.startLoc);
    }

    startNodeAt(pos, loc) {
      return new Node(this, pos, loc);
    }

    startNodeAtNode(type) {
      return this.startNodeAt(type.start, type.loc.start);
    }

    finishNode(node, type) {
      return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc);
    }

    finishNodeAt(node, type, pos, loc) {

      node.type = type;
      node.end = pos;
      node.loc.end = loc;
      if (this.options.ranges) node.range[1] = pos;
      this.processComment(node);
      return node;
    }

    resetStartLocation(node, start, startLoc) {
      node.start = start;
      node.loc.start = startLoc;
      if (this.options.ranges) node.range[0] = start;
    }

    resetEndLocation(node, end = this.state.lastTokEnd, endLoc = this.state.lastTokEndLoc) {
      node.end = end;
      node.loc.end = endLoc;
      if (this.options.ranges) node.range[1] = end;
    }

    resetStartLocationFromNode(node, locationNode) {
      this.resetStartLocation(node, locationNode.start, locationNode.loc.start);
    }

  }

  const unwrapParenthesizedExpression = node => {
    return node.type === "ParenthesizedExpression" ? unwrapParenthesizedExpression(node.expression) : node;
  };

  class LValParser extends NodeUtils {
    toAssignable(node) {
      var _node$extra, _node$extra3;

      let parenthesized = undefined;

      if (node.type === "ParenthesizedExpression" || ((_node$extra = node.extra) == null ? void 0 : _node$extra.parenthesized)) {
        parenthesized = unwrapParenthesizedExpression(node);

        if (parenthesized.type !== "Identifier" && parenthesized.type !== "MemberExpression") {
          this.raise(node.start, ErrorMessages.InvalidParenthesizedAssignment);
        }
      }

      switch (node.type) {
        case "Identifier":
        case "ObjectPattern":
        case "ArrayPattern":
        case "AssignmentPattern":
          break;

        case "ObjectExpression":
          node.type = "ObjectPattern";

          for (let i = 0, length = node.properties.length, last = length - 1; i < length; i++) {
            var _node$extra2;

            const prop = node.properties[i];
            const isLast = i === last;
            this.toAssignableObjectExpressionProp(prop, isLast);

            if (isLast && prop.type === "RestElement" && ((_node$extra2 = node.extra) == null ? void 0 : _node$extra2.trailingComma)) {
              this.raiseRestNotLast(node.extra.trailingComma);
            }
          }

          break;

        case "ObjectProperty":
          this.toAssignable(node.value);
          break;

        case "SpreadElement":
          {
            this.checkToRestConversion(node);
            node.type = "RestElement";
            const arg = node.argument;
            this.toAssignable(arg);
            break;
          }

        case "ArrayExpression":
          node.type = "ArrayPattern";
          this.toAssignableList(node.elements, (_node$extra3 = node.extra) == null ? void 0 : _node$extra3.trailingComma);
          break;

        case "AssignmentExpression":
          if (node.operator !== "=") {
            this.raise(node.left.end, ErrorMessages.MissingEqInAssignment);
          }

          node.type = "AssignmentPattern";
          delete node.operator;
          this.toAssignable(node.left);
          break;

        case "ParenthesizedExpression":
          this.toAssignable(parenthesized);
          break;
      }

      return node;
    }

    toAssignableObjectExpressionProp(prop, isLast) {
      if (prop.type === "ObjectMethod") {
        const error = prop.kind === "get" || prop.kind === "set" ? ErrorMessages.PatternHasAccessor : ErrorMessages.PatternHasMethod;
        this.raise(prop.key.start, error);
      } else if (prop.type === "SpreadElement" && !isLast) {
        this.raiseRestNotLast(prop.start);
      } else {
        this.toAssignable(prop);
      }
    }

    toAssignableList(exprList, trailingCommaPos) {
      let end = exprList.length;

      if (end) {
        const last = exprList[end - 1];

        if ((last == null ? void 0 : last.type) === "RestElement") {
          --end;
        } else if ((last == null ? void 0 : last.type) === "SpreadElement") {
          last.type = "RestElement";
          const arg = last.argument;
          this.toAssignable(arg);

          if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern" && arg.type !== "ObjectPattern") {
            this.unexpected(arg.start);
          }

          if (trailingCommaPos) {
            this.raiseTrailingCommaAfterRest(trailingCommaPos);
          }

          --end;
        }
      }

      for (let i = 0; i < end; i++) {
        const elt = exprList[i];

        if (elt) {
          this.toAssignable(elt);

          if (elt.type === "RestElement") {
            this.raiseRestNotLast(elt.start);
          }
        }
      }

      return exprList;
    }

    toReferencedList(exprList, isParenthesizedExpr) {
      return exprList;
    }

    toReferencedListDeep(exprList, isParenthesizedExpr) {
      this.toReferencedList(exprList, isParenthesizedExpr);

      for (let _i = 0; _i < exprList.length; _i++) {
        const expr = exprList[_i];

        if ((expr == null ? void 0 : expr.type) === "ArrayExpression") {
          this.toReferencedListDeep(expr.elements);
        }
      }
    }

    parseSpread(refExpressionErrors, refNeedsArrowPos) {
      const node = this.startNode();
      this.next();
      node.argument = this.parseMaybeAssignAllowIn(refExpressionErrors, undefined, refNeedsArrowPos);
      return this.finishNode(node, "SpreadElement");
    }

    parseRestBinding() {
      const node = this.startNode();
      this.next();
      node.argument = this.parseBindingAtom();
      return this.finishNode(node, "RestElement");
    }

    parseBindingAtom() {
      switch (this.state.type) {
        case types.bracketL:
          {
            const node = this.startNode();
            this.next();
            node.elements = this.parseBindingList(types.bracketR, 93, true);
            return this.finishNode(node, "ArrayPattern");
          }

        case types.braceL:
          return this.parseObjectLike(types.braceR, true);
      }

      return this.parseIdentifier();
    }

    parseBindingList(close, closeCharCode, allowEmpty, allowModifiers) {
      const elts = [];
      let first = true;

      while (!this.eat(close)) {
        if (first) {
          first = false;
        } else {
          this.expect(types.comma);
        }

        if (allowEmpty && this.match(types.comma)) {
          elts.push(null);
        } else if (this.eat(close)) {
          break;
        } else if (this.match(types.ellipsis)) {
          elts.push(this.parseAssignableListItemTypes(this.parseRestBinding()));
          this.checkCommaAfterRest(closeCharCode);
          this.expect(close);
          break;
        } else {
          const decorators = [];

          if (this.match(types.at) && this.hasPlugin("decorators")) {
            this.raise(this.state.start, ErrorMessages.UnsupportedParameterDecorator);
          }

          while (this.match(types.at)) {
            decorators.push(this.parseDecorator());
          }

          elts.push(this.parseAssignableListItem(allowModifiers, decorators));
        }
      }

      return elts;
    }

    parseAssignableListItem(allowModifiers, decorators) {
      const left = this.parseMaybeDefault();
      this.parseAssignableListItemTypes(left);
      const elt = this.parseMaybeDefault(left.start, left.loc.start, left);

      if (decorators.length) {
        left.decorators = decorators;
      }

      return elt;
    }

    parseAssignableListItemTypes(param) {
      return param;
    }

    parseMaybeDefault(startPos, startLoc, left) {
      var _startLoc, _startPos, _left;

      startLoc = (_startLoc = startLoc) != null ? _startLoc : this.state.startLoc;
      startPos = (_startPos = startPos) != null ? _startPos : this.state.start;
      left = (_left = left) != null ? _left : this.parseBindingAtom();
      if (!this.eat(types.eq)) return left;
      const node = this.startNodeAt(startPos, startLoc);
      node.left = left;
      node.right = this.parseMaybeAssignAllowIn();
      return this.finishNode(node, "AssignmentPattern");
    }

    checkLVal(expr, bindingType = BIND_NONE, checkClashes, contextDescription, disallowLetBinding, strictModeChanged = false) {
      switch (expr.type) {
        case "Identifier":
          if (this.state.strict && (strictModeChanged ? isStrictBindReservedWord(expr.name, this.inModule) : isStrictBindOnlyReservedWord(expr.name))) {
            this.raise(expr.start, bindingType === BIND_NONE ? ErrorMessages.StrictEvalArguments : ErrorMessages.StrictEvalArgumentsBinding, expr.name);
          }

          if (checkClashes) {
            const key = `_${expr.name}`;

            if (checkClashes[key]) {
              this.raise(expr.start, ErrorMessages.ParamDupe);
            } else {
              checkClashes[key] = true;
            }
          }

          if (disallowLetBinding && expr.name === "let") {
            this.raise(expr.start, ErrorMessages.LetInLexicalBinding);
          }

          if (!(bindingType & BIND_NONE)) {
            this.scope.declareName(expr.name, bindingType, expr.start);
          }

          break;

        case "MemberExpression":
          if (bindingType !== BIND_NONE) {
            this.raise(expr.start, ErrorMessages.InvalidPropertyBindingPattern);
          }

          break;

        case "ObjectPattern":
          for (let _i2 = 0, _expr$properties = expr.properties; _i2 < _expr$properties.length; _i2++) {
            let prop = _expr$properties[_i2];
            if (prop.type === "ObjectProperty") prop = prop.value;else if (prop.type === "ObjectMethod") continue;
            this.checkLVal(prop, bindingType, checkClashes, "object destructuring pattern", disallowLetBinding);
          }

          break;

        case "ArrayPattern":
          for (let _i3 = 0, _expr$elements = expr.elements; _i3 < _expr$elements.length; _i3++) {
            const elem = _expr$elements[_i3];

            if (elem) {
              this.checkLVal(elem, bindingType, checkClashes, "array destructuring pattern", disallowLetBinding);
            }
          }

          break;

        case "AssignmentPattern":
          this.checkLVal(expr.left, bindingType, checkClashes, "assignment pattern");
          break;

        case "RestElement":
          this.checkLVal(expr.argument, bindingType, checkClashes, "rest element");
          break;

        case "ParenthesizedExpression":
          this.checkLVal(expr.expression, bindingType, checkClashes, "parenthesized expression");
          break;

        default:
          {
            this.raise(expr.start, bindingType === BIND_NONE ? ErrorMessages.InvalidLhs : ErrorMessages.InvalidLhsBinding, contextDescription);
          }
      }
    }

    checkToRestConversion(node) {
      if (node.argument.type !== "Identifier" && node.argument.type !== "MemberExpression") {
        this.raise(node.argument.start, ErrorMessages.InvalidRestAssignmentPattern);
      }
    }

    checkCommaAfterRest(close) {
      if (this.match(types.comma)) {
        if (this.lookaheadCharCode() === close) {
          this.raiseTrailingCommaAfterRest(this.state.start);
        } else {
          this.raiseRestNotLast(this.state.start);
        }
      }
    }

    raiseRestNotLast(pos) {
      throw this.raise(pos, ErrorMessages.ElementAfterRest);
    }

    raiseTrailingCommaAfterRest(pos) {
      this.raise(pos, ErrorMessages.RestTrailingComma);
    }

  }

  class ExpressionParser extends LValParser {
    checkProto(prop, isRecord, protoRef, refExpressionErrors) {
      if (prop.type === "SpreadElement" || prop.type === "ObjectMethod" || prop.computed || prop.shorthand) {
        return;
      }

      const key = prop.key;
      const name = key.type === "Identifier" ? key.name : key.value;

      if (name === "__proto__") {
        if (isRecord) {
          this.raise(key.start, ErrorMessages.RecordNoProto);
          return;
        }

        if (protoRef.used) {
          if (refExpressionErrors) {
            if (refExpressionErrors.doubleProto === -1) {
              refExpressionErrors.doubleProto = key.start;
            }
          } else {
            this.raise(key.start, ErrorMessages.DuplicateProto);
          }
        }

        protoRef.used = true;
      }
    }

    shouldExitDescending(expr, potentialArrowAt) {
      return expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt;
    }

    getExpression() {
      let paramFlags = PARAM;

      if (this.hasPlugin("topLevelAwait") && this.inModule) {
        paramFlags |= PARAM_AWAIT;
      }

      this.scope.enter(SCOPE_PROGRAM);
      this.prodParam.enter(paramFlags);
      this.nextToken();
      const expr = this.parseExpression();

      if (!this.match(types.eof)) {
        this.unexpected();
      }

      expr.comments = this.state.comments;
      expr.errors = this.state.errors;
      return expr;
    }

    parseExpression(disallowIn, refExpressionErrors) {
      if (disallowIn) {
        return this.disallowInAnd(() => this.parseExpressionBase(refExpressionErrors));
      }

      return this.allowInAnd(() => this.parseExpressionBase(refExpressionErrors));
    }

    parseExpressionBase(refExpressionErrors) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const expr = this.parseMaybeAssign(refExpressionErrors);

      if (this.match(types.comma)) {
        const node = this.startNodeAt(startPos, startLoc);
        node.expressions = [expr];

        while (this.eat(types.comma)) {
          node.expressions.push(this.parseMaybeAssign(refExpressionErrors));
        }

        this.toReferencedList(node.expressions);
        return this.finishNode(node, "SequenceExpression");
      }

      return expr;
    }

    parseMaybeAssignDisallowIn(refExpressionErrors, afterLeftParse, refNeedsArrowPos) {
      return this.disallowInAnd(() => this.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos));
    }

    parseMaybeAssignAllowIn(refExpressionErrors, afterLeftParse, refNeedsArrowPos) {
      return this.allowInAnd(() => this.parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos));
    }

    parseMaybeAssign(refExpressionErrors, afterLeftParse, refNeedsArrowPos) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;

      if (this.isContextual("yield")) {
        if (this.prodParam.hasYield) {
          let left = this.parseYield();

          if (afterLeftParse) {
            left = afterLeftParse.call(this, left, startPos, startLoc);
          }

          return left;
        } else {
          this.state.exprAllowed = false;
        }
      }

      let ownExpressionErrors;

      if (refExpressionErrors) {
        ownExpressionErrors = false;
      } else {
        refExpressionErrors = new ExpressionErrors();
        ownExpressionErrors = true;
      }

      if (this.match(types.parenL) || this.match(types.name)) {
        this.state.potentialArrowAt = this.state.start;
      }

      let left = this.parseMaybeConditional(refExpressionErrors, refNeedsArrowPos);

      if (afterLeftParse) {
        left = afterLeftParse.call(this, left, startPos, startLoc);
      }

      if (this.state.type.isAssign) {
        const node = this.startNodeAt(startPos, startLoc);
        const operator = this.state.value;
        node.operator = operator;

        if (this.match(types.eq)) {
          node.left = this.toAssignable(left);
          refExpressionErrors.doubleProto = -1;
        } else {
          node.left = left;
        }

        if (refExpressionErrors.shorthandAssign >= node.left.start) {
          refExpressionErrors.shorthandAssign = -1;
        }

        this.checkLVal(left, undefined, undefined, "assignment expression");
        this.next();
        node.right = this.parseMaybeAssign();
        return this.finishNode(node, "AssignmentExpression");
      } else if (ownExpressionErrors) {
        this.checkExpressionErrors(refExpressionErrors, true);
      }

      return left;
    }

    parseMaybeConditional(refExpressionErrors, refNeedsArrowPos) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const potentialArrowAt = this.state.potentialArrowAt;
      const expr = this.parseExprOps(refExpressionErrors);

      if (this.shouldExitDescending(expr, potentialArrowAt)) {
        return expr;
      }

      return this.parseConditional(expr, startPos, startLoc, refNeedsArrowPos);
    }

    parseConditional(expr, startPos, startLoc, refNeedsArrowPos) {
      if (this.eat(types.question)) {
        const node = this.startNodeAt(startPos, startLoc);
        node.test = expr;
        node.consequent = this.parseMaybeAssignAllowIn();
        this.expect(types.colon);
        node.alternate = this.parseMaybeAssign();
        return this.finishNode(node, "ConditionalExpression");
      }

      return expr;
    }

    parseExprOps(refExpressionErrors) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const potentialArrowAt = this.state.potentialArrowAt;
      const expr = this.parseMaybeUnary(refExpressionErrors);

      if (this.shouldExitDescending(expr, potentialArrowAt)) {
        return expr;
      }

      return this.parseExprOp(expr, startPos, startLoc, -1);
    }

    parseExprOp(left, leftStartPos, leftStartLoc, minPrec) {
      let prec = this.state.type.binop;

      if (prec != null && (this.prodParam.hasIn || !this.match(types._in))) {
        if (prec > minPrec) {
          const op = this.state.type;

          if (op === types.pipeline) {
            this.expectPlugin("pipelineOperator");

            if (this.state.inFSharpPipelineDirectBody) {
              return left;
            }

            this.state.inPipeline = true;
            this.checkPipelineAtInfixOperator(left, leftStartPos);
          }

          const node = this.startNodeAt(leftStartPos, leftStartLoc);
          node.left = left;
          node.operator = this.state.value;

          if (op === types.exponent && left.type === "UnaryExpression" && (this.options.createParenthesizedExpressions || !(left.extra && left.extra.parenthesized))) {
            this.raise(left.argument.start, ErrorMessages.UnexpectedTokenUnaryExponentiation);
          }

          const logical = op === types.logicalOR || op === types.logicalAND;
          const coalesce = op === types.nullishCoalescing;

          if (coalesce) {
            prec = types.logicalAND.binop;
          }

          this.next();

          if (op === types.pipeline && this.getPluginOption("pipelineOperator", "proposal") === "minimal") {
            if (this.match(types.name) && this.state.value === "await" && this.prodParam.hasAwait) {
              throw this.raise(this.state.start, ErrorMessages.UnexpectedAwaitAfterPipelineBody);
            }
          }

          node.right = this.parseExprOpRightExpr(op, prec);
          this.finishNode(node, logical || coalesce ? "LogicalExpression" : "BinaryExpression");
          const nextOp = this.state.type;

          if (coalesce && (nextOp === types.logicalOR || nextOp === types.logicalAND) || logical && nextOp === types.nullishCoalescing) {
            throw this.raise(this.state.start, ErrorMessages.MixingCoalesceWithLogical);
          }

          return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec);
        }
      }

      return left;
    }

    parseExprOpRightExpr(op, prec) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;

      switch (op) {
        case types.pipeline:
          switch (this.getPluginOption("pipelineOperator", "proposal")) {
            case "smart":
              return this.withTopicPermittingContext(() => {
                return this.parseSmartPipelineBody(this.parseExprOpBaseRightExpr(op, prec), startPos, startLoc);
              });

            case "fsharp":
              return this.withSoloAwaitPermittingContext(() => {
                return this.parseFSharpPipelineBody(prec);
              });
          }

        default:
          return this.parseExprOpBaseRightExpr(op, prec);
      }
    }

    parseExprOpBaseRightExpr(op, prec) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      return this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec);
    }

    parseMaybeUnary(refExpressionErrors) {
      if (this.isContextual("await") && this.isAwaitAllowed()) {
        return this.parseAwait();
      }

      const update = this.match(types.incDec);
      const node = this.startNode();

      if (this.state.type.prefix) {
        node.operator = this.state.value;
        node.prefix = true;

        if (this.match(types._throw)) {
          this.expectPlugin("throwExpressions");
        }

        const isDelete = this.match(types._delete);
        this.next();
        node.argument = this.parseMaybeUnary();
        this.checkExpressionErrors(refExpressionErrors, true);

        if (this.state.strict && isDelete) {
          const arg = node.argument;

          if (arg.type === "Identifier") {
            this.raise(node.start, ErrorMessages.StrictDelete);
          } else if ((arg.type === "MemberExpression" || arg.type === "OptionalMemberExpression") && arg.property.type === "PrivateName") {
            this.raise(node.start, ErrorMessages.DeletePrivateField);
          }
        }

        if (!update) {
          return this.finishNode(node, "UnaryExpression");
        }
      }

      return this.parseUpdate(node, update, refExpressionErrors);
    }

    parseUpdate(node, update, refExpressionErrors) {
      if (update) {
        this.checkLVal(node.argument, undefined, undefined, "prefix operation");
        return this.finishNode(node, "UpdateExpression");
      }

      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      let expr = this.parseExprSubscripts(refExpressionErrors);
      if (this.checkExpressionErrors(refExpressionErrors, false)) return expr;

      while (this.state.type.postfix && !this.canInsertSemicolon()) {
        const node = this.startNodeAt(startPos, startLoc);
        node.operator = this.state.value;
        node.prefix = false;
        node.argument = expr;
        this.checkLVal(expr, undefined, undefined, "postfix operation");
        this.next();
        expr = this.finishNode(node, "UpdateExpression");
      }

      return expr;
    }

    parseExprSubscripts(refExpressionErrors) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      const potentialArrowAt = this.state.potentialArrowAt;
      const expr = this.parseExprAtom(refExpressionErrors);

      if (this.shouldExitDescending(expr, potentialArrowAt)) {
        return expr;
      }

      return this.parseSubscripts(expr, startPos, startLoc);
    }

    parseSubscripts(base, startPos, startLoc, noCalls) {
      const state = {
        optionalChainMember: false,
        maybeAsyncArrow: this.atPossibleAsyncArrow(base),
        stop: false
      };

      do {
        const oldMaybeInAsyncArrowHead = this.state.maybeInAsyncArrowHead;

        if (state.maybeAsyncArrow) {
          this.state.maybeInAsyncArrowHead = true;
        }

        base = this.parseSubscript(base, startPos, startLoc, noCalls, state);
        state.maybeAsyncArrow = false;
        this.state.maybeInAsyncArrowHead = oldMaybeInAsyncArrowHead;
      } while (!state.stop);

      return base;
    }

    parseSubscript(base, startPos, startLoc, noCalls, state) {
      if (!noCalls && this.eat(types.doubleColon)) {
        return this.parseBind(base, startPos, startLoc, noCalls, state);
      } else if (this.match(types.backQuote)) {
        return this.parseTaggedTemplateExpression(base, startPos, startLoc, state);
      }

      let optional = false;

      if (this.match(types.questionDot)) {
        state.optionalChainMember = optional = true;

        if (noCalls && this.lookaheadCharCode() === 40) {
          state.stop = true;
          return base;
        }

        this.next();
      }

      if (!noCalls && this.match(types.parenL)) {
        return this.parseCoverCallAndAsyncArrowHead(base, startPos, startLoc, state, optional);
      } else if (optional || this.match(types.bracketL) || this.eat(types.dot)) {
        return this.parseMember(base, startPos, startLoc, state, optional);
      } else {
        state.stop = true;
        return base;
      }
    }

    parseMember(base, startPos, startLoc, state, optional) {
      const node = this.startNodeAt(startPos, startLoc);
      const computed = this.eat(types.bracketL);
      node.object = base;
      node.computed = computed;
      const property = computed ? this.parseExpression() : this.parseMaybePrivateName(true);

      if (property.type === "PrivateName") {
        if (node.object.type === "Super") {
          this.raise(startPos, ErrorMessages.SuperPrivateField);
        }

        this.classScope.usePrivateName(property.id.name, property.start);
      }

      node.property = property;

      if (computed) {
        this.expect(types.bracketR);
      }

      if (state.optionalChainMember) {
        node.optional = optional;
        return this.finishNode(node, "OptionalMemberExpression");
      } else {
        return this.finishNode(node, "MemberExpression");
      }
    }

    parseBind(base, startPos, startLoc, noCalls, state) {
      const node = this.startNodeAt(startPos, startLoc);
      node.object = base;
      node.callee = this.parseNoCallExpr();
      state.stop = true;
      return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls);
    }

    parseCoverCallAndAsyncArrowHead(base, startPos, startLoc, state, optional) {
      const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;
      this.state.maybeInArrowParameters = true;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      this.next();
      let node = this.startNodeAt(startPos, startLoc);
      node.callee = base;

      if (state.optionalChainMember) {
        node.optional = optional;
      }

      if (optional) {
        node.arguments = this.parseCallExpressionArguments(types.parenR, false);
      } else {
        node.arguments = this.parseCallExpressionArguments(types.parenR, state.maybeAsyncArrow, base.type === "Import", base.type !== "Super", node);
      }

      this.finishCallExpression(node, state.optionalChainMember);

      if (state.maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) {
        state.stop = true;
        node = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node);
        this.checkYieldAwaitInDefaultParams();
        this.state.yieldPos = oldYieldPos;
        this.state.awaitPos = oldAwaitPos;
      } else {
        this.toReferencedListDeep(node.arguments);
        if (oldYieldPos !== -1) this.state.yieldPos = oldYieldPos;

        if (!this.isAwaitAllowed() && !oldMaybeInArrowParameters || oldAwaitPos !== -1) {
          this.state.awaitPos = oldAwaitPos;
        }
      }

      this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
      return node;
    }

    parseTaggedTemplateExpression(base, startPos, startLoc, state) {
      const node = this.startNodeAt(startPos, startLoc);
      node.tag = base;
      node.quasi = this.parseTemplate(true);

      if (state.optionalChainMember) {
        this.raise(startPos, ErrorMessages.OptionalChainingNoTemplate);
      }

      return this.finishNode(node, "TaggedTemplateExpression");
    }

    atPossibleAsyncArrow(base) {
      return base.type === "Identifier" && base.name === "async" && this.state.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && base.start === this.state.potentialArrowAt;
    }

    finishCallExpression(node, optional) {
      if (node.callee.type === "Import") {
        if (node.arguments.length === 2) {
          this.expectPlugin("moduleAttributes");
        }

        if (node.arguments.length === 0 || node.arguments.length > 2) {
          this.raise(node.start, ErrorMessages.ImportCallArity, this.hasPlugin("moduleAttributes") ? "one or two arguments" : "one argument");
        } else {
          for (let _i = 0, _node$arguments = node.arguments; _i < _node$arguments.length; _i++) {
            const arg = _node$arguments[_i];

            if (arg.type === "SpreadElement") {
              this.raise(arg.start, ErrorMessages.ImportCallSpreadArgument);
            }
          }
        }
      }

      return this.finishNode(node, optional ? "OptionalCallExpression" : "CallExpression");
    }

    parseCallExpressionArguments(close, possibleAsyncArrow, dynamicImport, allowPlaceholder, nodeForExtra) {
      const elts = [];
      let innerParenStart;
      let first = true;
      const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
      this.state.inFSharpPipelineDirectBody = false;

      while (!this.eat(close)) {
        if (first) {
          first = false;
        } else {
          this.expect(types.comma);

          if (this.match(close)) {
            if (dynamicImport && !this.hasPlugin("moduleAttributes")) {
              this.raise(this.state.lastTokStart, ErrorMessages.ImportCallArgumentTrailingComma);
            }

            if (nodeForExtra) {
              this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart);
            }

            this.next();
            break;
          }
        }

        if (this.match(types.parenL) && !innerParenStart) {
          innerParenStart = this.state.start;
        }

        elts.push(this.parseExprListItem(false, possibleAsyncArrow ? new ExpressionErrors() : undefined, possibleAsyncArrow ? {
          start: 0
        } : undefined, allowPlaceholder));
      }

      if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) {
        this.unexpected();
      }

      this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
      return elts;
    }

    shouldParseAsyncArrow() {
      return this.match(types.arrow) && !this.canInsertSemicolon();
    }

    parseAsyncArrowFromCallExpression(node, call) {
      var _call$extra;

      this.expect(types.arrow);
      this.parseArrowExpression(node, call.arguments, true, (_call$extra = call.extra) == null ? void 0 : _call$extra.trailingComma);
      return node;
    }

    parseNoCallExpr() {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
    }

    parseExprAtom(refExpressionErrors) {
      if (this.state.type === types.slash) this.readRegexp();
      const canBeArrow = this.state.potentialArrowAt === this.state.start;
      let node;

      switch (this.state.type) {
        case types._super:
          return this.parseSuper();

        case types._import:
          node = this.startNode();
          this.next();

          if (this.match(types.dot)) {
            return this.parseImportMetaProperty(node);
          }

          if (!this.match(types.parenL)) {
            this.raise(this.state.lastTokStart, ErrorMessages.UnsupportedImport);
          }

          return this.finishNode(node, "Import");

        case types._this:
          node = this.startNode();
          this.next();
          return this.finishNode(node, "ThisExpression");

        case types.name:
          {
            const containsEsc = this.state.containsEsc;
            const id = this.parseIdentifier();

            if (!containsEsc && id.name === "async" && !this.canInsertSemicolon()) {
              if (this.match(types._function)) {
                const last = this.state.context.length - 1;

                if (this.state.context[last] !== types$1.functionStatement) {
                  throw new Error("Internal error");
                }

                this.state.context[last] = types$1.functionExpression;
                this.next();
                return this.parseFunction(this.startNodeAtNode(id), undefined, true);
              } else if (this.match(types.name)) {
                return this.parseAsyncArrowUnaryFunction(id);
              }
            }

            if (canBeArrow && this.match(types.arrow) && !this.canInsertSemicolon()) {
              this.next();
              return this.parseArrowExpression(this.startNodeAtNode(id), [id], false);
            }

            return id;
          }

        case types._do:
          {
            return this.parseDo();
          }

        case types.regexp:
          {
            const value = this.state.value;
            node = this.parseLiteral(value.value, "RegExpLiteral");
            node.pattern = value.pattern;
            node.flags = value.flags;
            return node;
          }

        case types.num:
          return this.parseLiteral(this.state.value, "NumericLiteral");

        case types.bigint:
          return this.parseLiteral(this.state.value, "BigIntLiteral");

        case types.decimal:
          return this.parseLiteral(this.state.value, "DecimalLiteral");

        case types.string:
          return this.parseLiteral(this.state.value, "StringLiteral");

        case types._null:
          node = this.startNode();
          this.next();
          return this.finishNode(node, "NullLiteral");

        case types._true:
        case types._false:
          return this.parseBooleanLiteral();

        case types.parenL:
          return this.parseParenAndDistinguishExpression(canBeArrow);

        case types.bracketBarL:
        case types.bracketHashL:
          {
            return this.parseArrayLike(this.state.type === types.bracketBarL ? types.bracketBarR : types.bracketR, false, true, refExpressionErrors);
          }

        case types.bracketL:
          {
            return this.parseArrayLike(types.bracketR, true, false, refExpressionErrors);
          }

        case types.braceBarL:
        case types.braceHashL:
          {
            return this.parseObjectLike(this.state.type === types.braceBarL ? types.braceBarR : types.braceR, false, true, refExpressionErrors);
          }

        case types.braceL:
          {
            return this.parseObjectLike(types.braceR, false, false, refExpressionErrors);
          }

        case types._function:
          return this.parseFunctionOrFunctionSent();

        case types.at:
          this.parseDecorators();

        case types._class:
          node = this.startNode();
          this.takeDecorators(node);
          return this.parseClass(node, false);

        case types._new:
          return this.parseNewOrNewTarget();

        case types.backQuote:
          return this.parseTemplate(false);

        case types.doubleColon:
          {
            node = this.startNode();
            this.next();
            node.object = null;
            const callee = node.callee = this.parseNoCallExpr();

            if (callee.type === "MemberExpression") {
              return this.finishNode(node, "BindExpression");
            } else {
              throw this.raise(callee.start, ErrorMessages.UnsupportedBind);
            }
          }

        case types.hash:
          {
            if (this.state.inPipeline) {
              node = this.startNode();

              if (this.getPluginOption("pipelineOperator", "proposal") !== "smart") {
                this.raise(node.start, ErrorMessages.PrimaryTopicRequiresSmartPipeline);
              }

              this.next();

              if (!this.primaryTopicReferenceIsAllowedInCurrentTopicContext()) {
                this.raise(node.start, ErrorMessages.PrimaryTopicNotAllowed);
              }

              this.registerTopicReference();
              return this.finishNode(node, "PipelinePrimaryTopicReference");
            }

            const nextCh = this.input.codePointAt(this.state.end);

            if (isIdentifierStart(nextCh) || nextCh === 92) {
              const start = this.state.start;
              node = this.parseMaybePrivateName(true);

              if (this.match(types._in)) {
                this.expectPlugin("privateIn");
                this.classScope.usePrivateName(node.id.name, node.start);
              } else if (this.hasPlugin("privateIn")) {
                this.raise(this.state.start, ErrorMessages.PrivateInExpectedIn, node.id.name);
              } else {
                throw this.unexpected(start);
              }

              return node;
            }
          }

        case types.relational:
          {
            if (this.state.value === "<") {
              const lookaheadCh = this.input.codePointAt(this.nextTokenStart());

              if (isIdentifierStart(lookaheadCh) || lookaheadCh === 62) {
                  this.expectOnePlugin(["jsx", "flow", "typescript"]);
                }
            }
          }

        default:
          throw this.unexpected();
      }
    }

    parseAsyncArrowUnaryFunction(id) {
      const node = this.startNodeAtNode(id);
      const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
      const oldMaybeInAsyncArrowHead = this.state.maybeInAsyncArrowHead;
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;
      this.state.maybeInArrowParameters = true;
      this.state.maybeInAsyncArrowHead = true;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      const params = [this.parseIdentifier()];

      if (this.hasPrecedingLineBreak()) {
        this.raise(this.state.pos, ErrorMessages.LineTerminatorBeforeArrow);
      }

      this.expect(types.arrow);
      this.checkYieldAwaitInDefaultParams();
      this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
      this.state.maybeInAsyncArrowHead = oldMaybeInAsyncArrowHead;
      this.state.yieldPos = oldYieldPos;
      this.state.awaitPos = oldAwaitPos;
      this.parseArrowExpression(node, params, true);
      return node;
    }

    parseDo() {
      this.expectPlugin("doExpressions");
      const node = this.startNode();
      this.next();
      const oldLabels = this.state.labels;
      this.state.labels = [];
      node.body = this.parseBlock();
      this.state.labels = oldLabels;
      return this.finishNode(node, "DoExpression");
    }

    parseSuper() {
      const node = this.startNode();
      this.next();

      if (this.match(types.parenL) && !this.scope.allowDirectSuper && !this.options.allowSuperOutsideMethod) {
        this.raise(node.start, ErrorMessages.SuperNotAllowed);
      } else if (!this.scope.allowSuper && !this.options.allowSuperOutsideMethod) {
        this.raise(node.start, ErrorMessages.UnexpectedSuper);
      }

      if (!this.match(types.parenL) && !this.match(types.bracketL) && !this.match(types.dot)) {
        this.raise(node.start, ErrorMessages.UnsupportedSuper);
      }

      return this.finishNode(node, "Super");
    }

    parseBooleanLiteral() {
      const node = this.startNode();
      node.value = this.match(types._true);
      this.next();
      return this.finishNode(node, "BooleanLiteral");
    }

    parseMaybePrivateName(isPrivateNameAllowed) {
      const isPrivate = this.match(types.hash);

      if (isPrivate) {
        this.expectOnePlugin(["classPrivateProperties", "classPrivateMethods"]);

        if (!isPrivateNameAllowed) {
          this.raise(this.state.pos, ErrorMessages.UnexpectedPrivateField);
        }

        const node = this.startNode();
        this.next();
        this.assertNoSpace("Unexpected space between # and identifier");
        node.id = this.parseIdentifier(true);
        return this.finishNode(node, "PrivateName");
      } else {
        return this.parseIdentifier(true);
      }
    }

    parseFunctionOrFunctionSent() {
      const node = this.startNode();
      this.next();

      if (this.prodParam.hasYield && this.match(types.dot)) {
        const meta = this.createIdentifier(this.startNodeAtNode(node), "function");
        this.next();
        return this.parseMetaProperty(node, meta, "sent");
      }

      return this.parseFunction(node);
    }

    parseMetaProperty(node, meta, propertyName) {
      node.meta = meta;

      if (meta.name === "function" && propertyName === "sent") {
        if (this.isContextual(propertyName)) {
          this.expectPlugin("functionSent");
        } else if (!this.hasPlugin("functionSent")) {
          this.unexpected();
        }
      }

      const containsEsc = this.state.containsEsc;
      node.property = this.parseIdentifier(true);

      if (node.property.name !== propertyName || containsEsc) {
        this.raise(node.property.start, ErrorMessages.UnsupportedMetaProperty, meta.name, propertyName);
      }

      return this.finishNode(node, "MetaProperty");
    }

    parseImportMetaProperty(node) {
      const id = this.createIdentifier(this.startNodeAtNode(node), "import");
      this.next();

      if (this.isContextual("meta")) {
        if (!this.inModule) {
          this.raiseWithData(id.start, {
            code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED"
          }, ErrorMessages.ImportMetaOutsideModule);
        }

        this.sawUnambiguousESM = true;
      }

      return this.parseMetaProperty(node, id, "meta");
    }

    parseLiteral(value, type, startPos, startLoc) {
      startPos = startPos || this.state.start;
      startLoc = startLoc || this.state.startLoc;
      const node = this.startNodeAt(startPos, startLoc);
      this.addExtra(node, "rawValue", value);
      this.addExtra(node, "raw", this.input.slice(startPos, this.state.end));
      node.value = value;
      this.next();
      return this.finishNode(node, type);
    }

    parseParenAndDistinguishExpression(canBeArrow) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      let val;
      this.next();
      const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;
      const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
      this.state.maybeInArrowParameters = true;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      this.state.inFSharpPipelineDirectBody = false;
      const innerStartPos = this.state.start;
      const innerStartLoc = this.state.startLoc;
      const exprList = [];
      const refExpressionErrors = new ExpressionErrors();
      const refNeedsArrowPos = {
        start: 0
      };
      let first = true;
      let spreadStart;
      let optionalCommaStart;

      while (!this.match(types.parenR)) {
        if (first) {
          first = false;
        } else {
          this.expect(types.comma, refNeedsArrowPos.start || null);

          if (this.match(types.parenR)) {
            optionalCommaStart = this.state.start;
            break;
          }
        }

        if (this.match(types.ellipsis)) {
          const spreadNodeStartPos = this.state.start;
          const spreadNodeStartLoc = this.state.startLoc;
          spreadStart = this.state.start;
          exprList.push(this.parseParenItem(this.parseRestBinding(), spreadNodeStartPos, spreadNodeStartLoc));
          this.checkCommaAfterRest(41);
          break;
        } else {
          exprList.push(this.parseMaybeAssignAllowIn(refExpressionErrors, this.parseParenItem, refNeedsArrowPos));
        }
      }

      const innerEndPos = this.state.lastTokEnd;
      const innerEndLoc = this.state.lastTokEndLoc;
      this.expect(types.parenR);
      this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
      this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
      let arrowNode = this.startNodeAt(startPos, startLoc);

      if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) {
        if (!this.isAwaitAllowed() && !this.state.maybeInAsyncArrowHead) {
          this.state.awaitPos = oldAwaitPos;
        }

        this.checkYieldAwaitInDefaultParams();
        this.state.yieldPos = oldYieldPos;
        this.state.awaitPos = oldAwaitPos;

        for (let _i2 = 0; _i2 < exprList.length; _i2++) {
          const param = exprList[_i2];

          if (param.extra && param.extra.parenthesized) {
            this.unexpected(param.extra.parenStart);
          }
        }

        this.parseArrowExpression(arrowNode, exprList, false);
        return arrowNode;
      }

      if (oldYieldPos !== -1) this.state.yieldPos = oldYieldPos;
      if (oldAwaitPos !== -1) this.state.awaitPos = oldAwaitPos;

      if (!exprList.length) {
        this.unexpected(this.state.lastTokStart);
      }

      if (optionalCommaStart) this.unexpected(optionalCommaStart);
      if (spreadStart) this.unexpected(spreadStart);
      this.checkExpressionErrors(refExpressionErrors, true);
      if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start);
      this.toReferencedListDeep(exprList, true);

      if (exprList.length > 1) {
        val = this.startNodeAt(innerStartPos, innerStartLoc);
        val.expressions = exprList;
        this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
      } else {
        val = exprList[0];
      }

      if (!this.options.createParenthesizedExpressions) {
        this.addExtra(val, "parenthesized", true);
        this.addExtra(val, "parenStart", startPos);
        return val;
      }

      const parenExpression = this.startNodeAt(startPos, startLoc);
      parenExpression.expression = val;
      this.finishNode(parenExpression, "ParenthesizedExpression");
      return parenExpression;
    }

    shouldParseArrow() {
      return !this.canInsertSemicolon();
    }

    parseArrow(node) {
      if (this.eat(types.arrow)) {
        return node;
      }
    }

    parseParenItem(node, startPos, startLoc) {
      return node;
    }

    parseNewOrNewTarget() {
      const node = this.startNode();
      this.next();

      if (this.match(types.dot)) {
        const meta = this.createIdentifier(this.startNodeAtNode(node), "new");
        this.next();
        const metaProp = this.parseMetaProperty(node, meta, "target");

        if (!this.scope.inNonArrowFunction && !this.scope.inClass) {
          let error = ErrorMessages.UnexpectedNewTarget;

          if (this.hasPlugin("classProperties")) {
            error += " or class properties";
          }

          this.raise(metaProp.start, error);
        }

        return metaProp;
      }

      return this.parseNew(node);
    }

    parseNew(node) {
      node.callee = this.parseNoCallExpr();

      if (node.callee.type === "Import") {
        this.raise(node.callee.start, ErrorMessages.ImportCallNotNewExpression);
      } else if (node.callee.type === "OptionalMemberExpression" || node.callee.type === "OptionalCallExpression") {
        this.raise(this.state.lastTokEnd, ErrorMessages.OptionalChainingNoNew);
      } else if (this.eat(types.questionDot)) {
        this.raise(this.state.start, ErrorMessages.OptionalChainingNoNew);
      }

      this.parseNewArguments(node);
      return this.finishNode(node, "NewExpression");
    }

    parseNewArguments(node) {
      if (this.eat(types.parenL)) {
        const args = this.parseExprList(types.parenR);
        this.toReferencedList(args);
        node.arguments = args;
      } else {
        node.arguments = [];
      }
    }

    parseTemplateElement(isTagged) {
      const elem = this.startNode();

      if (this.state.value === null) {
        if (!isTagged) {
          this.raise(this.state.start + 1, ErrorMessages.InvalidEscapeSequenceTemplate);
        }
      }

      elem.value = {
        raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"),
        cooked: this.state.value
      };
      this.next();
      elem.tail = this.match(types.backQuote);
      return this.finishNode(elem, "TemplateElement");
    }

    parseTemplate(isTagged) {
      const node = this.startNode();
      this.next();
      node.expressions = [];
      let curElt = this.parseTemplateElement(isTagged);
      node.quasis = [curElt];

      while (!curElt.tail) {
        this.expect(types.dollarBraceL);
        node.expressions.push(this.parseExpression());
        this.expect(types.braceR);
        node.quasis.push(curElt = this.parseTemplateElement(isTagged));
      }

      this.next();
      return this.finishNode(node, "TemplateLiteral");
    }

    parseObjectLike(close, isPattern, isRecord, refExpressionErrors) {
      if (isRecord) {
        this.expectPlugin("recordAndTuple");
      }

      const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
      this.state.inFSharpPipelineDirectBody = false;
      const propHash = Object.create(null);
      let first = true;
      const node = this.startNode();
      node.properties = [];
      this.next();

      while (!this.eat(close)) {
        if (first) {
          first = false;
        } else {
          this.expect(types.comma);

          if (this.match(close)) {
            this.addExtra(node, "trailingComma", this.state.lastTokStart);
            this.next();
            break;
          }
        }

        const prop = this.parsePropertyDefinition(isPattern, refExpressionErrors);

        if (!isPattern) {
          this.checkProto(prop, isRecord, propHash, refExpressionErrors);
        }

        if (isRecord && prop.type !== "ObjectProperty" && prop.type !== "SpreadElement") {
          this.raise(prop.start, ErrorMessages.InvalidRecordProperty);
        }

        if (prop.shorthand) {
          this.addExtra(prop, "shorthand", true);
        }

        node.properties.push(prop);
      }

      this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
      let type = "ObjectExpression";

      if (isPattern) {
        type = "ObjectPattern";
      } else if (isRecord) {
        type = "RecordExpression";
      }

      return this.finishNode(node, type);
    }

    maybeAsyncOrAccessorProp(prop) {
      return !prop.computed && prop.key.type === "Identifier" && (this.isLiteralPropertyName() || this.match(types.bracketL) || this.match(types.star));
    }

    parsePropertyDefinition(isPattern, refExpressionErrors) {
      let decorators = [];

      if (this.match(types.at)) {
        if (this.hasPlugin("decorators")) {
          this.raise(this.state.start, ErrorMessages.UnsupportedPropertyDecorator);
        }

        while (this.match(types.at)) {
          decorators.push(this.parseDecorator());
        }
      }

      const prop = this.startNode();
      let isGenerator = false;
      let isAsync = false;
      let isAccessor = false;
      let startPos;
      let startLoc;

      if (this.match(types.ellipsis)) {
        if (decorators.length) this.unexpected();

        if (isPattern) {
          this.next();
          prop.argument = this.parseIdentifier();
          this.checkCommaAfterRest(125);
          return this.finishNode(prop, "RestElement");
        }

        return this.parseSpread();
      }

      if (decorators.length) {
        prop.decorators = decorators;
        decorators = [];
      }

      prop.method = false;

      if (isPattern || refExpressionErrors) {
        startPos = this.state.start;
        startLoc = this.state.startLoc;
      }

      if (!isPattern) {
        isGenerator = this.eat(types.star);
      }

      const containsEsc = this.state.containsEsc;
      const key = this.parsePropertyName(prop, false);

      if (!isPattern && !isGenerator && !containsEsc && this.maybeAsyncOrAccessorProp(prop)) {
        const keyName = key.name;

        if (keyName === "async" && !this.hasPrecedingLineBreak()) {
          isAsync = true;
          isGenerator = this.eat(types.star);
          this.parsePropertyName(prop, false);
        }

        if (keyName === "get" || keyName === "set") {
          isAccessor = true;
          prop.kind = keyName;

          if (this.match(types.star)) {
            isGenerator = true;
            this.raise(this.state.pos, ErrorMessages.AccessorIsGenerator, keyName);
            this.next();
          }

          this.parsePropertyName(prop, false);
        }
      }

      this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors);
      return prop;
    }

    getGetterSetterExpectedParamCount(method) {
      return method.kind === "get" ? 0 : 1;
    }

    checkGetterSetterParams(method) {
      const paramCount = this.getGetterSetterExpectedParamCount(method);
      const start = method.start;

      if (method.params.length !== paramCount) {
        if (method.kind === "get") {
          this.raise(start, ErrorMessages.BadGetterArity);
        } else {
          this.raise(start, ErrorMessages.BadSetterArity);
        }
      }

      if (method.kind === "set" && method.params[method.params.length - 1].type === "RestElement") {
        this.raise(start, ErrorMessages.BadSetterRestParameter);
      }
    }

    parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) {
      if (isAccessor) {
        this.parseMethod(prop, isGenerator, false, false, false, "ObjectMethod");
        this.checkGetterSetterParams(prop);
        return prop;
      }

      if (isAsync || isGenerator || this.match(types.parenL)) {
        if (isPattern) this.unexpected();
        prop.kind = "method";
        prop.method = true;
        return this.parseMethod(prop, isGenerator, isAsync, false, false, "ObjectMethod");
      }
    }

    parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors) {
      prop.shorthand = false;

      if (this.eat(types.colon)) {
        prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssignAllowIn(refExpressionErrors);
        return this.finishNode(prop, "ObjectProperty");
      }

      if (!prop.computed && prop.key.type === "Identifier") {
        this.checkReservedWord(prop.key.name, prop.key.start, true, false);

        if (isPattern) {
          prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone());
        } else if (this.match(types.eq) && refExpressionErrors) {
          if (refExpressionErrors.shorthandAssign === -1) {
            refExpressionErrors.shorthandAssign = this.state.start;
          }

          prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone());
        } else {
          prop.value = prop.key.__clone();
        }

        prop.shorthand = true;
        return this.finishNode(prop, "ObjectProperty");
      }
    }

    parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
      const node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors);
      if (!node) this.unexpected();
      return node;
    }

    parsePropertyName(prop, isPrivateNameAllowed) {
      if (this.eat(types.bracketL)) {
        prop.computed = true;
        prop.key = this.parseMaybeAssignAllowIn();
        this.expect(types.bracketR);
      } else {
        const oldInPropertyName = this.state.inPropertyName;
        this.state.inPropertyName = true;
        prop.key = this.match(types.num) || this.match(types.string) || this.match(types.bigint) || this.match(types.decimal) ? this.parseExprAtom() : this.parseMaybePrivateName(isPrivateNameAllowed);

        if (prop.key.type !== "PrivateName") {
          prop.computed = false;
        }

        this.state.inPropertyName = oldInPropertyName;
      }

      return prop.key;
    }

    initFunction(node, isAsync) {
      node.id = null;
      node.generator = false;
      node.async = !!isAsync;
    }

    parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) {
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      this.initFunction(node, isAsync);
      node.generator = !!isGenerator;
      const allowModifiers = isConstructor;
      this.scope.enter(SCOPE_FUNCTION | SCOPE_SUPER | (inClassScope ? SCOPE_CLASS : 0) | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
      this.prodParam.enter(functionFlags(isAsync, node.generator));
      this.parseFunctionParams(node, allowModifiers);
      this.parseFunctionBodyAndFinish(node, type, true);
      this.prodParam.exit();
      this.scope.exit();
      this.state.yieldPos = oldYieldPos;
      this.state.awaitPos = oldAwaitPos;
      return node;
    }

    parseArrayLike(close, canBePattern, isTuple, refExpressionErrors) {
      if (isTuple) {
        this.expectPlugin("recordAndTuple");
      }

      const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
      this.state.inFSharpPipelineDirectBody = false;
      const node = this.startNode();
      this.next();
      node.elements = this.parseExprList(close, !isTuple, refExpressionErrors, node);

      if (canBePattern && !this.state.maybeInArrowParameters) {
        this.toReferencedList(node.elements);
      }

      this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
      return this.finishNode(node, isTuple ? "TupleExpression" : "ArrayExpression");
    }

    parseArrowExpression(node, params, isAsync, trailingCommaPos) {
      this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW);
      let flags = functionFlags(isAsync, false);

      if (!this.match(types.bracketL) && this.prodParam.hasIn) {
        flags |= PARAM_IN;
      }

      this.prodParam.enter(flags);
      this.initFunction(node, isAsync);
      const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;

      if (params) {
        this.state.maybeInArrowParameters = true;
        this.setArrowFunctionParameters(node, params, trailingCommaPos);
      }

      this.state.maybeInArrowParameters = false;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      this.parseFunctionBody(node, true);
      this.prodParam.exit();
      this.scope.exit();
      this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
      this.state.yieldPos = oldYieldPos;
      this.state.awaitPos = oldAwaitPos;
      return this.finishNode(node, "ArrowFunctionExpression");
    }

    setArrowFunctionParameters(node, params, trailingCommaPos) {
      node.params = this.toAssignableList(params, trailingCommaPos);
    }

    parseFunctionBodyAndFinish(node, type, isMethod = false) {
      this.parseFunctionBody(node, false, isMethod);
      this.finishNode(node, type);
    }

    parseFunctionBody(node, allowExpression, isMethod = false) {
      const isExpression = allowExpression && !this.match(types.braceL);
      const oldInParameters = this.state.inParameters;
      this.state.inParameters = false;

      if (isExpression) {
        node.body = this.parseMaybeAssign();
        this.checkParams(node, false, allowExpression, false);
      } else {
        const oldStrict = this.state.strict;
        const oldLabels = this.state.labels;
        this.state.labels = [];
        this.prodParam.enter(this.prodParam.currentFlags() | PARAM_RETURN);
        node.body = this.parseBlock(true, false, hasStrictModeDirective => {
          const nonSimple = !this.isSimpleParamList(node.params);

          if (hasStrictModeDirective && nonSimple) {
            const errorPos = (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.end : node.start;
            this.raise(errorPos, ErrorMessages.IllegalLanguageModeDirective);
          }

          const strictModeChanged = !oldStrict && this.state.strict;
          this.checkParams(node, !this.state.strict && !allowExpression && !isMethod && !nonSimple, allowExpression, strictModeChanged);

          if (this.state.strict && node.id) {
            this.checkLVal(node.id, BIND_OUTSIDE, undefined, "function name", undefined, strictModeChanged);
          }
        });
        this.prodParam.exit();
        this.state.labels = oldLabels;
      }

      this.state.inParameters = oldInParameters;
    }

    isSimpleParamList(params) {
      for (let i = 0, len = params.length; i < len; i++) {
        if (params[i].type !== "Identifier") return false;
      }

      return true;
    }

    checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) {
      const nameHash = Object.create(null);

      for (let i = 0; i < node.params.length; i++) {
        this.checkLVal(node.params[i], BIND_VAR, allowDuplicates ? null : nameHash, "function parameter list", undefined, strictModeChanged);
      }
    }

    parseExprList(close, allowEmpty, refExpressionErrors, nodeForExtra) {
      const elts = [];
      let first = true;

      while (!this.eat(close)) {
        if (first) {
          first = false;
        } else {
          this.expect(types.comma);

          if (this.match(close)) {
            if (nodeForExtra) {
              this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart);
            }

            this.next();
            break;
          }
        }

        elts.push(this.parseExprListItem(allowEmpty, refExpressionErrors));
      }

      return elts;
    }

    parseExprListItem(allowEmpty, refExpressionErrors, refNeedsArrowPos, allowPlaceholder) {
      let elt;

      if (this.match(types.comma)) {
        if (!allowEmpty) {
          this.raise(this.state.pos, ErrorMessages.UnexpectedToken, ",");
        }

        elt = null;
      } else if (this.match(types.ellipsis)) {
        const spreadNodeStartPos = this.state.start;
        const spreadNodeStartLoc = this.state.startLoc;
        elt = this.parseParenItem(this.parseSpread(refExpressionErrors, refNeedsArrowPos), spreadNodeStartPos, spreadNodeStartLoc);
      } else if (this.match(types.question)) {
        this.expectPlugin("partialApplication");

        if (!allowPlaceholder) {
          this.raise(this.state.start, ErrorMessages.UnexpectedArgumentPlaceholder);
        }

        const node = this.startNode();
        this.next();
        elt = this.finishNode(node, "ArgumentPlaceholder");
      } else {
        elt = this.parseMaybeAssignAllowIn(refExpressionErrors, this.parseParenItem, refNeedsArrowPos);
      }

      return elt;
    }

    parseIdentifier(liberal) {
      const node = this.startNode();
      const name = this.parseIdentifierName(node.start, liberal);
      return this.createIdentifier(node, name);
    }

    createIdentifier(node, name) {
      node.name = name;
      node.loc.identifierName = name;
      return this.finishNode(node, "Identifier");
    }

    parseIdentifierName(pos, liberal) {
      let name;
      const {
        start,
        type
      } = this.state;

      if (type === types.name) {
        name = this.state.value;
      } else if (type.keyword) {
        name = type.keyword;
        const curContext = this.curContext();

        if ((type === types._class || type === types._function) && (curContext === types$1.functionStatement || curContext === types$1.functionExpression)) {
          this.state.context.pop();
        }
      } else {
        throw this.unexpected();
      }

      if (liberal) {
        this.state.type = types.name;
      } else {
        this.checkReservedWord(name, start, !!type.keyword, false);
      }

      this.next();
      return name;
    }

    checkReservedWord(word, startLoc, checkKeywords, isBinding) {
      if (this.prodParam.hasYield && word === "yield") {
        this.raise(startLoc, ErrorMessages.YieldBindingIdentifier);
        return;
      }

      if (word === "await") {
        if (this.prodParam.hasAwait) {
          this.raise(startLoc, ErrorMessages.AwaitBindingIdentifier);
          return;
        }

        if (this.state.awaitPos === -1 && (this.state.maybeInAsyncArrowHead || this.isAwaitAllowed())) {
          this.state.awaitPos = this.state.start;
        }
      }

      if (this.scope.inClass && !this.scope.inNonArrowFunction && word === "arguments") {
        this.raise(startLoc, ErrorMessages.ArgumentsDisallowedInInitializer);
        return;
      }

      if (checkKeywords && isKeyword(word)) {
        this.raise(startLoc, ErrorMessages.UnexpectedKeyword, word);
        return;
      }

      const reservedTest = !this.state.strict ? isReservedWord : isBinding ? isStrictBindReservedWord : isStrictReservedWord;

      if (reservedTest(word, this.inModule)) {
        if (!this.prodParam.hasAwait && word === "await") {
          this.raise(startLoc, ErrorMessages.AwaitNotInAsyncFunction);
        } else {
          this.raise(startLoc, ErrorMessages.UnexpectedReservedWord, word);
        }
      }
    }

    isAwaitAllowed() {
      if (this.scope.inFunction) return this.prodParam.hasAwait;
      if (this.options.allowAwaitOutsideFunction) return true;

      if (this.hasPlugin("topLevelAwait")) {
        return this.inModule && this.prodParam.hasAwait;
      }

      return false;
    }

    parseAwait() {
      const node = this.startNode();
      this.next();

      if (this.state.inParameters) {
        this.raise(node.start, ErrorMessages.AwaitExpressionFormalParameter);
      } else if (this.state.awaitPos === -1) {
        this.state.awaitPos = node.start;
      }

      if (this.eat(types.star)) {
        this.raise(node.start, ErrorMessages.ObsoleteAwaitStar);
      }

      if (!this.scope.inFunction && !this.options.allowAwaitOutsideFunction) {
        if (this.hasPrecedingLineBreak() || this.match(types.plusMin) || this.match(types.parenL) || this.match(types.bracketL) || this.match(types.backQuote) || this.match(types.regexp) || this.match(types.slash) || this.hasPlugin("v8intrinsic") && this.match(types.modulo)) {
          this.ambiguousScriptDifferentAst = true;
        } else {
          this.sawUnambiguousESM = true;
        }
      }

      if (!this.state.soloAwait) {
        node.argument = this.parseMaybeUnary();
      }

      return this.finishNode(node, "AwaitExpression");
    }

    parseYield() {
      const node = this.startNode();

      if (this.state.inParameters) {
        this.raise(node.start, ErrorMessages.YieldInParameter);
      } else if (this.state.yieldPos === -1) {
        this.state.yieldPos = node.start;
      }

      this.next();

      if (this.match(types.semi) || !this.match(types.star) && !this.state.type.startsExpr || this.hasPrecedingLineBreak()) {
        node.delegate = false;
        node.argument = null;
      } else {
        node.delegate = this.eat(types.star);
        node.argument = this.parseMaybeAssign();
      }

      return this.finishNode(node, "YieldExpression");
    }

    checkPipelineAtInfixOperator(left, leftStartPos) {
      if (this.getPluginOption("pipelineOperator", "proposal") === "smart") {
        if (left.type === "SequenceExpression") {
          this.raise(leftStartPos, ErrorMessages.PipelineHeadSequenceExpression);
        }
      }
    }

    parseSmartPipelineBody(childExpression, startPos, startLoc) {
      this.checkSmartPipelineBodyEarlyErrors(childExpression, startPos);
      return this.parseSmartPipelineBodyInStyle(childExpression, startPos, startLoc);
    }

    checkSmartPipelineBodyEarlyErrors(childExpression, startPos) {
      if (this.match(types.arrow)) {
        throw this.raise(this.state.start, ErrorMessages.PipelineBodyNoArrow);
      } else if (childExpression.type === "SequenceExpression") {
        this.raise(startPos, ErrorMessages.PipelineBodySequenceExpression);
      }
    }

    parseSmartPipelineBodyInStyle(childExpression, startPos, startLoc) {
      const bodyNode = this.startNodeAt(startPos, startLoc);
      const isSimpleReference = this.isSimpleReference(childExpression);

      if (isSimpleReference) {
        bodyNode.callee = childExpression;
      } else {
        if (!this.topicReferenceWasUsedInCurrentTopicContext()) {
          this.raise(startPos, ErrorMessages.PipelineTopicUnused);
        }

        bodyNode.expression = childExpression;
      }

      return this.finishNode(bodyNode, isSimpleReference ? "PipelineBareFunction" : "PipelineTopicExpression");
    }

    isSimpleReference(expression) {
      switch (expression.type) {
        case "MemberExpression":
          return !expression.computed && this.isSimpleReference(expression.object);

        case "Identifier":
          return true;

        default:
          return false;
      }
    }

    withTopicPermittingContext(callback) {
      const outerContextTopicState = this.state.topicContext;
      this.state.topicContext = {
        maxNumOfResolvableTopics: 1,
        maxTopicIndex: null
      };

      try {
        return callback();
      } finally {
        this.state.topicContext = outerContextTopicState;
      }
    }

    withTopicForbiddingContext(callback) {
      const outerContextTopicState = this.state.topicContext;
      this.state.topicContext = {
        maxNumOfResolvableTopics: 0,
        maxTopicIndex: null
      };

      try {
        return callback();
      } finally {
        this.state.topicContext = outerContextTopicState;
      }
    }

    withSoloAwaitPermittingContext(callback) {
      const outerContextSoloAwaitState = this.state.soloAwait;
      this.state.soloAwait = true;

      try {
        return callback();
      } finally {
        this.state.soloAwait = outerContextSoloAwaitState;
      }
    }

    allowInAnd(callback) {
      const flags = this.prodParam.currentFlags();
      const prodParamToSet = PARAM_IN & ~flags;

      if (prodParamToSet) {
        this.prodParam.enter(flags | PARAM_IN);

        try {
          return callback();
        } finally {
          this.prodParam.exit();
        }
      }

      return callback();
    }

    disallowInAnd(callback) {
      const flags = this.prodParam.currentFlags();
      const prodParamToClear = PARAM_IN & flags;

      if (prodParamToClear) {
        this.prodParam.enter(flags & ~PARAM_IN);

        try {
          return callback();
        } finally {
          this.prodParam.exit();
        }
      }

      return callback();
    }

    registerTopicReference() {
      this.state.topicContext.maxTopicIndex = 0;
    }

    primaryTopicReferenceIsAllowedInCurrentTopicContext() {
      return this.state.topicContext.maxNumOfResolvableTopics >= 1;
    }

    topicReferenceWasUsedInCurrentTopicContext() {
      return this.state.topicContext.maxTopicIndex != null && this.state.topicContext.maxTopicIndex >= 0;
    }

    parseFSharpPipelineBody(prec) {
      const startPos = this.state.start;
      const startLoc = this.state.startLoc;
      this.state.potentialArrowAt = this.state.start;
      const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
      this.state.inFSharpPipelineDirectBody = true;
      const ret = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec);
      this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
      return ret;
    }

  }

  const loopLabel = {
    kind: "loop"
  },
        switchLabel = {
    kind: "switch"
  };
  const FUNC_NO_FLAGS = 0b000,
        FUNC_STATEMENT = 0b001,
        FUNC_HANGING_STATEMENT = 0b010,
        FUNC_NULLABLE_ID = 0b100;
  class StatementParser extends ExpressionParser {
    parseTopLevel(file, program) {
      program.sourceType = this.options.sourceType;
      program.interpreter = this.parseInterpreterDirective();
      this.parseBlockBody(program, true, true, types.eof);

      if (this.inModule && !this.options.allowUndeclaredExports && this.scope.undefinedExports.size > 0) {
        for (let _i = 0, _Array$from = Array.from(this.scope.undefinedExports); _i < _Array$from.length; _i++) {
          const [name] = _Array$from[_i];
          const pos = this.scope.undefinedExports.get(name);
          this.raise(pos, ErrorMessages.ModuleExportUndefined, name);
        }
      }

      file.program = this.finishNode(program, "Program");
      file.comments = this.state.comments;
      if (this.options.tokens) file.tokens = this.tokens;
      return this.finishNode(file, "File");
    }

    stmtToDirective(stmt) {
      const expr = stmt.expression;
      const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start);
      const directive = this.startNodeAt(stmt.start, stmt.loc.start);
      const raw = this.input.slice(expr.start, expr.end);
      const val = directiveLiteral.value = raw.slice(1, -1);
      this.addExtra(directiveLiteral, "raw", raw);
      this.addExtra(directiveLiteral, "rawValue", val);
      directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end);
      return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end);
    }

    parseInterpreterDirective() {
      if (!this.match(types.interpreterDirective)) {
        return null;
      }

      const node = this.startNode();
      node.value = this.state.value;
      this.next();
      return this.finishNode(node, "InterpreterDirective");
    }

    isLet(context) {
      if (!this.isContextual("let")) {
        return false;
      }

      const next = this.nextTokenStart();
      const nextCh = this.input.charCodeAt(next);
      if (nextCh === 91) return true;
      if (context) return false;
      if (nextCh === 123) return true;

      if (isIdentifierStart(nextCh)) {
        let pos = next + 1;

        while (isIdentifierChar(this.input.charCodeAt(pos))) {
          ++pos;
        }

        const ident = this.input.slice(next, pos);
        if (!keywordRelationalOperator.test(ident)) return true;
      }

      return false;
    }

    parseStatement(context, topLevel) {
      if (this.match(types.at)) {
        this.parseDecorators(true);
      }

      return this.parseStatementContent(context, topLevel);
    }

    parseStatementContent(context, topLevel) {
      let starttype = this.state.type;
      const node = this.startNode();
      let kind;

      if (this.isLet(context)) {
        starttype = types._var;
        kind = "let";
      }

      switch (starttype) {
        case types._break:
        case types._continue:
          return this.parseBreakContinueStatement(node, starttype.keyword);

        case types._debugger:
          return this.parseDebuggerStatement(node);

        case types._do:
          return this.parseDoStatement(node);

        case types._for:
          return this.parseForStatement(node);

        case types._function:
          if (this.lookaheadCharCode() === 46) break;

          if (context) {
            if (this.state.strict) {
              this.raise(this.state.start, ErrorMessages.StrictFunction);
            } else if (context !== "if" && context !== "label") {
              this.raise(this.state.start, ErrorMessages.SloppyFunction);
            }
          }

          return this.parseFunctionStatement(node, false, !context);

        case types._class:
          if (context) this.unexpected();
          return this.parseClass(node, true);

        case types._if:
          return this.parseIfStatement(node);

        case types._return:
          return this.parseReturnStatement(node);

        case types._switch:
          return this.parseSwitchStatement(node);

        case types._throw:
          return this.parseThrowStatement(node);

        case types._try:
          return this.parseTryStatement(node);

        case types._const:
        case types._var:
          kind = kind || this.state.value;

          if (context && kind !== "var") {
            this.raise(this.state.start, ErrorMessages.UnexpectedLexicalDeclaration);
          }

          return this.parseVarStatement(node, kind);

        case types._while:
          return this.parseWhileStatement(node);

        case types._with:
          return this.parseWithStatement(node);

        case types.braceL:
          return this.parseBlock();

        case types.semi:
          return this.parseEmptyStatement(node);

        case types._import:
          {
            const nextTokenCharCode = this.lookaheadCharCode();

            if (nextTokenCharCode === 40 || nextTokenCharCode === 46) {
                break;
              }
          }

        case types._export:
          {
            if (!this.options.allowImportExportEverywhere && !topLevel) {
              this.raise(this.state.start, ErrorMessages.UnexpectedImportExport);
            }

            this.next();
            let result;

            if (starttype === types._import) {
              result = this.parseImport(node);

              if (result.type === "ImportDeclaration" && (!result.importKind || result.importKind === "value")) {
                this.sawUnambiguousESM = true;
              }
            } else {
              result = this.parseExport(node);

              if (result.type === "ExportNamedDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportAllDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportDefaultDeclaration") {
                this.sawUnambiguousESM = true;
              }
            }

            this.assertModuleNodeAllowed(node);
            return result;
          }

        default:
          {
            if (this.isAsyncFunction()) {
              if (context) {
                this.raise(this.state.start, ErrorMessages.AsyncFunctionInSingleStatementContext);
              }

              this.next();
              return this.parseFunctionStatement(node, true, !context);
            }
          }
      }

      const maybeName = this.state.value;
      const expr = this.parseExpression();

      if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) {
        return this.parseLabeledStatement(node, maybeName, expr, context);
      } else {
        return this.parseExpressionStatement(node, expr);
      }
    }

    assertModuleNodeAllowed(node) {
      if (!this.options.allowImportExportEverywhere && !this.inModule) {
        this.raiseWithData(node.start, {
          code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED"
        }, ErrorMessages.ImportOutsideModule);
      }
    }

    takeDecorators(node) {
      const decorators = this.state.decoratorStack[this.state.decoratorStack.length - 1];

      if (decorators.length) {
        node.decorators = decorators;
        this.resetStartLocationFromNode(node, decorators[0]);
        this.state.decoratorStack[this.state.decoratorStack.length - 1] = [];
      }
    }

    canHaveLeadingDecorator() {
      return this.match(types._class);
    }

    parseDecorators(allowExport) {
      const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1];

      while (this.match(types.at)) {
        const decorator = this.parseDecorator();
        currentContextDecorators.push(decorator);
      }

      if (this.match(types._export)) {
        if (!allowExport) {
          this.unexpected();
        }

        if (this.hasPlugin("decorators") && !this.getPluginOption("decorators", "decoratorsBeforeExport")) {
          this.raise(this.state.start, ErrorMessages.DecoratorExportClass);
        }
      } else if (!this.canHaveLeadingDecorator()) {
        throw this.raise(this.state.start, ErrorMessages.UnexpectedLeadingDecorator);
      }
    }

    parseDecorator() {
      this.expectOnePlugin(["decorators-legacy", "decorators"]);
      const node = this.startNode();
      this.next();

      if (this.hasPlugin("decorators")) {
        this.state.decoratorStack.push([]);
        const startPos = this.state.start;
        const startLoc = this.state.startLoc;
        let expr;

        if (this.eat(types.parenL)) {
          expr = this.parseExpression();
          this.expect(types.parenR);
        } else {
          expr = this.parseIdentifier(false);

          while (this.eat(types.dot)) {
            const node = this.startNodeAt(startPos, startLoc);
            node.object = expr;
            node.property = this.parseIdentifier(true);
            node.computed = false;
            expr = this.finishNode(node, "MemberExpression");
          }
        }

        node.expression = this.parseMaybeDecoratorArguments(expr);
        this.state.decoratorStack.pop();
      } else {
        node.expression = this.parseExprSubscripts();
      }

      return this.finishNode(node, "Decorator");
    }

    parseMaybeDecoratorArguments(expr) {
      if (this.eat(types.parenL)) {
        const node = this.startNodeAtNode(expr);
        node.callee = expr;
        node.arguments = this.parseCallExpressionArguments(types.parenR, false);
        this.toReferencedList(node.arguments);
        return this.finishNode(node, "CallExpression");
      }

      return expr;
    }

    parseBreakContinueStatement(node, keyword) {
      const isBreak = keyword === "break";
      this.next();

      if (this.isLineTerminator()) {
        node.label = null;
      } else {
        node.label = this.parseIdentifier();
        this.semicolon();
      }

      this.verifyBreakContinue(node, keyword);
      return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
    }

    verifyBreakContinue(node, keyword) {
      const isBreak = keyword === "break";
      let i;

      for (i = 0; i < this.state.labels.length; ++i) {
        const lab = this.state.labels[i];

        if (node.label == null || lab.name === node.label.name) {
          if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
          if (node.label && isBreak) break;
        }
      }

      if (i === this.state.labels.length) {
        this.raise(node.start, ErrorMessages.IllegalBreakContinue, keyword);
      }
    }

    parseDebuggerStatement(node) {
      this.next();
      this.semicolon();
      return this.finishNode(node, "DebuggerStatement");
    }

    parseHeaderExpression() {
      this.expect(types.parenL);
      const val = this.parseExpression();
      this.expect(types.parenR);
      return val;
    }

    parseDoStatement(node) {
      this.next();
      this.state.labels.push(loopLabel);
      node.body = this.withTopicForbiddingContext(() => this.parseStatement("do"));
      this.state.labels.pop();
      this.expect(types._while);
      node.test = this.parseHeaderExpression();
      this.eat(types.semi);
      return this.finishNode(node, "DoWhileStatement");
    }

    parseForStatement(node) {
      this.next();
      this.state.labels.push(loopLabel);
      let awaitAt = -1;

      if (this.isAwaitAllowed() && this.eatContextual("await")) {
        awaitAt = this.state.lastTokStart;
      }

      this.scope.enter(SCOPE_OTHER);
      this.expect(types.parenL);

      if (this.match(types.semi)) {
        if (awaitAt > -1) {
          this.unexpected(awaitAt);
        }

        return this.parseFor(node, null);
      }

      const isLet = this.isLet();

      if (this.match(types._var) || this.match(types._const) || isLet) {
        const init = this.startNode();
        const kind = isLet ? "let" : this.state.value;
        this.next();
        this.parseVar(init, true, kind);
        this.finishNode(init, "VariableDeclaration");

        if ((this.match(types._in) || this.isContextual("of")) && init.declarations.length === 1) {
          return this.parseForIn(node, init, awaitAt);
        }

        if (awaitAt > -1) {
          this.unexpected(awaitAt);
        }

        return this.parseFor(node, init);
      }

      const refExpressionErrors = new ExpressionErrors();
      const init = this.parseExpression(true, refExpressionErrors);

      if (this.match(types._in) || this.isContextual("of")) {
        this.toAssignable(init);
        const description = this.isContextual("of") ? "for-of statement" : "for-in statement";
        this.checkLVal(init, undefined, undefined, description);
        return this.parseForIn(node, init, awaitAt);
      } else {
        this.checkExpressionErrors(refExpressionErrors, true);
      }

      if (awaitAt > -1) {
        this.unexpected(awaitAt);
      }

      return this.parseFor(node, init);
    }

    parseFunctionStatement(node, isAsync, declarationPosition) {
      this.next();
      return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), isAsync);
    }

    parseIfStatement(node) {
      this.next();
      node.test = this.parseHeaderExpression();
      node.consequent = this.parseStatement("if");
      node.alternate = this.eat(types._else) ? this.parseStatement("if") : null;
      return this.finishNode(node, "IfStatement");
    }

    parseReturnStatement(node) {
      if (!this.prodParam.hasReturn && !this.options.allowReturnOutsideFunction) {
        this.raise(this.state.start, ErrorMessages.IllegalReturn);
      }

      this.next();

      if (this.isLineTerminator()) {
        node.argument = null;
      } else {
        node.argument = this.parseExpression();
        this.semicolon();
      }

      return this.finishNode(node, "ReturnStatement");
    }

    parseSwitchStatement(node) {
      this.next();
      node.discriminant = this.parseHeaderExpression();
      const cases = node.cases = [];
      this.expect(types.braceL);
      this.state.labels.push(switchLabel);
      this.scope.enter(SCOPE_OTHER);
      let cur;

      for (let sawDefault; !this.match(types.braceR);) {
        if (this.match(types._case) || this.match(types._default)) {
          const isCase = this.match(types._case);
          if (cur) this.finishNode(cur, "SwitchCase");
          cases.push(cur = this.startNode());
          cur.consequent = [];
          this.next();

          if (isCase) {
            cur.test = this.parseExpression();
          } else {
            if (sawDefault) {
              this.raise(this.state.lastTokStart, ErrorMessages.MultipleDefaultsInSwitch);
            }

            sawDefault = true;
            cur.test = null;
          }

          this.expect(types.colon);
        } else {
          if (cur) {
            cur.consequent.push(this.parseStatement(null));
          } else {
            this.unexpected();
          }
        }
      }

      this.scope.exit();
      if (cur) this.finishNode(cur, "SwitchCase");
      this.next();
      this.state.labels.pop();
      return this.finishNode(node, "SwitchStatement");
    }

    parseThrowStatement(node) {
      this.next();

      if (this.hasPrecedingLineBreak()) {
        this.raise(this.state.lastTokEnd, ErrorMessages.NewlineAfterThrow);
      }

      node.argument = this.parseExpression();
      this.semicolon();
      return this.finishNode(node, "ThrowStatement");
    }

    parseCatchClauseParam() {
      const param = this.parseBindingAtom();
      const simple = param.type === "Identifier";
      this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0);
      this.checkLVal(param, BIND_LEXICAL, null, "catch clause");
      return param;
    }

    parseTryStatement(node) {
      this.next();
      node.block = this.parseBlock();
      node.handler = null;

      if (this.match(types._catch)) {
        const clause = this.startNode();
        this.next();

        if (this.match(types.parenL)) {
          this.expect(types.parenL);
          clause.param = this.parseCatchClauseParam();
          this.expect(types.parenR);
        } else {
          clause.param = null;
          this.scope.enter(SCOPE_OTHER);
        }

        clause.body = this.withTopicForbiddingContext(() => this.parseBlock(false, false));
        this.scope.exit();
        node.handler = this.finishNode(clause, "CatchClause");
      }

      node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;

      if (!node.handler && !node.finalizer) {
        this.raise(node.start, ErrorMessages.NoCatchOrFinally);
      }

      return this.finishNode(node, "TryStatement");
    }

    parseVarStatement(node, kind) {
      this.next();
      this.parseVar(node, false, kind);
      this.semicolon();
      return this.finishNode(node, "VariableDeclaration");
    }

    parseWhileStatement(node) {
      this.next();
      node.test = this.parseHeaderExpression();
      this.state.labels.push(loopLabel);
      node.body = this.withTopicForbiddingContext(() => this.parseStatement("while"));
      this.state.labels.pop();
      return this.finishNode(node, "WhileStatement");
    }

    parseWithStatement(node) {
      if (this.state.strict) {
        this.raise(this.state.start, ErrorMessages.StrictWith);
      }

      this.next();
      node.object = this.parseHeaderExpression();
      node.body = this.withTopicForbiddingContext(() => this.parseStatement("with"));
      return this.finishNode(node, "WithStatement");
    }

    parseEmptyStatement(node) {
      this.next();
      return this.finishNode(node, "EmptyStatement");
    }

    parseLabeledStatement(node, maybeName, expr, context) {
      for (let _i2 = 0, _this$state$labels = this.state.labels; _i2 < _this$state$labels.length; _i2++) {
        const label = _this$state$labels[_i2];

        if (label.name === maybeName) {
          this.raise(expr.start, ErrorMessages.LabelRedeclaration, maybeName);
        }
      }

      const kind = this.state.type.isLoop ? "loop" : this.match(types._switch) ? "switch" : null;

      for (let i = this.state.labels.length - 1; i >= 0; i--) {
        const label = this.state.labels[i];

        if (label.statementStart === node.start) {
          label.statementStart = this.state.start;
          label.kind = kind;
        } else {
          break;
        }
      }

      this.state.labels.push({
        name: maybeName,
        kind: kind,
        statementStart: this.state.start
      });
      node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
      this.state.labels.pop();
      node.label = expr;
      return this.finishNode(node, "LabeledStatement");
    }

    parseExpressionStatement(node, expr) {
      node.expression = expr;
      this.semicolon();
      return this.finishNode(node, "ExpressionStatement");
    }

    parseBlock(allowDirectives = false, createNewLexicalScope = true, afterBlockParse) {
      const node = this.startNode();
      this.expect(types.braceL);

      if (createNewLexicalScope) {
        this.scope.enter(SCOPE_OTHER);
      }

      this.parseBlockBody(node, allowDirectives, false, types.braceR, afterBlockParse);

      if (createNewLexicalScope) {
        this.scope.exit();
      }

      return this.finishNode(node, "BlockStatement");
    }

    isValidDirective(stmt) {
      return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized;
    }

    parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse) {
      const body = node.body = [];
      const directives = node.directives = [];
      this.parseBlockOrModuleBlockBody(body, allowDirectives ? directives : undefined, topLevel, end, afterBlockParse);
    }

    parseBlockOrModuleBlockBody(body, directives, topLevel, end, afterBlockParse) {
      const octalPositions = [];
      const oldStrict = this.state.strict;
      let hasStrictModeDirective = false;
      let parsedNonDirective = false;

      while (!this.match(end)) {
        if (!parsedNonDirective && this.state.octalPositions.length) {
          octalPositions.push(...this.state.octalPositions);
        }

        const stmt = this.parseStatement(null, topLevel);

        if (directives && !parsedNonDirective && this.isValidDirective(stmt)) {
          const directive = this.stmtToDirective(stmt);
          directives.push(directive);

          if (!hasStrictModeDirective && directive.value.value === "use strict") {
            hasStrictModeDirective = true;
            this.setStrict(true);
          }

          continue;
        }

        parsedNonDirective = true;
        body.push(stmt);
      }

      if (this.state.strict && octalPositions.length) {
        for (let _i3 = 0; _i3 < octalPositions.length; _i3++) {
          const pos = octalPositions[_i3];
          this.raise(pos, ErrorMessages.StrictOctalLiteral);
        }
      }

      if (afterBlockParse) {
        afterBlockParse.call(this, hasStrictModeDirective);
      }

      if (!oldStrict) {
        this.setStrict(false);
      }

      this.next();
    }

    parseFor(node, init) {
      node.init = init;
      this.expect(types.semi);
      node.test = this.match(types.semi) ? null : this.parseExpression();
      this.expect(types.semi);
      node.update = this.match(types.parenR) ? null : this.parseExpression();
      this.expect(types.parenR);
      node.body = this.withTopicForbiddingContext(() => this.parseStatement("for"));
      this.scope.exit();
      this.state.labels.pop();
      return this.finishNode(node, "ForStatement");
    }

    parseForIn(node, init, awaitAt) {
      const isForIn = this.match(types._in);
      this.next();

      if (isForIn) {
        if (awaitAt > -1) this.unexpected(awaitAt);
      } else {
        node.await = awaitAt > -1;
      }

      if (init.type === "VariableDeclaration" && init.declarations[0].init != null && (!isForIn || this.state.strict || init.kind !== "var" || init.declarations[0].id.type !== "Identifier")) {
        this.raise(init.start, ErrorMessages.ForInOfLoopInitializer, isForIn ? "for-in" : "for-of");
      } else if (init.type === "AssignmentPattern") {
        this.raise(init.start, ErrorMessages.InvalidLhs, "for-loop");
      }

      node.left = init;
      node.right = isForIn ? this.parseExpression() : this.parseMaybeAssignAllowIn();
      this.expect(types.parenR);
      node.body = this.withTopicForbiddingContext(() => this.parseStatement("for"));
      this.scope.exit();
      this.state.labels.pop();
      return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement");
    }

    parseVar(node, isFor, kind) {
      const declarations = node.declarations = [];
      const isTypescript = this.hasPlugin("typescript");
      node.kind = kind;

      for (;;) {
        const decl = this.startNode();
        this.parseVarId(decl, kind);

        if (this.eat(types.eq)) {
          decl.init = isFor ? this.parseMaybeAssignDisallowIn() : this.parseMaybeAssignAllowIn();
        } else {
          if (kind === "const" && !(this.match(types._in) || this.isContextual("of"))) {
            if (!isTypescript) {
              this.unexpected();
            }
          } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(types._in) || this.isContextual("of")))) {
            this.raise(this.state.lastTokEnd, ErrorMessages.DeclarationMissingInitializer, "Complex binding patterns");
          }

          decl.init = null;
        }

        declarations.push(this.finishNode(decl, "VariableDeclarator"));
        if (!this.eat(types.comma)) break;
      }

      return node;
    }

    parseVarId(decl, kind) {
      decl.id = this.parseBindingAtom();
      this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, undefined, "variable declaration", kind !== "var");
    }

    parseFunction(node, statement = FUNC_NO_FLAGS, isAsync = false) {
      const isStatement = statement & FUNC_STATEMENT;
      const isHangingStatement = statement & FUNC_HANGING_STATEMENT;
      const requireId = !!isStatement && !(statement & FUNC_NULLABLE_ID);
      this.initFunction(node, isAsync);

      if (this.match(types.star) && isHangingStatement) {
        this.raise(this.state.start, ErrorMessages.GeneratorInSingleStatementContext);
      }

      node.generator = this.eat(types.star);

      if (isStatement) {
        node.id = this.parseFunctionId(requireId);
      }

      const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
      const oldYieldPos = this.state.yieldPos;
      const oldAwaitPos = this.state.awaitPos;
      this.state.maybeInArrowParameters = false;
      this.state.yieldPos = -1;
      this.state.awaitPos = -1;
      this.scope.enter(SCOPE_FUNCTION);
      this.prodParam.enter(functionFlags(isAsync, node.generator));

      if (!isStatement) {
        node.id = this.parseFunctionId();
      }

      this.parseFunctionParams(node);
      this.withTopicForbiddingContext(() => {
        this.parseFunctionBodyAndFinish(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
      });
      this.prodParam.exit();
      this.scope.exit();

      if (isStatement && !isHangingStatement) {
        this.registerFunctionStatementId(node);
      }

      this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
      this.state.yieldPos = oldYieldPos;
      this.state.awaitPos = oldAwaitPos;
      return node;
    }

    parseFunctionId(requireId) {
      return requireId || this.match(types.name) ? this.parseIdentifier() : null;
    }

    parseFunctionParams(node, allowModifiers) {
      const oldInParameters = this.state.inParameters;
      this.state.inParameters = true;
      this.expect(types.parenL);
      node.params = this.parseBindingList(types.parenR, 41, false, allowModifiers);
      this.state.inParameters = oldInParameters;
      this.checkYieldAwaitInDefaultParams();
    }

    registerFunctionStatementId(node) {
      if (!node.id) return;
      this.scope.declareName(node.id.name, this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION, node.id.start);
    }

    parseClass(node, isStatement, optionalId) {
      this.next();
      this.takeDecorators(node);
      const oldStrict = this.state.strict;
      this.state.strict = true;
      this.parseClassId(node, isStatement, optionalId);
      this.parseClassSuper(node);
      node.body = this.parseClassBody(!!node.superClass, oldStrict);
      return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
    }

    isClassProperty() {
      return this.match(types.eq) || this.match(types.semi) || this.match(types.braceR);
    }

    isClassMethod() {
      return this.match(types.parenL);
    }

    isNonstaticConstructor(method) {
      return !method.computed && !method.static && (method.key.name === "constructor" || method.key.value === "constructor");
    }

    parseClassBody(constructorAllowsSuper, oldStrict) {
      this.classScope.enter();
      const state = {
        hadConstructor: false
      };
      let decorators = [];
      const classBody = this.startNode();
      classBody.body = [];
      this.expect(types.braceL);
      this.withTopicForbiddingContext(() => {
        while (!this.match(types.braceR)) {
          if (this.eat(types.semi)) {
            if (decorators.length > 0) {
              throw this.raise(this.state.lastTokEnd, ErrorMessages.DecoratorSemicolon);
            }

            continue;
          }

          if (this.match(types.at)) {
            decorators.push(this.parseDecorator());
            continue;
          }

          const member = this.startNode();

          if (decorators.length) {
            member.decorators = decorators;
            this.resetStartLocationFromNode(member, decorators[0]);
            decorators = [];
          }

          this.parseClassMember(classBody, member, state, constructorAllowsSuper);

          if (member.kind === "constructor" && member.decorators && member.decorators.length > 0) {
            this.raise(member.start, ErrorMessages.DecoratorConstructor);
          }
        }
      });
      this.state.strict = oldStrict;
      this.next();

      if (decorators.length) {
        throw this.raise(this.state.start, ErrorMessages.TrailingDecorator);
      }

      this.classScope.exit();
      return this.finishNode(classBody, "ClassBody");
    }

    parseClassMemberFromModifier(classBody, member) {
      const key = this.parseIdentifier(true);

      if (this.isClassMethod()) {
        const method = member;
        method.kind = "method";
        method.computed = false;
        method.key = key;
        method.static = false;
        this.pushClassMethod(classBody, method, false, false, false, false);
        return true;
      } else if (this.isClassProperty()) {
        const prop = member;
        prop.computed = false;
        prop.key = key;
        prop.static = false;
        classBody.body.push(this.parseClassProperty(prop));
        return true;
      }

      return false;
    }

    parseClassMember(classBody, member, state, constructorAllowsSuper) {
      const isStatic = this.isContextual("static");

      if (isStatic && this.parseClassMemberFromModifier(classBody, member)) {
        return;
      }

      this.parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper);
    }

    parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper) {
      const publicMethod = member;
      const privateMethod = member;
      const publicProp = member;
      const privateProp = member;
      const method = publicMethod;
      const publicMember = publicMethod;
      member.static = isStatic;

      if (this.eat(types.star)) {
        method.kind = "method";
        this.parseClassElementName(method);

        if (method.key.type === "PrivateName") {
          this.pushClassPrivateMethod(classBody, privateMethod, true, false);
          return;
        }

        if (this.isNonstaticConstructor(publicMethod)) {
          this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsGenerator);
        }

        this.pushClassMethod(classBody, publicMethod, true, false, false, false);
        return;
      }

      const containsEsc = this.state.containsEsc;
      const key = this.parseClassElementName(member);
      const isPrivate = key.type === "PrivateName";
      const isSimple = key.type === "Identifier";
      const maybeQuestionTokenStart = this.state.start;
      this.parsePostMemberNameModifiers(publicMember);

      if (this.isClassMethod()) {
        method.kind = "method";

        if (isPrivate) {
          this.pushClassPrivateMethod(classBody, privateMethod, false, false);
          return;
        }

        const isConstructor = this.isNonstaticConstructor(publicMethod);
        let allowsDirectSuper = false;

        if (isConstructor) {
          publicMethod.kind = "constructor";

          if (state.hadConstructor && !this.hasPlugin("typescript")) {
            this.raise(key.start, ErrorMessages.DuplicateConstructor);
          }

          state.hadConstructor = true;
          allowsDirectSuper = constructorAllowsSuper;
        }

        this.pushClassMethod(classBody, publicMethod, false, false, isConstructor, allowsDirectSuper);
      } else if (this.isClassProperty()) {
        if (isPrivate) {
          this.pushClassPrivateProperty(classBody, privateProp);
        } else {
          this.pushClassProperty(classBody, publicProp);
        }
      } else if (isSimple && key.name === "async" && !containsEsc && !this.isLineTerminator()) {
        const isGenerator = this.eat(types.star);

        if (publicMember.optional) {
          this.unexpected(maybeQuestionTokenStart);
        }

        method.kind = "method";
        this.parseClassElementName(method);
        this.parsePostMemberNameModifiers(publicMember);

        if (method.key.type === "PrivateName") {
          this.pushClassPrivateMethod(classBody, privateMethod, isGenerator, true);
        } else {
          if (this.isNonstaticConstructor(publicMethod)) {
            this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsAsync);
          }

          this.pushClassMethod(classBody, publicMethod, isGenerator, true, false, false);
        }
      } else if (isSimple && (key.name === "get" || key.name === "set") && !containsEsc && !(this.match(types.star) && this.isLineTerminator())) {
        method.kind = key.name;
        this.parseClassElementName(publicMethod);

        if (method.key.type === "PrivateName") {
          this.pushClassPrivateMethod(classBody, privateMethod, false, false);
        } else {
          if (this.isNonstaticConstructor(publicMethod)) {
            this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsAccessor);
          }

          this.pushClassMethod(classBody, publicMethod, false, false, false, false);
        }

        this.checkGetterSetterParams(publicMethod);
      } else if (this.isLineTerminator()) {
        if (isPrivate) {
          this.pushClassPrivateProperty(classBody, privateProp);
        } else {
          this.pushClassProperty(classBody, publicProp);
        }
      } else {
        this.unexpected();
      }
    }

    parseClassElementName(member) {
      const key = this.parsePropertyName(member, true);

      if (!member.computed && member.static && (key.name === "prototype" || key.value === "prototype")) {
        this.raise(key.start, ErrorMessages.StaticPrototype);
      }

      if (key.type === "PrivateName" && key.id.name === "constructor") {
        this.raise(key.start, ErrorMessages.ConstructorClassPrivateField);
      }

      return key;
    }

    pushClassProperty(classBody, prop) {
      if (!prop.computed && (prop.key.name === "constructor" || prop.key.value === "constructor")) {
        this.raise(prop.key.start, ErrorMessages.ConstructorClassField);
      }

      classBody.body.push(this.parseClassProperty(prop));
    }

    pushClassPrivateProperty(classBody, prop) {
      this.expectPlugin("classPrivateProperties", prop.key.start);
      const node = this.parseClassPrivateProperty(prop);
      classBody.body.push(node);
      this.classScope.declarePrivateName(node.key.id.name, CLASS_ELEMENT_OTHER, node.key.start);
    }

    pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
      classBody.body.push(this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true));
    }

    pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
      this.expectPlugin("classPrivateMethods", method.key.start);
      const node = this.parseMethod(method, isGenerator, isAsync, false, false, "ClassPrivateMethod", true);
      classBody.body.push(node);
      const kind = node.kind === "get" ? node.static ? CLASS_ELEMENT_STATIC_GETTER : CLASS_ELEMENT_INSTANCE_GETTER : node.kind === "set" ? node.static ? CLASS_ELEMENT_STATIC_SETTER : CLASS_ELEMENT_INSTANCE_SETTER : CLASS_ELEMENT_OTHER;
      this.classScope.declarePrivateName(node.key.id.name, kind, node.key.start);
    }

    parsePostMemberNameModifiers(methodOrProp) {}

    parseClassPrivateProperty(node) {
      this.scope.enter(SCOPE_CLASS | SCOPE_SUPER);
      this.prodParam.enter(PARAM);
      node.value = this.eat(types.eq) ? this.parseMaybeAssignAllowIn() : null;
      this.semicolon();
      this.prodParam.exit();
      this.scope.exit();
      return this.finishNode(node, "ClassPrivateProperty");
    }

    parseClassProperty(node) {
      if (!node.typeAnnotation) {
        this.expectPlugin("classProperties");
      }

      this.scope.enter(SCOPE_CLASS | SCOPE_SUPER);
      this.prodParam.enter(PARAM);

      if (this.match(types.eq)) {
        this.expectPlugin("classProperties");
        this.next();
        node.value = this.parseMaybeAssignAllowIn();
      } else {
        node.value = null;
      }

      this.semicolon();
      this.prodParam.exit();
      this.scope.exit();
      return this.finishNode(node, "ClassProperty");
    }

    parseClassId(node, isStatement, optionalId, bindingType = BIND_CLASS) {
      if (this.match(types.name)) {
        node.id = this.parseIdentifier();

        if (isStatement) {
          this.checkLVal(node.id, bindingType, undefined, "class name");
        }
      } else {
        if (optionalId || !isStatement) {
          node.id = null;
        } else {
          this.unexpected(null, ErrorMessages.MissingClassName);
        }
      }
    }

    parseClassSuper(node) {
      node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
    }

    parseExport(node) {
      const hasDefault = this.maybeParseExportDefaultSpecifier(node);
      const parseAfterDefault = !hasDefault || this.eat(types.comma);
      const hasStar = parseAfterDefault && this.eatExportStar(node);
      const hasNamespace = hasStar && this.maybeParseExportNamespaceSpecifier(node);
      const parseAfterNamespace = parseAfterDefault && (!hasNamespace || this.eat(types.comma));
      const isFromRequired = hasDefault || hasStar;

      if (hasStar && !hasNamespace) {
        if (hasDefault) this.unexpected();
        this.parseExportFrom(node, true);
        return this.finishNode(node, "ExportAllDeclaration");
      }

      const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node);

      if (hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers || hasNamespace && parseAfterNamespace && !hasSpecifiers) {
        throw this.unexpected(null, types.braceL);
      }

      let hasDeclaration;

      if (isFromRequired || hasSpecifiers) {
        hasDeclaration = false;
        this.parseExportFrom(node, isFromRequired);
      } else {
        hasDeclaration = this.maybeParseExportDeclaration(node);
      }

      if (isFromRequired || hasSpecifiers || hasDeclaration) {
        this.checkExport(node, true, false, !!node.source);
        return this.finishNode(node, "ExportNamedDeclaration");
      }

      if (this.eat(types._default)) {
        node.declaration = this.parseExportDefaultExpression();
        this.checkExport(node, true, true);
        return this.finishNode(node, "ExportDefaultDeclaration");
      }

      throw this.unexpected(null, types.braceL);
    }

    eatExportStar(node) {
      return this.eat(types.star);
    }

    maybeParseExportDefaultSpecifier(node) {
      if (this.isExportDefaultSpecifier()) {
        this.expectPlugin("exportDefaultFrom");
        const specifier = this.startNode();
        specifier.exported = this.parseIdentifier(true);
        node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
        return true;
      }

      return false;
    }

    maybeParseExportNamespaceSpecifier(node) {
      if (this.isContextual("as")) {
        if (!node.specifiers) node.specifiers = [];
        const specifier = this.startNodeAt(this.state.lastTokStart, this.state.lastTokStartLoc);
        this.next();
        specifier.exported = this.parseIdentifier(true);
        node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier"));
        return true;
      }

      return false;
    }

    maybeParseExportNamedSpecifiers(node) {
      if (this.match(types.braceL)) {
        if (!node.specifiers) node.specifiers = [];
        node.specifiers.push(...this.parseExportSpecifiers());
        node.source = null;
        node.declaration = null;
        return true;
      }

      return false;
    }

    maybeParseExportDeclaration(node) {
      if (this.shouldParseExportDeclaration()) {
        node.specifiers = [];
        node.source = null;
        node.declaration = this.parseExportDeclaration(node);
        return true;
      }

      return false;
    }

    isAsyncFunction() {
      if (!this.isContextual("async")) return false;
      const next = this.nextTokenStart();
      return !lineBreak.test(this.input.slice(this.state.pos, next)) && this.isUnparsedContextual(next, "function");
    }

    parseExportDefaultExpression() {
      const expr = this.startNode();
      const isAsync = this.isAsyncFunction();

      if (this.match(types._function) || isAsync) {
        this.next();

        if (isAsync) {
          this.next();
        }

        return this.parseFunction(expr, FUNC_STATEMENT | FUNC_NULLABLE_ID, isAsync);
      } else if (this.match(types._class)) {
        return this.parseClass(expr, true, true);
      } else if (this.match(types.at)) {
        if (this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport")) {
          this.raise(this.state.start, ErrorMessages.DecoratorBeforeExport);
        }

        this.parseDecorators(false);
        return this.parseClass(expr, true, true);
      } else if (this.match(types._const) || this.match(types._var) || this.isLet()) {
        throw this.raise(this.state.start, ErrorMessages.UnsupportedDefaultExport);
      } else {
        const res = this.parseMaybeAssignAllowIn();
        this.semicolon();
        return res;
      }
    }

    parseExportDeclaration(node) {
      return this.parseStatement(null);
    }

    isExportDefaultSpecifier() {
      if (this.match(types.name)) {
        const value = this.state.value;

        if (value === "async" && !this.state.containsEsc || value === "let") {
          return false;
        }

        if ((value === "type" || value === "interface") && !this.state.containsEsc) {
          const l = this.lookahead();

          if (l.type === types.name && l.value !== "from" || l.type === types.braceL) {
            this.expectOnePlugin(["flow", "typescript"]);
            return false;
          }
        }
      } else if (!this.match(types._default)) {
        return false;
      }

      const next = this.nextTokenStart();
      const hasFrom = this.isUnparsedContextual(next, "from");

      if (this.input.charCodeAt(next) === 44 || this.match(types.name) && hasFrom) {
        return true;
      }

      if (this.match(types._default) && hasFrom) {
        const nextAfterFrom = this.input.charCodeAt(this.nextTokenStartSince(next + 4));
        return nextAfterFrom === 34 || nextAfterFrom === 39;
      }

      return false;
    }

    parseExportFrom(node, expect) {
      if (this.eatContextual("from")) {
        node.source = this.parseImportSource();
        this.checkExport(node);
      } else {
        if (expect) {
          this.unexpected();
        } else {
          node.source = null;
        }
      }

      this.semicolon();
    }

    shouldParseExportDeclaration() {
      if (this.match(types.at)) {
        this.expectOnePlugin(["decorators", "decorators-legacy"]);

        if (this.hasPlugin("decorators")) {
          if (this.getPluginOption("decorators", "decoratorsBeforeExport")) {
            this.unexpected(this.state.start, ErrorMessages.DecoratorBeforeExport);
          } else {
            return true;
          }
        }
      }

      return this.state.type.keyword === "var" || this.state.type.keyword === "const" || this.state.type.keyword === "function" || this.state.type.keyword === "class" || this.isLet() || this.isAsyncFunction();
    }

    checkExport(node, checkNames, isDefault, isFrom) {
      if (checkNames) {
        if (isDefault) {
          this.checkDuplicateExports(node, "default");

          if (this.hasPlugin("exportDefaultFrom")) {
            var _declaration$extra;

            const declaration = node.declaration;

            if (declaration.type === "Identifier" && declaration.name === "from" && declaration.end - declaration.start === 4 && !((_declaration$extra = declaration.extra) == null ? void 0 : _declaration$extra.parenthesized)) {
              this.raise(declaration.start, ErrorMessages.ExportDefaultFromAsIdentifier);
            }
          }
        } else if (node.specifiers && node.specifiers.length) {
          for (let _i4 = 0, _node$specifiers = node.specifiers; _i4 < _node$specifiers.length; _i4++) {
            const specifier = _node$specifiers[_i4];
            this.checkDuplicateExports(specifier, specifier.exported.name);

            if (!isFrom && specifier.local) {
              this.checkReservedWord(specifier.local.name, specifier.local.start, true, false);
              this.scope.checkLocalExport(specifier.local);
            }
          }
        } else if (node.declaration) {
          if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
            const id = node.declaration.id;
            if (!id) throw new Error("Assertion failure");
            this.checkDuplicateExports(node, id.name);
          } else if (node.declaration.type === "VariableDeclaration") {
            for (let _i5 = 0, _node$declaration$dec = node.declaration.declarations; _i5 < _node$declaration$dec.length; _i5++) {
              const declaration = _node$declaration$dec[_i5];
              this.checkDeclaration(declaration.id);
            }
          }
        }
      }

      const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1];

      if (currentContextDecorators.length) {
        throw this.raise(node.start, ErrorMessages.UnsupportedDecoratorExport);
      }
    }

    checkDeclaration(node) {
      if (node.type === "Identifier") {
        this.checkDuplicateExports(node, node.name);
      } else if (node.type === "ObjectPattern") {
        for (let _i6 = 0, _node$properties = node.properties; _i6 < _node$properties.length; _i6++) {
          const prop = _node$properties[_i6];
          this.checkDeclaration(prop);
        }
      } else if (node.type === "ArrayPattern") {
        for (let _i7 = 0, _node$elements = node.elements; _i7 < _node$elements.length; _i7++) {
          const elem = _node$elements[_i7];

          if (elem) {
            this.checkDeclaration(elem);
          }
        }
      } else if (node.type === "ObjectProperty") {
        this.checkDeclaration(node.value);
      } else if (node.type === "RestElement") {
        this.checkDeclaration(node.argument);
      } else if (node.type === "AssignmentPattern") {
        this.checkDeclaration(node.left);
      }
    }

    checkDuplicateExports(node, name) {
      if (this.state.exportedIdentifiers.indexOf(name) > -1) {
        this.raise(node.start, name === "default" ? ErrorMessages.DuplicateDefaultExport : ErrorMessages.DuplicateExport, name);
      }

      this.state.exportedIdentifiers.push(name);
    }

    parseExportSpecifiers() {
      const nodes = [];
      let first = true;
      this.expect(types.braceL);

      while (!this.eat(types.braceR)) {
        if (first) {
          first = false;
        } else {
          this.expect(types.comma);
          if (this.eat(types.braceR)) break;
        }

        const node = this.startNode();
        node.local = this.parseIdentifier(true);
        node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone();
        nodes.push(this.finishNode(node, "ExportSpecifier"));
      }

      return nodes;
    }

    parseImport(node) {
      node.specifiers = [];

      if (!this.match(types.string)) {
        const hasDefault = this.maybeParseDefaultImportSpecifier(node);
        const parseNext = !hasDefault || this.eat(types.comma);
        const hasStar = parseNext && this.maybeParseStarImportSpecifier(node);
        if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node);
        this.expectContextual("from");
      }

      node.source = this.parseImportSource();
      const attributes = this.maybeParseModuleAttributes();

      if (attributes) {
        node.attributes = attributes;
      }

      this.semicolon();
      return this.finishNode(node, "ImportDeclaration");
    }

    parseImportSource() {
      if (!this.match(types.string)) this.unexpected();
      return this.parseExprAtom();
    }

    shouldParseDefaultImport(node) {
      return this.match(types.name);
    }

    parseImportSpecifierLocal(node, specifier, type, contextDescription) {
      specifier.local = this.parseIdentifier();
      this.checkLVal(specifier.local, BIND_LEXICAL, undefined, contextDescription);
      node.specifiers.push(this.finishNode(specifier, type));
    }

    maybeParseModuleAttributes() {
      if (this.match(types._with) && !this.hasPrecedingLineBreak()) {
        this.expectPlugin("moduleAttributes");
        this.next();
      } else {
        if (this.hasPlugin("moduleAttributes")) return [];
        return null;
      }

      const attrs = [];
      const attributes = new Set();

      do {
        const node = this.startNode();
        node.key = this.parseIdentifier(true);

        if (node.key.name !== "type") {
          this.raise(node.key.start, ErrorMessages.ModuleAttributeDifferentFromType, node.key.name);
        }

        if (attributes.has(node.key.name)) {
          this.raise(node.key.start, ErrorMessages.ModuleAttributesWithDuplicateKeys, node.key.name);
        }

        attributes.add(node.key.name);
        this.expect(types.colon);

        if (!this.match(types.string)) {
          throw this.unexpected(this.state.start, ErrorMessages.ModuleAttributeInvalidValue);
        }

        node.value = this.parseLiteral(this.state.value, "StringLiteral");
        this.finishNode(node, "ImportAttribute");
        attrs.push(node);
      } while (this.eat(types.comma));

      return attrs;
    }

    maybeParseDefaultImportSpecifier(node) {
      if (this.shouldParseDefaultImport(node)) {
        this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier", "default import specifier");
        return true;
      }

      return false;
    }

    maybeParseStarImportSpecifier(node) {
      if (this.match(types.star)) {
        const specifier = this.startNode();
        this.next();
        this.expectContextual("as");
        this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier", "import namespace specifier");
        return true;
      }

      return false;
    }

    parseNamedImportSpecifiers(node) {
      let first = true;
      this.expect(types.braceL);

      while (!this.eat(types.braceR)) {
        if (first) {
          first = false;
        } else {
          if (this.eat(types.colon)) {
            throw this.raise(this.state.start, ErrorMessages.DestructureNamedImport);
          }

          this.expect(types.comma);
          if (this.eat(types.braceR)) break;
        }

        this.parseImportSpecifier(node);
      }
    }

    parseImportSpecifier(node) {
      const specifier = this.startNode();
      specifier.imported = this.parseIdentifier(true);

      if (this.eatContextual("as")) {
        specifier.local = this.parseIdentifier();
      } else {
        this.checkReservedWord(specifier.imported.name, specifier.start, true, true);
        specifier.local = specifier.imported.__clone();
      }

      this.checkLVal(specifier.local, BIND_LEXICAL, undefined, "import specifier");
      node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
    }

  }

  class ClassScope {
    constructor() {
      this.privateNames = new Set();
      this.loneAccessors = new Map();
      this.undefinedPrivateNames = new Map();
    }

  }
  class ClassScopeHandler {
    constructor(raise) {
      this.stack = [];
      this.undefinedPrivateNames = new Map();
      this.raise = raise;
    }

    current() {
      return this.stack[this.stack.length - 1];
    }

    enter() {
      this.stack.push(new ClassScope());
    }

    exit() {
      const oldClassScope = this.stack.pop();
      const current = this.current();

      for (let _i = 0, _Array$from = Array.from(oldClassScope.undefinedPrivateNames); _i < _Array$from.length; _i++) {
        const [name, pos] = _Array$from[_i];

        if (current) {
          if (!current.undefinedPrivateNames.has(name)) {
            current.undefinedPrivateNames.set(name, pos);
          }
        } else {
          this.raise(pos, ErrorMessages.InvalidPrivateFieldResolution, name);
        }
      }
    }

    declarePrivateName(name, elementType, pos) {
      const classScope = this.current();
      let redefined = classScope.privateNames.has(name);

      if (elementType & CLASS_ELEMENT_KIND_ACCESSOR) {
        const accessor = redefined && classScope.loneAccessors.get(name);

        if (accessor) {
          const oldStatic = accessor & CLASS_ELEMENT_FLAG_STATIC;
          const newStatic = elementType & CLASS_ELEMENT_FLAG_STATIC;
          const oldKind = accessor & CLASS_ELEMENT_KIND_ACCESSOR;
          const newKind = elementType & CLASS_ELEMENT_KIND_ACCESSOR;
          redefined = oldKind === newKind || oldStatic !== newStatic;
          if (!redefined) classScope.loneAccessors.delete(name);
        } else if (!redefined) {
          classScope.loneAccessors.set(name, elementType);
        }
      }

      if (redefined) {
        this.raise(pos, ErrorMessages.PrivateNameRedeclaration, name);
      }

      classScope.privateNames.add(name);
      classScope.undefinedPrivateNames.delete(name);
    }

    usePrivateName(name, pos) {
      let classScope;

      for (let _i2 = 0, _this$stack = this.stack; _i2 < _this$stack.length; _i2++) {
        classScope = _this$stack[_i2];
        if (classScope.privateNames.has(name)) return;
      }

      if (classScope) {
        classScope.undefinedPrivateNames.set(name, pos);
      } else {
        this.raise(pos, ErrorMessages.InvalidPrivateFieldResolution, name);
      }
    }

  }

  class Parser extends StatementParser {
    constructor(options, input) {
      options = getOptions(options);
      super(options, input);
      const ScopeHandler = this.getScopeHandler();
      this.options = options;
      this.inModule = this.options.sourceType === "module";
      this.scope = new ScopeHandler(this.raise.bind(this), this.inModule);
      this.prodParam = new ProductionParameterHandler();
      this.classScope = new ClassScopeHandler(this.raise.bind(this));
      this.plugins = pluginsMap(this.options.plugins);
      this.filename = options.sourceFilename;
    }

    getScopeHandler() {
      return ScopeHandler;
    }

    parse() {
      let paramFlags = PARAM;

      if (this.hasPlugin("topLevelAwait") && this.inModule) {
        paramFlags |= PARAM_AWAIT;
      }

      this.scope.enter(SCOPE_PROGRAM);
      this.prodParam.enter(paramFlags);
      const file = this.startNode();
      const program = this.startNode();
      this.nextToken();
      file.errors = null;
      this.parseTopLevel(file, program);
      file.errors = this.state.errors;
      return file;
    }

  }

  function pluginsMap(plugins) {
    const pluginMap = new Map();

    for (let _i = 0; _i < plugins.length; _i++) {
      const plugin = plugins[_i];
      const [name, options] = Array.isArray(plugin) ? plugin : [plugin, {}];
      if (!pluginMap.has(name)) pluginMap.set(name, options || {});
    }

    return pluginMap;
  }

  function parse(input, options) {
    var _options;

    if (((_options = options) == null ? void 0 : _options.sourceType) === "unambiguous") {
      options = Object.assign({}, options);

      try {
        options.sourceType = "module";
        const parser = getParser(options, input);
        const ast = parser.parse();

        if (parser.sawUnambiguousESM) {
          return ast;
        }

        if (parser.ambiguousScriptDifferentAst) {
          try {
            options.sourceType = "script";
            return getParser(options, input).parse();
          } catch (_unused) {}
        } else {
          ast.program.sourceType = "script";
        }

        return ast;
      } catch (moduleError) {
        try {
          options.sourceType = "script";
          return getParser(options, input).parse();
        } catch (_unused2) {}

        throw moduleError;
      }
    } else {
      return getParser(options, input).parse();
    }
  }
  function parseExpression(input, options) {
    const parser = getParser(options, input);

    if (parser.options.strictMode) {
      parser.state.strict = true;
    }

    return parser.getExpression();
  }

  function getParser(options, input) {
    let cls = Parser;

    if (options == null ? void 0 : options.plugins) {
      validatePlugins(options.plugins);
      cls = getParserClass(options.plugins);
    }

    return new cls(options, input);
  }

  const parserClassCache = {};

  function getParserClass(pluginsFromOptions) {
    const pluginList = mixinPluginNames.filter(name => hasPlugin(pluginsFromOptions, name));
    const key = pluginList.join("/");
    let cls = parserClassCache[key];

    if (!cls) {
      cls = Parser;

      for (let _i = 0; _i < pluginList.length; _i++) {
        const plugin = pluginList[_i];
        cls = mixinPlugins[plugin](cls);
      }

      parserClassCache[key] = cls;
    }

    return cls;
  }

  exports.parse = parse;
  exports.parseExpression = parseExpression;
  exports.tokTypes = types;

  });

  class WalkerBase {constructor() { WalkerBase.prototype.__init.call(this);WalkerBase.prototype.__init2.call(this);WalkerBase.prototype.__init3.call(this);WalkerBase.prototype.__init4.call(this); }
  	 __init() {this.should_skip = false;}
  	 __init2() {this.should_remove = false;}
  	 __init3() {this.replacement = null;}

  	 __init4() {this.context = {
  		skip: () => (this.should_skip = true),
  		remove: () => (this.should_remove = true),
  		replace: (node) => (this.replacement = node)
  	};}

  	 replace(parent, prop, index, node) {
  		if (parent) {
  			if (index !== null) {
  				parent[prop][index] = node;
  			} else {
  				parent[prop] = node;
  			}
  		}
  	}

  	 remove(parent, prop, index) {
  		if (parent) {
  			if (index !== null) {
  				parent[prop].splice(index, 1);
  			} else {
  				delete parent[prop];
  			}
  		}
  	}
  }

  class SyncWalkerClass extends WalkerBase {
  	
  	

  	constructor(walker) {
  		super();
  		this.enter = walker.enter;
  		this.leave = walker.leave;
  	}

  	 visit(
  		node,
  		parent,
  		enter,
  		leave,
  		prop,
  		index
  	) {
  		if (node) {
  			if (enter) {
  				const _should_skip = this.should_skip;
  				const _should_remove = this.should_remove;
  				const _replacement = this.replacement;
  				this.should_skip = false;
  				this.should_remove = false;
  				this.replacement = null;

  				enter.call(this.context, node, parent, prop, index);

  				if (this.replacement) {
  					node = this.replacement;
  					this.replace(parent, prop, index, node);
  				}

  				if (this.should_remove) {
  					this.remove(parent, prop, index);
  				}

  				const skipped = this.should_skip;
  				const removed = this.should_remove;

  				this.should_skip = _should_skip;
  				this.should_remove = _should_remove;
  				this.replacement = _replacement;

  				if (skipped) return node;
  				if (removed) return null;
  			}

  			for (const key in node) {
  				const value = (node )[key];

  				if (typeof value !== "object") {
  					continue;
  				} else if (Array.isArray(value)) {
  					for (let i = 0; i < value.length; i += 1) {
  						if (value[i] !== null && typeof value[i].type === 'string') {
  							if (!this.visit(value[i], node, enter, leave, key, i)) {
  								// removed
  								i--;
  							}
  						}
  					}
  				} else if (value !== null && typeof value.type === "string") {
  					this.visit(value, node, enter, leave, key, null);
  				}
  			}

  			if (leave) {
  				const _replacement = this.replacement;
  				const _should_remove = this.should_remove;
  				this.replacement = null;
  				this.should_remove = false;

  				leave.call(this.context, node, parent, prop, index);

  				if (this.replacement) {
  					node = this.replacement;
  					this.replace(parent, prop, index, node);
  				}

  				if (this.should_remove) {
  					this.remove(parent, prop, index);
  				}

  				const removed = this.should_remove;

  				this.replacement = _replacement;
  				this.should_remove = _should_remove;

  				if (removed) return null;
  			}
  		}

  		return node;
  	}
  }

  function walk$1(ast, walker) {
  	const instance = new SyncWalkerClass(walker);
  	return instance.visit(ast, null, walker.enter, walker.leave);
  }

  const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this');
  const transformExpression = (node, context) => {
      if (node.type === 5 /* INTERPOLATION */) {
          node.content = processExpression(node.content, context);
      }
      else if (node.type === 1 /* ELEMENT */) {
          // handle directives on element
          for (let i = 0; i < node.props.length; i++) {
              const dir = node.props[i];
              // do not process for v-on & v-for since they are special handled
              if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
                  const exp = dir.exp;
                  const arg = dir.arg;
                  // do not process exp if this is v-on:arg - we need special handling
                  // for wrapping inline statements.
                  if (exp &&
                      exp.type === 4 /* SIMPLE_EXPRESSION */ &&
                      !(dir.name === 'on' && arg)) {
                      dir.exp = processExpression(exp, context, 
                      // slot args must be processed as function params
                      dir.name === 'slot');
                  }
                  if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
                      dir.arg = processExpression(arg, context);
                  }
              }
          }
      }
  };
  // Important: since this function uses Node.js only dependencies, it should
  // always be used with a leading !false check so that it can be
  // tree-shaken from the browser build.
  function processExpression(node, context, 
  // some expressions like v-slot props & v-for aliases should be parsed as
  // function params
  asParams = false, 
  // v-on handler values may contain multiple statements
  asRawStatements = false) {
      if (!context.prefixIdentifiers || !node.content.trim()) {
          return node;
      }
      const { bindingMetadata } = context;
      const prefix = (raw) => {
          const source = hasOwn(bindingMetadata, raw)
              ? `$` + bindingMetadata[raw]
              : `_ctx`;
          return `${source}.${raw}`;
      };
      // fast path if expression is a simple identifier.
      const rawExp = node.content;
      // bail on parens to prevent any possible function invocations.
      const bailConstant = rawExp.indexOf(`(`) > -1;
      if (isSimpleIdentifier(rawExp)) {
          if (!asParams &&
              !context.identifiers[rawExp] &&
              !isGloballyWhitelisted(rawExp) &&
              !isLiteralWhitelisted(rawExp)) {
              node.content = prefix(rawExp);
          }
          else if (!context.identifiers[rawExp] && !bailConstant) {
              // mark node constant for hoisting unless it's referring a scope variable
              node.isConstant = true;
          }
          return node;
      }
      let ast;
      // exp needs to be parsed differently:
      // 1. Multiple inline statements (v-on, with presence of `;`): parse as raw
      //    exp, but make sure to pad with spaces for consistent ranges
      // 2. Expressions: wrap with parens (for e.g. object expressions)
      // 3. Function arguments (v-for, v-slot): place in a function argument position
      const source = asRawStatements
          ? ` ${rawExp} `
          : `(${rawExp})${asParams ? `=>{}` : ``}`;
      try {
          ast = lib.parse(source, {
              plugins: [...context.expressionPlugins, ...babelParserDefaultPlugins]
          }).program;
      }
      catch (e) {
          context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, e.message));
          return node;
      }
      const ids = [];
      const knownIds = Object.create(context.identifiers);
      const isDuplicate = (node) => ids.some(id => id.start === node.start);
      walk$1(ast, {
          enter(node, parent) {
              if (node.type === 'Identifier') {
                  if (!isDuplicate(node)) {
                      const needPrefix = shouldPrefix(node, parent);
                      if (!knownIds[node.name] && needPrefix) {
                          if (isPropertyShorthand(node, parent)) {
                              // property shorthand like { foo }, we need to add the key since we
                              // rewrite the value
                              node.prefix = `${node.name}: `;
                          }
                          node.name = prefix(node.name);
                          ids.push(node);
                      }
                      else if (!isStaticPropertyKey(node, parent)) {
                          // The identifier is considered constant unless it's pointing to a
                          // scope variable (a v-for alias, or a v-slot prop)
                          if (!(needPrefix && knownIds[node.name]) && !bailConstant) {
                              node.isConstant = true;
                          }
                          // also generate sub-expressions for other identifiers for better
                          // source map support. (except for property keys which are static)
                          ids.push(node);
                      }
                  }
              }
              else if (isFunction$1(node)) {
                  // walk function expressions and add its arguments to known identifiers
                  // so that we don't prefix them
                  node.params.forEach(p => walk$1(p, {
                      enter(child, parent) {
                          if (child.type === 'Identifier' &&
                              // do not record as scope variable if is a destructured key
                              !isStaticPropertyKey(child, parent) &&
                              // do not record if this is a default value
                              // assignment of a destructured variable
                              !(parent &&
                                  parent.type === 'AssignmentPattern' &&
                                  parent.right === child)) {
                              const { name } = child;
                              if (node.scopeIds && node.scopeIds.has(name)) {
                                  return;
                              }
                              if (name in knownIds) {
                                  knownIds[name]++;
                              }
                              else {
                                  knownIds[name] = 1;
                              }
                              (node.scopeIds || (node.scopeIds = new Set())).add(name);
                          }
                      }
                  }));
              }
          },
          leave(node) {
              if (node !== ast.body[0].expression && node.scopeIds) {
                  node.scopeIds.forEach((id) => {
                      knownIds[id]--;
                      if (knownIds[id] === 0) {
                          delete knownIds[id];
                      }
                  });
              }
          }
      });
      // We break up the compound expression into an array of strings and sub
      // expressions (for identifiers that have been prefixed). In codegen, if
      // an ExpressionNode has the `.children` property, it will be used instead of
      // `.content`.
      const children = [];
      ids.sort((a, b) => a.start - b.start);
      ids.forEach((id, i) => {
          // range is offset by -1 due to the wrapping parens when parsed
          const start = id.start - 1;
          const end = id.end - 1;
          const last = ids[i - 1];
          const leadingText = rawExp.slice(last ? last.end - 1 : 0, start);
          if (leadingText.length || id.prefix) {
              children.push(leadingText + (id.prefix || ``));
          }
          const source = rawExp.slice(start, end);
          children.push(createSimpleExpression(id.name, false, {
              source,
              start: advancePositionWithClone(node.loc.start, source, start),
              end: advancePositionWithClone(node.loc.start, source, end)
          }, id.isConstant /* isConstant */));
          if (i === ids.length - 1 && end < rawExp.length) {
              children.push(rawExp.slice(end));
          }
      });
      let ret;
      if (children.length) {
          ret = createCompoundExpression(children, node.loc);
      }
      else {
          ret = node;
          ret.isConstant = !bailConstant;
      }
      ret.identifiers = Object.keys(knownIds);
      return ret;
  }
  const isFunction$1 = (node) => {
      return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
  };
  const isStaticProperty = (node) => node &&
      (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
      !node.computed;
  const isPropertyShorthand = (node, parent) => {
      return (isStaticProperty(parent) &&
          parent.value === node &&
          parent.key.type === 'Identifier' &&
          parent.key.name === node.name &&
          parent.key.start === node.start);
  };
  const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;
  function shouldPrefix(identifier, parent) {
      if (!(isFunction$1(parent) &&
          // not id of a FunctionDeclaration
          (parent.id === identifier ||
              // not a params of a function
              parent.params.includes(identifier))) &&
          // not a key of Property
          !isStaticPropertyKey(identifier, parent) &&
          // not a property of a MemberExpression
          !((parent.type === 'MemberExpression' ||
              parent.type === 'OptionalMemberExpression') &&
              parent.property === identifier &&
              !parent.computed) &&
          // not in an Array destructure pattern
          !(parent.type === 'ArrayPattern') &&
          // skip whitelisted globals
          !isGloballyWhitelisted(identifier.name) &&
          // special case for webpack compilation
          identifier.name !== `require` &&
          // is a special keyword but parsed as identifier
          identifier.name !== `arguments`) {
          return true;
      }
  }

  const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
      return processIf(node, dir, context, (ifNode, branch, isRoot) => {
          // #1587: We need to dynamically increment the key based on the current
          // node's sibling nodes, since chained v-if/else branches are
          // rendered at the same depth
          const siblings = context.parent.children;
          let i = siblings.indexOf(ifNode);
          let key = 0;
          while (i-- >= 0) {
              const sibling = siblings[i];
              if (sibling && sibling.type === 9 /* IF */) {
                  key += sibling.branches.length;
              }
          }
          // Exit callback. Complete the codegenNode when all children have been
          // transformed.
          return () => {
              if (isRoot) {
                  ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
              }
              else {
                  // attach this branch's codegen node to the v-if root.
                  let parentCondition = ifNode.codegenNode;
                  while (parentCondition.alternate.type ===
                      19 /* JS_CONDITIONAL_EXPRESSION */) {
                      parentCondition = parentCondition.alternate;
                  }
                  parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
              }
          };
      });
  });
  // target-agnostic transform used for both Client and SSR
  function processIf(node, dir, context, processCodegen) {
      if (dir.name !== 'else' &&
          (!dir.exp || !dir.exp.content.trim())) {
          const loc = dir.exp ? dir.exp.loc : node.loc;
          context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));
          dir.exp = createSimpleExpression(`true`, false, loc);
      }
      if ( context.prefixIdentifiers && dir.exp) {
          // dir.exp can only be simple expression because vIf transform is applied
          // before expression transform.
          dir.exp = processExpression(dir.exp, context);
      }
      if (dir.name === 'if') {
          const branch = createIfBranch(node, dir);
          const ifNode = {
              type: 9 /* IF */,
              loc: node.loc,
              branches: [branch]
          };
          context.replaceNode(ifNode);
          if (processCodegen) {
              return processCodegen(ifNode, branch, true);
          }
      }
      else {
          // locate the adjacent v-if
          const siblings = context.parent.children;
          const comments = [];
          let i = siblings.indexOf(node);
          while (i-- >= -1) {
              const sibling = siblings[i];
              if ( sibling && sibling.type === 3 /* COMMENT */) {
                  context.removeNode(sibling);
                  comments.unshift(sibling);
                  continue;
              }
              if (sibling && sibling.type === 9 /* IF */) {
                  // move the node to the if node's branches
                  context.removeNode();
                  const branch = createIfBranch(node, dir);
                  if ( comments.length) {
                      branch.children = [...comments, ...branch.children];
                  }
                  // check if user is forcing same key on different branches
                  {
                      const key = branch.userKey;
                      if (key) {
                          sibling.branches.forEach(({ userKey }) => {
                              if (isSameKey(userKey, key)) {
                                  context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
                              }
                          });
                      }
                  }
                  sibling.branches.push(branch);
                  const onExit = processCodegen && processCodegen(sibling, branch, false);
                  // since the branch was removed, it will not be traversed.
                  // make sure to traverse here.
                  traverseNode(branch, context);
                  // call on exit
                  if (onExit)
                      onExit();
                  // make sure to reset currentNode after traversal to indicate this
                  // node has been removed.
                  context.currentNode = null;
              }
              else {
                  context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
              }
              break;
          }
      }
  }
  function createIfBranch(node, dir) {
      return {
          type: 10 /* IF_BRANCH */,
          loc: node.loc,
          condition: dir.name === 'else' ? undefined : dir.exp,
          children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
              ? node.children
              : [node],
          userKey: findProp(node, `key`)
      };
  }
  function createCodegenNodeForBranch(branch, keyIndex, context) {
      if (branch.condition) {
          return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context), 
          // make sure to pass in asBlock: true so that the comment node call
          // closes the current block.
          createCallExpression(context.helper(CREATE_COMMENT), [
               '"v-if"' ,
              'true'
          ]));
      }
      else {
          return createChildrenCodegenNode(branch, keyIndex, context);
      }
  }
  function createChildrenCodegenNode(branch, keyIndex, context) {
      const { helper } = context;
      const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, true));
      const { children } = branch;
      const firstChild = children[0];
      const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
      if (needFragmentWrapper) {
          if (children.length === 1 && firstChild.type === 11 /* FOR */) {
              // optimize away nested fragments when child is a ForNode
              const vnodeCall = firstChild.codegenNode;
              injectProp(vnodeCall, keyProperty, context);
              return vnodeCall;
          }
          else {
              return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, `${64 /* STABLE_FRAGMENT */} /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`, undefined, undefined, true, false, branch.loc);
          }
      }
      else {
          const vnodeCall = firstChild
              .codegenNode;
          // Change createVNode to createBlock.
          if (vnodeCall.type === 13 /* VNODE_CALL */) {
              vnodeCall.isBlock = true;
              helper(OPEN_BLOCK);
              helper(CREATE_BLOCK);
          }
          // inject branch key
          injectProp(vnodeCall, keyProperty, context);
          return vnodeCall;
      }
  }
  function isSameKey(a, b) {
      if (!a || a.type !== b.type) {
          return false;
      }
      if (a.type === 6 /* ATTRIBUTE */) {
          if (a.value.content !== b.value.content) {
              return false;
          }
      }
      else {
          // directive
          const exp = a.exp;
          const branchExp = b.exp;
          if (exp.type !== branchExp.type) {
              return false;
          }
          if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
              (exp.isStatic !== branchExp.isStatic ||
                  exp.content !== branchExp.content)) {
              return false;
          }
      }
      return true;
  }

  const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
      const { helper } = context;
      return processFor(node, dir, context, forNode => {
          // create the loop render function expression now, and add the
          // iterator on exit after all children have been traversed
          const renderExp = createCallExpression(helper(RENDER_LIST), [
              forNode.source
          ]);
          const keyProp = findProp(node, `key`);
          const keyProperty = keyProp
              ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */
                  ? createSimpleExpression(keyProp.value.content, true)
                  : keyProp.exp)
              : null;
          if ( context.prefixIdentifiers && keyProperty) {
              // #2085 process :key expression needs to be processed in order for it
              // to behave consistently for <template v-for> and <div v-for>.
              // In the case of `<template v-for>`, the node is discarded and never
              // traversed so its key expression won't be processed by the normal
              // transforms.
              keyProperty.value = processExpression(keyProperty.value, context);
          }
          const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
              forNode.source.isConstant;
          const fragmentFlag = isStableFragment
              ? 64 /* STABLE_FRAGMENT */
              : keyProp
                  ? 128 /* KEYED_FRAGMENT */
                  : 256 /* UNKEYED_FRAGMENT */;
          forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, `${fragmentFlag} /* ${PatchFlagNames[fragmentFlag]} */`, undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);
          return () => {
              // finish the codegen now that all children have been traversed
              let childBlock;
              const isTemplate = isTemplateNode(node);
              const { children } = forNode;
              // check <template v-for> key placement
              if ( isTemplate) {
                  node.children.some(c => {
                      if (c.type === 1 /* ELEMENT */) {
                          const key = findProp(c, 'key');
                          if (key) {
                              context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
                              return true;
                          }
                      }
                  });
              }
              const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
              const slotOutlet = isSlotOutlet(node)
                  ? node
                  : isTemplate &&
                      node.children.length === 1 &&
                      isSlotOutlet(node.children[0])
                      ? node.children[0] // api-extractor somehow fails to infer this
                      : null;
              if (slotOutlet) {
                  // <slot v-for="..."> or <template v-for="..."><slot/></template>
                  childBlock = slotOutlet.codegenNode;
                  if (isTemplate && keyProperty) {
                      // <template v-for="..." :key="..."><slot/></template>
                      // we need to inject the key to the renderSlot() call.
                      // the props for renderSlot is passed as the 3rd argument.
                      injectProp(childBlock, keyProperty, context);
                  }
              }
              else if (needFragmentWrapper) {
                  // <template v-for="..."> with text or multi-elements
                  // should generate a fragment block for each loop
                  childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, `${64 /* STABLE_FRAGMENT */} /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`, undefined, undefined, true);
              }
              else {
                  // Normal element v-for. Directly use the child's codegenNode
                  // but mark it as a block.
                  childBlock = children[0]
                      .codegenNode;
                  if (isTemplate && keyProperty) {
                      injectProp(childBlock, keyProperty, context);
                  }
                  childBlock.isBlock = !isStableFragment;
                  if (childBlock.isBlock) {
                      helper(OPEN_BLOCK);
                      helper(CREATE_BLOCK);
                  }
              }
              renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
          };
      });
  });
  // target-agnostic transform used for both Client and SSR
  function processFor(node, dir, context, processCodegen) {
      if (!dir.exp) {
          context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
          return;
      }
      const parseResult = parseForExpression(
      // can only be simple expression because vFor transform is applied
      // before expression transform.
      dir.exp, context);
      if (!parseResult) {
          context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
          return;
      }
      const { addIdentifiers, removeIdentifiers, scopes } = context;
      const { source, value, key, index } = parseResult;
      const forNode = {
          type: 11 /* FOR */,
          loc: dir.loc,
          source,
          valueAlias: value,
          keyAlias: key,
          objectIndexAlias: index,
          parseResult,
          children: isTemplateNode(node) ? node.children : [node]
      };
      context.replaceNode(forNode);
      // bookkeeping
      scopes.vFor++;
      if ( context.prefixIdentifiers) {
          // scope management
          // inject identifiers to context
          value && addIdentifiers(value);
          key && addIdentifiers(key);
          index && addIdentifiers(index);
      }
      const onExit = processCodegen && processCodegen(forNode);
      return () => {
          scopes.vFor--;
          if ( context.prefixIdentifiers) {
              value && removeIdentifiers(value);
              key && removeIdentifiers(key);
              index && removeIdentifiers(index);
          }
          if (onExit)
              onExit();
      };
  }
  const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
  // This regex doesn't cover the case if key or index aliases have destructuring,
  // but those do not make sense in the first place, so this works in practice.
  const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
  const stripParensRE = /^\(|\)$/g;
  function parseForExpression(input, context) {
      const loc = input.loc;
      const exp = input.content;
      const inMatch = exp.match(forAliasRE);
      if (!inMatch)
          return;
      const [, LHS, RHS] = inMatch;
      const result = {
          source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
          value: undefined,
          key: undefined,
          index: undefined
      };
      if ( context.prefixIdentifiers) {
          result.source = processExpression(result.source, context);
      }
      let valueContent = LHS.trim()
          .replace(stripParensRE, '')
          .trim();
      const trimmedOffset = LHS.indexOf(valueContent);
      const iteratorMatch = valueContent.match(forIteratorRE);
      if (iteratorMatch) {
          valueContent = valueContent.replace(forIteratorRE, '').trim();
          const keyContent = iteratorMatch[1].trim();
          let keyOffset;
          if (keyContent) {
              keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
              result.key = createAliasExpression(loc, keyContent, keyOffset);
              if ( context.prefixIdentifiers) {
                  result.key = processExpression(result.key, context, true);
              }
          }
          if (iteratorMatch[2]) {
              const indexContent = iteratorMatch[2].trim();
              if (indexContent) {
                  result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
                      ? keyOffset + keyContent.length
                      : trimmedOffset + valueContent.length));
                  if ( context.prefixIdentifiers) {
                      result.index = processExpression(result.index, context, true);
                  }
              }
          }
      }
      if (valueContent) {
          result.value = createAliasExpression(loc, valueContent, trimmedOffset);
          if ( context.prefixIdentifiers) {
              result.value = processExpression(result.value, context, true);
          }
      }
      return result;
  }
  function createAliasExpression(range, content, offset) {
      return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
  }
  function createForLoopParams({ value, key, index }) {
      const params = [];
      if (value) {
          params.push(value);
      }
      if (key) {
          if (!value) {
              params.push(createSimpleExpression(`_`, false));
          }
          params.push(key);
      }
      if (index) {
          if (!key) {
              if (!value) {
                  params.push(createSimpleExpression(`_`, false));
              }
              params.push(createSimpleExpression(`__`, false));
          }
          params.push(index);
      }
      return params;
  }

  const defaultFallback = createSimpleExpression(`undefined`, false);
  // A NodeTransform that:
  // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
  //    by transformExpression. This is only applied in non-browser builds with
  //    { prefixIdentifiers: true }.
  // 2. Track v-slot depths so that we know a slot is inside another slot.
  //    Note the exit callback is executed before buildSlots() on the same node,
  //    so only nested slots see positive numbers.
  const trackSlotScopes = (node, context) => {
      if (node.type === 1 /* ELEMENT */ &&
          (node.tagType === 1 /* COMPONENT */ ||
              node.tagType === 3 /* TEMPLATE */)) {
          // We are only checking non-empty v-slot here
          // since we only care about slots that introduce scope variables.
          const vSlot = findDir(node, 'slot');
          if (vSlot) {
              const slotProps = vSlot.exp;
              if ( context.prefixIdentifiers) {
                  slotProps && context.addIdentifiers(slotProps);
              }
              context.scopes.vSlot++;
              return () => {
                  if ( context.prefixIdentifiers) {
                      slotProps && context.removeIdentifiers(slotProps);
                  }
                  context.scopes.vSlot--;
              };
          }
      }
  };
  // A NodeTransform that tracks scope identifiers for scoped slots with v-for.
  // This transform is only applied in non-browser builds with { prefixIdentifiers: true }
  const trackVForSlotScopes = (node, context) => {
      let vFor;
      if (isTemplateNode(node) &&
          node.props.some(isVSlot) &&
          (vFor = findDir(node, 'for'))) {
          const result = (vFor.parseResult = parseForExpression(vFor.exp, context));
          if (result) {
              const { value, key, index } = result;
              const { addIdentifiers, removeIdentifiers } = context;
              value && addIdentifiers(value);
              key && addIdentifiers(key);
              index && addIdentifiers(index);
              return () => {
                  value && removeIdentifiers(value);
                  key && removeIdentifiers(key);
                  index && removeIdentifiers(index);
              };
          }
      }
  };
  const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
  // Instead of being a DirectiveTransform, v-slot processing is called during
  // transformElement to build the slots object for a component.
  function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
      context.helper(WITH_CTX);
      const { children, loc } = node;
      const slotsProperties = [];
      const dynamicSlots = [];
      const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));
      // If the slot is inside a v-for or another v-slot, force it to be dynamic
      // since it likely uses a scope variable.
      let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
      // with `prefixIdentifiers: true`, this can be further optimized to make
      // it dynamic only when the slot actually uses the scope variables.
      if ( !context.ssr && context.prefixIdentifiers) {
          hasDynamicSlots = hasScopeRef(node, context.identifiers);
      }
      // 1. Check for slot with slotProps on component itself.
      //    <Comp v-slot="{ prop }"/>
      const onComponentSlot = findDir(node, 'slot', true);
      if (onComponentSlot) {
          const { arg, exp } = onComponentSlot;
          if (arg && !isStaticExp(arg)) {
              hasDynamicSlots = true;
          }
          slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
      }
      // 2. Iterate through children and check for template slots
      //    <template v-slot:foo="{ prop }">
      let hasTemplateSlots = false;
      let hasNamedDefaultSlot = false;
      const implicitDefaultChildren = [];
      const seenSlotNames = new Set();
      for (let i = 0; i < children.length; i++) {
          const slotElement = children[i];
          let slotDir;
          if (!isTemplateNode(slotElement) ||
              !(slotDir = findDir(slotElement, 'slot', true))) {
              // not a <template v-slot>, skip.
              if (slotElement.type !== 3 /* COMMENT */) {
                  implicitDefaultChildren.push(slotElement);
              }
              continue;
          }
          if (onComponentSlot) {
              // already has on-component slot - this is incorrect usage.
              context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
              break;
          }
          hasTemplateSlots = true;
          const { children: slotChildren, loc: slotLoc } = slotElement;
          const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
          // check if name is dynamic.
          let staticSlotName;
          if (isStaticExp(slotName)) {
              staticSlotName = slotName ? slotName.content : `default`;
          }
          else {
              hasDynamicSlots = true;
          }
          const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
          // check if this slot is conditional (v-if/v-for)
          let vIf;
          let vElse;
          let vFor;
          if ((vIf = findDir(slotElement, 'if'))) {
              hasDynamicSlots = true;
              dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
          }
          else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
              // find adjacent v-if
              let j = i;
              let prev;
              while (j--) {
                  prev = children[j];
                  if (prev.type !== 3 /* COMMENT */) {
                      break;
                  }
              }
              if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
                  // remove node
                  children.splice(i, 1);
                  i--;
                  // attach this slot to previous conditional
                  let conditional = dynamicSlots[dynamicSlots.length - 1];
                  while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
                      conditional = conditional.alternate;
                  }
                  conditional.alternate = vElse.exp
                      ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
                      : buildDynamicSlot(slotName, slotFunction);
              }
              else {
                  context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
              }
          }
          else if ((vFor = findDir(slotElement, 'for'))) {
              hasDynamicSlots = true;
              const parseResult = vFor.parseResult ||
                  parseForExpression(vFor.exp, context);
              if (parseResult) {
                  // Render the dynamic slots as an array and add it to the createSlot()
                  // args. The runtime knows how to handle it appropriately.
                  dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
                      parseResult.source,
                      createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
                  ]));
              }
              else {
                  context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
              }
          }
          else {
              // check duplicate static names
              if (staticSlotName) {
                  if (seenSlotNames.has(staticSlotName)) {
                      context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
                      continue;
                  }
                  seenSlotNames.add(staticSlotName);
                  if (staticSlotName === 'default') {
                      hasNamedDefaultSlot = true;
                  }
              }
              slotsProperties.push(createObjectProperty(slotName, slotFunction));
          }
      }
      if (!onComponentSlot) {
          if (!hasTemplateSlots) {
              // implicit default slot (on component)
              slotsProperties.push(buildDefaultSlotProperty(undefined, children));
          }
          else if (implicitDefaultChildren.length) {
              // implicit default slot (mixed with named slots)
              if (hasNamedDefaultSlot) {
                  context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
              }
              else {
                  slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
              }
          }
      }
      const slotFlag = hasDynamicSlots
          ? 2 /* DYNAMIC */
          : hasForwardedSlots(node.children)
              ? 3 /* FORWARDED */
              : 1 /* STABLE */;
      let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 
      // 2 = compiled but dynamic = can skip normalization, but must run diff
      // 1 = compiled and static = can skip normalization AND diff as optimized
      createSimpleExpression('' + slotFlag, false))), loc);
      if (dynamicSlots.length) {
          slots = createCallExpression(context.helper(CREATE_SLOTS), [
              slots,
              createArrayExpression(dynamicSlots)
          ]);
      }
      return {
          slots,
          hasDynamicSlots
      };
  }
  function buildDynamicSlot(name, fn) {
      return createObjectExpression([
          createObjectProperty(`name`, name),
          createObjectProperty(`fn`, fn)
      ]);
  }
  function hasForwardedSlots(children) {
      for (let i = 0; i < children.length; i++) {
          const child = children[i];
          if (child.type === 1 /* ELEMENT */) {
              if (child.tagType === 2 /* SLOT */ ||
                  (child.tagType === 0 /* ELEMENT */ &&
                      hasForwardedSlots(child.children))) {
                  return true;
              }
          }
      }
      return false;
  }

  // some directive transforms (e.g. v-model) may return a symbol for runtime
  // import, which should be used instead of a resolveDirective call.
  const directiveImportMap = new WeakMap();
  // generate a JavaScript AST for this element's codegen
  const transformElement = (node, context) => {
      if (!(node.type === 1 /* ELEMENT */ &&
          (node.tagType === 0 /* ELEMENT */ ||
              node.tagType === 1 /* COMPONENT */))) {
          return;
      }
      // perform the work on exit, after all child expressions have been
      // processed and merged.
      return function postTransformElement() {
          const { tag, props } = node;
          const isComponent = node.tagType === 1 /* COMPONENT */;
          // The goal of the transform is to create a codegenNode implementing the
          // VNodeCall interface.
          const vnodeTag = isComponent
              ? resolveComponentType(node, context)
              : `"${tag}"`;
          const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
          let vnodeProps;
          let vnodeChildren;
          let vnodePatchFlag;
          let patchFlag = 0;
          let vnodeDynamicProps;
          let dynamicPropNames;
          let vnodeDirectives;
          let shouldUseBlock = 
          // dynamic component may resolve to plain elements
          isDynamicComponent ||
              vnodeTag === TELEPORT ||
              vnodeTag === SUSPENSE ||
              (!isComponent &&
                  // <svg> and <foreignObject> must be forced into blocks so that block
                  // updates inside get proper isSVG flag at runtime. (#639, #643)
                  // This is technically web-specific, but splitting the logic out of core
                  // leads to too much unnecessary complexity.
                  (tag === 'svg' ||
                      tag === 'foreignObject' ||
                      // #938: elements with dynamic keys should be forced into blocks
                      findProp(node, 'key', true)));
          // props
          if (props.length > 0) {
              const propsBuildResult = buildProps(node, context);
              vnodeProps = propsBuildResult.props;
              patchFlag = propsBuildResult.patchFlag;
              dynamicPropNames = propsBuildResult.dynamicPropNames;
              const directives = propsBuildResult.directives;
              vnodeDirectives =
                  directives && directives.length
                      ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
                      : undefined;
          }
          // children
          if (node.children.length > 0) {
              if (vnodeTag === KEEP_ALIVE) {
                  // Although a built-in component, we compile KeepAlive with raw children
                  // instead of slot functions so that it can be used inside Transition
                  // or other Transition-wrapping HOCs.
                  // To ensure correct updates with block optimizations, we need to:
                  // 1. Force keep-alive into a block. This avoids its children being
                  //    collected by a parent block.
                  shouldUseBlock = true;
                  // 2. Force keep-alive to always be updated, since it uses raw children.
                  patchFlag |= 1024 /* DYNAMIC_SLOTS */;
                  if ( node.children.length > 1) {
                      context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
                          start: node.children[0].loc.start,
                          end: node.children[node.children.length - 1].loc.end,
                          source: ''
                      }));
                  }
              }
              const shouldBuildAsSlots = isComponent &&
                  // Teleport is not a real component and has dedicated runtime handling
                  vnodeTag !== TELEPORT &&
                  // explained above.
                  vnodeTag !== KEEP_ALIVE;
              if (shouldBuildAsSlots) {
                  const { slots, hasDynamicSlots } = buildSlots(node, context);
                  vnodeChildren = slots;
                  if (hasDynamicSlots) {
                      patchFlag |= 1024 /* DYNAMIC_SLOTS */;
                  }
              }
              else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
                  const child = node.children[0];
                  const type = child.type;
                  // check for dynamic text children
                  const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
                      type === 8 /* COMPOUND_EXPRESSION */;
                  if (hasDynamicTextChild && !getStaticType(child)) {
                      patchFlag |= 1 /* TEXT */;
                  }
                  // pass directly if the only child is a text node
                  // (plain / interpolation / expression)
                  if (hasDynamicTextChild || type === 2 /* TEXT */) {
                      vnodeChildren = child;
                  }
                  else {
                      vnodeChildren = node.children;
                  }
              }
              else {
                  vnodeChildren = node.children;
              }
          }
          // patchFlag & dynamicPropNames
          if (patchFlag !== 0) {
              {
                  if (patchFlag < 0) {
                      // special flags (negative and mutually exclusive)
                      vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
                  }
                  else {
                      // bitwise flags
                      const flagNames = Object.keys(PatchFlagNames)
                          .map(Number)
                          .filter(n => n > 0 && patchFlag & n)
                          .map(n => PatchFlagNames[n])
                          .join(`, `);
                      vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
                  }
              }
              if (dynamicPropNames && dynamicPropNames.length) {
                  vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
              }
          }
          node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);
      };
  };
  function resolveComponentType(node, context, ssr = false) {
      const { tag } = node;
      // 1. dynamic component
      const isProp = node.tag === 'component' ? findProp(node, 'is') : findDir(node, 'is');
      if (isProp) {
          const exp = isProp.type === 6 /* ATTRIBUTE */
              ? isProp.value && createSimpleExpression(isProp.value.content, true)
              : isProp.exp;
          if (exp) {
              return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
                  exp
              ]);
          }
      }
      // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
      const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
      if (builtIn) {
          // built-ins are simply fallthroughs / have special handling during ssr
          // no we don't need to import their runtime equivalents
          if (!ssr)
              context.helper(builtIn);
          return builtIn;
      }
      // 3. user component (from setup bindings)
      if (context.bindingMetadata[tag] === 'setup') {
          return `$setup[${JSON.stringify(tag)}]`;
      }
      // 4. user component (resolve)
      context.helper(RESOLVE_COMPONENT);
      context.components.add(tag);
      return toValidAssetId(tag, `component`);
  }
  function buildProps(node, context, props = node.props, ssr = false) {
      const { tag, loc: elementLoc } = node;
      const isComponent = node.tagType === 1 /* COMPONENT */;
      let properties = [];
      const mergeArgs = [];
      const runtimeDirectives = [];
      // patchFlag analysis
      let patchFlag = 0;
      let hasRef = false;
      let hasClassBinding = false;
      let hasStyleBinding = false;
      let hasHydrationEventBinding = false;
      let hasDynamicKeys = false;
      let hasVnodeHook = false;
      const dynamicPropNames = [];
      const analyzePatchFlag = ({ key, value }) => {
          if (isStaticExp(key)) {
              const name = key.content;
              const isEventHandler = isOn(name);
              if (!isComponent &&
                  isEventHandler &&
                  // omit the flag for click handlers because hydration gives click
                  // dedicated fast path.
                  name.toLowerCase() !== 'onclick' &&
                  // omit v-model handlers
                  name !== 'onUpdate:modelValue' &&
                  // omit onVnodeXXX hooks
                  !isReservedProp(name)) {
                  hasHydrationEventBinding = true;
              }
              if (isEventHandler && isReservedProp(name)) {
                  hasVnodeHook = true;
              }
              if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
                  ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
                      value.type === 8 /* COMPOUND_EXPRESSION */) &&
                      getStaticType(value) > 0)) {
                  // skip if the prop is a cached handler or has constant value
                  return;
              }
              if (name === 'ref') {
                  hasRef = true;
              }
              else if (name === 'class' && !isComponent) {
                  hasClassBinding = true;
              }
              else if (name === 'style' && !isComponent) {
                  hasStyleBinding = true;
              }
              else if (name !== 'key' && !dynamicPropNames.includes(name)) {
                  dynamicPropNames.push(name);
              }
          }
          else {
              hasDynamicKeys = true;
          }
      };
      for (let i = 0; i < props.length; i++) {
          // static attribute
          const prop = props[i];
          if (prop.type === 6 /* ATTRIBUTE */) {
              const { loc, name, value } = prop;
              if (name === 'ref') {
                  hasRef = true;
              }
              // skip :is on <component>
              if (name === 'is' && tag === 'component') {
                  continue;
              }
              properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc)));
          }
          else {
              // directives
              const { name, arg, exp, loc } = prop;
              const isBind = name === 'bind';
              const isOn = name === 'on';
              // skip v-slot - it is handled by its dedicated transform.
              if (name === 'slot') {
                  if (!isComponent) {
                      context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));
                  }
                  continue;
              }
              // skip v-once - it is handled by its dedicated transform.
              if (name === 'once') {
                  continue;
              }
              // skip v-is and :is on <component>
              if (name === 'is' ||
                  (isBind && tag === 'component' && isBindKey(arg, 'is'))) {
                  continue;
              }
              // skip v-on in SSR compilation
              if (isOn && ssr) {
                  continue;
              }
              // special case for v-bind and v-on with no argument
              if (!arg && (isBind || isOn)) {
                  hasDynamicKeys = true;
                  if (exp) {
                      if (properties.length) {
                          mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
                          properties = [];
                      }
                      if (isBind) {
                          mergeArgs.push(exp);
                      }
                      else {
                          // v-on="obj" -> toHandlers(obj)
                          mergeArgs.push({
                              type: 14 /* JS_CALL_EXPRESSION */,
                              loc,
                              callee: context.helper(TO_HANDLERS),
                              arguments: [exp]
                          });
                      }
                  }
                  else {
                      context.onError(createCompilerError(isBind
                          ? 33 /* X_V_BIND_NO_EXPRESSION */
                          : 34 /* X_V_ON_NO_EXPRESSION */, loc));
                  }
                  continue;
              }
              const directiveTransform = context.directiveTransforms[name];
              if (directiveTransform) {
                  // has built-in directive transform.
                  const { props, needRuntime } = directiveTransform(prop, node, context);
                  !ssr && props.forEach(analyzePatchFlag);
                  properties.push(...props);
                  if (needRuntime) {
                      runtimeDirectives.push(prop);
                      if (isSymbol(needRuntime)) {
                          directiveImportMap.set(prop, needRuntime);
                      }
                  }
              }
              else {
                  // no built-in transform, this is a user custom directive.
                  runtimeDirectives.push(prop);
              }
          }
      }
      let propsExpression = undefined;
      // has v-bind="object" or v-on="object", wrap with mergeProps
      if (mergeArgs.length) {
          if (properties.length) {
              mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
          }
          if (mergeArgs.length > 1) {
              propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
          }
          else {
              // single v-bind with nothing else - no need for a mergeProps call
              propsExpression = mergeArgs[0];
          }
      }
      else if (properties.length) {
          propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
      }
      // patchFlag analysis
      if (hasDynamicKeys) {
          patchFlag |= 16 /* FULL_PROPS */;
      }
      else {
          if (hasClassBinding) {
              patchFlag |= 2 /* CLASS */;
          }
          if (hasStyleBinding) {
              patchFlag |= 4 /* STYLE */;
          }
          if (dynamicPropNames.length) {
              patchFlag |= 8 /* PROPS */;
          }
          if (hasHydrationEventBinding) {
              patchFlag |= 32 /* HYDRATE_EVENTS */;
          }
      }
      if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
          (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
          patchFlag |= 512 /* NEED_PATCH */;
      }
      return {
          props: propsExpression,
          directives: runtimeDirectives,
          patchFlag,
          dynamicPropNames
      };
  }
  // Dedupe props in an object literal.
  // Literal duplicated attributes would have been warned during the parse phase,
  // however, it's possible to encounter duplicated `onXXX` handlers with different
  // modifiers. We also need to merge static and dynamic class / style attributes.
  // - onXXX handlers / style: merge into array
  // - class: merge into single expression with concatenation
  function dedupeProperties(properties) {
      const knownProps = new Map();
      const deduped = [];
      for (let i = 0; i < properties.length; i++) {
          const prop = properties[i];
          // dynamic keys are always allowed
          if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
              deduped.push(prop);
              continue;
          }
          const name = prop.key.content;
          const existing = knownProps.get(name);
          if (existing) {
              if (name === 'style' || name === 'class' || name.startsWith('on')) {
                  mergeAsArray(existing, prop);
              }
              // unexpected duplicate, should have emitted error during parse
          }
          else {
              knownProps.set(name, prop);
              deduped.push(prop);
          }
      }
      return deduped;
  }
  function mergeAsArray(existing, incoming) {
      if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
          existing.value.elements.push(incoming.value);
      }
      else {
          existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
      }
  }
  function buildDirectiveArgs(dir, context) {
      const dirArgs = [];
      const runtime = directiveImportMap.get(dir);
      if (runtime) {
          dirArgs.push(context.helperString(runtime));
      }
      else {
          // inject statement for resolving directive
          context.helper(RESOLVE_DIRECTIVE);
          context.directives.add(dir.name);
          dirArgs.push(toValidAssetId(dir.name, `directive`));
      }
      const { loc } = dir;
      if (dir.exp)
          dirArgs.push(dir.exp);
      if (dir.arg) {
          if (!dir.exp) {
              dirArgs.push(`void 0`);
          }
          dirArgs.push(dir.arg);
      }
      if (Object.keys(dir.modifiers).length) {
          if (!dir.arg) {
              if (!dir.exp) {
                  dirArgs.push(`void 0`);
              }
              dirArgs.push(`void 0`);
          }
          const trueExpression = createSimpleExpression(`true`, false, loc);
          dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
      }
      return createArrayExpression(dirArgs, dir.loc);
  }
  function stringifyDynamicPropNames(props) {
      let propsNamesString = `[`;
      for (let i = 0, l = props.length; i < l; i++) {
          propsNamesString += JSON.stringify(props[i]);
          if (i < l - 1)
              propsNamesString += ', ';
      }
      return propsNamesString + `]`;
  }

  const transformSlotOutlet = (node, context) => {
      if (isSlotOutlet(node)) {
          const { children, loc } = node;
          const { slotName, slotProps } = processSlotOutlet(node, context);
          const slotArgs = [
              context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
              slotName
          ];
          if (slotProps) {
              slotArgs.push(slotProps);
          }
          if (children.length) {
              if (!slotProps) {
                  slotArgs.push(`{}`);
              }
              slotArgs.push(createFunctionExpression([], children, false, false, loc));
          }
          node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
      }
  };
  function processSlotOutlet(node, context) {
      let slotName = `"default"`;
      let slotProps = undefined;
      // check for <slot name="xxx" OR :name="xxx" />
      const name = findProp(node, 'name');
      if (name) {
          if (name.type === 6 /* ATTRIBUTE */ && name.value) {
              // static name
              slotName = JSON.stringify(name.value.content);
          }
          else if (name.type === 7 /* DIRECTIVE */ && name.exp) {
              // dynamic name
              slotName = name.exp;
          }
      }
      const propsWithoutName = name
          ? node.props.filter(p => p !== name)
          : node.props;
      if (propsWithoutName.length > 0) {
          const { props, directives } = buildProps(node, context, propsWithoutName);
          slotProps = props;
          if (directives.length) {
              context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
          }
      }
      return {
          slotName,
          slotProps
      };
  }

  const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;
  const transformOn = (dir, node, context, augmentor) => {
      const { loc, modifiers, arg } = dir;
      if (!dir.exp && !modifiers.length) {
          context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));
      }
      let eventName;
      if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
          if (arg.isStatic) {
              const rawName = arg.content;
              // for @vnode-xxx event listeners, auto convert it to camelCase
              const normalizedName = rawName.startsWith(`vnode`)
                  ? capitalize(camelize(rawName))
                  : capitalize(rawName);
              eventName = createSimpleExpression(`on${normalizedName}`, true, arg.loc);
          }
          else {
              eventName = createCompoundExpression([
                  `"on" + ${context.helperString(CAPITALIZE)}(`,
                  arg,
                  `)`
              ]);
          }
      }
      else {
          // already a compound expression.
          eventName = arg;
          eventName.children.unshift(`"on" + ${context.helperString(CAPITALIZE)}(`);
          eventName.children.push(`)`);
      }
      // handler processing
      let exp = dir.exp;
      if (exp && !exp.content.trim()) {
          exp = undefined;
      }
      let isCacheable = context.cacheHandlers && !exp;
      if (exp) {
          const isMemberExp = isMemberExpression(exp.content);
          const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
          const hasMultipleStatements = exp.content.includes(`;`);
          // process the expression since it's been skipped
          if ( context.prefixIdentifiers) {
              isInlineStatement && context.addIdentifiers(`$event`);
              exp = processExpression(exp, context, false, hasMultipleStatements);
              isInlineStatement && context.removeIdentifiers(`$event`);
              // with scope analysis, the function is hoistable if it has no reference
              // to scope variables.
              isCacheable =
                  context.cacheHandlers &&
                      // #1541 bail if this is a member exp handler passed to a component -
                      // we need to use the original function to preserve arity,
                      // e.g. <transition> relies on checking cb.length to determine
                      // transition end handling. Inline function is ok since its arity
                      // is preserved even when cached.
                      !(isMemberExp && node.tagType === 1 /* COMPONENT */) &&
                      // bail if the function references closure variables (v-for, v-slot)
                      // it must be passed fresh to avoid stale values.
                      !hasScopeRef(exp, context.identifiers);
              // If the expression is optimizable and is a member expression pointing
              // to a function, turn it into invocation (and wrap in an arrow function
              // below) so that it always accesses the latest value when called - thus
              // avoiding the need to be patched.
              if (isCacheable && isMemberExp) {
                  if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
                      exp.content += `(...args)`;
                  }
                  else {
                      exp.children.push(`(...args)`);
                  }
              }
          }
          if (isInlineStatement || (isCacheable && isMemberExp)) {
              // wrap inline statement in a function expression
              exp = createCompoundExpression([
                  `${isInlineStatement ? `$event` : `(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
                  exp,
                  hasMultipleStatements ? `}` : `)`
              ]);
          }
      }
      let ret = {
          props: [
              createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
          ]
      };
      // apply extended compiler augmentor
      if (augmentor) {
          ret = augmentor(ret);
      }
      if (isCacheable) {
          // cache handlers so that it's always the same handler being passed down.
          // this avoids unnecessary re-renders when users use inline handlers on
          // components.
          ret.props[0].value = context.cache(ret.props[0].value);
      }
      return ret;
  };

  // v-bind without arg is handled directly in ./transformElements.ts due to it affecting
  // codegen for the entire props object. This transform here is only for v-bind
  // *with* args.
  const transformBind = (dir, node, context) => {
      const { exp, modifiers, loc } = dir;
      const arg = dir.arg;
      // .prop is no longer necessary due to new patch behavior
      // .sync is replaced by v-model:arg
      if (modifiers.includes('camel')) {
          if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
              if (arg.isStatic) {
                  arg.content = camelize(arg.content);
              }
              else {
                  arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
              }
          }
          else {
              arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
              arg.children.push(`)`);
          }
      }
      if (!exp ||
          (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
          context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));
          return {
              props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
          };
      }
      return {
          props: [createObjectProperty(arg, exp)]
      };
  };

  // Merge adjacent text nodes and expressions into a single expression
  // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
  const transformText = (node, context) => {
      if (node.type === 0 /* ROOT */ ||
          node.type === 1 /* ELEMENT */ ||
          node.type === 11 /* FOR */ ||
          node.type === 10 /* IF_BRANCH */) {
          // perform the transform on node exit so that all expressions have already
          // been processed.
          return () => {
              const children = node.children;
              let currentContainer = undefined;
              let hasText = false;
              for (let i = 0; i < children.length; i++) {
                  const child = children[i];
                  if (isText(child)) {
                      hasText = true;
                      for (let j = i + 1; j < children.length; j++) {
                          const next = children[j];
                          if (isText(next)) {
                              if (!currentContainer) {
                                  currentContainer = children[i] = {
                                      type: 8 /* COMPOUND_EXPRESSION */,
                                      loc: child.loc,
                                      children: [child]
                                  };
                              }
                              // merge adjacent text node into current
                              currentContainer.children.push(` + `, next);
                              children.splice(j, 1);
                              j--;
                          }
                          else {
                              currentContainer = undefined;
                              break;
                          }
                      }
                  }
              }
              if (!hasText ||
                  // if this is a plain element with a single text child, leave it
                  // as-is since the runtime has dedicated fast path for this by directly
                  // setting textContent of the element.
                  // for component root it's always normalized anyway.
                  (children.length === 1 &&
                      (node.type === 0 /* ROOT */ ||
                          (node.type === 1 /* ELEMENT */ &&
                              node.tagType === 0 /* ELEMENT */)))) {
                  return;
              }
              // pre-convert text nodes into createTextVNode(text) calls to avoid
              // runtime normalization.
              for (let i = 0; i < children.length; i++) {
                  const child = children[i];
                  if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
                      const callArgs = [];
                      // createTextVNode defaults to single whitespace, so if it is a
                      // single space the code could be an empty call to save bytes.
                      if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
                          callArgs.push(child);
                      }
                      // mark dynamic text with flag so it gets patched inside a block
                      if (!context.ssr && child.type !== 2 /* TEXT */) {
                          callArgs.push(`${1 /* TEXT */} /* ${PatchFlagNames[1 /* TEXT */]} */`);
                      }
                      children[i] = {
                          type: 12 /* TEXT_CALL */,
                          content: child,
                          loc: child.loc,
                          codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
                      };
                  }
              }
          };
      }
  };

  const seen = new WeakSet();
  const transformOnce = (node, context) => {
      if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
          if (seen.has(node)) {
              return;
          }
          seen.add(node);
          context.helper(SET_BLOCK_TRACKING);
          return () => {
              const cur = context.currentNode;
              if (cur.codegenNode) {
                  cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
              }
          };
      }
  };

  const transformModel = (dir, node, context) => {
      const { exp, arg } = dir;
      if (!exp) {
          context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
          return createTransformProps();
      }
      const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : exp.loc.source;
      if (!isMemberExpression(expString)) {
          context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
          return createTransformProps();
      }
      if (
          context.prefixIdentifiers &&
          isSimpleIdentifier(expString) &&
          context.identifiers[expString]) {
          context.onError(createCompilerError(42 /* X_V_MODEL_ON_SCOPE_VARIABLE */, exp.loc));
          return createTransformProps();
      }
      const propName = arg ? arg : createSimpleExpression('modelValue', true);
      const eventName = arg
          ? isStaticExp(arg)
              ? `onUpdate:${arg.content}`
              : createCompoundExpression(['"onUpdate:" + ', arg])
          : `onUpdate:modelValue`;
      const props = [
          // modelValue: foo
          createObjectProperty(propName, dir.exp),
          // "onUpdate:modelValue": $event => (foo = $event)
          createObjectProperty(eventName, createCompoundExpression([`$event => (`, exp, ` = $event)`]))
      ];
      // cache v-model handler if applicable (when it doesn't refer any scope vars)
      if (
          context.prefixIdentifiers &&
          context.cacheHandlers &&
          !hasScopeRef(exp, context.identifiers)) {
          props[1].value = context.cache(props[1].value);
      }
      // modelModifiers: { foo: true, "bar-baz": true }
      if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
          const modifiers = dir.modifiers
              .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
              .join(`, `);
          const modifiersKey = arg
              ? isStaticExp(arg)
                  ? `${arg.content}Modifiers`
                  : createCompoundExpression([arg, ' + "Modifiers"'])
              : `modelModifiers`;
          props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, true)));
      }
      return createTransformProps(props);
  };
  function createTransformProps(props = []) {
      return { props };
  }

  function getBaseTransformPreset(prefixIdentifiers) {
      return [
          [
              transformOnce,
              transformIf,
              transformFor,
              ...( prefixIdentifiers
                  ? [
                      // order is important
                      trackVForSlotScopes,
                      transformExpression
                  ]
                  :  []),
              transformSlotOutlet,
              transformElement,
              trackSlotScopes,
              transformText
          ],
          {
              on: transformOn,
              bind: transformBind,
              model: transformModel
          }
      ];
  }
  // we name it `baseCompile` so that higher order compilers like
  // @vue/compiler-dom can export `compile` while re-exporting everything else.
  function baseCompile(template, options = {}) {
      const onError = options.onError || defaultOnError;
      const isModuleMode = options.mode === 'module';
      const prefixIdentifiers =  (options.prefixIdentifiers === true || isModuleMode);
      if (!prefixIdentifiers && options.cacheHandlers) {
          onError(createCompilerError(47 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
      }
      if (options.scopeId && !isModuleMode) {
          onError(createCompilerError(48 /* X_SCOPE_ID_NOT_SUPPORTED */));
      }
      const ast = isString(template) ? baseParse(template, options) : template;
      const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(prefixIdentifiers);
      transform(ast, extend({}, options, {
          prefixIdentifiers,
          nodeTransforms: [
              ...nodeTransforms,
              ...(options.nodeTransforms || []) // user transforms
          ],
          directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
          )
      }));
      return generate(ast, extend({}, options, {
          prefixIdentifiers
      }));
  }

  const noopDirectiveTransform = () => ({ props: [] });

  const V_MODEL_RADIO = Symbol( `vModelRadio` );
  const V_MODEL_CHECKBOX = Symbol( `vModelCheckbox` );
  const V_MODEL_TEXT = Symbol( `vModelText` );
  const V_MODEL_SELECT = Symbol( `vModelSelect` );
  const V_MODEL_DYNAMIC = Symbol( `vModelDynamic` );
  const V_ON_WITH_MODIFIERS = Symbol( `vOnModifiersGuard` );
  const V_ON_WITH_KEYS = Symbol( `vOnKeysGuard` );
  const V_SHOW = Symbol( `vShow` );
  const TRANSITION = Symbol( `Transition` );
  const TRANSITION_GROUP = Symbol( `TransitionGroup` );
  registerRuntimeHelpers({
      [V_MODEL_RADIO]: `vModelRadio`,
      [V_MODEL_CHECKBOX]: `vModelCheckbox`,
      [V_MODEL_TEXT]: `vModelText`,
      [V_MODEL_SELECT]: `vModelSelect`,
      [V_MODEL_DYNAMIC]: `vModelDynamic`,
      [V_ON_WITH_MODIFIERS]: `withModifiers`,
      [V_ON_WITH_KEYS]: `withKeys`,
      [V_SHOW]: `vShow`,
      [TRANSITION]: `Transition`,
      [TRANSITION_GROUP]: `TransitionGroup`
  });

  var namedCharacterReferences = {
  	GT: ">",
  	gt: ">",
  	LT: "<",
  	lt: "<",
  	"ac;": "∾",
  	"af;": "⁡",
  	AMP: "&",
  	amp: "&",
  	"ap;": "≈",
  	"DD;": "ⅅ",
  	"dd;": "ⅆ",
  	deg: "°",
  	"ee;": "ⅇ",
  	"eg;": "⪚",
  	"el;": "⪙",
  	ETH: "Ð",
  	eth: "ð",
  	"gE;": "≧",
  	"ge;": "≥",
  	"Gg;": "⋙",
  	"gg;": "≫",
  	"gl;": "≷",
  	"GT;": ">",
  	"Gt;": "≫",
  	"gt;": ">",
  	"ic;": "⁣",
  	"ii;": "ⅈ",
  	"Im;": "ℑ",
  	"in;": "∈",
  	"it;": "⁢",
  	"lE;": "≦",
  	"le;": "≤",
  	"lg;": "≶",
  	"Ll;": "⋘",
  	"ll;": "≪",
  	"LT;": "<",
  	"Lt;": "≪",
  	"lt;": "<",
  	"mp;": "∓",
  	"Mu;": "Μ",
  	"mu;": "μ",
  	"ne;": "≠",
  	"ni;": "∋",
  	not: "¬",
  	"Nu;": "Ν",
  	"nu;": "ν",
  	"Or;": "⩔",
  	"or;": "∨",
  	"oS;": "Ⓢ",
  	"Pi;": "Π",
  	"pi;": "π",
  	"pm;": "±",
  	"Pr;": "⪻",
  	"pr;": "≺",
  	"Re;": "ℜ",
  	REG: "®",
  	reg: "®",
  	"rx;": "℞",
  	"Sc;": "⪼",
  	"sc;": "≻",
  	shy: "­",
  	uml: "¨",
  	"wp;": "℘",
  	"wr;": "≀",
  	"Xi;": "Ξ",
  	"xi;": "ξ",
  	yen: "¥",
  	"acd;": "∿",
  	"acE;": "∾̳",
  	"Acy;": "А",
  	"acy;": "а",
  	"Afr;": "𝔄",
  	"afr;": "𝔞",
  	"AMP;": "&",
  	"amp;": "&",
  	"And;": "⩓",
  	"and;": "∧",
  	"ang;": "∠",
  	"apE;": "⩰",
  	"ape;": "≊",
  	"ast;": "*",
  	Auml: "Ä",
  	auml: "ä",
  	"Bcy;": "Б",
  	"bcy;": "б",
  	"Bfr;": "𝔅",
  	"bfr;": "𝔟",
  	"bne;": "=⃥",
  	"bot;": "⊥",
  	"Cap;": "⋒",
  	"cap;": "∩",
  	cent: "¢",
  	"Cfr;": "ℭ",
  	"cfr;": "𝔠",
  	"Chi;": "Χ",
  	"chi;": "χ",
  	"cir;": "○",
  	COPY: "©",
  	copy: "©",
  	"Cup;": "⋓",
  	"cup;": "∪",
  	"Dcy;": "Д",
  	"dcy;": "д",
  	"deg;": "°",
  	"Del;": "∇",
  	"Dfr;": "𝔇",
  	"dfr;": "𝔡",
  	"die;": "¨",
  	"div;": "÷",
  	"Dot;": "¨",
  	"dot;": "˙",
  	"Ecy;": "Э",
  	"ecy;": "э",
  	"Efr;": "𝔈",
  	"efr;": "𝔢",
  	"egs;": "⪖",
  	"ell;": "ℓ",
  	"els;": "⪕",
  	"ENG;": "Ŋ",
  	"eng;": "ŋ",
  	"Eta;": "Η",
  	"eta;": "η",
  	"ETH;": "Ð",
  	"eth;": "ð",
  	Euml: "Ë",
  	euml: "ë",
  	"Fcy;": "Ф",
  	"fcy;": "ф",
  	"Ffr;": "𝔉",
  	"ffr;": "𝔣",
  	"gap;": "⪆",
  	"Gcy;": "Г",
  	"gcy;": "г",
  	"gEl;": "⪌",
  	"gel;": "⋛",
  	"geq;": "≥",
  	"ges;": "⩾",
  	"Gfr;": "𝔊",
  	"gfr;": "𝔤",
  	"ggg;": "⋙",
  	"gla;": "⪥",
  	"glE;": "⪒",
  	"glj;": "⪤",
  	"gnE;": "≩",
  	"gne;": "⪈",
  	"Hat;": "^",
  	"Hfr;": "ℌ",
  	"hfr;": "𝔥",
  	"Icy;": "И",
  	"icy;": "и",
  	"iff;": "⇔",
  	"Ifr;": "ℑ",
  	"ifr;": "𝔦",
  	"Int;": "∬",
  	"int;": "∫",
  	Iuml: "Ï",
  	iuml: "ï",
  	"Jcy;": "Й",
  	"jcy;": "й",
  	"Jfr;": "𝔍",
  	"jfr;": "𝔧",
  	"Kcy;": "К",
  	"kcy;": "к",
  	"Kfr;": "𝔎",
  	"kfr;": "𝔨",
  	"lap;": "⪅",
  	"lat;": "⪫",
  	"Lcy;": "Л",
  	"lcy;": "л",
  	"lEg;": "⪋",
  	"leg;": "⋚",
  	"leq;": "≤",
  	"les;": "⩽",
  	"Lfr;": "𝔏",
  	"lfr;": "𝔩",
  	"lgE;": "⪑",
  	"lnE;": "≨",
  	"lne;": "⪇",
  	"loz;": "◊",
  	"lrm;": "‎",
  	"Lsh;": "↰",
  	"lsh;": "↰",
  	macr: "¯",
  	"Map;": "⤅",
  	"map;": "↦",
  	"Mcy;": "М",
  	"mcy;": "м",
  	"Mfr;": "𝔐",
  	"mfr;": "𝔪",
  	"mho;": "℧",
  	"mid;": "∣",
  	"nap;": "≉",
  	nbsp: " ",
  	"Ncy;": "Н",
  	"ncy;": "н",
  	"Nfr;": "𝔑",
  	"nfr;": "𝔫",
  	"ngE;": "≧̸",
  	"nge;": "≱",
  	"nGg;": "⋙̸",
  	"nGt;": "≫⃒",
  	"ngt;": "≯",
  	"nis;": "⋼",
  	"niv;": "∋",
  	"nlE;": "≦̸",
  	"nle;": "≰",
  	"nLl;": "⋘̸",
  	"nLt;": "≪⃒",
  	"nlt;": "≮",
  	"Not;": "⫬",
  	"not;": "¬",
  	"npr;": "⊀",
  	"nsc;": "⊁",
  	"num;": "#",
  	"Ocy;": "О",
  	"ocy;": "о",
  	"Ofr;": "𝔒",
  	"ofr;": "𝔬",
  	"ogt;": "⧁",
  	"ohm;": "Ω",
  	"olt;": "⧀",
  	"ord;": "⩝",
  	ordf: "ª",
  	ordm: "º",
  	"orv;": "⩛",
  	Ouml: "Ö",
  	ouml: "ö",
  	"par;": "∥",
  	para: "¶",
  	"Pcy;": "П",
  	"pcy;": "п",
  	"Pfr;": "𝔓",
  	"pfr;": "𝔭",
  	"Phi;": "Φ",
  	"phi;": "φ",
  	"piv;": "ϖ",
  	"prE;": "⪳",
  	"pre;": "⪯",
  	"Psi;": "Ψ",
  	"psi;": "ψ",
  	"Qfr;": "𝔔",
  	"qfr;": "𝔮",
  	QUOT: "\"",
  	quot: "\"",
  	"Rcy;": "Р",
  	"rcy;": "р",
  	"REG;": "®",
  	"reg;": "®",
  	"Rfr;": "ℜ",
  	"rfr;": "𝔯",
  	"Rho;": "Ρ",
  	"rho;": "ρ",
  	"rlm;": "‏",
  	"Rsh;": "↱",
  	"rsh;": "↱",
  	"scE;": "⪴",
  	"sce;": "⪰",
  	"Scy;": "С",
  	"scy;": "с",
  	sect: "§",
  	"Sfr;": "𝔖",
  	"sfr;": "𝔰",
  	"shy;": "­",
  	"sim;": "∼",
  	"smt;": "⪪",
  	"sol;": "/",
  	"squ;": "□",
  	"Sub;": "⋐",
  	"sub;": "⊂",
  	"Sum;": "∑",
  	"sum;": "∑",
  	"Sup;": "⋑",
  	"sup;": "⊃",
  	sup1: "¹",
  	sup2: "²",
  	sup3: "³",
  	"Tab;": "\t",
  	"Tau;": "Τ",
  	"tau;": "τ",
  	"Tcy;": "Т",
  	"tcy;": "т",
  	"Tfr;": "𝔗",
  	"tfr;": "𝔱",
  	"top;": "⊤",
  	"Ucy;": "У",
  	"ucy;": "у",
  	"Ufr;": "𝔘",
  	"ufr;": "𝔲",
  	"uml;": "¨",
  	Uuml: "Ü",
  	uuml: "ü",
  	"Vcy;": "В",
  	"vcy;": "в",
  	"Vee;": "⋁",
  	"vee;": "∨",
  	"Vfr;": "𝔙",
  	"vfr;": "𝔳",
  	"Wfr;": "𝔚",
  	"wfr;": "𝔴",
  	"Xfr;": "𝔛",
  	"xfr;": "𝔵",
  	"Ycy;": "Ы",
  	"ycy;": "ы",
  	"yen;": "¥",
  	"Yfr;": "𝔜",
  	"yfr;": "𝔶",
  	yuml: "ÿ",
  	"Zcy;": "З",
  	"zcy;": "з",
  	"Zfr;": "ℨ",
  	"zfr;": "𝔷",
  	"zwj;": "‍",
  	Acirc: "Â",
  	acirc: "â",
  	acute: "´",
  	AElig: "Æ",
  	aelig: "æ",
  	"andd;": "⩜",
  	"andv;": "⩚",
  	"ange;": "⦤",
  	"Aopf;": "𝔸",
  	"aopf;": "𝕒",
  	"apid;": "≋",
  	"apos;": "'",
  	Aring: "Å",
  	aring: "å",
  	"Ascr;": "𝒜",
  	"ascr;": "𝒶",
  	"Auml;": "Ä",
  	"auml;": "ä",
  	"Barv;": "⫧",
  	"bbrk;": "⎵",
  	"Beta;": "Β",
  	"beta;": "β",
  	"beth;": "ℶ",
  	"bNot;": "⫭",
  	"bnot;": "⌐",
  	"Bopf;": "𝔹",
  	"bopf;": "𝕓",
  	"boxH;": "═",
  	"boxh;": "─",
  	"boxV;": "║",
  	"boxv;": "│",
  	"Bscr;": "ℬ",
  	"bscr;": "𝒷",
  	"bsim;": "∽",
  	"bsol;": "\\",
  	"bull;": "•",
  	"bump;": "≎",
  	"caps;": "∩︀",
  	"Cdot;": "Ċ",
  	"cdot;": "ċ",
  	cedil: "¸",
  	"cent;": "¢",
  	"CHcy;": "Ч",
  	"chcy;": "ч",
  	"circ;": "ˆ",
  	"cirE;": "⧃",
  	"cire;": "≗",
  	"comp;": "∁",
  	"cong;": "≅",
  	"Copf;": "ℂ",
  	"copf;": "𝕔",
  	"COPY;": "©",
  	"copy;": "©",
  	"Cscr;": "𝒞",
  	"cscr;": "𝒸",
  	"csub;": "⫏",
  	"csup;": "⫐",
  	"cups;": "∪︀",
  	"Darr;": "↡",
  	"dArr;": "⇓",
  	"darr;": "↓",
  	"dash;": "‐",
  	"dHar;": "⥥",
  	"diam;": "⋄",
  	"DJcy;": "Ђ",
  	"djcy;": "ђ",
  	"Dopf;": "𝔻",
  	"dopf;": "𝕕",
  	"Dscr;": "𝒟",
  	"dscr;": "𝒹",
  	"DScy;": "Ѕ",
  	"dscy;": "ѕ",
  	"dsol;": "⧶",
  	"dtri;": "▿",
  	"DZcy;": "Џ",
  	"dzcy;": "џ",
  	"ecir;": "≖",
  	Ecirc: "Ê",
  	ecirc: "ê",
  	"Edot;": "Ė",
  	"eDot;": "≑",
  	"edot;": "ė",
  	"emsp;": " ",
  	"ensp;": " ",
  	"Eopf;": "𝔼",
  	"eopf;": "𝕖",
  	"epar;": "⋕",
  	"epsi;": "ε",
  	"Escr;": "ℰ",
  	"escr;": "ℯ",
  	"Esim;": "⩳",
  	"esim;": "≂",
  	"Euml;": "Ë",
  	"euml;": "ë",
  	"euro;": "€",
  	"excl;": "!",
  	"flat;": "♭",
  	"fnof;": "ƒ",
  	"Fopf;": "𝔽",
  	"fopf;": "𝕗",
  	"fork;": "⋔",
  	"Fscr;": "ℱ",
  	"fscr;": "𝒻",
  	"Gdot;": "Ġ",
  	"gdot;": "ġ",
  	"geqq;": "≧",
  	"gesl;": "⋛︀",
  	"GJcy;": "Ѓ",
  	"gjcy;": "ѓ",
  	"gnap;": "⪊",
  	"gneq;": "⪈",
  	"Gopf;": "𝔾",
  	"gopf;": "𝕘",
  	"Gscr;": "𝒢",
  	"gscr;": "ℊ",
  	"gsim;": "≳",
  	"gtcc;": "⪧",
  	"gvnE;": "≩︀",
  	"half;": "½",
  	"hArr;": "⇔",
  	"harr;": "↔",
  	"hbar;": "ℏ",
  	"Hopf;": "ℍ",
  	"hopf;": "𝕙",
  	"Hscr;": "ℋ",
  	"hscr;": "𝒽",
  	Icirc: "Î",
  	icirc: "î",
  	"Idot;": "İ",
  	"IEcy;": "Е",
  	"iecy;": "е",
  	iexcl: "¡",
  	"imof;": "⊷",
  	"IOcy;": "Ё",
  	"iocy;": "ё",
  	"Iopf;": "𝕀",
  	"iopf;": "𝕚",
  	"Iota;": "Ι",
  	"iota;": "ι",
  	"Iscr;": "ℐ",
  	"iscr;": "𝒾",
  	"isin;": "∈",
  	"Iuml;": "Ï",
  	"iuml;": "ï",
  	"Jopf;": "𝕁",
  	"jopf;": "𝕛",
  	"Jscr;": "𝒥",
  	"jscr;": "𝒿",
  	"KHcy;": "Х",
  	"khcy;": "х",
  	"KJcy;": "Ќ",
  	"kjcy;": "ќ",
  	"Kopf;": "𝕂",
  	"kopf;": "𝕜",
  	"Kscr;": "𝒦",
  	"kscr;": "𝓀",
  	"Lang;": "⟪",
  	"lang;": "⟨",
  	laquo: "«",
  	"Larr;": "↞",
  	"lArr;": "⇐",
  	"larr;": "←",
  	"late;": "⪭",
  	"lcub;": "{",
  	"ldca;": "⤶",
  	"ldsh;": "↲",
  	"leqq;": "≦",
  	"lesg;": "⋚︀",
  	"lHar;": "⥢",
  	"LJcy;": "Љ",
  	"ljcy;": "љ",
  	"lnap;": "⪉",
  	"lneq;": "⪇",
  	"Lopf;": "𝕃",
  	"lopf;": "𝕝",
  	"lozf;": "⧫",
  	"lpar;": "(",
  	"Lscr;": "ℒ",
  	"lscr;": "𝓁",
  	"lsim;": "≲",
  	"lsqb;": "[",
  	"ltcc;": "⪦",
  	"ltri;": "◃",
  	"lvnE;": "≨︀",
  	"macr;": "¯",
  	"male;": "♂",
  	"malt;": "✠",
  	micro: "µ",
  	"mlcp;": "⫛",
  	"mldr;": "…",
  	"Mopf;": "𝕄",
  	"mopf;": "𝕞",
  	"Mscr;": "ℳ",
  	"mscr;": "𝓂",
  	"nang;": "∠⃒",
  	"napE;": "⩰̸",
  	"nbsp;": " ",
  	"ncap;": "⩃",
  	"ncup;": "⩂",
  	"ngeq;": "≱",
  	"nges;": "⩾̸",
  	"ngtr;": "≯",
  	"nGtv;": "≫̸",
  	"nisd;": "⋺",
  	"NJcy;": "Њ",
  	"njcy;": "њ",
  	"nldr;": "‥",
  	"nleq;": "≰",
  	"nles;": "⩽̸",
  	"nLtv;": "≪̸",
  	"nmid;": "∤",
  	"Nopf;": "ℕ",
  	"nopf;": "𝕟",
  	"npar;": "∦",
  	"npre;": "⪯̸",
  	"nsce;": "⪰̸",
  	"Nscr;": "𝒩",
  	"nscr;": "𝓃",
  	"nsim;": "≁",
  	"nsub;": "⊄",
  	"nsup;": "⊅",
  	"ntgl;": "≹",
  	"ntlg;": "≸",
  	"nvap;": "≍⃒",
  	"nvge;": "≥⃒",
  	"nvgt;": ">⃒",
  	"nvle;": "≤⃒",
  	"nvlt;": "<⃒",
  	"oast;": "⊛",
  	"ocir;": "⊚",
  	Ocirc: "Ô",
  	ocirc: "ô",
  	"odiv;": "⨸",
  	"odot;": "⊙",
  	"ogon;": "˛",
  	"oint;": "∮",
  	"omid;": "⦶",
  	"Oopf;": "𝕆",
  	"oopf;": "𝕠",
  	"opar;": "⦷",
  	"ordf;": "ª",
  	"ordm;": "º",
  	"oror;": "⩖",
  	"Oscr;": "𝒪",
  	"oscr;": "ℴ",
  	"osol;": "⊘",
  	"Ouml;": "Ö",
  	"ouml;": "ö",
  	"para;": "¶",
  	"part;": "∂",
  	"perp;": "⊥",
  	"phiv;": "ϕ",
  	"plus;": "+",
  	"Popf;": "ℙ",
  	"popf;": "𝕡",
  	pound: "£",
  	"prap;": "⪷",
  	"prec;": "≺",
  	"prnE;": "⪵",
  	"prod;": "∏",
  	"prop;": "∝",
  	"Pscr;": "𝒫",
  	"pscr;": "𝓅",
  	"qint;": "⨌",
  	"Qopf;": "ℚ",
  	"qopf;": "𝕢",
  	"Qscr;": "𝒬",
  	"qscr;": "𝓆",
  	"QUOT;": "\"",
  	"quot;": "\"",
  	"race;": "∽̱",
  	"Rang;": "⟫",
  	"rang;": "⟩",
  	raquo: "»",
  	"Rarr;": "↠",
  	"rArr;": "⇒",
  	"rarr;": "→",
  	"rcub;": "}",
  	"rdca;": "⤷",
  	"rdsh;": "↳",
  	"real;": "ℜ",
  	"rect;": "▭",
  	"rHar;": "⥤",
  	"rhov;": "ϱ",
  	"ring;": "˚",
  	"Ropf;": "ℝ",
  	"ropf;": "𝕣",
  	"rpar;": ")",
  	"Rscr;": "ℛ",
  	"rscr;": "𝓇",
  	"rsqb;": "]",
  	"rtri;": "▹",
  	"scap;": "⪸",
  	"scnE;": "⪶",
  	"sdot;": "⋅",
  	"sect;": "§",
  	"semi;": ";",
  	"sext;": "✶",
  	"SHcy;": "Ш",
  	"shcy;": "ш",
  	"sime;": "≃",
  	"simg;": "⪞",
  	"siml;": "⪝",
  	"smid;": "∣",
  	"smte;": "⪬",
  	"solb;": "⧄",
  	"Sopf;": "𝕊",
  	"sopf;": "𝕤",
  	"spar;": "∥",
  	"Sqrt;": "√",
  	"squf;": "▪",
  	"Sscr;": "𝒮",
  	"sscr;": "𝓈",
  	"Star;": "⋆",
  	"star;": "☆",
  	"subE;": "⫅",
  	"sube;": "⊆",
  	"succ;": "≻",
  	"sung;": "♪",
  	"sup1;": "¹",
  	"sup2;": "²",
  	"sup3;": "³",
  	"supE;": "⫆",
  	"supe;": "⊇",
  	szlig: "ß",
  	"tbrk;": "⎴",
  	"tdot;": "⃛",
  	THORN: "Þ",
  	thorn: "þ",
  	times: "×",
  	"tint;": "∭",
  	"toea;": "⤨",
  	"Topf;": "𝕋",
  	"topf;": "𝕥",
  	"tosa;": "⤩",
  	"trie;": "≜",
  	"Tscr;": "𝒯",
  	"tscr;": "𝓉",
  	"TScy;": "Ц",
  	"tscy;": "ц",
  	"Uarr;": "↟",
  	"uArr;": "⇑",
  	"uarr;": "↑",
  	Ucirc: "Û",
  	ucirc: "û",
  	"uHar;": "⥣",
  	"Uopf;": "𝕌",
  	"uopf;": "𝕦",
  	"Upsi;": "ϒ",
  	"upsi;": "υ",
  	"Uscr;": "𝒰",
  	"uscr;": "𝓊",
  	"utri;": "▵",
  	"Uuml;": "Ü",
  	"uuml;": "ü",
  	"vArr;": "⇕",
  	"varr;": "↕",
  	"Vbar;": "⫫",
  	"vBar;": "⫨",
  	"Vert;": "‖",
  	"vert;": "|",
  	"Vopf;": "𝕍",
  	"vopf;": "𝕧",
  	"Vscr;": "𝒱",
  	"vscr;": "𝓋",
  	"Wopf;": "𝕎",
  	"wopf;": "𝕨",
  	"Wscr;": "𝒲",
  	"wscr;": "𝓌",
  	"xcap;": "⋂",
  	"xcup;": "⋃",
  	"xmap;": "⟼",
  	"xnis;": "⋻",
  	"Xopf;": "𝕏",
  	"xopf;": "𝕩",
  	"Xscr;": "𝒳",
  	"xscr;": "𝓍",
  	"xvee;": "⋁",
  	"YAcy;": "Я",
  	"yacy;": "я",
  	"YIcy;": "Ї",
  	"yicy;": "ї",
  	"Yopf;": "𝕐",
  	"yopf;": "𝕪",
  	"Yscr;": "𝒴",
  	"yscr;": "𝓎",
  	"YUcy;": "Ю",
  	"yucy;": "ю",
  	"Yuml;": "Ÿ",
  	"yuml;": "ÿ",
  	"Zdot;": "Ż",
  	"zdot;": "ż",
  	"Zeta;": "Ζ",
  	"zeta;": "ζ",
  	"ZHcy;": "Ж",
  	"zhcy;": "ж",
  	"Zopf;": "ℤ",
  	"zopf;": "𝕫",
  	"Zscr;": "𝒵",
  	"zscr;": "𝓏",
  	"zwnj;": "‌",
  	Aacute: "Á",
  	aacute: "á",
  	"Acirc;": "Â",
  	"acirc;": "â",
  	"acute;": "´",
  	"AElig;": "Æ",
  	"aelig;": "æ",
  	Agrave: "À",
  	agrave: "à",
  	"aleph;": "ℵ",
  	"Alpha;": "Α",
  	"alpha;": "α",
  	"Amacr;": "Ā",
  	"amacr;": "ā",
  	"amalg;": "⨿",
  	"angle;": "∠",
  	"angrt;": "∟",
  	"angst;": "Å",
  	"Aogon;": "Ą",
  	"aogon;": "ą",
  	"Aring;": "Å",
  	"aring;": "å",
  	"asymp;": "≈",
  	Atilde: "Ã",
  	atilde: "ã",
  	"awint;": "⨑",
  	"bcong;": "≌",
  	"bdquo;": "„",
  	"bepsi;": "϶",
  	"blank;": "␣",
  	"blk12;": "▒",
  	"blk14;": "░",
  	"blk34;": "▓",
  	"block;": "█",
  	"boxDL;": "╗",
  	"boxDl;": "╖",
  	"boxdL;": "╕",
  	"boxdl;": "┐",
  	"boxDR;": "╔",
  	"boxDr;": "╓",
  	"boxdR;": "╒",
  	"boxdr;": "┌",
  	"boxHD;": "╦",
  	"boxHd;": "╤",
  	"boxhD;": "╥",
  	"boxhd;": "┬",
  	"boxHU;": "╩",
  	"boxHu;": "╧",
  	"boxhU;": "╨",
  	"boxhu;": "┴",
  	"boxUL;": "╝",
  	"boxUl;": "╜",
  	"boxuL;": "╛",
  	"boxul;": "┘",
  	"boxUR;": "╚",
  	"boxUr;": "╙",
  	"boxuR;": "╘",
  	"boxur;": "└",
  	"boxVH;": "╬",
  	"boxVh;": "╫",
  	"boxvH;": "╪",
  	"boxvh;": "┼",
  	"boxVL;": "╣",
  	"boxVl;": "╢",
  	"boxvL;": "╡",
  	"boxvl;": "┤",
  	"boxVR;": "╠",
  	"boxVr;": "╟",
  	"boxvR;": "╞",
  	"boxvr;": "├",
  	"Breve;": "˘",
  	"breve;": "˘",
  	brvbar: "¦",
  	"bsemi;": "⁏",
  	"bsime;": "⋍",
  	"bsolb;": "⧅",
  	"bumpE;": "⪮",
  	"bumpe;": "≏",
  	"caret;": "⁁",
  	"caron;": "ˇ",
  	"ccaps;": "⩍",
  	Ccedil: "Ç",
  	ccedil: "ç",
  	"Ccirc;": "Ĉ",
  	"ccirc;": "ĉ",
  	"ccups;": "⩌",
  	"cedil;": "¸",
  	"check;": "✓",
  	"clubs;": "♣",
  	"Colon;": "∷",
  	"colon;": ":",
  	"comma;": ",",
  	"crarr;": "↵",
  	"Cross;": "⨯",
  	"cross;": "✗",
  	"csube;": "⫑",
  	"csupe;": "⫒",
  	"ctdot;": "⋯",
  	"cuepr;": "⋞",
  	"cuesc;": "⋟",
  	"cupor;": "⩅",
  	curren: "¤",
  	"cuvee;": "⋎",
  	"cuwed;": "⋏",
  	"cwint;": "∱",
  	"Dashv;": "⫤",
  	"dashv;": "⊣",
  	"dblac;": "˝",
  	"ddarr;": "⇊",
  	"Delta;": "Δ",
  	"delta;": "δ",
  	"dharl;": "⇃",
  	"dharr;": "⇂",
  	"diams;": "♦",
  	"disin;": "⋲",
  	divide: "÷",
  	"doteq;": "≐",
  	"dtdot;": "⋱",
  	"dtrif;": "▾",
  	"duarr;": "⇵",
  	"duhar;": "⥯",
  	Eacute: "É",
  	eacute: "é",
  	"Ecirc;": "Ê",
  	"ecirc;": "ê",
  	"eDDot;": "⩷",
  	"efDot;": "≒",
  	Egrave: "È",
  	egrave: "è",
  	"Emacr;": "Ē",
  	"emacr;": "ē",
  	"empty;": "∅",
  	"Eogon;": "Ę",
  	"eogon;": "ę",
  	"eplus;": "⩱",
  	"epsiv;": "ϵ",
  	"eqsim;": "≂",
  	"Equal;": "⩵",
  	"equiv;": "≡",
  	"erarr;": "⥱",
  	"erDot;": "≓",
  	"esdot;": "≐",
  	"exist;": "∃",
  	"fflig;": "ff",
  	"filig;": "fi",
  	"fjlig;": "fj",
  	"fllig;": "fl",
  	"fltns;": "▱",
  	"forkv;": "⫙",
  	frac12: "½",
  	frac14: "¼",
  	frac34: "¾",
  	"frasl;": "⁄",
  	"frown;": "⌢",
  	"Gamma;": "Γ",
  	"gamma;": "γ",
  	"Gcirc;": "Ĝ",
  	"gcirc;": "ĝ",
  	"gescc;": "⪩",
  	"gimel;": "ℷ",
  	"gneqq;": "≩",
  	"gnsim;": "⋧",
  	"grave;": "`",
  	"gsime;": "⪎",
  	"gsiml;": "⪐",
  	"gtcir;": "⩺",
  	"gtdot;": "⋗",
  	"Hacek;": "ˇ",
  	"harrw;": "↭",
  	"Hcirc;": "Ĥ",
  	"hcirc;": "ĥ",
  	"hoarr;": "⇿",
  	Iacute: "Í",
  	iacute: "í",
  	"Icirc;": "Î",
  	"icirc;": "î",
  	"iexcl;": "¡",
  	Igrave: "Ì",
  	igrave: "ì",
  	"iiint;": "∭",
  	"iiota;": "℩",
  	"IJlig;": "IJ",
  	"ijlig;": "ij",
  	"Imacr;": "Ī",
  	"imacr;": "ī",
  	"image;": "ℑ",
  	"imath;": "ı",
  	"imped;": "Ƶ",
  	"infin;": "∞",
  	"Iogon;": "Į",
  	"iogon;": "į",
  	"iprod;": "⨼",
  	iquest: "¿",
  	"isinE;": "⋹",
  	"isins;": "⋴",
  	"isinv;": "∈",
  	"Iukcy;": "І",
  	"iukcy;": "і",
  	"Jcirc;": "Ĵ",
  	"jcirc;": "ĵ",
  	"jmath;": "ȷ",
  	"Jukcy;": "Є",
  	"jukcy;": "є",
  	"Kappa;": "Κ",
  	"kappa;": "κ",
  	"lAarr;": "⇚",
  	"langd;": "⦑",
  	"laquo;": "«",
  	"larrb;": "⇤",
  	"lates;": "⪭︀",
  	"lBarr;": "⤎",
  	"lbarr;": "⤌",
  	"lbbrk;": "❲",
  	"lbrke;": "⦋",
  	"lceil;": "⌈",
  	"ldquo;": "“",
  	"lescc;": "⪨",
  	"lhard;": "↽",
  	"lharu;": "↼",
  	"lhblk;": "▄",
  	"llarr;": "⇇",
  	"lltri;": "◺",
  	"lneqq;": "≨",
  	"lnsim;": "⋦",
  	"loang;": "⟬",
  	"loarr;": "⇽",
  	"lobrk;": "⟦",
  	"lopar;": "⦅",
  	"lrarr;": "⇆",
  	"lrhar;": "⇋",
  	"lrtri;": "⊿",
  	"lsime;": "⪍",
  	"lsimg;": "⪏",
  	"lsquo;": "‘",
  	"ltcir;": "⩹",
  	"ltdot;": "⋖",
  	"ltrie;": "⊴",
  	"ltrif;": "◂",
  	"mdash;": "—",
  	"mDDot;": "∺",
  	"micro;": "µ",
  	middot: "·",
  	"minus;": "−",
  	"mumap;": "⊸",
  	"nabla;": "∇",
  	"napid;": "≋̸",
  	"napos;": "ʼn",
  	"natur;": "♮",
  	"nbump;": "≎̸",
  	"ncong;": "≇",
  	"ndash;": "–",
  	"neArr;": "⇗",
  	"nearr;": "↗",
  	"nedot;": "≐̸",
  	"nesim;": "≂̸",
  	"ngeqq;": "≧̸",
  	"ngsim;": "≵",
  	"nhArr;": "⇎",
  	"nharr;": "↮",
  	"nhpar;": "⫲",
  	"nlArr;": "⇍",
  	"nlarr;": "↚",
  	"nleqq;": "≦̸",
  	"nless;": "≮",
  	"nlsim;": "≴",
  	"nltri;": "⋪",
  	"notin;": "∉",
  	"notni;": "∌",
  	"npart;": "∂̸",
  	"nprec;": "⊀",
  	"nrArr;": "⇏",
  	"nrarr;": "↛",
  	"nrtri;": "⋫",
  	"nsime;": "≄",
  	"nsmid;": "∤",
  	"nspar;": "∦",
  	"nsubE;": "⫅̸",
  	"nsube;": "⊈",
  	"nsucc;": "⊁",
  	"nsupE;": "⫆̸",
  	"nsupe;": "⊉",
  	Ntilde: "Ñ",
  	ntilde: "ñ",
  	"numsp;": " ",
  	"nvsim;": "∼⃒",
  	"nwArr;": "⇖",
  	"nwarr;": "↖",
  	Oacute: "Ó",
  	oacute: "ó",
  	"Ocirc;": "Ô",
  	"ocirc;": "ô",
  	"odash;": "⊝",
  	"OElig;": "Œ",
  	"oelig;": "œ",
  	"ofcir;": "⦿",
  	Ograve: "Ò",
  	ograve: "ò",
  	"ohbar;": "⦵",
  	"olarr;": "↺",
  	"olcir;": "⦾",
  	"oline;": "‾",
  	"Omacr;": "Ō",
  	"omacr;": "ō",
  	"Omega;": "Ω",
  	"omega;": "ω",
  	"operp;": "⦹",
  	"oplus;": "⊕",
  	"orarr;": "↻",
  	"order;": "ℴ",
  	Oslash: "Ø",
  	oslash: "ø",
  	Otilde: "Õ",
  	otilde: "õ",
  	"ovbar;": "⌽",
  	"parsl;": "⫽",
  	"phone;": "☎",
  	"plusb;": "⊞",
  	"pluse;": "⩲",
  	plusmn: "±",
  	"pound;": "£",
  	"prcue;": "≼",
  	"Prime;": "″",
  	"prime;": "′",
  	"prnap;": "⪹",
  	"prsim;": "≾",
  	"quest;": "?",
  	"rAarr;": "⇛",
  	"radic;": "√",
  	"rangd;": "⦒",
  	"range;": "⦥",
  	"raquo;": "»",
  	"rarrb;": "⇥",
  	"rarrc;": "⤳",
  	"rarrw;": "↝",
  	"ratio;": "∶",
  	"RBarr;": "⤐",
  	"rBarr;": "⤏",
  	"rbarr;": "⤍",
  	"rbbrk;": "❳",
  	"rbrke;": "⦌",
  	"rceil;": "⌉",
  	"rdquo;": "”",
  	"reals;": "ℝ",
  	"rhard;": "⇁",
  	"rharu;": "⇀",
  	"rlarr;": "⇄",
  	"rlhar;": "⇌",
  	"rnmid;": "⫮",
  	"roang;": "⟭",
  	"roarr;": "⇾",
  	"robrk;": "⟧",
  	"ropar;": "⦆",
  	"rrarr;": "⇉",
  	"rsquo;": "’",
  	"rtrie;": "⊵",
  	"rtrif;": "▸",
  	"sbquo;": "‚",
  	"sccue;": "≽",
  	"Scirc;": "Ŝ",
  	"scirc;": "ŝ",
  	"scnap;": "⪺",
  	"scsim;": "≿",
  	"sdotb;": "⊡",
  	"sdote;": "⩦",
  	"seArr;": "⇘",
  	"searr;": "↘",
  	"setmn;": "∖",
  	"sharp;": "♯",
  	"Sigma;": "Σ",
  	"sigma;": "σ",
  	"simeq;": "≃",
  	"simgE;": "⪠",
  	"simlE;": "⪟",
  	"simne;": "≆",
  	"slarr;": "←",
  	"smile;": "⌣",
  	"smtes;": "⪬︀",
  	"sqcap;": "⊓",
  	"sqcup;": "⊔",
  	"sqsub;": "⊏",
  	"sqsup;": "⊐",
  	"srarr;": "→",
  	"starf;": "★",
  	"strns;": "¯",
  	"subnE;": "⫋",
  	"subne;": "⊊",
  	"supnE;": "⫌",
  	"supne;": "⊋",
  	"swArr;": "⇙",
  	"swarr;": "↙",
  	"szlig;": "ß",
  	"Theta;": "Θ",
  	"theta;": "θ",
  	"thkap;": "≈",
  	"THORN;": "Þ",
  	"thorn;": "þ",
  	"Tilde;": "∼",
  	"tilde;": "˜",
  	"times;": "×",
  	"TRADE;": "™",
  	"trade;": "™",
  	"trisb;": "⧍",
  	"TSHcy;": "Ћ",
  	"tshcy;": "ћ",
  	"twixt;": "≬",
  	Uacute: "Ú",
  	uacute: "ú",
  	"Ubrcy;": "Ў",
  	"ubrcy;": "ў",
  	"Ucirc;": "Û",
  	"ucirc;": "û",
  	"udarr;": "⇅",
  	"udhar;": "⥮",
  	Ugrave: "Ù",
  	ugrave: "ù",
  	"uharl;": "↿",
  	"uharr;": "↾",
  	"uhblk;": "▀",
  	"ultri;": "◸",
  	"Umacr;": "Ū",
  	"umacr;": "ū",
  	"Union;": "⋃",
  	"Uogon;": "Ų",
  	"uogon;": "ų",
  	"uplus;": "⊎",
  	"upsih;": "ϒ",
  	"UpTee;": "⊥",
  	"Uring;": "Ů",
  	"uring;": "ů",
  	"urtri;": "◹",
  	"utdot;": "⋰",
  	"utrif;": "▴",
  	"uuarr;": "⇈",
  	"varpi;": "ϖ",
  	"vBarv;": "⫩",
  	"VDash;": "⊫",
  	"Vdash;": "⊩",
  	"vDash;": "⊨",
  	"vdash;": "⊢",
  	"veeeq;": "≚",
  	"vltri;": "⊲",
  	"vnsub;": "⊂⃒",
  	"vnsup;": "⊃⃒",
  	"vprop;": "∝",
  	"vrtri;": "⊳",
  	"Wcirc;": "Ŵ",
  	"wcirc;": "ŵ",
  	"Wedge;": "⋀",
  	"wedge;": "∧",
  	"xcirc;": "◯",
  	"xdtri;": "▽",
  	"xhArr;": "⟺",
  	"xharr;": "⟷",
  	"xlArr;": "⟸",
  	"xlarr;": "⟵",
  	"xodot;": "⨀",
  	"xrArr;": "⟹",
  	"xrarr;": "⟶",
  	"xutri;": "△",
  	Yacute: "Ý",
  	yacute: "ý",
  	"Ycirc;": "Ŷ",
  	"ycirc;": "ŷ",
  	"Aacute;": "Á",
  	"aacute;": "á",
  	"Abreve;": "Ă",
  	"abreve;": "ă",
  	"Agrave;": "À",
  	"agrave;": "à",
  	"andand;": "⩕",
  	"angmsd;": "∡",
  	"angsph;": "∢",
  	"apacir;": "⩯",
  	"approx;": "≈",
  	"Assign;": "≔",
  	"Atilde;": "Ã",
  	"atilde;": "ã",
  	"barvee;": "⊽",
  	"Barwed;": "⌆",
  	"barwed;": "⌅",
  	"becaus;": "∵",
  	"bernou;": "ℬ",
  	"bigcap;": "⋂",
  	"bigcup;": "⋃",
  	"bigvee;": "⋁",
  	"bkarow;": "⤍",
  	"bottom;": "⊥",
  	"bowtie;": "⋈",
  	"boxbox;": "⧉",
  	"bprime;": "‵",
  	"brvbar;": "¦",
  	"bullet;": "•",
  	"Bumpeq;": "≎",
  	"bumpeq;": "≏",
  	"Cacute;": "Ć",
  	"cacute;": "ć",
  	"capand;": "⩄",
  	"capcap;": "⩋",
  	"capcup;": "⩇",
  	"capdot;": "⩀",
  	"Ccaron;": "Č",
  	"ccaron;": "č",
  	"Ccedil;": "Ç",
  	"ccedil;": "ç",
  	"circeq;": "≗",
  	"cirmid;": "⫯",
  	"Colone;": "⩴",
  	"colone;": "≔",
  	"commat;": "@",
  	"compfn;": "∘",
  	"Conint;": "∯",
  	"conint;": "∮",
  	"coprod;": "∐",
  	"copysr;": "℗",
  	"cularr;": "↶",
  	"CupCap;": "≍",
  	"cupcap;": "⩆",
  	"cupcup;": "⩊",
  	"cupdot;": "⊍",
  	"curarr;": "↷",
  	"curren;": "¤",
  	"cylcty;": "⌭",
  	"Dagger;": "‡",
  	"dagger;": "†",
  	"daleth;": "ℸ",
  	"Dcaron;": "Ď",
  	"dcaron;": "ď",
  	"dfisht;": "⥿",
  	"divide;": "÷",
  	"divonx;": "⋇",
  	"dlcorn;": "⌞",
  	"dlcrop;": "⌍",
  	"dollar;": "$",
  	"DotDot;": "⃜",
  	"drcorn;": "⌟",
  	"drcrop;": "⌌",
  	"Dstrok;": "Đ",
  	"dstrok;": "đ",
  	"Eacute;": "É",
  	"eacute;": "é",
  	"easter;": "⩮",
  	"Ecaron;": "Ě",
  	"ecaron;": "ě",
  	"ecolon;": "≕",
  	"Egrave;": "È",
  	"egrave;": "è",
  	"egsdot;": "⪘",
  	"elsdot;": "⪗",
  	"emptyv;": "∅",
  	"emsp13;": " ",
  	"emsp14;": " ",
  	"eparsl;": "⧣",
  	"eqcirc;": "≖",
  	"equals;": "=",
  	"equest;": "≟",
  	"Exists;": "∃",
  	"female;": "♀",
  	"ffilig;": "ffi",
  	"ffllig;": "ffl",
  	"ForAll;": "∀",
  	"forall;": "∀",
  	"frac12;": "½",
  	"frac13;": "⅓",
  	"frac14;": "¼",
  	"frac15;": "⅕",
  	"frac16;": "⅙",
  	"frac18;": "⅛",
  	"frac23;": "⅔",
  	"frac25;": "⅖",
  	"frac34;": "¾",
  	"frac35;": "⅗",
  	"frac38;": "⅜",
  	"frac45;": "⅘",
  	"frac56;": "⅚",
  	"frac58;": "⅝",
  	"frac78;": "⅞",
  	"gacute;": "ǵ",
  	"Gammad;": "Ϝ",
  	"gammad;": "ϝ",
  	"Gbreve;": "Ğ",
  	"gbreve;": "ğ",
  	"Gcedil;": "Ģ",
  	"gesdot;": "⪀",
  	"gesles;": "⪔",
  	"gtlPar;": "⦕",
  	"gtrarr;": "⥸",
  	"gtrdot;": "⋗",
  	"gtrsim;": "≳",
  	"hairsp;": " ",
  	"hamilt;": "ℋ",
  	"HARDcy;": "Ъ",
  	"hardcy;": "ъ",
  	"hearts;": "♥",
  	"hellip;": "…",
  	"hercon;": "⊹",
  	"homtht;": "∻",
  	"horbar;": "―",
  	"hslash;": "ℏ",
  	"Hstrok;": "Ħ",
  	"hstrok;": "ħ",
  	"hybull;": "⁃",
  	"hyphen;": "‐",
  	"Iacute;": "Í",
  	"iacute;": "í",
  	"Igrave;": "Ì",
  	"igrave;": "ì",
  	"iiiint;": "⨌",
  	"iinfin;": "⧜",
  	"incare;": "℅",
  	"inodot;": "ı",
  	"intcal;": "⊺",
  	"iquest;": "¿",
  	"isinsv;": "⋳",
  	"Itilde;": "Ĩ",
  	"itilde;": "ĩ",
  	"Jsercy;": "Ј",
  	"jsercy;": "ј",
  	"kappav;": "ϰ",
  	"Kcedil;": "Ķ",
  	"kcedil;": "ķ",
  	"kgreen;": "ĸ",
  	"Lacute;": "Ĺ",
  	"lacute;": "ĺ",
  	"lagran;": "ℒ",
  	"Lambda;": "Λ",
  	"lambda;": "λ",
  	"langle;": "⟨",
  	"larrfs;": "⤝",
  	"larrhk;": "↩",
  	"larrlp;": "↫",
  	"larrpl;": "⤹",
  	"larrtl;": "↢",
  	"lAtail;": "⤛",
  	"latail;": "⤙",
  	"lbrace;": "{",
  	"lbrack;": "[",
  	"Lcaron;": "Ľ",
  	"lcaron;": "ľ",
  	"Lcedil;": "Ļ",
  	"lcedil;": "ļ",
  	"ldquor;": "„",
  	"lesdot;": "⩿",
  	"lesges;": "⪓",
  	"lfisht;": "⥼",
  	"lfloor;": "⌊",
  	"lharul;": "⥪",
  	"llhard;": "⥫",
  	"Lmidot;": "Ŀ",
  	"lmidot;": "ŀ",
  	"lmoust;": "⎰",
  	"loplus;": "⨭",
  	"lowast;": "∗",
  	"lowbar;": "_",
  	"lparlt;": "⦓",
  	"lrhard;": "⥭",
  	"lsaquo;": "‹",
  	"lsquor;": "‚",
  	"Lstrok;": "Ł",
  	"lstrok;": "ł",
  	"lthree;": "⋋",
  	"ltimes;": "⋉",
  	"ltlarr;": "⥶",
  	"ltrPar;": "⦖",
  	"mapsto;": "↦",
  	"marker;": "▮",
  	"mcomma;": "⨩",
  	"midast;": "*",
  	"midcir;": "⫰",
  	"middot;": "·",
  	"minusb;": "⊟",
  	"minusd;": "∸",
  	"mnplus;": "∓",
  	"models;": "⊧",
  	"mstpos;": "∾",
  	"Nacute;": "Ń",
  	"nacute;": "ń",
  	"nbumpe;": "≏̸",
  	"Ncaron;": "Ň",
  	"ncaron;": "ň",
  	"Ncedil;": "Ņ",
  	"ncedil;": "ņ",
  	"nearhk;": "⤤",
  	"nequiv;": "≢",
  	"nesear;": "⤨",
  	"nexist;": "∄",
  	"nltrie;": "⋬",
  	"notinE;": "⋹̸",
  	"nparsl;": "⫽⃥",
  	"nprcue;": "⋠",
  	"nrarrc;": "⤳̸",
  	"nrarrw;": "↝̸",
  	"nrtrie;": "⋭",
  	"nsccue;": "⋡",
  	"nsimeq;": "≄",
  	"Ntilde;": "Ñ",
  	"ntilde;": "ñ",
  	"numero;": "№",
  	"nVDash;": "⊯",
  	"nVdash;": "⊮",
  	"nvDash;": "⊭",
  	"nvdash;": "⊬",
  	"nvHarr;": "⤄",
  	"nvlArr;": "⤂",
  	"nvrArr;": "⤃",
  	"nwarhk;": "⤣",
  	"nwnear;": "⤧",
  	"Oacute;": "Ó",
  	"oacute;": "ó",
  	"Odblac;": "Ő",
  	"odblac;": "ő",
  	"odsold;": "⦼",
  	"Ograve;": "Ò",
  	"ograve;": "ò",
  	"ominus;": "⊖",
  	"origof;": "⊶",
  	"Oslash;": "Ø",
  	"oslash;": "ø",
  	"Otilde;": "Õ",
  	"otilde;": "õ",
  	"Otimes;": "⨷",
  	"otimes;": "⊗",
  	"parsim;": "⫳",
  	"percnt;": "%",
  	"period;": ".",
  	"permil;": "‰",
  	"phmmat;": "ℳ",
  	"planck;": "ℏ",
  	"plankv;": "ℏ",
  	"plusdo;": "∔",
  	"plusdu;": "⨥",
  	"plusmn;": "±",
  	"preceq;": "⪯",
  	"primes;": "ℙ",
  	"prnsim;": "⋨",
  	"propto;": "∝",
  	"prurel;": "⊰",
  	"puncsp;": " ",
  	"qprime;": "⁗",
  	"Racute;": "Ŕ",
  	"racute;": "ŕ",
  	"rangle;": "⟩",
  	"rarrap;": "⥵",
  	"rarrfs;": "⤞",
  	"rarrhk;": "↪",
  	"rarrlp;": "↬",
  	"rarrpl;": "⥅",
  	"Rarrtl;": "⤖",
  	"rarrtl;": "↣",
  	"rAtail;": "⤜",
  	"ratail;": "⤚",
  	"rbrace;": "}",
  	"rbrack;": "]",
  	"Rcaron;": "Ř",
  	"rcaron;": "ř",
  	"Rcedil;": "Ŗ",
  	"rcedil;": "ŗ",
  	"rdquor;": "”",
  	"rfisht;": "⥽",
  	"rfloor;": "⌋",
  	"rharul;": "⥬",
  	"rmoust;": "⎱",
  	"roplus;": "⨮",
  	"rpargt;": "⦔",
  	"rsaquo;": "›",
  	"rsquor;": "’",
  	"rthree;": "⋌",
  	"rtimes;": "⋊",
  	"Sacute;": "Ś",
  	"sacute;": "ś",
  	"Scaron;": "Š",
  	"scaron;": "š",
  	"Scedil;": "Ş",
  	"scedil;": "ş",
  	"scnsim;": "⋩",
  	"searhk;": "⤥",
  	"seswar;": "⤩",
  	"sfrown;": "⌢",
  	"SHCHcy;": "Щ",
  	"shchcy;": "щ",
  	"sigmaf;": "ς",
  	"sigmav;": "ς",
  	"simdot;": "⩪",
  	"smashp;": "⨳",
  	"SOFTcy;": "Ь",
  	"softcy;": "ь",
  	"solbar;": "⌿",
  	"spades;": "♠",
  	"sqcaps;": "⊓︀",
  	"sqcups;": "⊔︀",
  	"sqsube;": "⊑",
  	"sqsupe;": "⊒",
  	"Square;": "□",
  	"square;": "□",
  	"squarf;": "▪",
  	"ssetmn;": "∖",
  	"ssmile;": "⌣",
  	"sstarf;": "⋆",
  	"subdot;": "⪽",
  	"Subset;": "⋐",
  	"subset;": "⊂",
  	"subsim;": "⫇",
  	"subsub;": "⫕",
  	"subsup;": "⫓",
  	"succeq;": "⪰",
  	"supdot;": "⪾",
  	"Supset;": "⋑",
  	"supset;": "⊃",
  	"supsim;": "⫈",
  	"supsub;": "⫔",
  	"supsup;": "⫖",
  	"swarhk;": "⤦",
  	"swnwar;": "⤪",
  	"target;": "⌖",
  	"Tcaron;": "Ť",
  	"tcaron;": "ť",
  	"Tcedil;": "Ţ",
  	"tcedil;": "ţ",
  	"telrec;": "⌕",
  	"there4;": "∴",
  	"thetav;": "ϑ",
  	"thinsp;": " ",
  	"thksim;": "∼",
  	"timesb;": "⊠",
  	"timesd;": "⨰",
  	"topbot;": "⌶",
  	"topcir;": "⫱",
  	"tprime;": "‴",
  	"tridot;": "◬",
  	"Tstrok;": "Ŧ",
  	"tstrok;": "ŧ",
  	"Uacute;": "Ú",
  	"uacute;": "ú",
  	"Ubreve;": "Ŭ",
  	"ubreve;": "ŭ",
  	"Udblac;": "Ű",
  	"udblac;": "ű",
  	"ufisht;": "⥾",
  	"Ugrave;": "Ù",
  	"ugrave;": "ù",
  	"ulcorn;": "⌜",
  	"ulcrop;": "⌏",
  	"urcorn;": "⌝",
  	"urcrop;": "⌎",
  	"Utilde;": "Ũ",
  	"utilde;": "ũ",
  	"vangrt;": "⦜",
  	"varphi;": "ϕ",
  	"varrho;": "ϱ",
  	"Vdashl;": "⫦",
  	"veebar;": "⊻",
  	"vellip;": "⋮",
  	"Verbar;": "‖",
  	"verbar;": "|",
  	"vsubnE;": "⫋︀",
  	"vsubne;": "⊊︀",
  	"vsupnE;": "⫌︀",
  	"vsupne;": "⊋︀",
  	"Vvdash;": "⊪",
  	"wedbar;": "⩟",
  	"wedgeq;": "≙",
  	"weierp;": "℘",
  	"wreath;": "≀",
  	"xoplus;": "⨁",
  	"xotime;": "⨂",
  	"xsqcup;": "⨆",
  	"xuplus;": "⨄",
  	"xwedge;": "⋀",
  	"Yacute;": "Ý",
  	"yacute;": "ý",
  	"Zacute;": "Ź",
  	"zacute;": "ź",
  	"Zcaron;": "Ž",
  	"zcaron;": "ž",
  	"zeetrf;": "ℨ",
  	"alefsym;": "ℵ",
  	"angrtvb;": "⊾",
  	"angzarr;": "⍼",
  	"asympeq;": "≍",
  	"backsim;": "∽",
  	"Because;": "∵",
  	"because;": "∵",
  	"bemptyv;": "⦰",
  	"between;": "≬",
  	"bigcirc;": "◯",
  	"bigodot;": "⨀",
  	"bigstar;": "★",
  	"bnequiv;": "≡⃥",
  	"boxplus;": "⊞",
  	"Cayleys;": "ℭ",
  	"Cconint;": "∰",
  	"ccupssm;": "⩐",
  	"Cedilla;": "¸",
  	"cemptyv;": "⦲",
  	"cirscir;": "⧂",
  	"coloneq;": "≔",
  	"congdot;": "⩭",
  	"cudarrl;": "⤸",
  	"cudarrr;": "⤵",
  	"cularrp;": "⤽",
  	"curarrm;": "⤼",
  	"dbkarow;": "⤏",
  	"ddagger;": "‡",
  	"ddotseq;": "⩷",
  	"demptyv;": "⦱",
  	"Diamond;": "⋄",
  	"diamond;": "⋄",
  	"digamma;": "ϝ",
  	"dotplus;": "∔",
  	"DownTee;": "⊤",
  	"dwangle;": "⦦",
  	"Element;": "∈",
  	"Epsilon;": "Ε",
  	"epsilon;": "ε",
  	"eqcolon;": "≕",
  	"equivDD;": "⩸",
  	"gesdoto;": "⪂",
  	"gtquest;": "⩼",
  	"gtrless;": "≷",
  	"harrcir;": "⥈",
  	"Implies;": "⇒",
  	"intprod;": "⨼",
  	"isindot;": "⋵",
  	"larrbfs;": "⤟",
  	"larrsim;": "⥳",
  	"lbrksld;": "⦏",
  	"lbrkslu;": "⦍",
  	"ldrdhar;": "⥧",
  	"LeftTee;": "⊣",
  	"lesdoto;": "⪁",
  	"lessdot;": "⋖",
  	"lessgtr;": "≶",
  	"lesssim;": "≲",
  	"lotimes;": "⨴",
  	"lozenge;": "◊",
  	"ltquest;": "⩻",
  	"luruhar;": "⥦",
  	"maltese;": "✠",
  	"minusdu;": "⨪",
  	"napprox;": "≉",
  	"natural;": "♮",
  	"nearrow;": "↗",
  	"NewLine;": "\n",
  	"nexists;": "∄",
  	"NoBreak;": "⁠",
  	"notinva;": "∉",
  	"notinvb;": "⋷",
  	"notinvc;": "⋶",
  	"NotLess;": "≮",
  	"notniva;": "∌",
  	"notnivb;": "⋾",
  	"notnivc;": "⋽",
  	"npolint;": "⨔",
  	"npreceq;": "⪯̸",
  	"nsqsube;": "⋢",
  	"nsqsupe;": "⋣",
  	"nsubset;": "⊂⃒",
  	"nsucceq;": "⪰̸",
  	"nsupset;": "⊃⃒",
  	"nvinfin;": "⧞",
  	"nvltrie;": "⊴⃒",
  	"nvrtrie;": "⊵⃒",
  	"nwarrow;": "↖",
  	"olcross;": "⦻",
  	"Omicron;": "Ο",
  	"omicron;": "ο",
  	"orderof;": "ℴ",
  	"orslope;": "⩗",
  	"OverBar;": "‾",
  	"pertenk;": "‱",
  	"planckh;": "ℎ",
  	"pluscir;": "⨢",
  	"plussim;": "⨦",
  	"plustwo;": "⨧",
  	"precsim;": "≾",
  	"Product;": "∏",
  	"quatint;": "⨖",
  	"questeq;": "≟",
  	"rarrbfs;": "⤠",
  	"rarrsim;": "⥴",
  	"rbrksld;": "⦎",
  	"rbrkslu;": "⦐",
  	"rdldhar;": "⥩",
  	"realine;": "ℛ",
  	"rotimes;": "⨵",
  	"ruluhar;": "⥨",
  	"searrow;": "↘",
  	"simplus;": "⨤",
  	"simrarr;": "⥲",
  	"subedot;": "⫃",
  	"submult;": "⫁",
  	"subplus;": "⪿",
  	"subrarr;": "⥹",
  	"succsim;": "≿",
  	"supdsub;": "⫘",
  	"supedot;": "⫄",
  	"suphsol;": "⟉",
  	"suphsub;": "⫗",
  	"suplarr;": "⥻",
  	"supmult;": "⫂",
  	"supplus;": "⫀",
  	"swarrow;": "↙",
  	"topfork;": "⫚",
  	"triplus;": "⨹",
  	"tritime;": "⨻",
  	"UpArrow;": "↑",
  	"Uparrow;": "⇑",
  	"uparrow;": "↑",
  	"Upsilon;": "Υ",
  	"upsilon;": "υ",
  	"uwangle;": "⦧",
  	"vzigzag;": "⦚",
  	"zigrarr;": "⇝",
  	"andslope;": "⩘",
  	"angmsdaa;": "⦨",
  	"angmsdab;": "⦩",
  	"angmsdac;": "⦪",
  	"angmsdad;": "⦫",
  	"angmsdae;": "⦬",
  	"angmsdaf;": "⦭",
  	"angmsdag;": "⦮",
  	"angmsdah;": "⦯",
  	"angrtvbd;": "⦝",
  	"approxeq;": "≊",
  	"awconint;": "∳",
  	"backcong;": "≌",
  	"barwedge;": "⌅",
  	"bbrktbrk;": "⎶",
  	"bigoplus;": "⨁",
  	"bigsqcup;": "⨆",
  	"biguplus;": "⨄",
  	"bigwedge;": "⋀",
  	"boxminus;": "⊟",
  	"boxtimes;": "⊠",
  	"bsolhsub;": "⟈",
  	"capbrcup;": "⩉",
  	"circledR;": "®",
  	"circledS;": "Ⓢ",
  	"cirfnint;": "⨐",
  	"clubsuit;": "♣",
  	"cupbrcap;": "⩈",
  	"curlyvee;": "⋎",
  	"cwconint;": "∲",
  	"DDotrahd;": "⤑",
  	"doteqdot;": "≑",
  	"DotEqual;": "≐",
  	"dotminus;": "∸",
  	"drbkarow;": "⤐",
  	"dzigrarr;": "⟿",
  	"elinters;": "⏧",
  	"emptyset;": "∅",
  	"eqvparsl;": "⧥",
  	"fpartint;": "⨍",
  	"geqslant;": "⩾",
  	"gesdotol;": "⪄",
  	"gnapprox;": "⪊",
  	"hksearow;": "⤥",
  	"hkswarow;": "⤦",
  	"imagline;": "ℐ",
  	"imagpart;": "ℑ",
  	"infintie;": "⧝",
  	"integers;": "ℤ",
  	"Integral;": "∫",
  	"intercal;": "⊺",
  	"intlarhk;": "⨗",
  	"laemptyv;": "⦴",
  	"ldrushar;": "⥋",
  	"leqslant;": "⩽",
  	"lesdotor;": "⪃",
  	"LessLess;": "⪡",
  	"llcorner;": "⌞",
  	"lnapprox;": "⪉",
  	"lrcorner;": "⌟",
  	"lurdshar;": "⥊",
  	"mapstoup;": "↥",
  	"multimap;": "⊸",
  	"naturals;": "ℕ",
  	"ncongdot;": "⩭̸",
  	"NotEqual;": "≠",
  	"notindot;": "⋵̸",
  	"NotTilde;": "≁",
  	"otimesas;": "⨶",
  	"parallel;": "∥",
  	"PartialD;": "∂",
  	"plusacir;": "⨣",
  	"pointint;": "⨕",
  	"Precedes;": "≺",
  	"precneqq;": "⪵",
  	"precnsim;": "⋨",
  	"profalar;": "⌮",
  	"profline;": "⌒",
  	"profsurf;": "⌓",
  	"raemptyv;": "⦳",
  	"realpart;": "ℜ",
  	"RightTee;": "⊢",
  	"rppolint;": "⨒",
  	"rtriltri;": "⧎",
  	"scpolint;": "⨓",
  	"setminus;": "∖",
  	"shortmid;": "∣",
  	"smeparsl;": "⧤",
  	"sqsubset;": "⊏",
  	"sqsupset;": "⊐",
  	"subseteq;": "⊆",
  	"Succeeds;": "≻",
  	"succneqq;": "⪶",
  	"succnsim;": "⋩",
  	"SuchThat;": "∋",
  	"Superset;": "⊃",
  	"supseteq;": "⊇",
  	"thetasym;": "ϑ",
  	"thicksim;": "∼",
  	"timesbar;": "⨱",
  	"triangle;": "▵",
  	"triminus;": "⨺",
  	"trpezium;": "⏢",
  	"Uarrocir;": "⥉",
  	"ulcorner;": "⌜",
  	"UnderBar;": "_",
  	"urcorner;": "⌝",
  	"varkappa;": "ϰ",
  	"varsigma;": "ς",
  	"vartheta;": "ϑ",
  	"backprime;": "‵",
  	"backsimeq;": "⋍",
  	"Backslash;": "∖",
  	"bigotimes;": "⨂",
  	"CenterDot;": "·",
  	"centerdot;": "·",
  	"checkmark;": "✓",
  	"CircleDot;": "⊙",
  	"complexes;": "ℂ",
  	"Congruent;": "≡",
  	"Coproduct;": "∐",
  	"dotsquare;": "⊡",
  	"DoubleDot;": "¨",
  	"DownArrow;": "↓",
  	"Downarrow;": "⇓",
  	"downarrow;": "↓",
  	"DownBreve;": "̑",
  	"gtrapprox;": "⪆",
  	"gtreqless;": "⋛",
  	"gvertneqq;": "≩︀",
  	"heartsuit;": "♥",
  	"HumpEqual;": "≏",
  	"LeftArrow;": "←",
  	"Leftarrow;": "⇐",
  	"leftarrow;": "←",
  	"LeftFloor;": "⌊",
  	"lesseqgtr;": "⋚",
  	"LessTilde;": "≲",
  	"lvertneqq;": "≨︀",
  	"Mellintrf;": "ℳ",
  	"MinusPlus;": "∓",
  	"ngeqslant;": "⩾̸",
  	"nleqslant;": "⩽̸",
  	"NotCupCap;": "≭",
  	"NotExists;": "∄",
  	"NotSubset;": "⊂⃒",
  	"nparallel;": "∦",
  	"nshortmid;": "∤",
  	"nsubseteq;": "⊈",
  	"nsupseteq;": "⊉",
  	"OverBrace;": "⏞",
  	"pitchfork;": "⋔",
  	"PlusMinus;": "±",
  	"rationals;": "ℚ",
  	"spadesuit;": "♠",
  	"subseteqq;": "⫅",
  	"subsetneq;": "⊊",
  	"supseteqq;": "⫆",
  	"supsetneq;": "⊋",
  	"Therefore;": "∴",
  	"therefore;": "∴",
  	"ThinSpace;": " ",
  	"triangleq;": "≜",
  	"TripleDot;": "⃛",
  	"UnionPlus;": "⊎",
  	"varpropto;": "∝",
  	"Bernoullis;": "ℬ",
  	"circledast;": "⊛",
  	"CirclePlus;": "⊕",
  	"complement;": "∁",
  	"curlywedge;": "⋏",
  	"eqslantgtr;": "⪖",
  	"EqualTilde;": "≂",
  	"Fouriertrf;": "ℱ",
  	"gtreqqless;": "⪌",
  	"ImaginaryI;": "ⅈ",
  	"Laplacetrf;": "ℒ",
  	"LeftVector;": "↼",
  	"lessapprox;": "⪅",
  	"lesseqqgtr;": "⪋",
  	"Lleftarrow;": "⇚",
  	"lmoustache;": "⎰",
  	"longmapsto;": "⟼",
  	"mapstodown;": "↧",
  	"mapstoleft;": "↤",
  	"nLeftarrow;": "⇍",
  	"nleftarrow;": "↚",
  	"NotElement;": "∉",
  	"NotGreater;": "≯",
  	"nsubseteqq;": "⫅̸",
  	"nsupseteqq;": "⫆̸",
  	"precapprox;": "⪷",
  	"Proportion;": "∷",
  	"RightArrow;": "→",
  	"Rightarrow;": "⇒",
  	"rightarrow;": "→",
  	"RightFloor;": "⌋",
  	"rmoustache;": "⎱",
  	"sqsubseteq;": "⊑",
  	"sqsupseteq;": "⊒",
  	"subsetneqq;": "⫋",
  	"succapprox;": "⪸",
  	"supsetneqq;": "⫌",
  	"ThickSpace;": "  ",
  	"TildeEqual;": "≃",
  	"TildeTilde;": "≈",
  	"UnderBrace;": "⏟",
  	"UpArrowBar;": "⤒",
  	"UpTeeArrow;": "↥",
  	"upuparrows;": "⇈",
  	"varepsilon;": "ϵ",
  	"varnothing;": "∅",
  	"backepsilon;": "϶",
  	"blacksquare;": "▪",
  	"circledcirc;": "⊚",
  	"circleddash;": "⊝",
  	"CircleMinus;": "⊖",
  	"CircleTimes;": "⊗",
  	"curlyeqprec;": "⋞",
  	"curlyeqsucc;": "⋟",
  	"diamondsuit;": "♦",
  	"eqslantless;": "⪕",
  	"Equilibrium;": "⇌",
  	"expectation;": "ℰ",
  	"GreaterLess;": "≷",
  	"LeftCeiling;": "⌈",
  	"LessGreater;": "≶",
  	"MediumSpace;": " ",
  	"NotLessLess;": "≪̸",
  	"NotPrecedes;": "⊀",
  	"NotSucceeds;": "⊁",
  	"NotSuperset;": "⊃⃒",
  	"nRightarrow;": "⇏",
  	"nrightarrow;": "↛",
  	"OverBracket;": "⎴",
  	"preccurlyeq;": "≼",
  	"precnapprox;": "⪹",
  	"quaternions;": "ℍ",
  	"RightVector;": "⇀",
  	"Rrightarrow;": "⇛",
  	"RuleDelayed;": "⧴",
  	"SmallCircle;": "∘",
  	"SquareUnion;": "⊔",
  	"straightphi;": "ϕ",
  	"SubsetEqual;": "⊆",
  	"succcurlyeq;": "≽",
  	"succnapprox;": "⪺",
  	"thickapprox;": "≈",
  	"UpDownArrow;": "↕",
  	"Updownarrow;": "⇕",
  	"updownarrow;": "↕",
  	"VerticalBar;": "∣",
  	"blacklozenge;": "⧫",
  	"DownArrowBar;": "⤓",
  	"DownTeeArrow;": "↧",
  	"ExponentialE;": "ⅇ",
  	"exponentiale;": "ⅇ",
  	"GreaterEqual;": "≥",
  	"GreaterTilde;": "≳",
  	"HilbertSpace;": "ℋ",
  	"HumpDownHump;": "≎",
  	"Intersection;": "⋂",
  	"LeftArrowBar;": "⇤",
  	"LeftTeeArrow;": "↤",
  	"LeftTriangle;": "⊲",
  	"LeftUpVector;": "↿",
  	"NotCongruent;": "≢",
  	"NotHumpEqual;": "≏̸",
  	"NotLessEqual;": "≰",
  	"NotLessTilde;": "≴",
  	"Proportional;": "∝",
  	"RightCeiling;": "⌉",
  	"risingdotseq;": "≓",
  	"RoundImplies;": "⥰",
  	"ShortUpArrow;": "↑",
  	"SquareSubset;": "⊏",
  	"triangledown;": "▿",
  	"triangleleft;": "◃",
  	"UnderBracket;": "⎵",
  	"varsubsetneq;": "⊊︀",
  	"varsupsetneq;": "⊋︀",
  	"VerticalLine;": "|",
  	"ApplyFunction;": "⁡",
  	"bigtriangleup;": "△",
  	"blacktriangle;": "▴",
  	"DifferentialD;": "ⅆ",
  	"divideontimes;": "⋇",
  	"DoubleLeftTee;": "⫤",
  	"DoubleUpArrow;": "⇑",
  	"fallingdotseq;": "≒",
  	"hookleftarrow;": "↩",
  	"leftarrowtail;": "↢",
  	"leftharpoonup;": "↼",
  	"LeftTeeVector;": "⥚",
  	"LeftVectorBar;": "⥒",
  	"LessFullEqual;": "≦",
  	"LongLeftArrow;": "⟵",
  	"Longleftarrow;": "⟸",
  	"longleftarrow;": "⟵",
  	"looparrowleft;": "↫",
  	"measuredangle;": "∡",
  	"NotEqualTilde;": "≂̸",
  	"NotTildeEqual;": "≄",
  	"NotTildeTilde;": "≉",
  	"ntriangleleft;": "⋪",
  	"Poincareplane;": "ℌ",
  	"PrecedesEqual;": "⪯",
  	"PrecedesTilde;": "≾",
  	"RightArrowBar;": "⇥",
  	"RightTeeArrow;": "↦",
  	"RightTriangle;": "⊳",
  	"RightUpVector;": "↾",
  	"shortparallel;": "∥",
  	"smallsetminus;": "∖",
  	"SucceedsEqual;": "⪰",
  	"SucceedsTilde;": "≿",
  	"SupersetEqual;": "⊇",
  	"triangleright;": "▹",
  	"UpEquilibrium;": "⥮",
  	"upharpoonleft;": "↿",
  	"varsubsetneqq;": "⫋︀",
  	"varsupsetneqq;": "⫌︀",
  	"VerticalTilde;": "≀",
  	"VeryThinSpace;": " ",
  	"curvearrowleft;": "↶",
  	"DiacriticalDot;": "˙",
  	"doublebarwedge;": "⌆",
  	"DoubleRightTee;": "⊨",
  	"downdownarrows;": "⇊",
  	"DownLeftVector;": "↽",
  	"GreaterGreater;": "⪢",
  	"hookrightarrow;": "↪",
  	"HorizontalLine;": "─",
  	"InvisibleComma;": "⁣",
  	"InvisibleTimes;": "⁢",
  	"LeftDownVector;": "⇃",
  	"leftleftarrows;": "⇇",
  	"LeftRightArrow;": "↔",
  	"Leftrightarrow;": "⇔",
  	"leftrightarrow;": "↔",
  	"leftthreetimes;": "⋋",
  	"LessSlantEqual;": "⩽",
  	"LongRightArrow;": "⟶",
  	"Longrightarrow;": "⟹",
  	"longrightarrow;": "⟶",
  	"looparrowright;": "↬",
  	"LowerLeftArrow;": "↙",
  	"NestedLessLess;": "≪",
  	"NotGreaterLess;": "≹",
  	"NotLessGreater;": "≸",
  	"NotSubsetEqual;": "⊈",
  	"NotVerticalBar;": "∤",
  	"nshortparallel;": "∦",
  	"ntriangleright;": "⋫",
  	"OpenCurlyQuote;": "‘",
  	"ReverseElement;": "∋",
  	"rightarrowtail;": "↣",
  	"rightharpoonup;": "⇀",
  	"RightTeeVector;": "⥛",
  	"RightVectorBar;": "⥓",
  	"ShortDownArrow;": "↓",
  	"ShortLeftArrow;": "←",
  	"SquareSuperset;": "⊐",
  	"TildeFullEqual;": "≅",
  	"trianglelefteq;": "⊴",
  	"upharpoonright;": "↾",
  	"UpperLeftArrow;": "↖",
  	"ZeroWidthSpace;": "​",
  	"bigtriangledown;": "▽",
  	"circlearrowleft;": "↺",
  	"CloseCurlyQuote;": "’",
  	"ContourIntegral;": "∮",
  	"curvearrowright;": "↷",
  	"DoubleDownArrow;": "⇓",
  	"DoubleLeftArrow;": "⇐",
  	"downharpoonleft;": "⇃",
  	"DownRightVector;": "⇁",
  	"leftharpoondown;": "↽",
  	"leftrightarrows;": "⇆",
  	"LeftRightVector;": "⥎",
  	"LeftTriangleBar;": "⧏",
  	"LeftUpTeeVector;": "⥠",
  	"LeftUpVectorBar;": "⥘",
  	"LowerRightArrow;": "↘",
  	"nLeftrightarrow;": "⇎",
  	"nleftrightarrow;": "↮",
  	"NotGreaterEqual;": "≱",
  	"NotGreaterTilde;": "≵",
  	"NotHumpDownHump;": "≎̸",
  	"NotLeftTriangle;": "⋪",
  	"NotSquareSubset;": "⊏̸",
  	"ntrianglelefteq;": "⋬",
  	"OverParenthesis;": "⏜",
  	"RightDownVector;": "⇂",
  	"rightleftarrows;": "⇄",
  	"rightsquigarrow;": "↝",
  	"rightthreetimes;": "⋌",
  	"ShortRightArrow;": "→",
  	"straightepsilon;": "ϵ",
  	"trianglerighteq;": "⊵",
  	"UpperRightArrow;": "↗",
  	"vartriangleleft;": "⊲",
  	"circlearrowright;": "↻",
  	"DiacriticalAcute;": "´",
  	"DiacriticalGrave;": "`",
  	"DiacriticalTilde;": "˜",
  	"DoubleRightArrow;": "⇒",
  	"DownArrowUpArrow;": "⇵",
  	"downharpoonright;": "⇂",
  	"EmptySmallSquare;": "◻",
  	"GreaterEqualLess;": "⋛",
  	"GreaterFullEqual;": "≧",
  	"LeftAngleBracket;": "⟨",
  	"LeftUpDownVector;": "⥑",
  	"LessEqualGreater;": "⋚",
  	"NonBreakingSpace;": " ",
  	"NotPrecedesEqual;": "⪯̸",
  	"NotRightTriangle;": "⋫",
  	"NotSucceedsEqual;": "⪰̸",
  	"NotSucceedsTilde;": "≿̸",
  	"NotSupersetEqual;": "⊉",
  	"ntrianglerighteq;": "⋭",
  	"rightharpoondown;": "⇁",
  	"rightrightarrows;": "⇉",
  	"RightTriangleBar;": "⧐",
  	"RightUpTeeVector;": "⥜",
  	"RightUpVectorBar;": "⥔",
  	"twoheadleftarrow;": "↞",
  	"UnderParenthesis;": "⏝",
  	"UpArrowDownArrow;": "⇅",
  	"vartriangleright;": "⊳",
  	"blacktriangledown;": "▾",
  	"blacktriangleleft;": "◂",
  	"DoubleUpDownArrow;": "⇕",
  	"DoubleVerticalBar;": "∥",
  	"DownLeftTeeVector;": "⥞",
  	"DownLeftVectorBar;": "⥖",
  	"FilledSmallSquare;": "◼",
  	"GreaterSlantEqual;": "⩾",
  	"LeftDoubleBracket;": "⟦",
  	"LeftDownTeeVector;": "⥡",
  	"LeftDownVectorBar;": "⥙",
  	"leftrightharpoons;": "⇋",
  	"LeftTriangleEqual;": "⊴",
  	"NegativeThinSpace;": "​",
  	"NotGreaterGreater;": "≫̸",
  	"NotLessSlantEqual;": "⩽̸",
  	"NotNestedLessLess;": "⪡̸",
  	"NotReverseElement;": "∌",
  	"NotSquareSuperset;": "⊐̸",
  	"NotTildeFullEqual;": "≇",
  	"RightAngleBracket;": "⟩",
  	"rightleftharpoons;": "⇌",
  	"RightUpDownVector;": "⥏",
  	"SquareSubsetEqual;": "⊑",
  	"twoheadrightarrow;": "↠",
  	"VerticalSeparator;": "❘",
  	"blacktriangleright;": "▸",
  	"DownRightTeeVector;": "⥟",
  	"DownRightVectorBar;": "⥗",
  	"LongLeftRightArrow;": "⟷",
  	"Longleftrightarrow;": "⟺",
  	"longleftrightarrow;": "⟷",
  	"NegativeThickSpace;": "​",
  	"NotLeftTriangleBar;": "⧏̸",
  	"PrecedesSlantEqual;": "≼",
  	"ReverseEquilibrium;": "⇋",
  	"RightDoubleBracket;": "⟧",
  	"RightDownTeeVector;": "⥝",
  	"RightDownVectorBar;": "⥕",
  	"RightTriangleEqual;": "⊵",
  	"SquareIntersection;": "⊓",
  	"SucceedsSlantEqual;": "≽",
  	"DoubleLongLeftArrow;": "⟸",
  	"DownLeftRightVector;": "⥐",
  	"LeftArrowRightArrow;": "⇆",
  	"leftrightsquigarrow;": "↭",
  	"NegativeMediumSpace;": "​",
  	"NotGreaterFullEqual;": "≧̸",
  	"NotRightTriangleBar;": "⧐̸",
  	"RightArrowLeftArrow;": "⇄",
  	"SquareSupersetEqual;": "⊒",
  	"CapitalDifferentialD;": "ⅅ",
  	"DoubleLeftRightArrow;": "⇔",
  	"DoubleLongRightArrow;": "⟹",
  	"EmptyVerySmallSquare;": "▫",
  	"NestedGreaterGreater;": "≫",
  	"NotDoubleVerticalBar;": "∦",
  	"NotGreaterSlantEqual;": "⩾̸",
  	"NotLeftTriangleEqual;": "⋬",
  	"NotSquareSubsetEqual;": "⋢",
  	"OpenCurlyDoubleQuote;": "“",
  	"ReverseUpEquilibrium;": "⥯",
  	"CloseCurlyDoubleQuote;": "”",
  	"DoubleContourIntegral;": "∯",
  	"FilledVerySmallSquare;": "▪",
  	"NegativeVeryThinSpace;": "​",
  	"NotPrecedesSlantEqual;": "⋠",
  	"NotRightTriangleEqual;": "⋭",
  	"NotSucceedsSlantEqual;": "⋡",
  	"DiacriticalDoubleAcute;": "˝",
  	"NotSquareSupersetEqual;": "⋣",
  	"NotNestedGreaterGreater;": "⪢̸",
  	"ClockwiseContourIntegral;": "∲",
  	"DoubleLongLeftRightArrow;": "⟺",
  	"CounterClockwiseContourIntegral;": "∳"
  };

  // lazy compute this to make this file tree-shakable for browser
  let maxCRNameLength;
  const decodeHtml = (rawText, asAttr) => {
      let offset = 0;
      const end = rawText.length;
      let decodedText = '';
      function advance(length) {
          offset += length;
          rawText = rawText.slice(length);
      }
      while (offset < end) {
          const head = /&(?:#x?)?/i.exec(rawText);
          if (!head || offset + head.index >= end) {
              const remaining = end - offset;
              decodedText += rawText.slice(0, remaining);
              advance(remaining);
              break;
          }
          // Advance to the "&".
          decodedText += rawText.slice(0, head.index);
          advance(head.index);
          if (head[0] === '&') {
              // Named character reference.
              let name = '';
              let value = undefined;
              if (/[0-9a-z]/i.test(rawText[1])) {
                  if (!maxCRNameLength) {
                      maxCRNameLength = Object.keys(namedCharacterReferences).reduce((max, name) => Math.max(max, name.length), 0);
                  }
                  for (let length = maxCRNameLength; !value && length > 0; --length) {
                      name = rawText.substr(1, length);
                      value = namedCharacterReferences[name];
                  }
                  if (value) {
                      const semi = name.endsWith(';');
                      if (asAttr &&
                          !semi &&
                          /[=a-z0-9]/i.test(rawText[name.length + 1] || '')) {
                          decodedText += '&' + name;
                          advance(1 + name.length);
                      }
                      else {
                          decodedText += value;
                          advance(1 + name.length);
                      }
                  }
                  else {
                      decodedText += '&' + name;
                      advance(1 + name.length);
                  }
              }
              else {
                  decodedText += '&';
                  advance(1);
              }
          }
          else {
              // Numeric character reference.
              const hex = head[0] === '&#x';
              const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/;
              const body = pattern.exec(rawText);
              if (!body) {
                  decodedText += head[0];
                  advance(head[0].length);
              }
              else {
                  // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
                  let cp = Number.parseInt(body[1], hex ? 16 : 10);
                  if (cp === 0) {
                      cp = 0xfffd;
                  }
                  else if (cp > 0x10ffff) {
                      cp = 0xfffd;
                  }
                  else if (cp >= 0xd800 && cp <= 0xdfff) {
                      cp = 0xfffd;
                  }
                  else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) ;
                  else if ((cp >= 0x01 && cp <= 0x08) ||
                      cp === 0x0b ||
                      (cp >= 0x0d && cp <= 0x1f) ||
                      (cp >= 0x7f && cp <= 0x9f)) {
                      cp = CCR_REPLACEMENTS[cp] || cp;
                  }
                  decodedText += String.fromCodePoint(cp);
                  advance(body[0].length);
              }
          }
      }
      return decodedText;
  };
  // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
  const CCR_REPLACEMENTS = {
      0x80: 0x20ac,
      0x82: 0x201a,
      0x83: 0x0192,
      0x84: 0x201e,
      0x85: 0x2026,
      0x86: 0x2020,
      0x87: 0x2021,
      0x88: 0x02c6,
      0x89: 0x2030,
      0x8a: 0x0160,
      0x8b: 0x2039,
      0x8c: 0x0152,
      0x8e: 0x017d,
      0x91: 0x2018,
      0x92: 0x2019,
      0x93: 0x201c,
      0x94: 0x201d,
      0x95: 0x2022,
      0x96: 0x2013,
      0x97: 0x2014,
      0x98: 0x02dc,
      0x99: 0x2122,
      0x9a: 0x0161,
      0x9b: 0x203a,
      0x9c: 0x0153,
      0x9e: 0x017e,
      0x9f: 0x0178
  };

  const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
  const parserOptions = {
      isVoidTag,
      isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
      isPreTag: tag => tag === 'pre',
      decodeEntities:  decodeHtml,
      isBuiltInComponent: (tag) => {
          if (isBuiltInType(tag, `Transition`)) {
              return TRANSITION;
          }
          else if (isBuiltInType(tag, `TransitionGroup`)) {
              return TRANSITION_GROUP;
          }
      },
      // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
      getNamespace(tag, parent) {
          let ns = parent ? parent.ns : 0 /* HTML */;
          if (parent && ns === 2 /* MATH_ML */) {
              if (parent.tag === 'annotation-xml') {
                  if (tag === 'svg') {
                      return 1 /* SVG */;
                  }
                  if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
                      a.name === 'encoding' &&
                      a.value != null &&
                      (a.value.content === 'text/html' ||
                          a.value.content === 'application/xhtml+xml'))) {
                      ns = 0 /* HTML */;
                  }
              }
              else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
                  tag !== 'mglyph' &&
                  tag !== 'malignmark') {
                  ns = 0 /* HTML */;
              }
          }
          else if (parent && ns === 1 /* SVG */) {
              if (parent.tag === 'foreignObject' ||
                  parent.tag === 'desc' ||
                  parent.tag === 'title') {
                  ns = 0 /* HTML */;
              }
          }
          if (ns === 0 /* HTML */) {
              if (tag === 'svg') {
                  return 1 /* SVG */;
              }
              if (tag === 'math') {
                  return 2 /* MATH_ML */;
              }
          }
          return ns;
      },
      // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
      getTextMode({ tag, ns }) {
          if (ns === 0 /* HTML */) {
              if (tag === 'textarea' || tag === 'title') {
                  return 1 /* RCDATA */;
              }
              if (isRawTextContainer(tag)) {
                  return 2 /* RAWTEXT */;
              }
          }
          return 0 /* DATA */;
      }
  };

  // Parse inline CSS strings for static style attributes into an object.
  // This is a NodeTransform since it works on the static `style` attribute and
  // converts it into a dynamic equivalent:
  // style="color: red" -> :style='{ "color": "red" }'
  // It is then processed by `transformElement` and included in the generated
  // props.
  const transformStyle = node => {
      if (node.type === 1 /* ELEMENT */) {
          node.props.forEach((p, i) => {
              if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
                  // replace p with an expression node
                  node.props[i] = {
                      type: 7 /* DIRECTIVE */,
                      name: `bind`,
                      arg: createSimpleExpression(`style`, true, p.loc),
                      exp: parseInlineCSS(p.value.content, p.loc),
                      modifiers: [],
                      loc: p.loc
                  };
              }
          });
      }
  };
  const parseInlineCSS = (cssText, loc) => {
      const normalized = parseStringStyle(cssText);
      return createSimpleExpression(JSON.stringify(normalized), false, loc, true);
  };

  function createDOMCompilerError(code, loc) {
      return createCompilerError(code, loc,  DOMErrorMessages );
  }
  const DOMErrorMessages = {
      [49 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
      [50 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
      [51 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
      [52 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
      [53 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
      [54 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
      [55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
      [56 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
      [57 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
      [58 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
      [59 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
  };

  const transformVHtml = (dir, node, context) => {
      const { exp, loc } = dir;
      if (!exp) {
          context.onError(createDOMCompilerError(49 /* X_V_HTML_NO_EXPRESSION */, loc));
      }
      if (node.children.length) {
          context.onError(createDOMCompilerError(50 /* X_V_HTML_WITH_CHILDREN */, loc));
          node.children.length = 0;
      }
      return {
          props: [
              createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
          ]
      };
  };

  const transformVText = (dir, node, context) => {
      const { exp, loc } = dir;
      if (!exp) {
          context.onError(createDOMCompilerError(51 /* X_V_TEXT_NO_EXPRESSION */, loc));
      }
      if (node.children.length) {
          context.onError(createDOMCompilerError(52 /* X_V_TEXT_WITH_CHILDREN */, loc));
          node.children.length = 0;
      }
      return {
          props: [
              createObjectProperty(createSimpleExpression(`textContent`, true, loc), exp || createSimpleExpression('', true))
          ]
      };
  };

  const transformModel$1 = (dir, node, context) => {
      const baseResult = transformModel(dir, node, context);
      // base transform has errors OR component v-model (only need props)
      if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
          return baseResult;
      }
      if (dir.arg) {
          context.onError(createDOMCompilerError(54 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
      }
      function checkDuplicatedValue() {
          const value = findProp(node, 'value');
          if (value) {
              context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
          }
      }
      const { tag } = node;
      const isCustomElement = context.isCustomElement(tag);
      if (tag === 'input' ||
          tag === 'textarea' ||
          tag === 'select' ||
          isCustomElement) {
          let directiveToUse = V_MODEL_TEXT;
          let isInvalidType = false;
          if (tag === 'input' || isCustomElement) {
              const type = findProp(node, `type`);
              if (type) {
                  if (type.type === 7 /* DIRECTIVE */) {
                      // :type="foo"
                      directiveToUse = V_MODEL_DYNAMIC;
                  }
                  else if (type.value) {
                      switch (type.value.content) {
                          case 'radio':
                              directiveToUse = V_MODEL_RADIO;
                              break;
                          case 'checkbox':
                              directiveToUse = V_MODEL_CHECKBOX;
                              break;
                          case 'file':
                              isInvalidType = true;
                              context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
                              break;
                          default:
                              // text type
                               checkDuplicatedValue();
                              break;
                      }
                  }
              }
              else if (hasDynamicKeyVBind(node)) {
                  // element has bindings with dynamic keys, which can possibly contain
                  // "type".
                  directiveToUse = V_MODEL_DYNAMIC;
              }
              else {
                  // text type
                   checkDuplicatedValue();
              }
          }
          else if (tag === 'select') {
              directiveToUse = V_MODEL_SELECT;
          }
          else {
              // textarea
               checkDuplicatedValue();
          }
          // inject runtime directive
          // by returning the helper symbol via needRuntime
          // the import will replaced a resolveDirective call.
          if (!isInvalidType) {
              baseResult.needRuntime = context.helper(directiveToUse);
          }
      }
      else {
          context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
      }
      // native vmodel doesn't need the `modelValue` props since they are also
      // passed to the runtime as `binding.value`. removing it reduces code size.
      baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
          p.key.content === 'modelValue'));
      return baseResult;
  };

  const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
  const isNonKeyModifier = /*#__PURE__*/ makeMap(
  // event propagation management
`stop,prevent,self,`   +
      // system modifiers + exact
      `ctrl,shift,alt,meta,exact,` +
      // mouse
      `middle`);
  // left & right could be mouse or key modifiers based on event type
  const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
  const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
  const resolveModifiers = (key, modifiers) => {
      const keyModifiers = [];
      const nonKeyModifiers = [];
      const eventOptionModifiers = [];
      for (let i = 0; i < modifiers.length; i++) {
          const modifier = modifiers[i];
          if (isEventOptionModifier(modifier)) {
              // eventOptionModifiers: modifiers for addEventListener() options,
              // e.g. .passive & .capture
              eventOptionModifiers.push(modifier);
          }
          else {
              // runtimeModifiers: modifiers that needs runtime guards
              if (maybeKeyModifier(modifier)) {
                  if (isStaticExp(key)) {
                      if (isKeyboardEvent(key.content)) {
                          keyModifiers.push(modifier);
                      }
                      else {
                          nonKeyModifiers.push(modifier);
                      }
                  }
                  else {
                      keyModifiers.push(modifier);
                      nonKeyModifiers.push(modifier);
                  }
              }
              else {
                  if (isNonKeyModifier(modifier)) {
                      nonKeyModifiers.push(modifier);
                  }
                  else {
                      keyModifiers.push(modifier);
                  }
              }
          }
      }
      return {
          keyModifiers,
          nonKeyModifiers,
          eventOptionModifiers
      };
  };
  const transformClick = (key, event) => {
      const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
      return isStaticClick
          ? createSimpleExpression(event, true)
          : key.type !== 4 /* SIMPLE_EXPRESSION */
              ? createCompoundExpression([
                  `(`,
                  key,
                  `) === "onClick" ? "${event}" : (`,
                  key,
                  `)`
              ])
              : key;
  };
  const transformOn$1 = (dir, node, context) => {
      return transformOn(dir, node, context, baseResult => {
          const { modifiers } = dir;
          if (!modifiers.length)
              return baseResult;
          let { key, value: handlerExp } = baseResult.props[0];
          const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers);
          // normalize click.right and click.middle since they don't actually fire
          if (nonKeyModifiers.includes('right')) {
              key = transformClick(key, `onContextmenu`);
          }
          if (nonKeyModifiers.includes('middle')) {
              key = transformClick(key, `onMouseup`);
          }
          if (nonKeyModifiers.length) {
              handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
                  handlerExp,
                  JSON.stringify(nonKeyModifiers)
              ]);
          }
          if (keyModifiers.length &&
              // if event name is dynamic, always wrap with keys guard
              (!isStaticExp(key) || isKeyboardEvent(key.content))) {
              handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
                  handlerExp,
                  JSON.stringify(keyModifiers)
              ]);
          }
          if (eventOptionModifiers.length) {
              const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
              key = isStaticExp(key)
                  ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
                  : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
          }
          return {
              props: [createObjectProperty(key, handlerExp)]
          };
      });
  };

  const transformShow = (dir, node, context) => {
      const { exp, loc } = dir;
      if (!exp) {
          context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */, loc));
      }
      return {
          props: [],
          needRuntime: context.helper(V_SHOW)
      };
  };

  const warnTransitionChildren = (node, context) => {
      if (node.type === 1 /* ELEMENT */ &&
          node.tagType === 1 /* COMPONENT */) {
          const component = context.isBuiltInComponent(node.tag);
          if (component === TRANSITION) {
              return () => {
                  if (node.children.length && hasMultipleChildren(node)) {
                      context.onError(createDOMCompilerError(58 /* X_TRANSITION_INVALID_CHILDREN */, {
                          start: node.children[0].loc.start,
                          end: node.children[node.children.length - 1].loc.end,
                          source: ''
                      }));
                  }
              };
          }
      }
  };
  function hasMultipleChildren(node) {
      // #1352 filter out potential comment nodes.
      const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */));
      const child = children[0];
      return (children.length !== 1 ||
          child.type === 11 /* FOR */ ||
          (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
  }

  /**
   * This module is Node-only.
   */
  /**
   * Turn eligible hoisted static trees into stringified static nodes, e.g.
   *
   * ```js
   * const _hoisted_1 = createStaticVNode(`<div class="foo">bar</div>`)
   * ```
   *
   * A single static vnode can contain stringified content for **multiple**
   * consecutive nodes (element and plain text), called a "chunk".
   * `@vue/runtime-dom` will create the content via innerHTML in a hidden
   * container element and insert all the nodes in place. The call must also
   * provide the number of nodes contained in the chunk so that during hydration
   * we can know how many nodes the static vnode should adopt.
   *
   * The optimization scans a children list that contains hoisted nodes, and
   * tries to find the largest chunk of consecutive hoisted nodes before running
   * into a non-hoisted node or the end of the list. A chunk is then converted
   * into a single static vnode and replaces the hoisted expression of the first
   * node in the chunk. Other nodes in the chunk are considered "merged" and
   * therefore removed from both the hoist list and the children array.
   *
   * This optimization is only performed in Node.js.
   */
  const stringifyStatic = (children, context, parent) => {
      if (parent.type === 1 /* ELEMENT */ &&
          (parent.tagType === 1 /* COMPONENT */ ||
              parent.tagType === 3 /* TEMPLATE */)) {
          return;
      }
      let nc = 0; // current node count
      let ec = 0; // current element with binding count
      const currentChunk = [];
      const stringifyCurrentChunk = (currentIndex) => {
          if (nc >= 20 /* NODE_COUNT */ ||
              ec >= 5 /* ELEMENT_WITH_BINDING_COUNT */) {
              // combine all currently eligible nodes into a single static vnode call
              const staticCall = createCallExpression(context.helper(CREATE_STATIC), [
                  JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')),
                  // the 2nd argument indicates the number of DOM nodes this static vnode
                  // will insert / hydrate
                  String(currentChunk.length)
              ]);
              // replace the first node's hoisted expression with the static vnode call
              replaceHoist(currentChunk[0], staticCall, context);
              if (currentChunk.length > 1) {
                  for (let i = 1; i < currentChunk.length; i++) {
                      // for the merged nodes, set their hoisted expression to null
                      replaceHoist(currentChunk[i], null, context);
                  }
                  // also remove merged nodes from children
                  const deleteCount = currentChunk.length - 1;
                  children.splice(currentIndex - currentChunk.length + 1, deleteCount);
                  return deleteCount;
              }
          }
          return 0;
      };
      let i = 0;
      for (; i < children.length; i++) {
          const child = children[i];
          const hoisted = getHoistedNode(child);
          if (hoisted) {
              // presence of hoisted means child must be a stringifiable node
              const node = child;
              const result = analyzeNode(node);
              if (result) {
                  // node is stringifiable, record state
                  nc += result[0];
                  ec += result[1];
                  currentChunk.push(node);
                  continue;
              }
          }
          // we only reach here if we ran into a node that is not stringifiable
          // check if currently analyzed nodes meet criteria for stringification.
          // adjust iteration index
          i -= stringifyCurrentChunk(i);
          // reset state
          nc = 0;
          ec = 0;
          currentChunk.length = 0;
      }
      // in case the last node was also stringifiable
      stringifyCurrentChunk(i);
  };
  const getHoistedNode = (node) => ((node.type === 1 /* ELEMENT */ && node.tagType === 0 /* ELEMENT */) ||
      node.type == 12 /* TEXT_CALL */) &&
      node.codegenNode &&
      node.codegenNode.type === 4 /* SIMPLE_EXPRESSION */ &&
      node.codegenNode.hoisted;
  const dataAriaRE = /^(data|aria)-/;
  const isStringifiableAttr = (name) => {
      return isKnownAttr(name) || dataAriaRE.test(name);
  };
  const replaceHoist = (node, replacement, context) => {
      const hoistToReplace = node.codegenNode.hoisted;
      context.hoists[context.hoists.indexOf(hoistToReplace)] = replacement;
  };
  const isNonStringifiable = /*#__PURE__*/ makeMap(`caption,thead,tr,th,tbody,td,tfoot,colgroup,col`);
  /**
   * for a hoisted node, analyze it and return:
   * - false: bailed (contains runtime constant)
   * - [nc, ec] where
   *   - nc is the number of nodes inside
   *   - ec is the number of element with bindings inside
   */
  function analyzeNode(node) {
      if (node.type === 1 /* ELEMENT */ && isNonStringifiable(node.tag)) {
          return false;
      }
      if (node.type === 12 /* TEXT_CALL */) {
          return [1, 0];
      }
      let nc = 1; // node count
      let ec = node.props.length > 0 ? 1 : 0; // element w/ binding count
      let bailed = false;
      const bail = () => {
          bailed = true;
          return false;
      };
      // TODO: check for cases where using innerHTML will result in different
      // output compared to imperative node insertions.
      // probably only need to check for most common case
      // i.e. non-phrasing-content tags inside `<p>`
      function walk(node) {
          for (let i = 0; i < node.props.length; i++) {
              const p = node.props[i];
              // bail on non-attr bindings
              if (p.type === 6 /* ATTRIBUTE */ && !isStringifiableAttr(p.name)) {
                  return bail();
              }
              if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
                  // bail on non-attr bindings
                  if (p.arg &&
                      (p.arg.type === 8 /* COMPOUND_EXPRESSION */ ||
                          (p.arg.isStatic && !isStringifiableAttr(p.arg.content)))) {
                      return bail();
                  }
              }
          }
          for (let i = 0; i < node.children.length; i++) {
              nc++;
              const child = node.children[i];
              if (child.type === 1 /* ELEMENT */) {
                  if (child.props.length > 0) {
                      ec++;
                  }
                  walk(child);
                  if (bailed) {
                      return false;
                  }
              }
          }
          return true;
      }
      return walk(node) ? [nc, ec] : false;
  }
  function stringifyNode(node, context) {
      if (isString(node)) {
          return node;
      }
      if (isSymbol(node)) {
          return ``;
      }
      switch (node.type) {
          case 1 /* ELEMENT */:
              return stringifyElement(node, context);
          case 2 /* TEXT */:
              return escapeHtml(node.content);
          case 3 /* COMMENT */:
              return `<!--${escapeHtml(node.content)}-->`;
          case 5 /* INTERPOLATION */:
              return escapeHtml(toDisplayString(evaluateConstant(node.content)));
          case 8 /* COMPOUND_EXPRESSION */:
              return escapeHtml(evaluateConstant(node));
          case 12 /* TEXT_CALL */:
              return stringifyNode(node.content, context);
          default:
              // static trees will not contain if/for nodes
              return '';
      }
  }
  function stringifyElement(node, context) {
      let res = `<${node.tag}`;
      for (let i = 0; i < node.props.length; i++) {
          const p = node.props[i];
          if (p.type === 6 /* ATTRIBUTE */) {
              res += ` ${p.name}`;
              if (p.value) {
                  res += `="${escapeHtml(p.value.content)}"`;
              }
          }
          else if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
              // constant v-bind, e.g. :foo="1"
              let evaluated = evaluateConstant(p.exp);
              const arg = p.arg && p.arg.content;
              if (arg === 'class') {
                  evaluated = normalizeClass(evaluated);
              }
              else if (arg === 'style') {
                  evaluated = stringifyStyle(normalizeStyle(evaluated));
              }
              res += ` ${p.arg.content}="${escapeHtml(evaluated)}"`;
          }
      }
      if (context.scopeId) {
          res += ` ${context.scopeId}`;
      }
      res += `>`;
      for (let i = 0; i < node.children.length; i++) {
          res += stringifyNode(node.children[i], context);
      }
      if (!isVoidTag(node.tag)) {
          res += `</${node.tag}>`;
      }
      return res;
  }
  // __UNSAFE__
  // Reason: eval.
  // It's technically safe to eval because only constant expressions are possible
  // here, e.g. `{{ 1 }}` or `{{ 'foo' }}`
  // in addition, constant exps bail on presence of parens so you can't even
  // run JSFuck in here. But we mark it unsafe for security review purposes.
  // (see compiler-core/src/transformExpressions)
  function evaluateConstant(exp) {
      if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
          return new Function(`return ${exp.content}`)();
      }
      else {
          // compound
          let res = ``;
          exp.children.forEach(c => {
              if (isString(c) || isSymbol(c)) {
                  return;
              }
              if (c.type === 2 /* TEXT */) {
                  res += c.content;
              }
              else if (c.type === 5 /* INTERPOLATION */) {
                  res += toDisplayString(evaluateConstant(c.content));
              }
              else {
                  res += evaluateConstant(c);
              }
          });
          return res;
      }
  }

  const ignoreSideEffectTags = (node, context) => {
      if (node.type === 1 /* ELEMENT */ &&
          node.tagType === 0 /* ELEMENT */ &&
          (node.tag === 'script' || node.tag === 'style')) {
          context.onError(createDOMCompilerError(59 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
          context.removeNode();
      }
  };

  const DOMNodeTransforms = [
      transformStyle,
      ...( [warnTransitionChildren] )
  ];
  const DOMDirectiveTransforms = {
      cloak: noopDirectiveTransform,
      html: transformVHtml,
      text: transformVText,
      model: transformModel$1,
      on: transformOn$1,
      show: transformShow
  };
  function compile(template, options = {}) {
      return baseCompile(template, extend({}, parserOptions, options, {
          nodeTransforms: [
              // ignore <script> and <tag>
              // this is not put inside DOMNodeTransforms because that list is used
              // by compiler-ssr to generate vnode fallback branches
              ignoreSideEffectTags,
              ...DOMNodeTransforms,
              ...(options.nodeTransforms || [])
          ],
          directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
          transformHoist:  stringifyStatic
      }));
  }
  function parse(template, options = {}) {
      return baseParse(template, extend({}, parserOptions, options));
  }

  var CompilerDOM = /*#__PURE__*/Object.freeze({
    __proto__: null,
    parserOptions: parserOptions,
    DOMNodeTransforms: DOMNodeTransforms,
    DOMDirectiveTransforms: DOMDirectiveTransforms,
    compile: compile,
    parse: parse,
    transformStyle: transformStyle,
    createDOMCompilerError: createDOMCompilerError,
    V_MODEL_RADIO: V_MODEL_RADIO,
    V_MODEL_CHECKBOX: V_MODEL_CHECKBOX,
    V_MODEL_TEXT: V_MODEL_TEXT,
    V_MODEL_SELECT: V_MODEL_SELECT,
    V_MODEL_DYNAMIC: V_MODEL_DYNAMIC,
    V_ON_WITH_MODIFIERS: V_ON_WITH_MODIFIERS,
    V_ON_WITH_KEYS: V_ON_WITH_KEYS,
    V_SHOW: V_SHOW,
    TRANSITION: TRANSITION,
    TRANSITION_GROUP: TRANSITION_GROUP,
    baseCompile: baseCompile,
    baseParse: baseParse,
    transform: transform,
    createTransformContext: createTransformContext,
    traverseNode: traverseNode,
    createStructuralDirectiveTransform: createStructuralDirectiveTransform,
    generate: generate,
    createCompilerError: createCompilerError,
    getBaseTransformPreset: getBaseTransformPreset,
    transformModel: transformModel,
    transformOn: transformOn,
    transformBind: transformBind,
    noopDirectiveTransform: noopDirectiveTransform,
    processIf: processIf,
    processFor: processFor,
    createForLoopParams: createForLoopParams,
    transformExpression: transformExpression,
    processExpression: processExpression,
    buildSlots: buildSlots,
    trackVForSlotScopes: trackVForSlotScopes,
    trackSlotScopes: trackSlotScopes,
    transformElement: transformElement,
    resolveComponentType: resolveComponentType,
    buildProps: buildProps,
    processSlotOutlet: processSlotOutlet,
    generateCodeFrame: generateCodeFrame,
    locStub: locStub,
    createRoot: createRoot,
    createVNodeCall: createVNodeCall,
    createArrayExpression: createArrayExpression,
    createObjectExpression: createObjectExpression,
    createObjectProperty: createObjectProperty,
    createSimpleExpression: createSimpleExpression,
    createInterpolation: createInterpolation,
    createCompoundExpression: createCompoundExpression,
    createCallExpression: createCallExpression,
    createFunctionExpression: createFunctionExpression,
    createConditionalExpression: createConditionalExpression,
    createCacheExpression: createCacheExpression,
    createBlockStatement: createBlockStatement,
    createTemplateLiteral: createTemplateLiteral,
    createIfStatement: createIfStatement,
    createAssignmentExpression: createAssignmentExpression,
    createSequenceExpression: createSequenceExpression,
    createReturnStatement: createReturnStatement,
    isStaticExp: isStaticExp,
    isBuiltInType: isBuiltInType,
    isCoreComponent: isCoreComponent,
    isSimpleIdentifier: isSimpleIdentifier,
    isMemberExpression: isMemberExpression,
    getInnerRange: getInnerRange,
    advancePositionWithClone: advancePositionWithClone,
    advancePositionWithMutation: advancePositionWithMutation,
    assert: assert,
    findDir: findDir,
    findProp: findProp,
    isBindKey: isBindKey,
    hasDynamicKeyVBind: hasDynamicKeyVBind,
    isText: isText,
    isVSlot: isVSlot,
    isTemplateNode: isTemplateNode,
    isSlotOutlet: isSlotOutlet,
    injectProp: injectProp,
    toValidAssetId: toValidAssetId,
    hasScopeRef: hasScopeRef,
    FRAGMENT: FRAGMENT,
    TELEPORT: TELEPORT,
    SUSPENSE: SUSPENSE,
    KEEP_ALIVE: KEEP_ALIVE,
    BASE_TRANSITION: BASE_TRANSITION,
    OPEN_BLOCK: OPEN_BLOCK,
    CREATE_BLOCK: CREATE_BLOCK,
    CREATE_VNODE: CREATE_VNODE,
    CREATE_COMMENT: CREATE_COMMENT,
    CREATE_TEXT: CREATE_TEXT,
    CREATE_STATIC: CREATE_STATIC,
    RESOLVE_COMPONENT: RESOLVE_COMPONENT,
    RESOLVE_DYNAMIC_COMPONENT: RESOLVE_DYNAMIC_COMPONENT,
    RESOLVE_DIRECTIVE: RESOLVE_DIRECTIVE,
    WITH_DIRECTIVES: WITH_DIRECTIVES,
    RENDER_LIST: RENDER_LIST,
    RENDER_SLOT: RENDER_SLOT,
    CREATE_SLOTS: CREATE_SLOTS,
    TO_DISPLAY_STRING: TO_DISPLAY_STRING,
    MERGE_PROPS: MERGE_PROPS,
    TO_HANDLERS: TO_HANDLERS,
    CAMELIZE: CAMELIZE,
    CAPITALIZE: CAPITALIZE,
    SET_BLOCK_TRACKING: SET_BLOCK_TRACKING,
    PUSH_SCOPE_ID: PUSH_SCOPE_ID,
    POP_SCOPE_ID: POP_SCOPE_ID,
    WITH_SCOPE_ID: WITH_SCOPE_ID,
    WITH_CTX: WITH_CTX,
    helperNameMap: helperNameMap,
    registerRuntimeHelpers: registerRuntimeHelpers
  });

  const sourceToSFC =  new Map()
      ;
  function parse$1(source, { sourceMap = true, filename = 'component.vue', sourceRoot = '', pad = false, compiler = CompilerDOM } = {}) {
      const sourceKey = source + sourceMap + filename + sourceRoot + pad + compiler.parse;
      const cache = sourceToSFC.get(sourceKey);
      if (cache) {
          return cache;
      }
      const descriptor = {
          filename,
          source,
          template: null,
          script: null,
          scriptSetup: null,
          styles: [],
          customBlocks: []
      };
      const errors = [];
      const ast = compiler.parse(source, {
          // there are no components at SFC parsing level
          isNativeTag: () => true,
          // preserve all whitespaces
          isPreTag: () => true,
          getTextMode: ({ tag, props }, parent) => {
              // all top level elements except <template> are parsed as raw text
              // containers
              if ((!parent && tag !== 'template') ||
                  // <template lang="xxx"> should also be treated as raw text
                  props.some(p => p.type === 6 /* ATTRIBUTE */ &&
                      p.name === 'lang' &&
                      p.value &&
                      p.value.content !== 'html')) {
                  return 2 /* RAWTEXT */;
              }
              else {
                  return 0 /* DATA */;
              }
          },
          onError: e => {
              errors.push(e);
          }
      });
      ast.children.forEach(node => {
          if (node.type !== 1 /* ELEMENT */) {
              return;
          }
          if (!node.children.length && !hasSrc(node)) {
              return;
          }
          switch (node.tag) {
              case 'template':
                  if (!descriptor.template) {
                      descriptor.template = createBlock(node, source, false);
                  }
                  else {
                      errors.push(createDuplicateBlockError(node));
                  }
                  break;
              case 'script':
                  const block = createBlock(node, source, pad);
                  const isSetup = !!block.attrs.setup;
                  if (isSetup && !descriptor.scriptSetup) {
                      descriptor.scriptSetup = block;
                      break;
                  }
                  if (!isSetup && !descriptor.script) {
                      descriptor.script = block;
                      break;
                  }
                  errors.push(createDuplicateBlockError(node, isSetup));
                  break;
              case 'style':
                  descriptor.styles.push(createBlock(node, source, pad));
                  break;
              default:
                  descriptor.customBlocks.push(createBlock(node, source, pad));
                  break;
          }
      });
      if (descriptor.scriptSetup) {
          if (descriptor.scriptSetup.src) {
              errors.push(new SyntaxError(`<script setup> cannot use the "src" attribute because ` +
                  `its syntax will be ambiguous outside of the component.`));
              descriptor.scriptSetup = null;
          }
          if (descriptor.script && descriptor.script.src) {
              errors.push(new SyntaxError(`<script> cannot use the "src" attribute when <script setup> is ` +
                  `also present because they must be processed together.`));
              descriptor.script = null;
          }
      }
      if (sourceMap) {
          const genMap = (block) => {
              if (block && !block.src) {
                  block.map = generateSourceMap(filename, source, block.content, sourceRoot, !pad || block.type === 'template' ? block.loc.start.line - 1 : 0);
              }
          };
          genMap(descriptor.template);
          genMap(descriptor.script);
          descriptor.styles.forEach(genMap);
          descriptor.customBlocks.forEach(genMap);
      }
      const result = {
          descriptor,
          errors
      };
      sourceToSFC.set(sourceKey, result);
      return result;
  }
  function createDuplicateBlockError(node, isScriptSetup = false) {
      const err = new SyntaxError(`Single file component can contain only one <${node.tag}${isScriptSetup ? ` setup` : ``}> element`);
      err.loc = node.loc;
      return err;
  }
  function createBlock(node, source, pad) {
      const type = node.tag;
      let { start, end } = node.loc;
      let content = '';
      if (node.children.length) {
          start = node.children[0].loc.start;
          end = node.children[node.children.length - 1].loc.end;
          content = source.slice(start.offset, end.offset);
      }
      const loc = {
          source: content,
          start,
          end
      };
      const attrs = {};
      const block = {
          type,
          content,
          loc,
          attrs
      };
      if (pad) {
          block.content = padContent(source, block, pad) + block.content;
      }
      node.props.forEach(p => {
          if (p.type === 6 /* ATTRIBUTE */) {
              attrs[p.name] = p.value ? p.value.content || true : true;
              if (p.name === 'lang') {
                  block.lang = p.value && p.value.content;
              }
              else if (p.name === 'src') {
                  block.src = p.value && p.value.content;
              }
              else if (type === 'style') {
                  if (p.name === 'scoped') {
                      block.scoped = true;
                  }
                  else if (p.name === 'vars' && typeof attrs.vars === 'string') {
                      block.vars = attrs.vars;
                  }
                  else if (p.name === 'module') {
                      block.module = attrs[p.name];
                  }
              }
              else if (type === 'template' && p.name === 'functional') {
                  block.functional = true;
              }
              else if (type === 'script' && p.name === 'setup') {
                  block.setup = attrs.setup;
              }
          }
      });
      return block;
  }
  const splitRE = /\r?\n/g;
  const emptyRE = /^(?:\/\/)?\s*$/;
  const replaceRE = /./g;
  function generateSourceMap(filename, source, generated, sourceRoot, lineOffset) {
      const map = new SourceMapGenerator$2({
          file: filename.replace(/\\/g, '/'),
          sourceRoot: sourceRoot.replace(/\\/g, '/')
      });
      map.setSourceContent(filename, source);
      generated.split(splitRE).forEach((line, index) => {
          if (!emptyRE.test(line)) {
              const originalLine = index + 1 + lineOffset;
              const generatedLine = index + 1;
              for (let i = 0; i < line.length; i++) {
                  if (!/\s/.test(line[i])) {
                      map.addMapping({
                          source: filename,
                          original: {
                              line: originalLine,
                              column: i
                          },
                          generated: {
                              line: generatedLine,
                              column: i
                          }
                      });
                  }
              }
          }
      });
      return JSON.parse(map.toString());
  }
  function padContent(content, block, pad) {
      content = content.slice(0, block.loc.start.offset);
      if (pad === 'space') {
          return content.replace(replaceRE, ' ');
      }
      else {
          const offset = content.split(splitRE).length;
          const padChar = block.type === 'script' && !block.lang ? '//\n' : '\n';
          return Array(offset).join(padChar);
      }
  }
  function hasSrc(node) {
      return node.props.some(p => {
          if (p.type !== 6 /* ATTRIBUTE */) {
              return false;
          }
          return p.name === 'src';
      });
  }

  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.

  // resolves . and .. elements in a path array with directory names there
  // must be no slashes, empty elements, or device names (c:\) in the array
  // (so also no leading and trailing slashes - it does not distinguish
  // relative and absolute paths)
  function normalizeArray(parts, allowAboveRoot) {
    // if the path tries to go above the root, `up` ends up > 0
    var up = 0;
    for (var i = parts.length - 1; i >= 0; i--) {
      var last = parts[i];
      if (last === '.') {
        parts.splice(i, 1);
      } else if (last === '..') {
        parts.splice(i, 1);
        up++;
      } else if (up) {
        parts.splice(i, 1);
        up--;
      }
    }

    // if the path is allowed to go above the root, restore leading ..s
    if (allowAboveRoot) {
      for (; up--; up) {
        parts.unshift('..');
      }
    }

    return parts;
  }

  // Split a filename into [root, dir, basename, ext], unix version
  // 'root' is just a slash, or nothing.
  var splitPathRe =
      /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  var splitPath = function(filename) {
    return splitPathRe.exec(filename).slice(1);
  };

  // path.resolve([from ...], to)
  // posix version
  function resolve() {
    var resolvedPath = '',
        resolvedAbsolute = false;

    for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
      var path = (i >= 0) ? arguments[i] : '/';

      // Skip empty and invalid entries
      if (typeof path !== 'string') {
        throw new TypeError('Arguments to path.resolve must be strings');
      } else if (!path) {
        continue;
      }

      resolvedPath = path + '/' + resolvedPath;
      resolvedAbsolute = path.charAt(0) === '/';
    }

    // At this point the path should be resolved to a full absolute path, but
    // handle relative paths to be safe (might happen when process.cwd() fails)

    // Normalize the path
    resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
      return !!p;
    }), !resolvedAbsolute).join('/');

    return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  }
  // path.normalize(path)
  // posix version
  function normalize(path) {
    var isPathAbsolute = isAbsolute(path),
        trailingSlash = substr(path, -1) === '/';

    // Normalize the path
    path = normalizeArray(filter(path.split('/'), function(p) {
      return !!p;
    }), !isPathAbsolute).join('/');

    if (!path && !isPathAbsolute) {
      path = '.';
    }
    if (path && trailingSlash) {
      path += '/';
    }

    return (isPathAbsolute ? '/' : '') + path;
  }
  // posix version
  function isAbsolute(path) {
    return path.charAt(0) === '/';
  }

  // posix version
  function join() {
    var paths = Array.prototype.slice.call(arguments, 0);
    return normalize(filter(paths, function(p, index) {
      if (typeof p !== 'string') {
        throw new TypeError('Arguments to path.join must be strings');
      }
      return p;
    }).join('/'));
  }


  // path.relative(from, to)
  // posix version
  function relative(from, to) {
    from = resolve(from).substr(1);
    to = resolve(to).substr(1);

    function trim(arr) {
      var start = 0;
      for (; start < arr.length; start++) {
        if (arr[start] !== '') break;
      }

      var end = arr.length - 1;
      for (; end >= 0; end--) {
        if (arr[end] !== '') break;
      }

      if (start > end) return [];
      return arr.slice(start, end - start + 1);
    }

    var fromParts = trim(from.split('/'));
    var toParts = trim(to.split('/'));

    var length = Math.min(fromParts.length, toParts.length);
    var samePartsLength = length;
    for (var i = 0; i < length; i++) {
      if (fromParts[i] !== toParts[i]) {
        samePartsLength = i;
        break;
      }
    }

    var outputParts = [];
    for (var i = samePartsLength; i < fromParts.length; i++) {
      outputParts.push('..');
    }

    outputParts = outputParts.concat(toParts.slice(samePartsLength));

    return outputParts.join('/');
  }

  var sep = '/';
  var delimiter = ':';

  function dirname(path) {
    var result = splitPath(path),
        root = result[0],
        dir = result[1];

    if (!root && !dir) {
      // No dirname whatsoever
      return '.';
    }

    if (dir) {
      // It has a dirname, strip trailing slash
      dir = dir.substr(0, dir.length - 1);
    }

    return root + dir;
  }

  function basename(path, ext) {
    var f = splitPath(path)[2];
    // TODO: make this comparison case-insensitive on windows?
    if (ext && f.substr(-1 * ext.length) === ext) {
      f = f.substr(0, f.length - ext.length);
    }
    return f;
  }


  function extname(path) {
    return splitPath(path)[3];
  }
  var path = {
    extname: extname,
    basename: basename,
    dirname: dirname,
    sep: sep,
    delimiter: delimiter,
    relative: relative,
    join: join,
    isAbsolute: isAbsolute,
    normalize: normalize,
    resolve: resolve
  };
  function filter (xs, f) {
      if (xs.filter) return xs.filter(f);
      var res = [];
      for (var i = 0; i < xs.length; i++) {
          if (f(xs[i], i, xs)) res.push(xs[i]);
      }
      return res;
  }

  // String.prototype.substr - negative index don't work in IE8
  var substr = 'ab'.substr(-1) === 'b' ?
      function (str, start, len) { return str.substr(start, len) } :
      function (str, start, len) {
          if (start < 0) start = str.length + start;
          return str.substr(start, len);
      }
  ;

  /*! https://mths.be/punycode v1.4.1 by @mathias */


  /** Highest positive signed 32-bit float value */
  var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1

  /** Bootstring parameters */
  var base = 36;
  var tMin = 1;
  var tMax = 26;
  var skew = 38;
  var damp = 700;
  var initialBias = 72;
  var initialN = 128; // 0x80
  var delimiter$1 = '-'; // '\x2D'
  var regexNonASCII = /[^\x20-\x7E]/; // unprintable ASCII chars + non-ASCII chars
  var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators

  /** Error messages */
  var errors = {
    'overflow': 'Overflow: input needs wider integers to process',
    'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
    'invalid-input': 'Invalid input'
  };

  /** Convenience shortcuts */
  var baseMinusTMin = base - tMin;
  var floor = Math.floor;
  var stringFromCharCode = String.fromCharCode;

  /*--------------------------------------------------------------------------*/

  /**
   * A generic error utility function.
   * @private
   * @param {String} type The error type.
   * @returns {Error} Throws a `RangeError` with the applicable error message.
   */
  function error(type) {
    throw new RangeError(errors[type]);
  }

  /**
   * A generic `Array#map` utility function.
   * @private
   * @param {Array} array The array to iterate over.
   * @param {Function} callback The function that gets called for every array
   * item.
   * @returns {Array} A new array of values returned by the callback function.
   */
  function map(array, fn) {
    var length = array.length;
    var result = [];
    while (length--) {
      result[length] = fn(array[length]);
    }
    return result;
  }

  /**
   * A simple `Array#map`-like wrapper to work with domain name strings or email
   * addresses.
   * @private
   * @param {String} domain The domain name or email address.
   * @param {Function} callback The function that gets called for every
   * character.
   * @returns {Array} A new string of characters returned by the callback
   * function.
   */
  function mapDomain(string, fn) {
    var parts = string.split('@');
    var result = '';
    if (parts.length > 1) {
      // In email addresses, only the domain name should be punycoded. Leave
      // the local part (i.e. everything up to `@`) intact.
      result = parts[0] + '@';
      string = parts[1];
    }
    // Avoid `split(regex)` for IE8 compatibility. See #17.
    string = string.replace(regexSeparators, '\x2E');
    var labels = string.split('.');
    var encoded = map(labels, fn).join('.');
    return result + encoded;
  }

  /**
   * Creates an array containing the numeric code points of each Unicode
   * character in the string. While JavaScript uses UCS-2 internally,
   * this function will convert a pair of surrogate halves (each of which
   * UCS-2 exposes as separate characters) into a single code point,
   * matching UTF-16.
   * @see `punycode.ucs2.encode`
   * @see <https://mathiasbynens.be/notes/javascript-encoding>
   * @memberOf punycode.ucs2
   * @name decode
   * @param {String} string The Unicode input string (UCS-2).
   * @returns {Array} The new array of code points.
   */
  function ucs2decode(string) {
    var output = [],
      counter = 0,
      length = string.length,
      value,
      extra;
    while (counter < length) {
      value = string.charCodeAt(counter++);
      if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
        // high surrogate, and there is a next character
        extra = string.charCodeAt(counter++);
        if ((extra & 0xFC00) == 0xDC00) { // low surrogate
          output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
        } else {
          // unmatched surrogate; only append this code unit, in case the next
          // code unit is the high surrogate of a surrogate pair
          output.push(value);
          counter--;
        }
      } else {
        output.push(value);
      }
    }
    return output;
  }

  /**
   * Converts a digit/integer into a basic code point.
   * @see `basicToDigit()`
   * @private
   * @param {Number} digit The numeric value of a basic code point.
   * @returns {Number} The basic code point whose value (when used for
   * representing integers) is `digit`, which needs to be in the range
   * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
   * used; else, the lowercase form is used. The behavior is undefined
   * if `flag` is non-zero and `digit` has no uppercase form.
   */
  function digitToBasic(digit, flag) {
    //  0..25 map to ASCII a..z or A..Z
    // 26..35 map to ASCII 0..9
    return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
  }

  /**
   * Bias adaptation function as per section 3.4 of RFC 3492.
   * https://tools.ietf.org/html/rfc3492#section-3.4
   * @private
   */
  function adapt(delta, numPoints, firstTime) {
    var k = 0;
    delta = firstTime ? floor(delta / damp) : delta >> 1;
    delta += floor(delta / numPoints);
    for ( /* no initialization */ ; delta > baseMinusTMin * tMax >> 1; k += base) {
      delta = floor(delta / baseMinusTMin);
    }
    return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
  }

  /**
   * Converts a string of Unicode symbols (e.g. a domain name label) to a
   * Punycode string of ASCII-only symbols.
   * @memberOf punycode
   * @param {String} input The string of Unicode symbols.
   * @returns {String} The resulting Punycode string of ASCII-only symbols.
   */
  function encode$2(input) {
    var n,
      delta,
      handledCPCount,
      basicLength,
      bias,
      j,
      m,
      q,
      k,
      t,
      currentValue,
      output = [],
      /** `inputLength` will hold the number of code points in `input`. */
      inputLength,
      /** Cached calculation results */
      handledCPCountPlusOne,
      baseMinusT,
      qMinusT;

    // Convert the input in UCS-2 to Unicode
    input = ucs2decode(input);

    // Cache the length
    inputLength = input.length;

    // Initialize the state
    n = initialN;
    delta = 0;
    bias = initialBias;

    // Handle the basic code points
    for (j = 0; j < inputLength; ++j) {
      currentValue = input[j];
      if (currentValue < 0x80) {
        output.push(stringFromCharCode(currentValue));
      }
    }

    handledCPCount = basicLength = output.length;

    // `handledCPCount` is the number of code points that have been handled;
    // `basicLength` is the number of basic code points.

    // Finish the basic string - if it is not empty - with a delimiter
    if (basicLength) {
      output.push(delimiter$1);
    }

    // Main encoding loop:
    while (handledCPCount < inputLength) {

      // All non-basic code points < n have been handled already. Find the next
      // larger one:
      for (m = maxInt, j = 0; j < inputLength; ++j) {
        currentValue = input[j];
        if (currentValue >= n && currentValue < m) {
          m = currentValue;
        }
      }

      // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
      // but guard against overflow
      handledCPCountPlusOne = handledCPCount + 1;
      if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
        error('overflow');
      }

      delta += (m - n) * handledCPCountPlusOne;
      n = m;

      for (j = 0; j < inputLength; ++j) {
        currentValue = input[j];

        if (currentValue < n && ++delta > maxInt) {
          error('overflow');
        }

        if (currentValue == n) {
          // Represent delta as a generalized variable-length integer
          for (q = delta, k = base; /* no condition */ ; k += base) {
            t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
            if (q < t) {
              break;
            }
            qMinusT = q - t;
            baseMinusT = base - t;
            output.push(
              stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
            );
            q = floor(qMinusT / baseMinusT);
          }

          output.push(stringFromCharCode(digitToBasic(q, 0)));
          bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
          delta = 0;
          ++handledCPCount;
        }
      }

      ++delta;
      ++n;

    }
    return output.join('');
  }

  /**
   * Converts a Unicode string representing a domain name or an email address to
   * Punycode. Only the non-ASCII parts of the domain name will be converted,
   * i.e. it doesn't matter if you call it with a domain that's already in
   * ASCII.
   * @memberOf punycode
   * @param {String} input The domain name or email address to convert, as a
   * Unicode string.
   * @returns {String} The Punycode representation of the given domain name or
   * email address.
   */
  function toASCII(input) {
    return mapDomain(input, function(string) {
      return regexNonASCII.test(string) ?
        'xn--' + encode$2(string) :
        string;
    });
  }

  var global$1 = (typeof global !== "undefined" ? global :
              typeof self !== "undefined" ? self :
              typeof window !== "undefined" ? window : {});

  var lookup = [];
  var revLookup = [];
  var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
  var inited = false;
  function init () {
    inited = true;
    var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    for (var i = 0, len = code.length; i < len; ++i) {
      lookup[i] = code[i];
      revLookup[code.charCodeAt(i)] = i;
    }

    revLookup['-'.charCodeAt(0)] = 62;
    revLookup['_'.charCodeAt(0)] = 63;
  }

  function toByteArray (b64) {
    if (!inited) {
      init();
    }
    var i, j, l, tmp, placeHolders, arr;
    var len = b64.length;

    if (len % 4 > 0) {
      throw new Error('Invalid string. Length must be a multiple of 4')
    }

    // the number of equal signs (place holders)
    // if there are two placeholders, than the two characters before it
    // represent one byte
    // if there is only one, then the three characters before it represent 2 bytes
    // this is just a cheap hack to not do indexOf twice
    placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0;

    // base64 is 4/3 + up to two characters of the original data
    arr = new Arr(len * 3 / 4 - placeHolders);

    // if there are placeholders, only get up to the last complete 4 chars
    l = placeHolders > 0 ? len - 4 : len;

    var L = 0;

    for (i = 0, j = 0; i < l; i += 4, j += 3) {
      tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)];
      arr[L++] = (tmp >> 16) & 0xFF;
      arr[L++] = (tmp >> 8) & 0xFF;
      arr[L++] = tmp & 0xFF;
    }

    if (placeHolders === 2) {
      tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4);
      arr[L++] = tmp & 0xFF;
    } else if (placeHolders === 1) {
      tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2);
      arr[L++] = (tmp >> 8) & 0xFF;
      arr[L++] = tmp & 0xFF;
    }

    return arr
  }

  function tripletToBase64 (num) {
    return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
  }

  function encodeChunk (uint8, start, end) {
    var tmp;
    var output = [];
    for (var i = start; i < end; i += 3) {
      tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]);
      output.push(tripletToBase64(tmp));
    }
    return output.join('')
  }

  function fromByteArray (uint8) {
    if (!inited) {
      init();
    }
    var tmp;
    var len = uint8.length;
    var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
    var output = '';
    var parts = [];
    var maxChunkLength = 16383; // must be multiple of 3

    // go through the array every three bytes, we'll deal with trailing stuff later
    for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
      parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)));
    }

    // pad the end with zeros, but make sure to not forget the extra bytes
    if (extraBytes === 1) {
      tmp = uint8[len - 1];
      output += lookup[tmp >> 2];
      output += lookup[(tmp << 4) & 0x3F];
      output += '==';
    } else if (extraBytes === 2) {
      tmp = (uint8[len - 2] << 8) + (uint8[len - 1]);
      output += lookup[tmp >> 10];
      output += lookup[(tmp >> 4) & 0x3F];
      output += lookup[(tmp << 2) & 0x3F];
      output += '=';
    }

    parts.push(output);

    return parts.join('')
  }

  function read (buffer, offset, isLE, mLen, nBytes) {
    var e, m;
    var eLen = nBytes * 8 - mLen - 1;
    var eMax = (1 << eLen) - 1;
    var eBias = eMax >> 1;
    var nBits = -7;
    var i = isLE ? (nBytes - 1) : 0;
    var d = isLE ? -1 : 1;
    var s = buffer[offset + i];

    i += d;

    e = s & ((1 << (-nBits)) - 1);
    s >>= (-nBits);
    nBits += eLen;
    for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}

    m = e & ((1 << (-nBits)) - 1);
    e >>= (-nBits);
    nBits += mLen;
    for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}

    if (e === 0) {
      e = 1 - eBias;
    } else if (e === eMax) {
      return m ? NaN : ((s ? -1 : 1) * Infinity)
    } else {
      m = m + Math.pow(2, mLen);
      e = e - eBias;
    }
    return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
  }

  function write (buffer, value, offset, isLE, mLen, nBytes) {
    var e, m, c;
    var eLen = nBytes * 8 - mLen - 1;
    var eMax = (1 << eLen) - 1;
    var eBias = eMax >> 1;
    var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0);
    var i = isLE ? 0 : (nBytes - 1);
    var d = isLE ? 1 : -1;
    var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;

    value = Math.abs(value);

    if (isNaN(value) || value === Infinity) {
      m = isNaN(value) ? 1 : 0;
      e = eMax;
    } else {
      e = Math.floor(Math.log(value) / Math.LN2);
      if (value * (c = Math.pow(2, -e)) < 1) {
        e--;
        c *= 2;
      }
      if (e + eBias >= 1) {
        value += rt / c;
      } else {
        value += rt * Math.pow(2, 1 - eBias);
      }
      if (value * c >= 2) {
        e++;
        c /= 2;
      }

      if (e + eBias >= eMax) {
        m = 0;
        e = eMax;
      } else if (e + eBias >= 1) {
        m = (value * c - 1) * Math.pow(2, mLen);
        e = e + eBias;
      } else {
        m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
        e = 0;
      }
    }

    for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

    e = (e << mLen) | m;
    eLen += mLen;
    for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

    buffer[offset + i - d] |= s * 128;
  }

  var toString = {}.toString;

  var isArray$1 = Array.isArray || function (arr) {
    return toString.call(arr) == '[object Array]';
  };

  var INSPECT_MAX_BYTES = 50;

  /**
   * If `Buffer.TYPED_ARRAY_SUPPORT`:
   *   === true    Use Uint8Array implementation (fastest)
   *   === false   Use Object implementation (most compatible, even IE6)
   *
   * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
   * Opera 11.6+, iOS 4.2+.
   *
   * Due to various browser bugs, sometimes the Object implementation will be used even
   * when the browser supports typed arrays.
   *
   * Note:
   *
   *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
   *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
   *
   *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
   *
   *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
   *     incorrect length in some situations.

   * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
   * get the Object implementation, which is slower but behaves correctly.
   */
  Buffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined
    ? global$1.TYPED_ARRAY_SUPPORT
    : true;

  function kMaxLength () {
    return Buffer.TYPED_ARRAY_SUPPORT
      ? 0x7fffffff
      : 0x3fffffff
  }

  function createBuffer (that, length) {
    if (kMaxLength() < length) {
      throw new RangeError('Invalid typed array length')
    }
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      // Return an augmented `Uint8Array` instance, for best performance
      that = new Uint8Array(length);
      that.__proto__ = Buffer.prototype;
    } else {
      // Fallback: Return an object instance of the Buffer class
      if (that === null) {
        that = new Buffer(length);
      }
      that.length = length;
    }

    return that
  }

  /**
   * The Buffer constructor returns instances of `Uint8Array` that have their
   * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
   * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
   * and the `Uint8Array` methods. Square bracket notation works as expected -- it
   * returns a single octet.
   *
   * The `Uint8Array` prototype remains unmodified.
   */

  function Buffer (arg, encodingOrOffset, length) {
    if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
      return new Buffer(arg, encodingOrOffset, length)
    }

    // Common case.
    if (typeof arg === 'number') {
      if (typeof encodingOrOffset === 'string') {
        throw new Error(
          'If encoding is specified then the first argument must be a string'
        )
      }
      return allocUnsafe(this, arg)
    }
    return from(this, arg, encodingOrOffset, length)
  }

  Buffer.poolSize = 8192; // not used by this implementation

  // TODO: Legacy, not needed anymore. Remove in next major version.
  Buffer._augment = function (arr) {
    arr.__proto__ = Buffer.prototype;
    return arr
  };

  function from (that, value, encodingOrOffset, length) {
    if (typeof value === 'number') {
      throw new TypeError('"value" argument must not be a number')
    }

    if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
      return fromArrayBuffer(that, value, encodingOrOffset, length)
    }

    if (typeof value === 'string') {
      return fromString(that, value, encodingOrOffset)
    }

    return fromObject(that, value)
  }

  /**
   * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
   * if value is a number.
   * Buffer.from(str[, encoding])
   * Buffer.from(array)
   * Buffer.from(buffer)
   * Buffer.from(arrayBuffer[, byteOffset[, length]])
   **/
  Buffer.from = function (value, encodingOrOffset, length) {
    return from(null, value, encodingOrOffset, length)
  };

  if (Buffer.TYPED_ARRAY_SUPPORT) {
    Buffer.prototype.__proto__ = Uint8Array.prototype;
    Buffer.__proto__ = Uint8Array;
  }

  function assertSize (size) {
    if (typeof size !== 'number') {
      throw new TypeError('"size" argument must be a number')
    } else if (size < 0) {
      throw new RangeError('"size" argument must not be negative')
    }
  }

  function alloc (that, size, fill, encoding) {
    assertSize(size);
    if (size <= 0) {
      return createBuffer(that, size)
    }
    if (fill !== undefined) {
      // Only pay attention to encoding if it's a string. This
      // prevents accidentally sending in a number that would
      // be interpretted as a start offset.
      return typeof encoding === 'string'
        ? createBuffer(that, size).fill(fill, encoding)
        : createBuffer(that, size).fill(fill)
    }
    return createBuffer(that, size)
  }

  /**
   * Creates a new filled Buffer instance.
   * alloc(size[, fill[, encoding]])
   **/
  Buffer.alloc = function (size, fill, encoding) {
    return alloc(null, size, fill, encoding)
  };

  function allocUnsafe (that, size) {
    assertSize(size);
    that = createBuffer(that, size < 0 ? 0 : checked(size) | 0);
    if (!Buffer.TYPED_ARRAY_SUPPORT) {
      for (var i = 0; i < size; ++i) {
        that[i] = 0;
      }
    }
    return that
  }

  /**
   * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
   * */
  Buffer.allocUnsafe = function (size) {
    return allocUnsafe(null, size)
  };
  /**
   * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
   */
  Buffer.allocUnsafeSlow = function (size) {
    return allocUnsafe(null, size)
  };

  function fromString (that, string, encoding) {
    if (typeof encoding !== 'string' || encoding === '') {
      encoding = 'utf8';
    }

    if (!Buffer.isEncoding(encoding)) {
      throw new TypeError('"encoding" must be a valid string encoding')
    }

    var length = byteLength(string, encoding) | 0;
    that = createBuffer(that, length);

    var actual = that.write(string, encoding);

    if (actual !== length) {
      // Writing a hex string, for example, that contains invalid characters will
      // cause everything after the first invalid character to be ignored. (e.g.
      // 'abxxcd' will be treated as 'ab')
      that = that.slice(0, actual);
    }

    return that
  }

  function fromArrayLike (that, array) {
    var length = array.length < 0 ? 0 : checked(array.length) | 0;
    that = createBuffer(that, length);
    for (var i = 0; i < length; i += 1) {
      that[i] = array[i] & 255;
    }
    return that
  }

  function fromArrayBuffer (that, array, byteOffset, length) {
    array.byteLength; // this throws if `array` is not a valid ArrayBuffer

    if (byteOffset < 0 || array.byteLength < byteOffset) {
      throw new RangeError('\'offset\' is out of bounds')
    }

    if (array.byteLength < byteOffset + (length || 0)) {
      throw new RangeError('\'length\' is out of bounds')
    }

    if (byteOffset === undefined && length === undefined) {
      array = new Uint8Array(array);
    } else if (length === undefined) {
      array = new Uint8Array(array, byteOffset);
    } else {
      array = new Uint8Array(array, byteOffset, length);
    }

    if (Buffer.TYPED_ARRAY_SUPPORT) {
      // Return an augmented `Uint8Array` instance, for best performance
      that = array;
      that.__proto__ = Buffer.prototype;
    } else {
      // Fallback: Return an object instance of the Buffer class
      that = fromArrayLike(that, array);
    }
    return that
  }

  function fromObject (that, obj) {
    if (internalIsBuffer(obj)) {
      var len = checked(obj.length) | 0;
      that = createBuffer(that, len);

      if (that.length === 0) {
        return that
      }

      obj.copy(that, 0, 0, len);
      return that
    }

    if (obj) {
      if ((typeof ArrayBuffer !== 'undefined' &&
          obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
        if (typeof obj.length !== 'number' || isnan(obj.length)) {
          return createBuffer(that, 0)
        }
        return fromArrayLike(that, obj)
      }

      if (obj.type === 'Buffer' && isArray$1(obj.data)) {
        return fromArrayLike(that, obj.data)
      }
    }

    throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
  }

  function checked (length) {
    // Note: cannot use `length < kMaxLength()` here because that fails when
    // length is NaN (which is otherwise coerced to zero.)
    if (length >= kMaxLength()) {
      throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                           'size: 0x' + kMaxLength().toString(16) + ' bytes')
    }
    return length | 0
  }
  Buffer.isBuffer = isBuffer;
  function internalIsBuffer (b) {
    return !!(b != null && b._isBuffer)
  }

  Buffer.compare = function compare (a, b) {
    if (!internalIsBuffer(a) || !internalIsBuffer(b)) {
      throw new TypeError('Arguments must be Buffers')
    }

    if (a === b) return 0

    var x = a.length;
    var y = b.length;

    for (var i = 0, len = Math.min(x, y); i < len; ++i) {
      if (a[i] !== b[i]) {
        x = a[i];
        y = b[i];
        break
      }
    }

    if (x < y) return -1
    if (y < x) return 1
    return 0
  };

  Buffer.isEncoding = function isEncoding (encoding) {
    switch (String(encoding).toLowerCase()) {
      case 'hex':
      case 'utf8':
      case 'utf-8':
      case 'ascii':
      case 'latin1':
      case 'binary':
      case 'base64':
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return true
      default:
        return false
    }
  };

  Buffer.concat = function concat (list, length) {
    if (!isArray$1(list)) {
      throw new TypeError('"list" argument must be an Array of Buffers')
    }

    if (list.length === 0) {
      return Buffer.alloc(0)
    }

    var i;
    if (length === undefined) {
      length = 0;
      for (i = 0; i < list.length; ++i) {
        length += list[i].length;
      }
    }

    var buffer = Buffer.allocUnsafe(length);
    var pos = 0;
    for (i = 0; i < list.length; ++i) {
      var buf = list[i];
      if (!internalIsBuffer(buf)) {
        throw new TypeError('"list" argument must be an Array of Buffers')
      }
      buf.copy(buffer, pos);
      pos += buf.length;
    }
    return buffer
  };

  function byteLength (string, encoding) {
    if (internalIsBuffer(string)) {
      return string.length
    }
    if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
        (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
      return string.byteLength
    }
    if (typeof string !== 'string') {
      string = '' + string;
    }

    var len = string.length;
    if (len === 0) return 0

    // Use a for loop to avoid recursion
    var loweredCase = false;
    for (;;) {
      switch (encoding) {
        case 'ascii':
        case 'latin1':
        case 'binary':
          return len
        case 'utf8':
        case 'utf-8':
        case undefined:
          return utf8ToBytes(string).length
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return len * 2
        case 'hex':
          return len >>> 1
        case 'base64':
          return base64ToBytes(string).length
        default:
          if (loweredCase) return utf8ToBytes(string).length // assume utf8
          encoding = ('' + encoding).toLowerCase();
          loweredCase = true;
      }
    }
  }
  Buffer.byteLength = byteLength;

  function slowToString (encoding, start, end) {
    var loweredCase = false;

    // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
    // property of a typed array.

    // This behaves neither like String nor Uint8Array in that we set start/end
    // to their upper/lower bounds if the value passed is out of range.
    // undefined is handled specially as per ECMA-262 6th Edition,
    // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
    if (start === undefined || start < 0) {
      start = 0;
    }
    // Return early if start > this.length. Done here to prevent potential uint32
    // coercion fail below.
    if (start > this.length) {
      return ''
    }

    if (end === undefined || end > this.length) {
      end = this.length;
    }

    if (end <= 0) {
      return ''
    }

    // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
    end >>>= 0;
    start >>>= 0;

    if (end <= start) {
      return ''
    }

    if (!encoding) encoding = 'utf8';

    while (true) {
      switch (encoding) {
        case 'hex':
          return hexSlice(this, start, end)

        case 'utf8':
        case 'utf-8':
          return utf8Slice(this, start, end)

        case 'ascii':
          return asciiSlice(this, start, end)

        case 'latin1':
        case 'binary':
          return latin1Slice(this, start, end)

        case 'base64':
          return base64Slice(this, start, end)

        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return utf16leSlice(this, start, end)

        default:
          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
          encoding = (encoding + '').toLowerCase();
          loweredCase = true;
      }
    }
  }

  // The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
  // Buffer instances.
  Buffer.prototype._isBuffer = true;

  function swap$1 (b, n, m) {
    var i = b[n];
    b[n] = b[m];
    b[m] = i;
  }

  Buffer.prototype.swap16 = function swap16 () {
    var len = this.length;
    if (len % 2 !== 0) {
      throw new RangeError('Buffer size must be a multiple of 16-bits')
    }
    for (var i = 0; i < len; i += 2) {
      swap$1(this, i, i + 1);
    }
    return this
  };

  Buffer.prototype.swap32 = function swap32 () {
    var len = this.length;
    if (len % 4 !== 0) {
      throw new RangeError('Buffer size must be a multiple of 32-bits')
    }
    for (var i = 0; i < len; i += 4) {
      swap$1(this, i, i + 3);
      swap$1(this, i + 1, i + 2);
    }
    return this
  };

  Buffer.prototype.swap64 = function swap64 () {
    var len = this.length;
    if (len % 8 !== 0) {
      throw new RangeError('Buffer size must be a multiple of 64-bits')
    }
    for (var i = 0; i < len; i += 8) {
      swap$1(this, i, i + 7);
      swap$1(this, i + 1, i + 6);
      swap$1(this, i + 2, i + 5);
      swap$1(this, i + 3, i + 4);
    }
    return this
  };

  Buffer.prototype.toString = function toString () {
    var length = this.length | 0;
    if (length === 0) return ''
    if (arguments.length === 0) return utf8Slice(this, 0, length)
    return slowToString.apply(this, arguments)
  };

  Buffer.prototype.equals = function equals (b) {
    if (!internalIsBuffer(b)) throw new TypeError('Argument must be a Buffer')
    if (this === b) return true
    return Buffer.compare(this, b) === 0
  };

  Buffer.prototype.inspect = function inspect () {
    var str = '';
    var max = INSPECT_MAX_BYTES;
    if (this.length > 0) {
      str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
      if (this.length > max) str += ' ... ';
    }
    return '<Buffer ' + str + '>'
  };

  Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
    if (!internalIsBuffer(target)) {
      throw new TypeError('Argument must be a Buffer')
    }

    if (start === undefined) {
      start = 0;
    }
    if (end === undefined) {
      end = target ? target.length : 0;
    }
    if (thisStart === undefined) {
      thisStart = 0;
    }
    if (thisEnd === undefined) {
      thisEnd = this.length;
    }

    if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
      throw new RangeError('out of range index')
    }

    if (thisStart >= thisEnd && start >= end) {
      return 0
    }
    if (thisStart >= thisEnd) {
      return -1
    }
    if (start >= end) {
      return 1
    }

    start >>>= 0;
    end >>>= 0;
    thisStart >>>= 0;
    thisEnd >>>= 0;

    if (this === target) return 0

    var x = thisEnd - thisStart;
    var y = end - start;
    var len = Math.min(x, y);

    var thisCopy = this.slice(thisStart, thisEnd);
    var targetCopy = target.slice(start, end);

    for (var i = 0; i < len; ++i) {
      if (thisCopy[i] !== targetCopy[i]) {
        x = thisCopy[i];
        y = targetCopy[i];
        break
      }
    }

    if (x < y) return -1
    if (y < x) return 1
    return 0
  };

  // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
  // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
  //
  // Arguments:
  // - buffer - a Buffer to search
  // - val - a string, Buffer, or number
  // - byteOffset - an index into `buffer`; will be clamped to an int32
  // - encoding - an optional encoding, relevant is val is a string
  // - dir - true for indexOf, false for lastIndexOf
  function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
    // Empty buffer means no match
    if (buffer.length === 0) return -1

    // Normalize byteOffset
    if (typeof byteOffset === 'string') {
      encoding = byteOffset;
      byteOffset = 0;
    } else if (byteOffset > 0x7fffffff) {
      byteOffset = 0x7fffffff;
    } else if (byteOffset < -0x80000000) {
      byteOffset = -0x80000000;
    }
    byteOffset = +byteOffset;  // Coerce to Number.
    if (isNaN(byteOffset)) {
      // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
      byteOffset = dir ? 0 : (buffer.length - 1);
    }

    // Normalize byteOffset: negative offsets start from the end of the buffer
    if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
    if (byteOffset >= buffer.length) {
      if (dir) return -1
      else byteOffset = buffer.length - 1;
    } else if (byteOffset < 0) {
      if (dir) byteOffset = 0;
      else return -1
    }

    // Normalize val
    if (typeof val === 'string') {
      val = Buffer.from(val, encoding);
    }

    // Finally, search either indexOf (if dir is true) or lastIndexOf
    if (internalIsBuffer(val)) {
      // Special case: looking for empty string/buffer always fails
      if (val.length === 0) {
        return -1
      }
      return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
    } else if (typeof val === 'number') {
      val = val & 0xFF; // Search for a byte value [0-255]
      if (Buffer.TYPED_ARRAY_SUPPORT &&
          typeof Uint8Array.prototype.indexOf === 'function') {
        if (dir) {
          return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
        } else {
          return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
        }
      }
      return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
    }

    throw new TypeError('val must be string, number or Buffer')
  }

  function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
    var indexSize = 1;
    var arrLength = arr.length;
    var valLength = val.length;

    if (encoding !== undefined) {
      encoding = String(encoding).toLowerCase();
      if (encoding === 'ucs2' || encoding === 'ucs-2' ||
          encoding === 'utf16le' || encoding === 'utf-16le') {
        if (arr.length < 2 || val.length < 2) {
          return -1
        }
        indexSize = 2;
        arrLength /= 2;
        valLength /= 2;
        byteOffset /= 2;
      }
    }

    function read (buf, i) {
      if (indexSize === 1) {
        return buf[i]
      } else {
        return buf.readUInt16BE(i * indexSize)
      }
    }

    var i;
    if (dir) {
      var foundIndex = -1;
      for (i = byteOffset; i < arrLength; i++) {
        if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
          if (foundIndex === -1) foundIndex = i;
          if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
        } else {
          if (foundIndex !== -1) i -= i - foundIndex;
          foundIndex = -1;
        }
      }
    } else {
      if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
      for (i = byteOffset; i >= 0; i--) {
        var found = true;
        for (var j = 0; j < valLength; j++) {
          if (read(arr, i + j) !== read(val, j)) {
            found = false;
            break
          }
        }
        if (found) return i
      }
    }

    return -1
  }

  Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
    return this.indexOf(val, byteOffset, encoding) !== -1
  };

  Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
    return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
  };

  Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
    return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
  };

  function hexWrite (buf, string, offset, length) {
    offset = Number(offset) || 0;
    var remaining = buf.length - offset;
    if (!length) {
      length = remaining;
    } else {
      length = Number(length);
      if (length > remaining) {
        length = remaining;
      }
    }

    // must be an even number of digits
    var strLen = string.length;
    if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')

    if (length > strLen / 2) {
      length = strLen / 2;
    }
    for (var i = 0; i < length; ++i) {
      var parsed = parseInt(string.substr(i * 2, 2), 16);
      if (isNaN(parsed)) return i
      buf[offset + i] = parsed;
    }
    return i
  }

  function utf8Write (buf, string, offset, length) {
    return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  }

  function asciiWrite (buf, string, offset, length) {
    return blitBuffer(asciiToBytes(string), buf, offset, length)
  }

  function latin1Write (buf, string, offset, length) {
    return asciiWrite(buf, string, offset, length)
  }

  function base64Write (buf, string, offset, length) {
    return blitBuffer(base64ToBytes(string), buf, offset, length)
  }

  function ucs2Write (buf, string, offset, length) {
    return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
  }

  Buffer.prototype.write = function write (string, offset, length, encoding) {
    // Buffer#write(string)
    if (offset === undefined) {
      encoding = 'utf8';
      length = this.length;
      offset = 0;
    // Buffer#write(string, encoding)
    } else if (length === undefined && typeof offset === 'string') {
      encoding = offset;
      length = this.length;
      offset = 0;
    // Buffer#write(string, offset[, length][, encoding])
    } else if (isFinite(offset)) {
      offset = offset | 0;
      if (isFinite(length)) {
        length = length | 0;
        if (encoding === undefined) encoding = 'utf8';
      } else {
        encoding = length;
        length = undefined;
      }
    // legacy write(string, encoding, offset, length) - remove in v0.13
    } else {
      throw new Error(
        'Buffer.write(string, encoding, offset[, length]) is no longer supported'
      )
    }

    var remaining = this.length - offset;
    if (length === undefined || length > remaining) length = remaining;

    if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
      throw new RangeError('Attempt to write outside buffer bounds')
    }

    if (!encoding) encoding = 'utf8';

    var loweredCase = false;
    for (;;) {
      switch (encoding) {
        case 'hex':
          return hexWrite(this, string, offset, length)

        case 'utf8':
        case 'utf-8':
          return utf8Write(this, string, offset, length)

        case 'ascii':
          return asciiWrite(this, string, offset, length)

        case 'latin1':
        case 'binary':
          return latin1Write(this, string, offset, length)

        case 'base64':
          // Warning: maxLength not taken into account in base64Write
          return base64Write(this, string, offset, length)

        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return ucs2Write(this, string, offset, length)

        default:
          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
          encoding = ('' + encoding).toLowerCase();
          loweredCase = true;
      }
    }
  };

  Buffer.prototype.toJSON = function toJSON () {
    return {
      type: 'Buffer',
      data: Array.prototype.slice.call(this._arr || this, 0)
    }
  };

  function base64Slice (buf, start, end) {
    if (start === 0 && end === buf.length) {
      return fromByteArray(buf)
    } else {
      return fromByteArray(buf.slice(start, end))
    }
  }

  function utf8Slice (buf, start, end) {
    end = Math.min(buf.length, end);
    var res = [];

    var i = start;
    while (i < end) {
      var firstByte = buf[i];
      var codePoint = null;
      var bytesPerSequence = (firstByte > 0xEF) ? 4
        : (firstByte > 0xDF) ? 3
        : (firstByte > 0xBF) ? 2
        : 1;

      if (i + bytesPerSequence <= end) {
        var secondByte, thirdByte, fourthByte, tempCodePoint;

        switch (bytesPerSequence) {
          case 1:
            if (firstByte < 0x80) {
              codePoint = firstByte;
            }
            break
          case 2:
            secondByte = buf[i + 1];
            if ((secondByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F);
              if (tempCodePoint > 0x7F) {
                codePoint = tempCodePoint;
              }
            }
            break
          case 3:
            secondByte = buf[i + 1];
            thirdByte = buf[i + 2];
            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F);
              if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
                codePoint = tempCodePoint;
              }
            }
            break
          case 4:
            secondByte = buf[i + 1];
            thirdByte = buf[i + 2];
            fourthByte = buf[i + 3];
            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F);
              if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
                codePoint = tempCodePoint;
              }
            }
        }
      }

      if (codePoint === null) {
        // we did not generate a valid codePoint so insert a
        // replacement char (U+FFFD) and advance only 1 byte
        codePoint = 0xFFFD;
        bytesPerSequence = 1;
      } else if (codePoint > 0xFFFF) {
        // encode to utf16 (surrogate pair dance)
        codePoint -= 0x10000;
        res.push(codePoint >>> 10 & 0x3FF | 0xD800);
        codePoint = 0xDC00 | codePoint & 0x3FF;
      }

      res.push(codePoint);
      i += bytesPerSequence;
    }

    return decodeCodePointsArray(res)
  }

  // Based on http://stackoverflow.com/a/22747272/680742, the browser with
  // the lowest limit is Chrome, with 0x10000 args.
  // We go 1 magnitude less, for safety
  var MAX_ARGUMENTS_LENGTH = 0x1000;

  function decodeCodePointsArray (codePoints) {
    var len = codePoints.length;
    if (len <= MAX_ARGUMENTS_LENGTH) {
      return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
    }

    // Decode in chunks to avoid "call stack size exceeded".
    var res = '';
    var i = 0;
    while (i < len) {
      res += String.fromCharCode.apply(
        String,
        codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
      );
    }
    return res
  }

  function asciiSlice (buf, start, end) {
    var ret = '';
    end = Math.min(buf.length, end);

    for (var i = start; i < end; ++i) {
      ret += String.fromCharCode(buf[i] & 0x7F);
    }
    return ret
  }

  function latin1Slice (buf, start, end) {
    var ret = '';
    end = Math.min(buf.length, end);

    for (var i = start; i < end; ++i) {
      ret += String.fromCharCode(buf[i]);
    }
    return ret
  }

  function hexSlice (buf, start, end) {
    var len = buf.length;

    if (!start || start < 0) start = 0;
    if (!end || end < 0 || end > len) end = len;

    var out = '';
    for (var i = start; i < end; ++i) {
      out += toHex(buf[i]);
    }
    return out
  }

  function utf16leSlice (buf, start, end) {
    var bytes = buf.slice(start, end);
    var res = '';
    for (var i = 0; i < bytes.length; i += 2) {
      res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256);
    }
    return res
  }

  Buffer.prototype.slice = function slice (start, end) {
    var len = this.length;
    start = ~~start;
    end = end === undefined ? len : ~~end;

    if (start < 0) {
      start += len;
      if (start < 0) start = 0;
    } else if (start > len) {
      start = len;
    }

    if (end < 0) {
      end += len;
      if (end < 0) end = 0;
    } else if (end > len) {
      end = len;
    }

    if (end < start) end = start;

    var newBuf;
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      newBuf = this.subarray(start, end);
      newBuf.__proto__ = Buffer.prototype;
    } else {
      var sliceLen = end - start;
      newBuf = new Buffer(sliceLen, undefined);
      for (var i = 0; i < sliceLen; ++i) {
        newBuf[i] = this[i + start];
      }
    }

    return newBuf
  };

  /*
   * Need to make sure that buffer isn't trying to write out of bounds.
   */
  function checkOffset (offset, ext, length) {
    if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
    if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
  }

  Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
    offset = offset | 0;
    byteLength = byteLength | 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);

    var val = this[offset];
    var mul = 1;
    var i = 0;
    while (++i < byteLength && (mul *= 0x100)) {
      val += this[offset + i] * mul;
    }

    return val
  };

  Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
    offset = offset | 0;
    byteLength = byteLength | 0;
    if (!noAssert) {
      checkOffset(offset, byteLength, this.length);
    }

    var val = this[offset + --byteLength];
    var mul = 1;
    while (byteLength > 0 && (mul *= 0x100)) {
      val += this[offset + --byteLength] * mul;
    }

    return val
  };

  Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 1, this.length);
    return this[offset]
  };

  Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length);
    return this[offset] | (this[offset + 1] << 8)
  };

  Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length);
    return (this[offset] << 8) | this[offset + 1]
  };

  Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length);

    return ((this[offset]) |
        (this[offset + 1] << 8) |
        (this[offset + 2] << 16)) +
        (this[offset + 3] * 0x1000000)
  };

  Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length);

    return (this[offset] * 0x1000000) +
      ((this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      this[offset + 3])
  };

  Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
    offset = offset | 0;
    byteLength = byteLength | 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);

    var val = this[offset];
    var mul = 1;
    var i = 0;
    while (++i < byteLength && (mul *= 0x100)) {
      val += this[offset + i] * mul;
    }
    mul *= 0x80;

    if (val >= mul) val -= Math.pow(2, 8 * byteLength);

    return val
  };

  Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
    offset = offset | 0;
    byteLength = byteLength | 0;
    if (!noAssert) checkOffset(offset, byteLength, this.length);

    var i = byteLength;
    var mul = 1;
    var val = this[offset + --i];
    while (i > 0 && (mul *= 0x100)) {
      val += this[offset + --i] * mul;
    }
    mul *= 0x80;

    if (val >= mul) val -= Math.pow(2, 8 * byteLength);

    return val
  };

  Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 1, this.length);
    if (!(this[offset] & 0x80)) return (this[offset])
    return ((0xff - this[offset] + 1) * -1)
  };

  Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length);
    var val = this[offset] | (this[offset + 1] << 8);
    return (val & 0x8000) ? val | 0xFFFF0000 : val
  };

  Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length);
    var val = this[offset + 1] | (this[offset] << 8);
    return (val & 0x8000) ? val | 0xFFFF0000 : val
  };

  Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length);

    return (this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16) |
      (this[offset + 3] << 24)
  };

  Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length);

    return (this[offset] << 24) |
      (this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      (this[offset + 3])
  };

  Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length);
    return read(this, offset, true, 23, 4)
  };

  Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length);
    return read(this, offset, false, 23, 4)
  };

  Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 8, this.length);
    return read(this, offset, true, 52, 8)
  };

  Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 8, this.length);
    return read(this, offset, false, 52, 8)
  };

  function checkInt (buf, value, offset, ext, max, min) {
    if (!internalIsBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
    if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
    if (offset + ext > buf.length) throw new RangeError('Index out of range')
  }

  Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset | 0;
    byteLength = byteLength | 0;
    if (!noAssert) {
      var maxBytes = Math.pow(2, 8 * byteLength) - 1;
      checkInt(this, value, offset, byteLength, maxBytes, 0);
    }

    var mul = 1;
    var i = 0;
    this[offset] = value & 0xFF;
    while (++i < byteLength && (mul *= 0x100)) {
      this[offset + i] = (value / mul) & 0xFF;
    }

    return offset + byteLength
  };

  Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset | 0;
    byteLength = byteLength | 0;
    if (!noAssert) {
      var maxBytes = Math.pow(2, 8 * byteLength) - 1;
      checkInt(this, value, offset, byteLength, maxBytes, 0);
    }

    var i = byteLength - 1;
    var mul = 1;
    this[offset + i] = value & 0xFF;
    while (--i >= 0 && (mul *= 0x100)) {
      this[offset + i] = (value / mul) & 0xFF;
    }

    return offset + byteLength
  };

  Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0);
    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value);
    this[offset] = (value & 0xff);
    return offset + 1
  };

  function objectWriteUInt16 (buf, value, offset, littleEndian) {
    if (value < 0) value = 0xffff + value + 1;
    for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
      buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
        (littleEndian ? i : 1 - i) * 8;
    }
  }

  Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff);
      this[offset + 1] = (value >>> 8);
    } else {
      objectWriteUInt16(this, value, offset, true);
    }
    return offset + 2
  };

  Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 8);
      this[offset + 1] = (value & 0xff);
    } else {
      objectWriteUInt16(this, value, offset, false);
    }
    return offset + 2
  };

  function objectWriteUInt32 (buf, value, offset, littleEndian) {
    if (value < 0) value = 0xffffffff + value + 1;
    for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
      buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff;
    }
  }

  Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset + 3] = (value >>> 24);
      this[offset + 2] = (value >>> 16);
      this[offset + 1] = (value >>> 8);
      this[offset] = (value & 0xff);
    } else {
      objectWriteUInt32(this, value, offset, true);
    }
    return offset + 4
  };

  Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 24);
      this[offset + 1] = (value >>> 16);
      this[offset + 2] = (value >>> 8);
      this[offset + 3] = (value & 0xff);
    } else {
      objectWriteUInt32(this, value, offset, false);
    }
    return offset + 4
  };

  Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) {
      var limit = Math.pow(2, 8 * byteLength - 1);

      checkInt(this, value, offset, byteLength, limit - 1, -limit);
    }

    var i = 0;
    var mul = 1;
    var sub = 0;
    this[offset] = value & 0xFF;
    while (++i < byteLength && (mul *= 0x100)) {
      if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
        sub = 1;
      }
      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF;
    }

    return offset + byteLength
  };

  Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) {
      var limit = Math.pow(2, 8 * byteLength - 1);

      checkInt(this, value, offset, byteLength, limit - 1, -limit);
    }

    var i = byteLength - 1;
    var mul = 1;
    var sub = 0;
    this[offset + i] = value & 0xFF;
    while (--i >= 0 && (mul *= 0x100)) {
      if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
        sub = 1;
      }
      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF;
    }

    return offset + byteLength
  };

  Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80);
    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value);
    if (value < 0) value = 0xff + value + 1;
    this[offset] = (value & 0xff);
    return offset + 1
  };

  Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff);
      this[offset + 1] = (value >>> 8);
    } else {
      objectWriteUInt16(this, value, offset, true);
    }
    return offset + 2
  };

  Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 8);
      this[offset + 1] = (value & 0xff);
    } else {
      objectWriteUInt16(this, value, offset, false);
    }
    return offset + 2
  };

  Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff);
      this[offset + 1] = (value >>> 8);
      this[offset + 2] = (value >>> 16);
      this[offset + 3] = (value >>> 24);
    } else {
      objectWriteUInt32(this, value, offset, true);
    }
    return offset + 4
  };

  Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
    value = +value;
    offset = offset | 0;
    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
    if (value < 0) value = 0xffffffff + value + 1;
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 24);
      this[offset + 1] = (value >>> 16);
      this[offset + 2] = (value >>> 8);
      this[offset + 3] = (value & 0xff);
    } else {
      objectWriteUInt32(this, value, offset, false);
    }
    return offset + 4
  };

  function checkIEEE754 (buf, value, offset, ext, max, min) {
    if (offset + ext > buf.length) throw new RangeError('Index out of range')
    if (offset < 0) throw new RangeError('Index out of range')
  }

  function writeFloat (buf, value, offset, littleEndian, noAssert) {
    if (!noAssert) {
      checkIEEE754(buf, value, offset, 4);
    }
    write(buf, value, offset, littleEndian, 23, 4);
    return offset + 4
  }

  Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
    return writeFloat(this, value, offset, true, noAssert)
  };

  Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
    return writeFloat(this, value, offset, false, noAssert)
  };

  function writeDouble (buf, value, offset, littleEndian, noAssert) {
    if (!noAssert) {
      checkIEEE754(buf, value, offset, 8);
    }
    write(buf, value, offset, littleEndian, 52, 8);
    return offset + 8
  }

  Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
    return writeDouble(this, value, offset, true, noAssert)
  };

  Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
    return writeDouble(this, value, offset, false, noAssert)
  };

  // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
  Buffer.prototype.copy = function copy (target, targetStart, start, end) {
    if (!start) start = 0;
    if (!end && end !== 0) end = this.length;
    if (targetStart >= target.length) targetStart = target.length;
    if (!targetStart) targetStart = 0;
    if (end > 0 && end < start) end = start;

    // Copy 0 bytes; we're done
    if (end === start) return 0
    if (target.length === 0 || this.length === 0) return 0

    // Fatal error conditions
    if (targetStart < 0) {
      throw new RangeError('targetStart out of bounds')
    }
    if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
    if (end < 0) throw new RangeError('sourceEnd out of bounds')

    // Are we oob?
    if (end > this.length) end = this.length;
    if (target.length - targetStart < end - start) {
      end = target.length - targetStart + start;
    }

    var len = end - start;
    var i;

    if (this === target && start < targetStart && targetStart < end) {
      // descending copy from end
      for (i = len - 1; i >= 0; --i) {
        target[i + targetStart] = this[i + start];
      }
    } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
      // ascending copy from start
      for (i = 0; i < len; ++i) {
        target[i + targetStart] = this[i + start];
      }
    } else {
      Uint8Array.prototype.set.call(
        target,
        this.subarray(start, start + len),
        targetStart
      );
    }

    return len
  };

  // Usage:
  //    buffer.fill(number[, offset[, end]])
  //    buffer.fill(buffer[, offset[, end]])
  //    buffer.fill(string[, offset[, end]][, encoding])
  Buffer.prototype.fill = function fill (val, start, end, encoding) {
    // Handle string cases:
    if (typeof val === 'string') {
      if (typeof start === 'string') {
        encoding = start;
        start = 0;
        end = this.length;
      } else if (typeof end === 'string') {
        encoding = end;
        end = this.length;
      }
      if (val.length === 1) {
        var code = val.charCodeAt(0);
        if (code < 256) {
          val = code;
        }
      }
      if (encoding !== undefined && typeof encoding !== 'string') {
        throw new TypeError('encoding must be a string')
      }
      if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
        throw new TypeError('Unknown encoding: ' + encoding)
      }
    } else if (typeof val === 'number') {
      val = val & 255;
    }

    // Invalid ranges are not set to a default, so can range check early.
    if (start < 0 || this.length < start || this.length < end) {
      throw new RangeError('Out of range index')
    }

    if (end <= start) {
      return this
    }

    start = start >>> 0;
    end = end === undefined ? this.length : end >>> 0;

    if (!val) val = 0;

    var i;
    if (typeof val === 'number') {
      for (i = start; i < end; ++i) {
        this[i] = val;
      }
    } else {
      var bytes = internalIsBuffer(val)
        ? val
        : utf8ToBytes(new Buffer(val, encoding).toString());
      var len = bytes.length;
      for (i = 0; i < end - start; ++i) {
        this[i + start] = bytes[i % len];
      }
    }

    return this
  };

  // HELPER FUNCTIONS
  // ================

  var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g;

  function base64clean (str) {
    // Node strips out invalid characters like \n and \t from the string, base64-js does not
    str = stringtrim(str).replace(INVALID_BASE64_RE, '');
    // Node converts strings with length < 2 to ''
    if (str.length < 2) return ''
    // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
    while (str.length % 4 !== 0) {
      str = str + '=';
    }
    return str
  }

  function stringtrim (str) {
    if (str.trim) return str.trim()
    return str.replace(/^\s+|\s+$/g, '')
  }

  function toHex (n) {
    if (n < 16) return '0' + n.toString(16)
    return n.toString(16)
  }

  function utf8ToBytes (string, units) {
    units = units || Infinity;
    var codePoint;
    var length = string.length;
    var leadSurrogate = null;
    var bytes = [];

    for (var i = 0; i < length; ++i) {
      codePoint = string.charCodeAt(i);

      // is surrogate component
      if (codePoint > 0xD7FF && codePoint < 0xE000) {
        // last char was a lead
        if (!leadSurrogate) {
          // no lead yet
          if (codePoint > 0xDBFF) {
            // unexpected trail
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
            continue
          } else if (i + 1 === length) {
            // unpaired lead
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
            continue
          }

          // valid lead
          leadSurrogate = codePoint;

          continue
        }

        // 2 leads in a row
        if (codePoint < 0xDC00) {
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
          leadSurrogate = codePoint;
          continue
        }

        // valid surrogate pair
        codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000;
      } else if (leadSurrogate) {
        // valid bmp char, but last char was a lead
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
      }

      leadSurrogate = null;

      // encode utf8
      if (codePoint < 0x80) {
        if ((units -= 1) < 0) break
        bytes.push(codePoint);
      } else if (codePoint < 0x800) {
        if ((units -= 2) < 0) break
        bytes.push(
          codePoint >> 0x6 | 0xC0,
          codePoint & 0x3F | 0x80
        );
      } else if (codePoint < 0x10000) {
        if ((units -= 3) < 0) break
        bytes.push(
          codePoint >> 0xC | 0xE0,
          codePoint >> 0x6 & 0x3F | 0x80,
          codePoint & 0x3F | 0x80
        );
      } else if (codePoint < 0x110000) {
        if ((units -= 4) < 0) break
        bytes.push(
          codePoint >> 0x12 | 0xF0,
          codePoint >> 0xC & 0x3F | 0x80,
          codePoint >> 0x6 & 0x3F | 0x80,
          codePoint & 0x3F | 0x80
        );
      } else {
        throw new Error('Invalid code point')
      }
    }

    return bytes
  }

  function asciiToBytes (str) {
    var byteArray = [];
    for (var i = 0; i < str.length; ++i) {
      // Node's code seems to be doing this and not & 0x7F..
      byteArray.push(str.charCodeAt(i) & 0xFF);
    }
    return byteArray
  }

  function utf16leToBytes (str, units) {
    var c, hi, lo;
    var byteArray = [];
    for (var i = 0; i < str.length; ++i) {
      if ((units -= 2) < 0) break

      c = str.charCodeAt(i);
      hi = c >> 8;
      lo = c % 256;
      byteArray.push(lo);
      byteArray.push(hi);
    }

    return byteArray
  }


  function base64ToBytes (str) {
    return toByteArray(base64clean(str))
  }

  function blitBuffer (src, dst, offset, length) {
    for (var i = 0; i < length; ++i) {
      if ((i + offset >= dst.length) || (i >= src.length)) break
      dst[i + offset] = src[i];
    }
    return i
  }

  function isnan (val) {
    return val !== val // eslint-disable-line no-self-compare
  }


  // the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence
  // The _isBuffer check is for Safari 5-7 support, because it's missing
  // Object.prototype.constructor. Remove this eventually
  function isBuffer(obj) {
    return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj))
  }

  function isFastBuffer (obj) {
    return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
  }

  // For Node v0.10 support. Remove this eventually.
  function isSlowBuffer (obj) {
    return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0))
  }

  var inherits;
  if (typeof Object.create === 'function'){
    inherits = function inherits(ctor, superCtor) {
      // implementation from standard node.js 'util' module
      ctor.super_ = superCtor;
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: ctor,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
    };
  } else {
    inherits = function inherits(ctor, superCtor) {
      ctor.super_ = superCtor;
      var TempCtor = function () {};
      TempCtor.prototype = superCtor.prototype;
      ctor.prototype = new TempCtor();
      ctor.prototype.constructor = ctor;
    };
  }
  var inherits$1 = inherits;

  var formatRegExp = /%[sdj%]/g;
  function format(f) {
    if (!isString$1(f)) {
      var objects = [];
      for (var i = 0; i < arguments.length; i++) {
        objects.push(inspect(arguments[i]));
      }
      return objects.join(' ');
    }

    var i = 1;
    var args = arguments;
    var len = args.length;
    var str = String(f).replace(formatRegExp, function(x) {
      if (x === '%%') return '%';
      if (i >= len) return x;
      switch (x) {
        case '%s': return String(args[i++]);
        case '%d': return Number(args[i++]);
        case '%j':
          try {
            return JSON.stringify(args[i++]);
          } catch (_) {
            return '[Circular]';
          }
        default:
          return x;
      }
    });
    for (var x = args[i]; i < len; x = args[++i]) {
      if (isNull(x) || !isObject$1(x)) {
        str += ' ' + x;
      } else {
        str += ' ' + inspect(x);
      }
    }
    return str;
  }

  // Mark that a method should not be used.
  // Returns a modified function which warns once by default.
  // If --no-deprecation is set, then it is a no-op.
  function deprecate(fn, msg) {
    // Allow for deprecating things in the process of starting up.
    if (isUndefined(global$1.process)) {
      return function() {
        return deprecate(fn, msg).apply(this, arguments);
      };
    }

    var warned = false;
    function deprecated() {
      if (!warned) {
        {
          console.error(msg);
        }
        warned = true;
      }
      return fn.apply(this, arguments);
    }

    return deprecated;
  }

  var debugs = {};
  var debugEnviron;
  function debuglog(set) {
    if (isUndefined(debugEnviron))
      debugEnviron =  '';
    set = set.toUpperCase();
    if (!debugs[set]) {
      if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
        var pid = 0;
        debugs[set] = function() {
          var msg = format.apply(null, arguments);
          console.error('%s %d: %s', set, pid, msg);
        };
      } else {
        debugs[set] = function() {};
      }
    }
    return debugs[set];
  }

  /**
   * Echos the value of a value. Trys to print the value out
   * in the best way possible given the different types.
   *
   * @param {Object} obj The object to print out.
   * @param {Object} opts Optional options object that alters the output.
   */
  /* legacy: obj, showHidden, depth, colors*/
  function inspect(obj, opts) {
    // default options
    var ctx = {
      seen: [],
      stylize: stylizeNoColor
    };
    // legacy...
    if (arguments.length >= 3) ctx.depth = arguments[2];
    if (arguments.length >= 4) ctx.colors = arguments[3];
    if (isBoolean(opts)) {
      // legacy...
      ctx.showHidden = opts;
    } else if (opts) {
      // got an "options" object
      _extend(ctx, opts);
    }
    // set default options
    if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
    if (isUndefined(ctx.depth)) ctx.depth = 2;
    if (isUndefined(ctx.colors)) ctx.colors = false;
    if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
    if (ctx.colors) ctx.stylize = stylizeWithColor;
    return formatValue(ctx, obj, ctx.depth);
  }

  // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
  inspect.colors = {
    'bold' : [1, 22],
    'italic' : [3, 23],
    'underline' : [4, 24],
    'inverse' : [7, 27],
    'white' : [37, 39],
    'grey' : [90, 39],
    'black' : [30, 39],
    'blue' : [34, 39],
    'cyan' : [36, 39],
    'green' : [32, 39],
    'magenta' : [35, 39],
    'red' : [31, 39],
    'yellow' : [33, 39]
  };

  // Don't use 'blue' not visible on cmd.exe
  inspect.styles = {
    'special': 'cyan',
    'number': 'yellow',
    'boolean': 'yellow',
    'undefined': 'grey',
    'null': 'bold',
    'string': 'green',
    'date': 'magenta',
    // "name": intentionally not styling
    'regexp': 'red'
  };


  function stylizeWithColor(str, styleType) {
    var style = inspect.styles[styleType];

    if (style) {
      return '\u001b[' + inspect.colors[style][0] + 'm' + str +
             '\u001b[' + inspect.colors[style][1] + 'm';
    } else {
      return str;
    }
  }


  function stylizeNoColor(str, styleType) {
    return str;
  }


  function arrayToHash(array) {
    var hash = {};

    array.forEach(function(val, idx) {
      hash[val] = true;
    });

    return hash;
  }


  function formatValue(ctx, value, recurseTimes) {
    // Provide a hook for user-specified inspect functions.
    // Check that value is an object with an inspect function on it
    if (ctx.customInspect &&
        value &&
        isFunction$2(value.inspect) &&
        // Filter out the util module, it's inspect function is special
        value.inspect !== inspect &&
        // Also filter out any prototype objects using the circular check.
        !(value.constructor && value.constructor.prototype === value)) {
      var ret = value.inspect(recurseTimes, ctx);
      if (!isString$1(ret)) {
        ret = formatValue(ctx, ret, recurseTimes);
      }
      return ret;
    }

    // Primitive types cannot have properties
    var primitive = formatPrimitive(ctx, value);
    if (primitive) {
      return primitive;
    }

    // Look up the keys of the object.
    var keys = Object.keys(value);
    var visibleKeys = arrayToHash(keys);

    if (ctx.showHidden) {
      keys = Object.getOwnPropertyNames(value);
    }

    // IE doesn't make error fields non-enumerable
    // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
    if (isError(value)
        && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
      return formatError(value);
    }

    // Some type of object without properties can be shortcutted.
    if (keys.length === 0) {
      if (isFunction$2(value)) {
        var name = value.name ? ': ' + value.name : '';
        return ctx.stylize('[Function' + name + ']', 'special');
      }
      if (isRegExp(value)) {
        return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
      }
      if (isDate(value)) {
        return ctx.stylize(Date.prototype.toString.call(value), 'date');
      }
      if (isError(value)) {
        return formatError(value);
      }
    }

    var base = '', array = false, braces = ['{', '}'];

    // Make Array say that they are Array
    if (isArray$2(value)) {
      array = true;
      braces = ['[', ']'];
    }

    // Make functions say that they are functions
    if (isFunction$2(value)) {
      var n = value.name ? ': ' + value.name : '';
      base = ' [Function' + n + ']';
    }

    // Make RegExps say that they are RegExps
    if (isRegExp(value)) {
      base = ' ' + RegExp.prototype.toString.call(value);
    }

    // Make dates with properties first say the date
    if (isDate(value)) {
      base = ' ' + Date.prototype.toUTCString.call(value);
    }

    // Make error with message first say the error
    if (isError(value)) {
      base = ' ' + formatError(value);
    }

    if (keys.length === 0 && (!array || value.length == 0)) {
      return braces[0] + base + braces[1];
    }

    if (recurseTimes < 0) {
      if (isRegExp(value)) {
        return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
      } else {
        return ctx.stylize('[Object]', 'special');
      }
    }

    ctx.seen.push(value);

    var output;
    if (array) {
      output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
    } else {
      output = keys.map(function(key) {
        return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
      });
    }

    ctx.seen.pop();

    return reduceToSingleString(output, base, braces);
  }


  function formatPrimitive(ctx, value) {
    if (isUndefined(value))
      return ctx.stylize('undefined', 'undefined');
    if (isString$1(value)) {
      var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                               .replace(/'/g, "\\'")
                                               .replace(/\\"/g, '"') + '\'';
      return ctx.stylize(simple, 'string');
    }
    if (isNumber(value))
      return ctx.stylize('' + value, 'number');
    if (isBoolean(value))
      return ctx.stylize('' + value, 'boolean');
    // For some reason typeof null is "object", so special case here.
    if (isNull(value))
      return ctx.stylize('null', 'null');
  }


  function formatError(value) {
    return '[' + Error.prototype.toString.call(value) + ']';
  }


  function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
    var output = [];
    for (var i = 0, l = value.length; i < l; ++i) {
      if (hasOwnProperty$1(value, String(i))) {
        output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
            String(i), true));
      } else {
        output.push('');
      }
    }
    keys.forEach(function(key) {
      if (!key.match(/^\d+$/)) {
        output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
            key, true));
      }
    });
    return output;
  }


  function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
    var name, str, desc;
    desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
    if (desc.get) {
      if (desc.set) {
        str = ctx.stylize('[Getter/Setter]', 'special');
      } else {
        str = ctx.stylize('[Getter]', 'special');
      }
    } else {
      if (desc.set) {
        str = ctx.stylize('[Setter]', 'special');
      }
    }
    if (!hasOwnProperty$1(visibleKeys, key)) {
      name = '[' + key + ']';
    }
    if (!str) {
      if (ctx.seen.indexOf(desc.value) < 0) {
        if (isNull(recurseTimes)) {
          str = formatValue(ctx, desc.value, null);
        } else {
          str = formatValue(ctx, desc.value, recurseTimes - 1);
        }
        if (str.indexOf('\n') > -1) {
          if (array) {
            str = str.split('\n').map(function(line) {
              return '  ' + line;
            }).join('\n').substr(2);
          } else {
            str = '\n' + str.split('\n').map(function(line) {
              return '   ' + line;
            }).join('\n');
          }
        }
      } else {
        str = ctx.stylize('[Circular]', 'special');
      }
    }
    if (isUndefined(name)) {
      if (array && key.match(/^\d+$/)) {
        return str;
      }
      name = JSON.stringify('' + key);
      if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
        name = name.substr(1, name.length - 2);
        name = ctx.stylize(name, 'name');
      } else {
        name = name.replace(/'/g, "\\'")
                   .replace(/\\"/g, '"')
                   .replace(/(^"|"$)/g, "'");
        name = ctx.stylize(name, 'string');
      }
    }

    return name + ': ' + str;
  }


  function reduceToSingleString(output, base, braces) {
    var length = output.reduce(function(prev, cur) {
      if (cur.indexOf('\n') >= 0) ;
      return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
    }, 0);

    if (length > 60) {
      return braces[0] +
             (base === '' ? '' : base + '\n ') +
             ' ' +
             output.join(',\n  ') +
             ' ' +
             braces[1];
    }

    return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
  }


  // NOTE: These type checking functions intentionally don't use `instanceof`
  // because it is fragile and can be easily faked with `Object.create()`.
  function isArray$2(ar) {
    return Array.isArray(ar);
  }

  function isBoolean(arg) {
    return typeof arg === 'boolean';
  }

  function isNull(arg) {
    return arg === null;
  }

  function isNullOrUndefined(arg) {
    return arg == null;
  }

  function isNumber(arg) {
    return typeof arg === 'number';
  }

  function isString$1(arg) {
    return typeof arg === 'string';
  }

  function isSymbol$1(arg) {
    return typeof arg === 'symbol';
  }

  function isUndefined(arg) {
    return arg === void 0;
  }

  function isRegExp(re) {
    return isObject$1(re) && objectToString$1(re) === '[object RegExp]';
  }

  function isObject$1(arg) {
    return typeof arg === 'object' && arg !== null;
  }

  function isDate(d) {
    return isObject$1(d) && objectToString$1(d) === '[object Date]';
  }

  function isError(e) {
    return isObject$1(e) &&
        (objectToString$1(e) === '[object Error]' || e instanceof Error);
  }

  function isFunction$2(arg) {
    return typeof arg === 'function';
  }

  function isPrimitive(arg) {
    return arg === null ||
           typeof arg === 'boolean' ||
           typeof arg === 'number' ||
           typeof arg === 'string' ||
           typeof arg === 'symbol' ||  // ES6 symbol
           typeof arg === 'undefined';
  }

  function isBuffer$1(maybeBuf) {
    return isBuffer(maybeBuf);
  }

  function objectToString$1(o) {
    return Object.prototype.toString.call(o);
  }


  function pad(n) {
    return n < 10 ? '0' + n.toString(10) : n.toString(10);
  }


  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
                'Oct', 'Nov', 'Dec'];

  // 26 Feb 16:19:34
  function timestamp() {
    var d = new Date();
    var time = [pad(d.getHours()),
                pad(d.getMinutes()),
                pad(d.getSeconds())].join(':');
    return [d.getDate(), months[d.getMonth()], time].join(' ');
  }


  // log is just a thin wrapper to console.log that prepends a timestamp
  function log() {
    console.log('%s - %s', timestamp(), format.apply(null, arguments));
  }

  function _extend(origin, add) {
    // Don't do anything if add isn't an object
    if (!add || !isObject$1(add)) return origin;

    var keys = Object.keys(add);
    var i = keys.length;
    while (i--) {
      origin[keys[i]] = add[keys[i]];
    }
    return origin;
  }
  function hasOwnProperty$1(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }

  var util$1 = {
    inherits: inherits$1,
    _extend: _extend,
    log: log,
    isBuffer: isBuffer$1,
    isPrimitive: isPrimitive,
    isFunction: isFunction$2,
    isError: isError,
    isDate: isDate,
    isObject: isObject$1,
    isRegExp: isRegExp,
    isUndefined: isUndefined,
    isSymbol: isSymbol$1,
    isString: isString$1,
    isNumber: isNumber,
    isNullOrUndefined: isNullOrUndefined,
    isNull: isNull,
    isBoolean: isBoolean,
    isArray: isArray$2,
    inspect: inspect,
    deprecate: deprecate,
    format: format,
    debuglog: debuglog
  };

  var util$2 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    format: format,
    deprecate: deprecate,
    debuglog: debuglog,
    inspect: inspect,
    isArray: isArray$2,
    isBoolean: isBoolean,
    isNull: isNull,
    isNullOrUndefined: isNullOrUndefined,
    isNumber: isNumber,
    isString: isString$1,
    isSymbol: isSymbol$1,
    isUndefined: isUndefined,
    isRegExp: isRegExp,
    isObject: isObject$1,
    isDate: isDate,
    isError: isError,
    isFunction: isFunction$2,
    isPrimitive: isPrimitive,
    isBuffer: isBuffer$1,
    log: log,
    inherits: inherits$1,
    _extend: _extend,
    'default': util$1
  });

  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.


  // If obj.hasOwnProperty has been overridden, then calling
  // obj.hasOwnProperty(prop) will break.
  // See: https://github.com/joyent/node/issues/1707
  function hasOwnProperty$2(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }
  var isArray$3 = Array.isArray || function (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
  };
  function stringifyPrimitive(v) {
    switch (typeof v) {
      case 'string':
        return v;

      case 'boolean':
        return v ? 'true' : 'false';

      case 'number':
        return isFinite(v) ? v : '';

      default:
        return '';
    }
  }

  function stringify (obj, sep, eq, name) {
    sep = sep || '&';
    eq = eq || '=';
    if (obj === null) {
      obj = undefined;
    }

    if (typeof obj === 'object') {
      return map$1(objectKeys(obj), function(k) {
        var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
        if (isArray$3(obj[k])) {
          return map$1(obj[k], function(v) {
            return ks + encodeURIComponent(stringifyPrimitive(v));
          }).join(sep);
        } else {
          return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
        }
      }).join(sep);

    }

    if (!name) return '';
    return encodeURIComponent(stringifyPrimitive(name)) + eq +
           encodeURIComponent(stringifyPrimitive(obj));
  }
  function map$1 (xs, f) {
    if (xs.map) return xs.map(f);
    var res = [];
    for (var i = 0; i < xs.length; i++) {
      res.push(f(xs[i], i));
    }
    return res;
  }

  var objectKeys = Object.keys || function (obj) {
    var res = [];
    for (var key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
    }
    return res;
  };

  function parse$2(qs, sep, eq, options) {
    sep = sep || '&';
    eq = eq || '=';
    var obj = {};

    if (typeof qs !== 'string' || qs.length === 0) {
      return obj;
    }

    var regexp = /\+/g;
    qs = qs.split(sep);

    var maxKeys = 1000;
    if (options && typeof options.maxKeys === 'number') {
      maxKeys = options.maxKeys;
    }

    var len = qs.length;
    // maxKeys <= 0 means that we should not limit keys count
    if (maxKeys > 0 && len > maxKeys) {
      len = maxKeys;
    }

    for (var i = 0; i < len; ++i) {
      var x = qs[i].replace(regexp, '%20'),
          idx = x.indexOf(eq),
          kstr, vstr, k, v;

      if (idx >= 0) {
        kstr = x.substr(0, idx);
        vstr = x.substr(idx + 1);
      } else {
        kstr = x;
        vstr = '';
      }

      k = decodeURIComponent(kstr);
      v = decodeURIComponent(vstr);

      if (!hasOwnProperty$2(obj, k)) {
        obj[k] = v;
      } else if (isArray$3(obj[k])) {
        obj[k].push(v);
      } else {
        obj[k] = [obj[k], v];
      }
    }

    return obj;
  }

  // Copyright Joyent, Inc. and other Node contributors.
  function Url() {
    this.protocol = null;
    this.slashes = null;
    this.auth = null;
    this.host = null;
    this.port = null;
    this.hostname = null;
    this.hash = null;
    this.search = null;
    this.query = null;
    this.pathname = null;
    this.path = null;
    this.href = null;
  }

  // Reference: RFC 3986, RFC 1808, RFC 2396

  // define these here so at least they only have to be
  // compiled once on the first module load.
  var protocolPattern = /^([a-z0-9.+-]+:)/i,
    portPattern = /:[0-9]*$/,

    // Special case for a simple path URL
    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,

    // RFC 2396: characters reserved for delimiting URLs.
    // We actually just auto-escape these.
    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],

    // RFC 2396: characters not allowed for various reasons.
    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),

    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
    autoEscape = ['\''].concat(unwise),
    // Characters that are never ever allowed in a hostname.
    // Note that any invalid chars are also handled, but these
    // are the ones that are *expected* to be seen, so we fast-path
    // them.
    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
    hostEndingChars = ['/', '?', '#'],
    hostnameMaxLen = 255,
    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
    // protocols that can allow "unsafe" and "unwise" chars.
    unsafeProtocol = {
      'javascript': true,
      'javascript:': true
    },
    // protocols that never have a hostname.
    hostlessProtocol = {
      'javascript': true,
      'javascript:': true
    },
    // protocols that always contain a // bit.
    slashedProtocol = {
      'http': true,
      'https': true,
      'ftp': true,
      'gopher': true,
      'file': true,
      'http:': true,
      'https:': true,
      'ftp:': true,
      'gopher:': true,
      'file:': true
    };

  function urlParse(url, parseQueryString, slashesDenoteHost) {
    if (url && isObject$1(url) && url instanceof Url) return url;

    var u = new Url;
    u.parse(url, parseQueryString, slashesDenoteHost);
    return u;
  }
  Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
    return parse$3(this, url, parseQueryString, slashesDenoteHost);
  };

  function parse$3(self, url, parseQueryString, slashesDenoteHost) {
    if (!isString$1(url)) {
      throw new TypeError('Parameter \'url\' must be a string, not ' + typeof url);
    }

    // Copy chrome, IE, opera backslash-handling behavior.
    // Back slashes before the query string get converted to forward slashes
    // See: https://code.google.com/p/chromium/issues/detail?id=25916
    var queryIndex = url.indexOf('?'),
      splitter =
      (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
      uSplit = url.split(splitter),
      slashRegex = /\\/g;
    uSplit[0] = uSplit[0].replace(slashRegex, '/');
    url = uSplit.join(splitter);

    var rest = url;

    // trim before proceeding.
    // This is to support parse stuff like "  http://foo.com  \n"
    rest = rest.trim();

    if (!slashesDenoteHost && url.split('#').length === 1) {
      // Try fast path regexp
      var simplePath = simplePathPattern.exec(rest);
      if (simplePath) {
        self.path = rest;
        self.href = rest;
        self.pathname = simplePath[1];
        if (simplePath[2]) {
          self.search = simplePath[2];
          if (parseQueryString) {
            self.query = parse$2(self.search.substr(1));
          } else {
            self.query = self.search.substr(1);
          }
        } else if (parseQueryString) {
          self.search = '';
          self.query = {};
        }
        return self;
      }
    }

    var proto = protocolPattern.exec(rest);
    if (proto) {
      proto = proto[0];
      var lowerProto = proto.toLowerCase();
      self.protocol = lowerProto;
      rest = rest.substr(proto.length);
    }

    // figure out if it's got a host
    // user@server is *always* interpreted as a hostname, and url
    // resolution will treat //foo/bar as host=foo,path=bar because that's
    // how the browser resolves relative URLs.
    if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
      var slashes = rest.substr(0, 2) === '//';
      if (slashes && !(proto && hostlessProtocol[proto])) {
        rest = rest.substr(2);
        self.slashes = true;
      }
    }
    var i, hec, l, p;
    if (!hostlessProtocol[proto] &&
      (slashes || (proto && !slashedProtocol[proto]))) {

      // there's a hostname.
      // the first instance of /, ?, ;, or # ends the host.
      //
      // If there is an @ in the hostname, then non-host chars *are* allowed
      // to the left of the last @ sign, unless some host-ending character
      // comes *before* the @-sign.
      // URLs are obnoxious.
      //
      // ex:
      // http://a@b@c/ => user:a@b host:c
      // http://a@b?@c => user:a host:c path:/?@c

      // v0.12 TODO(isaacs): This is not quite how Chrome does things.
      // Review our test case against browsers more comprehensively.

      // find the first instance of any hostEndingChars
      var hostEnd = -1;
      for (i = 0; i < hostEndingChars.length; i++) {
        hec = rest.indexOf(hostEndingChars[i]);
        if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
          hostEnd = hec;
      }

      // at this point, either we have an explicit point where the
      // auth portion cannot go past, or the last @ char is the decider.
      var auth, atSign;
      if (hostEnd === -1) {
        // atSign can be anywhere.
        atSign = rest.lastIndexOf('@');
      } else {
        // atSign must be in auth portion.
        // http://a@b/c@d => host:b auth:a path:/c@d
        atSign = rest.lastIndexOf('@', hostEnd);
      }

      // Now we have a portion which is definitely the auth.
      // Pull that off.
      if (atSign !== -1) {
        auth = rest.slice(0, atSign);
        rest = rest.slice(atSign + 1);
        self.auth = decodeURIComponent(auth);
      }

      // the host is the remaining to the left of the first non-host char
      hostEnd = -1;
      for (i = 0; i < nonHostChars.length; i++) {
        hec = rest.indexOf(nonHostChars[i]);
        if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
          hostEnd = hec;
      }
      // if we still have not hit it, then the entire thing is a host.
      if (hostEnd === -1)
        hostEnd = rest.length;

      self.host = rest.slice(0, hostEnd);
      rest = rest.slice(hostEnd);

      // pull out port.
      parseHost(self);

      // we've indicated that there is a hostname,
      // so even if it's empty, it has to be present.
      self.hostname = self.hostname || '';

      // if hostname begins with [ and ends with ]
      // assume that it's an IPv6 address.
      var ipv6Hostname = self.hostname[0] === '[' &&
        self.hostname[self.hostname.length - 1] === ']';

      // validate a little.
      if (!ipv6Hostname) {
        var hostparts = self.hostname.split(/\./);
        for (i = 0, l = hostparts.length; i < l; i++) {
          var part = hostparts[i];
          if (!part) continue;
          if (!part.match(hostnamePartPattern)) {
            var newpart = '';
            for (var j = 0, k = part.length; j < k; j++) {
              if (part.charCodeAt(j) > 127) {
                // we replace non-ASCII char with a temporary placeholder
                // we need this to make sure size of hostname is not
                // broken by replacing non-ASCII by nothing
                newpart += 'x';
              } else {
                newpart += part[j];
              }
            }
            // we test again with ASCII char only
            if (!newpart.match(hostnamePartPattern)) {
              var validParts = hostparts.slice(0, i);
              var notHost = hostparts.slice(i + 1);
              var bit = part.match(hostnamePartStart);
              if (bit) {
                validParts.push(bit[1]);
                notHost.unshift(bit[2]);
              }
              if (notHost.length) {
                rest = '/' + notHost.join('.') + rest;
              }
              self.hostname = validParts.join('.');
              break;
            }
          }
        }
      }

      if (self.hostname.length > hostnameMaxLen) {
        self.hostname = '';
      } else {
        // hostnames are always lower case.
        self.hostname = self.hostname.toLowerCase();
      }

      if (!ipv6Hostname) {
        // IDNA Support: Returns a punycoded representation of "domain".
        // It only converts parts of the domain name that
        // have non-ASCII characters, i.e. it doesn't matter if
        // you call it with a domain that already is ASCII-only.
        self.hostname = toASCII(self.hostname);
      }

      p = self.port ? ':' + self.port : '';
      var h = self.hostname || '';
      self.host = h + p;
      self.href += self.host;

      // strip [ and ] from the hostname
      // the host field still retains them, though
      if (ipv6Hostname) {
        self.hostname = self.hostname.substr(1, self.hostname.length - 2);
        if (rest[0] !== '/') {
          rest = '/' + rest;
        }
      }
    }

    // now rest is set to the post-host stuff.
    // chop off any delim chars.
    if (!unsafeProtocol[lowerProto]) {

      // First, make 100% sure that any "autoEscape" chars get
      // escaped, even if encodeURIComponent doesn't think they
      // need to be.
      for (i = 0, l = autoEscape.length; i < l; i++) {
        var ae = autoEscape[i];
        if (rest.indexOf(ae) === -1)
          continue;
        var esc = encodeURIComponent(ae);
        if (esc === ae) {
          esc = escape(ae);
        }
        rest = rest.split(ae).join(esc);
      }
    }


    // chop off from the tail first.
    var hash = rest.indexOf('#');
    if (hash !== -1) {
      // got a fragment string.
      self.hash = rest.substr(hash);
      rest = rest.slice(0, hash);
    }
    var qm = rest.indexOf('?');
    if (qm !== -1) {
      self.search = rest.substr(qm);
      self.query = rest.substr(qm + 1);
      if (parseQueryString) {
        self.query = parse$2(self.query);
      }
      rest = rest.slice(0, qm);
    } else if (parseQueryString) {
      // no query string, but parseQueryString still requested
      self.search = '';
      self.query = {};
    }
    if (rest) self.pathname = rest;
    if (slashedProtocol[lowerProto] &&
      self.hostname && !self.pathname) {
      self.pathname = '/';
    }

    //to support http.request
    if (self.pathname || self.search) {
      p = self.pathname || '';
      var s = self.search || '';
      self.path = p + s;
    }

    // finally, reconstruct the href based on what has been validated.
    self.href = format$1(self);
    return self;
  }

  function format$1(self) {
    var auth = self.auth || '';
    if (auth) {
      auth = encodeURIComponent(auth);
      auth = auth.replace(/%3A/i, ':');
      auth += '@';
    }

    var protocol = self.protocol || '',
      pathname = self.pathname || '',
      hash = self.hash || '',
      host = false,
      query = '';

    if (self.host) {
      host = auth + self.host;
    } else if (self.hostname) {
      host = auth + (self.hostname.indexOf(':') === -1 ?
        self.hostname :
        '[' + this.hostname + ']');
      if (self.port) {
        host += ':' + self.port;
      }
    }

    if (self.query &&
      isObject$1(self.query) &&
      Object.keys(self.query).length) {
      query = stringify(self.query);
    }

    var search = self.search || (query && ('?' + query)) || '';

    if (protocol && protocol.substr(-1) !== ':') protocol += ':';

    // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
    // unless they had them to begin with.
    if (self.slashes ||
      (!protocol || slashedProtocol[protocol]) && host !== false) {
      host = '//' + (host || '');
      if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
    } else if (!host) {
      host = '';
    }

    if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
    if (search && search.charAt(0) !== '?') search = '?' + search;

    pathname = pathname.replace(/[?#]/g, function(match) {
      return encodeURIComponent(match);
    });
    search = search.replace('#', '%23');

    return protocol + host + pathname + search + hash;
  }

  Url.prototype.format = function() {
    return format$1(this);
  };

  Url.prototype.resolve = function(relative) {
    return this.resolveObject(urlParse(relative, false, true)).format();
  };

  Url.prototype.resolveObject = function(relative) {
    if (isString$1(relative)) {
      var rel = new Url();
      rel.parse(relative, false, true);
      relative = rel;
    }

    var result = new Url();
    var tkeys = Object.keys(this);
    for (var tk = 0; tk < tkeys.length; tk++) {
      var tkey = tkeys[tk];
      result[tkey] = this[tkey];
    }

    // hash is always overridden, no matter what.
    // even href="" will remove it.
    result.hash = relative.hash;

    // if the relative url is empty, then there's nothing left to do here.
    if (relative.href === '') {
      result.href = result.format();
      return result;
    }

    // hrefs like //foo/bar always cut to the protocol.
    if (relative.slashes && !relative.protocol) {
      // take everything except the protocol from relative
      var rkeys = Object.keys(relative);
      for (var rk = 0; rk < rkeys.length; rk++) {
        var rkey = rkeys[rk];
        if (rkey !== 'protocol')
          result[rkey] = relative[rkey];
      }

      //urlParse appends trailing / to urls like http://www.example.com
      if (slashedProtocol[result.protocol] &&
        result.hostname && !result.pathname) {
        result.path = result.pathname = '/';
      }

      result.href = result.format();
      return result;
    }
    var relPath;
    if (relative.protocol && relative.protocol !== result.protocol) {
      // if it's a known url protocol, then changing
      // the protocol does weird things
      // first, if it's not file:, then we MUST have a host,
      // and if there was a path
      // to begin with, then we MUST have a path.
      // if it is file:, then the host is dropped,
      // because that's known to be hostless.
      // anything else is assumed to be absolute.
      if (!slashedProtocol[relative.protocol]) {
        var keys = Object.keys(relative);
        for (var v = 0; v < keys.length; v++) {
          var k = keys[v];
          result[k] = relative[k];
        }
        result.href = result.format();
        return result;
      }

      result.protocol = relative.protocol;
      if (!relative.host && !hostlessProtocol[relative.protocol]) {
        relPath = (relative.pathname || '').split('/');
        while (relPath.length && !(relative.host = relPath.shift()));
        if (!relative.host) relative.host = '';
        if (!relative.hostname) relative.hostname = '';
        if (relPath[0] !== '') relPath.unshift('');
        if (relPath.length < 2) relPath.unshift('');
        result.pathname = relPath.join('/');
      } else {
        result.pathname = relative.pathname;
      }
      result.search = relative.search;
      result.query = relative.query;
      result.host = relative.host || '';
      result.auth = relative.auth;
      result.hostname = relative.hostname || relative.host;
      result.port = relative.port;
      // to support http.request
      if (result.pathname || result.search) {
        var p = result.pathname || '';
        var s = result.search || '';
        result.path = p + s;
      }
      result.slashes = result.slashes || relative.slashes;
      result.href = result.format();
      return result;
    }

    var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
      isRelAbs = (
        relative.host ||
        relative.pathname && relative.pathname.charAt(0) === '/'
      ),
      mustEndAbs = (isRelAbs || isSourceAbs ||
        (result.host && relative.pathname)),
      removeAllDots = mustEndAbs,
      srcPath = result.pathname && result.pathname.split('/') || [],
      psychotic = result.protocol && !slashedProtocol[result.protocol];
    relPath = relative.pathname && relative.pathname.split('/') || [];
    // if the url is a non-slashed url, then relative
    // links like ../.. should be able
    // to crawl up to the hostname, as well.  This is strange.
    // result.protocol has already been set by now.
    // Later on, put the first path part into the host field.
    if (psychotic) {
      result.hostname = '';
      result.port = null;
      if (result.host) {
        if (srcPath[0] === '') srcPath[0] = result.host;
        else srcPath.unshift(result.host);
      }
      result.host = '';
      if (relative.protocol) {
        relative.hostname = null;
        relative.port = null;
        if (relative.host) {
          if (relPath[0] === '') relPath[0] = relative.host;
          else relPath.unshift(relative.host);
        }
        relative.host = null;
      }
      mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
    }
    var authInHost;
    if (isRelAbs) {
      // it's absolute.
      result.host = (relative.host || relative.host === '') ?
        relative.host : result.host;
      result.hostname = (relative.hostname || relative.hostname === '') ?
        relative.hostname : result.hostname;
      result.search = relative.search;
      result.query = relative.query;
      srcPath = relPath;
      // fall through to the dot-handling below.
    } else if (relPath.length) {
      // it's relative
      // throw away the existing file, and take the new path instead.
      if (!srcPath) srcPath = [];
      srcPath.pop();
      srcPath = srcPath.concat(relPath);
      result.search = relative.search;
      result.query = relative.query;
    } else if (!isNullOrUndefined(relative.search)) {
      // just pull out the search.
      // like href='?foo'.
      // Put this after the other two cases because it simplifies the booleans
      if (psychotic) {
        result.hostname = result.host = srcPath.shift();
        //occationaly the auth can get stuck only in host
        //this especially happens in cases like
        //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
        authInHost = result.host && result.host.indexOf('@') > 0 ?
          result.host.split('@') : false;
        if (authInHost) {
          result.auth = authInHost.shift();
          result.host = result.hostname = authInHost.shift();
        }
      }
      result.search = relative.search;
      result.query = relative.query;
      //to support http.request
      if (!isNull(result.pathname) || !isNull(result.search)) {
        result.path = (result.pathname ? result.pathname : '') +
          (result.search ? result.search : '');
      }
      result.href = result.format();
      return result;
    }

    if (!srcPath.length) {
      // no path at all.  easy.
      // we've already handled the other stuff above.
      result.pathname = null;
      //to support http.request
      if (result.search) {
        result.path = '/' + result.search;
      } else {
        result.path = null;
      }
      result.href = result.format();
      return result;
    }

    // if a url ENDs in . or .., then it must get a trailing slash.
    // however, if it ends in anything else non-slashy,
    // then it must NOT get a trailing slash.
    var last = srcPath.slice(-1)[0];
    var hasTrailingSlash = (
      (result.host || relative.host || srcPath.length > 1) &&
      (last === '.' || last === '..') || last === '');

    // strip single dots, resolve double dots to parent dir
    // if the path tries to go above the root, `up` ends up > 0
    var up = 0;
    for (var i = srcPath.length; i >= 0; i--) {
      last = srcPath[i];
      if (last === '.') {
        srcPath.splice(i, 1);
      } else if (last === '..') {
        srcPath.splice(i, 1);
        up++;
      } else if (up) {
        srcPath.splice(i, 1);
        up--;
      }
    }

    // if the path is allowed to go above the root, restore leading ..s
    if (!mustEndAbs && !removeAllDots) {
      for (; up--; up) {
        srcPath.unshift('..');
      }
    }

    if (mustEndAbs && srcPath[0] !== '' &&
      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
      srcPath.unshift('');
    }

    if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
      srcPath.push('');
    }

    var isAbsolute = srcPath[0] === '' ||
      (srcPath[0] && srcPath[0].charAt(0) === '/');

    // put the host back
    if (psychotic) {
      result.hostname = result.host = isAbsolute ? '' :
        srcPath.length ? srcPath.shift() : '';
      //occationaly the auth can get stuck only in host
      //this especially happens in cases like
      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
      authInHost = result.host && result.host.indexOf('@') > 0 ?
        result.host.split('@') : false;
      if (authInHost) {
        result.auth = authInHost.shift();
        result.host = result.hostname = authInHost.shift();
      }
    }

    mustEndAbs = mustEndAbs || (result.host && srcPath.length);

    if (mustEndAbs && !isAbsolute) {
      srcPath.unshift('');
    }

    if (!srcPath.length) {
      result.pathname = null;
      result.path = null;
    } else {
      result.pathname = srcPath.join('/');
    }

    //to support request.http
    if (!isNull(result.pathname) || !isNull(result.search)) {
      result.path = (result.pathname ? result.pathname : '') +
        (result.search ? result.search : '');
    }
    result.auth = relative.auth || result.auth;
    result.slashes = result.slashes || relative.slashes;
    result.href = result.format();
    return result;
  };

  Url.prototype.parseHost = function() {
    return parseHost(this);
  };

  function parseHost(self) {
    var host = self.host;
    var port = portPattern.exec(host);
    if (port) {
      port = port[0];
      if (port !== ':') {
        self.port = port.substr(1);
      }
      host = host.substr(0, host.length - port.length);
    }
    if (host) self.hostname = host;
  }

  function isRelativeUrl(url) {
      const firstChar = url.charAt(0);
      return firstChar === '.' || firstChar === '~' || firstChar === '@';
  }
  const externalRE = /^https?:\/\//;
  function isExternalUrl(url) {
      return externalRE.test(url);
  }
  const dataUrlRE = /^\s*data:/i;
  function isDataUrl(url) {
      return dataUrlRE.test(url);
  }
  /**
   * Parses string url into URL object.
   */
  function parseUrl(url) {
      const firstChar = url.charAt(0);
      if (firstChar === '~') {
          const secondChar = url.charAt(1);
          url = url.slice(secondChar === '/' ? 2 : 1);
      }
      return parseUriParts(url);
  }
  /**
   * vuejs/component-compiler-utils#22 Support uri fragment in transformed require
   * @param urlString an url as a string
   */
  function parseUriParts(urlString) {
      // A TypeError is thrown if urlString is not a string
      // @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost
      return urlParse(isString(urlString) ? urlString : '');
  }

  const defaultAssetUrlOptions = {
      base: null,
      includeAbsolute: false,
      tags: {
          video: ['src', 'poster'],
          source: ['src'],
          img: ['src'],
          image: ['xlink:href', 'href'],
          use: ['xlink:href', 'href']
      }
  };
  const normalizeOptions = (options) => {
      if (Object.keys(options).some(key => isArray(options[key]))) {
          // legacy option format which directly passes in tags config
          return {
              ...defaultAssetUrlOptions,
              tags: options
          };
      }
      return {
          ...defaultAssetUrlOptions,
          ...options
      };
  };
  const createAssetUrlTransformWithOptions = (options) => {
      return (node, context) => transformAssetUrl(node, context, options);
  };
  /**
   * A `@vue/compiler-core` plugin that transforms relative asset urls into
   * either imports or absolute urls.
   *
   * ``` js
   * // Before
   * createVNode('img', { src: './logo.png' })
   *
   * // After
   * import _imports_0 from './logo.png'
   * createVNode('img', { src: _imports_0 })
   * ```
   */
  const transformAssetUrl = (node, context, options = defaultAssetUrlOptions) => {
      if (node.type === 1 /* ELEMENT */) {
          if (!node.props.length) {
              return;
          }
          const tags = options.tags || defaultAssetUrlOptions.tags;
          const attrs = tags[node.tag];
          const wildCardAttrs = tags['*'];
          if (!attrs && !wildCardAttrs) {
              return;
          }
          const assetAttrs = (attrs || []).concat(wildCardAttrs || []);
          node.props.forEach((attr, index) => {
              if (attr.type !== 6 /* ATTRIBUTE */ ||
                  !assetAttrs.includes(attr.name) ||
                  !attr.value ||
                  isExternalUrl(attr.value.content) ||
                  isDataUrl(attr.value.content) ||
                  attr.value.content[0] === '#' ||
                  (!options.includeAbsolute && !isRelativeUrl(attr.value.content))) {
                  return;
              }
              const url = parseUrl(attr.value.content);
              if (options.base) {
                  // explicit base - directly rewrite the url into absolute url
                  // does not apply to absolute urls or urls that start with `@`
                  // since they are aliases
                  if (attr.value.content[0] !== '@' &&
                      isRelativeUrl(attr.value.content)) {
                      // when packaged in the browser, path will be using the posix-
                      // only version provided by rollup-plugin-node-builtins.
                      attr.value.content = (path.posix || path).join(options.base, url.path + (url.hash || ''));
                  }
                  return;
              }
              // otherwise, transform the url into an import.
              // this assumes a bundler will resolve the import into the correct
              // absolute url (e.g. webpack file-loader)
              const exp = getImportsExpressionExp(url.path, url.hash, attr.loc, context);
              node.props[index] = {
                  type: 7 /* DIRECTIVE */,
                  name: 'bind',
                  arg: createSimpleExpression(attr.name, true, attr.loc),
                  exp,
                  modifiers: [],
                  loc: attr.loc
              };
          });
      }
  };
  function getImportsExpressionExp(path, hash, loc, context) {
      if (path) {
          const importsArray = Array.from(context.imports);
          const existing = importsArray.find(i => i.path === path);
          if (existing) {
              return existing.exp;
          }
          const name = `_imports_${importsArray.length}`;
          const exp = createSimpleExpression(name, false, loc, true);
          exp.isRuntimeConstant = true;
          context.imports.add({ exp, path });
          if (hash && path) {
              const ret = context.hoist(createSimpleExpression(`${name} + '${hash}'`, false, loc, true));
              ret.isRuntimeConstant = true;
              return ret;
          }
          else {
              return exp;
          }
      }
      else {
          return createSimpleExpression(`''`, false, loc, true);
      }
  }

  const srcsetTags = ['img', 'source'];
  // http://w3c.github.io/html/semantics-embedded-content.html#ref-for-image-candidate-string-5
  const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g;
  const createSrcsetTransformWithOptions = (options) => {
      return (node, context) => transformSrcset(node, context, options);
  };
  const transformSrcset = (node, context, options = defaultAssetUrlOptions) => {
      if (node.type === 1 /* ELEMENT */) {
          if (srcsetTags.includes(node.tag) && node.props.length) {
              node.props.forEach((attr, index) => {
                  if (attr.name === 'srcset' && attr.type === 6 /* ATTRIBUTE */) {
                      if (!attr.value)
                          return;
                      const value = attr.value.content;
                      const imageCandidates = value.split(',').map(s => {
                          // The attribute value arrives here with all whitespace, except
                          // normal spaces, represented by escape sequences
                          const [url, descriptor] = s
                              .replace(escapedSpaceCharacters, ' ')
                              .trim()
                              .split(' ', 2);
                          return { url, descriptor };
                      });
                      // for data url need recheck url
                      for (let i = 0; i < imageCandidates.length; i++) {
                          if (imageCandidates[i].url.trim().startsWith('data:')) {
                              imageCandidates[i + 1].url =
                                  imageCandidates[i].url + ',' + imageCandidates[i + 1].url;
                              imageCandidates.splice(i, 1);
                          }
                      }
                      // When srcset does not contain any relative URLs, skip transforming
                      if (!options.includeAbsolute &&
                          !imageCandidates.some(({ url }) => isRelativeUrl(url))) {
                          return;
                      }
                      if (options.base) {
                          const base = options.base;
                          const set = [];
                          imageCandidates.forEach(({ url, descriptor }) => {
                              descriptor = descriptor ? ` ${descriptor}` : ``;
                              if (isRelativeUrl(url)) {
                                  set.push((path.posix || path).join(base, url) + descriptor);
                              }
                              else {
                                  set.push(url + descriptor);
                              }
                          });
                          attr.value.content = set.join(', ');
                          return;
                      }
                      const compoundExpression = createCompoundExpression([], attr.loc);
                      imageCandidates.forEach(({ url, descriptor }, index) => {
                          if (!isExternalUrl(url) &&
                              !isDataUrl(url) &&
                              (options.includeAbsolute || isRelativeUrl(url))) {
                              const { path } = parseUrl(url);
                              let exp;
                              if (path) {
                                  const importsArray = Array.from(context.imports);
                                  const existingImportsIndex = importsArray.findIndex(i => i.path === path);
                                  if (existingImportsIndex > -1) {
                                      exp = createSimpleExpression(`_imports_${existingImportsIndex}`, false, attr.loc, true);
                                  }
                                  else {
                                      exp = createSimpleExpression(`_imports_${importsArray.length}`, false, attr.loc, true);
                                      context.imports.add({ exp, path });
                                  }
                                  compoundExpression.children.push(exp);
                              }
                          }
                          else {
                              const exp = createSimpleExpression(`"${url}"`, false, attr.loc, true);
                              compoundExpression.children.push(exp);
                          }
                          const isNotLast = imageCandidates.length - 1 > index;
                          if (descriptor && isNotLast) {
                              compoundExpression.children.push(` + '${descriptor}, ' + `);
                          }
                          else if (descriptor) {
                              compoundExpression.children.push(` + '${descriptor}'`);
                          }
                          else if (isNotLast) {
                              compoundExpression.children.push(` + ', ' + `);
                          }
                      });
                      const hoisted = context.hoist(compoundExpression);
                      hoisted.isRuntimeConstant = true;
                      node.props[index] = {
                          type: 7 /* DIRECTIVE */,
                          name: 'bind',
                          arg: createSimpleExpression('srcset', true, attr.loc),
                          exp: hoisted,
                          modifiers: [],
                          loc: attr.loc
                      };
                  }
              });
          }
      }
  };

  const SSR_INTERPOLATE = Symbol(`ssrInterpolate`);
  const SSR_RENDER_VNODE = Symbol(`ssrRenderVNode`);
  const SSR_RENDER_COMPONENT = Symbol(`ssrRenderComponent`);
  const SSR_RENDER_SLOT = Symbol(`ssrRenderSlot`);
  const SSR_RENDER_CLASS = Symbol(`ssrRenderClass`);
  const SSR_RENDER_STYLE = Symbol(`ssrRenderStyle`);
  const SSR_RENDER_ATTRS = Symbol(`ssrRenderAttrs`);
  const SSR_RENDER_ATTR = Symbol(`ssrRenderAttr`);
  const SSR_RENDER_DYNAMIC_ATTR = Symbol(`ssrRenderDynamicAttr`);
  const SSR_RENDER_LIST = Symbol(`ssrRenderList`);
  const SSR_LOOSE_EQUAL = Symbol(`ssrLooseEqual`);
  const SSR_LOOSE_CONTAIN = Symbol(`ssrLooseContain`);
  const SSR_RENDER_DYNAMIC_MODEL = Symbol(`ssrRenderDynamicModel`);
  const SSR_GET_DYNAMIC_MODEL_PROPS = Symbol(`ssrGetDynamicModelProps`);
  const SSR_RENDER_TELEPORT = Symbol(`ssrRenderTeleport`);
  const SSR_RENDER_SUSPENSE = Symbol(`ssrRenderSuspense`);
  const SSR_RESOLVE_CSS_VARS = Symbol(`ssrResolveCssVars`);
  const ssrHelpers = {
      [SSR_INTERPOLATE]: `ssrInterpolate`,
      [SSR_RENDER_VNODE]: `ssrRenderVNode`,
      [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
      [SSR_RENDER_SLOT]: `ssrRenderSlot`,
      [SSR_RENDER_CLASS]: `ssrRenderClass`,
      [SSR_RENDER_STYLE]: `ssrRenderStyle`,
      [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
      [SSR_RENDER_ATTR]: `ssrRenderAttr`,
      [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
      [SSR_RENDER_LIST]: `ssrRenderList`,
      [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
      [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
      [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
      [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
      [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
      [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
      [SSR_RESOLVE_CSS_VARS]: `ssrResolveCssVars`
  };
  // Note: these are helpers imported from @vue/server-renderer
  // make sure the names match!
  registerRuntimeHelpers(ssrHelpers);

  // Plugin for the first transform pass, which simply constructs the AST node
  const ssrTransformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, processIf);
  // This is called during the 2nd transform pass to construct the SSR-specific
  // codegen nodes.
  function ssrProcessIf(node, context) {
      const [rootBranch] = node.branches;
      const ifStatement = createIfStatement(rootBranch.condition, processIfBranch(rootBranch, context));
      context.pushStatement(ifStatement);
      let currentIf = ifStatement;
      for (let i = 1; i < node.branches.length; i++) {
          const branch = node.branches[i];
          const branchBlockStatement = processIfBranch(branch, context);
          if (branch.condition) {
              // else-if
              currentIf = currentIf.alternate = createIfStatement(branch.condition, branchBlockStatement);
          }
          else {
              // else
              currentIf.alternate = branchBlockStatement;
          }
      }
      if (!currentIf.alternate) {
          currentIf.alternate = createBlockStatement([
              createCallExpression(`_push`, ['`<!---->`'])
          ]);
      }
  }
  function processIfBranch(branch, context) {
      const { children } = branch;
      const needFragmentWrapper = (children.length !== 1 || children[0].type !== 1 /* ELEMENT */) &&
          // optimize away nested fragments when the only child is a ForNode
          !(children.length === 1 && children[0].type === 11 /* FOR */);
      return processChildrenAsStatement(children, context, needFragmentWrapper);
  }

  // Plugin for the first transform pass, which simply constructs the AST node
  const ssrTransformFor = createStructuralDirectiveTransform('for', processFor);
  // This is called during the 2nd transform pass to construct the SSR-specific
  // codegen nodes.
  function ssrProcessFor(node, context) {
      const needFragmentWrapper = node.children.length !== 1 || node.children[0].type !== 1 /* ELEMENT */;
      const renderLoop = createFunctionExpression(createForLoopParams(node.parseResult));
      renderLoop.body = processChildrenAsStatement(node.children, context, needFragmentWrapper);
      // v-for always renders a fragment
      context.pushStringPart(`<!--[-->`);
      context.pushStatement(createCallExpression(context.helper(SSR_RENDER_LIST), [
          node.source,
          renderLoop
      ]));
      context.pushStringPart(`<!--]-->`);
  }

  const ssrTransformSlotOutlet = (node, context) => {
      if (isSlotOutlet(node)) {
          const { slotName, slotProps } = processSlotOutlet(node, context);
          node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_SLOT), [
              `_ctx.$slots`,
              slotName,
              slotProps || `{}`,
              `null`,
              `_push`,
              `_parent`
          ]);
      }
  };
  function ssrProcessSlotOutlet(node, context) {
      const renderCall = node.ssrCodegenNode;
      // has fallback content
      if (node.children.length) {
          const fallbackRenderFn = createFunctionExpression([]);
          fallbackRenderFn.body = processChildrenAsStatement(node.children, context);
          // _renderSlot(slots, name, props, fallback, ...)
          renderCall.arguments[3] = fallbackRenderFn;
      }
      context.pushStatement(node.ssrCodegenNode);
  }

  function createSSRCompilerError(code, loc) {
      return createCompilerError(code, loc, SSRErrorMessages);
  }
  const SSRErrorMessages = {
      [60 /* X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM */]: `Custom directive is missing corresponding SSR transform and will be ignored.`,
      [61 /* X_SSR_UNSAFE_ATTR_NAME */]: `Unsafe attribute name for SSR.`,
      [62 /* X_SSR_NO_TELEPORT_TARGET */]: `Missing the 'to' prop on teleport element.`,
      [63 /* X_SSR_INVALID_AST_NODE */]: `Invalid AST node during SSR transform.`
  };

  // Note: this is a 2nd-pass codegen transform.
  function ssrProcessTeleport(node, context) {
      const targetProp = findProp(node, 'to');
      if (!targetProp) {
          context.onError(createSSRCompilerError(62 /* X_SSR_NO_TELEPORT_TARGET */, node.loc));
          return;
      }
      let target;
      if (targetProp.type === 6 /* ATTRIBUTE */) {
          target =
              targetProp.value && createSimpleExpression(targetProp.value.content, true);
      }
      else {
          target = targetProp.exp;
      }
      if (!target) {
          context.onError(createSSRCompilerError(62 /* X_SSR_NO_TELEPORT_TARGET */, targetProp.loc));
          return;
      }
      const disabledProp = findProp(node, 'disabled', false, true /* allow empty */);
      const disabled = disabledProp
          ? disabledProp.type === 6 /* ATTRIBUTE */
              ? `true`
              : disabledProp.exp || `false`
          : `false`;
      const contentRenderFn = createFunctionExpression([`_push`], undefined, // Body is added later
      true, // newline
      false, // isSlot
      node.loc);
      contentRenderFn.body = processChildrenAsStatement(node.children, context);
      context.pushStatement(createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
          `_push`,
          contentRenderFn,
          target,
          disabled,
          `_parent`
      ]));
  }

  const wipMap = new WeakMap();
  // phase 1
  function ssrTransformSuspense(node, context) {
      return () => {
          if (node.children.length) {
              const wipEntry = {
                  slotsExp: null,
                  wipSlots: []
              };
              wipMap.set(node, wipEntry);
              wipEntry.slotsExp = buildSlots(node, context, (_props, children, loc) => {
                  const fn = createFunctionExpression([], undefined, // no return, assign body later
                  true, // newline
                  false, // suspense slots are not treated as normal slots
                  loc);
                  wipEntry.wipSlots.push({
                      fn,
                      children
                  });
                  return fn;
              }).slots;
          }
      };
  }
  // phase 2
  function ssrProcessSuspense(node, context) {
      // complete wip slots with ssr code
      const wipEntry = wipMap.get(node);
      if (!wipEntry) {
          return;
      }
      const { slotsExp, wipSlots } = wipEntry;
      for (let i = 0; i < wipSlots.length; i++) {
          const { fn, children } = wipSlots[i];
          fn.body = processChildrenAsStatement(children, context);
      }
      // _push(ssrRenderSuspense(slots))
      context.pushStatement(createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
          `_push`,
          slotsExp
      ]));
  }

  // We need to construct the slot functions in the 1st pass to ensure proper
  // scope tracking, but the children of each slot cannot be processed until
  // the 2nd pass, so we store the WIP slot functions in a weakmap during the 1st
  // pass and complete them in the 2nd pass.
  const wipMap$1 = new WeakMap();
  const componentTypeMap = new WeakMap();
  // ssr component transform is done in two phases:
  // In phase 1. we use `buildSlot` to analyze the children of the component into
  // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
  // the core transform context).
  // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
  // nodes.
  const ssrTransformComponent = (node, context) => {
      if (node.type !== 1 /* ELEMENT */ ||
          node.tagType !== 1 /* COMPONENT */) {
          return;
      }
      const component = resolveComponentType(node, context, true /* ssr */);
      componentTypeMap.set(node, component);
      if (isSymbol(component)) {
          if (component === SUSPENSE) {
              return ssrTransformSuspense(node, context);
          }
          return; // built-in component: fallthrough
      }
      // Build the fallback vnode-based branch for the component's slots.
      // We need to clone the node into a fresh copy and use the buildSlots' logic
      // to get access to the children of each slot. We then compile them with
      // a child transform pipeline using vnode-based transforms (instead of ssr-
      // based ones), and save the result branch (a ReturnStatement) in an array.
      // The branch is retrieved when processing slots again in ssr mode.
      const vnodeBranches = [];
      const clonedNode = clone(node);
      return function ssrPostTransformComponent() {
          // Using the cloned node, build the normal VNode-based branches (for
          // fallback in case the child is render-fn based). Store them in an array
          // for later use.
          if (clonedNode.children.length) {
              buildSlots(clonedNode, context, (props, children) => {
                  vnodeBranches.push(createVNodeSlotBranch(props, children, context));
                  return createFunctionExpression(undefined);
              });
          }
          const props = node.props.length > 0
              ? // note we are not passing ssr: true here because for components, v-on
                  // handlers should still be passed
                  buildProps(node, context).props || `null`
              : `null`;
          const wipEntries = [];
          wipMap$1.set(node, wipEntries);
          const buildSSRSlotFn = (props, children, loc) => {
              const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
              true, // newline
              true, // isSlot
              loc);
              wipEntries.push({
                  fn,
                  children,
                  // also collect the corresponding vnode branch built earlier
                  vnodeBranch: vnodeBranches[wipEntries.length]
              });
              return fn;
          };
          const slots = node.children.length
              ? buildSlots(node, context, buildSSRSlotFn).slots
              : `null`;
          if (typeof component !== 'string') {
              // dynamic component that resolved to a `resolveDynamicComponent` call
              // expression - since the resolved result may be a plain element (string)
              // or a VNode, handle it with `renderVNode`.
              node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_VNODE), [
                  `_push`,
                  createCallExpression(context.helper(CREATE_VNODE), [
                      component,
                      props,
                      slots
                  ]),
                  `_parent`
              ]);
          }
          else {
              node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, props, slots, `_parent`]);
          }
      };
  };
  function ssrProcessComponent(node, context) {
      const component = componentTypeMap.get(node);
      if (!node.ssrCodegenNode) {
          // this is a built-in component that fell-through.
          if (component === TELEPORT) {
              return ssrProcessTeleport(node, context);
          }
          else if (component === SUSPENSE) {
              return ssrProcessSuspense(node, context);
          }
          else {
              // real fall-through (e.g. KeepAlive): just render its children.
              processChildren(node.children, context, component === TRANSITION_GROUP);
          }
      }
      else {
          // finish up slot function expressions from the 1st pass.
          const wipEntries = wipMap$1.get(node) || [];
          for (let i = 0; i < wipEntries.length; i++) {
              const { fn, children, vnodeBranch } = wipEntries[i];
              // For each slot, we generate two branches: one SSR-optimized branch and
              // one normal vnode-based branch. The branches are taken based on the
              // presence of the 2nd `_push` argument (which is only present if the slot
              // is called by `_ssrRenderSlot`.
              fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
          }
          if (typeof component === 'string') {
              // static component
              context.pushStatement(createCallExpression(`_push`, [node.ssrCodegenNode]));
          }
          else {
              // dynamic component (`resolveDynamicComponent` call)
              // the codegen node is a `renderVNode` call
              context.pushStatement(node.ssrCodegenNode);
          }
      }
  }
  const rawOptionsMap = new WeakMap();
  const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(true);
  const vnodeNodeTransforms = [...baseNodeTransforms, ...DOMNodeTransforms];
  const vnodeDirectiveTransforms = {
      ...baseDirectiveTransforms,
      ...DOMDirectiveTransforms
  };
  function createVNodeSlotBranch(props, children, parentContext) {
      // apply a sub-transform using vnode-based transforms.
      const rawOptions = rawOptionsMap.get(parentContext.root);
      const subOptions = {
          ...rawOptions,
          // overwrite with vnode-based transforms
          nodeTransforms: [
              ...vnodeNodeTransforms,
              ...(rawOptions.nodeTransforms || [])
          ],
          directiveTransforms: {
              ...vnodeDirectiveTransforms,
              ...(rawOptions.directiveTransforms || {})
          }
      };
      // wrap the children with a wrapper template for proper children treatment.
      const wrapperNode = {
          type: 1 /* ELEMENT */,
          ns: 0 /* HTML */,
          tag: 'template',
          tagType: 3 /* TEMPLATE */,
          isSelfClosing: false,
          // important: provide v-slot="props" on the wrapper for proper
          // scope analysis
          props: [
              {
                  type: 7 /* DIRECTIVE */,
                  name: 'slot',
                  exp: props,
                  arg: undefined,
                  modifiers: [],
                  loc: locStub
              }
          ],
          children,
          loc: locStub,
          codegenNode: undefined
      };
      subTransform(wrapperNode, subOptions, parentContext);
      return createReturnStatement(children);
  }
  function subTransform(node, options, parentContext) {
      const childRoot = createRoot([node]);
      const childContext = createTransformContext(childRoot, options);
      // this sub transform is for vnode fallback branch so it should be handled
      // like normal render functions
      childContext.ssr = false;
      // inherit parent scope analysis state
      childContext.scopes = { ...parentContext.scopes };
      childContext.identifiers = { ...parentContext.identifiers };
      // traverse
      traverseNode(childRoot, childContext);
      ['helpers', 'components', 'directives', 'imports'].forEach(key => {
          childContext[key].forEach((value) => {
              parentContext[key].add(value);
          });
      });
  }
  function clone(v) {
      if (isArray(v)) {
          return v.map(clone);
      }
      else if (isObject(v)) {
          const res = {};
          for (const key in v) {
              res[key] = clone(v[key]);
          }
          return res;
      }
      else {
          return v;
      }
  }

  // for directives with children overwrite (e.g. v-html & v-text), we need to
  // store the raw children so that they can be added in the 2nd pass.
  const rawChildrenMap = new WeakMap();
  const ssrTransformElement = (node, context) => {
      if (node.type !== 1 /* ELEMENT */ ||
          node.tagType !== 0 /* ELEMENT */) {
          return;
      }
      return function ssrPostTransformElement() {
          // element
          // generate the template literal representing the open tag.
          const openTag = [`<${node.tag}`];
          // some tags need to be passed to runtime for special checks
          const needTagForRuntime = node.tag === 'textarea' || node.tag.indexOf('-') > 0;
          // v-bind="obj" or v-bind:[key] can potentially overwrite other static
          // attrs and can affect final rendering result, so when they are present
          // we need to bail out to full `renderAttrs`
          const hasDynamicVBind = hasDynamicKeyVBind(node);
          if (hasDynamicVBind) {
              const { props } = buildProps(node, context, node.props, true /* ssr */);
              if (props) {
                  const propsExp = createCallExpression(context.helper(SSR_RENDER_ATTRS), [props]);
                  if (node.tag === 'textarea') {
                      const existingText = node.children[0];
                      // If interpolation, this is dynamic <textarea> content, potentially
                      // injected by v-model and takes higher priority than v-bind value
                      if (!existingText || existingText.type !== 5 /* INTERPOLATION */) {
                          // <textarea> with dynamic v-bind. We don't know if the final props
                          // will contain .value, so we will have to do something special:
                          // assign the merged props to a temp variable, and check whether
                          // it contains value (if yes, render is as children).
                          const tempId = `_temp${context.temps++}`;
                          propsExp.arguments = [
                              createAssignmentExpression(createSimpleExpression(tempId, false), props)
                          ];
                          rawChildrenMap.set(node, createCallExpression(context.helper(SSR_INTERPOLATE), [
                              createConditionalExpression(createSimpleExpression(`"value" in ${tempId}`, false), createSimpleExpression(`${tempId}.value`, false), createSimpleExpression(existingText ? existingText.content : ``, true), false)
                          ]));
                      }
                  }
                  else if (node.tag === 'input') {
                      // <input v-bind="obj" v-model>
                      // we need to determine the props to render for the dynamic v-model
                      // and merge it with the v-bind expression.
                      const vModel = findVModel(node);
                      if (vModel) {
                          // 1. save the props (san v-model) in a temp variable
                          const tempId = `_temp${context.temps++}`;
                          const tempExp = createSimpleExpression(tempId, false);
                          propsExp.arguments = [
                              createSequenceExpression([
                                  createAssignmentExpression(tempExp, props),
                                  createCallExpression(context.helper(MERGE_PROPS), [
                                      tempExp,
                                      createCallExpression(context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), [
                                          tempExp,
                                          vModel.exp // model
                                      ])
                                  ])
                              ])
                          ];
                      }
                  }
                  if (needTagForRuntime) {
                      propsExp.arguments.push(`"${node.tag}"`);
                  }
                  openTag.push(propsExp);
              }
          }
          // book keeping static/dynamic class merging.
          let dynamicClassBinding = undefined;
          let staticClassBinding = undefined;
          // all style bindings are converted to dynamic by transformStyle.
          // but we need to make sure to merge them.
          let dynamicStyleBinding = undefined;
          for (let i = 0; i < node.props.length; i++) {
              const prop = node.props[i];
              // special cases with children override
              if (prop.type === 7 /* DIRECTIVE */) {
                  if (prop.name === 'html' && prop.exp) {
                      rawChildrenMap.set(node, prop.exp);
                  }
                  else if (prop.name === 'text' && prop.exp) {
                      node.children = [createInterpolation(prop.exp, prop.loc)];
                  }
                  else if (prop.name === 'slot') {
                      context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, prop.loc));
                  }
                  else if (isTextareaWithValue(node, prop) && prop.exp) {
                      if (!hasDynamicVBind) {
                          node.children = [createInterpolation(prop.exp, prop.loc)];
                      }
                  }
                  else {
                      // Directive transforms.
                      const directiveTransform = context.directiveTransforms[prop.name];
                      if (!directiveTransform) {
                          // no corresponding ssr directive transform found.
                          context.onError(createSSRCompilerError(60 /* X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM */, prop.loc));
                      }
                      else if (!hasDynamicVBind) {
                          const { props, ssrTagParts } = directiveTransform(prop, node, context);
                          if (ssrTagParts) {
                              openTag.push(...ssrTagParts);
                          }
                          for (let j = 0; j < props.length; j++) {
                              const { key, value } = props[j];
                              if (isStaticExp(key)) {
                                  let attrName = key.content;
                                  // static key attr
                                  if (attrName === 'class') {
                                      openTag.push(` class="`, (dynamicClassBinding = createCallExpression(context.helper(SSR_RENDER_CLASS), [value])), `"`);
                                  }
                                  else if (attrName === 'style') {
                                      if (dynamicStyleBinding) {
                                          // already has style binding, merge into it.
                                          mergeCall(dynamicStyleBinding, value);
                                      }
                                      else {
                                          openTag.push(` style="`, (dynamicStyleBinding = createCallExpression(context.helper(SSR_RENDER_STYLE), [value])), `"`);
                                      }
                                  }
                                  else {
                                      attrName =
                                          node.tag.indexOf('-') > 0
                                              ? attrName // preserve raw name on custom elements
                                              : propsToAttrMap[attrName] || attrName.toLowerCase();
                                      if (isBooleanAttr(attrName)) {
                                          openTag.push(createConditionalExpression(value, createSimpleExpression(' ' + attrName, true), createSimpleExpression('', true), false /* no newline */));
                                      }
                                      else if (isSSRSafeAttrName(attrName)) {
                                          openTag.push(createCallExpression(context.helper(SSR_RENDER_ATTR), [
                                              key,
                                              value
                                          ]));
                                      }
                                      else {
                                          context.onError(createSSRCompilerError(61 /* X_SSR_UNSAFE_ATTR_NAME */, key.loc));
                                      }
                                  }
                              }
                              else {
                                  // dynamic key attr
                                  // this branch is only encountered for custom directive
                                  // transforms that returns properties with dynamic keys
                                  const args = [key, value];
                                  if (needTagForRuntime) {
                                      args.push(`"${node.tag}"`);
                                  }
                                  openTag.push(createCallExpression(context.helper(SSR_RENDER_DYNAMIC_ATTR), args));
                              }
                          }
                      }
                  }
              }
              else {
                  // special case: value on <textarea>
                  if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
                      rawChildrenMap.set(node, escapeHtml(prop.value.content));
                  }
                  else if (!hasDynamicVBind) {
                      // static prop
                      if (prop.name === 'class' && prop.value) {
                          staticClassBinding = JSON.stringify(prop.value.content);
                      }
                      openTag.push(` ${prop.name}` +
                          (prop.value ? `="${escapeHtml(prop.value.content)}"` : ``));
                  }
              }
          }
          // handle co-existence of dynamic + static class bindings
          if (dynamicClassBinding && staticClassBinding) {
              mergeCall(dynamicClassBinding, staticClassBinding);
              removeStaticBinding(openTag, 'class');
          }
          if (context.scopeId) {
              openTag.push(` ${context.scopeId}`);
          }
          node.ssrCodegenNode = createTemplateLiteral(openTag);
      };
  };
  function isTextareaWithValue(node, prop) {
      return !!(node.tag === 'textarea' &&
          prop.name === 'bind' &&
          isBindKey(prop.arg, 'value'));
  }
  function mergeCall(call, arg) {
      const existing = call.arguments[0];
      if (existing.type === 17 /* JS_ARRAY_EXPRESSION */) {
          existing.elements.push(arg);
      }
      else {
          call.arguments[0] = createArrayExpression([existing, arg]);
      }
  }
  function removeStaticBinding(tag, binding) {
      const i = tag.findIndex(e => typeof e === 'string' && e.startsWith(` ${binding}=`));
      if (i > -1) {
          tag.splice(i, 1);
      }
  }
  function findVModel(node) {
      return node.props.find(p => p.type === 7 /* DIRECTIVE */ && p.name === 'model' && p.exp);
  }
  function ssrProcessElement(node, context) {
      const isVoidTag = context.options.isVoidTag || NO;
      const elementsToAdd = node.ssrCodegenNode.elements;
      for (let j = 0; j < elementsToAdd.length; j++) {
          context.pushStringPart(elementsToAdd[j]);
      }
      // Handle slot scopeId
      if (context.withSlotScopeId) {
          context.pushStringPart(createSimpleExpression(`_scopeId`, false));
      }
      // close open tag
      context.pushStringPart(`>`);
      const rawChildren = rawChildrenMap.get(node);
      if (rawChildren) {
          context.pushStringPart(rawChildren);
      }
      else if (node.children.length) {
          processChildren(node.children, context);
      }
      if (!isVoidTag(node.tag)) {
          // push closing tag
          context.pushStringPart(`</${node.tag}>`);
      }
  }

  // Because SSR codegen output is completely different from client-side output
  // (e.g. multiple elements can be concatenated into a single template literal
  // instead of each getting a corresponding call), we need to apply an extra
  // transform pass to convert the template AST into a fresh JS AST before
  // passing it to codegen.
  function ssrCodegenTransform(ast, options) {
      const context = createSSRTransformContext(ast, options);
      // inject <style vars> resolution
      // we do this instead of inlining the expression to ensure the vars are
      // only resolved once per render
      if (options.ssrCssVars) {
          const varsExp = processExpression(createSimpleExpression(options.ssrCssVars, false), createTransformContext(createRoot([]), options));
          context.body.push(createCompoundExpression([
              `const _cssVars = _${ssrHelpers[SSR_RESOLVE_CSS_VARS]}(`,
              varsExp,
              options.scopeId ? `, ${JSON.stringify(options.scopeId)}` : ``,
              `)`
          ]));
      }
      const isFragment = ast.children.length > 1 && ast.children.some(c => !isText(c));
      processChildren(ast.children, context, isFragment);
      ast.codegenNode = createBlockStatement(context.body);
      // Finalize helpers.
      // We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
      ast.ssrHelpers = [
          ...ast.helpers.filter(h => h in ssrHelpers),
          ...context.helpers
      ];
      ast.helpers = ast.helpers.filter(h => !(h in ssrHelpers));
  }
  function createSSRTransformContext(root, options, helpers = new Set(), withSlotScopeId = false) {
      const body = [];
      let currentString = null;
      return {
          root,
          options,
          body,
          helpers,
          withSlotScopeId,
          onError: options.onError ||
              (e => {
                  throw e;
              }),
          helper(name) {
              helpers.add(name);
              return name;
          },
          pushStringPart(part) {
              if (!currentString) {
                  const currentCall = createCallExpression(`_push`);
                  body.push(currentCall);
                  currentString = createTemplateLiteral([]);
                  currentCall.arguments.push(currentString);
              }
              const bufferedElements = currentString.elements;
              const lastItem = bufferedElements[bufferedElements.length - 1];
              if (isString(part) && isString(lastItem)) {
                  bufferedElements[bufferedElements.length - 1] += part;
              }
              else {
                  bufferedElements.push(part);
              }
          },
          pushStatement(statement) {
              // close current string
              currentString = null;
              body.push(statement);
          }
      };
  }
  function createChildContext(parent, withSlotScopeId = parent.withSlotScopeId) {
      // ensure child inherits parent helpers
      return createSSRTransformContext(parent.root, parent.options, parent.helpers, withSlotScopeId);
  }
  function processChildren(children, context, asFragment = false) {
      if (asFragment) {
          context.pushStringPart(`<!--[-->`);
      }
      for (let i = 0; i < children.length; i++) {
          const child = children[i];
          switch (child.type) {
              case 1 /* ELEMENT */:
                  switch (child.tagType) {
                      case 0 /* ELEMENT */:
                          ssrProcessElement(child, context);
                          break;
                      case 1 /* COMPONENT */:
                          ssrProcessComponent(child, context);
                          break;
                      case 2 /* SLOT */:
                          ssrProcessSlotOutlet(child, context);
                          break;
                      case 3 /* TEMPLATE */:
                          // TODO
                          break;
                      default:
                          context.onError(createSSRCompilerError(63 /* X_SSR_INVALID_AST_NODE */, child.loc));
                          // make sure we exhaust all possible types
                          const exhaustiveCheck = child;
                          return exhaustiveCheck;
                  }
                  break;
              case 2 /* TEXT */:
                  context.pushStringPart(escapeHtml(child.content));
                  break;
              case 3 /* COMMENT */:
                  // no need to escape comment here because the AST can only
                  // contain valid comments.
                  context.pushStringPart(`<!--${child.content}-->`);
                  break;
              case 5 /* INTERPOLATION */:
                  context.pushStringPart(createCallExpression(context.helper(SSR_INTERPOLATE), [child.content]));
                  break;
              case 9 /* IF */:
                  ssrProcessIf(child, context);
                  break;
              case 11 /* FOR */:
                  ssrProcessFor(child, context);
                  break;
              case 10 /* IF_BRANCH */:
                  // no-op - handled by ssrProcessIf
                  break;
              case 12 /* TEXT_CALL */:
              case 8 /* COMPOUND_EXPRESSION */:
                  // no-op - these two types can never appear as template child node since
                  // `transformText` is not used during SSR compile.
                  break;
              default:
                  context.onError(createSSRCompilerError(63 /* X_SSR_INVALID_AST_NODE */, child.loc));
                  // make sure we exhaust all possible types
                  const exhaustiveCheck = child;
                  return exhaustiveCheck;
          }
      }
      if (asFragment) {
          context.pushStringPart(`<!--]-->`);
      }
  }
  function processChildrenAsStatement(children, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
      const childContext = createChildContext(parentContext, withSlotScopeId);
      processChildren(children, childContext, asFragment);
      return createBlockStatement(childContext.body);
  }

  const ssrTransformModel = (dir, node, context) => {
      const model = dir.exp;
      function checkDuplicatedValue() {
          const value = findProp(node, 'value');
          if (value) {
              context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
          }
      }
      if (node.tagType === 0 /* ELEMENT */) {
          const res = { props: [] };
          const defaultProps = [
              // default value binding for text type inputs
              createObjectProperty(`value`, model)
          ];
          if (node.tag === 'input') {
              const type = findProp(node, 'type');
              if (type) {
                  const value = findValueBinding(node);
                  if (type.type === 7 /* DIRECTIVE */) {
                      // dynamic type
                      res.ssrTagParts = [
                          createCallExpression(context.helper(SSR_RENDER_DYNAMIC_MODEL), [
                              type.exp,
                              model,
                              value
                          ])
                      ];
                  }
                  else if (type.value) {
                      // static type
                      switch (type.value.content) {
                          case 'radio':
                              res.props = [
                                  createObjectProperty(`checked`, createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
                                      model,
                                      value
                                  ]))
                              ];
                              break;
                          case 'checkbox':
                              res.props = [
                                  createObjectProperty(`checked`, createConditionalExpression(createCallExpression(`Array.isArray`, [model]), createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
                                      model,
                                      value
                                  ]), model))
                              ];
                              break;
                          case 'file':
                              context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
                              break;
                          default:
                              checkDuplicatedValue();
                              res.props = defaultProps;
                              break;
                      }
                  }
              }
              else if (hasDynamicKeyVBind(node)) ;
              else {
                  // text type
                  checkDuplicatedValue();
                  res.props = defaultProps;
              }
          }
          else if (node.tag === 'textarea') {
              checkDuplicatedValue();
              node.children = [createInterpolation(model, model.loc)];
          }
          else if (node.tag === 'select') ;
          else {
              context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
          }
          return res;
      }
      else {
          // component v-model
          return transformModel(dir, node, context);
      }
  };
  function findValueBinding(node) {
      const valueBinding = findProp(node, 'value');
      return valueBinding
          ? valueBinding.type === 7 /* DIRECTIVE */
              ? valueBinding.exp
              : createSimpleExpression(valueBinding.value.content, true)
          : createSimpleExpression(`null`, false);
  }

  const ssrTransformShow = (dir, node, context) => {
      if (!dir.exp) {
          context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */));
      }
      return {
          props: [
              createObjectProperty(`style`, createConditionalExpression(dir.exp, createSimpleExpression(`null`, false), createObjectExpression([
                  createObjectProperty(`display`, createSimpleExpression(`none`, true))
              ]), false /* no newline */))
          ]
      };
  };

  const hasSingleChild = (node) => node.children.filter(n => n.type !== 3 /* COMMENT */).length === 1;
  const ssrInjectFallthroughAttrs = (node, context) => {
      // _attrs is provided as a function argument.
      // mark it as a known identifier so that it doesn't get prefixed by
      // transformExpression.
      if (node.type === 0 /* ROOT */) {
          context.identifiers._attrs = 1;
      }
      const parent = context.parent;
      if (!parent || parent.type !== 0 /* ROOT */) {
          return;
      }
      if (node.type === 10 /* IF_BRANCH */ && hasSingleChild(node)) {
          injectFallthroughAttrs(node.children[0]);
      }
      else if (hasSingleChild(parent)) {
          injectFallthroughAttrs(node);
      }
  };
  function injectFallthroughAttrs(node) {
      if (node.type === 1 /* ELEMENT */ &&
          (node.tagType === 0 /* ELEMENT */ ||
              node.tagType === 1 /* COMPONENT */) &&
          !findDir(node, 'for')) {
          node.props.push({
              type: 7 /* DIRECTIVE */,
              name: 'bind',
              arg: undefined,
              exp: createSimpleExpression(`_attrs`, false),
              modifiers: [],
              loc: locStub
          });
      }
  }

  const ssrInjectCssVars = (node, context) => {
      if (!context.ssrCssVars) {
          return;
      }
      // _cssVars is initailized once per render function
      // the code is injected in ssrCodegenTrasnform when creating the
      // ssr transform context
      if (node.type === 0 /* ROOT */) {
          context.identifiers._cssVars = 1;
      }
      const parent = context.parent;
      if (!parent || parent.type !== 0 /* ROOT */) {
          return;
      }
      context.helper(SSR_RESOLVE_CSS_VARS);
      if (node.type === 10 /* IF_BRANCH */) {
          for (const child of node.children) {
              injectCssVars(child);
          }
      }
      else {
          injectCssVars(node);
      }
  };
  function injectCssVars(node) {
      if (node.type === 1 /* ELEMENT */ &&
          (node.tagType === 0 /* ELEMENT */ ||
              node.tagType === 1 /* COMPONENT */) &&
          !findDir(node, 'for')) {
          node.props.push({
              type: 7 /* DIRECTIVE */,
              name: 'bind',
              arg: undefined,
              exp: createSimpleExpression(`_cssVars`, false),
              modifiers: [],
              loc: locStub
          });
      }
  }

  function compile$1(template, options = {}) {
      options = {
          ...options,
          // apply DOM-specific parsing options
          ...parserOptions,
          ssr: true,
          scopeId: options.mode === 'function' ? null : options.scopeId,
          // always prefix since compiler-ssr doesn't have size concern
          prefixIdentifiers: true,
          // disable optimizations that are unnecessary for ssr
          cacheHandlers: false,
          hoistStatic: false
      };
      const ast = baseParse(template, options);
      // Save raw options for AST. This is needed when performing sub-transforms
      // on slot vnode branches.
      rawOptionsMap.set(ast, options);
      transform(ast, {
          ...options,
          nodeTransforms: [
              ssrTransformIf,
              ssrTransformFor,
              trackVForSlotScopes,
              transformExpression,
              ssrTransformSlotOutlet,
              ssrInjectFallthroughAttrs,
              ssrInjectCssVars,
              ssrTransformElement,
              ssrTransformComponent,
              trackSlotScopes,
              transformStyle,
              ...(options.nodeTransforms || []) // user transforms
          ],
          directiveTransforms: {
              // reusing core v-bind
              bind: transformBind,
              // model and show has dedicated SSR handling
              model: ssrTransformModel,
              show: ssrTransformShow,
              // the following are ignored during SSR
              on: noopDirectiveTransform,
              cloak: noopDirectiveTransform,
              once: noopDirectiveTransform,
              ...(options.directiveTransforms || {}) // user transforms
          }
      });
      // traverse the template AST and convert into SSR codegen AST
      // by replacing ast.codegenNode.
      ssrCodegenTransform(ast, options);
      return generate(ast, options);
  }

  var CompilerSSR = /*#__PURE__*/Object.freeze({
    __proto__: null,
    compile: compile$1
  });

  function preprocess({ source, filename, preprocessOptions }, preprocessor) {
      // Consolidate exposes a callback based API, but the callback is in fact
      // called synchronously for most templating engines. In our case, we have to
      // expose a synchronous API so that it is usable in Jest transforms (which
      // have to be sync because they are applied via Node.js require hooks)
      let res = '';
      let err = null;
      preprocessor.render(source, { filename, ...preprocessOptions }, (_err, _res) => {
          if (_err)
              err = _err;
          res = _res;
      });
      if (err)
          throw err;
      return res;
  }
  function compileTemplate(options) {
      const { preprocessLang, preprocessCustomRequire } = options;
      if (
          preprocessLang &&
          !preprocessCustomRequire) {
          throw new Error(`[@vue/compiler-sfc] Template preprocessing in the browser build must ` +
              `provide the \`preprocessCustomRequire\` option to return the in-browser ` +
              `version of the preprocessor in the shape of { render(): string }.`);
      }
      const preprocessor = preprocessLang
          ? preprocessCustomRequire
              ? preprocessCustomRequire(preprocessLang)
              : require('consolidate')[preprocessLang]
          : false;
      if (preprocessor) {
          try {
              return doCompileTemplate({
                  ...options,
                  source: preprocess(options, preprocessor)
              });
          }
          catch (e) {
              return {
                  code: `export default function render() {}`,
                  source: options.source,
                  tips: [],
                  errors: [e]
              };
          }
      }
      else if (preprocessLang) {
          return {
              code: `export default function render() {}`,
              source: options.source,
              tips: [
                  `Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`
              ],
              errors: [
                  `Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`
              ]
          };
      }
      else {
          return doCompileTemplate(options);
      }
  }
  function doCompileTemplate({ filename, inMap, source, ssr = false, compiler = ssr ? CompilerSSR : CompilerDOM, compilerOptions = {}, transformAssetUrls }) {
      const errors = [];
      let nodeTransforms = [];
      if (isObject(transformAssetUrls)) {
          const assetOptions = normalizeOptions(transformAssetUrls);
          nodeTransforms = [
              createAssetUrlTransformWithOptions(assetOptions),
              createSrcsetTransformWithOptions(assetOptions)
          ];
      }
      else if (transformAssetUrls !== false) {
          nodeTransforms = [transformAssetUrl, transformSrcset];
      }
      let { code, map } = compiler.compile(source, {
          mode: 'module',
          prefixIdentifiers: true,
          hoistStatic: true,
          cacheHandlers: true,
          ...compilerOptions,
          nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []),
          filename,
          sourceMap: true,
          onError: e => errors.push(e)
      });
      // inMap should be the map produced by ./parse.ts which is a simple line-only
      // mapping. If it is present, we need to adjust the final map and errors to
      // reflect the original line numbers.
      if (inMap) {
          if (map) {
              map = mapLines(inMap, map);
          }
          if (errors.length) {
              patchErrors(errors, source, inMap);
          }
      }
      return { code, source, errors, tips: [], map };
  }
  function mapLines(oldMap, newMap) {
      if (!oldMap)
          return newMap;
      if (!newMap)
          return oldMap;
      const oldMapConsumer = new SourceMapConsumer$1(oldMap);
      const newMapConsumer = new SourceMapConsumer$1(newMap);
      const mergedMapGenerator = new SourceMapGenerator$2();
      newMapConsumer.eachMapping(m => {
          if (m.originalLine == null) {
              return;
          }
          const origPosInOldMap = oldMapConsumer.originalPositionFor({
              line: m.originalLine,
              column: m.originalColumn
          });
          if (origPosInOldMap.source == null) {
              return;
          }
          mergedMapGenerator.addMapping({
              generated: {
                  line: m.generatedLine,
                  column: m.generatedColumn
              },
              original: {
                  line: origPosInOldMap.line,
                  // use current column, since the oldMap produced by @vue/compiler-sfc
                  // does not
                  column: m.originalColumn
              },
              source: origPosInOldMap.source,
              name: origPosInOldMap.name
          });
      });
      // source-map's type definition is incomplete
      const generator = mergedMapGenerator;
      oldMapConsumer.sources.forEach((sourceFile) => {
          generator._sources.add(sourceFile);
          const sourceContent = oldMapConsumer.sourceContentFor(sourceFile);
          if (sourceContent != null) {
              mergedMapGenerator.setSourceContent(sourceFile, sourceContent);
          }
      });
      generator._sourceRoot = oldMap.sourceRoot;
      generator._file = oldMap.file;
      return generator.toJSON();
  }
  function patchErrors(errors, source, inMap) {
      const originalSource = inMap.sourcesContent[0];
      const offset = originalSource.indexOf(source);
      const lineOffset = originalSource.slice(0, offset).split(/\r?\n/).length - 1;
      errors.forEach(err => {
          if (err.loc) {
              err.loc.start.line += lineOffset;
              err.loc.start.offset += offset;
              if (err.loc.end !== err.loc.start) {
                  err.loc.end.line += lineOffset;
                  err.loc.end.offset += offset;
              }
          }
      });
  }

  var trimPlugin = postcss__default.plugin('trim', () => (css) => {
      css.walk(({ type, raws }) => {
          if (type === 'rule' || type === 'atrule') {
              if (raws.before)
                  raws.before = '\n';
              if (raws.after)
                  raws.after = '\n';
          }
      });
  });

  var indexesOf = function (ary, item) {
    var i = -1, indexes = [];
    while((i = ary.indexOf(item, i + 1)) !== -1)
      indexes.push(i);
    return indexes
  };

  function unique_pred(list, compare) {
    var ptr = 1
      , len = list.length
      , a=list[0], b=list[0];
    for(var i=1; i<len; ++i) {
      b = a;
      a = list[i];
      if(compare(a, b)) {
        if(i === ptr) {
          ptr++;
          continue
        }
        list[ptr++] = a;
      }
    }
    list.length = ptr;
    return list
  }

  function unique_eq(list) {
    var ptr = 1
      , len = list.length
      , a=list[0], b = list[0];
    for(var i=1; i<len; ++i, b=a) {
      b = a;
      a = list[i];
      if(a !== b) {
        if(i === ptr) {
          ptr++;
          continue
        }
        list[ptr++] = a;
      }
    }
    list.length = ptr;
    return list
  }

  function unique(list, compare, sorted) {
    if(list.length === 0) {
      return list
    }
    if(compare) {
      if(!sorted) {
        list.sort(compare);
      }
      return unique_pred(list, compare)
    }
    if(!sorted) {
      list.sort();
    }
    return unique_eq(list)
  }

  var uniq = unique;

  var unesc_1 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = unesc;
  var whitespace = '[\\x20\\t\\r\\n\\f]';
  var unescapeRegExp = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig');

  function unesc(str) {
    return str.replace(unescapeRegExp, function (_, escaped, escapedWhitespace) {
      var high = '0x' + escaped - 0x10000; // NaN means non-codepoint
      // Workaround erroneous numeric interpretation of +"0x"
      // eslint-disable-next-line no-self-compare

      return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint
      String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair)
      String.fromCharCode(high >> 10 | 0xd800, high & 0x3ff | 0xdc00);
    });
  }

  module.exports = exports.default;
  });

  var getProp_1 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = getProp;

  function getProp(obj) {
    for (var _len = arguments.length, props = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      props[_key - 1] = arguments[_key];
    }

    while (props.length > 0) {
      var prop = props.shift();

      if (!obj[prop]) {
        return undefined;
      }

      obj = obj[prop];
    }

    return obj;
  }

  module.exports = exports.default;
  });

  var ensureObject_1 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = ensureObject;

  function ensureObject(obj) {
    for (var _len = arguments.length, props = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      props[_key - 1] = arguments[_key];
    }

    while (props.length > 0) {
      var prop = props.shift();

      if (!obj[prop]) {
        obj[prop] = {};
      }

      obj = obj[prop];
    }
  }

  module.exports = exports.default;
  });

  var stripComments_1 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = stripComments;

  function stripComments(str) {
    var s = "";
    var commentStart = str.indexOf("/*");
    var lastEnd = 0;

    while (commentStart >= 0) {
      s = s + str.slice(lastEnd, commentStart);
      var commentEnd = str.indexOf("*/", commentStart + 2);

      if (commentEnd < 0) {
        return s;
      }

      lastEnd = commentEnd + 2;
      commentStart = str.indexOf("/*", lastEnd);
    }

    s = s + str.slice(lastEnd);
    return s;
  }

  module.exports = exports.default;
  });

  var util$3 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.stripComments = exports.ensureObject = exports.getProp = exports.unesc = void 0;

  var _unesc = _interopRequireDefault(unesc_1);

  exports.unesc = _unesc.default;

  var _getProp = _interopRequireDefault(getProp_1);

  exports.getProp = _getProp.default;

  var _ensureObject = _interopRequireDefault(ensureObject_1);

  exports.ensureObject = _ensureObject.default;

  var _stripComments = _interopRequireDefault(stripComments_1);

  exports.stripComments = _stripComments.default;

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  });

  var node = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;



  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  var cloneNode = function cloneNode(obj, parent) {
    if (typeof obj !== 'object' || obj === null) {
      return obj;
    }

    var cloned = new obj.constructor();

    for (var i in obj) {
      if (!obj.hasOwnProperty(i)) {
        continue;
      }

      var value = obj[i];
      var type = typeof value;

      if (i === 'parent' && type === 'object') {
        if (parent) {
          cloned[i] = parent;
        }
      } else if (value instanceof Array) {
        cloned[i] = value.map(function (j) {
          return cloneNode(j, cloned);
        });
      } else {
        cloned[i] = cloneNode(value, cloned);
      }
    }

    return cloned;
  };

  var Node =
  /*#__PURE__*/
  function () {
    function Node(opts) {
      if (opts === void 0) {
        opts = {};
      }

      Object.assign(this, opts);
      this.spaces = this.spaces || {};
      this.spaces.before = this.spaces.before || '';
      this.spaces.after = this.spaces.after || '';
    }

    var _proto = Node.prototype;

    _proto.remove = function remove() {
      if (this.parent) {
        this.parent.removeChild(this);
      }

      this.parent = undefined;
      return this;
    };

    _proto.replaceWith = function replaceWith() {
      if (this.parent) {
        for (var index in arguments) {
          this.parent.insertBefore(this, arguments[index]);
        }

        this.remove();
      }

      return this;
    };

    _proto.next = function next() {
      return this.parent.at(this.parent.index(this) + 1);
    };

    _proto.prev = function prev() {
      return this.parent.at(this.parent.index(this) - 1);
    };

    _proto.clone = function clone(overrides) {
      if (overrides === void 0) {
        overrides = {};
      }

      var cloned = cloneNode(this);

      for (var name in overrides) {
        cloned[name] = overrides[name];
      }

      return cloned;
    }
    /**
     * Some non-standard syntax doesn't follow normal escaping rules for css.
     * This allows non standard syntax to be appended to an existing property
     * by specifying the escaped value. By specifying the escaped value,
     * illegal characters are allowed to be directly inserted into css output.
     * @param {string} name the property to set
     * @param {any} value the unescaped value of the property
     * @param {string} valueEscaped optional. the escaped value of the property.
     */
    ;

    _proto.appendToPropertyAndEscape = function appendToPropertyAndEscape(name, value, valueEscaped) {
      if (!this.raws) {
        this.raws = {};
      }

      var originalValue = this[name];
      var originalEscaped = this.raws[name];
      this[name] = originalValue + value; // this may trigger a setter that updates raws, so it has to be set first.

      if (originalEscaped || valueEscaped !== value) {
        this.raws[name] = (originalEscaped || originalValue) + valueEscaped;
      } else {
        delete this.raws[name]; // delete any escaped value that was created by the setter.
      }
    }
    /**
     * Some non-standard syntax doesn't follow normal escaping rules for css.
     * This allows the escaped value to be specified directly, allowing illegal
     * characters to be directly inserted into css output.
     * @param {string} name the property to set
     * @param {any} value the unescaped value of the property
     * @param {string} valueEscaped the escaped value of the property.
     */
    ;

    _proto.setPropertyAndEscape = function setPropertyAndEscape(name, value, valueEscaped) {
      if (!this.raws) {
        this.raws = {};
      }

      this[name] = value; // this may trigger a setter that updates raws, so it has to be set first.

      this.raws[name] = valueEscaped;
    }
    /**
     * When you want a value to passed through to CSS directly. This method
     * deletes the corresponding raw value causing the stringifier to fallback
     * to the unescaped value.
     * @param {string} name the property to set.
     * @param {any} value The value that is both escaped and unescaped.
     */
    ;

    _proto.setPropertyWithoutEscape = function setPropertyWithoutEscape(name, value) {
      this[name] = value; // this may trigger a setter that updates raws, so it has to be set first.

      if (this.raws) {
        delete this.raws[name];
      }
    }
    /**
     * 
     * @param {number} line The number (starting with 1)
     * @param {number} column The column number (starting with 1)
     */
    ;

    _proto.isAtPosition = function isAtPosition(line, column) {
      if (this.source && this.source.start && this.source.end) {
        if (this.source.start.line > line) {
          return false;
        }

        if (this.source.end.line < line) {
          return false;
        }

        if (this.source.start.line === line && this.source.start.column > column) {
          return false;
        }

        if (this.source.end.line === line && this.source.end.column < column) {
          return false;
        }

        return true;
      }

      return undefined;
    };

    _proto.stringifyProperty = function stringifyProperty(name) {
      return this.raws && this.raws[name] || this[name];
    };

    _proto.toString = function toString() {
      return [this.rawSpaceBefore, String(this.stringifyProperty("value")), this.rawSpaceAfter].join('');
    };

    _createClass(Node, [{
      key: "rawSpaceBefore",
      get: function get() {
        var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.before;

        if (rawSpace === undefined) {
          rawSpace = this.spaces && this.spaces.before;
        }

        return rawSpace || "";
      },
      set: function set(raw) {
        (0, util$3.ensureObject)(this, "raws", "spaces");
        this.raws.spaces.before = raw;
      }
    }, {
      key: "rawSpaceAfter",
      get: function get() {
        var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.after;

        if (rawSpace === undefined) {
          rawSpace = this.spaces.after;
        }

        return rawSpace || "";
      },
      set: function set(raw) {
        (0, util$3.ensureObject)(this, "raws", "spaces");
        this.raws.spaces.after = raw;
      }
    }]);

    return Node;
  }();

  exports.default = Node;
  module.exports = exports.default;
  });

  var types = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.UNIVERSAL = exports.ATTRIBUTE = exports.CLASS = exports.COMBINATOR = exports.COMMENT = exports.ID = exports.NESTING = exports.PSEUDO = exports.ROOT = exports.SELECTOR = exports.STRING = exports.TAG = void 0;
  var TAG = 'tag';
  exports.TAG = TAG;
  var STRING = 'string';
  exports.STRING = STRING;
  var SELECTOR = 'selector';
  exports.SELECTOR = SELECTOR;
  var ROOT = 'root';
  exports.ROOT = ROOT;
  var PSEUDO = 'pseudo';
  exports.PSEUDO = PSEUDO;
  var NESTING = 'nesting';
  exports.NESTING = NESTING;
  var ID = 'id';
  exports.ID = ID;
  var COMMENT = 'comment';
  exports.COMMENT = COMMENT;
  var COMBINATOR = 'combinator';
  exports.COMBINATOR = COMBINATOR;
  var CLASS = 'class';
  exports.CLASS = CLASS;
  var ATTRIBUTE = 'attribute';
  exports.ATTRIBUTE = ATTRIBUTE;
  var UNIVERSAL = 'universal';
  exports.UNIVERSAL = UNIVERSAL;
  });

  var container = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _node = _interopRequireDefault(node);

  var types$1 = _interopRequireWildcard(types);

  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Container =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(Container, _Node);

    function Container(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;

      if (!_this.nodes) {
        _this.nodes = [];
      }

      return _this;
    }

    var _proto = Container.prototype;

    _proto.append = function append(selector) {
      selector.parent = this;
      this.nodes.push(selector);
      return this;
    };

    _proto.prepend = function prepend(selector) {
      selector.parent = this;
      this.nodes.unshift(selector);
      return this;
    };

    _proto.at = function at(index) {
      return this.nodes[index];
    };

    _proto.index = function index(child) {
      if (typeof child === 'number') {
        return child;
      }

      return this.nodes.indexOf(child);
    };

    _proto.removeChild = function removeChild(child) {
      child = this.index(child);
      this.at(child).parent = undefined;
      this.nodes.splice(child, 1);
      var index;

      for (var id in this.indexes) {
        index = this.indexes[id];

        if (index >= child) {
          this.indexes[id] = index - 1;
        }
      }

      return this;
    };

    _proto.removeAll = function removeAll() {
      for (var _iterator = this.nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var node = _ref;
        node.parent = undefined;
      }

      this.nodes = [];
      return this;
    };

    _proto.empty = function empty() {
      return this.removeAll();
    };

    _proto.insertAfter = function insertAfter(oldNode, newNode) {
      newNode.parent = this;
      var oldIndex = this.index(oldNode);
      this.nodes.splice(oldIndex + 1, 0, newNode);
      newNode.parent = this;
      var index;

      for (var id in this.indexes) {
        index = this.indexes[id];

        if (oldIndex <= index) {
          this.indexes[id] = index + 1;
        }
      }

      return this;
    };

    _proto.insertBefore = function insertBefore(oldNode, newNode) {
      newNode.parent = this;
      var oldIndex = this.index(oldNode);
      this.nodes.splice(oldIndex, 0, newNode);
      newNode.parent = this;
      var index;

      for (var id in this.indexes) {
        index = this.indexes[id];

        if (index <= oldIndex) {
          this.indexes[id] = index + 1;
        }
      }

      return this;
    };

    _proto._findChildAtPosition = function _findChildAtPosition(line, col) {
      var found = undefined;
      this.each(function (node) {
        if (node.atPosition) {
          var foundChild = node.atPosition(line, col);

          if (foundChild) {
            found = foundChild;
            return false;
          }
        } else if (node.isAtPosition(line, col)) {
          found = node;
          return false;
        }
      });
      return found;
    }
    /**
     * Return the most specific node at the line and column number given.
     * The source location is based on the original parsed location, locations aren't
     * updated as selector nodes are mutated.
     * 
     * Note that this location is relative to the location of the first character
     * of the selector, and not the location of the selector in the overall document
     * when used in conjunction with postcss.
     *
     * If not found, returns undefined.
     * @param {number} line The line number of the node to find. (1-based index)
     * @param {number} col  The column number of the node to find. (1-based index)
     */
    ;

    _proto.atPosition = function atPosition(line, col) {
      if (this.isAtPosition(line, col)) {
        return this._findChildAtPosition(line, col) || this;
      } else {
        return undefined;
      }
    };

    _proto._inferEndPosition = function _inferEndPosition() {
      if (this.last && this.last.source && this.last.source.end) {
        this.source = this.source || {};
        this.source.end = this.source.end || {};
        Object.assign(this.source.end, this.last.source.end);
      }
    };

    _proto.each = function each(callback) {
      if (!this.lastEach) {
        this.lastEach = 0;
      }

      if (!this.indexes) {
        this.indexes = {};
      }

      this.lastEach++;
      var id = this.lastEach;
      this.indexes[id] = 0;

      if (!this.length) {
        return undefined;
      }

      var index, result;

      while (this.indexes[id] < this.length) {
        index = this.indexes[id];
        result = callback(this.at(index), index);

        if (result === false) {
          break;
        }

        this.indexes[id] += 1;
      }

      delete this.indexes[id];

      if (result === false) {
        return false;
      }
    };

    _proto.walk = function walk(callback) {
      return this.each(function (node, i) {
        var result = callback(node, i);

        if (result !== false && node.length) {
          result = node.walk(callback);
        }

        if (result === false) {
          return false;
        }
      });
    };

    _proto.walkAttributes = function walkAttributes(callback) {
      var _this2 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.ATTRIBUTE) {
          return callback.call(_this2, selector);
        }
      });
    };

    _proto.walkClasses = function walkClasses(callback) {
      var _this3 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.CLASS) {
          return callback.call(_this3, selector);
        }
      });
    };

    _proto.walkCombinators = function walkCombinators(callback) {
      var _this4 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.COMBINATOR) {
          return callback.call(_this4, selector);
        }
      });
    };

    _proto.walkComments = function walkComments(callback) {
      var _this5 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.COMMENT) {
          return callback.call(_this5, selector);
        }
      });
    };

    _proto.walkIds = function walkIds(callback) {
      var _this6 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.ID) {
          return callback.call(_this6, selector);
        }
      });
    };

    _proto.walkNesting = function walkNesting(callback) {
      var _this7 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.NESTING) {
          return callback.call(_this7, selector);
        }
      });
    };

    _proto.walkPseudos = function walkPseudos(callback) {
      var _this8 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.PSEUDO) {
          return callback.call(_this8, selector);
        }
      });
    };

    _proto.walkTags = function walkTags(callback) {
      var _this9 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.TAG) {
          return callback.call(_this9, selector);
        }
      });
    };

    _proto.walkUniversals = function walkUniversals(callback) {
      var _this10 = this;

      return this.walk(function (selector) {
        if (selector.type === types$1.UNIVERSAL) {
          return callback.call(_this10, selector);
        }
      });
    };

    _proto.split = function split(callback) {
      var _this11 = this;

      var current = [];
      return this.reduce(function (memo, node, index) {
        var split = callback.call(_this11, node);
        current.push(node);

        if (split) {
          memo.push(current);
          current = [];
        } else if (index === _this11.length - 1) {
          memo.push(current);
        }

        return memo;
      }, []);
    };

    _proto.map = function map(callback) {
      return this.nodes.map(callback);
    };

    _proto.reduce = function reduce(callback, memo) {
      return this.nodes.reduce(callback, memo);
    };

    _proto.every = function every(callback) {
      return this.nodes.every(callback);
    };

    _proto.some = function some(callback) {
      return this.nodes.some(callback);
    };

    _proto.filter = function filter(callback) {
      return this.nodes.filter(callback);
    };

    _proto.sort = function sort(callback) {
      return this.nodes.sort(callback);
    };

    _proto.toString = function toString() {
      return this.map(String).join('');
    };

    _createClass(Container, [{
      key: "first",
      get: function get() {
        return this.at(0);
      }
    }, {
      key: "last",
      get: function get() {
        return this.at(this.length - 1);
      }
    }, {
      key: "length",
      get: function get() {
        return this.nodes.length;
      }
    }]);

    return Container;
  }(_node.default);

  exports.default = Container;
  module.exports = exports.default;
  });

  var root = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _container = _interopRequireDefault(container);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Root =
  /*#__PURE__*/
  function (_Container) {
    _inheritsLoose(Root, _Container);

    function Root(opts) {
      var _this;

      _this = _Container.call(this, opts) || this;
      _this.type = types.ROOT;
      return _this;
    }

    var _proto = Root.prototype;

    _proto.toString = function toString() {
      var str = this.reduce(function (memo, selector) {
        memo.push(String(selector));
        return memo;
      }, []).join(',');
      return this.trailingComma ? str + ',' : str;
    };

    _proto.error = function error(message, options) {
      if (this._error) {
        return this._error(message, options);
      } else {
        return new Error(message);
      }
    };

    _createClass(Root, [{
      key: "errorGenerator",
      set: function set(handler) {
        this._error = handler;
      }
    }]);

    return Root;
  }(_container.default);

  exports.default = Root;
  module.exports = exports.default;
  });

  var selector = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _container = _interopRequireDefault(container);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Selector =
  /*#__PURE__*/
  function (_Container) {
    _inheritsLoose(Selector, _Container);

    function Selector(opts) {
      var _this;

      _this = _Container.call(this, opts) || this;
      _this.type = types.SELECTOR;
      return _this;
    }

    return Selector;
  }(_container.default);

  exports.default = Selector;
  module.exports = exports.default;
  });

  /*! https://mths.be/cssesc v3.0.0 by @mathias */

  var object = {};
  var hasOwnProperty$3 = object.hasOwnProperty;
  var merge = function merge(options, defaults) {
  	if (!options) {
  		return defaults;
  	}
  	var result = {};
  	for (var key in defaults) {
  		// `if (defaults.hasOwnProperty(key) { … }` is not needed here, since
  		// only recognized option names are used.
  		result[key] = hasOwnProperty$3.call(options, key) ? options[key] : defaults[key];
  	}
  	return result;
  };

  var regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/;
  var regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/;
  var regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g;

  // https://mathiasbynens.be/notes/css-escapes#css
  var cssesc = function cssesc(string, options) {
  	options = merge(options, cssesc.options);
  	if (options.quotes != 'single' && options.quotes != 'double') {
  		options.quotes = 'single';
  	}
  	var quote = options.quotes == 'double' ? '"' : '\'';
  	var isIdentifier = options.isIdentifier;

  	var firstChar = string.charAt(0);
  	var output = '';
  	var counter = 0;
  	var length = string.length;
  	while (counter < length) {
  		var character = string.charAt(counter++);
  		var codePoint = character.charCodeAt();
  		var value = void 0;
  		// If it’s not a printable ASCII character…
  		if (codePoint < 0x20 || codePoint > 0x7E) {
  			if (codePoint >= 0xD800 && codePoint <= 0xDBFF && counter < length) {
  				// It’s a high surrogate, and there is a next character.
  				var extra = string.charCodeAt(counter++);
  				if ((extra & 0xFC00) == 0xDC00) {
  					// next character is low surrogate
  					codePoint = ((codePoint & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
  				} else {
  					// It’s an unmatched surrogate; only append this code unit, in case
  					// the next code unit is the high surrogate of a surrogate pair.
  					counter--;
  				}
  			}
  			value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
  		} else {
  			if (options.escapeEverything) {
  				if (regexAnySingleEscape.test(character)) {
  					value = '\\' + character;
  				} else {
  					value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
  				}
  			} else if (/[\t\n\f\r\x0B]/.test(character)) {
  				value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
  			} else if (character == '\\' || !isIdentifier && (character == '"' && quote == character || character == '\'' && quote == character) || isIdentifier && regexSingleEscape.test(character)) {
  				value = '\\' + character;
  			} else {
  				value = character;
  			}
  		}
  		output += value;
  	}

  	if (isIdentifier) {
  		if (/^-[-\d]/.test(output)) {
  			output = '\\-' + output.slice(1);
  		} else if (/\d/.test(firstChar)) {
  			output = '\\3' + firstChar + ' ' + output.slice(1);
  		}
  	}

  	// Remove spaces after `\HEX` escapes that are not followed by a hex digit,
  	// since they’re redundant. Note that this is only possible if the escape
  	// sequence isn’t preceded by an odd number of backslashes.
  	output = output.replace(regexExcessiveSpaces, function ($0, $1, $2) {
  		if ($1 && $1.length % 2) {
  			// It’s not safe to remove the space, so don’t.
  			return $0;
  		}
  		// Strip the space.
  		return ($1 || '') + $2;
  	});

  	if (!isIdentifier && options.wrap) {
  		return quote + output + quote;
  	}
  	return output;
  };

  // Expose default options (so they can be overridden globally).
  cssesc.options = {
  	'escapeEverything': false,
  	'isIdentifier': false,
  	'quotes': 'single',
  	'wrap': false
  };

  cssesc.version = '3.0.0';

  var cssesc_1 = cssesc;

  var className = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _cssesc = _interopRequireDefault(cssesc_1);



  var _node = _interopRequireDefault(node);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var ClassName =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(ClassName, _Node);

    function ClassName(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;
      _this.type = types.CLASS;
      _this._constructed = true;
      return _this;
    }

    var _proto = ClassName.prototype;

    _proto.toString = function toString() {
      return [this.rawSpaceBefore, String('.' + this.stringifyProperty("value")), this.rawSpaceAfter].join('');
    };

    _createClass(ClassName, [{
      key: "value",
      set: function set(v) {
        if (this._constructed) {
          var escaped = (0, _cssesc.default)(v, {
            isIdentifier: true
          });

          if (escaped !== v) {
            (0, util$3.ensureObject)(this, "raws");
            this.raws.value = escaped;
          } else if (this.raws) {
            delete this.raws.value;
          }
        }

        this._value = v;
      },
      get: function get() {
        return this._value;
      }
    }]);

    return ClassName;
  }(_node.default);

  exports.default = ClassName;
  module.exports = exports.default;
  });

  var comment = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _node = _interopRequireDefault(node);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Comment =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(Comment, _Node);

    function Comment(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;
      _this.type = types.COMMENT;
      return _this;
    }

    return Comment;
  }(_node.default);

  exports.default = Comment;
  module.exports = exports.default;
  });

  var id = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _node = _interopRequireDefault(node);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var ID =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(ID, _Node);

    function ID(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;
      _this.type = types.ID;
      return _this;
    }

    var _proto = ID.prototype;

    _proto.toString = function toString() {
      return [this.rawSpaceBefore, String('#' + this.stringifyProperty("value")), this.rawSpaceAfter].join('');
    };

    return ID;
  }(_node.default);

  exports.default = ID;
  module.exports = exports.default;
  });

  var namespace = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _cssesc = _interopRequireDefault(cssesc_1);



  var _node = _interopRequireDefault(node);

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Namespace =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(Namespace, _Node);

    function Namespace() {
      return _Node.apply(this, arguments) || this;
    }

    var _proto = Namespace.prototype;

    _proto.qualifiedName = function qualifiedName(value) {
      if (this.namespace) {
        return this.namespaceString + "|" + value;
      } else {
        return value;
      }
    };

    _proto.toString = function toString() {
      return [this.rawSpaceBefore, this.qualifiedName(this.stringifyProperty("value")), this.rawSpaceAfter].join('');
    };

    _createClass(Namespace, [{
      key: "namespace",
      get: function get() {
        return this._namespace;
      },
      set: function set(namespace) {
        if (namespace === true || namespace === "*" || namespace === "&") {
          this._namespace = namespace;

          if (this.raws) {
            delete this.raws.namespace;
          }

          return;
        }

        var escaped = (0, _cssesc.default)(namespace, {
          isIdentifier: true
        });
        this._namespace = namespace;

        if (escaped !== namespace) {
          (0, util$3.ensureObject)(this, "raws");
          this.raws.namespace = escaped;
        } else if (this.raws) {
          delete this.raws.namespace;
        }
      }
    }, {
      key: "ns",
      get: function get() {
        return this._namespace;
      },
      set: function set(namespace) {
        this.namespace = namespace;
      }
    }, {
      key: "namespaceString",
      get: function get() {
        if (this.namespace) {
          var ns = this.stringifyProperty("namespace");

          if (ns === true) {
            return '';
          } else {
            return ns;
          }
        } else {
          return '';
        }
      }
    }]);

    return Namespace;
  }(_node.default);

  exports.default = Namespace;
  module.exports = exports.default;
  });

  var tag = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _namespace = _interopRequireDefault(namespace);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Tag =
  /*#__PURE__*/
  function (_Namespace) {
    _inheritsLoose(Tag, _Namespace);

    function Tag(opts) {
      var _this;

      _this = _Namespace.call(this, opts) || this;
      _this.type = types.TAG;
      return _this;
    }

    return Tag;
  }(_namespace.default);

  exports.default = Tag;
  module.exports = exports.default;
  });

  var string = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _node = _interopRequireDefault(node);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var String =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(String, _Node);

    function String(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;
      _this.type = types.STRING;
      return _this;
    }

    return String;
  }(_node.default);

  exports.default = String;
  module.exports = exports.default;
  });

  var pseudo = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _container = _interopRequireDefault(container);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Pseudo =
  /*#__PURE__*/
  function (_Container) {
    _inheritsLoose(Pseudo, _Container);

    function Pseudo(opts) {
      var _this;

      _this = _Container.call(this, opts) || this;
      _this.type = types.PSEUDO;
      return _this;
    }

    var _proto = Pseudo.prototype;

    _proto.toString = function toString() {
      var params = this.length ? '(' + this.map(String).join(',') + ')' : '';
      return [this.rawSpaceBefore, this.stringifyProperty("value"), params, this.rawSpaceAfter].join('');
    };

    return Pseudo;
  }(_container.default);

  exports.default = Pseudo;
  module.exports = exports.default;
  });

  var attribute = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.unescapeValue = unescapeValue;
  exports.default = void 0;

  var _cssesc = _interopRequireDefault(cssesc_1);

  var _unesc = _interopRequireDefault(unesc_1);

  var _namespace = _interopRequireDefault(namespace);



  var _CSSESC_QUOTE_OPTIONS;

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var deprecate = util$2.deprecate;

  var WRAPPED_IN_QUOTES = /^('|")(.*)\1$/;
  var warnOfDeprecatedValueAssignment = deprecate(function () {}, "Assigning an attribute a value containing characters that might need to be escaped is deprecated. " + "Call attribute.setValue() instead.");
  var warnOfDeprecatedQuotedAssignment = deprecate(function () {}, "Assigning attr.quoted is deprecated and has no effect. Assign to attr.quoteMark instead.");
  var warnOfDeprecatedConstructor = deprecate(function () {}, "Constructing an Attribute selector with a value without specifying quoteMark is deprecated. Note: The value should be unescaped now.");

  function unescapeValue(value) {
    var deprecatedUsage = false;
    var quoteMark = null;
    var unescaped = value;
    var m = unescaped.match(WRAPPED_IN_QUOTES);

    if (m) {
      quoteMark = m[1];
      unescaped = m[2];
    }

    unescaped = (0, _unesc.default)(unescaped);

    if (unescaped !== value) {
      deprecatedUsage = true;
    }

    return {
      deprecatedUsage: deprecatedUsage,
      unescaped: unescaped,
      quoteMark: quoteMark
    };
  }

  function handleDeprecatedContructorOpts(opts) {
    if (opts.quoteMark !== undefined) {
      return opts;
    }

    if (opts.value === undefined) {
      return opts;
    }

    warnOfDeprecatedConstructor();

    var _unescapeValue = unescapeValue(opts.value),
        quoteMark = _unescapeValue.quoteMark,
        unescaped = _unescapeValue.unescaped;

    if (!opts.raws) {
      opts.raws = {};
    }

    if (opts.raws.value === undefined) {
      opts.raws.value = opts.value;
    }

    opts.value = unescaped;
    opts.quoteMark = quoteMark;
    return opts;
  }

  var Attribute =
  /*#__PURE__*/
  function (_Namespace) {
    _inheritsLoose(Attribute, _Namespace);

    function Attribute(opts) {
      var _this;

      if (opts === void 0) {
        opts = {};
      }

      _this = _Namespace.call(this, handleDeprecatedContructorOpts(opts)) || this;
      _this.type = types.ATTRIBUTE;
      _this.raws = _this.raws || {};
      Object.defineProperty(_this.raws, 'unquoted', {
        get: deprecate(function () {
          return _this.value;
        }, "attr.raws.unquoted is deprecated. Call attr.value instead."),
        set: deprecate(function () {
          return _this.value;
        }, "Setting attr.raws.unquoted is deprecated and has no effect. attr.value is unescaped by default now.")
      });
      _this._constructed = true;
      return _this;
    }
    /**
     * Returns the Attribute's value quoted such that it would be legal to use
     * in the value of a css file. The original value's quotation setting
     * used for stringification is left unchanged. See `setValue(value, options)`
     * if you want to control the quote settings of a new value for the attribute.
     *
     * You can also change the quotation used for the current value by setting quoteMark.
     *
     * Options:
     *   * quoteMark {'"' | "'" | null} - Use this value to quote the value. If this
     *     option is not set, the original value for quoteMark will be used. If
     *     indeterminate, a double quote is used. The legal values are:
     *     * `null` - the value will be unquoted and characters will be escaped as necessary.
     *     * `'` - the value will be quoted with a single quote and single quotes are escaped.
     *     * `"` - the value will be quoted with a double quote and double quotes are escaped.
     *   * preferCurrentQuoteMark {boolean} - if true, prefer the source quote mark
     *     over the quoteMark option value.
     *   * smart {boolean} - if true, will select a quote mark based on the value
     *     and the other options specified here. See the `smartQuoteMark()`
     *     method.
     **/


    var _proto = Attribute.prototype;

    _proto.getQuotedValue = function getQuotedValue(options) {
      if (options === void 0) {
        options = {};
      }

      var quoteMark = this._determineQuoteMark(options);

      var cssescopts = CSSESC_QUOTE_OPTIONS[quoteMark];
      var escaped = (0, _cssesc.default)(this._value, cssescopts);
      return escaped;
    };

    _proto._determineQuoteMark = function _determineQuoteMark(options) {
      return options.smart ? this.smartQuoteMark(options) : this.preferredQuoteMark(options);
    }
    /**
     * Set the unescaped value with the specified quotation options. The value
     * provided must not include any wrapping quote marks -- those quotes will
     * be interpreted as part of the value and escaped accordingly.
     */
    ;

    _proto.setValue = function setValue(value, options) {
      if (options === void 0) {
        options = {};
      }

      this._value = value;
      this._quoteMark = this._determineQuoteMark(options);

      this._syncRawValue();
    }
    /**
     * Intelligently select a quoteMark value based on the value's contents. If
     * the value is a legal CSS ident, it will not be quoted. Otherwise a quote
     * mark will be picked that minimizes the number of escapes.
     *
     * If there's no clear winner, the quote mark from these options is used,
     * then the source quote mark (this is inverted if `preferCurrentQuoteMark` is
     * true). If the quoteMark is unspecified, a double quote is used.
     *
     * @param options This takes the quoteMark and preferCurrentQuoteMark options
     * from the quoteValue method.
     */
    ;

    _proto.smartQuoteMark = function smartQuoteMark(options) {
      var v = this.value;
      var numSingleQuotes = v.replace(/[^']/g, '').length;
      var numDoubleQuotes = v.replace(/[^"]/g, '').length;

      if (numSingleQuotes + numDoubleQuotes === 0) {
        var escaped = (0, _cssesc.default)(v, {
          isIdentifier: true
        });

        if (escaped === v) {
          return Attribute.NO_QUOTE;
        } else {
          var pref = this.preferredQuoteMark(options);

          if (pref === Attribute.NO_QUOTE) {
            // pick a quote mark that isn't none and see if it's smaller
            var quote = this.quoteMark || options.quoteMark || Attribute.DOUBLE_QUOTE;
            var opts = CSSESC_QUOTE_OPTIONS[quote];
            var quoteValue = (0, _cssesc.default)(v, opts);

            if (quoteValue.length < escaped.length) {
              return quote;
            }
          }

          return pref;
        }
      } else if (numDoubleQuotes === numSingleQuotes) {
        return this.preferredQuoteMark(options);
      } else if (numDoubleQuotes < numSingleQuotes) {
        return Attribute.DOUBLE_QUOTE;
      } else {
        return Attribute.SINGLE_QUOTE;
      }
    }
    /**
     * Selects the preferred quote mark based on the options and the current quote mark value.
     * If you want the quote mark to depend on the attribute value, call `smartQuoteMark(opts)`
     * instead.
     */
    ;

    _proto.preferredQuoteMark = function preferredQuoteMark(options) {
      var quoteMark = options.preferCurrentQuoteMark ? this.quoteMark : options.quoteMark;

      if (quoteMark === undefined) {
        quoteMark = options.preferCurrentQuoteMark ? options.quoteMark : this.quoteMark;
      }

      if (quoteMark === undefined) {
        quoteMark = Attribute.DOUBLE_QUOTE;
      }

      return quoteMark;
    };

    _proto._syncRawValue = function _syncRawValue() {
      var rawValue = (0, _cssesc.default)(this._value, CSSESC_QUOTE_OPTIONS[this.quoteMark]);

      if (rawValue === this._value) {
        if (this.raws) {
          delete this.raws.value;
        }
      } else {
        this.raws.value = rawValue;
      }
    };

    _proto._handleEscapes = function _handleEscapes(prop, value) {
      if (this._constructed) {
        var escaped = (0, _cssesc.default)(value, {
          isIdentifier: true
        });

        if (escaped !== value) {
          this.raws[prop] = escaped;
        } else {
          delete this.raws[prop];
        }
      }
    };

    _proto._spacesFor = function _spacesFor(name) {
      var attrSpaces = {
        before: '',
        after: ''
      };
      var spaces = this.spaces[name] || {};
      var rawSpaces = this.raws.spaces && this.raws.spaces[name] || {};
      return Object.assign(attrSpaces, spaces, rawSpaces);
    };

    _proto._stringFor = function _stringFor(name, spaceName, concat) {
      if (spaceName === void 0) {
        spaceName = name;
      }

      if (concat === void 0) {
        concat = defaultAttrConcat;
      }

      var attrSpaces = this._spacesFor(spaceName);

      return concat(this.stringifyProperty(name), attrSpaces);
    }
    /**
     * returns the offset of the attribute part specified relative to the
     * start of the node of the output string.
     *
     * * "ns" - alias for "namespace"
     * * "namespace" - the namespace if it exists.
     * * "attribute" - the attribute name
     * * "attributeNS" - the start of the attribute or its namespace
     * * "operator" - the match operator of the attribute
     * * "value" - The value (string or identifier)
     * * "insensitive" - the case insensitivity flag;
     * @param part One of the possible values inside an attribute.
     * @returns -1 if the name is invalid or the value doesn't exist in this attribute.
     */
    ;

    _proto.offsetOf = function offsetOf(name) {
      var count = 1;

      var attributeSpaces = this._spacesFor("attribute");

      count += attributeSpaces.before.length;

      if (name === "namespace" || name === "ns") {
        return this.namespace ? count : -1;
      }

      if (name === "attributeNS") {
        return count;
      }

      count += this.namespaceString.length;

      if (this.namespace) {
        count += 1;
      }

      if (name === "attribute") {
        return count;
      }

      count += this.stringifyProperty("attribute").length;
      count += attributeSpaces.after.length;

      var operatorSpaces = this._spacesFor("operator");

      count += operatorSpaces.before.length;
      var operator = this.stringifyProperty("operator");

      if (name === "operator") {
        return operator ? count : -1;
      }

      count += operator.length;
      count += operatorSpaces.after.length;

      var valueSpaces = this._spacesFor("value");

      count += valueSpaces.before.length;
      var value = this.stringifyProperty("value");

      if (name === "value") {
        return value ? count : -1;
      }

      count += value.length;
      count += valueSpaces.after.length;

      var insensitiveSpaces = this._spacesFor("insensitive");

      count += insensitiveSpaces.before.length;

      if (name === "insensitive") {
        return this.insensitive ? count : -1;
      }

      return -1;
    };

    _proto.toString = function toString() {
      var _this2 = this;

      var selector = [this.rawSpaceBefore, '['];
      selector.push(this._stringFor('qualifiedAttribute', 'attribute'));

      if (this.operator && (this.value || this.value === '')) {
        selector.push(this._stringFor('operator'));
        selector.push(this._stringFor('value'));
        selector.push(this._stringFor('insensitiveFlag', 'insensitive', function (attrValue, attrSpaces) {
          if (attrValue.length > 0 && !_this2.quoted && attrSpaces.before.length === 0 && !(_this2.spaces.value && _this2.spaces.value.after)) {
            attrSpaces.before = " ";
          }

          return defaultAttrConcat(attrValue, attrSpaces);
        }));
      }

      selector.push(']');
      selector.push(this.rawSpaceAfter);
      return selector.join('');
    };

    _createClass(Attribute, [{
      key: "quoted",
      get: function get() {
        var qm = this.quoteMark;
        return qm === "'" || qm === '"';
      },
      set: function set(value) {
        warnOfDeprecatedQuotedAssignment();
      }
      /**
       * returns a single (`'`) or double (`"`) quote character if the value is quoted.
       * returns `null` if the value is not quoted.
       * returns `undefined` if the quotation state is unknown (this can happen when
       * the attribute is constructed without specifying a quote mark.)
       */

    }, {
      key: "quoteMark",
      get: function get() {
        return this._quoteMark;
      }
      /**
       * Set the quote mark to be used by this attribute's value.
       * If the quote mark changes, the raw (escaped) value at `attr.raws.value` of the attribute
       * value is updated accordingly.
       *
       * @param {"'" | '"' | null} quoteMark The quote mark or `null` if the value should be unquoted.
       */
      ,
      set: function set(quoteMark) {
        if (!this._constructed) {
          this._quoteMark = quoteMark;
          return;
        }

        if (this._quoteMark !== quoteMark) {
          this._quoteMark = quoteMark;

          this._syncRawValue();
        }
      }
    }, {
      key: "qualifiedAttribute",
      get: function get() {
        return this.qualifiedName(this.raws.attribute || this.attribute);
      }
    }, {
      key: "insensitiveFlag",
      get: function get() {
        return this.insensitive ? 'i' : '';
      }
    }, {
      key: "value",
      get: function get() {
        return this._value;
      }
      /**
       * Before 3.0, the value had to be set to an escaped value including any wrapped
       * quote marks. In 3.0, the semantics of `Attribute.value` changed so that the value
       * is unescaped during parsing and any quote marks are removed.
       *
       * Because the ambiguity of this semantic change, if you set `attr.value = newValue`,
       * a deprecation warning is raised when the new value contains any characters that would
       * require escaping (including if it contains wrapped quotes).
       *
       * Instead, you should call `attr.setValue(newValue, opts)` and pass options that describe
       * how the new value is quoted.
       */
      ,
      set: function set(v) {
        if (this._constructed) {
          var _unescapeValue2 = unescapeValue(v),
              deprecatedUsage = _unescapeValue2.deprecatedUsage,
              unescaped = _unescapeValue2.unescaped,
              quoteMark = _unescapeValue2.quoteMark;

          if (deprecatedUsage) {
            warnOfDeprecatedValueAssignment();
          }

          if (unescaped === this._value && quoteMark === this._quoteMark) {
            return;
          }

          this._value = unescaped;
          this._quoteMark = quoteMark;

          this._syncRawValue();
        } else {
          this._value = v;
        }
      }
    }, {
      key: "attribute",
      get: function get() {
        return this._attribute;
      },
      set: function set(name) {
        this._handleEscapes("attribute", name);

        this._attribute = name;
      }
    }]);

    return Attribute;
  }(_namespace.default);

  exports.default = Attribute;
  Attribute.NO_QUOTE = null;
  Attribute.SINGLE_QUOTE = "'";
  Attribute.DOUBLE_QUOTE = '"';
  var CSSESC_QUOTE_OPTIONS = (_CSSESC_QUOTE_OPTIONS = {
    "'": {
      quotes: 'single',
      wrap: true
    },
    '"': {
      quotes: 'double',
      wrap: true
    }
  }, _CSSESC_QUOTE_OPTIONS[null] = {
    isIdentifier: true
  }, _CSSESC_QUOTE_OPTIONS);

  function defaultAttrConcat(attrValue, attrSpaces) {
    return "" + attrSpaces.before + attrValue + attrSpaces.after;
  }
  });

  var universal = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _namespace = _interopRequireDefault(namespace);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Universal =
  /*#__PURE__*/
  function (_Namespace) {
    _inheritsLoose(Universal, _Namespace);

    function Universal(opts) {
      var _this;

      _this = _Namespace.call(this, opts) || this;
      _this.type = types.UNIVERSAL;
      _this.value = '*';
      return _this;
    }

    return Universal;
  }(_namespace.default);

  exports.default = Universal;
  module.exports = exports.default;
  });

  var combinator = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _node = _interopRequireDefault(node);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Combinator =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(Combinator, _Node);

    function Combinator(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;
      _this.type = types.COMBINATOR;
      return _this;
    }

    return Combinator;
  }(_node.default);

  exports.default = Combinator;
  module.exports = exports.default;
  });

  var nesting = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _node = _interopRequireDefault(node);



  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

  var Nesting =
  /*#__PURE__*/
  function (_Node) {
    _inheritsLoose(Nesting, _Node);

    function Nesting(opts) {
      var _this;

      _this = _Node.call(this, opts) || this;
      _this.type = types.NESTING;
      _this.value = '&';
      return _this;
    }

    return Nesting;
  }(_node.default);

  exports.default = Nesting;
  module.exports = exports.default;
  });

  var sortAscending_1 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = sortAscending;

  function sortAscending(list) {
    return list.sort(function (a, b) {
      return a - b;
    });
  }
  module.exports = exports.default;
  });

  var tokenTypes = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.combinator = exports.word = exports.comment = exports.str = exports.tab = exports.newline = exports.feed = exports.cr = exports.backslash = exports.bang = exports.slash = exports.doubleQuote = exports.singleQuote = exports.space = exports.greaterThan = exports.pipe = exports.equals = exports.plus = exports.caret = exports.tilde = exports.dollar = exports.closeSquare = exports.openSquare = exports.closeParenthesis = exports.openParenthesis = exports.semicolon = exports.colon = exports.comma = exports.at = exports.asterisk = exports.ampersand = void 0;
  var ampersand = 38; // `&`.charCodeAt(0);

  exports.ampersand = ampersand;
  var asterisk = 42; // `*`.charCodeAt(0);

  exports.asterisk = asterisk;
  var at = 64; // `@`.charCodeAt(0);

  exports.at = at;
  var comma = 44; // `,`.charCodeAt(0);

  exports.comma = comma;
  var colon = 58; // `:`.charCodeAt(0);

  exports.colon = colon;
  var semicolon = 59; // `;`.charCodeAt(0);

  exports.semicolon = semicolon;
  var openParenthesis = 40; // `(`.charCodeAt(0);

  exports.openParenthesis = openParenthesis;
  var closeParenthesis = 41; // `)`.charCodeAt(0);

  exports.closeParenthesis = closeParenthesis;
  var openSquare = 91; // `[`.charCodeAt(0);

  exports.openSquare = openSquare;
  var closeSquare = 93; // `]`.charCodeAt(0);

  exports.closeSquare = closeSquare;
  var dollar = 36; // `$`.charCodeAt(0);

  exports.dollar = dollar;
  var tilde = 126; // `~`.charCodeAt(0);

  exports.tilde = tilde;
  var caret = 94; // `^`.charCodeAt(0);

  exports.caret = caret;
  var plus = 43; // `+`.charCodeAt(0);

  exports.plus = plus;
  var equals = 61; // `=`.charCodeAt(0);

  exports.equals = equals;
  var pipe = 124; // `|`.charCodeAt(0);

  exports.pipe = pipe;
  var greaterThan = 62; // `>`.charCodeAt(0);

  exports.greaterThan = greaterThan;
  var space = 32; // ` `.charCodeAt(0);

  exports.space = space;
  var singleQuote = 39; // `'`.charCodeAt(0);

  exports.singleQuote = singleQuote;
  var doubleQuote = 34; // `"`.charCodeAt(0);

  exports.doubleQuote = doubleQuote;
  var slash = 47; // `/`.charCodeAt(0);

  exports.slash = slash;
  var bang = 33; // `!`.charCodeAt(0);

  exports.bang = bang;
  var backslash = 92; // '\\'.charCodeAt(0);

  exports.backslash = backslash;
  var cr = 13; // '\r'.charCodeAt(0);

  exports.cr = cr;
  var feed = 12; // '\f'.charCodeAt(0);

  exports.feed = feed;
  var newline = 10; // '\n'.charCodeAt(0);

  exports.newline = newline;
  var tab = 9; // '\t'.charCodeAt(0);
  // Expose aliases primarily for readability.

  exports.tab = tab;
  var str = singleQuote; // No good single character representation!

  exports.str = str;
  var comment = -1;
  exports.comment = comment;
  var word = -2;
  exports.word = word;
  var combinator = -3;
  exports.combinator = combinator;
  });

  var tokenize_1 = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = tokenize;
  exports.FIELDS = void 0;

  var t = _interopRequireWildcard(tokenTypes);

  var _unescapable, _wordDelimiters;

  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

  var unescapable = (_unescapable = {}, _unescapable[t.tab] = true, _unescapable[t.newline] = true, _unescapable[t.cr] = true, _unescapable[t.feed] = true, _unescapable);
  var wordDelimiters = (_wordDelimiters = {}, _wordDelimiters[t.space] = true, _wordDelimiters[t.tab] = true, _wordDelimiters[t.newline] = true, _wordDelimiters[t.cr] = true, _wordDelimiters[t.feed] = true, _wordDelimiters[t.ampersand] = true, _wordDelimiters[t.asterisk] = true, _wordDelimiters[t.bang] = true, _wordDelimiters[t.comma] = true, _wordDelimiters[t.colon] = true, _wordDelimiters[t.semicolon] = true, _wordDelimiters[t.openParenthesis] = true, _wordDelimiters[t.closeParenthesis] = true, _wordDelimiters[t.openSquare] = true, _wordDelimiters[t.closeSquare] = true, _wordDelimiters[t.singleQuote] = true, _wordDelimiters[t.doubleQuote] = true, _wordDelimiters[t.plus] = true, _wordDelimiters[t.pipe] = true, _wordDelimiters[t.tilde] = true, _wordDelimiters[t.greaterThan] = true, _wordDelimiters[t.equals] = true, _wordDelimiters[t.dollar] = true, _wordDelimiters[t.caret] = true, _wordDelimiters[t.slash] = true, _wordDelimiters);
  var hex = {};
  var hexChars = "0123456789abcdefABCDEF";

  for (var i = 0; i < hexChars.length; i++) {
    hex[hexChars.charCodeAt(i)] = true;
  }
  /**
   *  Returns the last index of the bar css word
   * @param {string} css The string in which the word begins
   * @param {number} start The index into the string where word's first letter occurs
   */


  function consumeWord(css, start) {
    var next = start;
    var code;

    do {
      code = css.charCodeAt(next);

      if (wordDelimiters[code]) {
        return next - 1;
      } else if (code === t.backslash) {
        next = consumeEscape(css, next) + 1;
      } else {
        // All other characters are part of the word
        next++;
      }
    } while (next < css.length);

    return next - 1;
  }
  /**
   *  Returns the last index of the escape sequence
   * @param {string} css The string in which the sequence begins
   * @param {number} start The index into the string where escape character (`\`) occurs.
   */


  function consumeEscape(css, start) {
    var next = start;
    var code = css.charCodeAt(next + 1);

    if (unescapable[code]) ; else if (hex[code]) {
      var hexDigits = 0; // consume up to 6 hex chars

      do {
        next++;
        hexDigits++;
        code = css.charCodeAt(next + 1);
      } while (hex[code] && hexDigits < 6); // if fewer than 6 hex chars, a trailing space ends the escape


      if (hexDigits < 6 && code === t.space) {
        next++;
      }
    } else {
      // the next char is part of the current word
      next++;
    }

    return next;
  }

  var FIELDS = {
    TYPE: 0,
    START_LINE: 1,
    START_COL: 2,
    END_LINE: 3,
    END_COL: 4,
    START_POS: 5,
    END_POS: 6
  };
  exports.FIELDS = FIELDS;

  function tokenize(input) {
    var tokens = [];
    var css = input.css.valueOf();
    var _css = css,
        length = _css.length;
    var offset = -1;
    var line = 1;
    var start = 0;
    var end = 0;
    var code, content, endColumn, endLine, escaped, escapePos, last, lines, next, nextLine, nextOffset, quote, tokenType;

    function unclosed(what, fix) {
      if (input.safe) {
        // fyi: this is never set to true.
        css += fix;
        next = css.length - 1;
      } else {
        throw input.error('Unclosed ' + what, line, start - offset, start);
      }
    }

    while (start < length) {
      code = css.charCodeAt(start);

      if (code === t.newline) {
        offset = start;
        line += 1;
      }

      switch (code) {
        case t.space:
        case t.tab:
        case t.newline:
        case t.cr:
        case t.feed:
          next = start;

          do {
            next += 1;
            code = css.charCodeAt(next);

            if (code === t.newline) {
              offset = next;
              line += 1;
            }
          } while (code === t.space || code === t.newline || code === t.tab || code === t.cr || code === t.feed);

          tokenType = t.space;
          endLine = line;
          endColumn = next - offset - 1;
          end = next;
          break;

        case t.plus:
        case t.greaterThan:
        case t.tilde:
        case t.pipe:
          next = start;

          do {
            next += 1;
            code = css.charCodeAt(next);
          } while (code === t.plus || code === t.greaterThan || code === t.tilde || code === t.pipe);

          tokenType = t.combinator;
          endLine = line;
          endColumn = start - offset;
          end = next;
          break;
        // Consume these characters as single tokens.

        case t.asterisk:
        case t.ampersand:
        case t.bang:
        case t.comma:
        case t.equals:
        case t.dollar:
        case t.caret:
        case t.openSquare:
        case t.closeSquare:
        case t.colon:
        case t.semicolon:
        case t.openParenthesis:
        case t.closeParenthesis:
          next = start;
          tokenType = code;
          endLine = line;
          endColumn = start - offset;
          end = next + 1;
          break;

        case t.singleQuote:
        case t.doubleQuote:
          quote = code === t.singleQuote ? "'" : '"';
          next = start;

          do {
            escaped = false;
            next = css.indexOf(quote, next + 1);

            if (next === -1) {
              unclosed('quote', quote);
            }

            escapePos = next;

            while (css.charCodeAt(escapePos - 1) === t.backslash) {
              escapePos -= 1;
              escaped = !escaped;
            }
          } while (escaped);

          tokenType = t.str;
          endLine = line;
          endColumn = start - offset;
          end = next + 1;
          break;

        default:
          if (code === t.slash && css.charCodeAt(start + 1) === t.asterisk) {
            next = css.indexOf('*/', start + 2) + 1;

            if (next === 0) {
              unclosed('comment', '*/');
            }

            content = css.slice(start, next + 1);
            lines = content.split('\n');
            last = lines.length - 1;

            if (last > 0) {
              nextLine = line + last;
              nextOffset = next - lines[last].length;
            } else {
              nextLine = line;
              nextOffset = offset;
            }

            tokenType = t.comment;
            line = nextLine;
            endLine = nextLine;
            endColumn = next - nextOffset;
          } else if (code === t.slash) {
            next = start;
            tokenType = code;
            endLine = line;
            endColumn = start - offset;
            end = next + 1;
          } else {
            next = consumeWord(css, start);
            tokenType = t.word;
            endLine = line;
            endColumn = next - offset;
          }

          end = next + 1;
          break;
      } // Ensure that the token structure remains consistent


      tokens.push([tokenType, // [0] Token type
      line, // [1] Starting line
      start - offset, // [2] Starting column
      endLine, // [3] Ending line
      endColumn, // [4] Ending column
      start, // [5] Start position / Source index
      end]); // Reset offset for the next token

      if (nextOffset) {
        offset = nextOffset;
        nextOffset = null;
      }

      start = end;
    }

    return tokens;
  }
  });

  var parser = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _indexesOf = _interopRequireDefault(indexesOf);

  var _uniq = _interopRequireDefault(uniq);

  var _root = _interopRequireDefault(root);

  var _selector = _interopRequireDefault(selector);

  var _className = _interopRequireDefault(className);

  var _comment = _interopRequireDefault(comment);

  var _id = _interopRequireDefault(id);

  var _tag = _interopRequireDefault(tag);

  var _string = _interopRequireDefault(string);

  var _pseudo = _interopRequireDefault(pseudo);

  var _attribute = _interopRequireWildcard(attribute);

  var _universal = _interopRequireDefault(universal);

  var _combinator = _interopRequireDefault(combinator);

  var _nesting = _interopRequireDefault(nesting);

  var _sortAscending = _interopRequireDefault(sortAscending_1);

  var _tokenize = _interopRequireWildcard(tokenize_1);

  var tokens = _interopRequireWildcard(tokenTypes);

  var types$1 = _interopRequireWildcard(types);



  var _WHITESPACE_TOKENS, _Object$assign;

  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  var WHITESPACE_TOKENS = (_WHITESPACE_TOKENS = {}, _WHITESPACE_TOKENS[tokens.space] = true, _WHITESPACE_TOKENS[tokens.cr] = true, _WHITESPACE_TOKENS[tokens.feed] = true, _WHITESPACE_TOKENS[tokens.newline] = true, _WHITESPACE_TOKENS[tokens.tab] = true, _WHITESPACE_TOKENS);
  var WHITESPACE_EQUIV_TOKENS = Object.assign({}, WHITESPACE_TOKENS, (_Object$assign = {}, _Object$assign[tokens.comment] = true, _Object$assign));

  function tokenStart(token) {
    return {
      line: token[_tokenize.FIELDS.START_LINE],
      column: token[_tokenize.FIELDS.START_COL]
    };
  }

  function tokenEnd(token) {
    return {
      line: token[_tokenize.FIELDS.END_LINE],
      column: token[_tokenize.FIELDS.END_COL]
    };
  }

  function getSource(startLine, startColumn, endLine, endColumn) {
    return {
      start: {
        line: startLine,
        column: startColumn
      },
      end: {
        line: endLine,
        column: endColumn
      }
    };
  }

  function getTokenSource(token) {
    return getSource(token[_tokenize.FIELDS.START_LINE], token[_tokenize.FIELDS.START_COL], token[_tokenize.FIELDS.END_LINE], token[_tokenize.FIELDS.END_COL]);
  }

  function getTokenSourceSpan(startToken, endToken) {
    if (!startToken) {
      return undefined;
    }

    return getSource(startToken[_tokenize.FIELDS.START_LINE], startToken[_tokenize.FIELDS.START_COL], endToken[_tokenize.FIELDS.END_LINE], endToken[_tokenize.FIELDS.END_COL]);
  }

  function unescapeProp(node, prop) {
    var value = node[prop];

    if (typeof value !== "string") {
      return;
    }

    if (value.indexOf("\\") !== -1) {
      (0, util$3.ensureObject)(node, 'raws');
      node[prop] = (0, util$3.unesc)(value);

      if (node.raws[prop] === undefined) {
        node.raws[prop] = value;
      }
    }

    return node;
  }

  var Parser =
  /*#__PURE__*/
  function () {
    function Parser(rule, options) {
      if (options === void 0) {
        options = {};
      }

      this.rule = rule;
      this.options = Object.assign({
        lossy: false,
        safe: false
      }, options);
      this.position = 0;
      this.css = typeof this.rule === 'string' ? this.rule : this.rule.selector;
      this.tokens = (0, _tokenize.default)({
        css: this.css,
        error: this._errorGenerator(),
        safe: this.options.safe
      });
      var rootSource = getTokenSourceSpan(this.tokens[0], this.tokens[this.tokens.length - 1]);
      this.root = new _root.default({
        source: rootSource
      });
      this.root.errorGenerator = this._errorGenerator();
      var selector = new _selector.default({
        source: {
          start: {
            line: 1,
            column: 1
          }
        }
      });
      this.root.append(selector);
      this.current = selector;
      this.loop();
    }

    var _proto = Parser.prototype;

    _proto._errorGenerator = function _errorGenerator() {
      var _this = this;

      return function (message, errorOptions) {
        if (typeof _this.rule === 'string') {
          return new Error(message);
        }

        return _this.rule.error(message, errorOptions);
      };
    };

    _proto.attribute = function attribute() {
      var attr = [];
      var startingToken = this.currToken;
      this.position++;

      while (this.position < this.tokens.length && this.currToken[_tokenize.FIELDS.TYPE] !== tokens.closeSquare) {
        attr.push(this.currToken);
        this.position++;
      }

      if (this.currToken[_tokenize.FIELDS.TYPE] !== tokens.closeSquare) {
        return this.expected('closing square bracket', this.currToken[_tokenize.FIELDS.START_POS]);
      }

      var len = attr.length;
      var node = {
        source: getSource(startingToken[1], startingToken[2], this.currToken[3], this.currToken[4]),
        sourceIndex: startingToken[_tokenize.FIELDS.START_POS]
      };

      if (len === 1 && !~[tokens.word].indexOf(attr[0][_tokenize.FIELDS.TYPE])) {
        return this.expected('attribute', attr[0][_tokenize.FIELDS.START_POS]);
      }

      var pos = 0;
      var spaceBefore = '';
      var commentBefore = '';
      var lastAdded = null;
      var spaceAfterMeaningfulToken = false;

      while (pos < len) {
        var token = attr[pos];
        var content = this.content(token);
        var next = attr[pos + 1];

        switch (token[_tokenize.FIELDS.TYPE]) {
          case tokens.space:
            // if (
            //     len === 1 ||
            //     pos === 0 && this.content(next) === '|'
            // ) {
            //     return this.expected('attribute', token[TOKEN.START_POS], content);
            // }
            spaceAfterMeaningfulToken = true;

            if (this.options.lossy) {
              break;
            }

            if (lastAdded) {
              (0, util$3.ensureObject)(node, 'spaces', lastAdded);
              var prevContent = node.spaces[lastAdded].after || '';
              node.spaces[lastAdded].after = prevContent + content;
              var existingComment = (0, util$3.getProp)(node, 'raws', 'spaces', lastAdded, 'after') || null;

              if (existingComment) {
                node.raws.spaces[lastAdded].after = existingComment + content;
              }
            } else {
              spaceBefore = spaceBefore + content;
              commentBefore = commentBefore + content;
            }

            break;

          case tokens.asterisk:
            if (next[_tokenize.FIELDS.TYPE] === tokens.equals) {
              node.operator = content;
              lastAdded = 'operator';
            } else if ((!node.namespace || lastAdded === "namespace" && !spaceAfterMeaningfulToken) && next) {
              if (spaceBefore) {
                (0, util$3.ensureObject)(node, 'spaces', 'attribute');
                node.spaces.attribute.before = spaceBefore;
                spaceBefore = '';
              }

              if (commentBefore) {
                (0, util$3.ensureObject)(node, 'raws', 'spaces', 'attribute');
                node.raws.spaces.attribute.before = spaceBefore;
                commentBefore = '';
              }

              node.namespace = (node.namespace || "") + content;
              var rawValue = (0, util$3.getProp)(node, 'raws', 'namespace') || null;

              if (rawValue) {
                node.raws.namespace += content;
              }

              lastAdded = 'namespace';
            }

            spaceAfterMeaningfulToken = false;
            break;

          case tokens.dollar:
            if (lastAdded === "value") {
              var oldRawValue = (0, util$3.getProp)(node, 'raws', 'value');
              node.value += "$";

              if (oldRawValue) {
                node.raws.value = oldRawValue + "$";
              }

              break;
            }

          // Falls through

          case tokens.caret:
            if (next[_tokenize.FIELDS.TYPE] === tokens.equals) {
              node.operator = content;
              lastAdded = 'operator';
            }

            spaceAfterMeaningfulToken = false;
            break;

          case tokens.combinator:
            if (content === '~' && next[_tokenize.FIELDS.TYPE] === tokens.equals) {
              node.operator = content;
              lastAdded = 'operator';
            }

            if (content !== '|') {
              spaceAfterMeaningfulToken = false;
              break;
            }

            if (next[_tokenize.FIELDS.TYPE] === tokens.equals) {
              node.operator = content;
              lastAdded = 'operator';
            } else if (!node.namespace && !node.attribute) {
              node.namespace = true;
            }

            spaceAfterMeaningfulToken = false;
            break;

          case tokens.word:
            if (next && this.content(next) === '|' && attr[pos + 2] && attr[pos + 2][_tokenize.FIELDS.TYPE] !== tokens.equals && // this look-ahead probably fails with comment nodes involved.
            !node.operator && !node.namespace) {
              node.namespace = content;
              lastAdded = 'namespace';
            } else if (!node.attribute || lastAdded === "attribute" && !spaceAfterMeaningfulToken) {
              if (spaceBefore) {
                (0, util$3.ensureObject)(node, 'spaces', 'attribute');
                node.spaces.attribute.before = spaceBefore;
                spaceBefore = '';
              }

              if (commentBefore) {
                (0, util$3.ensureObject)(node, 'raws', 'spaces', 'attribute');
                node.raws.spaces.attribute.before = commentBefore;
                commentBefore = '';
              }

              node.attribute = (node.attribute || "") + content;

              var _rawValue = (0, util$3.getProp)(node, 'raws', 'attribute') || null;

              if (_rawValue) {
                node.raws.attribute += content;
              }

              lastAdded = 'attribute';
            } else if (!node.value && node.value !== "" || lastAdded === "value" && !spaceAfterMeaningfulToken) {
              var _unescaped = (0, util$3.unesc)(content);

              var _oldRawValue = (0, util$3.getProp)(node, 'raws', 'value') || '';

              var oldValue = node.value || '';
              node.value = oldValue + _unescaped;
              node.quoteMark = null;

              if (_unescaped !== content || _oldRawValue) {
                (0, util$3.ensureObject)(node, 'raws');
                node.raws.value = (_oldRawValue || oldValue) + content;
              }

              lastAdded = 'value';
            } else {
              var insensitive = content === 'i' || content === "I";

              if ((node.value || node.value === '') && (node.quoteMark || spaceAfterMeaningfulToken)) {
                node.insensitive = insensitive;

                if (!insensitive || content === "I") {
                  (0, util$3.ensureObject)(node, 'raws');
                  node.raws.insensitiveFlag = content;
                }

                lastAdded = 'insensitive';

                if (spaceBefore) {
                  (0, util$3.ensureObject)(node, 'spaces', 'insensitive');
                  node.spaces.insensitive.before = spaceBefore;
                  spaceBefore = '';
                }

                if (commentBefore) {
                  (0, util$3.ensureObject)(node, 'raws', 'spaces', 'insensitive');
                  node.raws.spaces.insensitive.before = commentBefore;
                  commentBefore = '';
                }
              } else if (node.value || node.value === '') {
                lastAdded = 'value';
                node.value += content;

                if (node.raws.value) {
                  node.raws.value += content;
                }
              }
            }

            spaceAfterMeaningfulToken = false;
            break;

          case tokens.str:
            if (!node.attribute || !node.operator) {
              return this.error("Expected an attribute followed by an operator preceding the string.", {
                index: token[_tokenize.FIELDS.START_POS]
              });
            }

            var _unescapeValue = (0, _attribute.unescapeValue)(content),
                unescaped = _unescapeValue.unescaped,
                quoteMark = _unescapeValue.quoteMark;

            node.value = unescaped;
            node.quoteMark = quoteMark;
            lastAdded = 'value';
            (0, util$3.ensureObject)(node, 'raws');
            node.raws.value = content;
            spaceAfterMeaningfulToken = false;
            break;

          case tokens.equals:
            if (!node.attribute) {
              return this.expected('attribute', token[_tokenize.FIELDS.START_POS], content);
            }

            if (node.value) {
              return this.error('Unexpected "=" found; an operator was already defined.', {
                index: token[_tokenize.FIELDS.START_POS]
              });
            }

            node.operator = node.operator ? node.operator + content : content;
            lastAdded = 'operator';
            spaceAfterMeaningfulToken = false;
            break;

          case tokens.comment:
            if (lastAdded) {
              if (spaceAfterMeaningfulToken || next && next[_tokenize.FIELDS.TYPE] === tokens.space || lastAdded === 'insensitive') {
                var lastComment = (0, util$3.getProp)(node, 'spaces', lastAdded, 'after') || '';
                var rawLastComment = (0, util$3.getProp)(node, 'raws', 'spaces', lastAdded, 'after') || lastComment;
                (0, util$3.ensureObject)(node, 'raws', 'spaces', lastAdded);
                node.raws.spaces[lastAdded].after = rawLastComment + content;
              } else {
                var lastValue = node[lastAdded] || '';
                var rawLastValue = (0, util$3.getProp)(node, 'raws', lastAdded) || lastValue;
                (0, util$3.ensureObject)(node, 'raws');
                node.raws[lastAdded] = rawLastValue + content;
              }
            } else {
              commentBefore = commentBefore + content;
            }

            break;

          default:
            return this.error("Unexpected \"" + content + "\" found.", {
              index: token[_tokenize.FIELDS.START_POS]
            });
        }

        pos++;
      }

      unescapeProp(node, "attribute");
      unescapeProp(node, "namespace");
      this.newNode(new _attribute.default(node));
      this.position++;
    }
    /**
     * return a node containing meaningless garbage up to (but not including) the specified token position.
     * if the token position is negative, all remaining tokens are consumed.
     *
     * This returns an array containing a single string node if all whitespace,
     * otherwise an array of comment nodes with space before and after.
     *
     * These tokens are not added to the current selector, the caller can add them or use them to amend
     * a previous node's space metadata.
     *
     * In lossy mode, this returns only comments.
     */
    ;

    _proto.parseWhitespaceEquivalentTokens = function parseWhitespaceEquivalentTokens(stopPosition) {
      if (stopPosition < 0) {
        stopPosition = this.tokens.length;
      }

      var startPosition = this.position;
      var nodes = [];
      var space = "";
      var lastComment = undefined;

      do {
        if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) {
          if (!this.options.lossy) {
            space += this.content();
          }
        } else if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.comment) {
          var spaces = {};

          if (space) {
            spaces.before = space;
            space = "";
          }

          lastComment = new _comment.default({
            value: this.content(),
            source: getTokenSource(this.currToken),
            sourceIndex: this.currToken[_tokenize.FIELDS.START_POS],
            spaces: spaces
          });
          nodes.push(lastComment);
        }
      } while (++this.position < stopPosition);

      if (space) {
        if (lastComment) {
          lastComment.spaces.after = space;
        } else if (!this.options.lossy) {
          var firstToken = this.tokens[startPosition];
          var lastToken = this.tokens[this.position - 1];
          nodes.push(new _string.default({
            value: '',
            source: getSource(firstToken[_tokenize.FIELDS.START_LINE], firstToken[_tokenize.FIELDS.START_COL], lastToken[_tokenize.FIELDS.END_LINE], lastToken[_tokenize.FIELDS.END_COL]),
            sourceIndex: firstToken[_tokenize.FIELDS.START_POS],
            spaces: {
              before: space,
              after: ''
            }
          }));
        }
      }

      return nodes;
    }
    /**
     * 
     * @param {*} nodes 
     */
    ;

    _proto.convertWhitespaceNodesToSpace = function convertWhitespaceNodesToSpace(nodes, requiredSpace) {
      var _this2 = this;

      if (requiredSpace === void 0) {
        requiredSpace = false;
      }

      var space = "";
      var rawSpace = "";
      nodes.forEach(function (n) {
        var spaceBefore = _this2.lossySpace(n.spaces.before, requiredSpace);

        var rawSpaceBefore = _this2.lossySpace(n.rawSpaceBefore, requiredSpace);

        space += spaceBefore + _this2.lossySpace(n.spaces.after, requiredSpace && spaceBefore.length === 0);
        rawSpace += spaceBefore + n.value + _this2.lossySpace(n.rawSpaceAfter, requiredSpace && rawSpaceBefore.length === 0);
      });

      if (rawSpace === space) {
        rawSpace = undefined;
      }

      var result = {
        space: space,
        rawSpace: rawSpace
      };
      return result;
    };

    _proto.isNamedCombinator = function isNamedCombinator(position) {
      if (position === void 0) {
        position = this.position;
      }

      return this.tokens[position + 0] && this.tokens[position + 0][_tokenize.FIELDS.TYPE] === tokens.slash && this.tokens[position + 1] && this.tokens[position + 1][_tokenize.FIELDS.TYPE] === tokens.word && this.tokens[position + 2] && this.tokens[position + 2][_tokenize.FIELDS.TYPE] === tokens.slash;
    };

    _proto.namedCombinator = function namedCombinator() {
      if (this.isNamedCombinator()) {
        var nameRaw = this.content(this.tokens[this.position + 1]);
        var name = (0, util$3.unesc)(nameRaw).toLowerCase();
        var raws = {};

        if (name !== nameRaw) {
          raws.value = "/" + nameRaw + "/";
        }

        var node = new _combinator.default({
          value: "/" + name + "/",
          source: getSource(this.currToken[_tokenize.FIELDS.START_LINE], this.currToken[_tokenize.FIELDS.START_COL], this.tokens[this.position + 2][_tokenize.FIELDS.END_LINE], this.tokens[this.position + 2][_tokenize.FIELDS.END_COL]),
          sourceIndex: this.currToken[_tokenize.FIELDS.START_POS],
          raws: raws
        });
        this.position = this.position + 3;
        return node;
      } else {
        this.unexpected();
      }
    };

    _proto.combinator = function combinator() {
      var _this3 = this;

      if (this.content() === '|') {
        return this.namespace();
      } // We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector.


      var nextSigTokenPos = this.locateNextMeaningfulToken(this.position);

      if (nextSigTokenPos < 0 || this.tokens[nextSigTokenPos][_tokenize.FIELDS.TYPE] === tokens.comma) {
        var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos);

        if (nodes.length > 0) {
          var last = this.current.last;

          if (last) {
            var _this$convertWhitespa = this.convertWhitespaceNodesToSpace(nodes),
                space = _this$convertWhitespa.space,
                rawSpace = _this$convertWhitespa.rawSpace;

            if (rawSpace !== undefined) {
              last.rawSpaceAfter += rawSpace;
            }

            last.spaces.after += space;
          } else {
            nodes.forEach(function (n) {
              return _this3.newNode(n);
            });
          }
        }

        return;
      }

      var firstToken = this.currToken;
      var spaceOrDescendantSelectorNodes = undefined;

      if (nextSigTokenPos > this.position) {
        spaceOrDescendantSelectorNodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos);
      }

      var node;

      if (this.isNamedCombinator()) {
        node = this.namedCombinator();
      } else if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.combinator) {
        node = new _combinator.default({
          value: this.content(),
          source: getTokenSource(this.currToken),
          sourceIndex: this.currToken[_tokenize.FIELDS.START_POS]
        });
        this.position++;
      } else if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) ; else if (!spaceOrDescendantSelectorNodes) {
        this.unexpected();
      }

      if (node) {
        if (spaceOrDescendantSelectorNodes) {
          var _this$convertWhitespa2 = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes),
              _space = _this$convertWhitespa2.space,
              _rawSpace = _this$convertWhitespa2.rawSpace;

          node.spaces.before = _space;
          node.rawSpaceBefore = _rawSpace;
        }
      } else {
        // descendant combinator
        var _this$convertWhitespa3 = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes, true),
            _space2 = _this$convertWhitespa3.space,
            _rawSpace2 = _this$convertWhitespa3.rawSpace;

        if (!_rawSpace2) {
          _rawSpace2 = _space2;
        }

        var spaces = {};
        var raws = {
          spaces: {}
        };

        if (_space2.endsWith(' ') && _rawSpace2.endsWith(' ')) {
          spaces.before = _space2.slice(0, _space2.length - 1);
          raws.spaces.before = _rawSpace2.slice(0, _rawSpace2.length - 1);
        } else if (_space2.startsWith(' ') && _rawSpace2.startsWith(' ')) {
          spaces.after = _space2.slice(1);
          raws.spaces.after = _rawSpace2.slice(1);
        } else {
          raws.value = _rawSpace2;
        }

        node = new _combinator.default({
          value: ' ',
          source: getTokenSourceSpan(firstToken, this.tokens[this.position - 1]),
          sourceIndex: firstToken[_tokenize.FIELDS.START_POS],
          spaces: spaces,
          raws: raws
        });
      }

      if (this.currToken && this.currToken[_tokenize.FIELDS.TYPE] === tokens.space) {
        node.spaces.after = this.optionalSpace(this.content());
        this.position++;
      }

      return this.newNode(node);
    };

    _proto.comma = function comma() {
      if (this.position === this.tokens.length - 1) {
        this.root.trailingComma = true;
        this.position++;
        return;
      }

      this.current._inferEndPosition();

      var selector = new _selector.default({
        source: {
          start: tokenStart(this.tokens[this.position + 1])
        }
      });
      this.current.parent.append(selector);
      this.current = selector;
      this.position++;
    };

    _proto.comment = function comment() {
      var current = this.currToken;
      this.newNode(new _comment.default({
        value: this.content(),
        source: getTokenSource(current),
        sourceIndex: current[_tokenize.FIELDS.START_POS]
      }));
      this.position++;
    };

    _proto.error = function error(message, opts) {
      throw this.root.error(message, opts);
    };

    _proto.missingBackslash = function missingBackslash() {
      return this.error('Expected a backslash preceding the semicolon.', {
        index: this.currToken[_tokenize.FIELDS.START_POS]
      });
    };

    _proto.missingParenthesis = function missingParenthesis() {
      return this.expected('opening parenthesis', this.currToken[_tokenize.FIELDS.START_POS]);
    };

    _proto.missingSquareBracket = function missingSquareBracket() {
      return this.expected('opening square bracket', this.currToken[_tokenize.FIELDS.START_POS]);
    };

    _proto.unexpected = function unexpected() {
      return this.error("Unexpected '" + this.content() + "'. Escaping special characters with \\ may help.", this.currToken[_tokenize.FIELDS.START_POS]);
    };

    _proto.namespace = function namespace() {
      var before = this.prevToken && this.content(this.prevToken) || true;

      if (this.nextToken[_tokenize.FIELDS.TYPE] === tokens.word) {
        this.position++;
        return this.word(before);
      } else if (this.nextToken[_tokenize.FIELDS.TYPE] === tokens.asterisk) {
        this.position++;
        return this.universal(before);
      }
    };

    _proto.nesting = function nesting() {
      if (this.nextToken) {
        var nextContent = this.content(this.nextToken);

        if (nextContent === "|") {
          this.position++;
          return;
        }
      }

      var current = this.currToken;
      this.newNode(new _nesting.default({
        value: this.content(),
        source: getTokenSource(current),
        sourceIndex: current[_tokenize.FIELDS.START_POS]
      }));
      this.position++;
    };

    _proto.parentheses = function parentheses() {
      var last = this.current.last;
      var unbalanced = 1;
      this.position++;

      if (last && last.type === types$1.PSEUDO) {
        var selector = new _selector.default({
          source: {
            start: tokenStart(this.tokens[this.position - 1])
          }
        });
        var cache = this.current;
        last.append(selector);
        this.current = selector;

        while (this.position < this.tokens.length && unbalanced) {
          if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) {
            unbalanced++;
          }

          if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) {
            unbalanced--;
          }

          if (unbalanced) {
            this.parse();
          } else {
            this.current.source.end = tokenEnd(this.currToken);
            this.current.parent.source.end = tokenEnd(this.currToken);
            this.position++;
          }
        }

        this.current = cache;
      } else {
        // I think this case should be an error. It's used to implement a basic parse of media queries
        // but I don't think it's a good idea.
        var parenStart = this.currToken;
        var parenValue = "(";
        var parenEnd;

        while (this.position < this.tokens.length && unbalanced) {
          if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) {
            unbalanced++;
          }

          if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) {
            unbalanced--;
          }

          parenEnd = this.currToken;
          parenValue += this.parseParenthesisToken(this.currToken);
          this.position++;
        }

        if (last) {
          last.appendToPropertyAndEscape("value", parenValue, parenValue);
        } else {
          this.newNode(new _string.default({
            value: parenValue,
            source: getSource(parenStart[_tokenize.FIELDS.START_LINE], parenStart[_tokenize.FIELDS.START_COL], parenEnd[_tokenize.FIELDS.END_LINE], parenEnd[_tokenize.FIELDS.END_COL]),
            sourceIndex: parenStart[_tokenize.FIELDS.START_POS]
          }));
        }
      }

      if (unbalanced) {
        return this.expected('closing parenthesis', this.currToken[_tokenize.FIELDS.START_POS]);
      }
    };

    _proto.pseudo = function pseudo() {
      var _this4 = this;

      var pseudoStr = '';
      var startingToken = this.currToken;

      while (this.currToken && this.currToken[_tokenize.FIELDS.TYPE] === tokens.colon) {
        pseudoStr += this.content();
        this.position++;
      }

      if (!this.currToken) {
        return this.expected(['pseudo-class', 'pseudo-element'], this.position - 1);
      }

      if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.word) {
        this.splitWord(false, function (first, length) {
          pseudoStr += first;

          _this4.newNode(new _pseudo.default({
            value: pseudoStr,
            source: getTokenSourceSpan(startingToken, _this4.currToken),
            sourceIndex: startingToken[_tokenize.FIELDS.START_POS]
          }));

          if (length > 1 && _this4.nextToken && _this4.nextToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) {
            _this4.error('Misplaced parenthesis.', {
              index: _this4.nextToken[_tokenize.FIELDS.START_POS]
            });
          }
        });
      } else {
        return this.expected(['pseudo-class', 'pseudo-element'], this.currToken[_tokenize.FIELDS.START_POS]);
      }
    };

    _proto.space = function space() {
      var content = this.content(); // Handle space before and after the selector

      if (this.position === 0 || this.prevToken[_tokenize.FIELDS.TYPE] === tokens.comma || this.prevToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) {
        this.spaces = this.optionalSpace(content);
        this.position++;
      } else if (this.position === this.tokens.length - 1 || this.nextToken[_tokenize.FIELDS.TYPE] === tokens.comma || this.nextToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) {
        this.current.last.spaces.after = this.optionalSpace(content);
        this.position++;
      } else {
        this.combinator();
      }
    };

    _proto.string = function string() {
      var current = this.currToken;
      this.newNode(new _string.default({
        value: this.content(),
        source: getTokenSource(current),
        sourceIndex: current[_tokenize.FIELDS.START_POS]
      }));
      this.position++;
    };

    _proto.universal = function universal(namespace) {
      var nextToken = this.nextToken;

      if (nextToken && this.content(nextToken) === '|') {
        this.position++;
        return this.namespace();
      }

      var current = this.currToken;
      this.newNode(new _universal.default({
        value: this.content(),
        source: getTokenSource(current),
        sourceIndex: current[_tokenize.FIELDS.START_POS]
      }), namespace);
      this.position++;
    };

    _proto.splitWord = function splitWord(namespace, firstCallback) {
      var _this5 = this;

      var nextToken = this.nextToken;
      var word = this.content();

      while (nextToken && ~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[_tokenize.FIELDS.TYPE])) {
        this.position++;
        var current = this.content();
        word += current;

        if (current.lastIndexOf('\\') === current.length - 1) {
          var next = this.nextToken;

          if (next && next[_tokenize.FIELDS.TYPE] === tokens.space) {
            word += this.requiredSpace(this.content(next));
            this.position++;
          }
        }

        nextToken = this.nextToken;
      }

      var hasClass = (0, _indexesOf.default)(word, '.').filter(function (i) {
        return word[i - 1] !== '\\';
      });
      var hasId = (0, _indexesOf.default)(word, '#').filter(function (i) {
        return word[i - 1] !== '\\';
      }); // Eliminate Sass interpolations from the list of id indexes

      var interpolations = (0, _indexesOf.default)(word, '#{');

      if (interpolations.length) {
        hasId = hasId.filter(function (hashIndex) {
          return !~interpolations.indexOf(hashIndex);
        });
      }

      var indices = (0, _sortAscending.default)((0, _uniq.default)([0].concat(hasClass, hasId)));
      indices.forEach(function (ind, i) {
        var index = indices[i + 1] || word.length;
        var value = word.slice(ind, index);

        if (i === 0 && firstCallback) {
          return firstCallback.call(_this5, value, indices.length);
        }

        var node;
        var current = _this5.currToken;
        var sourceIndex = current[_tokenize.FIELDS.START_POS] + indices[i];
        var source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1));

        if (~hasClass.indexOf(ind)) {
          var classNameOpts = {
            value: value.slice(1),
            source: source,
            sourceIndex: sourceIndex
          };
          node = new _className.default(unescapeProp(classNameOpts, "value"));
        } else if (~hasId.indexOf(ind)) {
          var idOpts = {
            value: value.slice(1),
            source: source,
            sourceIndex: sourceIndex
          };
          node = new _id.default(unescapeProp(idOpts, "value"));
        } else {
          var tagOpts = {
            value: value,
            source: source,
            sourceIndex: sourceIndex
          };
          unescapeProp(tagOpts, "value");
          node = new _tag.default(tagOpts);
        }

        _this5.newNode(node, namespace); // Ensure that the namespace is used only once


        namespace = null;
      });
      this.position++;
    };

    _proto.word = function word(namespace) {
      var nextToken = this.nextToken;

      if (nextToken && this.content(nextToken) === '|') {
        this.position++;
        return this.namespace();
      }

      return this.splitWord(namespace);
    };

    _proto.loop = function loop() {
      while (this.position < this.tokens.length) {
        this.parse(true);
      }

      this.current._inferEndPosition();

      return this.root;
    };

    _proto.parse = function parse(throwOnParenthesis) {
      switch (this.currToken[_tokenize.FIELDS.TYPE]) {
        case tokens.space:
          this.space();
          break;

        case tokens.comment:
          this.comment();
          break;

        case tokens.openParenthesis:
          this.parentheses();
          break;

        case tokens.closeParenthesis:
          if (throwOnParenthesis) {
            this.missingParenthesis();
          }

          break;

        case tokens.openSquare:
          this.attribute();
          break;

        case tokens.dollar:
        case tokens.caret:
        case tokens.equals:
        case tokens.word:
          this.word();
          break;

        case tokens.colon:
          this.pseudo();
          break;

        case tokens.comma:
          this.comma();
          break;

        case tokens.asterisk:
          this.universal();
          break;

        case tokens.ampersand:
          this.nesting();
          break;

        case tokens.slash:
        case tokens.combinator:
          this.combinator();
          break;

        case tokens.str:
          this.string();
          break;
        // These cases throw; no break needed.

        case tokens.closeSquare:
          this.missingSquareBracket();

        case tokens.semicolon:
          this.missingBackslash();

        default:
          this.unexpected();
      }
    }
    /**
     * Helpers
     */
    ;

    _proto.expected = function expected(description, index, found) {
      if (Array.isArray(description)) {
        var last = description.pop();
        description = description.join(', ') + " or " + last;
      }

      var an = /^[aeiou]/.test(description[0]) ? 'an' : 'a';

      if (!found) {
        return this.error("Expected " + an + " " + description + ".", {
          index: index
        });
      }

      return this.error("Expected " + an + " " + description + ", found \"" + found + "\" instead.", {
        index: index
      });
    };

    _proto.requiredSpace = function requiredSpace(space) {
      return this.options.lossy ? ' ' : space;
    };

    _proto.optionalSpace = function optionalSpace(space) {
      return this.options.lossy ? '' : space;
    };

    _proto.lossySpace = function lossySpace(space, required) {
      if (this.options.lossy) {
        return required ? ' ' : '';
      } else {
        return space;
      }
    };

    _proto.parseParenthesisToken = function parseParenthesisToken(token) {
      var content = this.content(token);

      if (token[_tokenize.FIELDS.TYPE] === tokens.space) {
        return this.requiredSpace(content);
      } else {
        return content;
      }
    };

    _proto.newNode = function newNode(node, namespace) {
      if (namespace) {
        if (/^ +$/.test(namespace)) {
          if (!this.options.lossy) {
            this.spaces = (this.spaces || '') + namespace;
          }

          namespace = true;
        }

        node.namespace = namespace;
        unescapeProp(node, "namespace");
      }

      if (this.spaces) {
        node.spaces.before = this.spaces;
        this.spaces = '';
      }

      return this.current.append(node);
    };

    _proto.content = function content(token) {
      if (token === void 0) {
        token = this.currToken;
      }

      return this.css.slice(token[_tokenize.FIELDS.START_POS], token[_tokenize.FIELDS.END_POS]);
    };

    /**
     * returns the index of the next non-whitespace, non-comment token.
     * returns -1 if no meaningful token is found.
     */
    _proto.locateNextMeaningfulToken = function locateNextMeaningfulToken(startPosition) {
      if (startPosition === void 0) {
        startPosition = this.position + 1;
      }

      var searchPosition = startPosition;

      while (searchPosition < this.tokens.length) {
        if (WHITESPACE_EQUIV_TOKENS[this.tokens[searchPosition][_tokenize.FIELDS.TYPE]]) {
          searchPosition++;
          continue;
        } else {
          return searchPosition;
        }
      }

      return -1;
    };

    _createClass(Parser, [{
      key: "currToken",
      get: function get() {
        return this.tokens[this.position];
      }
    }, {
      key: "nextToken",
      get: function get() {
        return this.tokens[this.position + 1];
      }
    }, {
      key: "prevToken",
      get: function get() {
        return this.tokens[this.position - 1];
      }
    }]);

    return Parser;
  }();

  exports.default = Parser;
  module.exports = exports.default;
  });

  var processor = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _parser = _interopRequireDefault(parser);

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  var Processor =
  /*#__PURE__*/
  function () {
    function Processor(func, options) {
      this.func = func || function noop() {};

      this.funcRes = null;
      this.options = options;
    }

    var _proto = Processor.prototype;

    _proto._shouldUpdateSelector = function _shouldUpdateSelector(rule, options) {
      if (options === void 0) {
        options = {};
      }

      var merged = Object.assign({}, this.options, options);

      if (merged.updateSelector === false) {
        return false;
      } else {
        return typeof rule !== "string";
      }
    };

    _proto._isLossy = function _isLossy(options) {
      if (options === void 0) {
        options = {};
      }

      var merged = Object.assign({}, this.options, options);

      if (merged.lossless === false) {
        return true;
      } else {
        return false;
      }
    };

    _proto._root = function _root(rule, options) {
      if (options === void 0) {
        options = {};
      }

      var parser = new _parser.default(rule, this._parseOptions(options));
      return parser.root;
    };

    _proto._parseOptions = function _parseOptions(options) {
      return {
        lossy: this._isLossy(options)
      };
    };

    _proto._run = function _run(rule, options) {
      var _this = this;

      if (options === void 0) {
        options = {};
      }

      return new Promise(function (resolve, reject) {
        try {
          var root = _this._root(rule, options);

          Promise.resolve(_this.func(root)).then(function (transform) {
            var string = undefined;

            if (_this._shouldUpdateSelector(rule, options)) {
              string = root.toString();
              rule.selector = string;
            }

            return {
              transform: transform,
              root: root,
              string: string
            };
          }).then(resolve, reject);
        } catch (e) {
          reject(e);
          return;
        }
      });
    };

    _proto._runSync = function _runSync(rule, options) {
      if (options === void 0) {
        options = {};
      }

      var root = this._root(rule, options);

      var transform = this.func(root);

      if (transform && typeof transform.then === "function") {
        throw new Error("Selector processor returned a promise to a synchronous call.");
      }

      var string = undefined;

      if (options.updateSelector && typeof rule !== "string") {
        string = root.toString();
        rule.selector = string;
      }

      return {
        transform: transform,
        root: root,
        string: string
      };
    }
    /**
     * Process rule into a selector AST.
     *
     * @param rule {postcss.Rule | string} The css selector to be processed
     * @param options The options for processing
     * @returns {Promise<parser.Root>} The AST of the selector after processing it.
     */
    ;

    _proto.ast = function ast(rule, options) {
      return this._run(rule, options).then(function (result) {
        return result.root;
      });
    }
    /**
     * Process rule into a selector AST synchronously.
     *
     * @param rule {postcss.Rule | string} The css selector to be processed
     * @param options The options for processing
     * @returns {parser.Root} The AST of the selector after processing it.
     */
    ;

    _proto.astSync = function astSync(rule, options) {
      return this._runSync(rule, options).root;
    }
    /**
     * Process a selector into a transformed value asynchronously
     *
     * @param rule {postcss.Rule | string} The css selector to be processed
     * @param options The options for processing
     * @returns {Promise<any>} The value returned by the processor.
     */
    ;

    _proto.transform = function transform(rule, options) {
      return this._run(rule, options).then(function (result) {
        return result.transform;
      });
    }
    /**
     * Process a selector into a transformed value synchronously.
     *
     * @param rule {postcss.Rule | string} The css selector to be processed
     * @param options The options for processing
     * @returns {any} The value returned by the processor.
     */
    ;

    _proto.transformSync = function transformSync(rule, options) {
      return this._runSync(rule, options).transform;
    }
    /**
     * Process a selector into a new selector string asynchronously.
     *
     * @param rule {postcss.Rule | string} The css selector to be processed
     * @param options The options for processing
     * @returns {string} the selector after processing.
     */
    ;

    _proto.process = function process(rule, options) {
      return this._run(rule, options).then(function (result) {
        return result.string || result.root.toString();
      });
    }
    /**
     * Process a selector into a new selector string synchronously.
     *
     * @param rule {postcss.Rule | string} The css selector to be processed
     * @param options The options for processing
     * @returns {string} the selector after processing.
     */
    ;

    _proto.processSync = function processSync(rule, options) {
      var result = this._runSync(rule, options);

      return result.string || result.root.toString();
    };

    return Processor;
  }();

  exports.default = Processor;
  module.exports = exports.default;
  });

  var constructors = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.universal = exports.tag = exports.string = exports.selector = exports.root = exports.pseudo = exports.nesting = exports.id = exports.comment = exports.combinator = exports.className = exports.attribute = void 0;

  var _attribute = _interopRequireDefault(attribute);

  var _className = _interopRequireDefault(className);

  var _combinator = _interopRequireDefault(combinator);

  var _comment = _interopRequireDefault(comment);

  var _id = _interopRequireDefault(id);

  var _nesting = _interopRequireDefault(nesting);

  var _pseudo = _interopRequireDefault(pseudo);

  var _root = _interopRequireDefault(root);

  var _selector = _interopRequireDefault(selector);

  var _string = _interopRequireDefault(string);

  var _tag = _interopRequireDefault(tag);

  var _universal = _interopRequireDefault(universal);

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  var attribute$1 = function attribute(opts) {
    return new _attribute.default(opts);
  };

  exports.attribute = attribute$1;

  var className$1 = function className(opts) {
    return new _className.default(opts);
  };

  exports.className = className$1;

  var combinator$1 = function combinator(opts) {
    return new _combinator.default(opts);
  };

  exports.combinator = combinator$1;

  var comment$1 = function comment(opts) {
    return new _comment.default(opts);
  };

  exports.comment = comment$1;

  var id$1 = function id(opts) {
    return new _id.default(opts);
  };

  exports.id = id$1;

  var nesting$1 = function nesting(opts) {
    return new _nesting.default(opts);
  };

  exports.nesting = nesting$1;

  var pseudo$1 = function pseudo(opts) {
    return new _pseudo.default(opts);
  };

  exports.pseudo = pseudo$1;

  var root$1 = function root(opts) {
    return new _root.default(opts);
  };

  exports.root = root$1;

  var selector$1 = function selector(opts) {
    return new _selector.default(opts);
  };

  exports.selector = selector$1;

  var string$1 = function string(opts) {
    return new _string.default(opts);
  };

  exports.string = string$1;

  var tag$1 = function tag(opts) {
    return new _tag.default(opts);
  };

  exports.tag = tag$1;

  var universal$1 = function universal(opts) {
    return new _universal.default(opts);
  };

  exports.universal = universal$1;
  });

  var guards = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.isNode = isNode;
  exports.isPseudoElement = isPseudoElement;
  exports.isPseudoClass = isPseudoClass;
  exports.isContainer = isContainer;
  exports.isNamespace = isNamespace;
  exports.isUniversal = exports.isTag = exports.isString = exports.isSelector = exports.isRoot = exports.isPseudo = exports.isNesting = exports.isIdentifier = exports.isComment = exports.isCombinator = exports.isClassName = exports.isAttribute = void 0;



  var _IS_TYPE;

  var IS_TYPE = (_IS_TYPE = {}, _IS_TYPE[types.ATTRIBUTE] = true, _IS_TYPE[types.CLASS] = true, _IS_TYPE[types.COMBINATOR] = true, _IS_TYPE[types.COMMENT] = true, _IS_TYPE[types.ID] = true, _IS_TYPE[types.NESTING] = true, _IS_TYPE[types.PSEUDO] = true, _IS_TYPE[types.ROOT] = true, _IS_TYPE[types.SELECTOR] = true, _IS_TYPE[types.STRING] = true, _IS_TYPE[types.TAG] = true, _IS_TYPE[types.UNIVERSAL] = true, _IS_TYPE);

  function isNode(node) {
    return typeof node === "object" && IS_TYPE[node.type];
  }

  function isNodeType(type, node) {
    return isNode(node) && node.type === type;
  }

  var isAttribute = isNodeType.bind(null, types.ATTRIBUTE);
  exports.isAttribute = isAttribute;
  var isClassName = isNodeType.bind(null, types.CLASS);
  exports.isClassName = isClassName;
  var isCombinator = isNodeType.bind(null, types.COMBINATOR);
  exports.isCombinator = isCombinator;
  var isComment = isNodeType.bind(null, types.COMMENT);
  exports.isComment = isComment;
  var isIdentifier = isNodeType.bind(null, types.ID);
  exports.isIdentifier = isIdentifier;
  var isNesting = isNodeType.bind(null, types.NESTING);
  exports.isNesting = isNesting;
  var isPseudo = isNodeType.bind(null, types.PSEUDO);
  exports.isPseudo = isPseudo;
  var isRoot = isNodeType.bind(null, types.ROOT);
  exports.isRoot = isRoot;
  var isSelector = isNodeType.bind(null, types.SELECTOR);
  exports.isSelector = isSelector;
  var isString = isNodeType.bind(null, types.STRING);
  exports.isString = isString;
  var isTag = isNodeType.bind(null, types.TAG);
  exports.isTag = isTag;
  var isUniversal = isNodeType.bind(null, types.UNIVERSAL);
  exports.isUniversal = isUniversal;

  function isPseudoElement(node) {
    return isPseudo(node) && node.value && (node.value.startsWith("::") || node.value === ":before" || node.value === ":after");
  }

  function isPseudoClass(node) {
    return isPseudo(node) && !isPseudoElement(node);
  }

  function isContainer(node) {
    return !!(isNode(node) && node.walk);
  }

  function isNamespace(node) {
    return isAttribute(node) || isTag(node);
  }
  });

  var selectors = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;



  Object.keys(types).forEach(function (key) {
    if (key === "default" || key === "__esModule") return;
    exports[key] = types[key];
  });



  Object.keys(constructors).forEach(function (key) {
    if (key === "default" || key === "__esModule") return;
    exports[key] = constructors[key];
  });



  Object.keys(guards).forEach(function (key) {
    if (key === "default" || key === "__esModule") return;
    exports[key] = guards[key];
  });
  });

  var dist = createCommonjsModule(function (module, exports) {

  exports.__esModule = true;
  exports.default = void 0;

  var _processor = _interopRequireDefault(processor);

  var selectors$1 = _interopRequireWildcard(selectors);

  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  var parser = function parser(processor) {
    return new _processor.default(processor);
  };

  Object.assign(parser, selectors$1);
  delete parser.__esModule;
  var _default = parser;
  exports.default = _default;
  module.exports = exports.default;
  });

  var selectorParser = /*@__PURE__*/getDefaultExportFromCjs(dist);

  const animationNameRE = /^(-\w+-)?animation-name$/;
  const animationRE = /^(-\w+-)?animation$/;
  var scopedPlugin = postcss__default.plugin('vue-scoped', (id) => (root) => {
      const keyframes = Object.create(null);
      const shortId = id.replace(/^data-v-/, '');
      root.each(function rewriteSelectors(node) {
          if (node.type !== 'rule') {
              // handle media queries
              if (node.type === 'atrule') {
                  if (node.name === 'media' || node.name === 'supports') {
                      node.each(rewriteSelectors);
                  }
                  else if (/-?keyframes$/.test(node.name)) {
                      // register keyframes
                      keyframes[node.params] = node.params = node.params + '-' + shortId;
                  }
              }
              return;
          }
          node.selector = selectorParser(selectors => {
              function rewriteSelector(selector, slotted) {
                  let node = null;
                  let shouldInject = true;
                  // find the last child node to insert attribute selector
                  selector.each(n => {
                      // DEPRECATED ">>>" and "/deep/" combinator
                      if (n.type === 'combinator' &&
                          (n.value === '>>>' || n.value === '/deep/')) {
                          n.value = ' ';
                          n.spaces.before = n.spaces.after = '';
                          console.warn(`[@vue/compiler-sfc] the >>> and /deep/ combinators have ` +
                              `been deprecated. Use ::v-deep instead.`);
                          return false;
                      }
                      if (n.type === 'pseudo') {
                          const { value } = n;
                          // deep: inject [id] attribute at the node before the ::v-deep
                          // combinator.
                          if (value === ':deep' || value === '::v-deep') {
                              if (n.nodes.length) {
                                  // .foo ::v-deep(.bar) -> .foo[xxxxxxx] .bar
                                  // replace the current node with ::v-deep's inner selector
                                  selector.insertAfter(n, n.nodes[0]);
                                  // insert a space combinator before if it doesn't already have one
                                  const prev = selector.at(selector.index(n) - 1);
                                  if (!prev || !isSpaceCombinator(prev)) {
                                      selector.insertAfter(n, selectorParser.combinator({
                                          value: ' '
                                      }));
                                  }
                                  selector.removeChild(n);
                              }
                              else {
                                  // DEPRECATED usage
                                  // .foo ::v-deep .bar -> .foo[xxxxxxx] .bar
                                  console.warn(`[@vue/compiler-sfc] ::v-deep usage as a combinator has ` +
                                      `been deprecated. Use ::v-deep(<inner-selector>) instead.`);
                                  const prev = selector.at(selector.index(n) - 1);
                                  if (prev && isSpaceCombinator(prev)) {
                                      selector.removeChild(prev);
                                  }
                                  selector.removeChild(n);
                              }
                              return false;
                          }
                          // slot: use selector inside `::v-slotted` and inject [id + '-s']
                          // instead.
                          // ::v-slotted(.foo) -> .foo[xxxxxxx-s]
                          if (value === ':slotted' || value === '::v-slotted') {
                              rewriteSelector(n.nodes[0], true /* slotted */);
                              selector.insertAfter(n, n.nodes[0]);
                              selector.removeChild(n);
                              // since slotted attribute already scopes the selector there's no
                              // need for the non-slot attribute.
                              shouldInject = false;
                              return false;
                          }
                          // global: replace with inner selector and do not inject [id].
                          // ::v-global(.foo) -> .foo
                          if (value === ':global' || value === '::v-global') {
                              selectors.insertAfter(selector, n.nodes[0]);
                              selectors.removeChild(selector);
                              return false;
                          }
                      }
                      if (n.type !== 'pseudo' && n.type !== 'combinator') {
                          node = n;
                      }
                  });
                  if (node) {
                      node.spaces.after = '';
                  }
                  else {
                      // For deep selectors & standalone pseudo selectors,
                      // the attribute selectors are prepended rather than appended.
                      // So all leading spaces must be eliminated to avoid problems.
                      selector.first.spaces.before = '';
                  }
                  if (shouldInject) {
                      const idToAdd = slotted ? id + '-s' : id;
                      selector.insertAfter(
                      // If node is null it means we need to inject [id] at the start
                      // insertAfter can handle `null` here
                      node, selectorParser.attribute({
                          attribute: idToAdd,
                          value: idToAdd,
                          raws: {},
                          quoteMark: `"`
                      }));
                  }
              }
              selectors.each(selector => rewriteSelector(selector));
          }).processSync(node.selector);
      });
      if (Object.keys(keyframes).length) {
          // If keyframes are found in this <style>, find and rewrite animation names
          // in declarations.
          // Caveat: this only works for keyframes and animation rules in the same
          // <style> element.
          // individual animation-name declaration
          root.walkDecls(decl => {
              if (animationNameRE.test(decl.prop)) {
                  decl.value = decl.value
                      .split(',')
                      .map(v => keyframes[v.trim()] || v.trim())
                      .join(',');
              }
              // shorthand
              if (animationRE.test(decl.prop)) {
                  decl.value = decl.value
                      .split(',')
                      .map(v => {
                      const vals = v.trim().split(/\s+/);
                      const i = vals.findIndex(val => keyframes[val]);
                      if (i !== -1) {
                          vals.splice(i, 1, keyframes[vals[i]]);
                          return vals.join(' ');
                      }
                      else {
                          return v;
                      }
                  })
                      .join(',');
              }
          });
      }
  });
  function isSpaceCombinator(node) {
      return node.type === 'combinator' && /^\s+$/.test(node.value);
  }

  const cssVarRE = /\bvar\(--(global:)?([^)]+)\)/g;
  var scopedVarsPlugin = postcss__default.plugin('vue-scoped', (id) => (root) => {
      const shortId = id.replace(/^data-v-/, '');
      root.walkDecls(decl => {
          // rewrite CSS variables
          if (cssVarRE.test(decl.value)) {
              decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
                  return $1 ? `var(--${$2})` : `var(--${shortId}-${$2})`;
              });
          }
      });
  });

  var SourceMapConsumer$2 = sourceMap.SourceMapConsumer;
  var SourceMapGenerator$3 = sourceMap.SourceMapGenerator;

  var mergeSourceMap = merge$1;

  /**
   * Merge old source map and new source map and return merged.
   * If old or new source map value is falsy, return another one as it is.
   *
   * @param {object|string} [oldMap] old source map object
   * @param {object|string} [newmap] new source map object
   * @return {object|undefined} merged source map object, or undefined when both old and new source map are undefined
   */
  function merge$1(oldMap, newMap) {
    if (!oldMap) return newMap
    if (!newMap) return oldMap

    var oldMapConsumer = new SourceMapConsumer$2(oldMap);
    var newMapConsumer = new SourceMapConsumer$2(newMap);
    var mergedMapGenerator = new SourceMapGenerator$3();

    // iterate on new map and overwrite original position of new map with one of old map
    newMapConsumer.eachMapping(function(m) {
      // pass when `originalLine` is null.
      // It occurs in case that the node does not have origin in original code.
      if (m.originalLine == null) return

      var origPosInOldMap = oldMapConsumer.originalPositionFor({
        line: m.originalLine,
        column: m.originalColumn
      });

      if (origPosInOldMap.source == null) return

      mergedMapGenerator.addMapping({
        original: {
          line: origPosInOldMap.line,
          column: origPosInOldMap.column
        },
        generated: {
          line: m.generatedLine,
          column: m.generatedColumn
        },
        source: origPosInOldMap.source,
        name: origPosInOldMap.name
      });
    });

    var consumers = [oldMapConsumer, newMapConsumer];
    consumers.forEach(function(consumer) {
      consumer.sources.forEach(function(sourceFile) {
        mergedMapGenerator._sources.add(sourceFile);
        var sourceContent = consumer.sourceContentFor(sourceFile);
        if (sourceContent != null) {
          mergedMapGenerator.setSourceContent(sourceFile, sourceContent);
        }
      });
    });

    mergedMapGenerator._sourceRoot = oldMap.sourceRoot;
    mergedMapGenerator._file = oldMap.file;

    return JSON.parse(mergedMapGenerator.toString())
  }

  // .scss/.sass processor
  const scss = (source, map, options, load = require) => {
      const nodeSass = load('sass');
      const finalOptions = {
          ...options,
          data: getSource(source, options.filename, options.additionalData),
          file: options.filename,
          outFile: options.filename,
          sourceMap: !!map
      };
      try {
          const result = nodeSass.renderSync(finalOptions);
          const dependencies = result.stats.includedFiles;
          if (map) {
              return {
                  code: result.css.toString(),
                  map: mergeSourceMap(map, JSON.parse(result.map.toString())),
                  errors: [],
                  dependencies
              };
          }
          return { code: result.css.toString(), errors: [], dependencies };
      }
      catch (e) {
          return { code: '', errors: [e], dependencies: [] };
      }
  };
  const sass = (source, map, options, load) => scss(source, map, {
      ...options,
      indentedSyntax: true
  }, load);
  // .less
  const less = (source, map, options, load = require) => {
      const nodeLess = load('less');
      let result;
      let error = null;
      nodeLess.render(getSource(source, options.filename, options.additionalData), { ...options, syncImport: true }, (err, output) => {
          error = err;
          result = output;
      });
      if (error)
          return { code: '', errors: [error], dependencies: [] };
      const dependencies = result.imports;
      if (map) {
          return {
              code: result.css.toString(),
              map: mergeSourceMap(map, result.map),
              errors: [],
              dependencies: dependencies
          };
      }
      return {
          code: result.css.toString(),
          errors: [],
          dependencies: dependencies
      };
  };
  // .styl
  const styl = (source, map, options, load = require) => {
      const nodeStylus = load('stylus');
      try {
          const ref = nodeStylus(source);
          Object.keys(options).forEach(key => ref.set(key, options[key]));
          if (map)
              ref.set('sourcemap', { inline: false, comment: false });
          const result = ref.render();
          const dependencies = ref.deps();
          if (map) {
              return {
                  code: result,
                  map: mergeSourceMap(map, ref.sourcemap),
                  errors: [],
                  dependencies
              };
          }
          return { code: result, errors: [], dependencies };
      }
      catch (e) {
          return { code: '', errors: [e], dependencies: [] };
      }
  };
  function getSource(source, filename, additionalData) {
      if (!additionalData)
          return source;
      if (isFunction(additionalData)) {
          return additionalData(source, filename);
      }
      return additionalData + source;
  }
  const processors = {
      less,
      sass,
      scss,
      styl,
      stylus: styl
  };

  function compileStyle(options) {
      return doCompileStyle({
          ...options,
          isAsync: false
      });
  }
  function compileStyleAsync(options) {
      return doCompileStyle({ ...options, isAsync: true });
  }
  function doCompileStyle(options) {
      const { filename, id, scoped = false, vars = false, trim = true, modules = false, modulesOptions = {}, preprocessLang, postcssOptions, postcssPlugins } = options;
      const preprocessor = preprocessLang && processors[preprocessLang];
      const preProcessedSource = preprocessor && preprocess$1(options, preprocessor);
      const map = preProcessedSource ? preProcessedSource.map : options.map;
      const source = preProcessedSource ? preProcessedSource.code : options.source;
      const plugins = (postcssPlugins || []).slice();
      if (vars && scoped) {
          // vars + scoped, only applies to raw source before other transforms
          // #1623
          plugins.unshift(scopedVarsPlugin(id));
      }
      if (trim) {
          plugins.push(trimPlugin());
      }
      if (scoped) {
          plugins.push(scopedPlugin(id));
      }
      let cssModules;
      if (modules) {
          {
              throw new Error('[@vue/compiler-sfc] `modules` option is not supported in the browser build.');
          }
      }
      const postCSSOptions = {
          ...postcssOptions,
          to: filename,
          from: filename
      };
      if (map) {
          postCSSOptions.map = {
              inline: false,
              annotation: false,
              prev: map
          };
      }
      let result;
      let code;
      let outMap;
      // stylus output include plain css. so need remove the repeat item
      const dependencies = new Set(preProcessedSource ? preProcessedSource.dependencies : []);
      // sass has filename self when provided filename option
      dependencies.delete(filename);
      const errors = [];
      if (preProcessedSource && preProcessedSource.errors.length) {
          errors.push(...preProcessedSource.errors);
      }
      const recordPlainCssDependencies = (messages) => {
          messages.forEach(msg => {
              if (msg.type === 'dependency') {
                  // postcss output path is absolute position path
                  dependencies.add(msg.file);
              }
          });
          return dependencies;
      };
      try {
          result = postcss__default(plugins).process(source, postCSSOptions);
          // In async mode, return a promise.
          if (options.isAsync) {
              return result
                  .then(result => ({
                  code: result.css || '',
                  map: result.map && result.map.toJSON(),
                  errors,
                  modules: cssModules,
                  rawResult: result,
                  dependencies: recordPlainCssDependencies(result.messages)
              }))
                  .catch(error => ({
                  code: '',
                  map: undefined,
                  errors: [...errors, error],
                  rawResult: undefined,
                  dependencies
              }));
          }
          recordPlainCssDependencies(result.messages);
          // force synchronous transform (we know we only have sync plugins)
          code = result.css;
          outMap = result.map;
      }
      catch (e) {
          errors.push(e);
      }
      return {
          code: code || ``,
          map: outMap && outMap.toJSON(),
          errors,
          rawResult: result,
          dependencies
      };
  }
  function preprocess$1(options, preprocessor) {
      if ( !options.preprocessCustomRequire) {
          throw new Error(`[@vue/compiler-sfc] Style preprocessing in the browser build must ` +
              `provide the \`preprocessCustomRequire\` option to return the in-browser ` +
              `version of the preprocessor.`);
      }
      return preprocessor(options.source, options.map, {
          filename: options.filename,
          ...options.preprocessOptions
      }, options.preprocessCustomRequire);
  }

  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  function encode$3(decoded) {
      var sourceFileIndex = 0; // second field
      var sourceCodeLine = 0; // third field
      var sourceCodeColumn = 0; // fourth field
      var nameIndex = 0; // fifth field
      var mappings = '';
      for (var i = 0; i < decoded.length; i++) {
          var line = decoded[i];
          if (i > 0)
              mappings += ';';
          if (line.length === 0)
              continue;
          var generatedCodeColumn = 0; // first field
          var lineMappings = [];
          for (var _i = 0, line_1 = line; _i < line_1.length; _i++) {
              var segment = line_1[_i];
              var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn);
              generatedCodeColumn = segment[0];
              if (segment.length > 1) {
                  segmentMappings +=
                      encodeInteger(segment[1] - sourceFileIndex) +
                          encodeInteger(segment[2] - sourceCodeLine) +
                          encodeInteger(segment[3] - sourceCodeColumn);
                  sourceFileIndex = segment[1];
                  sourceCodeLine = segment[2];
                  sourceCodeColumn = segment[3];
              }
              if (segment.length === 5) {
                  segmentMappings += encodeInteger(segment[4] - nameIndex);
                  nameIndex = segment[4];
              }
              lineMappings.push(segmentMappings);
          }
          mappings += lineMappings.join(',');
      }
      return mappings;
  }
  function encodeInteger(num) {
      var result = '';
      num = num < 0 ? (-num << 1) | 1 : num << 1;
      do {
          var clamped = num & 31;
          num >>>= 5;
          if (num > 0) {
              clamped |= 32;
          }
          result += chars[clamped];
      } while (num > 0);
      return result;
  }

  var BitSet = function BitSet(arg) {
  	this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
  };

  BitSet.prototype.add = function add (n) {
  	this.bits[n >> 5] |= 1 << (n & 31);
  };

  BitSet.prototype.has = function has (n) {
  	return !!(this.bits[n >> 5] & (1 << (n & 31)));
  };

  var Chunk = function Chunk(start, end, content) {
  	this.start = start;
  	this.end = end;
  	this.original = content;

  	this.intro = '';
  	this.outro = '';

  	this.content = content;
  	this.storeName = false;
  	this.edited = false;

  	// we make these non-enumerable, for sanity while debugging
  	Object.defineProperties(this, {
  		previous: { writable: true, value: null },
  		next:     { writable: true, value: null }
  	});
  };

  Chunk.prototype.appendLeft = function appendLeft (content) {
  	this.outro += content;
  };

  Chunk.prototype.appendRight = function appendRight (content) {
  	this.intro = this.intro + content;
  };

  Chunk.prototype.clone = function clone () {
  	var chunk = new Chunk(this.start, this.end, this.original);

  	chunk.intro = this.intro;
  	chunk.outro = this.outro;
  	chunk.content = this.content;
  	chunk.storeName = this.storeName;
  	chunk.edited = this.edited;

  	return chunk;
  };

  Chunk.prototype.contains = function contains (index) {
  	return this.start < index && index < this.end;
  };

  Chunk.prototype.eachNext = function eachNext (fn) {
  	var chunk = this;
  	while (chunk) {
  		fn(chunk);
  		chunk = chunk.next;
  	}
  };

  Chunk.prototype.eachPrevious = function eachPrevious (fn) {
  	var chunk = this;
  	while (chunk) {
  		fn(chunk);
  		chunk = chunk.previous;
  	}
  };

  Chunk.prototype.edit = function edit (content, storeName, contentOnly) {
  	this.content = content;
  	if (!contentOnly) {
  		this.intro = '';
  		this.outro = '';
  	}
  	this.storeName = storeName;

  	this.edited = true;

  	return this;
  };

  Chunk.prototype.prependLeft = function prependLeft (content) {
  	this.outro = content + this.outro;
  };

  Chunk.prototype.prependRight = function prependRight (content) {
  	this.intro = content + this.intro;
  };

  Chunk.prototype.split = function split (index) {
  	var sliceIndex = index - this.start;

  	var originalBefore = this.original.slice(0, sliceIndex);
  	var originalAfter = this.original.slice(sliceIndex);

  	this.original = originalBefore;

  	var newChunk = new Chunk(index, this.end, originalAfter);
  	newChunk.outro = this.outro;
  	this.outro = '';

  	this.end = index;

  	if (this.edited) {
  		// TODO is this block necessary?...
  		newChunk.edit('', false);
  		this.content = '';
  	} else {
  		this.content = originalBefore;
  	}

  	newChunk.next = this.next;
  	if (newChunk.next) { newChunk.next.previous = newChunk; }
  	newChunk.previous = this;
  	this.next = newChunk;

  	return newChunk;
  };

  Chunk.prototype.toString = function toString () {
  	return this.intro + this.content + this.outro;
  };

  Chunk.prototype.trimEnd = function trimEnd (rx) {
  	this.outro = this.outro.replace(rx, '');
  	if (this.outro.length) { return true; }

  	var trimmed = this.content.replace(rx, '');

  	if (trimmed.length) {
  		if (trimmed !== this.content) {
  			this.split(this.start + trimmed.length).edit('', undefined, true);
  		}
  		return true;

  	} else {
  		this.edit('', undefined, true);

  		this.intro = this.intro.replace(rx, '');
  		if (this.intro.length) { return true; }
  	}
  };

  Chunk.prototype.trimStart = function trimStart (rx) {
  	this.intro = this.intro.replace(rx, '');
  	if (this.intro.length) { return true; }

  	var trimmed = this.content.replace(rx, '');

  	if (trimmed.length) {
  		if (trimmed !== this.content) {
  			this.split(this.end - trimmed.length);
  			this.edit('', undefined, true);
  		}
  		return true;

  	} else {
  		this.edit('', undefined, true);

  		this.outro = this.outro.replace(rx, '');
  		if (this.outro.length) { return true; }
  	}
  };

  var btoa = function () {
  	throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');
  };
  if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
  	btoa = function (str) { return window.btoa(unescape(encodeURIComponent(str))); };
  } else if (typeof Buffer === 'function') {
  	btoa = function (str) { return Buffer.from(str, 'utf-8').toString('base64'); };
  }

  var SourceMap = function SourceMap(properties) {
  	this.version = 3;
  	this.file = properties.file;
  	this.sources = properties.sources;
  	this.sourcesContent = properties.sourcesContent;
  	this.names = properties.names;
  	this.mappings = encode$3(properties.mappings);
  };

  SourceMap.prototype.toString = function toString () {
  	return JSON.stringify(this);
  };

  SourceMap.prototype.toUrl = function toUrl () {
  	return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
  };

  function guessIndent(code) {
  	var lines = code.split('\n');

  	var tabbed = lines.filter(function (line) { return /^\t+/.test(line); });
  	var spaced = lines.filter(function (line) { return /^ {2,}/.test(line); });

  	if (tabbed.length === 0 && spaced.length === 0) {
  		return null;
  	}

  	// More lines tabbed than spaced? Assume tabs, and
  	// default to tabs in the case of a tie (or nothing
  	// to go on)
  	if (tabbed.length >= spaced.length) {
  		return '\t';
  	}

  	// Otherwise, we need to guess the multiple
  	var min = spaced.reduce(function (previous, current) {
  		var numSpaces = /^ +/.exec(current)[0].length;
  		return Math.min(numSpaces, previous);
  	}, Infinity);

  	return new Array(min + 1).join(' ');
  }

  function getRelativePath(from, to) {
  	var fromParts = from.split(/[/\\]/);
  	var toParts = to.split(/[/\\]/);

  	fromParts.pop(); // get dirname

  	while (fromParts[0] === toParts[0]) {
  		fromParts.shift();
  		toParts.shift();
  	}

  	if (fromParts.length) {
  		var i = fromParts.length;
  		while (i--) { fromParts[i] = '..'; }
  	}

  	return fromParts.concat(toParts).join('/');
  }

  var toString$1 = Object.prototype.toString;

  function isObject$2(thing) {
  	return toString$1.call(thing) === '[object Object]';
  }

  function getLocator(source) {
  	var originalLines = source.split('\n');
  	var lineOffsets = [];

  	for (var i = 0, pos = 0; i < originalLines.length; i++) {
  		lineOffsets.push(pos);
  		pos += originalLines[i].length + 1;
  	}

  	return function locate(index) {
  		var i = 0;
  		var j = lineOffsets.length;
  		while (i < j) {
  			var m = (i + j) >> 1;
  			if (index < lineOffsets[m]) {
  				j = m;
  			} else {
  				i = m + 1;
  			}
  		}
  		var line = i - 1;
  		var column = index - lineOffsets[line];
  		return { line: line, column: column };
  	};
  }

  var Mappings = function Mappings(hires) {
  	this.hires = hires;
  	this.generatedCodeLine = 0;
  	this.generatedCodeColumn = 0;
  	this.raw = [];
  	this.rawSegments = this.raw[this.generatedCodeLine] = [];
  	this.pending = null;
  };

  Mappings.prototype.addEdit = function addEdit (sourceIndex, content, loc, nameIndex) {
  	if (content.length) {
  		var segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
  		if (nameIndex >= 0) {
  			segment.push(nameIndex);
  		}
  		this.rawSegments.push(segment);
  	} else if (this.pending) {
  		this.rawSegments.push(this.pending);
  	}

  	this.advance(content);
  	this.pending = null;
  };

  Mappings.prototype.addUneditedChunk = function addUneditedChunk (sourceIndex, chunk, original, loc, sourcemapLocations) {
  	var originalCharIndex = chunk.start;
  	var first = true;

  	while (originalCharIndex < chunk.end) {
  		if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {
  			this.rawSegments.push([this.generatedCodeColumn, sourceIndex, loc.line, loc.column]);
  		}

  		if (original[originalCharIndex] === '\n') {
  			loc.line += 1;
  			loc.column = 0;
  			this.generatedCodeLine += 1;
  			this.raw[this.generatedCodeLine] = this.rawSegments = [];
  			this.generatedCodeColumn = 0;
  			first = true;
  		} else {
  			loc.column += 1;
  			this.generatedCodeColumn += 1;
  			first = false;
  		}

  		originalCharIndex += 1;
  	}

  	this.pending = null;
  };

  Mappings.prototype.advance = function advance (str) {
  	if (!str) { return; }

  	var lines = str.split('\n');

  	if (lines.length > 1) {
  		for (var i = 0; i < lines.length - 1; i++) {
  			this.generatedCodeLine++;
  			this.raw[this.generatedCodeLine] = this.rawSegments = [];
  		}
  		this.generatedCodeColumn = 0;
  	}

  	this.generatedCodeColumn += lines[lines.length - 1].length;
  };

  var n = '\n';

  var warned = {
  	insertLeft: false,
  	insertRight: false,
  	storeName: false
  };

  var MagicString = function MagicString(string, options) {
  	if ( options === void 0 ) options = {};

  	var chunk = new Chunk(0, string.length, string);

  	Object.defineProperties(this, {
  		original:              { writable: true, value: string },
  		outro:                 { writable: true, value: '' },
  		intro:                 { writable: true, value: '' },
  		firstChunk:            { writable: true, value: chunk },
  		lastChunk:             { writable: true, value: chunk },
  		lastSearchedChunk:     { writable: true, value: chunk },
  		byStart:               { writable: true, value: {} },
  		byEnd:                 { writable: true, value: {} },
  		filename:              { writable: true, value: options.filename },
  		indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
  		sourcemapLocations:    { writable: true, value: new BitSet() },
  		storedNames:           { writable: true, value: {} },
  		indentStr:             { writable: true, value: guessIndent(string) }
  	});

  	this.byStart[0] = chunk;
  	this.byEnd[string.length] = chunk;
  };

  MagicString.prototype.addSourcemapLocation = function addSourcemapLocation (char) {
  	this.sourcemapLocations.add(char);
  };

  MagicString.prototype.append = function append (content) {
  	if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }

  	this.outro += content;
  	return this;
  };

  MagicString.prototype.appendLeft = function appendLeft (index, content) {
  	if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }

  	this._split(index);

  	var chunk = this.byEnd[index];

  	if (chunk) {
  		chunk.appendLeft(content);
  	} else {
  		this.intro += content;
  	}
  	return this;
  };

  MagicString.prototype.appendRight = function appendRight (index, content) {
  	if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }

  	this._split(index);

  	var chunk = this.byStart[index];

  	if (chunk) {
  		chunk.appendRight(content);
  	} else {
  		this.outro += content;
  	}
  	return this;
  };

  MagicString.prototype.clone = function clone () {
  	var cloned = new MagicString(this.original, { filename: this.filename });

  	var originalChunk = this.firstChunk;
  	var clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());

  	while (originalChunk) {
  		cloned.byStart[clonedChunk.start] = clonedChunk;
  		cloned.byEnd[clonedChunk.end] = clonedChunk;

  		var nextOriginalChunk = originalChunk.next;
  		var nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();

  		if (nextClonedChunk) {
  			clonedChunk.next = nextClonedChunk;
  			nextClonedChunk.previous = clonedChunk;

  			clonedChunk = nextClonedChunk;
  		}

  		originalChunk = nextOriginalChunk;
  	}

  	cloned.lastChunk = clonedChunk;

  	if (this.indentExclusionRanges) {
  		cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
  	}

  	cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);

  	cloned.intro = this.intro;
  	cloned.outro = this.outro;

  	return cloned;
  };

  MagicString.prototype.generateDecodedMap = function generateDecodedMap (options) {
  		var this$1 = this;

  	options = options || {};

  	var sourceIndex = 0;
  	var names = Object.keys(this.storedNames);
  	var mappings = new Mappings(options.hires);

  	var locate = getLocator(this.original);

  	if (this.intro) {
  		mappings.advance(this.intro);
  	}

  	this.firstChunk.eachNext(function (chunk) {
  		var loc = locate(chunk.start);

  		if (chunk.intro.length) { mappings.advance(chunk.intro); }

  		if (chunk.edited) {
  			mappings.addEdit(
  				sourceIndex,
  				chunk.content,
  				loc,
  				chunk.storeName ? names.indexOf(chunk.original) : -1
  			);
  		} else {
  			mappings.addUneditedChunk(sourceIndex, chunk, this$1.original, loc, this$1.sourcemapLocations);
  		}

  		if (chunk.outro.length) { mappings.advance(chunk.outro); }
  	});

  	return {
  		file: options.file ? options.file.split(/[/\\]/).pop() : null,
  		sources: [options.source ? getRelativePath(options.file || '', options.source) : null],
  		sourcesContent: options.includeContent ? [this.original] : [null],
  		names: names,
  		mappings: mappings.raw
  	};
  };

  MagicString.prototype.generateMap = function generateMap (options) {
  	return new SourceMap(this.generateDecodedMap(options));
  };

  MagicString.prototype.getIndentString = function getIndentString () {
  	return this.indentStr === null ? '\t' : this.indentStr;
  };

  MagicString.prototype.indent = function indent (indentStr, options) {
  	var pattern = /^[^\r\n]/gm;

  	if (isObject$2(indentStr)) {
  		options = indentStr;
  		indentStr = undefined;
  	}

  	indentStr = indentStr !== undefined ? indentStr : this.indentStr || '\t';

  	if (indentStr === '') { return this; } // noop

  	options = options || {};

  	// Process exclusion ranges
  	var isExcluded = {};

  	if (options.exclude) {
  		var exclusions =
  			typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;
  		exclusions.forEach(function (exclusion) {
  			for (var i = exclusion[0]; i < exclusion[1]; i += 1) {
  				isExcluded[i] = true;
  			}
  		});
  	}

  	var shouldIndentNextCharacter = options.indentStart !== false;
  	var replacer = function (match) {
  		if (shouldIndentNextCharacter) { return ("" + indentStr + match); }
  		shouldIndentNextCharacter = true;
  		return match;
  	};

  	this.intro = this.intro.replace(pattern, replacer);

  	var charIndex = 0;
  	var chunk = this.firstChunk;

  	while (chunk) {
  		var end = chunk.end;

  		if (chunk.edited) {
  			if (!isExcluded[charIndex]) {
  				chunk.content = chunk.content.replace(pattern, replacer);

  				if (chunk.content.length) {
  					shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';
  				}
  			}
  		} else {
  			charIndex = chunk.start;

  			while (charIndex < end) {
  				if (!isExcluded[charIndex]) {
  					var char = this.original[charIndex];

  					if (char === '\n') {
  						shouldIndentNextCharacter = true;
  					} else if (char !== '\r' && shouldIndentNextCharacter) {
  						shouldIndentNextCharacter = false;

  						if (charIndex === chunk.start) {
  							chunk.prependRight(indentStr);
  						} else {
  							this._splitChunk(chunk, charIndex);
  							chunk = chunk.next;
  							chunk.prependRight(indentStr);
  						}
  					}
  				}

  				charIndex += 1;
  			}
  		}

  		charIndex = chunk.end;
  		chunk = chunk.next;
  	}

  	this.outro = this.outro.replace(pattern, replacer);

  	return this;
  };

  MagicString.prototype.insert = function insert () {
  	throw new Error('magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)');
  };

  MagicString.prototype.insertLeft = function insertLeft (index, content) {
  	if (!warned.insertLeft) {
  		console.warn('magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead'); // eslint-disable-line no-console
  		warned.insertLeft = true;
  	}

  	return this.appendLeft(index, content);
  };

  MagicString.prototype.insertRight = function insertRight (index, content) {
  	if (!warned.insertRight) {
  		console.warn('magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead'); // eslint-disable-line no-console
  		warned.insertRight = true;
  	}

  	return this.prependRight(index, content);
  };

  MagicString.prototype.move = function move (start, end, index) {
  	if (index >= start && index <= end) { throw new Error('Cannot move a selection inside itself'); }

  	this._split(start);
  	this._split(end);
  	this._split(index);

  	var first = this.byStart[start];
  	var last = this.byEnd[end];

  	var oldLeft = first.previous;
  	var oldRight = last.next;

  	var newRight = this.byStart[index];
  	if (!newRight && last === this.lastChunk) { return this; }
  	var newLeft = newRight ? newRight.previous : this.lastChunk;

  	if (oldLeft) { oldLeft.next = oldRight; }
  	if (oldRight) { oldRight.previous = oldLeft; }

  	if (newLeft) { newLeft.next = first; }
  	if (newRight) { newRight.previous = last; }

  	if (!first.previous) { this.firstChunk = last.next; }
  	if (!last.next) {
  		this.lastChunk = first.previous;
  		this.lastChunk.next = null;
  	}

  	first.previous = newLeft;
  	last.next = newRight || null;

  	if (!newLeft) { this.firstChunk = first; }
  	if (!newRight) { this.lastChunk = last; }
  	return this;
  };

  MagicString.prototype.overwrite = function overwrite (start, end, content, options) {
  	if (typeof content !== 'string') { throw new TypeError('replacement content must be a string'); }

  	while (start < 0) { start += this.original.length; }
  	while (end < 0) { end += this.original.length; }

  	if (end > this.original.length) { throw new Error('end is out of bounds'); }
  	if (start === end)
  		{ throw new Error('Cannot overwrite a zero-length range – use appendLeft or prependRight instead'); }

  	this._split(start);
  	this._split(end);

  	if (options === true) {
  		if (!warned.storeName) {
  			console.warn('The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string'); // eslint-disable-line no-console
  			warned.storeName = true;
  		}

  		options = { storeName: true };
  	}
  	var storeName = options !== undefined ? options.storeName : false;
  	var contentOnly = options !== undefined ? options.contentOnly : false;

  	if (storeName) {
  		var original = this.original.slice(start, end);
  		this.storedNames[original] = true;
  	}

  	var first = this.byStart[start];
  	var last = this.byEnd[end];

  	if (first) {
  		if (end > first.end && first.next !== this.byStart[first.end]) {
  			throw new Error('Cannot overwrite across a split point');
  		}

  		first.edit(content, storeName, contentOnly);

  		if (first !== last) {
  			var chunk = first.next;
  			while (chunk !== last) {
  				chunk.edit('', false);
  				chunk = chunk.next;
  			}

  			chunk.edit('', false);
  		}
  	} else {
  		// must be inserting at the end
  		var newChunk = new Chunk(start, end, '').edit(content, storeName);

  		// TODO last chunk in the array may not be the last chunk, if it's moved...
  		last.next = newChunk;
  		newChunk.previous = last;
  	}
  	return this;
  };

  MagicString.prototype.prepend = function prepend (content) {
  	if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }

  	this.intro = content + this.intro;
  	return this;
  };

  MagicString.prototype.prependLeft = function prependLeft (index, content) {
  	if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }

  	this._split(index);

  	var chunk = this.byEnd[index];

  	if (chunk) {
  		chunk.prependLeft(content);
  	} else {
  		this.intro = content + this.intro;
  	}
  	return this;
  };

  MagicString.prototype.prependRight = function prependRight (index, content) {
  	if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }

  	this._split(index);

  	var chunk = this.byStart[index];

  	if (chunk) {
  		chunk.prependRight(content);
  	} else {
  		this.outro = content + this.outro;
  	}
  	return this;
  };

  MagicString.prototype.remove = function remove (start, end) {
  	while (start < 0) { start += this.original.length; }
  	while (end < 0) { end += this.original.length; }

  	if (start === end) { return this; }

  	if (start < 0 || end > this.original.length) { throw new Error('Character is out of bounds'); }
  	if (start > end) { throw new Error('end must be greater than start'); }

  	this._split(start);
  	this._split(end);

  	var chunk = this.byStart[start];

  	while (chunk) {
  		chunk.intro = '';
  		chunk.outro = '';
  		chunk.edit('');

  		chunk = end > chunk.end ? this.byStart[chunk.end] : null;
  	}
  	return this;
  };

  MagicString.prototype.lastChar = function lastChar () {
  	if (this.outro.length)
  		{ return this.outro[this.outro.length - 1]; }
  	var chunk = this.lastChunk;
  	do {
  		if (chunk.outro.length)
  			{ return chunk.outro[chunk.outro.length - 1]; }
  		if (chunk.content.length)
  			{ return chunk.content[chunk.content.length - 1]; }
  		if (chunk.intro.length)
  			{ return chunk.intro[chunk.intro.length - 1]; }
  	} while (chunk = chunk.previous);
  	if (this.intro.length)
  		{ return this.intro[this.intro.length - 1]; }
  	return '';
  };

  MagicString.prototype.lastLine = function lastLine () {
  	var lineIndex = this.outro.lastIndexOf(n);
  	if (lineIndex !== -1)
  		{ return this.outro.substr(lineIndex + 1); }
  	var lineStr = this.outro;
  	var chunk = this.lastChunk;
  	do {
  		if (chunk.outro.length > 0) {
  			lineIndex = chunk.outro.lastIndexOf(n);
  			if (lineIndex !== -1)
  				{ return chunk.outro.substr(lineIndex + 1) + lineStr; }
  			lineStr = chunk.outro + lineStr;
  		}

  		if (chunk.content.length > 0) {
  			lineIndex = chunk.content.lastIndexOf(n);
  			if (lineIndex !== -1)
  				{ return chunk.content.substr(lineIndex + 1) + lineStr; }
  			lineStr = chunk.content + lineStr;
  		}

  		if (chunk.intro.length > 0) {
  			lineIndex = chunk.intro.lastIndexOf(n);
  			if (lineIndex !== -1)
  				{ return chunk.intro.substr(lineIndex + 1) + lineStr; }
  			lineStr = chunk.intro + lineStr;
  		}
  	} while (chunk = chunk.previous);
  	lineIndex = this.intro.lastIndexOf(n);
  	if (lineIndex !== -1)
  		{ return this.intro.substr(lineIndex + 1) + lineStr; }
  	return this.intro + lineStr;
  };

  MagicString.prototype.slice = function slice (start, end) {
  		if ( start === void 0 ) start = 0;
  		if ( end === void 0 ) end = this.original.length;

  	while (start < 0) { start += this.original.length; }
  	while (end < 0) { end += this.original.length; }

  	var result = '';

  	// find start chunk
  	var chunk = this.firstChunk;
  	while (chunk && (chunk.start > start || chunk.end <= start)) {
  		// found end chunk before start
  		if (chunk.start < end && chunk.end >= end) {
  			return result;
  		}

  		chunk = chunk.next;
  	}

  	if (chunk && chunk.edited && chunk.start !== start)
  		{ throw new Error(("Cannot use replaced character " + start + " as slice start anchor.")); }

  	var startChunk = chunk;
  	while (chunk) {
  		if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
  			result += chunk.intro;
  		}

  		var containsEnd = chunk.start < end && chunk.end >= end;
  		if (containsEnd && chunk.edited && chunk.end !== end)
  			{ throw new Error(("Cannot use replaced character " + end + " as slice end anchor.")); }

  		var sliceStart = startChunk === chunk ? start - chunk.start : 0;
  		var sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;

  		result += chunk.content.slice(sliceStart, sliceEnd);

  		if (chunk.outro && (!containsEnd || chunk.end === end)) {
  			result += chunk.outro;
  		}

  		if (containsEnd) {
  			break;
  		}

  		chunk = chunk.next;
  	}

  	return result;
  };

  // TODO deprecate this? not really very useful
  MagicString.prototype.snip = function snip (start, end) {
  	var clone = this.clone();
  	clone.remove(0, start);
  	clone.remove(end, clone.original.length);

  	return clone;
  };

  MagicString.prototype._split = function _split (index) {
  	if (this.byStart[index] || this.byEnd[index]) { return; }

  	var chunk = this.lastSearchedChunk;
  	var searchForward = index > chunk.end;

  	while (chunk) {
  		if (chunk.contains(index)) { return this._splitChunk(chunk, index); }

  		chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
  	}
  };

  MagicString.prototype._splitChunk = function _splitChunk (chunk, index) {
  	if (chunk.edited && chunk.content.length) {
  		// zero-length edited chunks are a special case (overlapping replacements)
  		var loc = getLocator(this.original)(index);
  		throw new Error(
  			("Cannot split a chunk that has already been edited (" + (loc.line) + ":" + (loc.column) + " – \"" + (chunk.original) + "\")")
  		);
  	}

  	var newChunk = chunk.split(index);

  	this.byEnd[index] = chunk;
  	this.byStart[index] = newChunk;
  	this.byEnd[newChunk.end] = newChunk;

  	if (chunk === this.lastChunk) { this.lastChunk = newChunk; }

  	this.lastSearchedChunk = chunk;
  	return true;
  };

  MagicString.prototype.toString = function toString () {
  	var str = this.intro;

  	var chunk = this.firstChunk;
  	while (chunk) {
  		str += chunk.toString();
  		chunk = chunk.next;
  	}

  	return str + this.outro;
  };

  MagicString.prototype.isEmpty = function isEmpty () {
  	var chunk = this.firstChunk;
  	do {
  		if (chunk.intro.length && chunk.intro.trim() ||
  				chunk.content.length && chunk.content.trim() ||
  				chunk.outro.length && chunk.outro.trim())
  			{ return false; }
  	} while (chunk = chunk.next);
  	return true;
  };

  MagicString.prototype.length = function length () {
  	var chunk = this.firstChunk;
  	var length = 0;
  	do {
  		length += chunk.intro.length + chunk.content.length + chunk.outro.length;
  	} while (chunk = chunk.next);
  	return length;
  };

  MagicString.prototype.trimLines = function trimLines () {
  	return this.trim('[\\r\\n]');
  };

  MagicString.prototype.trim = function trim (charType) {
  	return this.trimStart(charType).trimEnd(charType);
  };

  MagicString.prototype.trimEndAborted = function trimEndAborted (charType) {
  	var rx = new RegExp((charType || '\\s') + '+$');

  	this.outro = this.outro.replace(rx, '');
  	if (this.outro.length) { return true; }

  	var chunk = this.lastChunk;

  	do {
  		var end = chunk.end;
  		var aborted = chunk.trimEnd(rx);

  		// if chunk was trimmed, we have a new lastChunk
  		if (chunk.end !== end) {
  			if (this.lastChunk === chunk) {
  				this.lastChunk = chunk.next;
  			}

  			this.byEnd[chunk.end] = chunk;
  			this.byStart[chunk.next.start] = chunk.next;
  			this.byEnd[chunk.next.end] = chunk.next;
  		}

  		if (aborted) { return true; }
  		chunk = chunk.previous;
  	} while (chunk);

  	return false;
  };

  MagicString.prototype.trimEnd = function trimEnd (charType) {
  	this.trimEndAborted(charType);
  	return this;
  };
  MagicString.prototype.trimStartAborted = function trimStartAborted (charType) {
  	var rx = new RegExp('^' + (charType || '\\s') + '+');

  	this.intro = this.intro.replace(rx, '');
  	if (this.intro.length) { return true; }

  	var chunk = this.firstChunk;

  	do {
  		var end = chunk.end;
  		var aborted = chunk.trimStart(rx);

  		if (chunk.end !== end) {
  			// special case...
  			if (chunk === this.lastChunk) { this.lastChunk = chunk.next; }

  			this.byEnd[chunk.end] = chunk;
  			this.byStart[chunk.next.start] = chunk.next;
  			this.byEnd[chunk.next.end] = chunk.next;
  		}

  		if (aborted) { return true; }
  		chunk = chunk.next;
  	} while (chunk);

  	return false;
  };

  MagicString.prototype.trimStart = function trimStart (charType) {
  	this.trimStartAborted(charType);
  	return this;
  };

  const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
  const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/;
  /**
   * Utility for rewriting `export default` in a script block into a variable
   * declaration so that we can inject things into it
   */
  function rewriteDefault(input, as, parserPlugins) {
      if (!hasDefaultExport(input)) {
          return input + `\nconst ${as} = {}`;
      }
      const replaced = input.replace(defaultExportRE, `$1const ${as} =`);
      if (!hasDefaultExport(replaced)) {
          return replaced;
      }
      // if the script somehow still contains `default export`, it probably has
      // multi-line comments or template strings. fallback to a full parse.
      const s = new MagicString(input);
      const ast = lib.parse(input, {
          sourceType: 'module',
          plugins: parserPlugins
      }).program.body;
      ast.forEach(node => {
          if (node.type === 'ExportDefaultDeclaration') {
              s.overwrite(node.start, node.declaration.start, `const ${as} = `);
          }
          if (node.type === 'ExportNamedDeclaration') {
              node.specifiers.forEach(specifier => {
                  if (specifier.type === 'ExportSpecifier' &&
                      specifier.exported.name === 'default') {
                      const end = specifier.end;
                      s.overwrite(specifier.start, input.charAt(end) === ',' ? end + 1 : end, ``);
                      s.append(`\nconst ${as} = ${specifier.local.name}`);
                  }
              });
          }
      });
      return s.toString();
  }
  function hasDefaultExport(input) {
      return defaultExportRE.test(input) || namedDefaultExportRE.test(input);
  }

  function genCssVarsCode(varsExp, scoped, knownBindings) {
      const exp = createSimpleExpression(varsExp, false);
      const context = createTransformContext(createRoot([]), {
          prefixIdentifiers: true
      });
      if (knownBindings) {
          // when compiling <script setup> we already know what bindings are exposed
          // so we can avoid prefixing them from the ctx.
          for (const key in knownBindings) {
              context.identifiers[key] = 1;
          }
      }
      const transformed = processExpression(exp, context);
      const transformedString = transformed.type === 4 /* SIMPLE_EXPRESSION */
          ? transformed.content
          : transformed.children
              .map(c => {
              return typeof c === 'string'
                  ? c
                  : c.content;
          })
              .join('');
      return `__useCssVars__(_ctx => (${transformedString})${scoped ? `, true` : ``})`;
  }
  // <script setup> already gets the calls injected as part of the transform
  // this is only for single normal <script>
  function injectCssVarsCalls(sfc, parserPlugins) {
      const script = rewriteDefault(sfc.script.content, `__default__`, parserPlugins);
      let calls = ``;
      for (const style of sfc.styles) {
          const vars = style.attrs.vars;
          if (typeof vars === 'string') {
              calls += genCssVarsCode(vars, !!style.scoped) + '\n';
          }
      }
      return (script +
          `\nimport { useCssVars as __useCssVars__ } from 'vue'\n` +
          `const __injectCSSVars__ = () => {\n${calls}}\n` +
          `const __setup__ = __default__.setup\n` +
          `__default__.setup = __setup__\n` +
          `  ? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }\n` +
          `  : __injectCSSVars__\n` +
          `export default __default__`);
  }

  let hasWarned = false;
  /**
   * Compile `<script setup>`
   * It requires the whole SFC descriptor because we need to handle and merge
   * normal `<script>` + `<script setup>` if both are present.
   */
  function compileScript(sfc, options = {}) {
      const { script, scriptSetup, styles, source, filename } = sfc;
      if ( !hasWarned && scriptSetup) {
          hasWarned = true;
          // @ts-ignore `console.info` cannot be null error
          console[console.info ? 'info' : 'log'](`\n[@vue/compiler-sfc] <script setup> is still an experimental proposal.\n` +
              `Follow https://github.com/vuejs/rfcs/pull/182 for its status.\n`);
      }
      const hasCssVars = styles.some(s => typeof s.attrs.vars === 'string');
      const scriptLang = script && script.lang;
      const scriptSetupLang = scriptSetup && scriptSetup.lang;
      const isTS = scriptLang === 'ts' || scriptSetupLang === 'ts';
      const plugins = [...babelParserDefaultPlugins, 'jsx'];
      if (options.babelParserPlugins)
          plugins.push(...options.babelParserPlugins);
      if (isTS)
          plugins.push('typescript', 'decorators-legacy');
      if (!scriptSetup) {
          if (!script) {
              throw new Error(`SFC contains no <script> tags.`);
          }
          if (scriptLang && scriptLang !== 'ts') {
              // do not process non js/ts script blocks
              return script;
          }
          try {
              const scriptAst = lib.parse(script.content, {
                  plugins,
                  sourceType: 'module'
              }).program.body;
              return {
                  ...script,
                  content: hasCssVars ? injectCssVarsCalls(sfc, plugins) : script.content,
                  bindings: analyzeScriptBindings(scriptAst),
                  scriptAst
              };
          }
          catch (e) {
              // silently fallback if parse fails since user may be using custom
              // babel syntax
              return script;
          }
      }
      if (script && scriptLang !== scriptSetupLang) {
          throw new Error(`<script> and <script setup> must have the same language type.`);
      }
      if (scriptSetupLang && scriptSetupLang !== 'ts') {
          // do not process non js/ts script blocks
          return scriptSetup;
      }
      const defaultTempVar = `__default__`;
      const bindings = {};
      const imports = {};
      const setupScopeVars = {};
      const setupExports = {};
      let exportAllIndex = 0;
      let defaultExport;
      let needDefaultExportRefCheck = false;
      let hasAwait = false;
      const checkDuplicateDefaultExport = (node) => {
          if (defaultExport) {
              // <script> already has export default
              throw new Error(`Default export is already declared in normal <script>.\n\n` +
                  generateCodeFrame(source, node.start + startOffset, node.start + startOffset + `export default`.length));
          }
      };
      const s = new MagicString(source);
      const startOffset = scriptSetup.loc.start.offset;
      const endOffset = scriptSetup.loc.end.offset;
      const scriptStartOffset = script && script.loc.start.offset;
      const scriptEndOffset = script && script.loc.end.offset;
      let scriptAst;
      // 1. process normal <script> first if it exists
      if (script) {
          // import dedupe between <script> and <script setup>
          scriptAst = lib.parse(script.content, {
              plugins,
              sourceType: 'module'
          }).program.body;
          for (const node of scriptAst) {
              if (node.type === 'ImportDeclaration') {
                  // record imports for dedupe
                  for (const { local: { name } } of node.specifiers) {
                      imports[name] = node.source.value;
                  }
              }
              else if (node.type === 'ExportDefaultDeclaration') {
                  // export default
                  defaultExport = node;
                  const start = node.start + scriptStartOffset;
                  s.overwrite(start, start + `export default`.length, `const ${defaultTempVar} =`);
              }
              else if (node.type === 'ExportNamedDeclaration' && node.specifiers) {
                  const defaultSpecifier = node.specifiers.find(s => s.exported.name === 'default');
                  if (defaultSpecifier) {
                      defaultExport = node;
                      // 1. remove specifier
                      if (node.specifiers.length > 1) {
                          s.remove(defaultSpecifier.start + scriptStartOffset, defaultSpecifier.end + scriptStartOffset);
                      }
                      else {
                          s.remove(node.start + scriptStartOffset, node.end + scriptStartOffset);
                      }
                      if (node.source) {
                          // export { x as default } from './x'
                          // rewrite to `import { x as __default__ } from './x'` and
                          // add to top
                          s.prepend(`import { ${defaultSpecifier.local.name} as ${defaultTempVar} } from '${node.source.value}'\n`);
                      }
                      else {
                          // export { x as default }
                          // rewrite to `const __default__ = x` and move to end
                          s.append(`\nconst ${defaultTempVar} = ${defaultSpecifier.local.name}\n`);
                      }
                  }
              }
          }
      }
      // 2. check <script setup="xxx"> function signature
      const setupValue = scriptSetup.setup;
      const hasExplicitSignature = typeof setupValue === 'string';
      let propsVar;
      let emitVar;
      let slotsVar;
      let attrsVar;
      let propsType = `{}`;
      let emitType = `(e: string, ...args: any[]) => void`;
      let slotsType = `__Slots__`;
      let attrsType = `Record<string, any>`;
      let propsASTNode;
      let setupCtxASTNode;
      // props/emits declared via types
      const typeDeclaredProps = {};
      const typeDeclaredEmits = new Set();
      // record declared types for runtime props type generation
      const declaredTypes = {};
      if (isTS && hasExplicitSignature) {
          // <script setup="xxx" lang="ts">
          // parse the signature to extract the props/emit variables the user wants
          // we need them to find corresponding type declarations.
          const signatureAST = lib.parse(`(${setupValue})=>{}`, { plugins }).program
              .body[0];
          const params = signatureAST
              .expression.params;
          if (params[0] && params[0].type === 'Identifier') {
              propsASTNode = params[0];
              propsVar = propsASTNode.name;
          }
          if (params[1] && params[1].type === 'ObjectPattern') {
              setupCtxASTNode = params[1];
              for (const p of params[1].properties) {
                  if (p.type === 'ObjectProperty' &&
                      p.key.type === 'Identifier' &&
                      p.value.type === 'Identifier') {
                      if (p.key.name === 'emit') {
                          emitVar = p.value.name;
                      }
                      else if (p.key.name === 'slots') {
                          slotsVar = p.value.name;
                      }
                      else if (p.key.name === 'attrs') {
                          attrsVar = p.value.name;
                      }
                  }
              }
          }
      }
      // 3. parse <script setup> and  walk over top level statements
      const scriptSetupAst = lib.parse(scriptSetup.content, {
          plugins: [
              ...plugins,
              // allow top level await but only inside <script setup>
              'topLevelAwait'
          ],
          sourceType: 'module'
      }).program.body;
      for (const node of scriptSetupAst) {
          const start = node.start + startOffset;
          let end = node.end + startOffset;
          // import or type declarations: move to top
          // locate comment
          if (node.trailingComments && node.trailingComments.length > 0) {
              const lastCommentNode = node.trailingComments[node.trailingComments.length - 1];
              end = lastCommentNode.end + startOffset;
          }
          // locate the end of whitespace between this statement and the next
          while (end <= source.length) {
              if (!/\s/.test(source.charAt(end))) {
                  break;
              }
              end++;
          }
          if (node.type === 'ImportDeclaration') {
              // import declarations are moved to top
              s.move(start, end, 0);
              // dedupe imports
              let prev;
              let removed = 0;
              for (const specifier of node.specifiers) {
                  if (imports[specifier.local.name]) {
                      // already imported in <script setup>, dedupe
                      removed++;
                      s.remove(prev ? prev.end + startOffset : specifier.start + startOffset, specifier.end + startOffset);
                  }
                  else {
                      imports[specifier.local.name] = node.source.value;
                  }
                  prev = specifier;
              }
              if (removed === node.specifiers.length) {
                  s.remove(node.start + startOffset, node.end + startOffset);
              }
          }
          if (node.type === 'ExportNamedDeclaration' && node.exportKind !== 'type') {
              // named exports
              if (node.declaration) {
                  // variable/function/class declarations.
                  // remove leading `export ` keyword
                  s.remove(start, start + 7);
                  walkDeclaration(node.declaration, setupExports);
              }
              if (node.specifiers.length) {
                  // named export with specifiers
                  if (node.source) {
                      // export { x } from './x'
                      // change it to import and move to top
                      s.overwrite(start, start + 6, 'import');
                      s.move(start, end, 0);
                  }
                  else {
                      // export { x }
                      s.remove(start, end);
                  }
                  for (const specifier of node.specifiers) {
                      if (specifier.type === 'ExportDefaultSpecifier') {
                          // export default from './x'
                          // rewrite to `import __default__ from './x'`
                          checkDuplicateDefaultExport(node);
                          defaultExport = node;
                          s.overwrite(specifier.exported.start + startOffset, specifier.exported.start + startOffset + 7, defaultTempVar);
                      }
                      else if (specifier.type === 'ExportSpecifier') {
                          if (specifier.exported.name === 'default') {
                              checkDuplicateDefaultExport(node);
                              defaultExport = node;
                              // 1. remove specifier
                              if (node.specifiers.length > 1) {
                                  // removing the default specifier from a list of specifiers.
                                  // look ahead until we reach the first non , or whitespace char.
                                  let end = specifier.end + startOffset;
                                  while (end < source.length) {
                                      if (/[^,\s]/.test(source.charAt(end))) {
                                          break;
                                      }
                                      end++;
                                  }
                                  s.remove(specifier.start + startOffset, end);
                              }
                              else {
                                  s.remove(node.start + startOffset, node.end + startOffset);
                              }
                              if (!node.source) {
                                  // export { x as default, ... }
                                  const local = specifier.local.name;
                                  if (setupScopeVars[local] || setupExports[local]) {
                                      throw new Error(`Cannot export locally defined variable as default in <script setup>.\n` +
                                          `Default export must be an object literal with no reference to local scope.\n` +
                                          generateCodeFrame(source, specifier.start + startOffset, specifier.end + startOffset));
                                  }
                                  // rewrite to `const __default__ = x` and move to end
                                  s.append(`\nconst ${defaultTempVar} = ${local}\n`);
                              }
                              else {
                                  // export { x as default } from './x'
                                  // rewrite to `import { x as __default__ } from './x'` and
                                  // add to top
                                  s.prepend(`import { ${specifier.local.name} as ${defaultTempVar} } from '${node.source.value}'\n`);
                              }
                          }
                          else {
                              setupExports[specifier.exported.name] = true;
                              if (node.source) {
                                  imports[specifier.exported.name] = node.source.value;
                              }
                          }
                      }
                  }
              }
          }
          if (node.type === 'ExportAllDeclaration') {
              // export * from './x'
              s.overwrite(start, node.source.start + startOffset, `import * as __export_all_${exportAllIndex++}__ from `);
              s.move(start, end, 0);
          }
          if (node.type === 'ExportDefaultDeclaration') {
              checkDuplicateDefaultExport(node);
              // export default {} inside <script setup>
              // this should be kept in module scope - move it to the end
              s.move(start, end, source.length);
              s.overwrite(start, start + `export default`.length, `const __default__ =`);
              // save it for analysis when all imports and variable declarations have
              // been recorded
              defaultExport = node;
              needDefaultExportRefCheck = true;
          }
          if ((node.type === 'VariableDeclaration' ||
              node.type === 'FunctionDeclaration' ||
              node.type === 'ClassDeclaration') &&
              !node.declare) {
              walkDeclaration(node, setupScopeVars);
          }
          // Type declarations
          if (node.type === 'VariableDeclaration' && node.declare) {
              s.remove(start, end);
              for (const { id } of node.declarations) {
                  if (id.type === 'Identifier') {
                      if (id.typeAnnotation &&
                          id.typeAnnotation.type === 'TSTypeAnnotation') {
                          const typeNode = id.typeAnnotation.typeAnnotation;
                          const typeString = source.slice(typeNode.start + startOffset, typeNode.end + startOffset);
                          if (typeNode.type === 'TSTypeLiteral') {
                              if (id.name === propsVar) {
                                  propsType = typeString;
                                  extractRuntimeProps(typeNode, typeDeclaredProps, declaredTypes);
                              }
                              else if (id.name === slotsVar) {
                                  slotsType = typeString;
                              }
                              else if (id.name === attrsVar) {
                                  attrsType = typeString;
                              }
                          }
                          else if (id.name === emitVar &&
                              typeNode.type === 'TSFunctionType') {
                              emitType = typeString;
                              extractRuntimeEmits(typeNode, typeDeclaredEmits);
                          }
                      }
                  }
              }
          }
          if (node.type === 'TSDeclareFunction' &&
              node.id &&
              node.id.name === emitVar) {
              const index = node.id.start + startOffset;
              s.overwrite(index, index + emitVar.length, '__emit__');
              emitType = `typeof __emit__`;
              extractRuntimeEmits(node, typeDeclaredEmits);
          }
          // move all type declarations to outer scope
          if (node.type.startsWith('TS') ||
              (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type')) {
              recordType(node, declaredTypes);
              s.move(start, end, 0);
          }
          // walk statements & named exports / variable declarations for top level
          // await
          if (node.type === 'VariableDeclaration' ||
              (node.type === 'ExportNamedDeclaration' &&
                  node.declaration &&
                  node.declaration.type === 'VariableDeclaration') ||
              node.type.endsWith('Statement')) {
              walk$1(node, {
                  enter(node) {
                      if (isFunction$3(node)) {
                          this.skip();
                      }
                      if (node.type === 'AwaitExpression') {
                          hasAwait = true;
                      }
                  }
              });
          }
      }
      // 4. check default export to make sure it doesn't reference setup scope
      // variables
      if (needDefaultExportRefCheck) {
          checkDefaultExport(defaultExport, setupScopeVars, imports, setupExports, source, startOffset);
      }
      // 5. remove non-script content
      if (script) {
          if (startOffset < scriptStartOffset) {
              // <script setup> before <script>
              s.remove(endOffset, scriptStartOffset);
              s.remove(scriptEndOffset, source.length);
          }
          else {
              // <script> before <script setup>
              s.remove(0, scriptStartOffset);
              s.remove(scriptEndOffset, startOffset);
              s.remove(endOffset, source.length);
          }
      }
      else {
          // only <script setup>
          s.remove(0, startOffset);
          s.remove(endOffset, source.length);
      }
      // 5. finalize setup argument signature.
      let args = ``;
      if (isTS) {
          if (slotsType === '__Slots__') {
              s.prepend(`import { Slots as __Slots__ } from 'vue'\n`);
          }
          const ctxType = `{
  emit: ${emitType},
  slots: ${slotsType},
  attrs: ${attrsType}
}`;
          if (hasExplicitSignature) {
              // inject types to user signature
              args = setupValue;
              const ss = new MagicString(args);
              if (propsASTNode) {
                  // compensate for () wraper offset
                  ss.appendRight(propsASTNode.end - 1, `: ${propsType}`);
              }
              if (setupCtxASTNode) {
                  ss.appendRight(setupCtxASTNode.end - 1, `: ${ctxType}`);
              }
              args = ss.toString();
          }
      }
      else {
          args = hasExplicitSignature ? setupValue : ``;
      }
      // 6. wrap setup code with function.
      // export the content of <script setup> as a named export, `setup`.
      // this allows `import { setup } from '*.vue'` for testing purposes.
      s.prependLeft(startOffset, `\nexport ${hasAwait ? `async ` : ``}function setup(${args}) {\n`);
      // generate return statement
      let returned = `{ ${Object.keys(setupExports).join(', ')} }`;
      // handle `export * from`. We need to call `toRefs` on the imported module
      // object before merging.
      if (exportAllIndex > 0) {
          s.prepend(`import { toRefs as __toRefs__ } from 'vue'\n`);
          for (let i = 0; i < exportAllIndex; i++) {
              returned += `,\n  __toRefs__(__export_all_${i}__)`;
          }
          returned = `Object.assign(\n  ${returned}\n)`;
      }
      // inject `useCssVars` calls
      if (hasCssVars) {
          s.prepend(`import { useCssVars as __useCssVars__ } from 'vue'\n`);
          for (const style of styles) {
              const vars = style.attrs.vars;
              if (typeof vars === 'string') {
                  s.prependRight(endOffset, `\n${genCssVarsCode(vars, !!style.scoped, setupExports)}`);
              }
          }
      }
      s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`);
      // 7. finalize default export
      if (isTS) {
          // for TS, make sure the exported type is still valid type with
          // correct props information
          s.prepend(`import { defineComponent as __define__ } from 'vue'\n`);
          // we have to use object spread for types to be merged properly
          // user's TS setting should compile it down to proper targets
          const def = defaultExport ? `\n  ...${defaultTempVar},` : ``;
          const runtimeProps = genRuntimeProps(typeDeclaredProps);
          const runtimeEmits = genRuntimeEmits(typeDeclaredEmits);
          s.append(`export default __define__({${def}${runtimeProps}${runtimeEmits}\n  setup\n})`);
      }
      else {
          if (defaultExport) {
              s.append(`${defaultTempVar}.setup = setup\nexport default ${defaultTempVar}`);
          }
          else {
              s.append(`export default { setup }`);
          }
      }
      // 8. expose bindings for template compiler optimization
      if (scriptAst) {
          Object.assign(bindings, analyzeScriptBindings(scriptAst));
      }
      Object.keys(setupExports).forEach(key => {
          bindings[key] = 'setup';
      });
      Object.keys(typeDeclaredProps).forEach(key => {
          bindings[key] = 'props';
      });
      Object.assign(bindings, analyzeScriptBindings(scriptSetupAst));
      s.trim();
      return {
          ...scriptSetup,
          bindings,
          content: s.toString(),
          map: s.generateMap({
              source: filename,
              hires: true,
              includeContent: true
          }),
          scriptAst,
          scriptSetupAst
      };
  }
  function walkDeclaration(node, bindings) {
      if (node.type === 'VariableDeclaration') {
          // export const foo = ...
          for (const { id } of node.declarations) {
              if (id.type === 'Identifier') {
                  bindings[id.name] = true;
              }
              else if (id.type === 'ObjectPattern') {
                  walkObjectPattern(id, bindings);
              }
              else if (id.type === 'ArrayPattern') {
                  walkArrayPattern(id, bindings);
              }
          }
      }
      else if (node.type === 'FunctionDeclaration' ||
          node.type === 'ClassDeclaration') {
          // export function foo() {} / export class Foo {}
          // export declarations must be named.
          bindings[node.id.name] = true;
      }
  }
  function walkObjectPattern(node, bindings) {
      for (const p of node.properties) {
          if (p.type === 'ObjectProperty') {
              // key can only be Identifier in ObjectPattern
              if (p.key.type === 'Identifier') {
                  if (p.key === p.value) {
                      // const { x } = ...
                      bindings[p.key.name] = true;
                  }
                  else {
                      walkPattern(p.value, bindings);
                  }
              }
          }
          else {
              // ...rest
              // argument can only be identifer when destructuring
              bindings[p.argument.name] = true;
          }
      }
  }
  function walkArrayPattern(node, bindings) {
      for (const e of node.elements) {
          e && walkPattern(e, bindings);
      }
  }
  function walkPattern(node, bindings) {
      if (node.type === 'Identifier') {
          bindings[node.name] = true;
      }
      else if (node.type === 'RestElement') {
          // argument can only be identifer when destructuring
          bindings[node.argument.name] = true;
      }
      else if (node.type === 'ObjectPattern') {
          walkObjectPattern(node, bindings);
      }
      else if (node.type === 'ArrayPattern') {
          walkArrayPattern(node, bindings);
      }
      else if (node.type === 'AssignmentPattern') {
          if (node.left.type === 'Identifier') {
              bindings[node.left.name] = true;
          }
          else {
              walkPattern(node.left, bindings);
          }
      }
  }
  function recordType(node, declaredTypes) {
      if (node.type === 'TSInterfaceDeclaration') {
          declaredTypes[node.id.name] = [`Object`];
      }
      else if (node.type === 'TSTypeAliasDeclaration') {
          declaredTypes[node.id.name] = inferRuntimeType(node.typeAnnotation, declaredTypes);
      }
      else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
          recordType(node.declaration, declaredTypes);
      }
  }
  function extractRuntimeProps(node, props, declaredTypes) {
      for (const m of node.members) {
          if (m.type === 'TSPropertySignature' && m.key.type === 'Identifier') {
              props[m.key.name] = {
                  key: m.key.name,
                  required: !m.optional,
                  type:  m.typeAnnotation
                      ? inferRuntimeType(m.typeAnnotation.typeAnnotation, declaredTypes)
                      : [`null`]
              };
          }
      }
  }
  function inferRuntimeType(node, declaredTypes) {
      switch (node.type) {
          case 'TSStringKeyword':
              return ['String'];
          case 'TSNumberKeyword':
              return ['Number'];
          case 'TSBooleanKeyword':
              return ['Boolean'];
          case 'TSObjectKeyword':
              return ['Object'];
          case 'TSTypeLiteral':
              // TODO (nice to have) generate runtime property validation
              return ['Object'];
          case 'TSFunctionType':
              return ['Function'];
          case 'TSArrayType':
          case 'TSTupleType':
              // TODO (nice to have) generate runtime element type/length checks
              return ['Array'];
          case 'TSLiteralType':
              switch (node.literal.type) {
                  case 'StringLiteral':
                      return ['String'];
                  case 'BooleanLiteral':
                      return ['Boolean'];
                  case 'NumericLiteral':
                  case 'BigIntLiteral':
                      return ['Number'];
                  default:
                      return [`null`];
              }
          case 'TSTypeReference':
              if (node.typeName.type === 'Identifier') {
                  if (declaredTypes[node.typeName.name]) {
                      return declaredTypes[node.typeName.name];
                  }
                  switch (node.typeName.name) {
                      case 'Array':
                      case 'Function':
                      case 'Object':
                      case 'Set':
                      case 'Map':
                      case 'WeakSet':
                      case 'WeakMap':
                          return [node.typeName.name];
                      case 'Record':
                      case 'Partial':
                      case 'Readonly':
                      case 'Pick':
                      case 'Omit':
                      case 'Exclude':
                      case 'Extract':
                      case 'Required':
                      case 'InstanceType':
                          return ['Object'];
                  }
              }
              return [`null`];
          case 'TSUnionType':
              return [
                  ...new Set([].concat(node.types.map(t => inferRuntimeType(t, declaredTypes))))
              ];
          case 'TSIntersectionType':
              return ['Object'];
          default:
              return [`null`]; // no runtime check
      }
  }
  function genRuntimeProps(props) {
      const keys = Object.keys(props);
      if (!keys.length) {
          return ``;
      }
      return `\n  props: {\n    ${keys
        .map(key => {
        const { type, required } = props[key];
        return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required} }`;
    })
        .join(',\n    ')}\n  } as unknown as undefined,`;
  }
  function toRuntimeTypeString(types) {
      return types.some(t => t === 'null')
          ? `null`
          : types.length > 1
              ? `[${types.join(', ')}]`
              : types[0];
  }
  function extractRuntimeEmits(node, emits) {
      const eventName = node.type === 'TSDeclareFunction' ? node.params[0] : node.parameters[0];
      if (eventName.type === 'Identifier' &&
          eventName.typeAnnotation &&
          eventName.typeAnnotation.type === 'TSTypeAnnotation') {
          const typeNode = eventName.typeAnnotation.typeAnnotation;
          if (typeNode.type === 'TSLiteralType') {
              emits.add(String(typeNode.literal.value));
          }
          else if (typeNode.type === 'TSUnionType') {
              for (const t of typeNode.types) {
                  if (t.type === 'TSLiteralType') {
                      emits.add(String(t.literal.value));
                  }
              }
          }
      }
  }
  function genRuntimeEmits(emits) {
      return emits.size
          ? `\n  emits: [${Array.from(emits)
            .map(p => JSON.stringify(p))
            .join(', ')}] as unknown as undefined,`
          : ``;
  }
  /**
   * export default {} inside `<script setup>` cannot access variables declared
   * inside since it's hoisted. Walk and check to make sure.
   */
  function checkDefaultExport(root, scopeVars, imports, exports, source, offset) {
      const knownIds = Object.create(null);
      walk$1(root, {
          enter(node, parent) {
              if (node.type === 'Identifier') {
                  if (!knownIds[node.name] &&
                      !isStaticPropertyKey$1(node, parent) &&
                      (scopeVars[node.name] || (!imports[node.name] && exports[node.name]))) {
                      throw new Error(`\`export default\` in <script setup> cannot reference locally ` +
                          `declared variables because it will be hoisted outside of the ` +
                          `setup() function. If your component options requires initialization ` +
                          `in the module scope, use a separate normal <script> to export ` +
                          `the options instead.\n\n` +
                          generateCodeFrame(source, node.start + offset, node.end + offset));
                  }
              }
              else if (isFunction$3(node)) {
                  // walk function expressions and add its arguments to known identifiers
                  // so that we don't prefix them
                  node.params.forEach(p => walk$1(p, {
                      enter(child, parent) {
                          if (child.type === 'Identifier' &&
                              // do not record as scope variable if is a destructured key
                              !isStaticPropertyKey$1(child, parent) &&
                              // do not record if this is a default value
                              // assignment of a destructured variable
                              !(parent &&
                                  parent.type === 'AssignmentPattern' &&
                                  parent.right === child)) {
                              const { name } = child;
                              if (node.scopeIds && node.scopeIds.has(name)) {
                                  return;
                              }
                              if (name in knownIds) {
                                  knownIds[name]++;
                              }
                              else {
                                  knownIds[name] = 1;
                              }
                              (node.scopeIds || (node.scopeIds = new Set())).add(name);
                          }
                      }
                  }));
              }
          },
          leave(node) {
              if (node.scopeIds) {
                  node.scopeIds.forEach((id) => {
                      knownIds[id]--;
                      if (knownIds[id] === 0) {
                          delete knownIds[id];
                      }
                  });
              }
          }
      });
  }
  function isStaticPropertyKey$1(node, parent) {
      return (parent &&
          (parent.type === 'ObjectProperty' || parent.type === 'ObjectMethod') &&
          !parent.computed &&
          parent.key === node);
  }
  function isFunction$3(node) {
      return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
  }
  function getObjectExpressionKeys(node) {
      const keys = [];
      for (const prop of node.properties) {
          if ((prop.type === 'ObjectProperty' || prop.type === 'ObjectMethod') &&
              !prop.computed) {
              if (prop.key.type === 'Identifier') {
                  keys.push(prop.key.name);
              }
              else if (prop.key.type === 'StringLiteral') {
                  keys.push(prop.key.value);
              }
          }
      }
      return keys;
  }
  function getArrayExpressionKeys(node) {
      const keys = [];
      for (const element of node.elements) {
          if (element && element.type === 'StringLiteral') {
              keys.push(element.value);
          }
      }
      return keys;
  }
  function getObjectOrArrayExpressionKeys(property) {
      if (property.value.type === 'ArrayExpression') {
          return getArrayExpressionKeys(property.value);
      }
      if (property.value.type === 'ObjectExpression') {
          return getObjectExpressionKeys(property.value);
      }
      return [];
  }
  /**
   * Analyze bindings in normal `<script>`
   * Note that `compileScriptSetup` already analyzes bindings as part of its
   * compilation process so this should only be used on single `<script>` SFCs.
   */
  function analyzeScriptBindings(ast) {
      const bindings = {};
      for (const node of ast) {
          if (node.type === 'ExportDefaultDeclaration' &&
              node.declaration.type === 'ObjectExpression') {
              for (const property of node.declaration.properties) {
                  if (property.type === 'ObjectProperty' &&
                      !property.computed &&
                      property.key.type === 'Identifier') {
                      // props
                      if (property.key.name === 'props') {
                          // props: ['foo']
                          // props: { foo: ... }
                          for (const key of getObjectOrArrayExpressionKeys(property)) {
                              bindings[key] = 'props';
                          }
                      }
                      // inject
                      else if (property.key.name === 'inject') {
                          // inject: ['foo']
                          // inject: { foo: {} }
                          for (const key of getObjectOrArrayExpressionKeys(property)) {
                              bindings[key] = 'options';
                          }
                      }
                      // computed & methods
                      else if (property.value.type === 'ObjectExpression' &&
                          (property.key.name === 'computed' ||
                              property.key.name === 'methods')) {
                          // methods: { foo() {} }
                          // computed: { foo() {} }
                          for (const key of getObjectExpressionKeys(property.value)) {
                              bindings[key] = 'options';
                          }
                      }
                  }
                  // setup & data
                  else if (property.type === 'ObjectMethod' &&
                      property.key.type === 'Identifier' &&
                      (property.key.name === 'setup' || property.key.name === 'data')) {
                      for (const bodyItem of property.body.body) {
                          // setup() {
                          //   return {
                          //     foo: null
                          //   }
                          // }
                          if (bodyItem.type === 'ReturnStatement' &&
                              bodyItem.argument &&
                              bodyItem.argument.type === 'ObjectExpression') {
                              for (const key of getObjectExpressionKeys(bodyItem.argument)) {
                                  bindings[key] = property.key.name;
                              }
                          }
                      }
                  }
              }
          }
      }
      return bindings;
  }

  exports.compileScript = compileScript;
  exports.compileStyle = compileStyle;
  exports.compileStyleAsync = compileStyleAsync;
  exports.compileTemplate = compileTemplate;
  exports.generateCodeFrame = generateCodeFrame;
  exports.parse = parse$1;
  exports.rewriteDefault = rewriteDefault;

  return exports;

}({}, postcss));