bp-space-invaders
Version:
The BP Space Invaders Game
239 lines • 35.1 kB
JavaScript
import { Alien1Class } from '../aliens/alien-1/alien-1.class';
import { Alien2Class } from '../aliens/alien-2/alien-2.class';
import { Alien3Class } from '../aliens/alien-3/alien-3.class';
import { Alien4Class } from '../aliens/alien-4/alien-4.class';
import { Alien5Class } from '../aliens/alien-5/alien-5.class';
import { Alien6Class } from '../aliens/alien-6/alien-6.class';
import { AlienBoss2Class } from '../aliens/alien-boss-2/alien-boss-2.class';
import { AssetClass } from '../asset/asset.class';
import { AssetAlignVerticalEnum } from '../asset/enum/asset-align-vertical.enum';
import { AssetAlignEnum } from '../asset/enum/asset-align.enum';
import { ObservableTypeEnum } from '../enum/observable-type.enum';
import { ALIEN_COLUMNS, ALIEN_ROWS } from '../gameboard/gameboard-constants';
export class InvasionService extends AssetClass {
constructor(gameService, ctx, boundary) {
super(gameService, ctx, boundary, 0);
this.aliens = [];
this.isAlienCreepLeft = true;
this.xAlienDelta = -10;
this.isBossing = false;
this.displayElapseTime = 0;
this.isGameStarted = false;
this.setup();
this.gameService.getMasterObservable().subscribe((resultModel) => {
if (resultModel.type === ObservableTypeEnum.gameStarted) {
this.isGameStarted = resultModel.booleanData;
if (resultModel.booleanData === false) {
this.alienBoss.isDestroyed = true;
this.isBossing = false;
}
}
else if (resultModel.type === ObservableTypeEnum.gamePaused && !resultModel.booleanData) {
this.setAlienBossDisplayElapseTime();
}
else if (resultModel.type === ObservableTypeEnum.alienBossDestroyed) {
this.toggleScore(true);
this.isBossing = false;
this.alienBoss.isDestroyed = true;
this.setAlienBossDisplayElapseTime();
}
else if (resultModel.type === ObservableTypeEnum.alienDestroyed) {
this.aliens[resultModel.numberData].isDestroyed = true;
this.aliens[resultModel.numberData].canFireWeapon = false;
this.findNextBombingAlien(resultModel.numberData);
}
});
}
spawn() {
this.assetAnimation = [[0]];
this.engineAnimation = [];
super.spawn();
}
setup() {
let alienRowCounter = 0;
Array(ALIEN_ROWS)
.fill(0)
.map(() => {
Array(ALIEN_COLUMNS)
.fill(0)
.map(() => {
if (alienRowCounter === 1) {
this.aliens.push(new Alien2Class(this.gameService, this.ctx, this.boundarySetup, this.aliens.length));
}
else if (alienRowCounter === 2) {
this.aliens.push(new Alien3Class(this.gameService, this.ctx, this.boundarySetup, this.aliens.length));
}
else if (alienRowCounter === 3) {
this.aliens.push(new Alien4Class(this.gameService, this.ctx, this.boundarySetup, this.aliens.length));
}
else if (alienRowCounter === 4) {
this.aliens.push(new Alien5Class(this.gameService, this.ctx, this.boundarySetup, this.aliens.length));
}
else if (alienRowCounter === 5) {
this.aliens.push(new Alien6Class(this.gameService, this.ctx, this.boundarySetup, this.aliens.length));
}
else {
this.aliens.push(new Alien1Class(this.gameService, this.ctx, this.boundarySetup, this.aliens.length));
}
});
alienRowCounter++;
});
this.alienBoss = new AlienBoss2Class(this.gameService, this.ctx, {
x: this.boundarySetup.x - 15,
y: 0,
height: 20,
width: this.boundarySetup.width + 20
}, 0);
this.aliens.push(this.alienBoss);
}
toggleScore(displayScore) {
this.gameService.emitMasterObservableEvent({
type: ObservableTypeEnum.displayScore,
booleanData: displayScore
});
}
findNextBombingAlien(alienPosition) {
const alienColumnIndex = alienPosition % ALIEN_COLUMNS;
const startingPosition = this.aliens.length - 1 - (ALIEN_COLUMNS - alienColumnIndex);
for (let index = startingPosition; index > 0; index -= ALIEN_COLUMNS) {
if (!this.aliens[index].isDestroyed) {
this.aliens[index].canFireWeapon = true;
return;
}
}
}
aliensDestroyed() {
return this.getActiveAliens().length === 0;
}
setupInvasion(yStart) {
const xStart = 60;
const xSpacer = 24;
const ySpacer = 20;
let xValue = 0;
let yValue = 0;
this.aliens.map((alien) => {
alien.isDestroyed = false;
alien.move({
x: xValue++ * xSpacer + xStart,
y: yValue * ySpacer + yStart
});
alien.canFireWeapon = false;
if (yValue === ALIEN_ROWS - 1) {
alien.canFireWeapon = true;
}
if (xValue % ALIEN_COLUMNS === 0) {
yValue++;
xValue = 0;
}
});
const asset = this.alienBoss.positionAsset(AssetAlignEnum.right, AssetAlignVerticalEnum.top);
this.alienBoss.move(asset);
}
splat() {
let isGameOver = false;
this.aliens
.filter((alien) => !alien.isDestroyed)
.map((alien) => {
if (alien.y + alien.getAssetHeight() >= this.boundary.floor) {
isGameOver = true;
}
});
return isGameOver;
}
getAllActiveAliens() {
return this.aliens.filter((alien) => alien.isDestroyed === false);
}
getActiveAliens() {
return this.aliens.filter((alien) => alien.isDestroyed === false && alien.isAlien());
}
increaseInvasionSpeed(creepSpeed) {
const totalAliens = this.getActiveAliens().length;
if (totalAliens < 20 && totalAliens > 15 && creepSpeed < 2) {
return true;
}
else if (totalAliens < 15 && totalAliens > 10 && creepSpeed < 3) {
return true;
}
else if (totalAliens < 10 && totalAliens > 5 && creepSpeed < 4) {
return true;
}
else if (totalAliens < 4 && totalAliens > 1 && creepSpeed < 5) {
return true;
}
else if (totalAliens === 1 && creepSpeed < 6) {
return true;
}
return false;
}
dropAliens() {
this.isAlienCreepLeft = !this.isAlienCreepLeft;
let lastAlien;
this.getActiveAliens().map((alien) => {
alien.move({
x: alien.x,
y: (alien.y += 10)
});
lastAlien = alien;
});
this.gameService.emitMasterObservableEvent({
type: ObservableTypeEnum.alienDrop,
numberData: lastAlien.y + lastAlien.getAssetHeight()
});
}
moveAliens() {
let creepSucceeded = true;
this.getActiveAliens().map((alien) => {
creepSucceeded =
creepSucceeded &&
alien.creep({
x: alien.x + this.xAlienDelta,
y: alien.y
});
});
if (creepSucceeded) {
this.getActiveAliens().map((alien) => {
alien.move({
x: alien.x + this.xAlienDelta,
y: alien.y
});
});
}
else {
this.dropAliens();
}
this.xAlienDelta = this.isAlienCreepLeft ? -10 : 10;
}
animate(now, creepSpeedLevel) {
this.assetTimer.elapsed = now - this.assetTimer.start;
if (this.assetTimer.elapsed > creepSpeedLevel) {
this.assetTimer.start = now;
this.moveAliens();
}
if (this.isBossing) {
this.alienBoss.animate(now);
}
this.getActiveAliens().map((alien) => {
alien.animate(now);
});
}
resetAlienCreep() {
this.toggleScore(true);
this.isBossing = false;
this.xAlienDelta = -10;
this.isAlienCreepLeft = true;
this.setAlienBossDisplayElapseTime();
}
setAlienBossDisplayElapseTime() {
clearTimeout(this.timerId);
if (!this.isGameStarted || this.isBossing) {
return;
}
this.displayElapseTime = Math.floor(Math.random() * 20000 + 1000);
this.timerId = window.setTimeout(() => {
this.isBossing = true;
this.toggleScore(false);
this.alienBoss.positionAlienBoss();
}, this.displayElapseTime);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52YXNpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwYWNlLWludmFkZXJzL3NyYy9saWIvc2VydmljZS9pbnZhc2lvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUU1RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDakYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFTN0UsTUFBTSxPQUFPLGVBQWdCLFNBQVEsVUFBVTtJQXlDN0MsWUFBWSxXQUF3QixFQUFFLEdBQTZCLEVBQUUsUUFBNEI7UUFDL0YsS0FBSyxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJ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QUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUtPLDZCQUE2QjtRQUduQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTNCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDekMsT0FBTztTQUNSO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQztRQUVsRSxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3BDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3JDLENBQUMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUM3QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBbGllbjFDbGFzcyB9IGZyb20gJy4uL2FsaWVucy9hbGllbi0xL2FsaWVuLTEuY2xhc3MnO1xuaW1wb3J0IHsgQWxpZW4yQ2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tMi9hbGllbi0yLmNsYXNzJztcbmltcG9ydCB7IEFsaWVuM0NsYXNzIH0gZnJvbSAnLi4vYWxpZW5zL2FsaWVuLTMvYWxpZW4tMy5jbGFzcyc7XG5pbXBvcnQgeyBBbGllbjRDbGFzcyB9IGZyb20gJy4uL2FsaWVucy9hbGllbi00L2FsaWVuLTQuY2xhc3MnO1xuaW1wb3J0IHsgQWxpZW41Q2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tNS9hbGllbi01LmNsYXNzJztcbmltcG9ydCB7IEFsaWVuNkNsYXNzIH0gZnJvbSAnLi4vYWxpZW5zL2FsaWVuLTYvYWxpZW4tNi5jbGFzcyc7XG5pbXBvcnQgeyBBbGllbkJvc3MyQ2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tYm9zcy0yL2FsaWVuLWJvc3MtMi5jbGFzcyc7XG5pbXBvcnQgeyBBbGllbkNsYXNzIH0gZnJvbSAnLi4vYWxpZW5zL2FsaWVuL2FsaWVuLmNsYXNzJztcbmltcG9ydCB7IEFzc2V0Q2xhc3MgfSBmcm9tICcuLi9hc3NldC9hc3NldC5jbGFzcyc7XG5pbXBvcnQgeyBBc3NldEFsaWduVmVydGljYWxFbnVtIH0gZnJvbSAnLi4vYXNzZXQvZW51bS9hc3NldC1hbGlnbi12ZXJ0aWNhbC5lbnVtJztcbmltcG9ydCB7IEFzc2V0QWxpZ25FbnVtIH0gZnJvbSAnLi4vYXNzZXQvZW51bS9hc3NldC1hbGlnbi5lbnVtJztcbmltcG9ydCB7IE9ic2VydmFibGVUeXBlRW51bSB9IGZyb20gJy4uL2VudW0vb2JzZXJ2YWJsZS10eXBlLmVudW0nO1xuaW1wb3J0IHsgQUxJRU5fQ09MVU1OUywgQUxJRU5fUk9XUyB9IGZyb20gJy4uL2dhbWVib2FyZC9nYW1lYm9hcmQtY29uc3RhbnRzJztcbmltcG9ydCB7IElBc3NldCB9IGZyb20gJy4uL2ludGVyZmFjZS9hc3NldC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQm91bmRhcnlTZXR1cE1vZGVsIH0gZnJvbSAnLi4vbW9kZWwvYm91bmRhcnktc2V0Lm1vZGVsJztcbmltcG9ydCB7IE9ic2VydmFibGVNb2RlbCB9IGZyb20gJy4uL21vZGVsL29ic2VydmFibGUubW9kZWwnO1xuaW1wb3J0IHsgR2FtZVNlcnZpY2UgfSBmcm9tICcuL2dhbWUuc2VydmljZSc7XG5cbi8qKlxuICogVGhlIGludmFzaW9uIHNlcnZpY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEludmFzaW9uU2VydmljZSBleHRlbmRzIEFzc2V0Q2xhc3Mge1xuICAvKipcbiAgICogVGhlIGFsaWVuIGJvc3NcbiAgICovXG4gIHByaXZhdGUgYWxpZW5Cb3NzOiBBbGllbkJvc3MyQ2xhc3M7XG4gIC8qKlxuICAgKiBUaGUgYWxpZW5zXG4gICAqL1xuICBwcml2YXRlIGFsaWVuczogQWxpZW5DbGFzc1tdO1xuICAvKipcbiAgICogQWxpZW4gQ3JlZXAgTW92aW5nIExlZnRcbiAgICovXG4gIHByaXZhdGUgaXNBbGllbkNyZWVwTGVmdDogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRoZSB4QWxpZW5EZWx0YSBtb3ZlbWVudFxuICAgKi9cbiAgcHJpdmF0ZSB4QWxpZW5EZWx0YTogbnVtYmVyO1xuICAvKipcbiAgICogSXMgQm9zc2luZ1xuICAgKi9cbiAgcHJpdmF0ZSBpc0Jvc3Npbmc6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUaGUgdGltZW91dCB0aW1lclxuICAgKi9cbiAgcHJpdmF0ZSB0aW1lcklkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZGlzcGxheSB0aW1lciBlbGFwc2UgdGltZVxuICAgKi9cbiAgcHJpdmF0ZSBkaXNwbGF5RWxhcHNlVGltZTogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGdhbWUgc3RhcnRlZFxuICAgKi9cbiAgcHJpdmF0ZSBpc0dhbWVTdGFydGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uc3RydWN0b3JcbiAgICpcbiAgICogQHBhcmFtIGdhbWVTZXJ2aWNlIFRoZSBHYW1lU2VydmljZVxuICAgKiBAcGFyYW0gY3R4IFRoZSBDVFhcbiAgICogQHBhcmFtIGJvdW5kYXJ5U2V0VXAgVGhlIEJvdW5kYXJ5IFNldCB1cFxuICAgKi9cbiAgY29uc3RydWN0b3IoZ2FtZVNlcnZpY2U6IEdhbWVTZXJ2aWNlLCBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgYm91bmRhcnk6IEJvdW5kYXJ5U2V0dXBNb2RlbCkge1xuICAgIHN1cGVyKGdhbWVTZXJ2aWNlLCBjdHgsIGJvdW5kYXJ5LCAwKTtcbiAgICB0aGlzLmFsaWVucyA9IFtdO1xuICAgIHRoaXMuaXNBbGllbkNyZWVwTGVmdCA9IHRydWU7XG4gICAgdGhpcy54QWxpZW5EZWx0YSA9IC0xMDtcbiAgICB0aGlzLmlzQm9zc2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZGlzcGxheUVsYXBzZVRpbWUgPSAwO1xuICAgIHRoaXMuaXNHYW1lU3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5zZXR1cCgpO1xuXG4gICAgdGhpcy5nYW1lU2VydmljZS5nZXRNYXN0ZXJPYnNlcnZhYmxlKCkuc3Vic2NyaWJlKChyZXN1bHRNb2RlbDogT2JzZXJ2YWJsZU1vZGVsKSA9PiB7XG4gICAgICBpZiAocmVzdWx0TW9kZWwudHlwZSA9PT0gT2JzZXJ2YWJsZVR5cGVFbnVtLmdhbWVTdGFydGVkKSB7XG4gICAgICAgIHRoaXMuaXNHYW1lU3RhcnRlZCA9IHJlc3VsdE1vZGVsLmJvb2xlYW5EYXRhO1xuICAgICAgICBpZiAocmVzdWx0TW9kZWwuYm9vbGVhbkRhdGEgPT09IGZhbHNlKSB7XG4gICAgICAgICAgdGhpcy5hbGllbkJvc3MuaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuaXNCb3NzaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0TW9kZWwudHlwZSA9PT0gT2JzZXJ2YWJsZVR5cGVFbnVtLmdhbWVQYXVzZWQgJiYgIXJlc3VsdE1vZGVsLmJvb2xlYW5EYXRhKSB7XG4gICAgICAgIHRoaXMuc2V0QWxpZW5Cb3NzRGlzcGxheUVsYXBzZVRpbWUoKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0TW9kZWwudHlwZSA9PT0gT2JzZXJ2YWJsZVR5cGVFbnVtLmFsaWVuQm9zc0Rlc3Ryb3llZCkge1xuICAgICAgICB0aGlzLnRvZ2dsZVNjb3JlKHRydWUpO1xuICAgICAgICB0aGlzLmlzQm9zc2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFsaWVuQm9zcy5pc0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgICAgIHRoaXMuc2V0QWxpZW5Cb3NzRGlzcGxheUVsYXBzZVRpbWUoKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0TW9kZWwudHlwZSA9PT0gT2JzZXJ2YWJsZVR5cGVFbnVtLmFsaWVuRGVzdHJveWVkKSB7XG4gICAgICAgIHRoaXMuYWxpZW5zW3Jlc3VsdE1vZGVsLm51bWJlckRhdGFdLmlzRGVzdHJveWVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5hbGllbnNbcmVzdWx0TW9kZWwubnVtYmVyRGF0YV0uY2FuRmlyZVdlYXBvbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpbmROZXh0Qm9tYmluZ0FsaWVuKHJlc3VsdE1vZGVsLm51bWJlckRhdGEpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwYXduIHRoZSBhbGllblxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHNwYXduKCk6IHZvaWQge1xuICAgIHRoaXMuYXNzZXRBbmltYXRpb24gPSBbWzBdXTtcbiAgICB0aGlzLmVuZ2luZUFuaW1hdGlvbiA9IFtdO1xuICAgIHN1cGVyLnNwYXduKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYm9hcmRcbiAgICovXG4gIHByaXZhdGUgc2V0dXAoKTogdm9pZCB7XG4gICAgbGV0IGFsaWVuUm93Q291bnRlciA9IDA7XG5cbiAgICBBcnJheShBTElFTl9ST1dTKVxuICAgICAgLmZpbGwoMClcbiAgICAgIC5tYXAoKCkgPT4ge1xuICAgICAgICBBcnJheShBTElFTl9DT0xVTU5TKVxuICAgICAgICAgIC5maWxsKDApXG4gICAgICAgICAgLm1hcCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYWxpZW5Sb3dDb3VudGVyID09PSAxKSB7XG4gICAgICAgICAgICAgIHRoaXMuYWxpZW5zLnB1c2gobmV3IEFsaWVuMkNsYXNzKHRoaXMuZ2FtZVNlcnZpY2UsIHRoaXMuY3R4LCB0aGlzLmJvdW5kYXJ5U2V0dXAsIHRoaXMuYWxpZW5zLmxlbmd0aCkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhbGllblJvd0NvdW50ZXIgPT09IDIpIHtcbiAgICAgICAgICAgICAgdGhpcy5hbGllbnMucHVzaChuZXcgQWxpZW4zQ2xhc3ModGhpcy5nYW1lU2VydmljZSwgdGhpcy5jdHgsIHRoaXMuYm91bmRhcnlTZXR1cCwgdGhpcy5hbGllbnMubGVuZ3RoKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFsaWVuUm93Q291bnRlciA9PT0gMykge1xuICAgICAgICAgICAgICB0aGlzLmFsaWVucy5wdXNoKG5ldyBBbGllbjRDbGFzcyh0aGlzLmdhbWVTZXJ2aWNlLCB0aGlzLmN0eCwgdGhpcy5ib3VuZGFyeVNldHVwLCB0aGlzLmFsaWVucy5sZW5ndGgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYWxpZW5Sb3dDb3VudGVyID09PSA0KSB7XG4gICAgICAgICAgICAgIHRoaXMuYWxpZW5zLnB1c2gobmV3IEFsaWVuNUNsYXNzKHRoaXMuZ2FtZVNlcnZpY2UsIHRoaXMuY3R4LCB0aGlzLmJvdW5kYXJ5U2V0dXAsIHRoaXMuYWxpZW5zLmxlbmd0aCkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhbGllblJvd0NvdW50ZXIgPT09IDUpIHtcbiAgICAgICAgICAgICAgdGhpcy5hbGllbnMucHVzaChuZXcgQWxpZW42Q2xhc3ModGhpcy5nYW1lU2VydmljZSwgdGhpcy5jdHgsIHRoaXMuYm91bmRhcnlTZXR1cCwgdGhpcy5hbGllbnMubGVuZ3RoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmFsaWVucy5wdXNoKG5ldyBBbGllbjFDbGFzcyh0aGlzLmdhbWVTZXJ2aWNlLCB0aGlzLmN0eCwgdGhpcy5ib3VuZGFyeVNldHVwLCB0aGlzLmFsaWVucy5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgYWxpZW5Sb3dDb3VudGVyKys7XG4gICAgICB9KTtcblxuICAgIHRoaXMuYWxpZW5Cb3NzID0gbmV3IEFsaWVuQm9zczJDbGFzcyhcbiAgICAgIHRoaXMuZ2FtZVNlcnZpY2UsXG4gICAgICB0aGlzLmN0eCxcbiAgICAgIHtcbiAgICAgICAgeDogdGhpcy5ib3VuZGFyeVNldHVwLnggLSAxNSxcbiAgICAgICAgeTogMCxcbiAgICAgICAgaGVpZ2h0OiAyMCxcbiAgICAgICAgd2lkdGg6IHRoaXMuYm91bmRhcnlTZXR1cC53aWR0aCArIDIwXG4gICAgICB9IGFzIEJvdW5kYXJ5U2V0dXBNb2RlbCxcbiAgICAgIDBcbiAgICApO1xuXG4gICAgdGhpcy5hbGllbnMucHVzaCh0aGlzLmFsaWVuQm9zcyk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlIFRoZSBTY29yZVxuICAgKiBAcGFyYW0gZGlzcGxheVNjb3JlIFRvIGRpc3BsYXkgb3Igbm90IGRpc3BhbHlcbiAgICovXG4gIHByaXZhdGUgdG9nZ2xlU2NvcmUoZGlzcGxheVNjb3JlOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5nYW1lU2VydmljZS5lbWl0TWFzdGVyT2JzZXJ2YWJsZUV2ZW50KHtcbiAgICAgIHR5cGU6IE9ic2VydmFibGVUeXBlRW51bS5kaXNwbGF5U2NvcmUsXG4gICAgICBib29sZWFuRGF0YTogZGlzcGxheVNjb3JlXG4gICAgfSBhcyBPYnNlcnZhYmxlTW9kZWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgdGhlIG5leHQgYWxpZW4gdGhhdCBjYW4gYm9tYlxuICAgKlxuICAgKiBAcGFyYW0gYWxpZW5Qb3NpdGlvbiBUaGUgaW5kZXggb2YgdGhlIGFsaWVuXG4gICAqL1xuICBwcml2YXRlIGZpbmROZXh0Qm9tYmluZ0FsaWVuKGFsaWVuUG9zaXRpb246IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGFsaWVuQ29sdW1uSW5kZXggPSBhbGllblBvc2l0aW9uICUgQUxJRU5fQ09MVU1OUztcblxuICAgIGNvbnN0IHN0YXJ0aW5nUG9zaXRpb24gPSB0aGlzLmFsaWVucy5sZW5ndGggLSAxIC0gKEFMSUVOX0NPTFVNTlMgLSBhbGllbkNvbHVtbkluZGV4KTtcblxuICAgIGZvciAobGV0IGluZGV4ID0gc3RhcnRpbmdQb3NpdGlvbjsgaW5kZXggPiAwOyBpbmRleCAtPSBBTElFTl9DT0xVTU5TKSB7XG4gICAgICBpZiAoIXRoaXMuYWxpZW5zW2luZGV4XS5pc0Rlc3Ryb3llZCkge1xuICAgICAgICB0aGlzLmFsaWVuc1tpbmRleF0uY2FuRmlyZVdlYXBvbiA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IGlmIHRoZSBhbGllbnMgYXJlIGRlc3Ryb3llZFxuICAgKi9cbiAgYWxpZW5zRGVzdHJveWVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdldEFjdGl2ZUFsaWVucygpLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBib2FyZFxuICAgKi9cbiAgcHVibGljIHNldHVwSW52YXNpb24oeVN0YXJ0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB4U3RhcnQgPSA2MDtcbiAgICBjb25zdCB4U3BhY2VyID0gMjQ7XG4gICAgY29uc3QgeVNwYWNlciA9IDIwO1xuICAgIGxldCB4VmFsdWUgPSAwO1xuICAgIGxldCB5VmFsdWUgPSAwO1xuXG4gICAgdGhpcy5hbGllbnMubWFwKChhbGllbjogQWxpZW5DbGFzcykgPT4ge1xuICAgICAgYWxpZW4uaXNEZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgIGFsaWVuLm1vdmUoe1xuICAgICAgICB4OiB4VmFsdWUrKyAqIHhTcGFjZXIgKyB4U3RhcnQsXG4gICAgICAgIHk6IHlWYWx1ZSAqIHlTcGFjZXIgKyB5U3RhcnRcbiAgICAgIH0gYXMgSUFzc2V0KTtcblxuICAgICAgYWxpZW4uY2FuRmlyZVdlYXBvbiA9IGZhbHNlO1xuXG4gICAgICBpZiAoeVZhbHVlID09PSBBTElFTl9ST1dTIC0gMSkge1xuICAgICAgICBhbGllbi5jYW5GaXJlV2VhcG9uID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHhWYWx1ZSAlIEFMSUVOX0NPTFVNTlMgPT09IDApIHtcbiAgICAgICAgeVZhbHVlKys7XG4gICAgICAgIHhWYWx1ZSA9IDA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBhc3NldCA9IHRoaXMuYWxpZW5Cb3NzLnBvc2l0aW9uQXNzZXQoQXNzZXRBbGlnbkVudW0ucmlnaHQsIEFzc2V0QWxpZ25WZXJ0aWNhbEVudW0udG9wKTtcbiAgICB0aGlzLmFsaWVuQm9zcy5tb3ZlKGFzc2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYWxpZW5zIGhhdmUgaGl0IHRoZSBib3R0b21cbiAgICovXG4gIHB1YmxpYyBzcGxhdCgpOiBib29sZWFuIHtcbiAgICBsZXQgaXNHYW1lT3ZlciA9IGZhbHNlO1xuICAgIHRoaXMuYWxpZW5zXG4gICAgICAuZmlsdGVyKChhbGllbjogQWxpZW5DbGFzcykgPT4gIWFsaWVuLmlzRGVzdHJveWVkKVxuICAgICAgLm1hcCgoYWxpZW46IEFsaWVuQ2xhc3MpID0+IHtcbiAgICAgICAgaWYgKGFsaWVuLnkgKyBhbGllbi5nZXRBc3NldEhlaWdodCgpID49IHRoaXMuYm91bmRhcnkuZmxvb3IpIHtcbiAgICAgICAgICBpc0dhbWVPdmVyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICByZXR1cm4gaXNHYW1lT3ZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgQWxsIEFjdGl2ZSBBbGllbnNcbiAgICovXG4gIHB1YmxpYyBnZXRBbGxBY3RpdmVBbGllbnMoKTogQWxpZW5DbGFzc1tdIHtcbiAgICByZXR1cm4gdGhpcy5hbGllbnMuZmlsdGVyKChhbGllbjogQWxpZW5DbGFzcykgPT4gYWxpZW4uaXNEZXN0cm95ZWQgPT09IGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgQWxsIEFjdGl2ZSBBbGllbnNcbiAgICovXG4gIHByaXZhdGUgZ2V0QWN0aXZlQWxpZW5zKCk6IEFsaWVuQ2xhc3NbXSB7XG4gICAgcmV0dXJuIHRoaXMuYWxpZW5zLmZpbHRlcigoYWxpZW46IEFsaWVuQ2xhc3MpID0+IGFsaWVuLmlzRGVzdHJveWVkID09PSBmYWxzZSAmJiBhbGllbi5pc0FsaWVuKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBBbGwgQWN0aXZlIEFsaWVuc1xuICAgKlxuICAgKiBAcGFyYW0gY3JlZXBTcGVlZCBUaGUgY3VycmVudCBjcmVlcCBzcGVlZFxuICAgKi9cbiAgcHVibGljIGluY3JlYXNlSW52YXNpb25TcGVlZChjcmVlcFNwZWVkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCB0b3RhbEFsaWVucyA9IHRoaXMuZ2V0QWN0aXZlQWxpZW5zKCkubGVuZ3RoO1xuXG4gICAgaWYgKHRvdGFsQWxpZW5zIDwgMjAgJiYgdG90YWxBbGllbnMgPiAxNSAmJiBjcmVlcFNwZWVkIDwgMikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh0b3RhbEFsaWVucyA8IDE1ICYmIHRvdGFsQWxpZW5zID4gMTAgJiYgY3JlZXBTcGVlZCA8IDMpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAodG90YWxBbGllbnMgPCAxMCAmJiB0b3RhbEFsaWVucyA+IDUgJiYgY3JlZXBTcGVlZCA8IDQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAodG90YWxBbGllbnMgPCA0ICYmIHRvdGFsQWxpZW5zID4gMSAmJiBjcmVlcFNwZWVkIDwgNSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh0b3RhbEFsaWVucyA9PT0gMSAmJiBjcmVlcFNwZWVkIDwgNikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIERyb3AgQWxsIHRoZSBhbGllbnNcbiAgICovXG4gIHByaXZhdGUgZHJvcEFsaWVucygpOiB2b2lkIHtcbiAgICB0aGlzLmlzQWxpZW5DcmVlcExlZnQgPSAhdGhpcy5pc0FsaWVuQ3JlZXBMZWZ0O1xuICAgIGxldCBsYXN0QWxpZW46IEFsaWVuQ2xhc3M7XG4gICAgdGhpcy5nZXRBY3RpdmVBbGllbnMoKS5tYXAoKGFsaWVuOiBBbGllbkNsYXNzKSA9PiB7XG4gICAgICBhbGllbi5tb3ZlKHtcbiAgICAgICAgeDogYWxpZW4ueCxcbiAgICAgICAgeTogKGFsaWVuLnkgKz0gMTApXG4gICAgICB9IGFzIElBc3NldCk7XG4gICAgICBsYXN0QWxpZW4gPSBhbGllbjtcbiAgICB9KTtcblxuICAgIHRoaXMuZ2FtZVNlcnZpY2UuZW1pdE1hc3Rlck9ic2VydmFibGVFdmVudCh7XG4gICAgICB0eXBlOiBPYnNlcnZhYmxlVHlwZUVudW0uYWxpZW5Ecm9wLFxuICAgICAgbnVtYmVyRGF0YTogbGFzdEFsaWVuLnkgKyBsYXN0QWxpZW4uZ2V0QXNzZXRIZWlnaHQoKVxuICAgIH0gYXMgT2JzZXJ2YWJsZU1vZGVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIEFsbCB0aGUgYWxpZW5zXG4gICAqL1xuICBwcml2YXRlIG1vdmVBbGllbnMoKTogdm9pZCB7XG4gICAgbGV0IGNyZWVwU3VjY2VlZGVkID0gdHJ1ZTtcbiAgICB0aGlzLmdldEFjdGl2ZUFsaWVucygpLm1hcCgoYWxpZW46IEFsaWVuQ2xhc3MpID0+IHtcbiAgICAgIGNyZWVwU3VjY2VlZGVkID1cbiAgICAgICAgY3JlZXBTdWNjZWVkZWQgJiZcbiAgICAgICAgYWxpZW4uY3JlZXAoe1xuICAgICAgICAgIHg6IGFsaWVuLnggKyB0aGlzLnhBbGllbkRlbHRhLFxuICAgICAgICAgIHk6IGFsaWVuLnlcbiAgICAgICAgfSBhcyBJQXNzZXQpO1xuICAgIH0pO1xuXG4gICAgaWYgKGNyZWVwU3VjY2VlZGVkKSB7XG4gICAgICB0aGlzLmdldEFjdGl2ZUFsaWVucygpLm1hcCgoYWxpZW46IEFsaWVuQ2xhc3MpID0+IHtcbiAgICAgICAgYWxpZW4ubW92ZSh7XG4gICAgICAgICAgeDogYWxpZW4ueCArIHRoaXMueEFsaWVuRGVsdGEsXG4gICAgICAgICAgeTogYWxpZW4ueVxuICAgICAgICB9IGFzIElBc3NldCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kcm9wQWxpZW5zKCk7XG4gICAgfVxuXG4gICAgdGhpcy54QWxpZW5EZWx0YSA9IHRoaXMuaXNBbGllbkNyZWVwTGVmdCA/IC0xMCA6IDEwO1xuICB9XG5cbiAgLyoqXG4gICAqIEFuaW1hdGUgdGhlIGludmFzaW9uXG4gICAqIEBwYXJhbSBub3cgVGhlIGN1cnJlbnQgdGltZVxuICAgKiBAcGFyYW0gY3JlZXBTcGVlZExldmVsIFRoZSBjdXJyZW50IGNyZWVwIHRpbWVyXG4gICAqL1xuICBwdWJsaWMgYW5pbWF0ZShub3c6IG51bWJlciwgY3JlZXBTcGVlZExldmVsOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmFzc2V0VGltZXIuZWxhcHNlZCA9IG5vdyAtIHRoaXMuYXNzZXRUaW1lci5zdGFydDtcblxuICAgIGlmICh0aGlzLmFzc2V0VGltZXIuZWxhcHNlZCA+IGNyZWVwU3BlZWRMZXZlbCkge1xuICAgICAgdGhpcy5hc3NldFRpbWVyLnN0YXJ0ID0gbm93O1xuICAgICAgdGhpcy5tb3ZlQWxpZW5zKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNCb3NzaW5nKSB7XG4gICAgICB0aGlzLmFsaWVuQm9zcy5hbmltYXRlKG5vdyk7XG4gICAgfVxuXG4gICAgdGhpcy5nZXRBY3RpdmVBbGllbnMoKS5tYXAoKGFsaWVuOiBBbGllbkNsYXNzKSA9PiB7XG4gICAgICBhbGllbi5hbmltYXRlKG5vdyk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgdGhlIEFsaWVuIENyZWVwXG4gICAqL1xuICBwdWJsaWMgcmVzZXRBbGllbkNyZWVwKCk6IHZvaWQge1xuICAgIHRoaXMudG9nZ2xlU2NvcmUodHJ1ZSk7XG4gICAgdGhpcy5pc0Jvc3NpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnhBbGllbkRlbHRhID0gLTEwO1xuICAgIHRoaXMuaXNBbGllbkNyZWVwTGVmdCA9IHRydWU7XG4gICAgdGhpcy5zZXRBbGllbkJvc3NEaXNwbGF5RWxhcHNlVGltZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgZGlzcGxheSBlbGFwc2UgdGltZVxuICAgKi9cbiAgcHJpdmF0ZSBzZXRBbGllbkJvc3NEaXNwbGF5RWxhcHNlVGltZSgpOiB2b2lkIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgKi9cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXJJZCk7XG5cbiAgICBpZiAoIXRoaXMuaXNHYW1lU3RhcnRlZCB8fCB0aGlzLmlzQm9zc2luZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZGlzcGxheUVsYXBzZVRpbWUgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyMDAwMCArIDEwMDApO1xuXG4gICAgdGhpcy50aW1lcklkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5pc0Jvc3NpbmcgPSB0cnVlO1xuICAgICAgdGhpcy50b2dnbGVTY29yZShmYWxzZSk7XG4gICAgICB0aGlzLmFsaWVuQm9zcy5wb3NpdGlvbkFsaWVuQm9zcygpO1xuICAgIH0sIHRoaXMuZGlzcGxheUVsYXBzZVRpbWUpO1xuICB9XG59XG4iXX0=