@firestone-hs/replay-parser
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.9.
207 lines • 35.3 kB
JavaScript
import { Injectable } from '@angular/core';
import { CardType, GameTag, Zone, isBattlegrounds } from '@firestone-hs/reference-data';
import { Entity } from '../../models/game/entity';
import { GameEntity } from '../../models/game/game-entity';
import { PlayerEntity } from '../../models/game/player-entity';
import { FullEntityHistoryItem } from '../../models/history/full-entity-history-item';
import { GameHistoryItem } from '../../models/history/game-history-item';
import { PlayerHistoryItem } from '../../models/history/player-history-item';
import { ShowEntityHistoryItem } from '../../models/history/show-entity-history-item';
import { TagChangeHistoryItem } from '../../models/history/tag-change-history-item';
import * as i0 from "@angular/core";
import * as i1 from "../all-cards.service";
export class GamePopulationService {
constructor(allCards) {
this.allCards = allCards;
}
initNewEntities(game, history, entityCardIdMapping) {
// Map of entityId - entity definition
// TODO: should we remove here all the SETASIDE / REMOVEDFROMGAME entities?
const entities = game
.getLatestParsedState()
.filter((entity) => ![Zone.REMOVEDFROMGAME].includes(entity.getTag(GameTag.ZONE)));
// console.debug('entities reduced from', game.getLatestParsedState().size, 'to', entities.size);
const entitiesAfterInit = this.initializeEntities(history, entities);
const entitiesAfterFillingCardIds = this.addMissingCardIds(entitiesAfterInit, entityCardIdMapping);
const entitiesAfterMissingInfo = this.completeMissingInformation(history, entitiesAfterFillingCardIds);
const entitiesAfterBasicData = this.addBasicData(entitiesAfterMissingInfo);
return entitiesAfterBasicData;
// return Game.createGame(game, {
// entities: entitiesAfterBasicData,
// } as Game);
// return entitiesAfterBasicData;
}
initializeEntities(history, entities) {
let result = entities;
for (const item of history) {
if (item instanceof PlayerHistoryItem) {
result = this.initializePlayer(item, result);
}
else if (item instanceof GameHistoryItem) {
result = this.initializeGame(item, result);
}
else if (item instanceof FullEntityHistoryItem) {
result = this.initializeFullEntity(item, result);
}
else if (item instanceof ShowEntityHistoryItem) {
result = this.initializeShowEntity(item, result);
}
}
return result;
}
addMissingCardIds(entitiesAfterInit, entityCardIdMapping) {
return entitiesAfterInit
.map((entity, entityId) => {
if (!entity.cardID) {
return entity.update({
cardID: entityCardIdMapping.get(entityId),
});
}
return entity;
})
.toMap();
}
initializePlayer(historyItem, entities) {
// Remove the battle tag if present
const playerName = historyItem.entityDefintion.name.indexOf('#') !== -1
? historyItem.entityDefintion.name.split('#')[0]
: historyItem.entityDefintion.name;
const entity = PlayerEntity.create({
id: historyItem.entityDefintion.id,
playerId: historyItem.entityDefintion.playerID,
accountHi: historyItem.accountHi,
accountLo: historyItem.accountLo,
name: playerName,
isMainPlayer: historyItem.isMainPlayer,
}).update(historyItem.entityDefintion);
return entities.set(entity.id, entity);
}
initializeGame(historyItem, entities) {
const base = Object.assign(new GameEntity(), {
id: historyItem.entityDefintion.id,
buildNumber: historyItem.buildNumber,
formatType: historyItem.formatType,
gameType: historyItem.gameType,
scenarioID: historyItem.scenarioID,
});
let entity = GameEntity.create(base).update(historyItem.entityDefintion);
// Battlegrounds doesn't have the right board state set at start
if (isBattlegrounds(historyItem.gameType)) {
// // console.log('initializing game entity with visual state', entity.tags.toJS(), entity);
entity = entity.updateTag(GameTag.BOARD_VISUAL_STATE, 1);
// // console.log('updated', entity.tags.toJS(), entity);
}
return entities.set(entity.id, entity);
}
initializeFullEntity(historyItem, entities) {
const newAttributes = {};
// We use the ShowEntity only to update the cardID at this stage
// and for a few other tags.
// Since we don't stop at mulligan stage, this means that otherwise
// a lot of other entities will be created
if (historyItem.entityDefintion.cardID) {
newAttributes.cardID = historyItem.entityDefintion.cardID;
}
// if (historyItem.entityDefintion.id === 73 || historyItem.entityDefintion.id === 74) {
// // // console.log('enriching', historyItem);
// }
const entity = entities
.get(historyItem.entityDefintion.id, Entity.create({ id: historyItem.entityDefintion.id }))
.update(newAttributes);
return entities.set(entity.id, entity);
}
initializeShowEntity(historyItem, entities) {
const newAttributes = {};
// Same here
if (historyItem.entityDefintion.cardID) {
newAttributes.cardID = historyItem.entityDefintion.cardID;
}
// if (historyItem.entityDefintion.id === 73 || historyItem.entityDefintion.id === 74) {
// // // console.log('enriching', historyItem);
// }
const entity = entities
.get(historyItem.entityDefintion.id, Entity.create({ id: historyItem.entityDefintion.id }))
.update(newAttributes);
return entities.set(entity.id, entity);
}
completeMissingInformation(history, entities) {
let result = entities;
for (const item of history) {
if (item instanceof TagChangeHistoryItem) {
result = this.addTagInformation(item, result);
}
if (item instanceof ShowEntityHistoryItem) {
result = this.addEntityInformation(item, result);
}
}
return result;
}
addTagInformation(item, entities) {
// if (item.tag.entity === 73 || item.tag.entity === 74) {
// // // console.log('enriching', item);
// }
if (item.tag.tag === GameTag.SECRET && item.tag.value === 1) {
const entity = entities.get(item.tag.entity)?.update({ tags: { [GameTag[item.tag.tag]]: 1 } });
return !!entity ? entities.set(entity.id, entity) : entities;
}
else if (item.tag.tag === GameTag.QUEST && item.tag.value === 1) {
const entity = entities.get(item.tag.entity)?.update({ tags: { [GameTag[item.tag.tag]]: 1 } });
return !!entity ? entities.set(entity.id, entity) : entities;
}
else if (item.tag.tag === GameTag.PARENT_CARD) {
const entity = entities
.get(item.tag.entity)
?.update({ tags: { [GameTag[item.tag.tag]]: item.tag.value } });
return !!entity ? entities.set(entity.id, entity) : entities;
}
return entities;
}
addEntityInformation(item, entities) {
// if (item.entityDefintion.id === 73 || item.entityDefintion.id === 74) {
// // // console.log('enriching', item);
// }
let result = entities;
if (item.entityDefintion.tags[GameTag[GameTag.SECRET]] === 1) {
const entity = entities.get(item.entityDefintion.id).update({
tags: { [GameTag[GameTag.SECRET]]: 1 },
});
result = entities.set(entity.id, entity);
}
const newTags = {
[GameTag[GameTag.CREATOR]]: item.entityDefintion.tags[GameTag[GameTag.CREATOR]],
[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_1]]: item.entityDefintion.tags[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_1]],
[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_2]]: item.entityDefintion.tags[GameTag[GameTag.TAG_SCRIPT_DATA_NUM_2]],
};
const finalEntity = result.get(item.entityDefintion.id).update({ tags: newTags });
return result.set(finalEntity.id, finalEntity);
}
addBasicData(entities) {
return entities
.map((value) => {
if (!value.cardID) {
return value;
}
const card = this.allCards.getCard(value.cardID);
let newTags = {};
if (card) {
if (card.type === 'Spell' && !value.getTag(GameTag.CARDTYPE)) {
newTags = { ...value.tags, [GameTag[GameTag.CARDTYPE]]: CardType.SPELL };
}
if (card.type === 'Enchantment' && !value.getTag(GameTag.CARDTYPE)) {
newTags = { ...value.tags, [GameTag[GameTag.CARDTYPE]]: CardType.ENCHANTMENT };
}
}
return value.update({ tags: newTags });
})
.toMap();
}
}
GamePopulationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: GamePopulationService, deps: [{ token: i1.AllCardsService }], target: i0.ɵɵFactoryTarget.Injectable });
GamePopulationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: GamePopulationService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: GamePopulationService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.AllCardsService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FtZS1wb3B1bGF0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9yZXBsYXktcGFyc2VyL3NyYy9saWIvc2VydmljZXMvZW50aXRpZXNwaXBlbGluZS9nYW1lLXBvcHVsYXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUV4RixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMvRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUN0RixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFFekUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDN0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDdEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sOENBQThDLENBQUM7OztBQVFwRixNQUFNLE9BQU8scUJBQXFCO0lBQ2pDLFlBQW9CLFFBQXlCO1FBQXpCLGFBQVEsR0FBUixRQUFRLENBQWlCO0lBQUcsQ0FBQztJQUUxQyxlQUFlLENBQ3JCLElBQVUsRUFDVixPQUErQixFQUMvQixtQkFBd0M7UUFFeEMsc0NBQXNDO1FBQ3RDLDJFQUEyRTtRQUMzRSxNQUFNLFFBQVEsR0FBd0IsSUFBSTthQUN4QyxvQkFBb0IsRUFBRTthQUN0QixNQUFNLENBQUMsQ0FBQyxNQUFjLEVBQUUsRUFB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Z3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENhcmRUeXBlLCBHYW1lVGFnLCBab25lLCBpc0JhdHRsZWdyb3VuZHMgfSBmcm9tICdAZmlyZXN0b25lLWhzL3JlZmVyZW5jZS1kYXRhJztcclxuaW1wb3J0IHsgTWFwIH0gZnJvbSAnaW1tdXRhYmxlJztcclxuaW1wb3J0IHsgRW50aXR5IH0gZnJvbSAnLi4vLi4vbW9kZWxzL2dhbWUvZW50aXR5JztcclxuaW1wb3J0IHsgR2FtZUVudGl0eSB9IGZyb20gJy4uLy4uL21vZGVscy9nYW1lL2dhbWUtZW50aXR5JztcclxuaW1wb3J0IHsgUGxheWVyRW50aXR5IH0gZnJvbSAnLi4vLi4vbW9kZWxzL2dhbWUvcGxheWVyLWVudGl0eSc7XHJcbmltcG9ydCB7IEZ1bGxFbnRpdHlIaXN0b3J5SXRlbSB9IGZyb20gJy4uLy4uL21vZGVscy9oaXN0b3J5L2Z1bGwtZW50aXR5LWhpc3RvcnktaXRlbSc7XHJcbmltcG9ydCB7IEdhbWVIaXN0b3J5SXRlbSB9IGZyb20gJy4uLy4uL21vZGVscy9oaXN0b3J5L2dhbWUtaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgSGlzdG9yeUl0ZW0gfSBmcm9tICcuLi8uLi9tb2RlbHMvaGlzdG9yeS9oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBQbGF5ZXJIaXN0b3J5SXRlbSB9IGZyb20gJy4uLy4uL21vZGVscy9oaXN0b3J5L3BsYXllci1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBTaG93RW50aXR5SGlzdG9yeUl0ZW0gfSBmcm9tICcuLi8uLi9tb2RlbHMvaGlzdG9yeS9zaG93LWVudGl0eS1oaXN0b3J5LWl0ZW0nO1xyXG5pbXBvcnQgeyBUYWdDaGFuZ2VIaXN0b3J5SXRlbSB9IGZyb20gJy4uLy4uL21vZGVscy9oaXN0b3J5L3RhZy1jaGFuZ2UtaGlzdG9yeS1pdGVtJztcclxuaW1wb3J0IHsgR2FtZSB9IGZyb20gJy4uLy4uL21vZGVscy9tb2RlbHMnO1xyXG5pbXBvcnQgeyBFbnRpdHlEZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3BhcnNlci9lbnRpdHktZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IEFsbENhcmRzU2VydmljZSB9IGZyb20gJy4uL2FsbC1jYXJkcy5zZXJ2aWNlJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuXHRwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBHYW1lUG9wdWxhdGlvblNlcnZpY2Uge1xyXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgYWxsQ2FyZHM6IEFsbENhcmRzU2VydmljZSkge31cclxuXHJcblx0cHVibGljIGluaXROZXdFbnRpdGllcyhcclxuXHRcdGdhbWU6IEdhbWUsXHJcblx0XHRoaXN0b3J5OiByZWFkb25seSBIaXN0b3J5SXRlbVtdLFxyXG5cdFx0ZW50aXR5Q2FyZElkTWFwcGluZzogTWFwPG51bWJlciwgc3RyaW5nPixcclxuXHQpOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdC8vIE1hcCBvZiBlbnRpdHlJZCAtIGVudGl0eSBkZWZpbml0aW9uXHJcblx0XHQvLyBUT0RPOiBzaG91bGQgd2UgcmVtb3ZlIGhlcmUgYWxsIHRoZSBTRVRBU0lERSAvIFJFTU9WRURGUk9NR0FNRSBlbnRpdGllcz9cclxuXHRcdGNvbnN0IGVudGl0aWVzOiBNYXA8bnVtYmVyLCBFbnRpdHk+ID0gZ2FtZVxyXG5cdFx0XHQuZ2V0TGF0ZXN0UGFyc2VkU3RhdGUoKVxyXG5cdFx0XHQuZmlsdGVyKChlbnRpdHk6IEVudGl0eSkgPT4gIVtab25lLlJFTU9WRURGUk9NR0FNRV0uaW5jbHVkZXMoZW50aXR5LmdldFRhZyhHYW1lVGFnLlpPTkUpKSk7XHJcblx0XHQvLyBjb25zb2xlLmRlYnVnKCdlbnRpdGllcyByZWR1Y2VkIGZyb20nLCBnYW1lLmdldExhdGVzdFBhcnNlZFN0YXRlKCkuc2l6ZSwgJ3RvJywgZW50aXRpZXMuc2l6ZSk7XHJcblx0XHRjb25zdCBlbnRpdGllc0FmdGVySW5pdDogTWFwPG51bWJlciwgRW50aXR5PiA9IHRoaXMuaW5pdGlhbGl6ZUVudGl0aWVzKGhpc3RvcnksIGVudGl0aWVzKTtcclxuXHRcdGNvbnN0IGVudGl0aWVzQWZ0ZXJGaWxsaW5nQ2FyZElkczogTWFwPG51bWJlciwgRW50aXR5PiA9IHRoaXMuYWRkTWlzc2luZ0NhcmRJZHMoXHJcblx0XHRcdGVudGl0aWVzQWZ0ZXJJbml0LFxyXG5cdFx0XHRlbnRpdHlDYXJkSWRNYXBwaW5nLFxyXG5cdFx0KTtcclxuXHRcdGNvbnN0IGVudGl0aWVzQWZ0ZXJNaXNzaW5nSW5mbzogTWFwPG51bWJlciwgRW50aXR5PiA9IHRoaXMuY29tcGxldGVNaXNzaW5nSW5mb3JtYXRpb24oXHJcblx0XHRcdGhpc3RvcnksXHJcblx0XHRcdGVudGl0aWVzQWZ0ZXJGaWxsaW5nQ2FyZElkcyxcclxuXHRcdCk7XHJcblx0XHRjb25zdCBlbnRpdGllc0FmdGVyQmFzaWNEYXRhOiBNYXA8bnVtYmVyLCBFbnRpdHk+ID0gdGhpcy5hZGRCYXNpY0RhdGEoZW50aXRpZXNBZnRlck1pc3NpbmdJbmZvKTtcclxuXHRcdHJldHVybiBlbnRpdGllc0FmdGVyQmFzaWNEYXRhO1xyXG5cdFx0Ly8gcmV0dXJuIEdhbWUuY3JlYXRlR2FtZShnYW1lLCB7XHJcblx0XHQvLyBcdGVudGl0aWVzOiBlbnRpdGllc0FmdGVyQmFzaWNEYXRhLFxyXG5cdFx0Ly8gfSBhcyBHYW1lKTtcclxuXHRcdC8vIHJldHVybiBlbnRpdGllc0FmdGVyQmFzaWNEYXRhO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBpbml0aWFsaXplRW50aXRpZXMoaGlzdG9yeTogcmVhZG9ubHkgSGlzdG9yeUl0ZW1bXSwgZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4pOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdGxldCByZXN1bHQgPSBlbnRpdGllcztcclxuXHRcdGZvciAoY29uc3QgaXRlbSBvZiBoaXN0b3J5KSB7XHJcblx0XHRcdGlmIChpdGVtIGluc3RhbmNlb2YgUGxheWVySGlzdG9yeUl0ZW0pIHtcclxuXHRcdFx0XHRyZXN1bHQgPSB0aGlzLmluaXRpYWxpemVQbGF5ZXIoaXRlbSwgcmVzdWx0KTtcclxuXHRcdFx0fSBlbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgR2FtZUhpc3RvcnlJdGVtKSB7XHJcblx0XHRcdFx0cmVzdWx0ID0gdGhpcy5pbml0aWFsaXplR2FtZShpdGVtLCByZXN1bHQpO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGl0ZW0gaW5zdGFuY2VvZiBGdWxsRW50aXR5SGlzdG9yeUl0ZW0pIHtcclxuXHRcdFx0XHRyZXN1bHQgPSB0aGlzLmluaXRpYWxpemVGdWxsRW50aXR5KGl0ZW0sIHJlc3VsdCk7XHJcblx0XHRcdH0gZWxzZSBpZiAoaXRlbSBpbnN0YW5jZW9mIFNob3dFbnRpdHlIaXN0b3J5SXRlbSkge1xyXG5cdFx0XHRcdHJlc3VsdCA9IHRoaXMuaW5pdGlhbGl6ZVNob3dFbnRpdHkoaXRlbSwgcmVzdWx0KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgYWRkTWlzc2luZ0NhcmRJZHMoXHJcblx0XHRlbnRpdGllc0FmdGVySW5pdDogTWFwPG51bWJlciwgRW50aXR5PixcclxuXHRcdGVudGl0eUNhcmRJZE1hcHBpbmc6IE1hcDxudW1iZXIsIHN0cmluZz4sXHJcblx0KTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHRyZXR1cm4gZW50aXRpZXNBZnRlckluaXRcclxuXHRcdFx0Lm1hcCgoZW50aXR5LCBlbnRpdHlJZCkgPT4ge1xyXG5cdFx0XHRcdGlmICghZW50aXR5LmNhcmRJRCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGVudGl0eS51cGRhdGUoe1xyXG5cdFx0XHRcdFx0XHRjYXJkSUQ6IGVudGl0eUNhcmRJZE1hcHBpbmcuZ2V0KGVudGl0eUlkKSxcclxuXHRcdFx0XHRcdH0gYXMgRW50aXR5RGVmaW5pdGlvbik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiBlbnRpdHk7XHJcblx0XHRcdH0pXHJcblx0XHRcdC50b01hcCgpO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBpbml0aWFsaXplUGxheWVyKGhpc3RvcnlJdGVtOiBQbGF5ZXJIaXN0b3J5SXRlbSwgZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4pOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdC8vIFJlbW92ZSB0aGUgYmF0dGxlIHRhZyBpZiBwcmVzZW50XHJcblx0XHRjb25zdCBwbGF5ZXJOYW1lID1cclxuXHRcdFx0aGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLm5hbWUuaW5kZXhPZignIycpICE9PSAtMVxyXG5cdFx0XHRcdD8gaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLm5hbWUuc3BsaXQoJyMnKVswXVxyXG5cdFx0XHRcdDogaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLm5hbWU7XHJcblx0XHRjb25zdCBlbnRpdHk6IFBsYXllckVudGl0eSA9IFBsYXllckVudGl0eS5jcmVhdGUoe1xyXG5cdFx0XHRpZDogaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLmlkLFxyXG5cdFx0XHRwbGF5ZXJJZDogaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLnBsYXllcklELFxyXG5cdFx0XHRhY2NvdW50SGk6IGhpc3RvcnlJdGVtLmFjY291bnRIaSxcclxuXHRcdFx0YWNjb3VudExvOiBoaXN0b3J5SXRlbS5hY2NvdW50TG8sXHJcblx0XHRcdG5hbWU6IHBsYXllck5hbWUsXHJcblx0XHRcdGlzTWFpblBsYXllcjogaGlzdG9yeUl0ZW0uaXNNYWluUGxheWVyLFxyXG5cdFx0fSBhcyBQbGF5ZXJFbnRpdHkpLnVwZGF0ZShoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24pO1xyXG5cdFx0cmV0dXJuIGVudGl0aWVzLnNldChlbnRpdHkuaWQsIGVudGl0eSk7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGluaXRpYWxpemVHYW1lKGhpc3RvcnlJdGVtOiBHYW1lSGlzdG9yeUl0ZW0sIGVudGl0aWVzOiBNYXA8bnVtYmVyLCBFbnRpdHk+KTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHRjb25zdCBiYXNlOiBHYW1lRW50aXR5ID0gT2JqZWN0LmFzc2lnbihuZXcgR2FtZUVudGl0eSgpLCB7XHJcblx0XHRcdGlkOiBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uaWQsXHJcblx0XHRcdGJ1aWxkTnVtYmVyOiBoaXN0b3J5SXRlbS5idWlsZE51bWJlcixcclxuXHRcdFx0Zm9ybWF0VHlwZTogaGlzdG9yeUl0ZW0uZm9ybWF0VHlwZSxcclxuXHRcdFx0Z2FtZVR5cGU6IGhpc3RvcnlJdGVtLmdhbWVUeXBlLFxyXG5cdFx0XHRzY2VuYXJpb0lEOiBoaXN0b3J5SXRlbS5zY2VuYXJpb0lELFxyXG5cdFx0fSk7XHJcblx0XHRsZXQgZW50aXR5OiBHYW1lRW50aXR5ID0gR2FtZUVudGl0eS5jcmVhdGUoYmFzZSkudXBkYXRlKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbik7XHJcblx0XHQvLyBCYXR0bGVncm91bmRzIGRvZXNuJ3QgaGF2ZSB0aGUgcmlnaHQgYm9hcmQgc3RhdGUgc2V0IGF0IHN0YXJ0XHJcblx0XHRpZiAoaXNCYXR0bGVncm91bmRzKGhpc3RvcnlJdGVtLmdhbWVUeXBlKSkge1xyXG5cdFx0XHQvLyAvLyBjb25zb2xlLmxvZygnaW5pdGlhbGl6aW5nIGdhbWUgZW50aXR5IHdpdGggdmlzdWFsIHN0YXRlJywgZW50aXR5LnRhZ3MudG9KUygpLCBlbnRpdHkpO1xyXG5cdFx0XHRlbnRpdHkgPSBlbnRpdHkudXBkYXRlVGFnKEdhbWVUYWcuQk9BUkRfVklTVUFMX1NUQVRFLCAxKTtcclxuXHRcdFx0Ly8gLy8gY29uc29sZS5sb2coJ3VwZGF0ZWQnLCBlbnRpdHkudGFncy50b0pTKCksIGVudGl0eSk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZW50aXRpZXMuc2V0KGVudGl0eS5pZCwgZW50aXR5KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgaW5pdGlhbGl6ZUZ1bGxFbnRpdHkoXHJcblx0XHRoaXN0b3J5SXRlbTogRnVsbEVudGl0eUhpc3RvcnlJdGVtLFxyXG5cdFx0ZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4sXHJcblx0KTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHRjb25zdCBuZXdBdHRyaWJ1dGVzOiBhbnkgPSB7fTtcclxuXHRcdC8vIFdlIHVzZSB0aGUgU2hvd0VudGl0eSBvbmx5IHRvIHVwZGF0ZSB0aGUgY2FyZElEIGF0IHRoaXMgc3RhZ2VcclxuXHRcdC8vIGFuZCBmb3IgYSBmZXcgb3RoZXIgdGFncy5cclxuXHRcdC8vIFNpbmNlIHdlIGRvbid0IHN0b3AgYXQgbXVsbGlnYW4gc3RhZ2UsIHRoaXMgbWVhbnMgdGhhdCBvdGhlcndpc2VcclxuXHRcdC8vIGEgbG90IG9mIG90aGVyIGVudGl0aWVzIHdpbGwgYmUgY3JlYXRlZFxyXG5cdFx0aWYgKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5jYXJkSUQpIHtcclxuXHRcdFx0bmV3QXR0cmlidXRlcy5jYXJkSUQgPSBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uY2FyZElEO1xyXG5cdFx0fVxyXG5cdFx0Ly8gaWYgKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCA9PT0gNzMgfHwgaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLmlkID09PSA3NCkge1xyXG5cdFx0Ly8gXHQvLyAvLyBjb25zb2xlLmxvZygnZW5yaWNoaW5nJywgaGlzdG9yeUl0ZW0pO1xyXG5cdFx0Ly8gfVxyXG5cdFx0Y29uc3QgZW50aXR5OiBFbnRpdHkgPSBlbnRpdGllc1xyXG5cdFx0XHQuZ2V0KGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCwgRW50aXR5LmNyZWF0ZSh7IGlkOiBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uaWQgfSBhcyBFbnRpdHkpKVxyXG5cdFx0XHQudXBkYXRlKG5ld0F0dHJpYnV0ZXMgYXMgRW50aXR5RGVmaW5pdGlvbik7XHJcblx0XHRyZXR1cm4gZW50aXRpZXMuc2V0KGVudGl0eS5pZCwgZW50aXR5KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgaW5pdGlhbGl6ZVNob3dFbnRpdHkoXHJcblx0XHRoaXN0b3J5SXRlbTogU2hvd0VudGl0eUhpc3RvcnlJdGVtLFxyXG5cdFx0ZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4sXHJcblx0KTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHRjb25zdCBuZXdBdHRyaWJ1dGVzOiBhbnkgPSB7fTtcclxuXHRcdC8vIFNhbWUgaGVyZVxyXG5cdFx0aWYgKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5jYXJkSUQpIHtcclxuXHRcdFx0bmV3QXR0cmlidXRlcy5jYXJkSUQgPSBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uY2FyZElEO1xyXG5cdFx0fVxyXG5cdFx0Ly8gaWYgKGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCA9PT0gNzMgfHwgaGlzdG9yeUl0ZW0uZW50aXR5RGVmaW50aW9uLmlkID09PSA3NCkge1xyXG5cdFx0Ly8gXHQvLyAvLyBjb25zb2xlLmxvZygnZW5yaWNoaW5nJywgaGlzdG9yeUl0ZW0pO1xyXG5cdFx0Ly8gfVxyXG5cdFx0Y29uc3QgZW50aXR5OiBFbnRpdHkgPSBlbnRpdGllc1xyXG5cdFx0XHQuZ2V0KGhpc3RvcnlJdGVtLmVudGl0eURlZmludGlvbi5pZCwgRW50aXR5LmNyZWF0ZSh7IGlkOiBoaXN0b3J5SXRlbS5lbnRpdHlEZWZpbnRpb24uaWQgfSBhcyBFbnRpdHkpKVxyXG5cdFx0XHQudXBkYXRlKG5ld0F0dHJpYnV0ZXMgYXMgRW50aXR5RGVmaW5pdGlvbik7XHJcblx0XHRyZXR1cm4gZW50aXRpZXMuc2V0KGVudGl0eS5pZCwgZW50aXR5KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgY29tcGxldGVNaXNzaW5nSW5mb3JtYXRpb24oXHJcblx0XHRoaXN0b3J5OiByZWFkb25seSBIaXN0b3J5SXRlbVtdLFxyXG5cdFx0ZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4sXHJcblx0KTogTWFwPG51bWJlciwgRW50aXR5PiB7XHJcblx0XHRsZXQgcmVzdWx0ID0gZW50aXRpZXM7XHJcblx0XHRmb3IgKGNvbnN0IGl0ZW0gb2YgaGlzdG9yeSkge1xyXG5cdFx0XHRpZiAoaXRlbSBpbnN0YW5jZW9mIFRhZ0NoYW5nZUhpc3RvcnlJdGVtKSB7XHJcblx0XHRcdFx0cmVzdWx0ID0gdGhpcy5hZGRUYWdJbmZvcm1hdGlvbihpdGVtLCByZXN1bHQpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChpdGVtIGluc3RhbmNlb2YgU2hvd0VudGl0eUhpc3RvcnlJdGVtKSB7XHJcblx0XHRcdFx0cmVzdWx0ID0gdGhpcy5hZGRFbnRpdHlJbmZvcm1hdGlvbihpdGVtLCByZXN1bHQpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBhZGRUYWdJbmZvcm1hdGlvbihpdGVtOiBUYWdDaGFuZ2VIaXN0b3J5SXRlbSwgZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4pOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdC8vIGlmIChpdGVtLnRhZy5lbnRpdHkgPT09IDczIHx8IGl0ZW0udGFnLmVudGl0eSA9PT0gNzQpIHtcclxuXHRcdC8vIFx0Ly8gLy8gY29uc29sZS5sb2coJ2VucmljaGluZycsIGl0ZW0pO1xyXG5cdFx0Ly8gfVxyXG5cdFx0aWYgKGl0ZW0udGFnLnRhZyA9PT0gR2FtZVRhZy5TRUNSRVQgJiYgaXRlbS50YWcudmFsdWUgPT09IDEpIHtcclxuXHRcdFx0Y29uc3QgZW50aXR5OiBFbnRpdHkgPSBlbnRpdGllcy5nZXQoaXRlbS50YWcuZW50aXR5KT8udXBkYXRlKHsgdGFnczogeyBbR2FtZVRhZ1tpdGVtLnRhZy50YWddXTogMSB9IH0pO1xyXG5cdFx0XHRyZXR1cm4gISFlbnRpdHkgPyBlbnRpdGllcy5zZXQoZW50aXR5LmlkLCBlbnRpdHkpIDogZW50aXRpZXM7XHJcblx0XHR9IGVsc2UgaWYgKGl0ZW0udGFnLnRhZyA9PT0gR2FtZVRhZy5RVUVTVCAmJiBpdGVtLnRhZy52YWx1ZSA9PT0gMSkge1xyXG5cdFx0XHRjb25zdCBlbnRpdHk6IEVudGl0eSA9IGVudGl0aWVzLmdldChpdGVtLnRhZy5lbnRpdHkpPy51cGRhdGUoeyB0YWdzOiB7IFtHYW1lVGFnW2l0ZW0udGFnLnRhZ11dOiAxIH0gfSk7XHJcblx0XHRcdHJldHVybiAhIWVudGl0eSA/IGVudGl0aWVzLnNldChlbnRpdHkuaWQsIGVudGl0eSkgOiBlbnRpdGllcztcclxuXHRcdH0gZWxzZSBpZiAoaXRlbS50YWcudGFnID09PSBHYW1lVGFnLlBBUkVOVF9DQVJEKSB7XHJcblx0XHRcdGNvbnN0IGVudGl0eTogRW50aXR5ID0gZW50aXRpZXNcclxuXHRcdFx0XHQuZ2V0KGl0ZW0udGFnLmVudGl0eSlcclxuXHRcdFx0XHQ/LnVwZGF0ZSh7IHRhZ3M6IHsgW0dhbWVUYWdbaXRlbS50YWcudGFnXV06IGl0ZW0udGFnLnZhbHVlIH0gfSk7XHJcblx0XHRcdHJldHVybiAhIWVudGl0eSA/IGVudGl0aWVzLnNldChlbnRpdHkuaWQsIGVudGl0eSkgOiBlbnRpdGllcztcclxuXHRcdH1cclxuXHRcdHJldHVybiBlbnRpdGllcztcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgYWRkRW50aXR5SW5mb3JtYXRpb24oaXRlbTogU2hvd0VudGl0eUhpc3RvcnlJdGVtLCBlbnRpdGllczogTWFwPG51bWJlciwgRW50aXR5Pik6IE1hcDxudW1iZXIsIEVudGl0eT4ge1xyXG5cdFx0Ly8gaWYgKGl0ZW0uZW50aXR5RGVmaW50aW9uLmlkID09PSA3MyB8fCBpdGVtLmVudGl0eURlZmludGlvbi5pZCA9PT0gNzQpIHtcclxuXHRcdC8vIFx0Ly8gLy8gY29uc29sZS5sb2coJ2VucmljaGluZycsIGl0ZW0pO1xyXG5cdFx0Ly8gfVxyXG5cdFx0bGV0IHJlc3VsdCA9IGVudGl0aWVzO1xyXG5cdFx0aWYgKGl0ZW0uZW50aXR5RGVmaW50aW9uLnRhZ3NbR2FtZVRhZ1tHYW1lVGFnLlNFQ1JFVF1dID09PSAxKSB7XHJcblx0XHRcdGNvbnN0IGVudGl0eTogRW50aXR5ID0gZW50aXRpZXMuZ2V0KGl0ZW0uZW50aXR5RGVmaW50aW9uLmlkKS51cGRhdGUoe1xyXG5cdFx0XHRcdHRhZ3M6IHsgW0dhbWVUYWdbR2FtZVRhZy5TRUNSRVRdXTogMSB9LFxyXG5cdFx0XHR9KTtcclxuXHRcdFx0cmVzdWx0ID0gZW50aXRpZXMuc2V0KGVudGl0eS5pZCwgZW50aXR5KTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IG5ld1RhZ3M6IHsgW3RhZ05hbWU6IHN0cmluZ106IG51bWJlciB9ID0ge1xyXG5cdFx0XHRbR2FtZVRhZ1tHYW1lVGFnLkNSRUFUT1JdXTogaXRlbS5lbnRpdHlEZWZpbnRpb24udGFnc1tHYW1lVGFnW0dhbWVUYWcuQ1JFQVRPUl1dLFxyXG5cdFx0XHRbR2FtZVRhZ1tHYW1lVGFnLlRBR19TQ1JJUFRfREFUQV9OVU1fMV1dOiBpdGVtLmVudGl0eURlZmludGlvbi50YWdzW0dhbWVUYWdbR2FtZVRhZy5UQUdfU0NSSVBUX0RBVEFfTlVNXzFdXSxcclxuXHRcdFx0W0dhbWVUYWdbR2FtZVRhZy5UQUdfU0NSSVBUX0RBVEFfTlVNXzJdXTogaXRlbS5lbnRpdHlEZWZpbnRpb24udGFnc1tHYW1lVGFnW0dhbWVUYWcuVEFHX1NDUklQVF9EQVRBX05VTV8yXV0sXHJcblx0XHR9O1xyXG5cdFx0Y29uc3QgZmluYWxFbnRpdHk6IEVudGl0eSA9IHJlc3VsdC5nZXQoaXRlbS5lbnRpdHlEZWZpbnRpb24uaWQpLnVwZGF0ZSh7IHRhZ3M6IG5ld1RhZ3MgfSk7XHJcblx0XHRyZXR1cm4gcmVzdWx0LnNldChmaW5hbEVudGl0eS5pZCwgZmluYWxFbnRpdHkpO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBhZGRCYXNpY0RhdGEoZW50aXRpZXM6IE1hcDxudW1iZXIsIEVudGl0eT4pOiBNYXA8bnVtYmVyLCBFbnRpdHk+IHtcclxuXHRcdHJldHVybiBlbnRpdGllc1xyXG5cdFx0XHQubWFwKCh2YWx1ZTogRW50aXR5KSA9PiB7XHJcblx0XHRcdFx0aWYgKCF2YWx1ZS5jYXJkSUQpIHtcclxuXHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Y29uc3QgY2FyZCA9IHRoaXMuYWxsQ2FyZHMuZ2V0Q2FyZCh2YWx1ZS5jYXJkSUQpO1xyXG5cdFx0XHRcdGxldCBuZXdUYWdzOiB7IFt0YWdOYW1lOiBzdHJpbmddOiBudW1iZXIgfSA9IHt9O1xyXG5cdFx0XHRcdGlmIChjYXJkKSB7XHJcblx0XHRcdFx0XHRpZiAoY2FyZC50eXBlID09PSAnU3BlbGwnICYmICF2YWx1ZS5nZXRUYWcoR2FtZVRhZy5DQVJEVFlQRSkpIHtcclxuXHRcdFx0XHRcdFx0bmV3VGFncyA9IHsgLi4udmFsdWUudGFncywgW0dhbWVUYWdbR2FtZVRhZy5DQVJEVFlQRV1dOiBDYXJkVHlwZS5TUEVMTCB9O1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKGNhcmQudHlwZSA9PT0gJ0VuY2hhbnRtZW50JyAmJiAhdmFsdWUuZ2V0VGFnKEdhbWVUYWcuQ0FSRFRZUEUpKSB7XHJcblx0XHRcdFx0XHRcdG5ld1RhZ3MgPSB7IC4uLnZhbHVlLnRhZ3MsIFtHYW1lVGFnW0dhbWVUYWcuQ0FSRFRZUEVdXTogQ2FyZFR5cGUuRU5DSEFOVE1FTlQgfTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIHZhbHVlLnVwZGF0ZSh7IHRhZ3M6IG5ld1RhZ3MgfSk7XHJcblx0XHRcdH0pXHJcblx0XHRcdC50b01hcCgpO1xyXG5cdH1cclxufVxyXG4iXX0=