@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
465 lines • 70.4 kB
JavaScript
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