UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

465 lines 70.4 kB
import { __decorate } from "tslib"; import { Injectable } from '@angular/core'; import { cloneArray, isEqual, mergeObjects } from '../core/utils'; import { DataUtil, DataType } from '../data-operations/data-util'; import { SortingDirection } from '../data-operations/sorting-expression.interface'; import { FilteringExpressionsTree } from '../data-operations/filtering-expressions-tree'; import { TransactionType } from '../services/transaction/transaction'; /** *@hidden */ let GridBaseAPIService = class GridBaseAPIService { constructor() { this.destroyMap = new Map(); } get_column_by_name(name) { return this.grid.columnList.find((col) => col.field === name); } get_summary_data() { const grid = this.grid; let data = grid.filteredData; if (!data) { if (grid.transactions.enabled) { data = DataUtil.mergeTransactions(cloneArray(grid.data), grid.transactions.getAggregatedChanges(true), grid.primaryKey); const deletedRows = grid.transactions.getTransactionLog().filter(t => t.type === TransactionType.DELETE).map(t => t.id); deletedRows.forEach(rowID => { const tempData = grid.primaryKey ? data.map(rec => rec[grid.primaryKey]) : data; const index = tempData.indexOf(rowID); if (index !== -1) { data.splice(index, 1); } }); } else { data = grid.data; } } return data; } /** * @hidden * @internal */ getRowData(rowID) { const data = this.get_all_data(this.grid.transactions.enabled); const index = this.get_row_index_in_data(rowID); return data[index]; } // TODO: Refactor escape_editMode() { this.grid.crudService.end(); } // TODO: Refactor get_cell_inEditMode() { return this.grid.crudService.cell; } get_row_index_in_data(rowID) { const grid = this.grid; if (!grid) { return -1; } const data = this.get_all_data(grid.transactions.enabled); return grid.primaryKey ? data.findIndex(record => record[grid.primaryKey] === rowID) : data.indexOf(rowID); } get_row_by_key(rowSelector) { const primaryKey = this.grid.primaryKey; if (primaryKey !== undefined && primaryKey !== null) { return this.grid.dataRowList.find((row) => row.rowData[primaryKey] === rowSelector); } else { return this.grid.dataRowList.find((row) => row.rowData === rowSelector); } } get_row_by_index(rowIndex) { return this.grid.rowList.find((row) => row.index === rowIndex); } get_cell_by_key(rowSelector, field) { const row = this.get_row_by_key(rowSelector); if (row && row.cells) { return row.cells.find((cell) => cell.column.field === field); } } get_cell_by_index(rowIndex, columnIndex) { const row = this.get_row_by_index(rowIndex); if (row && row.cells) { return row.cells.find((cell) => cell.columnIndex === columnIndex); } } get_cell_by_visible_index(rowIndex, columnIndex) { const row = this.get_row_by_index(rowIndex); if (row && row.cells) { return row.cells.find((cell) => cell.visibleColumnIndex === columnIndex); } } submit_value() { const cell = this.grid.crudService.cell; if (cell) { const args = this.update_cell(cell, cell.editValue); if (args.cancel) { return; } this.escape_editMode(); } } update_cell(cell, value) { const data = this.get_all_data(this.grid.transactions.enabled); const index = this.get_row_index_in_data(cell.id.rowID); cell.editValue = value; const args = cell.createEditEventArgs(); this.grid.onCellEdit.emit(args); if (args.cancel) { return args; } // Cast to number after emit // TODO: Clean up this args.newValue = cell.castToNumber(args.newValue); if (isEqual(args.oldValue, args.newValue)) { return args; } this.grid.summaryService.clearSummaryCache(args); this.updateData(this.grid, cell.id.rowID, data[index], cell.rowData, { [cell.column.field]: args.newValue }); if (this.grid.primaryKey === cell.column.field) { if (this.grid.selectionService.isRowSelected(cell.id.rowID)) { this.grid.selectionService.deselectRow(cell.id.rowID); this.grid.selectionService.selectRowById(args.newValue); } if (this.grid.hasSummarizedColumns) { this.grid.summaryService.removeSummaries(cell.id.rowID); } } if (!this.grid.rowEditable || !this.grid.crudService.row || this.grid.crudService.row.id !== cell.id.rowID || !this.grid.transactions.enabled) { this.grid.summaryService.clearSummaryCache(args); this.grid._pipeTrigger++; } return args; } /** * Updates related row of provided grid's data source with provided new row value * @param grid Grid to update data for * @param rowID ID of the row to update * @param rowValueInDataSource Initial value of the row as it is in data source * @param rowCurrentValue Current value of the row as it is with applied previous transactions * @param rowNewValue New value of the row */ updateData(grid, rowID, rowValueInDataSource, rowCurrentValue, rowNewValue) { if (grid.transactions.enabled) { const transaction = { id: rowID, type: TransactionType.UPDATE, newValue: rowNewValue }; grid.transactions.add(transaction, rowCurrentValue); } else { mergeObjects(rowValueInDataSource, rowNewValue); } } _update_row(row, value) { const grid = this.grid; const rowInEditMode = grid.crudService.row; row.newData = value ? value : grid.transactions.getAggregatedValue(row.id, true); if (rowInEditMode && row.id === rowInEditMode.id) { row.data = Object.assign(Object.assign({}, row.data), rowInEditMode.transactionState); // TODO: Workaround for updating a row in edit mode through the API } else if (this.grid.transactions.enabled) { const state = grid.transactions.getState(row.id); row.data = state ? Object.assign({}, row.data, state.value) : row.data; } } update_row(row, value) { const grid = this.grid; const selected = grid.selectionService.isRowSelected(row.id); const rowInEditMode = grid.crudService.row; const data = this.get_all_data(grid.transactions.enabled); const index = this.get_row_index_in_data(row.id); const hasSummarized = grid.hasSummarizedColumns; this._update_row(row, value); const args = row.createEditEventArgs(); // If no valid row is found if (index === -1) { return args; } grid.onRowEdit.emit(args); if (args.cancel) { return args; } if (rowInEditMode) { const hasChanges = grid.transactions.getState(args.rowID, true); grid.transactions.endPending(false); if (!hasChanges) { return args; } } if (!args.newValue) { return args; } if (hasSummarized) { grid.summaryService.removeSummaries(args.rowID); } this.updateData(grid, row.id, data[index], args.oldValue, args.newValue); const newId = grid.primaryKey ? args.newValue[grid.primaryKey] : args.newValue; if (selected) { grid.selectionService.deselectRow(row.id); grid.selectionService.selectRowById(newId); } if (hasSummarized) { grid.summaryService.removeSummaries(newId); } grid._pipeTrigger++; return args; } update_row_in_array(value, rowID, index) { const grid = this.grid; grid.data[index] = value; } sort(expression) { if (expression.dir === SortingDirection.None) { this.remove_grouping_expression(expression.fieldName); } const sortingState = cloneArray(this.grid.sortingExpressions); this.prepare_sorting_expression([sortingState], expression); this.grid.sortingExpressions = sortingState; } sort_multiple(expressions) { const sortingState = cloneArray(this.grid.sortingExpressions); for (const each of expressions) { if (each.dir === SortingDirection.None) { this.remove_grouping_expression(each.fieldName); } this.prepare_sorting_expression([sortingState], each); } this.grid.sortingExpressions = sortingState; } filter(fieldName, term, conditionOrExpressionsTree, ignoreCase) { const grid = this.grid; const filteringTree = grid.filteringExpressionsTree; grid.endEdit(false); if (grid.paging) { grid.page = 0; } const fieldFilterIndex = filteringTree.findIndex(fieldName); if (fieldFilterIndex > -1) { filteringTree.filteringOperands.splice(fieldFilterIndex, 1); } this.prepare_filtering_expression(filteringTree, fieldName, term, conditionOrExpressionsTree, ignoreCase, fieldFilterIndex); grid.filteringExpressionsTree = filteringTree; } filter_global(term, condition, ignoreCase) { if (!condition) { return; } const grid = this.grid; const filteringTree = grid.filteringExpressionsTree; grid.endEdit(false); if (grid.paging) { grid.page = 0; } filteringTree.filteringOperands = []; for (const column of grid.columns) { this.prepare_filtering_expression(filteringTree, column.field, term, condition, ignoreCase || column.filteringIgnoreCase); } grid.filteringExpressionsTree = filteringTree; } clear_filter(fieldName) { const grid = this.grid; grid.endEdit(false); const filteringState = grid.filteringExpressionsTree; const index = filteringState.findIndex(fieldName); if (index > -1) { filteringState.filteringOperands.splice(index, 1); } else if (!fieldName) { filteringState.filteringOperands = []; } grid.filteringExpressionsTree = filteringState; } clear_sort(fieldName) { const sortingState = this.grid.sortingExpressions; const index = sortingState.findIndex((expr) => expr.fieldName === fieldName); if (index > -1) { sortingState.splice(index, 1); this.grid.sortingExpressions = sortingState; } } prepare_filtering_expression(filteringState, fieldName, searchVal, conditionOrExpressionsTree, ignoreCase, insertAtIndex = -1) { let newExpressionsTree; const oldExpressionsTreeIndex = filteringState.findIndex(fieldName); const expressionsTree = conditionOrExpressionsTree instanceof FilteringExpressionsTree ? conditionOrExpressionsTree : null; const condition = conditionOrExpressionsTree instanceof FilteringExpressionsTree ? null : conditionOrExpressionsTree; const newExpression = { fieldName, searchVal, condition, ignoreCase }; if (oldExpressionsTreeIndex === -1) { // no expressions tree found for this field if (expressionsTree) { if (insertAtIndex > -1) { filteringState.filteringOperands.splice(insertAtIndex, 0, expressionsTree); } else { filteringState.filteringOperands.push(expressionsTree); } } else if (condition) { // create expressions tree for this field and add the new expression to it newExpressionsTree = new FilteringExpressionsTree(filteringState.operator, fieldName); newExpressionsTree.filteringOperands.push(newExpression); filteringState.filteringOperands.push(newExpressionsTree); } } } prepare_sorting_expression(stateCollections, expression) { if (expression.dir === SortingDirection.None) { stateCollections.forEach(state => { state.splice(state.findIndex((expr) => expr.fieldName === expression.fieldName), 1); }); return; } /** * We need to make sure the states in each collection with same fields point to the same object reference. * If the different state collections provided have different sizes we need to get the largest one. * That way we can get the state reference from the largest one that has the same fieldName as the expression to prepare. */ let maxCollection = stateCollections[0]; for (let i = 1; i < stateCollections.length; i++) { if (maxCollection.length < stateCollections[i].length) { maxCollection = stateCollections[i]; } } const maxExpr = maxCollection.find((expr) => expr.fieldName === expression.fieldName); stateCollections.forEach(collection => { const myExpr = collection.find((expr) => expr.fieldName === expression.fieldName); if (!myExpr && !maxExpr) { // Expression with this fieldName is missing from the current and the max collection. collection.push(expression); } else if (!myExpr && maxExpr) { // Expression with this fieldName is missing from the current and but the max collection has. collection.push(maxExpr); Object.assign(maxExpr, expression); } else { // The current collection has the expression so just update it. Object.assign(myExpr, expression); } }); } remove_grouping_expression(fieldName) { } clear_groupby(name) { } should_apply_number_style(column) { return column.dataType === DataType.Number; } get_data() { const grid = this.grid; const data = grid.data ? grid.data : []; return data; } get_all_data(includeTransactions = false) { const grid = this.grid; let data = grid.data ? grid.data : []; data = includeTransactions ? grid.dataWithAddedInTransactionRows : data; return data; } get_filtered_data() { return this.grid.filteredData; } getSortStrategyPerColumn(fieldName) { return this.get_column_by_name(fieldName) ? this.get_column_by_name(fieldName).sortStrategy : undefined; } addRowToData(rowData) { // Add row goes to transactions and if rowEditable is properly implemented, added rows will go to pending transactions // If there is a row in edit - > commit and close const grid = this.grid; if (grid.transactions.enabled) { const transactionId = grid.primaryKey ? rowData[grid.primaryKey] : rowData; const transaction = { id: transactionId, type: TransactionType.ADD, newValue: rowData }; grid.transactions.add(transaction); } else { grid.data.push(rowData); } } deleteRowFromData(rowID, index) { // if there is a row (index !== 0) delete it // if there is a row in ADD or UPDATE state change it's state to DELETE const grid = this.grid; if (index !== -1) { if (grid.transactions.enabled) { const transaction = { id: rowID, type: TransactionType.DELETE, newValue: null }; grid.transactions.add(transaction, grid.data[index]); } else { grid.data.splice(index, 1); } } else { const state = grid.transactions.getState(rowID); grid.transactions.add({ id: rowID, type: TransactionType.DELETE, newValue: null }, state && state.recordRef); } } deleteRowById(rowId) { let index; const grid = this.grid; const data = this.get_all_data(); if (grid.primaryKey) { index = data.map((record) => record[grid.primaryKey]).indexOf(rowId); } else { index = data.indexOf(rowId); } const state = grid.transactions.getState(rowId); const hasRowInNonDeletedState = state && state.type !== TransactionType.DELETE; // if there is a row (index !== -1) and the we have cell in edit mode on same row exit edit mode // if there is no row (index === -1), but there is a row in ADD or UPDATE state do as above // Otherwise just exit - there is nothing to delete if (index !== -1 || hasRowInNonDeletedState) { // Always exit edit when row is deleted grid.endEdit(true); } else { return; } // TODO: should we emit this when cascadeOnDelete is true for each row?!?! grid.onRowDeleted.emit({ data: data[index] }); this.deleteRowFromData(rowId, index); grid.selectionService.isRowSelected(rowId) ? grid.selectionService.deselectRow(rowId) : grid.selectionService.clearHeaderCBState(); grid._pipeTrigger++; grid.notifyChanges(); // Data needs to be recalculated if transactions are in place // If no transactions, `data` will be a reference to the grid getter, otherwise it will be stale const dataAfterDelete = grid.transactions.enabled ? grid.dataWithAddedInTransactionRows : data; grid.refreshSearch(); if (dataAfterDelete.length % grid.perPage === 0 && dataAfterDelete.length / grid.perPage - 1 < grid.page && grid.page !== 0) { grid.page--; } } get_row_id(rowData) { return this.grid.primaryKey ? rowData[this.grid.primaryKey] : rowData; } row_deleted_transaction(rowID) { const grid = this.grid; if (!grid) { return false; } if (!grid.transactions.enabled) { return false; } const state = grid.transactions.getState(rowID); if (state) { return state.type === TransactionType.DELETE; } return false; } atInexistingPage() { return this.grid.totalPages - 1 > this.grid.page; } }; GridBaseAPIService = __decorate([ Injectable() ], GridBaseAPIService); export { GridBaseAPIService }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2dyaWRzL2FwaS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRWxFLE9BQU8sRUFBc0IsZ0JBQWdCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUt2RyxPQUFPLEVBQTZCLHdCQUF3QixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDcEgsT0FBTyxFQUFlLGVBQWUsRUFBUyxNQUFNLHFDQUFxQyxDQUFDO0FBSTFGOztHQUVHO0FBRUgsSUFBYSxrQkFBa0IsR0FBL0IsTUFBYSxrQkFBa0I7SUFBL0I7UUFHYyxlQUFVLEdBQWtDLElBQUksR0FBRyxFQUE0QixDQUFDO0lBc2dCOUYsQ0FBQztJQXBnQlUsa0JBQWtCLENBQUMsSUFBWTtRQUNsQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQWUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRU0sZ0JBQWdCO1FBQ25CLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdkIsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUM3QixJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1AsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRTtnQkFDM0IsSUFBSSxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FDN0IsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJ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ZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2xvbmVBcnJheSwgaXNFcXVhbCwgbWVyZ2VPYmplY3RzIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5pbXBvcnQgeyBEYXRhVXRpbCwgRGF0YVR5cGUgfSBmcm9tICcuLi9kYXRhLW9wZXJhdGlvbnMvZGF0YS11dGlsJztcbmltcG9ydCB7IElGaWx0ZXJpbmdFeHByZXNzaW9uIH0gZnJvbSAnLi4vZGF0YS1vcGVyYXRpb25zL2ZpbHRlcmluZy1leHByZXNzaW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBJU29ydGluZ0V4cHJlc3Npb24sIFNvcnRpbmdEaXJlY3Rpb24gfSBmcm9tICcuLi9kYXRhLW9wZXJhdGlvbnMvc29ydGluZy1leHByZXNzaW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBJZ3hHcmlkQ2VsbENvbXBvbmVudCB9IGZyb20gJy4vY2VsbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4R3JpZEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2dyaWQtYmFzZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgSWd4Um93RGlyZWN0aXZlIH0gZnJvbSAnLi9yb3cuZGlyZWN0aXZlJztcbmltcG9ydCB7IElGaWx0ZXJpbmdPcGVyYXRpb24gfSBmcm9tICcuLi9kYXRhLW9wZXJhdGlvbnMvZmlsdGVyaW5nLWNvbmRpdGlvbic7XG5pbXBvcnQgeyBJRmlsdGVyaW5nRXhwcmVzc2lvbnNUcmVlLCBGaWx0ZXJpbmdFeHByZXNzaW9uc1RyZWUgfSBmcm9tICcuLi9kYXRhLW9wZXJhdGlvbnMvZmlsdGVyaW5nLWV4cHJlc3Npb25zLXRyZWUnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uVHlwZSwgU3RhdGUgfSBmcm9tICcuLi9zZXJ2aWNlcy90cmFuc2FjdGlvbi90cmFuc2FjdGlvbic7XG5pbXBvcnQgeyBJZ3hDZWxsLCBJZ3hSb3cgfSBmcm9tICcuL3NlbGVjdGlvbi9zZWxlY3Rpb24uc2VydmljZSc7XG5pbXBvcnQgeyBHcmlkVHlwZSB9IGZyb20gJy4vY29tbW9uL2dyaWQuaW50ZXJmYWNlJztcbmltcG9ydCB7IENvbHVtblR5cGUgfSBmcm9tICcuL2NvbW1vbi9jb2x1bW4uaW50ZXJmYWNlJztcbi8qKlxuICpAaGlkZGVuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBHcmlkQmFzZUFQSVNlcnZpY2UgPFQgZXh0ZW5kcyBJZ3hHcmlkQmFzZURpcmVjdGl2ZSAmIEdyaWRUeXBlPiB7XG5cbiAgICBncmlkOiBUO1xuICAgIHByb3RlY3RlZCBkZXN0cm95TWFwOiBNYXA8c3RyaW5nLCBTdWJqZWN0PGJvb2xlYW4+PiA9IG5ldyBNYXA8c3RyaW5nLCBTdWJqZWN0PGJvb2xlYW4+PigpO1xuXG4gICAgcHVibGljIGdldF9jb2x1bW5fYnlfbmFtZShuYW1lOiBzdHJpbmcpOiBDb2x1bW5UeXBlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZC5jb2x1bW5MaXN0LmZpbmQoKGNvbDogQ29sdW1uVHlwZSkgPT4gY29sLmZpZWxkID09PSBuYW1lKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0X3N1bW1hcnlfZGF0YSgpIHtcbiAgICAgICAgY29uc3QgZ3JpZCA9IHRoaXMuZ3JpZDtcbiAgICAgICAgbGV0IGRhdGEgPSBncmlkLmZpbHRlcmVkRGF0YTtcbiAgICAgICAgaWYgKCFkYXRhKSB7XG4gICAgICAgICAgICBpZiAoZ3JpZC50cmFuc2FjdGlvbnMuZW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBEYXRhVXRpbC5tZXJnZVRyYW5zYWN0aW9ucyhcbiAgICAgICAgICAgICAgICAgICAgY2xvbmVBcnJheShncmlkLmRhdGEpLFxuICAgICAgICAgICAgICAgICAgICBncmlkLnRyYW5zYWN0aW9ucy5nZXRBZ2dyZWdhdGVkQ2hhbmdlcyh0cnVlKSxcbiAgICAgICAgICAgICAgICAgICAgZ3JpZC5wcmltYXJ5S2V5XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkZWxldGVkUm93cyA9IGdyaWQudHJhbnNhY3Rpb25zLmdldFRyYW5zYWN0aW9uTG9nKCkuZmlsdGVyKHQgPT4gdC50eXBlID09PSBUcmFuc2FjdGlvblR5cGUuREVMRVRFKS5tYXAodCA9PiB0LmlkKTtcbiAgICAgICAgICAgICAgICBkZWxldGVkUm93cy5mb3JFYWNoKHJvd0lEID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVtcERhdGEgPSBncmlkLnByaW1hcnlLZXkgPyBkYXRhLm1hcChyZWMgPT4gcmVjW2dyaWQucHJpbWFyeUtleV0pIDogZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0ZW1wRGF0YS5pbmRleE9mKHJvd0lEKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICBkYXRhLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IGdyaWQuZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIGdldFJvd0RhdGEocm93SUQ6IGFueSkge1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5nZXRfYWxsX2RhdGEodGhpcy5ncmlkLnRyYW5zYWN0aW9ucy5lbmFibGVkKTtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmdldF9yb3dfaW5kZXhfaW5fZGF0YShyb3dJRCk7XG4gICAgICAgIHJldHVybiBkYXRhW2luZGV4XTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBSZWZhY3RvclxuICAgIHB1YmxpYyBlc2NhcGVfZWRpdE1vZGUoKSB7XG4gICAgICAgIHRoaXMuZ3JpZC5jcnVkU2VydmljZS5lbmQoKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBSZWZhY3RvclxuICAgIHB1YmxpYyBnZXRfY2VsbF9pbkVkaXRNb2RlKCk6IElneENlbGwge1xuICAgICAgICByZXR1cm4gdGhpcy5ncmlkLmNydWRTZXJ2aWNlLmNlbGw7XG4gICAgfVxuXG4gICAgcHVibGljIGdldF9yb3dfaW5kZXhfaW5fZGF0YShyb3dJRDogYW55KTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgZ3JpZCA9IHRoaXMuZ3JpZCBhcyBJZ3hHcmlkQmFzZURpcmVjdGl2ZTtcbiAgICAgICAgaWYgKCFncmlkKSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2V0X2FsbF9kYXRhKGdyaWQudHJhbnNhY3Rpb25zLmVuYWJsZWQpO1xuICAgICAgICByZXR1cm4gZ3JpZC5wcmltYXJ5S2V5ID8gZGF0YS5maW5kSW5kZXgocmVjb3JkID0+IHJlY29yZFtncmlkLnByaW1hcnlLZXldID09PSByb3dJRCkgOiBkYXRhLmluZGV4T2Yocm93SUQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRfcm93X2J5X2tleShyb3dTZWxlY3RvcjogYW55KTogSWd4Um93RGlyZWN0aXZlPElneEdyaWRCYXNlRGlyZWN0aXZlICYgR3JpZFR5cGU+IHtcbiAgICAgICAgY29uc3QgcHJpbWFyeUtleSA9IHRoaXMuZ3JpZC5wcmltYXJ5S2V5O1xuICAgICAgICBpZiAocHJpbWFyeUtleSAhPT0gdW5kZWZpbmVkICYmIHByaW1hcnlLZXkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdyaWQuZGF0YVJvd0xpc3QuZmluZCgocm93KSA9PiByb3cucm93RGF0YVtwcmltYXJ5S2V5XSA9PT0gcm93U2VsZWN0b3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZC5kYXRhUm93TGlzdC5maW5kKChyb3cpID0+IHJvdy5yb3dEYXRhID09PSByb3dTZWxlY3Rvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0X3Jvd19ieV9pbmRleChyb3dJbmRleDogbnVtYmVyKTogSWd4Um93RGlyZWN0aXZlPElneEdyaWRCYXNlRGlyZWN0aXZlICYgR3JpZFR5cGU+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZC5yb3dMaXN0LmZpbmQoKHJvdykgPT4gcm93LmluZGV4ID09PSByb3dJbmRleCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldF9jZWxsX2J5X2tleShyb3dTZWxlY3RvcjogYW55LCBmaWVsZDogc3RyaW5nKTogSWd4R3JpZENlbGxDb21wb25lbnQge1xuICAgICAgICBjb25zdCByb3cgPSB0aGlzLmdldF9yb3dfYnlfa2V5KHJvd1NlbGVjdG9yKTtcbiAgICAgICAgaWYgKHJvdyAmJiByb3cuY2VsbHMpIHtcbiAgICAgICAgICAgIHJldHVybiByb3cuY2VsbHMuZmluZCgoY2VsbCkgPT4gY2VsbC5jb2x1bW4uZmllbGQgPT09IGZpZWxkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRfY2VsbF9ieV9pbmRleChyb3dJbmRleDogbnVtYmVyLCBjb2x1bW5JbmRleDogbnVtYmVyKTogSWd4R3JpZENlbGxDb21wb25lbnQge1xuICAgICAgICBjb25zdCByb3cgPSB0aGlzLmdldF9yb3dfYnlfaW5kZXgocm93SW5kZXgpO1xuICAgICAgICBpZiAocm93ICYmIHJvdy5jZWxscykge1xuICAgICAgICAgICAgcmV0dXJuIHJvdy5jZWxscy5maW5kKChjZWxsKSA9PiBjZWxsLmNvbHVtbkluZGV4ID09PSBjb2x1bW5JbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0X2NlbGxfYnlfdmlzaWJsZV9pbmRleChyb3dJbmRleDogbnVtYmVyLCBjb2x1bW5JbmRleDogbnVtYmVyKTogSWd4R3JpZENlbGxDb21wb25lbnQge1xuICAgICAgICBjb25zdCByb3cgPSB0aGlzLmdldF9yb3dfYnlfaW5kZXgocm93SW5kZXgpO1xuICAgICAgICBpZiAocm93ICYmIHJvdy5jZWxscykge1xuICAgICAgICAgICAgcmV0dXJuIHJvdy5jZWxscy5maW5kKChjZWxsKSA9PiBjZWxsLnZpc2libGVDb2x1bW5JbmRleCA9PT0gY29sdW1uSW5kZXgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN1Ym1pdF92YWx1ZSgpIHtcbiAgICAgICAgY29uc3QgY2VsbCA9IHRoaXMuZ3JpZC5jcnVkU2VydmljZS5jZWxsO1xuICAgICAgICBpZiAoY2VsbCApIHtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLnVwZGF0ZV9jZWxsKGNlbGwsIGNlbGwuZWRpdFZhbHVlKTtcbiAgICAgICAgICAgIGlmIChhcmdzLmNhbmNlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZXNjYXBlX2VkaXRNb2RlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVfY2VsbChjZWxsOiBJZ3hDZWxsLCB2YWx1ZTogYW55KSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldF9hbGxfZGF0YSh0aGlzLmdyaWQudHJhbnNhY3Rpb25zLmVuYWJsZWQpO1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuZ2V0X3Jvd19pbmRleF9pbl9kYXRhKGNlbGwuaWQucm93SUQpO1xuXG4gICAgICAgIGNlbGwuZWRpdFZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgY29uc3QgYXJncyA9IGNlbGwuY3JlYXRlRWRpdEV2ZW50QXJncygpO1xuXG4gICAgICAgIHRoaXMuZ3JpZC5vbkNlbGxFZGl0LmVtaXQoYXJncyk7XG4gICAgICAgIGlmIChhcmdzLmNhbmNlbCkge1xuICAgICAgICAgICAgcmV0dXJuIGFyZ3M7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDYXN0IHRvIG51bWJlciBhZnRlciBlbWl0XG4gICAgICAgIC8vIFRPRE86IENsZWFuIHVwIHRoaXNcbiAgICAgICAgYXJncy5uZXdWYWx1ZSA9IGNlbGwuY2FzdFRvTnVtYmVyKGFyZ3MubmV3VmFsdWUpO1xuXG4gICAgICAgIGlmIChpc0VxdWFsKGFyZ3Mub2xkVmFsdWUsIGFyZ3MubmV3VmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJncztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZ3JpZC5zdW1tYXJ5U2VydmljZS5jbGVhclN1bW1hcnlDYWNoZShhcmdzKTtcbiAgICAgICAgdGhpcy51cGRhdGVEYXRhKHRoaXMuZ3JpZCwgY2VsbC5pZC5yb3dJRCwgZGF0YVtpbmRleF0sIGNlbGwucm93RGF0YSwgeyBbY2VsbC5jb2x1bW4uZmllbGQgXTogYXJncy5uZXdWYWx1ZSB9KTtcbiAgICAgICAgaWYgKHRoaXMuZ3JpZC5wcmltYXJ5S2V5ID09PSBjZWxsLmNvbHVtbi5maWVsZCkge1xuICAgICAgICAgICAgIGlmICh0aGlzLmdyaWQuc2VsZWN0aW9uU2VydmljZS5pc1Jvd1NlbGVjdGVkKGNlbGwuaWQucm93SUQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ncmlkLnNlbGVjdGlvblNlcnZpY2UuZGVzZWxlY3RSb3coY2VsbC5pZC5yb3dJRCk7XG4gICAgICAgICAgICAgICAgdGhpcy5ncmlkLnNlbGVjdGlvblNlcnZpY2Uuc2VsZWN0Um93QnlJZChhcmdzLm5ld1Zh