// ------------------------------------------------
// Alpine.js v2.8.2
// ------------------------------------------------

;(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined'
    ? (module.exports = factory())
    : typeof define === 'function' && define.amd
    ? define(factory)
    : ((global = global || self), (global.Alpine = factory()))
})(this, function () {
  'use strict'

  function _defineProperty(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      })
    } else {
      obj[key] = value
    }

    return obj
  }

  function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object)

    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(object)
      if (enumerableOnly)
        symbols = symbols.filter(function (sym) {
          return Object.getOwnPropertyDescriptor(object, sym).enumerable
        })
      keys.push.apply(keys, symbols)
    }

    return keys
  }

  function _objectSpread2(target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i] != null ? arguments[i] : {}

      if (i % 2) {
        ownKeys(Object(source), true).forEach(function (key) {
          _defineProperty(target, key, source[key])
        })
      } else if (Object.getOwnPropertyDescriptors) {
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source))
      } else {
        ownKeys(Object(source)).forEach(function (key) {
          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key))
        })
      }
    }

    return target
  }

  // Thanks @stimulus:
  // https://github.com/stimulusjs/stimulus/blob/master/packages/%40stimulus/core/src/application.ts
  function domReady() {
    return new Promise(resolve => {
      if (document.readyState == 'loading') {
        document.addEventListener('DOMContentLoaded', resolve)
      } else {
        resolve()
      }
    })
  }
  function arrayUnique(array) {
    return Array.from(new Set(array))
  }
  function isTesting() {
    return navigator.userAgent.includes('Node.js') || navigator.userAgent.includes('jsdom')
  }
  function checkedAttrLooseCompare(valueA, valueB) {
    return valueA == valueB
  }
  function warnIfMalformedTemplate(el, directive) {
    if (el.tagName.toLowerCase() !== 'template') {
      console.warn(
        `Alpine: [${directive}] directive should only be added to <template> tags. See https://github.com/alpinejs/alpine#${directive}`
      )
    } else if (el.content.childElementCount !== 1) {
      console.warn(
        `Alpine: <template> tag with [${directive}] encountered with an unexpected number of root elements. Make sure <template> has a single root element. `
      )
    }
  }
  function kebabCase(subject) {
    return subject
      .replace(/([a-z])([A-Z])/g, '$1-$2')
      .replace(/[_\s]/, '-')
      .toLowerCase()
  }
  function camelCase(subject) {
    return subject.toLowerCase().replace(/-(\w)/g, (match, char) => char.toUpperCase())
  }
  function walk(el, callback) {
    if (callback(el) === false) return
    let node = el.firstElementChild

    while (node) {
      walk(node, callback)
      node = node.nextElementSibling
    }
  }
  function debounce(func, wait) {
    var timeout
    return function () {
      var context = this,
        args = arguments

      var later = function later() {
        timeout = null
        func.apply(context, args)
      }

      clearTimeout(timeout)
      timeout = setTimeout(later, wait)
    }
  }

  const handleError = (el, expression, error) => {
    console.warn(`Alpine Error: "${error}"\n\nExpression: "${expression}"\nElement:`, el)

    if (!isTesting()) {
      Object.assign(error, {
        el,
        expression
      })
      throw error
    }
  }

  function tryCatch(cb, { el, expression }) {
    try {
      const value = cb()
      return value instanceof Promise ? value.catch(e => handleError(el, expression, e)) : value
    } catch (e) {
      handleError(el, expression, e)
    }
  }

  function saferEval(el, expression, dataContext, additionalHelperVariables = {}) {
    return tryCatch(
      () => {
        if (typeof expression === 'function') {
          return expression.call(dataContext)
        }

        return new Function(
          ['$data', ...Object.keys(additionalHelperVariables)],
          `var __alpine_result; with($data) { __alpine_result = ${expression} }; return __alpine_result`
        )(dataContext, ...Object.values(additionalHelperVariables))
      },
      {
        el,
        expression
      }
    )
  }
  function saferEvalNoReturn(el, expression, dataContext, additionalHelperVariables = {}) {
    return tryCatch(
      () => {
        if (typeof expression === 'function') {
          return Promise.resolve(expression.call(dataContext, additionalHelperVariables['$event']))
        }

        let AsyncFunction = Function
        /* MODERN-ONLY:START */

        AsyncFunction = Object.getPrototypeOf(async function () {}).constructor
        /* MODERN-ONLY:END */
        // For the cases when users pass only a function reference to the caller: `x-on:click="foo"`
        // Where "foo" is a function. Also, we'll pass the function the event instance when we call it.

        if (Object.keys(dataContext).includes(expression)) {
          let methodReference = new Function(
            ['dataContext', ...Object.keys(additionalHelperVariables)],
            `with(dataContext) { return ${expression} }`
          )(dataContext, ...Object.values(additionalHelperVariables))

          if (typeof methodReference === 'function') {
            return Promise.resolve(methodReference.call(dataContext, additionalHelperVariables['$event']))
          } else {
            return Promise.resolve()
          }
        }

        return Promise.resolve(
          new AsyncFunction(
            ['dataContext', ...Object.keys(additionalHelperVariables)],
            `with(dataContext) { ${expression} }`
          )(dataContext, ...Object.values(additionalHelperVariables))
        )
      },
      {
        el,
        expression
      }
    )
  }
  const xAttrRE = /^x-(on|bind|data|text|html|model|if|for|show|cloak|transition|ref|spread)\b/
  function isXAttr(attr) {
    const name = replaceAtAndColonWithStandardSyntax(attr.name)
    return xAttrRE.test(name)
  }
  function getXAttrs(el, component, type) {
    let directives = Array.from(el.attributes).filter(isXAttr).map(parseHtmlAttribute) // Get an object of directives from x-spread.

    let spreadDirective = directives.filter(directive => directive.type === 'spread')[0]

    if (spreadDirective) {
      let spreadObject = saferEval(el, spreadDirective.expression, component.$data) // Add x-spread directives to the pile of existing directives.

      directives = directives.concat(
        Object.entries(spreadObject).map(([name, value]) =>
          parseHtmlAttribute({
            name,
            value
          })
        )
      )
    }

    if (type) return directives.filter(i => i.type === type)
    return sortDirectives(directives)
  }

  function sortDirectives(directives) {
    let directiveOrder = ['bind', 'model', 'show', 'catch-all']
    return directives.sort((a, b) => {
      let typeA = directiveOrder.indexOf(a.type) === -1 ? 'catch-all' : a.type
      let typeB = directiveOrder.indexOf(b.type) === -1 ? 'catch-all' : b.type
      return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB)
    })
  }

  function parseHtmlAttribute({ name, value }) {
    const normalizedName = replaceAtAndColonWithStandardSyntax(name)
    const typeMatch = normalizedName.match(xAttrRE)
    const valueMatch = normalizedName.match(/:([a-zA-Z0-9\-:]+)/)
    const modifiers = normalizedName.match(/\.[^.\]]+(?=[^\]]*$)/g) || []
    return {
      type: typeMatch ? typeMatch[1] : null,
      value: valueMatch ? valueMatch[1] : null,
      modifiers: modifiers.map(i => i.replace('.', '')),
      expression: value
    }
  }
  function isBooleanAttr(attrName) {
    // As per HTML spec table https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute
    // Array roughly ordered by estimated usage
    const booleanAttributes = [
      'disabled',
      'checked',
      'required',
      'readonly',
      'hidden',
      'open',
      'selected',
      'autofocus',
      'itemscope',
      'multiple',
      'novalidate',
      'allowfullscreen',
      'allowpaymentrequest',
      'formnovalidate',
      'autoplay',
      'controls',
      'loop',
      'muted',
      'playsinline',
      'default',
      'ismap',
      'reversed',
      'async',
      'defer',
      'nomodule'
    ]
    return booleanAttributes.includes(attrName)
  }
  function replaceAtAndColonWithStandardSyntax(name) {
    if (name.startsWith('@')) {
      return name.replace('@', 'x-on:')
    } else if (name.startsWith(':')) {
      return name.replace(':', 'x-bind:')
    }

    return name
  }
  function convertClassStringToArray(classList, filterFn = Boolean) {
    return classList.split(' ').filter(filterFn)
  }
  const TRANSITION_TYPE_IN = 'in'
  const TRANSITION_TYPE_OUT = 'out'
  const TRANSITION_CANCELLED = 'cancelled'
  function transitionIn(el, show, reject, component, forceSkip = false) {
    // We don't want to transition on the initial page load.
    if (forceSkip) return show()

    if (el.__x_transition && el.__x_transition.type === TRANSITION_TYPE_IN) {
      // there is already a similar transition going on, this was probably triggered by
      // a change in a different property, let's just leave the previous one doing its job
      return
    }

    const attrs = getXAttrs(el, component, 'transition')
    const showAttr = getXAttrs(el, component, 'show')[0] // If this is triggered by a x-show.transition.

    if (showAttr && showAttr.modifiers.includes('transition')) {
      let modifiers = showAttr.modifiers // If x-show.transition.out, we'll skip the "in" transition.

      if (modifiers.includes('out') && !modifiers.includes('in')) return show()
      const settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out') // If x-show.transition.in...out... only use "in" related modifiers for this transition.

      modifiers = settingBothSidesOfTransition
        ? modifiers.filter((i, index) => index < modifiers.indexOf('out'))
        : modifiers
      transitionHelperIn(el, modifiers, show, reject) // Otherwise, we can assume x-transition:enter.
    } else if (attrs.some(attr => ['enter', 'enter-start', 'enter-end'].includes(attr.value))) {
      transitionClassesIn(el, component, attrs, show, reject)
    } else {
      // If neither, just show that damn thing.
      show()
    }
  }
  function transitionOut(el, hide, reject, component, forceSkip = false) {
    // We don't want to transition on the initial page load.
    if (forceSkip) return hide()

    if (el.__x_transition && el.__x_transition.type === TRANSITION_TYPE_OUT) {
      // there is already a similar transition going on, this was probably triggered by
      // a change in a different property, let's just leave the previous one doing its job
      return
    }

    const attrs = getXAttrs(el, component, 'transition')
    const showAttr = getXAttrs(el, component, 'show')[0]

    if (showAttr && showAttr.modifiers.includes('transition')) {
      let modifiers = showAttr.modifiers
      if (modifiers.includes('in') && !modifiers.includes('out')) return hide()
      const settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out')
      modifiers = settingBothSidesOfTransition
        ? modifiers.filter((i, index) => index > modifiers.indexOf('out'))
        : modifiers
      transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hide, reject)
    } else if (attrs.some(attr => ['leave', 'leave-start', 'leave-end'].includes(attr.value))) {
      transitionClassesOut(el, component, attrs, hide, reject)
    } else {
      hide()
    }
  }
  function transitionHelperIn(el, modifiers, showCallback, reject) {
    // Default values inspired by: https://material.io/design/motion/speed.html#duration
    const styleValues = {
      duration: modifierValue(modifiers, 'duration', 150),
      origin: modifierValue(modifiers, 'origin', 'center'),
      first: {
        opacity: 0,
        scale: modifierValue(modifiers, 'scale', 95)
      },
      second: {
        opacity: 1,
        scale: 100
      }
    }
    transitionHelper(el, modifiers, showCallback, () => {}, reject, styleValues, TRANSITION_TYPE_IN)
  }
  function transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hideCallback, reject) {
    // Make the "out" transition .5x slower than the "in". (Visually better)
    // HOWEVER, if they explicitly set a duration for the "out" transition,
    // use that.
    const duration = settingBothSidesOfTransition
      ? modifierValue(modifiers, 'duration', 150)
      : modifierValue(modifiers, 'duration', 150) / 2
    const styleValues = {
      duration: duration,
      origin: modifierValue(modifiers, 'origin', 'center'),
      first: {
        opacity: 1,
        scale: 100
      },
      second: {
        opacity: 0,
        scale: modifierValue(modifiers, 'scale', 95)
      }
    }
    transitionHelper(el, modifiers, () => {}, hideCallback, reject, styleValues, TRANSITION_TYPE_OUT)
  }

  function modifierValue(modifiers, key, fallback) {
    // If the modifier isn't present, use the default.
    if (modifiers.indexOf(key) === -1) return fallback // If it IS present, grab the value after it: x-show.transition.duration.500ms

    const rawValue = modifiers[modifiers.indexOf(key) + 1]
    if (!rawValue) return fallback

    if (key === 'scale') {
      // Check if the very next value is NOT a number and return the fallback.
      // If x-show.transition.scale, we'll use the default scale value.
      // That is how a user opts out of the opacity transition.
      if (!isNumeric(rawValue)) return fallback
    }

    if (key === 'duration') {
      // Support x-show.transition.duration.500ms && duration.500
      let match = rawValue.match(/([0-9]+)ms/)
      if (match) return match[1]
    }

    if (key === 'origin') {
      // Support chaining origin directions: x-show.transition.top.right
      if (['top', 'right', 'left', 'center', 'bottom'].includes(modifiers[modifiers.indexOf(key) + 2])) {
        return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(' ')
      }
    }

    return rawValue
  }

  function transitionHelper(el, modifiers, hook1, hook2, reject, styleValues, type) {
    // clear the previous transition if exists to avoid caching the wrong styles
    if (el.__x_transition) {
      el.__x_transition.cancel && el.__x_transition.cancel()
    } // If the user set these style values, we'll put them back when we're done with them.

    const opacityCache = el.style.opacity
    const transformCache = el.style.transform
    const transformOriginCache = el.style.transformOrigin // If no modifiers are present: x-show.transition, we'll default to both opacity and scale.

    const noModifiers = !modifiers.includes('opacity') && !modifiers.includes('scale')
    const transitionOpacity = noModifiers || modifiers.includes('opacity')
    const transitionScale = noModifiers || modifiers.includes('scale') // These are the explicit stages of a transition (same stages for in and for out).
    // This way you can get a birds eye view of the hooks, and the differences
    // between them.

    const stages = {
      start() {
        if (transitionOpacity) el.style.opacity = styleValues.first.opacity
        if (transitionScale) el.style.transform = `scale(${styleValues.first.scale / 100})`
      },

      during() {
        if (transitionScale) el.style.transformOrigin = styleValues.origin
        el.style.transitionProperty = [transitionOpacity ? `opacity` : ``, transitionScale ? `transform` : ``]
          .join(' ')
          .trim()
        el.style.transitionDuration = `${styleValues.duration / 1000}s`
        el.style.transitionTimingFunction = `cubic-bezier(0.4, 0.0, 0.2, 1)`
      },

      show() {
        hook1()
      },

      end() {
        if (transitionOpacity) el.style.opacity = styleValues.second.opacity
        if (transitionScale) el.style.transform = `scale(${styleValues.second.scale / 100})`
      },

      hide() {
        hook2()
      },

      cleanup() {
        if (transitionOpacity) el.style.opacity = opacityCache
        if (transitionScale) el.style.transform = transformCache
        if (transitionScale) el.style.transformOrigin = transformOriginCache
        el.style.transitionProperty = null
        el.style.transitionDuration = null
        el.style.transitionTimingFunction = null
      }
    }
    transition(el, stages, type, reject)
  }

  const ensureStringExpression = (expression, el, component) => {
    return typeof expression === 'function' ? component.evaluateReturnExpression(el, expression) : expression
  }

  function transitionClassesIn(el, component, directives, showCallback, reject) {
    const enter = convertClassStringToArray(
      ensureStringExpression(
        (
          directives.find(i => i.value === 'enter') || {
            expression: ''
          }
        ).expression,
        el,
        component
      )
    )
    const enterStart = convertClassStringToArray(
      ensureStringExpression(
        (
          directives.find(i => i.value === 'enter-start') || {
            expression: ''
          }
        ).expression,
        el,
        component
      )
    )
    const enterEnd = convertClassStringToArray(
      ensureStringExpression(
        (
          directives.find(i => i.value === 'enter-end') || {
            expression: ''
          }
        ).expression,
        el,
        component
      )
    )
    transitionClasses(el, enter, enterStart, enterEnd, showCallback, () => {}, TRANSITION_TYPE_IN, reject)
  }
  function transitionClassesOut(el, component, directives, hideCallback, reject) {
    const leave = convertClassStringToArray(
      ensureStringExpression(
        (
          directives.find(i => i.value === 'leave') || {
            expression: ''
          }
        ).expression,
        el,
        component
      )
    )
    const leaveStart = convertClassStringToArray(
      ensureStringExpression(
        (
          directives.find(i => i.value === 'leave-start') || {
            expression: ''
          }
        ).expression,
        el,
        component
      )
    )
    const leaveEnd = convertClassStringToArray(
      ensureStringExpression(
        (
          directives.find(i => i.value === 'leave-end') || {
            expression: ''
          }
        ).expression,
        el,
        component
      )
    )
    transitionClasses(el, leave, leaveStart, leaveEnd, () => {}, hideCallback, TRANSITION_TYPE_OUT, reject)
  }
  function transitionClasses(el, classesDuring, classesStart, classesEnd, hook1, hook2, type, reject) {
    // clear the previous transition if exists to avoid caching the wrong classes
    if (el.__x_transition) {
      el.__x_transition.cancel && el.__x_transition.cancel()
    }

    const originalClasses = el.__x_original_classes || []
    const stages = {
      start() {
        el.classList.add(...classesStart)
      },

      during() {
        el.classList.add(...classesDuring)
      },

      show() {
        hook1()
      },

      end() {
        // Don't remove classes that were in the original class attribute.
        el.classList.remove(...classesStart.filter(i => !originalClasses.includes(i)))
        el.classList.add(...classesEnd)
      },

      hide() {
        hook2()
      },

      cleanup() {
        el.classList.remove(...classesDuring.filter(i => !originalClasses.includes(i)))
        el.classList.remove(...classesEnd.filter(i => !originalClasses.includes(i)))
      }
    }
    transition(el, stages, type, reject)
  }
  function transition(el, stages, type, reject) {
    const finish = once(() => {
      stages.hide() // Adding an "isConnected" check, in case the callback
      // removed the element from the DOM.

      if (el.isConnected) {
        stages.cleanup()
      }

      delete el.__x_transition
    })
    el.__x_transition = {
      // Set transition type so we can avoid clearing transition if the direction is the same
      type: type,
      // create a callback for the last stages of the transition so we can call it
      // from different point and early terminate it. Once will ensure that function
      // is only called one time.
      cancel: once(() => {
        reject(TRANSITION_CANCELLED)
        finish()
      }),
      finish,
      // This store the next animation frame so we can cancel it
      nextFrame: null
    }
    stages.start()
    stages.during()
    el.__x_transition.nextFrame = requestAnimationFrame(() => {
      // Note: Safari's transitionDuration property will list out comma separated transition durations
      // for every single transition property. Let's grab the first one and call it a day.
      let duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, '').replace('s', '')) * 1000

      if (duration === 0) {
        duration = Number(getComputedStyle(el).animationDuration.replace('s', '')) * 1000
      }

      stages.show()
      el.__x_transition.nextFrame = requestAnimationFrame(() => {
        stages.end()
        setTimeout(el.__x_transition.finish, duration)
      })
    })
  }
  function isNumeric(subject) {
    return !Array.isArray(subject) && !isNaN(subject)
  } // Thanks @vuejs
  // https://github.com/vuejs/vue/blob/4de4649d9637262a9b007720b59f80ac72a5620c/src/shared/util.js

  function once(callback) {
    let called = false
    return function () {
      if (!called) {
        called = true
        callback.apply(this, arguments)
      }
    }
  }

  function handleForDirective(component, templateEl, expression, initialUpdate, extraVars) {
    warnIfMalformedTemplate(templateEl, 'x-for')
    let iteratorNames =
      typeof expression === 'function'
        ? parseForExpression(component.evaluateReturnExpression(templateEl, expression))
        : parseForExpression(expression)
    let items = evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(
      component,
      templateEl,
      iteratorNames,
      extraVars
    ) // As we walk the array, we'll also walk the DOM (updating/creating as we go).

    let currentEl = templateEl
    items.forEach((item, index) => {
      let iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars())
      let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables)
      let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey) // If we haven't found a matching key, insert the element at the current position.

      if (!nextEl) {
        nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl) // And transition it in if it's not the first page load.

        transitionIn(
          nextEl,
          () => {},
          () => {},
          component,
          initialUpdate
        )
        nextEl.__x_for = iterationScopeVariables
        component.initializeElements(nextEl, () => nextEl.__x_for) // Otherwise update the element we found.
      } else {
        // Temporarily remove the key indicator to allow the normal "updateElements" to work.
        delete nextEl.__x_for_key
        nextEl.__x_for = iterationScopeVariables
        component.updateElements(nextEl, () => nextEl.__x_for)
      }

      currentEl = nextEl
      currentEl.__x_for_key = currentKey
    })
    removeAnyLeftOverElementsFromPreviousUpdate(currentEl, component)
  } // This was taken from VueJS 2.* core. Thanks Vue!

  function parseForExpression(expression) {
    let forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/
    let stripParensRE = /^\(|\)$/g
    let forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
    let inMatch = String(expression).match(forAliasRE)
    if (!inMatch) return
    let res = {}
    res.items = inMatch[2].trim()
    let item = inMatch[1].trim().replace(stripParensRE, '')
    let iteratorMatch = item.match(forIteratorRE)

    if (iteratorMatch) {
      res.item = item.replace(forIteratorRE, '').trim()
      res.index = iteratorMatch[1].trim()

      if (iteratorMatch[2]) {
        res.collection = iteratorMatch[2].trim()
      }
    } else {
      res.item = item
    }

    return res
  }

  function getIterationScopeVariables(iteratorNames, item, index, items, extraVars) {
    // We must create a new object, so each iteration has a new scope
    let scopeVariables = extraVars ? _objectSpread2({}, extraVars) : {}
    scopeVariables[iteratorNames.item] = item
    if (iteratorNames.index) scopeVariables[iteratorNames.index] = index
    if (iteratorNames.collection) scopeVariables[iteratorNames.collection] = items
    return scopeVariables
  }

  function generateKeyForIteration(component, el, index, iterationScopeVariables) {
    let bindKeyAttribute = getXAttrs(el, component, 'bind').filter(attr => attr.value === 'key')[0] // If the dev hasn't specified a key, just return the index of the iteration.

    if (!bindKeyAttribute) return index
    return component.evaluateReturnExpression(el, bindKeyAttribute.expression, () => iterationScopeVariables)
  }

  function evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, el, iteratorNames, extraVars) {
    let ifAttribute = getXAttrs(el, component, 'if')[0]

    if (ifAttribute && !component.evaluateReturnExpression(el, ifAttribute.expression)) {
      return []
    }

    let items = component.evaluateReturnExpression(el, iteratorNames.items, extraVars) // This adds support for the `i in n` syntax.

    if (isNumeric(items) && items >= 0) {
      items = Array.from(Array(items).keys(), i => i + 1)
    }

    return items
  }

  function addElementInLoopAfterCurrentEl(templateEl, currentEl) {
    let clone = document.importNode(templateEl.content, true)
    currentEl.parentElement.insertBefore(clone, currentEl.nextElementSibling)
    return currentEl.nextElementSibling
  }

  function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
    if (!nextEl) return // If we are already past the x-for generated elements, we don't need to look ahead.

    if (nextEl.__x_for_key === undefined) return // If the the key's DO match, no need to look ahead.

    if (nextEl.__x_for_key === currentKey) return nextEl // If they don't, we'll look ahead for a match.
    // If we find it, we'll move it to the current position in the loop.

    let tmpNextEl = nextEl

    while (tmpNextEl) {
      if (tmpNextEl.__x_for_key === currentKey) {
        return tmpNextEl.parentElement.insertBefore(tmpNextEl, nextEl)
      }

      tmpNextEl =
        tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined
          ? tmpNextEl.nextElementSibling
          : false
    }
  }

  function removeAnyLeftOverElementsFromPreviousUpdate(currentEl, component) {
    var nextElementFromOldLoop =
      currentEl.nextElementSibling && currentEl.nextElementSibling.__x_for_key !== undefined
        ? currentEl.nextElementSibling
        : false

    while (nextElementFromOldLoop) {
      let nextElementFromOldLoopImmutable = nextElementFromOldLoop
      let nextSibling = nextElementFromOldLoop.nextElementSibling
      transitionOut(
        nextElementFromOldLoop,
        () => {
          nextElementFromOldLoopImmutable.remove()
        },
        () => {},
        component
      )
      nextElementFromOldLoop = nextSibling && nextSibling.__x_for_key !== undefined ? nextSibling : false
    }
  }

  function handleAttributeBindingDirective(component, el, attrName, expression, extraVars, attrType, modifiers) {
    var value = component.evaluateReturnExpression(el, expression, extraVars)

    if (attrName === 'value') {
      if (Alpine.ignoreFocusedForValueBinding && document.activeElement.isSameNode(el)) return // If nested model key is undefined, set the default value to empty string.

      if (value === undefined && String(expression).match(/\./)) {
        value = ''
      }

      if (el.type === 'radio') {
        // Set radio value from x-bind:value, if no "value" attribute exists.
        // If there are any initial state values, radio will have a correct
        // "checked" value since x-bind:value is processed before x-model.
        if (el.attributes.value === undefined && attrType === 'bind') {
          el.value = value
        } else if (attrType !== 'bind') {
          el.checked = checkedAttrLooseCompare(el.value, value)
        }
      } else if (el.type === 'checkbox') {
        // If we are explicitly binding a string to the :value, set the string,
        // If the value is a boolean, leave it alone, it will be set to "on"
        // automatically.
        if (typeof value !== 'boolean' && ![null, undefined].includes(value) && attrType === 'bind') {
          el.value = String(value)
        } else if (attrType !== 'bind') {
          if (Array.isArray(value)) {
            // I'm purposely not using Array.includes here because it's
            // strict, and because of Numeric/String mis-casting, I
            // want the "includes" to be "fuzzy".
            el.checked = value.some(val => checkedAttrLooseCompare(val, el.value))
          } else {
            el.checked = !!value
          }
        }
      } else if (el.tagName === 'SELECT') {
        updateSelect(el, value)
      } else {
        if (el.value === value) return
        el.value = value
      }
    } else if (attrName === 'class') {
      if (Array.isArray(value)) {
        const originalClasses = el.__x_original_classes || []
        el.setAttribute('class', arrayUnique(originalClasses.concat(value)).join(' '))
      } else if (typeof value === 'object') {
        // Sorting the keys / class names by their boolean value will ensure that
        // anything that evaluates to `false` and needs to remove classes is run first.
        const keysSortedByBooleanValue = Object.keys(value).sort((a, b) => value[a] - value[b])
        keysSortedByBooleanValue.forEach(classNames => {
          if (value[classNames]) {
            convertClassStringToArray(classNames).forEach(className => el.classList.add(className))
          } else {
            convertClassStringToArray(classNames).forEach(className => el.classList.remove(className))
          }
        })
      } else {
        const originalClasses = el.__x_original_classes || []
        const newClasses = value ? convertClassStringToArray(value) : []
        el.setAttribute('class', arrayUnique(originalClasses.concat(newClasses)).join(' '))
      }
    } else {
      attrName = modifiers.includes('camel') ? camelCase(attrName) : attrName // If an attribute's bound value is null, undefined or false, remove the attribute

      if ([null, undefined, false].includes(value)) {
        el.removeAttribute(attrName)
      } else {
        isBooleanAttr(attrName) ? setIfChanged(el, attrName, attrName) : setIfChanged(el, attrName, value)
      }
    }
  }

  function setIfChanged(el, attrName, value) {
    if (el.getAttribute(attrName) != value) {
      el.setAttribute(attrName, value)
    }
  }

  function updateSelect(el, value) {
    const arrayWrappedValue = [].concat(value).map(value => {
      return value + ''
    })
    Array.from(el.options).forEach(option => {
      option.selected = arrayWrappedValue.includes(option.value || option.text)
    })
  }

  function handleTextDirective(el, output, expression) {
    // If nested model key is undefined, set the default value to empty string.
    if (output === undefined && String(expression).match(/\./)) {
      output = ''
    }

    el.textContent = output
  }

  function handleHtmlDirective(component, el, expression, extraVars) {
    el.innerHTML = component.evaluateReturnExpression(el, expression, extraVars)
  }

  function handleShowDirective(component, el, value, modifiers, initialUpdate = false) {
    const hide = () => {
      el.style.display = 'none'
      el.__x_is_shown = false
    }

    const show = () => {
      if (el.style.length === 1 && el.style.display === 'none') {
        el.removeAttribute('style')
      } else {
        el.style.removeProperty('display')
      }

      el.__x_is_shown = true
    }

    if (initialUpdate === true) {
      if (value) {
        show()
      } else {
        hide()
      }

      return
    }

    const handle = (resolve, reject) => {
      if (value) {
        if (el.style.display === 'none' || el.__x_transition) {
          transitionIn(
            el,
            () => {
              show()
            },
            reject,
            component
          )
        }

        resolve(() => {})
      } else {
        if (el.style.display !== 'none') {
          transitionOut(
            el,
            () => {
              resolve(() => {
                hide()
              })
            },
            reject,
            component
          )
        } else {
          resolve(() => {})
        }
      }
    } // The working of x-show is a bit complex because we need to
    // wait for any child transitions to finish before hiding
    // some element. Also, this has to be done recursively.
    // If x-show.immediate, foregoe the waiting.

    if (modifiers.includes('immediate')) {
      handle(
        finish => finish(),
        () => {}
      )
      return
    } // x-show is encountered during a DOM tree walk. If an element
    // we encounter is NOT a child of another x-show element we
    // can execute the previous x-show stack (if one exists).

    if (component.showDirectiveLastElement && !component.showDirectiveLastElement.contains(el)) {
      component.executeAndClearRemainingShowDirectiveStack()
    }

    component.showDirectiveStack.push(handle)
    component.showDirectiveLastElement = el
  }

  function handleIfDirective(component, el, expressionResult, initialUpdate, extraVars) {
    warnIfMalformedTemplate(el, 'x-if')
    const elementHasAlreadyBeenAdded = el.nextElementSibling && el.nextElementSibling.__x_inserted_me === true

    if (expressionResult && (!elementHasAlreadyBeenAdded || el.__x_transition)) {
      const clone = document.importNode(el.content, true)
      el.parentElement.insertBefore(clone, el.nextElementSibling)
      transitionIn(
        el.nextElementSibling,
        () => {},
        () => {},
        component,
        initialUpdate
      )
      component.initializeElements(el.nextElementSibling, extraVars)
      el.nextElementSibling.__x_inserted_me = true
    } else if (!expressionResult && elementHasAlreadyBeenAdded) {
      transitionOut(
        el.nextElementSibling,
        () => {
          el.nextElementSibling.remove()
        },
        () => {},
        component,
        initialUpdate
      )
    }
  }

  function registerListener(component, el, event, modifiers, expression, extraVars = {}) {
    const options = {
      passive: modifiers.includes('passive')
    }

    if (modifiers.includes('camel')) {
      event = camelCase(event)
    }

    let handler, listenerTarget

    if (modifiers.includes('away')) {
      listenerTarget = document

      handler = e => {
        // Don't do anything if the click came from the element or within it.
        if (el.contains(e.target)) return // Don't do anything if this element isn't currently visible.

        if (el.offsetWidth < 1 && el.offsetHeight < 1) return // Now that we are sure the element is visible, AND the click
        // is from outside it, let's run the expression.

        runListenerHandler(component, expression, e, extraVars)

        if (modifiers.includes('once')) {
          document.removeEventListener(event, handler, options)
        }
      }
    } else {
      listenerTarget = modifiers.includes('window') ? window : modifiers.includes('document') ? document : el

      handler = e => {
        // Remove this global event handler if the element that declared it
        // has been removed. It's now stale.
        if (listenerTarget === window || listenerTarget === document) {
          if (!document.body.contains(el)) {
            listenerTarget.removeEventListener(event, handler, options)
            return
          }
        }

        if (isKeyEvent(event)) {
          if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {
            return
          }
        }

        if (modifiers.includes('prevent')) e.preventDefault()
        if (modifiers.includes('stop')) e.stopPropagation() // If the .self modifier isn't present, or if it is present and
        // the target element matches the element we are registering the
        // event on, run the handler

        if (!modifiers.includes('self') || e.target === el) {
          const returnValue = runListenerHandler(component, expression, e, extraVars)
          returnValue.then(value => {
            if (value === false) {
              e.preventDefault()
            } else {
              if (modifiers.includes('once')) {
                listenerTarget.removeEventListener(event, handler, options)
              }
            }
          })
        }
      }
    }

    if (modifiers.includes('debounce')) {
      let nextModifier = modifiers[modifiers.indexOf('debounce') + 1] || 'invalid-wait'
      let wait = isNumeric(nextModifier.split('ms')[0]) ? Number(nextModifier.split('ms')[0]) : 250
      handler = debounce(handler, wait)
    }

    listenerTarget.addEventListener(event, handler, options)
  }

  function runListenerHandler(component, expression, e, extraVars) {
    return component.evaluateCommandExpression(e.target, expression, () => {
      return _objectSpread2(
        _objectSpread2({}, extraVars()),
        {},
        {
          $event: e
        }
      )
    })
  }

  function isKeyEvent(event) {
    return ['keydown', 'keyup'].includes(event)
  }

  function isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {
    let keyModifiers = modifiers.filter(i => {
      return !['window', 'document', 'prevent', 'stop'].includes(i)
    })

    if (keyModifiers.includes('debounce')) {
      let debounceIndex = keyModifiers.indexOf('debounce')
      keyModifiers.splice(
        debounceIndex,
        isNumeric((keyModifiers[debounceIndex + 1] || 'invalid-wait').split('ms')[0]) ? 2 : 1
      )
    } // If no modifier is specified, we'll call it a press.

    if (keyModifiers.length === 0) return false // If one is passed, AND it matches the key pressed, we'll call it a press.

    if (keyModifiers.length === 1 && keyModifiers[0] === keyToModifier(e.key)) return false // The user is listening for key combinations.

    const systemKeyModifiers = ['ctrl', 'shift', 'alt', 'meta', 'cmd', 'super']
    const selectedSystemKeyModifiers = systemKeyModifiers.filter(modifier => keyModifiers.includes(modifier))
    keyModifiers = keyModifiers.filter(i => !selectedSystemKeyModifiers.includes(i))

    if (selectedSystemKeyModifiers.length > 0) {
      const activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter(modifier => {
        // Alias "cmd" and "super" to "meta"
        if (modifier === 'cmd' || modifier === 'super') modifier = 'meta'
        return e[`${modifier}Key`]
      }) // If all the modifiers selected are pressed, ...

      if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {
        // AND the remaining key is pressed as well. It's a press.
        if (keyModifiers[0] === keyToModifier(e.key)) return false
      }
    } // We'll call it NOT a valid keypress.

    return true
  }

  function keyToModifier(key) {
    switch (key) {
      case '/':
        return 'slash'

      case ' ':
      case 'Spacebar':
        return 'space'

      default:
        return key && kebabCase(key)
    }
  }

  function registerModelListener(component, el, modifiers, expression, extraVars) {
    // If the element we are binding to is a select, a radio, or checkbox
    // we'll listen for the change event instead of the "input" event.
    var event =
      el.tagName.toLowerCase() === 'select' || ['checkbox', 'radio'].includes(el.type) || modifiers.includes('lazy')
        ? 'change'
        : 'input'
    const listenerExpression = `${expression} = rightSideOfExpression($event, ${expression})`
    registerListener(component, el, event, modifiers, listenerExpression, () => {
      return _objectSpread2(
        _objectSpread2({}, extraVars()),
        {},
        {
          rightSideOfExpression: generateModelAssignmentFunction(el, modifiers, expression)
        }
      )
    })
  }

  function generateModelAssignmentFunction(el, modifiers, expression) {
    if (el.type === 'radio') {
      // Radio buttons only work properly when they share a name attribute.
      // People might assume we take care of that for them, because
      // they already set a shared "x-model" attribute.
      if (!el.hasAttribute('name')) el.setAttribute('name', expression)
    }

    return (event, currentValue) => {
      // Check for event.detail due to an issue where IE11 handles other events as a CustomEvent.
      if (event instanceof CustomEvent && event.detail) {
        return event.detail
      } else if (el.type === 'checkbox') {
        // If the data we are binding to is an array, toggle its value inside the array.
        if (Array.isArray(currentValue)) {
          const newValue = modifiers.includes('number') ? safeParseNumber(event.target.value) : event.target.value
          return event.target.checked
            ? currentValue.concat([newValue])
            : currentValue.filter(el => !checkedAttrLooseCompare(el, newValue))
        } else {
          return event.target.checked
        }
      } else if (el.tagName.toLowerCase() === 'select' && el.multiple) {
        return modifiers.includes('number')
          ? Array.from(event.target.selectedOptions).map(option => {
              const rawValue = option.value || option.text
              return safeParseNumber(rawValue)
            })
          : Array.from(event.target.selectedOptions).map(option => {
              return option.value || option.text
            })
      } else {
        const rawValue = event.target.value
        return modifiers.includes('number')
          ? safeParseNumber(rawValue)
          : modifiers.includes('trim')
          ? rawValue.trim()
          : rawValue
      }
    }
  }

  function safeParseNumber(rawValue) {
    const number = rawValue ? parseFloat(rawValue) : null
    return isNumeric(number) ? number : rawValue
  }

  /**
   * Copyright (C) 2017 salesforce.com, inc.
   */
  const { isArray } = Array
  const {
    getPrototypeOf,
    create: ObjectCreate,
    defineProperty: ObjectDefineProperty,
    defineProperties: ObjectDefineProperties,
    isExtensible,
    getOwnPropertyDescriptor,
    getOwnPropertyNames,
    getOwnPropertySymbols,
    preventExtensions,
    hasOwnProperty
  } = Object
  const { push: ArrayPush, concat: ArrayConcat, map: ArrayMap } = Array.prototype
  function isUndefined(obj) {
    return obj === undefined
  }
  function isFunction(obj) {
    return typeof obj === 'function'
  }
  function isObject(obj) {
    return typeof obj === 'object'
  }
  const proxyToValueMap = new WeakMap()
  function registerProxy(proxy, value) {
    proxyToValueMap.set(proxy, value)
  }
  const unwrap = replicaOrAny => proxyToValueMap.get(replicaOrAny) || replicaOrAny

  function wrapValue(membrane, value) {
    return membrane.valueIsObservable(value) ? membrane.getProxy(value) : value
  }
  /**
   * Unwrap property descriptors will set value on original descriptor
   * We only need to unwrap if value is specified
   * @param descriptor external descrpitor provided to define new property on original value
   */
  function unwrapDescriptor(descriptor) {
    if (hasOwnProperty.call(descriptor, 'value')) {
      descriptor.value = unwrap(descriptor.value)
    }
    return descriptor
  }
  function lockShadowTarget(membrane, shadowTarget, originalTarget) {
    const targetKeys = ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget))
    targetKeys.forEach(key => {
      let descriptor = getOwnPropertyDescriptor(originalTarget, key)
      // We do not need to wrap the descriptor if configurable
      // Because we can deal with wrapping it when user goes through
      // Get own property descriptor. There is also a chance that this descriptor
      // could change sometime in the future, so we can defer wrapping
      // until we need to
      if (!descriptor.configurable) {
        descriptor = wrapDescriptor(membrane, descriptor, wrapValue)
      }
      ObjectDefineProperty(shadowTarget, key, descriptor)
    })
    preventExtensions(shadowTarget)
  }
  class ReactiveProxyHandler {
    constructor(membrane, value) {
      this.originalTarget = value
      this.membrane = membrane
    }
    get(shadowTarget, key) {
      const { originalTarget, membrane } = this
      const value = originalTarget[key]
      const { valueObserved } = membrane
      valueObserved(originalTarget, key)
      return membrane.getProxy(value)
    }
    set(shadowTarget, key, value) {
      const {
        originalTarget,
        membrane: { valueMutated }
      } = this
      const oldValue = originalTarget[key]
      if (oldValue !== value) {
        originalTarget[key] = value
        valueMutated(originalTarget, key)
      } else if (key === 'length' && isArray(originalTarget)) {
        // fix for issue #236: push will add the new index, and by the time length
        // is updated, the internal length is already equal to the new length value
        // therefore, the oldValue is equal to the value. This is the forking logic
        // to support this use case.
        valueMutated(originalTarget, key)
      }
      return true
    }
    deleteProperty(shadowTarget, key) {
      const {
        originalTarget,
        membrane: { valueMutated }
      } = this
      delete originalTarget[key]
      valueMutated(originalTarget, key)
      return true
    }
    apply(shadowTarget, thisArg, argArray) {
      /* No op */
    }
    construct(target, argArray, newTarget) {
      /* No op */
    }
    has(shadowTarget, key) {
      const {
        originalTarget,
        membrane: { valueObserved }
      } = this
      valueObserved(originalTarget, key)
      return key in originalTarget
    }
    ownKeys(shadowTarget) {
      const { originalTarget } = this
      return ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget))
    }
    isExtensible(shadowTarget) {
      const shadowIsExtensible = isExtensible(shadowTarget)
      if (!shadowIsExtensible) {
        return shadowIsExtensible
      }
      const { originalTarget, membrane } = this
      const targetIsExtensible = isExtensible(originalTarget)
      if (!targetIsExtensible) {
        lockShadowTarget(membrane, shadowTarget, originalTarget)
      }
      return targetIsExtensible
    }
    setPrototypeOf(shadowTarget, prototype) {}
    getPrototypeOf(shadowTarget) {
      const { originalTarget } = this
      return getPrototypeOf(originalTarget)
    }
    getOwnPropertyDescriptor(shadowTarget, key) {
      const { originalTarget, membrane } = this
      const { valueObserved } = this.membrane
      // keys looked up via hasOwnProperty need to be reactive
      valueObserved(originalTarget, key)
      let desc = getOwnPropertyDescriptor(originalTarget, key)
      if (isUndefined(desc)) {
        return desc
      }
      const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key)
      if (!isUndefined(shadowDescriptor)) {
        return shadowDescriptor
      }
      // Note: by accessing the descriptor, the key is marked as observed
      // but access to the value, setter or getter (if available) cannot observe
      // mutations, just like regular methods, in which case we just do nothing.
      desc = wrapDescriptor(membrane, desc, wrapValue)
      if (!desc.configurable) {
        // If descriptor from original target is not configurable,
        // We must copy the wrapped descriptor over to the shadow target.
        // Otherwise, proxy will throw an invariant error.
        // This is our last chance to lock the value.
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
        ObjectDefineProperty(shadowTarget, key, desc)
      }
      return desc
    }
    preventExtensions(shadowTarget) {
      const { originalTarget, membrane } = this
      lockShadowTarget(membrane, shadowTarget, originalTarget)
      preventExtensions(originalTarget)
      return true
    }
    defineProperty(shadowTarget, key, descriptor) {
      const { originalTarget, membrane } = this
      const { valueMutated } = membrane
      const { configurable } = descriptor
      // We have to check for value in descriptor
      // because Object.freeze(proxy) calls this method
      // with only { configurable: false, writeable: false }
      // Additionally, method will only be called with writeable:false
      // if the descriptor has a value, as opposed to getter/setter
      // So we can just check if writable is present and then see if
      // value is present. This eliminates getter and setter descriptors
      if (hasOwnProperty.call(descriptor, 'writable') && !hasOwnProperty.call(descriptor, 'value')) {
        const originalDescriptor = getOwnPropertyDescriptor(originalTarget, key)
        descriptor.value = originalDescriptor.value
      }
      ObjectDefineProperty(originalTarget, key, unwrapDescriptor(descriptor))
      if (configurable === false) {
        ObjectDefineProperty(shadowTarget, key, wrapDescriptor(membrane, descriptor, wrapValue))
      }
      valueMutated(originalTarget, key)
      return true
    }
  }

  function wrapReadOnlyValue(membrane, value) {
    return membrane.valueIsObservable(value) ? membrane.getReadOnlyProxy(value) : value
  }
  class ReadOnlyHandler {
    constructor(membrane, value) {
      this.originalTarget = value
      this.membrane = membrane
    }
    get(shadowTarget, key) {
      const { membrane, originalTarget } = this
      const value = originalTarget[key]
      const { valueObserved } = membrane
      valueObserved(originalTarget, key)
      return membrane.getReadOnlyProxy(value)
    }
    set(shadowTarget, key, value) {
      return false
    }
    deleteProperty(shadowTarget, key) {
      return false
    }
    apply(shadowTarget, thisArg, argArray) {
      /* No op */
    }
    construct(target, argArray, newTarget) {
      /* No op */
    }
    has(shadowTarget, key) {
      const {
        originalTarget,
        membrane: { valueObserved }
      } = this
      valueObserved(originalTarget, key)
      return key in originalTarget
    }
    ownKeys(shadowTarget) {
      const { originalTarget } = this
      return ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget))
    }
    setPrototypeOf(shadowTarget, prototype) {}
    getOwnPropertyDescriptor(shadowTarget, key) {
      const { originalTarget, membrane } = this
      const { valueObserved } = membrane
      // keys looked up via hasOwnProperty need to be reactive
      valueObserved(originalTarget, key)
      let desc = getOwnPropertyDescriptor(originalTarget, key)
      if (isUndefined(desc)) {
        return desc
      }
      const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key)
      if (!isUndefined(shadowDescriptor)) {
        return shadowDescriptor
      }
      // Note: by accessing the descriptor, the key is marked as observed
      // but access to the value or getter (if available) cannot be observed,
      // just like regular methods, in which case we just do nothing.
      desc = wrapDescriptor(membrane, desc, wrapReadOnlyValue)
      if (hasOwnProperty.call(desc, 'set')) {
        desc.set = undefined // readOnly membrane does not allow setters
      }
      if (!desc.configurable) {
        // If descriptor from original target is not configurable,
        // We must copy the wrapped descriptor over to the shadow target.
        // Otherwise, proxy will throw an invariant error.
        // This is our last chance to lock the value.
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
        ObjectDefineProperty(shadowTarget, key, desc)
      }
      return desc
    }
    preventExtensions(shadowTarget) {
      return false
    }
    defineProperty(shadowTarget, key, descriptor) {
      return false
    }
  }
  function createShadowTarget(value) {
    let shadowTarget = undefined
    if (isArray(value)) {
      shadowTarget = []
    } else if (isObject(value)) {
      shadowTarget = {}
    }
    return shadowTarget
  }
  const ObjectDotPrototype = Object.prototype
  function defaultValueIsObservable(value) {
    // intentionally checking for null
    if (value === null) {
      return false
    }
    // treat all non-object types, including undefined, as non-observable values
    if (typeof value !== 'object') {
      return false
    }
    if (isArray(value)) {
      return true
    }
    const proto = getPrototypeOf(value)
    return proto === ObjectDotPrototype || proto === null || getPrototypeOf(proto) === null
  }
  const defaultValueObserved = (obj, key) => {
    /* do nothing */
  }
  const defaultValueMutated = (obj, key) => {
    /* do nothing */
  }
  const defaultValueDistortion = value => value
  function wrapDescriptor(membrane, descriptor, getValue) {
    const { set, get } = descriptor
    if (hasOwnProperty.call(descriptor, 'value')) {
      descriptor.value = getValue(membrane, descriptor.value)
    } else {
      if (!isUndefined(get)) {
        descriptor.get = function () {
          // invoking the original getter with the original target
          return getValue(membrane, get.call(unwrap(this)))
        }
      }
      if (!isUndefined(set)) {
        descriptor.set = function (value) {
          // At this point we don't have a clear indication of whether
          // or not a valid mutation will occur, we don't have the key,
          // and we are not sure why and how they are invoking this setter.
          // Nevertheless we preserve the original semantics by invoking the
          // original setter with the original target and the unwrapped value
          set.call(unwrap(this), membrane.unwrapProxy(value))
        }
      }
    }
    return descriptor
  }
  class ReactiveMembrane {
    constructor(options) {
      this.valueDistortion = defaultValueDistortion
      this.valueMutated = defaultValueMutated
      this.valueObserved = defaultValueObserved
      this.valueIsObservable = defaultValueIsObservable
      this.objectGraph = new WeakMap()
      if (!isUndefined(options)) {
        const { valueDistortion, valueMutated, valueObserved, valueIsObservable } = options
        this.valueDistortion = isFunction(valueDistortion) ? valueDistortion : defaultValueDistortion
        this.valueMutated = isFunction(valueMutated) ? valueMutated : defaultValueMutated
        this.valueObserved = isFunction(valueObserved) ? valueObserved : defaultValueObserved
        this.valueIsObservable = isFunction(valueIsObservable) ? valueIsObservable : defaultValueIsObservable
      }
    }
    getProxy(value) {
      const unwrappedValue = unwrap(value)
      const distorted = this.valueDistortion(unwrappedValue)
      if (this.valueIsObservable(distorted)) {
        const o = this.getReactiveState(unwrappedValue, distorted)
        // when trying to extract the writable version of a readonly
        // we return the readonly.
        return o.readOnly === value ? value : o.reactive
      }
      return distorted
    }
    getReadOnlyProxy(value) {
      value = unwrap(value)
      const distorted = this.valueDistortion(value)
      if (this.valueIsObservable(distorted)) {
        return this.getReactiveState(value, distorted).readOnly
      }
      return distorted
    }
    unwrapProxy(p) {
      return unwrap(p)
    }
    getReactiveState(value, distortedValue) {
      const { objectGraph } = this
      let reactiveState = objectGraph.get(distortedValue)
      if (reactiveState) {
        return reactiveState
      }
      const membrane = this
      reactiveState = {
        get reactive() {
          const reactiveHandler = new ReactiveProxyHandler(membrane, distortedValue)
          // caching the reactive proxy after the first time it is accessed
          const proxy = new Proxy(createShadowTarget(distortedValue), reactiveHandler)
          registerProxy(proxy, value)
          ObjectDefineProperty(this, 'reactive', { value: proxy })
          return proxy
        },
        get readOnly() {
          const readOnlyHandler = new ReadOnlyHandler(membrane, distortedValue)
          // caching the readOnly proxy after the first time it is accessed
          const proxy = new Proxy(createShadowTarget(distortedValue), readOnlyHandler)
          registerProxy(proxy, value)
          ObjectDefineProperty(this, 'readOnly', { value: proxy })
          return proxy
        }
      }
      objectGraph.set(distortedValue, reactiveState)
      return reactiveState
    }
  }
  /** version: 0.26.0 */

  function wrap(data, mutationCallback) {
    let membrane = new ReactiveMembrane({
      valueMutated(target, key) {
        mutationCallback(target, key)
      }
    })
    return {
      data: membrane.getProxy(data),
      membrane: membrane
    }
  }
  function unwrap$1(membrane, observable) {
    let unwrappedData = membrane.unwrapProxy(observable)
    let copy = {}
    Object.keys(unwrappedData).forEach(key => {
      if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return
      copy[key] = unwrappedData[key]
    })
    return copy
  }

  class Component {
    constructor(el, componentForClone = null) {
      this.$el = el
      const dataAttr = this.$el.getAttribute('x-data')
      const dataExpression = dataAttr === '' ? '{}' : dataAttr
      const initExpression = this.$el.getAttribute('x-init')
      let dataExtras = {
        $el: this.$el
      }
      let canonicalComponentElementReference = componentForClone ? componentForClone.$el : this.$el
      Object.entries(Alpine.magicProperties).forEach(([name, callback]) => {
        Object.defineProperty(dataExtras, `$${name}`, {
          get: function get() {
            return callback(canonicalComponentElementReference)
          }
        })
      })
      this.unobservedData = componentForClone
        ? componentForClone.getUnobservedData()
        : saferEval(el, dataExpression, dataExtras)
      // Construct a Proxy-based observable. This will be used to handle reactivity.

      let { membrane, data } = this.wrapDataInObservable(this.unobservedData)
      this.$data = data
      this.membrane = membrane // After making user-supplied data methods reactive, we can now add
      // our magic properties to the original data for access.

      this.unobservedData.$el = this.$el
      this.unobservedData.$refs = this.getRefsProxy()
      this.nextTickStack = []

      this.unobservedData.$nextTick = callback => {
        this.nextTickStack.push(callback)
      }

      this.watchers = {}

      this.unobservedData.$watch = (property, callback) => {
        if (!this.watchers[property]) this.watchers[property] = []
        this.watchers[property].push(callback)
      }
      /* MODERN-ONLY:START */
      // We remove this piece of code from the legacy build.
      // In IE11, we have already defined our helpers at this point.
      // Register custom magic properties.

      Object.entries(Alpine.magicProperties).forEach(([name, callback]) => {
        Object.defineProperty(this.unobservedData, `$${name}`, {
          get: function get() {
            return callback(canonicalComponentElementReference, this.$el)
          }
        })
      })
      /* MODERN-ONLY:END */

      this.showDirectiveStack = []
      this.showDirectiveLastElement
      componentForClone || Alpine.onBeforeComponentInitializeds.forEach(callback => callback(this))
      var initReturnedCallback // If x-init is present AND we aren't cloning (skip x-init on clone)

      if (initExpression && !componentForClone) {
        // We want to allow data manipulation, but not trigger DOM updates just yet.
        // We haven't even initialized the elements with their Alpine bindings. I mean c'mon.
        this.pauseReactivity = true
        initReturnedCallback = this.evaluateReturnExpression(this.$el, initExpression)
        this.pauseReactivity = false
      } // Register all our listeners and set all our attribute bindings.
      // If we're cloning a component, the third parameter ensures no duplicate
      // event listeners are registered (the mutation observer will take care of them)

      this.initializeElements(this.$el, () => {}, componentForClone) // Use mutation observer to detect new elements being added within this component at run-time.
      // Alpine's just so darn flexible amirite?

      this.listenForNewElementsToInitialize()

      if (typeof initReturnedCallback === 'function') {
        // Run the callback returned from the "x-init" hook to allow the user to do stuff after
        // Alpine's got it's grubby little paws all over everything.
        initReturnedCallback.call(this.$data)
      }

      componentForClone ||
        setTimeout(() => {
          Alpine.onComponentInitializeds.forEach(callback => callback(this))
        }, 0)
    }

    getUnobservedData() {
      return unwrap$1(this.membrane, this.$data)
    }

    wrapDataInObservable(data) {
      var self = this
      let updateDom = debounce(function () {
        self.updateElements(self.$el)
      }, 0)
      return wrap(data, (target, key) => {
        if (self.watchers[key]) {
          // If there's a watcher for this specific key, run it.
          self.watchers[key].forEach(callback => callback(target[key]))
        } else if (Array.isArray(target)) {
          // Arrays are special cases, if any of the items change, we consider the array as mutated.
          Object.keys(self.watchers).forEach(fullDotNotationKey => {
            let dotNotationParts = fullDotNotationKey.split('.') // Ignore length mutations since they would result in duplicate calls.
            // For example, when calling push, we would get a mutation for the item's key
            // and a second mutation for the length property.

            if (key === 'length') return
            dotNotationParts.reduce((comparisonData, part) => {
              if (Object.is(target, comparisonData[part])) {
                self.watchers[fullDotNotationKey].forEach(callback => callback(target))
              }

              return comparisonData[part]
            }, self.unobservedData)
          })
        } else {
          // Let's walk through the watchers with "dot-notation" (foo.bar) and see
          // if this mutation fits any of them.
          Object.keys(self.watchers)
            .filter(i => i.includes('.'))
            .forEach(fullDotNotationKey => {
              let dotNotationParts = fullDotNotationKey.split('.') // If this dot-notation watcher's last "part" doesn't match the current
              // key, then skip it early for performance reasons.

              if (key !== dotNotationParts[dotNotationParts.length - 1]) return // Now, walk through the dot-notation "parts" recursively to find
              // a match, and call the watcher if one's found.

              dotNotationParts.reduce((comparisonData, part) => {
                if (Object.is(target, comparisonData)) {
                  // Run the watchers.
                  self.watchers[fullDotNotationKey].forEach(callback => callback(target[key]))
                }

                return comparisonData[part]
              }, self.unobservedData)
            })
        } // Don't react to data changes for cases like the `x-created` hook.

        if (self.pauseReactivity) return
        updateDom()
      })
    }

    walkAndSkipNestedComponents(el, callback, initializeComponentCallback = () => {}) {
      walk(el, el => {
        // We've hit a component.
        if (el.hasAttribute('x-data')) {
          // If it's not the current one.
          if (!el.isSameNode(this.$el)) {
            // Initialize it if it's not.
            if (!el.__x) initializeComponentCallback(el) // Now we'll let that sub-component deal with itself.

            return false
          }
        }

        return callback(el)
      })
    }

    initializeElements(rootEl, extraVars = () => {}, componentForClone = false) {
      this.walkAndSkipNestedComponents(
        rootEl,
        el => {
          // Don't touch spawns from for loop
          if (el.__x_for_key !== undefined) return false // Don't touch spawns from if directives

          if (el.__x_inserted_me !== undefined) return false
          this.initializeElement(el, extraVars, componentForClone ? false : true)
        },
        el => {
          if (!componentForClone) el.__x = new Component(el)
        }
      )
      this.executeAndClearRemainingShowDirectiveStack()
      this.executeAndClearNextTickStack(rootEl)
    }

    initializeElement(el, extraVars, shouldRegisterListeners = true) {
      // To support class attribute merging, we have to know what the element's
      // original class attribute looked like for reference.
      if (el.hasAttribute('class') && getXAttrs(el, this).length > 0) {
        el.__x_original_classes = convertClassStringToArray(el.getAttribute('class'))
      }

      shouldRegisterListeners && this.registerListeners(el, extraVars)
      this.resolveBoundAttributes(el, true, extraVars)
    }

    updateElements(rootEl, extraVars = () => {}) {
      this.walkAndSkipNestedComponents(
        rootEl,
        el => {
          // Don't touch spawns from for loop (and check if the root is actually a for loop in a parent, don't skip it.)
          if (el.__x_for_key !== undefined && !el.isSameNode(this.$el)) return false
          this.updateElement(el, extraVars)
        },
        el => {
          el.__x = new Component(el)
        }
      )
      this.executeAndClearRemainingShowDirectiveStack()
      this.executeAndClearNextTickStack(rootEl)
    }

    executeAndClearNextTickStack(el) {
      // Skip spawns from alpine directives
      if (el === this.$el && this.nextTickStack.length > 0) {
        // We run the tick stack after the next frame to allow any
        // running transitions to pass the initial show stage.
        requestAnimationFrame(() => {
          while (this.nextTickStack.length > 0) {
            this.nextTickStack.shift()()
          }
        })
      }
    }

    executeAndClearRemainingShowDirectiveStack() {
      // The goal here is to start all the x-show transitions
      // and build a nested promise chain so that elements
      // only hide when the children are finished hiding.
      this.showDirectiveStack
        .reverse()
        .map(handler => {
          return new Promise((resolve, reject) => {
            handler(resolve, reject)
          })
        })
        .reduce(
          (promiseChain, promise) => {
            return promiseChain.then(() => {
              return promise.then(finishElement => {
                finishElement()
              })
            })
          },
          Promise.resolve(() => {})
        )
        .catch(e => {
          if (e !== TRANSITION_CANCELLED) throw e
        }) // We've processed the handler stack. let's clear it.

      this.showDirectiveStack = []
      this.showDirectiveLastElement = undefined
    }

    updateElement(el, extraVars) {
      this.resolveBoundAttributes(el, false, extraVars)
    }

    registerListeners(el, extraVars) {
      getXAttrs(el, this).forEach(({ type, value, modifiers, expression }) => {
        switch (type) {
          case 'on':
            registerListener(this, el, value, modifiers, expression, extraVars)
            break

          case 'model':
            registerModelListener(this, el, modifiers, expression, extraVars)
            break
        }
      })
    }

    resolveBoundAttributes(el, initialUpdate = false, extraVars) {
      let attrs = getXAttrs(el, this)
      attrs.forEach(({ type, value, modifiers, expression }) => {
        switch (type) {
          case 'model':
            handleAttributeBindingDirective(this, el, 'value', expression, extraVars, type, modifiers)
            break

          case 'bind':
            // The :key binding on an x-for is special, ignore it.
            if (el.tagName.toLowerCase() === 'template' && value === 'key') return
            handleAttributeBindingDirective(this, el, value, expression, extraVars, type, modifiers)
            break

          case 'text':
            var output = this.evaluateReturnExpression(el, expression, extraVars)
            handleTextDirective(el, output, expression)
            break

          case 'html':
            handleHtmlDirective(this, el, expression, extraVars)
            break

          case 'show':
            var output = this.evaluateReturnExpression(el, expression, extraVars)
            handleShowDirective(this, el, output, modifiers, initialUpdate)
            break

          case 'if':
            // If this element also has x-for on it, don't process x-if.
            // We will let the "x-for" directive handle the "if"ing.
            if (attrs.some(i => i.type === 'for')) return
            var output = this.evaluateReturnExpression(el, expression, extraVars)
            handleIfDirective(this, el, output, initialUpdate, extraVars)
            break

          case 'for':
            handleForDirective(this, el, expression, initialUpdate, extraVars)
            break

          case 'cloak':
            el.removeAttribute('x-cloak')
            break
        }
      })
    }

    evaluateReturnExpression(el, expression, extraVars = () => {}) {
      return saferEval(
        el,
        expression,
        this.$data,
        _objectSpread2(
          _objectSpread2({}, extraVars()),
          {},
          {
            $dispatch: this.getDispatchFunction(el)
          }
        )
      )
    }

    evaluateCommandExpression(el, expression, extraVars = () => {}) {
      return saferEvalNoReturn(
        el,
        expression,
        this.$data,
        _objectSpread2(
          _objectSpread2({}, extraVars()),
          {},
          {
            $dispatch: this.getDispatchFunction(el)
          }
        )
      )
    }

    getDispatchFunction(el) {
      return (event, detail = {}) => {
        el.dispatchEvent(
          new CustomEvent(event, {
            detail,
            bubbles: true
          })
        )
      }
    }

    listenForNewElementsToInitialize() {
      const targetNode = this.$el
      const observerOptions = {
        childList: true,
        attributes: true,
        subtree: true
      }
      const observer = new MutationObserver(mutations => {
        for (let i = 0; i < mutations.length; i++) {
          // Filter out mutations triggered from child components.
          const closestParentComponent = mutations[i].target.closest('[x-data]')
          if (!(closestParentComponent && closestParentComponent.isSameNode(this.$el))) continue

          if (mutations[i].type === 'attributes' && mutations[i].attributeName === 'x-data') {
            const xAttr = mutations[i].target.getAttribute('x-data') || '{}'
            const rawData = saferEval(this.$el, xAttr, {
              $el: this.$el
            })
            Object.keys(rawData).forEach(key => {
              if (this.$data[key] !== rawData[key]) {
                this.$data[key] = rawData[key]
              }
            })
          }

          if (mutations[i].addedNodes.length > 0) {
            mutations[i].addedNodes.forEach(node => {
              if (node.nodeType !== 1 || node.__x_inserted_me) return

              if (node.matches('[x-data]') && !node.__x) {
                node.__x = new Component(node)
                return
              }

              this.initializeElements(node)
            })
          }
        }
      })
      observer.observe(targetNode, observerOptions)
    }

    getRefsProxy() {
      var self = this
      var refObj = {}
      // One of the goals of this is to not hold elements in memory, but rather re-evaluate
      // the DOM when the system needs something from it. This way, the framework is flexible and
      // friendly to outside DOM changes from libraries like Vue/Livewire.
      // For this reason, I'm using an "on-demand" proxy to fake a "$refs" object.

      return new Proxy(refObj, {
        get(object, property) {
          if (property === '$isAlpineProxy') return true
          var ref // We can't just query the DOM because it's hard to filter out refs in
          // nested components.

          self.walkAndSkipNestedComponents(self.$el, el => {
            if (el.hasAttribute('x-ref') && el.getAttribute('x-ref') === property) {
              ref = el
            }
          })
          return ref
        }
      })
    }
  }

  const Alpine = {
    version: '2.8.2',
    pauseMutationObserver: false,
    magicProperties: {},
    onComponentInitializeds: [],
    onBeforeComponentInitializeds: [],
    ignoreFocusedForValueBinding: false,
    start: async function start() {
      if (!isTesting()) {
        await domReady()
      }

      this.discoverComponents(el => {
        this.initializeComponent(el)
      }) // It's easier and more performant to just support Turbolinks than listen
      // to MutationObserver mutations at the document level.

      document.addEventListener('turbolinks:load', () => {
        this.discoverUninitializedComponents(el => {
          this.initializeComponent(el)
        })
      })
      this.listenForNewUninitializedComponentsAtRunTime()
    },
    discoverComponents: function discoverComponents(callback) {
      const rootEls = document.querySelectorAll('[x-data]')
      rootEls.forEach(rootEl => {
        callback(rootEl)
      })
    },
    discoverUninitializedComponents: function discoverUninitializedComponents(callback, el = null) {
      const rootEls = (el || document).querySelectorAll('[x-data]')
      Array.from(rootEls)
        .filter(el => el.__x === undefined)
        .forEach(rootEl => {
          callback(rootEl)
        })
    },
    listenForNewUninitializedComponentsAtRunTime: function listenForNewUninitializedComponentsAtRunTime() {
      const targetNode = document.querySelector('body')
      const observerOptions = {
        childList: true,
        attributes: true,
        subtree: true
      }
      const observer = new MutationObserver(mutations => {
        if (this.pauseMutationObserver) return

        for (let i = 0; i < mutations.length; i++) {
          if (mutations[i].addedNodes.length > 0) {
            mutations[i].addedNodes.forEach(node => {
              // Discard non-element nodes (like line-breaks)
              if (node.nodeType !== 1) return // Discard any changes happening within an existing component.
              // They will take care of themselves.

              if (node.parentElement && node.parentElement.closest('[x-data]')) return
              this.discoverUninitializedComponents(el => {
                this.initializeComponent(el)
              }, node.parentElement)
            })
          }
        }
      })
      observer.observe(targetNode, observerOptions)
    },
    initializeComponent: function initializeComponent(el) {
      if (!el.__x) {
        // Wrap in a try/catch so that we don't prevent other components
        // from initializing when one component contains an error.
        try {
          el.__x = new Component(el)
        } catch (error) {
          setTimeout(() => {
            throw error
          }, 0)
        }
      }
    },
    clone: function clone(component, newEl) {
      if (!newEl.__x) {
        newEl.__x = new Component(newEl, component)
      }
    },
    addMagicProperty: function addMagicProperty(name, callback) {
      this.magicProperties[name] = callback
    },
    onComponentInitialized: function onComponentInitialized(callback) {
      this.onComponentInitializeds.push(callback)
    },
    onBeforeComponentInitialized: function onBeforeComponentInitialized(callback) {
      this.onBeforeComponentInitializeds.push(callback)
    }
  }

  if (!isTesting()) {
    window.Alpine = Alpine

    if (window.deferLoadingAlpine) {
      window.deferLoadingAlpine(function () {
        window.Alpine.start()
      })
    } else {
      window.Alpine.start()
    }
  }

  return Alpine
})
