matrix-react-sdk
Version:
SDK for matrix.org using React
264 lines (255 loc) • 39.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.generateCompletionDomId = exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _lodash = require("lodash");
var _Autocompleter = _interopRequireDefault(require("../../../autocomplete/Autocompleter"));
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _RoomContext = _interopRequireDefault(require("../../../contexts/RoomContext"));
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 2017-2024 New Vector Ltd.
Copyright 2016 Aviral Dasgupta
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
const MAX_PROVIDER_MATCHES = 20;
const generateCompletionDomId = n => `mx_Autocomplete_Completion_${n}`;
exports.generateCompletionDomId = generateCompletionDomId;
class Autocomplete extends _react.default.PureComponent {
constructor(props, context) {
super(props, context);
(0, _defineProperty2.default)(this, "autocompleter", void 0);
(0, _defineProperty2.default)(this, "queryRequested", void 0);
(0, _defineProperty2.default)(this, "debounceCompletionsRequest", void 0);
(0, _defineProperty2.default)(this, "containerRef", /*#__PURE__*/(0, _react.createRef)());
(0, _defineProperty2.default)(this, "hide", () => {
this.setState({
hide: true,
selectionOffset: 1,
completions: [],
completionList: []
});
});
(0, _defineProperty2.default)(this, "onConfirmCompletion", () => {
this.onCompletionClicked(this.state.selectionOffset);
});
(0, _defineProperty2.default)(this, "onCompletionClicked", selectionOffset => {
const count = this.countCompletions();
if (count === 0 || selectionOffset < 1 || selectionOffset > count) {
return false;
}
this.props.onConfirm(this.state.completionList[selectionOffset - 1]);
this.hide();
return true;
});
this.state = {
// list of completionResults, each containing completions
completions: [],
// array of completions, so we can look up current selection by offset quickly
completionList: [],
// how far down the completion list we are (THIS IS 1-INDEXED!)
selectionOffset: 1,
// whether we should show completions if they're available
shouldShowCompletions: true,
hide: false,
forceComplete: false
};
}
componentDidMount() {
this.autocompleter = new _Autocompleter.default(this.props.room, this.context.timelineRenderingType);
this.applyNewProps();
}
applyNewProps(oldQuery, oldRoom) {
if (oldRoom && this.props.room.roomId !== oldRoom.roomId) {
this.autocompleter?.destroy();
this.autocompleter = new _Autocompleter.default(this.props.room);
}
// Query hasn't changed so don't try to complete it
if (oldQuery === this.props.query) {
return;
}
this.complete(this.props.query, this.props.selection);
}
componentWillUnmount() {
this.autocompleter?.destroy();
}
complete(query, selection) {
this.queryRequested = query;
if (this.debounceCompletionsRequest) {
clearTimeout(this.debounceCompletionsRequest);
}
if (query === "") {
this.setState({
// Clear displayed completions
completions: [],
completionList: [],
// Reset selected completion
selectionOffset: 1,
// Hide the autocomplete box
hide: true
});
return Promise.resolve();
}
let autocompleteDelay = _SettingsStore.default.getValue("autocompleteDelay");
// Don't debounce if we are already showing completions
if (this.state.completions.length > 0 || this.state.forceComplete) {
autocompleteDelay = 0;
}
return new Promise(resolve => {
this.debounceCompletionsRequest = window.setTimeout(() => {
resolve(this.processQuery(query, selection));
}, autocompleteDelay);
});
}
async processQuery(query, selection) {
return this.autocompleter?.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES).then(completions => {
// Only ever process the completions for the most recent query being processed
if (query !== this.queryRequested) {
return;
}
this.processCompletions(completions);
});
}
processCompletions(completions) {
const completionList = (0, _lodash.flatMap)(completions, provider => provider.completions);
// Reset selection when completion list becomes empty.
let selectionOffset = 1;
if (completionList.length > 0) {
/* If the currently selected completion is still in the completion list,
try to find it and jump to it. If not, select composer.
*/
const currentSelection = this.state.selectionOffset <= 1 ? null : this.state.completionList[this.state.selectionOffset - 1].completion;
selectionOffset = completionList.findIndex(completion => completion.completion === currentSelection);
if (selectionOffset === -1) {
selectionOffset = 1;
} else {
selectionOffset++; // selectionOffset is 1-indexed!
}
}
let hide = true;
// If `completion.command.command` is truthy, then a provider has matched with the query
const anyMatches = completions.some(completion => !!completion.command.command);
if (anyMatches) {
hide = false;
if (this.props.onSelectionChange) {
this.props.onSelectionChange(selectionOffset - 1);
}
}
this.setState({
completions,
completionList,
selectionOffset,
hide,
// Force complete is turned off each time since we can't edit the query in that case
forceComplete: false
});
}
hasSelection() {
return this.countCompletions() > 0 && this.state.selectionOffset !== 0;
}
countCompletions() {
return this.state.completionList.length;
}
// called from MessageComposerInput
moveSelection(delta) {
const completionCount = this.countCompletions();
if (completionCount === 0) return; // there are no items to move the selection through
// Note: selectionOffset 0 represents the unsubstituted text, while 1 means first pill selected
const index = (this.state.selectionOffset + delta + completionCount - 1) % completionCount;
this.setSelection(1 + index);
}
onEscape(e) {
const completionCount = this.countCompletions();
if (completionCount === 0) {
// autocomplete is already empty, so don't preventDefault
return;
}
e.preventDefault();
// selectionOffset = 0, so we don't end up completing when autocomplete is hidden
this.hide();
}
forceComplete() {
return new Promise(resolve => {
this.setState({
forceComplete: true,
hide: false
}, () => {
this.complete(this.props.query, this.props.selection).then(() => {
resolve(this.countCompletions());
});
});
});
}
setSelection(selectionOffset) {
this.setState({
selectionOffset,
hide: false
});
if (this.props.onSelectionChange) {
this.props.onSelectionChange(selectionOffset - 1);
}
}
componentDidUpdate(prevProps) {
this.applyNewProps(prevProps.query, prevProps.room);
// this is the selected completion, so scroll it into view if needed
const selectedCompletion = this.refs[`completion${this.state.selectionOffset}`];
if (selectedCompletion) {
selectedCompletion.scrollIntoView({
behavior: "auto",
block: "nearest"
});
} else if (this.containerRef.current) {
this.containerRef.current.scrollTo({
top: 0
});
}
}
render() {
let position = 1;
const renderedCompletions = this.state.completions.map((completionResult, i) => {
const completions = completionResult.completions.map((completion, j) => {
const selected = position === this.state.selectionOffset;
const className = (0, _classnames.default)("mx_Autocomplete_Completion", {
selected
});
const componentPosition = position;
position++;
const onClick = () => {
this.onCompletionClicked(componentPosition);
};
return /*#__PURE__*/_react.default.cloneElement(completion.component, {
"key": j,
"ref": `completion${componentPosition}`,
"id": generateCompletionDomId(componentPosition - 1),
// 0 index the completion IDs
className,
onClick,
"aria-selected": selected
});
});
return completions.length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
key: i,
className: "mx_Autocomplete_ProviderSection",
role: "presentation"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Autocomplete_provider_name"
}, completionResult.provider.getName()), completionResult.provider.renderCompletions(completions)) : null;
}).filter(completion => !!completion);
return !this.state.hide && renderedCompletions.length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
id: "mx_Autocomplete",
className: "mx_Autocomplete",
ref: this.containerRef,
role: "listbox"
}, renderedCompletions) : null;
}
}
exports.default = Autocomplete;
(0, _defineProperty2.default)(Autocomplete, "contextType", _RoomContext.default);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2xhc3NuYW1lcyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfbG9kYXNoIiwiX0F1dG9jb21wbGV0ZXIiLCJfU2V0dGluZ3NTdG9yZSIsIl9Sb29tQ29udGV4dCIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIk1BWF9QUk9WSURFUl9NQVRDSEVTIiwiZ2VuZXJhdGVDb21wbGV0aW9uRG9tSWQiLCJleHBvcnRzIiwiQXV0b2NvbXBsZXRlIiwiUmVhY3QiLCJQdXJlQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImNvbnRleHQiLCJfZGVmaW5lUHJvcGVydHkyIiwiY3JlYXRlUmVmIiwic2V0U3RhdGUiLCJoaWRlIiwic2VsZWN0aW9uT2Zmc2V0IiwiY29tcGxldGlvbnMiLCJjb21wbGV0aW9uTGlzdCIsIm9uQ29tcGxldGlvbkNsaWNrZWQiLCJzdGF0ZSIsImNvdW50IiwiY291bnRDb21wbGV0aW9ucyIsIm9uQ29uZmlybSIsInNob3VsZFNob3dDb21wbGV0aW9ucyIsImZvcmNlQ29tcGxldGUiLCJjb21wb25lbnREaWRNb3VudCIsImF1dG9jb21wbGV0ZXIiLCJBdXRvY29tcGxldGVyIiwicm9vbSIsInRpbWVsaW5lUmVuZGVyaW5nVHlwZSIsImFwcGx5TmV3UHJvcHMiLCJvbGRRdWVyeSIsIm9sZFJvb20iLCJyb29tSWQiLCJkZXN0cm95IiwicXVlcnkiLCJjb21wbGV0ZSIsInNlbGVjdGlvbiIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwicXVlcnlSZXF1ZXN0ZWQiLCJkZWJvdW5jZUNvbXBsZXRpb25zUmVxdWVzdCIsImNsZWFyVGltZW91dCIsIlByb21pc2UiLCJyZXNvbHZlIiwiYXV0b2NvbXBsZXRlRGVsYXkiLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJsZW5ndGgiLCJ3aW5kb3ciLCJzZXRUaW1lb3V0IiwicHJvY2Vzc1F1ZXJ5IiwiZ2V0Q29tcGxldGlvbnMiLCJ0aGVuIiwicHJvY2Vzc0NvbXBsZXRpb25zIiwiZmxhdE1hcCIsInByb3ZpZGVyIiwiY3VycmVudFNlbGVjdGlvbiIsImNvbXBsZXRpb24iLCJmaW5kSW5kZXgiLCJhbnlNYXRjaGVzIiwic29tZSIsImNvbW1hbmQiLCJvblNlbGVjdGlvbkNoYW5nZSIsImhhc1NlbGVjdGlvbiIsIm1vdmVTZWxlY3Rpb24iLCJkZWx0YSIsImNvbXBsZXRpb25Db3VudCIsImluZGV4Iiwic2V0U2VsZWN0aW9uIiwib25Fc2NhcGUiLCJwcmV2ZW50RGVmYXVsdCIsImNvbXBvbmVudERpZFVwZGF0ZSIsInByZXZQcm9wcyIsInNlbGVjdGVkQ29tcGxldGlvbiIsInJlZnMiLCJzY3JvbGxJbnRvVmlldyIsImJlaGF2aW9yIiwiYmxvY2siLCJjb250YWluZXJSZWYiLCJjdXJyZW50Iiwic2Nyb2xsVG8iLCJ0b3AiLCJyZW5kZXIiLCJwb3NpdGlvbiIsInJlbmRlcmVkQ29tcGxldGlvbnMiLCJtYXAiLCJjb21wbGV0aW9uUmVzdWx0IiwiaiIsInNlbGVjdGVkIiwiY2xhc3NOYW1lIiwiY2xhc3NOYW1lcyIsImNvbXBvbmVudFBvc2l0aW9uIiwib25DbGljayIsImNsb25lRWxlbWVudCIsImNvbXBvbmVudCIsImNyZWF0ZUVsZW1lbnQiLCJrZXkiLCJyb2xlIiwiZ2V0TmFtZSIsInJlbmRlckNvbXBsZXRpb25zIiwiZmlsdGVyIiwiaWQiLCJyZWYiLCJSb29tQ29udGV4dCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL0F1dG9jb21wbGV0ZS50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE3LTIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAxNiBBdmlyYWwgRGFzZ3VwdGFcblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgS2V5Ym9hcmRFdmVudCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcbmltcG9ydCB7IGZsYXRNYXAgfSBmcm9tIFwibG9kYXNoXCI7XG5pbXBvcnQgeyBSb29tIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuXG5pbXBvcnQgQXV0b2NvbXBsZXRlciwgeyBJQ29tcGxldGlvbiwgSVNlbGVjdGlvblJhbmdlLCBJUHJvdmlkZXJDb21wbGV0aW9ucyB9IGZyb20gXCIuLi8uLi8uLi9hdXRvY29tcGxldGUvQXV0b2NvbXBsZXRlclwiO1xuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcbmltcG9ydCBSb29tQ29udGV4dCBmcm9tIFwiLi4vLi4vLi4vY29udGV4dHMvUm9vbUNvbnRleHRcIjtcblxuY29uc3QgTUFYX1BST1ZJREVSX01BVENIRVMgPSAyMDtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlQ29tcGxldGlvbkRvbUlkID0gKG46IG51bWJlcik6IHN0cmluZyA9PiBgbXhfQXV0b2NvbXBsZXRlX0NvbXBsZXRpb25fJHtufWA7XG5cbmludGVyZmFjZSBJUHJvcHMge1xuICAgIC8vIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHdoaWNoIHRvIHNob3cgYXV0b2NvbXBsZXRlIHN1Z2dlc3Rpb25zXG4gICAgcXVlcnk6IHN0cmluZztcbiAgICAvLyBtZXRob2QgaW52b2tlZCB3aXRoIHJhbmdlIGFuZCB0ZXh0IGNvbnRlbnQgd2hlbiBjb21wbGV0aW9uIGlzIGNvbmZpcm1lZFxuICAgIG9uQ29uZmlybTogKGNvbXBsZXRpb246IElDb21wbGV0aW9uKSA9PiB2b2lkO1xuICAgIC8vIG1ldGhvZCBpbnZva2VkIHdoZW4gc2VsZWN0ZWQgKGlmIGFueSkgY29tcGxldGlvbiBjaGFuZ2VzXG4gICAgb25TZWxlY3Rpb25DaGFuZ2U/OiAocGFydEluZGV4OiBudW1iZXIpID0+IHZvaWQ7XG4gICAgc2VsZWN0aW9uOiBJU2VsZWN0aW9uUmFuZ2U7XG4gICAgLy8gVGhlIHJvb20gaW4gd2hpY2ggd2UncmUgYXV0b2NvbXBsZXRpbmdcbiAgICByb29tOiBSb29tO1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBjb21wbGV0aW9uczogSVByb3ZpZGVyQ29tcGxldGlvbnNbXTtcbiAgICBjb21wbGV0aW9uTGlzdDogSUNvbXBsZXRpb25bXTtcbiAgICBzZWxlY3Rpb25PZmZzZXQ6IG51bWJlcjtcbiAgICBzaG91bGRTaG93Q29tcGxldGlvbnM6IGJvb2xlYW47XG4gICAgaGlkZTogYm9vbGVhbjtcbiAgICBmb3JjZUNvbXBsZXRlOiBib29sZWFuO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBdXRvY29tcGxldGUgZXh0ZW5kcyBSZWFjdC5QdXJlQ29tcG9uZW50PElQcm9wcywgSVN0YXRlPiB7XG4gICAgcHVibGljIGF1dG9jb21wbGV0ZXI/OiBBdXRvY29tcGxldGVyO1xuICAgIHB1YmxpYyBxdWVyeVJlcXVlc3RlZD86IHN0cmluZztcbiAgICBwdWJsaWMgZGVib3VuY2VDb21wbGV0aW9uc1JlcXVlc3Q/OiBudW1iZXI7XG4gICAgcHJpdmF0ZSBjb250YWluZXJSZWYgPSBjcmVhdGVSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgICBwdWJsaWMgc3RhdGljIGNvbnRleHRUeXBlID0gUm9vbUNvbnRleHQ7XG4gICAgcHVibGljIGRlY2xhcmUgY29udGV4dDogUmVhY3QuQ29udGV4dFR5cGU8dHlwZW9mIFJvb21Db250ZXh0PjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczogSVByb3BzLCBjb250ZXh0OiBSZWFjdC5Db250ZXh0VHlwZTx0eXBlb2YgUm9vbUNvbnRleHQ+KSB7XG4gICAgICAgIHN1cGVyKHByb3BzLCBjb250ZXh0KTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgLy8gbGlzdCBvZiBjb21wbGV0aW9uUmVzdWx0cywgZWFjaCBjb250YWluaW5nIGNvbXBsZXRpb25zXG4gICAgICAgICAgICBjb21wbGV0aW9uczogW10sXG5cbiAgICAgICAgICAgIC8vIGFycmF5IG9mIGNvbXBsZXRpb25zLCBzbyB3ZSBjYW4gbG9vayB1cCBjdXJyZW50IHNlbGVjdGlvbiBieSBvZmZzZXQgcXVpY2tseVxuICAgICAgICAgICAgY29tcGxldGlvbkxpc3Q6IFtdLFxuXG4gICAgICAgICAgICAvLyBob3cgZmFyIGRvd24gdGhlIGNvbXBsZXRpb24gbGlzdCB3ZSBhcmUgKFRISVMgSVMgMS1JTkRFWEVEISlcbiAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldDogMSxcblxuICAgICAgICAgICAgLy8gd2hldGhlciB3ZSBzaG91bGQgc2hvdyBjb21wbGV0aW9ucyBpZiB0aGV5J3JlIGF2YWlsYWJsZVxuICAgICAgICAgICAgc2hvdWxkU2hvd0NvbXBsZXRpb25zOiB0cnVlLFxuXG4gICAgICAgICAgICBoaWRlOiBmYWxzZSxcblxuICAgICAgICAgICAgZm9yY2VDb21wbGV0ZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZXIgPSBuZXcgQXV0b2NvbXBsZXRlcih0aGlzLnByb3BzLnJvb20sIHRoaXMuY29udGV4dC50aW1lbGluZVJlbmRlcmluZ1R5cGUpO1xuICAgICAgICB0aGlzLmFwcGx5TmV3UHJvcHMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5TmV3UHJvcHMob2xkUXVlcnk/OiBzdHJpbmcsIG9sZFJvb20/OiBSb29tKTogdm9pZCB7XG4gICAgICAgIGlmIChvbGRSb29tICYmIHRoaXMucHJvcHMucm9vbS5yb29tSWQgIT09IG9sZFJvb20ucm9vbUlkKSB7XG4gICAgICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZXI/LmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuYXV0b2NvbXBsZXRlciA9IG5ldyBBdXRvY29tcGxldGVyKHRoaXMucHJvcHMucm9vbSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBRdWVyeSBoYXNuJ3QgY2hhbmdlZCBzbyBkb24ndCB0cnkgdG8gY29tcGxldGUgaXRcbiAgICAgICAgaWYgKG9sZFF1ZXJ5ID09PSB0aGlzLnByb3BzLnF1ZXJ5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbXBsZXRlKHRoaXMucHJvcHMucXVlcnksIHRoaXMucHJvcHMuc2VsZWN0aW9uKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYXV0b2NvbXBsZXRlcj8uZGVzdHJveSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29tcGxldGUocXVlcnk6IHN0cmluZywgc2VsZWN0aW9uOiBJU2VsZWN0aW9uUmFuZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5xdWVyeVJlcXVlc3RlZCA9IHF1ZXJ5O1xuICAgICAgICBpZiAodGhpcy5kZWJvdW5jZUNvbXBsZXRpb25zUmVxdWVzdCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZGVib3VuY2VDb21wbGV0aW9uc1JlcXVlc3QpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChxdWVyeSA9PT0gXCJcIikge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgLy8gQ2xlYXIgZGlzcGxheWVkIGNvbXBsZXRpb25zXG4gICAgICAgICAgICAgICAgY29tcGxldGlvbnM6IFtdLFxuICAgICAgICAgICAgICAgIGNvbXBsZXRpb25MaXN0OiBbXSxcbiAgICAgICAgICAgICAgICAvLyBSZXNldCBzZWxlY3RlZCBjb21wbGV0aW9uXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uT2Zmc2V0OiAxLFxuICAgICAgICAgICAgICAgIC8vIEhpZGUgdGhlIGF1dG9jb21wbGV0ZSBib3hcbiAgICAgICAgICAgICAgICBoaWRlOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGF1dG9jb21wbGV0ZURlbGF5ID0gU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcImF1dG9jb21wbGV0ZURlbGF5XCIpO1xuXG4gICAgICAgIC8vIERvbid0IGRlYm91bmNlIGlmIHdlIGFyZSBhbHJlYWR5IHNob3dpbmcgY29tcGxldGlvbnNcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY29tcGxldGlvbnMubGVuZ3RoID4gMCB8fCB0aGlzLnN0YXRlLmZvcmNlQ29tcGxldGUpIHtcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZURlbGF5ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZWJvdW5jZUNvbXBsZXRpb25zUmVxdWVzdCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMucHJvY2Vzc1F1ZXJ5KHF1ZXJ5LCBzZWxlY3Rpb24pKTtcbiAgICAgICAgICAgIH0sIGF1dG9jb21wbGV0ZURlbGF5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzUXVlcnkocXVlcnk6IHN0cmluZywgc2VsZWN0aW9uOiBJU2VsZWN0aW9uUmFuZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0b2NvbXBsZXRlclxuICAgICAgICAgICAgPy5nZXRDb21wbGV0aW9ucyhxdWVyeSwgc2VsZWN0aW9uLCB0aGlzLnN0YXRlLmZvcmNlQ29tcGxldGUsIE1BWF9QUk9WSURFUl9NQVRDSEVTKVxuICAgICAgICAgICAgLnRoZW4oKGNvbXBsZXRpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gT25seSBldmVyIHByb2Nlc3MgdGhlIGNvbXBsZXRpb25zIGZvciB0aGUgbW9zdCByZWNlbnQgcXVlcnkgYmVpbmcgcHJvY2Vzc2VkXG4gICAgICAgICAgICAgICAgaWYgKHF1ZXJ5ICE9PSB0aGlzLnF1ZXJ5UmVxdWVzdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ29tcGxldGlvbnMoY29tcGxldGlvbnMpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwcm9jZXNzQ29tcGxldGlvbnMoY29tcGxldGlvbnM6IElQcm92aWRlckNvbXBsZXRpb25zW10pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29tcGxldGlvbkxpc3QgPSBmbGF0TWFwKGNvbXBsZXRpb25zLCAocHJvdmlkZXIpID0+IHByb3ZpZGVyLmNvbXBsZXRpb25zKTtcblxuICAgICAgICAvLyBSZXNldCBzZWxlY3Rpb24gd2hlbiBjb21wbGV0aW9uIGxpc3QgYmVjb21lcyBlbXB0eS5cbiAgICAgICAgbGV0IHNlbGVjdGlvbk9mZnNldCA9IDE7XG4gICAgICAgIGlmIChjb21wbGV0aW9uTGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvKiBJZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGNvbXBsZXRpb24gaXMgc3RpbGwgaW4gdGhlIGNvbXBsZXRpb24gbGlzdCxcbiAgICAgICAgICAgICB0cnkgdG8gZmluZCBpdCBhbmQganVtcCB0byBpdC4gSWYgbm90LCBzZWxlY3QgY29tcG9zZXIuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRTZWxlY3Rpb24gPVxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0aW9uT2Zmc2V0IDw9IDFcbiAgICAgICAgICAgICAgICAgICAgPyBudWxsXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy5zdGF0ZS5jb21wbGV0aW9uTGlzdFt0aGlzLnN0YXRlLnNlbGVjdGlvbk9mZnNldCAtIDFdLmNvbXBsZXRpb247XG4gICAgICAgICAgICBzZWxlY3Rpb25PZmZzZXQgPSBjb21wbGV0aW9uTGlzdC5maW5kSW5kZXgoKGNvbXBsZXRpb24pID0+IGNvbXBsZXRpb24uY29tcGxldGlvbiA9PT0gY3VycmVudFNlbGVjdGlvbik7XG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uT2Zmc2V0ID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldCA9IDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldCsrOyAvLyBzZWxlY3Rpb25PZmZzZXQgaXMgMS1pbmRleGVkIVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGhpZGUgPSB0cnVlO1xuICAgICAgICAvLyBJZiBgY29tcGxldGlvbi5jb21tYW5kLmNvbW1hbmRgIGlzIHRydXRoeSwgdGhlbiBhIHByb3ZpZGVyIGhhcyBtYXRjaGVkIHdpdGggdGhlIHF1ZXJ5XG4gICAgICAgIGNvbnN0IGFueU1hdGNoZXMgPSBjb21wbGV0aW9ucy5zb21lKChjb21wbGV0aW9uKSA9PiAhIWNvbXBsZXRpb24uY29tbWFuZC5jb21tYW5kKTtcbiAgICAgICAgaWYgKGFueU1hdGNoZXMpIHtcbiAgICAgICAgICAgIGhpZGUgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLm9uU2VsZWN0aW9uQ2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblNlbGVjdGlvbkNoYW5nZShzZWxlY3Rpb25PZmZzZXQgLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgY29tcGxldGlvbnMsXG4gICAgICAgICAgICBjb21wbGV0aW9uTGlzdCxcbiAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldCxcbiAgICAgICAgICAgIGhpZGUsXG4gICAgICAgICAgICAvLyBGb3JjZSBjb21wbGV0ZSBpcyB0dXJuZWQgb2ZmIGVhY2ggdGltZSBzaW5jZSB3ZSBjYW4ndCBlZGl0IHRoZSBxdWVyeSBpbiB0aGF0IGNhc2VcbiAgICAgICAgICAgIGZvcmNlQ29tcGxldGU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFzU2VsZWN0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jb3VudENvbXBsZXRpb25zKCkgPiAwICYmIHRoaXMuc3RhdGUuc2VsZWN0aW9uT2Zmc2V0ICE9PSAwO1xuICAgIH1cblxuICAgIHB1YmxpYyBjb3VudENvbXBsZXRpb25zKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmNvbXBsZXRpb25MaXN0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBjYWxsZWQgZnJvbSBNZXNzYWdlQ29tcG9zZXJJbnB1dFxuICAgIHB1YmxpYyBtb3ZlU2VsZWN0aW9uKGRlbHRhOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29tcGxldGlvbkNvdW50ID0gdGhpcy5jb3VudENvbXBsZXRpb25zKCk7XG4gICAgICAgIGlmIChjb21wbGV0aW9uQ291bnQgPT09IDApIHJldHVybjsgLy8gdGhlcmUgYXJlIG5vIGl0ZW1zIHRvIG1vdmUgdGhlIHNlbGVjdGlvbiB0aHJvdWdoXG5cbiAgICAgICAgLy8gTm90ZTogc2VsZWN0aW9uT2Zmc2V0IDAgcmVwcmVzZW50cyB0aGUgdW5zdWJzdGl0dXRlZCB0ZXh0LCB3aGlsZSAxIG1lYW5zIGZpcnN0IHBpbGwgc2VsZWN0ZWRcbiAgICAgICAgY29uc3QgaW5kZXggPSAodGhpcy5zdGF0ZS5zZWxlY3Rpb25PZmZzZXQgKyBkZWx0YSArIGNvbXBsZXRpb25Db3VudCAtIDEpICUgY29tcGxldGlvbkNvdW50O1xuICAgICAgICB0aGlzLnNldFNlbGVjdGlvbigxICsgaW5kZXgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkVzY2FwZShlOiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IGNvbXBsZXRpb25Db3VudCA9IHRoaXMuY291bnRDb21wbGV0aW9ucygpO1xuICAgICAgICBpZiAoY29tcGxldGlvbkNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAvLyBhdXRvY29tcGxldGUgaXMgYWxyZWFkeSBlbXB0eSwgc28gZG9uJ3QgcHJldmVudERlZmF1bHRcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAvLyBzZWxlY3Rpb25PZmZzZXQgPSAwLCBzbyB3ZSBkb24ndCBlbmQgdXAgY29tcGxldGluZyB3aGVuIGF1dG9jb21wbGV0ZSBpcyBoaWRkZW5cbiAgICAgICAgdGhpcy5oaWRlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoaWRlID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGhpZGU6IHRydWUsXG4gICAgICAgICAgICBzZWxlY3Rpb25PZmZzZXQ6IDEsXG4gICAgICAgICAgICBjb21wbGV0aW9uczogW10sXG4gICAgICAgICAgICBjb21wbGV0aW9uTGlzdDogW10sXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwdWJsaWMgZm9yY2VDb21wbGV0ZSgpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmb3JjZUNvbXBsZXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBoaWRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZSh0aGlzLnByb3BzLnF1ZXJ5LCB0aGlzLnByb3BzLnNlbGVjdGlvbikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY291bnRDb21wbGV0aW9ucygpKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNvbmZpcm1Db21wbGV0aW9uID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLm9uQ29tcGxldGlvbkNsaWNrZWQodGhpcy5zdGF0ZS5zZWxlY3Rpb25PZmZzZXQpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQ29tcGxldGlvbkNsaWNrZWQgPSAoc2VsZWN0aW9uT2Zmc2V0OiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgICAgICAgY29uc3QgY291bnQgPSB0aGlzLmNvdW50Q29tcGxldGlvbnMoKTtcbiAgICAgICAgaWYgKGNvdW50ID09PSAwIHx8IHNlbGVjdGlvbk9mZnNldCA8IDEgfHwgc2VsZWN0aW9uT2Zmc2V0ID4gY291bnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucHJvcHMub25Db25maXJtKHRoaXMuc3RhdGUuY29tcGxldGlvbkxpc3Rbc2VsZWN0aW9uT2Zmc2V0IC0gMV0pO1xuICAgICAgICB0aGlzLmhpZGUoKTtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBzZXRTZWxlY3Rpb24oc2VsZWN0aW9uT2Zmc2V0OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGlvbk9mZnNldCwgaGlkZTogZmFsc2UgfSk7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uU2VsZWN0aW9uQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uU2VsZWN0aW9uQ2hhbmdlKHNlbGVjdGlvbk9mZnNldCAtIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IElQcm9wcyk6IHZvaWQge1xuICAgICAgICB0aGlzLmFwcGx5TmV3UHJvcHMocHJldlByb3BzLnF1ZXJ5LCBwcmV2UHJvcHMucm9vbSk7XG4gICAgICAgIC8vIHRoaXMgaXMgdGhlIHNlbGVjdGVkIGNvbXBsZXRpb24sIHNvIHNjcm9sbCBpdCBpbnRvIHZpZXcgaWYgbmVlZGVkXG4gICAgICAgIGNvbnN0IHNlbGVjdGVkQ29tcGxldGlvbiA9IHRoaXMucmVmc1tgY29tcGxldGlvbiR7dGhpcy5zdGF0ZS5zZWxlY3Rpb25PZmZzZXR9YF0gYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAgICAgaWYgKHNlbGVjdGVkQ29tcGxldGlvbikge1xuICAgICAgICAgICAgc2VsZWN0ZWRDb21wbGV0aW9uLnNjcm9sbEludG9WaWV3KHtcbiAgICAgICAgICAgICAgICBiZWhhdmlvcjogXCJhdXRvXCIsXG4gICAgICAgICAgICAgICAgYmxvY2s6IFwibmVhcmVzdFwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jb250YWluZXJSZWYuY3VycmVudCkge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXJSZWYuY3VycmVudC5zY3JvbGxUbyh7IHRvcDogMCB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgbGV0IHBvc2l0aW9uID0gMTtcbiAgICAgICAgY29uc3QgcmVuZGVyZWRDb21wbGV0aW9ucyA9IHRoaXMuc3RhdGUuY29tcGxldGlvbnNcbiAgICAgICAgICAgIC5tYXAoKGNvbXBsZXRpb25SZXN1bHQsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wbGV0aW9ucyA9IGNvbXBsZXRpb25SZXN1bHQuY29tcGxldGlvbnMubWFwKChjb21wbGV0aW9uLCBqKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkID0gcG9zaXRpb24gPT09IHRoaXMuc3RhdGUuc2VsZWN0aW9uT2Zmc2V0O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBjbGFzc05hbWVzKFwibXhfQXV0b2NvbXBsZXRlX0NvbXBsZXRpb25cIiwgeyBzZWxlY3RlZCB9KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tcG9uZW50UG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24rKztcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbkNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkNvbXBsZXRpb25DbGlja2VkKGNvbXBvbmVudFBvc2l0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY2xvbmVFbGVtZW50KGNvbXBsZXRpb24uY29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImtleVwiOiBqLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJyZWZcIjogYGNvbXBsZXRpb24ke2NvbXBvbmVudFBvc2l0aW9ufWAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IGdlbmVyYXRlQ29tcGxldGlvbkRvbUlkKGNvbXBvbmVudFBvc2l0aW9uIC0gMSksIC8vIDAgaW5kZXggdGhlIGNvbXBsZXRpb24gSURzXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJhcmlhLXNlbGVjdGVkXCI6IHNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBjb21wbGV0aW9ucy5sZW5ndGggPiAwID8gKFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGtleT17aX0gY2xhc3NOYW1lPVwibXhfQXV0b2NvbXBsZXRlX1Byb3ZpZGVyU2VjdGlvblwiIHJvbGU9XCJwcmVzZW50YXRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQXV0b2NvbXBsZXRlX3Byb3ZpZGVyX25hbWVcIj57Y29tcGxldGlvblJlc3VsdC5wcm92aWRlci5nZXROYW1lKCl9PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB7Y29tcGxldGlvblJlc3VsdC5wcm92aWRlci5yZW5kZXJDb21wbGV0aW9ucyhjb21wbGV0aW9ucyl9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICkgOiBudWxsO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5maWx0ZXIoKGNvbXBsZXRpb24pID0+ICEhY29tcGxldGlvbik7XG5cbiAgICAgICAgcmV0dXJuICF0aGlzLnN0YXRlLmhpZGUgJiYgcmVuZGVyZWRDb21wbGV0aW9ucy5sZW5ndGggPiAwID8gKFxuICAgICAgICAgICAgPGRpdiBpZD1cIm14X0F1dG9jb21wbGV0ZVwiIGNsYXNzTmFtZT1cIm14X0F1dG9jb21wbGV0ZVwiIHJlZj17dGhpcy5jb250YWluZXJSZWZ9IHJvbGU9XCJsaXN0Ym94XCI+XG4gICAgICAgICAgICAgICAge3JlbmRlcmVkQ29tcGxldGlvbnN9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKSA6IG51bGw7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFdBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLE9BQUEsR0FBQUgsT0FBQTtBQUdBLElBQUFJLGNBQUEsR0FBQUYsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFLLGNBQUEsR0FBQUgsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFNLFlBQUEsR0FBQUosc0JBQUEsQ0FBQUYsT0FBQTtBQUF3RCxTQUFBTyx5QkFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxtQkFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBRix3QkFBQSxZQUFBQSxDQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBVCx3QkFBQVMsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUwsQ0FBQSxRQUFBRyxDQUFBLEdBQUFKLHdCQUFBLENBQUFHLENBQUEsT0FBQUMsQ0FBQSxJQUFBQSxDQUFBLENBQUFHLEdBQUEsQ0FBQU4sQ0FBQSxVQUFBRyxDQUFBLENBQUFJLEdBQUEsQ0FBQVAsQ0FBQSxPQUFBUSxDQUFBLEtBQUFDLFNBQUEsVUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLGNBQUEsSUFBQUQsTUFBQSxDQUFBRSx3QkFBQSxXQUFBQyxDQUFBLElBQUFkLENBQUEsb0JBQUFjLENBQUEsT0FBQUMsY0FBQSxDQUFBQyxJQUFBLENBQUFoQixDQUFBLEVBQUFjLENBQUEsU0FB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