{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/model/differ.js"],"names":["Differ","markerCollection","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_13__","this","_markerCollection","_changesInElement","Map","_elementSnapshots","_changedMarkers","_changeCount","_cachedChanges","_cachedChangesWithGraveyard","size","item","_isInInsertedElement","parent","_markRemove","startOffset","offsetSize","_markInsert","_step","range","Range","_createOn","_iterator","_createForOfIteratorHelper","getMarkersIntersectingRange","s","n","done","marker","value","markerRange","getRange","bufferMarkerChange","name","affectsData","err","e","f","operation","type","position","offset","nodes","maxOffset","_step2","_iterator2","getItems","shallow","_markAttribute","sourcePosition","isEqual","targetPosition","getShiftedBy","howMany","sourceParentInserted","targetParentInserted","getMovedRangeStart","_step3","_createFromPositionAndShift","_iterator3","splitElement","splitPosition","insertionPosition","graveyardPosition","mergedElement","graveyardParent","mergedIntoElement","markerName","oldRange","newRange","buffered","get","delete","set","_step4","result","_iterator4","_step4$value","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_slicedToArray_js__WEBPACK_IMPORTED_MODULE_8__","change","push","_step5","_iterator5","_step5$value","Array","from","map","data","_step6","_iterator6","_step6$value","options","arguments","length","undefined","includeChangesInGraveyard","slice","_step7","diffSet","_iterator7","keys","_step9","element","changes","sort","a","b","snapshotChildren","elementChildren","_getChildrenSnapshot","getChildren","actions","_generateActionsFromChanges","i","j","_iterator9","action","_getInsertDiff","_getRemoveDiff","_diffSet","elementAttributes","attributes","snapshotAttributes","Position","_createAt","index","offsetToIndex","getChild","apply","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_toConsumableArray_js__WEBPACK_IMPORTED_MODULE_5__","_getAttributesDiff","root","rootName","changeCount","isBefore","prevIndex","prevDiff","thisDiff","isConsecutiveTextRemove","isConsecutiveTextAdd","isConsecutiveAttributeChange","isFlat","attributeKey","attributeOldValue","attributeNewValue","end","filter","v","_step8","_iterator8","_changesInGraveyardFilter","clear","changeItem","count","_markChange","_removeAllNestedChanges","_makeSnapshot","_getChangesForElement","_handleChange","splice","has","inc","nodesToHandle","_step10","_iterator10","old","incEnd","oldEnd","unshift","intersectionLength","howManyAfter","attributePart","oldAttributes","newAttributes","diffs","_step11","_iterator11","_step11$value","key","oldValue","newValue","start","clone","_step12","_iterator12","_step12$value","_step13","_iterator13","_step14","_iterator14","is","children","_step15","snapshot","_iterator15","child","getAttributes","oldChildrenLength","_step16","oldChildrenHandled","_iterator16","repeat","split","entry","posInGy","rangeInGy"],"mappings":"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","file":"js/chunk-2d0c8d6b.0872632a.js","sourcesContent":["/**\n * @license Copyright (c) 2003-2021, 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 engine/model/differ\n */\n\nimport Position from './position';\nimport Range from './range';\n\n/**\n * Calculates the difference between two model states.\n *\n * Receives operations that are to be applied on the model document. Marks parts of the model document tree which\n * are changed and saves the state of these elements before the change. Then, it compares saved elements with the\n * changed elements, after all changes are applied on the model document. Calculates the diff between saved\n * elements and new ones and returns a change set.\n */\nexport default class Differ {\n\t/**\n\t * Creates a `Differ` instance.\n\t *\n\t * @param {module:engine/model/markercollection~MarkerCollection} markerCollection Model's marker collection.\n\t */\n\tconstructor( markerCollection ) {\n\t\t/**\n\t\t * Reference to the model's marker collection.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/markercollection~MarkerCollection}\n\t\t */\n\t\tthis._markerCollection = markerCollection;\n\n\t\t/**\n\t\t * A map that stores changes that happened in a given element.\n\t\t *\n\t\t * The keys of the map are references to the model elements.\n\t\t * The values of the map are arrays with changes that were done on this element.\n\t\t *\n\t\t * @private\n\t\t * @type {Map}\n\t\t */\n\t\tthis._changesInElement = new Map();\n\n\t\t/**\n\t\t * A map that stores \"element's children snapshots\". A snapshot is representing children of a given element before\n\t\t * the first change was applied on that element. Snapshot items are objects with two properties: `name`,\n\t\t * containing the element name (or `'$text'` for a text node) and `attributes` which is a map of the node's attributes.\n\t\t *\n\t\t * @private\n\t\t * @type {Map}\n\t\t */\n\t\tthis._elementSnapshots = new Map();\n\n\t\t/**\n\t\t * A map that stores all changed markers.\n\t\t *\n\t\t * The keys of the map are marker names.\n\t\t * The values of the map are objects with the `oldRange` and `newRange` properties. They store the marker range\n\t\t * state before and after the change.\n\t\t *\n\t\t * @private\n\t\t * @type {Map}\n\t\t */\n\t\tthis._changedMarkers = new Map();\n\n\t\t/**\n\t\t * Stores the number of changes that were processed. Used to order the changes chronologically. It is important\n\t\t * when changes are sorted.\n\t\t *\n\t\t * @private\n\t\t * @type {Number}\n\t\t */\n\t\tthis._changeCount = 0;\n\n\t\t/**\n\t\t * For efficiency purposes, `Differ` stores the change set returned by the differ after {@link #getChanges} call.\n\t\t * Cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t\t * return the cached value instead of calculating it again.\n\t\t *\n\t\t * This property stores those changes that did not take place in graveyard root.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.|null}\n\t\t */\n\t\tthis._cachedChanges = null;\n\n\t\t/**\n\t\t * For efficiency purposes, `Differ` stores the change set returned by the differ after the {@link #getChanges} call.\n\t\t * The cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t\t * return the cached value instead of calculating it again.\n\t\t *\n\t\t * This property stores all changes evaluated by `Differ`, including those that took place in the graveyard.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.|null}\n\t\t */\n\t\tthis._cachedChangesWithGraveyard = null;\n\t}\n\n\t/**\n\t * Informs whether there are any changes buffered in `Differ`.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tget isEmpty() {\n\t\treturn this._changesInElement.size == 0 && this._changedMarkers.size == 0;\n\t}\n\n\t/**\n\t * Marks given `item` in differ to be \"refreshed\". It means that the item will be marked as removed and inserted in the differ changes\n\t * set, so it will be effectively re-converted when differ changes will be handled by a dispatcher.\n\t *\n\t * @param {module:engine/model/item~Item} item Item to refresh.\n\t */\n\trefreshItem( item ) {\n\t\tif ( this._isInInsertedElement( item.parent ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._markRemove( item.parent, item.startOffset, item.offsetSize );\n\t\tthis._markInsert( item.parent, item.startOffset, item.offsetSize );\n\n\t\tconst range = Range._createOn( item );\n\n\t\tfor ( const marker of this._markerCollection.getMarkersIntersectingRange( range ) ) {\n\t\t\tconst markerRange = marker.getRange();\n\n\t\t\tthis.bufferMarkerChange( marker.name, markerRange, markerRange, marker.affectsData );\n\t\t}\n\n\t\t// Clear cache after each buffered operation as it is no longer valid.\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Buffers the given operation. An operation has to be buffered before it is executed.\n\t *\n\t * Operation type is checked and it is checked which nodes it will affect. These nodes are then stored in `Differ`\n\t * in the state before the operation is executed.\n\t *\n\t * @param {module:engine/model/operation/operation~Operation} operation An operation to buffer.\n\t */\n\tbufferOperation( operation ) {\n\t\t// Below we take an operation, check its type, then use its parameters in marking (private) methods.\n\t\t// The general rule is to not mark elements inside inserted element. All inserted elements are re-rendered.\n\t\t// Marking changes in them would cause a \"double\" changing then.\n\t\t//\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert': {\n\t\t\t\tif ( this._isInInsertedElement( operation.position.parent ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._markInsert( operation.position.parent, operation.position.offset, operation.nodes.maxOffset );\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'addAttribute':\n\t\t\tcase 'removeAttribute':\n\t\t\tcase 'changeAttribute': {\n\t\t\t\tfor ( const item of operation.range.getItems( { shallow: true } ) ) {\n\t\t\t\t\tif ( this._isInInsertedElement( item.parent ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._markAttribute( item );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'remove':\n\t\t\tcase 'move':\n\t\t\tcase 'reinsert': {\n\t\t\t\t// When range is moved to the same position then not mark it as a change.\n\t\t\t\t// See: https://github.com/ckeditor/ckeditor5-engine/issues/1664.\n\t\t\t\tif (\n\t\t\t\t\toperation.sourcePosition.isEqual( operation.targetPosition ) ||\n\t\t\t\t\toperation.sourcePosition.getShiftedBy( operation.howMany ).isEqual( operation.targetPosition )\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst sourceParentInserted = this._isInInsertedElement( operation.sourcePosition.parent );\n\t\t\t\tconst targetParentInserted = this._isInInsertedElement( operation.targetPosition.parent );\n\n\t\t\t\tif ( !sourceParentInserted ) {\n\t\t\t\t\tthis._markRemove( operation.sourcePosition.parent, operation.sourcePosition.offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\tif ( !targetParentInserted ) {\n\t\t\t\t\tthis._markInsert( operation.targetPosition.parent, operation.getMovedRangeStart().offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'rename': {\n\t\t\t\tif ( this._isInInsertedElement( operation.position.parent ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._markRemove( operation.position.parent, operation.position.offset, 1 );\n\t\t\t\tthis._markInsert( operation.position.parent, operation.position.offset, 1 );\n\n\t\t\t\tconst range = Range._createFromPositionAndShift( operation.position, 1 );\n\n\t\t\t\tfor ( const marker of this._markerCollection.getMarkersIntersectingRange( range ) ) {\n\t\t\t\t\tconst markerRange = marker.getRange();\n\n\t\t\t\t\tthis.bufferMarkerChange( marker.name, markerRange, markerRange, marker.affectsData );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'split': {\n\t\t\t\tconst splitElement = operation.splitPosition.parent;\n\n\t\t\t\t// Mark that children of the split element were removed.\n\t\t\t\tif ( !this._isInInsertedElement( splitElement ) ) {\n\t\t\t\t\tthis._markRemove( splitElement, operation.splitPosition.offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\t// Mark that the new element (split copy) was inserted.\n\t\t\t\tif ( !this._isInInsertedElement( operation.insertionPosition.parent ) ) {\n\t\t\t\t\tthis._markInsert( operation.insertionPosition.parent, operation.insertionPosition.offset, 1 );\n\t\t\t\t}\n\n\t\t\t\t// If the split took the element from the graveyard, mark that the element from the graveyard was removed.\n\t\t\t\tif ( operation.graveyardPosition ) {\n\t\t\t\t\tthis._markRemove( operation.graveyardPosition.parent, operation.graveyardPosition.offset, 1 );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'merge': {\n\t\t\t\t// Mark that the merged element was removed.\n\t\t\t\tconst mergedElement = operation.sourcePosition.parent;\n\n\t\t\t\tif ( !this._isInInsertedElement( mergedElement.parent ) ) {\n\t\t\t\t\tthis._markRemove( mergedElement.parent, mergedElement.startOffset, 1 );\n\t\t\t\t}\n\n\t\t\t\t// Mark that the merged element was inserted into graveyard.\n\t\t\t\tconst graveyardParent = operation.graveyardPosition.parent;\n\n\t\t\t\tthis._markInsert( graveyardParent, operation.graveyardPosition.offset, 1 );\n\n\t\t\t\t// Mark that children of merged element were inserted at new parent.\n\t\t\t\tconst mergedIntoElement = operation.targetPosition.parent;\n\n\t\t\t\tif ( !this._isInInsertedElement( mergedIntoElement ) ) {\n\t\t\t\t\tthis._markInsert( mergedIntoElement, operation.targetPosition.offset, mergedElement.maxOffset );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Clear cache after each buffered operation as it is no longer valid.\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Buffers a marker change.\n\t *\n\t * @param {String} markerName The name of the marker that changed.\n\t * @param {module:engine/model/range~Range|null} oldRange Marker range before the change or `null` if the marker has just\n\t * been created.\n\t * @param {module:engine/model/range~Range|null} newRange Marker range after the change or `null` if the marker was removed.\n\t * @param {Boolean} affectsData Flag indicating whether marker affects the editor data.\n\t */\n\tbufferMarkerChange( markerName, oldRange, newRange, affectsData ) {\n\t\tconst buffered = this._changedMarkers.get( markerName );\n\n\t\tif ( !buffered ) {\n\t\t\tthis._changedMarkers.set( markerName, {\n\t\t\t\toldRange,\n\t\t\t\tnewRange,\n\t\t\t\taffectsData\n\t\t\t} );\n\t\t} else {\n\t\t\tbuffered.newRange = newRange;\n\t\t\tbuffered.affectsData = affectsData;\n\n\t\t\tif ( buffered.oldRange == null && buffered.newRange == null ) {\n\t\t\t\t// The marker is going to be removed (`newRange == null`) but it did not exist before the first buffered change\n\t\t\t\t// (`buffered.oldRange == null`). In this case, do not keep the marker in buffer at all.\n\t\t\t\tthis._changedMarkers.delete( markerName );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns all markers that should be removed as a result of buffered changes.\n\t *\n\t * @returns {Array.} Markers to remove. Each array item is an object containing the `name` and `range` properties.\n\t */\n\tgetMarkersToRemove() {\n\t\tconst result = [];\n\n\t\tfor ( const [ name, change ] of this._changedMarkers ) {\n\t\t\tif ( change.oldRange != null ) {\n\t\t\t\tresult.push( { name, range: change.oldRange } );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns all markers which should be added as a result of buffered changes.\n\t *\n\t * @returns {Array.} Markers to add. Each array item is an object containing the `name` and `range` properties.\n\t */\n\tgetMarkersToAdd() {\n\t\tconst result = [];\n\n\t\tfor ( const [ name, change ] of this._changedMarkers ) {\n\t\t\tif ( change.newRange != null ) {\n\t\t\t\tresult.push( { name, range: change.newRange } );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns all markers which changed.\n\t *\n\t * @returns {Array.}\n\t */\n\tgetChangedMarkers() {\n\t\treturn Array.from( this._changedMarkers ).map( item => (\n\t\t\t{\n\t\t\t\tname: item[ 0 ],\n\t\t\t\tdata: {\n\t\t\t\t\toldRange: item[ 1 ].oldRange,\n\t\t\t\t\tnewRange: item[ 1 ].newRange\n\t\t\t\t}\n\t\t\t}\n\t\t) );\n\t}\n\n\t/**\n\t * Checks whether some of the buffered changes affect the editor data.\n\t *\n\t * Types of changes which affect the editor data:\n\t *\n\t * * model structure changes,\n\t * * attribute changes,\n\t * * changes of markers which were defined as `affectingData`.\n\t *\n\t * @returns {Boolean}\n\t */\n\thasDataChanges() {\n\t\tfor ( const [ , change ] of this._changedMarkers ) {\n\t\t\tif ( change.affectsData ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// If markers do not affect the data, check whether there are some changes in elements.\n\t\treturn this._changesInElement.size > 0;\n\t}\n\n\t/**\n\t * Calculates the diff between the old model tree state (the state before the first buffered operations since the last {@link #reset}\n\t * call) and the new model tree state (actual one). It should be called after all buffered operations are executed.\n\t *\n\t * The diff set is returned as an array of {@link module:engine/model/differ~DiffItem diff items}, each describing a change done\n\t * on the model. The items are sorted by the position on which the change happened. If a position\n\t * {@link module:engine/model/position~Position#isBefore is before} another one, it will be on an earlier index in the diff set.\n\t *\n\t * **Note**: Elements inside inserted element will not have a separate diff item, only the top most element change will be reported.\n\t *\n\t * Because calculating the diff is a costly operation, the result is cached. If no new operation was buffered since the\n\t * previous {@link #getChanges} call, the next call will return the cached value.\n\t *\n\t * @param {Object} options Additional options.\n\t * @param {Boolean} [options.includeChangesInGraveyard=false] If set to `true`, also changes that happened\n\t * in the graveyard root will be returned. By default, changes in the graveyard root are not returned.\n\t * @returns {Array.} Diff between the old and the new model tree state.\n\t */\n\tgetChanges( options = { includeChangesInGraveyard: false } ) {\n\t\t// If there are cached changes, just return them instead of calculating changes again.\n\t\tif ( this._cachedChanges ) {\n\t\t\tif ( options.includeChangesInGraveyard ) {\n\t\t\t\treturn this._cachedChangesWithGraveyard.slice();\n\t\t\t} else {\n\t\t\t\treturn this._cachedChanges.slice();\n\t\t\t}\n\t\t}\n\n\t\t// Will contain returned results.\n\t\tlet diffSet = [];\n\n\t\t// Check all changed elements.\n\t\tfor ( const element of this._changesInElement.keys() ) {\n\t\t\t// Get changes for this element and sort them.\n\t\t\tconst changes = this._changesInElement.get( element ).sort( ( a, b ) => {\n\t\t\t\tif ( a.offset === b.offset ) {\n\t\t\t\t\tif ( a.type != b.type ) {\n\t\t\t\t\t\t// If there are multiple changes at the same position, \"remove\" change should be first.\n\t\t\t\t\t\t// If the order is different, for example, we would first add some nodes and then removed them\n\t\t\t\t\t\t// (instead of the nodes that we should remove).\n\t\t\t\t\t\treturn a.type == 'remove' ? -1 : 1;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn a.offset < b.offset ? -1 : 1;\n\t\t\t} );\n\n\t\t\t// Get children of this element before any change was applied on it.\n\t\t\tconst snapshotChildren = this._elementSnapshots.get( element );\n\t\t\t// Get snapshot of current element's children.\n\t\t\tconst elementChildren = _getChildrenSnapshot( element.getChildren() );\n\n\t\t\t// Generate actions basing on changes done on element.\n\t\t\tconst actions = _generateActionsFromChanges( snapshotChildren.length, changes );\n\n\t\t\tlet i = 0; // Iterator in `elementChildren` array -- iterates through current children of element.\n\t\t\tlet j = 0; // Iterator in `snapshotChildren` array -- iterates through old children of element.\n\n\t\t\t// Process every action.\n\t\t\tfor ( const action of actions ) {\n\t\t\t\tif ( action === 'i' ) {\n\t\t\t\t\t// Generate diff item for this element and insert it into the diff set.\n\t\t\t\t\tdiffSet.push( this._getInsertDiff( element, i, elementChildren[ i ].name ) );\n\n\t\t\t\t\ti++;\n\t\t\t\t} else if ( action === 'r' ) {\n\t\t\t\t\t// Generate diff item for this element and insert it into the diff set.\n\t\t\t\t\tdiffSet.push( this._getRemoveDiff( element, i, snapshotChildren[ j ].name ) );\n\n\t\t\t\t\tj++;\n\t\t\t\t} else if ( action === 'a' ) {\n\t\t\t\t\t// Take attributes from saved and current children.\n\t\t\t\t\tconst elementAttributes = elementChildren[ i ].attributes;\n\t\t\t\t\tconst snapshotAttributes = snapshotChildren[ j ].attributes;\n\t\t\t\t\tlet range;\n\n\t\t\t\t\tif ( elementChildren[ i ].name == '$text' ) {\n\t\t\t\t\t\trange = new Range( Position._createAt( element, i ), Position._createAt( element, i + 1 ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst index = element.offsetToIndex( i );\n\t\t\t\t\t\trange = new Range( Position._createAt( element, i ), Position._createAt( element.getChild( index ), 0 ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Generate diff items for this change (there might be multiple attributes changed and\n\t\t\t\t\t// there is a single diff for each of them) and insert them into the diff set.\n\t\t\t\t\tdiffSet.push( ...this._getAttributesDiff( range, snapshotAttributes, elementAttributes ) );\n\n\t\t\t\t\ti++;\n\t\t\t\t\tj++;\n\t\t\t\t} else {\n\t\t\t\t\t// `action` is 'equal'. Child not changed.\n\t\t\t\t\ti++;\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Then, sort the changes by the position (change at position before other changes is first).\n\t\tdiffSet.sort( ( a, b ) => {\n\t\t\t// If the change is in different root, we don't care much, but we'd like to have all changes in given\n\t\t\t// root \"together\" in the array. So let's just sort them by the root name. It does not matter which root\n\t\t\t// will be processed first.\n\t\t\tif ( a.position.root != b.position.root ) {\n\t\t\t\treturn a.position.root.rootName < b.position.root.rootName ? -1 : 1;\n\t\t\t}\n\n\t\t\t// If change happens at the same position...\n\t\t\tif ( a.position.isEqual( b.position ) ) {\n\t\t\t\t// Keep chronological order of operations.\n\t\t\t\treturn a.changeCount - b.changeCount;\n\t\t\t}\n\n\t\t\t// If positions differ, position \"on the left\" should be earlier in the result.\n\t\t\treturn a.position.isBefore( b.position ) ? -1 : 1;\n\t\t} );\n\n\t\t// Glue together multiple changes (mostly on text nodes).\n\t\tfor ( let i = 1, prevIndex = 0; i < diffSet.length; i++ ) {\n\t\t\tconst prevDiff = diffSet[ prevIndex ];\n\t\t\tconst thisDiff = diffSet[ i ];\n\n\t\t\t// Glue remove changes if they happen on text on same position.\n\t\t\tconst isConsecutiveTextRemove =\n\t\t\t\tprevDiff.type == 'remove' && thisDiff.type == 'remove' &&\n\t\t\t\tprevDiff.name == '$text' && thisDiff.name == '$text' &&\n\t\t\t\tprevDiff.position.isEqual( thisDiff.position );\n\n\t\t\t// Glue insert changes if they happen on text on consecutive fragments.\n\t\t\tconst isConsecutiveTextAdd =\n\t\t\t\tprevDiff.type == 'insert' && thisDiff.type == 'insert' &&\n\t\t\t\tprevDiff.name == '$text' && thisDiff.name == '$text' &&\n\t\t\t\tprevDiff.position.parent == thisDiff.position.parent &&\n\t\t\t\tprevDiff.position.offset + prevDiff.length == thisDiff.position.offset;\n\n\t\t\t// Glue attribute changes if they happen on consecutive fragments and have same key, old value and new value.\n\t\t\tconst isConsecutiveAttributeChange =\n\t\t\t\tprevDiff.type == 'attribute' && thisDiff.type == 'attribute' &&\n\t\t\t\tprevDiff.position.parent == thisDiff.position.parent &&\n\t\t\t\tprevDiff.range.isFlat && thisDiff.range.isFlat &&\n\t\t\t\tprevDiff.position.offset + prevDiff.length == thisDiff.position.offset &&\n\t\t\t\tprevDiff.attributeKey == thisDiff.attributeKey &&\n\t\t\t\tprevDiff.attributeOldValue == thisDiff.attributeOldValue &&\n\t\t\t\tprevDiff.attributeNewValue == thisDiff.attributeNewValue;\n\n\t\t\tif ( isConsecutiveTextRemove || isConsecutiveTextAdd || isConsecutiveAttributeChange ) {\n\t\t\t\tprevDiff.length++;\n\n\t\t\t\tif ( isConsecutiveAttributeChange ) {\n\t\t\t\t\tprevDiff.range.end = prevDiff.range.end.getShiftedBy( 1 );\n\t\t\t\t}\n\n\t\t\t\tdiffSet[ i ] = null;\n\t\t\t} else {\n\t\t\t\tprevIndex = i;\n\t\t\t}\n\t\t}\n\n\t\tdiffSet = diffSet.filter( v => v );\n\n\t\t// Remove `changeCount` property from diff items. It is used only for sorting and is internal thing.\n\t\tfor ( const item of diffSet ) {\n\t\t\tdelete item.changeCount;\n\n\t\t\tif ( item.type == 'attribute' ) {\n\t\t\t\tdelete item.position;\n\t\t\t\tdelete item.length;\n\t\t\t}\n\t\t}\n\n\t\tthis._changeCount = 0;\n\n\t\t// Cache changes.\n\t\tthis._cachedChangesWithGraveyard = diffSet.slice();\n\t\tthis._cachedChanges = diffSet.filter( _changesInGraveyardFilter );\n\n\t\tif ( options.includeChangesInGraveyard ) {\n\t\t\treturn this._cachedChangesWithGraveyard;\n\t\t} else {\n\t\t\treturn this._cachedChanges;\n\t\t}\n\t}\n\n\t/**\n\t * Resets `Differ`. Removes all buffered changes.\n\t */\n\treset() {\n\t\tthis._changesInElement.clear();\n\t\tthis._elementSnapshots.clear();\n\t\tthis._changedMarkers.clear();\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Saves and handles an insert change.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @param {Number} howMany\n\t */\n\t_markInsert( parent, offset, howMany ) {\n\t\tconst changeItem = { type: 'insert', offset, howMany, count: this._changeCount++ };\n\n\t\tthis._markChange( parent, changeItem );\n\t}\n\n\t/**\n\t * Saves and handles a remove change.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @param {Number} howMany\n\t */\n\t_markRemove( parent, offset, howMany ) {\n\t\tconst changeItem = { type: 'remove', offset, howMany, count: this._changeCount++ };\n\n\t\tthis._markChange( parent, changeItem );\n\n\t\tthis._removeAllNestedChanges( parent, offset, howMany );\n\t}\n\n\t/**\n\t * Saves and handles an attribute change.\n\t *\n\t * @private\n\t * @param {module:engine/model/item~Item} item\n\t */\n\t_markAttribute( item ) {\n\t\tconst changeItem = { type: 'attribute', offset: item.startOffset, howMany: item.offsetSize, count: this._changeCount++ };\n\n\t\tthis._markChange( item.parent, changeItem );\n\t}\n\n\t/**\n\t * Saves and handles a model change.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Object} changeItem\n\t */\n\t_markChange( parent, changeItem ) {\n\t\t// First, make a snapshot of this parent's children (it will be made only if it was not made before).\n\t\tthis._makeSnapshot( parent );\n\n\t\t// Then, get all changes that already were done on the element (empty array if this is the first change).\n\t\tconst changes = this._getChangesForElement( parent );\n\n\t\t// Then, look through all the changes, and transform them or the new change.\n\t\tthis._handleChange( changeItem, changes );\n\n\t\t// Add the new change.\n\t\tchanges.push( changeItem );\n\n\t\t// Remove incorrect changes. During transformation some change might be, for example, included in another.\n\t\t// In that case, the change will have `howMany` property set to `0` or less. We need to remove those changes.\n\t\tfor ( let i = 0; i < changes.length; i++ ) {\n\t\t\tif ( changes[ i ].howMany < 1 ) {\n\t\t\t\tchanges.splice( i, 1 );\n\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets an array of changes that have already been saved for a given element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element\n\t * @returns {Array.}\n\t */\n\t_getChangesForElement( element ) {\n\t\tlet changes;\n\n\t\tif ( this._changesInElement.has( element ) ) {\n\t\t\tchanges = this._changesInElement.get( element );\n\t\t} else {\n\t\t\tchanges = [];\n\n\t\t\tthis._changesInElement.set( element, changes );\n\t\t}\n\n\t\treturn changes;\n\t}\n\n\t/**\n\t * Saves a children snapshot for a given element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element\n\t */\n\t_makeSnapshot( element ) {\n\t\tif ( !this._elementSnapshots.has( element ) ) {\n\t\t\tthis._elementSnapshots.set( element, _getChildrenSnapshot( element.getChildren() ) );\n\t\t}\n\t}\n\n\t/**\n\t * For a given newly saved change, compares it with a change already done on the element and modifies the incoming\n\t * change and/or the old change.\n\t *\n\t * @private\n\t * @param {Object} inc Incoming (new) change.\n\t * @param {Array.} changes An array containing all the changes done on that element.\n\t */\n\t_handleChange( inc, changes ) {\n\t\t// We need a helper variable that will store how many nodes are to be still handled for this change item.\n\t\t// `nodesToHandle` (how many nodes still need to be handled) and `howMany` (how many nodes were affected)\n\t\t// needs to be differentiated.\n\t\t//\n\t\t// This comes up when there are multiple changes that are affected by `inc` change item.\n\t\t//\n\t\t// For example: assume two insert changes: `{ offset: 2, howMany: 1 }` and `{ offset: 5, howMany: 1 }`.\n\t\t// Assume that `inc` change is remove `{ offset: 2, howMany: 2, nodesToHandle: 2 }`.\n\t\t//\n\t\t// Then, we:\n\t\t// - \"forget\" about first insert change (it is \"eaten\" by remove),\n\t\t// - because of that, at the end we will want to remove only one node (`nodesToHandle = 1`),\n\t\t// - but still we have to change offset of the second insert change from `5` to `3`!\n\t\t//\n\t\t// So, `howMany` does not change throughout items transformation and keeps information about how many nodes were affected,\n\t\t// while `nodesToHandle` means how many nodes need to be handled after the change item is transformed by other changes.\n\t\tinc.nodesToHandle = inc.howMany;\n\n\t\tfor ( const old of changes ) {\n\t\t\tconst incEnd = inc.offset + inc.howMany;\n\t\t\tconst oldEnd = old.offset + old.howMany;\n\n\t\t\tif ( inc.type == 'insert' ) {\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\told.howMany += inc.nodesToHandle;\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\tif ( inc.offset < old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\t// This case is more complicated, because attribute change has to be split into two.\n\t\t\t\t\t\t// Example (assume that uppercase and lowercase letters mean different attributes):\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// initial state:\t\tabcxyz\n\t\t\t\t\t\t// attribute change:\taBCXYz\n\t\t\t\t\t\t// incoming insert:\t\taBCfooXYz\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Change ranges cannot intersect because each item has to be described exactly (it was either\n\t\t\t\t\t\t// not changed, inserted, removed, or its attribute was changed). That's why old attribute\n\t\t\t\t\t\t// change has to be split and both parts has to be handled separately from now on.\n\t\t\t\t\t\tconst howMany = old.howMany;\n\n\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\n\t\t\t\t\t\t// Add the second part of attribute change to the beginning of processed array so it won't\n\t\t\t\t\t\t// be processed again in this loop.\n\t\t\t\t\t\tchanges.unshift( {\n\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\toffset: incEnd,\n\t\t\t\t\t\t\thowMany: howMany - old.howMany,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( inc.type == 'remove' ) {\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( incEnd <= oldEnd ) {\n\t\t\t\t\t\tif ( inc.offset < old.offset ) {\n\t\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\n\t\t\t\t\t\t\told.offset = inc.offset;\n\n\t\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\told.howMany -= inc.nodesToHandle;\n\t\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\t\tinc.nodesToHandle -= old.howMany;\n\t\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\t\tconst intersectionLength = oldEnd - inc.offset;\n\n\t\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < old.offset ) {\n\t\t\t\t\t\tinc.nodesToHandle += old.howMany;\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < old.offset ) {\n\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\n\t\t\t\t\t\told.offset = inc.offset;\n\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\tif ( incEnd <= oldEnd ) {\n\t\t\t\t\t\t\t// On first sight in this case we don't need to split attribute operation into two.\n\t\t\t\t\t\t\t// However the changes set is later converted to actions (see `_generateActionsFromChanges`).\n\t\t\t\t\t\t\t// For that reason, no two changes may intersect.\n\t\t\t\t\t\t\t// So we cannot have an attribute change that \"contains\" remove change.\n\t\t\t\t\t\t\t// Attribute change needs to be split.\n\t\t\t\t\t\t\tconst howMany = old.howMany;\n\n\t\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\n\t\t\t\t\t\t\tconst howManyAfter = howMany - old.howMany - inc.nodesToHandle;\n\n\t\t\t\t\t\t\t// Add the second part of attribute change to the beginning of processed array so it won't\n\t\t\t\t\t\t\t// be processed again in this loop.\n\t\t\t\t\t\t\tchanges.unshift( {\n\t\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\t\toffset: inc.offset,\n\t\t\t\t\t\t\t\thowMany: howManyAfter,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\told.howMany -= oldEnd - inc.offset;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( inc.type == 'attribute' ) {\n\t\t\t\t// In case of attribute change, `howMany` should be kept same as `nodesToHandle`. It's not an error.\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( inc.offset < old.offset && incEnd > old.offset ) {\n\t\t\t\t\t\tif ( incEnd > oldEnd ) {\n\t\t\t\t\t\t\t// This case is similar to a case described when incoming change was insert and old change was attribute.\n\t\t\t\t\t\t\t// See comment above.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// This time incoming change is attribute. We need to split incoming change in this case too.\n\t\t\t\t\t\t\t// However this time, the second part of the attribute change needs to be processed further\n\t\t\t\t\t\t\t// because there might be other changes that it collides with.\n\t\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\t\toffset: oldEnd,\n\t\t\t\t\t\t\t\thowMany: incEnd - oldEnd,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tthis._handleChange( attributePart, changes );\n\n\t\t\t\t\t\t\tchanges.push( attributePart );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t} else if ( inc.offset >= old.offset && inc.offset < oldEnd ) {\n\t\t\t\t\t\tif ( incEnd > oldEnd ) {\n\t\t\t\t\t\t\tinc.nodesToHandle = incEnd - oldEnd;\n\t\t\t\t\t\t\tinc.offset = oldEnd;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\t// This is a case when attribute change \"contains\" remove change.\n\t\t\t\t\t// The attribute change needs to be split into two because changes cannot intersect.\n\t\t\t\t\tif ( inc.offset < old.offset && incEnd > old.offset ) {\n\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\toffset: old.offset,\n\t\t\t\t\t\t\thowMany: incEnd - old.offset,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tthis._handleChange( attributePart, changes );\n\n\t\t\t\t\t\tchanges.push( attributePart );\n\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\t// There are only two conflicting scenarios possible here:\n\t\t\t\t\tif ( inc.offset >= old.offset && incEnd <= oldEnd ) {\n\t\t\t\t\t\t// `old` change includes `inc` change, or they are the same.\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\tinc.howMany = 0;\n\t\t\t\t\t\tinc.offset = 0;\n\t\t\t\t\t} else if ( inc.offset <= old.offset && incEnd >= oldEnd ) {\n\t\t\t\t\t\t// `inc` change includes `old` change.\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinc.howMany = inc.nodesToHandle;\n\t\tdelete inc.nodesToHandle;\n\t}\n\n\t/**\n\t * Returns an object with a single insert change description.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent The element in which the change happened.\n\t * @param {Number} offset The offset at which change happened.\n\t * @param {String} name The name of the removed element or `'$text'` for a character.\n\t * @returns {Object} The diff item.\n\t */\n\t_getInsertDiff( parent, offset, name ) {\n\t\treturn {\n\t\t\ttype: 'insert',\n\t\t\tposition: Position._createAt( parent, offset ),\n\t\t\tname,\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++\n\t\t};\n\t}\n\n\t/**\n\t * Returns an object with a single remove change description.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent The element in which change happened.\n\t * @param {Number} offset The offset at which change happened.\n\t * @param {String} name The name of the removed element or `'$text'` for a character.\n\t * @returns {Object} The diff item.\n\t */\n\t_getRemoveDiff( parent, offset, name ) {\n\t\treturn {\n\t\t\ttype: 'remove',\n\t\t\tposition: Position._createAt( parent, offset ),\n\t\t\tname,\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++\n\t\t};\n\t}\n\n\t/**\n\t * Returns an array of objects where each one is a single attribute change description.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range The range where the change happened.\n\t * @param {Map} oldAttributes A map, map iterator or compatible object that contains attributes before the change.\n\t * @param {Map} newAttributes A map, map iterator or compatible object that contains attributes after the change.\n\t * @returns {Array.} An array containing one or more diff items.\n\t */\n\t_getAttributesDiff( range, oldAttributes, newAttributes ) {\n\t\t// Results holder.\n\t\tconst diffs = [];\n\n\t\t// Clone new attributes as we will be performing changes on this object.\n\t\tnewAttributes = new Map( newAttributes );\n\n\t\t// Look through old attributes.\n\t\tfor ( const [ key, oldValue ] of oldAttributes ) {\n\t\t\t// Check what is the new value of the attribute (or if it was removed).\n\t\t\tconst newValue = newAttributes.has( key ) ? newAttributes.get( key ) : null;\n\n\t\t\t// If values are different (or attribute was removed)...\n\t\t\tif ( newValue !== oldValue ) {\n\t\t\t\t// Add diff item.\n\t\t\t\tdiffs.push( {\n\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\tposition: range.start,\n\t\t\t\t\trange: range.clone(),\n\t\t\t\t\tlength: 1,\n\t\t\t\t\tattributeKey: key,\n\t\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\t\tattributeNewValue: newValue,\n\t\t\t\t\tchangeCount: this._changeCount++\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Prevent returning two diff items for the same change.\n\t\t\tnewAttributes.delete( key );\n\t\t}\n\n\t\t// Look through new attributes that weren't handled above.\n\t\tfor ( const [ key, newValue ] of newAttributes ) {\n\t\t\t// Each of them is a new attribute. Add diff item.\n\t\t\tdiffs.push( {\n\t\t\t\ttype: 'attribute',\n\t\t\t\tposition: range.start,\n\t\t\t\trange: range.clone(),\n\t\t\t\tlength: 1,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: null,\n\t\t\t\tattributeNewValue: newValue,\n\t\t\t\tchangeCount: this._changeCount++\n\t\t\t} );\n\t\t}\n\n\t\treturn diffs;\n\t}\n\n\t/**\n\t * Checks whether given element or any of its parents is an element that is buffered as an inserted element.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} element Element to check.\n\t * @returns {Boolean}\n\t */\n\t_isInInsertedElement( element ) {\n\t\tconst parent = element.parent;\n\n\t\tif ( !parent ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst changes = this._changesInElement.get( parent );\n\t\tconst offset = element.startOffset;\n\n\t\tif ( changes ) {\n\t\t\tfor ( const change of changes ) {\n\t\t\t\tif ( change.type == 'insert' && offset >= change.offset && offset < change.offset + change.howMany ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this._isInInsertedElement( parent );\n\t}\n\n\t/**\n\t * Removes deeply all buffered changes that are registered in elements from range specified by `parent`, `offset`\n\t * and `howMany`.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} parent\n\t * @param {Number} offset\n\t * @param {Number} howMany\n\t */\n\t_removeAllNestedChanges( parent, offset, howMany ) {\n\t\tconst range = new Range( Position._createAt( parent, offset ), Position._createAt( parent, offset + howMany ) );\n\n\t\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( 'element' ) ) {\n\t\t\t\tthis._elementSnapshots.delete( item );\n\t\t\t\tthis._changesInElement.delete( item );\n\n\t\t\t\tthis._removeAllNestedChanges( item, 0, item.maxOffset );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Returns an array that is a copy of passed child list with the exception that text nodes are split to one or more\n// objects, each representing one character and attributes set on that character.\nfunction _getChildrenSnapshot( children ) {\n\tconst snapshot = [];\n\n\tfor ( const child of children ) {\n\t\tif ( child.is( '$text' ) ) {\n\t\t\tfor ( let i = 0; i < child.data.length; i++ ) {\n\t\t\t\tsnapshot.push( {\n\t\t\t\t\tname: '$text',\n\t\t\t\t\tattributes: new Map( child.getAttributes() )\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\tsnapshot.push( {\n\t\t\t\tname: child.name,\n\t\t\t\tattributes: new Map( child.getAttributes() )\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn snapshot;\n}\n\n// Generates array of actions for given changes set.\n// It simulates what `diff` function does.\n// Generated actions are:\n// - 'e' for 'equal' - when item at that position did not change,\n// - 'i' for 'insert' - when item at that position was inserted,\n// - 'r' for 'remove' - when item at that position was removed,\n// - 'a' for 'attribute' - when item at that position has it attributes changed.\n//\n// Example (assume that uppercase letters have bold attribute, compare with function code):\n//\n// children before:\tfooBAR\n// children after:\tfoxybAR\n//\n// changes: type: remove, offset: 1, howMany: 1\n//\t\t\ttype: insert, offset: 2, howMany: 2\n//\t\t\ttype: attribute, offset: 4, howMany: 1\n//\n// expected actions: equal (f), remove (o), equal (o), insert (x), insert (y), attribute (b), equal (A), equal (R)\n//\n// steps taken by th script:\n//\n// 1. change = \"type: remove, offset: 1, howMany: 1\"; offset = 0; oldChildrenHandled = 0\n// 1.1 between this change and the beginning is one not-changed node, fill with one equal action, one old child has been handled\n// 1.2 this change removes one node, add one remove action\n// 1.3 change last visited `offset` to 1\n// 1.4 since an old child has been removed, one more old child has been handled\n// 1.5 actions at this point are: equal, remove\n//\n// 2. change = \"type: insert, offset: 2, howMany: 2\"; offset = 1; oldChildrenHandled = 2\n// 2.1 between this change and previous change is one not-changed node, add equal action, another one old children has been handled\n// 2.2 this change inserts two nodes, add two insert actions\n// 2.3 change last visited offset to the end of the inserted range, that is 4\n// 2.4 actions at this point are: equal, remove, equal, insert, insert\n//\n// 3. change = \"type: attribute, offset: 4, howMany: 1\"; offset = 4, oldChildrenHandled = 3\n// 3.1 between this change and previous change are no not-changed nodes\n// 3.2 this change changes one node, add one attribute action\n// 3.3 change last visited `offset` to the end of change range, that is 5\n// 3.4 since an old child has been changed, one more old child has been handled\n// 3.5 actions at this point are: equal, remove, equal, insert, insert, attribute\n//\n// 4. after loop oldChildrenHandled = 4, oldChildrenLength = 6 (fooBAR is 6 characters)\n// 4.1 fill up with two equal actions\n//\n// The result actions are: equal, remove, equal, insert, insert, attribute, equal, equal.\nfunction _generateActionsFromChanges( oldChildrenLength, changes ) {\n\tconst actions = [];\n\n\tlet offset = 0;\n\tlet oldChildrenHandled = 0;\n\n\t// Go through all buffered changes.\n\tfor ( const change of changes ) {\n\t\t// First, fill \"holes\" between changes with \"equal\" actions.\n\t\tif ( change.offset > offset ) {\n\t\t\tfor ( let i = 0; i < change.offset - offset; i++ ) {\n\t\t\t\tactions.push( 'e' );\n\t\t\t}\n\n\t\t\toldChildrenHandled += change.offset - offset;\n\t\t}\n\n\t\t// Then, fill up actions accordingly to change type.\n\t\tif ( change.type == 'insert' ) {\n\t\t\tfor ( let i = 0; i < change.howMany; i++ ) {\n\t\t\t\tactions.push( 'i' );\n\t\t\t}\n\n\t\t\t// The last handled offset is after inserted range.\n\t\t\toffset = change.offset + change.howMany;\n\t\t} else if ( change.type == 'remove' ) {\n\t\t\tfor ( let i = 0; i < change.howMany; i++ ) {\n\t\t\t\tactions.push( 'r' );\n\t\t\t}\n\n\t\t\t// The last handled offset is at the position where the nodes were removed.\n\t\t\toffset = change.offset;\n\t\t\t// We removed `howMany` old nodes, update `oldChildrenHandled`.\n\t\t\toldChildrenHandled += change.howMany;\n\t\t} else {\n\t\t\tactions.push( ...'a'.repeat( change.howMany ).split( '' ) );\n\n\t\t\t// The last handled offset is at the position after the changed range.\n\t\t\toffset = change.offset + change.howMany;\n\t\t\t// We changed `howMany` old nodes, update `oldChildrenHandled`.\n\t\t\toldChildrenHandled += change.howMany;\n\t\t}\n\t}\n\n\t// Fill \"equal\" actions at the end of actions set. Use `oldChildrenHandled` to see how many children\n\t// has not been changed / removed at the end of their parent.\n\tif ( oldChildrenHandled < oldChildrenLength ) {\n\t\tfor ( let i = 0; i < oldChildrenLength - oldChildrenHandled - offset; i++ ) {\n\t\t\tactions.push( 'e' );\n\t\t}\n\t}\n\n\treturn actions;\n}\n\n// Filter callback for Array.filter that filters out change entries that are in graveyard.\nfunction _changesInGraveyardFilter( entry ) {\n\tconst posInGy = entry.position && entry.position.root.rootName == '$graveyard';\n\tconst rangeInGy = entry.range && entry.range.root.rootName == '$graveyard';\n\n\treturn !posInGy && !rangeInGy;\n}\n\n/**\n * The single diff item.\n *\n * Could be one of:\n *\n * * {@link module:engine/model/differ~DiffItemInsert `DiffItemInsert`},\n * * {@link module:engine/model/differ~DiffItemRemove `DiffItemRemove`},\n * * {@link module:engine/model/differ~DiffItemAttribute `DiffItemAttribute`}.\n *\n * @interface DiffItem\n */\n\n/**\n * The single diff item for inserted nodes.\n *\n * @class DiffItemInsert\n * @implements module:engine/model/differ~DiffItem\n */\n\n/**\n * The type of diff item.\n *\n * @member {'insert'} module:engine/model/differ~DiffItemInsert#type\n */\n\n/**\n * The name of the inserted elements or `'$text'` for a text node.\n *\n * @member {String} module:engine/model/differ~DiffItemInsert#name\n */\n\n/**\n * The position where the node was inserted.\n *\n * @member {module:engine/model/position~Position} module:engine/model/differ~DiffItemInsert#position\n */\n\n/**\n * The length of an inserted text node. For elements it is always 1 as each inserted element is counted as a one.\n *\n * @member {Number} module:engine/model/differ~DiffItemInsert#length\n */\n\n/**\n * The single diff item for removed nodes.\n *\n * @class DiffItemRemove\n * @implements module:engine/model/differ~DiffItem\n */\n\n/**\n * The type of diff item.\n *\n * @member {'remove'} module:engine/model/differ~DiffItemRemove#type\n */\n\n/**\n * The name of the removed element or `'$text'` for a text node.\n *\n * @member {String} module:engine/model/differ~DiffItemRemove#name\n */\n\n/**\n * The position where the node was removed.\n *\n * @member {module:engine/model/position~Position} module:engine/model/differ~DiffItemRemove#position\n */\n\n/**\n * The length of a removed text node. For elements it is always 1 as each removed element is counted as a one.\n *\n * @member {Number} module:engine/model/differ~DiffItemRemove#length\n */\n\n/**\n * The single diff item for attribute change.\n *\n * @class DiffItemAttribute\n * @implements module:engine/model/differ~DiffItem\n */\n\n/**\n * The type of diff item.\n *\n * @member {'attribute'} module:engine/model/differ~DiffItemAttribute#type\n */\n\n/**\n * The name of the changed attribute.\n *\n * @member {String} module:engine/model/differ~DiffItemAttribute#attributeKey\n */\n\n/**\n * An attribute previous value (before change).\n *\n * @member {String} module:engine/model/differ~DiffItemAttribute#attributeOldValue\n */\n\n/**\n * An attribute new value (after change).\n *\n * @member {String} module:engine/model/differ~DiffItemAttribute#attributeNewValue\n */\n\n/**\n * The range where the change happened.\n *\n * @member {module:engine/model/range~Range} module:engine/model/differ~DiffItemAttribute#range\n */\n"],"sourceRoot":""}