matrix-react-sdk
Version:
SDK for matrix.org using React
1,251 lines (1,098 loc) • 154 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.SendCustomEvent = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var sdk = _interopRequireWildcard(require("../../../index"));
var _SyntaxHighlight = _interopRequireDefault(require("../elements/SyntaxHighlight"));
var _languageHandler = require("../../../languageHandler");
var _Field = _interopRequireDefault(require("../elements/Field"));
var _MatrixClientContext = _interopRequireDefault(require("../../../contexts/MatrixClientContext"));
var _useEventEmitter = require("../../../hooks/useEventEmitter");
var _VerificationRequest = require("matrix-js-sdk/src/crypto/verification/request/VerificationRequest");
var _WidgetStore = _interopRequireDefault(require("../../../stores/WidgetStore"));
var _AsyncStore = require("../../../stores/AsyncStore");
var _Settings = require("../../../settings/Settings");
var _SettingsStore = _interopRequireWildcard(require("../../../settings/SettingsStore"));
var _Modal = _interopRequireDefault(require("../../../Modal"));
var _ErrorDialog = _interopRequireDefault(require("./ErrorDialog"));
var _replaceableComponent = require("../../../utils/replaceableComponent");
var _room = require("matrix-js-sdk/src/models/room");
var _event = require("matrix-js-sdk/src/models/event");
var _dec, _class, _class2, _temp;
class GenericEditor extends _react.default.PureComponent {
// static propTypes = {onBack: PropTypes.func.isRequired};
constructor(props) {
super(props);
this._onChange = this._onChange.bind(this);
this.onBack = this.onBack.bind(this);
}
onBack() {
if (this.state.message) {
this.setState({
message: null
});
} else {
this.props.onBack();
}
}
_onChange(e) {
this.setState({
[e.target.id]: e.target.type === 'checkbox' ? e.target.checked : e.target.value
});
}
_buttons() {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back')), !this.state.message && /*#__PURE__*/_react.default.createElement("button", {
onClick: this._send
}, (0, _languageHandler._t)('Send')));
}
textInput(id, label) {
return /*#__PURE__*/_react.default.createElement(_Field.default, {
id: id,
label: label,
size: "42",
autoFocus: true,
type: "text",
autoComplete: "on",
value: this.state[id],
onChange: this._onChange
});
}
}
class SendCustomEvent extends GenericEditor {
static getLabel() {
return (0, _languageHandler._t)('Send Custom Event');
}
constructor(props) {
super(props);
this._send = this._send.bind(this);
const {
eventType,
stateKey,
evContent
} = Object.assign({
eventType: '',
stateKey: '',
evContent: '{\n\n}'
}, this.props.inputs);
this.state = {
isStateEvent: Boolean(this.props.forceStateEvent),
eventType,
stateKey,
evContent
};
}
send(content) {
const cli = this.context;
if (this.state.isStateEvent) {
return cli.sendStateEvent(this.props.room.roomId, this.state.eventType, content, this.state.stateKey);
} else {
return cli.sendEvent(this.props.room.roomId, this.state.eventType, content);
}
}
async _send() {
if (this.state.eventType === '') {
this.setState({
message: (0, _languageHandler._t)('You must specify an event type!')
});
return;
}
let message;
try {
const content = JSON.parse(this.state.evContent);
await this.send(content);
message = (0, _languageHandler._t)('Event sent!');
} catch (e) {
message = (0, _languageHandler._t)('Failed to send custom event.') + ' (' + e.toString() + ')';
}
this.setState({
message
});
}
render() {
if (this.state.message) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, this.state.message), this._buttons());
}
const showTglFlip = !this.state.message && !this.props.forceStateEvent && !this.props.forceGeneralEvent;
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_content"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_eventTypeStateKeyGroup"
}, this.textInput('eventType', (0, _languageHandler._t)('Event Type')), this.state.isStateEvent && this.textInput('stateKey', (0, _languageHandler._t)('State Key'))), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement(_Field.default, {
id: "evContent",
label: (0, _languageHandler._t)("Event Content"),
type: "text",
className: "mx_DevTools_textarea",
autoComplete: "off",
value: this.state.evContent,
onChange: this._onChange,
element: "textarea"
})), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back')), !this.state.message && /*#__PURE__*/_react.default.createElement("button", {
onClick: this._send
}, (0, _languageHandler._t)('Send')), showTglFlip && /*#__PURE__*/_react.default.createElement("div", {
style: {
float: "right"
}
}, /*#__PURE__*/_react.default.createElement("input", {
id: "isStateEvent",
className: "mx_DevTools_tgl mx_DevTools_tgl-flip",
type: "checkbox",
onChange: this._onChange,
checked: this.state.isStateEvent
}), /*#__PURE__*/_react.default.createElement("label", {
className: "mx_DevTools_tgl-btn",
"data-tg-off": "Event",
"data-tg-on": "State Event",
htmlFor: "isStateEvent"
}))));
}
}
exports.SendCustomEvent = SendCustomEvent;
(0, _defineProperty2.default)(SendCustomEvent, "propTypes", {
onBack: _propTypes.default.func.isRequired,
room: _propTypes.default.instanceOf(_room.Room).isRequired,
forceStateEvent: _propTypes.default.bool,
forceGeneralEvent: _propTypes.default.bool,
inputs: _propTypes.default.object
});
(0, _defineProperty2.default)(SendCustomEvent, "contextType", _MatrixClientContext.default);
class SendAccountData extends GenericEditor {
static getLabel() {
return (0, _languageHandler._t)('Send Account Data');
}
constructor(props) {
super(props);
this._send = this._send.bind(this);
const {
eventType,
evContent
} = Object.assign({
eventType: '',
evContent: '{\n\n}'
}, this.props.inputs);
this.state = {
isRoomAccountData: Boolean(this.props.isRoomAccountData),
eventType,
evContent
};
}
send(content) {
const cli = this.context;
if (this.state.isRoomAccountData) {
return cli.setRoomAccountData(this.props.room.roomId, this.state.eventType, content);
}
return cli.setAccountData(this.state.eventType, content);
}
async _send() {
if (this.state.eventType === '') {
this.setState({
message: (0, _languageHandler._t)('You must specify an event type!')
});
return;
}
let message;
try {
const content = JSON.parse(this.state.evContent);
await this.send(content);
message = (0, _languageHandler._t)('Event sent!');
} catch (e) {
message = (0, _languageHandler._t)('Failed to send custom event.') + ' (' + e.toString() + ')';
}
this.setState({
message
});
}
render() {
if (this.state.message) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, this.state.message), this._buttons());
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_content"
}, this.textInput('eventType', (0, _languageHandler._t)('Event Type')), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement(_Field.default, {
id: "evContent",
label: (0, _languageHandler._t)("Event Content"),
type: "text",
className: "mx_DevTools_textarea",
autoComplete: "off",
value: this.state.evContent,
onChange: this._onChange,
element: "textarea"
})), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back')), !this.state.message && /*#__PURE__*/_react.default.createElement("button", {
onClick: this._send
}, (0, _languageHandler._t)('Send')), !this.state.message && /*#__PURE__*/_react.default.createElement("div", {
style: {
float: "right"
}
}, /*#__PURE__*/_react.default.createElement("input", {
id: "isRoomAccountData",
className: "mx_DevTools_tgl mx_DevTools_tgl-flip",
type: "checkbox",
onChange: this._onChange,
checked: this.state.isRoomAccountData,
disabled: this.props.forceMode
}), /*#__PURE__*/_react.default.createElement("label", {
className: "mx_DevTools_tgl-btn",
"data-tg-off": "Account Data",
"data-tg-on": "Room Data",
htmlFor: "isRoomAccountData"
}))));
}
}
(0, _defineProperty2.default)(SendAccountData, "propTypes", {
room: _propTypes.default.instanceOf(_room.Room).isRequired,
isRoomAccountData: _propTypes.default.bool,
forceMode: _propTypes.default.bool,
inputs: _propTypes.default.object
});
(0, _defineProperty2.default)(SendAccountData, "contextType", _MatrixClientContext.default);
const INITIAL_LOAD_TILES = 20;
const LOAD_TILES_STEP_SIZE = 50;
class FilteredList extends _react.default.PureComponent {
static filterChildren(children, query) {
if (!query) return children;
const lcQuery = query.toLowerCase();
return children.filter(child => child.key.toLowerCase().includes(lcQuery));
}
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "showAll", () => {
this.setState({
truncateAt: this.state.truncateAt + LOAD_TILES_STEP_SIZE
});
});
(0, _defineProperty2.default)(this, "createOverflowElement", (overflowCount
/*: number*/
, totalCount
/*: number*/
) => {
return /*#__PURE__*/_react.default.createElement("button", {
className: "mx_DevTools_RoomStateExplorer_button",
onClick: this.showAll
}, (0, _languageHandler._t)("and %(count)s others...", {
count: overflowCount
}));
});
(0, _defineProperty2.default)(this, "onQuery", ev => {
if (this.props.onChange) this.props.onChange(ev.target.value);
});
(0, _defineProperty2.default)(this, "getChildren", (start
/*: number*/
, end
/*: number*/
) => {
return this.state.filteredChildren.slice(start, end);
});
(0, _defineProperty2.default)(this, "getChildCount", () =>
/*: number*/
{
return this.state.filteredChildren.length;
});
this.state = {
filteredChildren: FilteredList.filterChildren(this.props.children, this.props.query),
truncateAt: INITIAL_LOAD_TILES
};
} // TODO: [REACT-WARNING] Replace with appropriate lifecycle event
UNSAFE_componentWillReceiveProps(nextProps) {
// eslint-disable-line camelcase
if (this.props.children === nextProps.children && this.props.query === nextProps.query) return;
this.setState({
filteredChildren: FilteredList.filterChildren(nextProps.children, nextProps.query),
truncateAt: INITIAL_LOAD_TILES
});
}
render() {
const TruncatedList = sdk.getComponent("elements.TruncatedList");
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_Field.default, {
label: (0, _languageHandler._t)('Filter results'),
autoFocus: true,
size: 64,
type: "text",
autoComplete: "off",
value: this.props.query,
onChange: this.onQuery,
className: "mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query" // force re-render so that autoFocus is applied when this component is re-used
,
key: this.props.children[0] ? this.props.children[0].key : ''
}), /*#__PURE__*/_react.default.createElement(TruncatedList, {
getChildren: this.getChildren,
getChildCount: this.getChildCount,
truncateAt: this.state.truncateAt,
createOverflowElement: this.createOverflowElement
}));
}
}
(0, _defineProperty2.default)(FilteredList, "propTypes", {
children: _propTypes.default.any,
query: _propTypes.default.string,
onChange: _propTypes.default.func
});
class RoomStateExplorer extends _react.default.PureComponent {
static getLabel() {
return (0, _languageHandler._t)('Explore Room State');
}
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "roomStateEvents", void 0);
this.roomStateEvents = this.props.room.currentState.events;
this.onBack = this.onBack.bind(this);
this.editEv = this.editEv.bind(this);
this.onQueryEventType = this.onQueryEventType.bind(this);
this.onQueryStateKey = this.onQueryStateKey.bind(this);
this.state = {
eventType: null,
event: null,
editing: false,
queryEventType: '',
queryStateKey: ''
};
}
browseEventType(eventType) {
return () => {
this.setState({
eventType
});
};
}
onViewSourceClick(event) {
return () => {
this.setState({
event
});
};
}
onBack() {
if (this.state.editing) {
this.setState({
editing: false
});
} else if (this.state.event) {
this.setState({
event: null
});
} else if (this.state.eventType) {
this.setState({
eventType: null
});
} else {
this.props.onBack();
}
}
editEv() {
this.setState({
editing: true
});
}
onQueryEventType(filterEventType) {
this.setState({
queryEventType: filterEventType
});
}
onQueryStateKey(filterStateKey) {
this.setState({
queryStateKey: filterStateKey
});
}
render() {
if (this.state.event) {
if (this.state.editing) {
return /*#__PURE__*/_react.default.createElement(SendCustomEvent, {
room: this.props.room,
forceStateEvent: true,
onBack: this.onBack,
inputs: {
eventType: this.state.event.getType(),
evContent: JSON.stringify(this.state.event.getContent(), null, '\t'),
stateKey: this.state.event.getStateKey()
}
});
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_ViewSource"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, /*#__PURE__*/_react.default.createElement(_SyntaxHighlight.default, {
className: "json"
}, JSON.stringify(this.state.event.event, null, 2))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back')), /*#__PURE__*/_react.default.createElement("button", {
onClick: this.editEv
}, (0, _languageHandler._t)('Edit'))));
}
let list = null;
const classes = 'mx_DevTools_RoomStateExplorer_button';
if (this.state.eventType === null) {
list = /*#__PURE__*/_react.default.createElement(FilteredList, {
query: this.state.queryEventType,
onChange: this.onQueryEventType
}, Array.from(this.roomStateEvents.entries()).map(([eventType, allStateKeys]) => {
let onClickFn;
if (allStateKeys.size === 1 && allStateKeys.has("")) {
onClickFn = this.onViewSourceClick(allStateKeys.get(""));
} else {
onClickFn = this.browseEventType(eventType);
}
return /*#__PURE__*/_react.default.createElement("button", {
className: classes,
key: eventType,
onClick: onClickFn
}, eventType);
}));
} else {
const stateGroup = this.roomStateEvents.get(this.state.eventType);
list = /*#__PURE__*/_react.default.createElement(FilteredList, {
query: this.state.queryStateKey,
onChange: this.onQueryStateKey
}, Array.from(stateGroup.entries()).map(([stateKey, ev]) => {
return /*#__PURE__*/_react.default.createElement("button", {
className: classes,
key: stateKey,
onClick: this.onViewSourceClick(ev)
}, stateKey);
}));
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, list), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back'))));
}
}
(0, _defineProperty2.default)(RoomStateExplorer, "propTypes", {
onBack: _propTypes.default.func.isRequired,
room: _propTypes.default.instanceOf(_room.Room).isRequired
});
(0, _defineProperty2.default)(RoomStateExplorer, "contextType", _MatrixClientContext.default);
class AccountDataExplorer extends _react.default.PureComponent {
static getLabel() {
return (0, _languageHandler._t)('Explore Account Data');
}
constructor(props) {
super(props);
this.onBack = this.onBack.bind(this);
this.editEv = this.editEv.bind(this);
this._onChange = this._onChange.bind(this);
this.onQueryEventType = this.onQueryEventType.bind(this);
this.state = {
isRoomAccountData: false,
event: null,
editing: false,
queryEventType: ''
};
}
getData() {
if (this.state.isRoomAccountData) {
return this.props.room.accountData;
}
return this.context.store.accountData;
}
onViewSourceClick(event) {
return () => {
this.setState({
event
});
};
}
onBack() {
if (this.state.editing) {
this.setState({
editing: false
});
} else if (this.state.event) {
this.setState({
event: null
});
} else {
this.props.onBack();
}
}
_onChange(e) {
this.setState({
[e.target.id]: e.target.type === 'checkbox' ? e.target.checked : e.target.value
});
}
editEv() {
this.setState({
editing: true
});
}
onQueryEventType(queryEventType) {
this.setState({
queryEventType
});
}
render() {
if (this.state.event) {
if (this.state.editing) {
return /*#__PURE__*/_react.default.createElement(SendAccountData, {
room: this.props.room,
isRoomAccountData: this.state.isRoomAccountData,
onBack: this.onBack,
inputs: {
eventType: this.state.event.getType(),
evContent: JSON.stringify(this.state.event.getContent(), null, '\t')
},
forceMode: true
});
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_ViewSource"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_content"
}, /*#__PURE__*/_react.default.createElement(_SyntaxHighlight.default, {
className: "json"
}, JSON.stringify(this.state.event.event, null, 2))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back')), /*#__PURE__*/_react.default.createElement("button", {
onClick: this.editEv
}, (0, _languageHandler._t)('Edit'))));
}
const rows = [];
const classes = 'mx_DevTools_RoomStateExplorer_button';
const data = this.getData();
Object.keys(data).forEach(evType => {
const ev = data[evType];
rows.push( /*#__PURE__*/_react.default.createElement("button", {
className: classes,
key: evType,
onClick: this.onViewSourceClick(ev)
}, evType));
});
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, /*#__PURE__*/_react.default.createElement(FilteredList, {
query: this.state.queryEventType,
onChange: this.onQueryEventType
}, rows)), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)('Back')), !this.state.message && /*#__PURE__*/_react.default.createElement("div", {
style: {
float: "right"
}
}, /*#__PURE__*/_react.default.createElement("input", {
id: "isRoomAccountData",
className: "mx_DevTools_tgl mx_DevTools_tgl-flip",
type: "checkbox",
onChange: this._onChange,
checked: this.state.isRoomAccountData
}), /*#__PURE__*/_react.default.createElement("label", {
className: "mx_DevTools_tgl-btn",
"data-tg-off": "Account Data",
"data-tg-on": "Room Data",
htmlFor: "isRoomAccountData"
}))));
}
}
(0, _defineProperty2.default)(AccountDataExplorer, "propTypes", {
onBack: _propTypes.default.func.isRequired,
room: _propTypes.default.instanceOf(_room.Room).isRequired
});
(0, _defineProperty2.default)(AccountDataExplorer, "contextType", _MatrixClientContext.default);
class ServersInRoomList extends _react.default.PureComponent {
static getLabel() {
return (0, _languageHandler._t)('View Servers in Room');
}
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onQuery", query => {
this.setState({
query
});
});
const room = this.props.room;
const servers = new Set();
room.currentState.getStateEvents("m.room.member").forEach(ev => servers.add(ev.getSender().split(":")[1]));
this.servers = Array.from(servers).map(s => /*#__PURE__*/_react.default.createElement("button", {
key: s,
className: "mx_DevTools_ServersInRoomList_button"
}, s));
this.state = {
query: ''
};
}
render() {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, /*#__PURE__*/_react.default.createElement(FilteredList, {
query: this.state.query,
onChange: this.onQuery
}, this.servers)), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.props.onBack
}, (0, _languageHandler._t)('Back'))));
}
}
(0, _defineProperty2.default)(ServersInRoomList, "propTypes", {
onBack: _propTypes.default.func.isRequired,
room: _propTypes.default.instanceOf(_room.Room).isRequired
});
(0, _defineProperty2.default)(ServersInRoomList, "contextType", _MatrixClientContext.default);
const PHASE_MAP = {
[_VerificationRequest.PHASE_UNSENT]: "unsent",
[_VerificationRequest.PHASE_REQUESTED]: "requested",
[_VerificationRequest.PHASE_READY]: "ready",
[_VerificationRequest.PHASE_DONE]: "done",
[_VerificationRequest.PHASE_STARTED]: "started",
[_VerificationRequest.PHASE_CANCELLED]: "cancelled"
};
function VerificationRequest({
txnId,
request
}) {
const [, updateState] = (0, _react.useState)();
const [timeout, setRequestTimeout] = (0, _react.useState)(request.timeout);
/* Re-render if something changes state */
(0, _useEventEmitter.useEventEmitter)(request, "change", updateState);
/* Keep re-rendering if there's a timeout */
(0, _react.useEffect)(() => {
if (request.timeout == 0) return;
/* Note that request.timeout is a getter, so its value changes */
const id = setInterval(() => {
setRequestTimeout(request.timeout);
}, 500);
return () => {
clearInterval(id);
};
}, [request]);
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_VerificationRequest"
}, /*#__PURE__*/_react.default.createElement("dl", null, /*#__PURE__*/_react.default.createElement("dt", null, "Transaction"), /*#__PURE__*/_react.default.createElement("dd", null, txnId), /*#__PURE__*/_react.default.createElement("dt", null, "Phase"), /*#__PURE__*/_react.default.createElement("dd", null, PHASE_MAP[request.phase] || request.phase), /*#__PURE__*/_react.default.createElement("dt", null, "Timeout"), /*#__PURE__*/_react.default.createElement("dd", null, Math.floor(timeout / 1000)), /*#__PURE__*/_react.default.createElement("dt", null, "Methods"), /*#__PURE__*/_react.default.createElement("dd", null, request.methods && request.methods.join(", ")), /*#__PURE__*/_react.default.createElement("dt", null, "requestingUserId"), /*#__PURE__*/_react.default.createElement("dd", null, request.requestingUserId), /*#__PURE__*/_react.default.createElement("dt", null, "observeOnly"), /*#__PURE__*/_react.default.createElement("dd", null, JSON.stringify(request.observeOnly))));
}
class VerificationExplorer extends _react.default.Component {
constructor(...args) {
super(...args);
(0, _defineProperty2.default)(this, "onNewRequest", () => {
this.forceUpdate();
});
}
static getLabel() {
return (0, _languageHandler._t)("Verification Requests");
}
/* Ensure this.context is the cli */
componentDidMount() {
const cli = this.context;
cli.on("crypto.verification.request", this.onNewRequest);
}
componentWillUnmount() {
const cli = this.context;
cli.off("crypto.verification.request", this.onNewRequest);
}
render() {
const cli = this.context;
const room = this.props.room;
const inRoomChannel = cli._crypto._inRoomVerificationRequests;
const inRoomRequests = (inRoomChannel._requestsByRoomId || new Map()).get(room.roomId) || new Map();
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, Array.from(inRoomRequests.entries()).reverse().map(([txnId, request]) => /*#__PURE__*/_react.default.createElement(VerificationRequest, {
txnId: txnId,
request: request,
key: txnId
}))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.props.onBack
}, (0, _languageHandler._t)("Back"))));
}
}
(0, _defineProperty2.default)(VerificationExplorer, "contextType", _MatrixClientContext.default);
class WidgetExplorer extends _react.default.Component {
static getLabel() {
return (0, _languageHandler._t)("Active Widgets");
}
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onWidgetStoreUpdate", () => {
this.forceUpdate();
});
(0, _defineProperty2.default)(this, "onQueryChange", query => {
this.setState({
query
});
});
(0, _defineProperty2.default)(this, "onEditWidget", widget => {
this.setState({
editWidget: widget
});
});
(0, _defineProperty2.default)(this, "onBack", () => {
const widgets = _WidgetStore.default.instance.getApps(this.props.room.roomId);
if (this.state.editWidget && widgets.includes(this.state.editWidget)) {
this.setState({
editWidget: null
});
} else {
this.props.onBack();
}
});
this.state = {
query: '',
editWidget: null // set to an IApp when editing
};
}
componentDidMount() {
_WidgetStore.default.instance.on(_AsyncStore.UPDATE_EVENT, this.onWidgetStoreUpdate);
}
componentWillUnmount() {
_WidgetStore.default.instance.off(_AsyncStore.UPDATE_EVENT, this.onWidgetStoreUpdate);
}
render() {
const room = this.props.room;
const editWidget = this.state.editWidget;
const widgets = _WidgetStore.default.instance.getApps(room.roomId);
if (editWidget && widgets.includes(editWidget)) {
const allState = Array.from(Array.from(room.currentState.events.values()).map(e => e.values())).reduce((p, c) => {
p.push(...c);
return p;
}, []);
const stateEv = allState.find(ev => ev.getId() === editWidget.eventId);
if (!stateEv) {
// "should never happen"
return /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("There was an error finding this widget."), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)("Back"))));
}
return /*#__PURE__*/_react.default.createElement(SendCustomEvent, {
onBack: this.onBack,
room: room,
forceStateEvent: true,
inputs: {
eventType: stateEv.getType(),
evContent: JSON.stringify(stateEv.getContent(), null, '\t'),
stateKey: stateEv.getStateKey()
}
});
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, /*#__PURE__*/_react.default.createElement(FilteredList, {
query: this.state.query,
onChange: this.onQueryChange
}, widgets.map(w => {
return /*#__PURE__*/_react.default.createElement("button", {
className: "mx_DevTools_RoomStateExplorer_button",
key: w.url + w.eventId,
onClick: () => this.onEditWidget(w)
}, w.url);
}))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)("Back"))));
}
}
class SettingsExplorer extends _react.default.Component {
static getLabel() {
return (0, _languageHandler._t)("Settings Explorer");
}
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onQueryChange", ev => {
this.setState({
query: ev.target.value
});
});
(0, _defineProperty2.default)(this, "onExplValuesEdit", ev => {
this.setState({
explicitValues: ev.target.value
});
});
(0, _defineProperty2.default)(this, "onExplRoomValuesEdit", ev => {
this.setState({
explicitRoomValues: ev.target.value
});
});
(0, _defineProperty2.default)(this, "onBack", () => {
if (this.state.editSetting) {
this.setState({
editSetting: null
});
} else if (this.state.viewSetting) {
this.setState({
viewSetting: null
});
} else {
this.props.onBack();
}
});
(0, _defineProperty2.default)(this, "onViewClick", (ev, settingId) => {
ev.preventDefault();
this.setState({
viewSetting: settingId
});
});
(0, _defineProperty2.default)(this, "onEditClick", (ev, settingId) => {
ev.preventDefault();
this.setState({
editSetting: settingId,
explicitValues: this.renderExplicitSettingValues(settingId, null),
explicitRoomValues: this.renderExplicitSettingValues(settingId, this.props.room.roomId)
});
});
(0, _defineProperty2.default)(this, "onSaveClick", async () => {
try {
const settingId = this.state.editSetting;
const parsedExplicit = JSON.parse(this.state.explicitValues);
const parsedExplicitRoom = JSON.parse(this.state.explicitRoomValues);
for (const level of Object.keys(parsedExplicit)) {
console.log(`[Devtools] Setting value of ${settingId} at ${level} from user input`);
try {
const val = parsedExplicit[level];
await _SettingsStore.default.setValue(settingId, null, level, val);
} catch (e) {
console.warn(e);
}
}
const roomId = this.props.room.roomId;
for (const level of Object.keys(parsedExplicit)) {
console.log(`[Devtools] Setting value of ${settingId} at ${level} in ${roomId} from user input`);
try {
const val = parsedExplicitRoom[level];
await _SettingsStore.default.setValue(settingId, roomId, level, val);
} catch (e) {
console.warn(e);
}
}
this.setState({
viewSetting: settingId,
editSetting: null
});
} catch (e) {
_Modal.default.createTrackedDialog('Devtools - Failed to save settings', '', _ErrorDialog.default, {
title: (0, _languageHandler._t)("Failed to save settings"),
description: e.message
});
}
});
this.state = {
query: '',
editSetting: null,
// set to a setting ID when editing
viewSetting: null,
// set to a setting ID when exploring in detail
explicitValues: null,
// stringified JSON for edit view
explicitRoomValues: null // stringified JSON for edit view
};
}
renderSettingValue(val) {
// Note: we don't .toString() a string because we want JSON.stringify to inject quotes for us
const toStringTypes = ['boolean', 'number'];
if (toStringTypes.includes(typeof val)) {
return val.toString();
} else {
return JSON.stringify(val);
}
}
renderExplicitSettingValues(setting, roomId) {
const vals = {};
for (const level of _SettingsStore.LEVEL_ORDER) {
try {
vals[level] = _SettingsStore.default.getValueAt(level, setting, roomId, true, true);
if (vals[level] === undefined) {
vals[level] = null;
}
} catch (e) {
console.warn(e);
}
}
return JSON.stringify(vals, null, 4);
}
renderCanEditLevel(roomId, level) {
const canEdit = _SettingsStore.default.canSetValue(this.state.editSetting, roomId, level);
const className = canEdit ? 'mx_DevTools_SettingsExplorer_mutable' : 'mx_DevTools_SettingsExplorer_immutable';
return /*#__PURE__*/_react.default.createElement("td", {
className: className
}, /*#__PURE__*/_react.default.createElement("code", null, canEdit.toString()));
}
render() {
const room = this.props.room;
if (!this.state.viewSetting && !this.state.editSetting) {
// view all settings
const allSettings = Object.keys(_Settings.SETTINGS).filter(n => this.state.query ? n.toLowerCase().includes(this.state.query.toLowerCase()) : true);
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content mx_DevTools_SettingsExplorer"
}, /*#__PURE__*/_react.default.createElement(_Field.default, {
label: (0, _languageHandler._t)('Filter results'),
autoFocus: true,
size: 64,
type: "text",
autoComplete: "off",
value: this.state.query,
onChange: this.onQueryChange,
className: "mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query"
}), /*#__PURE__*/_react.default.createElement("table", null, /*#__PURE__*/_react.default.createElement("thead", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", null, (0, _languageHandler._t)("Setting ID")), /*#__PURE__*/_react.default.createElement("th", null, (0, _languageHandler._t)("Value")), /*#__PURE__*/_react.default.createElement("th", null, (0, _languageHandler._t)("Value in this room")))), /*#__PURE__*/_react.default.createElement("tbody", null, allSettings.map(i => /*#__PURE__*/_react.default.createElement("tr", {
key: i
}, /*#__PURE__*/_react.default.createElement("td", null, /*#__PURE__*/_react.default.createElement("a", {
href: "",
onClick: e => this.onViewClick(e, i)
}, /*#__PURE__*/_react.default.createElement("code", null, i)), /*#__PURE__*/_react.default.createElement("a", {
href: "",
onClick: e => this.onEditClick(e, i),
className: "mx_DevTools_SettingsExplorer_edit"
}, "\u270F")), /*#__PURE__*/_react.default.createElement("td", null, /*#__PURE__*/_react.default.createElement("code", null, this.renderSettingValue(_SettingsStore.default.getValue(i)))), /*#__PURE__*/_react.default.createElement("td", null, /*#__PURE__*/_react.default.createElement("code", null, this.renderSettingValue(_SettingsStore.default.getValue(i, room.roomId))))))))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)("Back"))));
} else if (this.state.editSetting) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content mx_DevTools_SettingsExplorer"
}, /*#__PURE__*/_react.default.createElement("h3", null, (0, _languageHandler._t)("Setting:"), " ", /*#__PURE__*/_react.default.createElement("code", null, this.state.editSetting)), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_SettingsExplorer_warning"
}, /*#__PURE__*/_react.default.createElement("b", null, (0, _languageHandler._t)("Caution:")), " ", (0, _languageHandler._t)("This UI does NOT check the types of the values. Use at your own risk.")), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("Setting definition:"), /*#__PURE__*/_react.default.createElement("pre", null, /*#__PURE__*/_react.default.createElement("code", null, JSON.stringify(_Settings.SETTINGS[this.state.editSetting], null, 4)))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("table", null, /*#__PURE__*/_react.default.createElement("thead", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", null, (0, _languageHandler._t)("Level")), /*#__PURE__*/_react.default.createElement("th", null, (0, _languageHandler._t)("Settable at global")), /*#__PURE__*/_react.default.createElement("th", null, (0, _languageHandler._t)("Settable at room")))), /*#__PURE__*/_react.default.createElement("tbody", null, _SettingsStore.LEVEL_ORDER.map(lvl => /*#__PURE__*/_react.default.createElement("tr", {
key: lvl
}, /*#__PURE__*/_react.default.createElement("td", null, /*#__PURE__*/_react.default.createElement("code", null, lvl)), this.renderCanEditLevel(null, lvl), this.renderCanEditLevel(room.roomId, lvl)))))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_Field.default, {
id: "valExpl",
label: (0, _languageHandler._t)("Values at explicit levels"),
type: "text",
className: "mx_DevTools_textarea",
element: "textarea",
autoComplete: "off",
value: this.state.explicitValues,
onChange: this.onExplValuesEdit
})), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_Field.default, {
id: "valExpl",
label: (0, _languageHandler._t)("Values at explicit levels in this room"),
type: "text",
className: "mx_DevTools_textarea",
element: "textarea",
autoComplete: "off",
value: this.state.explicitRoomValues,
onChange: this.onExplRoomValuesEdit
}))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onSaveClick
}, (0, _languageHandler._t)("Save setting values")), /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)("Back"))));
} else if (this.state.viewSetting) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content mx_DevTools_SettingsExplorer"
}, /*#__PURE__*/_react.default.createElement("h3", null, (0, _languageHandler._t)("Setting:"), " ", /*#__PURE__*/_react.default.createElement("code", null, this.state.viewSetting)), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("Setting definition:"), /*#__PURE__*/_react.default.createElement("pre", null, /*#__PURE__*/_react.default.createElement("code", null, JSON.stringify(_Settings.SETTINGS[this.state.viewSetting], null, 4)))), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("Value:"), "\xA0", /*#__PURE__*/_react.default.createElement("code", null, this.renderSettingValue(_SettingsStore.default.getValue(this.state.viewSetting)))), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("Value in this room:"), "\xA0", /*#__PURE__*/_react.default.createElement("code", null, this.renderSettingValue(_SettingsStore.default.getValue(this.state.viewSetting, room.roomId)))), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("Values at explicit levels:"), /*#__PURE__*/_react.default.createElement("pre", null, /*#__PURE__*/_react.default.createElement("code", null, this.renderExplicitSettingValues(this.state.viewSetting, null)))), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("Values at explicit levels in this room:"), /*#__PURE__*/_react.default.createElement("pre", null, /*#__PURE__*/_react.default.createElement("code", null, this.renderExplicitSettingValues(this.state.viewSetting, room.roomId))))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: e => this.onEditClick(e, this.state.viewSetting)
}, (0, _languageHandler._t)("Edit Values")), /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onBack
}, (0, _languageHandler._t)("Back"))));
}
}
}
const Entries = [SendCustomEvent, RoomStateExplorer, SendAccountData, AccountDataExplorer, ServersInRoomList, VerificationExplorer, WidgetExplorer, SettingsExplorer];
let DevtoolsDialog = (_dec = (0, _replaceableComponent.replaceableComponent)("views.dialogs.DevtoolsDialog"), _dec(_class = (_temp = _class2 = class DevtoolsDialog extends _react.default.PureComponent {
constructor(props) {
super(props);
this.onBack = this.onBack.bind(this);
this.onCancel = this.onCancel.bind(this);
this.state = {
mode: null
};
}
componentWillUnmount() {
this._unmounted = true;
}
_setMode(mode) {
return () => {
this.setState({
mode
});
};
}
onBack() {
if (this.prevMode) {
this.setState({
mode: this.prevMode
});
this.prevMode = null;
} else {
this.setState({
mode: null
});
}
}
onCancel() {
this.props.onFinished(false);
}
render() {
let body;
if (this.state.mode) {
body = /*#__PURE__*/_react.default.createElement(_MatrixClientContext.default.Consumer, null, cli => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_label_left"
}, this.state.mode.getLabel()), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_label_right"
}, "Room ID: ", this.props.roomId), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_label_bottom"
}), /*#__PURE__*/_react.default.createElement(this.state.mode, {
onBack: this.onBack,
room: cli.getRoom(this.props.roomId)
})));
} else {
const classes = "mx_DevTools_RoomStateExplorer_button";
body = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_label_left"
}, (0, _languageHandler._t)('Toolbox')), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_label_right"
}, "Room ID: ", this.props.roomId), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_DevTools_label_bottom"
}), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, Entries.map(Entry => {
const label = Entry.getLabel();
const onClick = this._setMode(Entry);
return /*#__PURE__*/_react.default.createElement("button", {
className: classes,
key: label,
onClick: onClick
}, label);
}))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_buttons"
}, /*#__PURE__*/_react.default.createElement("button", {
onClick: this.onCancel
}, (0, _languageHandler._t)('Cancel'))));
}
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return /*#__PURE__*/_react.default.createElement(BaseDialog, {
className: "mx_QuestionDialog",
onFinished: this.props.onFinished,
title: (0, _languageHandler._t)('Developer Tools')
}, body);
}
}, (0, _defineProperty2.default)(_class2, "propTypes", {
roomId: _propTypes.default.string.isRequired,
onFinished: _propTypes.default.func.isRequired
}), _temp)) || _class);
exports.default = DevtoolsDialog;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL2RpYWxvZ3MvRGV2dG9vbHNEaWFsb2cuanMiXSwibmFtZXMiOlsiR2VuZXJpY0VkaXRvciIsIlJlYWN0IiwiUHVyZUNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJfb25DaGFuZ2UiLCJiaW5kIiwib25CYWNrIiwic3RhdGUiLCJtZXNzYWdlIiwic2V0U3RhdGUiLCJlIiwidGFyZ2V0IiwiaWQiLCJ0eXBlIiwiY2hlY2tlZCIsInZhbHVlIiwiX2J1dHRvbnMiLCJfc2VuZCIsInRleHRJbnB1dCIsImxhYmVsIiwiU2VuZEN1c3RvbUV2ZW50IiwiZ2V0TGFiZWwiLCJldmVudFR5cGUiLCJzdGF0ZUtleSIsImV2Q29udGVudCIsIk9iamVjdCIsImFzc2lnbiIsImlucHV0cyIsImlzU3RhdGVFdmVudCIsIkJvb2xlYW4iLCJmb3JjZVN0YXRlRXZlbnQiLCJzZW5kIiwiY29udGVudCIsImNsaSIsImNvbnRleHQiLCJzZW5kU3RhdGVFdmVudCIsInJvb20iLCJyb29tSWQiLCJzZW5kRXZlbnQiLCJKU09OIiwicGFyc2UiLCJ0b1N0cmluZyIsInJlbmRlciIsInNob3dUZ2xGbGlwIiwiZm9yY2VHZW5lcmFsRXZlbnQiLCJmbG9hdCIsIlByb3BUeXBlcyIsImZ1bmMiLCJpc1JlcXVpcmVkIiwiaW5zdGFuY2VPZiIsIlJvb20iLCJib29sIiwib2JqZWN0IiwiTWF0cml4Q2xpZW50Q29udGV4dCIsIlNlbmRBY2NvdW50RGF0YSIsImlzUm9vbUFjY291bnREYXRhIiwic2V0Um9vbUFjY291bnREYXRhIiwic2V0QWNjb3VudERhdGEiLCJmb3JjZU1vZGUiLCJJTklUSUFMX0xPQURfVElMRVMiLCJMT0FEX1RJTEVTX1NURVBfU0laRSIsIkZpbHRlcmVkTGlzdCIsImZpbHRlckNoaWxkcmVuIiwiY2hpbGRyZW4iLCJxdWVyeSIsImxjUXVlcnkiLCJ0b0xvd2VyQ2FzZSIsImZpbHRlciIsImNoaWxkIiwia2V5IiwiaW5jbHVkZXMiLCJ0cnVuY2F0ZUF0Iiwib3ZlcmZsb3dDb3VudCIsInRvdGFsQ291bnQiLCJzaG93QWxsIiwiY291bnQiLCJldiIsIm9uQ2hhbmdlIiwic3RhcnQiLCJlbmQiLCJmaWx0ZXJlZENoaWxkcmVuIiwic2xpY2UiLCJsZW5ndGgiLCJVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyIsIm5leHRQcm9wcyIsIlRydW5jYXRlZExpc3QiLCJzZGsiLCJnZXRDb21wb25lbnQiLCJvblF1ZXJ5IiwiZ2V0Q2hpbGRyZW4iLCJnZXRDaGlsZENvdW50IiwiY3JlYXRlT3ZlcmZsb3dFbGVtZW50IiwiYW55Iiwic3RyaW5nIiwiUm9vbVN0YXRlRXhwbG9yZXIiLCJyb29tU3RhdGVFdmVudHMiLCJjdXJyZW50U3RhdGUiLCJldmVudHMiLCJlZGl0RXYiLCJvblF1ZXJ5RXZlbnRUeXBlIiwib25RdWVyeVN0YXRlS2V5IiwiZXZlbnQiLCJlZGl0aW5nIiwicXVlcnlFdmVudFR5cGUiLCJxdWVyeVN0YXRlS2V5IiwiYnJvd3NlRXZlbnRUeXBlIiwib25WaWV3U291cmNlQ2xpY2siLCJmaWx0ZXJFdmVudFR5cGUiLCJmaWx0ZXJTdGF0ZUtleSIsImdldFR5cGUiLCJzdHJpbmdpZnkiLCJnZXRDb250ZW50IiwiZ2V0U3RhdGVLZXkiLCJsaXN0IiwiY2xhc3NlcyIsIkFycmF5IiwiZnJvbSIsImVudHJpZXMiLCJtYXAiLCJhbGxTdGF0ZUtleXMiLCJvbkNsaWNrRm4iLCJzaXplIiwiaGFzIiwiZ2V0Iiwic3RhdGVHcm91cCIsIkFjY291bnREYXRhRXhwbG9yZXIiLCJnZXREYXRhIiwiYWNjb3VudERhdGEiLCJzdG9yZSIsInJvd3MiLCJkYXRhIiwia2V5cyIsImZvckVhY2giLCJldlR5cGUiLCJwdXNoIiwiU2VydmVyc0luUm9vbUxpc3QiLCJzZXJ2ZXJzIiwiU2V0IiwiZ2V0U3RhdGVFdmVudHMiLCJhZGQiLCJnZXRTZW5kZXIiLCJzcGxpdCIsInMiLCJQSEFTRV9NQVAiLCJQSEFTRV9VTlNFTlQiLCJQSEFTRV9SRVFVRVNURUQiLCJQSEFTRV9SRUFEWSIsIlBIQVNFX0RPTkUiLCJQSEFTRV9TVEFSVEVEIiwiUEhBU0VfQ0FOQ0VMTEVEIiwiVmVyaWZpY2F0aW9uUmVxdWVzdCIsInR4bklkIiwicmVxdWVzdCIsInVwZGF0ZVN0YXRlIiwidGltZW91dCIsInNldFJlcXVlc3RUaW1lb3V0Iiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwicGhhc2UiLCJNYXRoIiwiZmxvb3IiLCJtZXRob2RzIiwiam9pbiIsInJlcXVlc3RpbmdVc2VySWQiLCJvYnNlcnZlT25seSIsIlZlcmlmaWNhdGlvbkV4cGxvcmVyIiwiQ29tcG9uZW50IiwiZm9yY2VVcGRhdGUiLCJjb21wb25lbnREaWRNb3VudCIsIm9uIiwib25OZXdSZXF1ZXN0IiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJvZmYiLCJpblJvb21DaGFubmVsIiwiX2NyeXB0byIsIl9pblJvb21WZXJpZmljYXRpb25SZXF1ZXN0cyIsImluUm9vbVJlcXVlc3RzIiwiX3JlcXVlc3RzQnlSb29tSWQiLCJNYXAiLCJyZXZlcnNlIiwiV2lkZ2V0RXhwbG9yZXIiLCJ3aWRnZXQiLCJlZGl0V2lkZ2V0Iiwid2lkZ2V0cyIsIldpZGdldFN0b3JlIiwiaW5zdGFuY2UiLCJnZXRBcHBzIiwiVVBEQVRFX0VWRU5UIiwib25XaWRnZXRTdG9yZVVwZGF0ZSIsImFsbFN0YXRlIiwidmFsdWVzIiwicmVkdWNlIiwicCIsImMiLCJzdGF0ZUV2IiwiZmluZCIsImdldElkIiwiZXZlbnRJZCIsIm9uUXVlcnlDaGFuZ2UiLCJ3IiwidXJsIiwib25FZGl0V2lkZ2V0IiwiU2V0dGluZ3NFeHBsb3JlciIsImV4cGxpY2l0VmFsdWVz