UNPKG

slate-dom

Version:

Tools for building completely customizable richtext editors with React.

2,565 lines 102 kB
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('slate')) :
	typeof define === 'function' && define.amd ? define(['exports', 'slate'], factory) :
	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SlateDom = {}, global.Slate));
})(this, (function (exports, slate) { 'use strict';

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

	function createCommonjsModule(fn, module) {
		return module = { exports: {} }, fn(module, module.exports), module.exports;
	}

	var arrayLikeToArray = createCommonjsModule(function (module) {
	function _arrayLikeToArray(arr, len) {
	  if (len == null || len > arr.length) len = arr.length;
	  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
	  return arr2;
	}
	module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(arrayLikeToArray);

	var arrayWithoutHoles = createCommonjsModule(function (module) {
	function _arrayWithoutHoles(arr) {
	  if (Array.isArray(arr)) return arrayLikeToArray(arr);
	}
	module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(arrayWithoutHoles);

	var iterableToArray = createCommonjsModule(function (module) {
	function _iterableToArray(iter) {
	  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
	}
	module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(iterableToArray);

	var unsupportedIterableToArray = createCommonjsModule(function (module) {
	function _unsupportedIterableToArray(o, minLen) {
	  if (!o) return;
	  if (typeof o === "string") return arrayLikeToArray(o, minLen);
	  var n = Object.prototype.toString.call(o).slice(8, -1);
	  if (n === "Object" && o.constructor) n = o.constructor.name;
	  if (n === "Map" || n === "Set") return Array.from(o);
	  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
	}
	module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(unsupportedIterableToArray);

	var nonIterableSpread = createCommonjsModule(function (module) {
	function _nonIterableSpread() {
	  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	}
	module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(nonIterableSpread);

	var toConsumableArray = createCommonjsModule(function (module) {
	function _toConsumableArray(arr) {
	  return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
	}
	module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	var _toConsumableArray = unwrapExports(toConsumableArray);

	var arrayWithHoles = createCommonjsModule(function (module) {
	function _arrayWithHoles(arr) {
	  if (Array.isArray(arr)) return arr;
	}
	module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(arrayWithHoles);

	var iterableToArrayLimit = createCommonjsModule(function (module) {
	function _iterableToArrayLimit(r, l) {
	  var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
	  if (null != t) {
	    var e,
	      n,
	      i,
	      u,
	      a = [],
	      f = !0,
	      o = !1;
	    try {
	      if (i = (t = t.call(r)).next, 0 === l) {
	        if (Object(t) !== t) return;
	        f = !1;
	      } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
	    } catch (r) {
	      o = !0, n = r;
	    } finally {
	      try {
	        if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return;
	      } finally {
	        if (o) throw n;
	      }
	    }
	    return a;
	  }
	}
	module.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(iterableToArrayLimit);

	var nonIterableRest = createCommonjsModule(function (module) {
	function _nonIterableRest() {
	  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	}
	module.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(nonIterableRest);

	var slicedToArray = createCommonjsModule(function (module) {
	function _slicedToArray(arr, i) {
	  return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
	}
	module.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	var _slicedToArray = unwrapExports(slicedToArray);

	function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
	function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$2(o, minLen); }
	function _arrayLikeToArray$2(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
	/**
	 * Types.
	 */
	// COMPAT: This is required to prevent TypeScript aliases from doing some very
	// weird things for Slate's types with the same name as globals. (2019/11/27)
	// https://github.com/microsoft/TypeScript/issues/35002
	var DOMNode = globalThis.Node;
	var DOMElement = globalThis.Element;
	var DOMText = globalThis.Text;
	var DOMRange = globalThis.Range;
	var DOMSelection = globalThis.Selection;
	var DOMStaticRange = globalThis.StaticRange;
	/**
	 * Returns the host window of a DOM node
	 */
	var getDefaultView = function getDefaultView(value) {
	  return value && value.ownerDocument && value.ownerDocument.defaultView || null;
	};
	/**
	 * Check if a DOM node is a comment node.
	 */
	var isDOMComment = function isDOMComment(value) {
	  return isDOMNode(value) && value.nodeType === 8;
	};
	/**
	 * Check if a DOM node is an element node.
	 */
	var isDOMElement = function isDOMElement(value) {
	  return isDOMNode(value) && value.nodeType === 1;
	};
	/**
	 * Check if a value is a DOM node.
	 */
	var isDOMNode = function isDOMNode(value) {
	  var window = getDefaultView(value);
	  return !!window && value instanceof window.Node;
	};
	/**
	 * Check if a value is a DOM selection.
	 */
	var isDOMSelection = function isDOMSelection(value) {
	  var window = value && value.anchorNode && getDefaultView(value.anchorNode);
	  return !!window && value instanceof window.Selection;
	};
	/**
	 * Check if a DOM node is an element node.
	 */
	var isDOMText = function isDOMText(value) {
	  return isDOMNode(value) && value.nodeType === 3;
	};
	/**
	 * Checks whether a paste event is a plaintext-only event.
	 */
	var isPlainTextOnlyPaste = function isPlainTextOnlyPaste(event) {
	  return event.clipboardData && event.clipboardData.getData('text/plain') !== '' && event.clipboardData.types.length === 1;
	};
	/**
	 * Normalize a DOM point so that it always refers to a text node.
	 */
	var normalizeDOMPoint = function normalizeDOMPoint(domPoint) {
	  var _domPoint = _slicedToArray(domPoint, 2),
	    node = _domPoint[0],
	    offset = _domPoint[1];
	  // If it's an element node, its offset refers to the index of its children
	  // including comment nodes, so try to find the right text child node.
	  if (isDOMElement(node) && node.childNodes.length) {
	    var isLast = offset === node.childNodes.length;
	    var index = isLast ? offset - 1 : offset;
	    // If the editable child found is in front of input offset, we instead seek to its end
	    var _getEditableChildAndI = getEditableChildAndIndex(node, index, isLast ? 'backward' : 'forward');
	    var _getEditableChildAndI2 = _slicedToArray(_getEditableChildAndI, 2);
	    node = _getEditableChildAndI2[0];
	    index = _getEditableChildAndI2[1];
	    isLast = index < offset;
	    // If the node has children, traverse until we have a leaf node. Leaf nodes
	    // can be either text nodes, or other void DOM nodes.
	    while (isDOMElement(node) && node.childNodes.length) {
	      var i = isLast ? node.childNodes.length - 1 : 0;
	      node = getEditableChild(node, i, isLast ? 'backward' : 'forward');
	    }
	    // Determine the new offset inside the text node.
	    offset = isLast && node.textContent != null ? node.textContent.length : 0;
	  }
	  // Return the node and offset.
	  return [node, offset];
	};
	/**
	 * Determines whether the active element is nested within a shadowRoot
	 */
	var hasShadowRoot = function hasShadowRoot(node) {
	  var parent = node && node.parentNode;
	  while (parent) {
	    if (parent.toString() === '[object ShadowRoot]') {
	      return true;
	    }
	    parent = parent.parentNode;
	  }
	  return false;
	};
	/**
	 * Get the nearest editable child and index at `index` in a `parent`, preferring
	 * `direction`.
	 */
	var getEditableChildAndIndex = function getEditableChildAndIndex(parent, index, direction) {
	  var childNodes = parent.childNodes;
	  var child = childNodes[index];
	  var i = index;
	  var triedForward = false;
	  var triedBackward = false;
	  // While the child is a comment node, or an element node with no children,
	  // keep iterating to find a sibling non-void, non-comment node.
	  while (isDOMComment(child) || isDOMElement(child) && child.childNodes.length === 0 || isDOMElement(child) && child.getAttribute('contenteditable') === 'false') {
	    if (triedForward && triedBackward) {
	      break;
	    }
	    if (i >= childNodes.length) {
	      triedForward = true;
	      i = index - 1;
	      direction = 'backward';
	      continue;
	    }
	    if (i < 0) {
	      triedBackward = true;
	      i = index + 1;
	      direction = 'forward';
	      continue;
	    }
	    child = childNodes[i];
	    index = i;
	    i += direction === 'forward' ? 1 : -1;
	  }
	  return [child, index];
	};
	/**
	 * Get the nearest editable child at `index` in a `parent`, preferring
	 * `direction`.
	 */
	var getEditableChild = function getEditableChild(parent, index, direction) {
	  var _getEditableChildAndI3 = getEditableChildAndIndex(parent, index, direction),
	    _getEditableChildAndI4 = _slicedToArray(_getEditableChildAndI3, 1),
	    child = _getEditableChildAndI4[0];
	  return child;
	};
	/**
	 * Get a plaintext representation of the content of a node, accounting for block
	 * elements which get a newline appended.
	 *
	 * The domNode must be attached to the DOM.
	 */
	var getPlainText = function getPlainText(domNode) {
	  var text = '';
	  if (isDOMText(domNode) && domNode.nodeValue) {
	    return domNode.nodeValue;
	  }
	  if (isDOMElement(domNode)) {
	    for (var _i = 0, _Array$from = Array.from(domNode.childNodes); _i < _Array$from.length; _i++) {
	      var childNode = _Array$from[_i];
	      text += getPlainText(childNode);
	    }
	    var display = getComputedStyle(domNode).getPropertyValue('display');
	    if (display === 'block' || display === 'list' || domNode.tagName === 'BR') {
	      text += '\n';
	    }
	  }
	  return text;
	};
	/**
	 * Get x-slate-fragment attribute from data-slate-fragment
	 */
	var catchSlateFragment = /data-slate-fragment="(.+?)"/m;
	var getSlateFragmentAttribute = function getSlateFragmentAttribute(dataTransfer) {
	  var htmlData = dataTransfer.getData('text/html');
	  var _ref = htmlData.match(catchSlateFragment) || [],
	    _ref2 = _slicedToArray(_ref, 2),
	    fragment = _ref2[1];
	  return fragment;
	};
	/**
	 * Get the dom selection from Shadow Root if possible, otherwise from the document
	 */
	var getSelection = function getSelection(root) {
	  if (root.getSelection != null) {
	    return root.getSelection();
	  }
	  return document.getSelection();
	};
	/**
	 * Check whether a mutation originates from a editable element inside the editor.
	 */
	var isTrackedMutation = function isTrackedMutation(editor, mutation, batch) {
	  var target = mutation.target;
	  if (isDOMElement(target) && target.matches('[contentEditable="false"]')) {
	    return false;
	  }
	  var _DOMEditor$getWindow = DOMEditor.getWindow(editor),
	    document = _DOMEditor$getWindow.document;
	  if (document.contains(target)) {
	    return DOMEditor.hasDOMNode(editor, target, {
	      editable: true
	    });
	  }
	  var parentMutation = batch.find(function (_ref3) {
	    var addedNodes = _ref3.addedNodes,
	      removedNodes = _ref3.removedNodes;
	    var _iterator = _createForOfIteratorHelper$2(addedNodes),
	      _step;
	    try {
	      for (_iterator.s(); !(_step = _iterator.n()).done;) {
	        var node = _step.value;
	        if (node === target || node.contains(target)) {
	          return true;
	        }
	      }
	    } catch (err) {
	      _iterator.e(err);
	    } finally {
	      _iterator.f();
	    }
	    var _iterator2 = _createForOfIteratorHelper$2(removedNodes),
	      _step2;
	    try {
	      for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
	        var _node = _step2.value;
	        if (_node === target || _node.contains(target)) {
	          return true;
	        }
	      }
	    } catch (err) {
	      _iterator2.e(err);
	    } finally {
	      _iterator2.f();
	    }
	  });
	  if (!parentMutation || parentMutation === mutation) {
	    return false;
	  }
	  // Target add/remove is tracked. Track the mutation if we track the parent mutation.
	  return isTrackedMutation(editor, parentMutation, batch);
	};
	/**
	 * Retrieves the deepest active element in the DOM, considering nested shadow DOMs.
	 */
	var getActiveElement = function getActiveElement() {
	  var activeElement = document.activeElement;
	  while ((_activeElement = activeElement) !== null && _activeElement !== void 0 && _activeElement.shadowRoot && (_activeElement$shadow = activeElement.shadowRoot) !== null && _activeElement$shadow !== void 0 && _activeElement$shadow.activeElement) {
	    var _activeElement, _activeElement$shadow, _activeElement2;
	    activeElement = (_activeElement2 = activeElement) === null || _activeElement2 === void 0 || (_activeElement2 = _activeElement2.shadowRoot) === null || _activeElement2 === void 0 ? void 0 : _activeElement2.activeElement;
	  }
	  return activeElement;
	};
	/**
	 * @returns `true` if `otherNode` is before `node` in the document; otherwise, `false`.
	 */
	var isBefore = function isBefore(node, otherNode) {
	  return Boolean(node.compareDocumentPosition(otherNode) & DOMNode.DOCUMENT_POSITION_PRECEDING);
	};
	/**
	 * @returns `true` if `otherNode` is after `node` in the document; otherwise, `false`.
	 */
	var isAfter = function isAfter(node, otherNode) {
	  return Boolean(node.compareDocumentPosition(otherNode) & DOMNode.DOCUMENT_POSITION_FOLLOWING);
	};

	var _navigator$userAgent$, _navigator$userAgent$2;
	var IS_IOS = typeof navigator !== 'undefined' && typeof window !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
	var IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
	var IS_ANDROID = typeof navigator !== 'undefined' && /Android/.test(navigator.userAgent);
	var IS_FIREFOX = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
	var IS_WEBKIT = typeof navigator !== 'undefined' && /AppleWebKit(?!.*Chrome)/i.test(navigator.userAgent);
	// "modern" Edge was released at 79.x
	var IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]|[0-7][0-8])(?:\.)/i.test(navigator.userAgent);
	var IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent);
	// Native `beforeInput` events don't work well with react on Chrome 75
	// and older, Chrome 76+ can use `beforeInput` though.
	var IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])(?:\.)/i.test(navigator.userAgent);
	var IS_ANDROID_CHROME_LEGACY = IS_ANDROID && typeof navigator !== 'undefined' && /Chrome?\/(?:[0-5]?\d)(?:\.)/i.test(navigator.userAgent);
	// Firefox did not support `beforeInput` until `v87`.
	var IS_FIREFOX_LEGACY = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox\/(?:[0-7][0-9]|[0-8][0-6])(?:\.)).*/i.test(navigator.userAgent);
	// UC mobile browser
	var IS_UC_MOBILE = typeof navigator !== 'undefined' && /.*UCBrowser/.test(navigator.userAgent);
	// Wechat browser (not including mac wechat)
	var IS_WECHATBROWSER = typeof navigator !== 'undefined' && /.*Wechat/.test(navigator.userAgent) && !/.*MacWechat/.test(navigator.userAgent) && (
	// avoid lookbehind (buggy in safari < 16.4)
	!IS_CHROME || IS_CHROME_LEGACY); // wechat and low chrome is real wechat
	// Check if DOM is available as React does internally.
	// https://github.com/facebook/react/blob/master/packages/shared/ExecutionEnvironment.js
	var CAN_USE_DOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
	// Check if the browser is Safari and older than 17
	typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) && /Version\/(\d+)/.test(navigator.userAgent) && ((_navigator$userAgent$ = navigator.userAgent.match(/Version\/(\d+)/)) !== null && _navigator$userAgent$ !== void 0 && _navigator$userAgent$[1] ? parseInt((_navigator$userAgent$2 = navigator.userAgent.match(/Version\/(\d+)/)) === null || _navigator$userAgent$2 === void 0 ? void 0 : _navigator$userAgent$2[1], 10) < 17 : false);
	// COMPAT: Firefox/Edge Legacy don't support the `beforeinput` event
	// Chrome Legacy doesn't support `beforeinput` correctly
	var HAS_BEFORE_INPUT_SUPPORT = (!IS_CHROME_LEGACY || !IS_ANDROID_CHROME_LEGACY) && !IS_EDGE_LEGACY &&
	// globalThis is undefined in older browsers
	typeof globalThis !== 'undefined' && globalThis.InputEvent &&
	// @ts-ignore The `getTargetRanges` property isn't recognized.
	typeof globalThis.InputEvent.prototype.getTargetRanges === 'function';

	var _typeof_1 = createCommonjsModule(function (module) {
	function _typeof(o) {
	  "@babel/helpers - typeof";

	  return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
	    return typeof o;
	  } : function (o) {
	    return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	  }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(o);
	}
	module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(_typeof_1);

	var toPrimitive = createCommonjsModule(function (module) {
	var _typeof = _typeof_1["default"];
	function _toPrimitive(input, hint) {
	  if (_typeof(input) !== "object" || input === null) return input;
	  var prim = input[Symbol.toPrimitive];
	  if (prim !== undefined) {
	    var res = prim.call(input, hint || "default");
	    if (_typeof(res) !== "object") return res;
	    throw new TypeError("@@toPrimitive must return a primitive value.");
	  }
	  return (hint === "string" ? String : Number)(input);
	}
	module.exports = _toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(toPrimitive);

	var toPropertyKey = createCommonjsModule(function (module) {
	var _typeof = _typeof_1["default"];

	function _toPropertyKey(arg) {
	  var key = toPrimitive(arg, "string");
	  return _typeof(key) === "symbol" ? key : String(key);
	}
	module.exports = _toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(toPropertyKey);

	var createClass = createCommonjsModule(function (module) {
	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, toPropertyKey(descriptor.key), descriptor);
	  }
	}
	function _createClass(Constructor, protoProps, staticProps) {
	  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
	  if (staticProps) _defineProperties(Constructor, staticProps);
	  Object.defineProperty(Constructor, "prototype", {
	    writable: false
	  });
	  return Constructor;
	}
	module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	var _createClass = unwrapExports(createClass);

	var classCallCheck = createCommonjsModule(function (module) {
	function _classCallCheck(instance, Constructor) {
	  if (!(instance instanceof Constructor)) {
	    throw new TypeError("Cannot call a class as a function");
	  }
	}
	module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	var _classCallCheck = unwrapExports(classCallCheck);

	var defineProperty = createCommonjsModule(function (module) {
	function _defineProperty(obj, key, value) {
	  key = toPropertyKey(key);
	  if (key in obj) {
	    Object.defineProperty(obj, key, {
	      value: value,
	      enumerable: true,
	      configurable: true,
	      writable: true
	    });
	  } else {
	    obj[key] = value;
	  }
	  return obj;
	}
	module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	var _defineProperty = unwrapExports(defineProperty);

	/**
	 * An auto-incrementing identifier for keys.
	 */
	var n = 0;
	/**
	 * A class that keeps track of a key string. We use a full class here because we
	 * want to be able to use them as keys in `WeakMap` objects.
	 */
	var Key = /*#__PURE__*/_createClass(function Key() {
	  _classCallCheck(this, Key);
	  _defineProperty(this, "id", void 0);
	  this.id = "".concat(n++);
	});

	/**
	 * Two weak maps that allow us rebuild a path given a node. They are populated
	 * at render time such that after a render occurs we can always backtrack.
	 */
	var IS_NODE_MAP_DIRTY = new WeakMap();
	var NODE_TO_INDEX = new WeakMap();
	var NODE_TO_PARENT = new WeakMap();
	/**
	 * Weak maps that allow us to go between Slate nodes and DOM nodes. These
	 * are used to resolve DOM event-related logic into Slate actions.
	 */
	var EDITOR_TO_WINDOW = new WeakMap();
	var EDITOR_TO_ELEMENT = new WeakMap();
	var EDITOR_TO_PLACEHOLDER_ELEMENT = new WeakMap();
	var ELEMENT_TO_NODE = new WeakMap();
	var NODE_TO_ELEMENT = new WeakMap();
	var NODE_TO_KEY = new WeakMap();
	var EDITOR_TO_KEY_TO_ELEMENT = new WeakMap();
	/**
	 * Weak maps for storing editor-related state.
	 */
	var IS_READ_ONLY = new WeakMap();
	var IS_FOCUSED = new WeakMap();
	var IS_COMPOSING = new WeakMap();
	var EDITOR_TO_USER_SELECTION = new WeakMap();
	/**
	 * Weak map for associating the context `onChange` context with the plugin.
	 */
	var EDITOR_TO_ON_CHANGE = new WeakMap();
	/**
	 * Weak maps for saving pending state on composition stage.
	 */
	var EDITOR_TO_SCHEDULE_FLUSH = new WeakMap();
	var EDITOR_TO_PENDING_INSERTION_MARKS = new WeakMap();
	var EDITOR_TO_USER_MARKS = new WeakMap();
	/**
	 * Android input handling specific weak-maps
	 */
	var EDITOR_TO_PENDING_DIFFS = new WeakMap();
	var EDITOR_TO_PENDING_ACTION = new WeakMap();
	var EDITOR_TO_PENDING_SELECTION = new WeakMap();
	var EDITOR_TO_FORCE_RENDER = new WeakMap();
	/**
	 * Symbols.
	 */
	var PLACEHOLDER_SYMBOL = Symbol('placeholder');
	var MARK_PLACEHOLDER_SYMBOL = Symbol('mark-placeholder');

	// eslint-disable-next-line no-redeclare
	var DOMEditor = {
	  androidPendingDiffs: function androidPendingDiffs(editor) {
	    return EDITOR_TO_PENDING_DIFFS.get(editor);
	  },
	  androidScheduleFlush: function androidScheduleFlush(editor) {
	    var _EDITOR_TO_SCHEDULE_F;
	    (_EDITOR_TO_SCHEDULE_F = EDITOR_TO_SCHEDULE_FLUSH.get(editor)) === null || _EDITOR_TO_SCHEDULE_F === void 0 || _EDITOR_TO_SCHEDULE_F();
	  },
	  blur: function blur(editor) {
	    var el = DOMEditor.toDOMNode(editor, editor);
	    var root = DOMEditor.findDocumentOrShadowRoot(editor);
	    IS_FOCUSED.set(editor, false);
	    if (root.activeElement === el) {
	      el.blur();
	    }
	  },
	  deselect: function deselect(editor) {
	    var selection = editor.selection;
	    var root = DOMEditor.findDocumentOrShadowRoot(editor);
	    var domSelection = getSelection(root);
	    if (domSelection && domSelection.rangeCount > 0) {
	      domSelection.removeAllRanges();
	    }
	    if (selection) {
	      slate.Transforms.deselect(editor);
	    }
	  },
	  findDocumentOrShadowRoot: function findDocumentOrShadowRoot(editor) {
	    var el = DOMEditor.toDOMNode(editor, editor);
	    var root = el.getRootNode();
	    if (root instanceof Document || root instanceof ShadowRoot) {
	      return root;
	    }
	    return el.ownerDocument;
	  },
	  findEventRange: function findEventRange(editor, event) {
	    if ('nativeEvent' in event) {
	      event = event.nativeEvent;
	    }
	    var _event = event,
	      x = _event.clientX,
	      y = _event.clientY,
	      target = _event.target;
	    if (x == null || y == null) {
	      throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
	    }
	    var node = DOMEditor.toSlateNode(editor, event.target);
	    var path = DOMEditor.findPath(editor, node);
	    // If the drop target is inside a void node, move it into either the
	    // next or previous node, depending on which side the `x` and `y`
	    // coordinates are closest to.
	    if (slate.Element.isElement(node) && slate.Editor.isVoid(editor, node)) {
	      var rect = target.getBoundingClientRect();
	      var isPrev = editor.isInline(node) ? x - rect.left < rect.left + rect.width - x : y - rect.top < rect.top + rect.height - y;
	      var edge = slate.Editor.point(editor, path, {
	        edge: isPrev ? 'start' : 'end'
	      });
	      var point = isPrev ? slate.Editor.before(editor, edge) : slate.Editor.after(editor, edge);
	      if (point) {
	        var _range = slate.Editor.range(editor, point);
	        return _range;
	      }
	    }
	    // Else resolve a range from the caret position where the drop occured.
	    var domRange;
	    var _DOMEditor$getWindow = DOMEditor.getWindow(editor),
	      document = _DOMEditor$getWindow.document;
	    // COMPAT: In Firefox, `caretRangeFromPoint` doesn't exist. (2016/07/25)
	    if (document.caretRangeFromPoint) {
	      domRange = document.caretRangeFromPoint(x, y);
	    } else {
	      var position = document.caretPositionFromPoint(x, y);
	      if (position) {
	        domRange = document.createRange();
	        domRange.setStart(position.offsetNode, position.offset);
	        domRange.setEnd(position.offsetNode, position.offset);
	      }
	    }
	    if (!domRange) {
	      throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
	    }
	    // Resolve a Slate range from the DOM range.
	    var range = DOMEditor.toSlateRange(editor, domRange, {
	      exactMatch: false,
	      suppressThrow: false
	    });
	    return range;
	  },
	  findKey: function findKey(editor, node) {
	    var key = NODE_TO_KEY.get(node);
	    if (!key) {
	      key = new Key();
	      NODE_TO_KEY.set(node, key);
	    }
	    return key;
	  },
	  findPath: function findPath(editor, node) {
	    var path = [];
	    var child = node;
	    while (true) {
	      var parent = NODE_TO_PARENT.get(child);
	      if (parent == null) {
	        if (slate.Editor.isEditor(child)) {
	          return path;
	        } else {
	          break;
	        }
	      }
	      var i = NODE_TO_INDEX.get(child);
	      if (i == null) {
	        break;
	      }
	      path.unshift(i);
	      child = parent;
	    }
	    throw new Error("Unable to find the path for Slate node: ".concat(slate.Scrubber.stringify(node)));
	  },
	  focus: function focus(editor) {
	    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
	      retries: 5
	    };
	    // Return if already focused
	    if (IS_FOCUSED.get(editor)) {
	      return;
	    }
	    // Return if no dom node is associated with the editor, which means the editor is not yet mounted
	    // or has been unmounted. This can happen especially, while retrying to focus the editor.
	    if (!EDITOR_TO_ELEMENT.get(editor)) {
	      return;
	    }
	    // Retry setting focus if the editor has pending operations.
	    // The DOM (selection) is unstable while changes are applied.
	    // Retry until retries are exhausted or editor is focused.
	    if (options.retries <= 0) {
	      throw new Error('Could not set focus, editor seems stuck with pending operations');
	    }
	    if (editor.operations.length > 0) {
	      setTimeout(function () {
	        DOMEditor.focus(editor, {
	          retries: options.retries - 1
	        });
	      }, 10);
	      return;
	    }
	    var el = DOMEditor.toDOMNode(editor, editor);
	    var root = DOMEditor.findDocumentOrShadowRoot(editor);
	    if (root.activeElement !== el) {
	      // Ensure that the DOM selection state is set to the editor's selection
	      if (editor.selection && root instanceof Document) {
	        var domSelection = getSelection(root);
	        var domRange = DOMEditor.toDOMRange(editor, editor.selection);
	        domSelection === null || domSelection === void 0 || domSelection.removeAllRanges();
	        domSelection === null || domSelection === void 0 || domSelection.addRange(domRange);
	      }
	      // Create a new selection in the top of the document if missing
	      if (!editor.selection) {
	        slate.Transforms.select(editor, slate.Editor.start(editor, []));
	      }
	      // IS_FOCUSED should be set before calling el.focus() to ensure that
	      // FocusedContext is updated to the correct value
	      IS_FOCUSED.set(editor, true);
	      el.focus({
	        preventScroll: true
	      });
	    }
	  },
	  getWindow: function getWindow(editor) {
	    var window = EDITOR_TO_WINDOW.get(editor);
	    if (!window) {
	      throw new Error('Unable to find a host window element for this editor');
	    }
	    return window;
	  },
	  hasDOMNode: function hasDOMNode(editor, target) {
	    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
	    var _options$editable = options.editable,
	      editable = _options$editable === void 0 ? false : _options$editable;
	    var editorEl = DOMEditor.toDOMNode(editor, editor);
	    var targetEl;
	    // COMPAT: In Firefox, reading `target.nodeType` will throw an error if
	    // target is originating from an internal "restricted" element (e.g. a
	    // stepper arrow on a number input). (2018/05/04)
	    // https://github.com/ianstormtaylor/slate/issues/1819
	    try {
	      targetEl = isDOMElement(target) ? target : target.parentElement;
	    } catch (err) {
	      if (err instanceof Error && !err.message.includes('Permission denied to access property "nodeType"')) {
	        throw err;
	      }
	    }
	    if (!targetEl) {
	      return false;
	    }
	    return targetEl.closest("[data-slate-editor]") === editorEl && (!editable || targetEl.isContentEditable ? true : typeof targetEl.isContentEditable === 'boolean' &&
	    // isContentEditable exists only on HTMLElement, and on other nodes it will be undefined
	    // this is the core logic that lets you know you got the right editor.selection instead of null when editor is contenteditable="false"(readOnly)
	    targetEl.closest('[contenteditable="false"]') === editorEl || !!targetEl.getAttribute('data-slate-zero-width'));
	  },
	  hasEditableTarget: function hasEditableTarget(editor, target) {
	    return isDOMNode(target) && DOMEditor.hasDOMNode(editor, target, {
	      editable: true
	    });
	  },
	  hasRange: function hasRange(editor, range) {
	    var anchor = range.anchor,
	      focus = range.focus;
	    return slate.Editor.hasPath(editor, anchor.path) && slate.Editor.hasPath(editor, focus.path);
	  },
	  hasSelectableTarget: function hasSelectableTarget(editor, target) {
	    return DOMEditor.hasEditableTarget(editor, target) || DOMEditor.isTargetInsideNonReadonlyVoid(editor, target);
	  },
	  hasTarget: function hasTarget(editor, target) {
	    return isDOMNode(target) && DOMEditor.hasDOMNode(editor, target);
	  },
	  insertData: function insertData(editor, data) {
	    editor.insertData(data);
	  },
	  insertFragmentData: function insertFragmentData(editor, data) {
	    return editor.insertFragmentData(data);
	  },
	  insertTextData: function insertTextData(editor, data) {
	    return editor.insertTextData(data);
	  },
	  isComposing: function isComposing(editor) {
	    return !!IS_COMPOSING.get(editor);
	  },
	  isFocused: function isFocused(editor) {
	    return !!IS_FOCUSED.get(editor);
	  },
	  isReadOnly: function isReadOnly(editor) {
	    return !!IS_READ_ONLY.get(editor);
	  },
	  isTargetInsideNonReadonlyVoid: function isTargetInsideNonReadonlyVoid(editor, target) {
	    if (IS_READ_ONLY.get(editor)) return false;
	    var slateNode = DOMEditor.hasTarget(editor, target) && DOMEditor.toSlateNode(editor, target);
	    return slate.Element.isElement(slateNode) && slate.Editor.isVoid(editor, slateNode);
	  },
	  setFragmentData: function setFragmentData(editor, data, originEvent) {
	    return editor.setFragmentData(data, originEvent);
	  },
	  toDOMNode: function toDOMNode(editor, node) {
	    var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
	    var domNode = slate.Editor.isEditor(node) ? EDITOR_TO_ELEMENT.get(editor) : KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.get(DOMEditor.findKey(editor, node));
	    if (!domNode) {
	      throw new Error("Cannot resolve a DOM node from Slate node: ".concat(slate.Scrubber.stringify(node)));
	    }
	    return domNode;
	  },
	  toDOMPoint: function toDOMPoint(editor, point) {
	    var _Editor$node = slate.Editor.node(editor, point.path),
	      _Editor$node2 = _slicedToArray(_Editor$node, 1),
	      node = _Editor$node2[0];
	    var el = DOMEditor.toDOMNode(editor, node);
	    var domPoint;
	    // If we're inside a void node, force the offset to 0, otherwise the zero
	    // width spacing character will result in an incorrect offset of 1
	    if (slate.Editor["void"](editor, {
	      at: point
	    })) {
	      point = {
	        path: point.path,
	        offset: 0
	      };
	    }
	    // For each leaf, we need to isolate its content, which means filtering
	    // to its direct text and zero-width spans. (We have to filter out any
	    // other siblings that may have been rendered alongside them.)
	    var selector = "[data-slate-string], [data-slate-zero-width]";
	    var texts = Array.from(el.querySelectorAll(selector));
	    var start = 0;
	    for (var i = 0; i < texts.length; i++) {
	      var text = texts[i];
	      var domNode = text.childNodes[0];
	      if (domNode == null || domNode.textContent == null) {
	        continue;
	      }
	      var length = domNode.textContent.length;
	      var attr = text.getAttribute('data-slate-length');
	      var trueLength = attr == null ? length : parseInt(attr, 10);
	      var end = start + trueLength;
	      // Prefer putting the selection inside the mark placeholder to ensure
	      // composed text is displayed with the correct marks.
	      var nextText = texts[i + 1];
	      if (point.offset === end && nextText !== null && nextText !== void 0 && nextText.hasAttribute('data-slate-mark-placeholder')) {
	        var _nextText$textContent;
	        var domText = nextText.childNodes[0];
	        domPoint = [
	        // COMPAT: If we don't explicity set the dom point to be on the actual
	        // dom text element, chrome will put the selection behind the actual dom
	        // text element, causing domRange.getBoundingClientRect() calls on a collapsed
	        // selection to return incorrect zero values (https://bugs.chromium.org/p/chromium/issues/detail?id=435438)
	        // which will cause issues when scrolling to it.
	        domText instanceof DOMText ? domText : nextText, (_nextText$textContent = nextText.textContent) !== null && _nextText$textContent !== void 0 && _nextText$textContent.startsWith("\uFEFF") ? 1 : 0];
	        break;
	      }
	      if (point.offset <= end) {
	        var offset = Math.min(length, Math.max(0, point.offset - start));
	        domPoint = [domNode, offset];
	        break;
	      }
	      start = end;
	    }
	    if (!domPoint) {
	      throw new Error("Cannot resolve a DOM point from Slate point: ".concat(slate.Scrubber.stringify(point)));
	    }
	    return domPoint;
	  },
	  toDOMRange: function toDOMRange(editor, range) {
	    var anchor = range.anchor,
	      focus = range.focus;
	    var isBackward = slate.Range.isBackward(range);
	    var domAnchor = DOMEditor.toDOMPoint(editor, anchor);
	    var domFocus = slate.Range.isCollapsed(range) ? domAnchor : DOMEditor.toDOMPoint(editor, focus);
	    var window = DOMEditor.getWindow(editor);
	    var domRange = window.document.createRange();
	    var _ref = isBackward ? domFocus : domAnchor,
	      _ref2 = _slicedToArray(_ref, 2),
	      startNode = _ref2[0],
	      startOffset = _ref2[1];
	    var _ref3 = isBackward ? domAnchor : domFocus,
	      _ref4 = _slicedToArray(_ref3, 2),
	      endNode = _ref4[0],
	      endOffset = _ref4[1];
	    // A slate Point at zero-width Leaf always has an offset of 0 but a native DOM selection at
	    // zero-width node has an offset of 1 so we have to check if we are in a zero-width node and
	    // adjust the offset accordingly.
	    var startEl = isDOMElement(startNode) ? startNode : startNode.parentElement;
	    var isStartAtZeroWidth = !!startEl.getAttribute('data-slate-zero-width');
	    var endEl = isDOMElement(endNode) ? endNode : endNode.parentElement;
	    var isEndAtZeroWidth = !!endEl.getAttribute('data-slate-zero-width');
	    domRange.setStart(startNode, isStartAtZeroWidth ? 1 : startOffset);
	    domRange.setEnd(endNode, isEndAtZeroWidth ? 1 : endOffset);
	    return domRange;
	  },
	  toSlateNode: function toSlateNode(editor, domNode) {
	    var domEl = isDOMElement(domNode) ? domNode : domNode.parentElement;
	    if (domEl && !domEl.hasAttribute('data-slate-node')) {
	      domEl = domEl.closest("[data-slate-node]");
	    }
	    var node = domEl ? ELEMENT_TO_NODE.get(domEl) : null;
	    if (!node) {
	      throw new Error("Cannot resolve a Slate node from DOM node: ".concat(domEl));
	    }
	    return node;
	  },
	  toSlatePoint: function toSlatePoint(editor, domPoint, options) {
	    var exactMatch = options.exactMatch,
	      suppressThrow = options.suppressThrow,
	      _options$searchDirect = options.searchDirection,
	      searchDirection = _options$searchDirect === void 0 ? 'backward' : _options$searchDirect;
	    var _ref5 = exactMatch ? domPoint : normalizeDOMPoint(domPoint),
	      _ref6 = _slicedToArray(_ref5, 2),
	      nearestNode = _ref6[0],
	      nearestOffset = _ref6[1];
	    var parentNode = nearestNode.parentNode;
	    var textNode = null;
	    var offset = 0;
	    if (parentNode) {
	      var _domNode$textContent, _domNode$textContent2;
	      var editorEl = DOMEditor.toDOMNode(editor, editor);
	      var potentialVoidNode = parentNode.closest('[data-slate-void="true"]');
	      // Need to ensure that the closest void node is actually a void node
	      // within this editor, and not a void node within some parent editor. This can happen
	      // if this editor is within a void node of another editor ("nested editors", like in
	      // the "Editable Voids" example on the docs site).
	      var voidNode = potentialVoidNode && editorEl.contains(potentialVoidNode) ? potentialVoidNode : null;
	      var potentialNonEditableNode = parentNode.closest('[contenteditable="false"]');
	      var nonEditableNode = potentialNonEditableNode && editorEl.contains(potentialNonEditableNode) ? potentialNonEditableNode : null;
	      var leafNode = parentNode.closest('[data-slate-leaf]');
	      var domNode = null;
	      // Calculate how far into the text node the `nearestNode` is, so that we
	      // can determine what the offset relative to the text node is.
	      if (leafNode) {
	        textNode = leafNode.closest('[data-slate-node="text"]');
	        if (textNode) {
	          var window = DOMEditor.getWindow(editor);
	          var range = window.document.createRange();
	          range.setStart(textNode, 0);
	          range.setEnd(nearestNode, nearestOffset);
	          var contents = range.cloneContents();
	          var removals = [].concat(_toConsumableArray(Array.prototype.slice.call(contents.querySelectorAll('[data-slate-zero-width]'))), _toConsumableArray(Array.prototype.slice.call(contents.querySelectorAll('[contenteditable=false]'))));
	          removals.forEach(function (el) {
	            // COMPAT: While composing at the start of a text node, some keyboards put
	            // the text content inside the zero width space.
	            if (IS_ANDROID && !exactMatch && el.hasAttribute('data-slate-zero-width') && el.textContent.length > 0 && el.textContext !== "\uFEFF") {
	              if (el.textContent.startsWith("\uFEFF")) {
	                el.textContent = el.textContent.slice(1);
	              }
	              return;
	            }
	            el.parentNode.removeChild(el);
	          });
	          // COMPAT: Edge has a bug where Range.prototype.toString() will
	          // convert \n into \r\n. The bug causes a loop when slate-dom
	          // attempts to reposition its cursor to match the native position. Use
	          // textContent.length instead.
	          // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10291116/
	          offset = contents.textContent.length;
	          domNode = textNode;
	        }
	      } else if (voidNode) {
	        // For void nodes, the element with the offset key will be a cousin, not an
	        // ancestor, so find it by going down from the nearest void parent and taking the
	        // first one that isn't inside a nested editor.
	        var leafNodes = voidNode.querySelectorAll('[data-slate-leaf]');
	        for (var index = 0; index < leafNodes.length; index++) {
	          var current = leafNodes[index];
	          if (DOMEditor.hasDOMNode(editor, current)) {
	            leafNode = current;
	            break;
	          }
	        }
	        // COMPAT: In read-only editors the leaf is not rendered.
	        if (!leafNode) {
	          offset = 1;
	        } else {
	          textNode = leafNode.closest('[data-slate-node="text"]');
	          domNode = leafNode;
	          offset = domNode.textContent.length;
	          domNode.querySelectorAll('[data-slate-zero-width]').forEach(function (el) {
	            offset -= el.textContent.length;
	          });
	        }
	      } else if (nonEditableNode) {
	        // Find the edge of the nearest leaf in `searchDirection`
	        var getLeafNodes = function getLeafNodes(node) {
	          return node ? node.querySelectorAll(
	          // Exclude leaf nodes in nested editors
	          '[data-slate-leaf]:not(:scope [data-slate-editor] [data-slate-leaf])') : [];
	        };
	        var elementNode = nonEditableNode.closest('[data-slate-node="element"]');
	        if (searchDirection === 'forward') {
	          var _leafNodes$find;
	          var _leafNodes = [].concat(_toConsumableArray(getLeafNodes(elementNode)), _toConsumableArray(getLeafNodes(elementNode === null || elementNode === void 0 ? void 0 : elementNode.nextElementSibling)));
	          leafNode = (_leafNodes$find = _leafNodes.find(function (leaf) {
	            return isAfter(nonEditableNode, leaf);
	          })) !== null && _leafNodes$find !== void 0 ? _leafNodes$find : null;
	        } else {
	          var _leafNodes2$findLast;
	          var _leafNodes2 = [].concat(_toConsumableArray(getLeafNodes(elementNode === null || elementNode === void 0 ? void 0 : elementNode.previousElementSibling)), _toConsumableArray(getLeafNodes(elementNode)));
	          leafNode = (_leafNodes2$findLast = _leafNodes2.findLast(function (leaf) {
	            return isBefore(nonEditableNode, leaf);
	          })) !== null && _leafNodes2$findLast !== void 0 ? _leafNodes2$findLast : null;
	        }
	        if (leafNode) {
	          textNode = leafNode.closest('[data-slate-node="text"]');
	          domNode = leafNode;
	          if (searchDirection === 'forward') {
	            offset = 0;
	          } else {
	            offset = domNode.textContent.length;
	            domNode.querySelectorAll('[data-slate-zero-width]').forEach(function (el) {
	              offset -= el.textContent.length;
	            });
	          }
	        }
	      }
	      if (domNode && offset === domNode.textContent.length &&
	      // COMPAT: Android IMEs might remove the zero width space while composing,
	      // and we don't add it for line-breaks.
	      IS_ANDROID && domNode.getAttribute('data-slate-zero-width') === 'z' && (_domNode$textContent = domNode.textContent) !== null && _domNode$textContent !== void 0 && _domNode$textContent.startsWith("\uFEFF") && (
	      // COMPAT: If the parent node is a Slate zero-width space, editor is
	      // because the text node should have no characters. However, during IME
	      // composition the ASCII characters will be prepended to the zero-width
	      // space, so subtract 1 from the offset to account for the zero-width
	      // space character.
	      parentNode.hasAttribute('data-slate-zero-width') ||
	      // COMPAT: In Firefox, `range.cloneContents()` returns an extra trailing '\n'
	      // when the document ends with a new-line character. This results in the offset
	      // length being off by one, so we need to subtract one to account for this.
	      IS_FIREFOX && (_domNode$textContent2 = domNode.textContent) !== null && _domNode$textContent2 !== void 0 && _domNode$textContent2.endsWith('\n\n'))) {
	        offset--;
	      }
	    }
	    if (IS_ANDROID && !textNode && !exactMatch) {
	      var node = parentNode.hasAttribute('data-slate-node') ? parentNode : parentNode.closest('[data-slate-node]');
	      if (node && DOMEditor.hasDOMNode(editor, node, {
	        editable: true
	      })) {
	        var _slateNode = DOMEditor.toSlateNode(editor, node);
	        var _Editor$start = slate.Editor.start(editor, DOMEditor.findPath(editor, _slateNode)),
	          _path = _Editor$start.path,
	          _offset = _Editor$start.offset;
	        if (!node.querySelector('[data-slate-leaf]')) {
	          _offset = nearestOffset;
	        }
	        return {
	          path: _path,
	          offset: _offset
	        };
	      }
	    }
	    if (!textNode) {
	      if (suppressThrow) {
	        return null;
	      }
	      throw new Error("Cannot resolve a Slate point from DOM point: ".concat(domPoint));
	    }
	    // COMPAT: If someone is clicking from one Slate editor into another,
	    // the select event fires twice, once for the old editor's `element`
	    // first, and then afterwards for the correct `element`. (2017/03/03)
	    var slateNode = DOMEditor.toSlateNode(editor, textNode);
	    var path = DOMEditor.findPath(editor, slateNode);
	    return {
	      path: path,
	      offset: offset
	    };
	  },
	  toSlateRange: function toSlateRange(editor, domRange, options) {
	    var _focusNode$textConten;
	    var exactMatch = options.exactMatch,
	      suppressThrow = options.suppressThrow;
	    var el = isDOMSelection(domRange) ? domRange.anchorNode : domRange.startContainer;
	    var anchorNode;
	    var anchorOffset;
	    var focusNode;
	    var focusOffset;
	    var isCollapsed;
	    if (el) {
	      if (isDOMSelection(domRange)) {
	        // COMPAT: In firefox the normal seletion way does not work
	        // (https://github.com/ianstormtaylor/slate/pull/5486#issue-1820720223)
	        if (IS_FIREFOX && domRange.rangeCount > 1) {
	          focusNode = domRange.focusNode; // Focus node works fine
	          var firstRange = domRange.getRangeAt(0);
	          var lastRange = domRange.getRangeAt(domRange.rangeCount - 1);
	          // Here we are in the contenteditable mode of a table in firefox
	          if (focusNode instanceof HTMLTableRowElement && firstRange.startContainer instanceof HTMLTableRowElement && lastRange.startContainer instanceof HTMLTableRowElement) {
	            // HTMLElement, becouse Element is a slate element
	            var getLastChildren = function getLastChildren(element) {
	              if (element.childElementCount > 0) {
	                return getLastChildren(element.children[0]);
	              } else {
	                return element;
	              }
	            };
	            var firstNodeRow = firstRange.startContainer;
	            var lastNodeRow = lastRange.startContainer;
	            // This should never fail as "The HTMLElement interface represents any HTML element."
	            var firstNode = getLastChildren(firstNodeRow.children[firstRange.startOffset]);
	            var lastNode = getLastChildren(lastNodeRow.children[lastRange.startOffset]);
	            // Zero, as we allways take the right one as the anchor point
	            focusOffset = 0;
	            if (lastNode.childNodes.length > 0) {
	              anchorNode = lastNode.childNodes[0];
	            } else {
	              anchorNode = lastNode;
	            }
	            if (firstNode.childNodes.length > 0) {
	              focusNode = firstNode.childNodes[0];
	            } else {
	              focusNode = firstNode;
	            }
	            if (lastNode instanceof HTMLElement) {
	              anchorOffset = lastNode.innerHTML.length;
	            } else {
	              // Fallback option
	              anchorOffset = 0;
	            }
	          } else {
	            // This is the read only mode of a firefox table
	            // Right to left
	            if (firstRange.startContainer === focusNode) {
	              anchorNode = lastRange.endContainer;
	              anchorOffset = lastRange.endOffset;
	              focusOffset = firstRange.startOffset;
	            } else {
	              // Left to right
	              anchorNode = firstRange.startContainer;
	              anchorOffset = firstRange.endOffset;
	              focusOffset = lastRange.startOffset;
	            }
	          }
	        } else {
	          anchorNode = domRange.anchorNode;
	          anchorOffset = domRange.anchorOffset;
	          focusNode = domRange.focusNode;
	          focusOffset = domRange.focusOffset;
	        }
	        // COMPAT: There's a bug in chrome that always returns `true` for
	        // `isCollapsed` for a Selection that comes from a ShadowRoot.
	        // (2020/08/08)
	        // https://bugs.chromium.org/p/chromium/issues/detail?id=447523
	        // IsCollapsed might not work in firefox, but this will
	        if (IS_CHROME && hasShadowRoot(anchorNode) || IS_FIREFOX) {
	          isCollapsed = domRange.anchorNode === domRange.focusNode && domRange.anchorOffset === domRange.focusOffset;
	        } else {
	          isCollapsed = domRange.isCollapsed;
	        }
	      } else {
	        anchorNode = domRange.startContainer;
	        anchorOffset = domRange.startOffset;
	        focusNode = domRange.endContainer;
	        focusOffset = domRange.endOffset;
	        isCollapsed = domRange.collapsed;
	      }
	    }
	    if (anchorNode == null || focusNode == null || anchorOffset == null || focusOffset == null) {
	      throw new Error("Cannot resolve a Slate range from DOM range: ".concat(domRange));
	    }
	    // COMPAT: Firefox sometimes includes an extra \n (rendered by TextString
	    // when isTrailing is true) in the focusOffset, resulting in an invalid
	    // Slate point. (2023/11/01)
	    if (IS_FIREFOX && (_focusNode$textConten = focusNode.textContent) !== null && _focusNode$textConten !== void 0 && _focusNode$textConten.endsWith('\n\n') && focusOffset === focusNode.textContent.length) {
	      focusOffset--;
	    }
	    var anchor = DOMEditor.toSlatePoint(editor, [anchorNode, anchorOffset], {
	      exactMatch: exactMatch,
	      suppressThrow: suppressThrow
	    });
	    if (!anchor) {
	      return null;
	    }
	    var focusBeforeAnchor = isBefore(anchorNode, focusNode) || anchorNode === focusNode && focusOffset < anchorOffset;
	    var focus = isCollapsed ? anchor : DOMEditor.toSlatePoint(editor, [focusNode, focusOffset], {
	      exactMatch: exactMatch,
	      suppressThrow: suppressThrow,
	      searchDirection: focusBeforeAnchor ? 'forward' : 'backward'
	    });
	    if (!focus) {
	      return null;
	    }
	    var range = {
	      anchor: anchor,
	      focus: focus
	    };
	    // if the selection is a hanging range that ends in a void
	    // and the DOM focus is an Element
	    // (meaning that the selection ends before the element)
	    // unhang the range to avoid mistakenly including the void
	    if (slate.Range.isExpanded(range) && slate.Range.isForward(range) && isDOMElement(focusNode) && slate.Editor["void"](editor, {
	      at: range.focus,
	      mode: 'highest'
	    })) {
	      range = slate.Editor.unhangRange(editor, range, {
	        voids: true
	      });
	    }
	    return range;
	  }
	};

	/**
	 * Check whether a text diff was applied in a way we can perform the pending action on /
	 * recover the pending selection.
	 */
	function verifyDiffState(editor, textDiff) {
	  var path = textDiff.path,
	    diff = textDiff.diff;
	  if (!slate.Editor.hasPath(editor, path)) {
	    return false;
	  }
	  var node = slate.Node.get(editor, path);
	  if (!slate.Text.isText(node)) {
	    return false;
	  }
	  if (diff.start !== node.text.length || diff.text.length === 0) {
	    return node.text.slice(diff.start, diff.start + diff.text.length) === diff.text;
	  }
	  var nextPath = slate.Path.next(path);
	  if (!slate.Editor.hasPath(editor, nextPath)) {
	    return false;
	  }
	  var nextNode = slate.Node.get(editor, nextPath);
	  return slate.Text.isText(nextNode) && nextNode.text.startsWith(diff.text);
	}
	function applyStringDiff(text) {
	  for (var _len = arguments.length, diffs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	    diffs[_key - 1] = arguments[_key];
	  }
	  return diffs.reduce(function (text, diff) {
	    return text.slice(0, diff.start) + diff.text + text.slice(diff.end);
	  }, text);
	}
	function longestCommonPrefixLength(str, another) {
	  var length = Math.min(str.length, another.length);
	  for (var i = 0; i < length; i++) {
	    if (str.charAt(i) !== another.charAt(i)) {
	      return i;
	    }
	  }
	  return length;
	}
	function longestCommonSuffixLength(str, another, max) {
	  var length = Math.min(str.length, another.length, max);
	  for (var i = 0; i < length; i++) {
	    if (str.charAt(str.length - i - 1) !== another.charAt(another.length - i - 1)) {
	      return i;
	    }
	  }
	  return length;
	}
	/**
	 * Remove redundant changes from the diff so that it spans the minimal possible range
	 */
	function normalizeStringDiff(targetText, diff) {
	  var start = diff.start,
	    end = diff.end,
	    text = diff.text;
	  var removedText = targetText.slice(start, end);
	  var prefixLength = longestCommonPrefixLength(removedText, text);
	  var max = Math.min(removedText.length - prefixLength, text.length - prefixLength);
	  var suffixLength = longestCommonSuffixLength(removedText, text, max);
	  var normalized = {
	    start: start + prefixLength,
	    end: end - suffixLength,
	    text: text.slice(prefixLength, text.length - suffixLength)
	  };
	  if (normalized.start === normalized.end && normalized.text.length === 0) {
	    return null;
	  }
	  return normalized;
	}
	/**
	 * Return a string diff that is equivalent to applying b after a spanning the range of
	 * both changes
	 */
	function mergeStringDiffs(targetText, a, b) {
	  var start = Math.min(a.start, b.start);
	  var overlap = Math.max(0, Math.min(a.start + a.text.length, b.end) - b.start);
	  var applied = applyStringDiff(targetText, a, b);
	  var sliceEnd = Math.max(b.start + b.text.length, a.start + a.text.length + (a.start + a.text.length > b.start ? b.text.length : 0) - overlap);
	  var text = applied.slice(start, sliceEnd);
	  var end = Math.max(a.end, b.end - a.text.length + (a.end - a.start));
	  return normalizeStringDiff(targetText, {
	    start: start,
	    end: end,
	    text: text
	  });
	}
	/**
	 * Get the slate range the text diff spans.
	 */
	function targetRange(textDiff) {
	  var path = textDiff.path,
	    diff = textDiff.diff;
	  return {
	    anchor: {
	      path: path,
	      offset: diff.start
	    },
	    focus: {
	      path: path,
	      offset: diff.end
	    }
	  };
	}
	/**
	 * Normalize a 'pending point' a.k.a a point based on the dom state before applying
	 * the pending diffs. Since the pending diffs might have been inserted with different
	 * marks we have to 'walk' the offset from the starting position to ensure we still
	 * have a valid point inside the document
	 */
	function normalizePoint(editor, point) {
	  var path = point.path,
	    offset = point.offset;
	  if (!slate.Editor.hasPath(editor, path)) {
	    return null;
	  }
	  var leaf = slate.Node.get(editor, path);
	  if (!slate.Text.isText(leaf)) {
	    return null;
	  }
	  var parentBlock = slate.Editor.above(editor, {
	    match: function match(n) {
	      return slate.Element.isElement(n) && slate.Editor.isBlock(editor, n);
	    },
	    at: path
	  });
	  if (!parentBlock) {
	    return null;
	  }
	  while (offset > leaf.text.length) {
	    var entry = slate.Editor.next(editor, {
	      at: path,
	      match: slate.Text.isText
	    });
	    if (!entry || !slate.Path.isDescendant(entry[1], parentBlock[1])) {
	      return null;
	    }
	    offset -= leaf.text.length;
	    leaf = entry[0];
	    path = entry[1];
	  }
	  return {
	    path: path,
	    offset: offset
	  };
	}
	/**
	 * Normalize a 'pending selection' to ensure it's valid in the current document state.
	 */
	function normalizeRange(editor, range) {
	  var anchor = normalizePoint(editor, range.anchor);
	  if (!anchor) {
	    return null;
	  }
	  if (slate.Range.isCollapsed(range)) {
	    return {
	      anchor: anchor,
	      focus: anchor
	    };
	  }
	  var focus = normalizePoint(editor, range.focus);
	  if (!focus) {
	    return null;
	  }
	  return {
	    anchor: anchor,
	    focus: focus
	  };
	}
	function transformPendingPoint(editor, point, op) {
	  var pendingDiffs = EDITOR_TO_PENDING_DIFFS.get(editor);
	  var textDiff = pendingDiffs === null || pendingDiffs === void 0 ? void 0 : pendingDiffs.find(function (_ref) {
	    var path = _ref.path;
	    return slate.Path.equals(path, point.path);
	  });
	  if (!textDiff || point.offset <= textDiff.diff.start) {
	    return slate.Point.transform(point, op, {
	      affinity: 'backward'
	    });
	  }
	  var diff = textDiff.diff;
	  // Point references location inside the diff => transform the point based on the location
	  // the diff will be applied to and add the offset inside the diff.
	  if (point.offset <= diff.start + diff.text.length) {
	    var _anchor = {
	      path: point.path,
	      offset: diff.start
	    };
	    var _transformed = slate.Point.transform(_anchor, op, {
	      affinity: 'backward'
	    });
	    if (!_transformed) {
	      return null;
	    }
	    return {
	      path: _transformed.path,
	      offset: _transformed.offset + point.offset - diff.start
	    };
	  }
	  // Point references location after the diff
	  var anchor = {
	    path: point.path,
	    offset: point.offset - diff.text.length + diff.end - diff.start
	  };
	  var transformed = slate.Point.transform(anchor, op, {
	    affinity: 'backward'
	  });
	  if (!transformed) {
	    return null;
	  }
	  if (op.type === 'split_node' && slate.Path.equals(op.path, point.path) && anchor.offset < op.position && diff.start < op.position) {
	    return transformed;
	  }
	  return {
	    path: transformed.path,
	    offset: transformed.offset + diff.text.length - diff.end + diff.start
	  };
	}
	function transformPendingRange(editor, range, op) {
	  var anchor = transformPendingPoint(editor, range.anchor, op);
	  if (!anchor) {
	    return null;
	  }
	  if (slate.Range.isCollapsed(range)) {
	    return {
	      anchor: anchor,
	      focus: anchor
	    };
	  }
	  var focus = transformPendingPoint(editor, range.focus, op);
	  if (!focus) {
	    return null;
	  }
	  return {
	    anchor: anchor,
	    focus: focus
	  };
	}
	function transformTextDiff(textDiff, op) {
	  var path = textDiff.path,
	    diff = textDiff.diff,
	    id = textDiff.id;
	  switch (op.type) {
	    case 'insert_text':
	      {
	        if (!slate.Path.equals(op.path, path) || op.offset >= diff.end) {
	          return textDiff;
	        }
	        if (op.offset <= diff.start) {
	          return {
	            diff: {
	              start: op.text.length + diff.start,
	              end: op.text.length + diff.end,
	              text: diff.text
	            },
	            id: id,
	            path: path
	          };
	        }
	        return {
	          diff: {
	            start: diff.start,
	            end: diff.end + op.text.length,
	            text: diff.text
	          },
	          id: id,
	          path: path
	        };
	      }
	    case 'remove_text':
	      {
	        if (!slate.Path.equals(op.path, path) || op.offset >= diff.end) {
	          return textDiff;
	        }
	        if (op.offset + op.text.length <= diff.start) {
	          return {
	            diff: {
	              start: diff.start - op.text.length,
	              end: diff.end - op.text.length,
	              text: diff.text
	            },
	            id: id,
	            path: path
	          };
	        }
	        return {
	          diff: {
	            start: diff.start,
	            end: diff.end - op.text.length,
	            text: diff.text
	          },
	          id: id,
	          path: path
	        };
	      }
	    case 'split_node':
	      {
	        if (!slate.Path.equals(op.path, path) || op.position >= diff.end) {
	          return {
	            diff: diff,
	            id: id,
	            path: slate.Path.transform(path, op, {
	              affinity: 'backward'
	            })
	          };
	        }
	        if (op.position > diff.start) {
	          return {
	            diff: {
	              start: diff.start,
	              end: Math.min(op.position, diff.end),
	              text: diff.text
	            },
	            id: id,
	            path: path
	          };
	        }
	        return {
	          diff: {
	            start: diff.start - op.position,
	            end: diff.end - op.position,
	            text: diff.text
	          },
	          id: id,
	          path: slate.Path.transform(path, op, {
	            affinity: 'forward'
	          })
	        };
	      }
	    case 'merge_node':
	      {
	        if (!slate.Path.equals(op.path, path)) {
	          return {
	            diff: diff,
	            id: id,
	            path: slate.Path.transform(path, op)
	          };
	        }
	        return {
	          diff: {
	            start: diff.start + op.position,
	            end: diff.end + op.position,
	            text: diff.text
	          },
	          id: id,
	          path: slate.Path.transform(path, op)
	        };
	      }
	  }
	  var newPath = slate.Path.transform(path, op);
	  if (!newPath) {
	    return null;
	  }
	  return {
	    diff: diff,
	    path: newPath,
	    id: id
	  };
	}

	/**
	 * Utilities for single-line deletion
	 */
	var doRectsIntersect = function doRectsIntersect(rect, compareRect) {
	  var middle = (compareRect.top + compareRect.bottom) / 2;
	  return rect.top <= middle && rect.bottom >= middle;
	};
	var areRangesSameLine = function areRangesSameLine(editor, range1, range2) {
	  var rect1 = DOMEditor.toDOMRange(editor, range1).getBoundingClientRect();
	  var rect2 = DOMEditor.toDOMRange(editor, range2).getBoundingClientRect();
	  return doRectsIntersect(rect1, rect2) && doRectsIntersect(rect2, rect1);
	};
	/**
	 * A helper utility that returns the end portion of a `Range`
	 * which is located on a single line.
	 *
	 * @param {Editor} editor The editor object to compare against
	 * @param {Range} parentRange The parent range to compare against
	 * @returns {Range} A valid portion of the parentRange which is one a single line
	 */
	var findCurrentLineRange = function findCurrentLineRange(editor, parentRange) {
	  var parentRangeBoundary = slate.Editor.range(editor, slate.Range.end(parentRange));
	  var positions = Array.from(slate.Editor.positions(editor, {
	    at: parentRange
	  }));
	  var left = 0;
	  var right = positions.length;
	  var middle = Math.floor(right / 2);
	  if (areRangesSameLine(editor, slate.Editor.range(editor, positions[left]), parentRangeBoundary)) {
	    return slate.Editor.range(editor, positions[left], parentRangeBoundary);
	  }
	  if (positions.length < 2) {
	    return slate.Editor.range(editor, positions[positions.length - 1], parentRangeBoundary);
	  }
	  while (middle !== positions.length && middle !== left) {
	    if (areRangesSameLine(editor, slate.Editor.range(editor, positions[middle]), parentRangeBoundary)) {
	      right = middle;
	    } else {
	      left = middle;
	    }
	    middle = Math.floor((left + right) / 2);
	  }
	  return slate.Editor.range(editor, positions[left], parentRangeBoundary);
	};

	function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
	function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); }
	function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
	function ownKeys$1(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
	function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
	/**
	 * `withDOM` adds DOM specific behaviors to the editor.
	 *
	 * If you are using TypeScript, you must extend Slate's CustomTypes to use
	 * this plugin.
	 *
	 * See https://docs.slatejs.org/concepts/11-typescript to learn how.
	 */
	var withDOM = function withDOM(editor) {
	  var clipboardFormatKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'x-slate-fragment';
	  var e = editor;
	  var apply = e.apply,
	    onChange = e.onChange,
	    deleteBackward = e.deleteBackward,
	    addMark = e.addMark,
	    removeMark = e.removeMark;
	  // The WeakMap which maps a key to a specific HTMLElement must be scoped to the editor instance to
	  // avoid collisions between editors in the DOM that share the same value.
	  EDITOR_TO_KEY_TO_ELEMENT.set(e, new WeakMap());
	  e.addMark = function (key, value) {
	    var _EDITOR_TO_SCHEDULE_F, _EDITOR_TO_PENDING_DI;
	    (_EDITOR_TO_SCHEDULE_F = EDITOR_TO_SCHEDULE_FLUSH.get(e)) === null || _EDITOR_TO_SCHEDULE_F === void 0 || _EDITOR_TO_SCHEDULE_F();
	    if (!EDITOR_TO_PENDING_INSERTION_MARKS.get(e) && (_EDITOR_TO_PENDING_DI = EDITOR_TO_PENDING_DIFFS.get(e)) !== null && _EDITOR_TO_PENDING_DI !== void 0 && _EDITOR_TO_PENDING_DI.length) {
	      // Ensure the current pending diffs originating from changes before the addMark
	      // are applied with the current formatting
	      EDITOR_TO_PENDING_INSERTION_MARKS.set(e, null);
	    }
	    EDITOR_TO_USER_MARKS["delete"](e);
	    addMark(key, value);
	  };
	  e.removeMark = function (key) {
	    var _EDITOR_TO_PENDING_DI2;
	    if (!EDITOR_TO_PENDING_INSERTION_MARKS.get(e) && (_EDITOR_TO_PENDING_DI2 = EDITOR_TO_PENDING_DIFFS.get(e)) !== null && _EDITOR_TO_PENDING_DI2 !== void 0 && _EDITOR_TO_PENDING_DI2.length) {
	      // Ensure the current pending diffs originating from changes before the addMark
	      // are applied with the current formatting
	      EDITOR_TO_PENDING_INSERTION_MARKS.set(e, null);
	    }
	    EDITOR_TO_USER_MARKS["delete"](e);
	    removeMark(key);
	  };
	  e.deleteBackward = function (unit) {
	    if (unit !== 'line') {
	      return deleteBackward(unit);
	    }
	    if (e.selection && slate.Range.isCollapsed(e.selection)) {
	      var parentBlockEntry = slate.Editor.above(e, {
	        match: function match(n) {
	          return slate.Element.isElement(n) && slate.Editor.isBlock(e, n);
	        },
	        at: e.selection
	      });
	      if (parentBlockEntry) {
	        var _parentBlockEntry = _slicedToArray(parentBlockEntry, 2),
	          parentBlockPath = _parentBlockEntry[1];
	        var parentElementRange = slate.Editor.range(e, parentBlockPath, e.selection.anchor);
	        var currentLineRange = findCurrentLineRange(e, parentElementRange);
	        if (!slate.Range.isCollapsed(currentLineRange)) {
	          slate.Transforms["delete"](e, {
	            at: currentLineRange
	          });
	        }
	      }
	    }
	  };
	  // This attempts to reset the NODE_TO_KEY entry to the correct value
	  // as apply() changes the object reference and hence invalidates the NODE_TO_KEY entry
	  e.apply = function (op) {
	    var matches = [];
	    var pathRefMatches = [];
	    var pendingDiffs = EDITOR_TO_PENDING_DIFFS.get(e);
	    if (pendingDiffs !== null && pendingDiffs !== void 0 && pendingDiffs.length) {
	      var transformed = pendingDiffs.map(function (textDiff) {
	        return transformTextDiff(textDiff, op);
	      }).filter(Boolean);
	      EDITOR_TO_PENDING_DIFFS.set(e, transformed);
	    }
	    var pendingSelection = EDITOR_TO_PENDING_SELECTION.get(e);
	    if (pendingSelection) {
	      EDITOR_TO_PENDING_SELECTION.set(e, transformPendingRange(e, pendingSelection, op));
	    }
	    var pendingAction = EDITOR_TO_PENDING_ACTION.get(e);
	    if (pendingAction !== null && pendingAction !== void 0 && pendingAction.at) {
	      var at = slate.Point.isPoint(pendingAction === null || pendingAction === void 0 ? void 0 : pendingAction.at) ? transformPendingPoint(e, pendingAction.at, op) : transformPendingRange(e, pendingAction.at, op);
	      EDITOR_TO_PENDING_ACTION.set(e, at ? _objectSpread$1(_objectSpread$1({}, pendingAction), {}, {
	        at: at
	      }) : null);
	    }
	    switch (op.type) {
	      case 'insert_text':
	      case 'remove_text':
	      case 'set_node':
	      case 'split_node':
	        {
	          matches.push.apply(matches, _toConsumableArray(getMatches(e, op.path)));
	          break;
	        }
	      case 'set_selection':
	        {
	          var _EDITOR_TO_USER_SELEC;
	          // Selection was manually set, don't restore the user selection after the change.
	          (_EDITOR_TO_USER_SELEC = EDITOR_TO_USER_SELECTION.get(e)) === null || _EDITOR_TO_USER_SELEC === void 0 || _EDITOR_TO_USER_SELEC.unref();
	          EDITOR_TO_USER_SELECTION["delete"](e);
	          break;
	        }
	      case 'insert_node':
	      case 'remove_node':
	        {
	          matches.push.apply(matches, _toConsumableArray(getMatches(e, slate.Path.parent(op.path))));
	          break;
	        }
	      case 'merge_node':
	        {
	          var prevPath = slate.Path.previous(op.path);
	          matches.push.apply(matches, _toConsumableArray(getMatches(e, prevPath)));
	          break;
	        }
	      case 'move_node':
	        {
	          var commonPath = slate.Path.common(slate.Path.parent(op.path), slate.Path.parent(op.newPath));
	          matches.push.apply(matches, _toConsumableArray(getMatches(e, commonPath)));
	          var changedPath;
	          if (slate.Path.isBefore(op.path, op.newPath)) {
	            matches.push.apply(matches, _toConsumableArray(getMatches(e, slate.Path.parent(op.path))));
	            changedPath = op.newPath;
	          } else {
	            matches.push.apply(matches, _toConsumableArray(getMatches(e, slate.Path.parent(op.newPath))));
	            changedPath = op.path;
	          }
	          var changedNode = slate.Node.get(editor, slate.Path.parent(changedPath));
	          var changedNodeKey = DOMEditor.findKey(e, changedNode);
	          var changedPathRef = slate.Editor.pathRef(e, slate.Path.parent(changedPath));
	          pathRefMatches.push([changedPathRef, changedNodeKey]);
	          break;
	        }
	    }
	    apply(op);
	    switch (op.type) {
	      case 'insert_node':
	      case 'remove_node':
	      case 'merge_node':
	      case 'move_node':
	      case 'split_node':
	      case 'insert_text':
	      case 'remove_text':
	      case 'set_selection':
	        {
	          // FIXME: Rename to something like IS_DOM_EDITOR_DESYNCED
	          // to better reflect reality, see #5792
	          IS_NODE_MAP_DIRTY.set(e, true);
	        }
	    }
	    for (var _i = 0, _matches = matches; _i < _matches.length; _i++) {
	      var _matches$_i = _slicedToArray(_matches[_i], 2),
	        path = _matches$_i[0],
	        key = _matches$_i[1];
	      var _Editor$node = slate.Editor.node(e, path),
	        _Editor$node2 = _slicedToArray(_Editor$node, 1),
	        node = _Editor$node2[0];
	      NODE_TO_KEY.set(node, key);
	    }
	    for (var _i2 = 0, _pathRefMatches = pathRefMatches; _i2 < _pathRefMatches.length; _i2++) {
	      var _pathRefMatches$_i = _slicedToArray(_pathRefMatches[_i2], 2),
	        pathRef = _pathRefMatches$_i[0],
	        _key = _pathRefMatches$_i[1];
	      if (pathRef.current) {
	        var _Editor$node3 = slate.Editor.node(e, pathRef.current),
	          _Editor$node4 = _slicedToArray(_Editor$node3, 1),
	          _node = _Editor$node4[0];
	        NODE_TO_KEY.set(_node, _key);
	      }
	      pathRef.unref();
	    }
	  };
	  e.setFragmentData = function (data) {
	    var selection = e.selection;
	    if (!selection) {
	      return;
	    }
	    var _Range$edges = slate.Range.edges(selection),
	      _Range$edges2 = _slicedToArray(_Range$edges, 2),
	      start = _Range$edges2[0],
	      end = _Range$edges2[1];
	    var startVoid = slate.Editor["void"](e, {
	      at: start.path
	    });
	    var endVoid = slate.Editor["void"](e, {
	      at: end.path
	    });
	    if (slate.Range.isCollapsed(selection) && !startVoid) {
	      return;
	    }
	    // Create a fake selection so that we can add a Base64-encoded copy of the
	    // fragment to the HTML, to decode on future pastes.
	    var domRange = DOMEditor.toDOMRange(e, selection);
	    var contents = domRange.cloneContents();
	    var attach = contents.childNodes[0];
	    // Make sure attach is non-empty, since empty nodes will not get copied.
	    contents.childNodes.forEach(function (node) {
	      if (node.textContent && node.textContent.trim() !== '') {
	        attach = node;
	      }
	    });
	    // COMPAT: If the end node is a void node, we need to move the end of the
	    // range from the void node's spacer span, to the end of the void node's
	    // content, since the spacer is before void's content in the DOM.
	    if (endVoid) {
	      var _endVoid = _slicedToArray(endVoid, 1),
	        voidNode = _endVoid[0];
	      var r = domRange.cloneRange();
	      var domNode = DOMEditor.toDOMNode(e, voidNode);
	      r.setEndAfter(domNode);
	      contents = r.cloneContents();
	    }
	    // COMPAT: If the start node is a void node, we need to attach the encoded
	    // fragment to the void node's content node instead of the spacer, because
	    // attaching it to empty `<div>/<span>` nodes will end up having it erased by
	    // most browsers. (2018/04/27)
	    if (startVoid) {
	      attach = contents.querySelector('[data-slate-spacer]');
	    }
	    // Remove any zero-width space spans from the cloned DOM so that they don't
	    // show up elsewhere when pasted.
	    Array.from(contents.querySelectorAll('[data-slate-zero-width]')).forEach(function (zw) {
	      var isNewline = zw.getAttribute('data-slate-zero-width') === 'n';
	      zw.textContent = isNewline ? '\n' : '';
	    });
	    // Set a `data-slate-fragment` attribute on a non-empty node, so it shows up
	    // in the HTML, and can be used for intra-Slate pasting. If it's a text
	    // node, wrap it in a `<span>` so we have something to set an attribute on.
	    if (isDOMText(attach)) {
	      var span = attach.ownerDocument.createElement('span');
	      // COMPAT: In Chrome and Safari, if we don't add the `white-space` style
	      // then leading and trailing spaces will be ignored. (2017/09/21)
	      span.style.whiteSpace = 'pre';
	      span.appendChild(attach);
	      contents.appendChild(span);
	      attach = span;
	    }
	    var fragment = e.getFragment();
	    var string = JSON.stringify(fragment);
	    var encoded = window.btoa(encodeURIComponent(string));
	    attach.setAttribute('data-slate-fragment', encoded);
	    data.setData("application/".concat(clipboardFormatKey), encoded);
	    // Add the content to a <div> so that we can get its inner HTML.
	    var div = contents.ownerDocument.createElement('div');
	    div.appendChild(contents);
	    div.setAttribute('hidden', 'true');
	    contents.ownerDocument.body.appendChild(div);
	    data.setData('text/html', div.innerHTML);
	    data.setData('text/plain', getPlainText(div));
	    contents.ownerDocument.body.removeChild(div);
	    return data;
	  };
	  e.insertData = function (data) {
	    if (!e.insertFragmentData(data)) {
	      e.insertTextData(data);
	    }
	  };
	  e.insertFragmentData = function (data) {
	    /**
	     * Checking copied fragment from application/x-slate-fragment or data-slate-fragment
	     */
	    var fragment = data.getData("application/".concat(clipboardFormatKey)) || getSlateFragmentAttribute(data);
	    if (fragment) {
	      var decoded = decodeURIComponent(window.atob(fragment));
	      var parsed = JSON.parse(decoded);
	      e.insertFragment(parsed);
	      return true;
	    }
	    return false;
	  };
	  e.insertTextData = function (data) {
	    var text = data.getData('text/plain');
	    if (text) {
	      var lines = text.split(/\r\n|\r|\n/);
	      var split = false;
	      var _iterator = _createForOfIteratorHelper$1(lines),
	        _step;
	      try {
	        for (_iterator.s(); !(_step = _iterator.n()).done;) {
	          var line = _step.value;
	          if (split) {
	            slate.Transforms.splitNodes(e, {
	              always: true
	            });
	          }
	          e.insertText(line);
	          split = true;
	        }
	      } catch (err) {
	        _iterator.e(err);
	      } finally {
	        _iterator.f();
	      }
	      return true;
	    }
	    return false;
	  };
	  e.onChange = function (options) {
	    var onContextChange = EDITOR_TO_ON_CHANGE.get(e);
	    if (onContextChange) {
	      onContextChange(options);
	    }
	    onChange(options);
	  };
	  return e;
	};
	var getMatches = function getMatches(e, path) {
	  var matches = [];
	  var _iterator2 = _createForOfIteratorHelper$1(slate.Editor.levels(e, {
	      at: path
	    })),
	    _step2;
	  try {
	    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
	      var _step2$value = _slicedToArray(_step2.value, 2),
	        n = _step2$value[0],
	        p = _step2$value[1];
	      var key = DOMEditor.findKey(e, n);
	      matches.push([p, key]);
	    }
	  } catch (err) {
	    _iterator2.e(err);
	  } finally {
	    _iterator2.f();
	  }
	  return matches;
	};

	var TRIPLE_CLICK = 3;

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

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

	/**
	 * Constants.
	 */

	var IS_MAC = typeof window != 'undefined' && /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);

	var MODIFIERS = {
	  alt: 'altKey',
	  control: 'ctrlKey',
	  meta: 'metaKey',
	  shift: 'shiftKey'
	};

	var ALIASES = {
	  add: '+',
	  break: 'pause',
	  cmd: 'meta',
	  command: 'meta',
	  ctl: 'control',
	  ctrl: 'control',
	  del: 'delete',
	  down: 'arrowdown',
	  esc: 'escape',
	  ins: 'insert',
	  left: 'arrowleft',
	  mod: IS_MAC ? 'meta' : 'control',
	  opt: 'alt',
	  option: 'alt',
	  return: 'enter',
	  right: 'arrowright',
	  space: ' ',
	  spacebar: ' ',
	  up: 'arrowup',
	  win: 'meta',
	  windows: 'meta'
	};

	var CODES = {
	  backspace: 8,
	  tab: 9,
	  enter: 13,
	  shift: 16,
	  control: 17,
	  alt: 18,
	  pause: 19,
	  capslock: 20,
	  escape: 27,
	  ' ': 32,
	  pageup: 33,
	  pagedown: 34,
	  end: 35,
	  home: 36,
	  arrowleft: 37,
	  arrowup: 38,
	  arrowright: 39,
	  arrowdown: 40,
	  insert: 45,
	  delete: 46,
	  meta: 91,
	  numlock: 144,
	  scrolllock: 145,
	  ';': 186,
	  '=': 187,
	  ',': 188,
	  '-': 189,
	  '.': 190,
	  '/': 191,
	  '`': 192,
	  '[': 219,
	  '\\': 220,
	  ']': 221,
	  '\'': 222
	};

	for (var f = 1; f < 20; f++) {
	  CODES['f' + f] = 111 + f;
	}

	/**
	 * Is hotkey?
	 */

	function isHotkey(hotkey, options, event) {
	  if (options && !('byKey' in options)) {
	    event = options;
	    options = null;
	  }

	  if (!Array.isArray(hotkey)) {
	    hotkey = [hotkey];
	  }

	  var array = hotkey.map(function (string) {
	    return parseHotkey(string, options);
	  });
	  var check = function check(e) {
	    return array.some(function (object) {
	      return compareHotkey(object, e);
	    });
	  };
	  var ret = event == null ? check : check(event);
	  return ret;
	}

	function isCodeHotkey(hotkey, event) {
	  return isHotkey(hotkey, event);
	}

	function isKeyHotkey(hotkey, event) {
	  return isHotkey(hotkey, { byKey: true }, event);
	}

	/**
	 * Parse.
	 */

	function parseHotkey(hotkey, options) {
	  var byKey = options && options.byKey;
	  var ret = {};

	  // Special case to handle the `+` key since we use it as a separator.
	  hotkey = hotkey.replace('++', '+add');
	  var values = hotkey.split('+');
	  var length = values.length;

	  // Ensure that all the modifiers are set to false unless the hotkey has them.

	  for (var k in MODIFIERS) {
	    ret[MODIFIERS[k]] = false;
	  }

	  var _iteratorNormalCompletion = true;
	  var _didIteratorError = false;
	  var _iteratorError = undefined;

	  try {
	    for (var _iterator = values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
	      var value = _step.value;

	      var optional = value.endsWith('?') && value.length > 1;

	      if (optional) {
	        value = value.slice(0, -1);
	      }

	      var name = toKeyName(value);
	      var modifier = MODIFIERS[name];

	      if (value.length > 1 && !modifier && !ALIASES[value] && !CODES[name]) {
	        throw new TypeError('Unknown modifier: "' + value + '"');
	      }

	      if (length === 1 || !modifier) {
	        if (byKey) {
	          ret.key = name;
	        } else {
	          ret.which = toKeyCode(value);
	        }
	      }

	      if (modifier) {
	        ret[modifier] = optional ? null : true;
	      }
	    }
	  } catch (err) {
	    _didIteratorError = true;
	    _iteratorError = err;
	  } finally {
	    try {
	      if (!_iteratorNormalCompletion && _iterator.return) {
	        _iterator.return();
	      }
	    } finally {
	      if (_didIteratorError) {
	        throw _iteratorError;
	      }
	    }
	  }

	  return ret;
	}

	/**
	 * Compare.
	 */

	function compareHotkey(object, event) {
	  for (var key in object) {
	    var expected = object[key];
	    var actual = void 0;

	    if (expected == null) {
	      continue;
	    }

	    if (key === 'key' && event.key != null) {
	      actual = event.key.toLowerCase();
	    } else if (key === 'which') {
	      actual = expected === 91 && event.which === 93 ? 91 : event.which;
	    } else {
	      actual = event[key];
	    }

	    if (actual == null && expected === false) {
	      continue;
	    }

	    if (actual !== expected) {
	      return false;
	    }
	  }

	  return true;
	}

	/**
	 * Utils.
	 */

	function toKeyCode(name) {
	  name = toKeyName(name);
	  var code = CODES[name] || name.toUpperCase().charCodeAt(0);
	  return code;
	}

	function toKeyName(name) {
	  name = name.toLowerCase();
	  name = ALIASES[name] || name;
	  return name;
	}

	/**
	 * Export.
	 */

	exports.default = isHotkey;
	exports.isHotkey = isHotkey;
	exports.isCodeHotkey = isCodeHotkey;
	exports.isKeyHotkey = isKeyHotkey;
	exports.parseHotkey = parseHotkey;
	exports.compareHotkey = compareHotkey;
	exports.toKeyCode = toKeyCode;
	exports.toKeyName = toKeyName;
	});

	unwrapExports(lib);
	var lib_1 = lib.isHotkey;
	lib.isCodeHotkey;
	lib.isKeyHotkey;
	lib.parseHotkey;
	lib.compareHotkey;
	lib.toKeyCode;
	lib.toKeyName;

	/**
	 * Hotkey mappings for each platform.
	 */
	var HOTKEYS = {
	  bold: 'mod+b',
	  compose: ['down', 'left', 'right', 'up', 'backspace', 'enter'],
	  moveBackward: 'left',
	  moveForward: 'right',
	  moveWordBackward: 'ctrl+left',
	  moveWordForward: 'ctrl+right',
	  deleteBackward: 'shift?+backspace',
	  deleteForward: 'shift?+delete',
	  extendBackward: 'shift+left',
	  extendForward: 'shift+right',
	  italic: 'mod+i',
	  insertSoftBreak: 'shift+enter',
	  splitBlock: 'enter',
	  undo: 'mod+z'
	};
	var APPLE_HOTKEYS = {
	  moveLineBackward: 'opt+up',
	  moveLineForward: 'opt+down',
	  moveWordBackward: 'opt+left',
	  moveWordForward: 'opt+right',
	  deleteBackward: ['ctrl+backspace', 'ctrl+h'],
	  deleteForward: ['ctrl+delete', 'ctrl+d'],
	  deleteLineBackward: 'cmd+shift?+backspace',
	  deleteLineForward: ['cmd+shift?+delete', 'ctrl+k'],
	  deleteWordBackward: 'opt+shift?+backspace',
	  deleteWordForward: 'opt+shift?+delete',
	  extendLineBackward: 'opt+shift+up',
	  extendLineForward: 'opt+shift+down',
	  redo: 'cmd+shift+z',
	  transposeCharacter: 'ctrl+t'
	};
	var WINDOWS_HOTKEYS = {
	  deleteWordBackward: 'ctrl+shift?+backspace',
	  deleteWordForward: 'ctrl+shift?+delete',
	  redo: ['ctrl+y', 'ctrl+shift+z']
	};
	/**
	 * Create a platform-aware hotkey checker.
	 */
	var create = function create(key) {
	  var generic = HOTKEYS[key];
	  var apple = APPLE_HOTKEYS[key];
	  var windows = WINDOWS_HOTKEYS[key];
	  var isGeneric = generic && lib_1(generic);
	  var isApple = apple && lib_1(apple);
	  var isWindows = windows && lib_1(windows);
	  return function (event) {
	    if (isGeneric && isGeneric(event)) return true;
	    if (IS_APPLE && isApple && isApple(event)) return true;
	    if (!IS_APPLE && isWindows && isWindows(event)) return true;
	    return false;
	  };
	};
	/**
	 * Hotkeys.
	 */
	var hotkeys = {
	  isBold: create('bold'),
	  isCompose: create('compose'),
	  isMoveBackward: create('moveBackward'),
	  isMoveForward: create('moveForward'),
	  isDeleteBackward: create('deleteBackward'),
	  isDeleteForward: create('deleteForward'),
	  isDeleteLineBackward: create('deleteLineBackward'),
	  isDeleteLineForward: create('deleteLineForward'),
	  isDeleteWordBackward: create('deleteWordBackward'),
	  isDeleteWordForward: create('deleteWordForward'),
	  isExtendBackward: create('extendBackward'),
	  isExtendForward: create('extendForward'),
	  isExtendLineBackward: create('extendLineBackward'),
	  isExtendLineForward: create('extendLineForward'),
	  isItalic: create('italic'),
	  isMoveLineBackward: create('moveLineBackward'),
	  isMoveLineForward: create('moveLineForward'),
	  isMoveWordBackward: create('moveWordBackward'),
	  isMoveWordForward: create('moveWordForward'),
	  isRedo: create('redo'),
	  isSoftBreak: create('insertSoftBreak'),
	  isSplitBlock: create('splitBlock'),
	  isTransposeCharacter: create('transposeCharacter'),
	  isUndo: create('undo')
	};

	var objectWithoutPropertiesLoose = createCommonjsModule(function (module) {
	function _objectWithoutPropertiesLoose(source, excluded) {
	  if (source == null) return {};
	  var target = {};
	  var sourceKeys = Object.keys(source);
	  var key, i;
	  for (i = 0; i < sourceKeys.length; i++) {
	    key = sourceKeys[i];
	    if (excluded.indexOf(key) >= 0) continue;
	    target[key] = source[key];
	  }
	  return target;
	}
	module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	unwrapExports(objectWithoutPropertiesLoose);

	var objectWithoutProperties = createCommonjsModule(function (module) {
	function _objectWithoutProperties(source, excluded) {
	  if (source == null) return {};
	  var target = objectWithoutPropertiesLoose(source, excluded);
	  var key, i;
	  if (Object.getOwnPropertySymbols) {
	    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
	    for (i = 0; i < sourceSymbolKeys.length; i++) {
	      key = sourceSymbolKeys[i];
	      if (excluded.indexOf(key) >= 0) continue;
	      if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
	      target[key] = source[key];
	    }
	  }
	  return target;
	}
	module.exports = _objectWithoutProperties, module.exports.__esModule = true, module.exports["default"] = module.exports;
	});

	var _objectWithoutProperties = unwrapExports(objectWithoutProperties);

	var _excluded = ["anchor", "focus"],
	  _excluded2 = ["anchor", "focus"];
	function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
	function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
	function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
	function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
	function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
	var shallowCompare = function shallowCompare(obj1, obj2) {
	  return Object.keys(obj1).length === Object.keys(obj2).length && Object.keys(obj1).every(function (key) {
	    return obj2.hasOwnProperty(key) && obj1[key] === obj2[key];
	  });
	};
	var isDecorationFlagsEqual = function isDecorationFlagsEqual(range, other) {
	  range.anchor;
	    range.focus;
	    var rangeOwnProps = _objectWithoutProperties(range, _excluded);
	  other.anchor;
	    other.focus;
	    var otherOwnProps = _objectWithoutProperties(other, _excluded2);
	  return range[PLACEHOLDER_SYMBOL] === other[PLACEHOLDER_SYMBOL] && shallowCompare(rangeOwnProps, otherOwnProps);
	};
	/**
	 * Check if a list of decorator ranges are equal to another.
	 *
	 * PERF: this requires the two lists to also have the ranges inside them in the
	 * same order, but this is an okay constraint for us since decorations are
	 * kept in order, and the odd case where they aren't is okay to re-render for.
	 */
	var isElementDecorationsEqual = function isElementDecorationsEqual(list, another) {
	  if (list === another) {
	    return true;
	  }
	  if (!list || !another) {
	    return false;
	  }
	  if (list.length !== another.length) {
	    return false;
	  }
	  for (var i = 0; i < list.length; i++) {
	    var range = list[i];
	    var other = another[i];
	    if (!slate.Range.equals(range, other) || !isDecorationFlagsEqual(range, other)) {
	      return false;
	    }
	  }
	  return true;
	};
	/**
	 * Check if a list of decorator ranges are equal to another.
	 *
	 * PERF: this requires the two lists to also have the ranges inside them in the
	 * same order, but this is an okay constraint for us since decorations are
	 * kept in order, and the odd case where they aren't is okay to re-render for.
	 */
	var isTextDecorationsEqual = function isTextDecorationsEqual(list, another) {
	  if (list === another) {
	    return true;
	  }
	  if (!list || !another) {
	    return false;
	  }
	  if (list.length !== another.length) {
	    return false;
	  }
	  for (var i = 0; i < list.length; i++) {
	    var range = list[i];
	    var other = another[i];
	    // compare only offsets because paths doesn't matter for text
	    if (range.anchor.offset !== other.anchor.offset || range.focus.offset !== other.focus.offset || !isDecorationFlagsEqual(range, other)) {
	      return false;
	    }
	  }
	  return true;
	};
	/**
	 * Split and group decorations by each child of a node.
	 *
	 * @returns An array with length equal to that of `node.children`. Each index
	 * corresponds to a child of `node`, and the value is an array of decorations
	 * for that child.
	 */
	var splitDecorationsByChild = function splitDecorationsByChild(editor, node, decorations) {
	  var decorationsByChild = Array.from(node.children, function () {
	    return [];
	  });
	  if (decorations.length === 0) {
	    return decorationsByChild;
	  }
	  var path = DOMEditor.findPath(editor, node);
	  var level = path.length;
	  var ancestorRange = slate.Editor.range(editor, path);
	  var cachedChildRanges = new Array(node.children.length);
	  var getChildRange = function getChildRange(index) {
	    var cachedRange = cachedChildRanges[index];
	    if (cachedRange) return cachedRange;
	    var childRange = slate.Editor.range(editor, [].concat(_toConsumableArray(path), [index]));
	    cachedChildRanges[index] = childRange;
	    return childRange;
	  };
	  var _iterator = _createForOfIteratorHelper(decorations),
	    _step;
	  try {
	    for (_iterator.s(); !(_step = _iterator.n()).done;) {
	      var decoration = _step.value;
	      var decorationRange = slate.Range.intersection(ancestorRange, decoration);
	      if (!decorationRange) continue;
	      var _Range$edges = slate.Range.edges(decorationRange),
	        _Range$edges2 = _slicedToArray(_Range$edges, 2),
	        startPoint = _Range$edges2[0],
	        endPoint = _Range$edges2[1];
	      var startIndex = startPoint.path[level];
	      var endIndex = endPoint.path[level];
	      for (var i = startIndex; i <= endIndex; i++) {
	        var ds = decorationsByChild[i];
	        if (!ds) continue;
	        var childRange = getChildRange(i);
	        var childDecorationRange = slate.Range.intersection(childRange, decoration);
	        if (!childDecorationRange) continue;
	        ds.push(_objectSpread(_objectSpread({}, decoration), childDecorationRange));
	      }
	    }
	  } catch (err) {
	    _iterator.e(err);
	  } finally {
	    _iterator.f();
	  }
	  return decorationsByChild;
	};

	exports.CAN_USE_DOM = CAN_USE_DOM;
	exports.DOMEditor = DOMEditor;
	exports.DOMElement = DOMElement;
	exports.DOMNode = DOMNode;
	exports.DOMRange = DOMRange;
	exports.DOMSelection = DOMSelection;
	exports.DOMStaticRange = DOMStaticRange;
	exports.DOMText = DOMText;
	exports.EDITOR_TO_ELEMENT = EDITOR_TO_ELEMENT;
	exports.EDITOR_TO_FORCE_RENDER = EDITOR_TO_FORCE_RENDER;
	exports.EDITOR_TO_KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT;
	exports.EDITOR_TO_ON_CHANGE = EDITOR_TO_ON_CHANGE;
	exports.EDITOR_TO_PENDING_ACTION = EDITOR_TO_PENDING_ACTION;
	exports.EDITOR_TO_PENDING_DIFFS = EDITOR_TO_PENDING_DIFFS;
	exports.EDITOR_TO_PENDING_INSERTION_MARKS = EDITOR_TO_PENDING_INSERTION_MARKS;
	exports.EDITOR_TO_PENDING_SELECTION = EDITOR_TO_PENDING_SELECTION;
	exports.EDITOR_TO_PLACEHOLDER_ELEMENT = EDITOR_TO_PLACEHOLDER_ELEMENT;
	exports.EDITOR_TO_SCHEDULE_FLUSH = EDITOR_TO_SCHEDULE_FLUSH;
	exports.EDITOR_TO_USER_MARKS = EDITOR_TO_USER_MARKS;
	exports.EDITOR_TO_USER_SELECTION = EDITOR_TO_USER_SELECTION;
	exports.EDITOR_TO_WINDOW = EDITOR_TO_WINDOW;
	exports.ELEMENT_TO_NODE = ELEMENT_TO_NODE;
	exports.HAS_BEFORE_INPUT_SUPPORT = HAS_BEFORE_INPUT_SUPPORT;
	exports.Hotkeys = hotkeys;
	exports.IS_ANDROID = IS_ANDROID;
	exports.IS_CHROME = IS_CHROME;
	exports.IS_COMPOSING = IS_COMPOSING;
	exports.IS_FIREFOX = IS_FIREFOX;
	exports.IS_FIREFOX_LEGACY = IS_FIREFOX_LEGACY;
	exports.IS_FOCUSED = IS_FOCUSED;
	exports.IS_IOS = IS_IOS;
	exports.IS_NODE_MAP_DIRTY = IS_NODE_MAP_DIRTY;
	exports.IS_READ_ONLY = IS_READ_ONLY;
	exports.IS_UC_MOBILE = IS_UC_MOBILE;
	exports.IS_WEBKIT = IS_WEBKIT;
	exports.IS_WECHATBROWSER = IS_WECHATBROWSER;
	exports.Key = Key;
	exports.MARK_PLACEHOLDER_SYMBOL = MARK_PLACEHOLDER_SYMBOL;
	exports.NODE_TO_ELEMENT = NODE_TO_ELEMENT;
	exports.NODE_TO_INDEX = NODE_TO_INDEX;
	exports.NODE_TO_KEY = NODE_TO_KEY;
	exports.NODE_TO_PARENT = NODE_TO_PARENT;
	exports.PLACEHOLDER_SYMBOL = PLACEHOLDER_SYMBOL;
	exports.TRIPLE_CLICK = TRIPLE_CLICK;
	exports.applyStringDiff = applyStringDiff;
	exports.getActiveElement = getActiveElement;
	exports.getDefaultView = getDefaultView;
	exports.getSelection = getSelection;
	exports.hasShadowRoot = hasShadowRoot;
	exports.isAfter = isAfter;
	exports.isBefore = isBefore;
	exports.isDOMElement = isDOMElement;
	exports.isDOMNode = isDOMNode;
	exports.isDOMSelection = isDOMSelection;
	exports.isElementDecorationsEqual = isElementDecorationsEqual;
	exports.isPlainTextOnlyPaste = isPlainTextOnlyPaste;
	exports.isTextDecorationsEqual = isTextDecorationsEqual;
	exports.isTrackedMutation = isTrackedMutation;
	exports.mergeStringDiffs = mergeStringDiffs;
	exports.normalizeDOMPoint = normalizeDOMPoint;
	exports.normalizePoint = normalizePoint;
	exports.normalizeRange = normalizeRange;
	exports.normalizeStringDiff = normalizeStringDiff;
	exports.splitDecorationsByChild = splitDecorationsByChild;
	exports.targetRange = targetRange;
	exports.verifyDiffState = verifyDiffState;
	exports.withDOM = withDOM;

}));