{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-table/src/tableutils.js"],"names":["TableUtils","this","decorate","tableCell","_step","tableRow","parent","table","rowIndex","getChildIndex","tableWalker","TableWalker","row","_iterator","_createForOfIteratorHelper","s","n","done","_step$value","value","cell","column","err","e","f","writer","options","createElement","rows","parseInt","columns","createEmptyRows","headingRows","updateNumericAttribute","Math","min","headingColumns","arguments","length","undefined","model","editor","insertAt","at","rowsToInsert","isCopyStructure","copyStructureFromAbove","copyStructureFrom","getRows","getColumns","CKEditorError","change","getAttribute","_step2","walkerEndRow","max","tableIterator","endRow","rowColSpansMap","Array","fill","_iterator2","_step2$value","cellHeight","cellWidth","lastCellRow","isOverlappingInsertedRow","isReferenceRow","setAttribute","insert","cellIndex","colspan","insertPosition","createPositionAt","createEmptyTableCell","abs","_this","columnsToInsert","tableColumns","_step4","includeAllSlots","_iterator4","tableSlot","cellAnchorColumn","cellAnchorRow","i","skipRow","createCells","getPositionBefore","_step3","_iterator3","getChildren","is","_this2","rowsToRemove","rowCount","first","last","_getCellsToMoveAndTri","getCellsToMoveAndTrimOnRemoveRow","cellsToMove","cellsToTrim","size","rowAfterRemovedSection","moveCellsToRow","remove","getChild","_step5","_iterator5","_step5$value","rowspan","updateHeadingRows","removeEmptyColumns","removeEmptyRows","_this3","columnsToRemove","adjustHeadingColumns","removedColumnIndex","_i","_arr","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_toConsumableArray_js__WEBPACK_IMPORTED_MODULE_10__","_arr$_i","numberOfCells","_breakSpanEvenly","breakSpanEvenly","newCellsSpan","updatedSpan","newCellsAttributes","cellsToInsert","createPositionAfter","_step6","tableMap","_tableMap$find","find","_ref","splitCellColumn","cellsToUpdate","filter","_ref2","isOnSameColumn","spansOverColumn","_iterator6","_step6$value","splitCellRow","startRow","_breakSpanEvenly2","_tableMap$find2","_ref3","cellColumn","_step7","_iterator7","isAfterSplitCell","isInEvenlySplitRow","_step8","_iterator8","_step8$value","rowspanToSet","reduce","columnWidth","from","child","Plugin","tableCellToInsert","attributes","cells","span","floor","removedColumnIndexes","headingsRemoved","newRows","_step9","Map","_iterator9","_step9$value","lastRowOfCell","isCellStickingOutFromRemovedRows","rowspanInRemovedSection","rowSpanToSet","set","isCellOverlappingRemovedRows","rowspanAdjustment","push","targetRowIndex","previousCell","_step10","tableRowMap","_iterator10","_step10$value","isAnchor","has","_cellsToMove$get","get","cellToMove","targetPosition","move","createRangeOn"],"mappings":"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","file":"js/chunk-2d0b23d4.09b0f5b3.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 table/tableutils\n */\n\nimport { CKEditorError } from 'ckeditor5/src/utils';\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport TableWalker from './tablewalker';\nimport { createEmptyTableCell, updateNumericAttribute } from './utils/common';\nimport { removeEmptyColumns, removeEmptyRows } from './utils/structure';\n\n/**\n * The table utilities plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableUtils';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tthis.decorate( 'insertColumns' );\n\t\tthis.decorate( 'insertRows' );\n\t}\n\n\t/**\n\t * Returns the table cell location as an object with table row and table column indexes.\n\t *\n\t * For instance, in the table below:\n\t *\n\t *\t\t 0 1 2 3\n\t *\t\t +---+---+---+---+\n\t *\t\t0 | a | b | c |\n\t *\t\t + + +---+\n\t *\t\t1 | | | d |\n\t *\t\t +---+---+ +---+\n\t *\t\t2 | e | | f |\n\t *\t\t +---+---+---+---+\n\t *\n\t * the method will return:\n\t *\n\t *\t\tconst cellA = table.getNodeByPath( [ 0, 0 ] );\n\t *\t\teditor.plugins.get( 'TableUtils' ).getCellLocation( cellA );\n\t *\t\t// will return { row: 0, column: 0 }\n\t *\n\t *\t\tconst cellD = table.getNodeByPath( [ 1, 0 ] );\n\t *\t\teditor.plugins.get( 'TableUtils' ).getCellLocation( cellD );\n\t *\t\t// will return { row: 1, column: 3 }\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @returns {Object} Returns a `{row, column}` object.\n\t */\n\tgetCellLocation( tableCell ) {\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { row: rowIndex } );\n\n\t\tfor ( const { cell, row, column } of tableWalker ) {\n\t\t\tif ( cell === tableCell ) {\n\t\t\t\treturn { row, column };\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates an empty table with a proper structure. The table needs to be inserted into the model,\n\t * for example, by using the {@link module:engine/model/model~Model#insertContent} function.\n\t *\n\t *\t\tmodel.change( ( writer ) => {\n\t *\t\t\t// Create a table of 2 rows and 7 columns:\n\t *\t\t\tconst table = tableUtils.createTable( writer, { rows: 2, columns: 7 } );\n\t *\n\t *\t\t\t// Insert a table to the model at the best position taking the current selection:\n\t *\t\t\tmodel.insertContent( table );\n\t *\t\t}\n\t *\n\t * @param {module:engine/model/writer~Writer} writer The model writer.\n\t * @param {Object} options\n\t * @param {Number} [options.rows=2] The number of rows to create.\n\t * @param {Number} [options.columns=2] The number of columns to create.\n\t * @param {Number} [options.headingRows=0] The number of heading rows.\n\t * @param {Number} [options.headingColumns=0] The number of heading columns.\n\t * @returns {module:engine/model/element~Element} The created table element.\n\t */\n\tcreateTable( writer, options ) {\n\t\tconst table = writer.createElement( 'table' );\n\n\t\tconst rows = parseInt( options.rows ) || 2;\n\t\tconst columns = parseInt( options.columns ) || 2;\n\n\t\tcreateEmptyRows( writer, table, 0, rows, columns );\n\n\t\tif ( options.headingRows ) {\n\t\t\tupdateNumericAttribute( 'headingRows', Math.min( options.headingRows, rows ), table, writer, 0 );\n\t\t}\n\n\t\tif ( options.headingColumns ) {\n\t\t\tupdateNumericAttribute( 'headingColumns', Math.min( options.headingColumns, columns ), table, writer, 0 );\n\t\t}\n\n\t\treturn table;\n\t}\n\n\t/**\n\t * Inserts rows into a table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).insertRows( table, { at: 1, rows: 2 } );\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *\t\trow index\n\t *\t\t 0 +---+---+---+ `at` = 1, +---+---+---+ 0\n\t *\t\t | a | b | c | `rows` = 2, | a | b | c |\n\t *\t\t 1 + +---+---+ <-- insert here + +---+---+ 1\n\t *\t\t | | d | e | | | | |\n\t *\t\t 2 + +---+---+ will give: + +---+---+ 2\n\t *\t\t | | f | g | | | | |\n\t *\t\t 3 +---+---+---+ + +---+---+ 3\n\t *\t\t | | d | e |\n\t *\t\t + +---+---+ 4\n\t *\t\t + + f | g |\n\t *\t\t +---+---+---+ 5\n\t *\n\t * @param {module:engine/model/element~Element} table The table model element where the rows will be inserted.\n\t * @param {Object} options\n\t * @param {Number} [options.at=0] The row index at which the rows will be inserted.\n\t * @param {Number} [options.rows=1] The number of rows to insert.\n\t * @param {Boolean|undefined} [options.copyStructureFromAbove] The flag for copying row structure. Note that\n\t * the row structure will not be copied if this option is not provided.\n\t */\n\tinsertRows( table, options = {} ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst rowsToInsert = options.rows || 1;\n\t\tconst isCopyStructure = options.copyStructureFromAbove !== undefined;\n\t\tconst copyStructureFrom = options.copyStructureFromAbove ? insertAt - 1 : insertAt;\n\n\t\tconst rows = this.getRows( table );\n\t\tconst columns = this.getColumns( table );\n\n\t\tif ( insertAt > rows ) {\n\t\t\t/**\n\t\t\t * The `options.at` points at a row position that does not exist.\n\t\t\t *\n\t\t\t * @error tableutils-insertrows-insert-out-of-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'tableutils-insertrows-insert-out-of-range',\n\t\t\t\tthis,\n\t\t\t\t{ options }\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t// Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.\n\t\t\tif ( headingRows > insertAt ) {\n\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + rowsToInsert, table, writer, 0 );\n\t\t\t}\n\n\t\t\t// Inserting at the end or at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( !isCopyStructure && ( insertAt === 0 || insertAt === rows ) ) {\n\t\t\t\tcreateEmptyRows( writer, table, insertAt, rowsToInsert, columns );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Iterate over all the rows above the inserted rows in order to check for the row-spanned cells.\n\t\t\tconst walkerEndRow = isCopyStructure ? Math.max( insertAt, copyStructureFrom ) : insertAt;\n\t\t\tconst tableIterator = new TableWalker( table, { endRow: walkerEndRow } );\n\n\t\t\t// Store spans of the reference row to reproduce it's structure. This array is column number indexed.\n\t\t\tconst rowColSpansMap = new Array( columns ).fill( 1 );\n\n\t\t\tfor ( const { row, column, cellHeight, cellWidth, cell } of tableIterator ) {\n\t\t\t\tconst lastCellRow = row + cellHeight - 1;\n\n\t\t\t\tconst isOverlappingInsertedRow = row < insertAt && insertAt <= lastCellRow;\n\t\t\t\tconst isReferenceRow = row <= copyStructureFrom && copyStructureFrom <= lastCellRow;\n\n\t\t\t\t// If the cell is row-spanned and overlaps the inserted row, then reserve space for it in the row map.\n\t\t\t\tif ( isOverlappingInsertedRow ) {\n\t\t\t\t\t// This cell overlaps the inserted rows so we need to expand it further.\n\t\t\t\t\twriter.setAttribute( 'rowspan', cellHeight + rowsToInsert, cell );\n\n\t\t\t\t\t// Mark this cell with negative number to indicate how many cells should be skipped when adding the new cells.\n\t\t\t\t\trowColSpansMap[ column ] = -cellWidth;\n\t\t\t\t}\n\t\t\t\t// Store the colspan from reference row.\n\t\t\t\telse if ( isCopyStructure && isReferenceRow ) {\n\t\t\t\t\trowColSpansMap[ column ] = cellWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( let rowIndex = 0; rowIndex < rowsToInsert; rowIndex++ ) {\n\t\t\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\t\t\twriter.insert( tableRow, table, insertAt );\n\n\t\t\t\tfor ( let cellIndex = 0; cellIndex < rowColSpansMap.length; cellIndex++ ) {\n\t\t\t\t\tconst colspan = rowColSpansMap[ cellIndex ];\n\t\t\t\t\tconst insertPosition = writer.createPositionAt( tableRow, 'end' );\n\n\t\t\t\t\t// Insert the empty cell only if this slot is not row-spanned from any other cell.\n\t\t\t\t\tif ( colspan > 0 ) {\n\t\t\t\t\t\tcreateEmptyTableCell( writer, insertPosition, colspan > 1 ? { colspan } : null );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Skip the col-spanned slots, there won't be any cells.\n\t\t\t\t\tcellIndex += Math.abs( colspan ) - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Inserts columns into a table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).insertColumns( table, { at: 1, columns: 2 } );\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *\t\t0 1 2 3 0 1 2 3 4 5\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t| a | b | | a | b |\n\t *\t\t+ +---+ + +---+\n\t *\t\t| | c | | | c |\n\t *\t\t+---+---+---+ will give: +---+---+---+---+---+\n\t *\t\t| d | e | f | | d | | | e | f |\n\t *\t\t+---+ +---+ +---+---+---+ +---+\n\t *\t\t| g | | h | | g | | | | h |\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t| i | | i |\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t ^---- insert here, `at` = 1, `columns` = 2\n\t *\n\t * @param {module:engine/model/element~Element} table The table model element where the columns will be inserted.\n\t * @param {Object} options\n\t * @param {Number} [options.at=0] The column index at which the columns will be inserted.\n\t * @param {Number} [options.columns=1] The number of columns to insert.\n\t */\n\tinsertColumns( table, options = {} ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst columnsToInsert = options.columns || 1;\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' );\n\n\t\t\t// Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.\n\t\t\tif ( insertAt < headingColumns ) {\n\t\t\t\twriter.setAttribute( 'headingColumns', headingColumns + columnsToInsert, table );\n\t\t\t}\n\n\t\t\tconst tableColumns = this.getColumns( table );\n\n\t\t\t// Inserting at the end and at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( insertAt === 0 || tableColumns === insertAt ) {\n\t\t\t\tfor ( const tableRow of table.getChildren() ) {\n\t\t\t\t\t// Ignore non-row elements inside the table (e.g. caption).\n\t\t\t\t\tif ( !tableRow.is( 'element', 'tableRow' ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tcreateCells( columnsToInsert, writer, writer.createPositionAt( tableRow, insertAt ? 'end' : 0 ) );\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableWalker = new TableWalker( table, { column: insertAt, includeAllSlots: true } );\n\n\t\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\t\tconst { row, cell, cellAnchorColumn, cellAnchorRow, cellWidth, cellHeight } = tableSlot;\n\n\t\t\t\t// When iterating over column the table walker outputs either:\n\t\t\t\t// - cells at given column index (cell \"e\" from method docs),\n\t\t\t\t// - spanned columns (spanned cell from row between cells \"g\" and \"h\" - spanned by \"e\", only if `includeAllSlots: true`),\n\t\t\t\t// - or a cell from the same row which spans over this column (cell \"a\").\n\n\t\t\t\tif ( cellAnchorColumn < insertAt ) {\n\t\t\t\t\t// If cell is anchored in previous column, it is a cell that spans over an inserted column (cell \"a\" & \"i\").\n\t\t\t\t\t// For such cells expand them by a number of columns inserted.\n\t\t\t\t\twriter.setAttribute( 'colspan', cellWidth + columnsToInsert, cell );\n\n\t\t\t\t\t// This cell will overlap cells in rows below so skip them (because of `includeAllSlots` option) - (cell \"a\")\n\t\t\t\t\tconst lastCellRow = cellAnchorRow + cellHeight - 1;\n\n\t\t\t\t\tfor ( let i = row; i <= lastCellRow; i++ ) {\n\t\t\t\t\t\ttableWalker.skipRow( i );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// It's either cell at this column index or spanned cell by a row-spanned cell from row above.\n\t\t\t\t\t// In table above it's cell \"e\" and a spanned position from row below (empty cell between cells \"g\" and \"h\")\n\t\t\t\t\tcreateCells( columnsToInsert, writer, tableSlot.getPositionBefore() );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes rows from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including `rowspan` attribute of table cells overlapping removed rows\n\t * and table headings values.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).removeRows( table, { at: 1, rows: 2 } );\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *\t\trow index\n\t *\t\t ┌───┬───┬───┐ `at` = 1 ┌───┬───┬───┐\n\t *\t\t 0 │ a │ b │ c │ `rows` = 2 │ a │ b │ c │ 0\n\t *\t\t │ ├───┼───┤ │ ├───┼───┤\n\t *\t\t 1 │ │ d │ e │ <-- remove from here │ │ d │ g │ 1\n\t *\t\t │ │ ├───┤ will give: ├───┼───┼───┤\n\t *\t\t 2 │ │ │ f │ │ h │ i │ j │ 2\n\t *\t\t │ │ ├───┤ └───┴───┴───┘\n\t *\t\t 3 │ │ │ g │\n\t *\t\t ├───┼───┼───┤\n\t *\t\t 4 │ h │ i │ j │\n\t *\t\t └───┴───┴───┘\n\t *\n\t * @param {module:engine/model/element~Element} table\n\t * @param {Object} options\n\t * @param {Number} options.at The row index at which the removing rows will start.\n\t * @param {Number} [options.rows=1] The number of rows to remove.\n\t */\n\tremoveRows( table, options ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst rowsToRemove = options.rows || 1;\n\t\tconst rowCount = this.getRows( table );\n\t\tconst first = options.at;\n\t\tconst last = first + rowsToRemove - 1;\n\n\t\tif ( last > rowCount - 1 ) {\n\t\t\t/**\n\t\t\t * The `options.at` param must point at existing row and `options.rows` must not exceed the rows in the table.\n\t\t\t *\n\t\t\t * @error tableutils-removerows-row-index-out-of-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'tableutils-removerows-row-index-out-of-range',\n\t\t\t\tthis,\n\t\t\t\t{ table, options }\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\t// Removing rows from the table require that most calculations to be done prior to changing table structure.\n\t\t\t// Preparations must be done in the same enqueueChange callback to use the current table structure.\n\n\t\t\t// 1. Preparation - get row-spanned cells that have to be modified after removing rows.\n\t\t\tconst { cellsToMove, cellsToTrim } = getCellsToMoveAndTrimOnRemoveRow( table, first, last );\n\n\t\t\t// 2. Execution\n\n\t\t\t// 2a. Move cells from removed rows that extends over a removed section - must be done before removing rows.\n\t\t\t// This will fill any gaps in a rows below that previously were empty because of row-spanned cells.\n\t\t\tif ( cellsToMove.size ) {\n\t\t\t\tconst rowAfterRemovedSection = last + 1;\n\t\t\t\tmoveCellsToRow( table, rowAfterRemovedSection, cellsToMove, writer );\n\t\t\t}\n\n\t\t\t// 2b. Remove all required rows.\n\t\t\tfor ( let i = last; i >= first; i-- ) {\n\t\t\t\twriter.remove( table.getChild( i ) );\n\t\t\t}\n\n\t\t\t// 2c. Update cells from rows above that overlap removed section. Similar to step 2 but does not involve moving cells.\n\t\t\tfor ( const { rowspan, cell } of cellsToTrim ) {\n\t\t\t\tupdateNumericAttribute( 'rowspan', rowspan, cell, writer );\n\t\t\t}\n\n\t\t\t// 2d. Adjust heading rows if removed rows were in a heading section.\n\t\t\tupdateHeadingRows( table, first, last, writer );\n\n\t\t\t// 2e. Remove empty columns (without anchored cells) if there are any.\n\t\t\tif ( !removeEmptyColumns( table, this ) ) {\n\t\t\t\t// If there wasn't any empty columns then we still need to check if this wasn't called\n\t\t\t\t// because of cleaning empty rows and we only removed one of them.\n\t\t\t\tremoveEmptyRows( table, this );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes columns from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including the `colspan` attribute of table cells overlapping removed columns\n\t * and table headings values.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).removeColumns( table, { at: 1, columns: 2 } );\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *\t\t 0 1 2 3 4 0 1 2\n\t *\t\t┌───────────────┬───┐ ┌───────┬───┐\n\t *\t\t│ a │ b │ │ a │ b │\n\t *\t\t│ ├───┤ │ ├───┤\n\t *\t\t│ │ c │ │ │ c │\n\t *\t\t├───┬───┬───┬───┼───┤ will give: ├───┬───┼───┤\n\t *\t\t│ d │ e │ f │ g │ h │ │ d │ g │ h │\n\t *\t\t├───┼───┼───┤ ├───┤ ├───┤ ├───┤\n\t *\t\t│ i │ j │ k │ │ l │ │ i │ │ l │\n\t *\t\t├───┴───┴───┴───┴───┤ ├───┴───┴───┤\n\t *\t\t│ m │ │ m │\n\t *\t\t└───────────────────┘ └───────────┘\n\t *\t\t ^---- remove from here, `at` = 1, `columns` = 2\n\t *\n\t * @param {module:engine/model/element~Element} table\n\t * @param {Object} options\n\t * @param {Number} options.at The row index at which the removing columns will start.\n\t * @param {Number} [options.columns=1] The number of columns to remove.\n\t */\n\tremoveColumns( table, options ) {\n\t\tconst model = this.editor.model;\n\t\tconst first = options.at;\n\t\tconst columnsToRemove = options.columns || 1;\n\t\tconst last = options.at + columnsToRemove - 1;\n\n\t\tmodel.change( writer => {\n\t\t\tadjustHeadingColumns( table, { first, last }, writer );\n\n\t\t\tfor ( let removedColumnIndex = last; removedColumnIndex >= first; removedColumnIndex-- ) {\n\t\t\t\tfor ( const { cell, column, cellWidth } of [ ...new TableWalker( table ) ] ) {\n\t\t\t\t\t// If colspaned cell overlaps removed column decrease its span.\n\t\t\t\t\tif ( column <= removedColumnIndex && cellWidth > 1 && column + cellWidth > removedColumnIndex ) {\n\t\t\t\t\t\tupdateNumericAttribute( 'colspan', cellWidth - 1, cell, writer );\n\t\t\t\t\t} else if ( column === removedColumnIndex ) {\n\t\t\t\t\t\t// The cell in removed column has colspan of 1.\n\t\t\t\t\t\twriter.remove( cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove empty rows that could appear after removing columns.\n\t\t\tif ( !removeEmptyRows( table, this ) ) {\n\t\t\t\t// If there wasn't any empty rows then we still need to check if this wasn't called\n\t\t\t\t// because of cleaning empty columns and we only removed one of them.\n\t\t\t\tremoveEmptyColumns( table, this );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell vertically into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating colspans of other cells in a column\n\t * and inserting cells (columns) after that cell.\n\t *\n\t * In the table below, if cell \"a\" is split into 3 cells:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * it will result in the table below:\n\t *\n\t *\t\t+---+---+---+---+---+\n\t *\t\t| a | | | b | c |\n\t *\t\t+---+---+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+---+---+\n\t *\n\t * So cell \"d\" will get its `colspan` updated to `3` and 2 cells will be added (2 columns will be created).\n\t *\n\t * Splitting a cell that already has a `colspan` attribute set will distribute the cell `colspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a |\n\t *\t\t+---+---+---+\n\t *\t\t| b | c | d |\n\t *\t\t+---+---+---+\n\t *\n\t * Splitting cell \"a\" with `colspan=3` into 2 cells will create 1 cell with a `colspan=a` and cell \"a\" that will have `colspan=2`:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | |\n\t *\t\t+---+---+---+\n\t *\t\t| b | c | d |\n\t *\t\t+---+---+---+\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {Number} numberOfCells\n\t */\n\tsplitCellVertically( tableCell, numberOfCells = 2 ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( colspan > 1 ) {\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( colspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'colspan', updatedSpan, tableCell, writer );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tconst cellsToInsert = colspan > numberOfCells ? numberOfCells - 1 : colspan - 1;\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\t\t\t}\n\n\t\t\t// Second check - the cell has colspan of 1 or we need to create more cells then the currently one spans over.\n\t\t\tif ( colspan < numberOfCells ) {\n\t\t\t\tconst cellsToInsert = numberOfCells - colspan;\n\n\t\t\t\t// First step: expand cells on the same column as split cell.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t\t\t// Get the column index of split cell.\n\t\t\t\tconst { column: splitCellColumn } = tableMap.find( ( { cell } ) => cell === tableCell );\n\n\t\t\t\t// Find cells which needs to be expanded vertically - those on the same column or those that spans over split cell's column.\n\t\t\t\tconst cellsToUpdate = tableMap.filter( ( { cell, cellWidth, column } ) => {\n\t\t\t\t\tconst isOnSameColumn = cell !== tableCell && column === splitCellColumn;\n\t\t\t\t\tconst spansOverColumn = ( column < splitCellColumn && column + cellWidth > splitCellColumn );\n\n\t\t\t\t\treturn isOnSameColumn || spansOverColumn;\n\t\t\t\t} );\n\n\t\t\t\t// Expand cells vertically.\n\t\t\t\tfor ( const { cell, cellWidth } of cellsToUpdate ) {\n\t\t\t\t\twriter.setAttribute( 'colspan', cellWidth + cellsToInsert, cell );\n\t\t\t\t}\n\n\t\t\t\t// Second step: create columns after split cell.\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\n\t\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tif ( headingColumns > splitCellColumn ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingColumns', headingColumns + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell horizontally into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating rowspans of other cells in the row and inserting rows with a single cell\n\t * below.\n\t *\n\t * If in the table below cell \"b\" is split into 3 cells:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * It will result in the table below:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+ +\n\t *\t\t| | | |\n\t *\t\t+ +---+ +\n\t *\t\t| | | |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * So cells \"a\" and \"b\" will get their `rowspan` updated to `3` and 2 rows with a single cell will be added.\n\t *\n\t * Splitting a cell that already has a `rowspan` attribute set will distribute the cell `rowspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+---+\n\t *\t\t| | d | e |\n\t *\t\t+ +---+---+\n\t *\t\t| | f | g |\n\t *\t\t+ +---+---+\n\t *\t\t| | h | i |\n\t *\t\t+---+---+---+\n\t *\n\t * Splitting cell \"a\" with `rowspan=4` into 3 cells will create 2 cells with a `rowspan=1` and cell \"a\" will have `rowspan=2`:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+---+\n\t *\t\t| | d | e |\n\t *\t\t+---+---+---+\n\t *\t\t| | f | g |\n\t *\t\t+---+---+---+\n\t *\t\t| | h | i |\n\t *\t\t+---+---+---+\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {Number} numberOfCells\n\t */\n\tsplitCellHorizontally( tableCell, numberOfCells = 2 ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\t\tconst splitCellRow = table.getChildIndex( tableRow );\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t// Cache table map before updating table.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, {\n\t\t\t\t\tstartRow: splitCellRow,\n\t\t\t\t\tendRow: splitCellRow + rowspan - 1,\n\t\t\t\t\tincludeAllSlots: true\n\t\t\t\t} ) ];\n\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( rowspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'rowspan', updatedSpan, tableCell, writer );\n\n\t\t\t\tconst { column: cellColumn } = tableMap.find( ( { cell } ) => cell === tableCell );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tfor ( const tableSlot of tableMap ) {\n\t\t\t\t\tconst { column, row } = tableSlot;\n\n\t\t\t\t\t// As both newly created cells and the split cell might have rowspan,\n\t\t\t\t\t// the insertion of new cells must go to appropriate rows:\n\t\t\t\t\t//\n\t\t\t\t\t// 1. It's a row after split cell + it's height.\n\t\t\t\t\tconst isAfterSplitCell = row >= splitCellRow + updatedSpan;\n\t\t\t\t\t// 2. Is on the same column.\n\t\t\t\t\tconst isOnSameColumn = column === cellColumn;\n\t\t\t\t\t// 3. And it's row index is after previous cell height.\n\t\t\t\t\tconst isInEvenlySplitRow = ( row + splitCellRow + updatedSpan ) % newCellsSpan === 0;\n\n\t\t\t\t\tif ( isAfterSplitCell && isOnSameColumn && isInEvenlySplitRow ) {\n\t\t\t\t\t\tcreateCells( 1, writer, tableSlot.getPositionBefore(), newCellsAttributes );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Second check - the cell has rowspan of 1 or we need to create more cells than the current cell spans over.\n\t\t\tif ( rowspan < numberOfCells ) {\n\t\t\t\t// We already split the cell in check one so here we split to the remaining number of cells only.\n\t\t\t\tconst cellsToInsert = numberOfCells - rowspan;\n\n\t\t\t\t// This check is needed since we need to check if there are any cells from previous rows than spans over this cell's row.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, { startRow: 0, endRow: splitCellRow } ) ];\n\n\t\t\t\t// First step: expand cells.\n\t\t\t\tfor ( const { cell, cellHeight, row } of tableMap ) {\n\t\t\t\t\t// Expand rowspan of cells that are either:\n\t\t\t\t\t// - on the same row as current cell,\n\t\t\t\t\t// - or are below split cell row and overlaps that row.\n\t\t\t\t\tif ( cell !== tableCell && row + cellHeight > splitCellRow ) {\n\t\t\t\t\t\tconst rowspanToSet = cellHeight + cellsToInsert;\n\n\t\t\t\t\t\twriter.setAttribute( 'rowspan', rowspanToSet, cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Second step: create rows with single cell below split cell.\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tcreateEmptyRows( writer, table, splitCellRow + 1, cellsToInsert, 1, newCellsAttributes );\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t\tif ( headingRows > splitCellRow ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the number of columns for a given table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).getColumns( table );\n\t *\n\t * @param {module:engine/model/element~Element} table The table to analyze.\n\t * @returns {Number}\n\t */\n\tgetColumns( table ) {\n\t\t// Analyze first row only as all the rows should have the same width.\n\t\t// Using the first row without checking if it's a tableRow because we expect\n\t\t// that table will have only tableRow model elements at the beginning.\n\t\tconst row = table.getChild( 0 );\n\n\t\treturn [ ...row.getChildren() ].reduce( ( columns, row ) => {\n\t\t\tconst columnWidth = parseInt( row.getAttribute( 'colspan' ) || 1 );\n\n\t\t\treturn columns + columnWidth;\n\t\t}, 0 );\n\t}\n\n\t/**\n\t * Returns the number of rows for a given table. Any other element present in the table model is omitted.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).getRows( table );\n\t *\n\t * @param {module:engine/model/element~Element} table The table to analyze.\n\t * @returns {Number}\n\t */\n\tgetRows( table ) {\n\t\t// Rowspan not included due to #6427.\n\t\treturn Array.from( table.getChildren() )\n\t\t\t.reduce( ( rowCount, child ) => child.is( 'element', 'tableRow' ) ? rowCount + 1 : rowCount, 0 );\n\t}\n}\n\n// Creates empty rows at the given index in an existing table.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/element~Element} table\n// @param {Number} insertAt The row index of row insertion.\n// @param {Number} rows The number of rows to create.\n// @param {Number} tableCellToInsert The number of cells to insert in each row.\nfunction createEmptyRows( writer, table, insertAt, rows, tableCellToInsert, attributes = {} ) {\n\tfor ( let i = 0; i < rows; i++ ) {\n\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\twriter.insert( tableRow, table, insertAt );\n\n\t\tcreateCells( tableCellToInsert, writer, writer.createPositionAt( tableRow, 'end' ), attributes );\n\t}\n}\n\n// Creates cells at a given position.\n//\n// @param {Number} columns The number of columns to create\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/position~Position} insertPosition\nfunction createCells( cells, writer, insertPosition, attributes = {} ) {\n\tfor ( let i = 0; i < cells; i++ ) {\n\t\tcreateEmptyTableCell( writer, insertPosition, attributes );\n\t}\n}\n\n// Evenly distributes the span of a cell to a number of provided cells.\n// The resulting spans will always be integer values.\n//\n// For instance breaking a span of 7 into 3 cells will return:\n//\n//\t\t{ newCellsSpan: 2, updatedSpan: 3 }\n//\n// as two cells will have a span of 2 and the remainder will go the first cell so its span will change to 3.\n//\n// @param {Number} span The span value do break.\n// @param {Number} numberOfCells The number of resulting spans.\n// @returns {{newCellsSpan: Number, updatedSpan: Number}}\nfunction breakSpanEvenly( span, numberOfCells ) {\n\tif ( span < numberOfCells ) {\n\t\treturn { newCellsSpan: 1, updatedSpan: 1 };\n\t}\n\n\tconst newCellsSpan = Math.floor( span / numberOfCells );\n\tconst updatedSpan = ( span - newCellsSpan * numberOfCells ) + newCellsSpan;\n\n\treturn { newCellsSpan, updatedSpan };\n}\n\n// Updates heading columns attribute if removing a row from head section.\nfunction adjustHeadingColumns( table, removedColumnIndexes, writer ) {\n\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\n\tif ( headingColumns && removedColumnIndexes.first < headingColumns ) {\n\t\tconst headingsRemoved = Math.min( headingColumns - 1 /* Other numbers are 0-based */, removedColumnIndexes.last ) -\n\t\t\tremovedColumnIndexes.first + 1;\n\n\t\twriter.setAttribute( 'headingColumns', headingColumns - headingsRemoved, table );\n\t}\n}\n\n// Calculates a new heading rows value for removing rows from heading section.\nfunction updateHeadingRows( table, first, last, writer ) {\n\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\tif ( first < headingRows ) {\n\t\tconst newRows = last < headingRows ? headingRows - ( last - first + 1 ) : first;\n\n\t\tupdateNumericAttribute( 'headingRows', newRows, table, writer, 0 );\n\t}\n}\n\n// Finds cells that will be:\n// - trimmed - Cells that are \"above\" removed rows sections and overlap the removed section - their rowspan must be trimmed.\n// - moved - Cells from removed rows section might stick out of. These cells are moved to the next row after a removed section.\n//\n// Sample table with overlapping & sticking out cells:\n//\n// +----+----+----+----+----+\n// | 00 | 01 | 02 | 03 | 04 |\n// +----+ + + + +\n// | 10 | | | | |\n// +----+----+ + + +\n// | 20 | 21 | | | | <-- removed row\n// + + +----+ + +\n// | | | 32 | | | <-- removed row\n// +----+ + +----+ +\n// | 40 | | | 43 | |\n// +----+----+----+----+----+\n//\n// In a table above:\n// - cells to trim: '02', '03' & '04'.\n// - cells to move: '21' & '32'.\nfunction getCellsToMoveAndTrimOnRemoveRow( table, first, last ) {\n\tconst cellsToMove = new Map();\n\tconst cellsToTrim = [];\n\n\tfor ( const { row, column, cellHeight, cell } of new TableWalker( table, { endRow: last } ) ) {\n\t\tconst lastRowOfCell = row + cellHeight - 1;\n\n\t\tconst isCellStickingOutFromRemovedRows = row >= first && row <= last && lastRowOfCell > last;\n\n\t\tif ( isCellStickingOutFromRemovedRows ) {\n\t\t\tconst rowspanInRemovedSection = last - row + 1;\n\t\t\tconst rowSpanToSet = cellHeight - rowspanInRemovedSection;\n\n\t\t\tcellsToMove.set( column, {\n\t\t\t\tcell,\n\t\t\t\trowspan: rowSpanToSet\n\t\t\t} );\n\t\t}\n\n\t\tconst isCellOverlappingRemovedRows = row < first && lastRowOfCell >= first;\n\n\t\tif ( isCellOverlappingRemovedRows ) {\n\t\t\tlet rowspanAdjustment;\n\n\t\t\t// Cell fully covers removed section - trim it by removed rows count.\n\t\t\tif ( lastRowOfCell >= last ) {\n\t\t\t\trowspanAdjustment = last - first + 1;\n\t\t\t}\n\t\t\t// Cell partially overlaps removed section - calculate cell's span that is in removed section.\n\t\t\telse {\n\t\t\t\trowspanAdjustment = lastRowOfCell - first + 1;\n\t\t\t}\n\n\t\t\tcellsToTrim.push( {\n\t\t\t\tcell,\n\t\t\t\trowspan: cellHeight - rowspanAdjustment\n\t\t\t} );\n\t\t}\n\t}\n\treturn { cellsToMove, cellsToTrim };\n}\n\nfunction moveCellsToRow( table, targetRowIndex, cellsToMove, writer ) {\n\tconst tableWalker = new TableWalker( table, {\n\t\tincludeAllSlots: true,\n\t\trow: targetRowIndex\n\t} );\n\n\tconst tableRowMap = [ ...tableWalker ];\n\tconst row = table.getChild( targetRowIndex );\n\n\tlet previousCell;\n\n\tfor ( const { column, cell, isAnchor } of tableRowMap ) {\n\t\tif ( cellsToMove.has( column ) ) {\n\t\t\tconst { cell: cellToMove, rowspan } = cellsToMove.get( column );\n\n\t\t\tconst targetPosition = previousCell ?\n\t\t\t\twriter.createPositionAfter( previousCell ) :\n\t\t\t\twriter.createPositionAt( row, 0 );\n\n\t\t\twriter.move( writer.createRangeOn( cellToMove ), targetPosition );\n\t\t\tupdateNumericAttribute( 'rowspan', rowspan, cellToMove, writer );\n\n\t\t\tpreviousCell = cellToMove;\n\t\t} else if ( isAnchor ) {\n\t\t\t// If cell is spanned then `cell` holds reference to overlapping cell. See ckeditor/ckeditor5#6502.\n\t\t\tpreviousCell = cell;\n\t\t}\n\t}\n}\n"],"sourceRoot":""}