text: /* eslint-disable */
  import CodeMirror from 'codemirror'
  ;(function(mod) {
    if (typeof exports == 'object' && typeof module == 'object')
      // CommonJS
      mod(require('codemirror/lib/codemirror'))
    else if (typeof define == 'function' && define.amd)
      // AMD
      define(['../../lib/codemirror'], mod) // Plain browser env
    else mod(CodeMirror)
  })(function(CodeMirror) {
    'use strict'
  
    var Pos = CodeMirror.Pos
  
    function getHints(cm, options) {
      var tags = options && options.schemaInfo
      var quote = (options && options.quoteChar) || '"'
      if (!tags) return
      var cur = cm.getCursor(),
        token = cm.getTokenAt(cur)
      token.type = token.type || 'trigger'
      if (token.end > cur.ch) {
        token.end = cur.ch
        token.string = token.string.slice(0, cur.ch - token.start)
      }
      var inner = CodeMirror.innerMode(cm.getMode(), token.state)
      if (inner.mode.name != 'xml') return
      var result = [],
        replaceToken = false,
        prefix
      var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string)
      var tagName = tag && /^\w/.test(token.string)
      var tagStart
      var trigger = token.type == 'trigger'
      var triggerName = trigger
  
      if (tagName) {
        var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start)
        var tagType = /<\/$/.test(before) ? 'close' : /<$/.test(before) ? 'open' : null
        if (tagType) tagStart = token.start - (tagType == 'close' ? 2 : 1)
      } else if (tag && token.string == '<') {
        tagType = 'open'
      } else if (tag && token.string == '</') {
        tagType = 'close'
      }
  
      if (triggerName) {
        var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start)
        var triggerType = /\+$/.test(before) ? 'trigger' : null
        tagStart = token.start
      }
  
      if (((!tag && !inner.state.tagName) || tagType) && options.tags == 'mjml') {
        if (tagName) prefix = token.string
        replaceToken = tagType
        var cx = inner.state.context,
          curTag = cx && tags[cx.tagName]
        var childList = cx ? curTag && curTag.children : tags['!top']
        if (childList && tagType != 'close') {
          for (var i = 0; i < childList.length; ++i)
            if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0) result.push('<' + childList[i])
        } else if (tagType != 'close') {
          for (var name in tags)
            if (
              tags.hasOwnProperty(name) &&
              name != '!top' &&
              name != '!attrs' &&
              (!prefix || name.lastIndexOf(prefix, 0) == 0)
            ) {
              result.push('<' + name)
            }
        }
        if (cx && (!prefix || (tagType == 'close' && cx.tagName.lastIndexOf(prefix, 0) == 0)))
          result.push('</' + cx.tagName + '>')
      } else if (((!tag && !inner.state.tagName) || triggerType) && options.tags == 'snippets') {
        if (triggerName) prefix = token.string
        replaceToken = triggerType
  
        for (var name in tags)
          if (tags.hasOwnProperty(name) && (!prefix || name.lastIndexOf(prefix, 0) == 0)) {
            replaceToken = true
            result.push(name)
          }
      } else {
        // Attribute completion
        var curTag = tags[inner.state.tagName],
          attrs = curTag && curTag.attrs
        var globalAttrs = tags['!attrs']
        if (!attrs && !globalAttrs) return
        if (!attrs) {
          attrs = globalAttrs
        } else if (globalAttrs) {
          // Combine tag-local and global attributes
          var set = {}
          for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm]
          for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm]
          attrs = set
        }
        if (token.type == 'string' || token.string == '=') {
          // A value
          var before = cm.getRange(
            Pos(cur.line, Math.max(0, cur.ch - 60)),
            Pos(cur.line, token.type == 'string' ? token.start : token.end),
          )
          var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/),
            atValues
          if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return
          if (typeof atValues == 'function') atValues = atValues.call(this, cm) // Functions can be used to supply values for autocomplete widget
          if (token.type == 'string') {
            prefix = token.string
            var n = 0
            if (/['"]/.test(token.string.charAt(0))) {
              quote = token.string.charAt(0)
              prefix = token.string.slice(1)
              n++
            }
            var len = token.string.length
            if (/['"]/.test(token.string.charAt(len - 1))) {
              quote = token.string.charAt(len - 1)
              prefix = token.string.substr(n, len - 2)
            }
            replaceToken = true
          }
          for (var i = 0; i < atValues.length; ++i)
            if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0)
              result.push(quote + atValues[i] + quote)
        } else {
          // An attribute name
          if (token.type == 'attribute') {
            prefix = token.string
            replaceToken = true
          }
          for (var attr in attrs)
            if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0))
              result.push(attr)
        }
      }
      return {
        list: result,
        from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
        to: replaceToken ? Pos(cur.line, token.end) : cur,
      }
    }
  
    CodeMirror.registerHelper('hint', 'xml', getHints)
  })
  