@jsprismarine/prismarine
Version:
Dedicated Minecraft Bedrock Edition server written in TypeScript
100 lines (99 loc) • 18.5 kB
JavaScript
import ChatEvent from "../../events/chat/ChatEvent.es.js";
import Identifiers from "../Identifiers.es.js";
import AvailableActorIdentifiersPacket from "../packet/AvailableActorIdentifiersPacket.es.js";
import BiomeDefinitionListPacket from "../packet/BiomeDefinitionListPacket.es.js";
import ItemComponentPacket from "../packet/ItemComponentPacket.es.js";
import ResourcePackStackPacket from "../packet/ResourcePackStackPacket.es.js";
import StartGamePacket from "../packet/StartGamePacket.es.js";
import { Chat, ChatType } from "../../chat/Chat.es.js";
import PlayerSpawnEvent from "../../events/player/PlayerSpawnEvent.es.js";
import PlayStatusType from "../type/PlayStatusType.es.js";
import RespawnPacket, { RespawnState } from "../packet/RespawnPacket.es.js";
import SetSpawnPositionPacket, { SpawnType } from "../packet/SetSpawnPositionPacket.es.js";
import ResourcePackStatusType from "../type/ResourcePackStatusType.es.js";
import { getGametypeId } from "@jsprismarine/minecraft";
//#region src/network/handler/ResourcePackResponseHandler.ts
var ResourcePackResponseHandler = class {
static NetID = Identifiers.ResourcePackResponsePacket;
async handle(packet, server, session) {
if (packet.status === ResourcePackStatusType.HaveAllPacks) {
const resourcePackStack = new ResourcePackStackPacket();
resourcePackStack.texturePackRequired = false;
resourcePackStack.experimentsAlreadyEnabled = false;
await session.getConnection().sendDataPacket(resourcePackStack);
} else if (packet.status === ResourcePackStatusType.Completed) {
const player = session.getPlayer();
server.getLogger().info(`§b${player.getName()}§f is attempting to join with id §b${player.getUUID()}§f (§b${player.getRuntimeId()}§f) from ${player.getAddress().getAddress()}:${player.getAddress().getPort()}`);
const spawnEvent = new PlayerSpawnEvent(player);
server.post(["playerSpawn", spawnEvent]);
if (spawnEvent.isCancelled()) return;
const world = player.getWorld();
await session.addToPlayerList();
await session.sendTime(world.getTicks());
const startGame = new StartGamePacket();
startGame.entityId = player.getRuntimeId();
startGame.runtimeEntityId = player.getRuntimeId();
startGame.gamemode = player.gamemode;
startGame.defaultGamemode = getGametypeId(server.getConfig().getGamemode());
startGame.worldSpawnPos = await world.getSpawnPosition();
startGame.playerPos = player.getPosition();
startGame.pitch = player.pitch;
startGame.yaw = player.yaw;
startGame.serverIdentifier = "JSPrismarine";
startGame.worldIdentifier = world.getName();
startGame.scenarioIdentifier = "JSPrismarine";
startGame.levelId = world.getUUID();
startGame.ticks = server.getTick();
startGame.time = world.getTicks();
startGame.worldName = world.getName();
startGame.seed = world.getSeed();
startGame.gamerules = world.getGameruleManager();
await session.getConnection().sendDataPacket(startGame);
const itemComponent = new ItemComponentPacket();
await session.getConnection().sendDataPacket(itemComponent);
const setSpawnPos = new SetSpawnPositionPacket();
setSpawnPos.dimension = 0;
setSpawnPos.position = await world.getSpawnPosition();
setSpawnPos.blockPosition = setSpawnPos.position;
setSpawnPos.type = SpawnType.PLAYER_SPAWN;
await session.getConnection().sendDataPacket(setSpawnPos);
await session.sendTime(world.getTicks());
await session.sendSettings();
await session.sendAvailableCommands();
await session.sendPlayerList();
await session.getConnection().sendDataPacket(new BiomeDefinitionListPacket());
await session.getConnection().sendDataPacket(new AvailableActorIdentifiersPacket());
await session.sendAttributes();
await session.sendMetadata();
await session.sendAbilities();
await session.sendCreativeContents();
const respawnPacket = new RespawnPacket();
respawnPacket.state = RespawnState.SERVER_SEARCHING_FOR_SPAWN;
respawnPacket.position = player.getPosition();
respawnPacket.runtimeEntityId = player.getRuntimeId();
await session.getConnection().sendDataPacket(respawnPacket);
respawnPacket.state = RespawnState.SERVER_READY_TO_SPAWN;
await session.getConnection().sendDataPacket(respawnPacket);
respawnPacket.state = RespawnState.CLIENT_READY_TO_SPAWN;
await session.getConnection().sendDataPacket(respawnPacket);
await session.getPlayer().sendSpawn();
await session.getPlayer().sendInitialSpawnChunks();
await session.sendPlayStatus(PlayStatusType.PlayerSpawn);
await Promise.all([server.getSessionManager().getAllPlayers().filter((p) => p !== player).map(async (p) => {
await p.getNetworkSession().sendSpawn(player);
await session.sendSpawn(p);
}), player.getWorld().getEntities().filter((e) => !e.isPlayer()).map(async (entity) => entity.sendSpawn(player))]);
const chatSpawnEvent = new ChatEvent(new Chat({
sender: server.getConsole(),
message: `§e%multiplayer.player.joined`,
parameters: [player.getName()],
needsTranslation: true,
type: ChatType.TRANSLATION
}));
await server.emit("chat", chatSpawnEvent);
}
}
};
//#endregion
export { ResourcePackResponseHandler as default };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVzb3VyY2VQYWNrUmVzcG9uc2VIYW5kbGVyLmVzLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9uZXR3b3JrL2hhbmRsZXIvUmVzb3VyY2VQYWNrUmVzcG9uc2VIYW5kbGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYXQsIENoYXRUeXBlIH0gZnJvbSAnLi4vLi4vY2hhdC9DaGF0JztcbmltcG9ydCBSZXNwYXduUGFja2V0LCB7IFJlc3Bhd25TdGF0ZSB9IGZyb20gJy4uL3BhY2tldC9SZXNwYXduUGFja2V0JztcbmltcG9ydCBTZXRTcGF3blBvc2l0aW9uUGFja2V0LCB7IFNwYXduVHlwZSB9IGZyb20gJy4uL3BhY2tldC9TZXRTcGF3blBvc2l0aW9uUGFja2V0JztcblxuaW1wb3J0IHsgZ2V0R2FtZXR5cGVJZCB9IGZyb20gJ0Bqc3ByaXNtYXJpbmUvbWluZWNyYWZ0JztcbmltcG9ydCB0eXBlIHsgUGxheWVyU2Vzc2lvbiB9IGZyb20gJy4uLy4uLyc7XG5pbXBvcnQgdHlwZSBTZXJ2ZXIgZnJvbSAnLi4vLi4vU2VydmVyJztcbmltcG9ydCBDaGF0RXZlbnQgZnJvbSAnLi4vLi4vZXZlbnRzL2NoYXQvQ2hhdEV2ZW50JztcbmltcG9ydCBQbGF5ZXJTcGF3bkV2ZW50IGZyb20gJy4uLy4uL2V2ZW50cy9wbGF5ZXIvUGxheWVyU3Bhd25FdmVudCc7XG5pbXBvcnQgSWRlbnRpZmllcnMgZnJvbSAnLi4vSWRlbnRpZmllcnMnO1xuaW1wb3J0IEF2YWlsYWJsZUFjdG9ySWRlbnRpZmllcnNQYWNrZXQgZnJvbSAnLi4vcGFja2V0L0F2YWlsYWJsZUFjdG9ySWRlbnRpZmllcnNQYWNrZXQnO1xuaW1wb3J0IEJpb21lRGVmaW5pdGlvbkxpc3RQYWNrZXQgZnJvbSAnLi4vcGFja2V0L0Jpb21lRGVmaW5pdGlvbkxpc3RQYWNrZXQnO1xuaW1wb3J0IEl0ZW1Db21wb25lbnRQYWNrZXQgZnJvbSAnLi4vcGFja2V0L0l0ZW1Db21wb25lbnRQYWNrZXQnO1xuaW1wb3J0IHR5cGUgUmVzb3VyY2VQYWNrUmVzcG9uc2VQYWNrZXQgZnJvbSAnLi4vcGFja2V0L1Jlc291cmNlUGFja1Jlc3BvbnNlUGFja2V0JztcbmltcG9ydCBSZXNvdXJjZVBhY2tTdGFja1BhY2tldCBmcm9tICcuLi9wYWNrZXQvUmVzb3VyY2VQYWNrU3RhY2tQYWNrZXQnO1xuaW1wb3J0IFN0YXJ0R2FtZVBhY2tldCBmcm9tICcuLi9wYWNrZXQvU3RhcnRHYW1lUGFja2V0JztcbmltcG9ydCBQbGF5U3RhdHVzVHlwZSBmcm9tICcuLi90eXBlL1BsYXlTdGF0dXNUeXBlJztcbmltcG9ydCBSZXNvdXJjZVBhY2tTdGF0dXNUeXBlIGZyb20gJy4uL3R5cGUvUmVzb3VyY2VQYWNrU3RhdHVzVHlwZSc7XG5pbXBvcnQgdHlwZSBQYWNrZXRIYW5kbGVyIGZyb20gJy4vUGFja2V0SGFuZGxlcic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlUGFja1Jlc3BvbnNlSGFuZGxlciBpbXBsZW1lbnRzIFBhY2tldEhhbmRsZXI8UmVzb3VyY2VQYWNrUmVzcG9uc2VQYWNrZXQ+IHtcbiAgICBwdWJsaWMgc3RhdGljIE5ldElEID0gSWRlbnRpZmllcnMuUmVzb3VyY2VQYWNrUmVzcG9uc2VQYWNrZXQ7XG5cbiAgICBwdWJsaWMgYXN5bmMgaGFuZGxlKHBhY2tldDogUmVzb3VyY2VQYWNrUmVzcG9uc2VQYWNrZXQsIHNlcnZlcjogU2VydmVyLCBzZXNzaW9uOiBQbGF5ZXJTZXNzaW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChwYWNrZXQuc3RhdHVzID09PSBSZXNvdXJjZVBhY2tTdGF0dXNUeXBlLkhhdmVBbGxQYWNrcykge1xuICAgICAgICAgICAgY29uc3QgcmVzb3VyY2VQYWNrU3RhY2sgPSBuZXcgUmVzb3VyY2VQYWNrU3RhY2tQYWNrZXQoKTtcbiAgICAgICAgICAgIHJlc291cmNlUGFja1N0YWNrLnRleHR1cmVQYWNrUmVxdWlyZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlc291cmNlUGFja1N0YWNrLmV4cGVyaW1lbnRzQWxyZWFkeUVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uZ2V0Q29ubmVjdGlvbigpLnNlbmREYXRhUGFja2V0KHJlc291cmNlUGFja1N0YWNrKTtcbiAgICAgICAgfSBlbHNlIGlmIChwYWNrZXQuc3RhdHVzID09PSBSZXNvdXJjZVBhY2tTdGF0dXNUeXBlLkNvbXBsZXRlZCkge1xuICAgICAgICAgICAgY29uc3QgcGxheWVyID0gc2Vzc2lvbi5nZXRQbGF5ZXIoKTtcbiAgICAgICAgICAgIHNlcnZlclxuICAgICAgICAgICAgICAgIC5nZXRMb2dnZXIoKVxuICAgICAgICAgICAgICAgIC5pbmZvKFxuICAgICAgICAgICAgICAgICAgICBgwqdiJHtwbGF5ZXIuZ2V0TmFtZSgpfcKnZiBpcyBhdHRlbXB0aW5nIHRvIGpvaW4gd2l0aCBpZCDCp2Ike3BsYXllci5nZXRVVUlEKCl9wqdmICjCp2Ike3BsYXllci5nZXRSdW50aW1lSWQoKX3Cp2YpIGZyb20gJHtwbGF5ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRBZGRyZXNzKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRBZGRyZXNzKCl9OiR7cGxheWVyLmdldEFkZHJlc3MoKS5nZXRQb3J0KCl9YFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIEVtaXQgcGxheWVyU3Bhd24gZXZlbnRcbiAgICAgICAgICAgIGNvbnN0IHNwYXduRXZlbnQgPSBuZXcgUGxheWVyU3Bhd25FdmVudChwbGF5ZXIpO1xuICAgICAgICAgICAgc2VydmVyLnBvc3QoWydwbGF5ZXJTcGF3bicsIHNwYXduRXZlbnRdKTtcbiAgICAgICAgICAgIGlmIChzcGF3bkV2ZW50LmlzQ2FuY2VsbGVkKCkpIHJldHVybjtcblxuICAgICAgICAgICAgLy8gVE9ETzogc2VuZCBpbnZlbnRvcnkgc2xvdHNcbiAgICAgICAgICAgIGNvbnN0IHdvcmxkID0gcGxheWVyLmdldFdvcmxkKCk7XG5cbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uYWRkVG9QbGF5ZXJMaXN0KCk7XG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnNlbmRUaW1lKHdvcmxkLmdldFRpY2tzKCkpO1xuXG4gICAgICAgICAgICBjb25zdCBzdGFydEdhbWUgPSBuZXcgU3RhcnRHYW1lUGFja2V0KCk7XG4gICAgICAgICAgICBzdGFydEdhbWUuZW50aXR5SWQgPSBwbGF5ZXIuZ2V0UnVudGltZUlkKCk7XG4gICAgICAgICAgICBzdGFydEdhbWUucnVudGltZUVudGl0eUlkID0gcGxheWVyLmdldFJ1bnRpbWVJZCgpO1xuICAgICAgICAgICAgc3RhcnRHYW1lLmdhbWVtb2RlID0gcGxheWVyLmdhbWVtb2RlO1xuICAgICAgICAgICAgc3RhcnRHYW1lLmRlZmF1bHRHYW1lbW9kZSA9IGdldEdhbWV0eXBlSWQoc2VydmVyLmdldENvbmZpZygpLmdldEdhbWVtb2RlKCkpO1xuXG4gICAgICAgICAgICBjb25zdCB3b3JsZFNwYXduUG9zID0gYXdhaXQgd29ybGQuZ2V0U3Bhd25Qb3NpdGlvbigpO1xuICAgICAgICAgICAgc3RhcnRHYW1lLndvcmxkU3Bhd25Qb3MgPSB3b3JsZFNwYXduUG9zO1xuXG4gICAgICAgICAgICBzdGFydEdhbWUucGxheWVyUG9zID0gcGxheWVyLmdldFBvc2l0aW9uKCk7XG4gICAgICAgICAgICBzdGFydEdhbWUucGl0Y2ggPSBwbGF5ZXIucGl0Y2g7XG4gICAgICAgICAgICBzdGFydEdhbWUueWF3ID0gcGxheWVyLnlhdztcblxuICAgICAgICAgICAgc3RhcnRHYW1lLnNlcnZlcklkZW50aWZpZXIgPSAnSlNQcmlzbWFyaW5lJztcbiAgICAgICAgICAgIHN0YXJ0R2FtZS53b3JsZElkZW50aWZpZXIgPSB3b3JsZC5nZXROYW1lKCk7XG4gICAgICAgICAgICBzdGFydEdhbWUuc2NlbmFyaW9JZGVudGlmaWVyID0gJ0pTUHJpc21hcmluZSc7XG4gICAgICAgICAgICBzdGFydEdhbWUubGV2ZWxJZCA9IHdvcmxkLmdldFVVSUQoKTtcbiAgICAgICAgICAgIHN0YXJ0R2FtZS50aWNrcyA9IHNlcnZlci5nZXRUaWNrKCk7XG4gICAgICAgICAgICBzdGFydEdhbWUudGltZSA9IHdvcmxkLmdldFRpY2tzKCk7XG4gICAgICAgICAgICBzdGFydEdhbWUud29ybGROYW1lID0gd29ybGQuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgc3RhcnRHYW1lLnNlZWQgPSB3b3JsZC5nZXRTZWVkKCk7XG4gICAgICAgICAgICBzdGFydEdhbWUuZ2FtZXJ1bGVzID0gd29ybGQuZ2V0R2FtZXJ1bGVNYW5hZ2VyKCk7XG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLmdldENvbm5lY3Rpb24oKS5zZW5kRGF0YVBhY2tldChzdGFydEdhbWUpO1xuXG4gICAgICAgICAgICBjb25zdCBpdGVtQ29tcG9uZW50ID0gbmV3IEl0ZW1Db21wb25lbnRQYWNrZXQoKTtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uZ2V0Q29ubmVjdGlvbigpLnNlbmREYXRhUGFja2V0KGl0ZW1Db21wb25lbnQpO1xuXG4gICAgICAgICAgICBjb25zdCBzZXRTcGF3blBvcyA9IG5ldyBTZXRTcGF3blBvc2l0aW9uUGFja2V0KCk7XG4gICAgICAgICAgICBzZXRTcGF3blBvcy5kaW1lbnNpb24gPSAwOyAvLyBUT0RPOiBlbnVtXG4gICAgICAgICAgICBzZXRTcGF3blBvcy5wb3NpdGlvbiA9IGF3YWl0IHdvcmxkLmdldFNwYXduUG9zaXRpb24oKTtcbiAgICAgICAgICAgIHNldFNwYXduUG9zLmJsb2NrUG9zaXRpb24gPSBzZXRTcGF3blBvcy5wb3NpdGlvbjtcbiAgICAgICAgICAgIHNldFNwYXduUG9zLnR5cGUgPSBTcGF3blR5cGUuUExBWUVSX1NQQVdOO1xuICAgICAgICAgICAgYXdhaXQgc2Vzc2lvbi5nZXRDb25uZWN0aW9uKCkuc2VuZERhdGFQYWNrZXQoc2V0U3Bhd25Qb3MpO1xuXG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnNlbmRUaW1lKHdvcmxkLmdldFRpY2tzKCkpO1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBzZXQgZGlmZmljdWx0eSBwYWNrZXRcbiAgICAgICAgICAgIC8vIFRPRE86IHNldCBjb21tYW5kcyBlbmFibGVkIHBhY2tldFxuXG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnNlbmRTZXR0aW5ncygpO1xuICAgICAgICAgICAgYXdhaXQgc2Vzc2lvbi5zZW5kQXZhaWxhYmxlQ29tbWFuZHMoKTtcblxuICAgICAgICAgICAgLy8gVE9ETzogZ2FtZSBydWxlcyBjaGFuZ2VkIHBhY2tldFxuXG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnNlbmRQbGF5ZXJMaXN0KCk7XG5cbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uZ2V0Q29ubmVjdGlvbigpLnNlbmREYXRhUGFja2V0KG5ldyBCaW9tZURlZmluaXRpb25MaXN0UGFja2V0KCkpO1xuICAgICAgICAgICAgYXdhaXQgc2Vzc2lvbi5nZXRDb25uZWN0aW9uKCkuc2VuZERhdGFQYWNrZXQobmV3IEF2YWlsYWJsZUFjdG9ySWRlbnRpZmllcnNQYWNrZXQoKSk7XG5cbiAgICAgICAgICAgIC8vIFRPRE86IHBsYXllciBmb2cgcGFja2V0XG5cbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uc2VuZEF0dHJpYnV0ZXMoKTtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uc2VuZE1ldGFkYXRhKCk7XG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnNlbmRBYmlsaXRpZXMoKTtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uc2VuZENyZWF0aXZlQ29udGVudHMoKTtcblxuICAgICAgICAgICAgLy8gU29tZSBwYWNrZXRzLi4uXG5cbiAgICAgICAgICAgIC8vIFRPRE86IGludmVudG9yeSBjcmFmdGluZyBkYXRhXG5cbiAgICAgICAgICAgIC8vIFRPRE86IGF2YWlsYWJsZSBjb21tYW5kc1xuXG4gICAgICAgICAgICBjb25zdCByZXNwYXduUGFja2V0ID0gbmV3IFJlc3Bhd25QYWNrZXQoKTtcbiAgICAgICAgICAgIHJlc3Bhd25QYWNrZXQuc3RhdGUgPSBSZXNwYXduU3RhdGUuU0VSVkVSX1NFQVJDSElOR19GT1JfU1BBV047XG4gICAgICAgICAgICByZXNwYXduUGFja2V0LnBvc2l0aW9uID0gcGxheWVyLmdldFBvc2l0aW9uKCk7XG4gICAgICAgICAgICByZXNwYXduUGFja2V0LnJ1bnRpbWVFbnRpdHlJZCA9IHBsYXllci5nZXRSdW50aW1lSWQoKTtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uZ2V0Q29ubmVjdGlvbigpLnNlbmREYXRhUGFja2V0KHJlc3Bhd25QYWNrZXQpO1xuXG4gICAgICAgICAgICByZXNwYXduUGFja2V0LnN0YXRlID0gUmVzcGF3blN0YXRlLlNFUlZFUl9SRUFEWV9UT19TUEFXTjtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uZ2V0Q29ubmVjdGlvbigpLnNlbmREYXRhUGFja2V0KHJlc3Bhd25QYWNrZXQpO1xuICAgICAgICAgICAgcmVzcGF3blBhY2tldC5zdGF0ZSA9IFJlc3Bhd25TdGF0ZS5DTElFTlRfUkVBRFlfVE9fU1BBV047XG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLmdldENvbm5lY3Rpb24oKS5zZW5kRGF0YVBhY2tldChyZXNwYXduUGFja2V0KTtcblxuICAgICAgICAgICAgLy8gU2VudCB0byBsZXQga25vdyB0aGUgY2xpZW50IHNhdmVkIGNodW5rc1xuICAgICAgICAgICAgYXdhaXQgc2Vzc2lvbi5nZXRQbGF5ZXIoKS5zZW5kU3Bhd24oKTtcbiAgICAgICAgICAgIGF3YWl0IHNlc3Npb24uZ2V0UGxheWVyKCkuc2VuZEluaXRpYWxTcGF3bkNodW5rcygpO1xuICAgICAgICAgICAgYXdhaXQgc2Vzc2lvbi5zZW5kUGxheVN0YXR1cyhQbGF5U3RhdHVzVHlwZS5QbGF5ZXJTcGF3bik7XG5cbiAgICAgICAgICAgIC8vIFN1bW1vbiBwbGF5ZXIocykgJiBlbnRpdGllc1xuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIHNlcnZlclxuICAgICAgICAgICAgICAgICAgICAuZ2V0U2Vzc2lvbk1hbmFnZXIoKVxuICAgICAgICAgICAgICAgICAgICAuZ2V0QWxsUGxheWVycygpXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoKHApID0+IHAgIT09IHBsYXllcilcbiAgICAgICAgICAgICAgICAgICAgLm1hcChhc3luYyAocCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcC5nZXROZXR3b3JrU2Vzc2lvbigpLnNlbmRTcGF3bihwbGF5ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2Vzc2lvbi5zZW5kU3Bhd24ocCk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHBsYXllclxuICAgICAgICAgICAgICAgICAgICAuZ2V0V29ybGQoKVxuICAgICAgICAgICAgICAgICAgICAuZ2V0RW50aXRpZXMoKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChlKSA9PiAhZS5pc1BsYXllcigpKVxuICAgICAgICAgICAgICAgICAgICAubWFwKGFzeW5jIChlbnRpdHkpID0+IGVudGl0eS5zZW5kU3Bhd24ocGxheWVyKSlcbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICAvLyBBbm5vdW5jZSBjb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCBjaGF0U3Bhd25FdmVudCA9IG5ldyBDaGF0RXZlbnQoXG4gICAgICAgICAgICAgICAgbmV3IENoYXQoe1xuICAgICAgICAgICAgICAgICAgICBzZW5kZXI6IHNlcnZlci5nZXRDb25zb2xlKCkhLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgwqdlJW11bHRpcGxheWVyLnBsYXllci5qb2luZWRgLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiBbcGxheWVyLmdldE5hbWUoKV0sXG4gICAgICAgICAgICAgICAgICAgIG5lZWRzVHJhbnNsYXRpb246IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IENoYXRUeXBlLlRSQU5TTEFUSU9OXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBhd2FpdCBzZXJ2ZXIuZW1pdCgnY2hhdCcsIGNoYXRTcGF3bkV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBLElBQXFCLDhCQUFyQixNQUFzRztDQUNsRyxPQUFjLFFBQVEsWUFBWTtDQUVsQyxNQUFhLE9BQU8sUUFBb0MsUUFBZ0IsU0FBdUM7RUFDM0csSUFBSSxPQUFPLFdBQVcsdUJBQXVCLGNBQWM7R0FDdkQsTUFBTSxvQkFBb0IsSUFBSSx3QkFBd0I7R0FDdEQsa0JBQWtCLHNCQUFzQjtHQUN4QyxrQkFBa0IsNEJBQTRCO0dBQzlDLE1BQU0sUUFBUSxjQUFjLEVBQUUsZUFBZSxpQkFBaUI7RUFDbEUsT0FBTyxJQUFJLE9BQU8sV0FBVyx1QkFBdUIsV0FBVztHQUMzRCxNQUFNLFNBQVMsUUFBUSxVQUFVO0dBQ2pDLE9BQ0ssVUFBVSxFQUNWLEtBQ0csS0FBSyxPQUFPLFFBQVEsRUFBRSxxQ0FBcUMsT0FBTyxRQUFRLEVBQUUsUUFBUSxPQUFPLGFBQWEsRUFBRSxXQUFXLE9BQ2hILFdBQVcsRUFDWCxXQUFXLEVBQUUsR0FBRyxPQUFPLFdBQVcsRUFBRSxRQUFRLEdBQ3JEO0dBR0osTUFBTSxhQUFhLElBQUksaUJBQWlCLE1BQU07R0FDOUMsT0FBTyxLQUFLLENBQUMsZUFBZSxVQUFVLENBQUM7R0FDdkMsSUFBSSxXQUFXLFlBQVksR0FBRztHQUc5QixNQUFNLFFBQVEsT0FBTyxTQUFTO0dBRTlCLE1BQU0sUUFBUSxnQkFBZ0I7R0FDOUIsTUFBTSxRQUFRLFNBQVMsTUFBTSxTQUFTLENBQUM7R0FFdkMsTUFBTSxZQUFZLElBQUksZ0JBQWdCO0dBQ3RDLFVBQVUsV0FBVyxPQUFPLGFBQWE7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