ngx-glide
Version:
Angular wrapper component of Glide carousel library
350 lines • 50.8 kB
JavaScript
import { isPlatformBrowser, NgForOf, NgIf, NgTemplateOutlet, } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, Output, PLATFORM_ID, ViewChild, } from '@angular/core';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import Glide from '@glidejs/glide';
import { defaultExtraSettings, defaultSettings } from './shared';
import * as i0 from "@angular/core";
// noinspection TypeScriptFieldCanBeMadeReadonly,DuplicatedCode
export class NgxGlideComponent {
constructor(changeDetectorRef, platformId) {
this.changeDetectorRef = changeDetectorRef;
this.platformId = platformId;
this.showArrows = defaultExtraSettings.showArrows;
this.showBullets = defaultExtraSettings.showBullets;
this.arrowLeftLabel = defaultExtraSettings.arrowLeftLabel;
this.arrowLeftTemplate = null;
this.arrowRightLabel = defaultExtraSettings.arrowRightLabel;
this.arrowRightTemplate = null;
this.listenToEvents = defaultExtraSettings.listenToEvents;
this.glideBullets = [];
this.type = defaultSettings.type;
this.startAt = defaultSettings.startAt;
this.perView = defaultSettings.perView;
this.focusAt = defaultSettings.focusAt;
this.gap = defaultSettings.gap;
this.autoplay = defaultSettings.autoplay;
this.hoverpause = defaultSettings.hoverpause;
this.keyboard = defaultSettings.keyboard;
this.bound = defaultSettings.bound;
this.swipeThreshold = defaultSettings.swipeThreshold;
this.dragThreshold = defaultSettings.dragThreshold;
this.perTouch = defaultSettings.perTouch;
this.touchRatio = defaultSettings.touchRatio;
this.touchAngle = defaultSettings.touchAngle;
this.animationDuration = defaultSettings.animationDuration;
this.rewind = defaultSettings.rewind;
this.rewindDuration = defaultSettings.rewindDuration;
this.animationTimingFunc = defaultSettings.animationTimingFunc;
this.direction = defaultSettings.direction;
this.peek = defaultSettings.peek;
this.breakpoints = defaultSettings.breakpoints;
this.classes = defaultSettings.classes;
this.throttle = defaultSettings.throttle;
this.mountedBefore = new EventEmitter();
this.mountedAfter = new EventEmitter();
this.updated = new EventEmitter();
this.played = new EventEmitter();
this.paused = new EventEmitter();
this.buildedBefore = new EventEmitter();
this.buildedAfter = new EventEmitter();
this.ranBefore = new EventEmitter();
this.ran = new EventEmitter();
this.ranAfter = new EventEmitter();
this.ranOffset = new EventEmitter();
this.runStarted = new EventEmitter();
this.runEnded = new EventEmitter();
this.moved = new EventEmitter();
this.movedAfter = new EventEmitter();
this.resized = new EventEmitter();
this.swipeStarted = new EventEmitter();
this.swipeMoved = new EventEmitter();
this.swipeEnded = new EventEmitter();
this.translateJumped = new EventEmitter();
}
static getGlideUpdateSettings(changes) {
const settings = {};
for (const key in changes) {
if (!Object.prototype.hasOwnProperty.call(changes, key)) {
continue;
}
if (!Object.prototype.hasOwnProperty.call(defaultSettings, key)) {
continue;
}
const change = changes[key];
if (change.previousValue !== change.currentValue) {
settings[key] = change.currentValue;
}
}
return settings;
}
ngOnChanges(changes) {
if (isPlatformBrowser(this.platformId) && changes && this.glide) {
this.update(NgxGlideComponent.getGlideUpdateSettings(changes));
}
}
ngAfterViewInit() {
if (isPlatformBrowser(this.platformId) && Glide) {
this.create();
}
}
ngOnDestroy() {
this.destroy();
}
getStyleDisplay(condition) {
return condition ? 'block' : 'none';
}
getIndex() {
return this.glide && this.glide.index;
}
// noinspection JSUnusedGlobalSymbols
getSettings() {
return this.glide && this.glide.settings;
}
// noinspection JSUnusedGlobalSymbols
getType() {
return this.glide && this.glide.type;
}
// noinspection JSUnusedGlobalSymbols
isDisabled() {
return this.glide && this.glide.disabled;
}
mount() {
if (this.glide) {
this.glide.mount();
}
}
update(settings) {
if (this.glide) {
this.glide.update(settings);
this.changeDetectorRef.detectChanges();
}
}
destroy() {
if (this.glide) {
this.glide.destroy();
}
}
// noinspection JSUnusedGlobalSymbols
go(pattern) {
if (this.glide) {
this.glide.go(pattern);
}
}
pause() {
if (this.glide) {
this.glide.pause();
}
}
play(force) {
if (this.glide) {
if (typeof force === 'number') {
this.glide.play(force);
}
else {
this.glide.play();
}
}
}
// noinspection JSUnusedGlobalSymbols
disable() {
if (this.glide) {
this.glide.disable();
}
}
enable() {
if (this.glide) {
this.glide.enable();
}
}
isType(type) {
return this.glide && this.glide.isType(type);
}
recreate() {
if (this.glide) {
this.destroy();
}
this.create();
}
create() {
this.initGlideBullets();
this.glide = new Glide(this.glideEl?.nativeElement, this.getGlideInitSettings());
this.initGlideEvents();
this.mount();
this.changeDetectorRef.detectChanges();
}
initGlideBullets() {
const glideSlidesNativeElement = this.glideSlidesEl?.nativeElement;
const childrenLength = glideSlidesNativeElement.children.length;
this.glideBullets = [...new Array(childrenLength).keys()];
this.changeDetectorRef.detectChanges();
}
initGlideEvents() {
if (!this.glide || !this.listenToEvents) {
return;
}
this.glide.on('mount.before', () => this.mountedBefore.emit());
this.glide.on('mount.after', () => this.mountedAfter.emit());
this.glide.on('update', () => this.updated.emit());
this.glide.on('play', () => this.played.emit());
this.glide.on('pause', () => this.paused.emit());
this.glide.on('build.before', () => this.buildedBefore.emit());
this.glide.on('build.after', () => this.buildedAfter.emit());
this.glide.on('run.before', (move) => this.ranBefore.emit(move));
this.glide.on('run', (move) => this.ran.emit(move));
this.glide.on('run.after', (move) => this.ranAfter.emit(move));
this.glide.on('run.offset', (move) => this.ranOffset.emit(move));
this.glide.on('run.start', (move) => this.runStarted.emit(move));
this.glide.on('run.end', (move) => this.runEnded.emit(move));
this.glide.on('move', (movement) => this.moved.emit(movement));
this.glide.on('move.after', (movement) => this.movedAfter.emit(movement));
this.glide.on('resize', () => this.resized.emit());
this.glide.on('swipe.start', () => this.swipeStarted.emit());
this.glide.on('swipe.move', () => this.swipeMoved.emit());
this.glide.on('swipe.end', () => this.swipeEnded.emit());
this.glide.on('translate.jump', (movement) => this.translateJumped.emit(movement));
}
getGlideInitSettings() {
return {
type: this.type,
startAt: this.startAt,
perView: this.perView,
focusAt: this.focusAt,
gap: this.gap,
autoplay: this.autoplay,
hoverpause: this.hoverpause,
keyboard: this.keyboard,
bound: this.bound,
swipeThreshold: this.swipeThreshold,
dragThreshold: this.dragThreshold,
perTouch: this.perTouch,
touchRatio: this.touchRatio,
touchAngle: this.touchAngle,
animationDuration: this.animationDuration,
rewind: this.rewind,
rewindDuration: this.rewindDuration,
animationTimingFunc: this.animationTimingFunc,
direction: this.direction,
peek: this.peek,
breakpoints: this.breakpoints,
classes: this.classes,
throttle: this.throttle,
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.6", ngImport: i0, type: NgxGlideComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.6", type: NgxGlideComponent, isStandalone: true, selector: "ngx-glide", inputs: { showArrows: "showArrows", showBullets: "showBullets", arrowLeftLabel: "arrowLeftLabel", arrowLeftTemplate: "arrowLeftTemplate", arrowRightLabel: "arrowRightLabel", arrowRightTemplate: "arrowRightTemplate", listenToEvents: "listenToEvents", type: "type", startAt: "startAt", perView: "perView", focusAt: "focusAt", gap: "gap", autoplay: "autoplay", hoverpause: "hoverpause", keyboard: "keyboard", bound: "bound", swipeThreshold: "swipeThreshold", dragThreshold: "dragThreshold", perTouch: "perTouch", touchRatio: "touchRatio", touchAngle: "touchAngle", animationDuration: "animationDuration", rewind: "rewind", rewindDuration: "rewindDuration", animationTimingFunc: "animationTimingFunc", direction: "direction", peek: "peek", breakpoints: "breakpoints", classes: "classes", throttle: "throttle" }, outputs: { mountedBefore: "mountedBefore", mountedAfter: "mountedAfter", updated: "updated", played: "played", paused: "paused", buildedBefore: "buildedBefore", buildedAfter: "buildedAfter", ranBefore: "ranBefore", ran: "ran", ranAfter: "ranAfter", ranOffset: "ranOffset", runStarted: "runStarted", runEnded: "runEnded", moved: "moved", movedAfter: "movedAfter", resized: "resized", swipeStarted: "swipeStarted", swipeMoved: "swipeMoved", swipeEnded: "swipeEnded", translateJumped: "translateJumped" }, viewQueries: [{ propertyName: "glideEl", first: true, predicate: ["glideEl"], descendants: true }, { propertyName: "glideSlidesEl", first: true, predicate: ["glideSlidesEl"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #glideEl class=\"glide\">\n <div class=\"glide__track\" data-glide-el=\"track\">\n <div #glideSlidesEl class=\"glide__slides\">\n <ng-content></ng-content>\n </div>\n </div>\n <div\n class=\"glide__arrows\"\n data-glide-el=\"controls\"\n [style.display]=\"showArrows ? 'block' : 'none'\"\n >\n <button\n class=\"glide__arrow glide__arrow--left\"\n data-glide-dir=\"<\"\n [style.display]=\"getStyleDisplay(!arrowLeftTemplate)\"\n >\n {{ arrowLeftLabel }}\n </button>\n <button\n class=\"glide__arrow glide__arrow--right\"\n data-glide-dir=\">\"\n [style.display]=\"getStyleDisplay(!arrowRightTemplate)\"\n >\n {{ arrowRightLabel }}\n </button>\n <div\n data-glide-dir=\"<\"\n [style.display]=\"getStyleDisplay(!!arrowLeftTemplate)\"\n >\n <ng-container *ngTemplateOutlet=\"arrowLeftTemplate\"></ng-container>\n </div>\n <div\n data-glide-dir=\">\"\n [style.display]=\"getStyleDisplay(!!arrowRightTemplate)\"\n >\n <ng-container *ngTemplateOutlet=\"arrowRightTemplate\"></ng-container>\n </div>\n </div>\n <div\n class=\"glide__bullets\"\n data-glide-el=\"controls[nav]\"\n [style.display]=\"showBullets ? 'block' : 'none'\"\n >\n <ng-container *ngIf=\"glideBullets\">\n <button\n *ngFor=\"let glideBullet of glideBullets\"\n class=\"glide__bullet\"\n [attr.data-glide-dir]=\"'=' + glideBullet\"\n ></button>\n </ng-container>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.6", ngImport: i0, type: NgxGlideComponent, decorators: [{
type: Component,
args: [{ standalone: true, imports: [NgIf, NgForOf, NgTemplateOutlet], selector: 'ngx-glide', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #glideEl class=\"glide\">\n <div class=\"glide__track\" data-glide-el=\"track\">\n <div #glideSlidesEl class=\"glide__slides\">\n <ng-content></ng-content>\n </div>\n </div>\n <div\n class=\"glide__arrows\"\n data-glide-el=\"controls\"\n [style.display]=\"showArrows ? 'block' : 'none'\"\n >\n <button\n class=\"glide__arrow glide__arrow--left\"\n data-glide-dir=\"<\"\n [style.display]=\"getStyleDisplay(!arrowLeftTemplate)\"\n >\n {{ arrowLeftLabel }}\n </button>\n <button\n class=\"glide__arrow glide__arrow--right\"\n data-glide-dir=\">\"\n [style.display]=\"getStyleDisplay(!arrowRightTemplate)\"\n >\n {{ arrowRightLabel }}\n </button>\n <div\n data-glide-dir=\"<\"\n [style.display]=\"getStyleDisplay(!!arrowLeftTemplate)\"\n >\n <ng-container *ngTemplateOutlet=\"arrowLeftTemplate\"></ng-container>\n </div>\n <div\n data-glide-dir=\">\"\n [style.display]=\"getStyleDisplay(!!arrowRightTemplate)\"\n >\n <ng-container *ngTemplateOutlet=\"arrowRightTemplate\"></ng-container>\n </div>\n </div>\n <div\n class=\"glide__bullets\"\n data-glide-el=\"controls[nav]\"\n [style.display]=\"showBullets ? 'block' : 'none'\"\n >\n <ng-container *ngIf=\"glideBullets\">\n <button\n *ngFor=\"let glideBullet of glideBullets\"\n class=\"glide__bullet\"\n [attr.data-glide-dir]=\"'=' + glideBullet\"\n ></button>\n </ng-container>\n </div>\n</div>\n" }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }]; }, propDecorators: { showArrows: [{
type: Input
}], showBullets: [{
type: Input
}], arrowLeftLabel: [{
type: Input
}], arrowLeftTemplate: [{
type: Input
}], arrowRightLabel: [{
type: Input
}], arrowRightTemplate: [{
type: Input
}], listenToEvents: [{
type: Input
}], type: [{
type: Input
}], startAt: [{
type: Input
}], perView: [{
type: Input
}], focusAt: [{
type: Input
}], gap: [{
type: Input
}], autoplay: [{
type: Input
}], hoverpause: [{
type: Input
}], keyboard: [{
type: Input
}], bound: [{
type: Input
}], swipeThreshold: [{
type: Input
}], dragThreshold: [{
type: Input
}], perTouch: [{
type: Input
}], touchRatio: [{
type: Input
}], touchAngle: [{
type: Input
}], animationDuration: [{
type: Input
}], rewind: [{
type: Input
}], rewindDuration: [{
type: Input
}], animationTimingFunc: [{
type: Input
}], direction: [{
type: Input
}], peek: [{
type: Input
}], breakpoints: [{
type: Input
}], classes: [{
type: Input
}], throttle: [{
type: Input
}], mountedBefore: [{
type: Output
}], mountedAfter: [{
type: Output
}], updated: [{
type: Output
}], played: [{
type: Output
}], paused: [{
type: Output
}], buildedBefore: [{
type: Output
}], buildedAfter: [{
type: Output
}], ranBefore: [{
type: Output
}], ran: [{
type: Output
}], ranAfter: [{
type: Output
}], ranOffset: [{
type: Output
}], runStarted: [{
type: Output
}], runEnded: [{
type: Output
}], moved: [{
type: Output
}], movedAfter: [{
type: Output
}], resized: [{
type: Output
}], swipeStarted: [{
type: Output
}], swipeMoved: [{
type: Output
}], swipeEnded: [{
type: Output
}], translateJumped: [{
type: Output
}], glideEl: [{
type: ViewChild,
args: ['glideEl', { static: false }]
}], glideSlidesEl: [{
type: ViewChild,
args: ['glideSlidesEl', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWdsaWRlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL25neC1nbGlkZS9zcmMvbGliL25neC1nbGlkZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9uZ3gtZ2xpZGUvc3JjL2xpYi9uZ3gtZ2xpZGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixPQUFPLEVBQ1AsSUFBSSxFQUNKLGdCQUFnQixHQUNqQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBR0wsTUFBTSxFQUNOLFdBQVcsRUFJWCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFFdkIsNkRBQTZEO0FBQzdELGFBQWE7QUFDYixPQUFPLEtBQUssTUFBTSxnQkFBZ0IsQ0FBQztBQUVuQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsZUFBZSxFQUFZLE1BQU0sVUFBVSxDQUFDOztBQUUzRSwrREFBK0Q7QUFRL0QsTUFBTSxPQUFPLGlCQUFpQjtJQThENUIsWUFDVSxpQkFBb0MsRUFDZixVQUFrQjtRQUR2QyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ2YsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUUvQyxJQUFJLENBQUMsVUFBVSxHQUFHLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRCxJQUFJLENBQUMsV0FBVyxHQUFHLG9CQUFvQixDQUFDLFdBQVcsQ0FBQztRQUNwRCxJQUFJLENBQUMsY0FBYyxHQUFHLG9CQUFvQixDQUFDLGNBQWMsQ0FBQztRQUMxRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsb0JBQW9CLENBQUMsZUFBZSxDQUFDO1FBQzVELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxvQkFBb0IsQ0FBQyxjQUFjLENBQUM7UUFFMUQsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFFdkIsSUFBSSxDQUFDLElBQUksR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxPQUFPLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQztRQUN2QyxJQUFJLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUM7UUFDdkMsSUFBSSxDQUFDLE9BQU8sR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxHQUFHLEdBQUcsZUFBZSxDQUFDLEdBQUcsQ0FBQztRQUMvQixJQUFJLENBQUMsUUFBUSxHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUM7UUFDekMsSUFBSSxDQUFDLFVBQVUsR0FBRyxlQUFlLENBQUMsVUFBVSxDQUFDO1FBQzdDLElBQUksQ0FBQyxRQUFRLEdBQUcsZUFBZSxDQUFDLFFBQVEsQ0FBQztRQUN6QyxJQUFJLENBQUMsS0FBSyxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLGNBQWMsR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFDO1FBQ3JELElBQUksQ0FBQyxhQUFhLEdBQUcsZUFBZSxDQUFDLGFBQWEsQ0FBQztRQUNuRCxJQUFJLENBQUMsUUFBUSxHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUM7UUFDekMsSUFBSSxDQUFDLFVBQVUsR0FBRyxlQUFlLENBQUMsVUFBVSxDQUFDO1FBQzdDLElBQUksQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDLFVBQVUsQ0FBQztRQUM3QyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsZUFBZSxDQUFDLGlCQUFpQixDQUFDO1FBQzNELElBQUksQ0FBQyxNQUFNLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQztRQUNyQyxJQUFJLENBQUMsY0FBYyxHQUFHLGVBQWUsQ0FBQyxjQUFjLENBQUM7UUFDckQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGVBQWUsQ0FBQyxtQkFBbUIsQ0FBQztRQUMvRCxJQUFJLENBQUMsU0FBUyxHQUFHLGVBQWUsQ0FBQyxTQUFTLENBQUM7UUFDM0MsSUFBSSxDQUFDLElBQUksR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDLFdBQVcsQ0FBQztRQUMvQyxJQUFJLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUM7UUFDdkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDO1FBRXpDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM5QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUN2QyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDdkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQzlDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM3QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksWUFBWSxFQUEyQixDQUFDO1FBQzdELElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxZQUFZLEVBQTJCLENBQUM7UUFDdkQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFlBQVksRUFBMkIsQ0FBQztRQUM1RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksWUFBWSxFQUEyQixDQUFDO1FBQzdELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQTJCLENBQUM7UUFDOUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFlBQVksRUFBMkIsQ0FBQztRQUM1RCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksWUFBWSxFQUEyQixDQUFDO1FBQ3pELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQTJCLENBQUM7UUFDOUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM3QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDM0MsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQzNDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxZQUFZLEVBQTJCLENBQUM7SUFDckUsQ0FBQztJQUVPLE1BQU0sQ0FBQyxzQkFBc0IsQ0FDbkMsT0FBc0I7UUFFdEIsTUFBTSxRQUFRLEdBQTRCLEVBQUUsQ0FBQztRQUU3QyxLQUFLLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBRTtZQUN6QixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsRUFBRTtnQkFDdkQsU0FBUzthQUNWO1lBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQy9ELFNBQVM7YUFDVjtZQUNELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQWlCLENBQUM7WUFDNUMsSUFBSSxNQUFNLENBQUMsYUFBYSxLQUFLLE1BQU0sQ0FBQyxZQUFZLEVBQUU7Z0JBQ2hELFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDO2FBQ3JDO1NBQ0Y7UUFFRCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQy9ELElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztTQUNoRTtJQUNILENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxFQUFFO1lBQy9DLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUNmO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVELGVBQWUsQ0FBQyxTQUFrQjtRQUNoQyxPQUFPLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDdEMsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDeEMsQ0FBQztJQUVELHFDQUFxQztJQUNyQyxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQzNDLENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsT0FBTztRQUNMLE9BQU8sSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztJQUN2QyxDQUFDO0lBRUQscUNBQXFDO0lBQ3JDLFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7SUFDM0MsQ0FBQztJQUVELEtBQUs7UUFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ3BCO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxRQUFpQztRQUN0QyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDeEM7SUFDSCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDdEI7SUFDSCxDQUFDO0lBRUQscUNBQXFDO0lBQ3JDLEVBQUUsQ0FBQyxPQUFlO1FBQ2hCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3hCO0lBQ0gsQ0FBQztJQUVELEtBQUs7UUFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ3BCO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFjO1FBQ2pCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNkLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO2dCQUM3QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN4QjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO2FBQ25CO1NBQ0Y7SUFDSCxDQUFDO0lBRUQscUNBQXFDO0lBQ3JDLE9BQU87UUFDTCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ3RCO0lBQ0gsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ3JCO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFZO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNkLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUNoQjtRQUNELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRU8sTUFBTTtRQUNaLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQ3BCLElBQUksQ0FBQyxPQUFPLEVBQUUsYUFBYSxFQUMzQixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FDNUIsQ0FBQztRQUNGLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDYixJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixNQUFNLHdCQUF3QixHQUM1QixJQUFJLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQztRQUNwQyxNQUFNLGNBQWMsR0FBVyx3QkFBd0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQ3hFLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFTyxlQUFlO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QyxPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUM1RCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDMUIsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUNyRCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDcEIsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUMzRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDekIsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUM1RCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDMUIsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDM0IsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUN6RCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDekIsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQWlDLEVBQUUsRUFBRSxDQUMxRCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FDMUIsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLFFBQWlDLEVBQUUsRUFBRSxDQUNoRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FDL0IsQ0FBQztRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsR0FB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O3NCQUFkLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFFWSxhQUFhO3NCQUE5QixNQUFNO2dCQUNXLFlBQVk7c0JBQTdCLE1BQU07Z0JBQ1csT0FBTztzQkFBeEIsTUFBTTtnQkFDVyxNQUFNO3NCQUF2QixNQUFNO2dCQUNXLE1BQU07c0JBQXZCLE1BQU07Z0JBQ1csYUFBYTtzQkFBOUIsTUFBTTtnQkFDVyxZQUFZO3NCQUE3QixNQUFNO2dCQUNXLFNBQVM7c0JBQTFCLE1BQU07Z0JBQ1csR0FBRztzQkFBcEIsTUFBTTtnQkFDVyxRQUFRO3NCQUF6QixNQUFNO2dCQUNXLFNBQVM7c0JBQTFCLE1BQU07Z0JBQ1csVUFBVTtzQkFBM0IsTUFBTTtnQkFDVyxRQUFRO3NCQUF6QixNQUFNO2dCQUNXLEtBQUs7c0JBQXRCLE1BQU07Z0JBQ1csVUFBVTtzQkFBM0IsTUFBTTtnQkFDVyxPQUFPO3NCQUF4QixNQUFNO2dCQUNXLFlBQVk7c0JBQTdCLE1BQU07Z0JBQ1csVUFBVTtzQkFBM0IsTUFBTTtnQkFDVyxVQUFVO3NCQUEzQixNQUFNO2dCQUNXLGVBQWU7c0JBQWhDLE1BQU07Z0JBRTBDLE9BQU87c0JBQXZELFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFFL0IsYUFBYTtzQkFEcEIsU0FBUzt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgaXNQbGF0Zm9ybUJyb3dzZXIsXG4gIE5nRm9yT2YsXG4gIE5nSWYsXG4gIE5nVGVtcGxhdGVPdXRsZXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBQTEFURk9STV9JRCxcbiAgU2ltcGxlQ2hhbmdlLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuLy8gQHRzLWlnbm9yZVxuaW1wb3J0IEdsaWRlIGZyb20gJ0BnbGlkZWpzL2dsaWRlJztcblxuaW1wb3J0IHsgZGVmYXVsdEV4dHJhU2V0dGluZ3MsIGRlZmF1bHRTZXR0aW5ncywgU2V0dGluZ3MgfSBmcm9tICcuL3NoYXJlZCc7XG5cbi8vIG5vaW5zcGVjdGlvbiBUeXBlU2NyaXB0RmllbGRDYW5CZU1hZGVSZWFkb25seSxEdXBsaWNhdGVkQ29kZVxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtOZ0lmLCBOZ0Zvck9mLCBOZ1RlbXBsYXRlT3V0bGV0XSxcbiAgc2VsZWN0b3I6ICduZ3gtZ2xpZGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vbmd4LWdsaWRlLmNvbXBvbmVudC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE5neEdsaWRlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBzaG93QXJyb3dzOiBib29sZWFuO1xuICBASW5wdXQoKSBzaG93QnVsbGV0czogYm9vbGVhbjtcbiAgQElucHV0KCkgYXJyb3dMZWZ0TGFiZWw6IHN0cmluZztcbiAgQElucHV0KCkgYXJyb3dMZWZ0VGVtcGxhdGU6IFRlbXBsYXRlUmVmPHVua25vd24+IHwgbnVsbDtcbiAgQElucHV0KCkgYXJyb3dSaWdodExhYmVsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGFycm93UmlnaHRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8dW5rbm93bj4gfCBudWxsO1xuICBASW5wdXQoKSBsaXN0ZW5Ub0V2ZW50czogYm9vbGVhbjtcblxuICBnbGlkZUJ1bGxldHM6IG51bWJlcltdO1xuXG4gIEBJbnB1dCgpIHR5cGU6IHN0cmluZztcbiAgQElucHV0KCkgc3RhcnRBdDogbnVtYmVyO1xuICBASW5wdXQoKSBwZXJWaWV3OiBudW1iZXI7XG4gIEBJbnB1dCgpIGZvY3VzQXQ6IG51bWJlciB8IHN0cmluZztcbiAgQElucHV0KCkgZ2FwOiBudW1iZXI7XG4gIEBJbnB1dCgpIGF1dG9wbGF5OiBudW1iZXIgfCBib29sZWFuO1xuICBASW5wdXQoKSBob3ZlcnBhdXNlOiBib29sZWFuO1xuICBASW5wdXQoKSBrZXlib2FyZDogYm9vbGVhbjtcbiAgQElucHV0KCkgYm91bmQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHN3aXBlVGhyZXNob2xkOiBudW1iZXIgfCBib29sZWFuO1xuICBASW5wdXQoKSBkcmFnVGhyZXNob2xkOiBudW1iZXIgfCBib29sZWFuO1xuICBASW5wdXQoKSBwZXJUb3VjaDogbnVtYmVyIHwgYm9vbGVhbjtcbiAgQElucHV0KCkgdG91Y2hSYXRpbzogbnVtYmVyO1xuICBASW5wdXQoKSB0b3VjaEFuZ2xlOiBudW1iZXI7XG4gIEBJbnB1dCgpIGFuaW1hdGlvbkR1cmF0aW9uOiBudW1iZXI7XG4gIEBJbnB1dCgpIHJld2luZDogYm9vbGVhbjtcbiAgQElucHV0KCkgcmV3aW5kRHVyYXRpb246IG51bWJlcjtcbiAgQElucHV0KCkgYW5pbWF0aW9uVGltaW5nRnVuYzogc3RyaW5nO1xuICBASW5wdXQoKSBkaXJlY3Rpb246IHN0cmluZztcbiAgQElucHV0KCkgcGVlazogbnVtYmVyIHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIEBJbnB1dCgpIGJyZWFrcG9pbnRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgQElucHV0KCkgY2xhc3NlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIEBJbnB1dCgpIHRocm90dGxlOiBudW1iZXI7XG5cbiAgQE91dHB1dCgpIHByaXZhdGUgbW91bnRlZEJlZm9yZTogRXZlbnRFbWl0dGVyPHZvaWQ+O1xuICBAT3V0cHV0KCkgcHJpdmF0ZSBtb3VudGVkQWZ0ZXI6IEV2ZW50RW1pdHRlcjx2b2lkPjtcbiAgQE91dHB1dCgpIHByaXZhdGUgdXBkYXRlZDogRXZlbnRFbWl0dGVyPHZvaWQ+O1xuICBAT3V0cHV0KCkgcHJpdmF0ZSBwbGF5ZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPjtcbiAgQE91dHB1dCgpIHByaXZhdGUgcGF1c2VkOiBFdmVudEVtaXR0ZXI8dm9pZD47XG4gIEBPdXRwdXQoKSBwcml2YXRlIGJ1aWxkZWRCZWZvcmU6IEV2ZW50RW1pdHRlcjx2b2lkPjtcbiAgQE91dHB1dCgpIHByaXZhdGUgYnVpbGRlZEFmdGVyOiBFdmVudEVtaXR0ZXI8dm9pZD47XG4gIEBPdXRwdXQoKSBwcml2YXRlIHJhbkJlZm9yZTogRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgQE91dHB1dCgpIHByaXZhdGUgcmFuOiBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICBAT3V0cHV0KCkgcHJpdmF0ZSByYW5BZnRlcjogRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgQE91dHB1dCgpIHByaXZhdGUgcmFuT2Zmc2V0OiBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICBAT3V0cHV0KCkgcHJpdmF0ZSBydW5TdGFydGVkOiBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICBAT3V0cHV0KCkgcHJpdmF0ZSBydW5FbmRlZDogRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgQE91dHB1dCgpIHByaXZhdGUgbW92ZWQ6IEV2ZW50RW1pdHRlcjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG4gIEBPdXRwdXQoKSBwcml2YXRlIG1vdmVkQWZ0ZXI6IEV2ZW50RW1pdHRlcjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG4gIEBPdXRwdXQoKSBwcml2YXRlIHJlc2l6ZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPjtcbiAgQE91dHB1dCgpIHByaXZhdGUgc3dpcGVTdGFydGVkOiBFdmVudEVtaXR0ZXI8dm9pZD47XG4gIEBPdXRwdXQoKSBwcml2YXRlIHN3aXBlTW92ZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPjtcbiAgQE91dHB1dCgpIHByaXZhdGUgc3dpcGVFbmRlZDogRXZlbnRFbWl0dGVyPHZvaWQ+O1xuICBAT3V0cHV0KCkgcHJpdmF0ZSB0cmFuc2xhdGVKdW1wZWQ6IEV2ZW50RW1pdHRlcjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG5cbiAgQFZpZXdDaGlsZCgnZ2xpZGVFbCcsIHsgc3RhdGljOiBmYWxzZSB9KSBwcml2YXRlIGdsaWRlRWw/OiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdnbGlkZVNsaWRlc0VsJywgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHByaXZhdGUgZ2xpZGVTbGlkZXNFbD86IEVsZW1lbnRSZWY7XG5cbiAgcHJpdmF0ZSBnbGlkZTogR2xpZGU7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBzdHJpbmdcbiAgKSB7XG4gICAgdGhpcy5zaG93QXJyb3dzID0gZGVmYXVsdEV4dHJhU2V0dGluZ3Muc2hvd0Fycm93cztcbiAgICB0aGlzLnNob3dCdWxsZXRzID0gZGVmYXVsdEV4dHJhU2V0dGluZ3Muc2hvd0J1bGxldHM7XG4gICAgdGhpcy5hcnJvd0xlZnRMYWJlbCA9IGRlZmF1bHRFeHRyYVNldHRpbmdzLmFycm93TGVmdExhYmVsO1xuICAgIHRoaXMuYXJyb3dMZWZ0VGVtcGxhdGUgPSBudWxsO1xuICAgIHRoaXMuYXJyb3dSaWdodExhYmVsID0gZGVmYXVsdEV4dHJhU2V0dGluZ3MuYXJyb3dSaWdodExhYmVsO1xuICAgIHRoaXMuYXJyb3dSaWdodFRlbXBsYXRlID0gbnVsbDtcbiAgICB0aGlzLmxpc3RlblRvRXZlbnRzID0gZGVmYXVsdEV4dHJhU2V0dGluZ3MubGlzdGVuVG9FdmVudHM7XG5cbiAgICB0aGlzLmdsaWRlQnVsbGV0cyA9IFtdO1xuXG4gICAgdGhpcy50eXBlID0gZGVmYXVsdFNldHRpbmdzLnR5cGU7XG4gICAgdGhpcy5zdGFydEF0ID0gZGVmYXVsdFNldHRpbmdzLnN0YXJ0QXQ7XG4gICAgdGhpcy5wZXJWaWV3ID0gZGVmYXVsdFNldHRpbmdzLnBlclZpZXc7XG4gICAgdGhpcy5mb2N1c0F0ID0gZGVmYXVsdFNldHRpbmdzLmZvY3VzQXQ7XG4gICAgdGhpcy5nYXAgPSBkZWZhdWx0U2V0dGluZ3MuZ2FwO1xuICAgIHRoaXMuYXV0b3BsYXkgPSBkZWZhdWx0U2V0dGluZ3MuYXV0b3BsYXk7XG4gICAgdGhpcy5ob3ZlcnBhdXNlID0gZGVmYXVsdFNldHRpbmdzLmhvdmVycGF1c2U7XG4gICAgdGhpcy5rZXlib2FyZCA9IGRlZmF1bHRTZXR0aW5ncy5rZXlib2FyZDtcbiAgICB0aGlzLmJvdW5kID0gZGVmYXVsdFNldHRpbmdzLmJvdW5kO1xuICAgIHRoaXMuc3dpcGVUaHJlc2hvbGQgPSBkZWZhdWx0U2V0dGluZ3Muc3dpcGVUaHJlc2hvbGQ7XG4gICAgdGhpcy5kcmFnVGhyZXNob2xkID0gZGVmYXVsdFNldHRpbmdzLmRyYWdUaHJlc2hvbGQ7XG4gICAgdGhpcy5wZXJUb3VjaCA9IGRlZmF1bHRTZXR0aW5ncy5wZXJUb3VjaDtcbiAgICB0aGlzLnRvdWNoUmF0aW8gPSBkZWZhdWx0U2V0dGluZ3MudG91Y2hSYXRpbztcbiAgICB0aGlzLnRvdWNoQW5nbGUgPSBkZWZhdWx0U2V0dGluZ3MudG91Y2hBbmdsZTtcbiAgICB0aGlzLmFuaW1hdGlvbkR1cmF0aW9uID0gZGVmYXVsdFNldHRpbmdzLmFuaW1hdGlvbkR1cmF0aW9uO1xuICAgIHRoaXMucmV3aW5kID0gZGVmYXVsdFNldHRpbmdzLnJld2luZDtcbiAgICB0aGlzLnJld2luZER1cmF0aW9uID0gZGVmYXVsdFNldHRpbmdzLnJld2luZER1cmF0aW9uO1xuICAgIHRoaXMuYW5pbWF0aW9uVGltaW5nRnVuYyA9IGRlZmF1bHRTZXR0aW5ncy5hbmltYXRpb25UaW1pbmdGdW5jO1xuICAgIHRoaXMuZGlyZWN0aW9uID0gZGVmYXVsdFNldHRpbmdzLmRpcmVjdGlvbjtcbiAgICB0aGlzLnBlZWsgPSBkZWZhdWx0U2V0dGluZ3MucGVlaztcbiAgICB0aGlzLmJyZWFrcG9pbnRzID0gZGVmYXVsdFNldHRpbmdzLmJyZWFrcG9pbnRzO1xuICAgIHRoaXMuY2xhc3NlcyA9IGRlZmF1bHRTZXR0aW5ncy5jbGFzc2VzO1xuICAgIHRoaXMudGhyb3R0bGUgPSBkZWZhdWx0U2V0dGluZ3MudGhyb3R0bGU7XG5cbiAgICB0aGlzLm1vdW50ZWRCZWZvcmUgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gICAgdGhpcy5tb3VudGVkQWZ0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gICAgdGhpcy51cGRhdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIHRoaXMucGxheWVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIHRoaXMucGF1c2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIHRoaXMuYnVpbGRlZEJlZm9yZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgICB0aGlzLmJ1aWxkZWRBZnRlciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgICB0aGlzLnJhbkJlZm9yZSA9IG5ldyBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KCk7XG4gICAgdGhpcy5yYW4gPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpO1xuICAgIHRoaXMucmFuQWZ0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpO1xuICAgIHRoaXMucmFuT2Zmc2V0ID0gbmV3IEV2ZW50RW1pdHRlcjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKTtcbiAgICB0aGlzLnJ1blN0YXJ0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpO1xuICAgIHRoaXMucnVuRW5kZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpO1xuICAgIHRoaXMubW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpO1xuICAgIHRoaXMubW92ZWRBZnRlciA9IG5ldyBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KCk7XG4gICAgdGhpcy5yZXNpemVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIHRoaXMuc3dpcGVTdGFydGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIHRoaXMuc3dpcGVNb3ZlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgICB0aGlzLnN3aXBlRW5kZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gICAgdGhpcy50cmFuc2xhdGVKdW1wZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0R2xpZGVVcGRhdGVTZXR0aW5ncyhcbiAgICBjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzXG4gICk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBzZXR0aW5nczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIGNoYW5nZXMpIHtcbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNoYW5nZXMsIGtleSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChkZWZhdWx0U2V0dGluZ3MsIGtleSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBjaGFuZ2UgPSBjaGFuZ2VzW2tleV0gYXMgU2ltcGxlQ2hhbmdlO1xuICAgICAgaWYgKGNoYW5nZS5wcmV2aW91c1ZhbHVlICE9PSBjaGFuZ2UuY3VycmVudFZhbHVlKSB7XG4gICAgICAgIHNldHRpbmdzW2tleV0gPSBjaGFuZ2UuY3VycmVudFZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzZXR0aW5ncztcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSAmJiBjaGFuZ2VzICYmIHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMudXBkYXRlKE5neEdsaWRlQ29tcG9uZW50LmdldEdsaWRlVXBkYXRlU2V0dGluZ3MoY2hhbmdlcykpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSAmJiBHbGlkZSkge1xuICAgICAgdGhpcy5jcmVhdGUoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGdldFN0eWxlRGlzcGxheShjb25kaXRpb246IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb25kaXRpb24gPyAnYmxvY2snIDogJ25vbmUnO1xuICB9XG5cbiAgZ2V0SW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nbGlkZSAmJiB0aGlzLmdsaWRlLmluZGV4O1xuICB9XG5cbiAgLy8gbm9pbnNwZWN0aW9uIEpTVW51c2VkR2xvYmFsU3ltYm9sc1xuICBnZXRTZXR0aW5ncygpOiBTZXR0aW5ncyB7XG4gICAgcmV0dXJuIHRoaXMuZ2xpZGUgJiYgdGhpcy5nbGlkZS5zZXR0aW5ncztcbiAgfVxuXG4gIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZEdsb2JhbFN5bWJvbHNcbiAgZ2V0VHlwZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdsaWRlICYmIHRoaXMuZ2xpZGUudHlwZTtcbiAgfVxuXG4gIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZEdsb2JhbFN5bWJvbHNcbiAgaXNEaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nbGlkZSAmJiB0aGlzLmdsaWRlLmRpc2FibGVkO1xuICB9XG5cbiAgbW91bnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMuZ2xpZGUubW91bnQoKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGUoc2V0dGluZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMuZ2xpZGUudXBkYXRlKHNldHRpbmdzKTtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMuZ2xpZGUuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZEdsb2JhbFN5bWJvbHNcbiAgZ28ocGF0dGVybjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMuZ2xpZGUuZ28ocGF0dGVybik7XG4gICAgfVxuICB9XG5cbiAgcGF1c2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMuZ2xpZGUucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICBwbGF5KGZvcmNlPzogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIGlmICh0eXBlb2YgZm9yY2UgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHRoaXMuZ2xpZGUucGxheShmb3JjZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdsaWRlLnBsYXkoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBub2luc3BlY3Rpb24gSlNVbnVzZWRHbG9iYWxTeW1ib2xzXG4gIGRpc2FibGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ2xpZGUpIHtcbiAgICAgIHRoaXMuZ2xpZGUuZGlzYWJsZSgpO1xuICAgIH1cbiAgfVxuXG4gIGVuYWJsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5nbGlkZSkge1xuICAgICAgdGhpcy5nbGlkZS5lbmFibGUoKTtcbiAgICB9XG4gIH1cblxuICBpc1R5cGUodHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2xpZGUgJiYgdGhpcy5nbGlkZS5pc1R5cGUodHlwZSk7XG4gIH1cblxuICByZWNyZWF0ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5nbGlkZSkge1xuICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuY3JlYXRlKCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRHbGlkZUJ1bGxldHMoKTtcbiAgICB0aGlzLmdsaWRlID0gbmV3IEdsaWRlKFxuICAgICAgdGhpcy5nbGlkZUVsPy5uYXRpdmVFbGVtZW50LFxuICAgICAgdGhpcy5nZXRHbGlkZUluaXRTZXR0aW5ncygpXG4gICAgKTtcbiAgICB0aGlzLmluaXRHbGlkZUV2ZW50cygpO1xuICAgIHRoaXMubW91bnQoKTtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdEdsaWRlQnVsbGV0cygpOiB2b2lkIHtcbiAgICBjb25zdCBnbGlkZVNsaWRlc05hdGl2ZUVsZW1lbnQ6IEhUTUxFbGVtZW50ID1cbiAgICAgIHRoaXMuZ2xpZGVTbGlkZXNFbD8ubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBjaGlsZHJlbkxlbmd0aDogbnVtYmVyID0gZ2xpZGVTbGlkZXNOYXRpdmVFbGVtZW50LmNoaWxkcmVuLmxlbmd0aDtcbiAgICB0aGlzLmdsaWRlQnVsbGV0cyA9IFsuLi5uZXcgQXJyYXkoY2hpbGRyZW5MZW5ndGgpLmtleXMoKV07XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIGluaXRHbGlkZUV2ZW50cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZ2xpZGUgfHwgIXRoaXMubGlzdGVuVG9FdmVudHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmdsaWRlLm9uKCdtb3VudC5iZWZvcmUnLCAoKSA9PiB0aGlzLm1vdW50ZWRCZWZvcmUuZW1pdCgpKTtcbiAgICB0aGlzLmdsaWRlLm9uKCdtb3VudC5hZnRlcicsICgpID0+IHRoaXMubW91bnRlZEFmdGVyLmVtaXQoKSk7XG4gICAgdGhpcy5nbGlkZS5vbigndXBkYXRlJywgKCkgPT4gdGhpcy51cGRhdGVkLmVtaXQoKSk7XG4gICAgdGhpcy5nbGlkZS5vbigncGxheScsICgpID0+IHRoaXMucGxheWVkLmVtaXQoKSk7XG4gICAgdGhpcy5nbGlkZS5vbigncGF1c2UnLCAoKSA9PiB0aGlzLnBhdXNlZC5lbWl0KCkpO1xuICAgIHRoaXMuZ2xpZGUub24oJ2J1aWxkLmJlZm9yZScsICgpID0+IHRoaXMuYnVpbGRlZEJlZm9yZS5lbWl0KCkpO1xuICAgIHRoaXMuZ2xpZGUub24oJ2J1aWxkLmFmdGVyJywgKCkgPT4gdGhpcy5idWlsZGVkQWZ0ZXIuZW1pdCgpKTtcbiAgICB0aGlzLmdsaWRlLm9uKCdydW4uYmVmb3JlJywgKG1vdmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy5yYW5CZWZvcmUuZW1pdChtb3ZlKVxuICAgICk7XG4gICAgdGhpcy5nbGlkZS5vbigncnVuJywgKG1vdmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy5yYW4uZW1pdChtb3ZlKVxuICAgICk7XG4gICAgdGhpcy5nbGlkZS5vbigncnVuLmFmdGVyJywgKG1vdmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy5yYW5BZnRlci5lbWl0KG1vdmUpXG4gICAgKTtcbiAgICB0aGlzLmdsaWRlLm9uKCdydW4ub2Zmc2V0JywgKG1vdmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy5yYW5PZmZzZXQuZW1pdChtb3ZlKVxuICAgICk7XG4gICAgdGhpcy5nbGlkZS5vbigncnVuLnN0YXJ0JywgKG1vdmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy5ydW5TdGFydGVkLmVtaXQobW92ZSlcbiAgICApO1xuICAgIHRoaXMuZ2xpZGUub24oJ3J1bi5lbmQnLCAobW92ZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+XG4gICAgICB0aGlzLnJ1bkVuZGVkLmVtaXQobW92ZSlcbiAgICApO1xuICAgIHRoaXMuZ2xpZGUub24oJ21vdmUnLCAobW92ZW1lbnQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy5tb3ZlZC5lbWl0KG1vdmVtZW50KVxuICAgICk7XG4gICAgdGhpcy5nbGlkZS5vbignbW92ZS5hZnRlcicsIChtb3ZlbWVudDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+XG4gICAgICB0aGlzLm1vdmVkQWZ0ZXIuZW1pdChtb3ZlbWVudClcbiAgICApO1xuICAgIHRoaXMuZ2xpZGUub24oJ3Jlc2l6ZScsICgpID0+IHRoaXMucmVzaXplZC5lbWl0KCkpO1xuICAgIHRoaXMuZ2xpZGUub24oJ3N3aXBlLnN0YXJ0JywgKCkgPT4gdGhpcy5zd2lwZVN0YXJ0ZWQuZW1pdCgpKTtcbiAgICB0aGlzLmdsaWRlLm9uKCdzd2lwZS5tb3ZlJywgKCkgPT4gdGhpcy5zd2lwZU1vdmVkLmVtaXQoKSk7XG4gICAgdGhpcy5nbGlkZS5vbignc3dpcGUuZW5kJywgKCkgPT4gdGhpcy5zd2lwZUVuZGVkLmVtaXQoKSk7XG4gICAgdGhpcy5nbGlkZS5vbigndHJhbnNsYXRlLmp1bXAnLCAobW92ZW1lbnQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgdGhpcy50cmFuc2xhdGVKdW1wZWQuZW1pdChtb3ZlbWVudClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRHbGlkZUluaXRTZXR0aW5ncygpOiBTZXR0aW5ncyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIHN0YXJ0QXQ6IHRoaXMuc3RhcnRBdCxcbiAgICAgIHBlclZpZXc6IHRoaXMucGVyVmlldyxcbiAgICAgIGZvY3VzQXQ6IHRoaXMuZm9jdXNBdCxcbiAgICAgIGdhcDogdGhpcy5nYXAsXG4gICAgICBhdXRvcGxheTogdGhpcy5hdXRvcGxheSxcbiAgICAgIGhvdmVycGF1c2U6IHRoaXMuaG92ZXJwYXVzZSxcbiAgICAgIGtleWJvYXJkOiB0aGlzLmtleWJvYXJkLFxuICAgICAgYm91bmQ6IHRoaXMuYm91bmQsXG4gICAgICBzd2lwZVRocmVzaG9sZDogdGhpcy5zd2lwZVRocmVzaG9sZCxcbiAgICAgIGRyYWdUaHJlc2hvbGQ6IHRoaXMuZHJhZ1RocmVzaG9sZCxcbiAgICAgIHBlclRvdWNoOiB0aGlzLnBlclRvdWNoLFxuICAgICAgdG91Y2hSYXRpbzogdGhpcy50b3VjaFJhdGlvLFxuICAgICAgdG91Y2hBbmdsZTogdGhpcy50b3VjaEFuZ2xlLFxuICAgICAgYW5pbWF0aW9uRHVyYXRpb246IHRoaXMuYW5pbWF0aW9uRHVyYXRpb24sXG4gICAgICByZXdpbmQ6IHRoaXMucmV3aW5kLFxuICAgICAgcmV3aW5kRHVyYXRpb246IHRoaXMucmV3aW5kRHVyYXRpb24sXG4gICAgICBhbmltYXRpb25UaW1pbmdGdW5jOiB0aGlzLmFuaW1hdGlvblRpbWluZ0Z1bmMsXG4gICAgICBkaXJlY3Rpb246IHRoaXMuZGlyZWN0aW9uLFxuICAgICAgcGVlazogdGhpcy5wZWVrLFxuICAgICAgYnJlYWtwb2ludHM6IHRoaXMuYnJlYWtwb2ludHMsXG4gICAgICBjbGFzc2VzOiB0aGlzLmNsYXNzZXMsXG4gICAgICB0aHJvdHRsZTogdGhpcy50aHJvdHRsZSxcbiAgICB9O1xuICB9XG59XG4iLCI8ZGl2ICNnbGlkZUVsIGNsYXNzPVwiZ2xpZGVcIj5cbiAgPGRpdiBjbGFzcz1cImdsaWRlX190cmFja1wiIGRhdGEtZ2xpZGUtZWw9XCJ0cmFja1wiPlxuICAgIDxkaXYgI2dsaWRlU2xpZGVzRWwgY2xhc3M9XCJnbGlkZV9fc2xpZGVzXCI+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2XG4gICAgY2xhc3M9XCJnbGlkZV9fYXJyb3dzXCJcbiAgICBkYXRhLWdsaWRlLWVsPVwiY29udHJvbHNcIlxuICAgIFtzdHlsZS5kaXNwbGF5XT1cInNob3dBcnJvd3MgPyAnYmxvY2snIDogJ25vbmUnXCJcbiAgPlxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiZ2xpZGVfX2Fycm93IGdsaWRlX19hcnJvdy0tbGVmdFwiXG4gICAgICBkYXRhLWdsaWRlLWRpcj1cIjxcIlxuICAgICAgW3N0eWxlLmRpc3BsYXldPVwiZ2V0U3R5bGVEaXNwbGF5KCFhcnJvd0xlZnRUZW1wbGF0ZSlcIlxuICAgID5cbiAgICAgIHt7IGFycm93TGVmdExhYmVsIH19XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3M9XCJnbGlkZV9fYXJyb3cgZ2xpZGVfX2Fycm93LS1yaWdodFwiXG4gICAgICBkYXRhLWdsaWRlLWRpcj1cIj5cIlxuICAgICAgW3N0eWxlLmRpc3BsYXldPVwiZ2V0U3R5bGVEaXNwbGF5KCFhcnJvd1JpZ2h0VGVtcGxhdGUpXCJcbiAgICA+XG4gICAgICB7eyBhcnJvd1JpZ2h0TGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cbiAgICA8ZGl2XG4gICAgICBkYXRhLWdsaWRlLWRpcj1cIjxcIlxuICAgICAgW3N0eWxlLmRpc3BsYXldPVwiZ2V0U3R5bGVEaXNwbGF5KCEhYXJyb3dMZWZ0VGVtcGxhdGUpXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYXJyb3dMZWZ0VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgIC