matrix-react-sdk
Version:
SDK for matrix.org using React
299 lines (233 loc) • 37.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _classnames = _interopRequireDefault(require("classnames"));
var _languageHandler = require("../../../languageHandler");
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _ratelimitedfunc = _interopRequireDefault(require("../../../ratelimitedfunc"));
var _SimpleRoomHeader = require("./SimpleRoomHeader");
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _RoomHeaderButtons = _interopRequireDefault(require("../right_panel/RoomHeaderButtons"));
var _E2EIcon = _interopRequireDefault(require("./E2EIcon"));
var _DecoratedRoomAvatar = _interopRequireDefault(require("../avatars/DecoratedRoomAvatar"));
var _AccessibleTooltipButton = _interopRequireDefault(require("../elements/AccessibleTooltipButton"));
var _RoomTopic = _interopRequireDefault(require("../elements/RoomTopic"));
var _RoomName = _interopRequireDefault(require("../elements/RoomName"));
var _CallHandler = require("../../../CallHandler");
var _replaceableComponent = require("../../../utils/replaceableComponent");
var _dec, _class, _class2, _temp;
let RoomHeader = (_dec = (0, _replaceableComponent.replaceableComponent)("views.rooms.RoomHeader"), _dec(_class = (_temp = _class2 = class RoomHeader extends _react.default.Component {
constructor(...args) {
super(...args);
(0, _defineProperty2.default)(this, "_onRoomStateEvents", (event, state) => {
if (!this.props.room || event.getRoomId() !== this.props.room.roomId) {
return;
} // redisplay the room name, topic, etc.
this._rateLimitedUpdate();
});
(0, _defineProperty2.default)(this, "_onRoomAccountData", (event, room) => {
if (!this.props.room || room.roomId !== this.props.room.roomId) return;
if (event.getType() !== "im.vector.room.read_pins") return;
this._rateLimitedUpdate();
});
(0, _defineProperty2.default)(this, "_rateLimitedUpdate", new _ratelimitedfunc.default(function () {
/* eslint-disable babel/no-invalid-this */
this.forceUpdate();
}, 500));
}
componentDidMount() {
const cli = _MatrixClientPeg.MatrixClientPeg.get();
cli.on("RoomState.events", this._onRoomStateEvents);
cli.on("Room.accountData", this._onRoomAccountData);
}
componentWillUnmount() {
const cli = _MatrixClientPeg.MatrixClientPeg.get();
if (cli) {
cli.removeListener("RoomState.events", this._onRoomStateEvents);
cli.removeListener("Room.accountData", this._onRoomAccountData);
}
}
_hasUnreadPins() {
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
if (!currentPinEvent) return false;
if (currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0) {
return false; // no pins == nothing to read
}
const readPinsEvent = this.props.room.getAccountData("im.vector.room.read_pins");
if (readPinsEvent && readPinsEvent.getContent()) {
const readStateEvents = readPinsEvent.getContent().event_ids || [];
if (readStateEvents) {
return !readStateEvents.includes(currentPinEvent.getId());
}
} // There's pins, and we haven't read any of them
return true;
}
_hasPins() {
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
if (!currentPinEvent) return false;
return !(currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0);
}
render() {
let searchStatus = null;
let cancelButton = null;
let pinnedEventsButton = null;
if (this.props.onCancelClick) {
cancelButton = /*#__PURE__*/_react.default.createElement(_SimpleRoomHeader.CancelButton, {
onClick: this.props.onCancelClick
});
} // don't display the search count until the search completes and
// gives us a valid (possibly zero) searchCount.
if (this.props.searchInfo && this.props.searchInfo.searchCount !== undefined && this.props.searchInfo.searchCount !== null) {
searchStatus = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_searchStatus"
}, "\xA0", (0, _languageHandler._t)("(~%(count)s results)", {
count: this.props.searchInfo.searchCount
}));
} // XXX: this is a bit inefficient - we could just compare room.name for 'Empty room'...
let settingsHint = false;
const members = this.props.room ? this.props.room.getJoinedMembers() : undefined;
if (members) {
if (members.length === 1 && members[0].userId === _MatrixClientPeg.MatrixClientPeg.get().credentials.userId) {
const nameEvent = this.props.room.currentState.getStateEvents('m.room.name', '');
if (!nameEvent || !nameEvent.getContent().name) {
settingsHint = true;
}
}
}
let oobName = (0, _languageHandler._t)("Join Room");
if (this.props.oobData && this.props.oobData.name) {
oobName = this.props.oobData.name;
}
const textClasses = (0, _classnames.default)('mx_RoomHeader_nametext', {
mx_RoomHeader_settingsHint: settingsHint
});
const name = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_name",
onClick: this.props.onSettingsClick
}, /*#__PURE__*/_react.default.createElement(_RoomName.default, {
room: this.props.room
}, name => {
const roomName = name || oobName;
return /*#__PURE__*/_react.default.createElement("div", {
dir: "auto",
className: textClasses,
title: roomName
}, roomName);
}), searchStatus);
const topicElement = /*#__PURE__*/_react.default.createElement(_RoomTopic.default, {
room: this.props.room
}, (topic, ref) => /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_topic",
ref: ref,
title: topic,
dir: "auto"
}, topic));
let roomAvatar;
if (this.props.room) {
roomAvatar = /*#__PURE__*/_react.default.createElement(_DecoratedRoomAvatar.default, {
room: this.props.room,
avatarSize: 32,
oobData: this.props.oobData,
viewAvatarOnClick: true
});
}
if (this.props.onPinnedClick && _SettingsStore.default.getValue('feature_pinning')) {
let pinsIndicator = null;
if (this._hasUnreadPins()) {
pinsIndicator = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_pinsIndicator mx_RoomHeader_pinsIndicatorUnread"
});
} else if (this._hasPins()) {
pinsIndicator = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_pinsIndicator"
});
}
pinnedEventsButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: "mx_RoomHeader_button mx_RoomHeader_pinnedButton",
onClick: this.props.onPinnedClick,
title: (0, _languageHandler._t)("Pinned Messages")
}, pinsIndicator);
}
let forgetButton;
if (this.props.onForgetClick) {
forgetButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: "mx_RoomHeader_button mx_RoomHeader_forgetButton",
onClick: this.props.onForgetClick,
title: (0, _languageHandler._t)("Forget room")
});
}
let appsButton;
if (this.props.onAppsClick) {
appsButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: (0, _classnames.default)("mx_RoomHeader_button mx_RoomHeader_appsButton", {
mx_RoomHeader_appsButton_highlight: this.props.appsShown
}),
onClick: this.props.onAppsClick,
title: this.props.appsShown ? (0, _languageHandler._t)("Hide Widgets") : (0, _languageHandler._t)("Show Widgets")
});
}
let searchButton;
if (this.props.onSearchClick && this.props.inRoom) {
searchButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: "mx_RoomHeader_button mx_RoomHeader_searchButton",
onClick: this.props.onSearchClick,
title: (0, _languageHandler._t)("Search")
});
}
let voiceCallButton;
let videoCallButton;
if (this.props.inRoom && _SettingsStore.default.getValue("showCallButtonsInComposer")) {
voiceCallButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: "mx_RoomHeader_button mx_RoomHeader_voiceCallButton",
onClick: () => this.props.onCallPlaced(_CallHandler.PlaceCallType.Voice),
title: (0, _languageHandler._t)("Voice call")
});
videoCallButton = /*#__PURE__*/_react.default.createElement(_AccessibleTooltipButton.default, {
className: "mx_RoomHeader_button mx_RoomHeader_videoCallButton",
onClick: ev => this.props.onCallPlaced(ev.shiftKey ? _CallHandler.PlaceCallType.ScreenSharing : _CallHandler.PlaceCallType.Video),
title: (0, _languageHandler._t)("Video call")
});
}
const rightRow = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_buttons"
}, videoCallButton, voiceCallButton, pinnedEventsButton, forgetButton, appsButton, searchButton);
const e2eIcon = this.props.e2eStatus ? /*#__PURE__*/_react.default.createElement(_E2EIcon.default, {
status: this.props.e2eStatus
}) : undefined;
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader light-panel"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_wrapper",
"aria-owns": "mx_RightPanel"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_avatar"
}, roomAvatar), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomHeader_e2eIcon"
}, e2eIcon), name, topicElement, cancelButton, rightRow, /*#__PURE__*/_react.default.createElement(_RoomHeaderButtons.default, null)));
}
}, (0, _defineProperty2.default)(_class2, "propTypes", {
room: _propTypes.default.object,
oobData: _propTypes.default.object,
inRoom: _propTypes.default.bool,
onSettingsClick: _propTypes.default.func,
onPinnedClick: _propTypes.default.func,
onSearchClick: _propTypes.default.func,
onLeaveClick: _propTypes.default.func,
onCancelClick: _propTypes.default.func,
e2eStatus: _propTypes.default.string,
onAppsClick: _propTypes.default.func,
appsShown: _propTypes.default.bool,
onCallPlaced: _propTypes.default.func // (PlaceCallType) => void;
}), (0, _defineProperty2.default)(_class2, "defaultProps", {
editing: false,
inRoom: false,
onCancelClick: null
}), _temp)) || _class);
exports.default = RoomHeader;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL1Jvb21IZWFkZXIuanMiXSwibmFtZXMiOlsiUm9vbUhlYWRlciIsIlJlYWN0IiwiQ29tcG9uZW50IiwiZXZlbnQiLCJzdGF0ZSIsInByb3BzIiwicm9vbSIsImdldFJvb21JZCIsInJvb21JZCIsIl9yYXRlTGltaXRlZFVwZGF0ZSIsImdldFR5cGUiLCJSYXRlTGltaXRlZEZ1bmMiLCJmb3JjZVVwZGF0ZSIsImNvbXBvbmVudERpZE1vdW50IiwiY2xpIiwiTWF0cml4Q2xpZW50UGVnIiwiZ2V0Iiwib24iLCJfb25Sb29tU3RhdGVFdmVudHMiLCJfb25Sb29tQWNjb3VudERhdGEiLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInJlbW92ZUxpc3RlbmVyIiwiX2hhc1VucmVhZFBpbnMiLCJjdXJyZW50UGluRXZlbnQiLCJjdXJyZW50U3RhdGUiLCJnZXRTdGF0ZUV2ZW50cyIsImdldENvbnRlbnQiLCJwaW5uZWQiLCJsZW5ndGgiLCJyZWFkUGluc0V2ZW50IiwiZ2V0QWNjb3VudERhdGEiLCJyZWFkU3RhdGVFdmVudHMiLCJldmVudF9pZHMiLCJpbmNsdWRlcyIsImdldElkIiwiX2hhc1BpbnMiLCJyZW5kZXIiLCJzZWFyY2hTdGF0dXMiLCJjYW5jZWxCdXR0b24iLCJwaW5uZWRFdmVudHNCdXR0b24iLCJvbkNhbmNlbENsaWNrIiwic2VhcmNoSW5mbyIsInNlYXJjaENvdW50IiwidW5kZWZpbmVkIiwiY291bnQiLCJzZXR0aW5nc0hpbnQiLCJtZW1iZXJzIiwiZ2V0Sm9pbmVkTWVtYmVycyIsInVzZXJJZCIsImNyZWRlbnRpYWxzIiwibmFtZUV2ZW50IiwibmFtZSIsIm9vYk5hbWUiLCJvb2JEYXRhIiwidGV4dENsYXNzZXMiLCJteF9Sb29tSGVhZGVyX3NldHRpbmdzSGludCIsIm9uU2V0dGluZ3NDbGljayIsInJvb21OYW1lIiwidG9waWNFbGVtZW50IiwidG9waWMiLCJyZWYiLCJyb29tQXZhdGFyIiwib25QaW5uZWRDbGljayIsIlNldHRpbmdzU3RvcmUiLCJnZXRWYWx1ZSIsInBpbnNJbmRpY2F0b3IiLCJmb3JnZXRCdXR0b24iLCJvbkZvcmdldENsaWNrIiwiYXBwc0J1dHRvbiIsIm9uQXBwc0NsaWNrIiwibXhfUm9vbUhlYWRlcl9hcHBzQnV0dG9uX2hpZ2hsaWdodCIsImFwcHNTaG93biIsInNlYXJjaEJ1dHRvbiIsIm9uU2VhcmNoQ2xpY2siLCJpblJvb20iLCJ2b2ljZUNhbGxCdXR0b24iLCJ2aWRlb0NhbGxCdXR0b24iLCJvbkNhbGxQbGFjZWQiLCJQbGFjZUNhbGxUeXBlIiwiVm9pY2UiLCJldiIsInNoaWZ0S2V5IiwiU2NyZWVuU2hhcmluZyIsIlZpZGVvIiwicmlnaHRSb3ciLCJlMmVJY29uIiwiZTJlU3RhdHVzIiwiUHJvcFR5cGVzIiwib2JqZWN0IiwiYm9vbCIsImZ1bmMiLCJvbkxlYXZlQ2xpY2siLCJzdHJpbmciLCJlZGl0aW5nIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQWlCQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztJQUdxQkEsVSxXQURwQixnREFBcUIsd0JBQXJCLEMsbUNBQUQsTUFDcUJBLFVBRHJCLFNBQ3dDQyxlQUFNQyxTQUQ5QyxDQUN3RDtBQUFBO0FBQUE7QUFBQSw4REFvQy9CLENBQUNDLEtBQUQsRUFBUUMsS0FBUixLQUFrQjtBQUNuQyxVQUFJLENBQUMsS0FBS0MsS0FBTCxDQUFXQyxJQUFaLElBQW9CSCxLQUFLLENBQUNJLFNBQU4sT0FBc0IsS0FBS0YsS0FBTCxDQUFXQyxJQUFYLENBQWdCRSxNQUE5RCxFQUFzRTtBQUNsRTtBQUNILE9BSGtDLENBS25DOzs7QUFDQSxXQUFLQyxrQkFBTDtBQUNILEtBM0NtRDtBQUFBLDhEQTZDL0IsQ0FBQ04sS0FBRCxFQUFRRyxJQUFSLEtBQWlCO0FBQ2xDLFVBQUksQ0FBQyxL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YyxtQkFBVUcsSUFOVjtBQU9mQyxFQUFBQSxZQUFZLEVBQUVKLG1CQUFVRyxJQVBUO0FBUWZsRCxFQUFBQSxhQUFhLEVBQUUrQyxtQkFBVUcsSUFSVjtBQVNmSixFQUFBQSxTQUFTLEVBQUVDLG1CQUFVSyxNQVROO0FBVWZ2QixFQUFBQSxXQUFXLEVBQUVrQixtQkFBVUcsSUFWUjtBQVdmbkIsRUFBQUEsU0FBUyxFQUFFZ0IsbUJBQVVFLElBWE47QUFZZlosRUFBQUEsWUFBWSxFQUFFVSxtQkFBVUcsSUFaVCxDQVllOztBQVpmLEMsMERBZUc7QUFDbEJHLEVBQUFBLE9BQU8sRUFBRSxLQURTO0FBRWxCbkIsRUFBQUEsTUFBTSxFQUFFLEtBRlU7QUFHbEJsQyxFQUFBQSxhQUFhLEVBQUU7QUFIRyxDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE1LCAyMDE2IE9wZW5NYXJrZXQgTHRkXG5Db3B5cmlnaHQgMjAxOSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgeyBfdCB9IGZyb20gJy4uLy4uLy4uL2xhbmd1YWdlSGFuZGxlcic7XG5pbXBvcnQge01hdHJpeENsaWVudFBlZ30gZnJvbSAnLi4vLi4vLi4vTWF0cml4Q2xpZW50UGVnJztcbmltcG9ydCBSYXRlTGltaXRlZEZ1bmMgZnJvbSAnLi4vLi4vLi4vcmF0ZWxpbWl0ZWRmdW5jJztcblxuaW1wb3J0IHtDYW5jZWxCdXR0b259IGZyb20gJy4vU2ltcGxlUm9vbUhlYWRlcic7XG5pbXBvcnQgU2V0dGluZ3NTdG9yZSBmcm9tIFwiLi4vLi4vLi4vc2V0dGluZ3MvU2V0dGluZ3NTdG9yZVwiO1xuaW1wb3J0IFJvb21IZWFkZXJCdXR0b25zIGZyb20gJy4uL3JpZ2h0X3BhbmVsL1Jvb21IZWFkZXJCdXR0b25zJztcbmltcG9ydCBFMkVJY29uIGZyb20gJy4vRTJFSWNvbic7XG5pbXBvcnQgRGVjb3JhdGVkUm9vbUF2YXRhciBmcm9tIFwiLi4vYXZhdGFycy9EZWNvcmF0ZWRSb29tQXZhdGFyXCI7XG5pbXBvcnQgQWNjZXNzaWJsZVRvb2x0aXBCdXR0b24gZnJvbSBcIi4uL2VsZW1lbnRzL0FjY2Vzc2libGVUb29sdGlwQnV0dG9uXCI7XG5pbXBvcnQgUm9vbVRvcGljIGZyb20gXCIuLi9lbGVtZW50cy9Sb29tVG9waWNcIjtcbmltcG9ydCBSb29tTmFtZSBmcm9tIFwiLi4vZWxlbWVudHMvUm9vbU5hbWVcIjtcbmltcG9ydCB7UGxhY2VDYWxsVHlwZX0gZnJvbSBcIi4uLy4uLy4uL0NhbGxIYW5kbGVyXCI7XG5pbXBvcnQge3JlcGxhY2VhYmxlQ29tcG9uZW50fSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvcmVwbGFjZWFibGVDb21wb25lbnRcIjtcblxuQHJlcGxhY2VhYmxlQ29tcG9uZW50KFwidmlld3Mucm9vbXMuUm9vbUhlYWRlclwiKVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUm9vbUhlYWRlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gICAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICAgICAgcm9vbTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgb29iRGF0YTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgaW5Sb29tOiBQcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgb25TZXR0aW5nc0NsaWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25QaW5uZWRDbGljazogUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uU2VhcmNoQ2xpY2s6IFByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkxlYXZlQ2xpY2s6IFByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNhbmNlbENsaWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZTJlU3RhdHVzOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBvbkFwcHNDbGljazogUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGFwcHNTaG93bjogUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIG9uQ2FsbFBsYWNlZDogUHJvcFR5cGVzLmZ1bmMsIC8vIChQbGFjZUNhbGxUeXBlKSA9PiB2b2lkO1xuICAgIH07XG5cbiAgICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgICAgICBlZGl0aW5nOiBmYWxzZSxcbiAgICAgICAgaW5Sb29tOiBmYWxzZSxcbiAgICAgICAgb25DYW5jZWxDbGljazogbnVsbCxcbiAgICB9O1xuXG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIGNvbnN0IGNsaSA9IE1hdHJpeENsaWVudFBlZy5nZXQoKTtcbiAgICAgICAgY2xpLm9uKFwiUm9vbVN0YXRlLmV2ZW50c1wiLCB0aGlzLl9vblJvb21TdGF0ZUV2ZW50cyk7XG4gICAgICAgIGNsaS5vbihcIlJvb20uYWNjb3VudERhdGFcIiwgdGhpcy5fb25Sb29tQWNjb3VudERhdGEpO1xuICAgIH1cblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG4gICAgICAgIGlmIChjbGkpIHtcbiAgICAgICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihcIlJvb21TdGF0ZS5ldmVudHNcIiwgdGhpcy5fb25Sb29tU3RhdGVFdmVudHMpO1xuICAgICAgICAgICAgY2xpLnJlbW92ZUxpc3RlbmVyKFwiUm9vbS5hY2NvdW50RGF0YVwiLCB0aGlzLl9vblJvb21BY2NvdW50RGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfb25Sb29tU3RhdGVFdmVudHMgPSAoZXZlbnQsIHN0YXRlKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5yb29tIHx8IGV2ZW50LmdldFJvb21JZCgpICE9PSB0aGlzLnByb3BzLnJvb20ucm9vbUlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZWRpc3BsYXkgdGhlIHJvb20gbmFtZSwgdG9waWMsIGV0Yy5cbiAgICAgICAgdGhpcy5fcmF0ZUxpbWl0ZWRVcGRhdGUoKTtcbiAgICB9O1xuXG4gICAgX29uUm9vbUFjY291bnREYXRhID0gKGV2ZW50LCByb29tKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5yb29tIHx8IHJvb20ucm9vbUlkICE9PSB0aGlzLnByb3BzLnJvb20ucm9vbUlkKSByZXR1cm47XG4gICAgICAgIGlmIChldmVudC5nZXRUeXBlKCkgIT09IFwiaW0udmVjdG9yLnJvb20ucmVhZF9waW5zXCIpIHJldHVybjtcblxuICAgICAgICB0aGlzLl9yYXRlTGltaXRlZFVwZGF0ZSgpO1xuICAgIH07XG5cbiAgICBfcmF0ZUxpbWl0ZWRVcGRhdGUgPSBuZXcgUmF0ZUxpbWl0ZWRGdW5jKGZ1bmN0aW9uKCkge1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBiYWJlbC9uby1pbnZhbGlkLXRoaXMgKi9cbiAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgIH0sIDUwMCk7XG5cbiAgICBfaGFzVW5yZWFkUGlucygpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBpbkV2ZW50ID0gdGhpcy5wcm9wcy5yb29tLmN1cnJlbnRTdGF0ZS5nZXRTdGF0ZUV2ZW50cyhcIm0ucm9vbS5waW5uZWRfZXZlbnRzXCIsICcnKTtcbiAgICAgICAgaWYgKCFjdXJyZW50UGluRXZlbnQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGN1cnJlbnRQaW5FdmVudC5nZXRDb250ZW50KCkucGlubmVkICYmIGN1cnJlbnRQaW5FdmVudC5nZXRDb250ZW50KCkucGlubmVkLmxlbmd0aCA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vIHBpbnMgPT0gbm90aGluZyB0byByZWFkXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWFkUGluc0V2ZW50ID0gdGhpcy5wcm9wcy5yb29tLmdldEFjY291bnREYXRhKFwiaW0udmVjdG9yLnJvb20ucmVhZF9waW5zXCIpO1xuICAgICAgICBpZiAocmVhZFBpbnNFdmVudCAmJiByZWFkUGluc0V2ZW50LmdldENvbnRlbnQoKSkge1xuICAgICAgICAgICAgY29uc3QgcmVhZFN0YXRlRXZlbnRzID0gcmVhZFBpbnNFdmVudC5nZXRDb250ZW50KCkuZXZlbnRfaWRzIHx8IFtdO1xuICAgICAgICAgICAgaWYgKHJlYWRTdGF0ZUV2ZW50cykge1xuICAgICAgICAgICAgICAgIHJldHVybiAhcmVhZFN0YXRlRXZlbnRzLmluY2x1ZGVzKGN1cnJlbnRQaW5FdmVudC5nZXRJZCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZXJlJ3MgcGlucywgYW5kIHdlIGhhdmVuJ3QgcmVhZCBhbnkgb2YgdGhlbVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBfaGFzUGlucygpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBpbkV2ZW50ID0gdGhpcy5wcm9wcy5yb29tLmN1cnJlbnRTdGF0ZS5nZXRTdGF0ZUV2ZW50cyhcIm0ucm9vbS5waW5uZWRfZXZlbnRzXCIsICcnKTtcbiAgICAgICAgaWYgKCFjdXJyZW50UGluRXZlbnQpIHJldHVybiBmYWxzZTtcblxuICAgICAgICByZXR1cm4gIShjdXJyZW50UGluRXZlbnQuZ2V0Q29udGVudCgpLnBpbm5lZCAmJiBjdXJyZW50UGluRXZlbnQuZ2V0Q29udGVudCgpLnBpbm5lZC5sZW5ndGggPD0gMCk7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgc2VhcmNoU3RhdHVzID0gbnVsbDtcbiAgICAgICAgbGV0IGNhbmNlbEJ1dHRvbiA9IG51bGw7XG4gICAgICAgIGxldCBwaW5uZWRFdmVudHNCdXR0b24gPSBudWxsO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uQ2FuY2VsQ2xpY2spIHtcbiAgICAgICAgICAgIGNhbmNlbEJ1dHRvbiA9IDxDYW5jZWxCdXR0b24gb25DbGljaz17dGhpcy5wcm9wcy5vbkNhbmNlbENsaWNrfSAvPjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRvbid0IGRpc3BsYXkgdGhlIHNlYXJjaCBjb3VudCB1bnRpbCB0aGUgc2VhcmNoIGNvbXBsZXRlcyBhbmRcbiAgICAgICAgLy8gZ2l2ZXMgdXMgYSB2YWxpZCAocG9zc2libHkgemVybykgc2VhcmNoQ291bnQuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLnNlYXJjaEluZm8gJiZcbiAgICAgICAgICAgIHRoaXMucHJvcHMuc2VhcmNoSW5mby5zZWFyY2hDb3VudCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICB0aGlzLnByb3BzLnNlYXJjaEluZm8uc2VhcmNoQ291bnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHNlYXJjaFN0YXR1cyA9IDxkaXYgY2xhc3NOYW1lPVwibXhfUm9vbUhlYWRlcl9zZWFyY2hTdGF0dXNcIj4mbmJzcDtcbiAgICAgICAgICAgICAgICB7IF90KFwiKH4lKGNvdW50KXMgcmVzdWx0cylcIiwgeyBjb3VudDogdGhpcy5wcm9wcy5zZWFyY2hJbmZvLnNlYXJjaENvdW50IH0pIH1cbiAgICAgICAgICAgIDwvZGl2PjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFhYWDogdGhpcyBpcyBhIGJpdCBpbmVmZmljaWVudCAtIHdlIGNvdWxkIGp1c3QgY29tcGFyZSByb29tLm5hbWUgZm9yICdFbXB0eSByb29tJy4uLlxuICAgICAgICBsZXQgc2V0dGluZ3NIaW50ID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG1lbWJlcnMgPSB0aGlzLnByb3BzLnJvb20gPyB0aGlzLnByb3BzLnJvb20uZ2V0Sm9pbmVkTWVtYmVycygpIDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAobWVtYmVycykge1xuICAgICAgICAgICAgaWYgKG1lbWJlcnMubGVuZ3RoID09PSAxICYmIG1lbWJlcnNbMF0udXNlcklkID09PSBNYXRyaXhDbGllbnRQZWcuZ2V0KCkuY3JlZGVudGlhbHMudXNlcklkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZUV2ZW50ID0gdGhpcy5wcm9wcy5yb29tLmN1cnJlbnRTdGF0ZS5nZXRTdGF0ZUV2ZW50cygnbS5yb29tLm5hbWUnLCAnJyk7XG4gICAgICAgICAgICAgICAgaWYgKCFuYW1lRXZlbnQgfHwgIW5hbWVFdmVudC5nZXRDb250ZW50KCkubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc0hpbnQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBvb2JOYW1lID0gX3QoXCJKb2luIFJvb21cIik7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9vYkRhdGEgJiYgdGhpcy5wcm9wcy5vb2JEYXRhLm5hbWUpIHtcbiAgICAgICAgICAgIG9vYk5hbWUgPSB0aGlzLnByb3BzLm9vYkRhdGEubmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRleHRDbGFzc2VzID0gY2xhc3NOYW1lcygnbXhfUm9vbUhlYWRlcl9uYW1ldGV4dCcsIHsgbXhfUm9vbUhlYWRlcl9zZXR0aW5nc0hpbnQ6IHNldHRpbmdzSGludCB9KTtcbiAgICAgICAgY29uc3QgbmFtZSA9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfbmFtZVwiIG9uQ2xpY2s9e3RoaXMucHJvcHMub25TZXR0aW5nc0NsaWNrfT5cbiAgICAgICAgICAgICAgICA8Um9vbU5hbWUgcm9vbT17dGhpcy5wcm9wcy5yb29tfT5cbiAgICAgICAgICAgICAgICAgICAgeyhuYW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByb29tTmFtZSA9IG5hbWUgfHwgb29iTmFtZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA8ZGl2IGRpcj1cImF1dG9cIiBjbGFzc05hbWU9e3RleHRDbGFzc2VzfSB0aXRsZT17cm9vbU5hbWV9Pnsgcm9vbU5hbWUgfTwvZGl2PjtcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICA8L1Jvb21OYW1lPlxuICAgICAgICAgICAgICAgIHsgc2VhcmNoU3RhdHVzIH1cbiAgICAgICAgICAgIDwvZGl2PjtcblxuICAgICAgICBjb25zdCB0b3BpY0VsZW1lbnQgPSA8Um9vbVRvcGljIHJvb209e3RoaXMucHJvcHMucm9vbX0+XG4gICAgICAgICAgICB7KHRvcGljLCByZWYpID0+IDxkaXYgY2xhc3NOYW1lPVwibXhfUm9vbUhlYWRlcl90b3BpY1wiIHJlZj17cmVmfSB0aXRsZT17dG9waWN9IGRpcj1cImF1dG9cIj5cbiAgICAgICAgICAgICAgICB7IHRvcGljIH1cbiAgICAgICAgICAgIDwvZGl2Pn1cbiAgICAgICAgPC9Sb29tVG9waWM+O1xuXG4gICAgICAgIGxldCByb29tQXZhdGFyO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5yb29tKSB7XG4gICAgICAgICAgICByb29tQXZhdGFyID0gPERlY29yYXRlZFJvb21BdmF0YXJcbiAgICAgICAgICAgICAgICByb29tPXt0aGlzLnByb3BzLnJvb219XG4gICAgICAgICAgICAgICAgYXZhdGFyU2l6ZT17MzJ9XG4gICAgICAgICAgICAgICAgb29iRGF0YT17dGhpcy5wcm9wcy5vb2JEYXRhfVxuICAgICAgICAgICAgICAgIHZpZXdBdmF0YXJPbkNsaWNrPXt0cnVlfVxuICAgICAgICAgICAgLz47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5vblBpbm5lZENsaWNrICYmIFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoJ2ZlYXR1cmVfcGlubmluZycpKSB7XG4gICAgICAgICAgICBsZXQgcGluc0luZGljYXRvciA9IG51bGw7XG4gICAgICAgICAgICBpZiAodGhpcy5faGFzVW5yZWFkUGlucygpKSB7XG4gICAgICAgICAgICAgICAgcGluc0luZGljYXRvciA9ICg8ZGl2IGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfcGluc0luZGljYXRvciBteF9Sb29tSGVhZGVyX3BpbnNJbmRpY2F0b3JVbnJlYWRcIiAvPik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2hhc1BpbnMoKSkge1xuICAgICAgICAgICAgICAgIHBpbnNJbmRpY2F0b3IgPSAoPGRpdiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX3BpbnNJbmRpY2F0b3JcIiAvPik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBpbm5lZEV2ZW50c0J1dHRvbiA9XG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVUb29sdGlwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfYnV0dG9uIG14X1Jvb21IZWFkZXJfcGlubmVkQnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5vblBpbm5lZENsaWNrfVxuICAgICAgICAgICAgICAgICAgICB0aXRsZT17X3QoXCJQaW5uZWQgTWVzc2FnZXNcIil9XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7IHBpbnNJbmRpY2F0b3IgfVxuICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZVRvb2x0aXBCdXR0b24+O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZvcmdldEJ1dHRvbjtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25Gb3JnZXRDbGljaykge1xuICAgICAgICAgICAgZm9yZ2V0QnV0dG9uID1cbiAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZVRvb2x0aXBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfUm9vbUhlYWRlcl9idXR0b24gbXhfUm9vbUhlYWRlcl9mb3JnZXRCdXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLnByb3BzLm9uRm9yZ2V0Q2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPXtfdChcIkZvcmdldCByb29tXCIpfSAvPjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhcHBzQnV0dG9uO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkFwcHNDbGljaykge1xuICAgICAgICAgICAgYXBwc0J1dHRvbiA9XG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVUb29sdGlwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhcIm14X1Jvb21IZWFkZXJfYnV0dG9uIG14X1Jvb21IZWFkZXJfYXBwc0J1dHRvblwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBteF9Sb29tSGVhZGVyX2FwcHNCdXR0b25faGlnaGxpZ2h0OiB0aGlzLnByb3BzLmFwcHNTaG93bixcbiAgICAgICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMucHJvcHMub25BcHBzQ2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPXt0aGlzLnByb3BzLmFwcHNTaG93biA/IF90KFwiSGlkZSBXaWRnZXRzXCIpIDogX3QoXCJTaG93IFdpZGdldHNcIil9IC8+O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHNlYXJjaEJ1dHRvbjtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25TZWFyY2hDbGljayAmJiB0aGlzLnByb3BzLmluUm9vbSkge1xuICAgICAgICAgICAgc2VhcmNoQnV0dG9uID1cbiAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZVRvb2x0aXBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfUm9vbUhlYWRlcl9idXR0b24gbXhfUm9vbUhlYWRlcl9zZWFyY2hCdXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLnByb3BzLm9uU2VhcmNoQ2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPXtfdChcIlNlYXJjaFwiKX0gLz47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdm9pY2VDYWxsQnV0dG9uO1xuICAgICAgICBsZXQgdmlkZW9DYWxsQnV0dG9uO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5pblJvb20gJiYgU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcInNob3dDYWxsQnV0dG9uc0luQ29tcG9zZXJcIikpIHtcbiAgICAgICAgICAgIHZvaWNlQ2FsbEJ1dHRvbiA9XG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVUb29sdGlwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfYnV0dG9uIG14X1Jvb21IZWFkZXJfdm9pY2VDYWxsQnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4gdGhpcy5wcm9wcy5vbkNhbGxQbGFjZWQoUGxhY2VDYWxsVHlwZS5Wb2ljZSl9XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPXtfdChcIlZvaWNlIGNhbGxcIil9IC8+O1xuICAgICAgICAgICAgdmlkZW9DYWxsQnV0dG9uID1cbiAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZVRvb2x0aXBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfUm9vbUhlYWRlcl9idXR0b24gbXhfUm9vbUhlYWRlcl92aWRlb0NhbGxCdXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZXYpID0+IHRoaXMucHJvcHMub25DYWxsUGxhY2VkKFxuICAgICAgICAgICAgICAgICAgICAgICAgZXYuc2hpZnRLZXkgPyBQbGFjZUNhbGxUeXBlLlNjcmVlblNoYXJpbmcgOiBQbGFjZUNhbGxUeXBlLlZpZGVvKX1cbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9e190KFwiVmlkZW8gY2FsbFwiKX0gLz47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByaWdodFJvdyA9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfYnV0dG9uc1wiPlxuICAgICAgICAgICAgICAgIHsgdmlkZW9DYWxsQnV0dG9uIH1cbiAgICAgICAgICAgICAgICB7IHZvaWNlQ2FsbEJ1dHRvbiB9XG4gICAgICAgICAgICAgICAgeyBwaW5uZWRFdmVudHNCdXR0b24gfVxuICAgICAgICAgICAgICAgIHsgZm9yZ2V0QnV0dG9uIH1cbiAgICAgICAgICAgICAgICB7IGFwcHNCdXR0b24gfVxuICAgICAgICAgICAgICAgIHsgc2VhcmNoQnV0dG9uIH1cbiAgICAgICAgICAgIDwvZGl2PjtcblxuICAgICAgICBjb25zdCBlMmVJY29uID0gdGhpcy5wcm9wcy5lMmVTdGF0dXMgPyA8RTJFSWNvbiBzdGF0dXM9e3RoaXMucHJvcHMuZTJlU3RhdHVzfSAvPiA6IHVuZGVmaW5lZDtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyIGxpZ2h0LXBhbmVsXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX3dyYXBwZXJcIiBhcmlhLW93bnM9XCJteF9SaWdodFBhbmVsXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfUm9vbUhlYWRlcl9hdmF0YXJcIj57IHJvb21BdmF0YXIgfTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfZTJlSWNvblwiPnsgZTJlSWNvbiB9PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIHsgbmFtZSB9XG4gICAgICAgICAgICAgICAgICAgIHsgdG9waWNFbGVtZW50IH1cbiAgICAgICAgICAgICAgICAgICAgeyBjYW5jZWxCdXR0b24gfVxuICAgICAgICAgICAgICAgICAgICB7IHJpZ2h0Um93IH1cbiAgICAgICAgICAgICAgICAgICAgPFJvb21IZWFkZXJCdXR0b25zIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG59XG4iXX0=