matrix-react-sdk
Version:
SDK for matrix.org using React
296 lines (290 loc) • 54.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.PipContainer = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _call = require("matrix-js-sdk/src/webrtc/call");
var _logger = require("matrix-js-sdk/src/logger");
var _LegacyCallView = _interopRequireDefault(require("../views/voip/LegacyCallView"));
var _LegacyCallHandler = _interopRequireWildcard(require("../../LegacyCallHandler"));
var _MatrixClientPeg = require("../../MatrixClientPeg");
var _PictureInPictureDragger = _interopRequireDefault(require("./PictureInPictureDragger"));
var _dispatcher = _interopRequireDefault(require("../../dispatcher/dispatcher"));
var _actions = require("../../dispatcher/actions");
var _WidgetLayoutStore = require("../../stores/widgets/WidgetLayoutStore");
var _ActiveWidgetStore = _interopRequireWildcard(require("../../stores/ActiveWidgetStore"));
var _AsyncStore = require("../../stores/AsyncStore");
var _SDKContext = require("../../contexts/SDKContext");
var _voiceBroadcast = require("../../voice-broadcast");
var _useCurrentVoiceBroadcastPlayback = require("../../voice-broadcast/hooks/useCurrentVoiceBroadcastPlayback");
var _WidgetPip = require("../views/pips/WidgetPip");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
Copyright 2024 New Vector Ltd.
Copyright 2017-2022 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.
*/
const SHOW_CALL_IN_STATES = [_call.CallState.Connected, _call.CallState.InviteSent, _call.CallState.Connecting, _call.CallState.CreateAnswer, _call.CallState.CreateOffer, _call.CallState.WaitLocalMedia];
// Splits a list of calls into one 'primary' one and a list
// (which should be a single element) of other calls.
// The primary will be the one not on hold, or an arbitrary one
// if they're all on hold)
function getPrimarySecondaryCallsForPip(roomId) {
if (!roomId) return [null, []];
const calls = _LegacyCallHandler.default.instance.getAllActiveCallsForPip(roomId);
let primary = null;
let secondaries = [];
for (const call of calls) {
if (!SHOW_CALL_IN_STATES.includes(call.state)) continue;
if (!call.isRemoteOnHold() && primary === null) {
primary = call;
} else {
secondaries.push(call);
}
}
if (primary === null && secondaries.length > 0) {
primary = secondaries[0];
secondaries = secondaries.slice(1);
}
if (secondaries.length > 1) {
// We should never be in more than two calls so this shouldn't happen
_logger.logger.log("Found more than 1 secondary call! Other calls will not be shown.");
}
return [primary, secondaries];
}
/**
* PipContainer shows a small version of the LegacyCallView or a sticky widget hovering over the UI in
* 'picture-in-picture' (PiP mode). It displays the call(s) which is *not* in the room the user is currently viewing
* and all widgets that are active but not shown in any other possible container.
*/
class PipContainerInner extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onMove", () => this.props.movePersistedElement.current?.());
(0, _defineProperty2.default)(this, "onRoomViewStoreUpdate", () => {
const newRoomId = _SDKContext.SdkContextClass.instance.roomViewStore.getRoomId();
const oldRoomId = this.state.viewedRoomId;
if (newRoomId === oldRoomId) return;
// The WidgetLayoutStore observer always tracks the currently viewed Room,
// so we don't end up with multiple observers and know what observer to remove on unmount
const oldRoom = _MatrixClientPeg.MatrixClientPeg.get()?.getRoom(oldRoomId);
if (oldRoom) {
_WidgetLayoutStore.WidgetLayoutStore.instance.off(_WidgetLayoutStore.WidgetLayoutStore.emissionForRoom(oldRoom), this.updateCalls);
}
const newRoom = _MatrixClientPeg.MatrixClientPeg.get()?.getRoom(newRoomId || undefined);
if (newRoom) {
_WidgetLayoutStore.WidgetLayoutStore.instance.on(_WidgetLayoutStore.WidgetLayoutStore.emissionForRoom(newRoom), this.updateCalls);
}
if (!newRoomId) return;
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(newRoomId);
this.setState({
viewedRoomId: newRoomId,
primaryCall: primaryCall,
secondaryCall: secondaryCalls[0]
});
this.updateShowWidgetInPip();
});
(0, _defineProperty2.default)(this, "onWidgetPersistence", () => {
this.updateShowWidgetInPip();
});
(0, _defineProperty2.default)(this, "onWidgetDockChanges", () => {
this.updateShowWidgetInPip();
});
(0, _defineProperty2.default)(this, "updateCalls", () => {
if (!this.state.viewedRoomId) return;
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.viewedRoomId);
this.setState({
primaryCall: primaryCall,
secondaryCall: secondaryCalls[0]
});
this.updateShowWidgetInPip();
});
(0, _defineProperty2.default)(this, "onCallRemoteHold", () => {
if (!this.state.viewedRoomId) return;
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.viewedRoomId);
this.setState({
primaryCall: primaryCall,
secondaryCall: secondaryCalls[0]
});
});
(0, _defineProperty2.default)(this, "onDoubleClick", () => {
const callRoomId = this.state.primaryCall?.roomId;
if (callRoomId ?? this.state.persistentRoomId) {
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_id: callRoomId ?? this.state.persistentRoomId ?? undefined,
metricsTrigger: "WebFloatingCallWindow"
});
}
});
const roomId = _SDKContext.SdkContextClass.instance.roomViewStore.getRoomId();
const [_primaryCall, _secondaryCalls] = getPrimarySecondaryCallsForPip(roomId);
this.state = {
viewedRoomId: roomId || undefined,
primaryCall: _primaryCall || null,
secondaryCall: _secondaryCalls[0],
persistentWidgetId: _ActiveWidgetStore.default.instance.getPersistentWidgetId(),
persistentRoomId: _ActiveWidgetStore.default.instance.getPersistentRoomId(),
showWidgetInPip: false
};
}
componentDidMount() {
_LegacyCallHandler.default.instance.addListener(_LegacyCallHandler.LegacyCallHandlerEvent.CallChangeRoom, this.updateCalls);
_LegacyCallHandler.default.instance.addListener(_LegacyCallHandler.LegacyCallHandlerEvent.CallState, this.updateCalls);
_SDKContext.SdkContextClass.instance.roomViewStore.addListener(_AsyncStore.UPDATE_EVENT, this.onRoomViewStoreUpdate);
_MatrixClientPeg.MatrixClientPeg.safeGet().on(_call.CallEvent.RemoteHoldUnhold, this.onCallRemoteHold);
const room = _MatrixClientPeg.MatrixClientPeg.safeGet().getRoom(this.state.viewedRoomId);
if (room) {
_WidgetLayoutStore.WidgetLayoutStore.instance.on(_WidgetLayoutStore.WidgetLayoutStore.emissionForRoom(room), this.updateCalls);
}
_ActiveWidgetStore.default.instance.on(_ActiveWidgetStore.ActiveWidgetStoreEvent.Persistence, this.onWidgetPersistence);
_ActiveWidgetStore.default.instance.on(_ActiveWidgetStore.ActiveWidgetStoreEvent.Dock, this.onWidgetDockChanges);
_ActiveWidgetStore.default.instance.on(_ActiveWidgetStore.ActiveWidgetStoreEvent.Undock, this.onWidgetDockChanges);
}
componentWillUnmount() {
_LegacyCallHandler.default.instance.removeListener(_LegacyCallHandler.LegacyCallHandlerEvent.CallChangeRoom, this.updateCalls);
_LegacyCallHandler.default.instance.removeListener(_LegacyCallHandler.LegacyCallHandlerEvent.CallState, this.updateCalls);
const cli = _MatrixClientPeg.MatrixClientPeg.get();
cli?.removeListener(_call.CallEvent.RemoteHoldUnhold, this.onCallRemoteHold);
_SDKContext.SdkContextClass.instance.roomViewStore.removeListener(_AsyncStore.UPDATE_EVENT, this.onRoomViewStoreUpdate);
const room = cli?.getRoom(this.state.viewedRoomId);
if (room) {
_WidgetLayoutStore.WidgetLayoutStore.instance.off(_WidgetLayoutStore.WidgetLayoutStore.emissionForRoom(room), this.updateCalls);
}
_ActiveWidgetStore.default.instance.off(_ActiveWidgetStore.ActiveWidgetStoreEvent.Persistence, this.onWidgetPersistence);
_ActiveWidgetStore.default.instance.off(_ActiveWidgetStore.ActiveWidgetStoreEvent.Dock, this.onWidgetDockChanges);
_ActiveWidgetStore.default.instance.off(_ActiveWidgetStore.ActiveWidgetStoreEvent.Undock, this.onWidgetDockChanges);
}
updateShowWidgetInPip() {
const persistentWidgetId = _ActiveWidgetStore.default.instance.getPersistentWidgetId();
const persistentRoomId = _ActiveWidgetStore.default.instance.getPersistentRoomId();
let fromAnotherRoom = false;
let notDocked = false;
// Sanity check the room - the widget may have been destroyed between render cycles, and
// thus no room is associated anymore.
if (persistentWidgetId && persistentRoomId && _MatrixClientPeg.MatrixClientPeg.safeGet().getRoom(persistentRoomId)) {
notDocked = !_ActiveWidgetStore.default.instance.isDocked(persistentWidgetId, persistentRoomId);
fromAnotherRoom = this.state.viewedRoomId !== persistentRoomId;
}
// The widget should only be shown as a persistent app (in a floating
// pip container) if it is not visible on screen: either because we are
// viewing a different room OR because it is in none of the possible
// containers of the room view.
const showWidgetInPip = fromAnotherRoom || notDocked;
this.setState({
showWidgetInPip,
persistentWidgetId,
persistentRoomId
});
}
createVoiceBroadcastPlaybackPipContent(voiceBroadcastPlayback) {
const content = this.state.viewedRoomId === voiceBroadcastPlayback.infoEvent.getRoomId() ? /*#__PURE__*/_react.default.createElement(_voiceBroadcast.VoiceBroadcastPlaybackBody, {
playback: voiceBroadcastPlayback,
pip: true
}) : /*#__PURE__*/_react.default.createElement(_voiceBroadcast.VoiceBroadcastSmallPlaybackBody, {
playback: voiceBroadcastPlayback
});
return ({
onStartMoving
}) => /*#__PURE__*/_react.default.createElement("div", {
key: `vb-playback-${voiceBroadcastPlayback.infoEvent.getId()}`,
onMouseDown: onStartMoving
}, content);
}
createVoiceBroadcastPreRecordingPipContent(voiceBroadcastPreRecording) {
return ({
onStartMoving
}) => /*#__PURE__*/_react.default.createElement("div", {
key: "vb-pre-recording",
onMouseDown: onStartMoving
}, /*#__PURE__*/_react.default.createElement(_voiceBroadcast.VoiceBroadcastPreRecordingPip, {
voiceBroadcastPreRecording: voiceBroadcastPreRecording
}));
}
createVoiceBroadcastRecordingPipContent(voiceBroadcastRecording) {
return ({
onStartMoving
}) => /*#__PURE__*/_react.default.createElement("div", {
key: `vb-recording-${voiceBroadcastRecording.infoEvent.getId()}`,
onMouseDown: onStartMoving
}, /*#__PURE__*/_react.default.createElement(_voiceBroadcast.VoiceBroadcastRecordingPip, {
recording: voiceBroadcastRecording
}));
}
render() {
const pipMode = true;
let pipContent = [];
if (this.props.voiceBroadcastRecording) {
pipContent = [this.createVoiceBroadcastRecordingPipContent(this.props.voiceBroadcastRecording)];
} else if (this.props.voiceBroadcastPreRecording) {
pipContent = [this.createVoiceBroadcastPreRecordingPipContent(this.props.voiceBroadcastPreRecording)];
} else if (this.props.voiceBroadcastPlayback) {
pipContent = [this.createVoiceBroadcastPlaybackPipContent(this.props.voiceBroadcastPlayback)];
}
if (this.state.primaryCall) {
// get a ref to call inside the current scope
const call = this.state.primaryCall;
pipContent.push(({
onStartMoving,
onResize
}) => /*#__PURE__*/_react.default.createElement(_LegacyCallView.default, {
key: "call-view",
onMouseDownOnHeader: onStartMoving,
call: call,
secondaryCall: this.state.secondaryCall,
pipMode: pipMode,
onResize: onResize
}));
}
if (this.state.showWidgetInPip && this.state.persistentWidgetId) {
pipContent.push(({
onStartMoving
}) => /*#__PURE__*/_react.default.createElement(_WidgetPip.WidgetPip, {
key: "widget-pip",
widgetId: this.state.persistentWidgetId,
room: _MatrixClientPeg.MatrixClientPeg.safeGet().getRoom(this.state.persistentRoomId ?? undefined),
viewingRoom: this.state.viewedRoomId === this.state.persistentRoomId,
onStartMoving: onStartMoving,
movePersistedElement: this.props.movePersistedElement
}));
}
if (pipContent.length) {
return /*#__PURE__*/_react.default.createElement(_PictureInPictureDragger.default, {
className: "mx_LegacyCallPreview",
draggable: pipMode,
onDoubleClick: this.onDoubleClick,
onMove: this.onMove
}, pipContent);
}
return null;
}
}
const PipContainer = () => {
const sdkContext = (0, _react.useContext)(_SDKContext.SDKContext);
const voiceBroadcastPreRecordingStore = sdkContext.voiceBroadcastPreRecordingStore;
const {
currentVoiceBroadcastPreRecording
} = (0, _voiceBroadcast.useCurrentVoiceBroadcastPreRecording)(voiceBroadcastPreRecordingStore);
const voiceBroadcastRecordingsStore = sdkContext.voiceBroadcastRecordingsStore;
const {
currentVoiceBroadcastRecording
} = (0, _voiceBroadcast.useCurrentVoiceBroadcastRecording)(voiceBroadcastRecordingsStore);
const voiceBroadcastPlaybacksStore = sdkContext.voiceBroadcastPlaybacksStore;
const {
currentVoiceBroadcastPlayback
} = (0, _useCurrentVoiceBroadcastPlayback.useCurrentVoiceBroadcastPlayback)(voiceBroadcastPlaybacksStore);
const movePersistedElement = (0, _react.useRef)();
return /*#__PURE__*/_react.default.createElement(PipContainerInner, {
voiceBroadcastPlayback: currentVoiceBroadcastPlayback,
voiceBroadcastPreRecording: currentVoiceBroadcastPreRecording,
voiceBroadcastRecording: currentVoiceBroadcastRecording,
movePersistedElement: movePersistedElement
});
};
exports.PipContainer = PipContainer;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2FsbCIsIl9sb2dnZXIiLCJfTGVnYWN5Q2FsbFZpZXciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX0xlZ2FjeUNhbGxIYW5kbGVyIiwiX01hdHJpeENsaWVudFBlZyIsIl9QaWN0dXJlSW5QaWN0dXJlRHJhZ2dlciIsIl9kaXNwYXRjaGVyIiwiX2FjdGlvbnMiLCJfV2lkZ2V0TGF5b3V0U3RvcmUiLCJfQWN0aXZlV2lkZ2V0U3RvcmUiLCJfQXN5bmNTdG9yZSIsIl9TREtDb250ZXh0IiwiX3ZvaWNlQnJvYWRjYXN0IiwiX3VzZUN1cnJlbnRWb2ljZUJyb2FkY2FzdFBsYXliYWNrIiwiX1dpZGdldFBpcCIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIlNIT1dfQ0FMTF9JTl9TVEFURVMiLCJDYWxsU3RhdGUiLCJDb25uZWN0ZWQiLCJJbnZpdGVTZW50IiwiQ29ubmVjdGluZyIsIkNyZWF0ZUFuc3dlciIsIkNyZWF0ZU9mZmVyIiwiV2FpdExvY2FsTWVkaWEiLCJnZXRQcmltYXJ5U2Vjb25kYXJ5Q2FsbHNGb3JQaXAiLCJyb29tSWQiLCJjYWxscyIsIkxlZ2FjeUNhbGxIYW5kbGVyIiwiaW5zdGFuY2UiLCJnZXRBbGxBY3RpdmVDYWxsc0ZvclBpcCIsInByaW1hcnkiLCJzZWNvbmRhcmllcyIsImluY2x1ZGVzIiwic3RhdGUiLCJpc1JlbW90ZU9uSG9sZCIsInB1c2giLCJsZW5ndGgiLCJzbGljZSIsImxvZ2dlciIsImxvZyIsIlBpcENvbnRhaW5lcklubmVyIiwiUmVhY3QiLCJDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsInByb3BzIiwiX2RlZmluZVByb3BlcnR5MiIsIm1vdmVQZXJzaXN0ZWRFbGVtZW50IiwiY3VycmVudCIsIm5ld1Jvb21JZCIsIlNka0NvbnRleHRDbGFzcyIsInJvb21WaWV3U3RvcmUiLCJnZXRSb29tSWQiLCJvbGRSb29tSWQiLCJ2aWV3ZWRSb29tSWQiLCJvbGRSb29tIiwiTWF0cml4Q2xpZW50UGVnIiwiZ2V0Um9vbSIsIldpZGdldExheW91dFN0b3JlIiwib2ZmIiwiZW1pc3Npb25Gb3JSb29tIiwidXBkYXRlQ2FsbHMiLCJuZXdSb29tIiwidW5kZWZpbmVkIiwib24iLCJwcmltYXJ5Q2FsbCIsInNlY29uZGFyeUNhbGxzIiwic2V0U3RhdGUiLCJzZWNvbmRhcnlDYWxsIiwidXBkYXRlU2hvd1dpZGdldEluUGlwIiwiY2FsbFJvb21JZCIsInBlcnNpc3RlbnRSb29tSWQiLCJkaXMiLCJkaXNwYXRjaCIsImFjdGlvbiIsIkFjdGlvbiIsIlZpZXdSb29tIiwicm9vbV9pZCIsIm1ldHJpY3NUcmlnZ2VyIiwicGVyc2lzdGVudFdpZGdldElkIiwiQWN0aXZlV2lkZ2V0U3RvcmUiLCJnZXRQZXJzaXN0ZW50V2lkZ2V0SWQiLCJnZXRQZXJzaXN0ZW50Um9vbUlkIiwic2hvd1dpZGdldEluUGlwIiwiY29tcG9uZW50RGlkTW91bnQiLCJhZGRMaXN0ZW5lciIsIkxlZ2FjeUNhbGxIYW5kbGVyRXZlbnQiLCJDYWxsQ2hhbmdlUm9vbSIsIlVQREFURV9FVkVOVCIsIm9uUm9vbVZpZXdTdG9yZVVwZGF0ZSIsInNhZmVHZXQiLCJDYWxsRXZlbnQiLCJSZW1vdGVIb2xkVW5ob2xkIiwib25DYWxsUmVtb3RlSG9sZCIsInJvb20iLCJBY3RpdmVXaWRnZXRTdG9yZUV2ZW50IiwiUGVyc2lzdGVuY2UiLCJvbldpZGdldFBlcnNpc3RlbmNlIiwiRG9jayIsIm9uV2lkZ2V0RG9ja0NoYW5nZXMiLCJVbmRvY2siLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInJlbW92ZUxpc3RlbmVyIiwiY2xpIiwiZnJvbUFub3RoZXJSb29tIiwibm90RG9ja2VkIiwiaXNEb2NrZWQiLCJjcmVhdGVWb2ljZUJyb2FkY2FzdFBsYXliYWNrUGlwQ29udGVudCIsInZvaWNlQnJvYWRjYXN0UGxheWJhY2siLCJjb250ZW50IiwiaW5mb0V2ZW50IiwiY3JlYXRlRWxlbWVudCIsIlZvaWNlQnJvYWRjYXN0UGxheWJhY2tCb2R5IiwicGxheWJhY2siLCJwaXAiLCJWb2ljZUJyb2FkY2FzdFNtYWxsUGxheWJhY2tCb2R5Iiwib25TdGFydE1vdmluZyIsImtleSIsImdldElkIiwib25Nb3VzZURvd24iLCJjcmVhdGVWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZ1BpcENvbnRlbnQiLCJ2b2ljZUJyb2FkY2FzdFByZVJlY29yZGluZyIsIlZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nUGlwIiwiY3JlYXRlVm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdQaXBDb250ZW50Iiwidm9pY2VCcm9hZGNhc3RSZWNvcmRpbmciLCJWb2ljZUJyb2FkY2FzdFJlY29yZGluZ1BpcCIsInJlY29yZGluZyIsInJlbmRlciIsInBpcE1vZGUiLCJwaXBDb250ZW50Iiwib25SZXNpemUiLCJvbk1vdXNlRG93bk9uSGVhZGVyIiwiV2lkZ2V0UGlwIiwid2lkZ2V0SWQiLCJ2aWV3aW5nUm9vbSIsImNsYXNzTmFtZSIsImRyYWdnYWJsZSIsIm9uRG91YmxlQ2xpY2siLCJvbk1vdmUiLCJQaXBDb250YWluZXIiLCJzZGtDb250ZXh0IiwidXNlQ29udGV4dCIsIlNES0NvbnRleHQiLCJ2b2ljZUJyb2FkY2FzdFByZVJlY29yZGluZ1N0b3JlIiwiY3VycmVudFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nIiwidXNlQ3VycmVudFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nIiwidm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdzU3RvcmUiLCJjdXJyZW50Vm9pY2VCcm9hZGNhc3RSZWNvcmRpbmciLCJ1c2VDdXJyZW50Vm9pY2VCcm9hZGNhc3RSZWNvcmRpbmciLCJ2b2ljZUJyb2FkY2FzdFBsYXliYWNrc1N0b3JlIiwiY3VycmVudFZvaWNlQnJvYWRjYXN0UGxheWJhY2siLCJ1c2VDdXJyZW50Vm9pY2VCcm9hZGNhc3RQbGF5YmFjayIsInVzZVJlZiIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zdHJ1Y3R1cmVzL1BpcENvbnRhaW5lci50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTctMjAyMiBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgTXV0YWJsZVJlZk9iamVjdCwgUmVhY3ROb2RlLCB1c2VDb250ZXh0LCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IENhbGxFdmVudCwgQ2FsbFN0YXRlLCBNYXRyaXhDYWxsIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3dlYnJ0Yy9jYWxsXCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbG9nZ2VyXCI7XG5pbXBvcnQgeyBPcHRpb25hbCB9IGZyb20gXCJtYXRyaXgtZXZlbnRzLXNka1wiO1xuXG5pbXBvcnQgTGVnYWN5Q2FsbFZpZXcgZnJvbSBcIi4uL3ZpZXdzL3ZvaXAvTGVnYWN5Q2FsbFZpZXdcIjtcbmltcG9ydCBMZWdhY3lDYWxsSGFuZGxlciwgeyBMZWdhY3lDYWxsSGFuZGxlckV2ZW50IH0gZnJvbSBcIi4uLy4uL0xlZ2FjeUNhbGxIYW5kbGVyXCI7XG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgUGljdHVyZUluUGljdHVyZURyYWdnZXIsIHsgQ3JlYXRlUGlwQ2hpbGRyZW4gfSBmcm9tIFwiLi9QaWN0dXJlSW5QaWN0dXJlRHJhZ2dlclwiO1xuaW1wb3J0IGRpcyBmcm9tIFwiLi4vLi4vZGlzcGF0Y2hlci9kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tIFwiLi4vLi4vZGlzcGF0Y2hlci9hY3Rpb25zXCI7XG5pbXBvcnQgeyBXaWRnZXRMYXlvdXRTdG9yZSB9IGZyb20gXCIuLi8uLi9zdG9yZXMvd2lkZ2V0cy9XaWRnZXRMYXlvdXRTdG9yZVwiO1xuaW1wb3J0IEFjdGl2ZVdpZGdldFN0b3JlLCB7IEFjdGl2ZVdpZGdldFN0b3JlRXZlbnQgfSBmcm9tIFwiLi4vLi4vc3RvcmVzL0FjdGl2ZVdpZGdldFN0b3JlXCI7XG5pbXBvcnQgeyBWaWV3Um9vbVBheWxvYWQgfSBmcm9tIFwiLi4vLi4vZGlzcGF0Y2hlci9wYXlsb2Fkcy9WaWV3Um9vbVBheWxvYWRcIjtcbmltcG9ydCB7IFVQREFURV9FVkVOVCB9IGZyb20gXCIuLi8uLi9zdG9yZXMvQXN5bmNTdG9yZVwiO1xuaW1wb3J0IHsgU0RLQ29udGV4dCwgU2RrQ29udGV4dENsYXNzIH0gZnJvbSBcIi4uLy4uL2NvbnRleHRzL1NES0NvbnRleHRcIjtcbmltcG9ydCB7XG4gICAgdXNlQ3VycmVudFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nLFxuICAgIHVzZUN1cnJlbnRWb2ljZUJyb2FkY2FzdFJlY29yZGluZyxcbiAgICBWb2ljZUJyb2FkY2FzdFBsYXliYWNrLFxuICAgIFZvaWNlQnJvYWRjYXN0UGxheWJhY2tCb2R5LFxuICAgIFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nLFxuICAgIFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nUGlwLFxuICAgIFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nLFxuICAgIFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nUGlwLFxuICAgIFZvaWNlQnJvYWRjYXN0U21hbGxQbGF5YmFja0JvZHksXG59IGZyb20gXCIuLi8uLi92b2ljZS1icm9hZGNhc3RcIjtcbmltcG9ydCB7IHVzZUN1cnJlbnRWb2ljZUJyb2FkY2FzdFBsYXliYWNrIH0gZnJvbSBcIi4uLy4uL3ZvaWNlLWJyb2FkY2FzdC9ob29rcy91c2VDdXJyZW50Vm9pY2VCcm9hZGNhc3RQbGF5YmFja1wiO1xuaW1wb3J0IHsgV2lkZ2V0UGlwIH0gZnJvbSBcIi4uL3ZpZXdzL3BpcHMvV2lkZ2V0UGlwXCI7XG5cbmNvbnN0IFNIT1dfQ0FMTF9JTl9TVEFURVMgPSBbXG4gICAgQ2FsbFN0YXRlLkNvbm5lY3RlZCxcbiAgICBDYWxsU3RhdGUuSW52aXRlU2VudCxcbiAgICBDYWxsU3RhdGUuQ29ubmVjdGluZyxcbiAgICBDYWxsU3RhdGUuQ3JlYXRlQW5zd2VyLFxuICAgIENhbGxTdGF0ZS5DcmVhdGVPZmZlcixcbiAgICBDYWxsU3RhdGUuV2FpdExvY2FsTWVkaWEsXG5dO1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICB2b2ljZUJyb2FkY2FzdFJlY29yZGluZzogT3B0aW9uYWw8Vm9pY2VCcm9hZGNhc3RSZWNvcmRpbmc+O1xuICAgIHZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nOiBPcHRpb25hbDxWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZz47XG4gICAgdm9pY2VCcm9hZGNhc3RQbGF5YmFjazogT3B0aW9uYWw8Vm9pY2VCcm9hZGNhc3RQbGF5YmFjaz47XG4gICAgbW92ZVBlcnNpc3RlZEVsZW1lbnQ6IE11dGFibGVSZWZPYmplY3Q8KCgpID0+IHZvaWQpIHwgdW5kZWZpbmVkPjtcbn1cblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgdmlld2VkUm9vbUlkPzogc3RyaW5nO1xuXG4gICAgLy8gVGhlIG1haW4gY2FsbCB0aGF0IHdlIGFyZSBkaXNwbGF5aW5nIChpZS4gbm90IGluY2x1ZGluZyB0aGUgY2FsbCBpbiB0aGUgcm9vbSBiZWluZyB2aWV3ZWQsIGlmIGFueSlcbiAgICBwcmltYXJ5Q2FsbDogTWF0cml4Q2FsbCB8IG51bGw7XG5cbiAgICAvLyBBbnkgb3RoZXIgY2FsbCB3ZSdyZSBkaXNwbGF5aW5nOiBvbmx5IGlmIHRoZSB1c2VyIGlzIG9uIHR3byBjYWxscyBhbmQgbm90IHZpZXdpbmcgZWl0aGVyIG9mIHRoZSByb29tc1xuICAgIC8vIHRoZXkgYmVsb25nIHRvXG4gICAgc2Vjb25kYXJ5Q2FsbDogTWF0cml4Q2FsbDtcblxuICAgIC8vIHdpZGdldCBjYW5kaWRhdGUgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBwaXAgdmlldy5cbiAgICBwZXJzaXN0ZW50V2lkZ2V0SWQ6IHN0cmluZyB8IG51bGw7XG4gICAgcGVyc2lzdGVudFJvb21JZDogc3RyaW5nIHwgbnVsbDtcbiAgICBzaG93V2lkZ2V0SW5QaXA6IGJvb2xlYW47XG59XG5cbi8vIFNwbGl0cyBhIGxpc3Qgb2YgY2FsbHMgaW50byBvbmUgJ3ByaW1hcnknIG9uZSBhbmQgYSBsaXN0XG4vLyAod2hpY2ggc2hvdWxkIGJlIGEgc2luZ2xlIGVsZW1lbnQpIG9mIG90aGVyIGNhbGxzLlxuLy8gVGhlIHByaW1hcnkgd2lsbCBiZSB0aGUgb25lIG5vdCBvbiBob2xkLCBvciBhbiBhcmJpdHJhcnkgb25lXG4vLyBpZiB0aGV5J3JlIGFsbCBvbiBob2xkKVxuZnVuY3Rpb24gZ2V0UHJpbWFyeVNlY29uZGFyeUNhbGxzRm9yUGlwKHJvb21JZDogT3B0aW9uYWw8c3RyaW5nPik6IFtNYXRyaXhDYWxsIHwgbnVsbCwgTWF0cml4Q2FsbFtdXSB7XG4gICAgaWYgKCFyb29tSWQpIHJldHVybiBbbnVsbCwgW11dO1xuXG4gICAgY29uc3QgY2FsbHMgPSBMZWdhY3lDYWxsSGFuZGxlci5pbnN0YW5jZS5nZXRBbGxBY3RpdmVDYWxsc0ZvclBpcChyb29tSWQpO1xuXG4gICAgbGV0IHByaW1hcnk6IE1hdHJpeENhbGwgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgc2Vjb25kYXJpZXM6IE1hdHJpeENhbGxbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBjYWxsIG9mIGNhbGxzKSB7XG4gICAgICAgIGlmICghU0hPV19DQUxMX0lOX1NUQVRFUy5pbmNsdWRlcyhjYWxsLnN0YXRlKSkgY29udGludWU7XG5cbiAgICAgICAgaWYgKCFjYWxsLmlzUmVtb3RlT25Ib2xkKCkgJiYgcHJpbWFyeSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcHJpbWFyeSA9IGNhbGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWNvbmRhcmllcy5wdXNoKGNhbGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByaW1hcnkgPT09IG51bGwgJiYgc2Vjb25kYXJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBwcmltYXJ5ID0gc2Vjb25kYXJpZXNbMF07XG4gICAgICAgIHNlY29uZGFyaWVzID0gc2Vjb25kYXJpZXMuc2xpY2UoMSk7XG4gICAgfVxuXG4gICAgaWYgKHNlY29uZGFyaWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgLy8gV2Ugc2hvdWxkIG5ldmVyIGJlIGluIG1vcmUgdGhhbiB0d28gY2FsbHMgc28gdGhpcyBzaG91bGRuJ3QgaGFwcGVuXG4gICAgICAgIGxvZ2dlci5sb2coXCJGb3VuZCBtb3JlIHRoYW4gMSBzZWNvbmRhcnkgY2FsbCEgT3RoZXIgY2FsbHMgd2lsbCBub3QgYmUgc2hvd24uXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBbcHJpbWFyeSwgc2Vjb25kYXJpZXNdO1xufVxuXG4vKipcbiAqIFBpcENvbnRhaW5lciBzaG93cyBhIHNtYWxsIHZlcnNpb24gb2YgdGhlIExlZ2FjeUNhbGxWaWV3IG9yIGEgc3RpY2t5IHdpZGdldCBob3ZlcmluZyBvdmVyIHRoZSBVSSBpblxuICogJ3BpY3R1cmUtaW4tcGljdHVyZScgKFBpUCBtb2RlKS4gSXQgZGlzcGxheXMgdGhlIGNhbGwocykgd2hpY2ggaXMgKm5vdCogaW4gdGhlIHJvb20gdGhlIHVzZXIgaXMgY3VycmVudGx5IHZpZXdpbmdcbiAqIGFuZCBhbGwgd2lkZ2V0cyB0aGF0IGFyZSBhY3RpdmUgYnV0IG5vdCBzaG93biBpbiBhbnkgb3RoZXIgcG9zc2libGUgY29udGFpbmVyLlxuICovXG5cbmNsYXNzIFBpcENvbnRhaW5lcklubmVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PElQcm9wcywgSVN0YXRlPiB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBJUHJvcHMpIHtcbiAgICAgICAgc3VwZXIocHJvcHMpO1xuXG4gICAgICAgIGNvbnN0IHJvb21JZCA9IFNka0NvbnRleHRDbGFzcy5pbnN0YW5jZS5yb29tVmlld1N0b3JlLmdldFJvb21JZCgpO1xuXG4gICAgICAgIGNvbnN0IFtwcmltYXJ5Q2FsbCwgc2Vjb25kYXJ5Q2FsbHNdID0gZ2V0UHJpbWFyeVNlY29uZGFyeUNhbGxzRm9yUGlwKHJvb21JZCk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIHZpZXdlZFJvb21JZDogcm9vbUlkIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHByaW1hcnlDYWxsOiBwcmltYXJ5Q2FsbCB8fCBudWxsLFxuICAgICAgICAgICAgc2Vjb25kYXJ5Q2FsbDogc2Vjb25kYXJ5Q2FsbHNbMF0sXG4gICAgICAgICAgICBwZXJzaXN0ZW50V2lkZ2V0SWQ6IEFjdGl2ZVdpZGdldFN0b3JlLmluc3RhbmNlLmdldFBlcnNpc3RlbnRXaWRnZXRJZCgpLFxuICAgICAgICAgICAgcGVyc2lzdGVudFJvb21JZDogQWN0aXZlV2lkZ2V0U3RvcmUuaW5zdGFuY2UuZ2V0UGVyc2lzdGVudFJvb21JZCgpLFxuICAgICAgICAgICAgc2hvd1dpZGdldEluUGlwOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIExlZ2FjeUNhbGxIYW5kbGVyLmluc3RhbmNlLmFkZExpc3RlbmVyKExlZ2FjeUNhbGxIYW5kbGVyRXZlbnQuQ2FsbENoYW5nZVJvb20sIHRoaXMudXBkYXRlQ2FsbHMpO1xuICAgICAgICBMZWdhY3lDYWxsSGFuZGxlci5pbnN0YW5jZS5hZGRMaXN0ZW5lcihMZWdhY3lDYWxsSGFuZGxlckV2ZW50LkNhbGxTdGF0ZSwgdGhpcy51cGRhdGVDYWxscyk7XG4gICAgICAgIFNka0NvbnRleHRDbGFzcy5pbnN0YW5jZS5yb29tVmlld1N0b3JlLmFkZExpc3RlbmVyKFVQREFURV9FVkVOVCwgdGhpcy5vblJvb21WaWV3U3RvcmVVcGRhdGUpO1xuICAgICAgICBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLm9uKENhbGxFdmVudC5SZW1vdGVIb2xkVW5ob2xkLCB0aGlzLm9uQ2FsbFJlbW90ZUhvbGQpO1xuICAgICAgICBjb25zdCByb29tID0gTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRSb29tKHRoaXMuc3RhdGUudmlld2VkUm9vbUlkKTtcbiAgICAgICAgaWYgKHJvb20pIHtcbiAgICAgICAgICAgIFdpZGdldExheW91dFN0b3JlLmluc3RhbmNlLm9uKFdpZGdldExheW91dFN0b3JlLmVtaXNzaW9uRm9yUm9vbShyb29tKSwgdGhpcy51cGRhdGVDYWxscyk7XG4gICAgICAgIH1cbiAgICAgICAgQWN0aXZlV2lkZ2V0U3RvcmUuaW5zdGFuY2Uub24oQWN0aXZlV2lkZ2V0U3RvcmVFdmVudC5QZXJzaXN0ZW5jZSwgdGhpcy5vbldpZGdldFBlcnNpc3RlbmNlKTtcbiAgICAgICAgQWN0aXZlV2lkZ2V0U3RvcmUuaW5zdGFuY2Uub24oQWN0aXZlV2lkZ2V0U3RvcmVFdmVudC5Eb2NrLCB0aGlzLm9uV2lkZ2V0RG9ja0NoYW5nZXMpO1xuICAgICAgICBBY3RpdmVXaWRnZXRTdG9yZS5pbnN0YW5jZS5vbihBY3RpdmVXaWRnZXRTdG9yZUV2ZW50LlVuZG9jaywgdGhpcy5vbldpZGdldERvY2tDaGFuZ2VzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIExlZ2FjeUNhbGxIYW5kbGVyLmluc3RhbmNlLnJlbW92ZUxpc3RlbmVyKExlZ2FjeUNhbGxIYW5kbGVyRXZlbnQuQ2FsbENoYW5nZVJvb20sIHRoaXMudXBkYXRlQ2FsbHMpO1xuICAgICAgICBMZWdhY3lDYWxsSGFuZGxlci5pbnN0YW5jZS5yZW1vdmVMaXN0ZW5lcihMZWdhY3lDYWxsSGFuZGxlckV2ZW50LkNhbGxTdGF0ZSwgdGhpcy51cGRhdGVDYWxscyk7XG4gICAgICAgIGNvbnN0IGNsaSA9IE1hdHJpeENsaWVudFBlZy5nZXQoKTtcbiAgICAgICAgY2xpPy5yZW1vdmVMaXN0ZW5lcihDYWxsRXZlbnQuUmVtb3RlSG9sZFVuaG9sZCwgdGhpcy5vbkNhbGxSZW1vdGVIb2xkKTtcbiAgICAgICAgU2RrQ29udGV4dENsYXNzLmluc3RhbmNlLnJvb21WaWV3U3RvcmUucmVtb3ZlTGlzdGVuZXIoVVBEQVRFX0VWRU5ULCB0aGlzLm9uUm9vbVZpZXdTdG9yZVVwZGF0ZSk7XG4gICAgICAgIGNvbnN0IHJvb20gPSBjbGk/LmdldFJvb20odGhpcy5zdGF0ZS52aWV3ZWRSb29tSWQpO1xuICAgICAgICBpZiAocm9vbSkge1xuICAgICAgICAgICAgV2lkZ2V0TGF5b3V0U3RvcmUuaW5zdGFuY2Uub2ZmKFdpZGdldExheW91dFN0b3JlLmVtaXNzaW9uRm9yUm9vbShyb29tKSwgdGhpcy51cGRhdGVDYWxscyk7XG4gICAgICAgIH1cbiAgICAgICAgQWN0aXZlV2lkZ2V0U3RvcmUuaW5zdGFuY2Uub2ZmKEFjdGl2ZVdpZGdldFN0b3JlRXZlbnQuUGVyc2lzdGVuY2UsIHRoaXMub25XaWRnZXRQZXJzaXN0ZW5jZSk7XG4gICAgICAgIEFjdGl2ZVdpZGdldFN0b3JlLmluc3RhbmNlLm9mZihBY3RpdmVXaWRnZXRTdG9yZUV2ZW50LkRvY2ssIHRoaXMub25XaWRnZXREb2NrQ2hhbmdlcyk7XG4gICAgICAgIEFjdGl2ZVdpZGdldFN0b3JlLmluc3RhbmNlLm9mZihBY3RpdmVXaWRnZXRTdG9yZUV2ZW50LlVuZG9jaywgdGhpcy5vbldpZGdldERvY2tDaGFuZ2VzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTW92ZSA9ICgpOiB2b2lkID0+IHRoaXMucHJvcHMubW92ZVBlcnNpc3RlZEVsZW1lbnQuY3VycmVudD8uKCk7XG5cbiAgICBwcml2YXRlIG9uUm9vbVZpZXdTdG9yZVVwZGF0ZSA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgbmV3Um9vbUlkID0gU2RrQ29udGV4dENsYXNzLmluc3RhbmNlLnJvb21WaWV3U3RvcmUuZ2V0Um9vbUlkKCk7XG4gICAgICAgIGNvbnN0IG9sZFJvb21JZCA9IHRoaXMuc3RhdGUudmlld2VkUm9vbUlkO1xuICAgICAgICBpZiAobmV3Um9vbUlkID09PSBvbGRSb29tSWQpIHJldHVybjtcbiAgICAgICAgLy8gVGhlIFdpZGdldExheW91dFN0b3JlIG9ic2VydmVyIGFsd2F5cyB0cmFja3MgdGhlIGN1cnJlbnRseSB2aWV3ZWQgUm9vbSxcbiAgICAgICAgLy8gc28gd2UgZG9uJ3QgZW5kIHVwIHdpdGggbXVsdGlwbGUgb2JzZXJ2ZXJzIGFuZCBrbm93IHdoYXQgb2JzZXJ2ZXIgdG8gcmVtb3ZlIG9uIHVubW91bnRcbiAgICAgICAgY29uc3Qgb2xkUm9vbSA9IE1hdHJpeENsaWVudFBlZy5nZXQoKT8uZ2V0Um9vbShvbGRSb29tSWQpO1xuICAgICAgICBpZiAob2xkUm9vbSkge1xuICAgICAgICAgICAgV2lkZ2V0TGF5b3V0U3RvcmUuaW5zdGFuY2Uub2ZmKFdpZGdldExheW91dFN0b3JlLmVtaXNzaW9uRm9yUm9vbShvbGRSb29tKSwgdGhpcy51cGRhdGVDYWxscyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3Um9vbSA9IE1hdHJpeENsaWVudFBlZy5nZXQoKT8uZ2V0Um9vbShuZXdSb29tSWQgfHwgdW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKG5ld1Jvb20pIHtcbiAgICAgICAgICAgIFdpZGdldExheW91dFN0b3JlLmluc3RhbmNlLm9uKFdpZGdldExheW91dFN0b3JlLmVtaXNzaW9uRm9yUm9vbShuZXdSb29tKSwgdGhpcy51cGRhdGVDYWxscyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFuZXdSb29tSWQpIHJldHVybjtcblxuICAgICAgICBjb25zdCBbcHJpbWFyeUNhbGwsIHNlY29uZGFyeUNhbGxzXSA9IGdldFByaW1hcnlTZWNvbmRhcnlDYWxsc0ZvclBpcChuZXdSb29tSWQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHZpZXdlZFJvb21JZDogbmV3Um9vbUlkLFxuICAgICAgICAgICAgcHJpbWFyeUNhbGw6IHByaW1hcnlDYWxsLFxuICAgICAgICAgICAgc2Vjb25kYXJ5Q2FsbDogc2Vjb25kYXJ5Q2FsbHNbMF0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwZGF0ZVNob3dXaWRnZXRJblBpcCgpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uV2lkZ2V0UGVyc2lzdGVuY2UgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlU2hvd1dpZGdldEluUGlwKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25XaWRnZXREb2NrQ2hhbmdlcyA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGVTaG93V2lkZ2V0SW5QaXAoKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSB1cGRhdGVDYWxscyA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnZpZXdlZFJvb21JZCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBbcHJpbWFyeUNhbGwsIHNlY29uZGFyeUNhbGxzXSA9IGdldFByaW1hcnlTZWNvbmRhcnlDYWxsc0ZvclBpcCh0aGlzLnN0YXRlLnZpZXdlZFJvb21JZCk7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBwcmltYXJ5Q2FsbDogcHJpbWFyeUNhbGwsXG4gICAgICAgICAgICBzZWNvbmRhcnlDYWxsOiBzZWNvbmRhcnlDYWxsc1swXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBkYXRlU2hvd1dpZGdldEluUGlwKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25DYWxsUmVtb3RlSG9sZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnZpZXdlZFJvb21JZCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBbcHJpbWFyeUNhbGwsIHNlY29uZGFyeUNhbGxzXSA9IGdldFByaW1hcnlTZWNvbmRhcnlDYWxsc0ZvclBpcCh0aGlzLnN0YXRlLnZpZXdlZFJvb21JZCk7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBwcmltYXJ5Q2FsbDogcHJpbWFyeUNhbGwsXG4gICAgICAgICAgICBzZWNvbmRhcnlDYWxsOiBzZWNvbmRhcnlDYWxsc1swXSxcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Eb3VibGVDbGljayA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgY2FsbFJvb21JZCA9IHRoaXMuc3RhdGUucHJpbWFyeUNhbGw/LnJvb21JZDtcbiAgICAgICAgaWYgKGNhbGxSb29tSWQgPz8gdGhpcy5zdGF0ZS5wZXJzaXN0ZW50Um9vbUlkKSB7XG4gICAgICAgICAgICBkaXMuZGlzcGF0Y2g8Vmlld1Jvb21QYXlsb2FkPih7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiBBY3Rpb24uVmlld1Jvb20sXG4gICAgICAgICAgICAgICAgcm9vbV9pZDogY2FsbFJvb21JZCA/PyB0aGlzLnN0YXRlLnBlcnNpc3RlbnRSb29tSWQgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG1ldHJpY3NUcmlnZ2VyOiBcIldlYkZsb2F0aW5nQ2FsbFdpbmRvd1wiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHVibGljIHVwZGF0ZVNob3dXaWRnZXRJblBpcCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcGVyc2lzdGVudFdpZGdldElkID0gQWN0aXZlV2lkZ2V0U3RvcmUuaW5zdGFuY2UuZ2V0UGVyc2lzdGVudFdpZGdldElkKCk7XG4gICAgICAgIGNvbnN0IHBlcnNpc3RlbnRSb29tSWQgPSBBY3RpdmVXaWRnZXRTdG9yZS5pbnN0YW5jZS5nZXRQZXJzaXN0ZW50Um9vbUlkKCk7XG5cbiAgICAgICAgbGV0IGZyb21Bbm90aGVyUm9vbSA9IGZhbHNlO1xuICAgICAgICBsZXQgbm90RG9ja2VkID0gZmFsc2U7XG4gICAgICAgIC8vIFNhbml0eSBjaGVjayB0aGUgcm9vbSAtIHRoZSB3aWRnZXQgbWF5IGhhdmUgYmVlbiBkZXN0cm95ZWQgYmV0d2VlbiByZW5kZXIgY3ljbGVzLCBhbmRcbiAgICAgICAgLy8gdGh1cyBubyByb29tIGlzIGFzc29jaWF0ZWQgYW55bW9yZS5cbiAgICAgICAgaWYgKHBlcnNpc3RlbnRXaWRnZXRJZCAmJiBwZXJzaXN0ZW50Um9vbUlkICYmIE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkuZ2V0Um9vbShwZXJzaXN0ZW50Um9vbUlkKSkge1xuICAgICAgICAgICAgbm90RG9ja2VkID0gIUFjdGl2ZVdpZGdldFN0b3JlLmluc3RhbmNlLmlzRG9ja2VkKHBlcnNpc3RlbnRXaWRnZXRJZCwgcGVyc2lzdGVudFJvb21JZCk7XG4gICAgICAgICAgICBmcm9tQW5vdGhlclJvb20gPSB0aGlzLnN0YXRlLnZpZXdlZFJvb21JZCAhPT0gcGVyc2lzdGVudFJvb21JZDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSB3aWRnZXQgc2hvdWxkIG9ubHkgYmUgc2hvd24gYXMgYSBwZXJzaXN0ZW50IGFwcCAoaW4gYSBmbG9hdGluZ1xuICAgICAgICAvLyBwaXAgY29udGFpbmVyKSBpZiBpdCBpcyBub3QgdmlzaWJsZSBvbiBzY3JlZW46IGVpdGhlciBiZWNhdXNlIHdlIGFyZVxuICAgICAgICAvLyB2aWV3aW5nIGEgZGlmZmVyZW50IHJvb20gT1IgYmVjYXVzZSBpdCBpcyBpbiBub25lIG9mIHRoZSBwb3NzaWJsZVxuICAgICAgICAvLyBjb250YWluZXJzIG9mIHRoZSByb29tIHZpZXcuXG4gICAgICAgIGNvbnN0IHNob3dXaWRnZXRJblBpcCA9IGZyb21Bbm90aGVyUm9vbSB8fCBub3REb2NrZWQ7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dXaWRnZXRJblBpcCwgcGVyc2lzdGVudFdpZGdldElkLCBwZXJzaXN0ZW50Um9vbUlkIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlVm9pY2VCcm9hZGNhc3RQbGF5YmFja1BpcENvbnRlbnQodm9pY2VCcm9hZGNhc3RQbGF5YmFjazogVm9pY2VCcm9hZGNhc3RQbGF5YmFjayk6IENyZWF0ZVBpcENoaWxkcmVuIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnZpZXdlZFJvb21JZCA9PT0gdm9pY2VCcm9hZGNhc3RQbGF5YmFjay5pbmZvRXZlbnQuZ2V0Um9vbUlkKCkgPyAoXG4gICAgICAgICAgICAgICAgPFZvaWNlQnJvYWRjYXN0UGxheWJhY2tCb2R5IHBsYXliYWNrPXt2b2ljZUJyb2FkY2FzdFBsYXliYWNrfSBwaXA9e3RydWV9IC8+XG4gICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgIDxWb2ljZUJyb2FkY2FzdFNtYWxsUGxheWJhY2tCb2R5IHBsYXliYWNrPXt2b2ljZUJyb2FkY2FzdFBsYXliYWNrfSAvPlxuICAgICAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gKHsgb25TdGFydE1vdmluZyB9KSA9PiAoXG4gICAgICAgICAgICA8ZGl2IGtleT17YHZiLXBsYXliYWNrLSR7dm9pY2VCcm9hZGNhc3RQbGF5YmFjay5pbmZvRXZlbnQuZ2V0SWQoKX1gfSBvbk1vdXNlRG93bj17b25TdGFydE1vdmluZ30+XG4gICAgICAgICAgICAgICAge2NvbnRlbnR9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nUGlwQ29udGVudChcbiAgICAgICAgdm9pY2VCcm9hZGNhc3RQcmVSZWNvcmRpbmc6IFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nLFxuICAgICk6IENyZWF0ZVBpcENoaWxkcmVuIHtcbiAgICAgICAgcmV0dXJuICh7IG9uU3RhcnRNb3ZpbmcgfSkgPT4gKFxuICAgICAgICAgICAgPGRpdiBrZXk9XCJ2Yi1wcmUtcmVjb3JkaW5nXCIgb25Nb3VzZURvd249e29uU3RhcnRNb3Zpbmd9PlxuICAgICAgICAgICAgICAgIDxWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZ1BpcCB2b2ljZUJyb2FkY2FzdFByZVJlY29yZGluZz17dm9pY2VCcm9hZGNhc3RQcmVSZWNvcmRpbmd9IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nUGlwQ29udGVudChcbiAgICAgICAgdm9pY2VCcm9hZGNhc3RSZWNvcmRpbmc6IFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nLFxuICAgICk6IENyZWF0ZVBpcENoaWxkcmVuIHtcbiAgICAgICAgcmV0dXJuICh7IG9uU3RhcnRNb3ZpbmcgfSkgPT4gKFxuICAgICAgICAgICAgPGRpdiBrZXk9e2B2Yi1yZWNvcmRpbmctJHt2b2ljZUJyb2FkY2FzdFJlY29yZGluZy5pbmZvRXZlbnQuZ2V0SWQoKX1gfSBvbk1vdXNlRG93bj17b25TdGFydE1vdmluZ30+XG4gICAgICAgICAgICAgICAgPFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nUGlwIHJlY29yZGluZz17dm9pY2VCcm9hZGNhc3RSZWNvcmRpbmd9IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IHBpcE1vZGUgPSB0cnVlO1xuICAgICAgICBsZXQgcGlwQ29udGVudDogQXJyYXk8Q3JlYXRlUGlwQ2hpbGRyZW4+ID0gW107XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMudm9pY2VCcm9hZGNhc3RSZWNvcmRpbmcpIHtcbiAgICAgICAgICAgIHBpcENvbnRlbnQgPSBbdGhpcy5jcmVhdGVWb2ljZUJyb2FkY2FzdFJlY29yZGluZ1BpcENvbnRlbnQodGhpcy5wcm9wcy52b2ljZUJyb2FkY2FzdFJlY29yZGluZyldO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMudm9pY2VCcm9hZGNhc3RQcmVSZWNvcmRpbmcpIHtcbiAgICAgICAgICAgIHBpcENvbnRlbnQgPSBbdGhpcy5jcmVhdGVWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZ1BpcENvbnRlbnQodGhpcy5wcm9wcy52b2ljZUJyb2FkY2FzdFByZVJlY29yZGluZyldO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMudm9pY2VCcm9hZGNhc3RQbGF5YmFjaykge1xuICAgICAgICAgICAgcGlwQ29udGVudCA9IFt0aGlzLmNyZWF0ZVZvaWNlQnJvYWRjYXN0UGxheWJhY2tQaXBDb250ZW50KHRoaXMucHJvcHMudm9pY2VCcm9hZGNhc3RQbGF5YmFjayldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUucHJpbWFyeUNhbGwpIHtcbiAgICAgICAgICAgIC8vIGdldCBhIHJlZiB0byBjYWxsIGluc2lkZSB0aGUgY3VycmVudCBzY29wZVxuICAgICAgICAgICAgY29uc3QgY2FsbCA9IHRoaXMuc3RhdGUucHJpbWFyeUNhbGw7XG4gICAgICAgICAgICBwaXBDb250ZW50LnB1c2goKHsgb25TdGFydE1vdmluZywgb25SZXNpemUgfSkgPT4gKFxuICAgICAgICAgICAgICAgIDxMZWdhY3lDYWxsVmlld1xuICAgICAgICAgICAgICAgICAgICBrZXk9XCJjYWxsLXZpZXdcIlxuICAgICAgICAgICAgICAgICAgICBvbk1vdXNlRG93bk9uSGVhZGVyPXtvblN0YXJ0TW92aW5nfVxuICAgICAgICAgICAgICAgICAgICBjYWxsPXtjYWxsfVxuICAgICAgICAgICAgICAgICAgICBzZWNvbmRhcnlDYWxsPXt0aGlzLnN0YXRlLnNlY29uZGFyeUNhbGx9XG4gICAgICAgICAgICAgICAgICAgIHBpcE1vZGU9e3BpcE1vZGV9XG4gICAgICAgICAgICAgICAgICAgIG9uUmVzaXplPXtvblJlc2l6ZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93V2lkZ2V0SW5QaXAgJiYgdGhpcy5zdGF0ZS5wZXJzaXN0ZW50V2lkZ2V0SWQpIHtcbiAgICAgICAgICAgIHBpcENvbnRlbnQucHVzaCgoeyBvblN0YXJ0TW92aW5nIH0pID0+IChcbiAgICAgICAgICAgICAgICA8V2lkZ2V0UGlwXG4gICAgICAgICAgICAgICAgICAgIGtleT1cIndpZGdldC1waXBcIlxuICAgICAgICAgICAgICAgICAgICB3aWRnZXRJZD17dGhpcy5zdGF0ZS5wZXJzaXN0ZW50V2lkZ2V0SWQhfVxuICAgICAgICAgICAgICAgICAgICByb29tPXtNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldFJvb20odGhpcy5zdGF0ZS5wZXJzaXN0ZW50Um9vbUlkID8/IHVuZGVmaW5lZCkhfVxuICAgICAgICAgICAgICAgICAgICB2aWV3aW5nUm9vbT17dGhpcy5zdGF0ZS52aWV3ZWRSb29tSWQgPT09IHRoaXMuc3RhdGUucGVyc2lzdGVudFJvb21JZH1cbiAgICAgICAgICAgICAgICAgICAgb25TdGFydE1vdmluZz17b25TdGFydE1vdmluZ31cbiAgICAgICAgICAgICAgICAgICAgbW92ZVBlcnNpc3RlZEVsZW1lbnQ9e3RoaXMucHJvcHMubW92ZVBlcnNpc3RlZEVsZW1lbnR9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBpcENvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxQaWN0dXJlSW5QaWN0dXJlRHJhZ2dlclxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsUHJldmlld1wiXG4gICAgICAgICAgICAgICAgICAgIGRyYWdnYWJsZT17cGlwTW9kZX1cbiAgICAgICAgICAgICAgICAgICAgb25Eb3VibGVDbGljaz17dGhpcy5vbkRvdWJsZUNsaWNrfVxuICAgICAgICAgICAgICAgICAgICBvbk1vdmU9e3RoaXMub25Nb3ZlfVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3BpcENvbnRlbnR9XG4gICAgICAgICAgICAgICAgPC9QaWN0dXJlSW5QaWN0dXJlRHJhZ2dlcj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG5cbmV4cG9ydCBjb25zdCBQaXBDb250YWluZXI6IFJlYWN0LkZDID0gKCkgPT4ge1xuICAgIGNvbnN0IHNka0NvbnRleHQgPSB1c2VDb250ZXh0KFNES0NvbnRleHQpO1xuICAgIGNvbnN0IHZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nU3RvcmUgPSBzZGtDb250ZXh0LnZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nU3RvcmU7XG4gICAgY29uc3QgeyBjdXJyZW50Vm9pY2VCcm9hZGNhc3RQcmVSZWNvcmRpbmcgfSA9IHVzZUN1cnJlbnRWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZyh2b2ljZUJyb2FkY2FzdFByZVJlY29yZGluZ1N0b3JlKTtcblxuICAgIGNvbnN0IHZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nc1N0b3JlID0gc2RrQ29udGV4dC52b2ljZUJyb2FkY2FzdFJlY29yZGluZ3NTdG9yZTtcbiAgICBjb25zdCB7IGN1cnJlbnRWb2ljZUJyb2FkY2FzdFJlY29yZGluZyB9ID0gdXNlQ3VycmVudFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nKHZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nc1N0b3JlKTtcblxuICAgIGNvbnN0IHZvaWNlQnJvYWRjYXN0UGxheWJhY2tzU3RvcmUgPSBzZGtDb250ZXh0LnZvaWNlQnJvYWRjYXN0UGxheWJhY2tzU3RvcmU7XG4gICAgY29uc3QgeyBjdXJyZW50Vm9pY2VCcm9hZGNhc3RQbGF5YmFjayB9ID0gdXNlQ3VycmVudFZvaWNlQnJvYWRjYXN0UGxheWJhY2sodm9pY2VCcm9hZGNhc3RQbGF5YmFja3NTdG9yZSk7XG5cbiAgICBjb25zdCBtb3ZlUGVyc2lzdGVkRWxlbWVudCA9IHVzZVJlZjwoKSA9PiB2b2lkPigpO1xuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPFBpcENvbnRhaW5lcklubmVyXG4gICAgICAgICAgICB2b2ljZUJyb2FkY2FzdFBsYXliYWNrPXtjdXJyZW50Vm9pY2VCcm9hZGNhc3RQbGF5YmFja31cbiAgICAgICAgICAgIHZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nPXtjdXJyZW50Vm9pY2VCcm9hZGNhc3RQcmVSZWNvcmRpbmd9XG4gICAgICAgICAgICB2b2ljZUJyb2FkY2FzdFJlY29yZGluZz17Y3VycmVudFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nfVxuICAgICAgICAgICAgbW92ZVBlcnNpc3RlZEVsZW1lbnQ9e21vdmVQZXJzaXN0ZWRFbGVtZW50fVxuICAgICAgICAvPlxuICAgICk7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLEtBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLE9BQUEsR0FBQUYsT0FBQTtBQUdBLElBQUFHLGVBQUEsR0FBQUMsc0JBQUEsQ0FBQUosT0FBQTtBQUNBLElBQUFLLGtCQUFBLEdBQUFOLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBTSxnQkFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sd0JBQUEsR0FBQUgsc0JBQUEsQ0FBQUosT0FBQTtBQUNBLElBQUFRLFdBQUEsR0FBQUosc0JBQUEsQ0FBQUosT0FBQTtBQUNBLElBQUFTLFFBQUEsR0FBQVQsT0FBQTtBQUNB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