{"version":3,"sources":["mobiledoc-dom-renderer/cards/image.js","mobiledoc-dom-renderer/index.js","mobiledoc-dom-renderer/renderer-factory.js","mobiledoc-dom-renderer/renderers/0-2.js","mobiledoc-dom-renderer/renderers/0-3.js","mobiledoc-dom-renderer/utils/array-utils.js","mobiledoc-dom-renderer/utils/dom.js","mobiledoc-dom-renderer/utils/marker-types.js","mobiledoc-dom-renderer/utils/render-type.js","mobiledoc-dom-renderer/utils/render-utils.js","mobiledoc-dom-renderer/utils/sanitization-utils.js","mobiledoc-dom-renderer/utils/section-types.js","mobiledoc-dom-renderer/utils/tag-names.js","mobiledoc-kit/cards/image.js","mobiledoc-kit/editor/edit-history.js","mobiledoc-kit/editor/edit-state.js","mobiledoc-kit/editor/editor.js","mobiledoc-kit/editor/event-manager.js","mobiledoc-kit/editor/key-commands.js","mobiledoc-kit/editor/mutation-handler.js","mobiledoc-kit/editor/post.js","mobiledoc-kit/editor/post/post-inserter.js","mobiledoc-kit/editor/selection-change-observer.js","mobiledoc-kit/editor/selection-manager.js","mobiledoc-kit/editor/text-input-handler.js","mobiledoc-kit/editor/text-input-handlers.js","mobiledoc-kit/editor/ui.js","mobiledoc-kit/index.js","mobiledoc-kit/models/_attributable.js","mobiledoc-kit/models/_markerable.js","mobiledoc-kit/models/_section.js","mobiledoc-kit/models/atom-node.js","mobiledoc-kit/models/atom.js","mobiledoc-kit/models/card-node.js","mobiledoc-kit/models/card.js","mobiledoc-kit/models/image.js","mobiledoc-kit/models/lifecycle-callbacks.js","mobiledoc-kit/models/list-item.js","mobiledoc-kit/models/list-section.js","mobiledoc-kit/models/marker.js","mobiledoc-kit/models/markup-section.js","mobiledoc-kit/models/markup.js","mobiledoc-kit/models/post-node-builder.js","mobiledoc-kit/models/post.js","mobiledoc-kit/models/render-node.js","mobiledoc-kit/models/render-tree.js","mobiledoc-kit/models/types.js","mobiledoc-kit/parsers/dom.js","mobiledoc-kit/parsers/html.js","mobiledoc-kit/parsers/mobiledoc/0-2.js","mobiledoc-kit/parsers/mobiledoc/0-3-1.js","mobiledoc-kit/parsers/mobiledoc/0-3-2.js","mobiledoc-kit/parsers/mobiledoc/0-3.js","mobiledoc-kit/parsers/mobiledoc/index.js","mobiledoc-kit/parsers/section.js","mobiledoc-kit/parsers/text.js","mobiledoc-kit/renderers/editor-dom.js","mobiledoc-kit/renderers/mobiledoc/0-2.js","mobiledoc-kit/renderers/mobiledoc/0-3-1.js","mobiledoc-kit/renderers/mobiledoc/0-3-2.js","mobiledoc-kit/renderers/mobiledoc/0-3.js","mobiledoc-kit/renderers/mobiledoc/index.js","mobiledoc-kit/utils/array-utils.js","mobiledoc-kit/utils/assert.js","mobiledoc-kit/utils/browser.js","mobiledoc-kit/utils/characters.js","mobiledoc-kit/utils/compiler.js","mobiledoc-kit/utils/copy.js","mobiledoc-kit/utils/cursor.js","mobiledoc-kit/utils/cursor/position.js","mobiledoc-kit/utils/cursor/range.js","mobiledoc-kit/utils/deprecate.js","mobiledoc-kit/utils/dom-utils.js","mobiledoc-kit/utils/element-map.js","mobiledoc-kit/utils/element-utils.js","mobiledoc-kit/utils/environment.js","mobiledoc-kit/utils/fixed-queue.js","mobiledoc-kit/utils/key.js","mobiledoc-kit/utils/keycodes.js","mobiledoc-kit/utils/keys.js","mobiledoc-kit/utils/linked-item.js","mobiledoc-kit/utils/linked-list.js","mobiledoc-kit/utils/log-manager.js","mobiledoc-kit/utils/markuperable.js","mobiledoc-kit/utils/merge.js","mobiledoc-kit/utils/mixin.js","mobiledoc-kit/utils/mobiledoc-error.js","mobiledoc-kit/utils/object-utils.js","mobiledoc-kit/utils/parse-utils.js","mobiledoc-kit/utils/placeholder-image-src.js","mobiledoc-kit/utils/selection-utils.js","mobiledoc-kit/utils/set.js","mobiledoc-kit/utils/string-utils.js","mobiledoc-kit/utils/to-range.js","mobiledoc-kit/version.js","mobiledoc-kit/views/tooltip.js","mobiledoc-kit/views/view.js","mobiledoc-text-renderer/cards/image.js","mobiledoc-text-renderer/index.js","mobiledoc-text-renderer/renderer-factory.js","mobiledoc-text-renderer/renderers/0-2.js","mobiledoc-text-renderer/renderers/0-3.js","mobiledoc-text-renderer/utils/marker-types.js","mobiledoc-text-renderer/utils/render-type.js","mobiledoc-text-renderer/utils/section-types.js"],"sourcesContent":["define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) {\n  'use strict';\n\n  exports['default'] = {\n    name: 'image',\n    type: _mobiledocDomRendererUtilsRenderType['default'],\n    render: function render(_ref) {\n      var payload = _ref.payload;\n      var dom = _ref.env.dom;\n\n      var img = dom.createElement('img');\n      img.src = payload.src;\n      return img;\n    }\n  };\n});","define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {\n  'use strict';\n\n  exports.registerGlobal = registerGlobal;\n  exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];\n\n  function registerGlobal(window) {\n    window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];\n  }\n\n  exports['default'] = _mobiledocDomRendererRendererFactory['default'];\n});","define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderers/0-2', 'mobiledoc-dom-renderer/renderers/0-3', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderers02, _mobiledocDomRendererRenderers03, _mobiledocDomRendererUtilsRenderType) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /**\n   * runtime DOM renderer\n   * renders a mobiledoc to DOM\n   *\n   * input: mobiledoc\n   * output: DOM\n   */\n\n  function validateCards(cards) {\n    if (!Array.isArray(cards)) {\n      throw new Error('`cards` must be passed as an array');\n    }\n    for (var i = 0; i < cards.length; i++) {\n      var card = cards[i];\n      if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n        throw new Error('Card \"' + card.name + '\" must be of type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n      }\n      if (!card.render) {\n        throw new Error('Card \"' + card.name + '\" must define `render`');\n      }\n    }\n  }\n\n  function validateAtoms(atoms) {\n    if (!Array.isArray(atoms)) {\n      throw new Error('`atoms` must be passed as an array');\n    }\n    for (var i = 0; i < atoms.length; i++) {\n      var atom = atoms[i];\n      if (atom.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n        throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n      }\n      if (!atom.render) {\n        throw new Error('Atom \"' + atom.name + '\" must define `render`');\n      }\n    }\n  }\n\n  var RendererFactory = (function () {\n    function RendererFactory() {\n      var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n      var _ref$cards = _ref.cards;\n      var cards = _ref$cards === undefined ? [] : _ref$cards;\n      var _ref$atoms = _ref.atoms;\n      var atoms = _ref$atoms === undefined ? [] : _ref$atoms;\n      var _ref$cardOptions = _ref.cardOptions;\n      var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions;\n      var unknownCardHandler = _ref.unknownCardHandler;\n      var unknownAtomHandler = _ref.unknownAtomHandler;\n      var _ref$markupElementRenderer = _ref.markupElementRenderer;\n      var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer;\n      var _ref$sectionElementRenderer = _ref.sectionElementRenderer;\n      var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer;\n      var dom = _ref.dom;\n      var _ref$markupSanitizer = _ref.markupSanitizer;\n      var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer;\n\n      _classCallCheck(this, RendererFactory);\n\n      validateCards(cards);\n      validateAtoms(atoms);\n\n      if (!dom) {\n        if (typeof window === 'undefined') {\n          throw new Error('A `dom` option must be provided to the renderer when running without window.document');\n        }\n        dom = window.document;\n      }\n\n      this.options = {\n        cards: cards,\n        atoms: atoms,\n        cardOptions: cardOptions,\n        unknownCardHandler: unknownCardHandler,\n        unknownAtomHandler: unknownAtomHandler,\n        markupElementRenderer: markupElementRenderer,\n        sectionElementRenderer: sectionElementRenderer,\n        dom: dom,\n        markupSanitizer: markupSanitizer\n      };\n    }\n\n    _createClass(RendererFactory, [{\n      key: 'render',\n      value: function render(mobiledoc) {\n        var version = mobiledoc.version;\n\n        switch (version) {\n          case _mobiledocDomRendererRenderers02.MOBILEDOC_VERSION:\n          case undefined:\n          case null:\n            return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render();\n          case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0:\n          case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n          case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n            return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render();\n          default:\n            throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n        }\n      }\n    }]);\n\n    return RendererFactory;\n  })();\n\n  exports['default'] = RendererFactory;\n});","define('mobiledoc-dom-renderer/renderers/0-2', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var MOBILEDOC_VERSION = '0.2.0';\n\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  var IMAGE_SECTION_TAG_NAME = 'img';\n\n  function validateVersion(version) {\n    if (version !== MOBILEDOC_VERSION) {\n      throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n    }\n  }\n\n  var Renderer = (function () {\n    function Renderer(mobiledoc, options) {\n      var _this = this;\n\n      _classCallCheck(this, Renderer);\n\n      var cards = options.cards;\n      var cardOptions = options.cardOptions;\n      var unknownCardHandler = options.unknownCardHandler;\n      var markupElementRenderer = options.markupElementRenderer;\n      var sectionElementRenderer = options.sectionElementRenderer;\n      var dom = options.dom;\n      var version = mobiledoc.version;\n      var sectionData = mobiledoc.sections;\n\n      validateVersion(version);\n\n      var _sectionData = _slicedToArray(sectionData, 2);\n\n      var markerTypes = _sectionData[0];\n      var sections = _sectionData[1];\n\n      this.dom = dom;\n      this.root = dom.createDocumentFragment();\n      this.markerTypes = markerTypes;\n      this.sections = sections;\n      this.cards = cards;\n      this.cardOptions = cardOptions;\n      this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n      this.sectionElementRenderer = {\n        '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n      };\n      Object.keys(sectionElementRenderer).forEach(function (key) {\n        _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n      });\n\n      this.markupElementRenderer = {\n        '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n      };\n      Object.keys(markupElementRenderer).forEach(function (key) {\n        _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n      });\n\n      this._renderCallbacks = [];\n      this._teardownCallbacks = [];\n      this._renderedChildNodes = [];\n    }\n\n    _createClass(Renderer, [{\n      key: 'render',\n      value: function render() {\n        var _this2 = this;\n\n        this.sections.forEach(function (section) {\n          var rendered = _this2.renderSection(section);\n          if (rendered) {\n            _this2.root.appendChild(rendered);\n          }\n        });\n        for (var i = 0; i < this._renderCallbacks.length; i++) {\n          this._renderCallbacks[i]();\n        }\n        // maintain a reference to child nodes so they can be cleaned up later by teardown\n        this._renderedChildNodes = [];\n        var node = this.root.firstChild;\n        while (node) {\n          this._renderedChildNodes.push(node);\n          node = node.nextSibling;\n        }\n        return { result: this.root, teardown: function teardown() {\n            return _this2.teardown();\n          } };\n      }\n    }, {\n      key: 'teardown',\n      value: function teardown() {\n        for (var i = 0; i < this._teardownCallbacks.length; i++) {\n          this._teardownCallbacks[i]();\n        }\n        for (var i = 0; i < this._renderedChildNodes.length; i++) {\n          var node = this._renderedChildNodes[i];\n          if (node.parentNode) {\n            node.parentNode.removeChild(node);\n          }\n        }\n      }\n    }, {\n      key: 'renderSection',\n      value: function renderSection(section) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n            return this.renderMarkupSection(section);\n          case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n            return this.renderImageSection(section);\n          case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n            return this.renderListSection(section);\n          case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n            return this.renderCardSection(section);\n          default:\n            throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n        }\n      }\n    }, {\n      key: 'renderMarkersOnElement',\n      value: function renderMarkersOnElement(element, markers) {\n        var elements = [element];\n        var currentElement = element;\n\n        var pushElement = function pushElement(openedElement) {\n          currentElement.appendChild(openedElement);\n          elements.push(openedElement);\n          currentElement = openedElement;\n        };\n\n        for (var i = 0, l = markers.length; i < l; i++) {\n          var marker = markers[i];\n\n          var _marker = _slicedToArray(marker, 3);\n\n          var openTypes = _marker[0];\n          var closeCount = _marker[1];\n          var text = _marker[2];\n\n          for (var j = 0, m = openTypes.length; j < m; j++) {\n            var markerType = this.markerTypes[openTypes[j]];\n\n            var _markerType = _slicedToArray(markerType, 2);\n\n            var tagName = _markerType[0];\n            var _markerType$1 = _markerType[1];\n            var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n            if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n              pushElement(this.renderMarkupElement(tagName, attrs));\n            } else {\n              closeCount--;\n            }\n          }\n\n          currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, text));\n\n          for (var j = 0, m = closeCount; j < m; j++) {\n            elements.pop();\n            currentElement = elements[elements.length - 1];\n          }\n        }\n      }\n\n      /**\n       * @param attrs Array\n       */\n    }, {\n      key: 'renderMarkupElement',\n      value: function renderMarkupElement(tagName, attrs) {\n        tagName = tagName.toLowerCase();\n        attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n        var renderer = this.markupElementRendererFor(tagName);\n        return renderer(tagName, this.dom, attrs);\n      }\n    }, {\n      key: 'markupElementRendererFor',\n      value: function markupElementRendererFor(tagName) {\n        return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n      }\n    }, {\n      key: 'renderListItem',\n      value: function renderListItem(markers) {\n        var element = this.dom.createElement('li');\n        this.renderMarkersOnElement(element, markers);\n        return element;\n      }\n    }, {\n      key: 'renderListSection',\n      value: function renderListSection(_ref) {\n        var _this3 = this;\n\n        var _ref2 = _slicedToArray(_ref, 3);\n\n        var type = _ref2[0];\n        var tagName = _ref2[1];\n        var listItems = _ref2[2];\n\n        if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n          return;\n        }\n        var element = this.dom.createElement(tagName);\n        listItems.forEach(function (li) {\n          element.appendChild(_this3.renderListItem(li));\n        });\n        return element;\n      }\n    }, {\n      key: 'renderImageSection',\n      value: function renderImageSection(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 2);\n\n        var type = _ref32[0];\n        var src = _ref32[1];\n\n        var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n        element.src = src;\n        return element;\n      }\n    }, {\n      key: 'findCard',\n      value: function findCard(name) {\n        for (var i = 0; i < this.cards.length; i++) {\n          if (this.cards[i].name === name) {\n            return this.cards[i];\n          }\n        }\n        if (name === _mobiledocDomRendererCardsImage['default'].name) {\n          return _mobiledocDomRendererCardsImage['default'];\n        }\n        return this._createUnknownCard(name);\n      }\n    }, {\n      key: '_createUnknownCard',\n      value: function _createUnknownCard(name) {\n        return {\n          name: name,\n          type: _mobiledocDomRendererUtilsRenderType['default'],\n          render: this.unknownCardHandler\n        };\n      }\n    }, {\n      key: '_createCardArgument',\n      value: function _createCardArgument(card) {\n        var _this4 = this;\n\n        var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        var env = {\n          name: card.name,\n          isInEditor: false,\n          dom: this.dom,\n          didRender: function didRender(callback) {\n            return _this4._registerRenderCallback(callback);\n          },\n          onTeardown: function onTeardown(callback) {\n            return _this4._registerTeardownCallback(callback);\n          }\n        };\n\n        var options = this.cardOptions;\n\n        return { env: env, options: options, payload: payload };\n      }\n    }, {\n      key: '_registerRenderCallback',\n      value: function _registerRenderCallback(callback) {\n        this._renderCallbacks.push(callback);\n      }\n    }, {\n      key: '_registerTeardownCallback',\n      value: function _registerTeardownCallback(callback) {\n        this._teardownCallbacks.push(callback);\n      }\n    }, {\n      key: 'renderCardSection',\n      value: function renderCardSection(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 3);\n\n        var type = _ref42[0];\n        var name = _ref42[1];\n        var payload = _ref42[2];\n\n        var card = this.findCard(name);\n\n        var cardArg = this._createCardArgument(card, payload);\n        var rendered = card.render(cardArg);\n\n        this._validateCardRender(rendered, card.name);\n\n        return rendered;\n      }\n    }, {\n      key: '_validateCardRender',\n      value: function _validateCardRender(rendered, cardName) {\n        if (!rendered) {\n          return;\n        }\n\n        if (typeof rendered !== 'object') {\n          throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n        }\n      }\n    }, {\n      key: 'renderMarkupSection',\n      value: function renderMarkupSection(_ref5) {\n        var _ref52 = _slicedToArray(_ref5, 3);\n\n        var type = _ref52[0];\n        var tagName = _ref52[1];\n        var markers = _ref52[2];\n\n        tagName = tagName.toLowerCase();\n        if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n          return;\n        }\n\n        var renderer = this.sectionElementRendererFor(tagName);\n        var element = renderer(tagName, this.dom);\n\n        this.renderMarkersOnElement(element, markers);\n        return element;\n      }\n    }, {\n      key: 'sectionElementRendererFor',\n      value: function sectionElementRendererFor(tagName) {\n        return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n      }\n    }, {\n      key: '_defaultUnknownCardHandler',\n      get: function get() {\n        return function (_ref6) {\n          var name = _ref6.env.name;\n\n          throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n        };\n      }\n    }]);\n\n    return Renderer;\n  })();\n\n  exports['default'] = Renderer;\n});","define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils', 'mobiledoc-dom-renderer/utils/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils, _mobiledocDomRendererUtilsMarkerTypes) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var MOBILEDOC_VERSION_0_3_0 = '0.3.0';\n  exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0;\n  var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n  exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n  var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n  exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n  var IMAGE_SECTION_TAG_NAME = 'img';\n\n  function validateVersion(version) {\n    switch (version) {\n      case MOBILEDOC_VERSION_0_3_0:\n      case MOBILEDOC_VERSION_0_3_1:\n      case MOBILEDOC_VERSION_0_3_2:\n        return;\n      default:\n        throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n    }\n  }\n\n  var Renderer = (function () {\n    function Renderer(mobiledoc, state) {\n      var _this = this;\n\n      _classCallCheck(this, Renderer);\n\n      var cards = state.cards;\n      var cardOptions = state.cardOptions;\n      var atoms = state.atoms;\n      var unknownCardHandler = state.unknownCardHandler;\n      var unknownAtomHandler = state.unknownAtomHandler;\n      var markupElementRenderer = state.markupElementRenderer;\n      var sectionElementRenderer = state.sectionElementRenderer;\n      var dom = state.dom;\n      var version = mobiledoc.version;\n      var sections = mobiledoc.sections;\n      var atomTypes = mobiledoc.atoms;\n      var cardTypes = mobiledoc.cards;\n      var markerTypes = mobiledoc.markups;\n\n      validateVersion(version);\n\n      this.dom = dom;\n      this.root = this.dom.createDocumentFragment();\n      this.sections = sections;\n      this.atomTypes = atomTypes;\n      this.cardTypes = cardTypes;\n      this.markerTypes = markerTypes;\n      this.cards = cards;\n      this.atoms = atoms;\n      this.cardOptions = cardOptions;\n      this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n      this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n      this.sectionElementRenderer = {\n        '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n      };\n      Object.keys(sectionElementRenderer).forEach(function (key) {\n        _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n      });\n\n      this.markupElementRenderer = {\n        '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n      };\n      Object.keys(markupElementRenderer).forEach(function (key) {\n        _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n      });\n\n      this._renderCallbacks = [];\n      this._teardownCallbacks = [];\n    }\n\n    _createClass(Renderer, [{\n      key: 'render',\n      value: function render() {\n        var _this2 = this;\n\n        this.sections.forEach(function (section) {\n          var rendered = _this2.renderSection(section);\n          if (rendered) {\n            _this2.root.appendChild(rendered);\n          }\n        });\n        for (var i = 0; i < this._renderCallbacks.length; i++) {\n          this._renderCallbacks[i]();\n        }\n        // maintain a reference to child nodes so they can be cleaned up later by teardown\n        this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);\n        return { result: this.root, teardown: function teardown() {\n            return _this2.teardown();\n          } };\n      }\n    }, {\n      key: 'teardown',\n      value: function teardown() {\n        for (var i = 0; i < this._teardownCallbacks.length; i++) {\n          this._teardownCallbacks[i]();\n        }\n        for (var i = 0; i < this._renderedChildNodes.length; i++) {\n          var node = this._renderedChildNodes[i];\n          if (node.parentNode) {\n            node.parentNode.removeChild(node);\n          }\n        }\n      }\n    }, {\n      key: 'renderSection',\n      value: function renderSection(section) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n            return this.renderMarkupSection(section);\n          case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n            return this.renderImageSection(section);\n          case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n            return this.renderListSection(section);\n          case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n            return this.renderCardSection(section);\n          default:\n            throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n        }\n      }\n    }, {\n      key: 'renderMarkersOnElement',\n      value: function renderMarkersOnElement(element, markers) {\n        var elements = [element];\n        var currentElement = element;\n\n        var pushElement = function pushElement(openedElement) {\n          currentElement.appendChild(openedElement);\n          elements.push(openedElement);\n          currentElement = openedElement;\n        };\n\n        for (var i = 0, l = markers.length; i < l; i++) {\n          var marker = markers[i];\n\n          var _marker = _slicedToArray(marker, 4);\n\n          var type = _marker[0];\n          var openTypes = _marker[1];\n          var closeCount = _marker[2];\n          var value = _marker[3];\n\n          for (var j = 0, m = openTypes.length; j < m; j++) {\n            var markerType = this.markerTypes[openTypes[j]];\n\n            var _markerType = _slicedToArray(markerType, 2);\n\n            var tagName = _markerType[0];\n            var _markerType$1 = _markerType[1];\n            var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n            if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n              pushElement(this.renderMarkupElement(tagName, attrs));\n            } else {\n              closeCount--;\n            }\n          }\n\n          switch (type) {\n            case _mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n              currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, value));\n              break;\n            case _mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n              currentElement.appendChild(this._renderAtom(value));\n              break;\n            default:\n              throw new Error('Unknown markup type (' + type + ')');\n          }\n\n          for (var j = 0, m = closeCount; j < m; j++) {\n            elements.pop();\n            currentElement = elements[elements.length - 1];\n          }\n        }\n      }\n\n      /**\n       * @param attrs Array\n       */\n    }, {\n      key: 'renderMarkupElement',\n      value: function renderMarkupElement(tagName, attrs) {\n        tagName = tagName.toLowerCase();\n        attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n        var renderer = this.markupElementRendererFor(tagName);\n        return renderer(tagName, this.dom, attrs);\n      }\n    }, {\n      key: 'markupElementRendererFor',\n      value: function markupElementRendererFor(tagName) {\n        return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n      }\n    }, {\n      key: 'renderListItem',\n      value: function renderListItem(markers) {\n        var element = this.dom.createElement('li');\n        this.renderMarkersOnElement(element, markers);\n        return element;\n      }\n    }, {\n      key: 'renderListSection',\n      value: function renderListSection(_ref) {\n        var _this3 = this;\n\n        var _ref2 = _slicedToArray(_ref, 3);\n\n        var type = _ref2[0];\n        var tagName = _ref2[1];\n        var listItems = _ref2[2];\n\n        if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n          return;\n        }\n        var element = this.dom.createElement(tagName);\n        listItems.forEach(function (li) {\n          element.appendChild(_this3.renderListItem(li));\n        });\n        return element;\n      }\n    }, {\n      key: 'renderImageSection',\n      value: function renderImageSection(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 2);\n\n        var type = _ref32[0];\n        var src = _ref32[1];\n\n        var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n        element.src = src;\n        return element;\n      }\n    }, {\n      key: 'findCard',\n      value: function findCard(name) {\n        for (var i = 0; i < this.cards.length; i++) {\n          if (this.cards[i].name === name) {\n            return this.cards[i];\n          }\n        }\n        if (name === _mobiledocDomRendererCardsImage['default'].name) {\n          return _mobiledocDomRendererCardsImage['default'];\n        }\n        return this._createUnknownCard(name);\n      }\n    }, {\n      key: '_findCardByIndex',\n      value: function _findCardByIndex(index) {\n        var cardType = this.cardTypes[index];\n        if (!cardType) {\n          throw new Error('No card definition found at index ' + index);\n        }\n\n        var _cardType = _slicedToArray(cardType, 2);\n\n        var name = _cardType[0];\n        var payload = _cardType[1];\n\n        var card = this.findCard(name);\n\n        return {\n          card: card,\n          payload: payload\n        };\n      }\n    }, {\n      key: '_createUnknownCard',\n      value: function _createUnknownCard(name) {\n        return {\n          name: name,\n          type: _mobiledocDomRendererUtilsRenderType['default'],\n          render: this.unknownCardHandler\n        };\n      }\n    }, {\n      key: '_createCardArgument',\n      value: function _createCardArgument(card) {\n        var _this4 = this;\n\n        var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        var env = {\n          name: card.name,\n          isInEditor: false,\n          dom: this.dom,\n          didRender: function didRender(callback) {\n            return _this4._registerRenderCallback(callback);\n          },\n          onTeardown: function onTeardown(callback) {\n            return _this4._registerTeardownCallback(callback);\n          }\n        };\n\n        var options = this.cardOptions;\n\n        return { env: env, options: options, payload: payload };\n      }\n    }, {\n      key: '_registerTeardownCallback',\n      value: function _registerTeardownCallback(callback) {\n        this._teardownCallbacks.push(callback);\n      }\n    }, {\n      key: '_registerRenderCallback',\n      value: function _registerRenderCallback(callback) {\n        this._renderCallbacks.push(callback);\n      }\n    }, {\n      key: 'renderCardSection',\n      value: function renderCardSection(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 2);\n\n        var type = _ref42[0];\n        var index = _ref42[1];\n\n        var _findCardByIndex2 = this._findCardByIndex(index);\n\n        var card = _findCardByIndex2.card;\n        var payload = _findCardByIndex2.payload;\n\n        var cardArg = this._createCardArgument(card, payload);\n        var rendered = card.render(cardArg);\n\n        this._validateCardRender(rendered, card.name);\n\n        return rendered;\n      }\n    }, {\n      key: '_validateCardRender',\n      value: function _validateCardRender(rendered, cardName) {\n        if (!rendered) {\n          return;\n        }\n\n        if (typeof rendered !== 'object') {\n          throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n        }\n      }\n    }, {\n      key: 'findAtom',\n      value: function findAtom(name) {\n        for (var i = 0; i < this.atoms.length; i++) {\n          if (this.atoms[i].name === name) {\n            return this.atoms[i];\n          }\n        }\n        return this._createUnknownAtom(name);\n      }\n    }, {\n      key: '_createUnknownAtom',\n      value: function _createUnknownAtom(name) {\n        return {\n          name: name,\n          type: _mobiledocDomRendererUtilsRenderType['default'],\n          render: this.unknownAtomHandler\n        };\n      }\n    }, {\n      key: '_createAtomArgument',\n      value: function _createAtomArgument(atom, value, payload) {\n        var _this5 = this;\n\n        var env = {\n          name: atom.name,\n          isInEditor: false,\n          dom: this.dom,\n          onTeardown: function onTeardown(callback) {\n            return _this5._registerTeardownCallback(callback);\n          }\n        };\n\n        var options = this.cardOptions;\n\n        return { env: env, options: options, value: value, payload: payload };\n      }\n    }, {\n      key: '_validateAtomRender',\n      value: function _validateAtomRender(rendered, atomName) {\n        if (!rendered) {\n          return;\n        }\n\n        if (typeof rendered !== 'object') {\n          throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n        }\n      }\n    }, {\n      key: '_findAtomByIndex',\n      value: function _findAtomByIndex(index) {\n        var atomType = this.atomTypes[index];\n        if (!atomType) {\n          throw new Error('No atom definition found at index ' + index);\n        }\n\n        var _atomType = _slicedToArray(atomType, 3);\n\n        var name = _atomType[0];\n        var value = _atomType[1];\n        var payload = _atomType[2];\n\n        var atom = this.findAtom(name);\n\n        return {\n          atom: atom,\n          value: value,\n          payload: payload\n        };\n      }\n    }, {\n      key: '_renderAtom',\n      value: function _renderAtom(index) {\n        var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n        var atom = _findAtomByIndex2.atom;\n        var value = _findAtomByIndex2.value;\n        var payload = _findAtomByIndex2.payload;\n\n        var atomArg = this._createAtomArgument(atom, value, payload);\n        var rendered = atom.render(atomArg);\n\n        this._validateAtomRender(rendered, atom.name);\n\n        return rendered || (0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, '');\n      }\n    }, {\n      key: 'renderMarkupSection',\n      value: function renderMarkupSection(_ref5) {\n        var _ref52 = _slicedToArray(_ref5, 4);\n\n        var type = _ref52[0];\n        var tagName = _ref52[1];\n        var markers = _ref52[2];\n        var _ref52$3 = _ref52[3];\n        var attributes = _ref52$3 === undefined ? [] : _ref52$3;\n\n        tagName = tagName.toLowerCase();\n        if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n          return;\n        }\n\n        var attrsObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attributes);\n        var renderer = this.sectionElementRendererFor(tagName);\n        var element = renderer(tagName, this.dom, attrsObj);\n\n        this.renderMarkersOnElement(element, markers);\n        return element;\n      }\n    }, {\n      key: 'sectionElementRendererFor',\n      value: function sectionElementRendererFor(tagName) {\n        return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n      }\n    }, {\n      key: '_defaultUnknownCardHandler',\n      get: function get() {\n        return function (_ref6) {\n          var name = _ref6.env.name;\n\n          throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n        };\n      }\n    }, {\n      key: '_defaultUnknownAtomHandler',\n      get: function get() {\n        return function (_ref7) {\n          var name = _ref7.env.name;\n\n          throw new Error('Atom \"' + name + '\" not found but no unknownAtomHandler was registered');\n        };\n      }\n    }]);\n\n    return Renderer;\n  })();\n\n  exports['default'] = Renderer;\n});","define(\"mobiledoc-dom-renderer/utils/array-utils\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  exports.includes = includes;\n  exports.kvArrayToObject = kvArrayToObject;\n  exports.objectToSortedKVArray = objectToSortedKVArray;\n\n  function includes(array, detectValue) {\n    for (var i = 0; i < array.length; i++) {\n      var value = array[i];\n      if (value === detectValue) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * @param {Array} array of key1,value1,key2,value2,...\n   * @return {Object} {key1:value1, key2:value2, ...}\n   * @private\n   */\n\n  function kvArrayToObject(array) {\n    if (!Array.isArray(array)) {\n      return {};\n    }\n\n    var obj = {};\n    for (var i = 0; i < array.length; i += 2) {\n      var key = array[i];\n      var value = array[i + 1];\n\n      obj[key] = value;\n    }\n    return obj;\n  }\n\n  /**\n   * @param {Object} {key1:value1, key2:value2, ...}\n   * @return {Array} array of key1,value1,key2,value2,...\n   * @private\n   */\n\n  function objectToSortedKVArray(obj) {\n    var keys = Object.keys(obj).sort();\n    var result = [];\n    keys.forEach(function (k) {\n      result.push(k);\n      result.push(obj[k]);\n    });\n    return result;\n  }\n});","define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) {\n  'use strict';\n\n  exports.createTextNode = createTextNode;\n  exports.normalizeTagName = normalizeTagName;\n  function addHTMLSpaces(text) {\n    var nbsp = ' ';\n    return text.replace(/  /g, ' ' + nbsp);\n  }\n\n  function createTextNode(dom, text) {\n    return dom.createTextNode(addHTMLSpaces(text));\n  }\n\n  function normalizeTagName(tagName) {\n    return tagName.toLowerCase();\n  }\n});","define(\"mobiledoc-dom-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var MARKUP_MARKER_TYPE = 0;\n  exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n  var ATOM_MARKER_TYPE = 1;\n  exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = 'dom';\n});","define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) {\n  'use strict';\n\n  exports.defaultSectionElementRenderer = defaultSectionElementRenderer;\n  exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer;\n  var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n  exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n  function _isValidAttribute(attr) {\n    return VALID_ATTRIBUTES.indexOf(attr) !== -1;\n  }\n\n  function handleMarkupSectionAttribute(element, attributeKey, attributeValue) {\n    if (!_isValidAttribute(attributeKey)) {\n      throw new Error('Cannot use attribute: ' + attributeKey);\n    }\n\n    element.setAttribute(attributeKey, attributeValue);\n  }\n\n  function defaultSectionElementRenderer(tagName, dom) {\n    var attrsObj = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n    var element = undefined;\n    if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) {\n      element = dom.createElement(tagName);\n\n      Object.keys(attrsObj).forEach(function (k) {\n        handleMarkupSectionAttribute(element, k, attrsObj[k]);\n      });\n    } else {\n      element = dom.createElement('div');\n      element.setAttribute('class', tagName);\n    }\n\n    return element;\n  }\n\n  function sanitizeAttribute(tagName, attrName, attrValue) {\n    if (tagName === 'a' && attrName === 'href') {\n      return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attrValue);\n    } else {\n      return attrValue;\n    }\n  }\n\n  function defaultMarkupElementRenderer(tagName, dom, attrsObj) {\n    var element = dom.createElement(tagName);\n    Object.keys(attrsObj).forEach(function (attrName) {\n      var attrValue = attrsObj[attrName];\n      attrValue = sanitizeAttribute(tagName, attrName, attrValue);\n      element.setAttribute(attrName, attrValue);\n    });\n    return element;\n  }\n});","define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {\n  'use strict';\n\n  exports.sanitizeHref = sanitizeHref;\n  exports.reduceAttributes = reduceAttributes;\n\n  var PROTOCOL_REGEXP = /^([a-z0-9.+-]+:)/i;\n\n  var badProtocols = ['javascript:', // jshint ignore:line\n  'vbscript:' // jshint ignore:line\n  ];\n\n  function getProtocol(url) {\n    var matches = url && url.match(PROTOCOL_REGEXP);\n    var protocol = matches && matches[0] || ':';\n    return protocol;\n  }\n\n  function sanitizeHref(url) {\n    var protocol = getProtocol(url).toLowerCase();\n    if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) {\n      return 'unsafe:' + url;\n    }\n    return url;\n  }\n\n  /**\n   * @param attributes array\n   * @return obj with normalized attribute names (lowercased)\n   */\n\n  function reduceAttributes(attributes) {\n    var obj = {};\n    for (var i = 0; i < attributes.length; i += 2) {\n      var key = attributes[i];\n      var val = attributes[i + 1];\n      obj[key.toLowerCase()] = val;\n    }\n    return obj;\n  }\n});","define(\"mobiledoc-dom-renderer/utils/section-types\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var MARKUP_SECTION_TYPE = 1;\n  exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n  var IMAGE_SECTION_TYPE = 2;\n  exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n  var LIST_SECTION_TYPE = 3;\n  exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n  var CARD_SECTION_TYPE = 10;\n  exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});","define('mobiledoc-dom-renderer/utils/tag-names', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsDom) {\n  'use strict';\n\n  exports.isValidSectionTagName = isValidSectionTagName;\n  exports.isMarkupSectionElementName = isMarkupSectionElementName;\n  exports.isValidMarkerType = isValidMarkerType;\n\n  var MARKUP_SECTION_TAG_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pull-quote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n  var MARKUP_SECTION_ELEMENT_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n  var LIST_SECTION_TAG_NAMES = ['ul', 'ol'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n  var MARKUP_TYPES = ['b', 'i', 'strong', 'em', 'a', 'u', 'sub', 'sup', 's', 'code'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n  function contains(array, item) {\n    return array.indexOf(item) !== -1;\n  }\n\n  function isValidSectionTagName(tagName, sectionType) {\n    tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n\n    switch (sectionType) {\n      case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n        return contains(MARKUP_SECTION_TAG_NAMES, tagName);\n      case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n        return contains(LIST_SECTION_TAG_NAMES, tagName);\n      default:\n        throw new Error('Cannot validate tagName for unknown section type \"' + sectionType + '\"');\n    }\n  }\n\n  function isMarkupSectionElementName(tagName) {\n    tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n    return contains(MARKUP_SECTION_ELEMENT_NAMES, tagName);\n  }\n\n  function isValidMarkerType(type) {\n    type = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(type);\n    return contains(MARKUP_TYPES, type);\n  }\n});","define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder-image-src'], function (exports, _mobiledocKitUtilsPlaceholderImageSrc) {\n  'use strict';\n\n  exports['default'] = {\n    name: 'image',\n    type: 'dom',\n\n    render: function render(_ref) {\n      var payload = _ref.payload;\n\n      var img = document.createElement('img');\n      img.src = payload.src || _mobiledocKitUtilsPlaceholderImageSrc['default'];\n      return img;\n    }\n  };\n});","define('mobiledoc-kit/editor/edit-history', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/utils/fixed-queue'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitUtilsFixedQueue) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function findLeafSectionAtIndex(post, index) {\n    var section = undefined;\n    post.walkAllLeafSections(function (_section, _index) {\n      if (index === _index) {\n        section = _section;\n      }\n    });\n    return section;\n  }\n\n  var Snapshot = (function () {\n    function Snapshot(takenAt, editor) {\n      var editAction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n      _classCallCheck(this, Snapshot);\n\n      this.mobiledoc = editor.serialize();\n      this.editor = editor;\n      this.editAction = editAction;\n      this.takenAt = takenAt;\n\n      this.snapshotRange();\n    }\n\n    _createClass(Snapshot, [{\n      key: 'snapshotRange',\n      value: function snapshotRange() {\n        var _editor = this.editor;\n        var range = _editor.range;\n        var cursor = _editor.cursor;\n\n        if (cursor.hasCursor() && !range.isBlank) {\n          var head = range.head;\n          var tail = range.tail;\n\n          this.range = {\n            head: [head.leafSectionIndex, head.offset],\n            tail: [tail.leafSectionIndex, tail.offset]\n          };\n        }\n      }\n    }, {\n      key: 'getRange',\n      value: function getRange(post) {\n        if (this.range) {\n          var _range = this.range;\n          var head = _range.head;\n          var tail = _range.tail;\n          var _head = head;\n\n          var _head2 = _slicedToArray(_head, 2);\n\n          var headLeafSectionIndex = _head2[0];\n          var headOffset = _head2[1];\n          var _tail = tail;\n\n          var _tail2 = _slicedToArray(_tail, 2);\n\n          var tailLeafSectionIndex = _tail2[0];\n          var tailOffset = _tail2[1];\n\n          var headSection = findLeafSectionAtIndex(post, headLeafSectionIndex);\n          var tailSection = findLeafSectionAtIndex(post, tailLeafSectionIndex);\n\n          head = headSection.toPosition(headOffset);\n          tail = tailSection.toPosition(tailOffset);\n\n          return head.toRange(tail);\n        }\n      }\n    }, {\n      key: 'groupsWith',\n      value: function groupsWith(groupingTimeout, editAction, takenAt) {\n        return editAction !== null && this.editAction === editAction && this.takenAt + groupingTimeout > takenAt;\n      }\n    }]);\n\n    return Snapshot;\n  })();\n\n  exports.Snapshot = Snapshot;\n\n  var EditHistory = (function () {\n    function EditHistory(editor, queueLength, groupingTimeout) {\n      _classCallCheck(this, EditHistory);\n\n      this.editor = editor;\n      this._undoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n      this._redoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n\n      this._pendingSnapshot = null;\n      this._groupingTimeout = groupingTimeout;\n    }\n\n    _createClass(EditHistory, [{\n      key: 'snapshot',\n      value: function snapshot() {\n        // update the current snapshot with the range read from DOM\n        if (this._pendingSnapshot) {\n          this._pendingSnapshot.snapshotRange();\n        }\n      }\n    }, {\n      key: 'storeSnapshot',\n      value: function storeSnapshot() {\n        var editAction = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];\n\n        var now = Date.now();\n        // store pending snapshot\n        var pendingSnapshot = this._pendingSnapshot;\n        if (pendingSnapshot) {\n          if (!pendingSnapshot.groupsWith(this._groupingTimeout, editAction, now)) {\n            this._undoStack.push(pendingSnapshot);\n          }\n          this._redoStack.clear();\n        }\n\n        // take new pending snapshot to store next time `storeSnapshot` is called\n        this._pendingSnapshot = new Snapshot(now, this.editor, editAction);\n      }\n    }, {\n      key: 'stepBackward',\n      value: function stepBackward(postEditor) {\n        // Throw away the pending snapshot\n        this._pendingSnapshot = null;\n\n        var snapshot = this._undoStack.pop();\n        if (snapshot) {\n          this._redoStack.push(new Snapshot(Date.now(), this.editor));\n          this._restoreFromSnapshot(snapshot, postEditor);\n        }\n      }\n    }, {\n      key: 'stepForward',\n      value: function stepForward(postEditor) {\n        var snapshot = this._redoStack.pop();\n        if (snapshot) {\n          this._undoStack.push(new Snapshot(Date.now(), this.editor));\n          this._restoreFromSnapshot(snapshot, postEditor);\n        }\n        postEditor.cancelSnapshot();\n      }\n    }, {\n      key: '_restoreFromSnapshot',\n      value: function _restoreFromSnapshot(snapshot, postEditor) {\n        var mobiledoc = snapshot.mobiledoc;\n        var editor = this.editor;\n        var builder = editor.builder;\n        var post = editor.post;\n\n        var restoredPost = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n\n        postEditor.removeAllSections();\n        postEditor.migrateSectionsFromPost(restoredPost);\n\n        // resurrect snapshotted range if it exists\n        var newRange = snapshot.getRange(post);\n        if (newRange) {\n          postEditor.setRange(newRange);\n        }\n      }\n    }]);\n\n    return EditHistory;\n  })();\n\n  exports['default'] = EditHistory;\n});","define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCursorRange) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /**\n   * Used by {@link Editor} to manage its current state (cursor, active markups\n   * and active sections).\n   * @private\n   */\n\n  var EditState = (function () {\n    function EditState(editor) {\n      _classCallCheck(this, EditState);\n\n      this.editor = editor;\n\n      var defaultState = {\n        range: _mobiledocKitUtilsCursorRange['default'].blankRange(),\n        activeMarkups: [],\n        activeSections: [],\n        activeSectionTagNames: [],\n        activeSectionAttributes: {}\n      };\n\n      this.prevState = this.state = defaultState;\n    }\n\n    _createClass(EditState, [{\n      key: 'updateRange',\n      value: function updateRange(newRange) {\n        this.prevState = this.state;\n        this.state = this._readState(newRange);\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this.editor = null;\n        this.prevState = this.state = null;\n      }\n\n      /**\n       * @return {Boolean}\n       */\n    }, {\n      key: 'rangeDidChange',\n      value: function rangeDidChange() {\n        var range = this.state.range;\n        var prevRange = this.prevState.range;\n\n        return !prevRange.isEqual(range);\n      }\n\n      /**\n       * @return {Boolean} Whether the input mode (active markups or active section tag names)\n       * has changed.\n       */\n    }, {\n      key: 'inputModeDidChange',\n      value: function inputModeDidChange() {\n        var state = this.state;\n        var prevState = this.prevState;\n\n        return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)((0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes));\n      }\n\n      /**\n       * @return {Range}\n       */\n    }, {\n      key: 'toggleMarkupState',\n\n      /**\n       * Update the editor's markup state. This is used when, e.g.,\n       * a user types meta+B when the editor has a cursor but no selected text;\n       * in this case the editor needs to track that it has an active \"b\" markup\n       * and apply it to the next text the user types.\n       */\n      value: function toggleMarkupState(markup) {\n        if ((0, _mobiledocKitUtilsArrayUtils.contains)(this.activeMarkups, markup)) {\n          this._removeActiveMarkup(markup);\n        } else {\n          this._addActiveMarkup(markup);\n        }\n      }\n    }, {\n      key: '_readState',\n      value: function _readState(range) {\n        var state = {\n          range: range,\n          activeMarkups: this._readActiveMarkups(range),\n          activeSections: this._readActiveSections(range)\n        };\n        // Section objects are 'live', so to check that they changed, we\n        // need to map their tagNames now (and compare to mapped tagNames later).\n        // In addition, to catch changes from ul -> ol, we keep track of the\n        // un-nested tag names (otherwise we'd only see li -> li change)\n        state.activeSectionTagNames = state.activeSections.map(function (s) {\n          return s.isNested ? s.parent.tagName : s.tagName;\n        });\n        state.activeSectionAttributes = this._readSectionAttributes(state.activeSections);\n        return state;\n      }\n    }, {\n      key: '_readActiveSections',\n      value: function _readActiveSections(range) {\n        var head = range.head;\n        var tail = range.tail;\n        var post = this.editor.post;\n\n        if (range.isBlank) {\n          return [];\n        } else {\n          return post.sections.readRange(head.section, tail.section);\n        }\n      }\n    }, {\n      key: '_readActiveMarkups',\n      value: function _readActiveMarkups(range) {\n        var post = this.editor.post;\n\n        return post.markupsInRange(range);\n      }\n    }, {\n      key: '_readSectionAttributes',\n      value: function _readSectionAttributes(sections) {\n        return sections.reduce(function (sectionAttributes, s) {\n          var attributes = s.isNested ? s.parent.attributes : s.attributes;\n          Object.keys(attributes || {}).forEach(function (attrName) {\n            var camelizedAttrName = attrName.replace(/^data-md-/, '');\n            var attrValue = attributes[attrName];\n            sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || [];\n            if (!(0, _mobiledocKitUtilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) {\n              sectionAttributes[camelizedAttrName].push(attrValue);\n            }\n          });\n          return sectionAttributes;\n        }, {});\n      }\n    }, {\n      key: '_removeActiveMarkup',\n      value: function _removeActiveMarkup(markup) {\n        var index = this.state.activeMarkups.indexOf(markup);\n        this.state.activeMarkups.splice(index, 1);\n      }\n    }, {\n      key: '_addActiveMarkup',\n      value: function _addActiveMarkup(markup) {\n        this.state.activeMarkups.push(markup);\n      }\n    }, {\n      key: 'range',\n      get: function get() {\n        return this.state.range;\n      }\n\n      /**\n       * @return {Section[]}\n       */\n    }, {\n      key: 'activeSections',\n      get: function get() {\n        return this.state.activeSections;\n      }\n\n      /**\n       * @return {Object}\n       */\n    }, {\n      key: 'activeSectionAttributes',\n      get: function get() {\n        return this.state.activeSectionAttributes;\n      }\n\n      /**\n       * @return {Markup[]}\n       */\n    }, {\n      key: 'activeMarkups',\n      get: function get() {\n        return this.state.activeMarkups;\n      }\n    }]);\n\n    return EditState;\n  })();\n\n  exports['default'] = EditState;\n});","define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/element-utils', 'mobiledoc-kit/utils/cursor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/environment', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/text-input-handlers', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/editor/mutation-handler', 'mobiledoc-kit/editor/edit-history', 'mobiledoc-kit/editor/event-manager', 'mobiledoc-kit/editor/edit-state', 'mobiledoc-dom-renderer', 'mobiledoc-text-renderer', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/log-manager', 'mobiledoc-kit/utils/to-range', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitViewsTooltip, _mobiledocKitEditorPost, _mobiledocKitCardsImage, _mobiledocKitUtilsKey, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersDom, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree, _mobiledocKitRenderersMobiledoc, _mobiledocKitUtilsMerge, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsElementUtils, _mobiledocKitUtilsCursor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsEnvironment, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorTextInputHandlers, _mobiledocKitEditorKeyCommands, _mobiledocKitModelsCard, _mobiledocKitUtilsAssert, _mobiledocKitEditorMutationHandler, _mobiledocKitEditorEditHistory, _mobiledocKitEditorEventManager, _mobiledocKitEditorEditState, _mobiledocDomRenderer, _mobiledocTextRenderer, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsLogManager, _mobiledocKitUtilsToRange, _mobiledocKitUtilsMobiledocError) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  // This export may later be deprecated, but re-export it from the renderer here\n  // for consumers that may depend on it.\n  Object.defineProperty(exports, 'EDITOR_ELEMENT_CLASS_NAME', {\n    enumerable: true,\n    get: function get() {\n      return _mobiledocKitRenderersEditorDom.EDITOR_ELEMENT_CLASS_NAME;\n    }\n  });\n\n  var defaults = {\n    placeholder: 'Write here...',\n    spellcheck: true,\n    autofocus: true,\n    showLinkTooltips: true,\n    undoDepth: 5,\n    undoBlockTimeout: 5000, // ms for an undo event\n    cards: [],\n    atoms: [],\n    cardOptions: {},\n    unknownCardHandler: function unknownCardHandler(_ref) {\n      var env = _ref.env;\n\n      throw new _mobiledocKitUtilsMobiledocError['default']('Unknown card encountered: ' + env.name);\n    },\n    unknownAtomHandler: function unknownAtomHandler(_ref2) {\n      var env = _ref2.env;\n\n      throw new _mobiledocKitUtilsMobiledocError['default']('Unknown atom encountered: ' + env.name);\n    },\n    mobiledoc: null,\n    html: null\n  };\n\n  var CALLBACK_QUEUES = {\n    DID_UPDATE: 'didUpdate',\n    WILL_RENDER: 'willRender',\n    DID_RENDER: 'didRender',\n    WILL_DELETE: 'willDelete',\n    DID_DELETE: 'didDelete',\n    WILL_HANDLE_NEWLINE: 'willHandleNewline',\n    CURSOR_DID_CHANGE: 'cursorDidChange',\n    DID_REPARSE: 'didReparse',\n    POST_DID_CHANGE: 'postDidChange',\n    INPUT_MODE_DID_CHANGE: 'inputModeDidChange'\n  };\n\n  /**\n   * The Editor is a core component of mobiledoc-kit. After instantiating\n   * an editor, use {@link Editor#render} to display the editor on the web page.\n   *\n   * An editor uses a {@link Post} internally to represent the displayed document.\n   * The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc\n   * is the transportable \"over-the-wire\" format (JSON) that is suited for persisting\n   * and sharing between editors and renderers (for display, e.g.), whereas the Post\n   * model is better suited for programmatic editing.\n   *\n   * The editor will call registered callbacks for certain state changes. These are:\n   *   * {@link Editor#cursorDidChange} -- The cursor position or selection changed.\n   *   * {@link Editor#postDidChange} -- The contents of the post changed due to user input or\n   *     programmatic editing. This hook can be used with {@link Editor#serialize}\n   *     to auto-save a post as it is being edited.\n   *   * {@link Editor#inputModeDidChange} -- The active section(s) or markup(s) at the current cursor\n   *     position or selection have changed. This hook can be used with\n   *     {@link Editor#activeMarkups} and {@link Editor#activeSections} to implement\n   *     a custom toolbar.\n   *   * {@link Editor#onTextInput} -- Register callbacks when the user enters text\n   *     that matches a given string or regex.\n   *   * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before\n   *     applying changes from {@link Editor#toggleMarkup}\n   */\n\n  var Editor = (function () {\n    /**\n     * @param {Object} [options]\n     * @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.\n     *        Supersedes `options.html`.\n     * @param {String|DOM} [options.html] The html (as a string or DOM fragment)\n     *        to parse and load into the editor.\n     *        Will be ignored if `options.mobiledoc` is also passed.\n     * @param {Array} [options.parserPlugins=[]]\n     * @param {Array} [options.cards=[]] The cards that the editor may render.\n     * @param {Array} [options.atoms=[]] The atoms that the editor may render.\n     * @param {Function} [options.unknownCardHandler] Invoked by the editor's renderer\n     *        whenever it encounters an unknown card.\n     * @param {Function} [options.unknownAtomHandler] Invoked by the editor's renderer\n     *        whenever it encounters an unknown atom.\n     * @param {String} [options.placeholder] Default text to show before user starts typing.\n     * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck\n     * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered.\n     * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links\n     * @param {number} [options.undoDepth=5] How many undo levels will be available.\n     *        Set to 0 to disable undo/redo functionality.\n     * @return {Editor}\n     * @public\n     */\n\n    function Editor() {\n      var _this = this;\n\n      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n      _classCallCheck(this, Editor);\n\n      (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType);\n      this._views = [];\n      this.isEditable = true;\n      this._parserPlugins = options.parserPlugins || [];\n\n      // FIXME: This should merge onto this.options\n      (0, _mobiledocKitUtilsMerge.mergeWithOptions)(this, defaults, options);\n      this.cards.push(_mobiledocKitCardsImage['default']);\n\n      _mobiledocKitEditorKeyCommands.DEFAULT_KEY_COMMANDS.forEach(function (kc) {\n        return _this.registerKeyCommand(kc);\n      });\n\n      this._logManager = new _mobiledocKitUtilsLogManager['default']();\n      this._parser = new _mobiledocKitParsersDom['default'](this.builder);\n      var cards = this.cards;\n      var atoms = this.atoms;\n      var unknownCardHandler = this.unknownCardHandler;\n      var unknownAtomHandler = this.unknownAtomHandler;\n      var cardOptions = this.cardOptions;\n\n      this._renderer = new _mobiledocKitRenderersEditorDom['default'](this, cards, atoms, unknownCardHandler, unknownAtomHandler, cardOptions);\n\n      this.post = this.loadPost();\n      this._renderTree = new _mobiledocKitModelsRenderTree['default'](this.post);\n\n      this._editHistory = new _mobiledocKitEditorEditHistory['default'](this, this.undoDepth, this.undoBlockTimeout);\n      this._eventManager = new _mobiledocKitEditorEventManager['default'](this);\n      this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this);\n      this._editState = new _mobiledocKitEditorEditState['default'](this);\n      this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n      this._beforeHooks = { toggleMarkup: [] };\n\n      _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) {\n        return _this.onTextInput(handler);\n      });\n\n      this.hasRendered = false;\n    }\n\n    /**\n     * Turns on verbose logging for the editor.\n     * @param {Array} [logTypes=[]] If present, only the given log types will be logged.\n     * @public\n     */\n\n    _createClass(Editor, [{\n      key: 'enableLogging',\n      value: function enableLogging() {\n        var logTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n        if (logTypes.length === 0) {\n          this._logManager.enableAll();\n        } else {\n          this._logManager.enableTypes(logTypes);\n        }\n      }\n\n      /**\n       * Disable all logging\n       * @public\n       */\n    }, {\n      key: 'disableLogging',\n      value: function disableLogging() {\n        this._logManager.disable();\n      }\n\n      /**\n       * @private\n       */\n    }, {\n      key: 'loggerFor',\n      value: function loggerFor(type) {\n        return this._logManager['for'](type);\n      }\n\n      /**\n       * The editor's instance of a post node builder.\n       * @type {PostNodeBuilder}\n       */\n    }, {\n      key: 'loadPost',\n      value: function loadPost() {\n        var mobiledoc = this.mobiledoc;\n        var html = this.html;\n\n        if (mobiledoc) {\n          return _mobiledocKitParsersMobiledoc['default'].parse(this.builder, mobiledoc);\n        } else if (html) {\n          if (typeof html === 'string') {\n            var options = { plugins: this._parserPlugins };\n            return new _mobiledocKitParsersHtml['default'](this.builder, options).parse(this.html);\n          } else {\n            var dom = html;\n            return this._parser.parse(dom);\n          }\n        } else {\n          return this.builder.createPost([this.builder.createMarkupSection()]);\n        }\n      }\n    }, {\n      key: 'rerender',\n      value: function rerender() {\n        var _this2 = this;\n\n        var postRenderNode = this.post.renderNode;\n\n        // if we haven't rendered this post's renderNode before, mark it dirty\n        if (!postRenderNode.element) {\n          (0, _mobiledocKitUtilsAssert['default'])('Must call `render` before `rerender` can be called', this.hasRendered);\n          postRenderNode.element = this.element;\n          postRenderNode.markDirty();\n        }\n\n        this.runCallbacks(CALLBACK_QUEUES.WILL_RENDER);\n        this._mutationHandler.suspendObservation(function () {\n          _this2._renderer.render(_this2._renderTree);\n        });\n        this.runCallbacks(CALLBACK_QUEUES.DID_RENDER);\n      }\n\n      /**\n       * @param {Element} element The DOM element to render into.\n       *        Its contents will be replaced by the editor's rendered post.\n       * @public\n       */\n    }, {\n      key: 'render',\n      value: function render(element) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot render an editor twice. Use `rerender` to update the ' + 'rendering of an existing editor instance.', !this.hasRendered);\n\n        element.spellcheck = this.spellcheck;\n\n        (0, _mobiledocKitUtilsDomUtils.clearChildNodes)(element);\n\n        this.element = element;\n\n        if (this.showLinkTooltips) {\n          this._addTooltip();\n        }\n\n        // A call to `run` will trigger the didUpdatePostCallbacks hooks with a\n        // postEditor.\n        this.run(function () {});\n\n        // Only set `hasRendered` to true after calling `run` to ensure that\n        // no cursorDidChange or other callbacks get fired before the editor is\n        // done rendering\n        this.hasRendered = true;\n        this.rerender();\n\n        this._mutationHandler.init();\n        this._eventManager.init();\n\n        if (this.isEditable === false) {\n          this.disableEditing();\n        } else {\n          this.enableEditing();\n        }\n\n        if (this.autofocus) {\n          this.selectRange(this.post.headPosition());\n        }\n      }\n    }, {\n      key: '_addTooltip',\n      value: function _addTooltip() {\n        this.addView(new _mobiledocKitViewsTooltip['default']({\n          rootElement: this.element,\n          showForTag: 'a'\n        }));\n      }\n    }, {\n      key: 'registerKeyCommand',\n\n      /**\n       * @param {Object} keyCommand The key command to register. It must specify a\n       * modifier key (meta, ctrl, etc), a string representing the ascii key, and\n       * a `run` method that will be passed the editor instance when the key command\n       * is invoked\n       * @public\n       */\n      value: function registerKeyCommand(rawKeyCommand) {\n        var keyCommand = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)(rawKeyCommand);\n        (0, _mobiledocKitUtilsAssert['default'])('Key Command is not valid', (0, _mobiledocKitEditorKeyCommands.validateKeyCommand)(keyCommand));\n        this.keyCommands.unshift(keyCommand);\n      }\n\n      /**\n       * @param {String} name If the keyCommand event has a name attribute it can be removed.\n       * @public\n       */\n    }, {\n      key: 'unregisterKeyCommands',\n      value: function unregisterKeyCommands(name) {\n        for (var i = this.keyCommands.length - 1; i > -1; i--) {\n          var keyCommand = this.keyCommands[i];\n\n          if (keyCommand.name === name) {\n            this.keyCommands.splice(i, 1);\n          }\n        }\n      }\n\n      /**\n       * Convenience for {@link PostEditor#deleteAtPosition}. Deletes and puts the\n       * cursor in the new position.\n       * @public\n       */\n    }, {\n      key: 'deleteAtPosition',\n      value: function deleteAtPosition(position, direction, _ref3) {\n        var unit = _ref3.unit;\n\n        this.run(function (postEditor) {\n          var nextPosition = postEditor.deleteAtPosition(position, direction, { unit: unit });\n          postEditor.setRange(nextPosition);\n        });\n      }\n\n      /**\n       * Convenience for {@link PostEditor#deleteRange}. Deletes and puts the\n       * cursor in the new position.\n       * @param {Range} range\n       * @public\n       */\n    }, {\n      key: 'deleteRange',\n      value: function deleteRange(range) {\n        this.run(function (postEditor) {\n          var nextPosition = postEditor.deleteRange(range);\n          postEditor.setRange(nextPosition);\n        });\n      }\n\n      /**\n       * @private\n       */\n    }, {\n      key: 'performDelete',\n      value: function performDelete() {\n        var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? { direction: _mobiledocKitUtilsKey.DIRECTION.BACKWARD, unit: 'char' } : arguments[0];\n\n        var direction = _ref4.direction;\n        var unit = _ref4.unit;\n        var range = this.range;\n\n        this.runCallbacks(CALLBACK_QUEUES.WILL_DELETE, [range, direction, unit]);\n        if (range.isCollapsed) {\n          this.deleteAtPosition(range.head, direction, { unit: unit });\n        } else {\n          this.deleteRange(range);\n        }\n        this.runCallbacks(CALLBACK_QUEUES.DID_DELETE, [range, direction, unit]);\n      }\n    }, {\n      key: 'handleNewline',\n      value: function handleNewline(event) {\n        var _this3 = this;\n\n        if (!this.hasCursor()) {\n          return;\n        }\n\n        event.preventDefault();\n\n        var range = this.range;\n\n        this.run(function (postEditor) {\n          var cursorSection = undefined;\n          if (!range.isCollapsed) {\n            var nextPosition = postEditor.deleteRange(range);\n            cursorSection = nextPosition.section;\n            if (cursorSection && cursorSection.isBlank) {\n              postEditor.setRange(cursorSection.headPosition());\n              return;\n            }\n          }\n\n          // Above logic might delete redundant range, so callback must run after it.\n          var defaultPrevented = false;\n          var event = { preventDefault: function preventDefault() {\n              defaultPrevented = true;\n            } };\n          _this3.runCallbacks(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, [event]);\n          if (defaultPrevented) {\n            return;\n          }\n\n          cursorSection = postEditor.splitSection(range.head)[1];\n          postEditor.setRange(cursorSection.headPosition());\n        });\n      }\n\n      /**\n       * Notify the editor that the post did change, and run associated\n       * callbacks.\n       * @private\n       */\n    }, {\n      key: '_postDidChange',\n      value: function _postDidChange() {\n        this.runCallbacks(CALLBACK_QUEUES.POST_DID_CHANGE);\n      }\n\n      /**\n       * Selects the given range or position. If given a collapsed range or a position, this positions the cursor\n       * at the range's position. Otherwise a selection is created in the editor\n       * surface encompassing the range.\n       * @param {Range|Position} range\n       */\n    }, {\n      key: 'selectRange',\n      value: function selectRange(range) {\n        range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n        this.cursor.selectRange(range);\n        this.range = range;\n      }\n    }, {\n      key: '_readRangeFromDOM',\n      value: function _readRangeFromDOM() {\n        this.range = this.cursor.offsets;\n      }\n    }, {\n      key: 'setPlaceholder',\n      value: function setPlaceholder(placeholder) {\n        (0, _mobiledocKitUtilsElementUtils.setData)(this.element, 'placeholder', placeholder);\n      }\n    }, {\n      key: '_reparsePost',\n      value: function _reparsePost() {\n        var post = this._parser.parse(this.element);\n        this.run(function (postEditor) {\n          postEditor.removeAllSections();\n          postEditor.migrateSectionsFromPost(post);\n          postEditor.setRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n        });\n\n        this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n        this._postDidChange();\n      }\n    }, {\n      key: '_reparseSections',\n      value: function _reparseSections() {\n        var _this4 = this;\n\n        var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n        var currentRange = undefined;\n        sections.forEach(function (section) {\n          _this4._parser.reparseSection(section, _this4._renderTree);\n        });\n        this._removeDetachedSections();\n\n        if (this._renderTree.isDirty) {\n          currentRange = this.range;\n        }\n\n        // force the current snapshot's range to remain the same rather than\n        // rereading it from DOM after the new character is applied and the browser\n        // updates the cursor position\n        var range = this._editHistory._pendingSnapshot.range;\n        this.run(function () {\n          _this4._editHistory._pendingSnapshot.range = range;\n        });\n        this.rerender();\n        if (currentRange) {\n          this.selectRange(currentRange);\n        }\n\n        this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n        this._postDidChange();\n      }\n\n      // FIXME this should be able to be removed now -- if any sections are detached,\n      // it's due to a bug in the code.\n    }, {\n      key: '_removeDetachedSections',\n      value: function _removeDetachedSections() {\n        (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.post.sections, function (s) {\n          return !s.renderNode.isAttached();\n        }), function (s) {\n          return s.renderNode.scheduleForRemoval();\n        });\n      }\n\n      /**\n       * The sections from the cursor's selection start to the selection end\n       * @type {Section[]}\n       */\n    }, {\n      key: 'detectMarkupInRange',\n      value: function detectMarkupInRange(range, markupTagName) {\n        var markups = this.post.markupsInRange(range);\n        return (0, _mobiledocKitUtilsArrayUtils.detect)(markups, function (markup) {\n          return markup.hasTag(markupTagName);\n        });\n      }\n\n      /**\n       * @type {Markup[]}\n       * @public\n       */\n    }, {\n      key: 'hasActiveMarkup',\n\n      /**\n       * @param {Markup|String} markup A markup instance, or a string (e.g. \"b\")\n       * @return {boolean}\n       */\n      value: function hasActiveMarkup(markup) {\n        var matchesFn = undefined;\n        if (typeof markup === 'string') {\n          (function () {\n            var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(markup);\n            matchesFn = function (m) {\n              return m.tagName === tagName;\n            };\n          })();\n        } else {\n          matchesFn = function (m) {\n            return m === markup;\n          };\n        }\n\n        return !!(0, _mobiledocKitUtilsArrayUtils.detect)(this.activeMarkups, matchesFn);\n      }\n\n      /**\n       * @param {String} version The mobiledoc version to serialize to.\n       * @return {Mobiledoc} Serialized mobiledoc\n       * @public\n       */\n    }, {\n      key: 'serialize',\n      value: function serialize() {\n        var version = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION : arguments[0];\n\n        return this.serializePost(this.post, 'mobiledoc', { version: version });\n      }\n\n      /**\n       * Serialize the editor's post to the requested format.\n       * Note that only mobiledoc format is lossless. If cards or atoms are present\n       * in the post, the html and text formats will omit them in output because\n       * the editor does not have access to the html and text versions of the\n       * cards/atoms.\n       * @param {string} format The format to serialize ('mobiledoc', 'text', 'html')\n       * @return {Object|String} The editor's post, serialized to {format}\n       * @public\n       */\n    }, {\n      key: 'serializeTo',\n      value: function serializeTo(format) {\n        var post = this.post;\n        return this.serializePost(post, format);\n      }\n\n      /**\n       * @param {Post}\n       * @param {String} format Same as {serializeTo}\n       * @param {Object} [options]\n       * @param {String} [options.version=MOBILEDOC_VERSION] version to serialize to\n       * @return {Object|String}\n       * @private\n       */\n    }, {\n      key: 'serializePost',\n      value: function serializePost(post, format) {\n        var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n        var validFormats = ['mobiledoc', 'html', 'text'];\n        (0, _mobiledocKitUtilsAssert['default'])('Unrecognized serialization format ' + format, (0, _mobiledocKitUtilsArrayUtils.contains)(validFormats, format));\n\n        if (format === 'mobiledoc') {\n          var version = options.version || _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n          return _mobiledocKitRenderersMobiledoc['default'].render(post, version);\n        } else {\n          var rendered = undefined;\n          var mobiledoc = this.serializePost(post, 'mobiledoc');\n          var unknownCardHandler = function unknownCardHandler() {};\n          var unknownAtomHandler = function unknownAtomHandler() {};\n          var rendererOptions = { unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n\n          switch (format) {\n            case 'html':\n              {\n                var result = undefined;\n                if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) {\n                  rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc);\n                  result = '<div>' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '</div>';\n                } else {\n                  // Fallback to text serialization\n                  result = this.serializePost(post, 'text', options);\n                }\n                return result;\n              }\n            case 'text':\n              rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc);\n              return rendered.result;\n          }\n        }\n      }\n    }, {\n      key: 'addView',\n      value: function addView(view) {\n        this._views.push(view);\n      }\n    }, {\n      key: 'removeAllViews',\n      value: function removeAllViews() {\n        this._views.forEach(function (v) {\n          return v.destroy();\n        });\n        this._views = [];\n      }\n\n      /**\n       * Whether the editor has a cursor (or a selected range).\n       * It is possible for the editor to be focused but not have a selection.\n       * In this case, key events will fire but the editor will not be able to\n       * determine a cursor position, so they will be ignored.\n       * @return {boolean}\n       * @public\n       */\n    }, {\n      key: 'hasCursor',\n      value: function hasCursor() {\n        return this.cursor.hasCursor();\n      }\n\n      /**\n       * Tears down the editor's attached event listeners and views.\n       * @public\n       */\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this.isDestroyed = true;\n        if (this._hasSelection()) {\n          this.cursor.clearSelection();\n        }\n        if (this._hasFocus()) {\n          this.element.blur(); // FIXME This doesn't blur the element on IE11\n        }\n        this._mutationHandler.destroy();\n        this._eventManager.destroy();\n        this.removeAllViews();\n        this._renderer.destroy();\n        this._editState.destroy();\n      }\n\n      /**\n       * Keep the user from directly editing the post using the keyboard and mouse.\n       * Modification via the programmatic API is still permitted.\n       * @see Editor#enableEditing\n       * @public\n       */\n    }, {\n      key: 'disableEditing',\n      value: function disableEditing() {\n        this.isEditable = false;\n        if (this.hasRendered) {\n          this._eventManager.stop();\n          this.element.setAttribute('contentEditable', false);\n          this.setPlaceholder('');\n          this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n        }\n      }\n\n      /**\n       * Allow the user to directly interact with editing a post via keyboard and mouse input.\n       * Editor instances are editable by default. Use this method to re-enable\n       * editing after disabling it.\n       * @see Editor#disableEditing\n       * @public\n       */\n    }, {\n      key: 'enableEditing',\n      value: function enableEditing() {\n        this.isEditable = true;\n        if (this.hasRendered) {\n          this._eventManager.start();\n          this.element.setAttribute('contentEditable', true);\n          this.setPlaceholder(this.placeholder);\n        }\n      }\n\n      /**\n       * Change a cardSection into edit mode\n       * If called before the card has been rendered, it will be marked so that\n       * it is rendered in edit mode when it gets rendered.\n       * @param {CardSection} cardSection\n       * @public\n       */\n    }, {\n      key: 'editCard',\n      value: function editCard(cardSection) {\n        this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.EDIT);\n      }\n\n      /**\n       * Change a cardSection into display mode\n       * If called before the card has been rendered, it will be marked so that\n       * it is rendered in display mode when it gets rendered.\n       * @param {CardSection} cardSection\n       * @return undefined\n       * @public\n       */\n    }, {\n      key: 'displayCard',\n      value: function displayCard(cardSection) {\n        this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.DISPLAY);\n      }\n\n      /**\n       * Run a new post editing session. Yields a block with a new {@link PostEditor}\n       * instance. This instance can be used to interact with the post abstract.\n       * Rendering will be deferred until after the callback is completed.\n       *\n       * Usage:\n       * ```\n       *   let markerRange = this.range;\n       *   editor.run((postEditor) => {\n       *     postEditor.deleteRange(markerRange);\n       *     // editing surface not updated yet\n       *     postEditor.schedule(() => {\n       *       console.log('logs during rerender flush');\n       *     });\n       *     // logging not yet flushed\n       *   });\n       *   // editing surface now updated.\n       *   // logging now flushed\n       * ```\n       *\n       * @param {Function} callback Called with an instance of\n       *        {@link PostEditor} as its argument.\n       * @return {Mixed} The return value of `callback`.\n       * @public\n       */\n    }, {\n      key: 'run',\n      value: function run(callback) {\n        var postEditor = new _mobiledocKitEditorPost['default'](this);\n        postEditor.begin();\n        this._editHistory.snapshot();\n        var result = callback(postEditor);\n        this.runCallbacks(CALLBACK_QUEUES.DID_UPDATE, [postEditor]);\n        postEditor.complete();\n        this._readRangeFromDOM();\n\n        if (postEditor._shouldCancelSnapshot) {\n          this._editHistory._pendingSnapshot = null;\n        }\n        this._editHistory.storeSnapshot(postEditor.editActionTaken);\n\n        return result;\n      }\n\n      /**\n       * @param {Function} callback Called with `postEditor` as its argument.\n       * @public\n       */\n    }, {\n      key: 'didUpdatePost',\n      value: function didUpdatePost(callback) {\n        this.addCallback(CALLBACK_QUEUES.DID_UPDATE, callback);\n      }\n\n      /**\n       * @param {Function} callback Called when the post has changed, either via\n       *        user input or programmatically. Use with {@link Editor#serialize} to\n       *        retrieve the post in portable mobiledoc format.\n       */\n    }, {\n      key: 'postDidChange',\n      value: function postDidChange(callback) {\n        this.addCallback(CALLBACK_QUEUES.POST_DID_CHANGE, callback);\n      }\n\n      /**\n       * Register a handler that will be invoked by the editor after the user enters\n       * matching text.\n       * @param {Object} inputHandler\n       * @param {String} inputHandler.name Required. Used by identifying handlers.\n       * @param {String} [inputHandler.text] Required if `match` is not provided\n       * @param {RegExp} [inputHandler.match] Required if `text` is not provided\n       * @param {Function} inputHandler.run This callback is invoked with the {@link Editor}\n       *                   instance and an array of matches. If `text` was provided,\n       *                   the matches array will equal [`text`], and if a `match`\n       *                   regex was provided the matches array will be the result of\n       *                   `match.exec` on the matching text. The callback is called\n       *                   after the matching text has been inserted.\n       * @public\n       */\n    }, {\n      key: 'onTextInput',\n      value: function onTextInput(inputHandler) {\n        this._eventManager.registerInputHandler(inputHandler);\n      }\n\n      /**\n       * Unregister all text input handlers\n       *\n       * @public\n       */\n    }, {\n      key: 'unregisterAllTextInputHandlers',\n      value: function unregisterAllTextInputHandlers() {\n        this._eventManager.unregisterAllTextInputHandlers();\n      }\n\n      /**\n       * Unregister text input handler by name\n       * @param {String} name The name of handler to be removed\n       *\n       * @public\n       */\n    }, {\n      key: 'unregisterTextInputHandler',\n      value: function unregisterTextInputHandler(name) {\n        this._eventManager.unregisterInputHandler(name);\n      }\n\n      /**\n       * @param {Function} callback Called when the editor's state (active markups or\n       * active sections) has changed, either via user input or programmatically\n       */\n    }, {\n      key: 'inputModeDidChange',\n      value: function inputModeDidChange(callback) {\n        this.addCallback(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE, callback);\n      }\n\n      /**\n       * @param {Function} callback This callback will be called before the editor\n       *        is rendered.\n       * @public\n       */\n    }, {\n      key: 'willRender',\n      value: function willRender(callback) {\n        this.addCallback(CALLBACK_QUEUES.WILL_RENDER, callback);\n      }\n\n      /**\n       * @param {Function} callback This callback will be called after the editor\n       *        is rendered.\n       * @public\n       */\n    }, {\n      key: 'didRender',\n      value: function didRender(callback) {\n        this.addCallback(CALLBACK_QUEUES.DID_RENDER, callback);\n      }\n\n      /**\n       * @param {Function} callback This callback will be called before deleting.\n       * @public\n       */\n    }, {\n      key: 'willDelete',\n      value: function willDelete(callback) {\n        this.addCallback(CALLBACK_QUEUES.WILL_DELETE, callback);\n      }\n\n      /**\n       * @param {Function} callback This callback will be called after deleting.\n       * @public\n       */\n    }, {\n      key: 'didDelete',\n      value: function didDelete(callback) {\n        this.addCallback(CALLBACK_QUEUES.DID_DELETE, callback);\n      }\n\n      /**\n       * @param {Function} callback This callback will be called before handling new line.\n       * @public\n       */\n    }, {\n      key: 'willHandleNewline',\n      value: function willHandleNewline(callback) {\n        this.addCallback(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, callback);\n      }\n\n      /**\n       * @param {Function} callback This callback will be called every time the cursor\n       *        position (or selection) changes.\n       * @public\n       */\n    }, {\n      key: 'cursorDidChange',\n      value: function cursorDidChange(callback) {\n        this.addCallback(CALLBACK_QUEUES.CURSOR_DID_CHANGE, callback);\n      }\n    }, {\n      key: '_rangeDidChange',\n      value: function _rangeDidChange() {\n        if (this.hasRendered) {\n          this.runCallbacks(CALLBACK_QUEUES.CURSOR_DID_CHANGE);\n        }\n      }\n    }, {\n      key: '_inputModeDidChange',\n      value: function _inputModeDidChange() {\n        this.runCallbacks(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE);\n      }\n    }, {\n      key: '_insertEmptyMarkupSectionAtCursor',\n      value: function _insertEmptyMarkupSectionAtCursor() {\n        var _this5 = this;\n\n        this.run(function (postEditor) {\n          var section = postEditor.builder.createMarkupSection('p');\n          postEditor.insertSectionBefore(_this5.post.sections, section);\n          postEditor.setRange(section.toRange());\n        });\n      }\n\n      /**\n       * @callback editorBeforeCallback\n       * @param { Object } details\n       * @param { Markup } details.markup\n       * @param { Range } details.range\n       * @param { boolean } details.willAdd Whether the markup will be applied\n       */\n\n      /**\n       * Register a callback that will be run before {@link Editor#toggleMarkup} is applied.\n       * If any callback returns literal `false`, the toggling of markup will be canceled.\n       * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and\n       * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks.\n       * @param {editorBeforeCallback}\n       */\n    }, {\n      key: 'beforeToggleMarkup',\n      value: function beforeToggleMarkup(callback) {\n        this._beforeHooks.toggleMarkup.push(callback);\n      }\n\n      /**\n       * Toggles the given markup at the editor's current {@link Range}.\n       * If the range is collapsed this changes the editor's state so that the\n       * next characters typed will be affected. If there is text selected\n       * (aka a non-collapsed range), the selections' markup will be toggled.\n       * If the editor is not focused and has no active range, nothing happens.\n       * Hooks added using #beforeToggleMarkup will be run before toggling,\n       * and if any of them returns literal false, toggling the markup will be canceled\n       * and no change will be applied.\n       * @param {String} markup E.g. \"b\", \"em\", \"a\"\n       * @param {Object} [attributes={}] E.g. {href: \"http://bustle.com\"}\n       * @public\n       * @see PostEditor#toggleMarkup\n       */\n    }, {\n      key: 'toggleMarkup',\n      value: function toggleMarkup(markup) {\n        var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        markup = this.builder.createMarkup(markup, attributes);\n        var range = this.range;\n\n        var willAdd = !this.detectMarkupInRange(range, markup.tagName);\n        var shouldCancel = this._runBeforeHooks('toggleMarkup', { markup: markup, range: range, willAdd: willAdd });\n        if (shouldCancel) {\n          return;\n        }\n\n        if (range.isCollapsed) {\n          this._editState.toggleMarkupState(markup);\n          this._inputModeDidChange();\n\n          // when clicking a button to toggle markup, the button can end up being focused,\n          // so ensure the editor is focused\n          this._ensureFocus();\n        } else {\n          this.run(function (postEditor) {\n            return postEditor.toggleMarkup(markup, range);\n          });\n        }\n      }\n\n      // If the editor has a selection but is not focused, focus it\n    }, {\n      key: '_ensureFocus',\n      value: function _ensureFocus() {\n        if (this._hasSelection() && !this._hasFocus()) {\n          this.focus();\n        }\n      }\n    }, {\n      key: 'focus',\n      value: function focus() {\n        this.element.focus();\n      }\n\n      /**\n       * Whether there is a selection inside the editor's element.\n       * It's possible to have a selection but not have focus.\n       * @see #_hasFocus\n       * @return {Boolean}\n       */\n    }, {\n      key: '_hasSelection',\n      value: function _hasSelection() {\n        var cursor = this.cursor;\n\n        return this.hasRendered && (cursor._hasCollapsedSelection() || cursor._hasSelection());\n      }\n\n      /**\n       * Whether the editor's element is focused\n       * It's possible to be focused but have no selection\n       * @see #_hasSelection\n       * @return {Boolean}\n       */\n    }, {\n      key: '_hasFocus',\n      value: function _hasFocus() {\n        return document.activeElement === this.element;\n      }\n\n      /**\n       * Toggles the tagName for the current active section(s). This will skip\n       * non-markerable sections. E.g. if the editor's range includes a \"P\" MarkupSection\n       * and a CardSection, only the MarkupSection will be toggled.\n       * @param {String} tagName The new tagname to change to.\n       * @public\n       * @see PostEditor#toggleSection\n       */\n    }, {\n      key: 'toggleSection',\n      value: function toggleSection(tagName) {\n        var _this6 = this;\n\n        this.run(function (postEditor) {\n          return postEditor.toggleSection(tagName, _this6.range);\n        });\n      }\n\n      /**\n       * Sets an attribute for the current active section(s).\n       *\n       * @param {String} key The attribute. The only valid attribute is 'text-align'.\n       * @param {String} value The value of the attribute.\n       * @public\n       * @see PostEditor#setAttribute\n       */\n    }, {\n      key: 'setAttribute',\n      value: function setAttribute(key, value) {\n        var _this7 = this;\n\n        this.run(function (postEditor) {\n          return postEditor.setAttribute(key, value, _this7.range);\n        });\n      }\n\n      /**\n       * Removes an attribute from the current active section(s).\n       *\n       * @param {String} key The attribute. The only valid attribute is 'text-align'.\n       * @public\n       * @see PostEditor#removeAttribute\n       */\n    }, {\n      key: 'removeAttribute',\n      value: function removeAttribute(key) {\n        var _this8 = this;\n\n        this.run(function (postEditor) {\n          return postEditor.removeAttribute(key, _this8.range);\n        });\n      }\n\n      /**\n       * Finds and runs the first matching key command for the event\n       *\n       * If multiple commands are bound to a key combination, the\n       * first matching one is run.\n       *\n       * If a command returns `false` then the next matching command\n       * is run instead.\n       *\n       * @param {Event} event The keyboard event triggered by the user\n       * @return {Boolean} true when a command was successfully run\n       * @private\n       */\n    }, {\n      key: 'handleKeyCommand',\n      value: function handleKeyCommand(event) {\n        var keyCommands = (0, _mobiledocKitEditorKeyCommands.findKeyCommands)(this.keyCommands, event);\n        for (var i = 0; i < keyCommands.length; i++) {\n          var keyCommand = keyCommands[i];\n          if (keyCommand.run(this) !== false) {\n            event.preventDefault();\n            return true;\n          }\n        }\n        return false;\n      }\n\n      /**\n       * Inserts the text at the current cursor position. If the editor has\n       * no current cursor position, nothing will be inserted. If the editor's\n       * range is not collapsed, it will be deleted before insertion.\n       *\n       * @param {String} text\n       * @public\n       */\n    }, {\n      key: 'insertText',\n      value: function insertText(text) {\n        if (!this.hasCursor()) {\n          return;\n        }\n        if (this.post.isBlank) {\n          this._insertEmptyMarkupSectionAtCursor();\n        }\n        var activeMarkups = this.activeMarkups;\n        var range = this.range;\n        var position = this.range.head;\n\n        this.run(function (postEditor) {\n          if (!range.isCollapsed) {\n            position = postEditor.deleteRange(range);\n          }\n\n          postEditor.insertTextWithMarkup(position, text, activeMarkups);\n        });\n      }\n\n      /**\n       * Inserts an atom at the current cursor position. If the editor has\n       * no current cursor position, nothing will be inserted. If the editor's\n       * range is not collapsed, it will be deleted before insertion.\n       * @param {String} atomName\n       * @param {String} [atomText='']\n       * @param {Object} [atomPayload={}]\n       * @return {Atom} The inserted atom.\n       * @public\n       */\n    }, {\n      key: 'insertAtom',\n      value: function insertAtom(atomName) {\n        var atomText = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n        var atomPayload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n        if (!this.hasCursor()) {\n          return;\n        }\n        if (this.post.isBlank) {\n          this._insertEmptyMarkupSectionAtCursor();\n        }\n\n        var atom = undefined;\n        var range = this.range;\n\n        this.run(function (postEditor) {\n          var position = range.head;\n\n          atom = postEditor.builder.createAtom(atomName, atomText, atomPayload);\n          if (!range.isCollapsed) {\n            position = postEditor.deleteRange(range);\n          }\n\n          postEditor.insertMarkers(position, [atom]);\n        });\n        return atom;\n      }\n\n      /**\n       * Inserts a card at the section after the current cursor position. If the editor has\n       * no current cursor position, nothing will be inserted. If the editor's\n       * range is not collapsed, it will be deleted before insertion. If the cursor is in\n       * a blank section, it will be replaced with a card section.\n       * The editor's cursor will be placed at the end of the inserted card.\n       * @param {String} cardName\n       * @param {Object} [cardPayload={}]\n       * @param {Boolean} [inEditMode=false] Whether the card should be inserted in edit mode.\n       * @return {Card} The inserted Card section.\n       * @public\n       */\n    }, {\n      key: 'insertCard',\n      value: function insertCard(cardName) {\n        var _this9 = this;\n\n        var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n        var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n        if (!this.hasCursor()) {\n          return;\n        }\n        if (this.post.isBlank) {\n          this._insertEmptyMarkupSectionAtCursor();\n        }\n\n        var card = undefined;\n        var range = this.range;\n\n        this.run(function (postEditor) {\n          var position = range.tail;\n          card = postEditor.builder.createCardSection(cardName, cardPayload);\n          if (inEditMode) {\n            _this9.editCard(card);\n          }\n\n          if (!range.isCollapsed) {\n            position = postEditor.deleteRange(range);\n          }\n\n          var section = position.section;\n          if (section.isNested) {\n            section = section.parent;\n          }\n\n          if (section.isBlank) {\n            postEditor.replaceSection(section, card);\n          } else {\n            var collection = _this9.post.sections;\n            postEditor.insertSectionBefore(collection, card, section.next);\n          }\n\n          // It is important to explicitly set the range to the end of the card.\n          // Otherwise it is possible to create an inconsistent state in the\n          // browser. For instance, if the user clicked a button that\n          // called `editor.insertCard`, the editor surface may retain\n          // the selection but lose focus, and the next keystroke by the user\n          // will cause an unexpected DOM mutation (which can wipe out the\n          // card).\n          // See: https://github.com/bustle/mobiledoc-kit/issues/286\n          postEditor.setRange(card.tailPosition());\n        });\n        return card;\n      }\n\n      /**\n       * @param {integer} x x-position in viewport\n       * @param {integer} y y-position in viewport\n       * @return {Position|null}\n       */\n    }, {\n      key: 'positionAtPoint',\n      value: function positionAtPoint(x, y) {\n        return _mobiledocKitUtilsCursorPosition['default'].atPoint(x, y, this);\n      }\n\n      /**\n       * @private\n       */\n    }, {\n      key: '_setCardMode',\n      value: function _setCardMode(cardSection, mode) {\n        var renderNode = cardSection.renderNode;\n        if (renderNode && renderNode.isRendered) {\n          var cardNode = renderNode.cardNode;\n          cardNode[mode]();\n        } else {\n          cardSection.setInitialMode(mode);\n        }\n      }\n    }, {\n      key: 'triggerEvent',\n      value: function triggerEvent(context, eventName, event) {\n        this._eventManager._trigger(context, eventName, event);\n      }\n    }, {\n      key: 'addCallback',\n      value: function addCallback() {\n        var _callbacks;\n\n        (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n      }\n    }, {\n      key: 'addCallbackOnce',\n      value: function addCallbackOnce() {\n        var _callbacks2;\n\n        (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n      }\n    }, {\n      key: 'runCallbacks',\n      value: function runCallbacks() {\n        var _callbacks3;\n\n        if (this.isDestroyed) {\n          // TODO warn that callback attempted after editor was destroyed\n          return;\n        }\n        (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n      }\n\n      /**\n       * Runs each callback for the given hookName.\n       * Only the hookName 'toggleMarkup' is currently supported\n       * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled\n       * @private\n       */\n    }, {\n      key: '_runBeforeHooks',\n      value: function _runBeforeHooks(hookName) {\n        var hooks = this._beforeHooks[hookName] || [];\n\n        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n          args[_key - 1] = arguments[_key];\n        }\n\n        for (var i = 0; i < hooks.length; i++) {\n          if (hooks[i].apply(hooks, args) === false) {\n            return true;\n          }\n        }\n      }\n    }, {\n      key: 'builder',\n      get: function get() {\n        if (!this._builder) {\n          this._builder = new _mobiledocKitModelsPostNodeBuilder['default']();\n        }\n        return this._builder;\n      }\n    }, {\n      key: 'keyCommands',\n      get: function get() {\n        if (!this._keyCommands) {\n          this._keyCommands = [];\n        }\n        return this._keyCommands;\n      }\n    }, {\n      key: 'cursor',\n      get: function get() {\n        return new _mobiledocKitUtilsCursor['default'](this);\n      }\n\n      /**\n       * Return the current range for the editor (may be cached).\n       * @return {Range}\n       */\n    }, {\n      key: 'range',\n      get: function get() {\n        return this._editState.range;\n      },\n      set: function set(newRange) {\n        this._editState.updateRange(newRange);\n\n        if (this._editState.rangeDidChange()) {\n          this._rangeDidChange();\n        }\n\n        if (this._editState.inputModeDidChange()) {\n          this._inputModeDidChange();\n        }\n      }\n    }, {\n      key: 'activeSections',\n      get: function get() {\n        return this._editState.activeSections;\n      }\n    }, {\n      key: 'activeSection',\n      get: function get() {\n        var activeSections = this.activeSections;\n\n        return activeSections[activeSections.length - 1];\n      }\n    }, {\n      key: 'activeSectionAttributes',\n      get: function get() {\n        return this._editState.activeSectionAttributes;\n      }\n    }, {\n      key: 'activeMarkups',\n      get: function get() {\n        return this._editState.activeMarkups;\n      }\n    }]);\n\n    return Editor;\n  })();\n\n  exports['default'] = Editor;\n});","define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/parse-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/editor/text-input-handler', 'mobiledoc-kit/editor/selection-manager', 'mobiledoc-kit/utils/browser'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitUtilsParseUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitEditorTextInputHandler, _mobiledocKitEditorSelectionManager, _mobiledocKitUtilsBrowser) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var ELEMENT_EVENT_TYPES = ['keydown', 'keyup', 'cut', 'copy', 'paste', 'keypress', 'drop'];\n\n  var EventManager = (function () {\n    function EventManager(editor) {\n      _classCallCheck(this, EventManager);\n\n      this.editor = editor;\n      this.logger = editor.loggerFor('event-manager');\n      this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor);\n      this._listeners = [];\n      this.modifierKeys = {\n        shift: false\n      };\n\n      this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this));\n      this.started = true;\n    }\n\n    _createClass(EventManager, [{\n      key: 'init',\n      value: function init() {\n        var _this = this;\n\n        var element = this.editor.element;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot init EventManager without element', !!element);\n\n        ELEMENT_EVENT_TYPES.forEach(function (type) {\n          _this._addListener(element, type);\n        });\n\n        this._selectionManager.start();\n      }\n    }, {\n      key: 'start',\n      value: function start() {\n        this.started = true;\n      }\n    }, {\n      key: 'stop',\n      value: function stop() {\n        this.started = false;\n      }\n    }, {\n      key: 'registerInputHandler',\n      value: function registerInputHandler(inputHandler) {\n        this._textInputHandler.register(inputHandler);\n      }\n    }, {\n      key: 'unregisterInputHandler',\n      value: function unregisterInputHandler(name) {\n        this._textInputHandler.unregister(name);\n      }\n    }, {\n      key: 'unregisterAllTextInputHandlers',\n      value: function unregisterAllTextInputHandlers() {\n        this._textInputHandler.destroy();\n        this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](this.editor);\n      }\n    }, {\n      key: '_addListener',\n      value: function _addListener(context, type) {\n        var _this2 = this;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Missing listener for ' + type, !!this[type]);\n\n        var listener = function listener(event) {\n          return _this2._handleEvent(type, event);\n        };\n        context.addEventListener(type, listener);\n        this._listeners.push([context, type, listener]);\n      }\n    }, {\n      key: '_removeListeners',\n      value: function _removeListeners() {\n        this._listeners.forEach(function (_ref) {\n          var _ref2 = _slicedToArray(_ref, 3);\n\n          var context = _ref2[0];\n          var type = _ref2[1];\n          var listener = _ref2[2];\n\n          context.removeEventListener(type, listener);\n        });\n        this._listeners = [];\n      }\n\n      // This is primarily useful for programmatically simulating events on the\n      // editor from the tests.\n    }, {\n      key: '_trigger',\n      value: function _trigger(context, type, event) {\n        (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this._listeners, function (_ref3) {\n          var _ref32 = _slicedToArray(_ref3, 2);\n\n          var _context = _ref32[0];\n          var _type = _ref32[1];\n\n          return _context === context && _type === type;\n        }), function (_ref4) {\n          var _ref42 = _slicedToArray(_ref4, 3);\n\n          var context = _ref42[0];\n          var listener = _ref42[2];\n\n          listener.call(context, event);\n        });\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this._textInputHandler.destroy();\n        this._selectionManager.destroy();\n        this._removeListeners();\n      }\n    }, {\n      key: '_handleEvent',\n      value: function _handleEvent(type, event) {\n        var element = event.target;\n\n        if (!this.started) {\n          // abort handling this event\n          return true;\n        }\n\n        if (!this.isElementAddressable(element)) {\n          // abort handling this event\n          return true;\n        }\n\n        this[type](event);\n      }\n    }, {\n      key: 'isElementAddressable',\n      value: function isElementAddressable(element) {\n        return this.editor.cursor.isAddressable(element);\n      }\n    }, {\n      key: 'selectionDidChange',\n      value: function selectionDidChange(selection /*, prevSelection */) {\n        var shouldNotify = true;\n        var anchorNode = selection.anchorNode;\n\n        if (!this.isElementAddressable(anchorNode)) {\n          if (!this.editor.range.isBlank) {\n            // Selection changed from something addressable to something\n            // not-addressable -- e.g., blur event, user clicked outside editor,\n            // etc\n            shouldNotify = true;\n          } else {\n            // selection changes wholly outside the editor should not trigger\n            // change notifications\n            shouldNotify = false;\n          }\n        }\n\n        if (shouldNotify) {\n          this.editor._readRangeFromDOM();\n        }\n      }\n    }, {\n      key: 'keypress',\n      value: function keypress(event) {\n        var editor = this.editor;\n        var _textInputHandler = this._textInputHandler;\n\n        if (!editor.hasCursor()) {\n          return;\n        }\n\n        var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n        if (!key.isPrintable()) {\n          return;\n        } else {\n          event.preventDefault();\n        }\n\n        _textInputHandler.handle(key.toString());\n      }\n    }, {\n      key: 'keydown',\n      value: function keydown(event) {\n        var editor = this.editor;\n\n        if (!editor.hasCursor()) {\n          return;\n        }\n        if (!editor.isEditable) {\n          return;\n        }\n\n        var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n        this._updateModifiersFromKey(key, { isDown: true });\n\n        if (editor.handleKeyCommand(event)) {\n          return;\n        }\n\n        if (editor.post.isBlank) {\n          editor._insertEmptyMarkupSectionAtCursor();\n        }\n\n        var range = editor.range;\n\n        switch (true) {\n          // FIXME This should be restricted to only card/atom boundaries\n          case key.isHorizontalArrowWithoutModifiersOtherThanShift():\n            {\n              var newRange = undefined;\n              if (key.isShift()) {\n                newRange = range.extend(key.direction * 1);\n              } else {\n                newRange = range.move(key.direction);\n              }\n\n              editor.selectRange(newRange);\n              event.preventDefault();\n              break;\n            }\n          case key.isDelete():\n            {\n              var direction = key.direction;\n\n              var unit = 'char';\n              if (key.altKey && _mobiledocKitUtilsBrowser['default'].isMac()) {\n                unit = 'word';\n              } else if (key.ctrlKey && !_mobiledocKitUtilsBrowser['default'].isMac()) {\n                unit = 'word';\n              }\n              editor.performDelete({ direction: direction, unit: unit });\n              event.preventDefault();\n              break;\n            }\n          case key.isEnter():\n            this._textInputHandler.handleNewLine();\n            editor.handleNewline(event);\n            break;\n          case key.isTab():\n            // Handle tab here because it does not fire a `keypress` event\n            event.preventDefault();\n            this._textInputHandler.handle(key.toString());\n            break;\n        }\n      }\n    }, {\n      key: 'keyup',\n      value: function keyup(event) {\n        var editor = this.editor;\n\n        if (!editor.hasCursor()) {\n          return;\n        }\n        var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n        this._updateModifiersFromKey(key, { isDown: false });\n      }\n    }, {\n      key: 'cut',\n      value: function cut(event) {\n        event.preventDefault();\n\n        this.copy(event);\n        this.editor.performDelete();\n      }\n    }, {\n      key: 'copy',\n      value: function copy(event) {\n        event.preventDefault();\n\n        var editor = this.editor;\n        var _editor = this.editor;\n        var range = _editor.range;\n        var post = _editor.post;\n\n        post = post.trimTo(range);\n\n        var data = {\n          html: editor.serializePost(post, 'html'),\n          text: editor.serializePost(post, 'text'),\n          mobiledoc: editor.serializePost(post, 'mobiledoc')\n        };\n\n        (0, _mobiledocKitUtilsParseUtils.setClipboardData)(event, data, window);\n      }\n    }, {\n      key: 'paste',\n      value: function paste(event) {\n        event.preventDefault();\n\n        var editor = this.editor;\n\n        var range = editor.range;\n\n        if (!range.isCollapsed) {\n          editor.performDelete();\n        }\n\n        if (editor.post.isBlank) {\n          editor._insertEmptyMarkupSectionAtCursor();\n        }\n\n        var position = editor.range.head;\n        var targetFormat = this.modifierKeys.shift ? 'text' : 'html';\n        var pastedPost = (0, _mobiledocKitUtilsParseUtils.parsePostFromPaste)(event, editor, { targetFormat: targetFormat });\n\n        editor.run(function (postEditor) {\n          var nextPosition = postEditor.insertPost(position, pastedPost);\n          postEditor.setRange(nextPosition);\n        });\n      }\n    }, {\n      key: 'drop',\n      value: function drop(event) {\n        event.preventDefault();\n\n        var x = event.clientX;\n        var y = event.clientY;\n        var editor = this.editor;\n\n        var position = editor.positionAtPoint(x, y);\n        if (!position) {\n          this.logger.log('Could not find drop position');\n          return;\n        }\n\n        var post = (0, _mobiledocKitUtilsParseUtils.parsePostFromDrop)(event, editor, { logger: this.logger });\n        if (!post) {\n          this.logger.log('Could not determine post from drop event');\n          return;\n        }\n\n        editor.run(function (postEditor) {\n          var nextPosition = postEditor.insertPost(position, post);\n          postEditor.setRange(nextPosition);\n        });\n      }\n    }, {\n      key: '_updateModifiersFromKey',\n      value: function _updateModifiersFromKey(key, _ref5) {\n        var isDown = _ref5.isDown;\n\n        if (key.isShiftKey()) {\n          this.modifierKeys.shift = isDown;\n        }\n      }\n    }]);\n\n    return EventManager;\n  })();\n\n  exports['default'] = EventManager;\n});","define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/browser', 'mobiledoc-kit/editor/ui'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsBrowser, _mobiledocKitEditorUi) {\n  'use strict';\n\n  exports.buildKeyCommand = buildKeyCommand;\n  exports.validateKeyCommand = validateKeyCommand;\n  exports.findKeyCommands = findKeyCommands;\n\n  function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n  function selectAll(editor) {\n    var post = editor.post;\n\n    editor.selectRange(post.toRange());\n  }\n\n  function gotoStartOfLine(editor) {\n    var range = editor.range;\n    var section = range.tail.section;\n\n    editor.run(function (postEditor) {\n      postEditor.setRange(section.headPosition());\n    });\n  }\n\n  function gotoEndOfLine(editor) {\n    var range = editor.range;\n    var section = range.tail.section;\n\n    editor.run(function (postEditor) {\n      postEditor.setRange(section.tailPosition());\n    });\n  }\n\n  function deleteToEndOfSection(editor) {\n    var range = editor.range;\n\n    if (range.isCollapsed) {\n      var _range = range;\n      var head = _range.head;\n      var section = _range.head.section;\n\n      range = head.toRange(section.tailPosition());\n    }\n    editor.run(function (postEditor) {\n      var nextPosition = postEditor.deleteRange(range);\n      postEditor.setRange(nextPosition);\n    });\n  }\n\n  var DEFAULT_KEY_COMMANDS = [{\n    str: 'META+B',\n    run: function run(editor) {\n      editor.toggleMarkup('strong');\n    }\n  }, {\n    str: 'CTRL+B',\n    run: function run(editor) {\n      editor.toggleMarkup('strong');\n    }\n  }, {\n    str: 'META+I',\n    run: function run(editor) {\n      editor.toggleMarkup('em');\n    }\n  }, {\n    str: 'CTRL+I',\n    run: function run(editor) {\n      editor.toggleMarkup('em');\n    }\n  }, {\n    str: 'META+U',\n    run: function run(editor) {\n      editor.toggleMarkup('u');\n    }\n  }, {\n    str: 'CTRL+U',\n    run: function run(editor) {\n      editor.toggleMarkup('u');\n    }\n  }, {\n    str: 'CTRL+K',\n    run: function run(editor) {\n      if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n        return deleteToEndOfSection(editor);\n      } else if (_mobiledocKitUtilsBrowser['default'].isWin()) {\n        return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n      }\n    }\n  }, {\n    str: 'CTRL+A',\n    run: function run(editor) {\n      if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n        gotoStartOfLine(editor);\n      } else {\n        selectAll(editor);\n      }\n    }\n  }, {\n    str: 'META+A',\n    run: function run(editor) {\n      if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n        selectAll(editor);\n      }\n    }\n  }, {\n    str: 'CTRL+E',\n    run: function run(editor) {\n      if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n        gotoEndOfLine(editor);\n      }\n    }\n  }, {\n    str: 'META+K',\n    run: function run(editor) {\n      return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n    }\n\n  }, {\n    str: 'META+Z',\n    run: function run(editor) {\n      editor.run(function (postEditor) {\n        postEditor.undoLastChange();\n      });\n    }\n  }, {\n    str: 'META+SHIFT+Z',\n    run: function run(editor) {\n      editor.run(function (postEditor) {\n        postEditor.redoLastChange();\n      });\n    }\n  }, {\n    str: 'CTRL+Z',\n    run: function run(editor) {\n      if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n        return false;\n      }\n      editor.run(function (postEditor) {\n        return postEditor.undoLastChange();\n      });\n    }\n  }, {\n    str: 'CTRL+SHIFT+Z',\n    run: function run(editor) {\n      if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n        return false;\n      }\n      editor.run(function (postEditor) {\n        return postEditor.redoLastChange();\n      });\n    }\n  }];\n\n  exports.DEFAULT_KEY_COMMANDS = DEFAULT_KEY_COMMANDS;\n  function modifierNamesToMask(modiferNames) {\n    var defaultVal = 0;\n    return (0, _mobiledocKitUtilsArrayUtils.reduce)(modiferNames, function (sum, name) {\n      var modifier = _mobiledocKitUtilsKey.MODIFIERS[name.toUpperCase()];\n      (0, _mobiledocKitUtilsAssert['default'])('No modifier named \"' + name + '\" found', !!modifier);\n      return sum + modifier;\n    }, defaultVal);\n  }\n\n  function characterToCode(character) {\n    var upperCharacter = character.toUpperCase();\n    var special = (0, _mobiledocKitUtilsKey.specialCharacterToCode)(upperCharacter);\n    if (special) {\n      return special;\n    } else {\n      (0, _mobiledocKitUtilsAssert['default'])('Only 1 character can be used in a key command str (got \"' + character + '\")', character.length === 1);\n      return upperCharacter.charCodeAt(0);\n    }\n  }\n\n  function buildKeyCommand(keyCommand) {\n    var str = keyCommand.str;\n\n    if (!str) {\n      return keyCommand;\n    }\n    (0, _mobiledocKitUtilsAssert['default'])('[deprecation] Key commands no longer use the `modifier` property', !keyCommand.modifier);\n\n    var _str$split$reverse = str.split('+').reverse();\n\n    var _str$split$reverse2 = _toArray(_str$split$reverse);\n\n    var character = _str$split$reverse2[0];\n\n    var modifierNames = _str$split$reverse2.slice(1);\n\n    keyCommand.modifierMask = modifierNamesToMask(modifierNames);\n    keyCommand.code = characterToCode(character);\n\n    return keyCommand;\n  }\n\n  function validateKeyCommand(keyCommand) {\n    return !!keyCommand.code && !!keyCommand.run;\n  }\n\n  function findKeyCommands(keyCommands, keyEvent) {\n    var key = _mobiledocKitUtilsKey['default'].fromEvent(keyEvent);\n\n    return (0, _mobiledocKitUtilsArrayUtils.filter)(keyCommands, function (_ref) {\n      var modifierMask = _ref.modifierMask;\n      var code = _ref.code;\n\n      return key.keyCode === code && key.modifierMask === modifierMask;\n    });\n  }\n});","define('mobiledoc-kit/editor/mutation-handler', ['exports', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsSet, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var MUTATION = {\n    NODES_CHANGED: 'childList',\n    CHARACTER_DATA: 'characterData'\n  };\n\n  var MutationHandler = (function () {\n    function MutationHandler(editor) {\n      var _this = this;\n\n      _classCallCheck(this, MutationHandler);\n\n      this.editor = editor;\n      this.logger = editor.loggerFor('mutation-handler');\n      this.renderTree = null;\n      this._isObserving = false;\n\n      this._observer = new MutationObserver(function (mutations) {\n        _this._handleMutations(mutations);\n      });\n    }\n\n    _createClass(MutationHandler, [{\n      key: 'init',\n      value: function init() {\n        this.startObserving();\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this.stopObserving();\n        this._observer = null;\n      }\n    }, {\n      key: 'suspendObservation',\n      value: function suspendObservation(callback) {\n        this.stopObserving();\n        callback();\n        this.startObserving();\n      }\n    }, {\n      key: 'stopObserving',\n      value: function stopObserving() {\n        if (this._isObserving) {\n          this._isObserving = false;\n          this._observer.disconnect();\n        }\n      }\n    }, {\n      key: 'startObserving',\n      value: function startObserving() {\n        if (!this._isObserving) {\n          var editor = this.editor;\n\n          (0, _mobiledocKitUtilsAssert['default'])('Cannot observe un-rendered editor', editor.hasRendered);\n\n          this._isObserving = true;\n          this.renderTree = editor._renderTree;\n\n          this._observer.observe(editor.element, {\n            characterData: true,\n            childList: true,\n            subtree: true\n          });\n        }\n      }\n    }, {\n      key: 'reparsePost',\n      value: function reparsePost() {\n        this.editor._reparsePost();\n      }\n    }, {\n      key: 'reparseSections',\n      value: function reparseSections(sections) {\n        this.editor._reparseSections(sections);\n      }\n\n      /**\n       * for each mutation:\n       *   * find the target nodes:\n       *     * if nodes changed, target nodes are:\n       *        * added nodes\n       *        * the target from which removed nodes were removed\n       *     * if character data changed\n       *       * target node is the mutation event's target (text node)\n       *     * filter out nodes that are no longer attached (parentNode is null)\n       *   * for each remaining node:\n       *   *  find its section, add to sections-to-reparse\n       *   *  if no section, reparse all (and break)\n       */\n    }, {\n      key: '_handleMutations',\n      value: function _handleMutations(mutations) {\n        var reparsePost = false;\n        var sections = new _mobiledocKitUtilsSet['default']();\n\n        for (var i = 0; i < mutations.length; i++) {\n          if (reparsePost) {\n            break;\n          }\n\n          var nodes = this._findTargetNodes(mutations[i]);\n\n          for (var j = 0; j < nodes.length; j++) {\n            var node = nodes[j];\n            var renderNode = this._findRenderNodeFromNode(node);\n            if (renderNode) {\n              if (renderNode.reparsesMutationOfChildNode(node)) {\n                var section = this._findSectionFromRenderNode(renderNode);\n                if (section) {\n                  sections.add(section);\n                } else {\n                  reparsePost = true;\n                }\n              }\n            } else {\n              reparsePost = true;\n              break;\n            }\n          }\n        }\n\n        if (reparsePost) {\n          this.logger.log('reparsePost (' + mutations.length + ' mutations)');\n          this.reparsePost();\n        } else if (sections.length) {\n          this.logger.log('reparse ' + sections.length + ' sections (' + mutations.length + ' mutations)');\n          this.reparseSections(sections.toArray());\n        }\n      }\n    }, {\n      key: '_findTargetNodes',\n      value: function _findTargetNodes(mutation) {\n        var nodes = [];\n\n        switch (mutation.type) {\n          case MUTATION.CHARACTER_DATA:\n            nodes.push(mutation.target);\n            break;\n          case MUTATION.NODES_CHANGED:\n            (0, _mobiledocKitUtilsArrayUtils.forEach)(mutation.addedNodes, function (n) {\n              return nodes.push(n);\n            });\n            if (mutation.removedNodes.length) {\n              nodes.push(mutation.target);\n            }\n            break;\n        }\n\n        var element = this.editor.element;\n        var attachedNodes = (0, _mobiledocKitUtilsArrayUtils.filter)(nodes, function (node) {\n          return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, node);\n        });\n        return attachedNodes;\n      }\n    }, {\n      key: '_findSectionRenderNodeFromNode',\n      value: function _findSectionRenderNodeFromNode(node) {\n        return this.renderTree.findRenderNodeFromElement(node, function (rn) {\n          return rn.postNode.isSection;\n        });\n      }\n    }, {\n      key: '_findRenderNodeFromNode',\n      value: function _findRenderNodeFromNode(node) {\n        return this.renderTree.findRenderNodeFromElement(node);\n      }\n    }, {\n      key: '_findSectionFromRenderNode',\n      value: function _findSectionFromRenderNode(renderNode) {\n        var sectionRenderNode = this._findSectionRenderNodeFromNode(renderNode.element);\n        return sectionRenderNode && sectionRenderNode.postNode;\n      }\n    }]);\n\n    return MutationHandler;\n  })();\n\n  exports['default'] = MutationHandler;\n});","define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/editor/post/post-inserter', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/to-range'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils, _mobiledocKitEditorPostPostInserter, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsToRange) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n  var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n  function isListSectionTagName(tagName) {\n    return tagName === 'ul' || tagName === 'ol';\n  }\n\n  function shrinkRange(range) {\n    var head = range.head;\n    var tail = range.tail;\n\n    if (tail.offset === 0 && head.section !== tail.section) {\n      range.tail = new _mobiledocKitUtilsCursorPosition['default'](tail.section.prev, tail.section.prev.length);\n    }\n\n    return range;\n  }\n\n  var CALLBACK_QUEUES = {\n    BEFORE_COMPLETE: 'beforeComplete',\n    COMPLETE: 'complete',\n    AFTER_COMPLETE: 'afterComplete'\n  };\n\n  // There are only two events that we're concerned about for Undo, that is inserting text and deleting content.\n  // These are the only two states that go on a \"run\" and create a combined undo, everything else has it's own\n  // deadicated undo.\n  var EDIT_ACTIONS = {\n    INSERT_TEXT: 1,\n    DELETE: 2\n  };\n\n  /**\n   * The PostEditor is used to modify a post. It should not be instantiated directly.\n   * Instead, a new instance of a PostEditor is created by the editor and passed\n   * as the argument to the callback in {@link Editor#run}.\n   *\n   * Usage:\n   * ```\n   * editor.run((postEditor) => {\n   *   // postEditor is an instance of PostEditor that can operate on the\n   *   // editor's post\n   * });\n   * ```\n   */\n\n  var PostEditor = (function () {\n    /**\n     * @private\n     */\n\n    function PostEditor(editor) {\n      var _this = this;\n\n      _classCallCheck(this, PostEditor);\n\n      this.editor = editor;\n      this.builder = this.editor.builder;\n      this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n      this._didComplete = false;\n      this.editActionTaken = null;\n\n      this._renderRange = function () {\n        return _this.editor.selectRange(_this._range);\n      };\n      this._postDidChange = function () {\n        return _this.editor._postDidChange();\n      };\n      this._rerender = function () {\n        return _this.editor.rerender();\n      };\n    }\n\n    _createClass(PostEditor, [{\n      key: 'addCallback',\n      value: function addCallback() {\n        var _callbacks;\n\n        (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n      }\n    }, {\n      key: 'addCallbackOnce',\n      value: function addCallbackOnce() {\n        var _callbacks2;\n\n        (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n      }\n    }, {\n      key: 'runCallbacks',\n      value: function runCallbacks() {\n        var _callbacks3;\n\n        (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n      }\n    }, {\n      key: 'begin',\n      value: function begin() {\n        // cache the editor's range\n        this._range = this.editor.range;\n      }\n\n      /**\n       * Schedules to select the given range on the editor after the postEditor\n       * has completed its work. This also updates the postEditor's active range\n       * (so that multiple calls to range-changing methods on the postEditor will\n       * update the correct range).\n       *\n       * Usage:\n       *   let range = editor.range;\n       *   editor.run(postEditor => {\n       *     let nextPosition = postEditor.deleteRange(range);\n       *\n       *     // Will position the editor's cursor at `nextPosition` after\n       *     // the postEditor finishes work and the editor rerenders.\n       *     postEditor.setRange(nextPosition);\n       *   });\n       * @param {Range|Position} range\n       * @public\n       */\n    }, {\n      key: 'setRange',\n      value: function setRange(range) {\n        range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n        // TODO validate that the range is valid\n        // (does not contain marked-for-removal head or tail sections?)\n        this._range = range;\n        this.scheduleAfterRender(this._renderRange, true);\n      }\n\n      /**\n       * Delete a range from the post\n       *\n       * Usage:\n       * ```\n       *     let { range } = editor;\n       *     editor.run((postEditor) => {\n       *       let nextPosition = postEditor.deleteRange(range);\n       *       postEditor.setRange(nextPosition);\n       *     });\n       * ```\n       * @param {Range} range Cursor Range object with head and tail Positions\n       * @return {Position} The position where the cursor would go after deletion\n       * @public\n       */\n    }, {\n      key: 'deleteRange',\n      value: function deleteRange(range) {\n        (0, _mobiledocKitUtilsAssert['default'])(\"Must pass MobiledocKit Range to `deleteRange`\", range instanceof _mobiledocKitUtilsCursorRange['default']);\n\n        this.editActionTaken = EDIT_ACTIONS.DELETE;\n\n        var head = range.head;\n        var headSection = range.head.section;\n        var tail = range.tail;\n        var tailSection = range.tail.section;\n        var post = this.editor.post;\n\n        if (headSection === tailSection) {\n          return this.cutSection(headSection, head, tail);\n        }\n\n        var nextSection = headSection.nextLeafSection();\n\n        var nextPos = this.cutSection(headSection, head, headSection.tailPosition());\n        // cutSection can replace the section, so re-read headSection here\n        headSection = nextPos.section;\n\n        // Remove sections in the middle of the range\n        while (nextSection !== tailSection) {\n          var tmp = nextSection;\n          nextSection = nextSection.nextLeafSection();\n          this.removeSection(tmp);\n        }\n\n        var tailPos = this.cutSection(tailSection, tailSection.headPosition(), tail);\n        // cutSection can replace the section, so re-read tailSection here\n        tailSection = tailPos.section;\n\n        if (tailSection.isBlank) {\n          this.removeSection(tailSection);\n        } else {\n          // If head and tail sections are markerable, join them\n          // Note: They may not be the same section type. E.g. this may join\n          // a tail section that was a list item onto a markup section, or vice versa.\n          // (This is the desired behavior.)\n          if (headSection.isMarkerable && tailSection.isMarkerable) {\n            headSection.join(tailSection);\n            this._markDirty(headSection);\n            this.removeSection(tailSection);\n          } else if (headSection.isBlank) {\n            this.removeSection(headSection);\n            nextPos = tailPos;\n          }\n        }\n\n        if (post.isBlank) {\n          post.sections.append(this.builder.createMarkupSection('p'));\n          nextPos = post.headPosition();\n        }\n\n        return nextPos;\n      }\n\n      /**\n       * Note: This method may replace `section` with a different section.\n       *\n       * \"Cut\" out the part of the section inside `headOffset` and `tailOffset`.\n       * If section is markerable this splits markers that straddle the head or tail (if necessary),\n       * and removes markers that are wholly inside the offsets.\n       * If section is a card, this may replace it with a blank markup section if the\n       * positions contain the entire card.\n       *\n       * @param {Section} section\n       * @param {Position} head\n       * @param {Position} tail\n       * @return {Position}\n       * @private\n       */\n    }, {\n      key: 'cutSection',\n      value: function cutSection(section, head, tail) {\n        var _this2 = this;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass head position and tail position to `cutSection`', head instanceof _mobiledocKitUtilsCursorPosition['default'] && tail instanceof _mobiledocKitUtilsCursorPosition['default']);\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass positions within same section to `cutSection`', head.section === tail.section);\n\n        if (section.isBlank || head.isEqual(tail)) {\n          return head;\n        }\n        if (section.isCardSection) {\n          if (head.isHead() && tail.isTail()) {\n            var newSection = this.builder.createMarkupSection();\n            this.replaceSection(section, newSection);\n            return newSection.headPosition();\n          } else {\n            return tail;\n          }\n        }\n\n        var range = head.toRange(tail);\n        this.splitMarkers(range).forEach(function (m) {\n          return _this2.removeMarker(m);\n        });\n\n        return head;\n      }\n    }, {\n      key: '_coalesceMarkers',\n      value: function _coalesceMarkers(section) {\n        if (section.isMarkerable) {\n          this._removeBlankMarkers(section);\n          this._joinSimilarMarkers(section);\n        }\n      }\n    }, {\n      key: '_removeBlankMarkers',\n      value: function _removeBlankMarkers(section) {\n        var _this3 = this;\n\n        (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n          return m.isBlank;\n        }), function (m) {\n          return _this3.removeMarker(m);\n        });\n      }\n\n      // joins markers that have identical markups\n    }, {\n      key: '_joinSimilarMarkers',\n      value: function _joinSimilarMarkers(section) {\n        var marker = section.markers.head;\n        var nextMarker = undefined;\n        while (marker && marker.next) {\n          nextMarker = marker.next;\n\n          if (marker.canJoin(nextMarker)) {\n            nextMarker.value = marker.value + nextMarker.value;\n            this._markDirty(nextMarker);\n            this.removeMarker(marker);\n          }\n\n          marker = nextMarker;\n        }\n      }\n    }, {\n      key: 'removeMarker',\n      value: function removeMarker(marker) {\n        this._scheduleForRemoval(marker);\n        if (marker.section) {\n          this._markDirty(marker.section);\n          marker.section.markers.remove(marker);\n        }\n      }\n    }, {\n      key: '_scheduleForRemoval',\n      value: function _scheduleForRemoval(postNode) {\n        var _this4 = this;\n\n        if (postNode.renderNode) {\n          postNode.renderNode.scheduleForRemoval();\n\n          this.scheduleRerender();\n          this.scheduleDidUpdate();\n        }\n        var removedAdjacentToList = postNode.prev && postNode.prev.isListSection || postNode.next && postNode.next.isListSection;\n        if (removedAdjacentToList) {\n          this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n            return _this4._joinContiguousListSections();\n          });\n        }\n      }\n    }, {\n      key: '_joinContiguousListSections',\n      value: function _joinContiguousListSections() {\n        var _this5 = this;\n\n        var post = this.editor.post;\n\n        var range = this._range;\n        var prev = undefined;\n        var groups = [];\n        var currentGroup = undefined;\n\n        // FIXME do we need to force a re-render of the range if changed sections\n        // are contained within the range?\n        var updatedHead = null;\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n          if (prev && prev.isListSection && section.isListSection && prev.tagName === section.tagName) {\n\n            currentGroup = currentGroup || [prev];\n            currentGroup.push(section);\n          } else {\n            if (currentGroup) {\n              groups.push(currentGroup);\n            }\n            currentGroup = null;\n          }\n          prev = section;\n        });\n\n        if (currentGroup) {\n          groups.push(currentGroup);\n        }\n\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(groups, function (group) {\n          var list = group[0];\n          (0, _mobiledocKitUtilsArrayUtils.forEach)(group, function (listSection) {\n            if (listSection === list) {\n              return;\n            }\n\n            var currentHead = range.head;\n            var prevPosition = undefined;\n\n            // FIXME is there a currentHead if there is no range?\n            // is the current head a list item in the section\n            if (!range.isBlank && currentHead.section.isListItem && currentHead.section.parent === listSection) {\n              prevPosition = list.tailPosition();\n            }\n            _this5._joinListSections(list, listSection);\n            if (prevPosition) {\n              updatedHead = prevPosition.move(FORWARD);\n            }\n          });\n        });\n\n        if (updatedHead) {\n          this.setRange(updatedHead);\n        }\n      }\n    }, {\n      key: '_joinListSections',\n      value: function _joinListSections(baseList, nextList) {\n        baseList.join(nextList);\n        this._markDirty(baseList);\n        this.removeSection(nextList);\n      }\n    }, {\n      key: '_markDirty',\n      value: function _markDirty(postNode) {\n        var _this6 = this;\n\n        if (postNode.renderNode) {\n          postNode.renderNode.markDirty();\n\n          this.scheduleRerender();\n          this.scheduleDidUpdate();\n        }\n        if (postNode.section) {\n          this._markDirty(postNode.section);\n        }\n        if (postNode.isMarkerable) {\n          this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n            return _this6._coalesceMarkers(postNode);\n          });\n        }\n      }\n\n      /**\n       * @param {Position} position object with {section, offset} the marker and offset to delete from\n       * @param {Number} direction The direction to delete in (default is BACKWARD)\n       * @return {Position} for positioning the cursor\n       * @public\n       * @deprecated after v0.10.3\n       */\n    }, {\n      key: 'deleteFrom',\n      value: function deleteFrom(position) {\n        var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n        (0, _mobiledocKitUtilsDeprecate['default'])(\"`postEditor#deleteFrom is deprecated. Use `deleteAtPosition(position, direction=BACKWARD, {unit}={unit: 'char'})` instead\");\n        return this.deleteAtPosition(position, direction, { unit: 'char' });\n      }\n\n      /**\n       * Delete 1 `unit` (can be 'char' or 'word') in the given `direction` at the given\n       * `position`. In almost all cases this will be equivalent to deleting the range formed\n       * by expanding the position 1 unit in the given direction. The exception is when deleting\n       * backward from the beginning of a list item, which reverts the list item into a markup section\n       * instead of joining it with its previous list item (if any).\n       *\n       * Usage:\n       *\n       *     let position = section.tailPosition();\n       *     // Section has text of \"Howdy!\"\n       *     editor.run((postEditor) => {\n       *       postEditor.deleteAtPosition(position);\n       *     });\n       *     // section has text of \"Howdy\"\n       *\n       * @param {Position} position The position to delete at\n       * @param {Direction} [direction=DIRECTION.BACKWARD] direction The direction to delete in\n       * @param {Object} [options]\n       * @param {String} [options.unit=\"char\"] The unit of deletion (\"word\" or \"char\")\n       * @return {Position}\n       */\n    }, {\n      key: 'deleteAtPosition',\n      value: function deleteAtPosition(position) {\n        var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n        var _ref = arguments.length <= 2 || arguments[2] === undefined ? { unit: 'char' } : arguments[2];\n\n        var unit = _ref.unit;\n\n        if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n          return this._deleteAtPositionBackward(position, unit);\n        } else {\n          return this._deleteAtPositionForward(position, unit);\n        }\n      }\n    }, {\n      key: '_deleteAtPositionBackward',\n      value: function _deleteAtPositionBackward(position, unit) {\n        if (position.isHead() && position.section.isListItem) {\n          this.toggleSection('p', position);\n          return this._range.head;\n        } else {\n          var prevPosition = unit === 'word' ? position.moveWord(BACKWARD) : position.move(BACKWARD);\n          var range = prevPosition.toRange(position);\n          return this.deleteRange(range);\n        }\n      }\n    }, {\n      key: '_deleteAtPositionForward',\n      value: function _deleteAtPositionForward(position, unit) {\n        var nextPosition = unit === 'word' ? position.moveWord(FORWARD) : position.move(FORWARD);\n        var range = position.toRange(nextPosition);\n        return this.deleteRange(range);\n      }\n\n      /**\n       * Split markers at two positions, once at the head, and if necessary once\n       * at the tail.\n       *\n       * Usage:\n       * ```\n       *     let range = editor.range;\n       *     editor.run((postEditor) => {\n       *       postEditor.splitMarkers(range);\n       *     });\n       * ```\n       * The return value will be marker object completely inside the offsets\n       * provided. Markers outside of the split may also have been modified.\n       *\n       * @param {Range} markerRange\n       * @return {Array} of markers that are inside the split\n       * @private\n       */\n    }, {\n      key: 'splitMarkers',\n      value: function splitMarkers(range) {\n        var post = this.editor.post;\n        var head = range.head;\n        var tail = range.tail;\n\n        this.splitSectionMarkerAtOffset(head.section, head.offset);\n        this.splitSectionMarkerAtOffset(tail.section, tail.offset);\n\n        return post.markersContainedByRange(range);\n      }\n    }, {\n      key: 'splitSectionMarkerAtOffset',\n      value: function splitSectionMarkerAtOffset(section, offset) {\n        var _this7 = this;\n\n        var edit = section.splitMarkerAtOffset(offset);\n        edit.removed.forEach(function (m) {\n          return _this7.removeMarker(m);\n        });\n      }\n\n      /**\n       * Split the section at the position.\n       *\n       * Usage:\n       * ```\n       *     let position = editor.cursor.offsets.head;\n       *     editor.run((postEditor) => {\n       *       postEditor.splitSection(position);\n       *     });\n       *     // Will result in the creation of two new sections\n       *     // replacing the old one at the cursor position\n       * ```\n       * The return value will be the two new sections. One or both of these\n       * sections can be blank (contain only a blank marker), for example if the\n       * headMarkerOffset is 0.\n       *\n       * @param {Position} position\n       * @return {Array} new sections, one for the first half and one for the second (either one can be null)\n       * @public\n       */\n    }, {\n      key: 'splitSection',\n      value: function splitSection(position) {\n        var _this8 = this;\n\n        var section = position.section;\n\n        if (section.isCardSection) {\n          return this._splitCardSection(section, position);\n        } else if (section.isListItem) {\n          var isLastAndBlank = section.isBlank && !section.next;\n          if (isLastAndBlank) {\n            // if is last, replace the item with a blank markup section\n            var _parent = section.parent;\n            var collection = this.editor.post.sections;\n            var blank = this.builder.createMarkupSection();\n            this.removeSection(section);\n            this.insertSectionBefore(collection, blank, _parent.next);\n\n            return [null, blank];\n          } else {\n            var _splitListItem2 = this._splitListItem(section, position);\n\n            var _splitListItem22 = _slicedToArray(_splitListItem2, 2);\n\n            var pre = _splitListItem22[0];\n            var post = _splitListItem22[1];\n\n            return [pre, post];\n          }\n        } else {\n          var splitSections = section.splitAtPosition(position);\n          splitSections.forEach(function (s) {\n            return _this8._coalesceMarkers(s);\n          });\n          this._replaceSection(section, splitSections);\n\n          return splitSections;\n        }\n      }\n\n      /**\n       * @param {Section} cardSection\n       * @param {Position} position to split at\n       * @return {Section[]} 2-item array of pre and post-split sections\n       * @private\n       */\n    }, {\n      key: '_splitCardSection',\n      value: function _splitCardSection(cardSection, position) {\n        var offset = position.offset;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cards section must be split at offset 0 or 1', offset === 0 || offset === 1);\n\n        var newSection = this.builder.createMarkupSection();\n        var nextSection = undefined;\n        var surroundingSections = undefined;\n\n        if (offset === 0) {\n          nextSection = cardSection;\n          surroundingSections = [newSection, cardSection];\n        } else {\n          nextSection = cardSection.next;\n          surroundingSections = [cardSection, newSection];\n        }\n\n        var collection = this.editor.post.sections;\n        this.insertSectionBefore(collection, newSection, nextSection);\n\n        return surroundingSections;\n      }\n\n      /**\n       * @param {Section} section\n       * @param {Section} newSection\n       * @return null\n       * @public\n       */\n    }, {\n      key: 'replaceSection',\n      value: function replaceSection(section, newSection) {\n        if (!section) {\n          // FIXME should a falsy section be a valid argument?\n          this.insertSectionBefore(this.editor.post.sections, newSection, null);\n        } else {\n          this._replaceSection(section, [newSection]);\n        }\n      }\n    }, {\n      key: 'moveSectionBefore',\n      value: function moveSectionBefore(collection, renderedSection, beforeSection) {\n        var newSection = renderedSection.clone();\n        this.removeSection(renderedSection);\n        this.insertSectionBefore(collection, newSection, beforeSection);\n        return newSection;\n      }\n\n      /**\n       * @param {Section} section A section that is already in DOM\n       * @public\n       */\n    }, {\n      key: 'moveSectionUp',\n      value: function moveSectionUp(renderedSection) {\n        var isFirst = !renderedSection.prev;\n        if (isFirst) {\n          return renderedSection;\n        }\n\n        var collection = renderedSection.parent.sections;\n        var beforeSection = renderedSection.prev;\n        return this.moveSectionBefore(collection, renderedSection, beforeSection);\n      }\n\n      /**\n       * @param {Section} section A section that is already in DOM\n       * @public\n       */\n    }, {\n      key: 'moveSectionDown',\n      value: function moveSectionDown(renderedSection) {\n        var isLast = !renderedSection.next;\n        if (isLast) {\n          return renderedSection;\n        }\n\n        var beforeSection = renderedSection.next.next;\n        var collection = renderedSection.parent.sections;\n        return this.moveSectionBefore(collection, renderedSection, beforeSection);\n      }\n\n      /**\n       * Insert an array of markers at the given position. If the position is in\n       * a non-markerable section (like a card section), this method throws an error.\n       *\n       * @param {Position} position\n       * @param {Marker[]} markers\n       * @return {Position} The position that represents the end of the inserted markers.\n       * @public\n       */\n    }, {\n      key: 'insertMarkers',\n      value: function insertMarkers(position, markers) {\n        var _this9 = this;\n\n        var section = position.section;\n        var offset = position.offset;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot insert markers at non-markerable position', section.isMarkerable);\n\n        this.editActionTaken = EDIT_ACTIONS.INSERT_TEXT;\n\n        var edit = section.splitMarkerAtOffset(offset);\n        edit.removed.forEach(function (marker) {\n          return _this9._scheduleForRemoval(marker);\n        });\n\n        var prevMarker = section.markerBeforeOffset(offset);\n        markers.forEach(function (marker) {\n          section.markers.insertAfter(marker, prevMarker);\n          offset += marker.length;\n          prevMarker = marker;\n        });\n\n        this._coalesceMarkers(section);\n        this._markDirty(section);\n\n        var nextPosition = section.toPosition(offset);\n        this.setRange(nextPosition);\n        return nextPosition;\n      }\n\n      /**\n       * Inserts text with the given markups, ignoring the existing markups at\n       * the position, if any.\n       *\n       * @param {Position} position\n       * @param {String} text\n       * @param {Markup[]} markups\n       * @return {Position} position at the end of the inserted text\n       */\n    }, {\n      key: 'insertTextWithMarkup',\n      value: function insertTextWithMarkup(position, text) {\n        var markups = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n        var section = position.section;\n\n        if (!section.isMarkerable) {\n          return;\n        }\n        var marker = this.builder.createMarker(text, markups);\n        return this.insertMarkers(position, [marker]);\n      }\n\n      /**\n       * Insert the text at the given position\n       * Inherits the markups already at that position, if any.\n       *\n       * @param {Position} position\n       * @param {String} text\n       * @return {Position} position at the end of the inserted text.\n       */\n    }, {\n      key: 'insertText',\n      value: function insertText(position, text) {\n        var section = position.section;\n\n        if (!section.isMarkerable) {\n          return;\n        }\n        var markups = position.marker && position.marker.markups;\n        markups = markups || [];\n        return this.insertTextWithMarkup(position, text, markups);\n      }\n    }, {\n      key: '_replaceSection',\n      value: function _replaceSection(section, newSections) {\n        var _this10 = this;\n\n        var nextSection = section.next;\n        var collection = section.parent.sections;\n\n        var nextNewSection = newSections[0];\n        if (nextNewSection.isMarkupSection && section.isListItem) {\n          // put the new section after the ListSection (section.parent)\n          // instead of after the ListItem\n          collection = section.parent.parent.sections;\n          nextSection = section.parent.next;\n        }\n\n        newSections.forEach(function (s) {\n          return _this10.insertSectionBefore(collection, s, nextSection);\n        });\n        this.removeSection(section);\n      }\n\n      /**\n       * Given a markerRange (for example `editor.range`) mark all markers\n       * inside it as a given markup. The markup must be provided as a post\n       * abstract node.\n       *\n       * Usage:\n       *\n       *     let range = editor.range;\n       *     let strongMarkup = editor.builder.createMarkup('strong');\n       *     editor.run((postEditor) => {\n       *       postEditor.addMarkupToRange(range, strongMarkup);\n       *     });\n       *     // Will result some markers possibly being split, and the markup\n       *     // being applied to all markers between the split.\n       *\n       * @param {Range} range\n       * @param {Markup} markup A markup post abstract node\n       * @public\n       */\n    }, {\n      key: 'addMarkupToRange',\n      value: function addMarkupToRange(range, markup) {\n        var _this11 = this;\n\n        if (range.isCollapsed) {\n          return;\n        }\n\n        var markers = this.splitMarkers(range);\n        if (markers.length) {\n          (function () {\n            // We insert the new markup at a consistent index across the range.\n            // If we just push on the end of the list, it can end up in different positions\n            // of the markup stack. This results in unnecessary closing and re-opening of\n            // the markup each time it changes position.\n            // If we just push it at the beginning of the list, this causes unnecessary closing\n            // and re-opening of surrounding tags.\n            // So, we look for any tags open across the whole range, and push into the stack\n            // at the end of those.\n            // Prompted by https://github.com/bustle/mobiledoc-kit/issues/360\n\n            var markupsOpenAcrossRange = (0, _mobiledocKitUtilsArrayUtils.reduce)(markers, function (soFar, marker) {\n              return (0, _mobiledocKitUtilsArrayUtils.commonItems)(soFar, marker.markups);\n            }, markers[0].markups);\n            var indexToInsert = markupsOpenAcrossRange.length;\n\n            markers.forEach(function (marker) {\n              marker.addMarkupAtIndex(markup, indexToInsert);\n              _this11._markDirty(marker);\n            });\n          })();\n        }\n      }\n\n      /**\n       * Given a markerRange (for example `editor.range`) remove the given\n       * markup from all contained markers.\n       *\n       * Usage:\n       * ```\n       *     let { range } = editor;\n       *     let markup = markerRange.headMarker.markups[0];\n       *     editor.run(postEditor => {\n       *       postEditor.removeMarkupFromRange(range, markup);\n       *     });\n       *     // Will result in some markers possibly being split, and the markup\n       *     // being removed from all markers between the split.\n       * ```\n       * @param {Range} range Object with offsets\n       * @param {Markup|Function} markupOrCallback A markup post abstract node or\n       * a function that returns true when passed a markup that should be removed\n       * @private\n       */\n    }, {\n      key: 'removeMarkupFromRange',\n      value: function removeMarkupFromRange(range, markupOrMarkupCallback) {\n        var _this12 = this;\n\n        if (range.isCollapsed) {\n          return;\n        }\n\n        this.splitMarkers(range).forEach(function (marker) {\n          marker.removeMarkup(markupOrMarkupCallback);\n          _this12._markDirty(marker);\n        });\n      }\n\n      /**\n       * Toggle the given markup in the given range (or at the position given). If the range/position\n       * has the markup, the markup will be removed. If nothing in the range/position\n       * has the markup, the markup will be added to everything in the range/position.\n       *\n       * Usage:\n       * ```\n       * // Remove any 'strong' markup if it exists in the selection, otherwise\n       * // make it all 'strong'\n       * editor.run(postEditor => postEditor.toggleMarkup('strong'));\n       *\n       * // add/remove a link to 'bustle.com' to the selection\n       * editor.run(postEditor => {\n       *   const linkMarkup = postEditor.builder.createMarkup('a', {href: 'http://bustle.com'});\n       *   postEditor.toggleMarkup(linkMarkup);\n       * });\n       * ```\n       * @param {Markup|String} markupOrString Either a markup object created using\n       * the builder (useful when adding a markup with attributes, like an 'a' markup),\n       * or, if a string, the tag name of the markup (e.g. 'strong', 'em') to toggle.\n       * @param {Range|Position} range in which to toggle. Defaults to current editor range.\n       * @public\n       */\n    }, {\n      key: 'toggleMarkup',\n      value: function toggleMarkup(markupOrMarkupString) {\n        var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n        range = (0, _mobiledocKitUtilsToRange['default'])(range);\n        var markup = typeof markupOrMarkupString === 'string' ? this.builder.createMarkup(markupOrMarkupString) : markupOrMarkupString;\n\n        var hasMarkup = this.editor.detectMarkupInRange(range, markup.tagName);\n        // FIXME: This implies only a single markup in a range. This may not be\n        // true for links (which are not the same object instance like multiple\n        // strong tags would be).\n        if (hasMarkup) {\n          this.removeMarkupFromRange(range, hasMarkup);\n        } else {\n          this.addMarkupToRange(range, markup);\n        }\n\n        this.setRange(range);\n      }\n\n      /**\n       * Toggles the tagName of the active section or sections in the given range/position.\n       * If every section has the tag name, they will all be reset to default sections.\n       * Otherwise, every section will be changed to the requested type\n       *\n       * @param {String} sectionTagName A valid markup section or\n       *        list section tag name (e.g. 'blockquote', 'h2', 'ul')\n       * @param {Range|Position} range The range over which to toggle.\n       *        Defaults to the current editor range.\n       * @public\n       */\n    }, {\n      key: 'toggleSection',\n      value: function toggleSection(sectionTagName) {\n        var _this13 = this;\n\n        var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n        range = shrinkRange((0, _mobiledocKitUtilsToRange['default'])(range));\n\n        sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName);\n        var post = this.editor.post;\n\n        var everySectionHasTagName = true;\n        post.walkMarkerableSections(range, function (section) {\n          if (!_this13._isSameSectionType(section, sectionTagName)) {\n            everySectionHasTagName = false;\n          }\n        });\n\n        var tagName = everySectionHasTagName ? 'p' : sectionTagName;\n        var sectionTransformations = [];\n        post.walkMarkerableSections(range, function (section) {\n          var changedSection = _this13.changeSectionTagName(section, tagName);\n\n          sectionTransformations.push({\n            from: section,\n            to: changedSection\n          });\n        });\n\n        var nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations);\n        this.setRange(nextRange);\n      }\n    }, {\n      key: '_determineNextRangeAfterToggleSection',\n      value: function _determineNextRangeAfterToggleSection(range, sectionTransformations) {\n        if (sectionTransformations.length) {\n          var changedHeadSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref2) {\n            var from = _ref2.from;\n\n            return from === range.headSection;\n          }).to;\n          var changedTailSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref3) {\n            var from = _ref3.from;\n\n            return from === range.tailSection;\n          }).to;\n\n          if (changedHeadSection.isListSection || changedTailSection.isListSection) {\n            // We don't know to which ListItem's the original sections point at, so\n            // we don't have enough information to reconstruct the range when\n            // dealing with lists.\n            return sectionTransformations[0].to.headPosition().toRange();\n          } else {\n            return _mobiledocKitUtilsCursorRange['default'].create(changedHeadSection, range.headSectionOffset, changedTailSection, range.tailSectionOffset, range.direction);\n          }\n        } else {\n          return range;\n        }\n      }\n    }, {\n      key: 'setAttribute',\n      value: function setAttribute(key, value) {\n        var range = arguments.length <= 2 || arguments[2] === undefined ? this._range : arguments[2];\n\n        this._mutateAttribute(key, range, function (section, attribute) {\n          if (section.getAttribute(attribute) !== value) {\n            section.setAttribute(attribute, value);\n            return true;\n          }\n        });\n      }\n    }, {\n      key: 'removeAttribute',\n      value: function removeAttribute(key) {\n        var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n        this._mutateAttribute(key, range, function (section, attribute) {\n          if (section.hasAttribute(attribute)) {\n            section.removeAttribute(attribute);\n            return true;\n          }\n        });\n      }\n    }, {\n      key: '_mutateAttribute',\n      value: function _mutateAttribute(key, range, cb) {\n        var _this14 = this;\n\n        range = (0, _mobiledocKitUtilsToRange['default'])(range);\n        var post = this.editor.post;\n\n        var attribute = 'data-md-' + key;\n\n        post.walkMarkerableSections(range, function (section) {\n          if (section.isListItem) {\n            section = section.parent;\n          }\n\n          if (cb(section, attribute) === true) {\n            _this14._markDirty(section);\n          }\n        });\n\n        this.setRange(range);\n      }\n    }, {\n      key: '_isSameSectionType',\n      value: function _isSameSectionType(section, sectionTagName) {\n        return section.isListItem ? section.parent.tagName === sectionTagName : section.tagName === sectionTagName;\n      }\n\n      /**\n       * @param {Markerable} section\n       * @private\n       */\n    }, {\n      key: 'changeSectionTagName',\n      value: function changeSectionTagName(section, newTagName) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot pass non-markerable section to `changeSectionTagName`', section.isMarkerable);\n\n        if (isListSectionTagName(newTagName)) {\n          return this._changeSectionToListItem(section, newTagName);\n        } else if (section.isListItem) {\n          return this._changeSectionFromListItem(section, newTagName);\n        } else {\n          section.tagName = newTagName;\n          this._markDirty(section);\n          return section;\n        }\n      }\n\n      /**\n       * Splits the item at the position given.\n       * If the position is at the start or end of the item, the pre- or post-item\n       * will contain a single empty (\"\") marker.\n       * @param {ListItem} item\n       * @param {Position} position\n       * @return {Array} the pre-item and post-item on either side of the split\n       * @private\n       */\n    }, {\n      key: '_splitListItem',\n      value: function _splitListItem(item, position) {\n        var section = position.section;\n        var offset = position.offset;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot split list item at position that does not include item', item === section);\n\n        item.splitMarkerAtOffset(offset);\n        var prevMarker = item.markerBeforeOffset(offset);\n        var preItem = this.builder.createListItem(),\n            postItem = this.builder.createListItem();\n\n        var currentItem = preItem;\n        item.markers.forEach(function (marker) {\n          currentItem.markers.append(marker.clone());\n          if (marker === prevMarker) {\n            currentItem = postItem;\n          }\n        });\n        this._replaceSection(item, [preItem, postItem]);\n        return [preItem, postItem];\n      }\n\n      /**\n       * Splits the list at the position given.\n       * @return {Array} pre-split list and post-split list, either of which could\n       * be blank (0-item list) if the position is at the start or end of the list.\n       *\n       * Note: Contiguous list sections will be joined in the before_complete queue\n       * of the postEditor.\n       *\n       * @private\n       */\n    }, {\n      key: '_splitListAtPosition',\n      value: function _splitListAtPosition(list, position) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at position not in list', position.section.parent === list);\n\n        var positionIsMiddle = !position.isHead() && !position.isTail();\n        if (positionIsMiddle) {\n          var item = position.section;\n\n          var _splitListItem3 = this._splitListItem(item, position);\n\n          var _splitListItem32 = _slicedToArray(_splitListItem3, 1);\n\n          var pre = _splitListItem32[0];\n\n          position = pre.tailPosition();\n        }\n\n        var preList = this.builder.createListSection(list.tagName);\n        var postList = this.builder.createListSection(list.tagName);\n\n        var preItem = position.section;\n        var currentList = preList;\n        list.items.forEach(function (item) {\n          // If this item matches the start item and the position is at its start,\n          // it should be appended to the postList instead of the preList\n          if (item === preItem && position.isEqual(item.headPosition())) {\n            currentList = postList;\n          }\n          currentList.items.append(item.clone());\n          // If we just appended the preItem, append the remaining items to the postList\n          if (item === preItem) {\n            currentList = postList;\n          }\n        });\n\n        this._replaceSection(list, [preList, postList]);\n        return [preList, postList];\n      }\n\n      /**\n       * @return Array of [prev, mid, next] lists. `prev` and `next` can\n       *         be blank, depending on the position of `item`. `mid` will always\n       *         be a 1-item list containing `item`. `prev` and `next` will be\n       *         removed in the before_complete queue if they are blank\n       *         (and still attached).\n       *\n       * @private\n       */\n    }, {\n      key: '_splitListAtItem',\n      value: function _splitListAtItem(list, item) {\n        var _this15 = this;\n\n        var next = list;\n        var prev = this.builder.createListSection(next.tagName, [], next.attributes);\n        var mid = this.builder.createListSection(next.tagName);\n\n        var addToPrev = true;\n        // must turn the LinkedList into an array so that we can remove items\n        // as we iterate through it\n        var items = next.items.toArray();\n        items.forEach(function (i) {\n          var listToAppend = undefined;\n          if (i === item) {\n            addToPrev = false;\n            listToAppend = mid;\n          } else if (addToPrev) {\n            listToAppend = prev;\n          } else {\n            return; // break after iterating prev and mid parts of the list\n          }\n          listToAppend.join(i);\n          _this15.removeSection(i);\n        });\n        var found = !addToPrev;\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found);\n\n        var collection = this.editor.post.sections;\n        this.insertSectionBefore(collection, mid, next);\n        this.insertSectionBefore(collection, prev, mid);\n\n        // Remove possibly blank prev/next lists\n        this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n          [prev, next].forEach(function (_list) {\n            var isAttached = !!_list.parent;\n            if (_list.isBlank && isAttached) {\n              _this15.removeSection(_list);\n            }\n          });\n        });\n\n        return [prev, mid, next];\n      }\n    }, {\n      key: '_changeSectionFromListItem',\n      value: function _changeSectionFromListItem(section, newTagName) {\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass list item to `_changeSectionFromListItem`', section.isListItem);\n\n        var listSection = section.parent;\n        var markupSection = this.builder.createMarkupSection(newTagName);\n        markupSection.join(section);\n\n        var _splitListAtItem2 = this._splitListAtItem(listSection, section);\n\n        var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 2);\n\n        var mid = _splitListAtItem22[1];\n\n        this.replaceSection(mid, markupSection);\n        return markupSection;\n      }\n    }, {\n      key: '_changeSectionToListItem',\n      value: function _changeSectionToListItem(section, newTagName) {\n        var isAlreadyCorrectListItem = section.isListItem && section.parent.tagName === newTagName;\n\n        if (isAlreadyCorrectListItem) {\n          return section;\n        }\n\n        var listSection = this.builder.createListSection(newTagName);\n        listSection.join(section);\n\n        var sectionToReplace = undefined;\n        if (section.isListItem) {\n          var _splitListAtItem3 = this._splitListAtItem(section.parent, section);\n\n          var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 2);\n\n          var mid = _splitListAtItem32[1];\n\n          sectionToReplace = mid;\n        } else {\n          sectionToReplace = section;\n        }\n        this.replaceSection(sectionToReplace, listSection);\n        return listSection;\n      }\n\n      /**\n       * Insert a given section before another one, updating the post abstract\n       * and the rendered UI.\n       *\n       * Usage:\n       * ```\n       *     let markerRange = editor.range;\n       *     let sectionWithCursor = markerRange.headMarker.section;\n       *     let section = editor.builder.createCardSection('my-image');\n       *     let collection = sectionWithCursor.parent.sections;\n       *     editor.run((postEditor) => {\n       *       postEditor.insertSectionBefore(collection, section, sectionWithCursor);\n       *     });\n       * ```\n       * @param {LinkedList} collection The list of sections to insert into\n       * @param {Object} section The new section\n       * @param {Object} beforeSection Optional The section \"before\" is relative to,\n       *        if falsy the new section will be appended to the collection\n       * @public\n       */\n    }, {\n      key: 'insertSectionBefore',\n      value: function insertSectionBefore(collection, section, beforeSection) {\n        collection.insertBefore(section, beforeSection);\n        this._markDirty(section.parent);\n      }\n\n      /**\n       * Insert the given section after the current active section, or, if no\n       * section is active, at the end of the document.\n       * @param {Section} section\n       * @public\n       */\n    }, {\n      key: 'insertSection',\n      value: function insertSection(section) {\n        var activeSection = this.editor.activeSection;\n        var nextSection = activeSection && activeSection.next;\n\n        var collection = this.editor.post.sections;\n        this.insertSectionBefore(collection, section, nextSection);\n      }\n\n      /**\n       * Insert the given section at the end of the document.\n       * @param {Section} section\n       * @public\n       */\n    }, {\n      key: 'insertSectionAtEnd',\n      value: function insertSectionAtEnd(section) {\n        this.insertSectionBefore(this.editor.post.sections, section, null);\n      }\n\n      /**\n       * Insert the `post` at the given position in the editor's post.\n       * @param {Position} position\n       * @param {Post} post\n       * @private\n       */\n    }, {\n      key: 'insertPost',\n      value: function insertPost(position, newPost) {\n        var post = this.editor.post;\n        var inserter = new _mobiledocKitEditorPostPostInserter['default'](this, post);\n        var nextPosition = inserter.insert(position, newPost);\n        return nextPosition;\n      }\n\n      /**\n       * Remove a given section from the post abstract and the rendered UI.\n       *\n       * Usage:\n       * ```\n       *     let { range } = editor;\n       *     let sectionWithCursor = range.head.section;\n       *     editor.run((postEditor) => {\n       *       postEditor.removeSection(sectionWithCursor);\n       *     });\n       * ```\n       * @param {Object} section The section to remove\n       * @public\n       */\n    }, {\n      key: 'removeSection',\n      value: function removeSection(section) {\n        var parent = section.parent;\n        this._scheduleForRemoval(section);\n        parent.sections.remove(section);\n\n        if (parent.isListSection) {\n          this._scheduleListRemovalIfEmpty(parent);\n        }\n      }\n    }, {\n      key: 'removeAllSections',\n      value: function removeAllSections() {\n        var _this16 = this;\n\n        this.editor.post.sections.toArray().forEach(function (section) {\n          _this16.removeSection(section);\n        });\n      }\n    }, {\n      key: 'migrateSectionsFromPost',\n      value: function migrateSectionsFromPost(post) {\n        var _this17 = this;\n\n        post.sections.toArray().forEach(function (section) {\n          post.sections.remove(section);\n          _this17.insertSectionBefore(_this17.editor.post.sections, section, null);\n        });\n      }\n    }, {\n      key: '_scheduleListRemovalIfEmpty',\n      value: function _scheduleListRemovalIfEmpty(listSection) {\n        var _this18 = this;\n\n        this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n          // if the list is attached and blank after we do other rendering stuff,\n          // remove it\n          var isAttached = !!listSection.parent;\n          if (isAttached && listSection.isBlank) {\n            _this18.removeSection(listSection);\n          }\n        });\n      }\n\n      /**\n       * A method for adding work the deferred queue\n       *\n       * @param {Function} callback to run during completion\n       * @param {Boolean} [once=false] Whether to only schedule the callback once.\n       * @public\n       */\n    }, {\n      key: 'schedule',\n      value: function schedule(callback) {\n        var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n        (0, _mobiledocKitUtilsAssert['default'])('Work can only be scheduled before a post edit has completed', !this._didComplete);\n        if (once) {\n          this.addCallbackOnce(CALLBACK_QUEUES.COMPLETE, callback);\n        } else {\n          this.addCallback(CALLBACK_QUEUES.COMPLETE, callback);\n        }\n      }\n\n      /**\n       * A method for adding work the deferred queue. The callback will only\n       * be added to the queue once, even if `scheduleOnce` is called multiple times.\n       * The function cannot be an anonymous function.\n       *\n       * @param {Function} callback to run during completion\n       * @public\n       */\n    }, {\n      key: 'scheduleOnce',\n      value: function scheduleOnce(callback) {\n        this.schedule(callback, true);\n      }\n\n      /**\n       * Add a rerender job to the queue\n       *\n       * @public\n       */\n    }, {\n      key: 'scheduleRerender',\n      value: function scheduleRerender() {\n        this.scheduleOnce(this._rerender);\n      }\n\n      /**\n       * Schedule a notification that the post has been changed.\n       * The notification will result in the editor firing its `postDidChange`\n       * hook after the postEditor completes its work (at the end of {@link Editor#run}).\n       *\n       * @public\n       */\n    }, {\n      key: 'scheduleDidUpdate',\n      value: function scheduleDidUpdate() {\n        this.scheduleOnce(this._postDidChange);\n      }\n    }, {\n      key: 'scheduleAfterRender',\n      value: function scheduleAfterRender(callback) {\n        var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n        if (once) {\n          this.addCallbackOnce(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n        } else {\n          this.addCallback(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n        }\n      }\n\n      /**\n       * Flush any work on the queue. {@link Editor#run} calls this method; it\n       * should not be called directly.\n       *\n       * @private\n       */\n    }, {\n      key: 'complete',\n      value: function complete() {\n        (0, _mobiledocKitUtilsAssert['default'])('Post editing can only be completed once', !this._didComplete);\n\n        this.runCallbacks(CALLBACK_QUEUES.BEFORE_COMPLETE);\n        this._didComplete = true;\n        this.runCallbacks(CALLBACK_QUEUES.COMPLETE);\n        this.runCallbacks(CALLBACK_QUEUES.AFTER_COMPLETE);\n      }\n    }, {\n      key: 'undoLastChange',\n      value: function undoLastChange() {\n        this.editor._editHistory.stepBackward(this);\n      }\n    }, {\n      key: 'redoLastChange',\n      value: function redoLastChange() {\n        this.editor._editHistory.stepForward(this);\n      }\n    }, {\n      key: 'cancelSnapshot',\n      value: function cancelSnapshot() {\n        this._shouldCancelSnapshot = true;\n      }\n    }]);\n\n    return PostEditor;\n  })();\n\n  exports['default'] = PostEditor;\n});","define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var MARKERABLE = 'markerable',\n      NESTED_MARKERABLE = 'nested_markerable',\n      NON_MARKERABLE = 'non_markerable';\n\n  var Visitor = (function () {\n    function Visitor(inserter, cursorPosition) {\n      _classCallCheck(this, Visitor);\n\n      var postEditor = inserter.postEditor;\n      var post = inserter.post;\n\n      this.postEditor = postEditor;\n      this._post = post;\n      this.cursorPosition = cursorPosition;\n      this.builder = this.postEditor.builder;\n\n      this._hasInsertedFirstLeafSection = false;\n    }\n\n    _createClass(Visitor, [{\n      key: 'visit',\n      value: function visit(node) {\n        var method = node.type;\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot visit node of type ' + node.type, !!this[method]);\n        this[method](node);\n      }\n    }, {\n      key: '_canMergeSection',\n      value: function _canMergeSection(section) {\n        if (this._hasInsertedFirstLeafSection) {\n          return false;\n        } else {\n          return this._isMarkerable && section.isMarkerable;\n        }\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.POST_TYPE,\n      value: function value(node) {\n        var _this = this;\n\n        if (this.cursorSection.isBlank && !this._isNested) {\n          // replace blank section with entire post\n          var newSections = node.sections.map(function (s) {\n            return s.clone();\n          });\n          this._replaceSection(this.cursorSection, newSections);\n        } else {\n          node.sections.forEach(function (section) {\n            return _this.visit(section);\n          });\n        }\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n      value: function value(node) {\n        this[MARKERABLE](node);\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n      value: function value(node) {\n        var _this2 = this;\n\n        var hasNext = !!node.next;\n        node.items.forEach(function (item) {\n          return _this2.visit(item);\n        });\n\n        if (this._isNested && hasNext) {\n          this._breakNestedAtCursor();\n        }\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n      value: function value(node) {\n        this[NESTED_MARKERABLE](node);\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.CARD_TYPE,\n      value: function value(node) {\n        this[NON_MARKERABLE](node);\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n      value: function value(node) {\n        this[NON_MARKERABLE](node);\n      }\n    }, {\n      key: NON_MARKERABLE,\n      value: function value(section) {\n        if (this._isNested) {\n          this._breakNestedAtCursor();\n        } else if (!this.cursorSection.isBlank) {\n          this._breakAtCursor();\n        }\n\n        this._insertLeafSection(section);\n      }\n    }, {\n      key: MARKERABLE,\n      value: function value(section) {\n        if (this._canMergeSection(section)) {\n          this._mergeSection(section);\n        } else if (this._isNested && this._isMarkerable) {\n          // If we are attaching a markerable section to a list item,\n          // insert a linebreak then merge the section onto the resulting blank list item\n          this._breakAtCursor();\n\n          // Advance the cursor to the head of the blank list item\n          var nextPosition = this.cursorSection.next.headPosition();\n          this.cursorPosition = nextPosition;\n\n          // Merge this section onto the list item\n          this._mergeSection(section);\n        } else {\n          this._breakAtCursor();\n          this._insertLeafSection(section);\n        }\n      }\n    }, {\n      key: NESTED_MARKERABLE,\n      value: function value(section) {\n        if (this._canMergeSection(section)) {\n          this._mergeSection(section);\n          return;\n        }\n\n        section = this._isNested ? section : this._wrapNestedSection(section);\n        this._breakAtCursor();\n        this._insertLeafSection(section);\n      }\n\n      // break out of a nested cursor position\n    }, {\n      key: '_breakNestedAtCursor',\n      value: function _breakNestedAtCursor() {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot call _breakNestedAtCursor if not nested', this._isNested);\n\n        var parent = this.cursorSection.parent;\n        var cursorAtEndOfList = this.cursorPosition.isEqual(parent.tailPosition());\n\n        if (cursorAtEndOfList) {\n          var blank = this.builder.createMarkupSection();\n          this._insertSectionAfter(blank, parent);\n        } else {\n          var _breakListAtCursor2 = this._breakListAtCursor();\n\n          var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 2);\n\n          var blank = _breakListAtCursor22[1];\n\n          this.cursorPosition = blank.tailPosition();\n        }\n      }\n    }, {\n      key: '_breakListAtCursor',\n      value: function _breakListAtCursor() {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot _splitParentSection if cursor position is not nested', this._isNested);\n\n        var list = this.cursorSection.parent,\n            position = this.cursorPosition,\n            blank = this.builder.createMarkupSection();\n\n        var _postEditor$_splitListAtPosition = this.postEditor._splitListAtPosition(list, position);\n\n        var _postEditor$_splitListAtPosition2 = _slicedToArray(_postEditor$_splitListAtPosition, 2);\n\n        var pre = _postEditor$_splitListAtPosition2[0];\n        var post = _postEditor$_splitListAtPosition2[1];\n\n        var collection = this._post.sections,\n            reference = post;\n        this.postEditor.insertSectionBefore(collection, blank, reference);\n        return [pre, blank, post];\n      }\n    }, {\n      key: '_wrapNestedSection',\n      value: function _wrapNestedSection(section) {\n        var tagName = section.parent.tagName;\n        var parent = this.builder.createListSection(tagName);\n        parent.items.append(section.clone());\n        return parent;\n      }\n    }, {\n      key: '_mergeSection',\n      value: function _mergeSection(section) {\n        (0, _mobiledocKitUtilsAssert['default'])('Can only merge markerable sections', this._isMarkerable && section.isMarkerable);\n        this._hasInsertedFirstLeafSection = true;\n\n        var markers = section.markers.map(function (m) {\n          return m.clone();\n        });\n        var position = this.postEditor.insertMarkers(this.cursorPosition, markers);\n\n        this.cursorPosition = position;\n      }\n\n      // Can be called to add a line break when in a nested section or a parent\n      // section.\n    }, {\n      key: '_breakAtCursor',\n      value: function _breakAtCursor() {\n        if (this.cursorSection.isBlank) {\n          return;\n        } else if (this._isMarkerable) {\n          this._breakMarkerableAtCursor();\n        } else {\n          this._breakNonMarkerableAtCursor();\n        }\n      }\n\n      // Inserts a blank section before/after the cursor,\n      // depending on cursor position.\n    }, {\n      key: '_breakNonMarkerableAtCursor',\n      value: function _breakNonMarkerableAtCursor() {\n        var collection = this._post.sections,\n            blank = this.builder.createMarkupSection(),\n            reference = this.cursorPosition.isHead() ? this.cursorSection : this.cursorSection.next;\n        this.postEditor.insertSectionBefore(collection, blank, reference);\n        this.cursorPosition = blank.tailPosition();\n      }\n    }, {\n      key: '_breakMarkerableAtCursor',\n      value: function _breakMarkerableAtCursor() {\n        var _postEditor$splitSection = this.postEditor.splitSection(this.cursorPosition);\n\n        var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 1);\n\n        var pre = _postEditor$splitSection2[0];\n\n        this.cursorPosition = pre.tailPosition();\n      }\n    }, {\n      key: '_replaceSection',\n      value: function _replaceSection(section, newSections) {\n        var _this3 = this;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot replace section that does not have parent.sections', section.parent && section.parent.sections);\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass enumerable to _replaceSection', !!newSections.forEach);\n\n        var collection = section.parent.sections;\n        var reference = section.next;\n        this.postEditor.removeSection(section);\n        newSections.forEach(function (section) {\n          _this3.postEditor.insertSectionBefore(collection, section, reference);\n        });\n        var lastSection = newSections[newSections.length - 1];\n\n        this.cursorPosition = lastSection.tailPosition();\n      }\n    }, {\n      key: '_insertSectionBefore',\n      value: function _insertSectionBefore(section, reference) {\n        var collection = this.cursorSection.parent.sections;\n        this.postEditor.insertSectionBefore(collection, section, reference);\n\n        this.cursorPosition = section.tailPosition();\n      }\n\n      // Insert a section after the parent section.\n      // E.g., add a markup section after a list section\n    }, {\n      key: '_insertSectionAfter',\n      value: function _insertSectionAfter(section, parent) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot _insertSectionAfter nested section', !parent.isNested);\n        var reference = parent.next;\n        var collection = this._post.sections;\n        this.postEditor.insertSectionBefore(collection, section, reference);\n        this.cursorPosition = section.tailPosition();\n      }\n    }, {\n      key: '_insertLeafSection',\n      value: function _insertLeafSection(section) {\n        (0, _mobiledocKitUtilsAssert['default'])('Can only _insertLeafSection when cursor is at end of section', this.cursorPosition.isTail());\n\n        this._hasInsertedFirstLeafSection = true;\n        section = section.clone();\n\n        if (this.cursorSection.isBlank) {\n          (0, _mobiledocKitUtilsAssert['default'])('Cannot insert leaf non-markerable section when cursor is nested', !(section.isMarkerable && this._isNested));\n          this._replaceSection(this.cursorSection, [section]);\n        } else if (this.cursorSection.next && this.cursorSection.next.isBlank) {\n          this._replaceSection(this.cursorSection.next, [section]);\n        } else {\n          var reference = this.cursorSection.next;\n          this._insertSectionBefore(section, reference);\n        }\n      }\n    }, {\n      key: 'cursorPosition',\n      get: function get() {\n        return this._cursorPosition;\n      },\n      set: function set(position) {\n        this._cursorPosition = position;\n        this.postEditor.setRange(position);\n      }\n    }, {\n      key: '_isMarkerable',\n      get: function get() {\n        return this.cursorSection.isMarkerable;\n      }\n    }, {\n      key: 'cursorSection',\n      get: function get() {\n        return this.cursorPosition.section;\n      }\n    }, {\n      key: 'cursorOffset',\n      get: function get() {\n        return this.cursorPosition.offset;\n      }\n    }, {\n      key: '_isNested',\n      get: function get() {\n        return this.cursorSection.isNested;\n      }\n    }]);\n\n    return Visitor;\n  })();\n\n  var Inserter = (function () {\n    function Inserter(postEditor, post) {\n      _classCallCheck(this, Inserter);\n\n      this.postEditor = postEditor;\n      this.post = post;\n    }\n\n    _createClass(Inserter, [{\n      key: 'insert',\n      value: function insert(cursorPosition, newPost) {\n        var visitor = new Visitor(this, cursorPosition);\n        if (!newPost.isBlank) {\n          visitor.visit(newPost);\n        }\n        return visitor.cursorPosition;\n      }\n    }]);\n\n    return Inserter;\n  })();\n\n  exports['default'] = Inserter;\n});","define(\"mobiledoc-kit/editor/selection-change-observer\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n  var instance = undefined;\n\n  var SelectionChangeObserver = (function () {\n    function SelectionChangeObserver() {\n      _classCallCheck(this, SelectionChangeObserver);\n\n      this.started = false;\n      this.listeners = [];\n      this.selection = {};\n    }\n\n    _createClass(SelectionChangeObserver, [{\n      key: \"addListener\",\n      value: function addListener(listener) {\n        if (this.listeners.indexOf(listener) === -1) {\n          this.listeners.push(listener);\n          this.start();\n        }\n      }\n    }, {\n      key: \"removeListener\",\n      value: function removeListener(listener) {\n        var index = this.listeners.indexOf(listener);\n        if (index !== -1) {\n          this.listeners.splice(index, 1);\n          if (this.listeners.length === 0) {\n            this.stop();\n          }\n        }\n      }\n    }, {\n      key: \"start\",\n      value: function start() {\n        if (this.started) {\n          return;\n        }\n        this.started = true;\n\n        this.poll();\n      }\n    }, {\n      key: \"stop\",\n      value: function stop() {\n        this.started = false;\n        this.selection = {};\n      }\n    }, {\n      key: \"notifyListeners\",\n      value: function notifyListeners() /* newSelection, prevSelection */{\n        var _arguments = arguments;\n\n        this.listeners.forEach(function (listener) {\n          listener.selectionDidChange.apply(listener, _arguments);\n        });\n      }\n    }, {\n      key: \"destroy\",\n      value: function destroy() {\n        this.stop();\n        this.listeners = [];\n      }\n    }, {\n      key: \"getSelection\",\n      value: function getSelection() {\n        var selection = window.getSelection();\n        var anchorNode = selection.anchorNode;\n        var focusNode = selection.focusNode;\n        var anchorOffset = selection.anchorOffset;\n        var focusOffset = selection.focusOffset;\n\n        return { anchorNode: anchorNode, focusNode: focusNode, anchorOffset: anchorOffset, focusOffset: focusOffset };\n      }\n    }, {\n      key: \"poll\",\n      value: function poll() {\n        var _this = this;\n\n        if (this.started) {\n          this.update();\n          this.runNext(function () {\n            return _this.poll();\n          });\n        }\n      }\n    }, {\n      key: \"runNext\",\n      value: function runNext(fn) {\n        window.requestAnimationFrame(fn);\n      }\n    }, {\n      key: \"update\",\n      value: function update() {\n        var prevSelection = this.selection;\n        var curSelection = this.getSelection();\n        if (!this.selectionIsEqual(prevSelection, curSelection)) {\n          this.selection = curSelection;\n          this.notifyListeners(curSelection, prevSelection);\n        }\n      }\n    }, {\n      key: \"selectionIsEqual\",\n      value: function selectionIsEqual(s1, s2) {\n        return s1.anchorNode === s2.anchorNode && s1.anchorOffset === s2.anchorOffset && s1.focusNode === s2.focusNode && s1.focusOffset === s2.focusOffset;\n      }\n    }], [{\n      key: \"getInstance\",\n      value: function getInstance() {\n        if (!instance) {\n          instance = new SelectionChangeObserver();\n        }\n        return instance;\n      }\n    }, {\n      key: \"addListener\",\n      value: function addListener(listener) {\n        SelectionChangeObserver.getInstance().addListener(listener);\n      }\n    }, {\n      key: \"removeListener\",\n      value: function removeListener(listener) {\n        SelectionChangeObserver.getInstance().removeListener(listener);\n      }\n    }]);\n\n    return SelectionChangeObserver;\n  })();\n\n  exports[\"default\"] = SelectionChangeObserver;\n});","define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/editor/selection-change-observer'], function (exports, _mobiledocKitEditorSelectionChangeObserver) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var SelectionManager = (function () {\n    function SelectionManager(editor, callback) {\n      _classCallCheck(this, SelectionManager);\n\n      this.editor = editor;\n      this.callback = callback;\n      this.started = false;\n    }\n\n    _createClass(SelectionManager, [{\n      key: 'start',\n      value: function start() {\n        if (this.started) {\n          return;\n        }\n\n        _mobiledocKitEditorSelectionChangeObserver['default'].addListener(this);\n        this.started = true;\n      }\n    }, {\n      key: 'stop',\n      value: function stop() {\n        this.started = false;\n        _mobiledocKitEditorSelectionChangeObserver['default'].removeListener(this);\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this.stop();\n      }\n    }, {\n      key: 'selectionDidChange',\n      value: function selectionDidChange() {\n        if (this.started) {\n          this.callback.apply(this, arguments);\n        }\n      }\n    }]);\n\n    return SelectionManager;\n  })();\n\n  exports['default'] = SelectionManager;\n});","define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsCharacters) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var TextInputHandler = (function () {\n    function TextInputHandler(editor) {\n      _classCallCheck(this, TextInputHandler);\n\n      this.editor = editor;\n      this._handlers = [];\n    }\n\n    _createClass(TextInputHandler, [{\n      key: 'register',\n      value: function register(handler) {\n        (0, _mobiledocKitUtilsAssert['default'])('Input Handler is not valid', this._validateHandler(handler));\n        this._handlers.push(handler);\n      }\n    }, {\n      key: 'unregister',\n      value: function unregister(name) {\n        var handlers = this._handlers;\n        for (var i = 0; i < handlers.length; i++) {\n          if (handlers[i].name === name) {\n            handlers.splice(i, 1);\n          }\n        }\n      }\n    }, {\n      key: 'handle',\n      value: function handle(string) {\n        var editor = this.editor;\n\n        editor.insertText(string);\n\n        var matchedHandler = this._findHandler();\n        if (matchedHandler) {\n          var _matchedHandler = _slicedToArray(matchedHandler, 2);\n\n          var handler = _matchedHandler[0];\n          var matches = _matchedHandler[1];\n\n          handler.run(editor, matches);\n        }\n      }\n    }, {\n      key: 'handleNewLine',\n      value: function handleNewLine() {\n        var editor = this.editor;\n\n        var matchedHandler = this._findHandler(_mobiledocKitUtilsCharacters.ENTER);\n        if (matchedHandler) {\n          var _matchedHandler2 = _slicedToArray(matchedHandler, 2);\n\n          var handler = _matchedHandler2[0];\n          var matches = _matchedHandler2[1];\n\n          handler.run(editor, matches);\n        }\n      }\n    }, {\n      key: '_findHandler',\n      value: function _findHandler() {\n        var string = arguments.length <= 0 || arguments[0] === undefined ? \"\" : arguments[0];\n        var _editor$range = this.editor.range;\n        var head = _editor$range.head;\n        var section = _editor$range.head.section;\n\n        var preText = section.textUntil(head) + string;\n\n        for (var i = 0; i < this._handlers.length; i++) {\n          var handler = this._handlers[i];\n          var text = handler.text;\n          var match = handler.match;\n\n          if (text && (0, _mobiledocKitUtilsStringUtils.endsWith)(preText, text)) {\n            return [handler, [text]];\n          } else if (match && match.test(preText)) {\n            return [handler, match.exec(preText)];\n          }\n        }\n      }\n    }, {\n      key: '_validateHandler',\n      value: function _validateHandler(handler) {\n        (0, _mobiledocKitUtilsDeprecate['default'])('Registered input handlers require a \"name\" property so that they can be unregistered', !!handler.name);\n        return !!handler.run && ( // has `run`\n        !!handler.text || !!handler.match) && // and `text` or `match`\n        !(!!handler.text && !!handler.match); // not both `text` and `match`\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this._handlers = [];\n      }\n    }]);\n\n    return TextInputHandler;\n  })();\n\n  exports['default'] = TextInputHandler;\n});","define('mobiledoc-kit/editor/text-input-handlers', ['exports'], function (exports) {\n  /**\n   * Convert section at the editor's cursor position into a list.\n   * Does nothing if the cursor position is not at the start of the section,\n   * or if the section is already a list item.\n   *\n   * @param {Editor} editor\n   * @param {String} listTagName (\"ul\" or \"ol\")\n   * @public\n   */\n  'use strict';\n\n  exports.replaceWithListSection = replaceWithListSection;\n  exports.replaceWithHeaderSection = replaceWithHeaderSection;\n\n  function replaceWithListSection(editor, listTagName) {\n    var _editor$range = editor.range;\n    var head = _editor$range.head;\n    var section = _editor$range.head.section;\n\n    // Skip if cursor is not at end of section\n    if (!head.isTail()) {\n      return;\n    }\n\n    if (section.isListItem) {\n      return;\n    }\n\n    editor.run(function (postEditor) {\n      var builder = postEditor.builder;\n\n      var item = builder.createListItem();\n      var listSection = builder.createListSection(listTagName, [item]);\n\n      postEditor.replaceSection(section, listSection);\n      postEditor.setRange(listSection.headPosition());\n    });\n  }\n\n  /**\n   * Convert section at the editor's cursor position into a header section.\n   * Does nothing if the cursor position is not at the start of the section.\n   *\n   * @param {Editor} editor\n   * @param {String} headingTagName ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')\n   * @public\n   */\n\n  function replaceWithHeaderSection(editor, headingTagName) {\n    var _editor$range2 = editor.range;\n    var head = _editor$range2.head;\n    var section = _editor$range2.head.section;\n\n    // Skip if cursor is not at end of section\n    if (!head.isTail()) {\n      return;\n    }\n\n    editor.run(function (postEditor) {\n      var builder = postEditor.builder;\n\n      var newSection = builder.createMarkupSection(headingTagName);\n      postEditor.replaceSection(section, newSection);\n      postEditor.setRange(newSection.headPosition());\n    });\n  }\n\n  var DEFAULT_TEXT_INPUT_HANDLERS = [{\n    name: 'ul',\n    // \"* \" -> ul\n    match: /^\\* $/,\n    run: function run(editor) {\n      replaceWithListSection(editor, 'ul');\n    }\n  }, {\n    name: 'ol',\n    // \"1\" -> ol, \"1.\" -> ol\n    match: /^1\\.? $/,\n    run: function run(editor) {\n      replaceWithListSection(editor, 'ol');\n    }\n  }, {\n    name: 'heading',\n    /*\n     * \"# \" -> h1\n     * \"## \" -> h2\n     * \"### \" -> h3\n     * \"#### \" -> h4\n     * \"##### \" -> h5\n     * \"###### \" -> h6\n     */\n    match: /^(#{1,6}) $/,\n    run: function run(editor, matches) {\n      var capture = matches[1];\n      var headingTag = 'h' + capture.length;\n      replaceWithHeaderSection(editor, headingTag);\n    }\n  }];\n  exports.DEFAULT_TEXT_INPUT_HANDLERS = DEFAULT_TEXT_INPUT_HANDLERS;\n});","define('mobiledoc-kit/editor/ui', ['exports'], function (exports) {\n  /**\n   * @module UI\n   */\n\n  /**\n   * @callback promptCallback\n   * @param {String} url The URL to pass back to the editor for linking\n   *        to the selected text.\n   */\n\n  /**\n   * @callback showPrompt\n   * @param {String} message The text of the prompt.\n   * @param {String} defaultValue The initial URL to display in the prompt.\n   * @param {module:UI~promptCallback} callback Once your handler has accepted a URL,\n   *        it should pass it to `callback` so that the editor may link the\n   *        selected text.\n   */\n\n  /**\n   * Exposes the core behavior for linking and unlinking text, and allows for\n   * customization of the URL input handler.\n   * @param {Editor} editor An editor instance to operate on. If a range is selected,\n   *        either prompt for a URL and add a link or un-link the\n   *        currently linked text.\n   * @param {module:UI~showPrompt} [showPrompt] An optional custom input handler. Defaults\n   *        to using `window.prompt`.\n   * @example\n   * let myPrompt = (message, defaultURL, promptCallback) => {\n   *   let url = window.prompt(\"Overriding the defaults\", \"http://placekitten.com\");\n   *   promptCallback(url);\n   * };\n   *\n   * editor.registerKeyCommand({\n   *   str: \"META+K\",\n   *   run(editor) {\n   *     toggleLink(editor, myPrompt);\n   *   }\n   * });\n   * @public\n   */\n\n  'use strict';\n\n  exports.toggleLink = toggleLink;\n  var defaultShowPrompt = function defaultShowPrompt(message, defaultValue, callback) {\n    return callback(window.prompt(message, defaultValue));\n  };\n\n  function toggleLink(editor) {\n    var showPrompt = arguments.length <= 1 || arguments[1] === undefined ? defaultShowPrompt : arguments[1];\n\n    if (editor.range.isCollapsed) {\n      return;\n    }\n\n    var selectedText = editor.cursor.selectedText();\n    var defaultUrl = '';\n    if (selectedText.indexOf('http') !== -1) {\n      defaultUrl = selectedText;\n    }\n\n    var range = editor.range;\n\n    var hasLink = editor.detectMarkupInRange(range, 'a');\n\n    if (hasLink) {\n      editor.toggleMarkup('a');\n    } else {\n      showPrompt('Enter a URL', defaultUrl, function (url) {\n        if (!url) {\n          return;\n        }\n\n        editor.toggleMarkup('a', { href: url });\n      });\n    }\n  }\n});","define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version', 'mobiledoc-kit/renderers/mobiledoc'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion, _mobiledocKitRenderersMobiledoc) {\n  'use strict';\n\n  exports.registerGlobal = registerGlobal;\n\n  var Mobiledoc = {\n    Editor: _mobiledocKitEditorEditor['default'],\n    UI: _mobiledocKitEditorUi,\n    ImageCard: _mobiledocKitCardsImage['default'],\n    Range: _mobiledocKitUtilsCursorRange['default'],\n    Position: _mobiledocKitUtilsCursorPosition['default'],\n    Error: _mobiledocKitUtilsMobiledocError['default'],\n    VERSION: _mobiledocKitVersion['default'],\n    MOBILEDOC_VERSION: _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION\n  };\n\n  function registerGlobal(global) {\n    global.Mobiledoc = Mobiledoc;\n  }\n\n  exports.Editor = _mobiledocKitEditorEditor['default'];\n  exports.UI = _mobiledocKitEditorUi;\n  exports.Range = _mobiledocKitUtilsCursorRange['default'];\n  exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n  exports.MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n  exports['default'] = Mobiledoc;\n});","define('mobiledoc-kit/models/_attributable', ['exports', 'mobiledoc-kit/utils/object-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsObjectUtils, _mobiledocKitUtilsArrayUtils) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  exports.attributable = attributable;\n  var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n  exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n  /*\n   * A \"mixin\" to add section attribute support\n   * to markup and list sections.\n   */\n\n  function attributable(ctx) {\n    ctx.attributes = {};\n\n    ctx.hasAttribute = function (key) {\n      return key in ctx.attributes;\n    };\n\n    ctx.setAttribute = function (key, value) {\n      if (!(0, _mobiledocKitUtilsArrayUtils.contains)(VALID_ATTRIBUTES, key)) {\n        throw new Error('Invalid attribute \"' + key + '\" was passed. Constrain attributes to the spec-compliant whitelist.');\n      }\n      ctx.attributes[key] = value;\n    };\n    ctx.removeAttribute = function (key) {\n      delete ctx.attributes[key];\n    };\n    ctx.getAttribute = function (key) {\n      return ctx.attributes[key];\n    };\n    ctx.eachAttribute = function (cb) {\n      (0, _mobiledocKitUtilsObjectUtils.entries)(ctx.attributes).forEach(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2);\n\n        var k = _ref2[0];\n        var v = _ref2[1];\n        return cb(k, v);\n      });\n    };\n  }\n});","define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n  function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var Markerable = (function (_Section) {\n    _inherits(Markerable, _Section);\n\n    function Markerable(type, tagName) {\n      var _this = this;\n\n      var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n      _classCallCheck(this, Markerable);\n\n      _get(Object.getPrototypeOf(Markerable.prototype), 'constructor', this).call(this, type);\n      this.isMarkerable = true;\n      this.tagName = tagName;\n      this.markers = new _mobiledocKitUtilsLinkedList['default']({\n        adoptItem: function adoptItem(m) {\n          (0, _mobiledocKitUtilsAssert['default'])('Can only insert markers and atoms into markerable (was: ' + m.type + ')', m.isMarker || m.isAtom);\n          m.section = m.parent = _this;\n        },\n        freeItem: function freeItem(m) {\n          return m.section = m.parent = null;\n        }\n      });\n\n      markers.forEach(function (m) {\n        return _this.markers.append(m);\n      });\n    }\n\n    _createClass(Markerable, [{\n      key: 'canJoin',\n      value: function canJoin(other) {\n        return other.isMarkerable && other.type === this.type && other.tagName === this.tagName;\n      }\n    }, {\n      key: 'clone',\n      value: function clone() {\n        var newMarkers = this.markers.map(function (m) {\n          return m.clone();\n        });\n        return this.builder.createMarkerableSection(this.type, this.tagName, newMarkers);\n      }\n    }, {\n      key: 'textUntil',\n      value: function textUntil(position) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot get textUntil for a position not in this section', position.section === this);\n        var marker = position.marker;\n        var offsetInMarker = position.offsetInMarker;\n\n        var text = '';\n        var currentMarker = this.markers.head;\n        while (currentMarker) {\n          if (currentMarker === marker) {\n            text += currentMarker.textUntil(offsetInMarker);\n            break;\n          } else {\n            text += currentMarker.text;\n            currentMarker = currentMarker.next;\n          }\n        }\n        return text;\n      }\n\n      /**\n       * @param {Marker}\n       * @param {Number} markerOffset The offset relative to the start of the marker\n       *\n       * @return {Number} The offset relative to the start of this section\n       */\n    }, {\n      key: 'offsetOfMarker',\n      value: function offsetOfMarker(marker) {\n        var markerOffset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot get offsetOfMarker for marker that is not child of this', marker.section === this);\n\n        // FIXME it is possible, when we get a cursor position before having finished reparsing,\n        // for markerOffset to be > marker.length. We shouldn't rely on this functionality.\n\n        var offset = 0;\n        var currentMarker = this.markers.head;\n        while (currentMarker && currentMarker !== marker.next) {\n          var _length = currentMarker === marker ? markerOffset : currentMarker.length;\n          offset += _length;\n          currentMarker = currentMarker.next;\n        }\n\n        return offset;\n      }\n\n      // puts clones of this.markers into beforeSection and afterSection,\n      // all markers before the marker/offset split go in beforeSection, and all\n      // after the marker/offset split go in afterSection\n      // @return {Array} [beforeSection, afterSection], two new sections\n    }, {\n      key: '_redistributeMarkers',\n      value: function _redistributeMarkers(beforeSection, afterSection, marker) {\n        var offset = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3];\n\n        var currentSection = beforeSection;\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(this.markers, function (m) {\n          if (m === marker) {\n            var _marker$split = marker.split(offset);\n\n            var _marker$split2 = _toArray(_marker$split);\n\n            var beforeMarker = _marker$split2[0];\n\n            var afterMarkers = _marker$split2.slice(1);\n\n            beforeSection.markers.append(beforeMarker);\n            (0, _mobiledocKitUtilsArrayUtils.forEach)(afterMarkers, function (_m) {\n              return afterSection.markers.append(_m);\n            });\n            currentSection = afterSection;\n          } else {\n            currentSection.markers.append(m.clone());\n          }\n        });\n\n        return [beforeSection, afterSection];\n      }\n    }, {\n      key: 'splitAtMarker',\n      value: function splitAtMarker() /*marker, offset=0*/{\n        (0, _mobiledocKitUtilsAssert['default'])('splitAtMarker must be implemented by sub-class', false);\n      }\n\n      /**\n       * Split this section's marker (if any) at the given offset, so that\n       * there is now a marker boundary at that offset (useful for later applying\n       * a markup to a range)\n       * @param {Number} sectionOffset The offset relative to start of this section\n       * @return {EditObject} An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank.\n       * After calling `splitMarkerAtOffset(offset)`, there will always be a valid\n       * result returned from `markerBeforeOffset(offset)`.\n       */\n    }, {\n      key: 'splitMarkerAtOffset',\n      value: function splitMarkerAtOffset(sectionOffset) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot splitMarkerAtOffset when offset is > length', sectionOffset <= this.length);\n        var markerOffset = undefined;\n        var len = 0;\n        var currentMarker = this.markers.head;\n        var edit = { added: [], removed: [] };\n\n        if (!currentMarker) {\n          var blankMarker = this.builder.createMarker();\n          this.markers.prepend(blankMarker);\n          edit.added.push(blankMarker);\n        } else {\n          while (currentMarker) {\n            len += currentMarker.length;\n            if (len === sectionOffset) {\n              // nothing to do, there is a gap at the requested offset\n              break;\n            } else if (len > sectionOffset) {\n              var _edit$added;\n\n              markerOffset = currentMarker.length - (len - sectionOffset);\n              var newMarkers = currentMarker.splitAtOffset(markerOffset);\n              (_edit$added = edit.added).push.apply(_edit$added, _toConsumableArray(newMarkers));\n              edit.removed.push(currentMarker);\n              this.markers.splice(currentMarker, 1, newMarkers);\n              break;\n            } else {\n              currentMarker = currentMarker.next;\n            }\n          }\n        }\n\n        return edit;\n      }\n    }, {\n      key: 'splitAtPosition',\n      value: function splitAtPosition(position) {\n        var marker = position.marker;\n        var offsetInMarker = position.offsetInMarker;\n\n        return this.splitAtMarker(marker, offsetInMarker);\n      }\n\n      // returns the marker just before this offset.\n      // It is an error to call this method with an offset that is in the middle\n      // of a marker.\n    }, {\n      key: 'markerBeforeOffset',\n      value: function markerBeforeOffset(sectionOffset) {\n        var len = 0;\n        var currentMarker = this.markers.head;\n\n        while (currentMarker) {\n          len += currentMarker.length;\n          if (len === sectionOffset) {\n            return currentMarker;\n          } else {\n            (0, _mobiledocKitUtilsAssert['default'])('markerBeforeOffset called with sectionOffset not between markers', len < sectionOffset);\n            currentMarker = currentMarker.next;\n          }\n        }\n      }\n    }, {\n      key: 'markerPositionAtOffset',\n      value: function markerPositionAtOffset(offset) {\n        var currentOffset = 0;\n        var currentMarker = undefined;\n        var remaining = offset;\n        this.markers.detect(function (marker) {\n          currentOffset = Math.min(remaining, marker.length);\n          remaining -= currentOffset;\n          if (remaining === 0) {\n            currentMarker = marker;\n            return true; // break out of detect\n          }\n        });\n\n        return { marker: currentMarker, offset: currentOffset };\n      }\n    }, {\n      key: 'markersFor',\n\n      /**\n       * @return {Array} New markers that match the boundaries of the\n       * range. Does not change the existing markers in this section.\n       */\n      value: function markersFor(headOffset, tailOffset) {\n        var range = { head: { section: this, offset: headOffset },\n          tail: { section: this, offset: tailOffset } };\n\n        var markers = [];\n        this._markersInRange(range, function (marker, _ref) {\n          var markerHead = _ref.markerHead;\n          var markerTail = _ref.markerTail;\n          var isContained = _ref.isContained;\n\n          var cloned = marker.clone();\n          if (!isContained) {\n            // cannot do marker.value.slice if the marker is an atom -- this breaks the atom's \"atomic\" value\n            // If a marker is an atom `isContained` should always be true so\n            // we shouldn't hit this code path. FIXME add tests\n            cloned.value = marker.value.slice(markerHead, markerTail);\n          }\n          markers.push(cloned);\n        });\n        return markers;\n      }\n    }, {\n      key: 'markupsInRange',\n      value: function markupsInRange(range) {\n        var markups = new _mobiledocKitUtilsSet['default']();\n        this._markersInRange(range, function (marker) {\n          marker.markups.forEach(function (m) {\n            return markups.add(m);\n          });\n        });\n        return markups.toArray();\n      }\n\n      // calls the callback with (marker, {markerHead, markerTail, isContained})\n      // for each marker that is wholly or partially contained in the range.\n    }, {\n      key: '_markersInRange',\n      value: function _markersInRange(range, callback) {\n        var head = range.head;\n        var tail = range.tail;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot call #_markersInRange if range expands beyond this section', head.section === this && tail.section === this);\n        var headOffset = head.offset;var tailOffset = tail.offset;\n\n        var currentHead = 0,\n            currentTail = 0,\n            currentMarker = this.markers.head;\n\n        while (currentMarker) {\n          currentTail += currentMarker.length;\n\n          if (currentTail > headOffset && currentHead < tailOffset) {\n            var markerHead = Math.max(headOffset - currentHead, 0);\n            var markerTail = currentMarker.length - Math.max(currentTail - tailOffset, 0);\n            var isContained = markerHead === 0 && markerTail === currentMarker.length;\n\n            callback(currentMarker, { markerHead: markerHead, markerTail: markerTail, isContained: isContained });\n          }\n\n          currentHead += currentMarker.length;\n          currentMarker = currentMarker.next;\n\n          if (currentHead > tailOffset) {\n            break;\n          }\n        }\n      }\n\n      // mutates this by appending the other section's (cloned) markers to it\n    }, {\n      key: 'join',\n      value: function join(otherSection) {\n        var _this2 = this;\n\n        var beforeMarker = this.markers.tail;\n        var afterMarker = null;\n\n        otherSection.markers.forEach(function (m) {\n          if (!m.isBlank) {\n            m = m.clone();\n            _this2.markers.append(m);\n            if (!afterMarker) {\n              afterMarker = m;\n            }\n          }\n        });\n\n        return { beforeMarker: beforeMarker, afterMarker: afterMarker };\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        if (!this.markers.length) {\n          return true;\n        }\n        return this.markers.every(function (m) {\n          return m.isBlank;\n        });\n      }\n    }, {\n      key: 'text',\n      get: function get() {\n        return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n          return prev + m.value;\n        }, '');\n      }\n    }, {\n      key: 'length',\n      get: function get() {\n        return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n          return prev + m.length;\n        }, 0);\n      }\n    }]);\n\n    return Markerable;\n  })(_mobiledocKitModels_section['default']);\n\n  exports['default'] = Markerable;\n});","define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/cursor/position'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCursorPosition) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  function unimplementedMethod(methodName, me) {\n    (0, _mobiledocKitUtilsAssert['default'])('`' + methodName + '()` must be implemented by ' + me.constructor.name, false);\n  }\n\n  var Section = (function (_LinkedItem) {\n    _inherits(Section, _LinkedItem);\n\n    function Section(type) {\n      _classCallCheck(this, Section);\n\n      _get(Object.getPrototypeOf(Section.prototype), 'constructor', this).call(this);\n      (0, _mobiledocKitUtilsAssert['default'])('Cannot create section without type', !!type);\n      this.type = type;\n      this.isSection = true;\n      this.isMarkerable = false;\n      this.isNested = false;\n      this.isSection = true;\n      this.isLeafSection = true;\n    }\n\n    _createClass(Section, [{\n      key: 'isValidTagName',\n      value: function isValidTagName() /* normalizedTagName */{\n        unimplementedMethod('isValidTagName', this);\n      }\n    }, {\n      key: 'clone',\n      value: function clone() {\n        unimplementedMethod('clone', this);\n      }\n    }, {\n      key: 'canJoin',\n      value: function canJoin() /* otherSection */{\n        unimplementedMethod('canJoin', this);\n      }\n\n      /**\n       * @return {Position} The position at the start of this section\n       * @public\n       */\n    }, {\n      key: 'headPosition',\n      value: function headPosition() {\n        return this.toPosition(0);\n      }\n\n      /**\n       * @return {Position} The position at the end of this section\n       * @public\n       */\n    }, {\n      key: 'tailPosition',\n      value: function tailPosition() {\n        return this.toPosition(this.length);\n      }\n\n      /**\n       * @param {Number} offset\n       * @return {Position} The position in this section at the given offset\n       * @public\n       */\n    }, {\n      key: 'toPosition',\n      value: function toPosition(offset) {\n        (0, _mobiledocKitUtilsAssert['default'])(\"Must pass number to `toPosition`\", typeof offset === 'number');\n        (0, _mobiledocKitUtilsAssert['default'])(\"Cannot call `toPosition` with offset > length\", offset <= this.length);\n\n        return new _mobiledocKitUtilsCursorPosition['default'](this, offset);\n      }\n\n      /**\n       * @return {Range} A range from this section's head to tail positions\n       * @public\n       */\n    }, {\n      key: 'toRange',\n      value: function toRange() {\n        return this.headPosition().toRange(this.tailPosition());\n      }\n    }, {\n      key: 'join',\n      value: function join() {\n        unimplementedMethod('join', this);\n      }\n    }, {\n      key: 'textUntil',\n      value: function textUntil() /* position */{\n        return '';\n      }\n\n      /**\n       * Markerable sections should override this method\n       */\n    }, {\n      key: 'splitMarkerAtOffset',\n      value: function splitMarkerAtOffset() {\n        var blankEdit = { added: [], removed: [] };\n        return blankEdit;\n      }\n    }, {\n      key: 'nextLeafSection',\n      value: function nextLeafSection() {\n        var next = this.next;\n        if (next) {\n          if (next.items) {\n            return next.items.head;\n          } else {\n            return next;\n          }\n        } else {\n          if (this.isNested) {\n            return this.parent.nextLeafSection();\n          }\n        }\n      }\n    }, {\n      key: 'immediatelyNextMarkerableSection',\n      value: function immediatelyNextMarkerableSection() {\n        var next = this.nextLeafSection();\n        while (next && !next.isMarkerable) {\n          next = next.nextLeafSection();\n        }\n        return next;\n      }\n    }, {\n      key: 'previousLeafSection',\n      value: function previousLeafSection() {\n        var prev = this.prev;\n\n        if (prev) {\n          if (prev.items) {\n            return prev.items.tail;\n          } else {\n            return prev;\n          }\n        } else {\n          if (this.isNested) {\n            return this.parent.previousLeafSection();\n          }\n        }\n      }\n    }, {\n      key: 'tagName',\n      set: function set(val) {\n        var normalizedTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(val);\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot set section tagName to ' + val, this.isValidTagName(normalizedTagName));\n        this._tagName = normalizedTagName;\n      },\n      get: function get() {\n        return this._tagName;\n      }\n    }, {\n      key: 'length',\n      get: function get() {\n        return 0;\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        unimplementedMethod('isBlank', this);\n      }\n    }]);\n\n    return Section;\n  })(_mobiledocKitUtilsLinkedItem['default']);\n\n  exports['default'] = Section;\n});","define('mobiledoc-kit/models/atom-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var AtomNode = (function () {\n    function AtomNode(editor, atom, model, element, atomOptions) {\n      _classCallCheck(this, AtomNode);\n\n      this.editor = editor;\n      this.atom = atom;\n      this.model = model;\n      this.atomOptions = atomOptions;\n      this.element = element;\n\n      this._teardownCallback = null;\n      this._rendered = null;\n    }\n\n    _createClass(AtomNode, [{\n      key: 'render',\n      value: function render() {\n        if (!this._rendered) {\n          var options = this.atomOptions;\n          var env = this.env;\n          var _model = this.model;\n          var value = _model.value;\n          var payload = _model.payload;\n\n          // cache initial render\n          this._rendered = this.atom.render({ options: options, env: env, value: value, payload: payload });\n        }\n\n        this._validateAndAppendRenderResult(this._rendered);\n      }\n    }, {\n      key: 'teardown',\n      value: function teardown() {\n        if (this._teardownCallback) {\n          this._teardownCallback();\n          this._teardownCallback = null;\n        }\n        if (this._rendered) {\n          this.element.removeChild(this._rendered);\n          this._rendered = null;\n        }\n      }\n    }, {\n      key: '_validateAndAppendRenderResult',\n      value: function _validateAndAppendRenderResult(rendered) {\n        if (!rendered) {\n          return;\n        }\n\n        var name = this.atom.name;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + name + '\" must return a DOM node (returned value was: \"' + rendered + '\")', !!rendered.nodeType);\n        this.element.appendChild(rendered);\n      }\n    }, {\n      key: 'env',\n      get: function get() {\n        var _this = this;\n\n        return {\n          name: this.atom.name,\n          onTeardown: function onTeardown(callback) {\n            return _this._teardownCallback = callback;\n          },\n          save: function save(value) {\n            var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n            _this.model.value = value;\n            _this.model.payload = payload;\n\n            _this.editor._postDidChange();\n            _this.teardown();\n            _this.render();\n          }\n        };\n      }\n    }]);\n\n    return AtomNode;\n  })();\n\n  exports['default'] = AtomNode;\n});","define('mobiledoc-kit/models/atom', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var ATOM_LENGTH = 1;\n\n  var Atom = (function (_LinkedItem) {\n    _inherits(Atom, _LinkedItem);\n\n    function Atom(name, value, payload) {\n      var _this = this;\n\n      var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n      _classCallCheck(this, Atom);\n\n      _get(Object.getPrototypeOf(Atom.prototype), 'constructor', this).call(this);\n      this.name = name;\n      this.value = value;\n      this.text = ''; // An atom never has text, but it does have a value\n      (0, _mobiledocKitUtilsAssert['default'])('Atom must have value', value !== undefined && value !== null);\n      this.payload = payload;\n      this.type = _mobiledocKitModelsTypes.ATOM_TYPE;\n      this.isMarker = false;\n      this.isAtom = true;\n\n      this.markups = [];\n      markups.forEach(function (m) {\n        return _this.addMarkup(m);\n      });\n    }\n\n    _createClass(Atom, [{\n      key: 'clone',\n      value: function clone() {\n        var clonedMarkups = this.markups.slice();\n        return this.builder.createAtom(this.name, this.value, this.payload, clonedMarkups);\n      }\n    }, {\n      key: 'canJoin',\n      value: function canJoin() /* other */{\n        return false;\n      }\n    }, {\n      key: 'textUntil',\n      value: function textUntil() /* offset */{\n        return '';\n      }\n    }, {\n      key: 'split',\n      value: function split() {\n        var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n        var endOffset = arguments.length <= 1 || arguments[1] === undefined ? offset : arguments[1];\n        return (function () {\n          var markers = [];\n\n          if (endOffset === 0) {\n            markers.push(this.builder.createMarker('', this.markups.slice()));\n          }\n\n          markers.push(this.clone());\n\n          if (offset === ATOM_LENGTH) {\n            markers.push(this.builder.createMarker('', this.markups.slice()));\n          }\n\n          return markers;\n        }).apply(this, arguments);\n      }\n    }, {\n      key: 'splitAtOffset',\n      value: function splitAtOffset(offset) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n\n        var builder = this.builder;\n\n        var clone = this.clone();\n        var blankMarker = builder.createMarker('');\n        var pre = undefined,\n            post = undefined;\n\n        if (offset === 0) {\n          pre = blankMarker;\n          post = clone;\n        } else if (offset === ATOM_LENGTH) {\n          pre = clone;\n          post = blankMarker;\n        } else {\n          (0, _mobiledocKitUtilsAssert['default'])('Invalid offset given to Atom#splitAtOffset: \"' + offset + '\"', false);\n        }\n\n        this.markups.forEach(function (markup) {\n          pre.addMarkup(markup);\n          post.addMarkup(markup);\n        });\n        return [pre, post];\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return false;\n      }\n    }, {\n      key: 'length',\n      get: function get() {\n        return ATOM_LENGTH;\n      }\n    }]);\n\n    return Atom;\n  })(_mobiledocKitUtilsLinkedItem['default']);\n\n  (0, _mobiledocKitUtilsMixin['default'])(Atom, _mobiledocKitUtilsMarkuperable['default']);\n\n  exports['default'] = Atom;\n});","define('mobiledoc-kit/models/card-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var CardNode = (function () {\n    function CardNode(editor, card, section, element, options) {\n      _classCallCheck(this, CardNode);\n\n      this.editor = editor;\n      this.card = card;\n      this.section = section;\n      this.element = element;\n      this.options = options;\n\n      this.mode = null;\n\n      this._teardownCallback = null;\n      this._rendered = null;\n    }\n\n    _createClass(CardNode, [{\n      key: 'render',\n      value: function render(mode) {\n        if (this.mode === mode) {\n          return;\n        }\n\n        this.teardown();\n\n        this.mode = mode;\n\n        var method = mode === 'display' ? 'render' : 'edit';\n        method = this.card[method];\n\n        (0, _mobiledocKitUtilsAssert['default'])('Card is missing \"' + method + '\" (tried to render mode: \"' + mode + '\")', !!method);\n        var rendered = method({\n          env: this.env,\n          options: this.options,\n          payload: this.section.payload\n        });\n\n        this._validateAndAppendRenderResult(rendered);\n      }\n    }, {\n      key: 'teardown',\n      value: function teardown() {\n        if (this._teardownCallback) {\n          this._teardownCallback();\n          this._teardownCallback = null;\n        }\n        if (this._rendered) {\n          this.element.removeChild(this._rendered);\n          this._rendered = null;\n        }\n      }\n    }, {\n      key: 'didRender',\n      value: function didRender() {\n        if (this._didRenderCallback) {\n          this._didRenderCallback();\n        }\n      }\n    }, {\n      key: 'display',\n      value: function display() {\n        this.render('display');\n      }\n    }, {\n      key: 'edit',\n      value: function edit() {\n        this.render('edit');\n      }\n    }, {\n      key: 'remove',\n      value: function remove() {\n        var _this = this;\n\n        this.editor.run(function (postEditor) {\n          return postEditor.removeSection(_this.section);\n        });\n      }\n    }, {\n      key: '_validateAndAppendRenderResult',\n      value: function _validateAndAppendRenderResult(rendered) {\n        if (!rendered) {\n          return;\n        }\n\n        var name = this.card.name;\n\n        (0, _mobiledocKitUtilsAssert['default'])('Card \"' + name + '\" must render dom (render value was: \"' + rendered + '\")', !!rendered.nodeType);\n        this.element.appendChild(rendered);\n        this._rendered = rendered;\n        this.didRender();\n      }\n    }, {\n      key: 'env',\n      get: function get() {\n        var _this2 = this;\n\n        return {\n          name: this.card.name,\n          isInEditor: true,\n          onTeardown: function onTeardown(callback) {\n            return _this2._teardownCallback = callback;\n          },\n          didRender: function didRender(callback) {\n            return _this2._didRenderCallback = callback;\n          },\n          edit: function edit() {\n            return _this2.edit();\n          },\n          save: function save(payload) {\n            var transition = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\n            _this2.section.payload = payload;\n\n            _this2.editor._postDidChange();\n            if (transition) {\n              _this2.display();\n            }\n          },\n          cancel: function cancel() {\n            return _this2.display();\n          },\n          remove: function remove() {\n            return _this2.remove();\n          },\n          postModel: this.section\n        };\n      }\n    }]);\n\n    return CardNode;\n  })();\n\n  exports['default'] = CardNode;\n});","define('mobiledoc-kit/models/card', ['exports', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/copy'], function (exports, _mobiledocKitModels_section, _mobiledocKitModelsTypes, _mobiledocKitUtilsCopy) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var CARD_MODES = {\n    DISPLAY: 'display',\n    EDIT: 'edit'\n  };\n\n  exports.CARD_MODES = CARD_MODES;\n  var CARD_LENGTH = 1;\n\n  var DEFAULT_INITIAL_MODE = CARD_MODES.DISPLAY;\n\n  var Card = (function (_Section) {\n    _inherits(Card, _Section);\n\n    function Card(name, payload) {\n      _classCallCheck(this, Card);\n\n      _get(Object.getPrototypeOf(Card.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.CARD_TYPE);\n      this.name = name;\n      this.payload = payload;\n      this.setInitialMode(DEFAULT_INITIAL_MODE);\n      this.isCardSection = true;\n    }\n\n    _createClass(Card, [{\n      key: 'canJoin',\n      value: function canJoin() {\n        return false;\n      }\n    }, {\n      key: 'clone',\n      value: function clone() {\n        var payload = (0, _mobiledocKitUtilsCopy.shallowCopyObject)(this.payload);\n        var card = this.builder.createCardSection(this.name, payload);\n        // If this card is currently rendered, clone the mode it is\n        // currently in as the default mode of the new card.\n        var mode = this._initialMode;\n        if (this.renderNode && this.renderNode.cardNode) {\n          mode = this.renderNode.cardNode.mode;\n        }\n        card.setInitialMode(mode);\n        return card;\n      }\n\n      /**\n       * set the mode that this will be rendered into initially\n       * @private\n       */\n    }, {\n      key: 'setInitialMode',\n      value: function setInitialMode(initialMode) {\n        // TODO validate initialMode\n        this._initialMode = initialMode;\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return false;\n      }\n    }, {\n      key: 'length',\n      get: function get() {\n        return CARD_LENGTH;\n      }\n    }]);\n\n    return Card;\n  })(_mobiledocKitModels_section['default']);\n\n  exports['default'] = Card;\n});","define('mobiledoc-kit/models/image', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var Image = (function (_Section) {\n    _inherits(Image, _Section);\n\n    function Image() {\n      _classCallCheck(this, Image);\n\n      _get(Object.getPrototypeOf(Image.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE);\n      this.src = null;\n    }\n\n    _createClass(Image, [{\n      key: 'canJoin',\n      value: function canJoin() {\n        return false;\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return false;\n      }\n    }, {\n      key: 'length',\n      get: function get() {\n        return 1;\n      }\n    }]);\n\n    return Image;\n  })(_mobiledocKitModels_section['default']);\n\n  exports['default'] = Image;\n});","define('mobiledoc-kit/models/lifecycle-callbacks', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var LifecycleCallbacks = (function () {\n    function LifecycleCallbacks() {\n      var _this = this;\n\n      var queueNames = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n      _classCallCheck(this, LifecycleCallbacks);\n\n      this.callbackQueues = {};\n      this.removalQueues = {};\n\n      queueNames.forEach(function (name) {\n        _this.callbackQueues[name] = [];\n        _this.removalQueues[name] = [];\n      });\n    }\n\n    _createClass(LifecycleCallbacks, [{\n      key: 'runCallbacks',\n      value: function runCallbacks(queueName) {\n        var args = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n        var queue = this._getQueue(queueName);\n        queue.forEach(function (cb) {\n          return cb.apply(undefined, _toConsumableArray(args));\n        });\n\n        var toRemove = this.removalQueues[queueName];\n        toRemove.forEach(function (cb) {\n          var index = queue.indexOf(cb);\n          if (index !== -1) {\n            queue.splice(index, 1);\n          }\n        });\n\n        this.removalQueues[queueName] = [];\n      }\n    }, {\n      key: 'addCallback',\n      value: function addCallback(queueName, callback) {\n        this._getQueue(queueName).push(callback);\n      }\n    }, {\n      key: '_scheduleCallbackForRemoval',\n      value: function _scheduleCallbackForRemoval(queueName, callback) {\n        this.removalQueues[queueName].push(callback);\n      }\n    }, {\n      key: 'addCallbackOnce',\n      value: function addCallbackOnce(queueName, callback) {\n        var queue = this._getQueue(queueName);\n        if (queue.indexOf(callback) === -1) {\n          queue.push(callback);\n          this._scheduleCallbackForRemoval(queueName, callback);\n        }\n      }\n    }, {\n      key: '_getQueue',\n      value: function _getQueue(queueName) {\n        var queue = this.callbackQueues[queueName];\n        (0, _mobiledocKitUtilsAssert['default'])('No queue found for \"' + queueName + '\"', !!queue);\n        return queue;\n      }\n    }]);\n\n    return LifecycleCallbacks;\n  })();\n\n  exports['default'] = LifecycleCallbacks;\n});","define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var VALID_LIST_ITEM_TAGNAMES = ['li'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n  exports.VALID_LIST_ITEM_TAGNAMES = VALID_LIST_ITEM_TAGNAMES;\n\n  var ListItem = (function (_Markerable) {\n    _inherits(ListItem, _Markerable);\n\n    function ListItem(tagName) {\n      var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n      _classCallCheck(this, ListItem);\n\n      _get(Object.getPrototypeOf(ListItem.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, tagName, markers);\n      this.isListItem = true;\n      this.isNested = true;\n    }\n\n    _createClass(ListItem, [{\n      key: 'isValidTagName',\n      value: function isValidTagName(normalizedTagName) {\n        return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_ITEM_TAGNAMES, normalizedTagName);\n      }\n    }, {\n      key: 'splitAtMarker',\n      value: function splitAtMarker(marker) {\n        var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n        // FIXME need to check if we are going to split into two list items\n        // or a list item and a new markup section:\n        var isLastItem = !this.next;\n        var createNewSection = !marker && offset === 0 && isLastItem;\n\n        var beforeSection = this.builder.createListItem();\n        var afterSection = createNewSection ? this.builder.createMarkupSection() : this.builder.createListItem();\n\n        return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n      }\n    }, {\n      key: 'post',\n      get: function get() {\n        return this.section.post;\n      }\n    }]);\n\n    return ListItem;\n  })(_mobiledocKitModels_markerable['default']);\n\n  exports['default'] = ListItem;\n});","define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitModels_attributable, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var VALID_LIST_SECTION_TAGNAMES = ['ul', 'ol'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n  exports.VALID_LIST_SECTION_TAGNAMES = VALID_LIST_SECTION_TAGNAMES;\n  var DEFAULT_TAG_NAME = VALID_LIST_SECTION_TAGNAMES[0];\n\n  exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n\n  var ListSection = (function (_Section) {\n    _inherits(ListSection, _Section);\n\n    function ListSection() {\n      var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n\n      var _this = this;\n\n      var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n      var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n      _classCallCheck(this, ListSection);\n\n      _get(Object.getPrototypeOf(ListSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_SECTION_TYPE);\n      this.tagName = tagName;\n      this.isListSection = true;\n      this.isLeafSection = false;\n\n      (0, _mobiledocKitModels_attributable.attributable)(this);\n      (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2);\n\n        var k = _ref2[0];\n        var v = _ref2[1];\n        return _this.setAttribute(k, v);\n      });\n\n      this.items = new _mobiledocKitUtilsLinkedList['default']({\n        adoptItem: function adoptItem(i) {\n          (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem);\n          i.section = i.parent = _this;\n        },\n        freeItem: function freeItem(i) {\n          return i.section = i.parent = null;\n        }\n      });\n      this.sections = this.items;\n\n      items.forEach(function (i) {\n        return _this.items.append(i);\n      });\n    }\n\n    _createClass(ListSection, [{\n      key: 'canJoin',\n      value: function canJoin() {\n        return false;\n      }\n    }, {\n      key: 'isValidTagName',\n      value: function isValidTagName(normalizedTagName) {\n        return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_SECTION_TAGNAMES, normalizedTagName);\n      }\n    }, {\n      key: 'headPosition',\n      value: function headPosition() {\n        return this.items.head.headPosition();\n      }\n    }, {\n      key: 'tailPosition',\n      value: function tailPosition() {\n        return this.items.tail.tailPosition();\n      }\n    }, {\n      key: 'clone',\n      value: function clone() {\n        var newSection = this.builder.createListSection(this.tagName);\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(this.items, function (i) {\n          return newSection.items.append(i.clone());\n        });\n        return newSection;\n      }\n\n      /**\n       * Mutates this list\n       * @param {ListSection|Markerable}\n       * @return null\n       */\n    }, {\n      key: 'join',\n      value: function join(other) {\n        var _this2 = this;\n\n        if (other.isListSection) {\n          other.items.forEach(function (i) {\n            return _this2.join(i);\n          });\n        } else if (other.isMarkerable) {\n          var item = this.builder.createListItem();\n          item.join(other);\n          this.items.append(item);\n        }\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return this.items.isEmpty;\n      }\n    }]);\n\n    return ListSection;\n  })(_mobiledocKitModels_section['default']);\n\n  exports['default'] = ListSection;\n});","define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsArrayUtils) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  // Unicode uses a pair of \"surrogate\" characters\" (a high- and low-surrogate)\n  // to encode characters outside the basic multilingual plane (like emoji and\n  // some languages).\n  // These values are the unicode code points for the start and end of the\n  // high- and low-surrogate characters.\n  // See \"high surrogate\" and \"low surrogate\" on\n  // https://en.wikipedia.org/wiki/Unicode_block\n  var HIGH_SURROGATE_RANGE = [0xD800, 0xDBFF];\n  exports.HIGH_SURROGATE_RANGE = HIGH_SURROGATE_RANGE;\n  var LOW_SURROGATE_RANGE = [0xDC00, 0xDFFF];\n\n  exports.LOW_SURROGATE_RANGE = LOW_SURROGATE_RANGE;\n  var Marker = (function (_LinkedItem) {\n    _inherits(Marker, _LinkedItem);\n\n    function Marker() {\n      var _this = this;\n\n      var value = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n      var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n      _classCallCheck(this, Marker);\n\n      _get(Object.getPrototypeOf(Marker.prototype), 'constructor', this).call(this);\n      this.value = value;\n      (0, _mobiledocKitUtilsAssert['default'])('Marker must have value', value !== undefined && value !== null);\n      this.markups = [];\n      this.type = _mobiledocKitModelsTypes.MARKER_TYPE;\n      this.isMarker = true;\n      this.isAtom = false;\n      markups.forEach(function (m) {\n        return _this.addMarkup(m);\n      });\n    }\n\n    _createClass(Marker, [{\n      key: 'clone',\n      value: function clone() {\n        var clonedMarkups = this.markups.slice();\n        return this.builder.createMarker(this.value, clonedMarkups);\n      }\n    }, {\n      key: 'charAt',\n      value: function charAt(offset) {\n        return this.value.slice(offset, offset + 1);\n      }\n\n      /**\n       * A marker's text is equal to its value.\n       * Compare with an Atom which distinguishes between text and value\n       */\n    }, {\n      key: 'deleteValueAtOffset',\n\n      // delete the character at this offset,\n      // update the value with the new value\n      value: function deleteValueAtOffset(offset) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot delete value at offset outside bounds', offset >= 0 && offset <= this.length);\n\n        var width = 1;\n        var code = this.value.charCodeAt(offset);\n        if (code >= HIGH_SURROGATE_RANGE[0] && code <= HIGH_SURROGATE_RANGE[1]) {\n          width = 2;\n        } else if (code >= LOW_SURROGATE_RANGE[0] && code <= LOW_SURROGATE_RANGE[1]) {\n          width = 2;\n          offset = offset - 1;\n        }\n\n        var left = this.value.slice(0, offset);\n        var right = this.value.slice(offset + width);\n\n        this.value = left + right;\n\n        return width;\n      }\n    }, {\n      key: 'canJoin',\n      value: function canJoin(other) {\n        return other && other.isMarker && (0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(this.markups, other.markups);\n      }\n    }, {\n      key: 'textUntil',\n      value: function textUntil(offset) {\n        return this.value.slice(0, offset);\n      }\n    }, {\n      key: 'split',\n      value: function split() {\n        var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n        var endOffset = arguments.length <= 1 || arguments[1] === undefined ? this.length : arguments[1];\n\n        var markers = [this.builder.createMarker(this.value.substring(0, offset)), this.builder.createMarker(this.value.substring(offset, endOffset)), this.builder.createMarker(this.value.substring(endOffset))];\n\n        this.markups.forEach(function (mu) {\n          return markers.forEach(function (m) {\n            return m.addMarkup(mu);\n          });\n        });\n        return markers;\n      }\n\n      /**\n       * @return {Array} 2 markers either or both of which could be blank\n       */\n    }, {\n      key: 'splitAtOffset',\n      value: function splitAtOffset(offset) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n        var value = this.value;\n        var builder = this.builder;\n\n        var pre = builder.createMarker(value.substring(0, offset));\n        var post = builder.createMarker(value.substring(offset));\n\n        this.markups.forEach(function (markup) {\n          pre.addMarkup(markup);\n          post.addMarkup(markup);\n        });\n\n        return [pre, post];\n      }\n    }, {\n      key: 'isEmpty',\n      get: function get() {\n        return this.isBlank;\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return this.length === 0;\n      }\n    }, {\n      key: 'text',\n      get: function get() {\n        return this.value;\n      }\n    }, {\n      key: 'length',\n      get: function get() {\n        return this.value.length;\n      }\n    }]);\n\n    return Marker;\n  })(_mobiledocKitUtilsLinkedItem['default']);\n\n  (0, _mobiledocKitUtilsMixin['default'])(Marker, _mobiledocKitUtilsMarkuperable['default']);\n\n  exports['default'] = Marker;\n});","define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModels_attributable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsObjectUtils) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  // valid values of `tagName` for a MarkupSection\n  var VALID_MARKUP_SECTION_TAGNAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n  exports.VALID_MARKUP_SECTION_TAGNAMES = VALID_MARKUP_SECTION_TAGNAMES;\n  // valid element names for a MarkupSection. A MarkupSection with a tagName\n  // not in this will be rendered as a div with a className matching the\n  // tagName\n  var MARKUP_SECTION_ELEMENT_NAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n  exports.MARKUP_SECTION_ELEMENT_NAMES = MARKUP_SECTION_ELEMENT_NAMES;\n  var DEFAULT_TAG_NAME = VALID_MARKUP_SECTION_TAGNAMES[8];\n\n  exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n  var MarkupSection = (function (_Markerable) {\n    _inherits(MarkupSection, _Markerable);\n\n    function MarkupSection() {\n      var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n\n      var _this = this;\n\n      var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n      var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n      _classCallCheck(this, MarkupSection);\n\n      _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers);\n\n      (0, _mobiledocKitModels_attributable.attributable)(this);\n      (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2);\n\n        var k = _ref2[0];\n        var v = _ref2[1];\n        return _this.setAttribute(k, v);\n      });\n\n      this.isMarkupSection = true;\n    }\n\n    _createClass(MarkupSection, [{\n      key: 'isValidTagName',\n      value: function isValidTagName(normalizedTagName) {\n        return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_MARKUP_SECTION_TAGNAMES, normalizedTagName);\n      }\n    }, {\n      key: 'splitAtMarker',\n      value: function splitAtMarker(marker) {\n        var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n        var beforeSection = this.builder.createMarkupSection(this.tagName, [], false, this.attributes);\n        var afterSection = this.builder.createMarkupSection();\n\n        return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n      }\n    }]);\n\n    return MarkupSection;\n  })(_mobiledocKitModels_markerable['default']);\n\n  exports['default'] = MarkupSection;\n});","define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var VALID_MARKUP_TAGNAMES = ['a', 'b', 'code', 'em', 'i', 's', // strikethrough\n  'strong', 'sub', // subscript\n  'sup', // superscript\n  'u'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n  exports.VALID_MARKUP_TAGNAMES = VALID_MARKUP_TAGNAMES;\n  var VALID_ATTRIBUTES = ['href', 'rel'];\n\n  exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n  /**\n   * A Markup is similar with an inline HTML tag that might be added to\n   * text to modify its meaning and/or display. Examples of types of markup\n   * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links).\n   * @property {String} tagName\n   */\n\n  var Markup = (function () {\n    /*\n     * @param {Object} attributes key-values\n     */\n\n    function Markup(tagName) {\n      var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n      _classCallCheck(this, Markup);\n\n      this.tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n      (0, _mobiledocKitUtilsAssert['default'])('Must use attributes object param (not array) for Markup', !Array.isArray(attributes));\n\n      this.attributes = (0, _mobiledocKitUtilsArrayUtils.filterObject)(attributes, VALID_ATTRIBUTES);\n      this.type = _mobiledocKitModelsTypes.MARKUP_TYPE;\n\n      (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1);\n    }\n\n    /**\n     * Whether text in the forward direction of the cursor (i.e. to the right in ltr text)\n     * should be considered to have this markup applied to it.\n     * @private\n     */\n\n    _createClass(Markup, [{\n      key: 'isForwardInclusive',\n      value: function isForwardInclusive() {\n        return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(\"a\") ? false : true;\n      }\n    }, {\n      key: 'isBackwardInclusive',\n      value: function isBackwardInclusive() {\n        return false;\n      }\n    }, {\n      key: 'hasTag',\n      value: function hasTag(tagName) {\n        return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n      }\n\n      /**\n       * Returns the attribute value\n       * @param {String} name, e.g. \"href\"\n       */\n    }, {\n      key: 'getAttribute',\n      value: function getAttribute(name) {\n        return this.attributes[name];\n      }\n    }], [{\n      key: 'isValidElement',\n      value: function isValidElement(element) {\n        var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n        return VALID_MARKUP_TAGNAMES.indexOf(tagName) !== -1;\n      }\n    }]);\n\n    return Markup;\n  })();\n\n  exports['default'] = Markup;\n});","define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/models/atom', 'mobiledoc-kit/models/post', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/image', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsAtom, _mobiledocKitModelsPost, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsImage, _mobiledocKitModelsMarker, _mobiledocKitModelsMarkup, _mobiledocKitModelsCard, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function cacheKey(tagName, attributes) {\n    return (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName) + '-' + (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(attributes).join('-');\n  }\n\n  function addMarkupToCache(cache, markup) {\n    cache[cacheKey(markup.tagName, markup.attributes)] = markup;\n  }\n\n  function findMarkupInCache(cache, tagName, attributes) {\n    var key = cacheKey(tagName, attributes);\n    return cache[key];\n  }\n\n  /**\n   * The PostNodeBuilder is used to create new {@link Post} primitives, such\n   * as a MarkupSection, a CardSection, a Markup, etc. Every instance of an\n   * {@link Editor} has its own builder instance. The builder can be used\n   * inside an {@link Editor#run} callback to programmatically create new\n   * Post primitives to insert into the document.\n   * A PostNodeBuilder should be read from the Editor, *not* instantiated on its own.\n   */\n\n  var PostNodeBuilder = (function () {\n    /**\n     * @private\n     */\n\n    function PostNodeBuilder() {\n      _classCallCheck(this, PostNodeBuilder);\n\n      this.markupCache = {};\n    }\n\n    /**\n     * @return {Post} A new, blank post\n     */\n\n    _createClass(PostNodeBuilder, [{\n      key: 'createPost',\n      value: function createPost() {\n        var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n        var post = new _mobiledocKitModelsPost['default']();\n        post.builder = this;\n\n        sections.forEach(function (s) {\n          return post.sections.append(s);\n        });\n\n        return post;\n      }\n    }, {\n      key: 'createMarkerableSection',\n      value: function createMarkerableSection(type, tagName) {\n        var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n        switch (type) {\n          case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n            return this.createListItem(markers);\n          case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n            return this.createMarkupSection(tagName, markers);\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Cannot create markerable section of type ' + type, false);\n        }\n      }\n\n      /**\n       * @param {tagName} [tagName='P']\n       * @param {Marker[]} [markers=[]]\n       * @return {MarkupSection}\n       */\n    }, {\n      key: 'createMarkupSection',\n      value: function createMarkupSection() {\n        var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0];\n        var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n        var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n        var attributes = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];\n\n        tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n        var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers, attributes);\n        if (isGenerated) {\n          section.isGenerated = true;\n        }\n        section.builder = this;\n        return section;\n      }\n    }, {\n      key: 'createListSection',\n      value: function createListSection() {\n        var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0];\n        var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n        var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n        tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n        var section = new _mobiledocKitModelsListSection['default'](tagName, items, attributes);\n        section.builder = this;\n        return section;\n      }\n    }, {\n      key: 'createListItem',\n      value: function createListItem() {\n        var markers = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n        var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('li');\n        var item = new _mobiledocKitModelsListItem['default'](tagName, markers);\n        item.builder = this;\n        return item;\n      }\n    }, {\n      key: 'createImageSection',\n      value: function createImageSection(url) {\n        var section = new _mobiledocKitModelsImage['default']();\n        if (url) {\n          section.src = url;\n        }\n        return section;\n      }\n\n      /**\n       * @param {String} name\n       * @param {Object} [payload={}]\n       * @return {CardSection}\n       */\n    }, {\n      key: 'createCardSection',\n      value: function createCardSection(name) {\n        var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        var card = new _mobiledocKitModelsCard['default'](name, payload);\n        card.builder = this;\n        return card;\n      }\n\n      /**\n       * @param {String} value\n       * @param {Markup[]} [markups=[]]\n       * @return {Marker}\n       */\n    }, {\n      key: 'createMarker',\n      value: function createMarker(value) {\n        var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n        var marker = new _mobiledocKitModelsMarker['default'](value, markups);\n        marker.builder = this;\n        return marker;\n      }\n\n      /**\n       * @param {String} name\n       * @param {String} [value='']\n       * @param {Object} [payload={}]\n       * @param {Markup[]} [markups=[]]\n       * @return {Atom}\n       */\n    }, {\n      key: 'createAtom',\n      value: function createAtom(name) {\n        var value = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n        var payload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n        var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n        var atom = new _mobiledocKitModelsAtom['default'](name, value, payload, markups);\n        atom.builder = this;\n        return atom;\n      }\n\n      /**\n       * @param {String} tagName\n       * @param {Object} attributes Key-value pairs of attributes for the markup\n       * @return {Markup}\n       */\n    }, {\n      key: 'createMarkup',\n      value: function createMarkup(tagName) {\n        var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n        var markup = findMarkupInCache(this.markupCache, tagName, attributes);\n        if (!markup) {\n          markup = new _mobiledocKitModelsMarkup['default'](tagName, attributes);\n          markup.builder = this;\n          addMarkupToCache(this.markupCache, markup);\n        }\n\n        return markup;\n      }\n    }]);\n\n    return PostNodeBuilder;\n  })();\n\n  exports['default'] = PostNodeBuilder;\n});","define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /**\n   * The Post is an in-memory representation of an editor's document.\n   * An editor always has a single post. The post is organized into a list of\n   * sections. Each section may be markerable (contains \"markers\", aka editable\n   * text) or non-markerable (e.g., a card).\n   * When persisting a post, it must first be serialized (loss-lessly) into\n   * mobiledoc using {@link Editor#serialize}.\n   */\n\n  var Post = (function () {\n    /**\n     * @private\n     */\n\n    function Post() {\n      var _this = this;\n\n      _classCallCheck(this, Post);\n\n      this.type = _mobiledocKitModelsTypes.POST_TYPE;\n      this.sections = new _mobiledocKitUtilsLinkedList['default']({\n        adoptItem: function adoptItem(s) {\n          return s.post = s.parent = _this;\n        },\n        freeItem: function freeItem(s) {\n          return s.post = s.parent = null;\n        }\n      });\n    }\n\n    /**\n     * @return {Position} The position at the start of the post (will be a {@link BlankPosition}\n     * if the post is blank)\n     * @public\n     */\n\n    _createClass(Post, [{\n      key: 'headPosition',\n      value: function headPosition() {\n        if (this.isBlank) {\n          return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n        } else {\n          return this.sections.head.headPosition();\n        }\n      }\n\n      /**\n       * @return {Position} The position at the end of the post (will be a {@link BlankPosition}\n       * if the post is blank)\n       * @public\n       */\n    }, {\n      key: 'tailPosition',\n      value: function tailPosition() {\n        if (this.isBlank) {\n          return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n        } else {\n          return this.sections.tail.tailPosition();\n        }\n      }\n\n      /**\n       * @return {Range} A range encompassing the entire post\n       * @public\n       */\n    }, {\n      key: 'toRange',\n      value: function toRange() {\n        return this.headPosition().toRange(this.tailPosition());\n      }\n    }, {\n      key: 'markersContainedByRange',\n\n      /**\n       * @param {Range} range\n       * @return {Array} markers that are completely contained by the range\n       */\n      value: function markersContainedByRange(range) {\n        var markers = [];\n\n        this.walkMarkerableSections(range, function (section) {\n          section._markersInRange(range.trimTo(section), function (m, _ref) {\n            var isContained = _ref.isContained;\n            if (isContained) {\n              markers.push(m);\n            }\n          });\n        });\n\n        return markers;\n      }\n    }, {\n      key: 'markupsInRange',\n      value: function markupsInRange(range) {\n        var markups = new _mobiledocKitUtilsSet['default']();\n\n        if (range.isCollapsed) {\n          var pos = range.head;\n          if (pos.isMarkerable) {\n            var back = pos.markerIn(-1);\n            var forward = pos.markerIn(1);\n\n            if (back && forward && back === forward) {\n              back.markups.forEach(function (m) {\n                return markups.add(m);\n              });\n            } else {\n              (back && back.markups || []).forEach(function (m) {\n                if (m.isForwardInclusive()) {\n                  markups.add(m);\n                }\n              });\n              (forward && forward.markups || []).forEach(function (m) {\n                if (m.isBackwardInclusive()) {\n                  markups.add(m);\n                }\n              });\n            }\n          }\n        } else {\n          this.walkMarkerableSections(range, function (section) {\n            (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markupsInRange(range.trimTo(section)), function (m) {\n              return markups.add(m);\n            });\n          });\n        }\n\n        return markups.toArray();\n      }\n    }, {\n      key: 'walkAllLeafSections',\n      value: function walkAllLeafSections(callback) {\n        var range = this.headPosition().toRange(this.tailPosition());\n        return this.walkLeafSections(range, callback);\n      }\n    }, {\n      key: 'walkLeafSections',\n      value: function walkLeafSections(range, callback) {\n        var head = range.head;\n        var tail = range.tail;\n\n        var index = 0;\n        var nextSection = undefined,\n            shouldStop = undefined;\n        var currentSection = head.section;\n\n        while (currentSection) {\n          nextSection = this._nextLeafSection(currentSection);\n          shouldStop = currentSection === tail.section;\n\n          callback(currentSection, index);\n          index++;\n\n          if (shouldStop) {\n            break;\n          } else {\n            currentSection = nextSection;\n          }\n        }\n      }\n    }, {\n      key: 'walkMarkerableSections',\n      value: function walkMarkerableSections(range, callback) {\n        this.walkLeafSections(range, function (section) {\n          if (section.isMarkerable) {\n            callback(section);\n          }\n        });\n      }\n\n      // return the next section that has markers after this one,\n      // possibly skipping non-markerable sections\n    }, {\n      key: '_nextLeafSection',\n      value: function _nextLeafSection(section) {\n        if (!section) {\n          return null;\n        }\n\n        var next = section.next;\n        if (next) {\n          if (next.isLeafSection) {\n            return next;\n          } else if (next.items) {\n            return next.items.head;\n          } else {\n            (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false);\n          }\n        } else if (section.isNested) {\n          // if there is no section after this, but this section is a child\n          // (e.g. a ListItem inside a ListSection), check for a markerable\n          // section after its parent\n          return this._nextLeafSection(section.parent);\n        }\n      }\n\n      /**\n       * @param {Range} range\n       * @return {Post} A new post, constrained to {range}\n       */\n    }, {\n      key: 'trimTo',\n      value: function trimTo(range) {\n        var post = this.builder.createPost();\n        var builder = this.builder;\n        var head = range.head;\n        var tail = range.tail;\n\n        var tailNotSelected = tail.offset === 0 && head.section !== tail.section;\n\n        var sectionParent = post,\n            listParent = null;\n        this.walkLeafSections(range, function (section) {\n          var newSection = undefined;\n          if (section.isMarkerable) {\n            if (section.isListItem) {\n              if (listParent) {\n                sectionParent = null;\n              } else {\n                listParent = builder.createListSection(section.parent.tagName);\n                post.sections.append(listParent);\n                sectionParent = null;\n              }\n              newSection = builder.createListItem();\n              listParent.items.append(newSection);\n            } else {\n              listParent = null;\n              sectionParent = post;\n              var tagName = tailNotSelected && tail.section === section ? 'p' : section.tagName;\n              newSection = builder.createMarkupSection(tagName);\n            }\n\n            var currentRange = range.trimTo(section);\n            (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markersFor(currentRange.headSectionOffset, currentRange.tailSectionOffset), function (m) {\n              return newSection.markers.append(m);\n            });\n          } else {\n            newSection = tailNotSelected && tail.section === section ? builder.createMarkupSection('p') : section.clone();\n\n            sectionParent = post;\n          }\n          if (sectionParent) {\n            sectionParent.sections.append(newSection);\n          }\n        });\n        return post;\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return this.sections.isEmpty;\n      }\n\n      /**\n       * If the post has no sections, or only has one, blank section, then it does\n       * not have content and this method returns false. Otherwise it is true.\n       * @return {Boolean}\n       * @public\n       */\n    }, {\n      key: 'hasContent',\n      get: function get() {\n        if (this.sections.length > 1 || this.sections.length === 1 && !this.sections.head.isBlank) {\n          return true;\n        } else {\n          return false;\n        }\n      }\n    }]);\n\n    return Post;\n  })();\n\n  exports['default'] = Post;\n});","define('mobiledoc-kit/models/render-node', ['exports', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var RenderNode = (function (_LinkedItem) {\n    _inherits(RenderNode, _LinkedItem);\n\n    function RenderNode(postNode, renderTree) {\n      _classCallCheck(this, RenderNode);\n\n      _get(Object.getPrototypeOf(RenderNode.prototype), 'constructor', this).call(this);\n      this.parent = null;\n      this.isDirty = true;\n      this.isRemoved = false;\n      this.postNode = postNode;\n      this._childNodes = null;\n      this._element = null;\n      this._cursorElement = null; // blank render nodes need a cursor element\n      this.renderTree = renderTree;\n\n      // RenderNodes for Markers keep track of their markupElement\n      this.markupElement = null;\n\n      // RenderNodes for Atoms use these properties\n      this.headTextNode = null;\n      this.tailTextNode = null;\n      this.atomNode = null;\n\n      // RenderNodes for cards use this property\n      this.cardNode = null;\n    }\n\n    _createClass(RenderNode, [{\n      key: 'isAttached',\n      value: function isAttached() {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot check if a renderNode is attached without an element.', !!this.element);\n        return (0, _mobiledocKitUtilsDomUtils.containsNode)(this.renderTree.rootElement, this.element);\n      }\n    }, {\n      key: 'scheduleForRemoval',\n      value: function scheduleForRemoval() {\n        this.isRemoved = true;\n        if (this.parent) {\n          this.parent.markDirty();\n        }\n      }\n    }, {\n      key: 'markDirty',\n      value: function markDirty() {\n        this.isDirty = true;\n        if (this.parent) {\n          this.parent.markDirty();\n        }\n      }\n    }, {\n      key: 'markClean',\n      value: function markClean() {\n        this.isDirty = false;\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this.element = null;\n        this.parent = null;\n        this.postNode = null;\n        this.renderTree = null;\n      }\n    }, {\n      key: 'reparsesMutationOfChildNode',\n      value: function reparsesMutationOfChildNode(node) {\n        if (this.postNode.isCardSection) {\n          return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.cardNode.element, node);\n        } else if (this.postNode.isAtom) {\n          return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.atomNode.element, node);\n        }\n        return true;\n      }\n    }, {\n      key: 'childNodes',\n      get: function get() {\n        var _this = this;\n\n        if (!this._childNodes) {\n          this._childNodes = new _mobiledocKitUtilsLinkedList['default']({\n            adoptItem: function adoptItem(item) {\n              return item.parent = _this;\n            },\n            freeItem: function freeItem(item) {\n              return item.destroy();\n            }\n          });\n        }\n        return this._childNodes;\n      }\n    }, {\n      key: 'isRendered',\n      get: function get() {\n        return !!this.element;\n      }\n    }, {\n      key: 'element',\n      set: function set(element) {\n        var currentElement = this._element;\n        this._element = element;\n\n        if (currentElement) {\n          this.renderTree.removeElementRenderNode(currentElement);\n        }\n\n        if (element) {\n          this.renderTree.setElementRenderNode(element, this);\n        }\n      },\n      get: function get() {\n        return this._element;\n      }\n    }, {\n      key: 'cursorElement',\n      set: function set(cursorElement) {\n        this._cursorElement = cursorElement;\n      },\n      get: function get() {\n        return this._cursorElement || this.element;\n      }\n    }]);\n\n    return RenderNode;\n  })(_mobiledocKitUtilsLinkedItem['default']);\n\n  exports['default'] = RenderNode;\n});","define('mobiledoc-kit/models/render-tree', ['exports', 'mobiledoc-kit/models/render-node', 'mobiledoc-kit/utils/element-map'], function (exports, _mobiledocKitModelsRenderNode, _mobiledocKitUtilsElementMap) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var RenderTree = (function () {\n    function RenderTree(rootPostNode) {\n      _classCallCheck(this, RenderTree);\n\n      this._rootNode = this.buildRenderNode(rootPostNode);\n      this._elements = new _mobiledocKitUtilsElementMap['default']();\n    }\n\n    /*\n     * @return {RenderNode} The root render node in this tree\n     */\n\n    _createClass(RenderTree, [{\n      key: 'getElementRenderNode',\n\n      /*\n       * @param {DOMNode} element\n       * @return {RenderNode} The renderNode for this element, if any\n       */\n      value: function getElementRenderNode(element) {\n        return this._elements.get(element);\n      }\n    }, {\n      key: 'setElementRenderNode',\n      value: function setElementRenderNode(element, renderNode) {\n        this._elements.set(element, renderNode);\n      }\n    }, {\n      key: 'removeElementRenderNode',\n      value: function removeElementRenderNode(element) {\n        this._elements.remove(element);\n      }\n\n      /**\n       * @param {DOMNode} element\n       * Walk up from the dom element until we find a renderNode element\n       */\n    }, {\n      key: 'findRenderNodeFromElement',\n      value: function findRenderNodeFromElement(element) {\n        var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {\n          return true;\n        } : arguments[1];\n\n        var renderNode = undefined;\n        while (element) {\n          renderNode = this.getElementRenderNode(element);\n          if (renderNode && conditionFn(renderNode)) {\n            return renderNode;\n          }\n\n          // continue loop\n          element = element.parentNode;\n\n          // stop if we are at the root element\n          if (element === this.rootElement) {\n            if (conditionFn(this.rootNode)) {\n              return this.rootNode;\n            } else {\n              return;\n            }\n          }\n        }\n      }\n    }, {\n      key: 'buildRenderNode',\n      value: function buildRenderNode(postNode) {\n        var renderNode = new _mobiledocKitModelsRenderNode['default'](postNode, this);\n        postNode.renderNode = renderNode;\n        return renderNode;\n      }\n    }, {\n      key: 'rootNode',\n      get: function get() {\n        return this._rootNode;\n      }\n\n      /**\n       * @return {Boolean}\n       */\n    }, {\n      key: 'isDirty',\n      get: function get() {\n        return this.rootNode && this.rootNode.isDirty;\n      }\n\n      /*\n       * @return {DOMNode} The root DOM element in this tree\n       */\n    }, {\n      key: 'rootElement',\n      get: function get() {\n        return this.rootNode.element;\n      }\n    }]);\n\n    return RenderTree;\n  })();\n\n  exports['default'] = RenderTree;\n});","define('mobiledoc-kit/models/types', ['exports'], function (exports) {\n  'use strict';\n\n  var MARKUP_SECTION_TYPE = 'markup-section';\n  exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n  var LIST_SECTION_TYPE = 'list-section';\n  exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n  var MARKUP_TYPE = 'markup';\n  exports.MARKUP_TYPE = MARKUP_TYPE;\n  var MARKER_TYPE = 'marker';\n  exports.MARKER_TYPE = MARKER_TYPE;\n  var POST_TYPE = 'post';\n  exports.POST_TYPE = POST_TYPE;\n  var LIST_ITEM_TYPE = 'list-item';\n  exports.LIST_ITEM_TYPE = LIST_ITEM_TYPE;\n  var CARD_TYPE = 'card-section';\n  exports.CARD_TYPE = CARD_TYPE;\n  var IMAGE_SECTION_TYPE = 'image-section';\n  exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n  var ATOM_TYPE = 'atom';\n  exports.ATOM_TYPE = ATOM_TYPE;\n});","define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/parsers/section', 'mobiledoc-kit/models/markup'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCharacters, _mobiledocKitParsersSection, _mobiledocKitModelsMarkup) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  exports.transformHTMLText = transformHTMLText;\n  exports.trimSectionText = trimSectionText;\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var GOOGLE_DOCS_CONTAINER_ID_REGEX = /^docs\\-internal\\-guid/;\n\n  var NO_BREAK_SPACE_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.NO_BREAK_SPACE, 'g');\n  var TAB_CHARACTER_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.TAB_CHARACTER, 'g');\n\n  function transformHTMLText(textContent) {\n    var text = textContent;\n    text = text.replace(NO_BREAK_SPACE_REGEX, ' ');\n    text = text.replace(TAB_CHARACTER_REGEX, _mobiledocKitUtilsCharacters.TAB);\n    return text;\n  }\n\n  function trimSectionText(section) {\n    if (section.isMarkerable && section.markers.length) {\n      var _section$markers = section.markers;\n      var head = _section$markers.head;\n      var tail = _section$markers.tail;\n\n      head.value = head.value.replace(/^\\s+/, '');\n      tail.value = tail.value.replace(/\\s+$/, '');\n    }\n  }\n\n  function isGoogleDocsContainer(element) {\n    return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id);\n  }\n\n  function detectRootElement(element) {\n    var childNodes = element.childNodes || [];\n    var googleDocsContainer = (0, _mobiledocKitUtilsArrayUtils.detect)(childNodes, isGoogleDocsContainer);\n\n    if (googleDocsContainer) {\n      return googleDocsContainer;\n    } else {\n      return element;\n    }\n  }\n\n  var TAG_REMAPPING = {\n    'b': 'strong',\n    'i': 'em'\n  };\n\n  function remapTagName(tagName) {\n    var normalized = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n    var remapped = TAG_REMAPPING[normalized];\n    return remapped || normalized;\n  }\n\n  function trim(str) {\n    return str.replace(/^\\s+/, '').replace(/\\s+$/, '');\n  }\n\n  function walkMarkerableNodes(parent, callback) {\n    var currentNode = parent;\n\n    if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(currentNode) || (0, _mobiledocKitUtilsDomUtils.isElementNode)(currentNode) && currentNode.classList.contains(_mobiledocKitRenderersEditorDom.ATOM_CLASS_NAME)) {\n      callback(currentNode);\n    } else {\n      currentNode = currentNode.firstChild;\n      while (currentNode) {\n        walkMarkerableNodes(currentNode, callback);\n        currentNode = currentNode.nextSibling;\n      }\n    }\n  }\n\n  /**\n   * Parses DOM element -> Post\n   * @private\n   */\n\n  var DOMParser = (function () {\n    function DOMParser(builder) {\n      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n      _classCallCheck(this, DOMParser);\n\n      this.builder = builder;\n      this.sectionParser = new _mobiledocKitParsersSection['default'](this.builder, options);\n    }\n\n    _createClass(DOMParser, [{\n      key: 'parse',\n      value: function parse(element) {\n        var _this = this;\n\n        var post = this.builder.createPost();\n        var rootElement = detectRootElement(element);\n\n        this._eachChildNode(rootElement, function (child) {\n          var sections = _this.parseSections(child);\n          _this.appendSections(post, sections);\n        });\n\n        // trim leading/trailing whitespace of markerable sections to avoid\n        // unnessary whitespace from indented HTML input\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n          return trimSectionText(section);\n        });\n\n        return post;\n      }\n    }, {\n      key: 'appendSections',\n      value: function appendSections(post, sections) {\n        var _this2 = this;\n\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(sections, function (section) {\n          return _this2.appendSection(post, section);\n        });\n      }\n    }, {\n      key: 'appendSection',\n      value: function appendSection(post, section) {\n        if (section.isBlank || section.isMarkerable && trim(section.text) === \"\" && !(0, _mobiledocKitUtilsArrayUtils.any)(section.markers, function (marker) {\n          return marker.isAtom;\n        })) {\n          return;\n        }\n\n        var lastSection = post.sections.tail;\n        if (lastSection && lastSection._inferredTagName && section._inferredTagName && lastSection.tagName === section.tagName) {\n          lastSection.join(section);\n        } else {\n          post.sections.append(section);\n        }\n      }\n    }, {\n      key: '_eachChildNode',\n      value: function _eachChildNode(element, callback) {\n        var nodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n          return callback(node);\n        });\n      }\n    }, {\n      key: 'parseSections',\n      value: function parseSections(element) {\n        return this.sectionParser.parse(element);\n      }\n\n      // walk up from the textNode until the rootNode, converting each\n      // parentNode into a markup\n    }, {\n      key: 'collectMarkups',\n      value: function collectMarkups(textNode, rootNode) {\n        var markups = [];\n        var currentNode = textNode.parentNode;\n        while (currentNode && currentNode !== rootNode) {\n          var markup = this.markupFromNode(currentNode);\n          if (markup) {\n            markups.push(markup);\n          }\n\n          currentNode = currentNode.parentNode;\n        }\n        return markups;\n      }\n\n      // Turn an element node into a markup\n    }, {\n      key: 'markupFromNode',\n      value: function markupFromNode(node) {\n        if (_mobiledocKitModelsMarkup['default'].isValidElement(node)) {\n          var tagName = remapTagName(node.tagName);\n          var attributes = (0, _mobiledocKitUtilsDomUtils.getAttributes)(node);\n          return this.builder.createMarkup(tagName, attributes);\n        }\n      }\n\n      // FIXME should move to the section parser?\n      // FIXME the `collectMarkups` logic could simplify the section parser?\n    }, {\n      key: 'reparseSection',\n      value: function reparseSection(section, renderTree) {\n        switch (section.type) {\n          case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n            return this.reparseListSection(section, renderTree);\n          case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n            return this.reparseListItem(section, renderTree);\n          case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n            return this.reparseMarkupSection(section, renderTree);\n          default:\n            return; // can only parse the above types\n        }\n      }\n    }, {\n      key: 'reparseMarkupSection',\n      value: function reparseMarkupSection(section, renderTree) {\n        return this._reparseSectionContainingMarkers(section, renderTree);\n      }\n    }, {\n      key: 'reparseListItem',\n      value: function reparseListItem(listItem, renderTree) {\n        return this._reparseSectionContainingMarkers(listItem, renderTree);\n      }\n    }, {\n      key: 'reparseListSection',\n      value: function reparseListSection(listSection, renderTree) {\n        var _this3 = this;\n\n        listSection.items.forEach(function (li) {\n          return _this3.reparseListItem(li, renderTree);\n        });\n      }\n    }, {\n      key: '_reparseSectionContainingMarkers',\n      value: function _reparseSectionContainingMarkers(section, renderTree) {\n        var _this4 = this;\n\n        var element = section.renderNode.element;\n        var seenRenderNodes = [];\n        var previousMarker = undefined;\n\n        walkMarkerableNodes(element, function (node) {\n          var marker = undefined;\n          var renderNode = renderTree.getElementRenderNode(node);\n          if (renderNode) {\n            if (renderNode.postNode.isMarker) {\n              var text = transformHTMLText(node.textContent);\n              var markups = _this4.collectMarkups(node, element);\n              if (text.length) {\n                marker = renderNode.postNode;\n                marker.value = text;\n                marker.markups = markups;\n              } else {\n                renderNode.scheduleForRemoval();\n              }\n            } else if (renderNode.postNode.isAtom) {\n              var _renderNode = renderNode;\n              var headTextNode = _renderNode.headTextNode;\n              var tailTextNode = _renderNode.tailTextNode;\n\n              if (headTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n                var value = headTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n                headTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n                if (previousMarker && previousMarker.isMarker) {\n                  previousMarker.value += value;\n                  if (previousMarker.renderNode) {\n                    previousMarker.renderNode.markDirty();\n                  }\n                } else {\n                  var postNode = renderNode.postNode;\n                  var newMarkups = postNode.markups.slice();\n                  var newPreviousMarker = _this4.builder.createMarker(value, newMarkups);\n                  section.markers.insertBefore(newPreviousMarker, postNode);\n\n                  var newPreviousRenderNode = renderTree.buildRenderNode(newPreviousMarker);\n                  newPreviousRenderNode.markDirty();\n                  section.renderNode.markDirty();\n\n                  seenRenderNodes.push(newPreviousRenderNode);\n                  section.renderNode.childNodes.insertBefore(newPreviousRenderNode, renderNode);\n                }\n              }\n              if (tailTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n                var value = tailTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n                tailTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n\n                if (renderNode.postNode.next && renderNode.postNode.next.isMarker) {\n                  var nextMarker = renderNode.postNode.next;\n\n                  if (nextMarker.renderNode) {\n                    var nextValue = nextMarker.renderNode.element.textContent;\n                    nextMarker.renderNode.element.textContent = value + nextValue;\n                  } else {\n                    var nextValue = value + nextMarker.value;\n                    nextMarker.value = nextValue;\n                  }\n                } else {\n                  var postNode = renderNode.postNode;\n                  var newMarkups = postNode.markups.slice();\n                  var newMarker = _this4.builder.createMarker(value, newMarkups);\n\n                  section.markers.insertAfter(newMarker, postNode);\n\n                  var newRenderNode = renderTree.buildRenderNode(newMarker);\n                  seenRenderNodes.push(newRenderNode);\n\n                  newRenderNode.markDirty();\n                  section.renderNode.markDirty();\n\n                  section.renderNode.childNodes.insertAfter(newRenderNode, renderNode);\n                }\n              }\n              if (renderNode) {\n                marker = renderNode.postNode;\n              }\n            }\n          } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n            var text = transformHTMLText(node.textContent);\n            var markups = _this4.collectMarkups(node, element);\n            marker = _this4.builder.createMarker(text, markups);\n\n            renderNode = renderTree.buildRenderNode(marker);\n            renderNode.element = node;\n            renderNode.markClean();\n            section.renderNode.markDirty();\n\n            var previousRenderNode = previousMarker && previousMarker.renderNode;\n            section.markers.insertAfter(marker, previousMarker);\n            section.renderNode.childNodes.insertAfter(renderNode, previousRenderNode);\n          }\n\n          if (renderNode) {\n            seenRenderNodes.push(renderNode);\n          }\n          previousMarker = marker;\n        });\n\n        var renderNode = section.renderNode.childNodes.head;\n        while (renderNode) {\n          if (seenRenderNodes.indexOf(renderNode) === -1) {\n            renderNode.scheduleForRemoval();\n          }\n          renderNode = renderNode.next;\n        }\n      }\n    }]);\n\n    return DOMParser;\n  })();\n\n  exports['default'] = DOMParser;\n});","define('mobiledoc-kit/parsers/html', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/parsers/dom'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitParsersDom) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var HTMLParser = (function () {\n    function HTMLParser(builder) {\n      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n      _classCallCheck(this, HTMLParser);\n\n      (0, _mobiledocKitUtilsAssert['default'])('Must pass builder to HTMLParser', builder);\n      this.builder = builder;\n      this.options = options;\n    }\n\n    /**\n     * @param {String} html to parse\n     * @return {Post} A post abstract\n     */\n\n    _createClass(HTMLParser, [{\n      key: 'parse',\n      value: function parse(html) {\n        var dom = (0, _mobiledocKitUtilsDomUtils.parseHTML)(html);\n        var parser = new _mobiledocKitParsersDom['default'](this.builder, this.options);\n        return parser.parse(dom);\n      }\n    }]);\n\n    return HTMLParser;\n  })();\n\n  exports['default'] = HTMLParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /*\n   * Parses from mobiledoc -> post\n   */\n\n  var MobiledocParser = (function () {\n    function MobiledocParser(builder) {\n      _classCallCheck(this, MobiledocParser);\n\n      this.builder = builder;\n    }\n\n    /**\n     * @param {Mobiledoc}\n     * @return {Post}\n     */\n\n    _createClass(MobiledocParser, [{\n      key: 'parse',\n      value: function parse(_ref) {\n        var sectionData = _ref.sections;\n\n        try {\n          var markerTypes = sectionData[0];\n          var sections = sectionData[1];\n\n          var post = this.builder.createPost();\n\n          this.markups = [];\n          this.markerTypes = this.parseMarkerTypes(markerTypes);\n          this.parseSections(sections, post);\n\n          return post;\n        } catch (e) {\n          (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n        }\n      }\n    }, {\n      key: 'parseMarkerTypes',\n      value: function parseMarkerTypes(markerTypes) {\n        var _this = this;\n\n        return markerTypes.map(function (markerType) {\n          return _this.parseMarkerType(markerType);\n        });\n      }\n    }, {\n      key: 'parseMarkerType',\n      value: function parseMarkerType(_ref2) {\n        var _ref22 = _slicedToArray(_ref2, 2);\n\n        var tagName = _ref22[0];\n        var attributesArray = _ref22[1];\n\n        var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n        return this.builder.createMarkup(tagName, attributesObject);\n      }\n    }, {\n      key: 'parseSections',\n      value: function parseSections(sections, post) {\n        var _this2 = this;\n\n        sections.forEach(function (section) {\n          return _this2.parseSection(section, post);\n        });\n      }\n    }, {\n      key: 'parseSection',\n      value: function parseSection(section, post) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_MARKUP_SECTION_TYPE:\n            this.parseMarkupSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_IMAGE_SECTION_TYPE:\n            this.parseImageSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_CARD_SECTION_TYPE:\n            this.parseCardSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_LIST_SECTION_TYPE:\n            this.parseListSection(section, post);\n            break;\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ' + type, false);\n        }\n      }\n    }, {\n      key: 'parseCardSection',\n      value: function parseCardSection(_ref3, post) {\n        var _ref32 = _slicedToArray(_ref3, 3);\n\n        var name = _ref32[1];\n        var payload = _ref32[2];\n\n        var section = this.builder.createCardSection(name, payload);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseImageSection',\n      value: function parseImageSection(_ref4, post) {\n        var _ref42 = _slicedToArray(_ref4, 2);\n\n        var src = _ref42[1];\n\n        var section = this.builder.createImageSection(src);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseMarkupSection',\n      value: function parseMarkupSection(_ref5, post) {\n        var _ref52 = _slicedToArray(_ref5, 3);\n\n        var tagName = _ref52[1];\n        var markers = _ref52[2];\n\n        var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n        post.sections.append(section);\n        this.parseMarkers(markers, section);\n        // Strip blank markers after they have been created. This ensures any\n        // markup they include has been correctly populated.\n        (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n          return m.isBlank;\n        }).forEach(function (m) {\n          section.markers.remove(m);\n        });\n      }\n    }, {\n      key: 'parseListSection',\n      value: function parseListSection(_ref6, post) {\n        var _ref62 = _slicedToArray(_ref6, 3);\n\n        var tagName = _ref62[1];\n        var items = _ref62[2];\n\n        var section = this.builder.createListSection(tagName);\n        post.sections.append(section);\n        this.parseListItems(items, section);\n      }\n    }, {\n      key: 'parseListItems',\n      value: function parseListItems(items, section) {\n        var _this3 = this;\n\n        items.forEach(function (i) {\n          return _this3.parseListItem(i, section);\n        });\n      }\n    }, {\n      key: 'parseListItem',\n      value: function parseListItem(markers, section) {\n        var item = this.builder.createListItem();\n        this.parseMarkers(markers, item);\n        section.items.append(item);\n      }\n    }, {\n      key: 'parseMarkers',\n      value: function parseMarkers(markers, parent) {\n        var _this4 = this;\n\n        markers.forEach(function (m) {\n          return _this4.parseMarker(m, parent);\n        });\n      }\n    }, {\n      key: 'parseMarker',\n      value: function parseMarker(_ref7, parent) {\n        var _this5 = this;\n\n        var _ref72 = _slicedToArray(_ref7, 3);\n\n        var markerTypeIndexes = _ref72[0];\n        var closeCount = _ref72[1];\n        var value = _ref72[2];\n\n        markerTypeIndexes.forEach(function (index) {\n          _this5.markups.push(_this5.markerTypes[index]);\n        });\n        var marker = this.builder.createMarker(value, this.markups.slice());\n        parent.markers.append(marker);\n        this.markups = this.markups.slice(0, this.markups.length - closeCount);\n      }\n    }]);\n\n    return MobiledocParser;\n  })();\n\n  exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /*\n   * Parses from mobiledoc -> post\n   */\n\n  var MobiledocParser = (function () {\n    function MobiledocParser(builder) {\n      _classCallCheck(this, MobiledocParser);\n\n      this.builder = builder;\n    }\n\n    /**\n     * @param {Mobiledoc}\n     * @return {Post}\n     */\n\n    _createClass(MobiledocParser, [{\n      key: 'parse',\n      value: function parse(_ref) {\n        var sections = _ref.sections;\n        var markerTypes = _ref.markups;\n        var cardTypes = _ref.cards;\n        var atomTypes = _ref.atoms;\n\n        try {\n          var post = this.builder.createPost();\n\n          this.markups = [];\n          this.markerTypes = this.parseMarkerTypes(markerTypes);\n          this.cardTypes = this.parseCardTypes(cardTypes);\n          this.atomTypes = this.parseAtomTypes(atomTypes);\n          this.parseSections(sections, post);\n\n          return post;\n        } catch (e) {\n          (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n        }\n      }\n    }, {\n      key: 'parseMarkerTypes',\n      value: function parseMarkerTypes(markerTypes) {\n        var _this = this;\n\n        return markerTypes.map(function (markerType) {\n          return _this.parseMarkerType(markerType);\n        });\n      }\n    }, {\n      key: 'parseMarkerType',\n      value: function parseMarkerType(_ref2) {\n        var _ref22 = _slicedToArray(_ref2, 2);\n\n        var tagName = _ref22[0];\n        var attributesArray = _ref22[1];\n\n        var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n        return this.builder.createMarkup(tagName, attributesObject);\n      }\n    }, {\n      key: 'parseCardTypes',\n      value: function parseCardTypes(cardTypes) {\n        var _this2 = this;\n\n        return cardTypes.map(function (cardType) {\n          return _this2.parseCardType(cardType);\n        });\n      }\n    }, {\n      key: 'parseCardType',\n      value: function parseCardType(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 2);\n\n        var cardName = _ref32[0];\n        var cardPayload = _ref32[1];\n\n        return [cardName, cardPayload];\n      }\n    }, {\n      key: 'parseAtomTypes',\n      value: function parseAtomTypes(atomTypes) {\n        var _this3 = this;\n\n        return atomTypes.map(function (atomType) {\n          return _this3.parseAtomType(atomType);\n        });\n      }\n    }, {\n      key: 'parseAtomType',\n      value: function parseAtomType(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 3);\n\n        var atomName = _ref42[0];\n        var atomValue = _ref42[1];\n        var atomPayload = _ref42[2];\n\n        return [atomName, atomValue, atomPayload];\n      }\n    }, {\n      key: 'parseSections',\n      value: function parseSections(sections, post) {\n        var _this4 = this;\n\n        sections.forEach(function (section) {\n          return _this4.parseSection(section, post);\n        });\n      }\n    }, {\n      key: 'parseSection',\n      value: function parseSection(section, post) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_SECTION_TYPE:\n            this.parseMarkupSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_IMAGE_SECTION_TYPE:\n            this.parseImageSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_CARD_SECTION_TYPE:\n            this.parseCardSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_LIST_SECTION_TYPE:\n            this.parseListSection(section, post);\n            break;\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n        }\n      }\n    }, {\n      key: 'getAtomTypeFromIndex',\n      value: function getAtomTypeFromIndex(index) {\n        var atomType = this.atomTypes[index];\n        (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n        return atomType;\n      }\n    }, {\n      key: 'getCardTypeFromIndex',\n      value: function getCardTypeFromIndex(index) {\n        var cardType = this.cardTypes[index];\n        (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n        return cardType;\n      }\n    }, {\n      key: 'parseCardSection',\n      value: function parseCardSection(_ref5, post) {\n        var _ref52 = _slicedToArray(_ref5, 2);\n\n        var cardIndex = _ref52[1];\n\n        var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n        var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n        var name = _getCardTypeFromIndex2[0];\n        var payload = _getCardTypeFromIndex2[1];\n\n        var section = this.builder.createCardSection(name, payload);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseImageSection',\n      value: function parseImageSection(_ref6, post) {\n        var _ref62 = _slicedToArray(_ref6, 2);\n\n        var src = _ref62[1];\n\n        var section = this.builder.createImageSection(src);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseMarkupSection',\n      value: function parseMarkupSection(_ref7, post) {\n        var _ref72 = _slicedToArray(_ref7, 3);\n\n        var tagName = _ref72[1];\n        var markers = _ref72[2];\n\n        var section = this.builder.createMarkupSection(tagName);\n        post.sections.append(section);\n        this.parseMarkers(markers, section);\n        // Strip blank markers after they have been created. This ensures any\n        // markup they include has been correctly populated.\n        (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n          return m.isBlank;\n        }).forEach(function (m) {\n          section.markers.remove(m);\n        });\n      }\n    }, {\n      key: 'parseListSection',\n      value: function parseListSection(_ref8, post) {\n        var _ref82 = _slicedToArray(_ref8, 3);\n\n        var tagName = _ref82[1];\n        var items = _ref82[2];\n\n        var section = this.builder.createListSection(tagName);\n        post.sections.append(section);\n        this.parseListItems(items, section);\n      }\n    }, {\n      key: 'parseListItems',\n      value: function parseListItems(items, section) {\n        var _this5 = this;\n\n        items.forEach(function (i) {\n          return _this5.parseListItem(i, section);\n        });\n      }\n    }, {\n      key: 'parseListItem',\n      value: function parseListItem(markers, section) {\n        var item = this.builder.createListItem();\n        this.parseMarkers(markers, item);\n        section.items.append(item);\n      }\n    }, {\n      key: 'parseMarkers',\n      value: function parseMarkers(markers, parent) {\n        var _this6 = this;\n\n        markers.forEach(function (m) {\n          return _this6.parseMarker(m, parent);\n        });\n      }\n    }, {\n      key: 'parseMarker',\n      value: function parseMarker(_ref9, parent) {\n        var _this7 = this;\n\n        var _ref92 = _slicedToArray(_ref9, 4);\n\n        var type = _ref92[0];\n        var markerTypeIndexes = _ref92[1];\n        var closeCount = _ref92[2];\n        var value = _ref92[3];\n\n        markerTypeIndexes.forEach(function (index) {\n          _this7.markups.push(_this7.markerTypes[index]);\n        });\n\n        var marker = this.buildMarkerType(type, value);\n        parent.markers.append(marker);\n\n        this.markups = this.markups.slice(0, this.markups.length - closeCount);\n      }\n    }, {\n      key: 'buildMarkerType',\n      value: function buildMarkerType(type, value) {\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE:\n            return this.builder.createMarker(value, this.markups.slice());\n          case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE:\n            {\n              var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n              var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n              var atomName = _getAtomTypeFromIndex2[0];\n              var atomValue = _getAtomTypeFromIndex2[1];\n              var atomPayload = _getAtomTypeFromIndex2[2];\n\n              return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n            }\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n        }\n      }\n    }]);\n\n    return MobiledocParser;\n  })();\n\n  exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /*\n   * Parses from mobiledoc -> post\n   */\n\n  var MobiledocParser = (function () {\n    function MobiledocParser(builder) {\n      _classCallCheck(this, MobiledocParser);\n\n      this.builder = builder;\n    }\n\n    /**\n     * @param {Mobiledoc}\n     * @return {Post}\n     */\n\n    _createClass(MobiledocParser, [{\n      key: 'parse',\n      value: function parse(_ref) {\n        var sections = _ref.sections;\n        var markerTypes = _ref.markups;\n        var cardTypes = _ref.cards;\n        var atomTypes = _ref.atoms;\n\n        try {\n          var post = this.builder.createPost();\n\n          this.markups = [];\n          this.markerTypes = this.parseMarkerTypes(markerTypes);\n          this.cardTypes = this.parseCardTypes(cardTypes);\n          this.atomTypes = this.parseAtomTypes(atomTypes);\n          this.parseSections(sections, post);\n\n          return post;\n        } catch (e) {\n          (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n        }\n      }\n    }, {\n      key: 'parseMarkerTypes',\n      value: function parseMarkerTypes(markerTypes) {\n        var _this = this;\n\n        return markerTypes.map(function (markerType) {\n          return _this.parseMarkerType(markerType);\n        });\n      }\n    }, {\n      key: 'parseMarkerType',\n      value: function parseMarkerType(_ref2) {\n        var _ref22 = _slicedToArray(_ref2, 2);\n\n        var tagName = _ref22[0];\n        var attributesArray = _ref22[1];\n\n        var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n        return this.builder.createMarkup(tagName, attributesObject);\n      }\n    }, {\n      key: 'parseCardTypes',\n      value: function parseCardTypes(cardTypes) {\n        var _this2 = this;\n\n        return cardTypes.map(function (cardType) {\n          return _this2.parseCardType(cardType);\n        });\n      }\n    }, {\n      key: 'parseCardType',\n      value: function parseCardType(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 2);\n\n        var cardName = _ref32[0];\n        var cardPayload = _ref32[1];\n\n        return [cardName, cardPayload];\n      }\n    }, {\n      key: 'parseAtomTypes',\n      value: function parseAtomTypes(atomTypes) {\n        var _this3 = this;\n\n        return atomTypes.map(function (atomType) {\n          return _this3.parseAtomType(atomType);\n        });\n      }\n    }, {\n      key: 'parseAtomType',\n      value: function parseAtomType(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 3);\n\n        var atomName = _ref42[0];\n        var atomValue = _ref42[1];\n        var atomPayload = _ref42[2];\n\n        return [atomName, atomValue, atomPayload];\n      }\n    }, {\n      key: 'parseSections',\n      value: function parseSections(sections, post) {\n        var _this4 = this;\n\n        sections.forEach(function (section) {\n          return _this4.parseSection(section, post);\n        });\n      }\n    }, {\n      key: 'parseSection',\n      value: function parseSection(section, post) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_SECTION_TYPE:\n            this.parseMarkupSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_IMAGE_SECTION_TYPE:\n            this.parseImageSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_CARD_SECTION_TYPE:\n            this.parseCardSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_LIST_SECTION_TYPE:\n            this.parseListSection(section, post);\n            break;\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n        }\n      }\n    }, {\n      key: 'getAtomTypeFromIndex',\n      value: function getAtomTypeFromIndex(index) {\n        var atomType = this.atomTypes[index];\n        (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n        return atomType;\n      }\n    }, {\n      key: 'getCardTypeFromIndex',\n      value: function getCardTypeFromIndex(index) {\n        var cardType = this.cardTypes[index];\n        (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n        return cardType;\n      }\n    }, {\n      key: 'parseCardSection',\n      value: function parseCardSection(_ref5, post) {\n        var _ref52 = _slicedToArray(_ref5, 2);\n\n        var cardIndex = _ref52[1];\n\n        var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n        var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n        var name = _getCardTypeFromIndex2[0];\n        var payload = _getCardTypeFromIndex2[1];\n\n        var section = this.builder.createCardSection(name, payload);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseImageSection',\n      value: function parseImageSection(_ref6, post) {\n        var _ref62 = _slicedToArray(_ref6, 2);\n\n        var src = _ref62[1];\n\n        var section = this.builder.createImageSection(src);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseMarkupSection',\n      value: function parseMarkupSection(_ref7, post) {\n        var _ref72 = _slicedToArray(_ref7, 4);\n\n        var tagName = _ref72[1];\n        var markers = _ref72[2];\n        var attributesArray = _ref72[3];\n\n        var section = this.builder.createMarkupSection(tagName);\n        post.sections.append(section);\n        if (attributesArray) {\n          (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref8) {\n            var _ref82 = _slicedToArray(_ref8, 2);\n\n            var key = _ref82[0];\n            var value = _ref82[1];\n\n            section.setAttribute(key, value);\n          });\n        }\n        this.parseMarkers(markers, section);\n        // Strip blank markers after they have been created. This ensures any\n        // markup they include has been correctly populated.\n        (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n          return m.isBlank;\n        }).forEach(function (m) {\n          section.markers.remove(m);\n        });\n      }\n    }, {\n      key: 'parseListSection',\n      value: function parseListSection(_ref9, post) {\n        var _ref92 = _slicedToArray(_ref9, 4);\n\n        var tagName = _ref92[1];\n        var items = _ref92[2];\n        var attributesArray = _ref92[3];\n\n        var section = this.builder.createListSection(tagName);\n        post.sections.append(section);\n        if (attributesArray) {\n          (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref10) {\n            var _ref102 = _slicedToArray(_ref10, 2);\n\n            var key = _ref102[0];\n            var value = _ref102[1];\n\n            section.setAttribute(key, value);\n          });\n        }\n        this.parseListItems(items, section);\n      }\n    }, {\n      key: 'parseListItems',\n      value: function parseListItems(items, section) {\n        var _this5 = this;\n\n        items.forEach(function (i) {\n          return _this5.parseListItem(i, section);\n        });\n      }\n    }, {\n      key: 'parseListItem',\n      value: function parseListItem(markers, section) {\n        var item = this.builder.createListItem();\n        this.parseMarkers(markers, item);\n        section.items.append(item);\n      }\n    }, {\n      key: 'parseMarkers',\n      value: function parseMarkers(markers, parent) {\n        var _this6 = this;\n\n        markers.forEach(function (m) {\n          return _this6.parseMarker(m, parent);\n        });\n      }\n    }, {\n      key: 'parseMarker',\n      value: function parseMarker(_ref11, parent) {\n        var _this7 = this;\n\n        var _ref112 = _slicedToArray(_ref11, 4);\n\n        var type = _ref112[0];\n        var markerTypeIndexes = _ref112[1];\n        var closeCount = _ref112[2];\n        var value = _ref112[3];\n\n        markerTypeIndexes.forEach(function (index) {\n          _this7.markups.push(_this7.markerTypes[index]);\n        });\n\n        var marker = this.buildMarkerType(type, value);\n        parent.markers.append(marker);\n\n        this.markups = this.markups.slice(0, this.markups.length - closeCount);\n      }\n    }, {\n      key: 'buildMarkerType',\n      value: function buildMarkerType(type, value) {\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_MARKER_TYPE:\n            return this.builder.createMarker(value, this.markups.slice());\n          case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_ATOM_MARKER_TYPE:\n            {\n              var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n              var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n              var atomName = _getAtomTypeFromIndex2[0];\n              var atomValue = _getAtomTypeFromIndex2[1];\n              var atomPayload = _getAtomTypeFromIndex2[2];\n\n              return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n            }\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n        }\n      }\n    }]);\n\n    return MobiledocParser;\n  })();\n\n  exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc03, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /*\n   * Parses from mobiledoc -> post\n   */\n\n  var MobiledocParser = (function () {\n    function MobiledocParser(builder) {\n      _classCallCheck(this, MobiledocParser);\n\n      this.builder = builder;\n    }\n\n    /**\n     * @param {Mobiledoc}\n     * @return {Post}\n     */\n\n    _createClass(MobiledocParser, [{\n      key: 'parse',\n      value: function parse(_ref) {\n        var sections = _ref.sections;\n        var markerTypes = _ref.markups;\n        var cardTypes = _ref.cards;\n        var atomTypes = _ref.atoms;\n\n        try {\n          var post = this.builder.createPost();\n\n          this.markups = [];\n          this.markerTypes = this.parseMarkerTypes(markerTypes);\n          this.cardTypes = this.parseCardTypes(cardTypes);\n          this.atomTypes = this.parseAtomTypes(atomTypes);\n          this.parseSections(sections, post);\n\n          return post;\n        } catch (e) {\n          (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n        }\n      }\n    }, {\n      key: 'parseMarkerTypes',\n      value: function parseMarkerTypes(markerTypes) {\n        var _this = this;\n\n        return markerTypes.map(function (markerType) {\n          return _this.parseMarkerType(markerType);\n        });\n      }\n    }, {\n      key: 'parseMarkerType',\n      value: function parseMarkerType(_ref2) {\n        var _ref22 = _slicedToArray(_ref2, 2);\n\n        var tagName = _ref22[0];\n        var attributesArray = _ref22[1];\n\n        var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n        return this.builder.createMarkup(tagName, attributesObject);\n      }\n    }, {\n      key: 'parseCardTypes',\n      value: function parseCardTypes(cardTypes) {\n        var _this2 = this;\n\n        return cardTypes.map(function (cardType) {\n          return _this2.parseCardType(cardType);\n        });\n      }\n    }, {\n      key: 'parseCardType',\n      value: function parseCardType(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 2);\n\n        var cardName = _ref32[0];\n        var cardPayload = _ref32[1];\n\n        return [cardName, cardPayload];\n      }\n    }, {\n      key: 'parseAtomTypes',\n      value: function parseAtomTypes(atomTypes) {\n        var _this3 = this;\n\n        return atomTypes.map(function (atomType) {\n          return _this3.parseAtomType(atomType);\n        });\n      }\n    }, {\n      key: 'parseAtomType',\n      value: function parseAtomType(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 3);\n\n        var atomName = _ref42[0];\n        var atomValue = _ref42[1];\n        var atomPayload = _ref42[2];\n\n        return [atomName, atomValue, atomPayload];\n      }\n    }, {\n      key: 'parseSections',\n      value: function parseSections(sections, post) {\n        var _this4 = this;\n\n        sections.forEach(function (section) {\n          return _this4.parseSection(section, post);\n        });\n      }\n    }, {\n      key: 'parseSection',\n      value: function parseSection(section, post) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_SECTION_TYPE:\n            this.parseMarkupSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_IMAGE_SECTION_TYPE:\n            this.parseImageSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_CARD_SECTION_TYPE:\n            this.parseCardSection(section, post);\n            break;\n          case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_LIST_SECTION_TYPE:\n            this.parseListSection(section, post);\n            break;\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n        }\n      }\n    }, {\n      key: 'getAtomTypeFromIndex',\n      value: function getAtomTypeFromIndex(index) {\n        var atomType = this.atomTypes[index];\n        (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n        return atomType;\n      }\n    }, {\n      key: 'getCardTypeFromIndex',\n      value: function getCardTypeFromIndex(index) {\n        var cardType = this.cardTypes[index];\n        (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n        return cardType;\n      }\n    }, {\n      key: 'parseCardSection',\n      value: function parseCardSection(_ref5, post) {\n        var _ref52 = _slicedToArray(_ref5, 2);\n\n        var cardIndex = _ref52[1];\n\n        var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n        var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n        var name = _getCardTypeFromIndex2[0];\n        var payload = _getCardTypeFromIndex2[1];\n\n        var section = this.builder.createCardSection(name, payload);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseImageSection',\n      value: function parseImageSection(_ref6, post) {\n        var _ref62 = _slicedToArray(_ref6, 2);\n\n        var src = _ref62[1];\n\n        var section = this.builder.createImageSection(src);\n        post.sections.append(section);\n      }\n    }, {\n      key: 'parseMarkupSection',\n      value: function parseMarkupSection(_ref7, post) {\n        var _ref72 = _slicedToArray(_ref7, 3);\n\n        var tagName = _ref72[1];\n        var markers = _ref72[2];\n\n        var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n        post.sections.append(section);\n        this.parseMarkers(markers, section);\n        // Strip blank markers after they have been created. This ensures any\n        // markup they include has been correctly populated.\n        (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n          return m.isBlank;\n        }).forEach(function (m) {\n          section.markers.remove(m);\n        });\n      }\n    }, {\n      key: 'parseListSection',\n      value: function parseListSection(_ref8, post) {\n        var _ref82 = _slicedToArray(_ref8, 3);\n\n        var tagName = _ref82[1];\n        var items = _ref82[2];\n\n        var section = this.builder.createListSection(tagName);\n        post.sections.append(section);\n        this.parseListItems(items, section);\n      }\n    }, {\n      key: 'parseListItems',\n      value: function parseListItems(items, section) {\n        var _this5 = this;\n\n        items.forEach(function (i) {\n          return _this5.parseListItem(i, section);\n        });\n      }\n    }, {\n      key: 'parseListItem',\n      value: function parseListItem(markers, section) {\n        var item = this.builder.createListItem();\n        this.parseMarkers(markers, item);\n        section.items.append(item);\n      }\n    }, {\n      key: 'parseMarkers',\n      value: function parseMarkers(markers, parent) {\n        var _this6 = this;\n\n        markers.forEach(function (m) {\n          return _this6.parseMarker(m, parent);\n        });\n      }\n    }, {\n      key: 'parseMarker',\n      value: function parseMarker(_ref9, parent) {\n        var _this7 = this;\n\n        var _ref92 = _slicedToArray(_ref9, 4);\n\n        var type = _ref92[0];\n        var markerTypeIndexes = _ref92[1];\n        var closeCount = _ref92[2];\n        var value = _ref92[3];\n\n        markerTypeIndexes.forEach(function (index) {\n          _this7.markups.push(_this7.markerTypes[index]);\n        });\n\n        var marker = this.buildMarkerType(type, value);\n        parent.markers.append(marker);\n\n        this.markups = this.markups.slice(0, this.markups.length - closeCount);\n      }\n    }, {\n      key: 'buildMarkerType',\n      value: function buildMarkerType(type, value) {\n        switch (type) {\n          case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE:\n            return this.builder.createMarker(value, this.markups.slice());\n          case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE:\n            {\n              var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n              var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n              var atomName = _getAtomTypeFromIndex2[0];\n              var atomValue = _getAtomTypeFromIndex2[1];\n              var atomPayload = _getAtomTypeFromIndex2[2];\n\n              return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n            }\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n        }\n      }\n    }]);\n\n    return MobiledocParser;\n  })();\n\n  exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/parsers/mobiledoc/0-3-2', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitParsersMobiledoc032, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  function parseVersion(mobiledoc) {\n    return mobiledoc.version;\n  }\n\n  exports['default'] = {\n    parse: function parse(builder, mobiledoc) {\n      var version = parseVersion(mobiledoc);\n      switch (version) {\n        case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n          return new _mobiledocKitParsersMobiledoc02['default'](builder).parse(mobiledoc);\n        case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n          return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc);\n        case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n          return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc);\n        case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION:\n          return new _mobiledocKitParsersMobiledoc032['default'](builder).parse(mobiledoc);\n        default:\n          (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false);\n      }\n    }\n  };\n});","define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkup, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitParsersDom, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var SKIPPABLE_ELEMENT_TAG_NAMES = ['style', 'head', 'title', 'meta'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n  var NEWLINES = /\\s*\\n\\s*/g;\n  function sanitize(text) {\n    return text.replace(NEWLINES, ' ');\n  }\n\n  /**\n   * parses an element into a section, ignoring any non-markup\n   * elements contained within\n   * @private\n   */\n\n  var SectionParser = (function () {\n    function SectionParser(builder) {\n      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n      _classCallCheck(this, SectionParser);\n\n      this.builder = builder;\n      this.plugins = options.plugins || [];\n    }\n\n    _createClass(SectionParser, [{\n      key: 'parse',\n      value: function parse(element) {\n        var _this = this;\n\n        if (this._isSkippable(element)) {\n          return [];\n        }\n        this.sections = [];\n        this.state = {};\n\n        this._updateStateFromElement(element);\n\n        var finished = false;\n\n        // top-level text nodes will be run through parseNode later so avoid running\n        // the node through parserPlugins twice\n        if (!(0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n          finished = this.runPlugins(element);\n        }\n\n        if (!finished) {\n          var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n\n          (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n            _this.parseNode(el);\n          });\n        }\n\n        this._closeCurrentSection();\n\n        return this.sections;\n      }\n    }, {\n      key: 'runPlugins',\n      value: function runPlugins(node) {\n        var _this2 = this;\n\n        var isNodeFinished = false;\n        var env = {\n          addSection: function addSection(section) {\n            // avoid creating empty paragraphs due to wrapper elements around\n            // parser-plugin-handled elements\n            if (_this2.state.section && _this2.state.section.isMarkerable && !_this2.state.section.text && !_this2.state.text) {\n              _this2.state.section = null;\n            } else {\n              _this2._closeCurrentSection();\n            }\n            _this2.sections.push(section);\n          },\n          addMarkerable: function addMarkerable(marker) {\n            var state = _this2.state;\n            var section = state.section;\n\n            // if the first element doesn't create it's own state and it's plugin\n            // handler uses `addMarkerable` we won't have a section yet\n            if (!section) {\n              state.text = '';\n              state.section = _this2.builder.createMarkupSection((0, _mobiledocKitUtilsDomUtils.normalizeTagName)('p'));\n              section = state.section;\n            }\n            (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable);\n            if (state.text) {\n              _this2._createMarker();\n            }\n            section.markers.append(marker);\n          },\n          nodeFinished: function nodeFinished() {\n            isNodeFinished = true;\n          }\n        };\n        for (var i = 0; i < this.plugins.length; i++) {\n          var plugin = this.plugins[i];\n          plugin(node, this.builder, env);\n          if (isNodeFinished) {\n            return true;\n          }\n        }\n        return false;\n      }\n\n      /* eslint-disable complexity */\n    }, {\n      key: 'parseNode',\n      value: function parseNode(node) {\n        var _this3 = this;\n\n        if (!this.state.section) {\n          this._updateStateFromElement(node);\n        }\n\n        var nodeFinished = this.runPlugins(node);\n        if (nodeFinished) {\n          return;\n        }\n\n        // handle closing the current section and starting a new one if we hit a\n        // new-section-creating element.\n        if (this.state.section && !(0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.tagName) {\n          var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.tagName);\n          var isListSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName);\n          var isListItem = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName);\n          var isMarkupSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName);\n          var isNestedListSection = isListSection && this.state.section.isListItem;\n          var lastSection = this.sections[this.sections.length - 1];\n\n          // lists can continue after breaking out for a markup section,\n          // in that situation, start a new list using the same list type\n          if (isListItem && this.state.section.isMarkupSection) {\n            this._closeCurrentSection();\n            this._updateStateFromElement(node.parentElement);\n          }\n\n          // we can hit a list item after parsing a nested list, when that happens\n          // and the lists are of different types we need to make sure we switch\n          // the list type back\n          if (isListItem && lastSection && lastSection.isListSection) {\n            var parentElement = node.parentElement;\n            var parentElementTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(parentElement.tagName);\n            if (parentElementTagName !== lastSection.tagName) {\n              this._closeCurrentSection();\n              this._updateStateFromElement(parentElement);\n            }\n          }\n\n          // if we've broken out of a list due to nested section-level elements we\n          // can hit the next list item without having a list section in the current\n          // state. In this instance we find the parent list node and use it to\n          // re-initialize the state with a new list section\n          if (isListItem && !(this.state.section.isListItem || this.state.section.isListSection) && !lastSection.isListSection) {\n            this._closeCurrentSection();\n            this._updateStateFromElement(node.parentElement);\n          }\n\n          // if we have consecutive list sections of different types (ul, ol) then\n          // ensure we close the current section and start a new one\n          var isNewListSection = lastSection && lastSection.isListSection && this.state.section.isListItem && isListSection && tagName !== lastSection.tagName;\n\n          if (isNewListSection || isListSection && !isNestedListSection || isMarkupSection || isListItem) {\n            // don't break out of the list for list items that contain a single <p>.\n            // deals with typical case of <li><p>Text</p></li><li><p>Text</p></li>\n            if (this.state.section.isListItem && tagName === 'p' && !node.nextSibling && (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.parentElement.tagName))) {\n              this.parseElementNode(node);\n              return;\n            }\n\n            // avoid creating empty paragraphs due to wrapper elements around\n            // section-creating elements\n            if (this.state.section.isMarkerable && !this.state.text && this.state.section.markers.length === 0) {\n              this.state.section = null;\n            } else {\n              this._closeCurrentSection();\n            }\n\n            this._updateStateFromElement(node);\n          }\n\n          if (this.state.section.isListSection) {\n            // ensure the list section is closed and added to the sections list.\n            // _closeCurrentSection handles pushing list items onto the list section\n            this._closeCurrentSection();\n\n            (0, _mobiledocKitUtilsArrayUtils.forEach)(node.childNodes, function (node) {\n              _this3.parseNode(node);\n            });\n            return;\n          }\n        }\n\n        switch (node.nodeType) {\n          case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT:\n            this.parseTextNode(node);\n            break;\n          case _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT:\n            this.parseElementNode(node);\n            break;\n        }\n      }\n    }, {\n      key: 'parseElementNode',\n      value: function parseElementNode(element) {\n        var _state$markups,\n            _this4 = this;\n\n        var state = this.state;\n\n        var markups = this._markupsFromElement(element);\n        if (markups.length && state.text.length && state.section.isMarkerable) {\n          this._createMarker();\n        }\n        (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups));\n\n        (0, _mobiledocKitUtilsArrayUtils.forEach)(element.childNodes, function (node) {\n          _this4.parseNode(node);\n        });\n\n        if (markups.length && state.text.length && state.section.isMarkerable) {\n          // create the marker started for this node\n          this._createMarker();\n        }\n\n        // pop the current markups from the stack\n        state.markups.splice(-markups.length, markups.length);\n      }\n    }, {\n      key: 'parseTextNode',\n      value: function parseTextNode(textNode) {\n        var state = this.state;\n\n        state.text += sanitize(textNode.textContent);\n      }\n    }, {\n      key: '_updateStateFromElement',\n      value: function _updateStateFromElement(element) {\n        if ((0, _mobiledocKitUtilsDomUtils.isCommentNode)(element)) {\n          return;\n        }\n\n        var state = this.state;\n\n        state.section = this._createSectionFromElement(element);\n        state.markups = this._markupsFromElement(element);\n        state.text = '';\n      }\n    }, {\n      key: '_closeCurrentSection',\n      value: function _closeCurrentSection() {\n        var sections = this.sections;\n        var state = this.state;\n\n        var lastSection = sections[sections.length - 1];\n\n        if (!state.section) {\n          return;\n        }\n\n        // close a trailing text node if it exists\n        if (state.text.length && state.section.isMarkerable) {\n          this._createMarker();\n        }\n\n        // push listItems onto the listSection or add a new section\n        if (state.section.isListItem && lastSection && lastSection.isListSection) {\n          (0, _mobiledocKitParsersDom.trimSectionText)(state.section);\n          lastSection.items.append(state.section);\n        } else {\n          // avoid creating empty markup sections, especially useful for indented source\n          if (state.section.isMarkerable && !state.section.text.trim() && !(0, _mobiledocKitUtilsArrayUtils.any)(state.section.markers, function (marker) {\n            return marker.isAtom;\n          })) {\n            state.section = null;\n            state.text = '';\n            return;\n          }\n\n          // remove empty list sections before creating a new section\n          if (lastSection && lastSection.isListSection && lastSection.items.length === 0) {\n            sections.pop();\n          }\n\n          sections.push(state.section);\n        }\n\n        state.section = null;\n        state.text = '';\n      }\n    }, {\n      key: '_markupsFromElement',\n      value: function _markupsFromElement(element) {\n        var builder = this.builder;\n\n        var markups = [];\n        if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n          return markups;\n        }\n\n        var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n        if (this._isValidMarkupForElement(tagName, element)) {\n          markups.push(builder.createMarkup(tagName, (0, _mobiledocKitUtilsDomUtils.getAttributes)(element)));\n        }\n\n        this._markupsFromElementStyle(element).forEach(function (markup) {\n          return markups.push(markup);\n        });\n\n        return markups;\n      }\n    }, {\n      key: '_isValidMarkupForElement',\n      value: function _isValidMarkupForElement(tagName, element) {\n        if (_mobiledocKitModelsMarkup.VALID_MARKUP_TAGNAMES.indexOf(tagName) === -1) {\n          return false;\n        } else if (tagName === 'b') {\n          // google docs add a <b style=\"font-weight: normal;\"> that should not\n          // create a \"b\" markup\n          return element.style.fontWeight !== 'normal';\n        }\n        return true;\n      }\n    }, {\n      key: '_markupsFromElementStyle',\n      value: function _markupsFromElementStyle(element) {\n        var builder = this.builder;\n\n        var markups = [];\n        var _element$style = element.style;\n        var fontStyle = _element$style.fontStyle;\n        var fontWeight = _element$style.fontWeight;\n\n        if (fontStyle === 'italic') {\n          markups.push(builder.createMarkup('em'));\n        }\n        if (fontWeight === 'bold' || fontWeight === '700') {\n          markups.push(builder.createMarkup('strong'));\n        }\n        return markups;\n      }\n    }, {\n      key: '_createMarker',\n      value: function _createMarker() {\n        var state = this.state;\n\n        var text = (0, _mobiledocKitParsersDom.transformHTMLText)(state.text);\n        var marker = this.builder.createMarker(text, state.markups);\n        state.section.markers.append(marker);\n        state.text = '';\n      }\n    }, {\n      key: '_getSectionDetails',\n      value: function _getSectionDetails(element) {\n        var sectionType = undefined,\n            tagName = undefined,\n            inferredTagName = false;\n\n        if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n          tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n          sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n          inferredTagName = true;\n        } else {\n          tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n\n          // blockquote>p is valid html and should be treated as a blockquote section\n          // rather than a plain markup section\n          if (tagName === 'p' && element.parentElement && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.parentElement.tagName) === 'blockquote') {\n            tagName = 'blockquote';\n          }\n\n          if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName)) {\n            sectionType = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n          } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName)) {\n            sectionType = _mobiledocKitModelsTypes.LIST_ITEM_TYPE;\n          } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName)) {\n            sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n          } else {\n            sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n            tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n            inferredTagName = true;\n          }\n        }\n\n        return { sectionType: sectionType, tagName: tagName, inferredTagName: inferredTagName };\n      }\n    }, {\n      key: '_createSectionFromElement',\n      value: function _createSectionFromElement(element) {\n        if ((0, _mobiledocKitUtilsDomUtils.isCommentNode)(element)) {\n          return;\n        }\n\n        var builder = this.builder;\n\n        var section = undefined;\n\n        var _getSectionDetails2 = this._getSectionDetails(element);\n\n        var tagName = _getSectionDetails2.tagName;\n        var sectionType = _getSectionDetails2.sectionType;\n        var inferredTagName = _getSectionDetails2.inferredTagName;\n\n        switch (sectionType) {\n          case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n            section = builder.createListSection(tagName);\n            break;\n          case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n            section = builder.createListItem();\n            break;\n          case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n            section = builder.createMarkupSection(tagName);\n            section._inferredTagName = inferredTagName;\n            break;\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Cannot parse section from element', false);\n        }\n\n        return section;\n      }\n    }, {\n      key: '_isSkippable',\n      value: function _isSkippable(element) {\n        return element.nodeType === _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT && (0, _mobiledocKitUtilsArrayUtils.contains)(SKIPPABLE_ELEMENT_TAG_NAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName));\n      }\n    }]);\n\n    return SectionParser;\n  })();\n\n  exports['default'] = SectionParser;\n});","define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup-section'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkupSection) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var UL_LI_REGEX = /^\\* (.*)$/;\n  var OL_LI_REGEX = /^\\d\\.? (.*)$/;\n  var CR = '\\r';\n  var LF = '\\n';\n  var CR_REGEX = new RegExp(CR, 'g');\n  var CR_LF_REGEX = new RegExp(CR + LF, 'g');\n\n  var SECTION_BREAK = LF;\n\n  exports.SECTION_BREAK = SECTION_BREAK;\n  function normalizeLineEndings(text) {\n    return text.replace(CR_LF_REGEX, LF).replace(CR_REGEX, LF);\n  }\n\n  var TextParser = (function () {\n    function TextParser(builder, options) {\n      _classCallCheck(this, TextParser);\n\n      this.builder = builder;\n      this.options = options;\n\n      this.post = this.builder.createPost();\n      this.prevSection = null;\n    }\n\n    /**\n     * @param {String} text to parse\n     * @return {Post} a post abstract\n     */\n\n    _createClass(TextParser, [{\n      key: 'parse',\n      value: function parse(text) {\n        var _this = this;\n\n        text = normalizeLineEndings(text);\n        text.split(SECTION_BREAK).forEach(function (text) {\n          var section = _this._parseSection(text);\n          _this._appendSection(section);\n        });\n\n        return this.post;\n      }\n    }, {\n      key: '_parseSection',\n      value: function _parseSection(text) {\n        var tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME,\n            type = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n            section = undefined;\n\n        if (UL_LI_REGEX.test(text)) {\n          tagName = 'ul';\n          type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n          text = text.match(UL_LI_REGEX)[1];\n        } else if (OL_LI_REGEX.test(text)) {\n          tagName = 'ol';\n          type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n          text = text.match(OL_LI_REGEX)[1];\n        }\n\n        var markers = [this.builder.createMarker(text)];\n\n        switch (type) {\n          case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n            {\n              var item = this.builder.createListItem(markers);\n              var list = this.builder.createListSection(tagName, [item]);\n              section = list;\n              break;\n            }\n          case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n            section = this.builder.createMarkupSection(tagName, markers);\n            break;\n          default:\n            (0, _mobiledocKitUtilsAssert['default'])('Unknown type encountered ' + type, false);\n        }\n\n        return section;\n      }\n    }, {\n      key: '_appendSection',\n      value: function _appendSection(section) {\n        var _this2 = this;\n\n        var isSameListSection = section.isListSection && this.prevSection && this.prevSection.isListSection && this.prevSection.tagName === section.tagName;\n\n        if (isSameListSection) {\n          section.items.forEach(function (item) {\n            _this2.prevSection.items.append(item.clone());\n          });\n        } else {\n          this.post.sections.insertAfter(section, this.prevSection);\n          this.prevSection = section;\n        }\n      }\n    }]);\n\n    return TextParser;\n  })();\n\n  exports['default'] = TextParser;\n});","define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/card-node', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/atom-node', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitModelsCardNode, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsAtomNode, _mobiledocKitModelsTypes, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitModelsMarkupSection, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCharacters) {\n  'use strict';\n\n  var _destroyHooks;\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  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; }\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var CARD_ELEMENT_CLASS_NAME = '__mobiledoc-card';\n  exports.CARD_ELEMENT_CLASS_NAME = CARD_ELEMENT_CLASS_NAME;\n  var NO_BREAK_SPACE = ' ';\n  exports.NO_BREAK_SPACE = NO_BREAK_SPACE;\n  var TAB_CHARACTER = ' ';\n  exports.TAB_CHARACTER = TAB_CHARACTER;\n  var SPACE = ' ';\n  exports.SPACE = SPACE;\n  var ZWNJ = '‌';\n  exports.ZWNJ = ZWNJ;\n  var ATOM_CLASS_NAME = '-mobiledoc-kit__atom';\n  exports.ATOM_CLASS_NAME = ATOM_CLASS_NAME;\n  var EDITOR_HAS_NO_CONTENT_CLASS_NAME = '__has-no-content';\n  exports.EDITOR_HAS_NO_CONTENT_CLASS_NAME = EDITOR_HAS_NO_CONTENT_CLASS_NAME;\n  var EDITOR_ELEMENT_CLASS_NAME = '__mobiledoc-editor';\n\n  exports.EDITOR_ELEMENT_CLASS_NAME = EDITOR_ELEMENT_CLASS_NAME;\n  function createElementFromMarkup(doc, markup) {\n    var element = doc.createElement(markup.tagName);\n    Object.keys(markup.attributes).forEach(function (k) {\n      element.setAttribute(k, markup.attributes[k]);\n    });\n    return element;\n  }\n\n  var TWO_SPACES = '' + SPACE + SPACE;\n  var SPACE_AND_NO_BREAK = '' + SPACE + NO_BREAK_SPACE;\n  var SPACES_REGEX = new RegExp(TWO_SPACES, 'g');\n  var TAB_REGEX = new RegExp(_mobiledocKitUtilsCharacters.TAB, 'g');\n  var endsWithSpace = function endsWithSpace(text) {\n    return (0, _mobiledocKitUtilsStringUtils.endsWith)(text, SPACE);\n  };\n  var startsWithSpace = function startsWithSpace(text) {\n    return (0, _mobiledocKitUtilsStringUtils.startsWith)(text, SPACE);\n  };\n\n  // FIXME: This can be done more efficiently with a single pass\n  // building a correct string based on the original.\n  function renderHTMLText(marker) {\n    var text = marker.value;\n    text = text.replace(SPACES_REGEX, SPACE_AND_NO_BREAK).replace(TAB_REGEX, TAB_CHARACTER);\n\n    // If the first marker has a leading space or the last marker has a\n    // trailing space, the browser will collapse the space when we position\n    // the cursor.\n    // See https://github.com/bustle/mobiledoc-kit/issues/68\n    //   and https://github.com/bustle/mobiledoc-kit/issues/75\n    if (marker.isMarker && endsWithSpace(text) && !marker.next) {\n      text = text.substr(0, text.length - 1) + NO_BREAK_SPACE;\n    }\n    if (marker.isMarker && startsWithSpace(text) && (!marker.prev || marker.prev.isMarker && endsWithSpace(marker.prev.value))) {\n      text = NO_BREAK_SPACE + text.substr(1);\n    }\n    return text;\n  }\n\n  // ascends from element upward, returning the last parent node that is not\n  // parentElement\n  function penultimateParentOf(element, parentElement) {\n    while (parentElement && element.parentNode !== parentElement && element.parentNode !== document.body // ensure the while loop stops\n    ) {\n      element = element.parentNode;\n    }\n    return element;\n  }\n\n  function setSectionAttributesOnElement(section, element) {\n    section.eachAttribute(function (key, value) {\n      element.setAttribute(key, value);\n    });\n  }\n\n  function renderMarkupSection(section) {\n    var element = undefined;\n    if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) {\n      element = document.createElement(section.tagName);\n    } else {\n      element = document.createElement('div');\n      (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName);\n    }\n\n    setSectionAttributesOnElement(section, element);\n\n    return element;\n  }\n\n  function renderListSection(section) {\n    var element = document.createElement(section.tagName);\n\n    setSectionAttributesOnElement(section, element);\n\n    return element;\n  }\n\n  function renderListItem() {\n    return document.createElement('li');\n  }\n\n  function renderCursorPlaceholder() {\n    return document.createElement('br');\n  }\n\n  function renderInlineCursorPlaceholder() {\n    return document.createTextNode(ZWNJ);\n  }\n\n  function renderCard() {\n    var wrapper = document.createElement('div');\n    var cardElement = document.createElement('div');\n    cardElement.contentEditable = false;\n    (0, _mobiledocKitUtilsDomUtils.addClassName)(cardElement, CARD_ELEMENT_CLASS_NAME);\n    wrapper.appendChild(renderInlineCursorPlaceholder());\n    wrapper.appendChild(cardElement);\n    wrapper.appendChild(renderInlineCursorPlaceholder());\n    return { wrapper: wrapper, cardElement: cardElement };\n  }\n\n  /**\n   * Wrap the element in all of the opened markups\n   * @return {DOMElement} the wrapped element\n   * @private\n   */\n  function wrapElement(element, openedMarkups) {\n    var wrappedElement = element;\n\n    for (var i = openedMarkups.length - 1; i >= 0; i--) {\n      var markup = openedMarkups[i];\n      var openedElement = createElementFromMarkup(document, markup);\n      openedElement.appendChild(wrappedElement);\n      wrappedElement = openedElement;\n    }\n\n    return wrappedElement;\n  }\n\n  // Attach the element to its parent element at the correct position based on the\n  // previousRenderNode\n  function attachElementToParent(element, parentElement) {\n    var previousRenderNode = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n    if (previousRenderNode) {\n      var previousSibling = previousRenderNode.element;\n      var previousSiblingPenultimate = penultimateParentOf(previousSibling, parentElement);\n      parentElement.insertBefore(element, previousSiblingPenultimate.nextSibling);\n    } else {\n      parentElement.insertBefore(element, parentElement.firstChild);\n    }\n  }\n\n  function renderAtom(atom, element, previousRenderNode) {\n    var atomElement = document.createElement('span');\n    atomElement.contentEditable = false;\n\n    var wrapper = document.createElement('span');\n    (0, _mobiledocKitUtilsDomUtils.addClassName)(wrapper, ATOM_CLASS_NAME);\n    var headTextNode = renderInlineCursorPlaceholder();\n    var tailTextNode = renderInlineCursorPlaceholder();\n\n    wrapper.appendChild(headTextNode);\n    wrapper.appendChild(atomElement);\n    wrapper.appendChild(tailTextNode);\n\n    var wrappedElement = wrapElement(wrapper, atom.openedMarkups);\n    attachElementToParent(wrappedElement, element, previousRenderNode);\n\n    return {\n      markupElement: wrappedElement,\n      wrapper: wrapper,\n      atomElement: atomElement,\n      headTextNode: headTextNode,\n      tailTextNode: tailTextNode\n    };\n  }\n\n  function getNextMarkerElement(renderNode) {\n    var element = renderNode.element.parentNode;\n    var marker = renderNode.postNode;\n    var closedCount = marker.closedMarkups.length;\n\n    while (closedCount--) {\n      element = element.parentNode;\n    }\n    return element;\n  }\n\n  /**\n   * Render the marker\n   * @param {Marker} marker the marker to render\n   * @param {DOMNode} element the element to attach the rendered marker to\n   * @param {RenderNode} [previousRenderNode] The render node before this one, which\n   *        affects the determination of where to insert this rendered marker.\n   * @return {Object} With properties `element` and `markupElement`.\n   *         The element (textNode) that has the text for\n   *         this marker, and the outermost rendered element. If the marker has no\n   *         markups, element and markupElement will be the same textNode\n   * @private\n   */\n  function renderMarker(marker, parentElement, previousRenderNode) {\n    var text = renderHTMLText(marker);\n\n    var element = document.createTextNode(text);\n    var markupElement = wrapElement(element, marker.openedMarkups);\n    attachElementToParent(markupElement, parentElement, previousRenderNode);\n\n    return { element: element, markupElement: markupElement };\n  }\n\n  // Attach the render node's element to the DOM,\n  // replacing the originalElement if it exists\n  function attachRenderNodeElementToDOM(renderNode) {\n    var originalElement = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n    var element = renderNode.element;\n    var hasRendered = !!originalElement;\n\n    if (hasRendered) {\n      var parentElement = renderNode.parent.element;\n      parentElement.replaceChild(element, originalElement);\n    } else {\n      var parentElement = undefined,\n          nextSiblingElement = undefined;\n      if (renderNode.prev) {\n        var previousElement = renderNode.prev.element;\n        parentElement = previousElement.parentNode;\n        nextSiblingElement = previousElement.nextSibling;\n      } else {\n        parentElement = renderNode.parent.element;\n        nextSiblingElement = parentElement.firstChild;\n      }\n      parentElement.insertBefore(element, nextSiblingElement);\n    }\n  }\n\n  function removeRenderNodeSectionFromParent(renderNode, section) {\n    var parent = renderNode.parent.postNode;\n    parent.sections.remove(section);\n  }\n\n  function removeRenderNodeElementFromParent(renderNode) {\n    if (renderNode.element && renderNode.element.parentNode) {\n      renderNode.element.parentNode.removeChild(renderNode.element);\n    }\n  }\n\n  function validateCards() {\n    var cards = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n    (0, _mobiledocKitUtilsArrayUtils.forEach)(cards, function (card) {\n      (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define type \"dom\", has: \"' + card.type + '\"', card.type === 'dom');\n      (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define `render` method', !!card.render);\n    });\n    return cards;\n  }\n\n  function validateAtoms() {\n    var atoms = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n    (0, _mobiledocKitUtilsArrayUtils.forEach)(atoms, function (atom) {\n      (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define type \"dom\", has: \"' + atom.type + '\"', atom.type === 'dom');\n      (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define `render` method', !!atom.render);\n    });\n    return atoms;\n  }\n\n  var Visitor = (function () {\n    function Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n      _classCallCheck(this, Visitor);\n\n      this.editor = editor;\n      this.cards = validateCards(cards);\n      this.atoms = validateAtoms(atoms);\n      this.unknownCardHandler = unknownCardHandler;\n      this.unknownAtomHandler = unknownAtomHandler;\n      this.options = options;\n    }\n\n    _createClass(Visitor, [{\n      key: '_findCard',\n      value: function _findCard(cardName) {\n        var card = (0, _mobiledocKitUtilsArrayUtils.detect)(this.cards, function (card) {\n          return card.name === cardName;\n        });\n        return card || this._createUnknownCard(cardName);\n      }\n    }, {\n      key: '_createUnknownCard',\n      value: function _createUnknownCard(cardName) {\n        (0, _mobiledocKitUtilsAssert['default'])('Unknown card \"' + cardName + '\" found, but no unknownCardHandler is defined', !!this.unknownCardHandler);\n\n        return {\n          name: cardName,\n          type: 'dom',\n          render: this.unknownCardHandler,\n          edit: this.unknownCardHandler\n        };\n      }\n    }, {\n      key: '_findAtom',\n      value: function _findAtom(atomName) {\n        var atom = (0, _mobiledocKitUtilsArrayUtils.detect)(this.atoms, function (atom) {\n          return atom.name === atomName;\n        });\n        return atom || this._createUnknownAtom(atomName);\n      }\n    }, {\n      key: '_createUnknownAtom',\n      value: function _createUnknownAtom(atomName) {\n        (0, _mobiledocKitUtilsAssert['default'])('Unknown atom \"' + atomName + '\" found, but no unknownAtomHandler is defined', !!this.unknownAtomHandler);\n\n        return {\n          name: atomName,\n          type: 'dom',\n          render: this.unknownAtomHandler\n        };\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.POST_TYPE,\n      value: function value(renderNode, post, visit) {\n        if (!renderNode.element) {\n          renderNode.element = document.createElement('div');\n        }\n        (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_ELEMENT_CLASS_NAME);\n        if (post.hasContent) {\n          (0, _mobiledocKitUtilsDomUtils.removeClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n        } else {\n          (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n        }\n        visit(renderNode, post.sections);\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n      value: function value(renderNode, section, visit) {\n        var originalElement = renderNode.element;\n\n        // Always rerender the section -- its tag name or attributes may have changed.\n        // TODO make this smarter, only rerendering and replacing the element when necessary\n        renderNode.element = renderMarkupSection(section);\n        renderNode.cursorElement = null;\n        attachRenderNodeElementToDOM(renderNode, originalElement);\n\n        if (section.isBlank) {\n          var cursorPlaceholder = renderCursorPlaceholder();\n          renderNode.element.appendChild(cursorPlaceholder);\n          renderNode.cursorElement = cursorPlaceholder;\n        } else {\n          var visitAll = true;\n          visit(renderNode, section.markers, visitAll);\n        }\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n      value: function value(renderNode, section, visit) {\n        var originalElement = renderNode.element;\n\n        renderNode.element = renderListSection(section);\n        attachRenderNodeElementToDOM(renderNode, originalElement);\n\n        var visitAll = true;\n        visit(renderNode, section.items, visitAll);\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n      value: function value(renderNode, item, visit) {\n        // FIXME do we need to do anything special for rerenders?\n        renderNode.element = renderListItem();\n        renderNode.cursorElement = null;\n        attachRenderNodeElementToDOM(renderNode, null);\n\n        if (item.isBlank) {\n          var cursorPlaceholder = renderCursorPlaceholder();\n          renderNode.element.appendChild(cursorPlaceholder);\n          renderNode.cursorElement = cursorPlaceholder;\n        } else {\n          var visitAll = true;\n          visit(renderNode, item.markers, visitAll);\n        }\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.MARKER_TYPE,\n      value: function value(renderNode, marker) {\n        var parentElement = undefined;\n\n        if (renderNode.prev) {\n          parentElement = getNextMarkerElement(renderNode.prev);\n        } else {\n          parentElement = renderNode.parent.element;\n        }\n\n        var _renderMarker = renderMarker(marker, parentElement, renderNode.prev);\n\n        var element = _renderMarker.element;\n        var markupElement = _renderMarker.markupElement;\n\n        renderNode.element = element;\n        renderNode.markupElement = markupElement;\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n      value: function value(renderNode, section) {\n        if (renderNode.element) {\n          if (renderNode.element.src !== section.src) {\n            renderNode.element.src = section.src;\n          }\n        } else {\n          var element = document.createElement('img');\n          element.src = section.src;\n          if (renderNode.prev) {\n            var previousElement = renderNode.prev.element;\n            var nextElement = previousElement.nextSibling;\n            if (nextElement) {\n              nextElement.parentNode.insertBefore(element, nextElement);\n            }\n          }\n          if (!element.parentNode) {\n            renderNode.parent.element.appendChild(element);\n          }\n          renderNode.element = element;\n        }\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.CARD_TYPE,\n      value: function value(renderNode, section) {\n        var originalElement = renderNode.element;\n        var editor = this.editor;\n        var options = this.options;\n\n        var card = this._findCard(section.name);\n\n        var _renderCard = renderCard();\n\n        var wrapper = _renderCard.wrapper;\n        var cardElement = _renderCard.cardElement;\n\n        renderNode.element = wrapper;\n        attachRenderNodeElementToDOM(renderNode, originalElement);\n\n        var cardNode = new _mobiledocKitModelsCardNode['default'](editor, card, section, cardElement, options);\n        renderNode.cardNode = cardNode;\n\n        var initialMode = section._initialMode;\n        cardNode[initialMode]();\n      }\n    }, {\n      key: _mobiledocKitModelsTypes.ATOM_TYPE,\n      value: function value(renderNode, atomModel) {\n        var parentElement = undefined;\n\n        if (renderNode.prev) {\n          parentElement = getNextMarkerElement(renderNode.prev);\n        } else {\n          parentElement = renderNode.parent.element;\n        }\n\n        var editor = this.editor;\n        var options = this.options;\n\n        var _renderAtom = renderAtom(atomModel, parentElement, renderNode.prev);\n\n        var wrapper = _renderAtom.wrapper;\n        var markupElement = _renderAtom.markupElement;\n        var atomElement = _renderAtom.atomElement;\n        var headTextNode = _renderAtom.headTextNode;\n        var tailTextNode = _renderAtom.tailTextNode;\n\n        var atom = this._findAtom(atomModel.name);\n\n        var atomNode = renderNode.atomNode;\n        if (!atomNode) {\n          // create new AtomNode\n          atomNode = new _mobiledocKitModelsAtomNode['default'](editor, atom, atomModel, atomElement, options);\n        } else {\n          // retarget atomNode to new atom element\n          atomNode.element = atomElement;\n        }\n\n        atomNode.render();\n\n        renderNode.atomNode = atomNode;\n        renderNode.element = wrapper;\n        renderNode.headTextNode = headTextNode;\n        renderNode.tailTextNode = tailTextNode;\n        renderNode.markupElement = markupElement;\n      }\n    }]);\n\n    return Visitor;\n  })();\n\n  var destroyHooks = (_destroyHooks = {}, _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.POST_TYPE, function () /*renderNode, post*/{\n    (0, _mobiledocKitUtilsAssert['default'])('post destruction is not supported by the renderer', false);\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (renderNode, section) {\n    removeRenderNodeSectionFromParent(renderNode, section);\n    removeRenderNodeElementFromParent(renderNode);\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (renderNode, section) {\n    removeRenderNodeSectionFromParent(renderNode, section);\n    removeRenderNodeElementFromParent(renderNode);\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (renderNode, li) {\n    removeRenderNodeSectionFromParent(renderNode, li);\n    removeRenderNodeElementFromParent(renderNode);\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKER_TYPE, function (renderNode, marker) {\n    // FIXME before we render marker, should delete previous renderNode's element\n    // and up until the next marker element\n\n    // If an atom throws during render we may end up later destroying a renderNode\n    // that has not rendered yet, so exit early here if so.\n    if (!renderNode.isRendered) {\n      return;\n    }\n    var markupElement = renderNode.markupElement;\n\n    if (marker.section) {\n      marker.section.markers.remove(marker);\n    }\n\n    if (markupElement.parentNode) {\n      // if no parentNode, the browser already removed this element\n      markupElement.parentNode.removeChild(markupElement);\n    }\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (renderNode, section) {\n    removeRenderNodeSectionFromParent(renderNode, section);\n    removeRenderNodeElementFromParent(renderNode);\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.CARD_TYPE, function (renderNode, section) {\n    if (renderNode.cardNode) {\n      renderNode.cardNode.teardown();\n    }\n    removeRenderNodeSectionFromParent(renderNode, section);\n    removeRenderNodeElementFromParent(renderNode);\n  }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.ATOM_TYPE, function (renderNode, atom) {\n    if (renderNode.atomNode) {\n      renderNode.atomNode.teardown();\n    }\n\n    // an atom is a kind of marker so just call its destroy hook vs copying here\n    destroyHooks[_mobiledocKitModelsTypes.MARKER_TYPE](renderNode, atom);\n  }), _destroyHooks);\n\n  // removes children from parentNode (a RenderNode) that are scheduled for removal\n  function removeDestroyedChildren(parentNode) {\n    var forceRemoval = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n    var child = parentNode.childNodes.head;\n    var nextChild = undefined,\n        method = undefined;\n    while (child) {\n      nextChild = child.next;\n      if (child.isRemoved || forceRemoval) {\n        removeDestroyedChildren(child, true);\n        method = child.postNode.type;\n        (0, _mobiledocKitUtilsAssert['default'])('editor-dom cannot destroy \"' + method + '\"', !!destroyHooks[method]);\n        destroyHooks[method](child, child.postNode);\n        parentNode.childNodes.remove(child);\n      }\n      child = nextChild;\n    }\n  }\n\n  // Find an existing render node for the given postNode, or\n  // create one, insert it into the tree, and return it\n  function lookupNode(renderTree, parentNode, postNode, previousNode) {\n    if (postNode.renderNode) {\n      return postNode.renderNode;\n    } else {\n      var renderNode = renderTree.buildRenderNode(postNode);\n      parentNode.childNodes.insertAfter(renderNode, previousNode);\n      return renderNode;\n    }\n  }\n\n  var Renderer = (function () {\n    function Renderer(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n      _classCallCheck(this, Renderer);\n\n      this.editor = editor;\n      this.visitor = new Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options);\n      this.nodes = [];\n      this.hasRendered = false;\n    }\n\n    _createClass(Renderer, [{\n      key: 'destroy',\n      value: function destroy() {\n        if (!this.hasRendered) {\n          return;\n        }\n        var renderNode = this.renderTree.rootNode;\n        var force = true;\n        removeDestroyedChildren(renderNode, force);\n      }\n    }, {\n      key: 'visit',\n      value: function visit(renderTree, parentNode, postNodes) {\n        var _this = this;\n\n        var visitAll = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];\n\n        var previousNode = undefined;\n        postNodes.forEach(function (postNode) {\n          var node = lookupNode(renderTree, parentNode, postNode, previousNode);\n          if (node.isDirty || visitAll) {\n            _this.nodes.push(node);\n          }\n          previousNode = node;\n        });\n      }\n    }, {\n      key: 'render',\n      value: function render(renderTree) {\n        var _this2 = this;\n\n        this.hasRendered = true;\n        this.renderTree = renderTree;\n        var renderNode = renderTree.rootNode;\n        var method = undefined,\n            postNode = undefined;\n\n        while (renderNode) {\n          removeDestroyedChildren(renderNode);\n          postNode = renderNode.postNode;\n\n          method = postNode.type;\n          (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]);\n          this.visitor[method](renderNode, postNode, function () {\n            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n              args[_key] = arguments[_key];\n            }\n\n            return _this2.visit.apply(_this2, [renderTree].concat(args));\n          });\n          renderNode.markClean();\n          renderNode = this.nodes.shift();\n        }\n      }\n    }]);\n\n    return Renderer;\n  })();\n\n  exports['default'] = Renderer;\n});","define('mobiledoc-kit/renderers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n  'use strict';\n\n  var _visitor;\n\n  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; }\n\n  var MOBILEDOC_VERSION = '0.2.0';\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n  exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n  var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n  exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n  var MOBILEDOC_LIST_SECTION_TYPE = 3;\n  exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n  var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n  exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n  var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n    opcodes.push(['openPost']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkupSection', node.tagName]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openListSection', node.tagName]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n    opcodes.push(['openListItem']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openImageSection', node.src]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n    opcodes.push(['openCardSection', node.name, node.payload]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n  }), _visitor);\n\n  var postOpcodeCompiler = {\n    openMarker: function openMarker(closeCount, value) {\n      this.markupMarkerIds = [];\n      this.markers.push([this.markupMarkerIds, closeCount, value || '']);\n    },\n    openMarkupSection: function openMarkupSection(tagName) {\n      this.markers = [];\n      this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n    },\n    openListSection: function openListSection(tagName) {\n      this.items = [];\n      this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n    },\n    openListItem: function openListItem() {\n      this.markers = [];\n      this.items.push(this.markers);\n    },\n    openImageSection: function openImageSection(url) {\n      this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n    },\n    openCardSection: function openCardSection(name, payload) {\n      this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, name, payload]);\n    },\n    openPost: function openPost() {\n      this.markerTypes = [];\n      this.sections = [];\n      this.result = {\n        version: MOBILEDOC_VERSION,\n        sections: [this.markerTypes, this.sections]\n      };\n    },\n    openMarkup: function openMarkup(tagName, attributes) {\n      var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n      this.markupMarkerIds.push(index);\n    },\n    _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n      if (!this._markerTypeCache) {\n        this._markerTypeCache = {};\n      }\n      var key = tagName + '-' + attributesArray.join('-');\n\n      var index = this._markerTypeCache[key];\n      if (index === undefined) {\n        var markerType = [tagName];\n        if (attributesArray.length) {\n          markerType.push(attributesArray);\n        }\n        this.markerTypes.push(markerType);\n\n        index = this.markerTypes.length - 1;\n        this._markerTypeCache[key] = index;\n      }\n\n      return index;\n    }\n  };\n\n  /**\n   * Render from post -> mobiledoc\n   */\n  exports['default'] = {\n    /**\n     * @param {Post}\n     * @return {Mobiledoc}\n     */\n    render: function render(post) {\n      var opcodes = [];\n      (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n      var compiler = Object.create(postOpcodeCompiler);\n      (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n      return compiler.result;\n    }\n  };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n  'use strict';\n\n  var _visitor;\n\n  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; }\n\n  var MOBILEDOC_VERSION = '0.3.1';\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n  exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n  var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n  exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n  var MOBILEDOC_LIST_SECTION_TYPE = 3;\n  exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n  var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n  exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n  var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n  exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n  var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n  exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n  var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n    opcodes.push(['openPost']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkupSection', node.tagName]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openListSection', node.tagName]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n    opcodes.push(['openListItem']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openImageSection', node.src]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n    opcodes.push(['openCardSection', node.name, node.payload]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n    opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _visitor);\n\n  var postOpcodeCompiler = {\n    openMarker: function openMarker(closeCount, value) {\n      this.markupMarkerIds = [];\n      this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n    },\n    openMarkupSection: function openMarkupSection(tagName) {\n      this.markers = [];\n      this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n    },\n    openListSection: function openListSection(tagName) {\n      this.items = [];\n      this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n    },\n    openListItem: function openListItem() {\n      this.markers = [];\n      this.items.push(this.markers);\n    },\n    openImageSection: function openImageSection(url) {\n      this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n    },\n    openCardSection: function openCardSection(name, payload) {\n      var index = this._addCardTypeIndex(name, payload);\n      this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n    },\n    openAtom: function openAtom(closeCount, name, value, payload) {\n      var index = this._addAtomTypeIndex(name, value, payload);\n      this.markupMarkerIds = [];\n      this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n    },\n    openPost: function openPost() {\n      this.atomTypes = [];\n      this.cardTypes = [];\n      this.markerTypes = [];\n      this.sections = [];\n      this.result = {\n        version: MOBILEDOC_VERSION,\n        atoms: this.atomTypes,\n        cards: this.cardTypes,\n        markups: this.markerTypes,\n        sections: this.sections\n      };\n    },\n    openMarkup: function openMarkup(tagName, attributes) {\n      var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n      this.markupMarkerIds.push(index);\n    },\n    _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n      var cardType = [cardName, payload];\n      this.cardTypes.push(cardType);\n      return this.cardTypes.length - 1;\n    },\n    _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n      var atomType = [atomName, atomValue, payload];\n      this.atomTypes.push(atomType);\n      return this.atomTypes.length - 1;\n    },\n    _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n      if (!this._markerTypeCache) {\n        this._markerTypeCache = {};\n      }\n      var key = tagName + '-' + attributesArray.join('-');\n\n      var index = this._markerTypeCache[key];\n      if (index === undefined) {\n        var markerType = [tagName];\n        if (attributesArray.length) {\n          markerType.push(attributesArray);\n        }\n        this.markerTypes.push(markerType);\n\n        index = this.markerTypes.length - 1;\n        this._markerTypeCache[key] = index;\n      }\n\n      return index;\n    }\n  };\n\n  /**\n   * Render from post -> mobiledoc\n   */\n  exports['default'] = {\n    /**\n     * @param {Post}\n     * @return {Mobiledoc}\n     */\n    render: function render(post) {\n      var opcodes = [];\n      (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n      var compiler = Object.create(postOpcodeCompiler);\n      (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n      return compiler.result;\n    }\n  };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n  'use strict';\n\n  var _visitor;\n\n  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; }\n\n  var MOBILEDOC_VERSION = '0.3.2';\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n  exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n  var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n  exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n  var MOBILEDOC_LIST_SECTION_TYPE = 3;\n  exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n  var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n  exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n  var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n  exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n  var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n  exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n  var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n    opcodes.push(['openPost']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkupSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openListSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n    opcodes.push(['openListItem']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openImageSection', node.src]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n    opcodes.push(['openCardSection', node.name, node.payload]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n    opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _visitor);\n\n  var postOpcodeCompiler = {\n    openMarker: function openMarker(closeCount, value) {\n      this.markupMarkerIds = [];\n      this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n    },\n    openMarkupSection: function openMarkupSection(tagName, attributes) {\n      this.markers = [];\n      if (attributes && attributes.length !== 0) {\n        this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]);\n      } else {\n        this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n      }\n    },\n    openListSection: function openListSection(tagName, attributes) {\n      this.items = [];\n      if (attributes && attributes.length !== 0) {\n        this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]);\n      } else {\n        this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n      }\n    },\n    openListItem: function openListItem() {\n      this.markers = [];\n      this.items.push(this.markers);\n    },\n    openImageSection: function openImageSection(url) {\n      this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n    },\n    openCardSection: function openCardSection(name, payload) {\n      var index = this._addCardTypeIndex(name, payload);\n      this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n    },\n    openAtom: function openAtom(closeCount, name, value, payload) {\n      var index = this._addAtomTypeIndex(name, value, payload);\n      this.markupMarkerIds = [];\n      this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n    },\n    openPost: function openPost() {\n      this.atomTypes = [];\n      this.cardTypes = [];\n      this.markerTypes = [];\n      this.sections = [];\n      this.result = {\n        version: MOBILEDOC_VERSION,\n        atoms: this.atomTypes,\n        cards: this.cardTypes,\n        markups: this.markerTypes,\n        sections: this.sections\n      };\n    },\n    openMarkup: function openMarkup(tagName, attributes) {\n      var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n      this.markupMarkerIds.push(index);\n    },\n    _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n      var cardType = [cardName, payload];\n      this.cardTypes.push(cardType);\n      return this.cardTypes.length - 1;\n    },\n    _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n      var atomType = [atomName, atomValue, payload];\n      this.atomTypes.push(atomType);\n      return this.atomTypes.length - 1;\n    },\n    _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n      if (!this._markerTypeCache) {\n        this._markerTypeCache = {};\n      }\n      var key = tagName + '-' + attributesArray.join('-');\n\n      var index = this._markerTypeCache[key];\n      if (index === undefined) {\n        var markerType = [tagName];\n        if (attributesArray.length) {\n          markerType.push(attributesArray);\n        }\n        this.markerTypes.push(markerType);\n\n        index = this.markerTypes.length - 1;\n        this._markerTypeCache[key] = index;\n      }\n\n      return index;\n    }\n  };\n\n  /**\n   * Render from post -> mobiledoc\n   */\n  exports['default'] = {\n    /**\n     * @param {Post}\n     * @return {Mobiledoc}\n     */\n    render: function render(post) {\n      var opcodes = [];\n      (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n      var compiler = Object.create(postOpcodeCompiler);\n      (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n      return compiler.result;\n    }\n  };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n  'use strict';\n\n  var _visitor;\n\n  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; }\n\n  var MOBILEDOC_VERSION = '0.3.0';\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n  exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n  var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n  exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n  var MOBILEDOC_LIST_SECTION_TYPE = 3;\n  exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n  var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n  exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n  var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n  exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n  var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n  exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n  var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n    opcodes.push(['openPost']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkupSection', node.tagName]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openListSection', node.tagName]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n    opcodes.push(['openListItem']);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n    opcodes.push(['openImageSection', node.src]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n    opcodes.push(['openCardSection', node.name, node.payload]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n    opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n  }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n    opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n    (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n  }), _visitor);\n\n  var postOpcodeCompiler = {\n    openMarker: function openMarker(closeCount, value) {\n      this.markupMarkerIds = [];\n      this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n    },\n    openMarkupSection: function openMarkupSection(tagName) {\n      this.markers = [];\n      this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n    },\n    openListSection: function openListSection(tagName) {\n      this.items = [];\n      this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n    },\n    openListItem: function openListItem() {\n      this.markers = [];\n      this.items.push(this.markers);\n    },\n    openImageSection: function openImageSection(url) {\n      this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n    },\n    openCardSection: function openCardSection(name, payload) {\n      var index = this._addCardTypeIndex(name, payload);\n      this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n    },\n    openAtom: function openAtom(closeCount, name, value, payload) {\n      var index = this._addAtomTypeIndex(name, value, payload);\n      this.markupMarkerIds = [];\n      this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n    },\n    openPost: function openPost() {\n      this.atomTypes = [];\n      this.cardTypes = [];\n      this.markerTypes = [];\n      this.sections = [];\n      this.result = {\n        version: MOBILEDOC_VERSION,\n        atoms: this.atomTypes,\n        cards: this.cardTypes,\n        markups: this.markerTypes,\n        sections: this.sections\n      };\n    },\n    openMarkup: function openMarkup(tagName, attributes) {\n      var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n      this.markupMarkerIds.push(index);\n    },\n    _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n      var cardType = [cardName, payload];\n      this.cardTypes.push(cardType);\n      return this.cardTypes.length - 1;\n    },\n    _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n      var atomType = [atomName, atomValue, payload];\n      this.atomTypes.push(atomType);\n      return this.atomTypes.length - 1;\n    },\n    _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n      if (!this._markerTypeCache) {\n        this._markerTypeCache = {};\n      }\n      var key = tagName + '-' + attributesArray.join('-');\n\n      var index = this._markerTypeCache[key];\n      if (index === undefined) {\n        var markerType = [tagName];\n        if (attributesArray.length) {\n          markerType.push(attributesArray);\n        }\n        this.markerTypes.push(markerType);\n\n        index = this.markerTypes.length - 1;\n        this._markerTypeCache[key] = index;\n      }\n\n      return index;\n    }\n  };\n\n  /**\n   * Render from post -> mobiledoc\n   */\n  exports['default'] = {\n    /**\n     * @param {Post}\n     * @return {Mobiledoc}\n     */\n    render: function render(post) {\n      var opcodes = [];\n      (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n      var compiler = Object.create(postOpcodeCompiler);\n      (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n      return compiler.result;\n    }\n  };\n});","define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION;\n\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  exports['default'] = {\n    render: function render(post, version) {\n      switch (version) {\n        case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n          return _mobiledocKitRenderersMobiledoc02['default'].render(post);\n        case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n          return _mobiledocKitRenderersMobiledoc03['default'].render(post);\n        case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n          return _mobiledocKitRenderersMobiledoc031['default'].render(post);\n        case undefined:\n        case null:\n        case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION:\n          return _mobiledocKitRenderersMobiledoc032['default'].render(post);\n        default:\n          (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false);\n      }\n    }\n  };\n});","define(\"mobiledoc-kit/utils/array-utils\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  function detect(enumerable, callback) {\n    if (enumerable.detect) {\n      return enumerable.detect(callback);\n    } else {\n      for (var i = 0; i < enumerable.length; i++) {\n        if (callback(enumerable[i])) {\n          return enumerable[i];\n        }\n      }\n    }\n  }\n\n  function any(enumerable, callback) {\n    if (enumerable.any) {\n      return enumerable.any(callback);\n    }\n\n    for (var i = 0; i < enumerable.length; i++) {\n      if (callback(enumerable[i])) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  function every(enumerable, callback) {\n    if (enumerable.every) {\n      return enumerable.every(callback);\n    }\n\n    for (var i = 0; i < enumerable.length; i++) {\n      if (!callback(enumerable[i])) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  function toArray(arrayLike) {\n    return Array.prototype.slice.call(arrayLike);\n  }\n\n  /**\n   * Useful for array-like things that aren't\n   * actually arrays, like NodeList\n   * @private\n   */\n  function forEach(enumerable, callback) {\n    if (enumerable.forEach) {\n      enumerable.forEach(callback);\n    } else {\n      for (var i = 0; i < enumerable.length; i++) {\n        callback(enumerable[i], i);\n      }\n    }\n  }\n\n  function filter(enumerable, conditionFn) {\n    var filtered = [];\n    forEach(enumerable, function (i) {\n      if (conditionFn(i)) {\n        filtered.push(i);\n      }\n    });\n    return filtered;\n  }\n\n  /**\n   * @return {Integer} the number of items that are the same, starting from the 0th index, in a and b\n   * @private\n   */\n  function commonItemLength(listA, listB) {\n    var offset = 0;\n    while (offset < listA.length && offset < listB.length) {\n      if (listA[offset] !== listB[offset]) {\n        break;\n      }\n      offset++;\n    }\n    return offset;\n  }\n\n  /**\n   * @return {Array} the items that are the same, starting from the 0th index, in a and b\n   * @private\n   */\n  function commonItems(listA, listB) {\n    var offset = 0;\n    while (offset < listA.length && offset < listB.length) {\n      if (listA[offset] !== listB[offset]) {\n        break;\n      }\n      offset++;\n    }\n    return listA.slice(0, offset);\n  }\n\n  // return new array without falsy items like ruby's `compact`\n  function compact(enumerable) {\n    return filter(enumerable, function (i) {\n      return !!i;\n    });\n  }\n\n  function reduce(enumerable, callback, initialValue) {\n    var previousValue = initialValue;\n    forEach(enumerable, function (val, index) {\n      previousValue = callback(previousValue, val, index);\n    });\n    return previousValue;\n  }\n\n  /**\n   * @param {Array} array of key1,value1,key2,value2,...\n   * @return {Object} {key1:value1, key2:value2, ...}\n   * @private\n   */\n  function kvArrayToObject(array) {\n    var obj = {};\n    for (var i = 0; i < array.length; i += 2) {\n      var key = array[i];\n      var value = array[i + 1];\n\n      obj[key] = value;\n    }\n    return obj;\n  }\n\n  function objectToSortedKVArray(obj) {\n    var keys = Object.keys(obj).sort();\n    var result = [];\n    keys.forEach(function (k) {\n      result.push(k);\n      result.push(obj[k]);\n    });\n    return result;\n  }\n\n  // check shallow equality of two non-nested arrays\n  function isArrayEqual(arr1, arr2) {\n    var l1 = arr1.length,\n        l2 = arr2.length;\n    if (l1 !== l2) {\n      return false;\n    }\n\n    for (var i = 0; i < l1; i++) {\n      if (arr1[i] !== arr2[i]) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  // return an object with only the valid keys\n  function filterObject(object) {\n    var validKeys = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n    var result = {};\n    forEach(filter(Object.keys(object), function (key) {\n      return validKeys.indexOf(key) !== -1;\n    }), function (key) {\n      return result[key] = object[key];\n    });\n    return result;\n  }\n\n  function contains(array, item) {\n    return array.indexOf(item) !== -1;\n  }\n\n  function values(object) {\n    return Object.keys(object).map(function (key) {\n      return object[key];\n    });\n  }\n\n  exports.detect = detect;\n  exports.forEach = forEach;\n  exports.any = any;\n  exports.every = every;\n  exports.filter = filter;\n  exports.commonItemLength = commonItemLength;\n  exports.commonItems = commonItems;\n  exports.compact = compact;\n  exports.reduce = reduce;\n  exports.objectToSortedKVArray = objectToSortedKVArray;\n  exports.kvArrayToObject = kvArrayToObject;\n  exports.isArrayEqual = isArrayEqual;\n  exports.toArray = toArray;\n  exports.filterObject = filterObject;\n  exports.contains = contains;\n  exports.values = values;\n});","define('mobiledoc-kit/utils/assert', ['exports', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitUtilsMobiledocError) {\n  'use strict';\n\n  exports['default'] = function (message, conditional) {\n    if (!conditional) {\n      throw new _mobiledocKitUtilsMobiledocError['default'](message);\n    }\n  };\n});","define('mobiledoc-kit/utils/browser', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = {\n    isMac: function isMac() {\n      return typeof window !== 'undefined' && window.navigator && /Mac/.test(window.navigator.platform);\n    },\n    isWin: function isWin() {\n      return typeof window !== 'undefined' && window.navigator && /Win/.test(window.navigator.platform);\n    }\n  };\n});","define('mobiledoc-kit/utils/characters', ['exports'], function (exports) {\n  'use strict';\n\n  var TAB = '\\t';\n  exports.TAB = TAB;\n  var ENTER = '\\n';\n  exports.ENTER = ENTER;\n  var SPACE = ' ';\n  exports.SPACE = SPACE;\n});","define('mobiledoc-kit/utils/compiler', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  exports.visit = visit;\n  exports.compile = compile;\n  exports.visitArray = visitArray;\n\n  function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n  function visit(visitor, node, opcodes) {\n    var method = node.type;\n    (0, _mobiledocKitUtilsAssert['default'])('Cannot visit unknown type ' + method, !!visitor[method]);\n    visitor[method](node, opcodes);\n  }\n\n  function compile(compiler, opcodes) {\n    for (var i = 0, l = opcodes.length; i < l; i++) {\n      var _opcodes$i = _toArray(opcodes[i]);\n\n      var method = _opcodes$i[0];\n\n      var params = _opcodes$i.slice(1);\n\n      var _length = params.length;\n      if (_length === 0) {\n        compiler[method].call(compiler);\n      } else if (_length === 1) {\n        compiler[method].call(compiler, params[0]);\n      } else if (_length === 2) {\n        compiler[method].call(compiler, params[0], params[1]);\n      } else {\n        compiler[method].apply(compiler, params);\n      }\n    }\n  }\n\n  function visitArray(visitor, nodes, opcodes) {\n    if (!nodes || nodes.length === 0) {\n      return;\n    }\n    (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n      visit(visitor, node, opcodes);\n    });\n  }\n});","define(\"mobiledoc-kit/utils/copy\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  function shallowCopyObject(object) {\n    var copy = {};\n    Object.keys(object).forEach(function (key) {\n      copy[key] = object[key];\n    });\n    return copy;\n  }\n\n  exports.shallowCopyObject = shallowCopyObject;\n});","define('mobiledoc-kit/utils/cursor', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/key'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKey) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n  exports.Range = _mobiledocKitUtilsCursorRange['default'];\n\n  var Cursor = (function () {\n    function Cursor(editor) {\n      _classCallCheck(this, Cursor);\n\n      this.editor = editor;\n      this.renderTree = editor._renderTree;\n      this.post = editor.post;\n    }\n\n    _createClass(Cursor, [{\n      key: 'clearSelection',\n      value: function clearSelection() {\n        (0, _mobiledocKitUtilsSelectionUtils.clearSelection)();\n      }\n\n      /**\n       * @return {Boolean} true when there is either a collapsed cursor in the\n       * editor's element or a selection that is contained in the editor's element\n       */\n    }, {\n      key: 'hasCursor',\n      value: function hasCursor() {\n        return this.editor.hasRendered && (this._hasCollapsedSelection() || this._hasSelection());\n      }\n    }, {\n      key: 'hasSelection',\n      value: function hasSelection() {\n        return this.editor.hasRendered && this._hasSelection();\n      }\n\n      /**\n       * @return {Boolean} Can the cursor be on this element?\n       */\n    }, {\n      key: 'isAddressable',\n      value: function isAddressable(element) {\n        var renderTree = this.renderTree;\n\n        var renderNode = renderTree.findRenderNodeFromElement(element);\n        if (renderNode && renderNode.postNode.isCardSection) {\n          var renderedElement = renderNode.element;\n\n          // card sections have addressable text nodes containing &zwnj;\n          // as their first and last child\n          if (element !== renderedElement && element !== renderedElement.firstChild && element !== renderedElement.lastChild) {\n            return false;\n          }\n        }\n\n        return !!renderNode;\n      }\n\n      /*\n       * @return {Range} Cursor#Range object\n       */\n    }, {\n      key: '_findNodeForPosition',\n      value: function _findNodeForPosition(position) {\n        var section = position.section;\n\n        var node = undefined,\n            offset = undefined;\n        if (section.isCardSection) {\n          offset = 0;\n          if (position.offset === 0) {\n            node = section.renderNode.element.firstChild;\n          } else {\n            node = section.renderNode.element.lastChild;\n          }\n        } else if (section.isBlank) {\n          node = section.renderNode.cursorElement;\n          offset = 0;\n        } else {\n          var marker = position.marker;\n          var offsetInMarker = position.offsetInMarker;\n\n          if (marker.isAtom) {\n            if (offsetInMarker > 0) {\n              // FIXME -- if there is a next marker, focus on it?\n              offset = 0;\n              node = marker.renderNode.tailTextNode;\n            } else {\n              offset = 0;\n              node = marker.renderNode.headTextNode;\n            }\n          } else {\n            node = marker.renderNode.element;\n            offset = offsetInMarker;\n          }\n        }\n\n        return { node: node, offset: offset };\n      }\n    }, {\n      key: 'selectRange',\n      value: function selectRange(range) {\n        if (range.isBlank) {\n          this.clearSelection();\n          return;\n        }\n\n        var head = range.head;\n        var tail = range.tail;\n        var direction = range.direction;\n\n        var _findNodeForPosition2 = this._findNodeForPosition(head);\n\n        var headNode = _findNodeForPosition2.node;\n        var headOffset = _findNodeForPosition2.offset;\n\n        var _findNodeForPosition3 = this._findNodeForPosition(tail);\n\n        var tailNode = _findNodeForPosition3.node;\n        var tailOffset = _findNodeForPosition3.offset;\n\n        this._moveToNode(headNode, headOffset, tailNode, tailOffset, direction);\n\n        // Firefox sometimes doesn't keep focus in the editor after adding a card\n        this.editor._ensureFocus();\n      }\n    }, {\n      key: 'selectedText',\n      value: function selectedText() {\n        // FIXME remove this\n        return this.selection.toString();\n      }\n\n      /**\n       * @param {textNode} node\n       * @param {integer} offset\n       * @param {textNode} endNode\n       * @param {integer} endOffset\n       * @param {integer} direction forward or backward, default forward\n       * @private\n       */\n    }, {\n      key: '_moveToNode',\n      value: function _moveToNode(node, offset, endNode, endOffset) {\n        var direction = arguments.length <= 4 || arguments[4] === undefined ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : arguments[4];\n\n        this.clearSelection();\n\n        if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n          var _ref = [endNode, endOffset, node, offset];\n          node = _ref[0];\n          offset = _ref[1];\n          endNode = _ref[2];\n          endOffset = _ref[3];\n        }\n\n        var range = document.createRange();\n        range.setStart(node, offset);\n        if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD && !!this.selection.extend) {\n          this.selection.addRange(range);\n          this.selection.extend(endNode, endOffset);\n        } else {\n          range.setEnd(endNode, endOffset);\n          this.selection.addRange(range);\n        }\n      }\n    }, {\n      key: '_hasSelection',\n      value: function _hasSelection() {\n        var element = this.editor.element;\n        var _selectionRange = this._selectionRange;\n\n        if (!_selectionRange || _selectionRange.collapsed) {\n          return false;\n        }\n\n        return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode) && (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.focusNode);\n      }\n    }, {\n      key: '_hasCollapsedSelection',\n      value: function _hasCollapsedSelection() {\n        var _selectionRange = this._selectionRange;\n\n        if (!_selectionRange) {\n          return false;\n        }\n\n        var element = this.editor.element;\n        return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode);\n      }\n    }, {\n      key: 'offsets',\n      get: function get() {\n        if (!this.hasCursor()) {\n          return _mobiledocKitUtilsCursorRange['default'].blankRange();\n        }\n\n        var selection = this.selection;\n        var renderTree = this.renderTree;\n\n        var parentNode = this.editor.element;\n        selection = (0, _mobiledocKitUtilsSelectionUtils.constrainSelectionTo)(selection, parentNode);\n\n        var _comparePosition = (0, _mobiledocKitUtilsSelectionUtils.comparePosition)(selection);\n\n        var headNode = _comparePosition.headNode;\n        var headOffset = _comparePosition.headOffset;\n        var tailNode = _comparePosition.tailNode;\n        var tailOffset = _comparePosition.tailOffset;\n        var direction = _comparePosition.direction;\n\n        var headPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, headNode, headOffset);\n        var tailPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, tailNode, tailOffset);\n\n        return new _mobiledocKitUtilsCursorRange['default'](headPosition, tailPosition, direction);\n      }\n    }, {\n      key: 'selection',\n      get: function get() {\n        return window.getSelection();\n      }\n    }, {\n      key: '_selectionRange',\n      get: function get() {\n        var selection = this.selection;\n\n        if (selection.rangeCount === 0) {\n          return null;\n        }\n        return selection.getRangeAt(0);\n      }\n    }]);\n\n    return Cursor;\n  })();\n\n  exports['default'] = Cursor;\n});","define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitModelsMarker, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsKey, _mobiledocKitUtilsCursorRange) {\n  'use strict';\n\n  var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n  var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n  // generated via http://xregexp.com/ to cover chars that \\w misses\n  // (new XRegExp('\\\\p{Alphabetic}|[0-9]|_|:')).toString()\n  var WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ﬀ-ﬆﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼＡ-Ｚａ-ｚｦ-ﾾￂ-ￇￊ-ￏￒ-ￗￚ-ￜ]|[0-9]|_|:/;\n\n  function findParentSectionFromNode(renderTree, node) {\n    var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) {\n      return renderNode.postNode.isSection;\n    });\n\n    return renderNode && renderNode.postNode;\n  }\n\n  function findOffsetInMarkerable(markerable, node, offset) {\n    var offsetInSection = 0;\n    var marker = markerable.markers.head;\n    while (marker) {\n      var markerNode = marker.renderNode.element;\n      if (markerNode === node) {\n        return offsetInSection + offset;\n      } else if (marker.isAtom) {\n        if (marker.renderNode.headTextNode === node) {\n          return offsetInSection;\n        } else if (marker.renderNode.tailTextNode === node) {\n          return offsetInSection + 1;\n        }\n      }\n\n      offsetInSection += marker.length;\n      marker = marker.next;\n    }\n\n    return offsetInSection;\n  }\n\n  function findOffsetInSection(section, node, offset) {\n    if (section.isMarkerable) {\n      return findOffsetInMarkerable(section, node, offset);\n    } else {\n      (0, _mobiledocKitUtilsAssert['default'])('findOffsetInSection must be called with markerable or card section', section.isCardSection);\n\n      var wrapperNode = section.renderNode.element;\n      var endTextNode = wrapperNode.lastChild;\n      if (node === endTextNode) {\n        return 1;\n      }\n      return 0;\n    }\n  }\n\n  var Position = undefined,\n      BlankPosition = undefined;\n\n  Position = (function () {\n    /**\n     * A position is a logical location (zero-width, or \"collapsed\") in a post,\n     * typically between two characters in a section.\n     * Two positions (a head and a tail) make up a {@link Range}.\n     * @constructor\n     */\n\n    function Position(section) {\n      var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n      var isBlank = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n      _classCallCheck(this, Position);\n\n      if (!isBlank) {\n        (0, _mobiledocKitUtilsAssert['default'])('Position must have a section that is addressable by the cursor', section && section.isLeafSection);\n        (0, _mobiledocKitUtilsAssert['default'])('Position must have numeric offset', typeof offset === 'number');\n      }\n\n      this.section = section;\n      this.offset = offset;\n      this.isBlank = isBlank;\n    }\n\n    /**\n     * @param {integer} x x-position in current viewport\n     * @param {integer} y y-position in current viewport\n     * @param {Editor} editor\n     * @return {Position|null}\n     */\n\n    _createClass(Position, [{\n      key: 'toRange',\n\n      /**\n       * Returns a range from this position to the given tail. If no explicit\n       * tail is given this returns a collapsed range focused on this position.\n       * @param {Position} [tail=this] The ending position\n       * @return {Range}\n       * @public\n       */\n      value: function toRange() {\n        var tail = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0];\n        var direction = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n        return new _mobiledocKitUtilsCursorRange['default'](this, tail, direction);\n      }\n    }, {\n      key: 'markerIn',\n\n      /**\n       * Returns the marker in `direction` from this position.\n       * If the position is in the middle of a marker, the direction is irrelevant.\n       * Otherwise, if the position is at a boundary between two markers, returns the\n       * marker to the left if `direction` === BACKWARD and the marker to the right\n       * if `direction` === FORWARD (assuming left-to-right text direction).\n       * @param {Direction}\n       * @return {Marker|undefined}\n       */\n      value: function markerIn(direction) {\n        if (!this.isMarkerable) {\n          return;\n        }\n\n        var marker = this.marker;\n        var offsetInMarker = this.offsetInMarker;\n\n        if (!marker) {\n          return;\n        }\n\n        if (offsetInMarker > 0 && offsetInMarker < marker.length) {\n          return marker;\n        } else if (offsetInMarker === 0) {\n          return direction === BACKWARD ? marker : marker.prev;\n        } else if (offsetInMarker === marker.length) {\n          return direction === FORWARD ? marker.next : marker;\n        }\n      }\n    }, {\n      key: 'isEqual',\n      value: function isEqual(position) {\n        return this.section === position.section && this.offset === position.offset;\n      }\n\n      /**\n       * @return {Boolean} If this position is at the head of the post\n       */\n    }, {\n      key: 'isHeadOfPost',\n      value: function isHeadOfPost() {\n        return this.move(BACKWARD).isEqual(this);\n      }\n\n      /**\n       * @return {Boolean} If this position is at the tail of the post\n       */\n    }, {\n      key: 'isTailOfPost',\n      value: function isTailOfPost() {\n        return this.move(FORWARD).isEqual(this);\n      }\n\n      /**\n       * @return {Boolean} If this position is at the head of its section\n       */\n    }, {\n      key: 'isHead',\n      value: function isHead() {\n        return this.isEqual(this.section.headPosition());\n      }\n\n      /**\n       * @return {Boolean} If this position is at the tail of its section\n       */\n    }, {\n      key: 'isTail',\n      value: function isTail() {\n        return this.isEqual(this.section.tailPosition());\n      }\n\n      /**\n       * Move the position 1 unit in `direction`.\n       *\n       * @param {Number} units to move. > 0 moves right, < 0 moves left\n       * @return {Position} Return a new position one unit in the given\n       * direction. If the position is moving left and at the beginning of the post,\n       * the same position will be returned. Same if the position is moving right and\n       * at the end of the post.\n       */\n    }, {\n      key: 'move',\n      value: function move(units) {\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Position#move', typeof units === 'number');\n\n        if (units < 0) {\n          return this.moveLeft().move(++units);\n        } else if (units > 0) {\n          return this.moveRight().move(--units);\n        } else {\n          return this;\n        }\n      }\n\n      /**\n       * @param {Number} direction (FORWARD or BACKWARD)\n       * @return {Position} The result of moving 1 \"word\" unit in `direction`\n       */\n    }, {\n      key: 'moveWord',\n      value: function moveWord(direction) {\n        var isPostBoundary = direction === BACKWARD ? this.isHeadOfPost() : this.isTailOfPost();\n        if (isPostBoundary) {\n          return this;\n        }\n\n        if (!this.isMarkerable) {\n          return this.move(direction);\n        }\n\n        var pos = this;\n\n        // Helper fn to check if the pos is at the `dir` boundary of its section\n        var isBoundary = function isBoundary(pos, dir) {\n          return dir === BACKWARD ? pos.isHead() : pos.isTail();\n        };\n        // Get the char at this position (looking forward/right)\n        var getChar = function getChar(pos) {\n          var marker = pos.marker;\n          var offsetInMarker = pos.offsetInMarker;\n\n          return marker.charAt(offsetInMarker);\n        };\n        // Get the char in `dir` at this position\n        var peekChar = function peekChar(pos, dir) {\n          return dir === BACKWARD ? getChar(pos.move(BACKWARD)) : getChar(pos);\n        };\n        // Whether there is an atom in `dir` from this position\n        var isAtom = function isAtom(pos, dir) {\n          // Special case when position is at end, the marker associated with it is\n          // the marker to its left. Normally `pos#marker` is the marker to the right of the pos's offset.\n          if (dir === BACKWARD && pos.isTail() && pos.marker.isAtom) {\n            return true;\n          }\n          return dir === BACKWARD ? pos.move(BACKWARD).marker.isAtom : pos.marker.isAtom;\n        };\n\n        if (isBoundary(pos, direction)) {\n          // extend movement into prev/next section\n          return pos.move(direction).moveWord(direction);\n        }\n\n        var seekWord = function seekWord(pos) {\n          return !isBoundary(pos, direction) && !isAtom(pos, direction) && !WORD_CHAR_REGEX.test(peekChar(pos, direction));\n        };\n\n        // move(dir) while we are seeking the first word char\n        while (seekWord(pos)) {\n          pos = pos.move(direction);\n        }\n\n        if (isAtom(pos, direction)) {\n          return pos.move(direction);\n        }\n\n        var seekBoundary = function seekBoundary(pos) {\n          return !isBoundary(pos, direction) && !isAtom(pos, direction) && WORD_CHAR_REGEX.test(peekChar(pos, direction));\n        };\n\n        // move(dir) while we are seeking the first boundary position\n        while (seekBoundary(pos)) {\n          pos = pos.move(direction);\n        }\n\n        return pos;\n      }\n\n      /**\n       * The position to the left of this position.\n       * If this position is the post's headPosition it returns itself.\n       * @return {Position}\n       * @private\n       */\n    }, {\n      key: 'moveLeft',\n      value: function moveLeft() {\n        if (this.isHead()) {\n          var prev = this.section.previousLeafSection();\n          return prev ? prev.tailPosition() : this;\n        } else {\n          var offset = this.offset - 1;\n          if (this.isMarkerable && this.marker) {\n            var code = this.marker.value.charCodeAt(offset);\n            if (code >= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[1]) {\n              offset = offset - 1;\n            }\n          }\n          return new Position(this.section, offset);\n        }\n      }\n\n      /**\n       * The position to the right of this position.\n       * If this position is the post's tailPosition it returns itself.\n       * @return {Position}\n       * @private\n       */\n    }, {\n      key: 'moveRight',\n      value: function moveRight() {\n        if (this.isTail()) {\n          var next = this.section.nextLeafSection();\n          return next ? next.headPosition() : this;\n        } else {\n          var offset = this.offset + 1;\n          if (this.isMarkerable && this.marker) {\n            var code = this.marker.value.charCodeAt(offset - 1);\n            if (code >= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[1]) {\n              offset = offset + 1;\n            }\n          }\n          return new Position(this.section, offset);\n        }\n      }\n    }, {\n      key: 'leafSectionIndex',\n      get: function get() {\n        var _this = this;\n\n        var post = this.section.post;\n        var leafSectionIndex = undefined;\n        post.walkAllLeafSections(function (section, index) {\n          if (section === _this.section) {\n            leafSectionIndex = index;\n          }\n        });\n        return leafSectionIndex;\n      }\n    }, {\n      key: 'isMarkerable',\n      get: function get() {\n        return this.section && this.section.isMarkerable;\n      }\n\n      /**\n       * Returns the marker at this position, in the backward direction\n       * (i.e., the marker to the left of the cursor if the cursor is on a marker boundary and text is left-to-right)\n       * @return {Marker|undefined}\n       */\n    }, {\n      key: 'marker',\n      get: function get() {\n        return this.isMarkerable && this.markerPosition.marker;\n      }\n    }, {\n      key: 'offsetInMarker',\n      get: function get() {\n        return this.markerPosition.offset;\n      }\n    }, {\n      key: 'markerPosition',\n\n      /**\n       * @private\n       */\n      get: function get() {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot get markerPosition without a section', !!this.section);\n        (0, _mobiledocKitUtilsAssert['default'])('cannot get markerPosition of a non-markerable', !!this.section.isMarkerable);\n        return this.section.markerPositionAtOffset(this.offset);\n      }\n    }], [{\n      key: 'atPoint',\n      value: function atPoint(x, y, editor) {\n        var _renderTree = editor._renderTree;\n        var rootElement = editor.element;\n\n        var elementFromPoint = document.elementFromPoint(x, y);\n        if (!(0, _mobiledocKitUtilsDomUtils.containsNode)(rootElement, elementFromPoint)) {\n          return;\n        }\n\n        var _findOffsetInNode = (0, _mobiledocKitUtilsSelectionUtils.findOffsetInNode)(elementFromPoint, { left: x, top: y });\n\n        var node = _findOffsetInNode.node;\n        var offset = _findOffsetInNode.offset;\n\n        return Position.fromNode(_renderTree, node, offset);\n      }\n    }, {\n      key: 'blankPosition',\n      value: function blankPosition() {\n        return new BlankPosition();\n      }\n    }, {\n      key: 'fromNode',\n      value: function fromNode(renderTree, node, offset) {\n        if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n          return Position.fromTextNode(renderTree, node, offset);\n        } else {\n          return Position.fromElementNode(renderTree, node, offset);\n        }\n      }\n    }, {\n      key: 'fromTextNode',\n      value: function fromTextNode(renderTree, textNode, offsetInNode) {\n        var renderNode = renderTree.getElementRenderNode(textNode);\n        var section = undefined,\n            offsetInSection = undefined;\n\n        if (renderNode) {\n          var marker = renderNode.postNode;\n          section = marker.section;\n\n          (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for mapped text node \"' + textNode.textContent + '\"', !!section);\n          offsetInSection = section.offsetOfMarker(marker, offsetInNode);\n        } else {\n          // all text nodes should be rendered by markers except:\n          //   * text nodes inside cards\n          //   * text nodes created by the browser during text input\n          // both of these should have rendered parent sections, though\n          section = findParentSectionFromNode(renderTree, textNode);\n          (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for un-mapped text node \"' + textNode.textContent + '\"', !!section);\n\n          offsetInSection = findOffsetInSection(section, textNode, offsetInNode);\n        }\n\n        return new Position(section, offsetInSection);\n      }\n    }, {\n      key: 'fromElementNode',\n      value: function fromElementNode(renderTree, elementNode, offset) {\n        var position = undefined;\n\n        // The browser may change the reported selection to equal the editor's root\n        // element if the user clicks an element that is immediately removed,\n        // which can happen when clicking to remove a card.\n        if (elementNode === renderTree.rootElement) {\n          var post = renderTree.rootNode.postNode;\n          position = offset === 0 ? post.headPosition() : post.tailPosition();\n        } else {\n          var section = findParentSectionFromNode(renderTree, elementNode);\n          (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section from element node', !!section);\n\n          if (section.isCardSection) {\n            // Selections in cards are usually made on a text node\n            // containing a &zwnj;  on one side or the other of the card but\n            // some scenarios (Firefox) will result in selecting the\n            // card's wrapper div. If the offset is 2 we've selected\n            // the final zwnj and should consider the cursor at the\n            // end of the card (offset 1). Otherwise,  the cursor is at\n            // the start of the card\n            position = offset < 2 ? section.headPosition() : section.tailPosition();\n          } else {\n\n            // In Firefox it is possible for the cursor to be on an atom's wrapper\n            // element. (In Chrome/Safari, the browser corrects this to be on\n            // one of the text nodes surrounding the wrapper).\n            // This code corrects for when the browser reports the cursor position\n            // to be on the wrapper element itself\n            var renderNode = renderTree.getElementRenderNode(elementNode);\n            var postNode = renderNode && renderNode.postNode;\n            if (postNode && postNode.isAtom) {\n              var sectionOffset = section.offsetOfMarker(postNode);\n              if (offset > 1) {\n                // we are on the tail side of the atom\n                sectionOffset += postNode.length;\n              }\n              position = new Position(section, sectionOffset);\n            } else if (offset >= elementNode.childNodes.length) {\n\n              // This is to deal with how Firefox handles triple-click selections.\n              // See https://stackoverflow.com/a/21234837/1269194 for an\n              // explanation.\n              position = section.tailPosition();\n            } else {\n              // The offset is 0 if the cursor is on a non-atom-wrapper element node\n              // (e.g., a <br> tag in a blank markup section)\n              position = section.headPosition();\n            }\n          }\n        }\n\n        return position;\n      }\n    }]);\n\n    return Position;\n  })();\n\n  BlankPosition = (function (_Position) {\n    _inherits(BlankPosition, _Position);\n\n    function BlankPosition() {\n      _classCallCheck(this, BlankPosition);\n\n      _get(Object.getPrototypeOf(BlankPosition.prototype), 'constructor', this).call(this, null, 0, true);\n    }\n\n    _createClass(BlankPosition, [{\n      key: 'isEqual',\n      value: function isEqual(other) {\n        return other && other.isBlank;\n      }\n    }, {\n      key: 'toRange',\n      value: function toRange() {\n        return _mobiledocKitUtilsCursorRange['default'].blankRange();\n      }\n    }, {\n      key: 'isHeadOfPost',\n      value: function isHeadOfPost() {\n        return false;\n      }\n    }, {\n      key: 'isTailOfPost',\n      value: function isTailOfPost() {\n        return false;\n      }\n    }, {\n      key: 'isHead',\n      value: function isHead() {\n        return false;\n      }\n    }, {\n      key: 'isTail',\n      value: function isTail() {\n        return false;\n      }\n    }, {\n      key: 'move',\n      value: function move() {\n        return this;\n      }\n    }, {\n      key: 'moveWord',\n      value: function moveWord() {\n        return this;\n      }\n    }, {\n      key: 'leafSectionIndex',\n      get: function get() {\n        (0, _mobiledocKitUtilsAssert['default'])('must implement get leafSectionIndex', false);\n      }\n    }, {\n      key: 'isMarkerable',\n      get: function get() {\n        return false;\n      }\n    }, {\n      key: 'marker',\n      get: function get() {\n        return false;\n      }\n    }, {\n      key: 'markerPosition',\n      get: function get() {\n        return {};\n      }\n    }]);\n\n    return BlankPosition;\n  })(Position);\n\n  exports['default'] = Position;\n});","define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsKey, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /**\n   * A logical range of a {@link Post}.\n   * Usually an instance of Range will be read from the {@link Editor#range} property,\n   * but it may be useful to instantiate a range directly when programmatically modifying a Post.\n   */\n\n  var Range = (function () {\n    /**\n     * @param {Position} head\n     * @param {Position} [tail=head]\n     * @param {Direction} [direction=null]\n     * @return {Range}\n     * @private\n     */\n\n    function Range(head) {\n      var tail = arguments.length <= 1 || arguments[1] === undefined ? head : arguments[1];\n      var direction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n      return (function () {\n        _classCallCheck(this, Range);\n\n        /** @property {Position} head */\n        this.head = head;\n\n        /** @property {Position} tail */\n        this.tail = tail;\n\n        /** @property {Direction} direction */\n        this.direction = direction;\n      }).apply(this, arguments);\n    }\n\n    /**\n     * Shorthand to create a new range from a section(s) and offset(s).\n     * When given only a head section and offset, creates a collapsed range.\n     * @param {Section} headSection\n     * @param {number} headOffset\n     * @param {Section} [tailSection=headSection]\n     * @param {number} [tailOffset=headOffset]\n     * @param {Direction} [direction=null]\n     * @return {Range}\n     */\n\n    _createClass(Range, [{\n      key: 'trimTo',\n\n      /**\n       * @param {Markerable} section\n       * @return {Range} A range that is constrained to only the part that\n       * includes the section.\n       * FIXME -- if the section isn't the head or tail, it's assumed to be\n       * wholly contained. It's possible to call `trimTo` with a selection that is\n       * outside of the range, though, which would invalidate that assumption.\n       * There's no efficient way to determine if a section is within a range, yet.\n       * @private\n       */\n      value: function trimTo(section) {\n        var length = section.length;\n\n        var headOffset = section === this.head.section ? Math.min(this.head.offset, length) : 0;\n        var tailOffset = section === this.tail.section ? Math.min(this.tail.offset, length) : length;\n\n        return Range.create(section, headOffset, section, tailOffset);\n      }\n\n      /**\n       * Expands the range 1 unit in the given direction\n       * If the range is expandable in the given direction, always returns a\n       * non-collapsed range.\n       * @param {Number} units If units is > 0, the range is extended to the right,\n       *                 otherwise range is extended to the left.\n       * @return {Range}\n       * @public\n       */\n    }, {\n      key: 'extend',\n      value: function extend(units) {\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Range#extend', typeof units === 'number');\n\n        if (units === 0) {\n          return this;\n        }\n\n        var head = this.head;\n        var tail = this.tail;\n        var currentDirection = this.direction;\n\n        switch (currentDirection) {\n          case _mobiledocKitUtilsKey.DIRECTION.FORWARD:\n            return new Range(head, tail.move(units), currentDirection);\n          case _mobiledocKitUtilsKey.DIRECTION.BACKWARD:\n            return new Range(head.move(units), tail, currentDirection);\n          default:\n            {\n              var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n              return new Range(head, tail, newDirection).extend(units);\n            }\n        }\n      }\n\n      /**\n       * Moves this range 1 unit in the given direction.\n       * If the range is collapsed, returns a collapsed range shifted by 1 unit,\n       * otherwise collapses this range to the position at the `direction` end of the range.\n       * Always returns a collapsed range.\n       * @param {Direction} direction\n       * @return {Range}\n       * @public\n       */\n    }, {\n      key: 'move',\n      value: function move(direction) {\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass DIRECTION.FORWARD (' + _mobiledocKitUtilsKey.DIRECTION.FORWARD + ') or DIRECTION.BACKWARD (' + _mobiledocKitUtilsKey.DIRECTION.BACKWARD + ') to Range#move', direction === _mobiledocKitUtilsKey.DIRECTION.FORWARD || direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD);\n\n        var focusedPosition = this.focusedPosition;\n        var isCollapsed = this.isCollapsed;\n\n        if (isCollapsed) {\n          return new Range(focusedPosition.move(direction));\n        } else {\n          return this._collapse(direction);\n        }\n      }\n\n      /**\n       * expand a range to all markers matching a given check\n       *\n       * @param {Function} detectMarker\n       * @return {Range} The expanded range\n       *\n       * @public\n       */\n    }, {\n      key: 'expandByMarker',\n      value: function expandByMarker(detectMarker) {\n        var head = this.head;\n        var tail = this.tail;\n        var direction = this.direction;\n        var headSection = head.section;\n\n        if (headSection !== tail.section) {\n          throw new Error('#expandByMarker does not work across sections. Perhaps you should confirm the range is collapsed');\n        }\n\n        var firstNotMatchingDetect = function firstNotMatchingDetect(i) {\n          return !detectMarker(i);\n        };\n\n        var headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true);\n        if (!headMarker && detectMarker(headSection.markers.head)) {\n          headMarker = headSection.markers.head;\n        } else {\n          headMarker = headMarker.next || head.marker;\n        }\n        var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker));\n\n        var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker);\n        if (!tailMarker && detectMarker(headSection.markers.tail)) {\n          tailMarker = headSection.markers.tail;\n        } else {\n          tailMarker = tailMarker.prev || tail.marker;\n        }\n        var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length);\n\n        return headPosition.toRange(tailPosition, direction);\n      }\n    }, {\n      key: '_collapse',\n      value: function _collapse(direction) {\n        return new Range(direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail);\n      }\n    }, {\n      key: 'isEqual',\n      value: function isEqual(other) {\n        return other && this.head.isEqual(other.head) && this.tail.isEqual(other.tail);\n      }\n    }, {\n      key: 'focusedPosition',\n      get: function get() {\n        return this.direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail;\n      }\n    }, {\n      key: 'isBlank',\n      get: function get() {\n        return this.head.isBlank && this.tail.isBlank;\n      }\n\n      // \"legacy\" APIs\n    }, {\n      key: 'headSection',\n      get: function get() {\n        return this.head.section;\n      }\n    }, {\n      key: 'tailSection',\n      get: function get() {\n        return this.tail.section;\n      }\n    }, {\n      key: 'headSectionOffset',\n      get: function get() {\n        return this.head.offset;\n      }\n    }, {\n      key: 'tailSectionOffset',\n      get: function get() {\n        return this.tail.offset;\n      }\n    }, {\n      key: 'isCollapsed',\n      get: function get() {\n        return this.head.isEqual(this.tail);\n      }\n    }, {\n      key: 'headMarker',\n      get: function get() {\n        return this.head.marker;\n      }\n    }, {\n      key: 'tailMarker',\n      get: function get() {\n        return this.tail.marker;\n      }\n    }, {\n      key: 'headMarkerOffset',\n      get: function get() {\n        return this.head.offsetInMarker;\n      }\n    }, {\n      key: 'tailMarkerOffset',\n      get: function get() {\n        return this.tail.offsetInMarker;\n      }\n    }], [{\n      key: 'create',\n      value: function create(headSection, headOffset) {\n        var tailSection = arguments.length <= 2 || arguments[2] === undefined ? headSection : arguments[2];\n        var tailOffset = arguments.length <= 3 || arguments[3] === undefined ? headOffset : arguments[3];\n        var direction = arguments.length <= 4 || arguments[4] === undefined ? null : arguments[4];\n        return (function () {\n          return new Range(new _mobiledocKitUtilsCursorPosition['default'](headSection, headOffset), new _mobiledocKitUtilsCursorPosition['default'](tailSection, tailOffset), direction);\n        })();\n      }\n    }, {\n      key: 'blankRange',\n      value: function blankRange() {\n        return new Range(_mobiledocKitUtilsCursorPosition['default'].blankPosition(), _mobiledocKitUtilsCursorPosition['default'].blankPosition());\n      }\n    }]);\n\n    return Range;\n  })();\n\n  exports['default'] = Range;\n});","define(\"mobiledoc-kit/utils/deprecate\", [\"exports\"], function (exports) {\n  /**\n   * Usage:\n   * Without a conditional, always prints deprecate message:\n   *   `deprecate('This is deprecated')`\n   *\n   * Conditional deprecation, works similarly to `assert`, prints deprecation if\n   * conditional is false:\n   *   `deprecate('Deprecated only if foo !== bar', foo === bar)`\n   */\n  \"use strict\";\n\n  exports[\"default\"] = deprecate;\n\n  function deprecate(message) {\n    var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n    if (!conditional) {\n      // eslint-disable-next-line no-console\n      console.log(\"[mobiledoc-kit] [DEPRECATED]: \" + message);\n    }\n  }\n});","define('mobiledoc-kit/utils/dom-utils', ['exports', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsArrayUtils) {\n  'use strict';\n\n  var NODE_TYPES = {\n    ELEMENT: 1,\n    TEXT: 3,\n    COMMENT: 8\n  };\n\n  exports.NODE_TYPES = NODE_TYPES;\n  function isTextNode(node) {\n    return node.nodeType === NODE_TYPES.TEXT;\n  }\n\n  function isCommentNode(node) {\n    return node.nodeType === NODE_TYPES.COMMENT;\n  }\n\n  function isElementNode(node) {\n    return node.nodeType === NODE_TYPES.ELEMENT;\n  }\n\n  // perform a pre-order tree traversal of the dom, calling `callbackFn(node)`\n  // for every node for which `conditionFn(node)` is true\n  function walkDOM(topNode) {\n    var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n    var conditionFn = arguments.length <= 2 || arguments[2] === undefined ? function () {\n      return true;\n    } : arguments[2];\n\n    var currentNode = topNode;\n\n    if (conditionFn(currentNode)) {\n      callbackFn(currentNode);\n    }\n\n    currentNode = currentNode.firstChild;\n\n    while (currentNode) {\n      walkDOM(currentNode, callbackFn, conditionFn);\n      currentNode = currentNode.nextSibling;\n    }\n  }\n\n  function walkTextNodes(topNode) {\n    var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n\n    var conditionFn = function conditionFn(node) {\n      return isTextNode(node);\n    };\n    walkDOM(topNode, callbackFn, conditionFn);\n  }\n\n  function clearChildNodes(element) {\n    while (element.childNodes.length) {\n      element.removeChild(element.childNodes[0]);\n    }\n  }\n\n  /**\n   * @return {Boolean} true when the child node is contained or the same as\n   * (e.g., inclusive containment)  the parent node\n   *  see https://github.com/webmodules/node-contains/blob/master/index.js\n   *  Mimics the behavior of `Node.contains`, which is broken in IE 10\n   *  @private\n   */\n  function containsNode(parentNode, childNode) {\n    if (parentNode === childNode) {\n      return true;\n    }\n    var position = parentNode.compareDocumentPosition(childNode);\n    return !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY);\n  }\n\n  /**\n   * converts the element's NamedNodeMap of attrs into\n   * an object with key-value pairs\n   * @param {DOMNode} element\n   * @return {Object} key-value pairs\n   * @private\n   */\n  function getAttributes(element) {\n    var result = {};\n    if (element.hasAttributes()) {\n      (0, _mobiledocKitUtilsArrayUtils.forEach)(element.attributes, function (_ref) {\n        var name = _ref.name;\n        var value = _ref.value;\n\n        result[name] = value;\n      });\n    }\n    return result;\n  }\n\n  function addClassName(element, className) {\n    element.classList.add(className);\n  }\n\n  function removeClassName(element, className) {\n    element.classList.remove(className);\n  }\n\n  function normalizeTagName(tagName) {\n    return tagName.toLowerCase();\n  }\n\n  function parseHTML(html) {\n    var div = document.createElement('div');\n    div.innerHTML = html;\n    return div;\n  }\n\n  function serializeHTML(node) {\n    var div = document.createElement('div');\n    div.appendChild(node);\n    return div.innerHTML;\n  }\n\n  exports.containsNode = containsNode;\n  exports.clearChildNodes = clearChildNodes;\n  exports.getAttributes = getAttributes;\n  exports.walkDOM = walkDOM;\n  exports.walkTextNodes = walkTextNodes;\n  exports.addClassName = addClassName;\n  exports.removeClassName = removeClassName;\n  exports.normalizeTagName = normalizeTagName;\n  exports.isTextNode = isTextNode;\n  exports.isCommentNode = isCommentNode;\n  exports.isElementNode = isElementNode;\n  exports.parseHTML = parseHTML;\n  exports.serializeHTML = serializeHTML;\n});","define('mobiledoc-kit/utils/element-map', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  // start at one to make the falsy semantics easier\n  var uuidGenerator = 1;\n\n  var ElementMap = (function () {\n    function ElementMap() {\n      _classCallCheck(this, ElementMap);\n\n      this._map = {};\n    }\n\n    _createClass(ElementMap, [{\n      key: 'set',\n      value: function set(key, value) {\n        var uuid = key._uuid;\n        if (!uuid) {\n          key._uuid = uuid = '' + uuidGenerator++;\n        }\n        this._map[uuid] = value;\n      }\n    }, {\n      key: 'get',\n      value: function get(key) {\n        if (key._uuid) {\n          return this._map[key._uuid];\n        }\n        return null;\n      }\n    }, {\n      key: 'remove',\n      value: function remove(key) {\n        (0, _mobiledocKitUtilsAssert['default'])('tried to fetch a value for an element not seen before', !!key._uuid);\n        delete this._map[key._uuid];\n      }\n    }]);\n\n    return ElementMap;\n  })();\n\n  exports['default'] = ElementMap;\n});","define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils) {\n  'use strict';\n\n  function getEventTargetMatchingTag(tagName, target, container) {\n    tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n    // Traverses up DOM from an event target to find the node matching specifed tag\n    while (target && target !== container) {\n      if ((0, _mobiledocKitUtilsDomUtils.normalizeTagName)(target.tagName) === tagName) {\n        return target;\n      }\n      target = target.parentNode;\n    }\n  }\n\n  function getElementRelativeOffset(element) {\n    var offset = { left: 0, top: -window.pageYOffset };\n    var offsetParent = element.offsetParent;\n    var offsetParentPosition = window.getComputedStyle(offsetParent).position;\n    var offsetParentRect;\n\n    if (offsetParentPosition === 'relative') {\n      offsetParentRect = offsetParent.getBoundingClientRect();\n      offset.left = offsetParentRect.left;\n      offset.top = offsetParentRect.top;\n    }\n    return offset;\n  }\n\n  function getElementComputedStyleNumericProp(element, prop) {\n    return parseFloat(window.getComputedStyle(element)[prop]);\n  }\n\n  function positionElementToRect(element, rect, topOffset, leftOffset) {\n    var relativeOffset = getElementRelativeOffset(element);\n    var style = element.style;\n    var round = Math.round;\n    var left, top;\n\n    topOffset = topOffset || 0;\n    leftOffset = leftOffset || 0;\n    left = round(rect.left - relativeOffset.left - leftOffset);\n    top = round(rect.top - relativeOffset.top - topOffset);\n    style.left = left + 'px';\n    style.top = top + 'px';\n    return { left: left, top: top };\n  }\n\n  function positionElementHorizontallyCenteredToRect(element, rect, topOffset) {\n    var horizontalCenter = element.offsetWidth / 2 - rect.width / 2;\n    return positionElementToRect(element, rect, topOffset, horizontalCenter);\n  }\n\n  function positionElementCenteredBelow(element, belowElement) {\n    var elementMargin = getElementComputedStyleNumericProp(element, 'marginTop');\n    return positionElementHorizontallyCenteredToRect(element, belowElement.getBoundingClientRect(), -element.offsetHeight - elementMargin);\n  }\n\n  function setData(element, name, value) {\n    if (element.dataset) {\n      element.dataset[name] = value;\n    } else {\n      var dataName = (0, _mobiledocKitUtilsStringUtils.dasherize)(name);\n      return element.setAttribute(dataName, value);\n    }\n  }\n\n  function whenElementIsNotInDOM(element, callback) {\n    var isCanceled = false;\n    var observerFn = function observerFn() {\n      if (isCanceled) {\n        return;\n      }\n      if (!element.parentNode) {\n        callback();\n      } else {\n        window.requestAnimationFrame(observerFn);\n      }\n    };\n    observerFn();\n    return { cancel: function cancel() {\n        return isCanceled = true;\n      } };\n  }\n\n  exports.setData = setData;\n  exports.getEventTargetMatchingTag = getEventTargetMatchingTag;\n  exports.getElementRelativeOffset = getElementRelativeOffset;\n  exports.getElementComputedStyleNumericProp = getElementComputedStyleNumericProp;\n  exports.positionElementToRect = positionElementToRect;\n  exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect;\n  exports.positionElementCenteredBelow = positionElementCenteredBelow;\n  exports.whenElementIsNotInDOM = whenElementIsNotInDOM;\n});","define('mobiledoc-kit/utils/environment', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = {\n    hasDOM: function hasDOM() {\n      return typeof document !== 'undefined';\n    }\n  };\n});","define(\"mobiledoc-kit/utils/fixed-queue\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n  var FixedQueue = (function () {\n    function FixedQueue() {\n      var length = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\n      _classCallCheck(this, FixedQueue);\n\n      this._maxLength = length;\n      this._items = [];\n    }\n\n    _createClass(FixedQueue, [{\n      key: \"pop\",\n      value: function pop() {\n        return this._items.pop();\n      }\n    }, {\n      key: \"push\",\n      value: function push(item) {\n        this._items.push(item);\n        if (this.length > this._maxLength) {\n          this._items.shift();\n        }\n      }\n    }, {\n      key: \"clear\",\n      value: function clear() {\n        this._items = [];\n      }\n    }, {\n      key: \"toArray\",\n      value: function toArray() {\n        return this._items;\n      }\n    }, {\n      key: \"length\",\n      get: function get() {\n        return this._items.length;\n      }\n    }]);\n\n    return FixedQueue;\n  })();\n\n  exports[\"default\"] = FixedQueue;\n});","define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/keys', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKeys, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  exports.modifierMask = modifierMask;\n  exports.specialCharacterToCode = specialCharacterToCode;\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /**\n   * @typedef Direction\n   * @enum {number}\n   * @property {number} FORWARD\n   * @property {number} BACKWARD\n   */\n  var DIRECTION = {\n    FORWARD: 1,\n    BACKWARD: -1\n  };\n  exports.DIRECTION = DIRECTION;\n  var MODIFIERS = {\n    META: 1, // also called \"command\" on OS X\n    CTRL: 2,\n    SHIFT: 4,\n    ALT: 8 // also called \"option\" on OS X\n  };\n\n  exports.MODIFIERS = MODIFIERS;\n\n  function modifierMask(event) {\n    var metaKey = event.metaKey;\n    var shiftKey = event.shiftKey;\n    var ctrlKey = event.ctrlKey;\n    var altKey = event.altKey;\n\n    var modVal = function modVal(val, modifier) {\n      return val && modifier || 0;\n    };\n    return modVal(metaKey, MODIFIERS.META) + modVal(shiftKey, MODIFIERS.SHIFT) + modVal(ctrlKey, MODIFIERS.CTRL) + modVal(altKey, MODIFIERS.ALT);\n  }\n\n  var SPECIAL_KEYS = {\n    BACKSPACE: _mobiledocKitUtilsKeycodes['default'].BACKSPACE,\n    TAB: _mobiledocKitUtilsKeycodes['default'].TAB,\n    ENTER: _mobiledocKitUtilsKeycodes['default'].ENTER,\n    ESC: _mobiledocKitUtilsKeycodes['default'].ESC,\n    SPACE: _mobiledocKitUtilsKeycodes['default'].SPACE,\n    PAGEUP: _mobiledocKitUtilsKeycodes['default'].PAGEUP,\n    PAGEDOWN: _mobiledocKitUtilsKeycodes['default'].PAGEDOWN,\n    END: _mobiledocKitUtilsKeycodes['default'].END,\n    HOME: _mobiledocKitUtilsKeycodes['default'].HOME,\n    LEFT: _mobiledocKitUtilsKeycodes['default'].LEFT,\n    UP: _mobiledocKitUtilsKeycodes['default'].UP,\n    RIGHT: _mobiledocKitUtilsKeycodes['default'].RIGHT,\n    DOWN: _mobiledocKitUtilsKeycodes['default'].DOWN,\n    INS: _mobiledocKitUtilsKeycodes['default'].INS,\n    DEL: _mobiledocKitUtilsKeycodes['default'].DELETE\n  };\n\n  function specialCharacterToCode(specialCharacter) {\n    return SPECIAL_KEYS[specialCharacter];\n  }\n\n  // heuristic for determining if `event` is a key event\n  function isKeyEvent(event) {\n    return (/^key/.test(event.type)\n    );\n  }\n\n  /**\n   * An abstraction around a KeyEvent\n   * that key listeners in the editor can use\n   * to determine what sort of key was pressed\n   */\n  var Key = (function () {\n    function Key(event) {\n      _classCallCheck(this, Key);\n\n      this.key = event.key;\n      this.keyCode = event.keyCode;\n      this.charCode = event.charCode;\n      this.event = event;\n      this.modifierMask = modifierMask(event);\n    }\n\n    _createClass(Key, [{\n      key: 'toString',\n      value: function toString() {\n        if (this.isTab()) {\n          return _mobiledocKitUtilsCharacters.TAB;\n        }\n        return String.fromCharCode(this.charCode);\n      }\n\n      // See https://caniuse.com/#feat=keyboardevent-key for browser support.\n    }, {\n      key: 'isKeySupported',\n      value: function isKeySupported() {\n        return this.key;\n      }\n    }, {\n      key: 'isKey',\n      value: function isKey(identifier) {\n        if (this.isKeySupported()) {\n          (0, _mobiledocKitUtilsAssert['default'])('Must define Keys.' + identifier + '.', _mobiledocKitUtilsKeys['default'][identifier]);\n          return this.key === _mobiledocKitUtilsKeys['default'][identifier];\n        } else {\n          (0, _mobiledocKitUtilsAssert['default'])('Must define Keycodes.' + identifier + '.', _mobiledocKitUtilsKeycodes['default'][identifier]);\n          return this.keyCode === _mobiledocKitUtilsKeycodes['default'][identifier];\n        }\n      }\n    }, {\n      key: 'isEscape',\n      value: function isEscape() {\n        return this.isKey('ESC');\n      }\n    }, {\n      key: 'isDelete',\n      value: function isDelete() {\n        return this.isKey('BACKSPACE') || this.isForwardDelete();\n      }\n    }, {\n      key: 'isForwardDelete',\n      value: function isForwardDelete() {\n        return this.isKey('DELETE');\n      }\n    }, {\n      key: 'isArrow',\n      value: function isArrow() {\n        return this.isHorizontalArrow() || this.isVerticalArrow();\n      }\n    }, {\n      key: 'isHorizontalArrow',\n      value: function isHorizontalArrow() {\n        return this.isLeftArrow() || this.isRightArrow();\n      }\n    }, {\n      key: 'isHorizontalArrowWithoutModifiersOtherThanShift',\n      value: function isHorizontalArrowWithoutModifiersOtherThanShift() {\n        return this.isHorizontalArrow() && !(this.ctrlKey || this.metaKey || this.altKey);\n      }\n    }, {\n      key: 'isVerticalArrow',\n      value: function isVerticalArrow() {\n        return this.isKey('UP') || this.isKey('DOWN');\n      }\n    }, {\n      key: 'isLeftArrow',\n      value: function isLeftArrow() {\n        return this.isKey('LEFT');\n      }\n    }, {\n      key: 'isRightArrow',\n      value: function isRightArrow() {\n        return this.isKey('RIGHT');\n      }\n    }, {\n      key: 'isHome',\n      value: function isHome() {\n        return this.isKey('HOME');\n      }\n    }, {\n      key: 'isEnd',\n      value: function isEnd() {\n        return this.isKey('END');\n      }\n    }, {\n      key: 'isPageUp',\n      value: function isPageUp() {\n        return this.isKey('PAGEUP');\n      }\n    }, {\n      key: 'isPageDown',\n      value: function isPageDown() {\n        return this.isKey('PAGEDOWN');\n      }\n    }, {\n      key: 'isInsert',\n      value: function isInsert() {\n        return this.isKey('INS');\n      }\n    }, {\n      key: 'isClear',\n      value: function isClear() {\n        return this.isKey('CLEAR');\n      }\n    }, {\n      key: 'isPause',\n      value: function isPause() {\n        return this.isKey('PAUSE');\n      }\n    }, {\n      key: 'isSpace',\n      value: function isSpace() {\n        return this.isKey('SPACE');\n      }\n\n      // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but\n      // it will also fire a keydown event for the tab+modifier (ctrl). This causes\n      // Mobiledoc to erroneously insert a tab character before FF switches to the\n      // new browser tab.  Chrome doesn't fire this event so the issue doesn't\n      // arise there. Fix this by returning false when the TAB key event includes a\n      // modifier.\n      // See: https://github.com/bustle/mobiledoc-kit/issues/565\n    }, {\n      key: 'isTab',\n      value: function isTab() {\n        return !this.hasAnyModifier() && this.isKey('TAB');\n      }\n    }, {\n      key: 'isEnter',\n      value: function isEnter() {\n        return this.isKey('ENTER');\n      }\n\n      /*\n       * If the key is the actual shift key. This is false when the shift key\n       * is held down and the source `event` is not the shift key.\n       * @see {isShift}\n       * @return {bool}\n       */\n    }, {\n      key: 'isShiftKey',\n      value: function isShiftKey() {\n        return this.isKey('SHIFT');\n      }\n\n      /*\n       * If the key is the actual alt key (aka \"option\" on mac). This is false when the alt key\n       * is held down and the source `event` is not the alt key.\n       * @return {bool}\n       */\n    }, {\n      key: 'isAltKey',\n      value: function isAltKey() {\n        return this.isKey('ALT');\n      }\n\n      /*\n       * If the key is the actual ctrl key. This is false when the ctrl key\n       * is held down and the source `event` is not the ctrl key.\n       * @return {bool}\n       */\n    }, {\n      key: 'isCtrlKey',\n      value: function isCtrlKey() {\n        return this.isKey('CTRL');\n      }\n    }, {\n      key: 'isIME',\n      value: function isIME() {\n        // FIXME the IME action seems to get lost when we issue an\n        // `editor.deleteSelection` before it (in Chrome)\n        return this.keyCode === _mobiledocKitUtilsKeycodes['default'].IME;\n      }\n    }, {\n      key: 'isShift',\n\n      /**\n       * If the shift key is depressed.\n       * For example, while holding down meta+shift, pressing the \"v\"\n       * key would result in an event whose `Key` had `isShift()` with a truthy value,\n       * because the shift key is down when pressing the \"v\".\n       * @see {isShiftKey} which checks if the key is actually the shift key itself.\n       * @return {bool}\n       */\n      value: function isShift() {\n        return this.shiftKey;\n      }\n    }, {\n      key: 'hasModifier',\n      value: function hasModifier(modifier) {\n        return modifier & this.modifierMask;\n      }\n    }, {\n      key: 'hasAnyModifier',\n      value: function hasAnyModifier() {\n        return !!this.modifierMask;\n      }\n    }, {\n      key: 'isPrintableKey',\n      value: function isPrintableKey() {\n        return !(this.isArrow() || this.isHome() || this.isEnd() || this.isPageUp() || this.isPageDown() || this.isInsert() || this.isClear() || this.isPause() || this.isEscape());\n      }\n    }, {\n      key: 'isNumberKey',\n      value: function isNumberKey() {\n        if (this.isKeySupported()) {\n          return this.key >= '0' && this.key <= '9';\n        } else {\n          var code = this.keyCode;\n          return code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9; // numpad keys\n        }\n      }\n    }, {\n      key: 'isLetterKey',\n      value: function isLetterKey() {\n        if (this.isKeySupported()) {\n          var key = this.key;\n          return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z';\n        } else {\n          var code = this.keyCode;\n          return code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z;\n        }\n      }\n    }, {\n      key: 'isPunctuation',\n      value: function isPunctuation() {\n        if (this.isKeySupported()) {\n          var key = this.key;\n          return key >= ';' && key <= '`' || key >= '[' && key <= '\"';\n        } else {\n          var code = this.keyCode;\n          return code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['\"'];\n        }\n      }\n\n      /**\n       * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position\n       *   and http://stackoverflow.com/a/12467610/137784\n       */\n    }, {\n      key: 'isPrintable',\n      value: function isPrintable() {\n        if (this.ctrlKey || this.metaKey) {\n          return false;\n        }\n\n        // Firefox calls keypress events for some keys that should not be printable\n        if (!this.isPrintableKey()) {\n          return false;\n        }\n\n        return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME();\n      }\n    }, {\n      key: 'direction',\n      get: function get() {\n        switch (true) {\n          case this.isDelete():\n            return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n          case this.isHorizontalArrow():\n            return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n        }\n      }\n    }, {\n      key: 'ctrlKey',\n      get: function get() {\n        return MODIFIERS.CTRL & this.modifierMask;\n      }\n    }, {\n      key: 'metaKey',\n      get: function get() {\n        return MODIFIERS.META & this.modifierMask;\n      }\n    }, {\n      key: 'shiftKey',\n      get: function get() {\n        return MODIFIERS.SHIFT & this.modifierMask;\n      }\n    }, {\n      key: 'altKey',\n      get: function get() {\n        return MODIFIERS.ALT & this.modifierMask;\n      }\n    }], [{\n      key: 'fromEvent',\n      value: function fromEvent(event) {\n        (0, _mobiledocKitUtilsAssert['default'])('Must pass a Key event to Key.fromEvent', event && isKeyEvent(event));\n        return new Key(event);\n      }\n    }]);\n\n    return Key;\n  })();\n\n  exports['default'] = Key;\n});","define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = {\n    BACKSPACE: 8,\n    SPACE: 32,\n    ENTER: 13,\n    SHIFT: 16,\n    ESC: 27,\n    DELETE: 46,\n    '0': 48,\n    '9': 57,\n    A: 65,\n    Z: 90,\n    a: 97,\n    z: 122,\n    'NUMPAD_0': 186,\n    'NUMPAD_9': 111,\n    ';': 186,\n    '.': 190,\n    '`': 192,\n    '[': 219,\n    '\"': 222,\n\n    // Input Method Editor uses multiple keystrokes to display characters.\n    // Example on mac: press option-i then i. This fires 2 key events in Chrome\n    // with keyCode 229 and displays ˆ and then î.\n    // See http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html#fixed-virtual-key-codes\n    IME: 229,\n\n    TAB: 9,\n    CLEAR: 12,\n    PAUSE: 19,\n    PAGEUP: 33,\n    PAGEDOWN: 34,\n    END: 35,\n    HOME: 36,\n    LEFT: 37,\n    UP: 38,\n    RIGHT: 39,\n    DOWN: 40,\n    INS: 45,\n    META: 91,\n    ALT: 18,\n    CTRL: 17\n  };\n});","define('mobiledoc-kit/utils/keys', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = {\n    BACKSPACE: 'Backspace',\n    SPACE: ' ',\n    ENTER: 'Enter',\n    SHIFT: 'Shift',\n    ESC: 'Escape',\n    DELETE: 'Delete',\n    INS: 'Insert',\n    HOME: 'Home',\n    END: 'End',\n    PAGEUP: 'PageUp',\n    PAGEDOWN: 'PageDown',\n    CLEAR: 'Clear',\n    PAUSE: 'Pause',\n    TAB: 'Tab',\n    ALT: 'Alt',\n    CTRL: 'Control',\n\n    LEFT: 'ArrowLeft',\n    RIGHT: 'ArrowRight',\n    UP: 'ArrowUp',\n    DOWN: 'ArrowDown'\n  };\n});","define(\"mobiledoc-kit/utils/linked-item\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n  var LinkedItem = function LinkedItem() {\n    _classCallCheck(this, LinkedItem);\n\n    this.next = null;\n    this.prev = null;\n  };\n\n  exports[\"default\"] = LinkedItem;\n});","define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var PARENT_PROP = '__parent';\n\n  var LinkedList = (function () {\n    function LinkedList(options) {\n      _classCallCheck(this, LinkedList);\n\n      this.head = null;\n      this.tail = null;\n      this.length = 0;\n\n      if (options) {\n        var adoptItem = options.adoptItem;\n        var freeItem = options.freeItem;\n\n        this._adoptItem = adoptItem;\n        this._freeItem = freeItem;\n      }\n    }\n\n    _createClass(LinkedList, [{\n      key: 'adoptItem',\n      value: function adoptItem(item) {\n        item[PARENT_PROP] = this;\n        this.length++;\n        if (this._adoptItem) {\n          this._adoptItem(item);\n        }\n      }\n    }, {\n      key: 'freeItem',\n      value: function freeItem(item) {\n        item[PARENT_PROP] = null;\n        this.length--;\n        if (this._freeItem) {\n          this._freeItem(item);\n        }\n      }\n    }, {\n      key: 'prepend',\n      value: function prepend(item) {\n        this.insertBefore(item, this.head);\n      }\n    }, {\n      key: 'append',\n      value: function append(item) {\n        this.insertBefore(item, null);\n      }\n    }, {\n      key: 'insertAfter',\n      value: function insertAfter(item, prevItem) {\n        var nextItem = prevItem ? prevItem.next : this.head;\n        this.insertBefore(item, nextItem);\n      }\n    }, {\n      key: '_ensureItemIsNotAlreadyInList',\n      value: function _ensureItemIsNotAlreadyInList(item) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item.next && !item.prev && this.head !== item);\n      }\n    }, {\n      key: 'insertBefore',\n      value: function insertBefore(item, nextItem) {\n        this._ensureItemIsNotInList(item);\n        this.adoptItem(item);\n\n        var insertPos = undefined;\n        if (nextItem && nextItem.prev) {\n          insertPos = 'middle';\n        } else if (nextItem) {\n          insertPos = 'start';\n        } else {\n          insertPos = 'end';\n        }\n\n        switch (insertPos) {\n          case 'start':\n            if (this.head) {\n              item.next = this.head;\n              this.head.prev = item;\n            }\n            this.head = item;\n\n            break;\n          case 'middle':\n            {\n              var prevItem = nextItem.prev;\n              item.next = nextItem;\n              item.prev = prevItem;\n              nextItem.prev = item;\n              prevItem.next = item;\n\n              break;\n            }\n          case 'end':\n            {\n              var tail = this.tail;\n              item.prev = tail;\n\n              if (tail) {\n                tail.next = item;\n              } else {\n                this.head = item;\n              }\n              this.tail = item;\n\n              break;\n            }\n        }\n      }\n    }, {\n      key: 'remove',\n      value: function remove(item) {\n        if (!item[PARENT_PROP]) {\n          return;\n        }\n        this._ensureItemIsInThisList(item);\n        this.freeItem(item);\n\n        var prev = item.prev;\n        var next = item.next;\n\n        item.prev = null;\n        item.next = null;\n\n        if (prev) {\n          prev.next = next;\n        } else {\n          this.head = next;\n        }\n\n        if (next) {\n          next.prev = prev;\n        } else {\n          this.tail = prev;\n        }\n      }\n    }, {\n      key: 'forEach',\n      value: function forEach(callback) {\n        var item = this.head;\n        var index = 0;\n        while (item) {\n          callback(item, index++);\n          item = item.next;\n        }\n      }\n    }, {\n      key: 'map',\n      value: function map(callback) {\n        var result = [];\n        this.forEach(function (i) {\n          return result.push(callback(i));\n        });\n        return result;\n      }\n    }, {\n      key: 'walk',\n      value: function walk(startItem, endItem, callback) {\n        var item = startItem || this.head;\n        while (item) {\n          callback(item);\n          if (item === endItem) {\n            break;\n          }\n          item = item.next;\n        }\n      }\n    }, {\n      key: 'readRange',\n      value: function readRange(startItem, endItem) {\n        var items = [];\n        this.walk(startItem, endItem, function (item) {\n          items.push(item);\n        });\n        return items;\n      }\n    }, {\n      key: 'toArray',\n      value: function toArray() {\n        return this.readRange();\n      }\n    }, {\n      key: 'detect',\n      value: function detect(callback) {\n        var item = arguments.length <= 1 || arguments[1] === undefined ? this.head : arguments[1];\n        var reverse = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n        while (item) {\n          if (callback(item)) {\n            return item;\n          }\n          item = reverse ? item.prev : item.next;\n        }\n      }\n    }, {\n      key: 'any',\n      value: function any(callback) {\n        return !!this.detect(callback);\n      }\n    }, {\n      key: 'every',\n      value: function every(callback) {\n        var item = this.head;\n        while (item) {\n          if (!callback(item)) {\n            return false;\n          }\n          item = item.next;\n        }\n        return true;\n      }\n    }, {\n      key: 'objectAt',\n      value: function objectAt(targetIndex) {\n        var index = -1;\n        return this.detect(function () {\n          index++;\n          return targetIndex === index;\n        });\n      }\n    }, {\n      key: 'splice',\n      value: function splice(targetItem, removalCount, newItems) {\n        var _this = this;\n\n        var item = targetItem;\n        var nextItem = item.next;\n        var count = 0;\n        while (item && count < removalCount) {\n          count++;\n          nextItem = item.next;\n          this.remove(item);\n          item = nextItem;\n        }\n        newItems.forEach(function (newItem) {\n          _this.insertBefore(newItem, nextItem);\n        });\n      }\n    }, {\n      key: 'removeBy',\n      value: function removeBy(conditionFn) {\n        var item = this.head;\n        while (item) {\n          var nextItem = item.next;\n\n          if (conditionFn(item)) {\n            this.remove(item);\n          }\n\n          item = nextItem;\n        }\n      }\n    }, {\n      key: '_ensureItemIsNotInList',\n      value: function _ensureItemIsNotInList(item) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item[PARENT_PROP]);\n      }\n    }, {\n      key: '_ensureItemIsInThisList',\n      value: function _ensureItemIsInThisList(item) {\n        (0, _mobiledocKitUtilsAssert['default'])('Cannot remove item that is in another list', item[PARENT_PROP] === this);\n      }\n    }, {\n      key: 'isEmpty',\n      get: function get() {\n        return this.length === 0;\n      }\n    }]);\n\n    return LinkedList;\n  })();\n\n  exports['default'] = LinkedList;\n});","define(\"mobiledoc-kit/utils/log-manager\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n  var Logger = (function () {\n    function Logger(type, manager) {\n      _classCallCheck(this, Logger);\n\n      this.type = type;\n      this.manager = manager;\n    }\n\n    _createClass(Logger, [{\n      key: \"isEnabled\",\n      value: function isEnabled() {\n        return this.manager.isEnabled(this.type);\n      }\n    }, {\n      key: \"log\",\n      value: function log() {\n        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n          args[_key] = arguments[_key];\n        }\n\n        args.unshift(\"[\" + this.type + \"]\");\n        if (this.isEnabled()) {\n          var _window$console;\n\n          (_window$console = window.console).log.apply(_window$console, args);\n        }\n      }\n    }]);\n\n    return Logger;\n  })();\n\n  var LogManager = (function () {\n    function LogManager() {\n      _classCallCheck(this, LogManager);\n\n      this.enabledTypes = [];\n      this.allEnabled = false;\n    }\n\n    _createClass(LogManager, [{\n      key: \"for\",\n      value: function _for(type) {\n        return new Logger(type, this);\n      }\n    }, {\n      key: \"enableAll\",\n      value: function enableAll() {\n        this.allEnabled = true;\n      }\n    }, {\n      key: \"enableTypes\",\n      value: function enableTypes(types) {\n        this.enabledTypes = this.enabledTypes.concat(types);\n      }\n    }, {\n      key: \"disable\",\n      value: function disable() {\n        this.enabledTypes = [];\n        this.allEnabled = false;\n      }\n    }, {\n      key: \"isEnabled\",\n      value: function isEnabled(type) {\n        return this.allEnabled || this.enabledTypes.indexOf(type) !== -1;\n      }\n    }]);\n\n    return LogManager;\n  })();\n\n  exports[\"default\"] = LogManager;\n});","define('mobiledoc-kit/utils/markuperable', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var Markerupable = (function () {\n    function Markerupable() {\n      _classCallCheck(this, Markerupable);\n    }\n\n    _createClass(Markerupable, [{\n      key: 'clearMarkups',\n      value: function clearMarkups() {\n        this.markups = [];\n      }\n    }, {\n      key: 'addMarkup',\n      value: function addMarkup(markup) {\n        this.markups.push(markup);\n      }\n    }, {\n      key: 'addMarkupAtIndex',\n      value: function addMarkupAtIndex(markup, index) {\n        this.markups.splice(index, 0, markup);\n      }\n    }, {\n      key: 'removeMarkup',\n      value: function removeMarkup(markupOrMarkupCallback) {\n        var _this = this;\n\n        var callback = undefined;\n        if (typeof markupOrMarkupCallback === 'function') {\n          callback = markupOrMarkupCallback;\n        } else {\n          (function () {\n            var markup = markupOrMarkupCallback;\n            callback = function (_markup) {\n              return _markup === markup;\n            };\n          })();\n        }\n\n        (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.markups, callback), function (m) {\n          return _this._removeMarkup(m);\n        });\n      }\n    }, {\n      key: '_removeMarkup',\n      value: function _removeMarkup(markup) {\n        var index = this.markups.indexOf(markup);\n        if (index !== -1) {\n          this.markups.splice(index, 1);\n        }\n      }\n    }, {\n      key: 'hasMarkup',\n      value: function hasMarkup(tagNameOrMarkup) {\n        return !!this.getMarkup(tagNameOrMarkup);\n      }\n    }, {\n      key: 'getMarkup',\n      value: function getMarkup(tagNameOrMarkup) {\n        var _this2 = this;\n\n        if (typeof tagNameOrMarkup === 'string') {\n          var _ret2 = (function () {\n            var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagNameOrMarkup);\n            return {\n              v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n                return markup.tagName === tagName;\n              })\n            };\n          })();\n\n          if (typeof _ret2 === 'object') return _ret2.v;\n        } else {\n          var _ret3 = (function () {\n            var targetMarkup = tagNameOrMarkup;\n            return {\n              v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n                return markup === targetMarkup;\n              })\n            };\n          })();\n\n          if (typeof _ret3 === 'object') return _ret3.v;\n        }\n      }\n    }, {\n      key: 'openedMarkups',\n      get: function get() {\n        var count = 0;\n        if (this.prev) {\n          count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.prev.markups);\n        }\n\n        return this.markups.slice(count);\n      }\n    }, {\n      key: 'closedMarkups',\n      get: function get() {\n        var count = 0;\n        if (this.next) {\n          count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.next.markups);\n        }\n\n        return this.markups.slice(count);\n      }\n    }]);\n\n    return Markerupable;\n  })();\n\n  exports['default'] = Markerupable;\n});","define(\"mobiledoc-kit/utils/merge\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  function mergeWithOptions(original, updates, options) {\n    options = options || {};\n    for (var prop in updates) {\n      if (options.hasOwnProperty(prop)) {\n        original[prop] = options[prop];\n      } else if (updates.hasOwnProperty(prop)) {\n        original[prop] = updates[prop];\n      }\n    }\n    return original;\n  }\n\n  /**\n   * Merges properties of one object into another\n   * @private\n   */\n  function merge(original, updates) {\n    return mergeWithOptions(original, updates);\n  }\n\n  exports.mergeWithOptions = mergeWithOptions;\n  exports.merge = merge;\n});","define('mobiledoc-kit/utils/mixin', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = mixin;\n  var CONSTRUCTOR_FN_NAME = 'constructor';\n\n  function mixin(target, source) {\n    target = target.prototype;\n    // Fallback to just `source` to allow mixing in a plain object (pojo)\n    source = source.prototype || source;\n\n    Object.getOwnPropertyNames(source).forEach(function (name) {\n      if (name !== CONSTRUCTOR_FN_NAME) {\n        var descriptor = Object.getOwnPropertyDescriptor(source, name);\n\n        Object.defineProperty(target, name, descriptor);\n      }\n    });\n  }\n});","define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) {\n  'use strict';\n\n  var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];\n\n  function MobiledocError() {\n    var tmp = Error.apply(this, arguments);\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n    // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.\n    for (var idx = 0; idx < errorProps.length; idx++) {\n      this[errorProps[idx]] = tmp[errorProps[idx]];\n    }\n  }\n\n  MobiledocError.prototype = Object.create(Error.prototype);\n\n  exports['default'] = MobiledocError;\n});","define(\"mobiledoc-kit/utils/object-utils\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  exports.entries = entries;\n\n  function entries(obj) {\n    var ownProps = Object.keys(obj);\n    var i = ownProps.length;\n    var resArray = new Array(i);\n\n    while (i--) {\n      resArray[i] = [ownProps[i], obj[ownProps[i]]];\n    }\n\n    return resArray;\n  }\n});","define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) {\n  /* global JSON */\n  'use strict';\n\n  exports.getContentFromPasteEvent = getContentFromPasteEvent;\n  exports.setClipboardData = setClipboardData;\n  exports.parsePostFromPaste = parsePostFromPaste;\n  exports.parsePostFromDrop = parsePostFromDrop;\n  var MIME_TEXT_PLAIN = 'text/plain';\n  exports.MIME_TEXT_PLAIN = MIME_TEXT_PLAIN;\n  var MIME_TEXT_HTML = 'text/html';\n  exports.MIME_TEXT_HTML = MIME_TEXT_HTML;\n  var NONSTANDARD_IE_TEXT_TYPE = 'Text';\n\n  exports.NONSTANDARD_IE_TEXT_TYPE = NONSTANDARD_IE_TEXT_TYPE;\n  var MOBILEDOC_REGEX = new RegExp(/data\\-mobiledoc='(.*?)'>/);\n\n  /**\n   * @return {Post}\n   * @private\n   */\n  function parsePostFromHTML(html, builder, plugins) {\n    var post = undefined;\n\n    if (MOBILEDOC_REGEX.test(html)) {\n      var mobiledocString = html.match(MOBILEDOC_REGEX)[1];\n      var mobiledoc = JSON.parse(mobiledocString);\n      post = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n    } else {\n      post = new _mobiledocKitParsersHtml['default'](builder, { plugins: plugins }).parse(html);\n    }\n\n    return post;\n  }\n\n  /**\n   * @return {Post}\n   * @private\n   */\n  function parsePostFromText(text, builder, plugins) {\n    var parser = new _mobiledocKitParsersText['default'](builder, { plugins: plugins });\n    var post = parser.parse(text);\n    return post;\n  }\n\n  /**\n   * @return {{html: String, text: String}}\n   * @private\n   */\n\n  function getContentFromPasteEvent(event, window) {\n    var html = '',\n        text = '';\n\n    var clipboardData = event.clipboardData;\n\n    if (clipboardData && clipboardData.getData) {\n      html = clipboardData.getData(MIME_TEXT_HTML);\n      text = clipboardData.getData(MIME_TEXT_PLAIN);\n    } else if (window.clipboardData && window.clipboardData.getData) {\n      // IE\n      // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n      // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n      // object instead of the per-event event.clipboardData object on the other browsers.\n      html = window.clipboardData.getData(NONSTANDARD_IE_TEXT_TYPE);\n    }\n\n    return { html: html, text: text };\n  }\n\n  /**\n   * @return {{html: String, text: String}}\n   * @private\n   */\n  function getContentFromDropEvent(event, logger) {\n    var html = '',\n        text = '';\n\n    try {\n      html = event.dataTransfer.getData(MIME_TEXT_HTML);\n      text = event.dataTransfer.getData(MIME_TEXT_PLAIN);\n    } catch (e) {\n      // FIXME IE11 does not include any data in the 'text/html' or 'text/plain'\n      // mimetypes. It throws an error 'Invalid argument' when attempting to read\n      // these properties.\n      if (logger) {\n        logger.log('Error getting drop data: ', e);\n      }\n    }\n\n    return { html: html, text: text };\n  }\n\n  /**\n   * @param {CopyEvent|CutEvent}\n   * @param {Editor}\n   * @param {Window}\n   * @private\n   */\n\n  function setClipboardData(event, _ref, window) {\n    var mobiledoc = _ref.mobiledoc;\n    var html = _ref.html;\n    var text = _ref.text;\n\n    if (mobiledoc && html) {\n      html = '<div data-mobiledoc=\\'' + JSON.stringify(mobiledoc) + '\\'>' + html + '</div>';\n    }\n\n    var clipboardData = event.clipboardData;\n    var nonstandardClipboardData = window.clipboardData;\n\n    if (clipboardData && clipboardData.setData) {\n      clipboardData.setData(MIME_TEXT_HTML, html);\n      clipboardData.setData(MIME_TEXT_PLAIN, text);\n    } else if (nonstandardClipboardData && nonstandardClipboardData.setData) {\n      // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n      // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n      // object instead of the per-event event.clipboardData object on the other browsers.\n      nonstandardClipboardData.setData(NONSTANDARD_IE_TEXT_TYPE, html);\n    }\n  }\n\n  /**\n   * @param {PasteEvent}\n   * @param {{builder: Builder, _parserPlugins: Array}} options\n   * @return {Post}\n   * @private\n   */\n\n  function parsePostFromPaste(pasteEvent, _ref2) {\n    var builder = _ref2.builder;\n    var plugins = _ref2._parserPlugins;\n\n    var _ref3 = arguments.length <= 2 || arguments[2] === undefined ? { targetFormat: 'html' } : arguments[2];\n\n    var targetFormat = _ref3.targetFormat;\n\n    var _getContentFromPasteEvent = getContentFromPasteEvent(pasteEvent, window);\n\n    var html = _getContentFromPasteEvent.html;\n    var text = _getContentFromPasteEvent.text;\n\n    if (targetFormat === 'html' && html && html.length) {\n      return parsePostFromHTML(html, builder, plugins);\n    } else if (text && text.length) {\n      return parsePostFromText(text, builder, plugins);\n    }\n  }\n\n  /**\n   * @param {DropEvent}\n   * @param {Editor} editor\n   * @param {Object} [options={}] Can pass a logger\n   * @return {Post}\n   * @private\n   */\n\n  function parsePostFromDrop(dropEvent, editor) {\n    var _ref4 = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n    var logger = _ref4.logger;\n    var builder = editor.builder;\n    var plugins = editor._parserPlugins;\n\n    var _getContentFromDropEvent = getContentFromDropEvent(dropEvent, logger);\n\n    var html = _getContentFromDropEvent.html;\n    var text = _getContentFromDropEvent.text;\n\n    if (html && html.length) {\n      return parsePostFromHTML(html, builder, plugins);\n    } else if (text && text.length) {\n      return parsePostFromText(text, builder, plugins);\n    }\n  }\n});","define(\"mobiledoc-kit/utils/placeholder-image-src\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var placeholderImageSrc = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAMFBMVEXp7vG6vsHm6+63u77Hy868wMPe4+bO09bh5unr8fTR1djAxMfM0NPX3N/c4eTBxcjXRf5TAAACh0lEQVR4nO3b6ZKqMBSFUSQMYZL3f9tbBq/NEEDiqUqOfusn1ZXKbjcQlGQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC6RkbsGHuabChEtHmiGYfS3EQYM+Sxw/gMQvmcNnYaj6oTDHi73WPn2eqnj9B8zo3TJXcq5uNjXmVff86VwSR3JtryMa1BYqi7S1hJDCVpSigyLcGhJJEwzlCSNtPKrbVhVwsdCfOhH7uuaG3ARV9DwsaOzxt3N1yPqCHhvXytTUz92VDpmE/LLhZwl++R6Sds6sUa/PL6K/2E2fIhw1xdRKefsFolrPc+xNx/N0k/4fpBsdhL2HfeiN+TsDCms8dDpeRyS3P3QDl6Iqaf8L0rTf+80m6Lmn7Ct+4Wxf+/2RY1/YRv3PHz/u+fsCmqgoTnq7Z+8SGviqoh4dnKu1ieqauiakh4/PQ0r6ivqDoSHj0B97eNRVG1JNxV+L4bnxdVecJtRTdFVZ7QU9F1UXUn9FZ0VVRlCav5ob2KLouqKmFjy676u2HsVnRRVFUJq3J+8KCi86IqSthMvyl209Hjijqm3RsqAZ5pNfa5PJ2KelJRjQmr1/r7cfy0ouoSNvOfvbvhvKLaEr4qOin9kTQnrN7LpDZhE/Zmhp6Eq4p+YcKgiipKGFhRRQkDK6ooYfgLbiSMioQkJGF8P5XwHv4O+7AaKiXzaeXh1kMl5AffTUxiKEm/krD94BR8Gdxl1fceSlR58ZhXKbEpyD2amNiBtmrJLTMHL1LF8/rpXkSZXEmz8K8uvAFFNm6Iq0aBLUFOmeCuJ6exrcCmoLpN7kYx891bSAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgh/wDdr8peyRHLogAAAAASUVORK5CYII=\";\n\n  exports[\"default\"] = placeholderImageSrc;\n});","define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils) {\n  'use strict';\n\n  function clearSelection() {\n    window.getSelection().removeAllRanges();\n  }\n\n  function textNodeRects(node) {\n    var range = document.createRange();\n    range.setEnd(node, node.nodeValue.length);\n    range.setStart(node, 0);\n    return range.getClientRects();\n  }\n\n  function findOffsetInTextNode(node, coords) {\n    var len = node.nodeValue.length;\n    var range = document.createRange();\n    for (var i = 0; i < len; i++) {\n      range.setEnd(node, i + 1);\n      range.setStart(node, i);\n      var rect = range.getBoundingClientRect();\n      if (rect.top === rect.bottom) {\n        continue;\n      }\n      if (rect.left <= coords.left && rect.right >= coords.left && rect.top <= coords.top && rect.bottom >= coords.top) {\n        return { node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };\n      }\n    }\n    return { node: node, offset: 0 };\n  }\n\n  /*\n   * @param {Object} coords with `top` and `left`\n   * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js\n   * @return {Object} {node, offset}\n   */\n  /* eslint-disable complexity */\n  function findOffsetInNode(_x, _x2) {\n    var _again = true;\n\n    _function: while (_again) {\n      var node = _x,\n          coords = _x2;\n      _again = false;\n\n      var closest = undefined,\n          dyClosest = 1e8,\n          coordsClosest = undefined,\n          offset = 0;\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        var rects = undefined;\n        if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child)) {\n          rects = child.getClientRects();\n        } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(child)) {\n          rects = textNodeRects(child);\n        } else {\n          continue;\n        }\n\n        for (var i = 0; i < rects.length; i++) {\n          var rect = rects[i];\n          if (rect.left <= coords.left && rect.right >= coords.left) {\n            var dy = rect.top > coords.top ? rect.top - coords.top : rect.bottom < coords.top ? coords.top - rect.bottom : 0;\n            if (dy < dyClosest) {\n              closest = child;\n              dyClosest = dy;\n              coordsClosest = dy ? { left: coords.left, top: rect.top } : coords;\n              if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child) && !child.firstChild) {\n                offset = i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);\n              }\n              continue;\n            }\n          }\n          if (!closest && (coords.top >= rect.bottom || coords.top >= rect.top && coords.left >= rect.right)) {\n            offset = i + 1;\n          }\n        }\n      }\n      if (!closest) {\n        return { node: node, offset: offset };\n      }\n      if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(closest)) {\n        return findOffsetInTextNode(closest, coordsClosest);\n      }\n      if (closest.firstChild) {\n        _x = closest;\n        _x2 = coordsClosest;\n        _again = true;\n        closest = dyClosest = coordsClosest = offset = child = rects = i = rect = dy = undefined;\n        continue _function;\n      }\n      return { node: node, offset: offset };\n    }\n  }\n  /* eslint-enable complexity */\n\n  function constrainNodeTo(node, parentNode, existingOffset) {\n    var compare = parentNode.compareDocumentPosition(node);\n    if (compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n      // the node is inside parentNode, do nothing\n      return { node: node, offset: existingOffset };\n    } else if (compare & Node.DOCUMENT_POSITION_CONTAINS) {\n      // the node contains parentNode. This shouldn't happen.\n      return { node: node, offset: existingOffset };\n    } else if (compare & Node.DOCUMENT_POSITION_PRECEDING) {\n      // node is before parentNode. return start of deepest first child\n      var child = parentNode.firstChild;\n      while (child.firstChild) {\n        child = child.firstChild;\n      }\n      return { node: child, offset: 0 };\n    } else if (compare & Node.DOCUMENT_POSITION_FOLLOWING) {\n      // node is after parentNode. return end of deepest last child\n      var child = parentNode.lastChild;\n      while (child.lastChild) {\n        child = child.lastChild;\n      }\n\n      var offset = (0, _mobiledocKitUtilsDomUtils.isTextNode)(child) ? child.textContent.length : 1;\n      return { node: child, offset: offset };\n    } else {\n      return { node: node, offset: existingOffset };\n    }\n  }\n\n  /*\n   * Returns a new selection that is constrained within parentNode.\n   * If the anchorNode or focusNode are outside the parentNode, they are replaced with the beginning\n   * or end of the parentNode's children\n   */\n  function constrainSelectionTo(selection, parentNode) {\n    var _constrainNodeTo = constrainNodeTo(selection.anchorNode, parentNode, selection.anchorOffset);\n\n    var anchorNode = _constrainNodeTo.node;\n    var anchorOffset = _constrainNodeTo.offset;\n\n    var _constrainNodeTo2 = constrainNodeTo(selection.focusNode, parentNode, selection.focusOffset);\n\n    var focusNode = _constrainNodeTo2.node;\n    var focusOffset = _constrainNodeTo2.offset;\n\n    return { anchorNode: anchorNode, anchorOffset: anchorOffset, focusNode: focusNode, focusOffset: focusOffset };\n  }\n\n  function comparePosition(_x3) {\n    var _again2 = true;\n\n    _function2: while (_again2) {\n      var selection = _x3;\n      _again2 = false;\n      var anchorNode = selection.anchorNode;\n      var focusNode = selection.focusNode;\n      var anchorOffset = selection.anchorOffset;\n      var focusOffset = selection.focusOffset;\n\n      var headNode = undefined,\n          tailNode = undefined,\n          headOffset = undefined,\n          tailOffset = undefined,\n          direction = undefined;\n\n      var position = anchorNode.compareDocumentPosition(focusNode);\n\n      // IE may select return focus and anchor nodes far up the DOM tree instead of\n      // picking the deepest, most specific possible node. For example in\n      //\n      //     <div><span>abc</span><span>def</span></div>\n      //\n      // with a cursor between c and d, IE might say the focusNode is <div> with\n      // an offset of 1. However the anchorNode for a selection might still be\n      // <span> 2 if there was a selection.\n      //\n      // This code walks down the DOM tree until a good comparison of position can be\n      // made.\n      //\n      if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n        if (focusOffset < focusNode.childNodes.length) {\n          focusNode = focusNode.childNodes[focusOffset];\n          focusOffset = 0;\n        } else {\n          // This situation happens on IE when triple-clicking to select.\n          // Set the focus to the very last character inside the node.\n          while (focusNode.lastChild) {\n            focusNode = focusNode.lastChild;\n          }\n          focusOffset = focusNode.textContent.length;\n        }\n\n        _x3 = {\n          focusNode: focusNode,\n          focusOffset: focusOffset,\n          anchorNode: anchorNode, anchorOffset: anchorOffset\n        };\n        _again2 = true;\n        anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = undefined;\n        continue _function2;\n      } else if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n        var offset = anchorOffset - 1;\n        if (offset < 0) {\n          offset = 0;\n        }\n        _x3 = {\n          anchorNode: anchorNode.childNodes[offset],\n          anchorOffset: 0,\n          focusNode: focusNode, focusOffset: focusOffset\n        };\n        _again2 = true;\n        anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = offset = undefined;\n        continue _function2;\n\n        // The meat of translating anchor and focus nodes to head and tail nodes\n      } else if (position & Node.DOCUMENT_POSITION_FOLLOWING) {\n          headNode = anchorNode;tailNode = focusNode;\n          headOffset = anchorOffset;tailOffset = focusOffset;\n          direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n        } else if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n          headNode = focusNode;tailNode = anchorNode;\n          headOffset = focusOffset;tailOffset = anchorOffset;\n          direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n        } else {\n          // same node\n          headNode = tailNode = anchorNode;\n          headOffset = anchorOffset;\n          tailOffset = focusOffset;\n          if (tailOffset < headOffset) {\n            // Swap the offset order\n            headOffset = focusOffset;\n            tailOffset = anchorOffset;\n            direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n          } else if (headOffset < tailOffset) {\n            direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n          } else {\n            direction = null;\n          }\n        }\n\n      return { headNode: headNode, headOffset: headOffset, tailNode: tailNode, tailOffset: tailOffset, direction: direction };\n    }\n  }\n\n  exports.clearSelection = clearSelection;\n  exports.comparePosition = comparePosition;\n  exports.findOffsetInNode = findOffsetInNode;\n  exports.constrainSelectionTo = constrainSelectionTo;\n});","define(\"mobiledoc-kit/utils/set\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n  var Set = (function () {\n    function Set() {\n      var _this = this;\n\n      var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n      _classCallCheck(this, Set);\n\n      this.items = [];\n      items.forEach(function (i) {\n        return _this.add(i);\n      });\n    }\n\n    _createClass(Set, [{\n      key: \"add\",\n      value: function add(item) {\n        if (!this.has(item)) {\n          this.items.push(item);\n        }\n      }\n    }, {\n      key: \"has\",\n      value: function has(item) {\n        return this.items.indexOf(item) !== -1;\n      }\n    }, {\n      key: \"toArray\",\n      value: function toArray() {\n        return this.items;\n      }\n    }, {\n      key: \"length\",\n      get: function get() {\n        return this.items.length;\n      }\n    }]);\n\n    return Set;\n  })();\n\n  exports[\"default\"] = Set;\n});","define('mobiledoc-kit/utils/string-utils', ['exports'], function (exports) {\n  /*\n   * @param {String} string\n   * @return {String} a dasherized string. 'modelIndex' -> 'model-index', etc\n   */\n  'use strict';\n\n  exports.dasherize = dasherize;\n  exports.capitalize = capitalize;\n  exports.startsWith = startsWith;\n  exports.endsWith = endsWith;\n\n  function dasherize(string) {\n    return string.replace(/[A-Z]/g, function (match, offset) {\n      var lower = match.toLowerCase();\n\n      return offset === 0 ? lower : '-' + lower;\n    });\n  }\n\n  function capitalize(string) {\n    return string.charAt(0).toUpperCase() + string.slice(1);\n  }\n\n  function startsWith(string, character) {\n    return string.charAt(0) === character;\n  }\n\n  function endsWith(string, endString) {\n    var index = string.lastIndexOf(endString);\n    return index !== -1 && index === string.length - endString.length;\n  }\n});","define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n  'use strict';\n\n  exports['default'] = toRange;\n\n  function toRange(rangeLike) {\n    (0, _mobiledocKitUtilsAssert['default'])('Must pass non-blank object to \"toRange\"', !!rangeLike);\n\n    if (rangeLike instanceof _mobiledocKitUtilsCursorRange['default']) {\n      return rangeLike;\n    } else if (rangeLike instanceof _mobiledocKitUtilsCursorPosition['default']) {\n      return rangeLike.toRange();\n    }\n\n    (0, _mobiledocKitUtilsAssert['default'])('Incorrect structure for rangeLike: ' + rangeLike, false);\n  }\n});","define('mobiledoc-kit/version', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = '##VERSION##';\n});","define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n  var DELAY = 200;\n\n  var Tooltip = (function (_View) {\n    _inherits(Tooltip, _View);\n\n    function Tooltip(options) {\n      var _this = this;\n\n      _classCallCheck(this, Tooltip);\n\n      var rootElement = options.rootElement;\n\n      var timeout = undefined;\n      options.classNames = ['__mobiledoc-tooltip'];\n      _get(Object.getPrototypeOf(Tooltip.prototype), 'constructor', this).call(this, options);\n\n      this.addEventListener(rootElement, 'mouseover', function (e) {\n        var target = (0, _mobiledocKitUtilsElementUtils.getEventTargetMatchingTag)(options.showForTag, e.target, rootElement);\n        if (target && target.isContentEditable) {\n          timeout = setTimeout(function () {\n            _this.showLink(target.href, target);\n          }, DELAY);\n        }\n      });\n\n      this.addEventListener(rootElement, 'mouseout', function (e) {\n        clearTimeout(timeout);\n        if (_this.elementObserver) {\n          _this.elementObserver.cancel();\n        }\n        var toElement = e.toElement || e.relatedTarget;\n        if (toElement && toElement.className !== _this.element.className) {\n          _this.hide();\n        }\n      });\n    }\n\n    _createClass(Tooltip, [{\n      key: 'showMessage',\n      value: function showMessage(message, element) {\n        var tooltipElement = this.element;\n        tooltipElement.innerHTML = message;\n        this.show();\n        (0, _mobiledocKitUtilsElementUtils.positionElementCenteredBelow)(tooltipElement, element);\n      }\n    }, {\n      key: 'showLink',\n      value: function showLink(link, element) {\n        var _this2 = this;\n\n        var message = '<a href=\"' + link + '\" target=\"_blank\">' + link + '</a>';\n        this.showMessage(message, element);\n        this.elementObserver = (0, _mobiledocKitUtilsElementUtils.whenElementIsNotInDOM)(element, function () {\n          return _this2.hide();\n        });\n      }\n    }]);\n\n    return Tooltip;\n  })(_mobiledocKitViewsView['default']);\n\n  exports['default'] = Tooltip;\n});","define('mobiledoc-kit/views/view', ['exports', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsDomUtils) {\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var View = (function () {\n    function View() {\n      var _this = this;\n\n      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n      _classCallCheck(this, View);\n\n      options.tagName = options.tagName || 'div';\n      options.container = options.container || document.body;\n\n      this.element = document.createElement(options.tagName);\n      this.container = options.container;\n      this.isShowing = false;\n\n      var classNames = options.classNames || [];\n      classNames.forEach(function (name) {\n        return (0, _mobiledocKitUtilsDomUtils.addClassName)(_this.element, name);\n      });\n      this._eventListeners = [];\n    }\n\n    _createClass(View, [{\n      key: 'addEventListener',\n      value: function addEventListener(element, type, listener) {\n        element.addEventListener(type, listener);\n        this._eventListeners.push([element, type, listener]);\n      }\n    }, {\n      key: 'removeAllEventListeners',\n      value: function removeAllEventListeners() {\n        this._eventListeners.forEach(function (_ref) {\n          var _ref2 = _slicedToArray(_ref, 3);\n\n          var element = _ref2[0];\n          var type = _ref2[1];\n          var listener = _ref2[2];\n\n          element.removeEventListener(type, listener);\n        });\n      }\n    }, {\n      key: 'show',\n      value: function show() {\n        if (!this.isShowing) {\n          this.container.appendChild(this.element);\n          this.isShowing = true;\n          return true;\n        }\n      }\n    }, {\n      key: 'hide',\n      value: function hide() {\n        if (this.isShowing) {\n          this.container.removeChild(this.element);\n          this.isShowing = false;\n          return true;\n        }\n      }\n    }, {\n      key: 'destroy',\n      value: function destroy() {\n        this.removeAllEventListeners();\n        this.hide();\n        this.isDestroyed = true;\n      }\n    }]);\n\n    return View;\n  })();\n\n  exports['default'] = View;\n});","define('mobiledoc-text-renderer/cards/image', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = {\n    name: 'image-card',\n    type: 'text',\n    render: function render() {}\n  };\n});","define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) {\n  'use strict';\n\n  exports.registerGlobal = registerGlobal;\n\n  function registerGlobal(window) {\n    window.MobiledocTextRenderer = _mobiledocTextRendererRendererFactory['default'];\n  }\n\n  exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default'];\n  exports['default'] = _mobiledocTextRendererRendererFactory['default'];\n});","define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) {\n  'use strict';\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  /**\n   * runtime Text renderer\n   * renders a mobiledoc to Text\n   *\n   * input: mobiledoc\n   * output: Text (string)\n   */\n\n  function validateCards(cards) {\n    if (!Array.isArray(cards)) {\n      throw new Error('`cards` must be passed as an array');\n    }\n    for (var i = 0; i < cards.length; i++) {\n      var card = cards[i];\n      if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n        throw new Error('Card \"' + card.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n      }\n      if (!card.render) {\n        throw new Error('Card \"' + card.name + '\" must define `render`');\n      }\n    }\n  }\n\n  function validateAtoms(atoms) {\n    if (!Array.isArray(atoms)) {\n      throw new Error('`atoms` must be passed as an array');\n    }\n    for (var i = 0; i < atoms.length; i++) {\n      var atom = atoms[i];\n      if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n        throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n      }\n      if (!atom.render) {\n        throw new Error('Atom \"' + atom.name + '\" must define `render`');\n      }\n    }\n  }\n\n  var RendererFactory = (function () {\n    function RendererFactory() {\n      var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n      var cards = _ref.cards;\n      var atoms = _ref.atoms;\n      var cardOptions = _ref.cardOptions;\n      var unknownCardHandler = _ref.unknownCardHandler;\n      var unknownAtomHandler = _ref.unknownAtomHandler;\n\n      _classCallCheck(this, RendererFactory);\n\n      cards = cards || [];\n      validateCards(cards);\n      atoms = atoms || [];\n      validateAtoms(atoms);\n      cardOptions = cardOptions || {};\n\n      this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n    }\n\n    _createClass(RendererFactory, [{\n      key: 'render',\n      value: function render(mobiledoc) {\n        var version = mobiledoc.version;\n\n        switch (version) {\n          case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION:\n            return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render();\n          case undefined:\n          case null:\n          case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3:\n          case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n          case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n            return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render();\n          default:\n            throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n        }\n      }\n    }]);\n\n    return RendererFactory;\n  })();\n\n  exports['default'] = RendererFactory;\n});","define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) {\n  /**\n   * runtime Text renderer\n   * renders a mobiledoc to Text\n   *\n   * input: mobiledoc\n   * output: Text (string)\n   */\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var LINE_BREAK = '\\n';\n\n  var MOBILEDOC_VERSION = '0.2.0';\n\n  exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n  function validateVersion(version) {\n    if (version !== MOBILEDOC_VERSION) {\n      throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n    }\n  }\n\n  var Renderer = (function () {\n    function Renderer(mobiledoc, state) {\n      _classCallCheck(this, Renderer);\n\n      var cards = state.cards;\n      var cardOptions = state.cardOptions;\n      var atoms = state.atoms;\n      var unknownCardHandler = state.unknownCardHandler;\n      var version = mobiledoc.version;\n      var sectionData = mobiledoc.sections;\n\n      validateVersion(version);\n\n      var _sectionData = _slicedToArray(sectionData, 2);\n\n      var sections = _sectionData[1];\n\n      this.root = [];\n      this.sections = sections;\n      this.cards = cards;\n      this.atoms = atoms;\n      this.cardOptions = cardOptions;\n      this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n      this._teardownCallbacks = [];\n    }\n\n    _createClass(Renderer, [{\n      key: 'render',\n      value: function render() {\n        var _this = this;\n\n        this.sections.forEach(function (section) {\n          _this.root.push(_this.renderSection(section));\n        });\n\n        var result = this.root.join(LINE_BREAK);\n        return { result: result, teardown: function teardown() {\n            return _this.teardown();\n          } };\n      }\n    }, {\n      key: 'teardown',\n      value: function teardown() {\n        for (var i = 0; i < this._teardownCallbacks.length; i++) {\n          this._teardownCallbacks[i]();\n        }\n      }\n    }, {\n      key: 'renderSection',\n\n      // for the text renderer, a missing card is a no-op\n      value: function renderSection(section) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n            return this.renderMarkupSection(section);\n          case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n            return this.renderImageSection(section);\n          case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n            return this.renderListSection(section);\n          case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n            return this.renderCardSection(section);\n          default:\n            throw new Error('Unimplemented renderer for type ' + type);\n        }\n      }\n    }, {\n      key: 'renderImageSection',\n      value: function renderImageSection() {\n        return '';\n      }\n    }, {\n      key: 'renderListSection',\n      value: function renderListSection(_ref) {\n        var _this2 = this;\n\n        var _ref2 = _slicedToArray(_ref, 3);\n\n        var type = _ref2[0];\n        var tagName = _ref2[1];\n        var items = _ref2[2];\n\n        return items.map(function (li) {\n          return _this2.renderListItem(li);\n        }).join(LINE_BREAK);\n      }\n    }, {\n      key: 'renderListItem',\n      value: function renderListItem(markers) {\n        return this.renderMarkers(markers);\n      }\n    }, {\n      key: 'findCard',\n      value: function findCard(name) {\n        for (var i = 0; i < this.cards.length; i++) {\n          if (this.cards[i].name === name) {\n            return this.cards[i];\n          }\n        }\n        if (name === _mobiledocTextRendererCardsImage['default'].name) {\n          return _mobiledocTextRendererCardsImage['default'];\n        }\n        return this._createUnknownCard(name);\n      }\n    }, {\n      key: '_createUnknownCard',\n      value: function _createUnknownCard(name) {\n        return {\n          name: name,\n          type: _mobiledocTextRendererUtilsRenderType['default'],\n          render: this.unknownCardHandler\n        };\n      }\n    }, {\n      key: 'renderCardSection',\n      value: function renderCardSection(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 3);\n\n        var type = _ref32[0];\n        var name = _ref32[1];\n        var payload = _ref32[2];\n\n        var card = this.findCard(name);\n\n        var cardArg = this._createCardArgument(card, payload);\n        var rendered = card.render(cardArg);\n\n        this._validateCardRender(rendered, card.name);\n\n        return rendered || '';\n      }\n    }, {\n      key: '_validateCardRender',\n      value: function _validateCardRender(rendered, cardName) {\n        if (!rendered) {\n          return;\n        }\n\n        if (typeof rendered !== 'string') {\n          throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n        }\n      }\n    }, {\n      key: '_registerTeardownCallback',\n      value: function _registerTeardownCallback(callback) {\n        this._teardownCallbacks.push(callback);\n      }\n    }, {\n      key: '_createCardArgument',\n      value: function _createCardArgument(card) {\n        var _this3 = this;\n\n        var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        var env = {\n          name: card.name,\n          isInEditor: false,\n          onTeardown: function onTeardown(callback) {\n            return _this3._registerTeardownCallback(callback);\n          }\n        };\n\n        var options = this.cardOptions;\n\n        return { env: env, options: options, payload: payload };\n      }\n    }, {\n      key: 'renderMarkupSection',\n      value: function renderMarkupSection(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 3);\n\n        var type = _ref42[0];\n        var tagName = _ref42[1];\n        var markers = _ref42[2];\n\n        return this.renderMarkers(markers);\n      }\n    }, {\n      key: 'renderMarkers',\n      value: function renderMarkers(markers) {\n        var str = '';\n        markers.forEach(function (m) {\n          var _m = _slicedToArray(m, 3);\n\n          var text = _m[2];\n\n          str += text;\n        });\n        return str;\n      }\n    }, {\n      key: '_defaultUnknownCardHandler',\n      get: function get() {\n        return function () {};\n      }\n    }]);\n\n    return Renderer;\n  })();\n\n  exports['default'] = Renderer;\n});","define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) {\n  /**\n   * runtime Text renderer\n   * renders a mobiledoc to Text\n   *\n   * input: mobiledoc\n   * output: Text (string)\n   */\n  'use strict';\n\n  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n  var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n  var LINE_BREAK = '\\n';\n\n  var MOBILEDOC_VERSION_0_3 = '0.3.0';\n  exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3;\n  var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n  exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n  var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n  exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n  function validateVersion(version) {\n    if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1 && version !== MOBILEDOC_VERSION_0_3_2) {\n      throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n    }\n  }\n\n  var Renderer = (function () {\n    function Renderer(mobiledoc, state) {\n      _classCallCheck(this, Renderer);\n\n      var cards = state.cards;\n      var cardOptions = state.cardOptions;\n      var atoms = state.atoms;\n      var unknownCardHandler = state.unknownCardHandler;\n      var unknownAtomHandler = state.unknownAtomHandler;\n      var version = mobiledoc.version;\n      var sections = mobiledoc.sections;\n      var atomTypes = mobiledoc.atoms;\n      var cardTypes = mobiledoc.cards;\n\n      validateVersion(version);\n\n      this.root = [];\n      this.sections = sections;\n      this.atomTypes = atomTypes;\n      this.cardTypes = cardTypes;\n      this.cards = cards;\n      this.atoms = atoms;\n      this.cardOptions = cardOptions;\n      this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n      this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n      this._teardownCallbacks = [];\n    }\n\n    _createClass(Renderer, [{\n      key: 'render',\n      value: function render() {\n        var _this = this;\n\n        this.sections.forEach(function (section) {\n          _this.root.push(_this.renderSection(section));\n        });\n\n        var result = this.root.join(LINE_BREAK);\n        return { result: result, teardown: function teardown() {\n            return _this.teardown();\n          } };\n      }\n    }, {\n      key: 'teardown',\n      value: function teardown() {\n        for (var i = 0; i < this._teardownCallbacks.length; i++) {\n          this._teardownCallbacks[i]();\n        }\n      }\n    }, {\n      key: 'renderSection',\n      value: function renderSection(section) {\n        var _section = _slicedToArray(section, 1);\n\n        var type = _section[0];\n\n        switch (type) {\n          case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n            return this.renderMarkupSection(section);\n          case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n            return this.renderImageSection(section);\n          case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n            return this.renderListSection(section);\n          case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n            return this.renderCardSection(section);\n          default:\n            throw new Error('Unimplemented renderer for type ' + type);\n        }\n      }\n    }, {\n      key: 'renderImageSection',\n      value: function renderImageSection() {\n        return '';\n      }\n    }, {\n      key: 'renderListSection',\n      value: function renderListSection(_ref) {\n        var _this2 = this;\n\n        var _ref2 = _slicedToArray(_ref, 3);\n\n        var type = _ref2[0];\n        var tagName = _ref2[1];\n        var items = _ref2[2];\n\n        return items.map(function (li) {\n          return _this2.renderListItem(li);\n        }).join(LINE_BREAK);\n      }\n    }, {\n      key: 'renderListItem',\n      value: function renderListItem(markers) {\n        return this.renderMarkers(markers);\n      }\n    }, {\n      key: 'findCard',\n      value: function findCard(name) {\n        for (var i = 0; i < this.cards.length; i++) {\n          if (this.cards[i].name === name) {\n            return this.cards[i];\n          }\n        }\n        if (name === _mobiledocTextRendererCardsImage['default'].name) {\n          return _mobiledocTextRendererCardsImage['default'];\n        }\n        return this._createUnknownCard(name);\n      }\n    }, {\n      key: '_findCardByIndex',\n      value: function _findCardByIndex(index) {\n        var cardType = this.cardTypes[index];\n        if (!cardType) {\n          throw new Error('No card definition found at index ' + index);\n        }\n\n        var _cardType = _slicedToArray(cardType, 2);\n\n        var name = _cardType[0];\n        var payload = _cardType[1];\n\n        var card = this.findCard(name);\n\n        return {\n          card: card,\n          payload: payload\n        };\n      }\n    }, {\n      key: '_createUnknownCard',\n      value: function _createUnknownCard(name) {\n        return {\n          name: name,\n          type: _mobiledocTextRendererUtilsRenderType['default'],\n          render: this.unknownCardHandler\n        };\n      }\n    }, {\n      key: 'renderCardSection',\n      value: function renderCardSection(_ref3) {\n        var _ref32 = _slicedToArray(_ref3, 2);\n\n        var type = _ref32[0];\n        var index = _ref32[1];\n\n        var _findCardByIndex2 = this._findCardByIndex(index);\n\n        var card = _findCardByIndex2.card;\n        var payload = _findCardByIndex2.payload;\n\n        var cardArg = this._createCardArgument(card, payload);\n        var rendered = card.render(cardArg);\n\n        this._validateCardRender(rendered, card.name);\n\n        return rendered || '';\n      }\n    }, {\n      key: '_validateCardRender',\n      value: function _validateCardRender(rendered, cardName) {\n        if (!rendered) {\n          return;\n        }\n\n        if (typeof rendered !== 'string') {\n          throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n        }\n      }\n    }, {\n      key: '_registerTeardownCallback',\n      value: function _registerTeardownCallback(callback) {\n        this._teardownCallbacks.push(callback);\n      }\n    }, {\n      key: '_createCardArgument',\n      value: function _createCardArgument(card) {\n        var _this3 = this;\n\n        var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n        var env = {\n          name: card.name,\n          isInEditor: false,\n          onTeardown: function onTeardown(callback) {\n            return _this3._registerTeardownCallback(callback);\n          }\n        };\n\n        var options = this.cardOptions;\n\n        return { env: env, options: options, payload: payload };\n      }\n    }, {\n      key: 'renderMarkupSection',\n      value: function renderMarkupSection(_ref4) {\n        var _ref42 = _slicedToArray(_ref4, 3);\n\n        var type = _ref42[0];\n        var tagName = _ref42[1];\n        var markers = _ref42[2];\n\n        return this.renderMarkers(markers);\n      }\n    }, {\n      key: 'findAtom',\n      value: function findAtom(name) {\n        for (var i = 0; i < this.atoms.length; i++) {\n          if (this.atoms[i].name === name) {\n            return this.atoms[i];\n          }\n        }\n        return this._createUnknownAtom(name);\n      }\n    }, {\n      key: '_createUnknownAtom',\n      value: function _createUnknownAtom(name) {\n        return {\n          name: name,\n          type: _mobiledocTextRendererUtilsRenderType['default'],\n          render: this.unknownAtomHandler\n        };\n      }\n    }, {\n      key: '_createAtomArgument',\n      value: function _createAtomArgument(atom, value, payload) {\n        var _this4 = this;\n\n        var env = {\n          name: atom.name,\n          onTeardown: function onTeardown(callback) {\n            return _this4._registerTeardownCallback(callback);\n          }\n        };\n\n        var options = this.cardOptions;\n\n        return { env: env, options: options, value: value, payload: payload };\n      }\n    }, {\n      key: '_validateAtomRender',\n      value: function _validateAtomRender(rendered, atomName) {\n        if (!rendered) {\n          return;\n        }\n\n        if (typeof rendered !== 'string') {\n          throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n        }\n      }\n    }, {\n      key: '_findAtomByIndex',\n      value: function _findAtomByIndex(index) {\n        var atomType = this.atomTypes[index];\n        if (!atomType) {\n          throw new Error('No atom definition found at index ' + index);\n        }\n\n        var _atomType = _slicedToArray(atomType, 3);\n\n        var name = _atomType[0];\n        var value = _atomType[1];\n        var payload = _atomType[2];\n\n        var atom = this.findAtom(name);\n\n        return {\n          atom: atom,\n          value: value,\n          payload: payload\n        };\n      }\n    }, {\n      key: '_renderAtom',\n      value: function _renderAtom(index) {\n        var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n        var atom = _findAtomByIndex2.atom;\n        var value = _findAtomByIndex2.value;\n        var payload = _findAtomByIndex2.payload;\n\n        var atomArg = this._createAtomArgument(atom, value, payload);\n        var rendered = atom.render(atomArg);\n\n        this._validateAtomRender(rendered, atom.name);\n\n        return rendered || '';\n      }\n    }, {\n      key: 'renderMarkers',\n      value: function renderMarkers(markers) {\n        var _this5 = this;\n\n        var str = '';\n        markers.forEach(function (m) {\n          var _m = _slicedToArray(m, 4);\n\n          var type = _m[0];\n          var value = _m[3];\n\n          switch (type) {\n            case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n              str += value;\n              break;\n            case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n              str += _this5._renderAtom(value);\n              break;\n            default:\n              throw new Error('Unknown markup type (' + type + ')');\n          }\n        });\n        return str;\n      }\n    }, {\n      key: '_defaultUnknownCardHandler',\n      get: function get() {\n        return function () {\n          // for the text renderer, a missing card is a no-op\n        };\n      }\n    }, {\n      key: '_defaultUnknownAtomHandler',\n      get: function get() {\n        return function (_ref5) {\n          var value = _ref5.value;\n\n          return value || '';\n        };\n      }\n    }]);\n\n    return Renderer;\n  })();\n\n  exports['default'] = Renderer;\n});","define(\"mobiledoc-text-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var MARKUP_MARKER_TYPE = 0;\n  exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n  var ATOM_MARKER_TYPE = 1;\n  exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) {\n  'use strict';\n\n  exports['default'] = 'text';\n});","define(\"mobiledoc-text-renderer/utils/section-types\", [\"exports\"], function (exports) {\n  \"use strict\";\n\n  var MARKUP_SECTION_TYPE = 1;\n  exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n  var IMAGE_SECTION_TYPE = 2;\n  exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n  var LIST_SECTION_TYPE = 3;\n  exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n  var CARD_SECTION_TYPE = 10;\n  exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACp3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC97CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5WA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;","file":"mobiledoc-kit.js"}