matrix-react-sdk
Version:
SDK for matrix.org using React
168 lines (160 loc) • 25.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.NaturalAlgorithm = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _logger = require("matrix-js-sdk/src/logger");
var _tagSorting = require("../tag-sorting");
var _OrderingAlgorithm = require("./OrderingAlgorithm");
var _models = require("../../models");
var _RoomNotificationStateStore = require("../../../notifications/RoomNotificationStateStore");
/*
Copyright 2024 New Vector Ltd.
Copyright 2020 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
/**
* Uses the natural tag sorting algorithm order to determine tag ordering. No
* additional behavioural changes are present.
*/
class NaturalAlgorithm extends _OrderingAlgorithm.OrderingAlgorithm {
constructor(tagId, initialSortingAlgorithm) {
super(tagId, initialSortingAlgorithm);
(0, _defineProperty2.default)(this, "cachedCategorizedOrderedRooms", {
defaultRooms: [],
mutedRooms: []
});
}
setRooms(rooms) {
const {
defaultRooms,
mutedRooms
} = this.categorizeRooms(rooms);
this.cachedCategorizedOrderedRooms = {
defaultRooms: (0, _tagSorting.sortRoomsWithAlgorithm)(defaultRooms, this.tagId, this.sortingAlgorithm),
mutedRooms: (0, _tagSorting.sortRoomsWithAlgorithm)(mutedRooms, this.tagId, this.sortingAlgorithm)
};
this.buildCachedOrderedRooms();
}
handleRoomUpdate(room, cause) {
const isSplice = cause === _models.RoomUpdateCause.NewRoom || cause === _models.RoomUpdateCause.RoomRemoved;
const isInPlace = cause === _models.RoomUpdateCause.Timeline || cause === _models.RoomUpdateCause.ReadReceipt || cause === _models.RoomUpdateCause.PossibleMuteChange;
const isMuted = this.isMutedToBottom && this.getRoomIsMuted(room);
if (!isSplice && !isInPlace) {
throw new Error(`Unsupported update cause: ${cause}`);
}
if (cause === _models.RoomUpdateCause.NewRoom) {
if (isMuted) {
this.cachedCategorizedOrderedRooms.mutedRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.mutedRooms, room], this.tagId, this.sortingAlgorithm);
} else {
this.cachedCategorizedOrderedRooms.defaultRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.defaultRooms, room], this.tagId, this.sortingAlgorithm);
}
this.buildCachedOrderedRooms();
return true;
} else if (cause === _models.RoomUpdateCause.RoomRemoved) {
return this.removeRoom(room);
} else if (cause === _models.RoomUpdateCause.PossibleMuteChange) {
if (this.isMutedToBottom) {
return this.onPossibleMuteChange(room);
} else {
return false;
}
}
// TODO: Optimize this to avoid useless operations: https://github.com/vector-im/element-web/issues/14457
// For example, we can skip updates to alphabetic (sometimes) and manually ordered tags
if (isMuted) {
this.cachedCategorizedOrderedRooms.mutedRooms = (0, _tagSorting.sortRoomsWithAlgorithm)(this.cachedCategorizedOrderedRooms.mutedRooms, this.tagId, this.sortingAlgorithm);
} else {
this.cachedCategorizedOrderedRooms.defaultRooms = (0, _tagSorting.sortRoomsWithAlgorithm)(this.cachedCategorizedOrderedRooms.defaultRooms, this.tagId, this.sortingAlgorithm);
}
this.buildCachedOrderedRooms();
return true;
}
/**
* Remove a room from the cached room list
* @param room Room to remove
* @returns {boolean} true when room list should update as result
*/
removeRoom(room) {
const defaultIndex = this.cachedCategorizedOrderedRooms.defaultRooms.findIndex(r => r.roomId === room.roomId);
if (defaultIndex > -1) {
this.cachedCategorizedOrderedRooms.defaultRooms.splice(defaultIndex, 1);
this.buildCachedOrderedRooms();
return true;
}
const mutedIndex = this.cachedCategorizedOrderedRooms.mutedRooms.findIndex(r => r.roomId === room.roomId);
if (mutedIndex > -1) {
this.cachedCategorizedOrderedRooms.mutedRooms.splice(mutedIndex, 1);
this.buildCachedOrderedRooms();
return true;
}
_logger.logger.warn(`Tried to remove unknown room from ${this.tagId}: ${room.roomId}`);
// room was not in cached lists, no update
return false;
}
/**
* Sets cachedOrderedRooms from cachedCategorizedOrderedRooms
*/
buildCachedOrderedRooms() {
this.cachedOrderedRooms = [...this.cachedCategorizedOrderedRooms.defaultRooms, ...this.cachedCategorizedOrderedRooms.mutedRooms];
}
getRoomIsMuted(room) {
// It's fine for us to call this a lot because it's cached, and we shouldn't be
// wasting anything by doing so as the store holds single references
const state = _RoomNotificationStateStore.RoomNotificationStateStore.instance.getRoomState(room);
return state.muted;
}
categorizeRooms(rooms) {
if (!this.isMutedToBottom) {
return {
defaultRooms: rooms,
mutedRooms: []
};
}
return rooms.reduce((acc, room) => {
if (this.getRoomIsMuted(room)) {
acc.mutedRooms.push(room);
} else {
acc.defaultRooms.push(room);
}
return acc;
}, {
defaultRooms: [],
mutedRooms: []
});
}
onPossibleMuteChange(room) {
const isMuted = this.getRoomIsMuted(room);
if (isMuted) {
const defaultIndex = this.cachedCategorizedOrderedRooms.defaultRooms.findIndex(r => r.roomId === room.roomId);
// room has been muted
if (defaultIndex > -1) {
// remove from the default list
this.cachedCategorizedOrderedRooms.defaultRooms.splice(defaultIndex, 1);
// add to muted list and reorder
this.cachedCategorizedOrderedRooms.mutedRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.mutedRooms, room], this.tagId, this.sortingAlgorithm);
// rebuild
this.buildCachedOrderedRooms();
return true;
}
} else {
const mutedIndex = this.cachedCategorizedOrderedRooms.mutedRooms.findIndex(r => r.roomId === room.roomId);
// room has been unmuted
if (mutedIndex > -1) {
// remove from the muted list
this.cachedCategorizedOrderedRooms.mutedRooms.splice(mutedIndex, 1);
// add to default list and reorder
this.cachedCategorizedOrderedRooms.defaultRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.defaultRooms, room], this.tagId, this.sortingAlgorithm);
// rebuild
this.buildCachedOrderedRooms();
return true;
}
}
return false;
}
}
exports.NaturalAlgorithm = NaturalAlgorithm;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9nZ2VyIiwicmVxdWlyZSIsIl90YWdTb3J0aW5nIiwiX09yZGVyaW5nQWxnb3JpdGhtIiwiX21vZGVscyIsIl9Sb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZSIsIk5hdHVyYWxBbGdvcml0aG0iLCJPcmRlcmluZ0FsZ29yaXRobSIsImNvbnN0cnVjdG9yIiwidGFnSWQiLCJpbml0aWFsU29ydGluZ0FsZ29yaXRobSIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZGVmYXVsdFJvb21zIiwibXV0ZWRSb29tcyIsInNldFJvb21zIiwicm9vbXMiLCJjYXRlZ29yaXplUm9vbXMiLCJjYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcyIsInNvcnRSb29tc1dpdGhBbGdvcml0aG0iLCJzb3J0aW5nQWxnb3JpdGhtIiwiYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMiLCJoYW5kbGVSb29tVXBkYXRlIiwicm9vbSIsImNhdXNlIiwiaXNTcGxpY2UiLCJSb29tVXBkYXRlQ2F1c2UiLCJOZXdSb29tIiwiUm9vbVJlbW92ZWQiLCJpc0luUGxhY2UiLCJUaW1lbGluZSIsIlJlYWRSZWNlaXB0IiwiUG9zc2libGVNdXRlQ2hhbmdlIiwiaXNNdXRlZCIsImlzTXV0ZWRUb0JvdHRvbSIsImdldFJvb21Jc011dGVkIiwiRXJyb3IiLCJyZW1vdmVSb29tIiwib25Qb3NzaWJsZU11dGVDaGFuZ2UiLCJkZWZhdWx0SW5kZXgiLCJmaW5kSW5kZXgiLCJyIiwicm9vbUlkIiwic3BsaWNlIiwibXV0ZWRJbmRleCIsImxvZ2dlciIsIndhcm4iLCJjYWNoZWRPcmRlcmVkUm9vbXMiLCJzdGF0ZSIsIlJvb21Ob3RpZmljYXRpb25TdGF0ZVN0b3JlIiwiaW5zdGFuY2UiLCJnZXRSb29tU3RhdGUiLCJtdXRlZCIsInJlZHVjZSIsImFjYyIsInB1c2giLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3N0b3Jlcy9yb29tLWxpc3QvYWxnb3JpdGhtcy9saXN0LW9yZGVyaW5nL05hdHVyYWxBbGdvcml0aG0udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgUm9vbSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcblxuaW1wb3J0IHsgU29ydEFsZ29yaXRobSB9IGZyb20gXCIuLi9tb2RlbHNcIjtcbmltcG9ydCB7IHNvcnRSb29tc1dpdGhBbGdvcml0aG0gfSBmcm9tIFwiLi4vdGFnLXNvcnRpbmdcIjtcbmltcG9ydCB7IE9yZGVyaW5nQWxnb3JpdGhtIH0gZnJvbSBcIi4vT3JkZXJpbmdBbGdvcml0aG1cIjtcbmltcG9ydCB7IFJvb21VcGRhdGVDYXVzZSwgVGFnSUQgfSBmcm9tIFwiLi4vLi4vbW9kZWxzXCI7XG5pbXBvcnQgeyBSb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZSB9IGZyb20gXCIuLi8uLi8uLi9ub3RpZmljYXRpb25zL1Jvb21Ob3RpZmljYXRpb25TdGF0ZVN0b3JlXCI7XG5cbnR5cGUgTmF0dXJhbENhdGVnb3JpemVkUm9vbU1hcCA9IHtcbiAgICBkZWZhdWx0Um9vbXM6IFJvb21bXTtcbiAgICBtdXRlZFJvb21zOiBSb29tW107XG59O1xuXG4vKipcbiAqIFVzZXMgdGhlIG5hdHVyYWwgdGFnIHNvcnRpbmcgYWxnb3JpdGhtIG9yZGVyIHRvIGRldGVybWluZSB0YWcgb3JkZXJpbmcuIE5vXG4gKiBhZGRpdGlvbmFsIGJlaGF2aW91cmFsIGNoYW5nZXMgYXJlIHByZXNlbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOYXR1cmFsQWxnb3JpdGhtIGV4dGVuZHMgT3JkZXJpbmdBbGdvcml0aG0ge1xuICAgIHByaXZhdGUgY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXM6IE5hdHVyYWxDYXRlZ29yaXplZFJvb21NYXAgPSB7XG4gICAgICAgIGRlZmF1bHRSb29tczogW10sXG4gICAgICAgIG11dGVkUm9vbXM6IFtdLFxuICAgIH07XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHRhZ0lkOiBUYWdJRCwgaW5pdGlhbFNvcnRpbmdBbGdvcml0aG06IFNvcnRBbGdvcml0aG0pIHtcbiAgICAgICAgc3VwZXIodGFnSWQsIGluaXRpYWxTb3J0aW5nQWxnb3JpdGhtKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Um9vbXMocm9vbXM6IFJvb21bXSk6IHZvaWQge1xuICAgICAgICBjb25zdCB7IGRlZmF1bHRSb29tcywgbXV0ZWRSb29tcyB9ID0gdGhpcy5jYXRlZ29yaXplUm9vbXMocm9vbXMpO1xuXG4gICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMgPSB7XG4gICAgICAgICAgICBkZWZhdWx0Um9vbXM6IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oZGVmYXVsdFJvb21zLCB0aGlzLnRhZ0lkLCB0aGlzLnNvcnRpbmdBbGdvcml0aG0pLFxuICAgICAgICAgICAgbXV0ZWRSb29tczogc29ydFJvb21zV2l0aEFsZ29yaXRobShtdXRlZFJvb21zLCB0aGlzLnRhZ0lkLCB0aGlzLnNvcnRpbmdBbGdvcml0aG0pLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmJ1aWxkQ2FjaGVkT3JkZXJlZFJvb21zKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGhhbmRsZVJvb21VcGRhdGUocm9vbTogUm9vbSwgY2F1c2U6IFJvb21VcGRhdGVDYXVzZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBpc1NwbGljZSA9IGNhdXNlID09PSBSb29tVXBkYXRlQ2F1c2UuTmV3Um9vbSB8fCBjYXVzZSA9PT0gUm9vbVVwZGF0ZUNhdXNlLlJvb21SZW1vdmVkO1xuICAgICAgICBjb25zdCBpc0luUGxhY2UgPVxuICAgICAgICAgICAgY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5UaW1lbGluZSB8fFxuICAgICAgICAgICAgY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5SZWFkUmVjZWlwdCB8fFxuICAgICAgICAgICAgY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5Qb3NzaWJsZU11dGVDaGFuZ2U7XG4gICAgICAgIGNvbnN0IGlzTXV0ZWQgPSB0aGlzLmlzTXV0ZWRUb0JvdHRvbSAmJiB0aGlzLmdldFJvb21Jc011dGVkKHJvb20pO1xuXG4gICAgICAgIGlmICghaXNTcGxpY2UgJiYgIWlzSW5QbGFjZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCB1cGRhdGUgY2F1c2U6ICR7Y2F1c2V9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5OZXdSb29tKSB7XG4gICAgICAgICAgICBpZiAoaXNNdXRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcyA9IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgICAgIFsuLi50aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMgPSBzb3J0Um9vbXNXaXRoQWxnb3JpdGhtKFxuICAgICAgICAgICAgICAgICAgICBbLi4udGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGNhdXNlID09PSBSb29tVXBkYXRlQ2F1c2UuUm9vbVJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlbW92ZVJvb20ocm9vbSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5Qb3NzaWJsZU11dGVDaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTXV0ZWRUb0JvdHRvbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9uUG9zc2libGVNdXRlQ2hhbmdlKHJvb20pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUT0RPOiBPcHRpbWl6ZSB0aGlzIHRvIGF2b2lkIHVzZWxlc3Mgb3BlcmF0aW9uczogaHR0cHM6Ly9naXRodWIuY29tL3ZlY3Rvci1pbS9lbGVtZW50LXdlYi9pc3N1ZXMvMTQ0NTdcbiAgICAgICAgLy8gRm9yIGV4YW1wbGUsIHdlIGNhbiBza2lwIHVwZGF0ZXMgdG8gYWxwaGFiZXRpYyAoc29tZXRpbWVzKSBhbmQgbWFudWFsbHkgb3JkZXJlZCB0YWdzXG4gICAgICAgIGlmIChpc011dGVkKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMgPSBzb3J0Um9vbXNXaXRoQWxnb3JpdGhtKFxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcyxcbiAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgIHRoaXMuc29ydGluZ0FsZ29yaXRobSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcyA9IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsXG4gICAgICAgICAgICAgICAgdGhpcy50YWdJZCxcbiAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgcm9vbSBmcm9tIHRoZSBjYWNoZWQgcm9vbSBsaXN0XG4gICAgICogQHBhcmFtIHJvb20gUm9vbSB0byByZW1vdmVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSB3aGVuIHJvb20gbGlzdCBzaG91bGQgdXBkYXRlIGFzIHJlc3VsdFxuICAgICAqL1xuICAgIHByaXZhdGUgcmVtb3ZlUm9vbShyb29tOiBSb29tKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRJbmRleCA9IHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMuZGVmYXVsdFJvb21zLmZpbmRJbmRleCgocikgPT4gci5yb29tSWQgPT09IHJvb20ucm9vbUlkKTtcbiAgICAgICAgaWYgKGRlZmF1bHRJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcy5zcGxpY2UoZGVmYXVsdEluZGV4LCAxKTtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG11dGVkSW5kZXggPSB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMuZmluZEluZGV4KChyKSA9PiByLnJvb21JZCA9PT0gcm9vbS5yb29tSWQpO1xuICAgICAgICBpZiAobXV0ZWRJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMuc3BsaWNlKG11dGVkSW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5idWlsZENhY2hlZE9yZGVyZWRSb29tcygpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBsb2dnZXIud2FybihgVHJpZWQgdG8gcmVtb3ZlIHVua25vd24gcm9vbSBmcm9tICR7dGhpcy50YWdJZH06ICR7cm9vbS5yb29tSWR9YCk7XG4gICAgICAgIC8vIHJvb20gd2FzIG5vdCBpbiBjYWNoZWQgbGlzdHMsIG5vIHVwZGF0ZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBjYWNoZWRPcmRlcmVkUm9vbXMgZnJvbSBjYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tc1xuICAgICAqL1xuICAgIHByaXZhdGUgYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2FjaGVkT3JkZXJlZFJvb21zID0gW1xuICAgICAgICAgICAgLi4udGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsXG4gICAgICAgICAgICAuLi50aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMsXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSb29tSXNNdXRlZChyb29tOiBSb29tKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIEl0J3MgZmluZSBmb3IgdXMgdG8gY2FsbCB0aGlzIGEgbG90IGJlY2F1c2UgaXQncyBjYWNoZWQsIGFuZCB3ZSBzaG91bGRuJ3QgYmVcbiAgICAgICAgLy8gd2FzdGluZyBhbnl0aGluZyBieSBkb2luZyBzbyBhcyB0aGUgc3RvcmUgaG9sZHMgc2luZ2xlIHJlZmVyZW5jZXNcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBSb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZS5pbnN0YW5jZS5nZXRSb29tU3RhdGUocm9vbSk7XG4gICAgICAgIHJldHVybiBzdGF0ZS5tdXRlZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhdGVnb3JpemVSb29tcyhyb29tczogUm9vbVtdKTogTmF0dXJhbENhdGVnb3JpemVkUm9vbU1hcCB7XG4gICAgICAgIGlmICghdGhpcy5pc011dGVkVG9Cb3R0b20pIHtcbiAgICAgICAgICAgIHJldHVybiB7IGRlZmF1bHRSb29tczogcm9vbXMsIG11dGVkUm9vbXM6IFtdIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJvb21zLnJlZHVjZTxOYXR1cmFsQ2F0ZWdvcml6ZWRSb29tTWFwPihcbiAgICAgICAgICAgIChhY2MsIHJvb206IFJvb20pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRSb29tSXNNdXRlZChyb29tKSkge1xuICAgICAgICAgICAgICAgICAgICBhY2MubXV0ZWRSb29tcy5wdXNoKHJvb20pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFjYy5kZWZhdWx0Um9vbXMucHVzaChyb29tKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IGRlZmF1bHRSb29tczogW10sIG11dGVkUm9vbXM6IFtdIH0gYXMgTmF0dXJhbENhdGVnb3JpemVkUm9vbU1hcCxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUG9zc2libGVNdXRlQ2hhbmdlKHJvb206IFJvb20pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgaXNNdXRlZCA9IHRoaXMuZ2V0Um9vbUlzTXV0ZWQocm9vbSk7XG4gICAgICAgIGlmIChpc011dGVkKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0SW5kZXggPSB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcy5maW5kSW5kZXgoXG4gICAgICAgICAgICAgICAgKHIpID0+IHIucm9vbUlkID09PSByb29tLnJvb21JZCxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIHJvb20gaGFzIGJlZW4gbXV0ZWRcbiAgICAgICAgICAgIGlmIChkZWZhdWx0SW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBmcm9tIHRoZSBkZWZhdWx0IGxpc3RcbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcy5zcGxpY2UoZGVmYXVsdEluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAvLyBhZGQgdG8gbXV0ZWQgbGlzdCBhbmQgcmVvcmRlclxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcyA9IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgICAgIFsuLi50aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAvLyByZWJ1aWxkXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZENhY2hlZE9yZGVyZWRSb29tcygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbXV0ZWRJbmRleCA9IHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcy5maW5kSW5kZXgoKHIpID0+IHIucm9vbUlkID09PSByb29tLnJvb21JZCk7XG5cbiAgICAgICAgICAgIC8vIHJvb20gaGFzIGJlZW4gdW5tdXRlZFxuICAgICAgICAgICAgaWYgKG11dGVkSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBmcm9tIHRoZSBtdXRlZCBsaXN0XG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5tdXRlZFJvb21zLnNwbGljZShtdXRlZEluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAvLyBhZGQgdG8gZGVmYXVsdCBsaXN0IGFuZCByZW9yZGVyXG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMgPSBzb3J0Um9vbXNXaXRoQWxnb3JpdGhtKFxuICAgICAgICAgICAgICAgICAgICBbLi4udGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAvLyByZWJ1aWxkXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZENhY2hlZE9yZGVyZWRSb29tcygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFTQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFHQSxJQUFBQyxXQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxrQkFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksMkJBQUEsR0FBQUosT0FBQTtBQWZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQWdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1LLGdCQUFnQixTQUFTQyxvQ0FBaUIsQ0FBQztFQUs3Q0MsV0FBV0EsQ0FBQ0MsS0FBWSxFQUFFQyx1QkFBc0MsRUFBRTtJQUNyRSxLQUFLLENBQUNELEtBQUssRUFBRUMsdUJBQXVCLENBQUM7SUFBQyxJQUFBQyxnQkFBQSxDQUFBQyxPQUFBLHlDQUx5QjtNQUMvREMsWUFBWSxFQUFFLEVBQUU7TUFDaEJDLFVBQVUsRUFBRTtJQUNoQixDQUFDO0VBR0Q7RUFFT0MsUUFBUUEsQ0FBQ0MsS0FBYSxFQUFRO0lBQ2pDLE1BQU07TUFBRUgsWUFBWTtNQUFFQztJQUFXLENBQUMsR0FBRyxJQUFJLENBQUNHLGVBQWUsQ0FBQ0QsS0FBSyxDQUFDO0lBRWhFLElBQUksQ0FBQ0UsNkJBQTZCLEdBQUc7TUFDakNMLFlBQVksRUFBRSxJQUFBTSxrQ0FBc0IsRUFBQ04sWUFBWSxFQUFFLElBQUksQ0FBQ0osS0FBSyxFQUFFLElBQUksQ0FBQ1csZ0JBQWdCLENBQUM7TUFDckZOLFVBQVUsRUFBRSxJQUFBSyxrQ0FBc0IsRUFBQ0wsVUFBVSxFQUFFLElBQUksQ0FBQ0wsS0FBSyxFQUFFLElBQUksQ0FBQ1csZ0JBQWdCO0lBQ3BGLENBQUM7SUFDRCxJQUFJLENBQUNDLHVCQUF1QixDQUFDLENBQUM7RUFDbEM7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