@firestone-hs/replay-parser
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.9.
399 lines • 78.5 kB
JavaScript
import { Injectable } from '@angular/core';
import { CardType, GameTag, GameType, Zone } from '@firestone-hs/reference-data';
import { Map } from 'immutable';
import { Game } from '../../models/game/game';
import { ActionParserConfig, ActionTurn, AttackAction, DamageAction, Entity, MinionDeathAction, PlayerEntity, PowerTargetAction, StartTurnAction, SummonAction, } from '../../models/models';
import * as i0 from "@angular/core";
import * as i1 from "../all-cards.service";
import * as i2 from "../gamepipeline/narrator.service";
export class BattlegroundsSimulationParserService {
constructor(allCards, narrator) {
this.allCards = allCards;
this.narrator = narrator;
}
async parse(bgsSimulation, config = new ActionParserConfig()) {
await this.allCards.initializeCardsDb();
const bgsSimulationWithIds = {
...bgsSimulation,
playerEntityId: bgsSimulation.actions[0].playerEntityId,
playerHeroPowerEntityId: 100000002,
playerCardId: bgsSimulation.actions[0].playerCardId,
playerHeroPowerCardId: bgsSimulation.actions[0].playerHeroPowerCardId,
playerHeroPowerUsed: bgsSimulation.actions[0].playerHeroPowerUsed,
opponentEntityId: bgsSimulation.actions[0].opponentEntityId,
opponentHeroPowerEntityId: 200000002,
opponentCardId: bgsSimulation.actions[0].opponentCardId,
opponentHeroPowerCardId: bgsSimulation.actions[0].opponentHeroPowerCardId,
opponentHeroPowerUsed: bgsSimulation.actions[0].opponentHeroPowerUsed,
};
const playerEntity = this.buildPlayerEntity(bgsSimulationWithIds);
const opponentEntity = this.buildOpponentEntity(bgsSimulationWithIds);
const playerHeroPowerEntity = this.buildPlayerHeroPowerEntity(bgsSimulationWithIds, playerEntity);
const opponentHeroPowerEntity = this.buildOpponentHeroPowerEntity(bgsSimulationWithIds, opponentEntity);
let game = Game.createGame({
players: [playerEntity, opponentEntity],
turns: Map.of(0, this.buildSingleBgsTurn(bgsSimulationWithIds, playerEntity, opponentEntity, playerHeroPowerEntity, opponentHeroPowerEntity)),
gameType: GameType.GT_BATTLEGROUNDS,
});
game = this.narrator.populateActionTextForLastTurn(game);
game = this.narrator.createGameStoryForLastTurn(game);
// console.log('built game', game, game.turns.toJS(), 'from', bgsSimulationWithIds);
return game;
}
buildSingleBgsTurn(bgsSimulation, playerEntity, opponentEntity, playerHeroPowerEntity, opponentHeroPowerEntity) {
return ActionTurn.create({
turn: 'battle',
activePlayer: undefined,
actions: bgsSimulation.actions.map((action) => this.buildGameAction(action, playerEntity, opponentEntity, bgsSimulation.anomalies)),
});
}
buildGameAction(action, playerEntity, opponentEntity, anomalies) {
const damages = this.buildDamages(action.type, action.damages, playerEntity, opponentEntity);
const playerRewardEntity = this.buildPlayerRewardEntity(action, playerEntity);
const opponentRewardEntity = this.buildOpponentRewardEntity(action, opponentEntity);
if (action.type === 'start-of-combat') {
const result = StartTurnAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages),
}, this.allCards);
// // console.log('built attack action', result, result.entities.toJS());
return result;
}
else if (action.type === 'player-attack') {
const result = AttackAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages),
originId: playerEntity.id,
targetId: opponentEntity.id,
targets: [[playerEntity.id, opponentEntity.id]],
damages: damages,
}, this.allCards);
// // console.log('built attack action', result, result.entities.toJS());
return result;
}
else if (action.type === 'opponent-attack') {
const result = AttackAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages),
originId: opponentEntity.id,
targetId: playerEntity.id,
targets: [[opponentEntity.id, playerEntity.id]],
damages: damages,
}, this.allCards);
// // console.log('built attack action', result, result.entities.toJS());
return result;
}
else if (action.type === 'attack') {
const result = AttackAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages),
originId: action.sourceEntityId,
targetId: action.targetEntityId,
targets: [[action.sourceEntityId, action.targetEntityId]],
damages: damages,
}, this.allCards);
// // console.log('built attack action', result, result.entities.toJS());
return result;
}
else if (action.type === 'damage') {
return DamageAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages),
damages: damages,
}, this.allCards);
}
else if (action.type === 'power-target') {
// // console.log('parsing powertargetaction', action);
const targetIds = action.targetEntityIds ?? [action.targetEntityId];
return PowerTargetAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages),
originId: action.sourceEntityId,
targetIds: targetIds,
targets: targetIds.map((targetId) => [action.sourceEntityId, targetId]),
}, this.allCards);
}
else if (action.type === 'spawn') {
return SummonAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
originId: action.sourceEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, null),
entityIds: action.spawns.map((entity) => entity.entityId),
}, this.allCards);
}
else if (action.type === 'minion-death') {
return MinionDeathAction.create({
playerId: action.playerEntityId,
opponentId: action.opponentEntityId,
entities: this.buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, null),
deadMinions: action.deaths.map((entity) => entity.entityId),
}, this.allCards);
}
}
buildDamages(actionType, damages, playerEntity, opponentEntity) {
if (!damages || damages.length === 0) {
return null;
}
if (actionType === 'player-attack') {
const damage = !!damages?.length ? damages[0].damage ?? 0 : 0;
return Map([[opponentEntity.id, damage]]);
}
else if (actionType === 'opponent-attack') {
const damage = !!damages?.length ? damages[0].damage ?? 0 : 0;
return Map([[playerEntity.id, damage]]);
}
const result = {};
for (const damage of damages) {
result[damage.targetEntityId] = (result[damage.targetEntityId] || 0) + damage.damage;
}
const arrayFromWhichToBuildMap = Object.keys(result).map((damagedEntityId) => [
parseInt(damagedEntityId),
result[damagedEntityId],
]);
// // console.log('building damage array', arrayFromWhichToBuildMap, result, damages);
return Map(arrayFromWhichToBuildMap);
}
buildEntities(action, playerRewardEntity, opponentRewardEntity, anomalies, damages) {
const playerEntity = this.buildGenericPlayerEntity('Player', action.playerEntityId, action.playerEntityId, action.playerCardId);
const opponentEntity = this.buildGenericPlayerEntity('Opponent', action.opponentEntityId, action.opponentEntityId, action.opponentCardId);
const playerHeroPowerEntity = this.buildGenericHeroPowerEntity(action.playerHeroPowerCardId, action.playerHeroPowerEntityId, action.playerHeroPowerUsed, playerEntity.playerId);
const opponentHeroPowerEntity = this.buildGenericHeroPowerEntity(action.opponentHeroPowerCardId, action.opponentHeroPowerEntityId, action.opponentHeroPowerUsed, opponentEntity.playerId);
const anomalyEntities = (anomalies ?? []).map((anomaly) => this.buildAnomalyEntity(anomaly));
const allSourceEntities = [
...(action.playerBoard || []),
...(action.opponentBoard || []),
// ...(action.spawns || []), // They are already present on the board
...(action.deaths || []),
];
// // console.log('parsing action', action.type, allSourceEntities, action);
const friendlyBoardEntities = allSourceEntities
.filter((entity) => entity.friendly)
.map((boardEntity, index) => this.buildEntity(boardEntity, this.findPositionOnBoard(action, boardEntity.entityId) ?? index, playerEntity, damages));
const opponentBoardEntities = allSourceEntities
.filter((entity) => !entity.friendly)
.map((boardEntity, index) => this.buildEntity(boardEntity, this.findPositionOnBoard(action, boardEntity.entityId) ?? index, opponentEntity, damages));
const allHandEntities = [...(action.playerHand || []), ...(action.opponentHand || [])];
const friendlyHandEntities = allHandEntities
.filter((entity) => entity.friendly)
.map((entity, index) => this.buildEntity(entity, index, playerEntity, damages, Zone.HAND));
const opponentHandEntities = allHandEntities
.filter((entity) => !entity.friendly)
.map((entity, index) => this.buildEntity(entity, index, opponentEntity, damages, Zone.HAND));
const playerSecretEntities = (action.playerSecrets || []).map((entity, index) => this.buildSecretEntity(entity, index, playerEntity, damages));
const opponentSecretEntities = (action.opponentSecrets || []).map((entity, index) => this.buildSecretEntity(entity, index, opponentEntity, damages));
const playerTrinketEntities = (action.playerTrinkets || []).map((entity, index) => this.buildTrinketEntity(entity, playerEntity, index));
const opponentTrinketEntities = (action.opponentTrinkets || []).map((entity, index) => this.buildTrinketEntity(entity, opponentEntity, index));
// // console.log('split entities', friendlyEntities, opponentEntities);
const allEntities = [
Object.assign(new PlayerEntity(), playerEntity, {
damageForThisAction: damages && damages.get(playerEntity.id) ? damages.get(playerEntity.id) : undefined,
}),
Object.assign(new PlayerEntity(), opponentEntity, {
damageForThisAction: damages && damages.get(opponentEntity.id) ? damages.get(opponentEntity.id) : undefined,
}),
playerHeroPowerEntity,
opponentHeroPowerEntity,
playerRewardEntity,
opponentRewardEntity,
...anomalyEntities,
...friendlyBoardEntities,
...opponentBoardEntities,
...friendlyHandEntities,
...opponentHandEntities,
...playerSecretEntities,
...opponentSecretEntities,
...playerTrinketEntities,
...opponentTrinketEntities,
].filter((e) => !!e);
const mapEntries = allEntities.map((entity) => [entity.id, entity]);
// // console.log('map entries', mapEntries);
const result = Map(mapEntries);
// // console.log('built entities', result.get(1), result);
return result;
}
findPositionOnBoard(action, entityId) {
if (!action.deaths) {
return undefined;
}
for (let i = 0; i < action.deaths.length; i++) {
if (action.deaths[i].entityId === entityId) {
return action.deadMinionsPositionsOnBoard[i];
}
}
return undefined;
}
buildEntity(boardEntity, boardPosition, playerEntity, damages, zone = Zone.PLAY) {
const refCard = this.allCards.getCard(boardEntity.cardId);
const tags = {
[GameTag[GameTag.CONTROLLER]]: playerEntity.playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.MINION,
[GameTag[GameTag.ZONE]]: zone ?? Zone.PLAY,
[GameTag[GameTag.ZONE_POSITION]]: boardPosition,
[GameTag[GameTag.ATK]]: boardEntity.attack,
[GameTag[GameTag.HEALTH]]: boardEntity.maxHealth ?? boardEntity.health,
[GameTag[GameTag.DAMAGE]]: (boardEntity.maxHealth ?? boardEntity.health) - boardEntity.health,
[GameTag[GameTag.TAUNT]]: boardEntity.taunt ? 1 : 0,
[GameTag[GameTag.POISONOUS]]: boardEntity.poisonous || boardEntity.venomous ? 1 : 0,
[GameTag[GameTag.DIVINE_SHIELD]]: boardEntity.divineShield ? 1 : 0,
[GameTag[GameTag.REBORN]]: boardEntity.reborn ? 1 : 0,
[GameTag[GameTag.WINDFURY]]: boardEntity.windfury ? 1 : 0,
[GameTag[GameTag.DEATHRATTLE]]: refCard.mechanics?.includes(GameTag[GameTag.DEATHRATTLE]) ? 1 : 0,
[GameTag[GameTag.TRIGGER_VISUAL]]: refCard.mechanics?.includes(GameTag[GameTag.TRIGGER_VISUAL]) ? 1 : 0,
[GameTag[GameTag.STEALTH]]: boardEntity.stealth ? 1 : 0,
[GameTag[GameTag.PREMIUM]]: refCard.battlegroundsNormalDbfId || refCard.premium ? 1 : 0,
[GameTag[GameTag.TECH_LEVEL]]: refCard.techLevel,
};
return Entity.create({
id: boardEntity.entityId,
cardID: boardEntity.cardId,
tags: tags,
damageForThisAction: damages && damages.get(boardEntity.entityId) ? damages.get(boardEntity.entityId) : undefined,
});
}
buildSecretEntity(boardEntity, boardPosition, playerEntity, damages) {
const refCard = this.allCards.getCard(boardEntity.cardId);
const tags = {
[GameTag[GameTag.CONTROLLER]]: playerEntity.playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.SPELL,
[GameTag[GameTag.ZONE]]: Zone.SECRET,
[GameTag[GameTag.CLASS]]: GameTag[refCard.classes?.[0].toUpperCase() ?? 'NEUTRAL'],
[GameTag[GameTag.ZONE_POSITION]]: boardPosition,
};
return Entity.create({
id: boardEntity.entityId,
cardID: boardEntity.cardId,
tags: tags,
damageForThisAction: damages && damages.get(boardEntity.entityId) ? damages.get(boardEntity.entityId) : undefined,
});
}
buildTrinketEntity(boardEntity, playerEntity, index) {
const refCard = this.allCards.getCard(boardEntity.cardId);
const tags = {
[GameTag[GameTag.CONTROLLER]]: playerEntity.playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.BATTLEGROUND_TRINKET,
[GameTag[GameTag.ZONE]]: Zone.PLAY,
[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_6]]: index + 1,
};
return Entity.create({
id: boardEntity.entityId,
cardID: boardEntity.cardId,
tags: tags,
});
}
buildPlayerEntity(bgsSimulation) {
return this.buildGenericPlayerEntity('Player', bgsSimulation.playerEntityId, bgsSimulation.playerEntityId, bgsSimulation.playerCardId);
}
buildPlayerHeroPowerEntity(bgsSimulation, playerEntity) {
return this.buildGenericHeroPowerEntity(bgsSimulation.playerHeroPowerCardId, bgsSimulation.playerHeroPowerEntityId, bgsSimulation.playerHeroPowerUsed, playerEntity.playerId);
}
buildGenericHeroPowerEntity(cardId, entityId, used, playerId) {
if (!cardId) {
return null;
}
const tags = {
[GameTag[GameTag.CONTROLLER]]: playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.HERO_POWER,
[GameTag[GameTag.ZONE]]: Zone.PLAY,
[GameTag[GameTag.ENTITY_ID]]: Zone.PLAY,
[GameTag[GameTag.EXHAUSTED]]: used ? 1 : 0,
};
return Entity.create({
id: entityId,
cardID: cardId,
tags: tags,
});
}
buildAnomalyEntity(cardId) {
if (!cardId) {
return null;
}
const tags = {
[GameTag[GameTag.CARDTYPE]]: CardType.BATTLEGROUND_ANOMALY,
[GameTag[GameTag.ZONE]]: Zone.PLAY,
[GameTag[GameTag.ENTITY_ID]]: Zone.PLAY,
};
return Entity.create({
id: 6666666661,
cardID: cardId,
tags: tags,
});
}
buildPlayerRewardEntity(action, playerEntity) {
const cardId = action.playerRewardCardId ?? action.playerHeroPowers?.[1]?.cardId;
const entityId = action.playerRewardEntityId ?? action.playerHeroPowers?.[1]?.entityId;
console.debug('player quest reward card id', cardId);
if (!cardId) {
return null;
}
const tags = {
[GameTag[GameTag.CONTROLLER]]: playerEntity.playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.BATTLEGROUND_QUEST_REWARD,
[GameTag[GameTag.ZONE]]: Zone.PLAY,
[GameTag[GameTag.ENTITY_ID]]: entityId,
[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_1]]: action.playerRewardData,
};
console.debug('player quest reward tags', tags);
return Entity.create({
id: entityId,
cardID: cardId,
tags: tags,
});
}
buildOpponentRewardEntity(action, playerEntity) {
const cardId = action.opponentRewardCardId ?? action.opponentHeroPowers?.[1]?.cardId;
const entityId = action.opponentRewardEntityId ?? action.opponentHeroPowers?.[1]?.entityId;
if (!cardId) {
return null;
}
const tags = {
[GameTag[GameTag.CONTROLLER]]: playerEntity.playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.BATTLEGROUND_QUEST_REWARD,
[GameTag[GameTag.ZONE]]: Zone.PLAY,
[GameTag[GameTag.ENTITY_ID]]: entityId,
[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_1]]: action.opponentRewardData,
};
return Entity.create({
id: entityId,
cardID: cardId,
tags: tags,
});
}
buildOpponentHeroPowerEntity(bgsSimulation, playerEntity) {
return this.buildGenericHeroPowerEntity(bgsSimulation.opponentHeroPowerCardId, bgsSimulation.opponentHeroPowerEntityId, bgsSimulation.opponentHeroPowerUsed, playerEntity.playerId);
}
buildOpponentEntity(bgsSimulation) {
return this.buildGenericPlayerEntity('Opponent', bgsSimulation.opponentEntityId, bgsSimulation.opponentEntityId, bgsSimulation.opponentCardId);
}
buildGenericPlayerEntity(name, playerId, playerEntityId, playerCardId) {
const tags = {
[GameTag[GameTag.PLAYER_ID]]: playerId,
[GameTag[GameTag.CARDTYPE]]: CardType.PLAYER,
// Cheating here: using the same entity for player and hero
[GameTag[GameTag.HERO_ENTITY]]: playerEntityId,
[GameTag[GameTag.ZONE]]: Zone.PLAY,
};
return PlayerEntity.create({
id: playerEntityId,
playerId: playerId,
cardID: playerCardId,
name: name,
tags: tags,
});
}
}
BattlegroundsSimulationParserService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: BattlegroundsSimulationParserService, deps: [{ token: i1.AllCardsService }, { token: i2.NarratorService }], target: i0.ɵɵFactoryTarget.Injectable });
BattlegroundsSimulationParserService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: BattlegroundsSimulationParserService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: BattlegroundsSimulationParserService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.AllCardsService }, { type: i2.NarratorService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF0dGxlZ3JvdW5kcy1zaW11bGF0aW9uLXBhcnNlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcmVwbGF5LXBhcnNlci9zcmMvbGliL3NlcnZpY2VzL2JhdHRsZWdyb3VuZHMtc2ltdWxhdGlvbi9iYXR0bGVncm91bmRzLXNpbXVsYXRpb24tcGFyc2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFLakYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUMsT0FBTyxFQUVOLGtCQUFrQixFQUNsQixVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixNQUFNLEVBQ04saUJBQWlCLEVBQ2pCLFlBQVksRUFDWixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLFlBQVksR0FFWixNQUFNLHFCQUFxQixDQUFDOzs7O0FBUTdCLE1BQU0sT0FBTyxvQ0FBb0M7SUFDaEQsWUFDUyxRQUF5QixFQUN6QixRQUF5QjtRQUR6QixhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQUN6QixhQUFRLEdBQVIsUUFBUSxDQUFpQjtJQUMvQixDQUFDO0lBRUcsS0FBSyxDQUFDLEtBQUssQ0FDakIsYUFBeUIsRUFDekIsU0FBNkIsSUFBSSxrQkFBa0IsRUFBRTtRQUVyRCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN4QyxNQUFNLG9CQUFvQixHQUF1QjtZQUNoRCxHQUFHLGFBQWE7WUFDaEIsY0FBYyxFQUFFLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENB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TUFBTSxJQUFJLEdBQWtDO1lBQzNDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFFBQVE7WUFDdEMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLE1BQU07WUFDNUMsMkRBQTJEO1lBQzNELENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLGNBQWM7WUFDOUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUk7U0FDbEMsQ0FBQztRQUNGLE9BQU8sWUFBWSxDQUFDLE1BQU0sQ0FBQztZQUMxQixFQUFFLEVBQUUsY0FBYztZQUNsQixRQUFRLEVBQUUsUUFBUTtZQUNsQixNQUFNLEVBQUUsWUFBWTtZQUNwQixJQUFJLEVBQUUsSUFBSTtZQUNWLElBQUksRUFBRSxJQUFJO1NBQ00sQ0FBQyxDQUFDO0lBQ3BCLENBQUM7O2lJQS9oQlcsb0NBQW9DO3FJQUFwQyxvQ0FBb0MsY0FGcEMsTUFBTTsyRkFFTixvQ0FBb0M7a0JBSGhELFVBQVU7bUJBQUM7b0JBQ1gsVUFBVSxFQUFFLE1BQU07aUJBQ2xCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDYXJkVHlwZSwgR2FtZVRhZywgR2FtZVR5cGUsIFpvbmUgfSBmcm9tICdAZmlyZXN0b25lLWhzL3JlZmVyZW5jZS1kYXRhJztcclxuaW1wb3J0IHsgQm9hcmRFbnRpdHkgfSBmcm9tICdAZmlyZXN0b25lLWhzL3NpbXVsYXRlLWJncy1iYXR0bGUvZGlzdC9ib2FyZC1lbnRpdHknO1xyXG5pbXBvcnQgeyBCb2FyZFNlY3JldCB9IGZyb20gJ0BmaXJlc3RvbmUtaHMvc2ltdWxhdGUtYmdzLWJhdHRsZS9kaXN0L2JvYXJkLXNlY3JldCc7XHJcbmltcG9ydCB7IERhbWFnZSwgR2FtZUFjdGlvbiB9IGZyb20gJ0BmaXJlc3RvbmUtaHMvc2ltdWxhdGUtYmdzLWJhdHRsZS9kaXN0L3NpbXVsYXRpb24vc3BlY3RhdG9yL2dhbWUtYWN0aW9uJztcclxuaW1wb3J0IHsgR2FtZVNhbXBsZSB9IGZyb20gJ0BmaXJlc3RvbmUtaHMvc2ltdWxhdGUtYmdzLWJhdHRsZS9kaXN0L3NpbXVsYXRpb24vc3BlY3RhdG9yL2dhbWUtc2FtcGxlJztcclxuaW1wb3J0IHsgTWFwIH0gZnJvbSAnaW1tdXRhYmxlJztcclxuaW1wb3J0IHsgR2FtZSB9IGZyb20gJy4uLy4uL21vZGVscy9nYW1lL2dhbWUnO1xyXG5pbXBvcnQge1xyXG5cdEFjdGlvbixcclxuXHRBY3Rpb25QYXJzZXJDb25maWcsXHJcblx0QWN0aW9uVHVybixcclxuXHRBdHRhY2tBY3Rpb24sXHJcblx0RGFtYWdlQWN0aW9uLFxyXG5cdEVudGl0eSxcclxuXHRNaW5pb25EZWF0aEFjdGlvbixcclxuXHRQbGF5ZXJFbnRpdHksXHJcblx0UG93ZXJUYXJnZXRBY3Rpb24sXHJcblx0U3RhcnRUdXJuQWN0aW9uLFxyXG5cdFN1bW1vbkFjdGlvbixcclxuXHRUdXJuLFxyXG59IGZyb20gJy4uLy4uL21vZGVscy9tb2RlbHMnO1xyXG5pbXBvcnQgeyBBbGxDYXJkc1NlcnZpY2UgfSBmcm9tICcuLi9hbGwtY2FyZHMuc2VydmljZSc7XHJcbmltcG9ydCB7IE5hcnJhdG9yU2VydmljZSB9IGZyb20gJy4uL2dhbWVwaXBlbGluZS9uYXJyYXRvci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRXh0ZW5kZWRHYW1lU2FtcGxlIH0gZnJvbSAnLi9leHRlbmRlZC1nYW1lLXNhbXBsZSc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcblx0cHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQmF0dGxlZ3JvdW5kc1NpbXVsYXRpb25QYXJzZXJTZXJ2aWNlIHtcclxuXHRjb25zdHJ1Y3RvcihcclxuXHRcdHByaXZhdGUgYWxsQ2FyZHM6IEFsbENhcmRzU2VydmljZSxcclxuXHRcdHByaXZhdGUgbmFycmF0b3I6IE5hcnJhdG9yU2VydmljZSxcclxuXHQpIHt9XHJcblxyXG5cdHB1YmxpYyBhc3luYyBwYXJzZShcclxuXHRcdGJnc1NpbXVsYXRpb246IEdhbWVTYW1wbGUsXHJcblx0XHRjb25maWc6IEFjdGlvblBhcnNlckNvbmZpZyA9IG5ldyBBY3Rpb25QYXJzZXJDb25maWcoKSxcclxuXHQpOiBQcm9taXNlPEdhbWU+IHtcclxuXHRcdGF3YWl0IHRoaXMuYWxsQ2FyZHMuaW5pdGlhbGl6ZUNhcmRzRGIoKTtcclxuXHRcdGNvbnN0IGJnc1NpbXVsYXRpb25XaXRoSWRzOiBFeHRlbmRlZEdhbWVTYW1wbGUgPSB7XHJcblx0XHRcdC4uLmJnc1NpbXVsYXRpb24sXHJcblx0XHRcdHBsYXllckVudGl0eUlkOiBiZ3NTaW11bGF0aW9uLmFjdGlvbnNbMF0ucGxheWVyRW50aXR5SWQsXHJcblx0XHRcdHBsYXllckhlcm9Qb3dlckVudGl0eUlkOiAxMDAwMDAwMDIsXHJcblx0XHRcdHBsYXllckNhcmRJZDogYmdzU2ltdWxhdGlvbi5hY3Rpb25zWzBdLnBsYXllckNhcmRJZCxcclxuXHRcdFx0cGxheWVySGVyb1Bvd2VyQ2FyZElkOiBiZ3NTaW11bGF0aW9uLmFjdGlvbnNbMF0ucGxheWVySGVyb1Bvd2VyQ2FyZElkLFxyXG5cdFx0XHRwbGF5ZXJIZXJvUG93ZXJVc2VkOiBiZ3NTaW11bGF0aW9uLmFjdGlvbnNbMF0ucGxheWVySGVyb1Bvd2VyVXNlZCxcclxuXHRcdFx0b3Bwb25lbnRFbnRpdHlJZDogYmdzU2ltdWxhdGlvbi5hY3Rpb25zWzBdLm9wcG9uZW50RW50aXR5SWQsXHJcblx0XHRcdG9wcG9uZW50SGVyb1Bvd2VyRW50aXR5SWQ6IDIwMDAwMDAwMixcclxuXHRcdFx0b3Bwb25lbnRDYXJkSWQ6IGJnc1NpbXVsYXRpb24uYWN0aW9uc1swXS5vcHBvbmVudENhcmRJZCxcclxuXHRcdFx0b3Bwb25lbnRIZXJvUG93ZXJDYXJkSWQ6IGJnc1NpbXVsYXRpb24uYWN0aW9uc1swXS5vcHBvbmVudEhlcm9Qb3dlckNhcmRJZCxcclxuXHRcdFx0b3Bwb25lbnRIZXJvUG93ZXJVc2VkOiBiZ3NTaW11bGF0aW9uLmFjdGlvbnNbMF0ub3Bwb25lbnRIZXJvUG93ZXJVc2VkLFxyXG5cdFx0fTtcclxuXHJcblx0XHRjb25zdCBwbGF5ZXJFbnRpdHk6IFBsYXllckVudGl0eSA9IHRoaXMuYnVpbGRQbGF5ZXJFbnRpdHkoYmdzU2ltdWxhdGlvbldpdGhJZHMpO1xyXG5cdFx0Y29uc3Qgb3Bwb25lbnRFbnRpdHk6IFBsYXllckVudGl0eSA9IHRoaXMuYnVpbGRPcHBvbmVudEVudGl0eShiZ3NTaW11bGF0aW9uV2l0aElkcyk7XHJcblx0XHRjb25zdCBwbGF5ZXJIZXJvUG93ZXJFbnRpdHk6IEVudGl0eSA9IHRoaXMuYnVpbGRQbGF5ZXJIZXJvUG93ZXJFbnRpdHkoYmdzU2ltdWxhdGlvbldpdGhJZHMsIHBsYXllckVudGl0eSk7XHJcblx0XHRjb25zdCBvcHBvbmVudEh