}\n */\n\n\n _createClass(Range, [{\n key: _Symbol$iterator,\n value:\n /*#__PURE__*/\n regeneratorRuntime.mark(function value() {\n return regeneratorRuntime.wrap(function value$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n return _context.delegateYield(new TreeWalker({\n boundaries: this,\n ignoreElementEnd: true\n }), \"t0\", 1);\n\n case 1:\n case \"end\":\n return _context.stop();\n }\n }\n }, value, this);\n })\n /**\n * Returns whether the range is collapsed, that is it start and end positions are equal.\n *\n * @type {Boolean}\n */\n\n }, {\n key: \"isCollapsed\",\n get: function get() {\n return this.start.isEqual(this.end);\n }\n /**\n * Returns whether this range is flat, that is if {@link module:engine/view/range~Range#start start} position and\n * {@link module:engine/view/range~Range#end end} position are in the same {@link module:engine/view/position~Position#parent parent}.\n *\n * @type {Boolean}\n */\n\n }, {\n key: \"isFlat\",\n get: function get() {\n return this.start.parent === this.end.parent;\n }\n /**\n * Range root element.\n *\n * @type {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment}\n */\n\n }, {\n key: \"root\",\n get: function get() {\n return this.start.root;\n }\n /**\n * Creates a maximal range that has the same content as this range but is expanded in both ways (at the beginning\n * and at the end).\n *\n * For example:\n *\n *\t\tFoo
{Bar}
-> Foo
[Bar]
\n *\t\tfoo{bar}
-> foo[bar]
\n *\n * Note that in the sample above:\n *\n * - `` have type of {@link module:engine/view/containerelement~ContainerElement},\n * - `` have type of {@link module:engine/view/attributeelement~AttributeElement},\n * - `` have type of {@link module:engine/view/uielement~UIElement}.\n *\n * @returns {module:engine/view/range~Range} Enlarged range.\n */\n\n }, {\n key: \"getEnlarged\",\n value: function getEnlarged() {\n var start = this.start.getLastMatchingPosition(enlargeTrimSkip, {\n direction: 'backward'\n });\n var end = this.end.getLastMatchingPosition(enlargeTrimSkip); // Fix positions, in case if they are in Text node.\n\n if (start.parent.is('$text') && start.isAtStart) {\n start = Position._createBefore(start.parent);\n }\n\n if (end.parent.is('$text') && end.isAtEnd) {\n end = Position._createAfter(end.parent);\n }\n\n return new Range(start, end);\n }\n /**\n * Creates a minimum range that has the same content as this range but is trimmed in both ways (at the beginning\n * and at the end).\n *\n * For example:\n *\n *\t\tFoo
[Bar]
-> Foo
{Bar}
\n *\t\tfoo[bar]
-> foo{bar}
\n *\n * Note that in the sample above:\n *\n * - `` have type of {@link module:engine/view/containerelement~ContainerElement},\n * - `` have type of {@link module:engine/view/attributeelement~AttributeElement},\n * - `` have type of {@link module:engine/view/uielement~UIElement}.\n *\n * @returns {module:engine/view/range~Range} Shrink range.\n */\n\n }, {\n key: \"getTrimmed\",\n value: function getTrimmed() {\n var start = this.start.getLastMatchingPosition(enlargeTrimSkip);\n\n if (start.isAfter(this.end) || start.isEqual(this.end)) {\n return new Range(start, start);\n }\n\n var end = this.end.getLastMatchingPosition(enlargeTrimSkip, {\n direction: 'backward'\n });\n var nodeAfterStart = start.nodeAfter;\n var nodeBeforeEnd = end.nodeBefore; // Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes.\n\n if (nodeAfterStart && nodeAfterStart.is('$text')) {\n start = new Position(nodeAfterStart, 0);\n }\n\n if (nodeBeforeEnd && nodeBeforeEnd.is('$text')) {\n end = new Position(nodeBeforeEnd, nodeBeforeEnd.data.length);\n }\n\n return new Range(start, end);\n }\n /**\n * Two ranges are equal if their start and end positions are equal.\n *\n * @param {module:engine/view/range~Range} otherRange Range to compare with.\n * @returns {Boolean} `true` if ranges are equal, `false` otherwise\n */\n\n }, {\n key: \"isEqual\",\n value: function isEqual(otherRange) {\n return this == otherRange || this.start.isEqual(otherRange.start) && this.end.isEqual(otherRange.end);\n }\n /**\n * Checks whether this range contains given {@link module:engine/view/position~Position position}.\n *\n * @param {module:engine/view/position~Position} position Position to check.\n * @returns {Boolean} `true` if given {@link module:engine/view/position~Position position} is contained in this range,\n * `false` otherwise.\n */\n\n }, {\n key: \"containsPosition\",\n value: function containsPosition(position) {\n return position.isAfter(this.start) && position.isBefore(this.end);\n }\n /**\n * Checks whether this range contains given {@link module:engine/view/range~Range range}.\n *\n * @param {module:engine/view/range~Range} otherRange Range to check.\n * @param {Boolean} [loose=false] Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n * @returns {Boolean} `true` if given {@link module:engine/view/range~Range range} boundaries are contained by this range, `false`\n * otherwise.\n */\n\n }, {\n key: \"containsRange\",\n value: function containsRange(otherRange) {\n var loose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (otherRange.isCollapsed) {\n loose = false;\n }\n\n var containsStart = this.containsPosition(otherRange.start) || loose && this.start.isEqual(otherRange.start);\n var containsEnd = this.containsPosition(otherRange.end) || loose && this.end.isEqual(otherRange.end);\n return containsStart && containsEnd;\n }\n /**\n * Computes which part(s) of this {@link module:engine/view/range~Range range} is not a part of given\n * {@link module:engine/view/range~Range range}.\n * Returned array contains zero, one or two {@link module:engine/view/range~Range ranges}.\n *\n * Examples:\n *\n *\t\tlet foo = downcastWriter.createText( 'foo' );\n *\t\tlet img = downcastWriter.createContainerElement( 'img' );\n *\t\tlet bar = downcastWriter.createText( 'bar' );\n *\t\tlet p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n *\n *\t\tlet range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n *\t\tlet otherRange = view.createRange( // \"oo\", img, \"ba\" are in range.\n *\t\t\tview.createPositionAt( foo, 1 ),\n *\t\t\tview.createPositionAt( bar, 2 )\n *\t\t);\n *\t\tlet transformed = range.getDifference( otherRange );\n *\t\t// transformed array has no ranges because `otherRange` contains `range`\n *\n *\t\totherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n *\t\ttransformed = range.getDifference( otherRange );\n *\t\t// transformed array has one range: from ( p, 2 ) to ( bar, 1 )\n *\n *\t\totherRange = view.createRange( view.createPositionAt( p, 1 ), view.createPositionAt( p, 2 ) ); // img is in range.\n *\t\ttransformed = range.getDifference( otherRange );\n *\t\t// transformed array has two ranges: from ( foo, 1 ) to ( p, 1 ) and from ( p, 2 ) to ( bar, 1 )\n *\n * @param {module:engine/view/range~Range} otherRange Range to differentiate against.\n * @returns {Array.} The difference between ranges.\n */\n\n }, {\n key: \"getDifference\",\n value: function getDifference(otherRange) {\n var ranges = [];\n\n if (this.isIntersecting(otherRange)) {\n // Ranges intersect.\n if (this.containsPosition(otherRange.start)) {\n // Given range start is inside this range. This means that we have to\n // add shrunken range - from the start to the middle of this range.\n ranges.push(new Range(this.start, otherRange.start));\n }\n\n if (this.containsPosition(otherRange.end)) {\n // Given range end is inside this range. This means that we have to\n // add shrunken range - from the middle of this range to the end.\n ranges.push(new Range(otherRange.end, this.end));\n }\n } else {\n // Ranges do not intersect, return the original range.\n ranges.push(this.clone());\n }\n\n return ranges;\n }\n /**\n * Returns an intersection of this {@link module:engine/view/range~Range range} and given {@link module:engine/view/range~Range range}.\n * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n *\n * Examples:\n *\n *\t\tlet foo = downcastWriter.createText( 'foo' );\n *\t\tlet img = downcastWriter.createContainerElement( 'img' );\n *\t\tlet bar = downcastWriter.createText( 'bar' );\n *\t\tlet p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n *\n *\t\tlet range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n *\t\tlet otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n *\t\tlet transformed = range.getIntersection( otherRange ); // range from ( foo, 1 ) to ( p, 2 ).\n *\n *\t\totherRange = view.createRange( view.createPositionAt( bar, 1 ), view.createPositionAt( bar, 3 ); \"ar\" is in range.\n *\t\ttransformed = range.getIntersection( otherRange ); // null - no common part.\n *\n * @param {module:engine/view/range~Range} otherRange Range to check for intersection.\n * @returns {module:engine/view/range~Range|null} A common part of given ranges or `null` if ranges have no common part.\n */\n\n }, {\n key: \"getIntersection\",\n value: function getIntersection(otherRange) {\n if (this.isIntersecting(otherRange)) {\n // Ranges intersect, so a common range will be returned.\n // At most, it will be same as this range.\n var commonRangeStart = this.start;\n var commonRangeEnd = this.end;\n\n if (this.containsPosition(otherRange.start)) {\n // Given range start is inside this range. This means thaNt we have to\n // shrink common range to the given range start.\n commonRangeStart = otherRange.start;\n }\n\n if (this.containsPosition(otherRange.end)) {\n // Given range end is inside this range. This means that we have to\n // shrink common range to the given range end.\n commonRangeEnd = otherRange.end;\n }\n\n return new Range(commonRangeStart, commonRangeEnd);\n } // Ranges do not intersect, so they do not have common part.\n\n\n return null;\n }\n /**\n * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n *\n * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n * @param {module:engine/view/position~Position} [options.startPosition]\n * @param {Boolean} [options.singleCharacters=false]\n * @param {Boolean} [options.shallow=false]\n * @param {Boolean} [options.ignoreElementEnd=false]\n * @returns {module:engine/view/treewalker~TreeWalker}\n */\n\n }, {\n key: \"getWalker\",\n value: function getWalker() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n options.boundaries = this;\n return new TreeWalker(options);\n }\n /**\n * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n * which is a common ancestor of range's both ends (in which the entire range is contained).\n *\n * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null}\n */\n\n }, {\n key: \"getCommonAncestor\",\n value: function getCommonAncestor() {\n return this.start.getCommonAncestor(this.end);\n }\n /**\n * Returns an {@link module:engine/view/element~Element Element} contained by the range.\n * The element will be returned when it is the **only** node within the range and **fully–contained**\n * at the same time.\n *\n * @returns {module:engine/view/element~Element|null}\n */\n\n }, {\n key: \"getContainedElement\",\n value: function getContainedElement() {\n if (this.isCollapsed) {\n return null;\n }\n\n var nodeAfterStart = this.start.nodeAfter;\n var nodeBeforeEnd = this.end.nodeBefore; // Handle the situation when the range position is at the beginning / at the end of a text node.\n // In such situation `.nodeAfter` and `.nodeBefore` are `null` but the range still might be spanning\n // over one element.\n //\n // Foo{}bar
vs Foo[]bar
\n //\n // These are basically the same range, only the difference is if the range position is at\n // at the end/at the beginning of a text node or just before/just after the text node.\n //\n\n if (this.start.parent.is('$text') && this.start.isAtEnd && this.start.parent.nextSibling) {\n nodeAfterStart = this.start.parent.nextSibling;\n }\n\n if (this.end.parent.is('$text') && this.end.isAtStart && this.end.parent.previousSibling) {\n nodeBeforeEnd = this.end.parent.previousSibling;\n }\n\n if (nodeAfterStart && nodeAfterStart.is('element') && nodeAfterStart === nodeBeforeEnd) {\n return nodeAfterStart;\n }\n\n return null;\n }\n /**\n * Clones this range.\n *\n * @returns {module:engine/view/range~Range}\n */\n\n }, {\n key: \"clone\",\n value: function clone() {\n return new Range(this.start, this.end);\n }\n /**\n * Returns an iterator that iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n * them.\n *\n * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n * set to `true`. However it returns only {@link module:engine/view/item~Item items},\n * not {@link module:engine/view/treewalker~TreeWalkerValue}.\n *\n * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n * a full list of available options.\n *\n * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n * @returns {Iterable.}\n */\n\n }, {\n key: \"getItems\",\n value:\n /*#__PURE__*/\n regeneratorRuntime.mark(function getItems() {\n var options,\n treeWalker,\n _iterator,\n _step,\n _value,\n _args2 = arguments;\n\n return regeneratorRuntime.wrap(function getItems$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n options = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};\n options.boundaries = this;\n options.ignoreElementEnd = true;\n treeWalker = new TreeWalker(options);\n _iterator = _createForOfIteratorHelper(treeWalker);\n _context2.prev = 5;\n\n _iterator.s();\n\n case 7:\n if ((_step = _iterator.n()).done) {\n _context2.next = 13;\n break;\n }\n\n _value = _step.value;\n _context2.next = 11;\n return _value.item;\n\n case 11:\n _context2.next = 7;\n break;\n\n case 13:\n _context2.next = 18;\n break;\n\n case 15:\n _context2.prev = 15;\n _context2.t0 = _context2[\"catch\"](5);\n\n _iterator.e(_context2.t0);\n\n case 18:\n _context2.prev = 18;\n\n _iterator.f();\n\n return _context2.finish(18);\n\n case 21:\n case \"end\":\n return _context2.stop();\n }\n }\n }, getItems, this, [[5, 15, 18, 21]]);\n })\n /**\n * Returns an iterator that iterates over all {@link module:engine/view/position~Position positions} that are boundaries or\n * contained in this range.\n *\n * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n * {@link module:engine/view/position~Position positions}, not {@link module:engine/view/treewalker~TreeWalkerValue}.\n *\n * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n * a full list of available options.\n *\n * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n * @returns {Iterable.}\n */\n\n }, {\n key: \"getPositions\",\n value:\n /*#__PURE__*/\n regeneratorRuntime.mark(function getPositions() {\n var options,\n treeWalker,\n _iterator2,\n _step2,\n _value2,\n _args3 = arguments;\n\n return regeneratorRuntime.wrap(function getPositions$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n options = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {};\n options.boundaries = this;\n treeWalker = new TreeWalker(options);\n _context3.next = 5;\n return treeWalker.position;\n\n case 5:\n _iterator2 = _createForOfIteratorHelper(treeWalker);\n _context3.prev = 6;\n\n _iterator2.s();\n\n case 8:\n if ((_step2 = _iterator2.n()).done) {\n _context3.next = 14;\n break;\n }\n\n _value2 = _step2.value;\n _context3.next = 12;\n return _value2.nextPosition;\n\n case 12:\n _context3.next = 8;\n break;\n\n case 14:\n _context3.next = 19;\n break;\n\n case 16:\n _context3.prev = 16;\n _context3.t0 = _context3[\"catch\"](6);\n\n _iterator2.e(_context3.t0);\n\n case 19:\n _context3.prev = 19;\n\n _iterator2.f();\n\n return _context3.finish(19);\n\n case 22:\n case \"end\":\n return _context3.stop();\n }\n }\n }, getPositions, this, [[6, 16, 19, 22]]);\n })\n /**\n * Checks whether this object is of the given type.\n *\n *\t\trange.is( 'range' ); // -> true\n *\t\trange.is( 'view:range' ); // -> true\n *\n *\t\trange.is( 'model:range' ); // -> false\n *\t\trange.is( 'element' ); // -> false\n *\t\trange.is( 'selection' ); // -> false\n *\n * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.\n *\n * @param {String} type\n * @returns {Boolean}\n */\n\n }, {\n key: \"is\",\n value: function is(type) {\n return type === 'range' || type === 'view:range';\n }\n /**\n * Checks and returns whether this range intersects with the given range.\n *\n * @param {module:engine/view/range~Range} otherRange Range to compare with.\n * @returns {Boolean} True if ranges intersect.\n */\n\n }, {\n key: \"isIntersecting\",\n value: function isIntersecting(otherRange) {\n return this.start.isBefore(otherRange.end) && this.end.isAfter(otherRange.start);\n }\n /**\n * Creates a range from the given parents and offsets.\n *\n * @protected\n * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} startElement Start position\n * parent element.\n * @param {Number} startOffset Start position offset.\n * @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} endElement End position\n * parent element.\n * @param {Number} endOffset End position offset.\n * @returns {module:engine/view/range~Range} Created range.\n */\n\n }], [{\n key: \"_createFromParentsAndOffsets\",\n value: function _createFromParentsAndOffsets(startElement, startOffset, endElement, endOffset) {\n return new this(new Position(startElement, startOffset), new Position(endElement, endOffset));\n }\n /**\n * Creates a new range, spreading from specified {@link module:engine/view/position~Position position} to a position moved by\n * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n *\n * @protected\n * @param {module:engine/view/position~Position} position Beginning of the range.\n * @param {Number} shift How long the range should be.\n * @returns {module:engine/view/range~Range}\n */\n\n }, {\n key: \"_createFromPositionAndShift\",\n value: function _createFromPositionAndShift(position, shift) {\n var start = position;\n var end = position.getShiftedBy(shift);\n return shift > 0 ? new this(start, end) : new this(end, start);\n }\n /**\n * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n * that element and ends after the last child of that element.\n *\n * @protected\n * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n * @returns {module:engine/view/range~Range}\n */\n\n }, {\n key: \"_createIn\",\n value: function _createIn(element) {\n return this._createFromParentsAndOffsets(element, 0, element, element.childCount);\n }\n /**\n * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n *\n * @protected\n * @param {module:engine/view/item~Item} item\n * @returns {module:engine/view/range~Range}\n */\n\n }, {\n key: \"_createOn\",\n value: function _createOn(item) {\n var size = item.is('$textProxy') ? item.offsetSize : 1;\n return this._createFromPositionAndShift(Position._createBefore(item), size);\n }\n }]);\n\n return Range;\n}(Symbol.iterator); // Function used by getEnlarged and getTrimmed methods.\n\n\nexport { Range as default };\n\nfunction enlargeTrimSkip(value) {\n if (value.item.is('attributeElement') || value.item.is('uiElement')) {\n return true;\n }\n\n return false;\n}","function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _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.\"); }\n\nfunction _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); }\n\nfunction _iterableToArray(iter) { if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }\n\nfunction _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; }\n\n/**\n * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/observablemixin\n */\nimport EmitterMixin from './emittermixin';\nimport CKEditorError from './ckeditorerror';\nimport { extend, isObject } from 'lodash-es';\nvar observablePropertiesSymbol = Symbol('observableProperties');\nvar boundObservablesSymbol = Symbol('boundObservables');\nvar boundPropertiesSymbol = Symbol('boundProperties');\n/**\n * A mixin that injects the \"observable properties\" and data binding functionality described in the\n * {@link ~Observable} interface.\n *\n * Read more about the concept of observables in the:\n * * {@glink framework/guides/architecture/core-editor-architecture#event-system-and-observables \"Event system and observables\"}\n * section of the {@glink framework/guides/architecture/core-editor-architecture \"Core editor architecture\"} guide,\n * * {@glink framework/guides/deep-dive/observables \"Observables\" deep dive} guide.\n *\n * @mixin ObservableMixin\n * @mixes module:utils/emittermixin~EmitterMixin\n * @implements module:utils/observablemixin~Observable\n */\n\nvar ObservableMixin = {\n /**\n * @inheritDoc\n */\n set: function set(name, value) {\n var _this = this;\n\n // If the first parameter is an Object, iterate over its properties.\n if (isObject(name)) {\n Object.keys(name).forEach(function (property) {\n _this.set(property, name[property]);\n }, this);\n return;\n }\n\n initObservable(this);\n var properties = this[observablePropertiesSymbol];\n\n if (name in this && !properties.has(name)) {\n /**\n * Cannot override an existing property.\n *\n * This error is thrown when trying to {@link ~Observable#set set} a property with\n * a name of an already existing property. For example:\n *\n *\t\tlet observable = new Model();\n *\t\tobservable.property = 1;\n *\t\tobservable.set( 'property', 2 );\t\t\t// throws\n *\n *\t\tobservable.set( 'property', 1 );\n *\t\tobservable.set( 'property', 2 );\t\t\t// ok, because this is an existing property.\n *\n * @error observable-set-cannot-override\n */\n throw new CKEditorError('observable-set-cannot-override', this);\n }\n\n Object.defineProperty(this, name, {\n enumerable: true,\n configurable: true,\n get: function get() {\n return properties.get(name);\n },\n set: function set(value) {\n var oldValue = properties.get(name); // Fire `set` event before the new value will be set to make it possible\n // to override observable property without affecting `change` event.\n // See https://github.com/ckeditor/ckeditor5-utils/issues/171.\n\n var newValue = this.fire('set:' + name, name, value, oldValue);\n\n if (newValue === undefined) {\n newValue = value;\n } // Allow undefined as an initial value like A.define( 'x', undefined ) (#132).\n // Note: When properties map has no such own property, then its value is undefined.\n\n\n if (oldValue !== newValue || !properties.has(name)) {\n properties.set(name, newValue);\n this.fire('change:' + name, name, newValue, oldValue);\n }\n }\n });\n this[name] = value;\n },\n\n /**\n * @inheritDoc\n */\n bind: function bind() {\n var _this2 = this;\n\n for (var _len = arguments.length, bindProperties = new Array(_len), _key = 0; _key < _len; _key++) {\n bindProperties[_key] = arguments[_key];\n }\n\n if (!bindProperties.length || !isStringArray(bindProperties)) {\n /**\n * All properties must be strings.\n *\n * @error observable-bind-wrong-properties\n */\n throw new CKEditorError('observable-bind-wrong-properties', this);\n }\n\n if (new Set(bindProperties).size !== bindProperties.length) {\n /**\n * Properties must be unique.\n *\n * @error observable-bind-duplicate-properties\n */\n throw new CKEditorError('observable-bind-duplicate-properties', this);\n }\n\n initObservable(this);\n var boundProperties = this[boundPropertiesSymbol];\n bindProperties.forEach(function (propertyName) {\n if (boundProperties.has(propertyName)) {\n /**\n * Cannot bind the same property more than once.\n *\n * @error observable-bind-rebind\n */\n throw new CKEditorError('observable-bind-rebind', _this2);\n }\n });\n var bindings = new Map(); // @typedef {Object} Binding\n // @property {Array} property Property which is bound.\n // @property {Array} to Array of observable–property components of the binding (`{ observable: ..., property: .. }`).\n // @property {Array} callback A function which processes `to` components.\n\n bindProperties.forEach(function (a) {\n var binding = {\n property: a,\n to: []\n };\n boundProperties.set(a, binding);\n bindings.set(a, binding);\n }); // @typedef {Object} BindChain\n // @property {Function} to See {@link ~ObservableMixin#_bindTo}.\n // @property {Function} toMany See {@link ~ObservableMixin#_bindToMany}.\n // @property {module:utils/observablemixin~Observable} _observable The observable which initializes the binding.\n // @property {Array} _bindProperties Array of `_observable` properties to be bound.\n // @property {Array} _to Array of `to()` observable–properties (`{ observable: toObservable, properties: ...toProperties }`).\n // @property {Map} _bindings Stores bindings to be kept in\n // {@link ~ObservableMixin#_boundProperties}/{@link ~ObservableMixin#_boundObservables}\n // initiated in this binding chain.\n\n return {\n to: bindTo,\n toMany: bindToMany,\n _observable: this,\n _bindProperties: bindProperties,\n _to: [],\n _bindings: bindings\n };\n },\n\n /**\n * @inheritDoc\n */\n unbind: function unbind() {\n var _this3 = this;\n\n // Nothing to do here if not inited yet.\n if (!this[observablePropertiesSymbol]) {\n return;\n }\n\n var boundProperties = this[boundPropertiesSymbol];\n var boundObservables = this[boundObservablesSymbol];\n\n for (var _len2 = arguments.length, unbindProperties = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n unbindProperties[_key2] = arguments[_key2];\n }\n\n if (unbindProperties.length) {\n if (!isStringArray(unbindProperties)) {\n /**\n * Properties must be strings.\n *\n * @error observable-unbind-wrong-properties\n */\n throw new CKEditorError('observable-unbind-wrong-properties', this);\n }\n\n unbindProperties.forEach(function (propertyName) {\n var binding = boundProperties.get(propertyName); // Nothing to do if the binding is not defined\n\n if (!binding) {\n return;\n }\n\n var toObservable, toProperty, toProperties, toPropertyBindings;\n binding.to.forEach(function (to) {\n // TODO: ES6 destructuring.\n toObservable = to[0];\n toProperty = to[1];\n toProperties = boundObservables.get(toObservable);\n toPropertyBindings = toProperties[toProperty];\n toPropertyBindings[\"delete\"](binding);\n\n if (!toPropertyBindings.size) {\n delete toProperties[toProperty];\n }\n\n if (!Object.keys(toProperties).length) {\n boundObservables[\"delete\"](toObservable);\n\n _this3.stopListening(toObservable, 'change');\n }\n });\n boundProperties[\"delete\"](propertyName);\n });\n } else {\n boundObservables.forEach(function (bindings, boundObservable) {\n _this3.stopListening(boundObservable, 'change');\n });\n boundObservables.clear();\n boundProperties.clear();\n }\n },\n\n /**\n * @inheritDoc\n */\n decorate: function decorate(methodName) {\n var _this4 = this;\n\n var originalMethod = this[methodName];\n\n if (!originalMethod) {\n /**\n * Cannot decorate an undefined method.\n *\n * @error observablemixin-cannot-decorate-undefined\n * @param {Object} object The object which method should be decorated.\n * @param {String} methodName Name of the method which does not exist.\n */\n throw new CKEditorError('observablemixin-cannot-decorate-undefined', this, {\n object: this,\n methodName: methodName\n });\n }\n\n this.on(methodName, function (evt, args) {\n evt[\"return\"] = originalMethod.apply(_this4, args);\n });\n\n this[methodName] = function () {\n for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n args[_key3] = arguments[_key3];\n }\n\n return this.fire(methodName, args);\n };\n }\n};\nextend(ObservableMixin, EmitterMixin);\nexport default ObservableMixin; // Init symbol properties needed for the observable mechanism to work.\n//\n// @private\n// @param {module:utils/observablemixin~ObservableMixin} observable\n\nfunction initObservable(observable) {\n // Do nothing if already inited.\n if (observable[observablePropertiesSymbol]) {\n return;\n } // The internal hash containing the observable's state.\n //\n // @private\n // @type {Map}\n\n\n Object.defineProperty(observable, observablePropertiesSymbol, {\n value: new Map()\n }); // Map containing bindings to external observables. It shares the binding objects\n // (`{ observable: A, property: 'a', to: ... }`) with {@link module:utils/observablemixin~ObservableMixin#_boundProperties} and\n // it is used to observe external observables to update own properties accordingly.\n // See {@link module:utils/observablemixin~ObservableMixin#bind}.\n //\n //\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n //\t\tconsole.log( A._boundObservables );\n //\n //\t\t\tMap( {\n //\t\t\t\tB: {\n //\t\t\t\t\tx: Set( [\n //\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n //\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n //\t\t\t\t\t] ),\n //\t\t\t\t\ty: Set( [\n //\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n //\t\t\t\t\t] )\n //\t\t\t\t}\n //\t\t\t} )\n //\n //\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n //\t\tconsole.log( A._boundObservables );\n //\n //\t\t\tMap( {\n //\t\t\t\tB: {\n //\t\t\t\t\tx: Set( [\n //\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n //\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n //\t\t\t\t\t] ),\n //\t\t\t\t\ty: Set( [\n //\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n //\t\t\t\t\t] ),\n //\t\t\t\t\tz: Set( [\n //\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n //\t\t\t\t\t] )\n //\t\t\t\t},\n //\t\t\t\tC: {\n //\t\t\t\t\tw: Set( [\n //\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n //\t\t\t\t\t] )\n //\t\t\t\t}\n //\t\t\t} )\n //\n // @private\n // @type {Map}\n\n Object.defineProperty(observable, boundObservablesSymbol, {\n value: new Map()\n }); // Object that stores which properties of this observable are bound and how. It shares\n // the binding objects (`{ observable: A, property: 'a', to: ... }`) with\n // {@link module:utils/observablemixin~ObservableMixin#_boundObservables}. This data structure is\n // a reverse of {@link module:utils/observablemixin~ObservableMixin#_boundObservables} and it is helpful for\n // {@link module:utils/observablemixin~ObservableMixin#unbind}.\n //\n // See {@link module:utils/observablemixin~ObservableMixin#bind}.\n //\n //\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n //\t\tconsole.log( A._boundProperties );\n //\n //\t\t\tMap( {\n //\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n //\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n //\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n //\t\t\t} )\n //\n //\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n //\t\tconsole.log( A._boundProperties );\n //\n //\t\t\tMap( {\n //\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n //\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n //\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] },\n //\t\t\t\td: { observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n //\t\t\t} )\n //\n // @private\n // @type {Map}\n\n Object.defineProperty(observable, boundPropertiesSymbol, {\n value: new Map()\n });\n} // A chaining for {@link module:utils/observablemixin~ObservableMixin#bind} providing `.to()` interface.\n//\n// @private\n// @param {...[Observable|String|Function]} args Arguments of the `.to( args )` binding.\n\n\nfunction bindTo() {\n var _this5 = this;\n\n var parsedArgs = parseBindToArgs.apply(void 0, arguments);\n var bindingsKeys = Array.from(this._bindings.keys());\n var numberOfBindings = bindingsKeys.length; // Eliminate A.bind( 'x' ).to( B, C )\n\n if (!parsedArgs.callback && parsedArgs.to.length > 1) {\n /**\n * Binding multiple observables only possible with callback.\n *\n * @error observable-bind-to-no-callback\n */\n throw new CKEditorError('observable-bind-to-no-callback', this);\n } // Eliminate A.bind( 'x', 'y' ).to( B, callback )\n\n\n if (numberOfBindings > 1 && parsedArgs.callback) {\n /**\n * Cannot bind multiple properties and use a callback in one binding.\n *\n * @error observable-bind-to-extra-callback\n */\n throw new CKEditorError('observable-bind-to-extra-callback', this);\n }\n\n parsedArgs.to.forEach(function (to) {\n // Eliminate A.bind( 'x', 'y' ).to( B, 'a' )\n if (to.properties.length && to.properties.length !== numberOfBindings) {\n /**\n * The number of properties must match.\n *\n * @error observable-bind-to-properties-length\n */\n throw new CKEditorError('observable-bind-to-properties-length', _this5);\n } // When no to.properties specified, observing source properties instead i.e.\n // A.bind( 'x', 'y' ).to( B ) -> Observe B.x and B.y\n\n\n if (!to.properties.length) {\n to.properties = _this5._bindProperties;\n }\n });\n this._to = parsedArgs.to; // Fill {@link BindChain#_bindings} with callback. When the callback is set there's only one binding.\n\n if (parsedArgs.callback) {\n this._bindings.get(bindingsKeys[0]).callback = parsedArgs.callback;\n }\n\n attachBindToListeners(this._observable, this._to); // Update observable._boundProperties and observable._boundObservables.\n\n updateBindToBound(this); // Set initial values of bound properties.\n\n this._bindProperties.forEach(function (propertyName) {\n updateBoundObservableProperty(_this5._observable, propertyName);\n });\n} // Binds to an attribute in a set of iterable observables.\n//\n// @private\n// @param {Array.} observables\n// @param {String} attribute\n// @param {Function} callback\n\n\nfunction bindToMany(observables, attribute, callback) {\n if (this._bindings.size > 1) {\n /**\n * Binding one attribute to many observables only possible with one attribute.\n *\n * @error observable-bind-to-many-not-one-binding\n */\n throw new CKEditorError('observable-bind-to-many-not-one-binding', this);\n }\n\n this.to.apply(this, _toConsumableArray(getBindingTargets(observables, attribute)).concat([// ...using given callback to parse attribute values.\n callback]));\n} // Returns an array of binding components for\n// {@link Observable#bind} from a set of iterable observables.\n//\n// @param {Array.} observables\n// @param {String} attribute\n// @returns {Array.}\n\n\nfunction getBindingTargets(observables, attribute) {\n var observableAndAttributePairs = observables.map(function (observable) {\n return [observable, attribute];\n }); // Merge pairs to one-dimension array of observables and attributes.\n\n return Array.prototype.concat.apply([], observableAndAttributePairs);\n} // Check if all entries of the array are of `String` type.\n//\n// @private\n// @param {Array} arr An array to be checked.\n// @returns {Boolean}\n\n\nfunction isStringArray(arr) {\n return arr.every(function (a) {\n return typeof a == 'string';\n });\n} // Parses and validates {@link Observable#bind}`.to( args )` arguments and returns\n// an object with a parsed structure. For example\n//\n//\t\tA.bind( 'x' ).to( B, 'a', C, 'b', call );\n//\n// becomes\n//\n//\t\t{\n//\t\t\tto: [\n//\t\t\t\t{ observable: B, properties: [ 'a' ] },\n//\t\t\t\t{ observable: C, properties: [ 'b' ] },\n//\t\t\t],\n//\t\t\tcallback: call\n// \t\t}\n//\n// @private\n// @param {...*} args Arguments of {@link Observable#bind}`.to( args )`.\n// @returns {Object}\n\n\nfunction parseBindToArgs() {\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n\n // Eliminate A.bind( 'x' ).to()\n if (!args.length) {\n /**\n * Invalid argument syntax in `to()`.\n *\n * @error observable-bind-to-parse-error\n */\n throw new CKEditorError('observable-bind-to-parse-error', null);\n }\n\n var parsed = {\n to: []\n };\n var lastObservable;\n\n if (typeof args[args.length - 1] == 'function') {\n parsed.callback = args.pop();\n }\n\n args.forEach(function (a) {\n if (typeof a == 'string') {\n lastObservable.properties.push(a);\n } else if (_typeof(a) == 'object') {\n lastObservable = {\n observable: a,\n properties: []\n };\n parsed.to.push(lastObservable);\n } else {\n throw new CKEditorError('observable-bind-to-parse-error', null);\n }\n });\n return parsed;\n} // Synchronizes {@link module:utils/observablemixin#_boundObservables} with {@link Binding}.\n//\n// @private\n// @param {Binding} binding A binding to store in {@link Observable#_boundObservables}.\n// @param {Observable} toObservable A observable, which is a new component of `binding`.\n// @param {String} toPropertyName A name of `toObservable`'s property, a new component of the `binding`.\n\n\nfunction updateBoundObservables(observable, binding, toObservable, toPropertyName) {\n var boundObservables = observable[boundObservablesSymbol];\n var bindingsToObservable = boundObservables.get(toObservable);\n var bindings = bindingsToObservable || {};\n\n if (!bindings[toPropertyName]) {\n bindings[toPropertyName] = new Set();\n } // Pass the binding to a corresponding Set in `observable._boundObservables`.\n\n\n bindings[toPropertyName].add(binding);\n\n if (!bindingsToObservable) {\n boundObservables.set(toObservable, bindings);\n }\n} // Synchronizes {@link Observable#_boundProperties} and {@link Observable#_boundObservables}\n// with {@link BindChain}.\n//\n// Assuming the following binding being created\n//\n// \t\tA.bind( 'a', 'b' ).to( B, 'x', 'y' );\n//\n// the following bindings were initialized by {@link Observable#bind} in {@link BindChain#_bindings}:\n//\n// \t\t{\n// \t\t\ta: { observable: A, property: 'a', to: [] },\n// \t\t\tb: { observable: A, property: 'b', to: [] },\n// \t\t}\n//\n// Iterate over all bindings in this chain and fill their `to` properties with\n// corresponding to( ... ) arguments (components of the binding), so\n//\n// \t\t{\n// \t\t\ta: { observable: A, property: 'a', to: [ B, 'x' ] },\n// \t\t\tb: { observable: A, property: 'b', to: [ B, 'y' ] },\n// \t\t}\n//\n// Then update the structure of {@link Observable#_boundObservables} with updated\n// binding, so it becomes:\n//\n// \t\tMap( {\n// \t\t\tB: {\n// \t\t\t\tx: Set( [\n// \t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] }\n// \t\t\t\t] ),\n// \t\t\t\ty: Set( [\n// \t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n// \t\t\t\t] )\n//\t\t\t}\n// \t\t} )\n//\n// @private\n// @param {BindChain} chain The binding initialized by {@link Observable#bind}.\n\n\nfunction updateBindToBound(chain) {\n var toProperty;\n\n chain._bindings.forEach(function (binding, propertyName) {\n // Note: For a binding without a callback, this will run only once\n // like in A.bind( 'x', 'y' ).to( B, 'a', 'b' )\n // TODO: ES6 destructuring.\n chain._to.forEach(function (to) {\n toProperty = to.properties[binding.callback ? 0 : chain._bindProperties.indexOf(propertyName)];\n binding.to.push([to.observable, toProperty]);\n updateBoundObservables(chain._observable, binding, to.observable, toProperty);\n });\n });\n} // Updates an property of a {@link Observable} with a value\n// determined by an entry in {@link Observable#_boundProperties}.\n//\n// @private\n// @param {Observable} observable A observable which property is to be updated.\n// @param {String} propertyName An property to be updated.\n\n\nfunction updateBoundObservableProperty(observable, propertyName) {\n var boundProperties = observable[boundPropertiesSymbol];\n var binding = boundProperties.get(propertyName);\n var propertyValue; // When a binding with callback is created like\n //\n // \t\tA.bind( 'a' ).to( B, 'b', C, 'c', callback );\n //\n // collect B.b and C.c, then pass them to callback to set A.a.\n\n if (binding.callback) {\n propertyValue = binding.callback.apply(observable, binding.to.map(function (to) {\n return to[0][to[1]];\n }));\n } else {\n propertyValue = binding.to[0];\n propertyValue = propertyValue[0][propertyValue[1]];\n }\n\n if (Object.prototype.hasOwnProperty.call(observable, propertyName)) {\n observable[propertyName] = propertyValue;\n } else {\n observable.set(propertyName, propertyValue);\n }\n} // Starts listening to changes in {@link BindChain._to} observables to update\n// {@link BindChain._observable} {@link BindChain._bindProperties}. Also sets the\n// initial state of {@link BindChain._observable}.\n//\n// @private\n// @param {BindChain} chain The chain initialized by {@link Observable#bind}.\n\n\nfunction attachBindToListeners(observable, toBindings) {\n toBindings.forEach(function (to) {\n var boundObservables = observable[boundObservablesSymbol];\n var bindings; // If there's already a chain between the observables (`observable` listens to\n // `to.observable`), there's no need to create another `change` event listener.\n\n if (!boundObservables.get(to.observable)) {\n observable.listenTo(to.observable, 'change', function (evt, propertyName) {\n bindings = boundObservables.get(to.observable)[propertyName]; // Note: to.observable will fire for any property change, react\n // to changes of properties which are bound only.\n\n if (bindings) {\n bindings.forEach(function (binding) {\n updateBoundObservableProperty(observable, binding.property);\n });\n }\n });\n }\n });\n}\n/**\n * An interface which adds \"observable properties\" and data binding functionality.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~ObservableMixin} mixin.\n *\n * Read more about the usage of this interface in the:\n * * {@glink framework/guides/architecture/core-editor-architecture#event-system-and-observables \"Event system and observables\"}\n * section of the {@glink framework/guides/architecture/core-editor-architecture \"Core editor architecture\"} guide,\n * * {@glink framework/guides/deep-dive/observables \"Observables\" deep dive} guide.\n *\n * @interface Observable\n * @extends module:utils/emittermixin~Emitter\n */\n\n/**\n * Fired when a property changed value.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} );\n *\n *\t\tobservable.prop = 2; // -> 'prop has changed from 1 to 2'\n *\n * @event change:{property}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\n\n/**\n * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).\n *\n * You can control the final value of the property by using\n * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.\n *\n *\t\tobservable.set( 'prop', 1 );\n *\n *\t\tobservable.on( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );\n *\t\t\tconsole.log( `Current property value is ${ observable[ propertyName ] }` );\n *\n *\t\t\t// Let's override the value.\n *\t\t\tevt.return = 3;\n *\t\t} );\n *\n *\t\tobservable.on( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n *\t\t\tconsole.log( `Value has changed from ${ oldValue } to ${ newValue }` );\n *\t\t} );\n *\n *\t\tobservable.prop = 2; // -> 'Value is going to be changed from 1 to 2'\n *\t\t // -> 'Current property value is 1'\n *\t\t // -> 'Value has changed from 1 to 3'\n *\n * **Note:** The event is fired even when the new value is the same as the old value.\n *\n * @event set:{property}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\n\n/**\n * Creates and sets the value of an observable property of this object. Such a property becomes a part\n * of the state and is observable.\n *\n * It accepts also a single object literal containing key/value pairs with properties to be set.\n *\n * This method throws the `observable-set-cannot-override` error if the observable instance already\n * has a property with the given property name. This prevents from mistakenly overriding existing\n * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.\n *\n * @method #set\n * @param {String|Object} name The property's name or object with `name=>value` pairs.\n * @param {*} [value] The property's value (if `name` was passed in the first parameter).\n */\n\n/**\n * Binds {@link #set observable properties} to other objects implementing the\n * {@link module:utils/observablemixin~Observable} interface.\n *\n * Read more in the {@glink framework/guides/deep-dive/observables#property-bindings dedicated guide}\n * covering the topic of property bindings with some additional examples.\n *\n * Consider two objects: a `button` and an associated `command` (both `Observable`).\n *\n * A simple property binding could be as follows:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isEnabled' );\n *\n * or even shorter:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command );\n *\n * which works in the following way:\n *\n * * `button.isEnabled` **instantly equals** `command.isEnabled`,\n * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.\n *\n * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.\n *\n * You can also \"rename\" the property in the binding by specifying the new name in the `to()` chain:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isWorking' );\n *\n * It is possible to bind more than one property at a time to shorten the code:\n *\n *\t\tbutton.bind( 'isEnabled', 'value' ).to( command );\n *\n * which corresponds to:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command );\n *\t\tbutton.bind( 'value' ).to( command );\n *\n * The binding can include more than one observable, combining multiple data sources in a custom callback:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',\n *\t\t\t( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );\n *\n * Using a custom callback allows processing the value before passing it to the target property:\n *\n *\t\tbutton.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );\n *\n * It is also possible to bind to the same property in an array of observables.\n * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them\n * must be enabled for the button to become enabled, use the following code:\n *\n *\t\tbutton.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',\n *\t\t\t( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );\n *\n * @method #bind\n * @param {...String} bindProperties Observable properties that will be bound to other observable(s).\n * @returns {Object} The bind chain with the `to()` and `toMany()` methods.\n */\n\n/**\n * Removes the binding created with {@link #bind}.\n *\n *\t\t// Removes the binding for the 'a' property.\n *\t\tA.unbind( 'a' );\n *\n *\t\t// Removes bindings for all properties.\n *\t\tA.unbind();\n *\n * @method #unbind\n * @param {...String} [unbindProperties] Observable properties to be unbound. All the bindings will\n * be released if no properties are provided.\n */\n\n/**\n * Turns the given methods of this object into event-based ones. This means that the new method will fire an event\n * (named after the method) and the original action will be plugged as a listener to that event.\n *\n * Read more in the {@glink framework/guides/deep-dive/observables#decorating-object-methods dedicated guide}\n * covering the topic of decorating methods with some additional examples.\n *\n * Decorating the method does not change its behavior (it only adds an event),\n * but it allows to modify it later on by listening to the method's event.\n *\n * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:\n *\n *\t\tclass Foo {\n *\t\t\tconstructor() {\n *\t\t\t\tthis.decorate( 'method' );\n *\t\t\t}\n *\n *\t\t\tmethod() {\n *\t\t\t\tconsole.log( 'called!' );\n *\t\t\t}\n *\t\t}\n *\n *\t\tconst foo = new Foo();\n *\t\tfoo.on( 'method', ( evt ) => {\n *\t\t\tevt.stop();\n *\t\t}, { priority: 'high' } );\n *\n *\t\tfoo.method(); // Nothing is logged.\n *\n *\n * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener\n * has been used to execute this particular callback before the one which calls the original method\n * (which uses the \"normal\" priority).\n *\n * It is also possible to change the returned value:\n *\n *\t\tfoo.on( 'method', ( evt ) => {\n *\t\t\tevt.return = 'Foo!';\n *\t\t} );\n *\n *\t\tfoo.method(); // -> 'Foo'\n *\n * Finally, it is possible to access and modify the arguments the method is called with:\n *\n *\t\tmethod( a, b ) {\n *\t\t\tconsole.log( `${ a }, ${ b }` );\n *\t\t}\n *\n *\t\t// ...\n *\n *\t\tfoo.on( 'method', ( evt, args ) => {\n *\t\t\targs[ 0 ] = 3;\n *\n *\t\t\tconsole.log( args[ 1 ] ); // -> 2\n *\t\t}, { priority: 'high' } );\n *\n *\t\tfoo.method( 1, 2 ); // -> '3, 2'\n *\n * @method #decorate\n * @param {String} methodName Name of the method to decorate.\n */","function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/command\n */\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\n\nvar Command = /*#__PURE__*/function () {\n /**\n * Creates a new `Command` instance.\n *\n * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n */\n function Command(editor) {\n var _this = this;\n\n _classCallCheck(this, Command);\n\n /**\n * The editor on which this command will be used.\n *\n * @readonly\n * @member {module:core/editor/editor~Editor}\n */\n this.editor = editor;\n /**\n * The value of the command. A concrete command class should define what it represents for it.\n *\n * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n * And the value of the `'link'` command may be an object with links details.\n *\n * It is possible for a command to have no value (e.g. for stateless actions such as `'imageUpload'`).\n *\n * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n *\n * @observable\n * @readonly\n * @member #value\n */\n\n this.set('value', undefined);\n /**\n * Flag indicating whether a command is enabled or disabled.\n * A disabled command will do nothing when executed.\n *\n * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n *\n * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n *\n *\t\tfunction disableCommand( cmd ) {\n *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n *\n *\t\t\tcmd.isEnabled = false;\n *\n *\t\t\t// Make it possible to enable the command again.\n *\t\t\treturn () => {\n *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n *\t\t\t\tcmd.refresh();\n *\t\t\t};\n *\n *\t\t\tfunction forceDisable( evt ) {\n *\t\t\t\tevt.return = false;\n *\t\t\t\tevt.stop();\n *\t\t\t}\n *\t\t}\n *\n *\t\t// Usage:\n *\n *\t\t// Disabling the command.\n *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n *\n *\t\t// Enabling the command again.\n *\t\tenableBold();\n *\n * @observable\n * @readonly\n * @member {Boolean} #isEnabled\n */\n\n this.set('isEnabled', false);\n /**\n * Holds identifiers for {@link #forceDisabled} mechanism.\n *\n * @type {Set.}\n * @private\n */\n\n this._disableStack = new Set();\n this.decorate('execute'); // By default every command is refreshed when changes are applied to the model.\n\n this.listenTo(this.editor.model.document, 'change', function () {\n _this.refresh();\n });\n this.on('execute', function (evt) {\n if (!_this.isEnabled) {\n evt.stop();\n }\n }, {\n priority: 'high'\n }); // By default commands are disabled when the editor is in read-only mode.\n\n this.listenTo(editor, 'change:isReadOnly', function (evt, name, value) {\n if (value) {\n _this.forceDisabled('readOnlyMode');\n } else {\n _this.clearForceDisabled('readOnlyMode');\n }\n });\n }\n /**\n * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n * in this method.\n *\n * This method is automatically called when\n * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n */\n\n\n _createClass(Command, [{\n key: \"refresh\",\n value: function refresh() {\n this.isEnabled = true;\n }\n /**\n * Disables the command.\n *\n * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n *\n * Disabling and enabling a command:\n *\n *\t\tcommand.isEnabled; // -> true\n *\t\tcommand.forceDisabled( 'MyFeature' );\n *\t\tcommand.isEnabled; // -> false\n *\t\tcommand.clearForceDisabled( 'MyFeature' );\n *\t\tcommand.isEnabled; // -> true\n *\n * Command disabled by multiple features:\n *\n *\t\tcommand.forceDisabled( 'MyFeature' );\n *\t\tcommand.forceDisabled( 'OtherFeature' );\n *\t\tcommand.clearForceDisabled( 'MyFeature' );\n *\t\tcommand.isEnabled; // -> false\n *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n *\t\tcommand.isEnabled; // -> true\n *\n * Multiple disabling with the same identifier is redundant:\n *\n *\t\tcommand.forceDisabled( 'MyFeature' );\n *\t\tcommand.forceDisabled( 'MyFeature' );\n *\t\tcommand.clearForceDisabled( 'MyFeature' );\n *\t\tcommand.isEnabled; // -> true\n *\n * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n * so the command might be still disabled after {@link #clearForceDisabled} was used.\n *\n * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n */\n\n }, {\n key: \"forceDisabled\",\n value: function forceDisabled(id) {\n this._disableStack.add(id);\n\n if (this._disableStack.size == 1) {\n this.on('set:isEnabled', forceDisable, {\n priority: 'highest'\n });\n this.isEnabled = false;\n }\n }\n /**\n * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.\n *\n * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n */\n\n }, {\n key: \"clearForceDisabled\",\n value: function clearForceDisabled(id) {\n this._disableStack[\"delete\"](id);\n\n if (this._disableStack.size == 0) {\n this.off('set:isEnabled', forceDisable);\n this.refresh();\n }\n }\n /**\n * Executes the command.\n *\n * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n * to the command.\n *\n * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n *\n * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n *\n * This method may return a value, which would be forwarded all the way down to the\n * {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * @fires execute\n */\n\n }, {\n key: \"execute\",\n value: function execute() {}\n /**\n * Destroys the command.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.stopListening();\n }\n /**\n * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n * possible to change/cancel the behavior of the command by listening to this event.\n *\n * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n *\n * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n * by a high priority listener in order to prevent command execution.\n *\n * @event execute\n */\n\n }]);\n\n return Command;\n}();\n\nexport { Command as default };\nmix(Command, ObservableMixin); // Helper function that forces command to be disabled.\n\nfunction forceDisable(evt) {\n evt[\"return\"] = false;\n evt.stop();\n}","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && typeof btoa !== 'undefined') {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of \\n\\n\";\n\nfunction url(ele) {\n return ele.hasAttribute('url') ? ele.getAttribute('url') : location.href;\n}\n\nvar UpdatesForElement = /*#__PURE__*/function (_SubscribingElement) {\n _inherits(UpdatesForElement, _SubscribingElement);\n\n var _super = _createSuper(UpdatesForElement);\n\n function UpdatesForElement() {\n var _this;\n\n _classCallCheck(this, UpdatesForElement);\n\n _this = _super.call(this);\n\n var shadowRoot = _this.attachShadow({\n mode: 'open'\n });\n\n shadowRoot.innerHTML = template;\n return _this;\n }\n\n _createClass(UpdatesForElement, [{\n key: \"connectedCallback\",\n value: function () {\n var _connectedCallback = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var consumer;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!this.preview) {\n _context.next = 2;\n break;\n }\n\n return _context.abrupt(\"return\");\n\n case 2:\n this.update = debounce(this.update.bind(this), this.debounce);\n _context.next = 5;\n return CableReady.consumer;\n\n case 5:\n consumer = _context.sent;\n\n if (consumer) {\n this.createSubscription(consumer, 'CableReady::Stream', this.update);\n } else {\n console.error('The `updates-for` helper cannot connect without an ActionCable consumer.\\nPlease run `rails generate cable_ready:helpers` to fix this.');\n }\n\n case 7:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function connectedCallback() {\n return _connectedCallback.apply(this, arguments);\n }\n\n return connectedCallback;\n }()\n }, {\n key: \"update\",\n value: function () {\n var _update = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(data) {\n var _this2 = this;\n\n var identifier, query, blocks, only, html, template, _loop, i, _ret;\n\n return regeneratorRuntime.wrap(function _callee2$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n identifier = this.getAttribute('identifier');\n query = \"updates-for[identifier=\\\"\".concat(identifier, \"\\\"]\");\n blocks = document.querySelectorAll(query);\n\n if (!(blocks[0] !== this)) {\n _context3.next = 5;\n break;\n }\n\n return _context3.abrupt(\"return\");\n\n case 5:\n only = this.getAttribute('only');\n\n if (!(only && data.changed && !only.split(' ').some(function (attribute) {\n return data.changed.includes(attribute);\n }))) {\n _context3.next = 8;\n break;\n }\n\n return _context3.abrupt(\"return\");\n\n case 8:\n html = {};\n template = document.createElement('template');\n _loop = /*#__PURE__*/regeneratorRuntime.mark(function _loop(i) {\n var response, fragments, operation;\n return regeneratorRuntime.wrap(function _loop$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n blocks[i].setAttribute('updating', 'updating');\n\n if (html.hasOwnProperty(url(blocks[i]))) {\n _context2.next = 8;\n break;\n }\n\n _context2.next = 4;\n return graciouslyFetch(url(blocks[i]), {\n 'X-Cable-Ready': 'update'\n });\n\n case 4:\n response = _context2.sent;\n _context2.next = 7;\n return response.text();\n\n case 7:\n html[url(blocks[i])] = _context2.sent;\n\n case 8:\n template.innerHTML = String(html[url(blocks[i])]).trim();\n _context2.next = 11;\n return _this2.resolveTurboFrames(template.content);\n\n case 11:\n fragments = template.content.querySelectorAll(query);\n\n if (!(fragments.length <= i)) {\n _context2.next = 15;\n break;\n }\n\n console.warn('Update aborted due to mismatched number of elements');\n return _context2.abrupt(\"return\", {\n v: void 0\n });\n\n case 15:\n activeElement.set(document.activeElement);\n operation = {\n element: blocks[i],\n html: fragments[i],\n permanentAttributeName: 'data-ignore-updates'\n };\n dispatch(blocks[i], 'cable-ready:before-update', operation);\n morphdom(blocks[i], fragments[i], {\n childrenOnly: true,\n onBeforeElUpdated: shouldMorph(operation),\n onElUpdated: function onElUpdated(_) {\n blocks[i].removeAttribute('updating');\n dispatch(blocks[i], 'cable-ready:after-update', operation);\n assignFocus(operation.focusSelector);\n }\n });\n\n case 19:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _loop);\n });\n i = 0;\n\n case 12:\n if (!(i < blocks.length)) {\n _context3.next = 20;\n break;\n }\n\n return _context3.delegateYield(_loop(i), \"t0\", 14);\n\n case 14:\n _ret = _context3.t0;\n\n if (!(_typeof(_ret) === \"object\")) {\n _context3.next = 17;\n break;\n }\n\n return _context3.abrupt(\"return\", _ret.v);\n\n case 17:\n i++;\n _context3.next = 12;\n break;\n\n case 20:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function update(_x) {\n return _update.apply(this, arguments);\n }\n\n return update;\n }()\n }, {\n key: \"resolveTurboFrames\",\n value: function () {\n var _resolveTurboFrames = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(documentFragment) {\n var _this3 = this;\n\n var reloadingTurboFrames;\n return regeneratorRuntime.wrap(function _callee4$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n reloadingTurboFrames = _toConsumableArray(documentFragment.querySelectorAll('turbo-frame[src]:not([loading=\"lazy\"])'));\n return _context5.abrupt(\"return\", Promise.all(reloadingTurboFrames.map(function (frame) {\n return new Promise( /*#__PURE__*/function () {\n var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(resolve) {\n var frameResponse, frameTemplate;\n return regeneratorRuntime.wrap(function _callee3$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return graciouslyFetch(frame.getAttribute('src'), {\n 'Turbo-Frame': frame.id,\n 'X-Cable-Ready': 'update'\n });\n\n case 2:\n frameResponse = _context4.sent;\n frameTemplate = document.createElement('template');\n _context4.next = 6;\n return frameResponse.text();\n\n case 6:\n frameTemplate.innerHTML = _context4.sent;\n _context4.next = 9;\n return _this3.resolveTurboFrames(frameTemplate.content);\n\n case 9:\n documentFragment.querySelector(\"turbo-frame#\".concat(frame.id)).innerHTML = String(frameTemplate.content.querySelector(\"turbo-frame#\".concat(frame.id)).innerHTML).trim();\n resolve();\n\n case 11:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee3);\n }));\n\n return function (_x3) {\n return _ref.apply(this, arguments);\n };\n }());\n })));\n\n case 2:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee4);\n }));\n\n function resolveTurboFrames(_x2) {\n return _resolveTurboFrames.apply(this, arguments);\n }\n\n return resolveTurboFrames;\n }()\n }, {\n key: \"debounce\",\n get: function get() {\n return this.hasAttribute('debounce') ? parseInt(this.getAttribute('debounce')) : 20;\n }\n }]);\n\n return UpdatesForElement;\n}(SubscribingElement);\n\nexport { UpdatesForElement as default };","import { xpathToElement, dispatch } from './utils';\nimport activeElement from './active_element';\nimport OperationStore from './operation_store';\nimport actionCable from './action_cable';\nimport StreamFromElement from './elements/stream_from_element';\nimport UpdatesForElement from './elements/updates_for_element';\n\nvar perform = function perform(operations) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n emitMissingElementWarnings: true\n };\n var batches = {};\n operations.forEach(function (operation) {\n if (!!operation.batch) batches[operation.batch] = batches[operation.batch] ? ++batches[operation.batch] : 1;\n });\n operations.forEach(function (operation) {\n var name = operation.operation;\n\n try {\n if (operation.selector) {\n operation.element = operation.xpath ? xpathToElement(operation.selector) : document[operation.selectAll ? 'querySelectorAll' : 'querySelector'](operation.selector);\n } else {\n operation.element = document;\n }\n\n if (operation.element || options.emitMissingElementWarnings) {\n activeElement.set(document.activeElement);\n var cableReadyOperation = OperationStore.all[name];\n\n if (cableReadyOperation) {\n cableReadyOperation(operation);\n if (!!operation.batch && --batches[operation.batch] === 0) dispatch(document, 'cable-ready:batch-complete', {\n batch: operation.batch\n });\n } else {\n console.error(\"CableReady couldn't find the \\\"\".concat(name, \"\\\" operation. Make sure you use the camelized form when calling an operation method.\"));\n }\n }\n } catch (e) {\n if (operation.element) {\n console.error(\"CableReady detected an error in \".concat(name, \": \").concat(e.message, \". If you need to support older browsers make sure you've included the corresponding polyfills. https://docs.stimulusreflex.com/setup#polyfills-for-ie11.\"));\n console.error(e);\n } else {\n console.warn(\"CableReady \".concat(name, \" failed due to missing DOM element for selector: '\").concat(operation.selector, \"'\"));\n }\n }\n });\n};\n\nvar performAsync = function performAsync(operations) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n emitMissingElementWarnings: true\n };\n return new Promise(function (resolve, reject) {\n try {\n resolve(perform(operations, options));\n } catch (err) {\n reject(err);\n }\n });\n};\n\nvar initialize = function initialize() {\n var initializeOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var consumer = initializeOptions.consumer;\n actionCable.setConsumer(consumer);\n if (!customElements.get('stream-from')) customElements.define('stream-from', StreamFromElement);\n if (!customElements.get('updates-for')) customElements.define('updates-for', UpdatesForElement);\n};\n\nexport { perform, performAsync, initialize };\nexport var consumer = actionCable.getConsumer();","import { version } from '../package.json';\nimport * as MorphCallbacks from './morph_callbacks';\nimport { shouldMorphCallbacks, didMorphCallbacks } from './morph_callbacks';\nimport * as Utils from './utils';\nimport OperationStore, { addOperation, addOperations } from './operation_store';\nimport { perform, performAsync, initialize, consumer } from './cable_ready';\nimport StreamFromElement from './elements/stream_from_element';\nimport UpdatesForElement from './elements/updates_for_element';\nimport SubscribingElement from './elements/subscribing_element';\nexport { Utils, MorphCallbacks, StreamFromElement, UpdatesForElement, SubscribingElement };\nexport default {\n perform: perform,\n performAsync: performAsync,\n shouldMorphCallbacks: shouldMorphCallbacks,\n didMorphCallbacks: didMorphCallbacks,\n initialize: initialize,\n consumer: consumer,\n addOperation: addOperation,\n addOperations: addOperations,\n version: version,\n\n get DOMOperations() {\n console.warn('DEPRECATED: Please use `CableReady.operations` instead of `CableReady.DOMOperations`');\n return OperationStore.all;\n },\n\n get operations() {\n return OperationStore.all;\n }\n\n};","function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar adapters = {\n logger: self.console,\n WebSocket: self.WebSocket\n};\nvar logger = {\n log: function log() {\n if (this.enabled) {\n var _adapters$logger;\n\n for (var _len = arguments.length, messages = new Array(_len), _key = 0; _key < _len; _key++) {\n messages[_key] = arguments[_key];\n }\n\n messages.push(Date.now());\n\n (_adapters$logger = adapters.logger).log.apply(_adapters$logger, [\"[ActionCable]\"].concat(messages));\n }\n }\n};\n\nvar now = function now() {\n return new Date().getTime();\n};\n\nvar secondsSince = function secondsSince(time) {\n return (now() - time) / 1e3;\n};\n\nvar ConnectionMonitor = /*#__PURE__*/function () {\n function ConnectionMonitor(connection) {\n _classCallCheck(this, ConnectionMonitor);\n\n this.visibilityDidChange = this.visibilityDidChange.bind(this);\n this.connection = connection;\n this.reconnectAttempts = 0;\n }\n\n _createClass(ConnectionMonitor, [{\n key: \"start\",\n value: function start() {\n if (!this.isRunning()) {\n this.startedAt = now();\n delete this.stoppedAt;\n this.startPolling();\n addEventListener(\"visibilitychange\", this.visibilityDidChange);\n logger.log(\"ConnectionMonitor started. stale threshold = \".concat(this.constructor.staleThreshold, \" s\"));\n }\n }\n }, {\n key: \"stop\",\n value: function stop() {\n if (this.isRunning()) {\n this.stoppedAt = now();\n this.stopPolling();\n removeEventListener(\"visibilitychange\", this.visibilityDidChange);\n logger.log(\"ConnectionMonitor stopped\");\n }\n }\n }, {\n key: \"isRunning\",\n value: function isRunning() {\n return this.startedAt && !this.stoppedAt;\n }\n }, {\n key: \"recordPing\",\n value: function recordPing() {\n this.pingedAt = now();\n }\n }, {\n key: \"recordConnect\",\n value: function recordConnect() {\n this.reconnectAttempts = 0;\n this.recordPing();\n delete this.disconnectedAt;\n logger.log(\"ConnectionMonitor recorded connect\");\n }\n }, {\n key: \"recordDisconnect\",\n value: function recordDisconnect() {\n this.disconnectedAt = now();\n logger.log(\"ConnectionMonitor recorded disconnect\");\n }\n }, {\n key: \"startPolling\",\n value: function startPolling() {\n this.stopPolling();\n this.poll();\n }\n }, {\n key: \"stopPolling\",\n value: function stopPolling() {\n clearTimeout(this.pollTimeout);\n }\n }, {\n key: \"poll\",\n value: function poll() {\n var _this = this;\n\n this.pollTimeout = setTimeout(function () {\n _this.reconnectIfStale();\n\n _this.poll();\n }, this.getPollInterval());\n }\n }, {\n key: \"getPollInterval\",\n value: function getPollInterval() {\n var _this$constructor = this.constructor,\n staleThreshold = _this$constructor.staleThreshold,\n reconnectionBackoffRate = _this$constructor.reconnectionBackoffRate;\n var backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));\n var jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;\n var jitter = jitterMax * Math.random();\n return staleThreshold * 1e3 * backoff * (1 + jitter);\n }\n }, {\n key: \"reconnectIfStale\",\n value: function reconnectIfStale() {\n if (this.connectionIsStale()) {\n logger.log(\"ConnectionMonitor detected stale connection. reconnectAttempts = \".concat(this.reconnectAttempts, \", time stale = \").concat(secondsSince(this.refreshedAt), \" s, stale threshold = \").concat(this.constructor.staleThreshold, \" s\"));\n this.reconnectAttempts++;\n\n if (this.disconnectedRecently()) {\n logger.log(\"ConnectionMonitor skipping reopening recent disconnect. time disconnected = \".concat(secondsSince(this.disconnectedAt), \" s\"));\n } else {\n logger.log(\"ConnectionMonitor reopening\");\n this.connection.reopen();\n }\n }\n }\n }, {\n key: \"refreshedAt\",\n get: function get() {\n return this.pingedAt ? this.pingedAt : this.startedAt;\n }\n }, {\n key: \"connectionIsStale\",\n value: function connectionIsStale() {\n return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;\n }\n }, {\n key: \"disconnectedRecently\",\n value: function disconnectedRecently() {\n return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;\n }\n }, {\n key: \"visibilityDidChange\",\n value: function visibilityDidChange() {\n var _this2 = this;\n\n if (document.visibilityState === \"visible\") {\n setTimeout(function () {\n if (_this2.connectionIsStale() || !_this2.connection.isOpen()) {\n logger.log(\"ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = \".concat(document.visibilityState));\n\n _this2.connection.reopen();\n }\n }, 200);\n }\n }\n }]);\n\n return ConnectionMonitor;\n}();\n\nConnectionMonitor.staleThreshold = 6;\nConnectionMonitor.reconnectionBackoffRate = .15;\nvar INTERNAL = {\n message_types: {\n welcome: \"welcome\",\n disconnect: \"disconnect\",\n ping: \"ping\",\n confirmation: \"confirm_subscription\",\n rejection: \"reject_subscription\"\n },\n disconnect_reasons: {\n unauthorized: \"unauthorized\",\n invalid_request: \"invalid_request\",\n server_restart: \"server_restart\"\n },\n default_mount_path: \"/cable\",\n protocols: [\"actioncable-v1-json\", \"actioncable-unsupported\"]\n};\nvar message_types = INTERNAL.message_types,\n protocols = INTERNAL.protocols;\nvar supportedProtocols = protocols.slice(0, protocols.length - 1);\nvar indexOf = [].indexOf;\n\nvar Connection = /*#__PURE__*/function () {\n function Connection(consumer) {\n _classCallCheck(this, Connection);\n\n this.open = this.open.bind(this);\n this.consumer = consumer;\n this.subscriptions = this.consumer.subscriptions;\n this.monitor = new ConnectionMonitor(this);\n this.disconnected = true;\n }\n\n _createClass(Connection, [{\n key: \"send\",\n value: function send(data) {\n if (this.isOpen()) {\n this.webSocket.send(JSON.stringify(data));\n return true;\n } else {\n return false;\n }\n }\n }, {\n key: \"open\",\n value: function open() {\n if (this.isActive()) {\n logger.log(\"Attempted to open WebSocket, but existing socket is \".concat(this.getState()));\n return false;\n } else {\n logger.log(\"Opening WebSocket, current state is \".concat(this.getState(), \", subprotocols: \").concat(protocols));\n\n if (this.webSocket) {\n this.uninstallEventHandlers();\n }\n\n this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);\n this.installEventHandlers();\n this.monitor.start();\n return true;\n }\n }\n }, {\n key: \"close\",\n value: function close() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {\n allowReconnect: true\n },\n allowReconnect = _ref.allowReconnect;\n\n if (!allowReconnect) {\n this.monitor.stop();\n }\n\n if (this.isActive()) {\n return this.webSocket.close();\n }\n }\n }, {\n key: \"reopen\",\n value: function reopen() {\n logger.log(\"Reopening WebSocket, current state is \".concat(this.getState()));\n\n if (this.isActive()) {\n try {\n return this.close();\n } catch (error) {\n logger.log(\"Failed to reopen WebSocket\", error);\n } finally {\n logger.log(\"Reopening WebSocket in \".concat(this.constructor.reopenDelay, \"ms\"));\n setTimeout(this.open, this.constructor.reopenDelay);\n }\n } else {\n return this.open();\n }\n }\n }, {\n key: \"getProtocol\",\n value: function getProtocol() {\n if (this.webSocket) {\n return this.webSocket.protocol;\n }\n }\n }, {\n key: \"isOpen\",\n value: function isOpen() {\n return this.isState(\"open\");\n }\n }, {\n key: \"isActive\",\n value: function isActive() {\n return this.isState(\"open\", \"connecting\");\n }\n }, {\n key: \"isProtocolSupported\",\n value: function isProtocolSupported() {\n return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;\n }\n }, {\n key: \"isState\",\n value: function isState() {\n for (var _len2 = arguments.length, states = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n states[_key2] = arguments[_key2];\n }\n\n return indexOf.call(states, this.getState()) >= 0;\n }\n }, {\n key: \"getState\",\n value: function getState() {\n if (this.webSocket) {\n for (var state in adapters.WebSocket) {\n if (adapters.WebSocket[state] === this.webSocket.readyState) {\n return state.toLowerCase();\n }\n }\n }\n\n return null;\n }\n }, {\n key: \"installEventHandlers\",\n value: function installEventHandlers() {\n for (var eventName in this.events) {\n var handler = this.events[eventName].bind(this);\n this.webSocket[\"on\".concat(eventName)] = handler;\n }\n }\n }, {\n key: \"uninstallEventHandlers\",\n value: function uninstallEventHandlers() {\n for (var eventName in this.events) {\n this.webSocket[\"on\".concat(eventName)] = function () {};\n }\n }\n }]);\n\n return Connection;\n}();\n\nConnection.reopenDelay = 500;\nConnection.prototype.events = {\n message: function message(event) {\n if (!this.isProtocolSupported()) {\n return;\n }\n\n var _JSON$parse = JSON.parse(event.data),\n identifier = _JSON$parse.identifier,\n message = _JSON$parse.message,\n reason = _JSON$parse.reason,\n reconnect = _JSON$parse.reconnect,\n type = _JSON$parse.type;\n\n switch (type) {\n case message_types.welcome:\n this.monitor.recordConnect();\n return this.subscriptions.reload();\n\n case message_types.disconnect:\n logger.log(\"Disconnecting. Reason: \".concat(reason));\n return this.close({\n allowReconnect: reconnect\n });\n\n case message_types.ping:\n return this.monitor.recordPing();\n\n case message_types.confirmation:\n this.subscriptions.confirmSubscription(identifier);\n return this.subscriptions.notify(identifier, \"connected\");\n\n case message_types.rejection:\n return this.subscriptions.reject(identifier);\n\n default:\n return this.subscriptions.notify(identifier, \"received\", message);\n }\n },\n open: function open() {\n logger.log(\"WebSocket onopen event, using '\".concat(this.getProtocol(), \"' subprotocol\"));\n this.disconnected = false;\n\n if (!this.isProtocolSupported()) {\n logger.log(\"Protocol is unsupported. Stopping monitor and disconnecting.\");\n return this.close({\n allowReconnect: false\n });\n }\n },\n close: function close(event) {\n logger.log(\"WebSocket onclose event\");\n\n if (this.disconnected) {\n return;\n }\n\n this.disconnected = true;\n this.monitor.recordDisconnect();\n return this.subscriptions.notifyAll(\"disconnected\", {\n willAttemptReconnect: this.monitor.isRunning()\n });\n },\n error: function error() {\n logger.log(\"WebSocket onerror event\");\n }\n};\n\nvar extend = function extend(object, properties) {\n if (properties != null) {\n for (var key in properties) {\n var value = properties[key];\n object[key] = value;\n }\n }\n\n return object;\n};\n\nvar Subscription = /*#__PURE__*/function () {\n function Subscription(consumer) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var mixin = arguments.length > 2 ? arguments[2] : undefined;\n\n _classCallCheck(this, Subscription);\n\n this.consumer = consumer;\n this.identifier = JSON.stringify(params);\n extend(this, mixin);\n }\n\n _createClass(Subscription, [{\n key: \"perform\",\n value: function perform(action) {\n var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n data.action = action;\n return this.send(data);\n }\n }, {\n key: \"send\",\n value: function send(data) {\n return this.consumer.send({\n command: \"message\",\n identifier: this.identifier,\n data: JSON.stringify(data)\n });\n }\n }, {\n key: \"unsubscribe\",\n value: function unsubscribe() {\n return this.consumer.subscriptions.remove(this);\n }\n }]);\n\n return Subscription;\n}();\n\nvar SubscriptionGuarantor = /*#__PURE__*/function () {\n function SubscriptionGuarantor(subscriptions) {\n _classCallCheck(this, SubscriptionGuarantor);\n\n this.subscriptions = subscriptions;\n this.pendingSubscriptions = [];\n }\n\n _createClass(SubscriptionGuarantor, [{\n key: \"guarantee\",\n value: function guarantee(subscription) {\n if (this.pendingSubscriptions.indexOf(subscription) == -1) {\n logger.log(\"SubscriptionGuarantor guaranteeing \".concat(subscription.identifier));\n this.pendingSubscriptions.push(subscription);\n } else {\n logger.log(\"SubscriptionGuarantor already guaranteeing \".concat(subscription.identifier));\n }\n\n this.startGuaranteeing();\n }\n }, {\n key: \"forget\",\n value: function forget(subscription) {\n logger.log(\"SubscriptionGuarantor forgetting \".concat(subscription.identifier));\n this.pendingSubscriptions = this.pendingSubscriptions.filter(function (s) {\n return s !== subscription;\n });\n }\n }, {\n key: \"startGuaranteeing\",\n value: function startGuaranteeing() {\n this.stopGuaranteeing();\n this.retrySubscribing();\n }\n }, {\n key: \"stopGuaranteeing\",\n value: function stopGuaranteeing() {\n clearTimeout(this.retryTimeout);\n }\n }, {\n key: \"retrySubscribing\",\n value: function retrySubscribing() {\n var _this3 = this;\n\n this.retryTimeout = setTimeout(function () {\n if (_this3.subscriptions && typeof _this3.subscriptions.subscribe === \"function\") {\n _this3.pendingSubscriptions.map(function (subscription) {\n logger.log(\"SubscriptionGuarantor resubscribing \".concat(subscription.identifier));\n\n _this3.subscriptions.subscribe(subscription);\n });\n }\n }, 500);\n }\n }]);\n\n return SubscriptionGuarantor;\n}();\n\nvar Subscriptions = /*#__PURE__*/function () {\n function Subscriptions(consumer) {\n _classCallCheck(this, Subscriptions);\n\n this.consumer = consumer;\n this.guarantor = new SubscriptionGuarantor(this);\n this.subscriptions = [];\n }\n\n _createClass(Subscriptions, [{\n key: \"create\",\n value: function create(channelName, mixin) {\n var channel = channelName;\n var params = _typeof(channel) === \"object\" ? channel : {\n channel: channel\n };\n var subscription = new Subscription(this.consumer, params, mixin);\n return this.add(subscription);\n }\n }, {\n key: \"add\",\n value: function add(subscription) {\n this.subscriptions.push(subscription);\n this.consumer.ensureActiveConnection();\n this.notify(subscription, \"initialized\");\n this.subscribe(subscription);\n return subscription;\n }\n }, {\n key: \"remove\",\n value: function remove(subscription) {\n this.forget(subscription);\n\n if (!this.findAll(subscription.identifier).length) {\n this.sendCommand(subscription, \"unsubscribe\");\n }\n\n return subscription;\n }\n }, {\n key: \"reject\",\n value: function reject(identifier) {\n var _this4 = this;\n\n return this.findAll(identifier).map(function (subscription) {\n _this4.forget(subscription);\n\n _this4.notify(subscription, \"rejected\");\n\n return subscription;\n });\n }\n }, {\n key: \"forget\",\n value: function forget(subscription) {\n this.guarantor.forget(subscription);\n this.subscriptions = this.subscriptions.filter(function (s) {\n return s !== subscription;\n });\n return subscription;\n }\n }, {\n key: \"findAll\",\n value: function findAll(identifier) {\n return this.subscriptions.filter(function (s) {\n return s.identifier === identifier;\n });\n }\n }, {\n key: \"reload\",\n value: function reload() {\n var _this5 = this;\n\n return this.subscriptions.map(function (subscription) {\n return _this5.subscribe(subscription);\n });\n }\n }, {\n key: \"notifyAll\",\n value: function notifyAll(callbackName) {\n var _this6 = this;\n\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n\n return this.subscriptions.map(function (subscription) {\n return _this6.notify.apply(_this6, [subscription, callbackName].concat(args));\n });\n }\n }, {\n key: \"notify\",\n value: function notify(subscription, callbackName) {\n for (var _len4 = arguments.length, args = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {\n args[_key4 - 2] = arguments[_key4];\n }\n\n var subscriptions;\n\n if (typeof subscription === \"string\") {\n subscriptions = this.findAll(subscription);\n } else {\n subscriptions = [subscription];\n }\n\n return subscriptions.map(function (subscription) {\n return typeof subscription[callbackName] === \"function\" ? subscription[callbackName].apply(subscription, args) : undefined;\n });\n }\n }, {\n key: \"subscribe\",\n value: function subscribe(subscription) {\n if (this.sendCommand(subscription, \"subscribe\")) {\n this.guarantor.guarantee(subscription);\n }\n }\n }, {\n key: \"confirmSubscription\",\n value: function confirmSubscription(identifier) {\n var _this7 = this;\n\n logger.log(\"Subscription confirmed \".concat(identifier));\n this.findAll(identifier).map(function (subscription) {\n return _this7.guarantor.forget(subscription);\n });\n }\n }, {\n key: \"sendCommand\",\n value: function sendCommand(subscription, command) {\n var identifier = subscription.identifier;\n return this.consumer.send({\n command: command,\n identifier: identifier\n });\n }\n }]);\n\n return Subscriptions;\n}();\n\nvar Consumer = /*#__PURE__*/function () {\n function Consumer(url) {\n _classCallCheck(this, Consumer);\n\n this._url = url;\n this.subscriptions = new Subscriptions(this);\n this.connection = new Connection(this);\n }\n\n _createClass(Consumer, [{\n key: \"url\",\n get: function get() {\n return createWebSocketURL(this._url);\n }\n }, {\n key: \"send\",\n value: function send(data) {\n return this.connection.send(data);\n }\n }, {\n key: \"connect\",\n value: function connect() {\n return this.connection.open();\n }\n }, {\n key: \"disconnect\",\n value: function disconnect() {\n return this.connection.close({\n allowReconnect: false\n });\n }\n }, {\n key: \"ensureActiveConnection\",\n value: function ensureActiveConnection() {\n if (!this.connection.isActive()) {\n return this.connection.open();\n }\n }\n }]);\n\n return Consumer;\n}();\n\nfunction createWebSocketURL(url) {\n if (typeof url === \"function\") {\n url = url();\n }\n\n if (url && !/^wss?:/i.test(url)) {\n var a = document.createElement(\"a\");\n a.href = url;\n a.href = a.href;\n a.protocol = a.protocol.replace(\"http\", \"ws\");\n return a.href;\n } else {\n return url;\n }\n}\n\nfunction createConsumer() {\n var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getConfig(\"url\") || INTERNAL.default_mount_path;\n return new Consumer(url);\n}\n\nfunction getConfig(name) {\n var element = document.head.querySelector(\"meta[name='action-cable-\".concat(name, \"']\"));\n\n if (element) {\n return element.getAttribute(\"content\");\n }\n}\n\nexport { Connection, ConnectionMonitor, Consumer, INTERNAL, Subscription, SubscriptionGuarantor, Subscriptions, adapters, createConsumer, createWebSocketURL, getConfig, logger };","// Action Cable provides the framework to deal with WebSockets in Rails.\n// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.\n\nimport { createConsumer } from \"@rails/actioncable\"\n\nexport default createConsumer()\n","// Load all the controllers within this directory and all subdirectories.\n// Controller files must be named *_controller.js.\n\nimport { Application } from \"stimulus\"\nimport { definitionsFromContext } from \"stimulus/webpack-helpers\"\nimport RevealController from 'stimulus-reveal'\nimport CableReady from 'cable_ready'\nimport consumer from '../channels/consumer'\n\nconst application = Application.start()\nconst context = require.context(\"controllers\", true, /_controller\\.js$/)\napplication.load(definitionsFromContext(context))\napplication.register('reveal', RevealController)\nCableReady.initialize({ consumer })","export function definitionsFromContext(context) {\n return context.keys().map(function (key) {\n return definitionForModuleWithContextAndKey(context, key);\n }).filter(function (value) {\n return value;\n });\n}\n\nfunction definitionForModuleWithContextAndKey(context, key) {\n var identifier = identifierForContextKey(key);\n\n if (identifier) {\n return definitionForModuleAndIdentifier(context(key), identifier);\n }\n}\n\nfunction definitionForModuleAndIdentifier(module, identifier) {\n var controllerConstructor = module[\"default\"];\n\n if (typeof controllerConstructor == \"function\") {\n return {\n identifier: identifier,\n controllerConstructor: controllerConstructor\n };\n }\n}\n\nexport function identifierForContextKey(key) {\n var logicalName = (key.match(/^(?:\\.\\/)?(.+)(?:[_-]controller\\..+?)$/) || [])[1];\n\n if (logicalName) {\n return logicalName.replace(/_/g, \"-\").replace(/\\//g, \"--\");\n }\n}","function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nimport { DirectUpload } from \"@rails/activestorage\";\nexport var AttachmentUpload = /*#__PURE__*/function () {\n function AttachmentUpload(attachment, element) {\n _classCallCheck(this, AttachmentUpload);\n\n this.attachment = attachment;\n this.element = element;\n this.directUpload = new DirectUpload(attachment.file, this.directUploadUrl, this.directUploadToken, this.attachmentName, this);\n }\n\n _createClass(AttachmentUpload, [{\n key: \"start\",\n value: function start() {\n this.directUpload.create(this.directUploadDidComplete.bind(this));\n }\n }, {\n key: \"directUploadWillStoreFileWithXHR\",\n value: function directUploadWillStoreFileWithXHR(xhr) {\n var _this = this;\n\n xhr.upload.addEventListener(\"progress\", function (event) {\n var progress = event.loaded / event.total * 100;\n\n _this.attachment.setUploadProgress(progress);\n });\n }\n }, {\n key: \"directUploadDidComplete\",\n value: function directUploadDidComplete(error, attributes) {\n if (error) {\n throw new Error(\"Direct upload failed: \".concat(error));\n }\n\n this.attachment.setAttributes({\n sgid: attributes.attachable_sgid,\n url: this.createBlobUrl(attributes.signed_id, attributes.filename)\n });\n }\n }, {\n key: \"createBlobUrl\",\n value: function createBlobUrl(signedId, filename) {\n return this.blobUrlTemplate.replace(\":signed_id\", signedId).replace(\":filename\", encodeURIComponent(filename));\n }\n }, {\n key: \"directUploadUrl\",\n get: function get() {\n return this.element.dataset.directUploadUrl;\n }\n }, {\n key: \"blobUrlTemplate\",\n get: function get() {\n return this.element.dataset.blobUrlTemplate;\n }\n }, {\n key: \"directUploadToken\",\n get: function get() {\n return this.element.getAttribute(\"data-direct-upload-token\");\n }\n }, {\n key: \"attachmentName\",\n get: function get() {\n return this.element.getAttribute(\"data-direct-upload-attachment-name\");\n }\n }]);\n\n return AttachmentUpload;\n}();","import { AttachmentUpload } from \"./attachment_upload\";\naddEventListener(\"trix-attachment-add\", function (event) {\n var attachment = event.attachment,\n target = event.target;\n\n if (attachment.file) {\n var upload = new AttachmentUpload(attachment, target);\n upload.start();\n }\n});","import baseClone from './_baseClone.js';\n/** Used to compose bitmasks for cloning. */\n\nvar CLONE_DEEP_FLAG = 1,\n CLONE_SYMBOLS_FLAG = 4;\n/**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(true);\n * }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\n\nfunction cloneDeepWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n}\n\nexport default cloneDeepWith;","import baseClone from './_baseClone.js';\n/** Used to compose bitmasks for cloning. */\n\nvar CLONE_SYMBOLS_FLAG = 4;\n/**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\n\nfunction clone(value) {\n return baseClone(value, CLONE_SYMBOLS_FLAG);\n}\n\nexport default clone;"],"sourceRoot":""}