matrix-react-sdk
Version:
SDK for matrix.org using React
158 lines (147 loc) • 21.4 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.avatarUrlForMember = avatarUrlForMember;
exports.avatarUrlForRoom = avatarUrlForRoom;
exports.avatarUrlForUser = avatarUrlForUser;
exports.defaultAvatarUrlForString = defaultAvatarUrlForString;
exports.getAvatarTextColor = getAvatarTextColor;
exports.getInitialLetter = getInitialLetter;
var _compoundWeb = require("@vector-im/compound-web");
var _DMRoomMap = _interopRequireDefault(require("./utils/DMRoomMap"));
var _Media = require("./customisations/Media");
var _isLocalRoom = require("./utils/localRoom/isLocalRoom");
var _strings = require("./utils/strings");
/*
Copyright 2024 New Vector Ltd.
Copyright 2015, 2016 OpenMarket Ltd
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
/**
* Hardcoded from the Compound colors.
* Shade for background as defined in the compound web implementation
* https://github.com/vector-im/compound-web/blob/main/src/components/Avatar
*/
const AVATAR_BG_COLORS = ["#e9f2ff", "#faeefb", "#e3f7ed", "#ffecf0", "#ffefe4", "#e3f5f8", "#f1efff", "#e0f8d9"];
const AVATAR_TEXT_COLORS = ["#043894", "#671481", "#004933", "#7e0642", "#850000", "#004077", "#4c05b5", "#004b00"];
// Not to be used for BaseAvatar urls as that has similar default avatar fallback already
function avatarUrlForMember(member, width, height, resizeMethod) {
let url;
if (member?.getMxcAvatarUrl()) {
url = (0, _Media.mediaFromMxc)(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(width, height, resizeMethod);
}
if (!url) {
// member can be null here currently since on invites, the JS SDK
// does not have enough info to build a RoomMember object for
// the inviter.
url = defaultAvatarUrlForString(member ? member.userId : "");
}
return url;
}
/**
* Determines the HEX color to use in the avatar pills
* @param id the user or room ID
* @returns the text color to use on the avatar
*/
function getAvatarTextColor(id) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const index = (0, _compoundWeb.useIdColorHash)(id);
return AVATAR_TEXT_COLORS[index - 1];
}
function avatarUrlForUser(user, width, height, resizeMethod) {
if (!user.avatarUrl) return null;
return (0, _Media.mediaFromMxc)(user.avatarUrl).getThumbnailOfSourceHttp(width, height, resizeMethod);
}
function isValidHexColor(color) {
return typeof color === "string" && (color.length === 7 || color.length === 9) && color.charAt(0) === "#" && !color.slice(1).split("").some(c => isNaN(parseInt(c, 16)));
}
function urlForColor(color) {
const size = 40;
const canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext("2d");
// bail out when using jsdom in unit tests
if (!ctx) {
return "";
}
ctx.fillStyle = color;
ctx.fillRect(0, 0, size, size);
return canvas.toDataURL();
}
// XXX: Ideally we'd clear this cache when the theme changes
// but since this function is at global scope, it's a bit
// hard to install a listener here, even if there were a clear event to listen to
const colorToDataURLCache = new Map();
function defaultAvatarUrlForString(s) {
if (!s) return ""; // XXX: should never happen but empirically does by evidence of a rageshake
// eslint-disable-next-line react-hooks/rules-of-hooks
const colorIndex = (0, _compoundWeb.useIdColorHash)(s);
// overwritten color value in custom themes
const cssVariable = `--avatar-background-colors_${colorIndex}`;
const cssValue = getComputedStyle(document.body).getPropertyValue(cssVariable);
const color = cssValue || AVATAR_BG_COLORS[colorIndex - 1];
let dataUrl = colorToDataURLCache.get(color);
if (!dataUrl) {
// validate color as this can come from account_data
// with custom theming
if (isValidHexColor(color)) {
dataUrl = urlForColor(color);
colorToDataURLCache.set(color, dataUrl);
} else {
dataUrl = "";
}
}
return dataUrl;
}
/**
* returns the first (non-sigil) character of 'name',
* converted to uppercase
* @param {string} name
* @return {string} the first letter
*/
function getInitialLetter(name) {
if (!name) {
// XXX: We should find out what causes the name to sometimes be falsy.
console.trace("`name` argument to `getInitialLetter` not supplied");
return undefined;
}
if (name.length < 1) {
return undefined;
}
const initial = name[0];
if ((initial === "@" || initial === "#" || initial === "+") && name[1]) {
name = name.substring(1);
}
return (0, _strings.getFirstGrapheme)(name).toUpperCase();
}
function avatarUrlForRoom(room, width, height, resizeMethod) {
if (!room) return null; // null-guard
if (room.getMxcAvatarUrl()) {
const media = (0, _Media.mediaFromMxc)(room.getMxcAvatarUrl() ?? undefined);
if (width !== undefined && height !== undefined) {
return media.getThumbnailOfSourceHttp(width, height, resizeMethod);
}
return media.srcHttp;
}
// space rooms cannot be DMs so skip the rest
if (room.isSpaceRoom()) return null;
// If the room is not a DM don't fallback to a member avatar
if (!_DMRoomMap.default.shared().getUserIdForRoomId(room.roomId) && !(0, _isLocalRoom.isLocalRoom)(room)) {
return null;
}
// If there are only two members in the DM use the avatar of the other member
const otherMember = room.getAvatarFallbackMember();
if (otherMember?.getMxcAvatarUrl()) {
const media = (0, _Media.mediaFromMxc)(otherMember.getMxcAvatarUrl());
if (width !== undefined && height !== undefined) {
return media.getThumbnailOfSourceHttp(width, height, resizeMethod);
}
return media.srcHttp;
}
return null;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29tcG91bmRXZWIiLCJyZXF1aXJlIiwiX0RNUm9vbU1hcCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfTWVkaWEiLCJfaXNMb2NhbFJvb20iLCJfc3RyaW5ncyIsIkFWQVRBUl9CR19DT0xPUlMiLCJBVkFUQVJfVEVYVF9DT0xPUlMiLCJhdmF0YXJVcmxGb3JNZW1iZXIiLCJtZW1iZXIiLCJ3aWR0aCIsImhlaWdodCIsInJlc2l6ZU1ldGhvZCIsInVybCIsImdldE14Y0F2YXRhclVybCIsIm1lZGlhRnJvbU14YyIsImdldFRodW1ibmFpbE9mU291cmNlSHR0cCIsImRlZmF1bHRBdmF0YXJVcmxGb3JTdHJpbmciLCJ1c2VySWQiLCJnZXRBdmF0YXJUZXh0Q29sb3IiLCJpZCIsImluZGV4IiwidXNlSWRDb2xvckhhc2giLCJhdmF0YXJVcmxGb3JVc2VyIiwidXNlciIsImF2YXRhclVybCIsImlzVmFsaWRIZXhDb2xvciIsImNvbG9yIiwibGVuZ3RoIiwiY2hhckF0Iiwic2xpY2UiLCJzcGxpdCIsInNvbWUiLCJjIiwiaXNOYU4iLCJwYXJzZUludCIsInVybEZvckNvbG9yIiwic2l6ZSIsImNhbnZhcyIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudCIsImN0eCIsImdldENvbnRleHQiLCJmaWxsU3R5bGUiLCJmaWxsUmVjdCIsInRvRGF0YVVSTCIsImNvbG9yVG9EYXRhVVJMQ2FjaGUiLCJNYXAiLCJzIiwiY29sb3JJbmRleCIsImNzc1ZhcmlhYmxlIiwiY3NzVmFsdWUiLCJnZXRDb21wdXRlZFN0eWxlIiwiYm9keSIsImdldFByb3BlcnR5VmFsdWUiLCJkYXRhVXJsIiwiZ2V0Iiwic2V0IiwiZ2V0SW5pdGlhbExldHRlciIsIm5hbWUiLCJjb25zb2xlIiwidHJhY2UiLCJ1bmRlZmluZWQiLCJpbml0aWFsIiwic3Vic3RyaW5nIiwiZ2V0Rmlyc3RHcmFwaGVtZSIsInRvVXBwZXJDYXNlIiwiYXZhdGFyVXJsRm9yUm9vbSIsInJvb20iLCJtZWRpYSIsInNyY0h0dHAiLCJpc1NwYWNlUm9vbSIsIkRNUm9vbU1hcCIsInNoYXJlZCIsImdldFVzZXJJZEZvclJvb21JZCIsInJvb21JZCIsImlzTG9jYWxSb29tIiwib3RoZXJNZW1iZXIiLCJnZXRBdmF0YXJGYWxsYmFja01lbWJlciJdLCJzb3VyY2VzIjpbIi4uL3NyYy9BdmF0YXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTUsIDIwMTYgT3Blbk1hcmtldCBMdGRcblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgUm9vbU1lbWJlciwgVXNlciwgUm9vbSwgUmVzaXplTWV0aG9kIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgdXNlSWRDb2xvckhhc2ggfSBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC13ZWJcIjtcblxuaW1wb3J0IERNUm9vbU1hcCBmcm9tIFwiLi91dGlscy9ETVJvb21NYXBcIjtcbmltcG9ydCB7IG1lZGlhRnJvbU14YyB9IGZyb20gXCIuL2N1c3RvbWlzYXRpb25zL01lZGlhXCI7XG5pbXBvcnQgeyBpc0xvY2FsUm9vbSB9IGZyb20gXCIuL3V0aWxzL2xvY2FsUm9vbS9pc0xvY2FsUm9vbVwiO1xuaW1wb3J0IHsgZ2V0Rmlyc3RHcmFwaGVtZSB9IGZyb20gXCIuL3V0aWxzL3N0cmluZ3NcIjtcblxuLyoqXG4gKiBIYXJkY29kZWQgZnJvbSB0aGUgQ29tcG91bmQgY29sb3JzLlxuICogU2hhZGUgZm9yIGJhY2tncm91bmQgYXMgZGVmaW5lZCBpbiB0aGUgY29tcG91bmQgd2ViIGltcGxlbWVudGF0aW9uXG4gKiBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2NvbXBvdW5kLXdlYi9ibG9iL21haW4vc3JjL2NvbXBvbmVudHMvQXZhdGFyXG4gKi9cbmNvbnN0IEFWQVRBUl9CR19DT0xPUlMgPSBbXCIjZTlmMmZmXCIsIFwiI2ZhZWVmYlwiLCBcIiNlM2Y3ZWRcIiwgXCIjZmZlY2YwXCIsIFwiI2ZmZWZlNFwiLCBcIiNlM2Y1ZjhcIiwgXCIjZjFlZmZmXCIsIFwiI2UwZjhkOVwiXTtcbmNvbnN0IEFWQVRBUl9URVhUX0NPTE9SUyA9IFtcIiMwNDM4OTRcIiwgXCIjNjcxNDgxXCIsIFwiIzAwNDkzM1wiLCBcIiM3ZTA2NDJcIiwgXCIjODUwMDAwXCIsIFwiIzAwNDA3N1wiLCBcIiM0YzA1YjVcIiwgXCIjMDA0YjAwXCJdO1xuXG4vLyBOb3QgdG8gYmUgdXNlZCBmb3IgQmFzZUF2YXRhciB1cmxzIGFzIHRoYXQgaGFzIHNpbWlsYXIgZGVmYXVsdCBhdmF0YXIgZmFsbGJhY2sgYWxyZWFkeVxuZXhwb3J0IGZ1bmN0aW9uIGF2YXRhclVybEZvck1lbWJlcihcbiAgICBtZW1iZXI6IFJvb21NZW1iZXIgfCB1bmRlZmluZWQsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICByZXNpemVNZXRob2Q6IFJlc2l6ZU1ldGhvZCxcbik6IHN0cmluZyB7XG4gICAgbGV0IHVybDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBpZiAobWVtYmVyPy5nZXRNeGNBdmF0YXJVcmwoKSkge1xuICAgICAgICB1cmwgPSBtZWRpYUZyb21NeGMobWVtYmVyLmdldE14Y0F2YXRhclVybCgpKS5nZXRUaHVtYm5haWxPZlNvdXJjZUh0dHAod2lkdGgsIGhlaWdodCwgcmVzaXplTWV0aG9kKTtcbiAgICB9XG4gICAgaWYgKCF1cmwpIHtcbiAgICAgICAgLy8gbWVtYmVyIGNhbiBiZSBudWxsIGhlcmUgY3VycmVudGx5IHNpbmNlIG9uIGludml0ZXMsIHRoZSBKUyBTREtcbiAgICAgICAgLy8gZG9lcyBub3QgaGF2ZSBlbm91Z2ggaW5mbyB0byBidWlsZCBhIFJvb21NZW1iZXIgb2JqZWN0IGZvclxuICAgICAgICAvLyB0aGUgaW52aXRlci5cbiAgICAgICAgdXJsID0gZGVmYXVsdEF2YXRhclVybEZvclN0cmluZyhtZW1iZXIgPyBtZW1iZXIudXNlcklkIDogXCJcIik7XG4gICAgfVxuICAgIHJldHVybiB1cmw7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgSEVYIGNvbG9yIHRvIHVzZSBpbiB0aGUgYXZhdGFyIHBpbGxzXG4gKiBAcGFyYW0gaWQgdGhlIHVzZXIgb3Igcm9vbSBJRFxuICogQHJldHVybnMgdGhlIHRleHQgY29sb3IgdG8gdXNlIG9uIHRoZSBhdmF0YXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF2YXRhclRleHRDb2xvcihpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvcnVsZXMtb2YtaG9va3NcbiAgICBjb25zdCBpbmRleCA9IHVzZUlkQ29sb3JIYXNoKGlkKTtcblxuICAgIHJldHVybiBBVkFUQVJfVEVYVF9DT0xPUlNbaW5kZXggLSAxXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF2YXRhclVybEZvclVzZXIoXG4gICAgdXNlcjogUGljazxVc2VyLCBcImF2YXRhclVybFwiPixcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIHJlc2l6ZU1ldGhvZD86IFJlc2l6ZU1ldGhvZCxcbik6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICghdXNlci5hdmF0YXJVcmwpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBtZWRpYUZyb21NeGModXNlci5hdmF0YXJVcmwpLmdldFRodW1ibmFpbE9mU291cmNlSHR0cCh3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QpO1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkSGV4Q29sb3IoY29sb3I6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAgIHR5cGVvZiBjb2xvciA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAoY29sb3IubGVuZ3RoID09PSA3IHx8IGNvbG9yLmxlbmd0aCA9PT0gOSkgJiZcbiAgICAgICAgY29sb3IuY2hhckF0KDApID09PSBcIiNcIiAmJlxuICAgICAgICAhY29sb3JcbiAgICAgICAgICAgIC5zbGljZSgxKVxuICAgICAgICAgICAgLnNwbGl0KFwiXCIpXG4gICAgICAgICAgICAuc29tZSgoYykgPT4gaXNOYU4ocGFyc2VJbnQoYywgMTYpKSlcbiAgICApO1xufVxuXG5mdW5jdGlvbiB1cmxGb3JDb2xvcihjb2xvcjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzaXplID0gNDA7XG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBjYW52YXMud2lkdGggPSBzaXplO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBzaXplO1xuICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgLy8gYmFpbCBvdXQgd2hlbiB1c2luZyBqc2RvbSBpbiB1bml0IHRlc3RzXG4gICAgaWYgKCFjdHgpIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICAgIGN0eC5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICBjdHguZmlsbFJlY3QoMCwgMCwgc2l6ZSwgc2l6ZSk7XG4gICAgcmV0dXJuIGNhbnZhcy50b0RhdGFVUkwoKTtcbn1cblxuLy8gWFhYOiBJZGVhbGx5IHdlJ2QgY2xlYXIgdGhpcyBjYWNoZSB3aGVuIHRoZSB0aGVtZSBjaGFuZ2VzXG4vLyBidXQgc2luY2UgdGhpcyBmdW5jdGlvbiBpcyBhdCBnbG9iYWwgc2NvcGUsIGl0J3MgYSBiaXRcbi8vIGhhcmQgdG8gaW5zdGFsbCBhIGxpc3RlbmVyIGhlcmUsIGV2ZW4gaWYgdGhlcmUgd2VyZSBhIGNsZWFyIGV2ZW50IHRvIGxpc3RlbiB0b1xuY29uc3QgY29sb3JUb0RhdGFVUkxDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QXZhdGFyVXJsRm9yU3RyaW5nKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFzKSByZXR1cm4gXCJcIjsgLy8gWFhYOiBzaG91bGQgbmV2ZXIgaGFwcGVuIGJ1dCBlbXBpcmljYWxseSBkb2VzIGJ5IGV2aWRlbmNlIG9mIGEgcmFnZXNoYWtlXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL3J1bGVzLW9mLWhvb2tzXG4gICAgY29uc3QgY29sb3JJbmRleCA9IHVzZUlkQ29sb3JIYXNoKHMpO1xuICAgIC8vIG92ZXJ3cml0dGVuIGNvbG9yIHZhbHVlIGluIGN1c3RvbSB0aGVtZXNcbiAgICBjb25zdCBjc3NWYXJpYWJsZSA9IGAtLWF2YXRhci1iYWNrZ3JvdW5kLWNvbG9yc18ke2NvbG9ySW5kZXh9YDtcbiAgICBjb25zdCBjc3NWYWx1ZSA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZShjc3NWYXJpYWJsZSk7XG4gICAgY29uc3QgY29sb3IgPSBjc3NWYWx1ZSB8fCBBVkFUQVJfQkdfQ09MT1JTW2NvbG9ySW5kZXggLSAxXTtcbiAgICBsZXQgZGF0YVVybCA9IGNvbG9yVG9EYXRhVVJMQ2FjaGUuZ2V0KGNvbG9yKTtcbiAgICBpZiAoIWRhdGFVcmwpIHtcbiAgICAgICAgLy8gdmFsaWRhdGUgY29sb3IgYXMgdGhpcyBjYW4gY29tZSBmcm9tIGFjY291bnRfZGF0YVxuICAgICAgICAvLyB3aXRoIGN1c3RvbSB0aGVtaW5nXG4gICAgICAgIGlmIChpc1ZhbGlkSGV4Q29sb3IoY29sb3IpKSB7XG4gICAgICAgICAgICBkYXRhVXJsID0gdXJsRm9yQ29sb3IoY29sb3IpO1xuICAgICAgICAgICAgY29sb3JUb0RhdGFVUkxDYWNoZS5zZXQoY29sb3IsIGRhdGFVcmwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0YVVybCA9IFwiXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRhdGFVcmw7XG59XG5cbi8qKlxuICogcmV0dXJucyB0aGUgZmlyc3QgKG5vbi1zaWdpbCkgY2hhcmFjdGVyIG9mICduYW1lJyxcbiAqIGNvbnZlcnRlZCB0byB1cHBlcmNhc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBmaXJzdCBsZXR0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEluaXRpYWxMZXR0ZXIobmFtZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgLy8gWFhYOiBXZSBzaG91bGQgZmluZCBvdXQgd2hhdCBjYXVzZXMgdGhlIG5hbWUgdG8gc29tZXRpbWVzIGJlIGZhbHN5LlxuICAgICAgICBjb25zb2xlLnRyYWNlKFwiYG5hbWVgIGFyZ3VtZW50IHRvIGBnZXRJbml0aWFsTGV0dGVyYCBub3Qgc3VwcGxpZWRcIik7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmIChuYW1lLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsID0gbmFtZVswXTtcbiAgICBpZiAoKGluaXRpYWwgPT09IFwiQFwiIHx8IGluaXRpYWwgPT09IFwiI1wiIHx8IGluaXRpYWwgPT09IFwiK1wiKSAmJiBuYW1lWzFdKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygxKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0Rmlyc3RHcmFwaGVtZShuYW1lKS50b1VwcGVyQ2FzZSgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXZhdGFyVXJsRm9yUm9vbShcbiAgICByb29tOiBSb29tIHwgbnVsbCxcbiAgICB3aWR0aD86IG51bWJlcixcbiAgICBoZWlnaHQ/OiBudW1iZXIsXG4gICAgcmVzaXplTWV0aG9kPzogUmVzaXplTWV0aG9kLFxuKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKCFyb29tKSByZXR1cm4gbnVsbDsgLy8gbnVsbC1ndWFyZFxuXG4gICAgaWYgKHJvb20uZ2V0TXhjQXZhdGFyVXJsKCkpIHtcbiAgICAgICAgY29uc3QgbWVkaWEgPSBtZWRpYUZyb21NeGMocm9vbS5nZXRNeGNBdmF0YXJVcmwoKSA/PyB1bmRlZmluZWQpO1xuICAgICAgICBpZiAod2lkdGggIT09IHVuZGVmaW5lZCAmJiBoZWlnaHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG1lZGlhLmdldFRodW1ibmFpbE9mU291cmNlSHR0cCh3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZWRpYS5zcmNIdHRwO1xuICAgIH1cblxuICAgIC8vIHNwYWNlIHJvb21zIGNhbm5vdCBiZSBETXMgc28gc2tpcCB0aGUgcmVzdFxuICAgIGlmIChyb29tLmlzU3BhY2VSb29tKCkpIHJldHVybiBudWxsO1xuXG4gICAgLy8gSWYgdGhlIHJvb20gaXMgbm90IGEgRE0gZG9uJ3QgZmFsbGJhY2sgdG8gYSBtZW1iZXIgYXZhdGFyXG4gICAgaWYgKCFETVJvb21NYXAuc2hhcmVkKCkuZ2V0VXNlcklkRm9yUm9vbUlkKHJvb20ucm9vbUlkKSAmJiAhaXNMb2NhbFJvb20ocm9vbSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUgYXJlIG9ubHkgdHdvIG1lbWJlcnMgaW4gdGhlIERNIHVzZSB0aGUgYXZhdGFyIG9mIHRoZSBvdGhlciBtZW1iZXJcbiAgICBjb25zdCBvdGhlck1lbWJlciA9IHJvb20uZ2V0QXZhdGFyRmFsbGJhY2tNZW1iZXIoKTtcbiAgICBpZiAob3RoZXJNZW1iZXI/LmdldE14Y0F2YXRhclVybCgpKSB7XG4gICAgICAgIGNvbnN0IG1lZGlhID0gbWVkaWFGcm9tTXhjKG90aGVyTWVtYmVyLmdldE14Y0F2YXRhclVybCgpKTtcbiAgICAgICAgaWYgKHdpZHRoICE9PSB1bmRlZmluZWQgJiYgaGVpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBtZWRpYS5nZXRUaHVtYm5haWxPZlNvdXJjZUh0dHAod2lkdGgsIGhlaWdodCwgcmVzaXplTWV0aG9kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVkaWEuc3JjSHR0cDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQVNBLElBQUFBLFlBQUEsR0FBQUMsT0FBQTtBQUVBLElBQUFDLFVBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLE1BQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFlBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFFBQUEsR0FBQUwsT0FBQTtBQWRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNTSxnQkFBZ0IsR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUM7QUFDakgsTUFBTUMsa0JBQWtCLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDOztBQUVuSDtBQUNPLFNBQVNDLGtCQUFrQkEsQ0FDOUJDLE1BQThCLEVBQzlCQyxLQUFhLEVBQ2JDLE1BQWMsRUFDZEMsWUFBMEIsRUFDcEI7RUFDTixJQUFJQyxHQUE4QjtFQUNsQyxJQUFJSixNQUFNLEVBQUVLLGVBQWUsQ0FBQyxDQUFDLEVBQUU7SUFDM0JELEdBQUcsR0FBRyxJQUFBRSxtQkFBWSxFQUFDTixNQUFNLENBQUNLLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQ0Usd0JBQXdCLENBQUNOLEtBQUssRUFBRUMsTUFBTSxFQUFFQyxZQUFZLENBQUM7RUFDdEc7RUFDQSxJQUFJLENBQUNDLEdBQUcsRUFBRTtJQUNOO0lBQ0E7SUFDQTtJQUNBQSxHQUFHLEdBQUdJLHlCQUF5QixDQUFDUixNQUFNLEdBQUdBLE1BQU0sQ0FBQ1MsTUFBTSxHQUFHLEVBQUUsQ0FBQztFQUNoRTtFQUNBLE9BQU9MLEdBQUc7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU00sa0JBQWtCQSxDQUFDQyxFQUFVLEVBQVU7RUFDbkQ7RUFDQSxNQUFNQyxLQUFLLEdBQUcsSUFBQUMsMkJBQWMsRUFBQ0YsRUFBRSxDQUFDO0VBRWhDLE9BQU9iLGtCQUFrQixDQUFDYyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ3hDO0FBRU8sU0FBU0UsZ0JBQWdCQSxDQUM1QkMsSUFBNkIsRUFDN0JkLEtBQWEsRUFDYkMsTUFBYyxFQUNkQyxZQUEyQixFQUNkO0VBQ2IsSUFBSSxDQUFDWSxJQUFJLENBQUNDLFNBQVMsRUFBRSxPQUFPLElBQUk7RUFDaEMsT0FBTyxJQUFBVixtQkFBWSxFQUFDUyxJQUFJLENBQUNDLFNBQVMsQ0FBQyxDQUFDVCx3QkFBd0IsQ0FBQ04sS0FBSyxFQUFFQyxNQUFNLEVBQUVDLFlBQVksQ0FBQztBQUM3RjtBQUVBLFNBQVNjLGVBQWVBLENBQUNDLEtBQWEsRUFBVztFQUM3QyxPQUNJLE9BQU9BLEtBQUssS0FBSyxRQUFRLEtBQ3hCQSxLQUFLLENBQUNDLE1BQU0sS0FBSyxDQUFDLElBQUlELEtBQUssQ0FBQ0MsTUFBTSxLQUFLLENBQUMsQ0FBQyxJQUMxQ0QsS0FBSyxDQUFDRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUN2QixDQUFDRixLQUFLLENBQ0RHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FDUkMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUNUQyxJQUFJLENBQUVDLENBQUMsSUFBS0MsS0FBSyxDQUFDQyxRQUFRLENBQUNGLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRWhEO0FBRUEsU0FBU0csV0FBV0EsQ0FBQ1QsS0FBYSxFQUFVO0VBQ3hDLE1BQU1VLElBQUksR0FBRyxFQUFFO0VBQ2YsTUFBTUMsTUFBTSxHQUFHQyxRQUFRLENBQUNDLGFBQWEsQ0FBQyxRQUFRLENBQUM7RUFDL0NGLE1BQU0sQ0FBQzVCLEtBQUssR0FBRzJCLElBQUk7RUFDbkJDLE1BQU0sQ0FBQzNCLE1BQU0sR0FBRzBCLElBQUk7RUFDcEIsTUFBTUksR0FBRyxHQUFHSCxNQUFNLENBQUNJLFVBQVUsQ0FBQyxJQUFJLENBQUM7RUFDbkM7RUFDQSxJQUFJLENBQUNELEdBQUcsRUFBRTtJQUNOLE9BQU8sRUFBRTtFQUNiO0VBQ0FBLEdBQUcsQ0FBQ0UsU0FBUyxHQUFHaEIsS0FBSztFQUNyQmMsR0FBRyxDQUFDRyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRVAsSUFBSSxFQUFFQSxJQUFJLENBQUM7RUFDOUIsT0FBT0MsTUFBTSxDQUFDTyxTQUFTLENBQUMsQ0FBQztBQUM3Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNQyxtQkFBbUIsR0FBRyxJQUFJQyxHQUFHLENBQWlCLENBQUM7QUFFOUMsU0FBUzlCLHlCQUF5QkEsQ0FBQytCLENBQVMsRUFBVTtFQUN6RCxJQUFJLENBQUNBLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0VBQ25CO0VBQ0EsTUFBTUMsVUFBVSxHQUFHLElBQUEzQiwyQkFBYyxFQUFDMEIsQ0FBQyxDQUFDO0VBQ3BDO0VBQ0EsTUFBTUUsV0FBVyxHQUFHLDhCQUE4QkQsVUFBVSxFQUFFO0VBQzlELE1BQU1FLFFBQVEsR0FBR0MsZ0JBQWdCLENBQUNiLFFBQVEsQ0FBQ2MsSUFBSSxDQUFDLENBQUNDLGdCQUFnQixDQUFDSixXQUFXLENBQUM7RUFDOUUsTUFBTXZCLEtBQUssR0FBR3dCLFFBQVEsSUFBSTdDLGdCQUFnQixDQUFDMkMsVUFBVSxHQUFHLENBQUMsQ0FBQztFQUMxRCxJQUFJTSxPQUFPLEdBQUdULG1CQUFtQixDQUFDVSxHQUFHLENBQUM3QixLQUFLLENBQUM7RUFDNUMsSUFBSSxDQUFDNEIsT0FBTyxFQUFFO0lBQ1Y7SUFDQTtJQUNBLElBQUk3QixlQUFlLENBQUNDLEtBQUssQ0FBQyxFQUFFO01BQ3hCNEIsT0FBTyxHQUFHbkIsV0FBVyxDQUFDVCxLQUFLLENBQUM7TUFDNUJtQixtQkFBbUIsQ0FBQ1csR0FBRyxDQUFDOUIsS0FBSyxFQUFFNEIsT0FBTyxDQUFDO0lBQzNDLENBQUMsTUFBTTtNQUNIQSxPQUFPLEdBQUcsRUFBRTtJQUNoQjtFQUNKO0VBQ0EsT0FBT0EsT0FBTztBQUNsQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTRyxnQkFBZ0JBLENBQUNDLElBQVksRUFBc0I7RUFDL0QsSUFBSSxDQUFDQSxJQUFJLEVBQUU7SUFDUDtJQUNBQyxPQUFPLENBQUNDLEtBQUssQ0FBQyxvREFBb0QsQ0FBQztJQUNuRSxPQUFPQyxTQUFTO0VBQ3BCO0VBQ0EsSUFBSUgsSUFBSSxDQUFDL0IsTUFBTSxHQUFHLENBQUMsRUFBRTtJQUNqQixPQUFPa0MsU0FBUztFQUNwQjtFQUVBLE1BQU1DLE9BQU8sR0FBR0osSUFBSSxDQUFDLENBQUMsQ0FBQztFQUN2QixJQUFJLENBQUNJLE9BQU8sS0FBSyxHQUFHLElBQUlBLE9BQU8sS0FBSyxHQUFHLElBQUlBLE9BQU8sS0FBSyxHQUFHLEtBQUtKLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtJQUNwRUEsSUFBSSxHQUFHQSxJQUFJLENBQUNLLFNBQVMsQ0FBQyxDQUFDLENBQUM7RUFDNUI7RUFFQSxPQUFPLElBQUFDLHlCQUFnQixFQUFDTixJQUFJLENBQUMsQ0FBQ08sV0FBVyxDQUFDLENBQUM7QUFDL0M7QUFFTyxTQUFTQyxnQkFBZ0JBLENBQzVCQyxJQUFpQixFQUNqQjFELEtBQWMsRUFDZEMsTUFBZSxFQUNmQyxZQUEyQixFQUNkO0VBQ2IsSUFBSSxDQUFDd0QsSUFBSSxFQUFFLE9BQU8sSUFBSSxDQUFDLENBQUM7O0VBRXhCLElBQUlBLElBQUksQ0FBQ3RELGVBQWUsQ0FBQyxDQUFDLEVBQUU7SUFDeEIsTUFBTXVELEtBQUssR0FBRyxJQUFBdEQsbUJBQVksRUFBQ3FELElBQUksQ0FBQ3RELGVBQWUsQ0FBQyxDQUFDLElBQUlnRCxTQUFTLENBQUM7SUFDL0QsSUFBSXBELEtBQUssS0FBS29ELFNBQVMsSUFBSW5ELE1BQU0sS0FBS21ELFNBQVMsRUFBRTtNQUM3QyxPQUFPTyxLQUFLLENBQUNyRCx3QkFBd0IsQ0FBQ04sS0FBSyxFQUFFQyxNQUFNLEVBQUVDLFlBQVksQ0FBQztJQUN0RTtJQUNBLE9BQU95RCxLQUFLLENBQUNDLE9BQU87RUFDeEI7O0VBRUE7RUFDQSxJQUFJRixJQUFJLENBQUNHLFdBQVcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxJQUFJOztFQUVuQztFQUNBLElBQUksQ0FBQ0Msa0JBQVMsQ0FBQ0MsTUFBTSxDQUFDLENBQUMsQ0FBQ0Msa0JBQWtCLENBQUNOLElBQUksQ0FBQ08sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFBQyx3QkFBVyxFQUFDUixJQUFJLENBQUMsRUFBRTtJQUMzRSxPQUFPLElBQUk7RUFDZjs7RUFFQTtFQUNBLE1BQU1TLFdBQVcsR0FBR1QsSUFBSSxDQUFDVSx1QkFBdUIsQ0FBQyxDQUFDO0VBQ2xELElBQUlELFdBQVcsRUFBRS9ELGVBQWUsQ0FBQyxDQUFDLEVBQUU7SUFDaEMsTUFBTXVELEtBQUssR0FBRyxJQUFBdEQsbUJBQVksRUFBQzhELFdBQVcsQ0FBQy9ELGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDekQsSUFBSUosS0FBSyxLQUFLb0QsU0FBUyxJQUFJbkQsTUFBTSxLQUFLbUQsU0FBUyxFQUFFO01BQzdDLE9BQU9PLEtBQUssQ0FBQ3JELHdCQUF3QixDQUFDTixLQUFLLEVBQUVDLE1BQU0sRUFBRUMsWUFBWSxDQUFDO0lBQ3RFO0lBQ0EsT0FBT3lELEtBQUssQ0FBQ0MsT0FBTztFQUN4QjtFQUNBLE9BQU8sSUFBSTtBQUNmIiwiaWdub3JlTGlzdCI6W119