matrix-react-sdk
Version:
SDK for matrix.org using React
315 lines (250 loc) • 34.7 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _MatrixClientPeg = require("../MatrixClientPeg");
var _UserAddress = require("../UserAddress");
var _GroupStore = _interopRequireDefault(require("../stores/GroupStore"));
var _languageHandler = require("../languageHandler");
var sdk = _interopRequireWildcard(require("../index"));
var _Modal = _interopRequireDefault(require("../Modal"));
var _SettingsStore = _interopRequireDefault(require("../settings/SettingsStore"));
var _promise = require("./promise");
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017, 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Invites multiple addresses to a room or group, handling rate limiting from the server
*/
class MultiInviter {
/**
* @param {string} targetId The ID of the room or group to invite to
*/
constructor(targetId) {
if (targetId[0] === '+') {
this.roomId = null;
this.groupId = targetId;
} else {
this.roomId = targetId;
this.groupId = null;
}
this.canceled = false;
this.addrs = [];
this.busy = false;
this.completionStates = {}; // State of each address (invited or error)
this.errors = {}; // { address: {errorText, errcode} }
this.deferred = null;
}
/**
* Invite users to this room. This may only be called once per
* instance of the class.
*
* @param {array} addrs Array of addresses to invite
* @param {string} reason Reason for inviting (optional)
* @returns {Promise} Resolved when all invitations in the queue are complete
*/
invite(addrs, reason) {
if (this.addrs.length > 0) {
throw new Error("Already inviting/invited");
}
this.addrs.push(...addrs);
this.reason = reason;
for (const addr of this.addrs) {
if ((0, _UserAddress.getAddressType)(addr) === null) {
this.completionStates[addr] = 'error';
this.errors[addr] = {
errcode: 'M_INVALID',
errorText: (0, _languageHandler._t)('Unrecognised address')
};
}
}
this.deferred = (0, _promise.defer)();
this._inviteMore(0);
return this.deferred.promise;
}
/**
* Stops inviting. Causes promises returned by invite() to be rejected.
*/
cancel() {
if (!this.busy) return;
this._canceled = true;
this.deferred.reject(new Error('canceled'));
}
getCompletionState(addr) {
return this.completionStates[addr];
}
getErrorText(addr) {
return this.errors[addr] ? this.errors[addr].errorText : null;
}
async _inviteToRoom(roomId, addr, ignoreProfile) {
const addrType = (0, _UserAddress.getAddressType)(addr);
if (addrType === 'email') {
return _MatrixClientPeg.MatrixClientPeg.get().inviteByEmail(roomId, addr);
} else if (addrType === 'mx-user-id') {
const room = _MatrixClientPeg.MatrixClientPeg.get().getRoom(roomId);
if (!room) throw new Error("Room not found");
const member = room.getMember(addr);
if (member && ['join', 'invite'].includes(member.membership)) {
throw {
errcode: "RIOT.ALREADY_IN_ROOM",
error: "Member already invited"
};
}
if (!ignoreProfile && _SettingsStore.default.getValue("promptBeforeInviteUnknownUsers", this.roomId)) {
const profile = await _MatrixClientPeg.MatrixClientPeg.get().getProfileInfo(addr);
if (!profile) {
// noinspection ExceptionCaughtLocallyJS
throw new Error("User has no profile");
}
}
return _MatrixClientPeg.MatrixClientPeg.get().invite(roomId, addr, undefined, this.reason);
} else {
throw new Error('Unsupported address');
}
}
_doInvite(address, ignoreProfile) {
return new Promise((resolve, reject) => {
console.log(`Inviting ${address}`);
let doInvite;
if (this.groupId !== null) {
doInvite = _GroupStore.default.inviteUserToGroup(this.groupId, address);
} else {
doInvite = this._inviteToRoom(this.roomId, address, ignoreProfile);
}
doInvite.then(() => {
if (this._canceled) {
return;
}
this.completionStates[address] = 'invited';
delete this.errors[address];
resolve();
}).catch(err => {
if (this._canceled) {
return;
}
console.error(err);
let errorText;
let fatal = false;
if (err.errcode === 'M_FORBIDDEN') {
fatal = true;
errorText = (0, _languageHandler._t)('You do not have permission to invite people to this room.');
} else if (err.errcode === "RIOT.ALREADY_IN_ROOM") {
errorText = (0, _languageHandler._t)("User %(userId)s is already in the room", {
userId: address
});
} else if (err.errcode === 'M_LIMIT_EXCEEDED') {
// we're being throttled so wait a bit & try again
setTimeout(() => {
this._doInvite(address, ignoreProfile).then(resolve, reject);
}, 5000);
return;
} else if (['M_NOT_FOUND', 'M_USER_NOT_FOUND'].includes(err.errcode)) {
errorText = (0, _languageHandler._t)("User %(user_id)s does not exist", {
user_id: address
});
} else if (err.errcode === 'M_PROFILE_UNDISCLOSED') {
errorText = (0, _languageHandler._t)("User %(user_id)s may or may not exist", {
user_id: address
});
} else if (err.errcode === 'M_PROFILE_NOT_FOUND' && !ignoreProfile) {
// Invite without the profile check
console.warn(`User ${address} does not have a profile - inviting anyways automatically`);
this._doInvite(address, true).then(resolve, reject);
} else if (err.errcode === "M_BAD_STATE") {
errorText = (0, _languageHandler._t)("The user must be unbanned before they can be invited.");
} else if (err.errcode === "M_UNSUPPORTED_ROOM_VERSION") {
errorText = (0, _languageHandler._t)("The user's homeserver does not support the version of the room.");
} else {
errorText = (0, _languageHandler._t)('Unknown server error');
}
this.completionStates[address] = 'error';
this.errors[address] = {
errorText,
errcode: err.errcode
};
this.busy = !fatal;
this.fatal = fatal;
if (fatal) {
reject();
} else {
resolve();
}
});
});
}
_inviteMore(nextIndex, ignoreProfile) {
if (this._canceled) {
return;
}
if (nextIndex === this.addrs.length) {
this.busy = false;
if (Object.keys(this.errors).length > 0 && !this.groupId) {
// There were problems inviting some people - see if we can invite them
// without caring if they exist or not.
const unknownProfileErrors = ['M_NOT_FOUND', 'M_USER_NOT_FOUND', 'M_PROFILE_UNDISCLOSED', 'M_PROFILE_NOT_FOUND'];
const unknownProfileUsers = Object.keys(this.errors).filter(a => unknownProfileErrors.includes(this.errors[a].errcode));
if (unknownProfileUsers.length > 0) {
const inviteUnknowns = () => {
const promises = unknownProfileUsers.map(u => this._doInvite(u, true));
Promise.all(promises).then(() => this.deferred.resolve(this.completionStates));
};
if (!_SettingsStore.default.getValue("promptBeforeInviteUnknownUsers", this.roomId)) {
inviteUnknowns();
return;
}
const AskInviteAnywayDialog = sdk.getComponent("dialogs.AskInviteAnywayDialog");
console.log("Showing failed to invite dialog...");
_Modal.default.createTrackedDialog('Failed to invite', '', AskInviteAnywayDialog, {
unknownProfileUsers: unknownProfileUsers.map(u => {
return {
userId: u,
errorText: this.errors[u].errorText
};
}),
onInviteAnyways: () => inviteUnknowns(),
onGiveUp: () => {
// Fake all the completion states because we already warned the user
for (const addr of unknownProfileUsers) {
this.completionStates[addr] = 'invited';
}
this.deferred.resolve(this.completionStates);
}
});
return;
}
}
this.deferred.resolve(this.completionStates);
return;
}
const addr = this.addrs[nextIndex]; // don't try to invite it if it's an invalid address
// (it will already be marked as an error though,
// so no need to do so again)
if ((0, _UserAddress.getAddressType)(addr) === null) {
this._inviteMore(nextIndex + 1);
return;
} // don't re-invite (there's no way in the UI to do this, but
// for sanity's sake)
if (this.completionStates[addr] === 'invited') {
this._inviteMore(nextIndex + 1);
return;
}
this._doInvite(addr, ignoreProfile).then(() => {
this._inviteMore(nextIndex + 1, ignoreProfile);
}).catch(() => this.deferred.resolve(this.completionStates));
}
}
exports.default = MultiInviter;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9NdWx0aUludml0ZXIuanMiXSwibmFtZXMiOlsiTXVsdGlJbnZpdGVyIiwiY29uc3RydWN0b3IiLCJ0YXJnZXRJZCIsInJvb21JZCIsImdyb3VwSWQiLCJjYW5jZWxlZCIsImFkZHJzIiwiYnVzeSIsImNvbXBsZXRpb25TdGF0ZXMiLCJlcnJvcnMiLCJkZWZlcnJlZCIsImludml0ZSIsInJlYXNvbiIsImxlbmd0aCIsIkVycm9yIiwicHVzaCIsImFkZHIiLCJlcnJjb2RlIiwiZXJyb3JUZXh0IiwiX2ludml0ZU1vcmUiLCJwcm9taXNlIiwiY2FuY2VsIiwiX2NhbmNlbGVkIiwicmVqZWN0IiwiZ2V0Q29tcGxldGlvblN0YXRlIiwiZ2V0RXJyb3JUZXh0IiwiX2ludml0ZVRvUm9vbSIsImlnbm9yZVByb2ZpbGUiLCJhZGRyVHlwZSIsIk1hdHJpeENsaWVudFBlZyIsImdldCIsImludml0ZUJ5RW1haWwiLCJyb29tIiwiZ2V0Um9vbSIsIm1lbWJlciIsImdldE1lbWJlciIsImluY2x1ZGVzIiwibWVtYmVyc2hpcCIsImVycm9yIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwicHJvZmlsZSIsImdldFByb2ZpbGVJbmZvIiwidW5kZWZpbmVkIiwiX2RvSW52aXRlIiwiYWRkcmVzcyIsIlByb21pc2UiLCJyZXNvbHZlIiwiY29uc29sZSIsImxvZyIsImRvSW52aXRlIiwiR3JvdXBTdG9yZSIsImludml0ZVVzZXJUb0dyb3VwIiwidGhlbiIsImNhdGNoIiwiZXJyIiwiZmF0YWwiLCJ1c2VySWQiLCJzZXRUaW1lb3V0IiwidXNlcl9pZCIsIndhcm4iLCJuZXh0SW5kZXgiLCJPYmplY3QiLCJrZXlzIiwidW5rbm93blByb2ZpbGVFcnJvcnMiLCJ1bmtub3duUHJvZmlsZVVzZXJzIiwiZmlsdGVyIiwiYSIsImludml0ZVVua25vd25zIiwicHJvbWlzZXMiLCJtYXAiLCJ1IiwiYWxsIiwiQXNrSW52aXRlQW55d2F5RGlhbG9nIiwic2RrIiwiZ2V0Q29tcG9uZW50IiwiTW9kYWwiLCJjcmVhdGVUcmFja2VkRGlhbG9nIiwib25JbnZpdGVBbnl3YXlzIiwib25HaXZlVXAiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBaUJBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQXhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFXQTtBQUNBO0FBQ0E7QUFDZSxNQUFNQSxZQUFOLENBQW1CO0FBQzlCO0FBQ0o7QUFDQTtBQUNJQyxFQUFBQSxXQUFXLENBQUNDLFFBQUQsRUFBVztBQUNsQixRQUFJQSxRQUFRLENBQUMsQ0FBRCxDQUFSLEtBQWdCLEdBQXBCLEVBQXlCO0FBQ3JCLFdBQUtDLE1BQUwsR0FBYyxJQUFkO0FBQ0EsV0FBS0MsT0FBTCxHQUFlRixRQUFmO0FBQ0gsS0FIRCxNQUdPO0FBQ0gsV0FBS0MsTUFBTCxHQUFjRCxRQUFkO0FBQ0EsV0FBS0UsT0FBTCxHQUFlLElBQWY7QUFDSDs7QUFFRCxTQUFLQyxRQUFMLEdBQWdCLEtBQWhCO0FBQ0EsU0FBS0MsS0FBTCxHQUFhLEVBQWI7QUFDQSxTQUFLQyxJQUFMLEdBQVksS0FBWjtBQUNBLFNBQUtDLGdCQUFMLEdBQXdCLEVBQXhCLENBWmtCLENBWVU7O0FBQzVCLFNBQUtDLE1BQUwsR0FBYyxFQUFkLENBYmtCLENBYUE7O0FBQ2xCLFNBQUtDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDSDtBQUVEO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNJQyxFQUFBQSxNQUFNLENBQUNMLEtBQUQsRUFBUU0sTUFBUixFQUFnQjtBQUNsQixRQUFJLEtBQUtOLEtBQUwsQ0FBV08sTUFBWCxHQUFvQixDQUF4QixFQUEyQjtBQUN2QixZQUFNLElBQUlDLEtBQUosQ0FBVSwwQkFBVixDQUFOO0FBQ0g7O0FBQ0QsU0FBS1IsS0FBTCxDQUFXUyxJQUFYLENB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RmdDO0FBR3JFVyxZQUFBQSxRQUFRLEVBQUUsTUFBTTtBQUNaO0FBQ0EsbUJBQUssTUFBTS9ELElBQVgsSUFBbUJpRCxtQkFBbkIsRUFBd0M7QUFDcEMscUJBQUt6RCxnQkFBTCxDQUFzQlEsSUFBdEIsSUFBOEIsU0FBOUI7QUFDSDs7QUFDRCxtQkFBS04sUUFBTCxDQUFjcUMsT0FBZCxDQUFzQixLQUFLdkMsZ0JBQTNCO0FBQ0g7QUFUb0UsV0FBekU7O0FBV0E7QUFDSDtBQUNKOztBQUNELFdBQUtFLFFBQUwsQ0FBY3FDLE9BQWQsQ0FBc0IsS0FBS3ZDLGdCQUEzQjtBQUNBO0FBQ0g7O0FBRUQsVUFBTVEsSUFBSSxHQUFHLEtBQUtWLEtBQUwsQ0FBV3VELFNBQVgsQ0FBYixDQTVDa0MsQ0E4Q2xDO0FBQ0E7QUFDQTs7QUFDQSxRQUFJLGlDQUFlN0MsSUFBZixNQUF5QixJQUE3QixFQUFtQztBQUMvQixXQUFLRyxXQUFMLENBQWlCMEMsU0FBUyxHQUFHLENBQTdCOztBQUNBO0FBQ0gsS0FwRGlDLENBc0RsQztBQUNBOzs7QUFDQSxRQUFJLEtBQUtyRCxnQkFBTCxDQUFzQlEsSUFBdEIsTUFBZ0MsU0FBcEMsRUFBK0M7QUFDM0MsV0FBS0csV0FBTCxDQUFpQjBDLFNBQVMsR0FBRyxDQUE3Qjs7QUFDQTtBQUNIOztBQUVELFNBQUtqQixTQUFMLENBQWU1QixJQUFmLEVBQXFCVyxhQUFyQixFQUFvQzBCLElBQXBDLENBQXlDLE1BQU07QUFDM0MsV0FBS2xDLFdBQUwsQ0FBaUIwQyxTQUFTLEdBQUcsQ0FBN0IsRUFBZ0NsQyxhQUFoQztBQUNILEtBRkQsRUFFRzJCLEtBRkgsQ0FFUyxNQUFNLEtBQUs1QyxRQUFMLENBQWNxQyxPQUFkLENBQXNCLEtBQUt2QyxnQkFBM0IsQ0FGZjtBQUdIOztBQXhPNkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMTYgT3Blbk1hcmtldCBMdGRcbkNvcHlyaWdodCAyMDE3LCAyMDE4IE5ldyBWZWN0b3IgTHRkXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IHtNYXRyaXhDbGllbnRQZWd9IGZyb20gJy4uL01hdHJpeENsaWVudFBlZyc7XG5pbXBvcnQge2dldEFkZHJlc3NUeXBlfSBmcm9tICcuLi9Vc2VyQWRkcmVzcyc7XG5pbXBvcnQgR3JvdXBTdG9yZSBmcm9tICcuLi9zdG9yZXMvR3JvdXBTdG9yZSc7XG5pbXBvcnQge190fSBmcm9tIFwiLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgKiBhcyBzZGsgZnJvbSBcIi4uL2luZGV4XCI7XG5pbXBvcnQgTW9kYWwgZnJvbSBcIi4uL01vZGFsXCI7XG5pbXBvcnQgU2V0dGluZ3NTdG9yZSBmcm9tIFwiLi4vc2V0dGluZ3MvU2V0dGluZ3NTdG9yZVwiO1xuaW1wb3J0IHtkZWZlcn0gZnJvbSBcIi4vcHJvbWlzZVwiO1xuXG4vKipcbiAqIEludml0ZXMgbXVsdGlwbGUgYWRkcmVzc2VzIHRvIGEgcm9vbSBvciBncm91cCwgaGFuZGxpbmcgcmF0ZSBsaW1pdGluZyBmcm9tIHRoZSBzZXJ2ZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlJbnZpdGVyIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0SWQgVGhlIElEIG9mIHRoZSByb29tIG9yIGdyb3VwIHRvIGludml0ZSB0b1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldElkKSB7XG4gICAgICAgIGlmICh0YXJnZXRJZFswXSA9PT0gJysnKSB7XG4gICAgICAgICAgICB0aGlzLnJvb21JZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmdyb3VwSWQgPSB0YXJnZXRJZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucm9vbUlkID0gdGFyZ2V0SWQ7XG4gICAgICAgICAgICB0aGlzLmdyb3VwSWQgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYW5jZWxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFkZHJzID0gW107XG4gICAgICAgIHRoaXMuYnVzeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNvbXBsZXRpb25TdGF0ZXMgPSB7fTsgLy8gU3RhdGUgb2YgZWFjaCBhZGRyZXNzIChpbnZpdGVkIG9yIGVycm9yKVxuICAgICAgICB0aGlzLmVycm9ycyA9IHt9OyAvLyB7IGFkZHJlc3M6IHtlcnJvclRleHQsIGVycmNvZGV9IH1cbiAgICAgICAgdGhpcy5kZWZlcnJlZCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52aXRlIHVzZXJzIHRvIHRoaXMgcm9vbS4gVGhpcyBtYXkgb25seSBiZSBjYWxsZWQgb25jZSBwZXJcbiAgICAgKiBpbnN0YW5jZSBvZiB0aGUgY2xhc3MuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBhZGRycyBBcnJheSBvZiBhZGRyZXNzZXMgdG8gaW52aXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHJlYXNvbiBSZWFzb24gZm9yIGludml0aW5nIChvcHRpb25hbClcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVzb2x2ZWQgd2hlbiBhbGwgaW52aXRhdGlvbnMgaW4gdGhlIHF1ZXVlIGFyZSBjb21wbGV0ZVxuICAgICAqL1xuICAgIGludml0ZShhZGRycywgcmVhc29uKSB7XG4gICAgICAgIGlmICh0aGlzLmFkZHJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFscmVhZHkgaW52aXRpbmcvaW52aXRlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZHJzLnB1c2goLi4uYWRkcnMpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcblxuICAgICAgICBmb3IgKGNvbnN0IGFkZHIgb2YgdGhpcy5hZGRycykge1xuICAgICAgICAgICAgaWYgKGdldEFkZHJlc3NUeXBlKGFkZHIpID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0aW9uU3RhdGVzW2FkZHJdID0gJ2Vycm9yJztcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yc1thZGRyXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyY29kZTogJ01fSU5WQUxJRCcsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogX3QoJ1VucmVjb2duaXNlZCBhZGRyZXNzJyksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlZmVycmVkID0gZGVmZXIoKTtcbiAgICAgICAgdGhpcy5faW52aXRlTW9yZSgwKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5kZWZlcnJlZC5wcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGludml0aW5nLiBDYXVzZXMgcHJvbWlzZXMgcmV0dXJuZWQgYnkgaW52aXRlKCkgdG8gYmUgcmVqZWN0ZWQuXG4gICAgICovXG4gICAgY2FuY2VsKCkge1xuICAgICAgICBpZiAoIXRoaXMuYnVzeSkgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuX2NhbmNlbGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kZWZlcnJlZC5yZWplY3QobmV3IEVycm9yKCdjYW5jZWxlZCcpKTtcbiAgICB9XG5cbiAgICBnZXRDb21wbGV0aW9uU3RhdGUoYWRkcikge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0aW9uU3RhdGVzW2FkZHJdO1xuICAgIH1cblxuICAgIGdldEVycm9yVGV4dChhZGRyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yc1thZGRyXSA/IHRoaXMuZXJyb3JzW2FkZHJdLmVycm9yVGV4dCA6IG51bGw7XG4gICAgfVxuXG4gICAgYXN5bmMgX2ludml0ZVRvUm9vbShyb29tSWQsIGFkZHIsIGlnbm9yZVByb2ZpbGUpIHtcbiAgICAgICAgY29uc3QgYWRkclR5cGUgPSBnZXRBZGRyZXNzVHlwZShhZGRyKTtcblxuICAgICAgICBpZiAoYWRkclR5cGUgPT09ICdlbWFpbCcpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRyaXhDbGllbnRQZWcuZ2V0KCkuaW52aXRlQnlFbWFpbChyb29tSWQsIGFkZHIpO1xuICAgICAgICB9IGVsc2UgaWYgKGFkZHJUeXBlID09PSAnbXgtdXNlci1pZCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvb20gPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCkuZ2V0Um9vbShyb29tSWQpO1xuICAgICAgICAgICAgaWYgKCFyb29tKSB0aHJvdyBuZXcgRXJyb3IoXCJSb29tIG5vdCBmb3VuZFwiKTtcblxuICAgICAgICAgICAgY29uc3QgbWVtYmVyID0gcm9vbS5nZXRNZW1iZXIoYWRkcik7XG4gICAgICAgICAgICBpZiAobWVtYmVyICYmIFsnam9pbicsICdpbnZpdGUnXS5pbmNsdWRlcyhtZW1iZXIubWVtYmVyc2hpcCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyB7ZXJyY29kZTogXCJSSU9ULkFMUkVBRFlfSU5fUk9PTVwiLCBlcnJvcjogXCJNZW1iZXIgYWxyZWFkeSBpbnZpdGVkXCJ9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWlnbm9yZVByb2ZpbGUgJiYgU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcInByb21wdEJlZm9yZUludml0ZVVua25vd25Vc2Vyc1wiLCB0aGlzLnJvb21JZCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9maWxlID0gYXdhaXQgTWF0cml4Q2xpZW50UGVnLmdldCgpLmdldFByb2ZpbGVJbmZvKGFkZHIpO1xuICAgICAgICAgICAgICAgIGlmICghcHJvZmlsZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBub2luc3BlY3Rpb24gRXhjZXB0aW9uQ2F1Z2h0TG9jYWxseUpTXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVzZXIgaGFzIG5vIHByb2ZpbGVcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gTWF0cml4Q2xpZW50UGVnLmdldCgpLmludml0ZShyb29tSWQsIGFkZHIsIHVuZGVmaW5lZCwgdGhpcy5yZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBhZGRyZXNzJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfZG9JbnZpdGUoYWRkcmVzcywgaWdub3JlUHJvZmlsZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYEludml0aW5nICR7YWRkcmVzc31gKTtcblxuICAgICAgICAgICAgbGV0IGRvSW52aXRlO1xuICAgICAgICAgICAgaWYgKHRoaXMuZ3JvdXBJZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRvSW52aXRlID0gR3JvdXBTdG9yZS5pbnZpdGVVc2VyVG9Hcm91cCh0aGlzLmdyb3VwSWQsIGFkZHJlc3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb0ludml0ZSA9IHRoaXMuX2ludml0ZVRvUm9vbSh0aGlzLnJvb21JZCwgYWRkcmVzcywgaWdub3JlUHJvZmlsZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRvSW52aXRlLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0aW9uU3RhdGVzW2FkZHJlc3NdID0gJ2ludml0ZWQnO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmVycm9yc1thZGRyZXNzXTtcblxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2FuY2VsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcblxuICAgICAgICAgICAgICAgIGxldCBlcnJvclRleHQ7XG4gICAgICAgICAgICAgICAgbGV0IGZhdGFsID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaWYgKGVyci5lcnJjb2RlID09PSAnTV9GT1JCSURERU4nKSB7XG4gICAgICAgICAgICAgICAgICAgIGZhdGFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JUZXh0ID0gX3QoJ1lvdSBkbyBub3QgaGF2ZSBwZXJtaXNzaW9uIHRvIGludml0ZSBwZW9wbGUgdG8gdGhpcyByb29tLicpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyLmVycmNvZGUgPT09IFwiUklPVC5BTFJFQURZX0lOX1JPT01cIikge1xuICAgICAgICAgICAgICAgICAgICBlcnJvclRleHQgPSBfdChcIlVzZXIgJSh1c2VySWQpcyBpcyBhbHJlYWR5IGluIHRoZSByb29tXCIsIHt1c2VySWQ6IGFkZHJlc3N9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVyci5lcnJjb2RlID09PSAnTV9MSU1JVF9FWENFRURFRCcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gd2UncmUgYmVpbmcgdGhyb3R0bGVkIHNvIHdhaXQgYSBiaXQgJiB0cnkgYWdhaW5cbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9kb0ludml0ZShhZGRyZXNzLCBpZ25vcmVQcm9maWxlKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH0sIDUwMDApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChbJ01fTk9UX0ZPVU5EJywgJ01fVVNFUl9OT1RfRk9VTkQnXS5pbmNsdWRlcyhlcnIuZXJyY29kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JUZXh0ID0gX3QoXCJVc2VyICUodXNlcl9pZClzIGRvZXMgbm90IGV4aXN0XCIsIHt1c2VyX2lkOiBhZGRyZXNzfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlcnIuZXJyY29kZSA9PT0gJ01fUFJPRklMRV9VTkRJU0NMT1NFRCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JUZXh0ID0gX3QoXCJVc2VyICUodXNlcl9pZClzIG1heSBvciBtYXkgbm90IGV4aXN0XCIsIHt1c2VyX2lkOiBhZGRyZXNzfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlcnIuZXJyY29kZSA9PT0gJ01fUFJPRklMRV9OT1RfRk9VTkQnICYmICFpZ25vcmVQcm9maWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEludml0ZSB3aXRob3V0IHRoZSBwcm9maWxlIGNoZWNrXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgVXNlciAke2FkZHJlc3N9IGRvZXMgbm90IGhhdmUgYSBwcm9maWxlIC0gaW52aXRpbmcgYW55d2F5cyBhdXRvbWF0aWNhbGx5YCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2RvSW52aXRlKGFkZHJlc3MsIHRydWUpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVyci5lcnJjb2RlID09PSBcIk1fQkFEX1NUQVRFXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JUZXh0ID0gX3QoXCJUaGUgdXNlciBtdXN0IGJlIHVuYmFubmVkIGJlZm9yZSB0aGV5IGNhbiBiZSBpbnZpdGVkLlwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVyci5lcnJjb2RlID09PSBcIk1fVU5TVVBQT1JURURfUk9PTV9WRVJTSU9OXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JUZXh0ID0gX3QoXCJUaGUgdXNlcidzIGhvbWVzZXJ2ZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgdmVyc2lvbiBvZiB0aGUgcm9vbS5cIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JUZXh0ID0gX3QoJ1Vua25vd24gc2VydmVyIGVycm9yJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0aW9uU3RhdGVzW2FkZHJlc3NdID0gJ2Vycm9yJztcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yc1thZGRyZXNzXSA9IHtlcnJvclRleHQsIGVycmNvZGU6IGVyci5lcnJjb2RlfTtcblxuICAgICAgICAgICAgICAgIHRoaXMuYnVzeSA9ICFmYXRhbDtcbiAgICAgICAgICAgICAgICB0aGlzLmZhdGFsID0gZmF0YWw7XG5cbiAgICAgICAgICAgICAgICBpZiAoZmF0YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfaW52aXRlTW9yZShuZXh0SW5kZXgsIGlnbm9yZVByb2ZpbGUpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NhbmNlbGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmV4dEluZGV4ID09PSB0aGlzLmFkZHJzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5idXN5ID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5lcnJvcnMpLmxlbmd0aCA+IDAgJiYgIXRoaXMuZ3JvdXBJZCkge1xuICAgICAgICAgICAgICAgIC8vIFRoZXJlIHdlcmUgcHJvYmxlbXMgaW52aXRpbmcgc29tZSBwZW9wbGUgLSBzZWUgaWYgd2UgY2FuIGludml0ZSB0aGVtXG4gICAgICAgICAgICAgICAgLy8gd2l0aG91dCBjYXJpbmcgaWYgdGhleSBleGlzdCBvciBub3QuXG4gICAgICAgICAgICAgICAgY29uc3QgdW5rbm93blByb2ZpbGVFcnJvcnMgPSBbJ01fTk9UX0ZPVU5EJywgJ01fVVNFUl9OT1RfRk9VTkQnLCAnTV9QUk9GSUxFX1VORElTQ0xPU0VEJywgJ01fUFJPRklMRV9OT1RfRk9VTkQnXTtcbiAgICAgICAgICAgICAgICBjb25zdCB1bmtub3duUHJvZmlsZVVzZXJzID0gT2JqZWN0LmtleXModGhpcy5lcnJvcnMpLmZpbHRlcihhID0+IHVua25vd25Qcm9maWxlRXJyb3JzLmluY2x1ZGVzKHRoaXMuZXJyb3JzW2FdLmVycmNvZGUpKTtcblxuICAgICAgICAgICAgICAgIGlmICh1bmtub3duUHJvZmlsZVVzZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW52aXRlVW5rbm93bnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IHVua25vd25Qcm9maWxlVXNlcnMubWFwKHUgPT4gdGhpcy5fZG9JbnZpdGUodSwgdHJ1ZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4gdGhpcy5kZWZlcnJlZC5yZXNvbHZlKHRoaXMuY29tcGxldGlvblN0YXRlcykpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcInByb21wdEJlZm9yZUludml0ZVVua25vd25Vc2Vyc1wiLCB0aGlzLnJvb21JZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGludml0ZVVua25vd25zKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBBc2tJbnZpdGVBbnl3YXlEaWFsb2cgPSBzZGsuZ2V0Q29tcG9uZW50KFwiZGlhbG9ncy5Bc2tJbnZpdGVBbnl3YXlEaWFsb2dcIik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiU2hvd2luZyBmYWlsZWQgdG8gaW52aXRlIGRpYWxvZy4uLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgTW9kYWwuY3JlYXRlVHJhY2tlZERpYWxvZygnRmFpbGVkIHRvIGludml0ZScsICcnLCBBc2tJbnZpdGVBbnl3YXlEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25Qcm9maWxlVXNlcnM6IHVua25vd25Qcm9maWxlVXNlcnMubWFwKHUgPT4ge3JldHVybiB7dXNlcklkOiB1LCBlcnJvclRleHQ6IHRoaXMuZXJyb3JzW3VdLmVycm9yVGV4dH07fSksXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkludml0ZUFueXdheXM6ICgpID0+IGludml0ZVVua25vd25zKCksXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkdpdmVVcDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZha2UgYWxsIHRoZSBjb21wbGV0aW9uIHN0YXRlcyBiZWNhdXNlIHdlIGFscmVhZHkgd2FybmVkIHRoZSB1c2VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBhZGRyIG9mIHVua25vd25Qcm9maWxlVXNlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0aW9uU3RhdGVzW2FkZHJdID0gJ2ludml0ZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmVycmVkLnJlc29sdmUodGhpcy5jb21wbGV0aW9uU3RhdGVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kZWZlcnJlZC5yZXNvbHZlKHRoaXMuY29tcGxldGlvblN0YXRlcyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRyID0gdGhpcy5hZGRyc1tuZXh0SW5kZXhdO1xuXG4gICAgICAgIC8vIGRvbid0IHRyeSB0byBpbnZpdGUgaXQgaWYgaXQncyBhbiBpbnZhbGlkIGFkZHJlc3NcbiAgICAgICAgLy8gKGl0IHdpbGwgYWxyZWFkeSBiZSBtYXJrZWQgYXMgYW4gZXJyb3IgdGhvdWdoLFxuICAgICAgICAvLyBzbyBubyBuZWVkIHRvIGRvIHNvIGFnYWluKVxuICAgICAgICBpZiAoZ2V0QWRkcmVzc1R5cGUoYWRkcikgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX2ludml0ZU1vcmUobmV4dEluZGV4ICsgMSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkb24ndCByZS1pbnZpdGUgKHRoZXJlJ3Mgbm8gd2F5IGluIHRoZSBVSSB0byBkbyB0aGlzLCBidXRcbiAgICAgICAgLy8gZm9yIHNhbml0eSdzIHNha2UpXG4gICAgICAgIGlmICh0aGlzLmNvbXBsZXRpb25TdGF0ZXNbYWRkcl0gPT09ICdpbnZpdGVkJykge1xuICAgICAgICAgICAgdGhpcy5faW52aXRlTW9yZShuZXh0SW5kZXggKyAxKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2RvSW52aXRlKGFkZHIsIGlnbm9yZVByb2ZpbGUpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5faW52aXRlTW9yZShuZXh0SW5kZXggKyAxLCBpZ25vcmVQcm9maWxlKTtcbiAgICAgICAgfSkuY2F0Y2goKCkgPT4gdGhpcy5kZWZlcnJlZC5yZXNvbHZlKHRoaXMuY29tcGxldGlvblN0YXRlcykpO1xuICAgIH1cbn1cbiJdfQ==