UNPKG

@vendasta/store

Version:

Components and data for Store

348 lines 82 kB
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Component, EventEmitter, HostListener, Inject, Input, Output, } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Environment, EnvironmentService } from '@vendasta/core';
import { ImageTransformationService } from '@vendasta/image-transformation';
import { ProductCost } from '@vendasta/marketplace-apps/v1';
import { ProductAnalyticsService } from '@vendasta/product-analytics';
import { combineLatest, ReplaySubject } from 'rxjs';
import { map, startWith, take } from 'rxjs/operators';
import { Product } from '../shared/product';
import { HeaderActionType } from '../store-item';
import { MarketingType, SelectedTab } from './product-details-v2.interface';
import * as i0 from "@angular/core";
import * as i1 from "@vendasta/image-transformation";
import * as i2 from "@angular/cdk/layout";
import * as i3 from "@ngx-translate/core";
import * as i4 from "@angular/router";
import * as i5 from "@vendasta/product-analytics";
import * as i6 from "@vendasta/uikit";
import * as i7 from "@angular/material/chips";
import * as i8 from "@angular/material/button";
import * as i9 from "@angular/material/menu";
import * as i10 from "@angular/material/tabs";
import * as i11 from "./product-info/product-info.component";
import * as i12 from "./screenshots-files/screenshots-files.component";
import * as i13 from "./editions-marketing/editions-marketing.component";
import * as i14 from "@angular/common";
import * as i15 from "@angular/flex-layout/extended";
import * as i16 from "@angular/material/tooltip";
import * as i17 from "@angular/material/badge";
export class VaProductDetailsV2Component {
    constructor(imageTransformationService, breakpointObserver, translateService, environmentService, router, route, snowplowService) {
        this.imageTransformationService = imageTransformationService;
        this.translateService = translateService;
        this.environmentService = environmentService;
        this.router = router;
        this.route = route;
        this.snowplowService = snowplowService;
        this.marketingType = MarketingType.Partner;
        this.isEditionActionUsed = false;
        this.headerActionClick = new EventEmitter();
        this.addonSelected = new EventEmitter();
        this.contactActionClick = new EventEmitter();
        this.editionActionClick = new EventEmitter();
        this.updateState$$ = new ReplaySubject();
        this.srcsetHeaderImage = '';
        this.overflowTagsList = '';
        this.showMoreChip = false;
        this.moreChipPosition = '';
        this.hiddenChipNum = 0;
        this.moreList = [];
        this.onlyMore = false;
        this.ownedAndOperated = null;
        this.defaultHeaderImage = 'https://firebasestorage.googleapis.com/v0/b/partner-central-demo.appspot.com/o/no-banner.png?alt=media&token=e5299062-ea20-498b-b37e-39f3cf8a78a8';
        breakpointObserver.observe([Breakpoints.HandsetPortrait]).subscribe((result) => {
            if (result.matches) {
                this.mobileLayout = true;
            }
            else {
                this.mobileLayout = false;
            }
        });
    }
    ngOnInit() {
        this.setOwnedOperatedList();
        this.isHeaderActionUsed =
            this.headerActionType !== HeaderActionType.NONE && this.headerActionClick.observers.length > 0;
        this.isAddonSelectedUsed = this.addonSelected.observers.length > 0;
        this.isContactActionUsed = this.contactActionClick.observers.length > 0;
        if (!!this.appTags && this.appTags.length && !!this.appTags[0].appData) {
            this.appTagArr = [];
            this.appTags[0].appData.forEach((entry) => {
                if (entry.kind.startsWith('tag') &&
                    entry.kind !== 'tag/country' &&
                    entry.kind !== 'tag/source' &&
                    entry.kind !== 'tag/vendor') {
                    entry.values.forEach((value) => {
                        const capitalized = value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');
                        this.appTagArr = this.appTagArr.concat(capitalized);
                    });
                }
            });
            this.chipLabels = this.appTagArr;
        }
        else {
            this.chipLabels = this.getTags();
        }
        if (this.product.headerImageUrl) {
            const imageWidthSizes = [680, 900, 1200];
            this.srcsetHeaderImage = this.imageTransformationService.getSrcSetForImage(this.product.headerImageUrl, imageWidthSizes);
        }
        if (this.ownedAndOperated) {
            this.isOO = this.ownedAndOperated.includes(this.product.productId);
        }
        this.tabState$ = combineLatest([this.route.queryParams, this.updateState$$]).pipe(map(([params, _]) => {
            const tabIndex = Number(params['tab']);
            let selectedTab = !SelectedTab[tabIndex] ? SelectedTab.ProductInformation : tabIndex;
            if (!this.editionsMarketing && selectedTab === SelectedTab.EditionsAndPricing) {
                selectedTab = SelectedTab.ScreenshotsAndFiles;
            }
            return {
                tab: selectedTab,
                editionsTabVisible: this.editionsMarketing?.length > 0,
            };
        }), startWith({
            tab: SelectedTab.ProductInformation,
            editionsTabVisible: this.editionsMarketing?.length > 0,
        }));
    }
    ngAfterViewInit() {
        setTimeout(() => {
            this.detectWrap('chipItem');
            this.onTabChanged();
        });
    }
    ngOnChanges() {
        this.updateState$$.next(null);
    }
    setOwnedOperatedList() {
        switch (this.environmentService.getEnvironment()) {
            case Environment.PROD: {
                this.ownedAndOperated = [
                    'RM',
                    'SM',
                    'MP-94072e44d5364872b672d7ab4fc7a7e8',
                    'MP-c4974d390a044c28aec31e421aa662b2',
                    'MP-ee4ea04e553a4b1780caf7aad7be07cd', // website
                ];
                break;
            }
            case Environment.DEMO: {
                this.ownedAndOperated = [
                    'RM',
                    'SM',
                    'MP-94072e44d5364872b672d7ab4fc7a7e8',
                    'MP-fba21121b71148c9bb33e11fcd92d520',
                    'MP-9cc9f21f0a234a46ad78087fc09f16bc', // website
                ];
                break;
            }
            default: {
                this.ownedAndOperated = [
                    'RM',
                    'SM',
                    'MP-94072e44d5364872b672d7ab4fc7a7e8',
                    'MP-fba21121b71148c9bb33e11fcd92d520',
                    'MP-9cc9f21f0a234a46ad78087fc09f16bc', // website
                ];
                break;
            }
        }
    }
    //  Will be deprecated when the new tagging system is fully implemented
    getTags() {
        const tags = [];
        if (this.product.trialConfiguration?.trialEnabled) {
            tags.push('Free Trial');
        }
        tags.push(...this.product.getLmiCategoryNames());
        return tags;
    }
    onResize(event) {
        this.detectWrap('chipItem');
    }
    detectWrap(className) {
        const wrappedItems = [];
        const items = Array.from(document.getElementsByClassName(className));
        const initialEl = items[0];
        if (!initialEl) {
            return;
        }
        const initialBounds = initialEl.getBoundingClientRect();
        const itemsLength = items.length;
        let breakIndex = itemsLength;
        items.forEach((itemEl, index) => {
            const bounds = itemEl.getBoundingClientRect();
            if (initialBounds.top < bounds.top) {
                wrappedItems.push(itemEl.textContent);
                if (breakIndex === itemsLength) {
                    breakIndex = index;
                }
            }
        });
        let breakItem;
        if (breakIndex === 1 && this.detectMoreClip()) {
            breakItem = document.getElementById('chipStart');
            wrappedItems.push(items[0].textContent);
            items[0].style.visibility = 'hidden';
            this.onlyMore = true;
        }
        else {
            breakItem = items[breakIndex - 1];
            items[0].style.visibility = 'visible';
            this.onlyMore = false;
        }
        this.showMoreChip = wrappedItems.length > 0;
        this.hiddenChipNum = wrappedItems.length;
        this.moreChipPosition = breakItem.offsetLeft + breakItem.offsetWidth + 4 + 'px';
        this.moreList = wrappedItems;
    }
    detectMoreClip() {
        const moreChip = document.getElementsByClassName('more-chip-spacer')[0];
        const webActionContainer = document.getElementById('web-action-container');
        const chipListWrapper = document.getElementsByClassName('mat-chip-list-wrapper')[0];
        if (webActionContainer) {
            const actionContainerBounds = webActionContainer.getBoundingClientRect();
            return !(moreChip.getBoundingClientRect().right < actionContainerBounds.left);
        }
        else if (chipListWrapper.scrollWidth > chipListWrapper.offsetWidth) {
            return true;
        }
        else {
            return false;
        }
    }
    isProductEnabled() {
        if (this.parentProduct) {
            return !this.parentProduct.isArchived && this.product && !this.product.isArchived;
        }
        else {
            return this.product && !this.product.isArchived;
        }
    }
    isProductSuspended() {
        if (this.parentProduct) {
            return this.parentProduct.isSuspended && this.product && this.product.isSuspended;
        }
        else {
            return this.product && this.product.isSuspended;
        }
    }
    /*
     * Resolves the string that should be used for the Enable button.
     */
    getEnableButtonText() {
        const turnOnAppTranslationKey = 'FRONTEND.STORE.STORE_STATE.START_SELLING';
        const productAlreadyOnTranslationKey = 'FRONTEND.STORE.STORE_STATE.SELLING';
        const turnOnAddOnTranslationKey = 'FRONTEND.STORE.STORE_STATE.ADD_ON.START_SELLING';
        if (this.headerActionType === HeaderActionType.ADD_TO_CART) {
            return this.translateService.instant('FRONTEND.STORE.ADD_TO_CART');
        }
        else if (this.headerActionType === HeaderActionType.BUY_IT_NOW) {
            return this.translateService.instant('FRONTEND.STORE.BUY_IT_NOW');
        }
        else if (this.headerActionType === HeaderActionType.NONE) {
            return null;
        }
        else if (this.isProductEnabled()) {
            return this.translateService.instant(productAlreadyOnTranslationKey);
        }
        else {
            if (this.parentProduct) {
                if (this.parentProduct.isArchived) {
                    return this.translateService.instant(turnOnAppTranslationKey);
                }
                else {
                    return this.translateService.instant(turnOnAddOnTranslationKey);
                }
            }
            else {
                return this.translateService.instant(turnOnAppTranslationKey);
            }
        }
    }
    checkButtonDisable() {
        if (this.headerActionType === HeaderActionType.ADD_TO_CART ||
            this.headerActionType === HeaderActionType.BUY_IT_NOW) {
            return false;
        }
        else {
            return this.isProductEnabled() || this.isProductSuspended();
        }
    }
    onHeaderActionClicked() {
        if (this.headerActionType === HeaderActionType.BUY_IT_NOW ||
            this.headerActionType === HeaderActionType.ADD_TO_CART) {
            const label = this.editionsMarketing?.length > 0 ? 'editioned-product' : 'editionless-product';
            this.snowplowService.trackClick('store:app-view', `add-${label}`, this.product.productId);
        }
        this.headerActionClick.emit();
    }
    onEditionActionClicked(product) {
        const property = `${product.appId}:${product.editionId}`;
        this.snowplowService.trackClick('store:editions-tab', 'add-editioned-product', property);
        this.editionActionClick.emit(product);
    }
    onTabChanged(event) {
        if (event) {
            this.route.queryParams.pipe(take(1)).subscribe((queryParams) => this.router.navigate([], {
                queryParams: {
                    ...queryParams,
                    tab: event.index,
                },
            }));
        }
        this.tabRef = Array.from(document.getElementsByClassName('mat-tab-body-active'));
        // hack to fix mat-tab bug of scrolling to top of page on tab switch
        this.tabScrollHack = this.tabRef[0]?.clientHeight + 369 + 'px;';
    }
}
VaProductDetailsV2Component.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: VaProductDetailsV2Component, deps: [{ token: i1.ImageTransformationService }, { token: i2.BreakpointObserver }, { token: i3.TranslateService }, { token: EnvironmentService }, { token: i4.Router }, { token: i4.ActivatedRoute }, { token: i5.ProductAnalyticsService }], target: i0.ɵɵFactoryTarget.Component });
VaProductDetailsV2Component.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: VaProductDetailsV2Component, selector: "app-product-details-v2", inputs: { product: "product", partnerId: "partnerId", parentProduct: "parentProduct", appTags: "appTags", businessCountryCode: "businessCountryCode", marketingType: "marketingType", billingPrice: "billingPrice", marketplaceCost: "marketplaceCost", editionsMarketing: "editionsMarketing", editionOrder: "editionOrder", headerActionType: "headerActionType", isEditionActionUsed: "isEditionActionUsed", productDependenciesFeatureFlag: "productDependenciesFeatureFlag" }, outputs: { headerActionClick: "headerActionClick", addonSelected: "addonSelected", contactActionClick: "contactActionClick", editionActionClick: "editionActionClick" }, host: { listeners: { "window:resize": "onResize($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"page\" [ngStyle]=\"{ 'min-height': tabScrollHack }\">\n  <ng-container *ngIf=\"product.headerImageUrl; else defaultBanner\">\n    <div class=\"background-logo\">\n      <img\n        [src]=\"product.headerImageUrl\"\n        [srcset]=\"srcsetHeaderImage\"\n        class=\"bannerImage\"\n      />\n    </div>\n  </ng-container>\n\n  <ng-template #defaultBanner>\n    <div class=\"background-logo\">\n      <img [src]=\"defaultHeaderImage\" class=\"defaultBannerImage\" />\n    </div>\n  </ng-template>\n  <div>\n    <div *ngIf=\"mobileLayout; else webLayout\" class=\"mobile-container\">\n      <div class=\"flex-row\">\n        <div class=\"icon\">\n          <va-icon\n            [iconUrl]=\"product.iconUrl\"\n            [name]=\"product.name\"\n            [diameter]=\"60\"\n          ></va-icon>\n        </div>\n        <div class=\"centered-column\">\n          <div class=\"title\">{{ product.name }}</div>\n          <div class=\"tag-line\">{{ product.tagline }}</div>\n        </div>\n      </div>\n      <div class=\"mobile-chip-container\">\n        <mat-chip-list>\n          <div class=\"flex-row\">\n            <div id=\"chipStart\"></div>\n            <div class=\"chip-list\">\n              <mat-chip *ngFor=\"let chip of chipLabels\" class=\"chipItem\">\n                {{ chip }}\n              </mat-chip>\n            </div>\n            <div class=\"more-chip-spacer\">\n              <mat-chip\n                *ngIf=\"showMoreChip\"\n                [matTooltip]=\"overflowTagsList\"\n                (mouseenter)=\"$event.stopImmediatePropagation()\"\n                (mouseleave)=\"$event.stopImmediatePropagation()\"\n                #tooltip=\"matTooltip\"\n                (click)=\"tooltip.toggle()\"\n                class=\"more-chip\"\n                [ngStyle]=\"{ left: moreChipPosition }\"\n              >\n                <span [matBadge]=\"hiddenChipNum\" [matBadgeOverlap]=\"false\">\n                  {{\n                    onlyMore\n                      ? ('FRONTEND.STORE.TAGS' | translate)\n                      : ('FRONTEND.STORE.MORE' | translate)\n                  }}\n                </span>\n              </mat-chip>\n            </div>\n          </div>\n        </mat-chip-list>\n      </div>\n\n      <div\n        *ngIf=\"isHeaderActionUsed || isContactActionUsed\"\n        class=\"product-actions-container\"\n      >\n        <button\n          *ngIf=\"isHeaderActionUsed\"\n          mat-raised-button\n          color=\"primary\"\n          [disabled]=\"checkButtonDisable()\"\n          (click)=\"onHeaderActionClicked()\"\n        >\n          <span>{{ getEnableButtonText() }}</span>\n        </button>\n        <a *ngIf=\"isContactActionUsed\" (click)=\"contactActionClick.emit()\">\n          {{ 'FRONTEND.STORE.CONTACT_US' | translate }}\n        </a>\n      </div>\n    </div>\n\n    <ng-template #webLayout>\n      <div class=\"web-container\">\n        <div class=\"icon-container\">\n          <div class=\"icon\">\n            <va-icon\n              [iconUrl]=\"product.iconUrl\"\n              [name]=\"product.name\"\n              [diameter]=\"120\"\n              id=\"thing\"\n            ></va-icon>\n          </div>\n        </div>\n        <div class=\"web-center-container\">\n          <div class=\"web-name-chips-container\">\n            <div class=\"title small-gutter\">{{ product.name }}</div>\n            <div class=\"web-chip-container\">\n              <mat-chip-list>\n                <div class=\"flex-row\">\n                  <div id=\"chipStart\"></div>\n                  <div class=\"chip-list\">\n                    <mat-chip *ngFor=\"let chip of chipLabels\" class=\"chipItem\">\n                      {{ chip }}\n                    </mat-chip>\n                  </div>\n                  <div class=\"more-chip-spacer\">\n                    <mat-chip\n                      *ngIf=\"showMoreChip\"\n                      [matMenuTriggerFor]=\"menu\"\n                      class=\"more-chip\"\n                      [ngStyle]=\"{ left: moreChipPosition }\"\n                    >\n                      <span\n                        [matBadge]=\"hiddenChipNum\"\n                        [matBadgeOverlap]=\"false\"\n                      >\n                        {{\n                          onlyMore\n                            ? ('FRONTEND.STORE.TAGS' | translate)\n                            : ('FRONTEND.STORE.MORE' | translate)\n                        }}\n                      </span>\n                    </mat-chip>\n                    <mat-menu #menu=\"matMenu\">\n                      <button mat-menu-item *ngFor=\"let tag of moreList\">\n                        <li>{{ tag }}</li>\n                      </button>\n                    </mat-menu>\n                  </div>\n                </div>\n              </mat-chip-list>\n            </div>\n          </div>\n          <div class=\"tag-line small-gutter\">\n            {{ product.tagline }}\n          </div>\n        </div>\n        <div\n          *ngIf=\"isHeaderActionUsed || isContactActionUsed\"\n          id=\"web-action-container\"\n          class=\"web-product-actions-container\"\n        >\n          <button\n            *ngIf=\"isHeaderActionUsed\"\n            mat-raised-button\n            color=\"primary\"\n            [disabled]=\"checkButtonDisable()\"\n            (click)=\"onHeaderActionClicked()\"\n          >\n            <span>{{ getEnableButtonText() }}</span>\n          </button>\n          <a *ngIf=\"isContactActionUsed\" (click)=\"contactActionClick.emit()\">\n            {{ 'FRONTEND.STORE.CONTACT_US' | translate }}\n          </a>\n        </div>\n      </div>\n    </ng-template>\n  </div>\n  <ng-container *ngIf=\"tabState$ | async as tabState\">\n    <mat-tab-group\n      [selectedIndex]=\"tabState.tab\"\n      (selectedTabChange)=\"onTabChanged($event)\"\n    >\n      <mat-tab\n        label=\"{{\n          'FRONTEND.STORE.PRODUCT_DETAILS.TAB_LABELS.PRODUCT_INFORMATION'\n            | translate\n        }}\"\n      >\n        <app-product-info\n          [product]=\"product\"\n          [partnerId]=\"partnerId\"\n          [billingPrice]=\"billingPrice\"\n          [marketplaceCost]=\"marketplaceCost\"\n          [marketingType]=\"marketingType\"\n          [isOO]=\"isOO\"\n          [businessCountryCode]=\"businessCountryCode\"\n          [showPricing]=\"true\"\n          [productDependenciesFeatureFlag]=\"productDependenciesFeatureFlag\"\n          (addonSelected)=\"addonSelected.emit($event)\"\n        ></app-product-info>\n      </mat-tab>\n      <mat-tab\n        label=\"{{\n          'FRONTEND.STORE.PRODUCT_DETAILS.TAB_LABELS.SCREENSHOTS_AND_FILES'\n            | translate\n        }}\"\n      >\n        <app-screenshots-files\n          [app]=\"product\"\n          [lightboxRef]=\"lightboxRef\"\n        ></app-screenshots-files>\n      </mat-tab>\n      <mat-tab\n        *ngIf=\"tabState.editionsTabVisible\"\n        label=\"{{\n          'FRONTEND.STORE.PRODUCT_DETAILS.TAB_LABELS.EDITIONS_AND_PRICING'\n            | translate\n        }}\"\n      >\n        <ng-template matTabContent>\n          <app-editions-marketing\n            [contactSales]=\"product.shouldContactSales\"\n            [marketingType]=\"marketingType\"\n            [billingPrice]=\"billingPrice\"\n            [marketplaceCost]=\"marketplaceCost\"\n            [editionsMarketing]=\"editionsMarketing\"\n            [editionOrder]=\"editionOrder\"\n            [isEditionActionUsed]=\"isEditionActionUsed\"\n            (editionActionClick)=\"onEditionActionClicked($event)\"\n          ></app-editions-marketing>\n        </ng-template>\n      </mat-tab>\n    </mat-tab-group>\n  </ng-container>\n</div>\n<va-lightbox #lightboxRef></va-lightbox>\n", styles: [".page{position:relative;margin:0 auto 20px;background:#ffffff;color:#212121;box-shadow:0 3px 10px rgba(33,33,33,.3);overflow:hidden;font-size:16px}:host ::ng-deep div.mat-chip-list-wrapper{display:flex;flex-wrap:nowrap;overflow-x:hidden}:host ::ng-deep div.mat-chip-list-wrapper .mat-chip{flex:0 0 auto;color:gray}:host ::ng-deep div.mat-tab-body-content{background-color:#e0e0e0;padding:12px}@media screen and (max-width: 600px){:host ::ng-deep div.mat-tab-body-content{padding:0}}.background-logo{width:100%;height:200px;background-color:#e0e0e0;display:flex}@media screen and (max-width: 768px){.background-logo{height:150px}}@media screen and (max-width: 600px){.background-logo{height:100px}}.background-logo .defaultBannerImage{height:inherit;margin-left:auto;margin-right:auto}.background-logo .bannerImage{-o-object-fit:cover;object-fit:cover;width:100%;-o-object-position:top;object-position:top}.icon-container{position:relative;width:150px;height:0;margin:0 16px;min-width:150px}.icon{display:flex;align-items:center;justify-content:center;height:150px;width:150px;border:1px solid lightgrey;border-radius:4px;position:absolute;bottom:-59px;background-color:#fff}.icon img{width:75%;height:75%}@media screen and (max-width: 600px){.icon{position:static;position:initial;width:75px;height:75px;min-height:75px;min-width:75px;margin:0;border:none}}.title{font-size:24px;white-space:nowrap}.tag-line{padding-top:8px!important;font-size:16px}.centered-column{display:flex;flex-direction:column;justify-content:center}.small-gutter{padding:0 8px}.flex-row{display:flex;flex-direction:row}.flex-row-center{display:flex;flex-direction:row;justify-content:center}.mobile-container{display:flex;flex-direction:column;padding:8px}.mobile-chip-container{width:100%;padding:16px 16px 0}.web-chip-container{padding:0 8px;max-width:450px}.chip-list{display:flex;flex-flow:row wrap;overflow:hidden;height:40px}.product-actions-container{display:flex;flex-direction:column;justify-content:center;padding:16px}.product-actions-container a{text-align:center;margin-top:16px}.web-product-actions-container{display:flex;flex-direction:column;margin-left:auto;padding-left:8px}.web-product-actions-container a{text-align:center;margin-top:16px}.web-center-container{min-width:300px}.web-container{padding:16px;display:flex}.web-name-chips-container{display:flex;align-content:center}@media screen and (max-width: 768px){.web-name-chips-container{flex-direction:column}}:host ::ng-deep .mat-tooltip{font-size:14px;white-space:pre}.more-chip{overflow:visible;position:absolute}.more-chip-spacer{min-width:77px;overflow:hidden}\n"], components: [{ type: i6.IconComponent, selector: "va-icon", inputs: ["iconUrl", "name", "diameter", "backgroundColor", "borderColor", "fontColor"] }, { type: i7.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button],             button[mat-fab], button[mat-mini-fab], button[mat-stroked-button],             button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i9.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i10.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby"], exportAs: ["matTab"] }, { type: i11.ProductInfoComponent, selector: "app-product-info", inputs: ["product", "partnerId", "billingPrice", "marketplaceCost", "showPricing", "hasVerifiedContract", "canAccessContractPricing", "businessCountryCode", "isOO", "marketingType", "productDependenciesFeatureFlag"], outputs: ["addonSelected"] }, { type: i12.ScreenshotsFilesComponent, selector: "app-screenshots-files", inputs: ["app", "clickable", "lightboxRef"] }, { type: i13.EditionsMarketingComponent, selector: "app-editions-marketing", inputs: ["contactSales", "marketingType", "billingPrice", "marketplaceCost", "editionsMarketing", "editionOrder", "isEditionActionUsed"], outputs: ["editionActionClick"] }, { type: i6.VaLightboxComponent, selector: "va-lightbox", inputs: ["useSrcSet"] }], directives: [{ type: i14.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i15.DefaultStyleDirective, selector: "  [ngStyle],  [ngStyle.xs], [ngStyle.sm], [ngStyle.md], [ngStyle.lg], [ngStyle.xl],  [ngStyle.lt-sm], [ngStyle.lt-md], [ngStyle.lt-lg], [ngStyle.lt-xl],  [ngStyle.gt-xs], [ngStyle.gt-sm], [ngStyle.gt-md], [ngStyle.gt-lg]", inputs: ["ngStyle", "ngStyle.xs", "ngStyle.sm", "ngStyle.md", "ngStyle.lg", "ngStyle.xl", "ngStyle.lt-sm", "ngStyle.lt-md", "ngStyle.lt-lg", "ngStyle.lt-xl", "ngStyle.gt-xs", "ngStyle.gt-sm", "ngStyle.gt-md", "ngStyle.gt-lg"] }, { type: i14.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i14.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i16.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i17.MatBadge, selector: "[matBadge]", inputs: ["matBadgeDisabled", "matBadgeColor", "matBadgeOverlap", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i10.MatTabContent, selector: "[matTabContent]" }], pipes: { "translate": i3.TranslatePipe, "async": i14.AsyncPipe } });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: VaProductDetailsV2Component, decorators: [{
            type: Component,
            args: [{ selector: 'app-product-details-v2', template: "<div class=\"page\" [ngStyle]=\"{ 'min-height': tabScrollHack }\">\n  <ng-container *ngIf=\"product.headerImageUrl; else defaultBanner\">\n    <div class=\"background-logo\">\n      <img\n        [src]=\"product.headerImageUrl\"\n        [srcset]=\"srcsetHeaderImage\"\n        class=\"bannerImage\"\n      />\n    </div>\n  </ng-container>\n\n  <ng-template #defaultBanner>\n    <div class=\"background-logo\">\n      <img [src]=\"defaultHeaderImage\" class=\"defaultBannerImage\" />\n    </div>\n  </ng-template>\n  <div>\n    <div *ngIf=\"mobileLayout; else webLayout\" class=\"mobile-container\">\n      <div class=\"flex-row\">\n        <div class=\"icon\">\n          <va-icon\n            [iconUrl]=\"product.iconUrl\"\n            [name]=\"product.name\"\n            [diameter]=\"60\"\n          ></va-icon>\n        </div>\n        <div class=\"centered-column\">\n          <div class=\"title\">{{ product.name }}</div>\n          <div class=\"tag-line\">{{ product.tagline }}</div>\n        </div>\n      </div>\n      <div class=\"mobile-chip-container\">\n        <mat-chip-list>\n          <div class=\"flex-row\">\n            <div id=\"chipStart\"></div>\n            <div class=\"chip-list\">\n              <mat-chip *ngFor=\"let chip of chipLabels\" class=\"chipItem\">\n                {{ chip }}\n              </mat-chip>\n            </div>\n            <div class=\"more-chip-spacer\">\n              <mat-chip\n                *ngIf=\"showMoreChip\"\n                [matTooltip]=\"overflowTagsList\"\n                (mouseenter)=\"$event.stopImmediatePropagation()\"\n                (mouseleave)=\"$event.stopImmediatePropagation()\"\n                #tooltip=\"matTooltip\"\n                (click)=\"tooltip.toggle()\"\n                class=\"more-chip\"\n                [ngStyle]=\"{ left: moreChipPosition }\"\n              >\n                <span [matBadge]=\"hiddenChipNum\" [matBadgeOverlap]=\"false\">\n                  {{\n                    onlyMore\n                      ? ('FRONTEND.STORE.TAGS' | translate)\n                      : ('FRONTEND.STORE.MORE' | translate)\n                  }}\n                </span>\n              </mat-chip>\n            </div>\n          </div>\n        </mat-chip-list>\n      </div>\n\n      <div\n        *ngIf=\"isHeaderActionUsed || isContactActionUsed\"\n        class=\"product-actions-container\"\n      >\n        <button\n          *ngIf=\"isHeaderActionUsed\"\n          mat-raised-button\n          color=\"primary\"\n          [disabled]=\"checkButtonDisable()\"\n          (click)=\"onHeaderActionClicked()\"\n        >\n          <span>{{ getEnableButtonText() }}</span>\n        </button>\n        <a *ngIf=\"isContactActionUsed\" (click)=\"contactActionClick.emit()\">\n          {{ 'FRONTEND.STORE.CONTACT_US' | translate }}\n        </a>\n      </div>\n    </div>\n\n    <ng-template #webLayout>\n      <div class=\"web-container\">\n        <div class=\"icon-container\">\n          <div class=\"icon\">\n            <va-icon\n              [iconUrl]=\"product.iconUrl\"\n              [name]=\"product.name\"\n              [diameter]=\"120\"\n              id=\"thing\"\n            ></va-icon>\n          </div>\n        </div>\n        <div class=\"web-center-container\">\n          <div class=\"web-name-chips-container\">\n            <div class=\"title small-gutter\">{{ product.name }}</div>\n            <div class=\"web-chip-container\">\n              <mat-chip-list>\n                <div class=\"flex-row\">\n                  <div id=\"chipStart\"></div>\n                  <div class=\"chip-list\">\n                    <mat-chip *ngFor=\"let chip of chipLabels\" class=\"chipItem\">\n                      {{ chip }}\n                    </mat-chip>\n                  </div>\n                  <div class=\"more-chip-spacer\">\n                    <mat-chip\n                      *ngIf=\"showMoreChip\"\n                      [matMenuTriggerFor]=\"menu\"\n                      class=\"more-chip\"\n                      [ngStyle]=\"{ left: moreChipPosition }\"\n                    >\n                      <span\n                        [matBadge]=\"hiddenChipNum\"\n                        [matBadgeOverlap]=\"false\"\n                      >\n                        {{\n                          onlyMore\n                            ? ('FRONTEND.STORE.TAGS' | translate)\n                            : ('FRONTEND.STORE.MORE' | translate)\n                        }}\n                      </span>\n                    </mat-chip>\n                    <mat-menu #menu=\"matMenu\">\n                      <button mat-menu-item *ngFor=\"let tag of moreList\">\n                        <li>{{ tag }}</li>\n                      </button>\n                    </mat-menu>\n                  </div>\n                </div>\n              </mat-chip-list>\n            </div>\n          </div>\n          <div class=\"tag-line small-gutter\">\n            {{ product.tagline }}\n          </div>\n        </div>\n        <div\n          *ngIf=\"isHeaderActionUsed || isContactActionUsed\"\n          id=\"web-action-container\"\n          class=\"web-product-actions-container\"\n        >\n          <button\n            *ngIf=\"isHeaderActionUsed\"\n            mat-raised-button\n            color=\"primary\"\n            [disabled]=\"checkButtonDisable()\"\n            (click)=\"onHeaderActionClicked()\"\n          >\n            <span>{{ getEnableButtonText() }}</span>\n          </button>\n          <a *ngIf=\"isContactActionUsed\" (click)=\"contactActionClick.emit()\">\n            {{ 'FRONTEND.STORE.CONTACT_US' | translate }}\n          </a>\n        </div>\n      </div>\n    </ng-template>\n  </div>\n  <ng-container *ngIf=\"tabState$ | async as tabState\">\n    <mat-tab-group\n      [selectedIndex]=\"tabState.tab\"\n      (selectedTabChange)=\"onTabChanged($event)\"\n    >\n      <mat-tab\n        label=\"{{\n          'FRONTEND.STORE.PRODUCT_DETAILS.TAB_LABELS.PRODUCT_INFORMATION'\n            | translate\n        }}\"\n      >\n        <app-product-info\n          [product]=\"product\"\n          [partnerId]=\"partnerId\"\n          [billingPrice]=\"billingPrice\"\n          [marketplaceCost]=\"marketplaceCost\"\n          [marketingType]=\"marketingType\"\n          [isOO]=\"isOO\"\n          [businessCountryCode]=\"businessCountryCode\"\n          [showPricing]=\"true\"\n          [productDependenciesFeatureFlag]=\"productDependenciesFeatureFlag\"\n          (addonSelected)=\"addonSelected.emit($event)\"\n        ></app-product-info>\n      </mat-tab>\n      <mat-tab\n        label=\"{{\n          'FRONTEND.STORE.PRODUCT_DETAILS.TAB_LABELS.SCREENSHOTS_AND_FILES'\n            | translate\n        }}\"\n      >\n        <app-screenshots-files\n          [app]=\"product\"\n          [lightboxRef]=\"lightboxRef\"\n        ></app-screenshots-files>\n      </mat-tab>\n      <mat-tab\n        *ngIf=\"tabState.editionsTabVisible\"\n        label=\"{{\n          'FRONTEND.STORE.PRODUCT_DETAILS.TAB_LABELS.EDITIONS_AND_PRICING'\n            | translate\n        }}\"\n      >\n        <ng-template matTabContent>\n          <app-editions-marketing\n            [contactSales]=\"product.shouldContactSales\"\n            [marketingType]=\"marketingType\"\n            [billingPrice]=\"billingPrice\"\n            [marketplaceCost]=\"marketplaceCost\"\n            [editionsMarketing]=\"editionsMarketing\"\n            [editionOrder]=\"editionOrder\"\n            [isEditionActionUsed]=\"isEditionActionUsed\"\n            (editionActionClick)=\"onEditionActionClicked($event)\"\n          ></app-editions-marketing>\n        </ng-template>\n      </mat-tab>\n    </mat-tab-group>\n  </ng-container>\n</div>\n<va-lightbox #lightboxRef></va-lightbox>\n", styles: [".page{position:relative;margin:0 auto 20px;background:#ffffff;color:#212121;box-shadow:0 3px 10px rgba(33,33,33,.3);overflow:hidden;font-size:16px}:host ::ng-deep div.mat-chip-list-wrapper{display:flex;flex-wrap:nowrap;overflow-x:hidden}:host ::ng-deep div.mat-chip-list-wrapper .mat-chip{flex:0 0 auto;color:gray}:host ::ng-deep div.mat-tab-body-content{background-color:#e0e0e0;padding:12px}@media screen and (max-width: 600px){:host ::ng-deep div.mat-tab-body-content{padding:0}}.background-logo{width:100%;height:200px;background-color:#e0e0e0;display:flex}@media screen and (max-width: 768px){.background-logo{height:150px}}@media screen and (max-width: 600px){.background-logo{height:100px}}.background-logo .defaultBannerImage{height:inherit;margin-left:auto;margin-right:auto}.background-logo .bannerImage{-o-object-fit:cover;object-fit:cover;width:100%;-o-object-position:top;object-position:top}.icon-container{position:relative;width:150px;height:0;margin:0 16px;min-width:150px}.icon{display:flex;align-items:center;justify-content:center;height:150px;width:150px;border:1px solid lightgrey;border-radius:4px;position:absolute;bottom:-59px;background-color:#fff}.icon img{width:75%;height:75%}@media screen and (max-width: 600px){.icon{position:static;position:initial;width:75px;height:75px;min-height:75px;min-width:75px;margin:0;border:none}}.title{font-size:24px;white-space:nowrap}.tag-line{padding-top:8px!important;font-size:16px}.centered-column{display:flex;flex-direction:column;justify-content:center}.small-gutter{padding:0 8px}.flex-row{display:flex;flex-direction:row}.flex-row-center{display:flex;flex-direction:row;justify-content:center}.mobile-container{display:flex;flex-direction:column;padding:8px}.mobile-chip-container{width:100%;padding:16px 16px 0}.web-chip-container{padding:0 8px;max-width:450px}.chip-list{display:flex;flex-flow:row wrap;overflow:hidden;height:40px}.product-actions-container{display:flex;flex-direction:column;justify-content:center;padding:16px}.product-actions-container a{text-align:center;margin-top:16px}.web-product-actions-container{display:flex;flex-direction:column;margin-left:auto;padding-left:8px}.web-product-actions-container a{text-align:center;margin-top:16px}.web-center-container{min-width:300px}.web-container{padding:16px;display:flex}.web-name-chips-container{display:flex;align-content:center}@media screen and (max-width: 768px){.web-name-chips-container{flex-direction:column}}:host ::ng-deep .mat-tooltip{font-size:14px;white-space:pre}.more-chip{overflow:visible;position:absolute}.more-chip-spacer{min-width:77px;overflow:hidden}\n"] }]
        }], ctorParameters: function () { return [{ type: i1.ImageTransformationService }, { type: i2.BreakpointObserver }, { type: i3.TranslateService }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [EnvironmentService]
                }] }, { type: i4.Router }, { type: i4.ActivatedRoute }, { type: i5.ProductAnalyticsService }]; }, propDecorators: { product: [{
                type: Input
            }], partnerId: [{
                type: Input
            }], parentProduct: [{
                type: Input
            }], appTags: [{
                type: Input
            }], businessCountryCode: [{
                type: Input
            }], marketingType: [{
                type: Input
            }], billingPrice: [{
                type: Input
            }], marketplaceCost: [{
                type: Input
            }], editionsMarketing: [{
                type: Input
            }], editionOrder: [{
                type: Input
            }], headerActionType: [{
                type: Input
            }], isEditionActionUsed: [{
                type: Input
            }], productDependenciesFeatureFlag: [{
                type: Input
            }], headerActionClick: [{
                type: Output
            }], addonSelected: [{
                type: Output
            }], contactActionClick: [{
                type: Output
            }], editionActionClick: [{
                type: Output
            }], onResize: [{
                type: HostListener,
                args: ['window:resize', ['$event']]
            }] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1kZXRhaWxzLXYyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc3RvcmUvc3JjL2xpYi9wcm9kdWN0LWRldGFpbHMtdjIvcHJvZHVjdC1kZXRhaWxzLXYyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc3RvcmUvc3JjL2xpYi9wcm9kdWN0LWRldGFpbHMtdjIvcHJvZHVjdC1kZXRhaWxzLXYyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUErQixNQUFNLGdCQUFnQixDQUFDO0FBQzlGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzVFLE9BQU8sRUFBd0IsV0FBVyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBYyxhQUFhLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEUsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxnQkFBZ0Is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OzJCQUFDLGtCQUFrQjtvSUFsRG5CLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLDhCQUE4QjtzQkFBdEMsS0FBSztnQkFFSSxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBRUcsa0JBQWtCO3NCQUEzQixNQUFNO2dCQTRKUCxRQUFRO3NCQURQLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnJlYWtwb2ludE9ic2VydmVyLCBCcmVha3BvaW50cyB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9sYXlvdXQnO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRUYWJDaGFuZ2VFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBQcm9kdWN0UHJpY2luZyB9IGZyb20gJ0B2ZW5kYXN0YS9iaWxsaW5nJztcbmltcG9ydCB7IEVudmlyb25tZW50LCBFbnZpcm9ubWVudFNlcnZpY2UsIEVudmlyb25tZW50U2VydmljZUludGVyZmFjZSB9IGZyb20gJ0B2ZW5kYXN0YS9jb3JlJztcbmltcG9ydCB7IEltYWdlVHJhbnNmb3JtYXRpb25TZXJ2aWNlIH0gZnJvbSAnQHZlbmRhc3RhL2ltYWdlLXRyYW5zZm9ybWF0aW9uJztcbmltcG9ydCB7IEFwcEVkaXRpb25zTWFya2V0aW5nLCBQcm9kdWN0Q29zdCB9IGZyb20gJ0B2ZW5kYXN0YS9tYXJrZXRwbGFjZS1hcHBzL3YxJztcbmltcG9ydCB7IFByb2R1Y3RBbmFseXRpY3NTZXJ2aWNlIH0gZnJvbSAnQHZlbmRhc3RhL3Byb2R1Y3QtYW5hbHl0aWNzJztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUsIFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc3RhcnRXaXRoLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgTWFya2V0cGxhY2VBcHBEYXRhIH0gZnJvbSAnLi4vc2hhcmVkL21hcmtldHBsYWNlLWFwcC1kYXRhJztcbmltcG9ydCB7IFByb2R1Y3QgfSBmcm9tICcuLi9zaGFyZWQvcHJvZHVjdCc7XG5pbXBvcnQgeyBIZWFkZXJBY3Rpb25UeXBlIH0gZnJvbSAnLi4vc3RvcmUtaXRlbSc7XG5pbXBvcnQgeyBNYXJrZXRpbmdUeXBlLCBTZWxlY3RlZFRhYiB9IGZyb20gJy4vcHJvZHVjdC1kZXRhaWxzLXYyLmludGVyZmFjZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWRpdGlvbkFjdGlvbkNsaWNrRXZlbnQge1xuICBhcHBJZDogc3RyaW5nO1xuICBlZGl0aW9uSWQ6IHN0cmluZztcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXByb2R1Y3QtZGV0YWlscy12MicsXG4gIHRlbXBsYXRlVXJsOiAnLi9wcm9kdWN0LWRldGFpbHMtdjIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wcm9kdWN0LWRldGFpbHMtdjIuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgVmFQcm9kdWN0RGV0YWlsc1YyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBwcm9kdWN0OiBQcm9kdWN0O1xuICBASW5wdXQoKSBwYXJ0bmVySWQ6IHN0cmluZztcbiAgQElucHV0KCkgcGFyZW50UHJvZHVjdDogUHJvZHVjdDtcbiAgQElucHV0KCkgYXBwVGFnczogTWFya2V0cGxhY2VBcHBEYXRhW107XG4gIEBJbnB1dCgpIGJ1c2luZXNzQ291bnRyeUNvZGU6IHN0cmluZztcbiAgQElucHV0KCkgbWFya2V0aW5nVHlwZTogTWFya2V0aW5nVHlwZSA9IE1hcmtldGluZ1R5cGUuUGFydG5lcjtcbiAgQElucHV0KCkgYmlsbGluZ1ByaWNlOiBQcm9kdWN0UHJpY2luZztcbiAgQElucHV0KCkgbWFya2V0cGxhY2VDb3N0OiBQcm9kdWN0Q29zdDtcbiAgQElucHV0KCkgZWRpdGlvbnNNYXJrZXRpbmc6IEFwcEVkaXRpb25zTWFya2V0aW5nW107XG4gIEBJbnB1dCgpIGVkaXRpb25PcmRlcjogc3RyaW5nW107XG4gIEBJbnB1dCgpIGhlYWRlckFjdGlvblR5cGU6IEhlYWRlckFjdGlvblR5cGU7XG4gIEBJbnB1dCgpIGlzRWRpdGlvbkFjdGlvblVzZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgcHJvZHVjdERlcGVuZGVuY2llc0ZlYXR1cmVGbGFnOiBzdHJpbmc7XG5cbiAgQE91dHB1dCgpIGhlYWRlckFjdGlvbkNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBpc0hlYWRlckFjdGlvblVzZWQ6IGJvb2xlYW47XG4gIEBPdXRwdXQoKSBhZGRvblNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIGlzQWRkb25TZWxlY3RlZFVzZWQ6IGJvb2xlYW47XG4gIEBPdXRwdXQoKSBjb250YWN0QWN0aW9uQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIGlzQ29udGFjdEFjdGlvblVzZWQ6IGJvb2xlYW47XG4gIEBPdXRwdXQoKSBlZGl0aW9uQWN0aW9uQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPEVkaXRpb25BY3Rpb25DbGlja0V2ZW50PigpO1xuXG4gIHRhYlN0YXRlJDogT2JzZXJ2YWJsZTx7IHRhYjogU2VsZWN0ZWRUYWI7IGVkaXRpb25zVGFiVmlzaWJsZTogYm9vbGVhbiB9PjtcbiAgdXBkYXRlU3RhdGUkJCA9IG5ldyBSZXBsYXlTdWJqZWN0PG51bGw+KCk7XG5cbiAgY2hpcExhYmVsczogc3RyaW5nW107XG4gIGFwcFRhZ0Fycjogc3RyaW5nW107XG4gIHNyY3NldEhlYWRlckltYWdlID0gJyc7XG5cbiAgbW9iaWxlTGF5b3V0OiBib29sZWFuO1xuICBvdmVyZmxvd1RhZ3NMaXN0ID0gJyc7XG4gIHNob3dNb3JlQ2hpcCA9IGZhbHNlO1xuICBtb3JlQ2hpcFBvc2l0aW9uID0gJyc7XG4gIGhpZGRlbkNoaXBOdW0gPSAwO1xuICBtb3JlTGlzdCA9IFtdO1xuICBvbmx5TW9yZSA9IGZhbHNlO1xuXG4gIHRhYlNjcm9sbEhhY2s6IHN0cmluZztcbiAgdGFiUmVmOiBhbnk7XG5cbiAgb3duZWRBbmRPcGVyYXRlZDogc3RyaW5nW10gPSBudWxsO1xuICBpc09POiBib29sZWFuO1xuXG4gIHJlYWRvbmx5IGRlZmF1bHRIZWFkZXJJbWFnZSA9XG4gICAgJ2h0dHBzOi8vZmlyZWJhc2VzdG9yYWdlLmdvb2dsZWFwaXMuY29tL3YwL2IvcGFydG5lci1jZW50cmFsLWRlbW8uYXBwc3BvdC5jb20vby9uby1iYW5uZXIucG5nP2FsdD1tZWRpYSZ0b2tlbj1lNTI5OTA2Mi1lYTIwLTQ5OGItYjM3ZS0zOWYzY2Y4YTc4YTgnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaW1hZ2VUcmFuc2Zvcm1hdGlvblNlcnZpY2U6IEltYWdlVHJhbnNmb3JtYXRpb25TZXJ2aWNlLFxuICAgIGJyZWFrcG9pbnRPYnNlcnZlcjogQnJlYWtwb2ludE9ic2VydmVyLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBASW5qZWN0KEVudmlyb25tZW50U2VydmljZSkgcHJpdmF0ZSBlbnZpcm9ubWVudFNlcnZpY2U6IEVudmlyb25tZW50U2VydmljZUludGVyZmFjZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgc25vd3Bsb3dTZXJ2aWNlOiBQcm9kdWN0QW5hbHl0aWNzU2VydmljZSxcbiAgKSB7XG4gICAgYnJlYWtwb2ludE9ic2VydmVyLm9ic2VydmUoW0JyZWFrcG9pbnRzLkhhbmRzZXRQb3J0cmFpdF0pLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0Lm1hdGNoZXMpIHtcbiAgICAgICAgdGhpcy5tb2JpbGVMYXlvdXQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tb2JpbGVMYXlvdXQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0T3duZWRPcGVyYXRlZExpc3QoKTtcbiAgICB0aGlzLmlzSGVhZGVyQWN0aW9uVXNlZCA9XG4gICAgICB0aGlzLmhlYWRlckFjdGlvblR5cGUgIT09IEhlYWRlckFjdGlvblR5cGUuTk9ORSAmJiB0aGlzLmhlYWRlckFjdGlvbkNsaWNrLm9ic2VydmVycy5sZW5ndGggPiAwO1xuICAgIHRoaXMuaXNBZGRvblNlbGVjdGVkVXNlZCA9IHRoaXMuYWRkb25TZWxlY3RlZC5vYnNlcnZlcnMubGVuZ3RoID4gMDtcbiAgICB0aGlzLmlzQ29udGFjdEFjdGlvblVzZWQgPSB0aGlzLmNvbnRhY3RBY3Rpb25DbGljay5vYnNlcnZlcnMubGVuZ3RoID4gMDtcbiAgICBpZiAoISF0aGlzLmFwcFRhZ3MgJiYgdGhpcy5hcHBUYWdzLmxlbmd0aCAmJiAhIXRoaXMuYXBwVGFnc1swXS5hcHBEYXRhKSB7XG4gICAgICB0aGlzLmFwcFRhZ0FyciA9IFtdO1xuICAgICAgdGhpcy5hcHBUYWdzWzBdLmFwcERhdGEuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVudHJ5LmtpbmQuc3RhcnRzV2l0aCgndGFnJykgJiZcbiAgICAgICAgICBlbnRyeS5raW5kICE9PSAndGFnL2NvdW50cnknICYmXG4gICAgICAgICAgZW50cnkua2luZCAhPT0gJ3RhZy9zb3VyY2UnICYmXG4gICAgICAgICAgZW50cnkua2luZCAhPT0gJ3RhZy92ZW5kb3InXG4gICAgICAgICkge1xuICAgICAgICAgIGVudHJ5LnZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2FwaXRhbGl6ZWQgPSB2YWx1ZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHZhbHVlLnNsaWNlKDEpLnJlcGxhY2UoL18vZywgJyAnKTtcbiAgICAgICAgICAgIHRoaXMuYXBwVGFnQXJyID0gdGhpcy5hcHBUYWdBcnIuY29uY2F0KGNhcGl0YWxpemVkKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLmNoaXBMYWJlbHMgPSB0aGlzLmFwcFRhZ0FycjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jaGlwTGFiZWxzID0gdGhpcy5nZXRUYWdzKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnByb2R1Y3QuaGVhZGVySW1hZ2VVcmwpIHtcbiAgICAgIGNvbnN0IGltYWdlV2lkdGhTaXplcyA9IFs2ODAsIDkwMCwgMTIwMF07XG4gICAgICB0aGlzLnNyY3NldEhlYWRlckltYWdlID0gdGhpcy5pbWFnZVRyYW5zZm9ybWF0aW9uU2VydmljZS5nZXRTcmNTZXRGb3JJbWFnZShcbiAgICAgICAgdGhpcy5wcm9kdWN0LmhlYWRlckltYWdlVXJsLFxuICAgICAgICBpbWFnZVdpZHRoU2l6ZXMsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodGhpcy5vd25lZEFuZE9wZXJhdGVkKSB7XG4gICAgICB0aGlzLmlzT08gPSB0aGlzLm93bmVkQW5kT3BlcmF0ZWQuaW5jbHVkZXModGhpcy5wcm9kdWN0LnByb2R1Y3RJZCk7XG4gICAgfVxuXG4gICAgdGhpcy50YWJTdGF0ZSQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLCB0aGlzLnVwZGF0ZVN0YXRlJCRdKS5waXBlKFxuICAgICAgbWFwKChbcGFyYW1zLCBfXSkgPT4ge1xuICAgICAgICBjb25zdCB0YWJJbmRleDogbnVtYmVyID0gTnVtYmVyKHBhcmFtc1sndGFiJ10pO1xuICAgICAgICBsZXQgc2VsZWN0ZWRUYWIgPSAhU2VsZWN0ZWRUYWJbdGFiSW5kZXhdID8gU2VsZWN0ZWRUYWIuUHJvZHVjdEluZm9ybWF0aW9uIDogdGFiSW5kZXg7XG4gICAgICAgIGlmICghdGhpcy5lZGl0aW9uc01hcmtldGluZyAmJiBzZWxlY3RlZFRhYiA9PT0gU2VsZWN0ZWRUYWIuRWRpdGlvbnNBbmRQcmljaW5nKSB7XG4gICAgICAgICAgc2VsZWN0ZWRUYWIgPSBTZWxlY3RlZFRhYi5TY3JlZW5zaG90c0FuZEZpbGVzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGFiOiBzZWxlY3RlZFRhYixcbiAgICAgICAgICBlZGl0aW9uc1RhYlZpc2libGU6IHRoaXMuZWRpdGlvbnNNYXJrZXRpbmc/Lmxlbmd0aCA+IDAsXG4gICAgICAgIH07XG4gICAgICB9KSxcbiAgICAgIHN0YXJ0V2l0aCh7XG4gICAgICAgIHRhYjogU2VsZWN0ZWRUYWIuUHJvZHVjdEluZm9ybWF0aW9uLFxuICAgICAgICBlZGl0aW9uc1RhYlZpc2libGU6IHRoaXMuZWRpdGlvbnNNYXJrZXRpbmc/Lmxlbmd0aCA+IDAsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kZXRlY3RXcmFwKCdjaGlwSXRlbScpO1xuICAgICAgdGhpcy5vblRhYkNoYW5nZWQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlU3RhdGUkJC5uZXh0KG51bGwpO1xuICB9XG5cbiAgc2V0T3duZWRPcGVyYXRlZExpc3QoKTogdm9pZCB7XG4gICAgc3dpdGNoICh0aGlzLmVudmlyb25tZW50U2VydmljZS5nZXRFbnZpcm9ubWVudCgpKSB7XG4gICAgICBjYXNlIEVudmlyb25tZW50LlBST0Q6IHtcbiAgICAgICAgdGhpcy5vd25lZEFuZE9wZXJhdGVkID0gW1xuICAgICAgICAgICdSTScsIC8vIHJlcCBtYW5cbiAgICAgICAgICAnU00nLCAvLyBzb2NpYWwgbWFya2V0aW5nXG4gICAgICAgICAgJ01QLTk0MDcyZTQ0ZDUzNjQ4NzJiNjcyZDdhYjRmYzdhN2U4JywgLy8gYWQgaW50ZWxcbiAgICAgICAgICAnTVAtYzQ5NzRkMzkwYTA0NGMyOGFlYzMxZTQyMWFhNjYyYjInLCAvLyBjdXN0b21lciB2b2ljZVxuICAgICAgICAgICdNUC1lZTRlYTA0ZTU1M2E0YjE3ODBjYWY3YWFkN2JlMDdjZCcsIC8vIHdlYnNpdGVcbiAgICAgICAgXTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIEVudmlyb25tZW50LkRFTU86IHtcbiAgICAgICAgdGhpcy5vd25lZEFuZE9wZXJhdGVkID0gW1xuICAgICAgICAgICdSTScsIC8vIHJlcCBtYW5cbiAgICAgICAgICAnU00nLCAvLyBzb2NpYWwgbWFya2V0aW5nXG4gICAgICAgICAgJ01QLTk0MDcyZTQ0ZDUzNjQ4NzJiNjcyZDdhYjRmYzdhN2U4JywgLy8gYWQgaW50ZWxcbiAgICAgICAgICAnTVAtZmJhMjExMjFiNzExNDhjOWJiMzNlMTFmY2Q5MmQ1MjAnLCAvLyBjdXN0b21lciB2b2ljZVxuICAgICAgICAgICdNUC05Y2M5ZjIxZjBhMjM0YTQ2YWQ3ODA4N2ZjMDlmMTZiYycsIC8vIHdlYnNpdGVcbiAgICAgICAgXTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHRoaXMub3duZWRBbmRPcGVyYXRlZCA9IFtcbiAgICAgICAgICAnUk0nLCAvLyByZXAgbWFuXG4gICAgICAgICAgJ1NNJywgLy8gc29jaWFsIG1hcmtldGluZ1xuICAgICAgICAgICdNUC05NDA3MmU0NGQ1MzY0ODcyYjY3MmQ3YWI0ZmM3YTdlOCcsIC8vIGFkIGludGVsXG4gICAgICAgICAgJ01QLWZiYTIxMTIxYjcxMTQ4YzliYjMzZTExZmNkOTJkNTIwJywgLy8gY3VzdG9tZXIgdm9pY2VcbiAgICAgICAgICAnTVAtOWNjOWYyMWYwYTIzNGE0NmFkNzgwODdmYzA5ZjE2YmMnLCAvLyB3ZWJzaXRlXG4gICAgICAgIF07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vICBXaWxsIGJlIGRlcHJlY2F0ZWQgd2hlbiB0aGUgbmV3IHRhZ2dpbmcgc3lzdGVtIGlzIGZ1bGx5IGltcGxlbWVudGVkXG4gIGdldFRhZ3MoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHRhZ3MgPSBbXTtcbiAgICBpZiAodGhpcy5wcm9kdWN0LnRyaWFsQ29uZmlndXJhdGlvbj8udHJpYWxFbmFibGVkKSB7XG4gICAgICB0YWdzLnB1c2goJ0ZyZWUgVHJpYWwnKTtcbiAgICB9XG4gICAgdGFncy5wdXNoKC4uLnRoaXMucHJvZHVjdC5nZXRMbWlDYXRlZ29yeU5hbWVzKCkpO1xuICAgIHJldHVybiB0YWdzO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gIG9uUmVzaXplKGV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5kZXRlY3RXcmFwKCdjaGlwSXRlbScpO1xuICB9XG5cbiAgZGV0ZWN0V3JhcChjbGFzc05hbWUpOiB2b2lkIHtcbiAgICBjb25zdCB3cmFwcGVkSXRlbXM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgaXRlbXMgPSBBcnJheS5mcm9tKGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKSk7XG5cbiAgICBjb25zdCBpbml0aWFsRWwgPSBpdGVtc1swXTtcbiAgICBpZiAoIWluaXRpYWxFbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbml0aWFsQm91bmRzID0gaW5pdGlhbEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGl0ZW1zTGVuZ3RoID0gaXRlbXMubGVuZ3RoO1xuICAgIGxldCBicmVha0luZGV4ID0gaXRlbXNMZW5ndGg7XG5cbiAgICBpdGVtcy5mb3JFYWNoKChpdGVtRWw6IEhUTUxFbGVtZW50LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgYm91bmRzID0gaXRlbUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgaWYgKGluaXRpYWxCb3VuZHMudG9wIDwgYm91bmRzLnRvcCkge1xuICAgICAgICB3cmFwcGVkSXRlbXMucHVzaChpdGVtRWwudGV4dENvbnRlbnQpO1xuICAgICAgICBpZiAoYnJlYWtJbmRleCA9PT0gaXRlbXNMZW5ndGgpIHtcbiAgICAgICAgICBicmVha0luZGV4ID0gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCBicmVha0l0ZW07XG4gICAgaWYgKGJyZWFrSW5kZXggPT09IDEgJiYgdGhpcy5kZXRlY3RNb3JlQ2xpcCgpKSB7XG4gICAgICBicmVha0l0ZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hpcFN0YXJ0Jyk7XG4gICAgICB3cmFwcGVkSXRlbXMucHVzaCgoPEhUTUxFbGVtZW50Pml0ZW1zWzBdKS50ZXh0Q29udGVudCk7XG4gICAgICAoPEhUTUxFbGVtZW50Pml0ZW1zWzBdKS5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgICB0aGlzLm9ubHlNb3JlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWtJdGVtID0gPEhUTUxFbGVtZW50Pml0ZW1zW2JyZWFrSW5kZXggLSAxXTtcbiAgICAgICg8SFRNTEVsZW1lbnQ+aXRlbXNbMF0pLnN0eWxlLnZpc2liaWxpdHkgPSAndmlzaWJsZSc7XG4gICAgICB0aGlzLm9ubHlNb3JlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy5zaG93TW9yZUNoaXAgPSB3cmFwcGVkSXRlbXMubGVuZ3RoID4gMDtcbiAgICB0aGlzLmhpZGRlbkNoaXBOdW0gPSB3cmFwcGVkSXRlbXMubGVuZ3RoO1xuICAgIHRoaXMubW9yZUNoaXBQb3NpdGlvbiA9IGJyZWFrSXRlbS5vZmZzZXRMZWZ0ICsgYnJlYWtJdGVtLm9mZnNldFdpZHRoICsgNCArICdweCc7XG4gICAgdGhpcy5tb3JlTGlzdCA9IHdyYXBwZWRJdGVtcztcbiAgfVxuXG4gIGRldGVjdE1vcmVDbGlwKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG1vcmVDaGlwID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbW9yZS1jaGlwLXNwYWNlcicpWzBdO1xuICAgIGNvbnN0IHdlYkFjdGlvbkNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd3ZWItYWN0aW9uLWNvbnRhaW5lcicpO1xuICAgIGNvbnN0IGNoaXBMaXN0V3JhcHBlciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ21hdC1jaGlwLWxpc3Qtd3JhcHBlcicpWzBdIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICh3ZWJBY3Rpb25Db250YWluZXIpIHtcbiAgICAgIGNvbnN0IGFjdGlvbkNvbnRhaW5lckJvdW5kcyA9IHdlYkFjdGlvbkNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHJldHVybiAhKG1vcmVDaGlwLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0IDwgYWN0aW9uQ29udGFpbmVyQm91bmRzLmxlZnQpO1xuICAgIH0gZWxzZSBpZiAoY2hpcExpc3RXcmFwcGVyLnNjcm9sbFdpZHRoID4gY2hpcExpc3RXcmFwcGVyLm9mZnNldFdpZHRoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlzUHJvZHVjdEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMucGFyZW50UHJvZHVjdCkge1xuICAgICAgcmV0dXJuICF0aGlzLnBhcmVudFByb2R1Y3QuaXNBcmNoaXZlZCAmJiB0aGlzLnByb2R1Y3QgJiYgIXRoaXMucHJvZHVjdC5pc0FyY2hpdmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9kdWN0ICYmICF0aGlzLnByb2R1Y3QuaXNBcmNoaXZlZDtcbiAgICB9XG4gIH1cblxuICBpc1Byb2R1Y3RTdXNwZW5kZWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMucGFyZW50UHJvZHVjdCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyZW50UHJvZHVjdC5pc1N1c3BlbmRlZCAmJiB0aGlzLnByb2R1Y3QgJiYgdGhpcy5wcm9kdWN0LmlzU3VzcGVuZGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9kdWN0ICYmIHRoaXMucHJvZHVjdC5pc1N1c3BlbmRlZDtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBSZXNvbHZlcyB0aGUgc3RyaW5nIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBFbmFibGUgYnV0dG9uLlxuICAgKi9cbiAgZ2V0RW5hYmxlQnV0dG9uVGV4dCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHR1cm5PbkFwcFRyYW5zbGF0aW9uS2V5ID0gJ0ZST05URU5ELlNUT1JFLlNUT1JFX1NUQVRFLlNUQVJUX1NFTExJTkcnO1xuICAgIGNvbnN0IHByb2R1Y3RBbHJlYWR5T25UcmFuc2xhdGlvbktleSA9ICdGUk9OVEVORC5TVE9SRS5TVE9SRV9TVEFURS5TRUxMSU5HJztcbiAgICBjb25zdCB0dXJuT25BZGRPblRyYW5zbGF0aW9uS2V5ID0gJ0ZST05URU5ELlNUT1JFLlNUT1JFX1NUQVRFLkFERF9PTi5TVEFSVF9TRUxMSU5HJztcbiAgICBpZiAodGhpcy5oZWFkZXJBY3Rpb25UeXBlID09PSBIZWFkZXJBY3Rpb25UeXBlLkFERF9UT19DQVJUKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoJ0ZST05URU5ELlNUT1JFLkFERF9UT19DQVJUJyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmhlYWRlckFjdGlvblR5cGUgPT09IEhlYWRlckFjdGlvblR5cGUuQlVZX0lUX05PVykge1xuICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KCdGUk9OVEVORC5TVE9SRS5CVVlfSVRfTk9XJyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmhlYWRlckFjdGlvblR5cGUgPT09IEhlYWRlckFjdGlvblR5cGUuTk9ORSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzUHJvZHVjdEVuYWJsZWQoKSkge1xuICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KHByb2R1Y3RBbHJlYWR5T25UcmFuc2xhdGlvbktleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnBhcmVudFByb2R1Y3QpIHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50UHJvZHVjdC5pc0FyY2hpdmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KHR1cm5PbkFwcFRyYW5zbGF0aW9uS2V5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQodHVybk9uQWRkT25UcmFuc2xhdGlvbktleSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCh0dXJuT25BcHBUcmFuc2xhdGlvbktleSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY2hlY2tCdXR0b25EaXNhYmxlKCk6IGJvb2xlYW4ge1xuICAgIGlmIChcbiAgICAgIHRoaXMuaGVhZGVyQWN0aW9uVHlwZSA9PT0gSGVhZGVyQWN0aW9uVHlwZS5BRERfVE9fQ0FSVCB8fFxuICAgICAgdGhpcy5oZWFkZXJBY3Rpb25UeXBlID09PSBIZWFkZXJBY3Rpb25UeXBlLkJVWV9JVF9OT1dcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaXNQcm9kdWN0RW5hYmxlZCgpIHx8IHRoaXMuaXNQcm9kdWN0U3VzcGVuZGVkKCk7XG4gICAgfVxuICB9XG5cbiAgb25IZWFkZXJBY3Rpb25DbGlja2VkKCk6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHRoaXMuaGVhZGVyQWN0aW9uVHlwZSA9PT0gSGVhZGVyQWN0aW9uVHlwZS5CVVlfSVRfTk9XIHx8XG4gICAgICB0aGlzLmhlYWRlckFjdGlvblR5cGUgPT09IEhlYWRlckFjdGlvblR5cGUuQUREX1RPX0NBUlRcbiAgICApIHtcbiAgICAgIGNvbnN0IGxhYmVsID0gdGhpcy5lZGl0aW9uc01hcmtldGluZz8ubGVuZ3RoID4gMCA/ICdlZGl0aW9uZWQtcHJvZHVjdCcgOiAnZWRpdGlvbmxlc3MtcHJvZHVjdCc7XG4gICAgICB0aGlzLnNub3dwbG93U2VydmljZS50cmFja0NsaWNrKCdzdG9yZTphcHAtdmlldycsIGBhZGQtJHtsYWJlbH1gLCB0aGlzLnByb2R1Y3QucHJvZHVjdElkKTtcbiAgICB9XG4gICAgdGhpcy5oZWFkZXJBY3Rpb25DbGljay5lbWl0KCk7XG4gIH1cblxuICBvbkVkaXRpb25BY3Rpb25DbGlja2VkKHByb2R1Y3Q6IHsgYXBwSWQ6IHN0cmluZzsgZWRpdGlvbklkOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgIGNvbnN0IHByb3BlcnR5ID0gYCR7cHJvZHVjdC5hcHBJZH06JHtwcm9kdWN0LmVkaXRpb25JZH1gO1xuICAgIHRoaXMuc25vd3Bsb3dTZXJ2aWNlLnRyYWNrQ2xpY2soJ3N0b3JlOmVkaXRpb25zLXRhYicsICdhZGQtZWRpdGlvbmVkLXByb2R1Y3QnLCBwcm9wZXJ0eSk7XG4gICAgdGhpcy5lZGl0aW9uQWN0aW9uQ2xpY2suZW1pdChwcm9kdWN0KTtcbiAgfVxuXG4gIG9uVGFiQ2hhbmdlZChldmVudD86IE1hdFRhYkNoYW5nZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKChxdWVyeVBhcmFtcykgPT5cbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW10sIHtcbiAgICAgICAgICBxdWVyeVBhcmFtczoge1xuICAgICAgICAgICAgLi4ucXVlcnlQYXJhbXMsXG4gICAgICAgICAgICB0YWI6IGV2ZW50LmluZGV4LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy50YWJSZWYgPSBBcnJheS5mcm9tKGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ21hdC10YWItYm9keS1hY3RpdmUnKSk7XG4gICAgLy8gaGFjayB0byBmaXggbWF0LXRhYiBidWcgb2Ygc2Nyb2xsaW5nIHRvIHRvcCBvZiBwYWdlIG9uIHRhYiBzd2l0Y2hcbiAgICB0aGlzLnRhYlNjcm9sbEhhY2sgPSB0aGlzLnRhYlJlZlswXT8uY2xpZW50SGVpZ2h0ICsgMzY5ICsgJ3B4Oyc7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJwYWdlXCIgW25nU3R5bGVdPVwieyAnbWluLWhlaWdodCc6IHRhYlNjcm9sbEhhY2sgfVwiPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicHJvZHVjdC5oZWFkZXJJbWFnZVVybDsgZWxzZSBkZWZhdWx0QmFubmVyXCI+XG4gICAgPGRpdiBjbGFzcz1cImJhY2tncm91bmQtbG9nb1wiPlxuICAgICAgPGltZ1xuICAgICAgICBbc3JjXT1cInByb2R1Y3QuaGVhZGVySW1hZ2VVcmxcIlxuICAgICAgICBbc3Jjc2V0XT1cInNyY3NldEhlYWRlckltYWdlXCJcbiAgICAgICAgY2xhc3M9XCJiYW5uZXJJbWFnZVwiXG4gICAgICAvPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bmctdGVtcGxhdGUgI2RlZmF1bHRCYW5uZXI+XG4gICAgPGRpdiBjbGFzcz1cImJhY2tncm91bmQtbG9nb1wiPlxuICAgICAgPGltZyBbc3JjXT1cImRlZmF1bHRIZWFkZXJJbWFnZVwiIGNsYXNzPVwiZGVmYXVsdEJhbm5lckltYWdlXCIgLz5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbiAgPGRpdj5cbiAgICA8ZGl2ICpuZ0lmPVwibW9iaWxlTGF5b3V0OyBlbHNlIHdlYkxheW91dFwiIGNsYXNzPVwibW9iaWxlLWNvbnRhaW5lclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXgtcm93XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+XG4gICAgICAgICAgPHZhLWljb25cbiAgICAgICAgICAgIFtpY29uVXJsXT1cInByb2R1Y3QuaWNvblVybFwiXG4gICAgICAgICAgICBbbmFtZV09XCJwcm9kdWN0Lm5hbWVcIlxuICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjYwXCJcbiAgICAgICAgICA+PC92YS1pY29uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlcmVkLWNvbHVtblwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aXRsZVwiPnt7IHByb2R1Y3QubmFtZSB9fTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWctbGluZVwiPnt7IHByb2R1Y3QudGFnbGluZSB9fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm1vYmlsZS1jaGlwLWNvbnRhaW5lclwiPlxuICAgICAgICA8bWF0LWNoaXAtbGlzdD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1yb3dcIj5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJjaGlwU3RhcnRcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGlwLWxpc3RcIj5cbiAgICAgICAgICAgICAgPG1hdC1jaGlwICpuZ0Zvcj1cImxldCBjaGlwIG9mIGNoaXBMYWJlbHNcIiBjbGFzcz1cImNoaXBJdGVtXCI+XG4gICAgICAgICAgICAgICAge3sgY2hpcCB9fVxuICAgICAgICAgICAgICA8L21hdC1jaGlwPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9yZS1jaGlwLXNwYWNlclwiPlxuICAgICAgICAgICAgICA8bWF0LWNoaXBcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dNb3JlQ2hpcFwiXG4gICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwib3ZlcmZsb3dUYWdzTGlzdFwiXG4gICAgICAgICAgICAgICAgKG1vdXNlZW50ZXIpPVwiJGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgICAobW91c2VsZWF2ZSk9XCIkZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgICAgICN0b29sdGlwPVwibWF0VG9vbHRpcFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvb2x0aXAudG9nZ2xlKClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwibW9yZS1jaGlwXCJcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7IGxlZnQ6IG1vcmVDaGlwUG9zaXRpb24gfVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBbbWF0QmFkZ2VdPVwiaGlkZGVuQ2hpcE51bVwiIFttYXRCYWRnZU92ZXJsYXBdPVwiZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICAgIG9ubHlNb3JlXG4gICAgICAgICAgICAgICAgICAgICAgPyAoJ0ZST05URU5ELlNUT1JFLlRBR1MnIHwgdHJhbnNsYXRlKVxuICAgICAgICAgICAgICAgICAgICAgIDogKCdGUk9OVEVORC5TVE9SRS5NT1JFJyB8IHRyYW5zbGF0ZSlcbiAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L21hdC1jaGlwPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LWNoaXAtbGlzdD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0lmPVwiaXNIZWFkZXJBY3Rpb25Vc2VkIHx8IGlzQ29udGFjdEFjdGlvblVzZWRcIlxuICAgICAgICBjbGFzcz1cInByb2R1Y3QtYWN0aW9ucy1jb250YWluZXJcIlxuICAgICAgPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCJpc0hlYWRlckFjdGlvblVzZWRcIlxuICAgICAgICAgIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiY2hlY2tCdXR0b25EaXNhYmxlKClcIlxuICAgICAgICAgIChjbGljayk9XCJvbkhlYWRlckFjdGlvbkNsaWNrZWQoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8c3Bhbj57eyBnZXRFbmFibGVCdXR0b25UZXh0KCkgfX08L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YSAqbmdJZj1cImlzQ29udGFjdEFjdGlvblVzZWRcIiAoY2xpY2spPVwiY29udGFjdEFjdGlvbkNsaWNrLmVtaXQoKVwiPlxuICAgICAgICAgIHt7ICdGUk9OVEVORC5TVE9SRS5DT05UQUNUX1VTJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2E+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxuZy10ZW1wbGF0ZSAjd2ViTGF5b3V0PlxuICAgICAgPGRpdiBjbGFzcz1cIndlYi1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImljb24tY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImljb25cIj5cbiAgICAgICAgICAgIDx2YS1pY29uXG4gICAgICAgICAgICAgIFtpY29uVXJsXT1cInByb2R1Y3QuaWNvblVybFwiXG4gICAgICAgICAgICAgIFtuYW1lXT1cInByb2R1Y3QubmFtZVwiXG4gICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxMjBcIlxuICAgICAgICAgICAgICBpZD1cInRoaW5nXCJcbiAgICAgICAgICAgID48L3ZhLWljb24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwid2ViLWNlbnRlci1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwid2ViLW5hbWUtY2hpcHMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGUgc21hbGwtZ3V0dGVyXCI+e3sgcHJvZHVjdC5uYW1lIH19PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2ViLWNoaXAtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxtYXQtY2hpcC1saXN0PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImNoaXBTdGFydFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoaXAtbGlzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNoaXAgKm5nRm9yPVwibGV0IGNoaXAgb2YgY2hpcExhYmVsc1wiIGNsYXNzPVwiY2hpcEl0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBjaGlwIH19XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoaXA+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb3JlLWNoaXAtc3BhY2VyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtY2hpcFxuICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2hvd01vcmVDaGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICBbbWF0TWVudVRyaWdnZXJGb3JdPVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtb3JlLWNoaXBcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgbGVmdDogbW9yZUNoaXBQb3NpdGlvbiB9XCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWF0QmFkZ2VdPVwiaGlkZGVuQ2hpcE51bVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWF0QmFkZ2VPdmVybGFwXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5TW9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKCdGUk9OVEVORC5TVE9SRS5UQUdTJyB8IHRyYW5zbGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgnRlJPTlRFTkQuU1RPUkUuTU9SRScgfCB0cmFuc2xhdGUpXG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hpcD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1tZW51ICNtZW51PVwibWF0TWVudVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAqbmdGb3I9XCJsZXQgdGFnIG9mIG1vcmVMaXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGk+e3sgdGFnIH19PC9saT5cbiAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtbWVudT5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L21hdC1jaGlwLWxpc3Q+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFnLWxpbmUgc21hbGwtZ3V0dGVyXCI+XG4gICAgICAgICAgICB7eyBwcm9kdWN0LnRhZ2xpbmUgfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdJZj1cImlzSGVhZGVyQWN0aW9uVXNlZCB8fCBpc0NvbnRhY3RBY3Rpb25Vc2VkXCJcbiAgICAgICAgICBpZD1cIndlYi1hY3Rpb24tY29udGFpbmVyXCJcbiAgICAgICAgICBjbGFzcz1cIndlYi1wcm9kdWN0LWFjdGlvbnMtY29udGFpbmVyXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaXNIZWFkZXJBY3Rpb25Vc2VkXCJcbiAgICAgICAgICAgIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImNoZWNrQnV0dG9uRGlzYWJsZSgpXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkhlYWRlckFjdGlvbkNsaWNrZWQoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4+e3sgZ2V0RW5hYmxlQnV0dG9uVGV4dCgpIH19PC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxhICpuZ0lmPVwiaXNDb250YWN0QWN0aW9uVXNlZFwiIChjbGljayk9XCJjb250YWN0QWN0aW9uQ2xpY2suZW1pdCgpXCI+XG4gICAgICAgICAgICB7eyAnRlJPTlRFTkQuU1RPUkUuQ09OVEFDVF9VUycgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWJTdGF0ZSQgfCBhc3luYyBhcyB0YWJTdGF0ZVwiPlxuICAgIDxtYXQtdGFiLWdyb3VwXG4gICAgICBbc2VsZWN0ZWRJbmRleF09XCJ0YWJTdGF0ZS50YWJcIlxuICAgICAgKHNlbGVjdGVkVGFiQ2hhbmdlKT1cIm9uVGFiQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICA+XG4gICAgICA8bWF0LXRhYlxuICAgICAgICBsYWJlbD1cInt7XG4gICAgICAgICAgJ0ZST05URU5ELlNUT1JFLlBST0RVQ1RfREVUQUlMUy5UQUJfTEFCRUxTLlBST0RVQ1RfSU5GT1JNQVRJT04nXG4gICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICB9fVwiXG4gICAgICA+XG4gICAgICAgIDxhcHAtcHJvZHVjdC1pbmZvXG4gICAgICAgICAgW3Byb2R1Y3RdPVwicHJvZHVjdFwiXG4gICAgICAgICAgW3BhcnRuZXJJZF09XCJwYXJ0bmVySWRcIlxuICAgICAgICAgIFtiaWxsaW5nUHJpY2VdPVwiYmlsbGluZ1ByaWNlXCJcbiAgICAgICAgICBbbWFya2V0cGxhY2VDb3N0XT1cIm1hcmtldHBsYWNlQ29zdFwiXG4gICAgICAgICAgW21hcmtldGluZ1R5cGVdPVwibWFya2V0aW5nVHlwZVwiXG4gICAgICAgICAgW2lzT09dPVwiaXNPT1wiXG4gICAgICAgICAgW2J1c2luZXNzQ291bnRyeUNvZGVdPVwiYnVzaW5lc3NDb3VudHJ5Q29kZVwiXG4gICAgICAgICAgW3Nob3dQcmljaW5nXT1cInRydWVcIlxuICAgICAgICAgIFtwcm9kdWN0RGVwZW5kZW5jaWVzRmVhdHVyZUZsYWddPVwicHJvZHVjdERlcGVuZGVuY2llc0ZlYXR1cmVGbGFnXCJcbiAgICAgICAgICAoYWRkb25TZWxlY3RlZCk9XCJhZGRvblNlbGVjdGVkLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgID48L2FwcC1wcm9kdWN0LWluZm8+XG4gICAgICA8L21hdC10YWI+XG4gICAgICA8bWF0LXRhYlxuICAgICAgICBsYWJlbD1cInt7XG4gICAgICAgICAgJ0ZST05URU5ELlNUT1JFLlBST0RVQ1RfREVUQUlMUy5UQUJfTEFCRUxTLlNDUkVFTlNIT1RTX0FORF9GSUxFUydcbiAgICAgICAgICAgIHwgdHJhbnNsYXRlXG4gICAgICAgIH19XCJcbiAgICAgID5cbiAgICAgICAgPGFwcC1zY3JlZW5zaG90cy1maWxlc1xuICAgICAgICAgIFthcHBdPVwicHJvZHVjdFwiXG4gICAgICAgICAgW2xpZ2h0Ym94UmVmXT1cImxpZ2h0Ym94UmVmXCJcbiAgICAgICAgPjwvYXBwLXNjcmVlbnNob3RzLWZpbGVzPlxuICAgICAgPC9tYXQtdGFiPlxuICAgICAgPG1hdC10YWJcbiAgICAgICAgKm5nSWY9XCJ0YWJTdGF0ZS5lZGl0aW9uc1RhYlZpc2libGVcIlxuICAgICAgICBsYWJlbD1cInt7XG4gICAgICAgICAgJ0ZST05URU5ELlNUT1JFLlBST0RVQ1RfREVUQUlMUy5UQUJfTEFCRUxTLkVESVRJT05TX0FORF9QUklDSU5HJ1xuICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgfX1cIlxuICAgICAgPlxuICAgICAgICA8bmctdGVtcGxhdGUgbWF0VGFiQ29udGVudD5cbiAgICAgICAgICA8YXBwLWVkaXRpb25zLW1hcmtldGluZ1xuICAgICAgICAgICAgW2NvbnRhY3RTYWxlc109XCJwcm9kdWN0LnNob3VsZENvbnRhY3RTYWxlc1wiXG4gICAgICAgICAgICBbbWFya2V0aW5nVHlwZV09XCJtYXJrZXRpbmdUeXBlXCJcbiAgICAgICAgICAgIFtiaWxsaW5nUHJpY2VdPVwiYmlsbGluZ1ByaWNlXCJcbiAgICAgICAgICAgIFttYXJrZXRwbGFjZUNvc3RdPVwibWFya2V0cGxhY2VDb3N0XCJcbiAgICAgICAgICAgIFtlZGl0aW9uc01hcmtldGluZ109XCJlZGl0aW9uc01hcmtldGluZ1wiXG4gICAgICAgICAgICBbZWRpdGlvbk9yZGVyXT1cImVkaXRpb25PcmRlclwiXG4gICAgICAgICAgICBbaXNFZGl0aW9uQWN0aW9uVXNlZF09XCJpc0VkaXRpb25BY3Rpb25Vc2VkXCJcbiAgICAgICAgICAgIChlZGl0aW9uQWN0aW9uQ2xpY2spPVwib25FZGl0aW9uQWN0aW9uQ2xpY2tlZCgkZXZlbnQpXCJcbiAgICAgICAgICA+PC9hcHAtZWRpdGlvbnMtbWFya2V0aW5nPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9tYXQtdGFiPlxuICAgIDwvbWF0LXRhYi1ncm91cD5cbiAgPC9uZy1jb250YWluZXI+XG48L2Rpdj5cbjx2YS1saWdodGJveCAjbGlnaHRib3hSZWY+PC92YS1saWdodGJveD5cbiJdfQ==