UNPKG

matrix-react-sdk

Version:
324 lines (251 loc) 36.1 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _utils = require("flux/utils"); var _dispatcher = _interopRequireDefault(require("../dispatcher/dispatcher")); var _GroupStore = _interopRequireDefault(require("./GroupStore")); var _Analytics = _interopRequireDefault(require("../Analytics")); var RoomNotifs = _interopRequireWildcard(require("../RoomNotifs")); var _MatrixClientPeg = require("../MatrixClientPeg"); var _SettingsStore = _interopRequireDefault(require("../settings/SettingsStore")); /* Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ const INITIAL_STATE = { orderedTags: null, orderedTagsAccountData: null, hasSynced: false, joinedGroupIds: null, selectedTags: [], // Last selected tag when shift was not being pressed anchorTag: null }; /** * A class for storing application state for ordering tags in the GroupFilterPanel. */ class GroupFilterOrderStore extends _utils.Store { constructor() { super(_dispatcher.default); // Initialise state this._state = Object.assign({}, INITIAL_STATE); _SettingsStore.default.monitorSetting("TagPanel.enableTagPanel", null); } _setState(newState) { this._state = Object.assign(this._state, newState); this.__emitChange(); } __onDispatch(payload) { switch (payload.action) { // Initialise state after initial sync case 'view_room': { const relatedGroupIds = _GroupStore.default.getGroupIdsForRoomId(payload.room_id); this._updateBadges(relatedGroupIds); break; } case 'MatrixActions.sync': { if (payload.state === 'SYNCING' || payload.state === 'PREPARED') { this._updateBadges(); } if (!(payload.prevState !== 'PREPARED' && payload.state === 'PREPARED')) { break; } const tagOrderingEvent = payload.matrixClient.getAccountData('im.vector.web.tag_ordering'); const tagOrderingEventContent = tagOrderingEvent ? tagOrderingEvent.getContent() : {}; this._setState({ orderedTagsAccountData: tagOrderingEventContent.tags || null, removedTagsAccountData: tagOrderingEventContent.removedTags || null, hasSynced: true }); this._updateOrderedTags(); break; } // Get ordering from account data case 'MatrixActions.accountData': { if (payload.event_type !== 'im.vector.web.tag_ordering') break; // Ignore remote echos caused by this store so as to avoid setting // state back to old state. if (payload.event_content._storeId === this.getStoreId()) break; this._setState({ orderedTagsAccountData: payload.event_content ? payload.event_content.tags : null, removedTagsAccountData: payload.event_content ? payload.event_content.removedTags : null }); this._updateOrderedTags(); break; } // Initialise the state such that if account data is unset, default to joined groups case 'GroupActions.fetchJoinedGroups.success': { this._setState({ joinedGroupIds: payload.result.groups.sort(), // Sort lexically hasFetchedJoinedGroups: true }); this._updateOrderedTags(); break; } case 'TagOrderActions.moveTag.pending': { // Optimistic update of a moved tag this._setState({ orderedTags: payload.request.tags, removedTagsAccountData: payload.request.removedTags }); break; } case 'TagOrderActions.removeTag.pending': { // Optimistic update of a removed tag this._setState({ removedTagsAccountData: payload.request.removedTags }); this._updateOrderedTags(); break; } case 'select_tag': { const allowMultiple = !_SettingsStore.default.getValue("feature_communities_v2_prototypes"); let newTags = []; // Shift-click semantics if (payload.shiftKey && allowMultiple) { // Select range of tags let start = this._state.orderedTags.indexOf(this._state.anchorTag); let end = this._state.orderedTags.indexOf(payload.tag); if (start === -1) { start = end; } if (start > end) { const temp = start; start = end; end = temp; } newTags = payload.ctrlOrCmdKey ? this._state.selectedTags : []; newTags = [...new Set(this._state.orderedTags.slice(start, end + 1).concat(newTags))]; } else { if (payload.ctrlOrCmdKey && allowMultiple) { // Toggle individual tag if (this._state.selectedTags.includes(payload.tag)) { newTags = this._state.selectedTags.filter(t => t !== payload.tag); } else { newTags = [...this._state.selectedTags, payload.tag]; } } else { if (this._state.selectedTags.length === 1 && this._state.selectedTags.includes(payload.tag)) { // Existing (only) selected tag is being normally clicked again, clear tags newTags = []; } else { // Select individual tag newTags = [payload.tag]; } } // Only set the anchor tag if the tag was previously unselected, otherwise // the next range starts with an unselected tag. if (!this._state.selectedTags.includes(payload.tag)) { this._setState({ anchorTag: payload.tag }); } } this._setState({ selectedTags: newTags }); _Analytics.default.trackEvent('FilterStore', 'select_tag'); } break; case 'deselect_tags': if (payload.tag) { // if a tag is passed, only deselect that tag this._setState({ selectedTags: this._state.selectedTags.filter(tag => tag !== payload.tag) }); } else { this._setState({ selectedTags: [] }); } _Analytics.default.trackEvent('FilterStore', 'deselect_tags'); break; case 'on_client_not_viable': case 'on_logged_out': { // Reset state without pushing an update to the view, which generally assumes that // the matrix client isn't `null` and so causing a re-render will cause NPEs. this._state = Object.assign({}, INITIAL_STATE); break; } case 'setting_updated': if (payload.settingName === 'TagPanel.enableTagPanel' && !payload.newValue) { this._setState({ selectedTags: [] }); _Analytics.default.trackEvent('FilterStore', 'disable_tags'); } break; } } _updateBadges(groupIds = this._state.joinedGroupIds) { if (groupIds && groupIds.length) { const client = _MatrixClientPeg.MatrixClientPeg.get(); const changedBadges = {}; groupIds.forEach(groupId => { const rooms = _GroupStore.default.getGroupRooms(groupId).map(r => client.getRoom(r.roomId)) // to Room objects .filter(r => r !== null && r !== undefined); // filter out rooms we haven't joined from the group const badge = rooms && RoomNotifs.aggregateNotificationCount(rooms); changedBadges[groupId] = badge && badge.count !== 0 ? badge : undefined; }); const newBadges = Object.assign({}, this._state.badges, changedBadges); this._setState({ badges: newBadges }); } } _updateOrderedTags() { this._setState({ orderedTags: this._state.hasSynced && this._state.hasFetchedJoinedGroups ? this._mergeGroupsAndTags() : null }); } _mergeGroupsAndTags() { const groupIds = this._state.joinedGroupIds || []; const tags = this._state.orderedTagsAccountData || []; const removedTags = new Set(this._state.removedTagsAccountData || []); const tagsToKeep = tags.filter(t => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.has(t)); const groupIdsToAdd = groupIds.filter(groupId => !tags.includes(groupId) && !removedTags.has(groupId)); return tagsToKeep.concat(groupIdsToAdd); } getGroupBadge(groupId) { const badges = this._state.badges; return badges && badges[groupId]; } getOrderedTags() { return this._state.orderedTags; } getRemovedTagsAccountData() { return this._state.removedTagsAccountData; } getStoreId() { // Generate a random ID to prevent this store from clobbering its // state with redundant remote echos. if (!this._id) this._id = Math.random().toString(16).slice(2, 10); return this._id; } getSelectedTags() { return this._state.selectedTags; } } if (global.singletonGroupFilterOrderStore === undefined) { global.singletonGroupFilterOrderStore = new GroupFilterOrderStore(); } var _default = global.singletonGroupFilterOrderStore; exports.default = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZXMvR3JvdXBGaWx0ZXJPcmRlclN0b3JlLmpzIl0sIm5hbWVzIjpbIklOSVRJQUxfU1RBVEUiLCJvcmRlcmVkVGFncyIsIm9yZGVyZWRUYWdzQWNjb3VudERhdGEiLCJoYXNTeW5jZWQiLCJqb2luZWRHcm91cElkcyIsInNlbGVjdGVkVGFncyIsImFuY2hvclRhZyIsIkdyb3VwRmlsdGVyT3JkZXJTdG9yZSIsIlN0b3JlIiwiY29uc3RydWN0b3IiLCJkaXMiLCJfc3RhdGUiLCJPYmplY3QiLCJhc3NpZ24iLCJTZXR0aW5nc1N0b3JlIiwibW9uaXRvclNldHRpbmciLCJfc2V0U3RhdGUiLCJuZXdTdGF0ZSIsIl9fZW1pdENoYW5nZSIsIl9fb25EaXNwYXRjaCIsInBheWxvYWQiLCJhY3Rpb24iLCJyZWxhdGVkR3JvdXBJZHMiLCJHcm91cFN0b3JlIiwiZ2V0R3JvdXBJZHNGb3JSb29tSWQiLCJyb29tX2lkIiwiX3VwZGF0ZUJhZGdlcyIsInN0YXRlIiwicHJldlN0YXRlIiwidGFnT3JkZXJpbmdFdmVudCIsIm1hdHJpeENsaWVudCIsImdldEFjY291bnREYXRhIiwidGFnT3JkZXJpbmdFdmVudENvbnRlbnQiLCJnZXRDb250ZW50IiwidGFncyIsInJlbW92ZWRUYWdzQWNjb3VudERhdGEiLCJyZW1vdmVkVGFncyIsIl91cGRhdGVPcmRlcmVkVGFncyIsImV2ZW50X3R5cGUiLCJldmVudF9jb250ZW50IiwiX3N0b3JlSWQiLCJnZXRTdG9yZUlkIiwicmVzdWx0IiwiZ3JvdXBzIiwic29ydCIsImhhc0ZldGNoZWRKb2luZWRHcm91cHMiLCJyZXF1ZXN0IiwiYWxsb3dNdWx0aXBsZSIsImdldFZhbHVlIiwibmV3VGFncyIsInNoaWZ0S2V5Iiwic3RhcnQiLCJpbmRleE9mIiwiZW5kIiwidGFnIiwidGVtcCIsImN0cmxPckNtZEtleSIsIlNldCIsInNsaWNlIiwiY29uY2F0IiwiaW5jbHVkZXMiLCJmaWx0ZXIiLCJ0IiwibGVuZ3RoIiwiQW5hbHl0aWNzIiwidHJhY2tFdmVudCIsInNldHRpbmdOYW1lIiwibmV3VmFsdWUiLCJncm91cElkcyIsImNsaWVudCIsIk1hdHJpeENsaWVudFBlZyIsImdldCIsImNoYW5nZWRCYWRnZXMiLCJmb3JFYWNoIiwiZ3JvdXBJZCIsInJvb21zIiwiZ2V0R3JvdXBSb29tcyIsIm1hcCIsInIiLCJnZXRSb29tIiwicm9vbUlkIiwidW5kZWZpbmVkIiwiYmFkZ2UiLCJSb29tTm90aWZzIiwiYWdncmVnYXRlTm90aWZpY2F0aW9uQ291bnQiLCJjb3VudCIsIm5ld0JhZGdlcyIsImJhZGdlcyIsIl9tZXJnZUdyb3Vwc0FuZFRhZ3MiLCJ0YWdzVG9LZWVwIiwiaGFzIiwiZ3JvdXBJZHNUb0FkZCIsImdldEdyb3VwQmFkZ2UiLCJnZXRPcmRlcmVkVGFncyIsImdldFJlbW92ZWRUYWdzQWNjb3VudERhdGEiLCJfaWQiLCJNYXRoIiwicmFuZG9tIiwidG9TdHJpbmciLCJnZXRTZWxlY3RlZFRhZ3MiLCJnbG9iYWwiLCJzaW5nbGV0b25Hcm91cEZpbHRlck9yZGVyU3RvcmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBZUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVNBLE1BQU1BLGFBQWEsR0FBRztBQUNsQkMsRUFBQUEsV0FBVyxFQUFFLElBREs7QUFFbEJDLEVBQUFBLHNCQUFzQixFQUFFLElBRk47QUFHbEJDLEVBQUFBLFNBQVMsRUFBRSxLQUhPO0FBSWxCQyxFQUFBQSxjQUFjLEVBQUUsSUFKRTtBQU1sQkMsRUFBQUEsWUFBWSxFQUFFLEVBTkk7QUFPbEI7QUFDQUMsRUFBQUEsU0FBUyxFQUFFO0FBUk8sQ0FBdEI7QUFXQTtBQUNBO0FBQ0E7O0FBQ0EsTUFBTUMscUJBQU4sU0FBb0NDLFlBQXBDLENBQTBDO0FBQ3RDQyxFQUFBQSxXQUFXLEdB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TCxHQUFXQyxJQUFJLENBQUNDLE1BQUwsR0FBY0MsUUFBZCxDQUF1QixFQUF2QixFQUEyQnhDLEtBQTNCLENBQWlDLENBQWpDLEVBQW9DLEVBQXBDLENBQVg7QUFDZixXQUFPLEtBQUtxQyxHQUFaO0FBQ0g7O0FBRURJLEVBQUFBLGVBQWUsR0FBRztBQUNkLFdBQU8sS0FBS3hGLE1BQUwsQ0FBWU4sWUFBbkI7QUFDSDs7QUF0T3FDOztBQXlPMUMsSUFBSStGLE1BQU0sQ0FBQ0MsOEJBQVAsS0FBMENwQixTQUE5QyxFQUF5RDtBQUNyRG1CLEVBQUFBLE1BQU0sQ0FBQ0MsOEJBQVAsR0FBd0MsSUFBSTlGLHFCQUFKLEVBQXhDO0FBQ0g7O2VBQ2M2RixNQUFNLENBQUNDLDhCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE3IE5ldyBWZWN0b3IgTHRkXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cbmltcG9ydCB7U3RvcmV9IGZyb20gJ2ZsdXgvdXRpbHMnO1xuaW1wb3J0IGRpcyBmcm9tICcuLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXInO1xuaW1wb3J0IEdyb3VwU3RvcmUgZnJvbSAnLi9Hcm91cFN0b3JlJztcbmltcG9ydCBBbmFseXRpY3MgZnJvbSAnLi4vQW5hbHl0aWNzJztcbmltcG9ydCAqIGFzIFJvb21Ob3RpZnMgZnJvbSBcIi4uL1Jvb21Ob3RpZnNcIjtcbmltcG9ydCB7TWF0cml4Q2xpZW50UGVnfSBmcm9tICcuLi9NYXRyaXhDbGllbnRQZWcnO1xuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcblxuY29uc3QgSU5JVElBTF9TVEFURSA9IHtcbiAgICBvcmRlcmVkVGFnczogbnVsbCxcbiAgICBvcmRlcmVkVGFnc0FjY291bnREYXRhOiBudWxsLFxuICAgIGhhc1N5bmNlZDogZmFsc2UsXG4gICAgam9pbmVkR3JvdXBJZHM6IG51bGwsXG5cbiAgICBzZWxlY3RlZFRhZ3M6IFtdLFxuICAgIC8vIExhc3Qgc2VsZWN0ZWQgdGFnIHdoZW4gc2hpZnQgd2FzIG5vdCBiZWluZyBwcmVzc2VkXG4gICAgYW5jaG9yVGFnOiBudWxsLFxufTtcblxuLyoqXG4gKiBBIGNsYXNzIGZvciBzdG9yaW5nIGFwcGxpY2F0aW9uIHN0YXRlIGZvciBvcmRlcmluZyB0YWdzIGluIHRoZSBHcm91cEZpbHRlclBhbmVsLlxuICovXG5jbGFzcyBHcm91cEZpbHRlck9yZGVyU3RvcmUgZXh0ZW5kcyBTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKGRpcyk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGlzZSBzdGF0ZVxuICAgICAgICB0aGlzLl9zdGF0ZSA9IE9iamVjdC5hc3NpZ24oe30sIElOSVRJQUxfU1RBVEUpO1xuICAgICAgICBTZXR0aW5nc1N0b3JlLm1vbml0b3JTZXR0aW5nKFwiVGFnUGFuZWwuZW5hYmxlVGFnUGFuZWxcIiwgbnVsbCk7XG4gICAgfVxuXG4gICAgX3NldFN0YXRlKG5ld1N0YXRlKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gT2JqZWN0LmFzc2lnbih0aGlzLl9zdGF0ZSwgbmV3U3RhdGUpO1xuICAgICAgICB0aGlzLl9fZW1pdENoYW5nZSgpO1xuICAgIH1cblxuICAgIF9fb25EaXNwYXRjaChwYXlsb2FkKSB7XG4gICAgICAgIHN3aXRjaCAocGF5bG9hZC5hY3Rpb24pIHtcbiAgICAgICAgICAgIC8vIEluaXRpYWxpc2Ugc3RhdGUgYWZ0ZXIgaW5pdGlhbCBzeW5jXG4gICAgICAgICAgICBjYXNlICd2aWV3X3Jvb20nOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZEdyb3VwSWRzID0gR3JvdXBTdG9yZS5nZXRHcm91cElkc0ZvclJvb21JZChwYXlsb2FkLnJvb21faWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUJhZGdlcyhyZWxhdGVkR3JvdXBJZHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnTWF0cml4QWN0aW9ucy5zeW5jJzoge1xuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLnN0YXRlID09PSAnU1lOQ0lORycgfHwgcGF5bG9hZC5zdGF0ZSA9PT0gJ1BSRVBBUkVEJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVCYWRnZXMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEocGF5bG9hZC5wcmV2U3RhdGUgIT09ICdQUkVQQVJFRCcgJiYgcGF5bG9hZC5zdGF0ZSA9PT0gJ1BSRVBBUkVEJykpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHRhZ09yZGVyaW5nRXZlbnQgPSBwYXlsb2FkLm1hdHJpeENsaWVudC5nZXRBY2NvdW50RGF0YSgnaW0udmVjdG9yLndlYi50YWdfb3JkZXJpbmcnKTtcbiAgICAgICAgICAgICAgICBjb25zdCB0YWdPcmRlcmluZ0V2ZW50Q29udGVudCA9IHRhZ09yZGVyaW5nRXZlbnQgPyB0YWdPcmRlcmluZ0V2ZW50LmdldENvbnRlbnQoKSA6IHt9O1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgb3JkZXJlZFRhZ3NBY2NvdW50RGF0YTogdGFnT3JkZXJpbmdFdmVudENvbnRlbnQudGFncyB8fCBudWxsLFxuICAgICAgICAgICAgICAgICAgICByZW1vdmVkVGFnc0FjY291bnREYXRhOiB0YWdPcmRlcmluZ0V2ZW50Q29udGVudC5yZW1vdmVkVGFncyB8fCBudWxsLFxuICAgICAgICAgICAgICAgICAgICBoYXNTeW5jZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlT3JkZXJlZFRhZ3MoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEdldCBvcmRlcmluZyBmcm9tIGFjY291bnQgZGF0YVxuICAgICAgICAgICAgY2FzZSAnTWF0cml4QWN0aW9ucy5hY2NvdW50RGF0YSc6IHtcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5ldmVudF90eXBlICE9PSAnaW0udmVjdG9yLndlYi50YWdfb3JkZXJpbmcnKSBicmVhaztcblxuICAgICAgICAgICAgICAgIC8vIElnbm9yZSByZW1vdGUgZWNob3MgY2F1c2VkIGJ5IHRoaXMgc3RvcmUgc28gYXMgdG8gYXZvaWQgc2V0dGluZ1xuICAgICAgICAgICAgICAgIC8vIHN0YXRlIGJhY2sgdG8gb2xkIHN0YXRlLlxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLmV2ZW50X2NvbnRlbnQuX3N0b3JlSWQgPT09IHRoaXMuZ2V0U3RvcmVJZCgpKSBicmVhaztcblxuICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgb3JkZXJlZFRhZ3NBY2NvdW50RGF0YTogcGF5bG9hZC5ldmVudF9jb250ZW50ID8gcGF5bG9hZC5ldmVudF9jb250ZW50LnRhZ3MgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICByZW1vdmVkVGFnc0FjY291bnREYXRhOiBwYXlsb2FkLmV2ZW50X2NvbnRlbnQgPyBwYXlsb2FkLmV2ZW50X2NvbnRlbnQucmVtb3ZlZFRhZ3MgOiBudWxsLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU9yZGVyZWRUYWdzKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBJbml0aWFsaXNlIHRoZSBzdGF0ZSBzdWNoIHRoYXQgaWYgYWNjb3VudCBkYXRhIGlzIHVuc2V0LCBkZWZhdWx0IHRvIGpvaW5lZCBncm91cHNcbiAgICAgICAgICAgIGNhc2UgJ0dyb3VwQWN0aW9ucy5mZXRjaEpvaW5lZEdyb3Vwcy5zdWNjZXNzJzoge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgam9pbmVkR3JvdXBJZHM6IHBheWxvYWQucmVzdWx0Lmdyb3Vwcy5zb3J0KCksIC8vIFNvcnQgbGV4aWNhbGx5XG4gICAgICAgICAgICAgICAgICAgIGhhc0ZldGNoZWRKb2luZWRHcm91cHM6IHRydWUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlT3JkZXJlZFRhZ3MoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgJ1RhZ09yZGVyQWN0aW9ucy5tb3ZlVGFnLnBlbmRpbmcnOiB7XG4gICAgICAgICAgICAgICAgLy8gT3B0aW1pc3RpYyB1cGRhdGUgb2YgYSBtb3ZlZCB0YWdcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIG9yZGVyZWRUYWdzOiBwYXlsb2FkLnJlcXVlc3QudGFncyxcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZFRhZ3NBY2NvdW50RGF0YTogcGF5bG9hZC5yZXF1ZXN0LnJlbW92ZWRUYWdzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnVGFnT3JkZXJBY3Rpb25zLnJlbW92ZVRhZy5wZW5kaW5nJzoge1xuICAgICAgICAgICAgICAgIC8vIE9wdGltaXN0aWMgdXBkYXRlIG9mIGEgcmVtb3ZlZCB0YWdcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZWRUYWdzQWNjb3VudERhdGE6IHBheWxvYWQucmVxdWVzdC5yZW1vdmVkVGFncyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVPcmRlcmVkVGFncygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnc2VsZWN0X3RhZyc6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbGxvd011bHRpcGxlID0gIVNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJmZWF0dXJlX2NvbW11bml0aWVzX3YyX3Byb3RvdHlwZXNcIik7XG5cbiAgICAgICAgICAgICAgICBsZXQgbmV3VGFncyA9IFtdO1xuICAgICAgICAgICAgICAgIC8vIFNoaWZ0LWNsaWNrIHNlbWFudGljc1xuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLnNoaWZ0S2V5ICYmIGFsbG93TXVsdGlwbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2VsZWN0IHJhbmdlIG9mIHRhZ3NcbiAgICAgICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5fc3RhdGUub3JkZXJlZFRhZ3MuaW5kZXhPZih0aGlzLl9zdGF0ZS5hbmNob3JUYWcpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgZW5kID0gdGhpcy5fc3RhdGUub3JkZXJlZFRhZ3MuaW5kZXhPZihwYXlsb2FkLnRhZyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0ID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBlbmQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0ID4gZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZW1wID0gc3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGVuZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZCA9IHRlbXA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmV3VGFncyA9IHBheWxvYWQuY3RybE9yQ21kS2V5ID8gdGhpcy5fc3RhdGUuc2VsZWN0ZWRUYWdzIDogW107XG4gICAgICAgICAgICAgICAgICAgIG5ld1RhZ3MgPSBbLi4ubmV3IFNldChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLm9yZGVyZWRUYWdzLnNsaWNlKHN0YXJ0LCBlbmQgKyAxKS5jb25jYXQobmV3VGFncyksXG4gICAgICAgICAgICAgICAgICAgICldO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLmN0cmxPckNtZEtleSAmJiBhbGxvd011bHRpcGxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUb2dnbGUgaW5kaXZpZHVhbCB0YWdcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5zZWxlY3RlZFRhZ3MuaW5jbHVkZXMocGF5bG9hZC50YWcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGFncyA9IHRoaXMuX3N0YXRlLnNlbGVjdGVkVGFncy5maWx0ZXIoKHQpID0+IHQgIT09IHBheWxvYWQudGFnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGFncyA9IFsuLi50aGlzLl9zdGF0ZS5zZWxlY3RlZFRhZ3MsIHBheWxvYWQudGFnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5zZWxlY3RlZFRhZ3MubGVuZ3RoID09PSAxICYmIHRoaXMuX3N0YXRlLnNlbGVjdGVkVGFncy5pbmNsdWRlcyhwYXlsb2FkLnRhZykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFeGlzdGluZyAob25seSkgc2VsZWN0ZWQgdGFnIGlzIGJlaW5nIG5vcm1hbGx5IGNsaWNrZWQgYWdhaW4sIGNsZWFyIHRhZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdUYWdzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNlbGVjdCBpbmRpdmlkdWFsIHRhZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RhZ3MgPSBbcGF5bG9hZC50YWddO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgc2V0IHRoZSBhbmNob3IgdGFnIGlmIHRoZSB0YWcgd2FzIHByZXZpb3VzbHkgdW5zZWxlY3RlZCwgb3RoZXJ3aXNlXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBuZXh0IHJhbmdlIHN0YXJ0cyB3aXRoIGFuIHVuc2VsZWN0ZWQgdGFnLlxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3N0YXRlLnNlbGVjdGVkVGFncy5pbmNsdWRlcyhwYXlsb2FkLnRhZykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JUYWc6IHBheWxvYWQudGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkVGFnczogbmV3VGFncyxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIEFuYWx5dGljcy50cmFja0V2ZW50KCdGaWx0ZXJTdG9yZScsICdzZWxlY3RfdGFnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkZXNlbGVjdF90YWdzJzpcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC50YWcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgYSB0YWcgaXMgcGFzc2VkLCBvbmx5IGRlc2VsZWN0IHRoYXQgdGFnXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkVGFnczogdGhpcy5fc3RhdGUuc2VsZWN0ZWRUYWdzLmZpbHRlcih0YWcgPT4gdGFnICE9PSBwYXlsb2FkLnRhZyksXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkVGFnczogW10sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBBbmFseXRpY3MudHJhY2tFdmVudCgnRmlsdGVyU3RvcmUnLCAnZGVzZWxlY3RfdGFncycpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnb25fY2xpZW50X25vdF92aWFibGUnOlxuICAgICAgICAgICAgY2FzZSAnb25fbG9nZ2VkX291dCc6IHtcbiAgICAgICAgICAgICAgICAvLyBSZXNldCBzdGF0ZSB3aXRob3V0IHB1c2hpbmcgYW4gdXBkYXRlIHRvIHRoZSB2aWV3LCB3aGljaCBnZW5lcmFsbHkgYXNzdW1lcyB0aGF0XG4gICAgICAgICAgICAgICAgLy8gdGhlIG1hdHJpeCBjbGllbnQgaXNuJ3QgYG51bGxgIGFuZCBzbyBjYXVzaW5nIGEgcmUtcmVuZGVyIHdpbGwgY2F1c2UgTlBFcy5cbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IE9iamVjdC5hc3NpZ24oe30sIElOSVRJQUxfU1RBVEUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnc2V0dGluZ191cGRhdGVkJzpcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5zZXR0aW5nTmFtZSA9PT0gJ1RhZ1BhbmVsLmVuYWJsZVRhZ1BhbmVsJyAmJiAhcGF5bG9hZC5uZXdWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFRhZ3M6IFtdLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgQW5hbHl0aWNzLnRyYWNrRXZlbnQoJ0ZpbHRlclN0b3JlJywgJ2Rpc2FibGVfdGFncycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVCYWRnZXMoZ3JvdXBJZHMgPSB0aGlzLl9zdGF0ZS5qb2luZWRHcm91cElkcykge1xuICAgICAgICBpZiAoZ3JvdXBJZHMgJiYgZ3JvdXBJZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBjbGllbnQgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG4gICAgICAgICAgICBjb25zdCBjaGFuZ2VkQmFkZ2VzID0ge307XG4gICAgICAgICAgICBncm91cElkcy5mb3JFYWNoKGdyb3VwSWQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvb21zID1cbiAgICAgICAgICAgICAgICAgICAgR3JvdXBTdG9yZS5nZXRHcm91cFJvb21zKGdyb3VwSWQpXG4gICAgICAgICAgICAgICAgICAgICAgICAubWFwKHIgPT4gY2xpZW50LmdldFJvb20oci5yb29tSWQpKSAvLyB0byBSb29tIG9iamVjdHNcbiAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIociA9PiByICE9PSBudWxsICYmIHIgIT09IHVuZGVmaW5lZCk7ICAgLy8gZmlsdGVyIG91dCByb29tcyB3ZSBoYXZlbid0IGpvaW5lZCBmcm9tIHRoZSBncm91cFxuICAgICAgICAgICAgICAgIGNvbnN0IGJhZGdlID0gcm9vbXMgJiYgUm9vbU5vdGlmcy5hZ2dyZWdhdGVOb3RpZmljYXRpb25Db3VudChyb29tcyk7XG4gICAgICAgICAgICAgICAgY2hhbmdlZEJhZGdlc1tncm91cElkXSA9IChiYWRnZSAmJiBiYWRnZS5jb3VudCAhPT0gMCkgPyBiYWRnZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgbmV3QmFkZ2VzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fc3RhdGUuYmFkZ2VzLCBjaGFuZ2VkQmFkZ2VzKTtcbiAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKHtiYWRnZXM6IG5ld0JhZGdlc30pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3VwZGF0ZU9yZGVyZWRUYWdzKCkge1xuICAgICAgICB0aGlzLl9zZXRTdGF0ZSh7XG4gICAgICAgICAgICBvcmRlcmVkVGFnczpcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5oYXNTeW5jZWQgJiZcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5oYXNGZXRjaGVkSm9pbmVkR3JvdXBzID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWVyZ2VHcm91cHNBbmRUYWdzKCkgOiBudWxsLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfbWVyZ2VHcm91cHNBbmRUYWdzKCkge1xuICAgICAgICBjb25zdCBncm91cElkcyA9IHRoaXMuX3N0YXRlLmpvaW5lZEdyb3VwSWRzIHx8IFtdO1xuICAgICAgICBjb25zdCB0YWdzID0gdGhpcy5fc3RhdGUub3JkZXJlZFRhZ3NBY2NvdW50RGF0YSB8fCBbXTtcbiAgICAgICAgY29uc3QgcmVtb3ZlZFRhZ3MgPSBuZXcgU2V0KHRoaXMuX3N0YXRlLnJlbW92ZWRUYWdzQWNjb3VudERhdGEgfHwgW10pO1xuXG5cbiAgICAgICAgY29uc3QgdGFnc1RvS2VlcCA9IHRhZ3MuZmlsdGVyKFxuICAgICAgICAgICAgKHQpID0+ICh0WzBdICE9PSAnKycgfHwgZ3JvdXBJZHMuaW5jbHVkZXModCkpICYmICFyZW1vdmVkVGFncy5oYXModCksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgZ3JvdXBJZHNUb0FkZCA9IGdyb3VwSWRzLmZpbHRlcihcbiAgICAgICAgICAgIChncm91cElkKSA9PiAhdGFncy5pbmNsdWRlcyhncm91cElkKSAmJiAhcmVtb3ZlZFRhZ3MuaGFzKGdyb3VwSWQpLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0YWdzVG9LZWVwLmNvbmNhdChncm91cElkc1RvQWRkKTtcbiAgICB9XG5cbiAgICBnZXRHcm91cEJhZGdlKGdyb3VwSWQpIHtcbiAgICAgICAgY29uc3QgYmFkZ2VzID0gdGhpcy5fc3RhdGUuYmFkZ2VzO1xuICAgICAgICByZXR1cm4gYmFkZ2VzICYmIGJhZGdlc1tncm91cElkXTtcbiAgICB9XG5cbiAgICBnZXRPcmRlcmVkVGFncygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLm9yZGVyZWRUYWdzO1xuICAgIH1cblxuICAgIGdldFJlbW92ZWRUYWdzQWNjb3VudERhdGEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5yZW1vdmVkVGFnc0FjY291bnREYXRhO1xuICAgIH1cblxuICAgIGdldFN0b3JlSWQoKSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIGEgcmFuZG9tIElEIHRvIHByZXZlbnQgdGhpcyBzdG9yZSBmcm9tIGNsb2JiZXJpbmcgaXRzXG4gICAgICAgIC8vIHN0YXRlIHdpdGggcmVkdW5kYW50IHJlbW90ZSBlY2hvcy5cbiAgICAgICAgaWYgKCF0aGlzLl9pZCkgdGhpcy5faWQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDE2KS5zbGljZSgyLCAxMCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9pZDtcbiAgICB9XG5cbiAgICBnZXRTZWxlY3RlZFRhZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5zZWxlY3RlZFRhZ3M7XG4gICAgfVxufVxuXG5pZiAoZ2xvYmFsLnNpbmdsZXRvbkdyb3VwRmlsdGVyT3JkZXJTdG9yZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZ2xvYmFsLnNpbmdsZXRvbkdyb3VwRmlsdGVyT3JkZXJTdG9yZSA9IG5ldyBHcm91cEZpbHRlck9yZGVyU3RvcmUoKTtcbn1cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbC5zaW5nbGV0b25Hcm91cEZpbHRlck9yZGVyU3RvcmU7XG4iXX0=