UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

162 lines 62.9 kB
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Router } from '@angular/router'; import { ApplicationService } from '@c8y/client'; import { AlertService, GainsightService, gettext, PackageType, PluginsService, WizardModalService } from '@c8y/ngx-components'; import { BehaviorSubject } from 'rxjs'; import { EcosystemService } from './ecosystem.service'; import { PRODUCT_EXPERIENCE_ECOSYSTEM } from './ecosystem.model'; import { APP_STATE, PACKAGE_TYPE_LABELS } from './ecosystem.constants'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; import * as i2 from "./ecosystem.service"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "@angular/router"; import * as i5 from "@angular/common"; import * as i6 from "ngx-bootstrap/dropdown"; import * as i7 from "ngx-bootstrap/tooltip"; import * as i8 from "@angular/cdk/a11y"; import * as i9 from "./translate-package-label.pipe"; export class ApplicationCardComponent { get openButtonTitle() { return !this.disableOpenInBrowser ? gettext('Open') : gettext('This application is overridden.'); } constructor(applicationService, ecosystemService, alertService, router, wizardModalService, alert, pluginService, gainsightService) { this.applicationService = applicationService; this.ecosystemService = ecosystemService; this.alertService = alertService; this.router = router; this.wizardModalService = wizardModalService; this.alert = alert; this.pluginService = pluginService; this.gainsightService = gainsightService; this.CURRENT_LOCATION = location.href; this.canEdit = true; this.onAppDeleted = new EventEmitter(); this.onAppCloned = new EventEmitter(); this.packageTypeLabels = PACKAGE_TYPE_LABELS; this.PACKAGE_TYPE = PackageType; this.UNPACKED_LABEL = APP_STATE.UNPACKED.label; this.CANNOT_DELETE_HINT = gettext(`Subscribed or current applications can't be deleted. Delete the application on the parent tenant or unsubscribe it from the current.`); this.PACKAGE_CONTENT_UNDETERMINED_LABEL = gettext('Package contents could not be determined.'); } async ngOnInit() { this.appState = this.ecosystemService.getAppState(this.app); this.canOpenInBrowser = this.ecosystemService.canOpenAppInBrowser(this.app); this.packageType = this.pluginService.getPackageType(this.app); this.disableOpenInBrowser = this.canOpenInBrowser && (await this.ecosystemService.isOverwrittenByCustomApp(this.app)); this.canDelete = await this.ecosystemService.canDeleteApp(this.app); this.isPackage = this.ecosystemService.isPackage(this.app); this.packageContentState = this.ecosystemService.getPackageContentState(this.app); this.isPlugin = this.ecosystemService.isPlugin(this.app); this.isFeature = this.ecosystemService.isFeature(this.app); this.isMicroservice = this.ecosystemService.isMicroservice(this.app); this.isExternal = this.ecosystemService.isExternal(this.app); this.canClone = !this.isMicroservice && !this.isPlugin; this.isUnpacked = this.ecosystemService.isUnpacked(this.app); this.isShowVersion = this.shouldShowVersion(); await this.applicationUpdateCheck(); } shouldShowVersion() { return !!this.app.manifest?.version; } detail() { this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.APPLICATION_CARD, { component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.APPLICATION_CARD, action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.EDIT, url: this.CURRENT_LOCATION }); if (this.isMicroservice) { this.router.navigateByUrl(`/ecosystem/microservice/microservices/${this.app.id}`); return; } if (this.isPackage) { this.router.navigateByUrl(`/ecosystem/extension/extensions/${this.app.id}`); return; } if (this.isFeature) { this.router.navigateByUrl(`/ecosystem/application/features/${this.app.id}`); return; } this.router.navigateByUrl(`/ecosystem/application/applications/${this.app.id}`); } openApp() { this.ecosystemService.openApp(this.app); } async delete() { try { await this.ecosystemService.deleteApp(this.app); this.onAppDeleted.emit(); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.APPLICATION_CARD, { component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.APPLICATION_CARD, action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DELETE, url: this.CURRENT_LOCATION }); } catch (ex) { if (ex) { this.alertService.addServerFailure(ex); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.APPLICATION_CARD, { component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.APPLICATION_CARD, result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SERVER_FAILURE, url: this.CURRENT_LOCATION }); } } } async clone() { const wizardConfig = { headerText: 'Add Application', headerIcon: 'c8y-atom' }; const initialState = { wizardConfig, componentInitialState: { selectedApp: new BehaviorSubject(this.app) }, id: 'duplicateApplication' }; const modalOptions = { initialState }; const modalRef = this.wizardModalService.show(modalOptions); modalRef.content.onClose.subscribe(() => { this.onAppCloned.next(); }); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.APPLICATION_CARD, { component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.APPLICATION_CARD, action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.CLONE, url: this.CURRENT_LOCATION }); } async applicationUpdateCheck() { if (this.app.manifest?.source) { try { this.blueprintApplicationVersion = (await this.applicationService.listVersions(this.app.manifest?.source)).data; this.latestApplicationVersion = this.ecosystemService.getApplicationVersionObjectByTag(this.blueprintApplicationVersion, 'latest'); this.shouldUpgradePackage = this.ecosystemService.shouldUpgradePackage(this.app.manifest?.version, this.latestApplicationVersion); } catch (error) { if (!this.blueprintApplicationVersion) { return; } this.alert.addServerFailure(error); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ApplicationCardComponent, deps: [{ token: i1.ApplicationService }, { token: i2.EcosystemService }, { token: i3.AlertService }, { token: i4.Router }, { token: i3.WizardModalService }, { token: i3.AlertService }, { token: i3.PluginsService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ApplicationCardComponent, selector: "c8y-application-card", inputs: { app: "app", canEdit: "canEdit" }, outputs: { onAppDeleted: "onAppDeleted", onAppCloned: "onAppCloned" }, ngImport: i0, template: "<div\n class=\"card pointer card--d-col notFeature\"\n data-cy=\"application-card--extensions-list\"\n *ngIf=\"!isFeature\"\n>\n <div\n class=\"card-block text-center card-column-40\"\n data-cy=\"application-card--package-name\"\n (click)=\"detail()\"\n >\n <button\n class=\"card__ribbon btn-clean\"\n [attr.aria-label]=\"\n (app.label || app.manifest?.label | translatePackageLabel) +\n ': ' +\n (packageTypeLabels[packageType].tooltip | translate)\n \"\n tooltip=\"{{ packageTypeLabels[packageType].tooltip | translate }}\"\n placement=\"right\"\n type=\"button\"\n *ngIf=\"packageType !== PACKAGE_TYPE.CUSTOM\"\n [delay]=\"500\"\n >\n <span\n [ngClass]=\"{\n 'bg-info': packageType === PACKAGE_TYPE.COMMUNITY,\n 'bg-primary': packageType === PACKAGE_TYPE.OFFICIAL,\n 'bg-warning': packageType === PACKAGE_TYPE.ARCHIVED\n }\"\n >\n {{ app.label || app.manifest?.label | translatePackageLabel }}\n </span>\n </button>\n <div class=\"card-appicon\">\n <c8y-app-icon\n *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n [app]=\"app\"\n [contextPath]=\"app.contextPath\"\n [name]=\"app.name\"\n ></c8y-app-icon>\n <i\n c8yIcon=\"big-parcel\"\n *ngIf=\"isPackage\"\n ></i>\n <i\n c8yIcon=\"microchip\"\n *ngIf=\"isMicroservice\"\n ></i>\n <i\n c8yIcon=\"globe1\"\n *ngIf=\"isExternal\"\n ></i>\n </div>\n <div style=\"line-height: 1.3\">\n <p class=\"e2e-appCardName text-medium text-break-word\">\n {{ app | humanizeAppName | async }}\n </p>\n <ng-container *ngIf=\"isShowVersion\">\n <p class=\"small text-muted\">\n <em>{{ app.manifest.version }}</em>\n <button\n class=\"btn-clean m-l-4\"\n [attr.aria-label]=\"'Update available' | translate\"\n [tooltip]=\"'Update available' | translate\"\n *ngIf=\"shouldUpgradePackage && isUnpacked\"\n >\n <i\n class=\"text-warning icon-16\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n </p>\n </ng-container>\n <p\n class=\"small text-break-word\"\n *ngIf=\"app.manifest?.author\"\n >\n {{ app.manifest.author }}\n </p>\n </div>\n </div>\n <div\n class=\"card-block p-0 no-min-height card--d-col card-column-80 flex-grow\"\n (click)=\"detail()\"\n >\n <div class=\"card-block no-min-height p-t-0 p-b-0 card-column-80\">\n <div class=\"text-center-grid\">\n <div class=\"p-b-8 card-hidden-grid\"></div>\n <p\n class=\"small l-h-tight p-b-8 p-l-0 p-r-0 text-break-word\"\n *ngIf=\"app.description || app.manifest?.description\"\n >\n {{ app.description || app.manifest?.description | translate }}\n </p>\n <p\n class=\"small l-h-tight p-b-8 p-l-0 p-r-0\"\n *ngIf=\"!app.description && !app.manifest?.description\"\n >\n <em class=\"text-muted\">{{ 'No description available.' | translate }}</em>\n </p>\n </div>\n </div>\n <div\n class=\"card-block no-min-height p-t-0 p-b-0 d-flex card-column-20 text-center-grid flex-wrap gap-8\"\n >\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n ((isUnpacked ? UNPACKED_LABEL : appState?.label) | translate) +\n ': ' +\n (appState?.tooltip | translate)\n \"\n [tooltip]=\"appState?.tooltip | translate\"\n placement=\"top\"\n [delay]=\"500\"\n >\n <span\n class=\"label\"\n [ngClass]=\"appState?.class\"\n >\n {{ appState?.label | translate }}\n </span>\n </button>\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n (packageContentState?.label | translate) +\n ': ' +\n (packageContentState?.tooltip\n ? packageContentState?.tooltip\n : PACKAGE_CONTENT_UNDETERMINED_LABEL) | translate\n \"\n [tooltip]=\"\n (packageContentState?.tooltip\n ? packageContentState?.tooltip\n : PACKAGE_CONTENT_UNDETERMINED_LABEL\n ) | translate\n \"\n placement=\"top\"\n *ngIf=\"isPackage\"\n >\n <span\n class=\"label\"\n [ngClass]=\"packageContentState?.class ? packageContentState?.class : 'label-danger'\"\n >\n {{\n packageContentState?.label || packageTypeLabels[PACKAGE_TYPE.UNKNOWN].label | translate\n }}\n </span>\n </button>\n </div>\n <div class=\"card-footer no-min-height p-t-0 p-b-0 card-column-20 text-center-grid\">\n <div class=\"p-b-16 card-hidden-list\"></div>\n <button\n class=\"btn btn-sm btn-default\"\n [title]=\"openButtonTitle | translate\"\n type=\"button\"\n (click)=\"openApp(); $event.stopPropagation()\"\n *ngIf=\"canOpenInBrowser\"\n [disabled]=\"disableOpenInBrowser\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"external-link\"\n ></i>\n {{ 'Open' | translate }}\n </button>\n <div class=\"p-b-32 card-hidden-list\"></div>\n </div>\n </div>\n <div class=\"p-r-40 card-hidden-grid\"></div>\n <div\n class=\"card-actions m-t-0\"\n *ngIf=\"canEdit || canOpenInBrowser || canDelete\"\n >\n <div\n class=\"dropdown\"\n #appCardDropdown=\"bs-dropdown\"\n dropdown\n [cdkTrapFocus]=\"appCardDropdown.isOpen\"\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Settings' | translate }}\"\n data-cy=\"application-card--settings-button\"\n type=\"button\"\n dropdownToggle\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n *dropdownMenu\n >\n <li *ngIf=\"canEdit\">\n <button\n title=\"{{ 'Edit' | translate }}\"\n data-cy=\"application-card--edit-button\"\n (click)=\"detail()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"pencil\"\n ></i>\n {{ 'Edit' | translate }}\n </button>\n </li>\n <ng-container *c8yIfAllowed=\"['ROLE_APPLICATION_MANAGEMENT_ADMIN']\">\n <li>\n <button\n [title]=\"canDelete ? ('Delete' | translate) : (CANNOT_DELETE_HINT | translate)\"\n type=\"button\"\n data-cy=\"application-card--delete-button\"\n [disabled]=\"!canDelete\"\n (click)=\"delete()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"delete\"\n ></i>\n {{ 'Delete' | translate }}\n </button>\n </li>\n <li *ngIf=\"canClone\">\n <button\n [title]=\"'Clone`package,verb`' | translate\"\n type=\"button\"\n *ngIf=\"isPackage\"\n (click)=\"clone()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"copy\"\n ></i>\n {{ 'Clone`package,verb`' | translate }}\n </button>\n <button\n [title]=\"'Clone`application,verb`' | translate\"\n type=\"button\"\n *ngIf=\"!isPackage\"\n (click)=\"clone()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"copy\"\n ></i>\n {{ 'Clone`application,verb`' | translate }}\n </button>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n</div>\n\n<button\n class=\"card pointer card--d-col\"\n type=\"button\"\n (click)=\"detail()\"\n *ngIf=\"isFeature\"\n>\n <div class=\"card-block text-center card-column-40\">\n <div class=\"card-appicon\">\n <c8y-app-icon\n *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n [app]=\"app\"\n [contextPath]=\"app.contextPath\"\n [name]=\"app.name\"\n ></c8y-app-icon>\n <i c8yIcon=\"tab\"></i>\n </div>\n <div>\n <p\n class=\"e2e-appCardName text-medium\"\n title=\"{{ app | humanizeAppName | async }}\"\n >\n {{ app | humanizeAppName | async }}\n </p>\n <ng-container *ngIf=\"isShowVersion\">\n <p class=\"small text-muted\">\n <em>{{ app.manifest.version }}</em>\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Update available' | translate\"\n *ngIf=\"shouldUpgradePackage && isUnpacked\"\n ></i>\n </p>\n </ng-container>\n </div>\n </div>\n <div class=\"card-block p-0 no-min-height card--d-col card-column-80 flex-grow\">\n <div class=\"card-block no-min-height p-t-0 p-b-0 card-column-80\">\n <div\n class=\"text-center-grid\"\n *ngIf=\"app.description || app.manifest?.description\"\n >\n <div class=\"p-b-8 card-hidden-grid\"></div>\n <p class=\"small l-h-tight p-b-8 p-l-0 p-r-0\">\n {{ app.description || app.manifest?.description | translate }}\n </p>\n </div>\n </div>\n <div class=\"card-block no-min-height p-t-0 p-b-0 card-column-20 text-center-grid\">\n <span\n class=\"label\"\n [ngClass]=\"appState.class\"\n >\n {{ appState.label | translate }}\n </span>\n </div>\n <div\n class=\"card-block no-min-height p-t-0 p-b-0 card-column-20 text-center-grid\"\n *ngIf=\"isPackage\"\n >\n <span\n class=\"label\"\n [ngClass]=\"packageContentState.class\"\n >\n {{ packageContentState.label | translate }}\n </span>\n </div>\n <div class=\"p-b-32 card-hidden-list\"></div>\n </div>\n</button>\n", dependencies: [{ kind: "component", type: i3.AppIconComponent, selector: "c8y-app-icon", inputs: ["contextPath", "name", "app"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.IfAllowedDirective, selector: "[c8yIfAllowed]", inputs: ["c8yIfAllowed", "c8yIfAllowedAllowAny"] }, { kind: "directive", type: i6.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i6.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i6.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: i7.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: i8.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: i9.TranslatePackageLabelPipe, name: "translatePackageLabel" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ApplicationCardComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-application-card', template: "<div\n class=\"card pointer card--d-col notFeature\"\n data-cy=\"application-card--extensions-list\"\n *ngIf=\"!isFeature\"\n>\n <div\n class=\"card-block text-center card-column-40\"\n data-cy=\"application-card--package-name\"\n (click)=\"detail()\"\n >\n <button\n class=\"card__ribbon btn-clean\"\n [attr.aria-label]=\"\n (app.label || app.manifest?.label | translatePackageLabel) +\n ': ' +\n (packageTypeLabels[packageType].tooltip | translate)\n \"\n tooltip=\"{{ packageTypeLabels[packageType].tooltip | translate }}\"\n placement=\"right\"\n type=\"button\"\n *ngIf=\"packageType !== PACKAGE_TYPE.CUSTOM\"\n [delay]=\"500\"\n >\n <span\n [ngClass]=\"{\n 'bg-info': packageType === PACKAGE_TYPE.COMMUNITY,\n 'bg-primary': packageType === PACKAGE_TYPE.OFFICIAL,\n 'bg-warning': packageType === PACKAGE_TYPE.ARCHIVED\n }\"\n >\n {{ app.label || app.manifest?.label | translatePackageLabel }}\n </span>\n </button>\n <div class=\"card-appicon\">\n <c8y-app-icon\n *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n [app]=\"app\"\n [contextPath]=\"app.contextPath\"\n [name]=\"app.name\"\n ></c8y-app-icon>\n <i\n c8yIcon=\"big-parcel\"\n *ngIf=\"isPackage\"\n ></i>\n <i\n c8yIcon=\"microchip\"\n *ngIf=\"isMicroservice\"\n ></i>\n <i\n c8yIcon=\"globe1\"\n *ngIf=\"isExternal\"\n ></i>\n </div>\n <div style=\"line-height: 1.3\">\n <p class=\"e2e-appCardName text-medium text-break-word\">\n {{ app | humanizeAppName | async }}\n </p>\n <ng-container *ngIf=\"isShowVersion\">\n <p class=\"small text-muted\">\n <em>{{ app.manifest.version }}</em>\n <button\n class=\"btn-clean m-l-4\"\n [attr.aria-label]=\"'Update available' | translate\"\n [tooltip]=\"'Update available' | translate\"\n *ngIf=\"shouldUpgradePackage && isUnpacked\"\n >\n <i\n class=\"text-warning icon-16\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n </p>\n </ng-container>\n <p\n class=\"small text-break-word\"\n *ngIf=\"app.manifest?.author\"\n >\n {{ app.manifest.author }}\n </p>\n </div>\n </div>\n <div\n class=\"card-block p-0 no-min-height card--d-col card-column-80 flex-grow\"\n (click)=\"detail()\"\n >\n <div class=\"card-block no-min-height p-t-0 p-b-0 card-column-80\">\n <div class=\"text-center-grid\">\n <div class=\"p-b-8 card-hidden-grid\"></div>\n <p\n class=\"small l-h-tight p-b-8 p-l-0 p-r-0 text-break-word\"\n *ngIf=\"app.description || app.manifest?.description\"\n >\n {{ app.description || app.manifest?.description | translate }}\n </p>\n <p\n class=\"small l-h-tight p-b-8 p-l-0 p-r-0\"\n *ngIf=\"!app.description && !app.manifest?.description\"\n >\n <em class=\"text-muted\">{{ 'No description available.' | translate }}</em>\n </p>\n </div>\n </div>\n <div\n class=\"card-block no-min-height p-t-0 p-b-0 d-flex card-column-20 text-center-grid flex-wrap gap-8\"\n >\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n ((isUnpacked ? UNPACKED_LABEL : appState?.label) | translate) +\n ': ' +\n (appState?.tooltip | translate)\n \"\n [tooltip]=\"appState?.tooltip | translate\"\n placement=\"top\"\n [delay]=\"500\"\n >\n <span\n class=\"label\"\n [ngClass]=\"appState?.class\"\n >\n {{ appState?.label | translate }}\n </span>\n </button>\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n (packageContentState?.label | translate) +\n ': ' +\n (packageContentState?.tooltip\n ? packageContentState?.tooltip\n : PACKAGE_CONTENT_UNDETERMINED_LABEL) | translate\n \"\n [tooltip]=\"\n (packageContentState?.tooltip\n ? packageContentState?.tooltip\n : PACKAGE_CONTENT_UNDETERMINED_LABEL\n ) | translate\n \"\n placement=\"top\"\n *ngIf=\"isPackage\"\n >\n <span\n class=\"label\"\n [ngClass]=\"packageContentState?.class ? packageContentState?.class : 'label-danger'\"\n >\n {{\n packageContentState?.label || packageTypeLabels[PACKAGE_TYPE.UNKNOWN].label | translate\n }}\n </span>\n </button>\n </div>\n <div class=\"card-footer no-min-height p-t-0 p-b-0 card-column-20 text-center-grid\">\n <div class=\"p-b-16 card-hidden-list\"></div>\n <button\n class=\"btn btn-sm btn-default\"\n [title]=\"openButtonTitle | translate\"\n type=\"button\"\n (click)=\"openApp(); $event.stopPropagation()\"\n *ngIf=\"canOpenInBrowser\"\n [disabled]=\"disableOpenInBrowser\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"external-link\"\n ></i>\n {{ 'Open' | translate }}\n </button>\n <div class=\"p-b-32 card-hidden-list\"></div>\n </div>\n </div>\n <div class=\"p-r-40 card-hidden-grid\"></div>\n <div\n class=\"card-actions m-t-0\"\n *ngIf=\"canEdit || canOpenInBrowser || canDelete\"\n >\n <div\n class=\"dropdown\"\n #appCardDropdown=\"bs-dropdown\"\n dropdown\n [cdkTrapFocus]=\"appCardDropdown.isOpen\"\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Settings' | translate }}\"\n data-cy=\"application-card--settings-button\"\n type=\"button\"\n dropdownToggle\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n *dropdownMenu\n >\n <li *ngIf=\"canEdit\">\n <button\n title=\"{{ 'Edit' | translate }}\"\n data-cy=\"application-card--edit-button\"\n (click)=\"detail()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"pencil\"\n ></i>\n {{ 'Edit' | translate }}\n </button>\n </li>\n <ng-container *c8yIfAllowed=\"['ROLE_APPLICATION_MANAGEMENT_ADMIN']\">\n <li>\n <button\n [title]=\"canDelete ? ('Delete' | translate) : (CANNOT_DELETE_HINT | translate)\"\n type=\"button\"\n data-cy=\"application-card--delete-button\"\n [disabled]=\"!canDelete\"\n (click)=\"delete()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"delete\"\n ></i>\n {{ 'Delete' | translate }}\n </button>\n </li>\n <li *ngIf=\"canClone\">\n <button\n [title]=\"'Clone`package,verb`' | translate\"\n type=\"button\"\n *ngIf=\"isPackage\"\n (click)=\"clone()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"copy\"\n ></i>\n {{ 'Clone`package,verb`' | translate }}\n </button>\n <button\n [title]=\"'Clone`application,verb`' | translate\"\n type=\"button\"\n *ngIf=\"!isPackage\"\n (click)=\"clone()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"copy\"\n ></i>\n {{ 'Clone`application,verb`' | translate }}\n </button>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n</div>\n\n<button\n class=\"card pointer card--d-col\"\n type=\"button\"\n (click)=\"detail()\"\n *ngIf=\"isFeature\"\n>\n <div class=\"card-block text-center card-column-40\">\n <div class=\"card-appicon\">\n <c8y-app-icon\n *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n [app]=\"app\"\n [contextPath]=\"app.contextPath\"\n [name]=\"app.name\"\n ></c8y-app-icon>\n <i c8yIcon=\"tab\"></i>\n </div>\n <div>\n <p\n class=\"e2e-appCardName text-medium\"\n title=\"{{ app | humanizeAppName | async }}\"\n >\n {{ app | humanizeAppName | async }}\n </p>\n <ng-container *ngIf=\"isShowVersion\">\n <p class=\"small text-muted\">\n <em>{{ app.manifest.version }}</em>\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Update available' | translate\"\n *ngIf=\"shouldUpgradePackage && isUnpacked\"\n ></i>\n </p>\n </ng-container>\n </div>\n </div>\n <div class=\"card-block p-0 no-min-height card--d-col card-column-80 flex-grow\">\n <div class=\"card-block no-min-height p-t-0 p-b-0 card-column-80\">\n <div\n class=\"text-center-grid\"\n *ngIf=\"app.description || app.manifest?.description\"\n >\n <div class=\"p-b-8 card-hidden-grid\"></div>\n <p class=\"small l-h-tight p-b-8 p-l-0 p-r-0\">\n {{ app.description || app.manifest?.description | translate }}\n </p>\n </div>\n </div>\n <div class=\"card-block no-min-height p-t-0 p-b-0 card-column-20 text-center-grid\">\n <span\n class=\"label\"\n [ngClass]=\"appState.class\"\n >\n {{ appState.label | translate }}\n </span>\n </div>\n <div\n class=\"card-block no-min-height p-t-0 p-b-0 card-column-20 text-center-grid\"\n *ngIf=\"isPackage\"\n >\n <span\n class=\"label\"\n [ngClass]=\"packageContentState.class\"\n >\n {{ packageContentState.label | translate }}\n </span>\n </div>\n <div class=\"p-b-32 card-hidden-list\"></div>\n </div>\n</button>\n" }] }], ctorParameters: () => [{ type: i1.ApplicationService }, { type: i2.EcosystemService }, { type: i3.AlertService }, { type: i4.Router }, { type: i3.WizardModalService }, { type: i3.AlertService }, { type: i3.PluginsService }, { type: i3.GainsightService }], propDecorators: { app: [{ type: Input }], canEdit: [{ type: Input }], onAppDeleted: [{ type: Output }], onAppCloned: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24tY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9lY29zeXN0ZW0vc2hhcmVkL2FwcGxpY2F0aW9uLWNhcmQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vZWNvc3lzdGVtL3NoYXJlZC9hcHBsaWNhdGlvbi1jYXJkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBcUMsTUFBTSxhQUFhLENBQUM7QUFDcEYsT0FBTyxFQUNMLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsT0FBTyxFQUNQLFdBQVcsRUFDWCxjQUFjLEVBSWQsa0JBQWtCLEVBQ25CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVqRSxPQUFPLEVBQUUsU0FBUyxFQUFvQixtQkFBbUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7Ozs7OztBQU16RixNQUFNLE9BQU8sd0JBQXdCO0lBeUJuQyxJQUFJLGVBQWU7UUFDakIsT0FBTyxDQUFDLElBQUksQ0FBQyxvQkFBb0I7WUFDL0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDakIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFZRCxZQUNVLGtCQUFzQyxFQUN0QyxnQkFBa0MsRUFDbEMsWUFBMEIsRUFDMUIsTUFBYyxFQUNk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SUFBSSxDQUFDO2dCQUVQLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0NBQWdDLENBQ3BGLElBQUksQ0FBQywyQkFBMkIsRUFDaEMsUUFBUSxDQUNULENBQUM7Z0JBQ0YsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxvQkFBb0IsQ0FDcEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUMxQixJQUFJLENBQUMsd0JBQXdCLENBQzlCLENBQUM7WUFDSixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixJQUFJLENBQUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7b0JBQ3RDLE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQzsrR0EzTFUsd0JBQXdCO21HQUF4Qix3QkFBd0IsK0tDekJyQyxxK1RBcVVBOzs0RkQ1U2Esd0JBQXdCO2tCQUpwQyxTQUFTOytCQUNFLHNCQUFzQjs4UkFNdkIsR0FBRztzQkFBWCxLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQXBwbGljYXRpb25TZXJ2aWNlLCBJQXBwbGljYXRpb24sIElBcHBsaWNhdGlvblZlcnNpb24gfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQge1xuICBBbGVydFNlcnZpY2UsXG4gIEdhaW5zaWdodFNlcnZpY2UsXG4gIGdldHRleHQsXG4gIFBhY2thZ2VUeXBlLFxuICBQbHVnaW5zU2VydmljZSxcbiAgV2l6YXJkLFxuICBXaXphcmRDb21wb25lbnQsXG4gIFdpemFyZENvbmZpZyxcbiAgV2l6YXJkTW9kYWxTZXJ2aWNlXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgTW9kYWxPcHRpb25zIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC9tb2RhbCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEVjb3N5c3RlbVNlcnZpY2UgfSBmcm9tICcuL2Vjb3N5c3RlbS5zZXJ2aWNlJztcbmltcG9ydCB7IFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0gfSBmcm9tICcuL2Vjb3N5c3RlbS5tb2RlbCc7XG5pbXBvcnQgeyBEdXBsaWNhdGVBcHBsaWNhdGlvbkNvbXBvbmVudCB9IGZyb20gJy4vZHVwbGljYXRlLWFwcGxpY2F0aW9uL2R1cGxpY2F0ZS1hcHBsaWNhdGlvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgQVBQX1NUQVRFLCBBcHBsaWNhdGlvblN0YXRlLCBQQUNLQUdFX1RZUEVfTEFCRUxTIH0gZnJvbSAnLi9lY29zeXN0ZW0uY29uc3RhbnRzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWFwcGxpY2F0aW9uLWNhcmQnLFxuICB0ZW1wbGF0ZVVybDogJy4vYXBwbGljYXRpb24tY2FyZC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgQXBwbGljYXRpb25DYXJkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQ1VSUkVOVF9MT0NBVElPTiA9IGxvY2F0aW9uLmhyZWY7XG5cbiAgQElucHV0KCkgYXBwOiBJQXBwbGljYXRpb247XG4gIEBJbnB1dCgpIGNhbkVkaXQgPSB0cnVlO1xuICBAT3V0cHV0KCkgb25BcHBEZWxldGVkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkFwcENsb25lZDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBhcHBTdGF0ZTogQXBwbGljYXRpb25TdGF0ZTtcbiAgcGFja2FnZUNvbnRlbnRTdGF0ZTogQXBwbGljYXRpb25TdGF0ZTtcbiAgcGFja2FnZVR5cGU6IFBhY2thZ2VUeXBlO1xuICBjYW5PcGVuSW5Ccm93c2VyOiBib29sZWFuO1xuICBkaXNhYmxlT3BlbkluQnJvd3NlcjogYm9vbGVhbjtcbiAgY2FuRGVsZXRlOiBib29sZWFuO1xuICBpc1BhY2thZ2U6IGJvb2xlYW47XG4gIGlzUGx1Z2luOiBib29sZWFuO1xuICBpc0ZlYXR1cmU6IGJvb2xlYW47XG4gIGlzRXh0ZXJuYWw6IGJvb2xlYW47XG4gIGlzTWljcm9zZXJ2aWNlOiBib29sZWFuO1xuICBjYW5DbG9uZTogYm9vbGVhbjtcbiAgaXNVbnBhY2tlZDogYm9vbGVhbjtcbiAgc2hvdWxkVXBncmFkZVBhY2thZ2U6IGJvb2xlYW47XG4gIGJsdWVwcmludEFwcGxpY2F0aW9uVmVyc2lvbjogSUFwcGxpY2F0aW9uVmVyc2lvbltdO1xuICBsYXRlc3RBcHBsaWNhdGlvblZlcnNpb246IElBcHBsaWNhdGlvblZlcnNpb247XG4gIGlzU2hvd1ZlcnNpb246IGJvb2xlYW47XG4gIGlzT3duZWRCeU1hbmFnZW1lbnRUZW5hbnQ6IGJvb2xlYW47XG4gIGdldCBvcGVuQnV0dG9uVGl0bGUoKSB7XG4gICAgcmV0dXJuICF0aGlzLmRpc2FibGVPcGVuSW5Ccm93c2VyXG4gICAgICA/IGdldHRleHQoJ09wZW4nKVxuICAgICAgOiBnZXR0ZXh0KCdUaGlzIGFwcGxpY2F0aW9uIGlzIG92ZXJyaWRkZW4uJyk7XG4gIH1cblxuICByZWFkb25seSBwYWNrYWdlVHlwZUxhYmVscyA9IFBBQ0tBR0VfVFlQRV9MQUJFTFM7XG4gIHJlYWRvbmx5IFBBQ0tBR0VfVFlQRSA9IFBhY2thZ2VUeXBlO1xuICByZWFkb25seSBVTlBBQ0tFRF9MQUJFTCA9IEFQUF9TVEFURS5VTlBBQ0tFRC5sYWJlbDtcbiAgcmVhZG9ubHkgQ0FOTk9UX0RFTEVURV9ISU5UID0gZ2V0dGV4dChcbiAgICBgU3Vic2NyaWJlZCBvciBjdXJyZW50IGFwcGxpY2F0aW9ucyBjYW4ndCBiZSBkZWxldGVkLiBEZWxldGUgdGhlIGFwcGxpY2F0aW9uIG9uIHRoZSBwYXJlbnQgdGVuYW50IG9yIHVuc3Vic2NyaWJlIGl0IGZyb20gdGhlIGN1cnJlbnQuYFxuICApO1xuICByZWFkb25seSBQQUNLQUdFX0NPTlRFTlRfVU5ERVRFUk1JTkVEX0xBQkVMID0gZ2V0dGV4dChcbiAgICAnUGFja2FnZSBjb250ZW50cyBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZC4nXG4gICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhcHBsaWNhdGlvblNlcnZpY2U6IEFwcGxpY2F0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIGVjb3N5c3RlbVNlcnZpY2U6IEVjb3N5c3RlbVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgd2l6YXJkTW9kYWxTZXJ2aWNlOiBXaXphcmRNb2RhbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbGVydDogQWxlcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGx1Z2luU2VydmljZTogUGx1Z2luc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmFwcFN0YXRlID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmdldEFwcFN0YXRlKHRoaXMuYXBwKTtcbiAgICB0aGlzLmNhbk9wZW5JbkJyb3dzZXIgPSB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuY2FuT3BlbkFwcEluQnJvd3Nlcih0aGlzLmFwcCk7XG4gICAgdGhpcy5wYWNrYWdlVHlwZSA9IHRoaXMucGx1Z2luU2VydmljZS5nZXRQYWNrYWdlVHlwZSh0aGlzLmFwcCk7XG4gICAgdGhpcy5kaXNhYmxlT3BlbkluQnJvd3NlciA9XG4gICAgICB0aGlzLmNhbk9wZW5JbkJyb3dzZXIgJiYgKGF3YWl0IHRoaXMuZWNvc3lzdGVtU2VydmljZS5pc092ZXJ3cml0dGVuQnlDdXN0b21BcHAodGhpcy5hcHApKTtcbiAgICB0aGlzLmNhbkRlbGV0ZSA9IGF3YWl0IHRoaXMuZWNvc3lzdGVtU2VydmljZS5jYW5EZWxldGVBcHAodGhpcy5hcHApO1xuICAgIHRoaXMuaXNQYWNrYWdlID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmlzUGFja2FnZSh0aGlzLmFwcCk7XG4gICAgdGhpcy5wYWNrYWdlQ29udGVudFN0YXRlID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmdldFBhY2thZ2VDb250ZW50U3RhdGUodGhpcy5hcHApO1xuICAgIHRoaXMuaXNQbHVnaW4gPSB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuaXNQbHVnaW4odGhpcy5hcHApO1xuICAgIHRoaXMuaXNGZWF0dXJlID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmlzRmVhdHVyZSh0aGlzLmFwcCk7XG4gICAgdGhpcy5pc01pY3Jvc2VydmljZSA9IHRoaXMuZWNvc3lzdGVtU2VydmljZS5pc01pY3Jvc2VydmljZSh0aGlzLmFwcCk7XG4gICAgdGhpcy5pc0V4dGVybmFsID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmlzRXh0ZXJuYWwodGhpcy5hcHApO1xuICAgIHRoaXMuY2FuQ2xvbmUgPSAhdGhpcy5pc01pY3Jvc2VydmljZSAmJiAhdGhpcy5pc1BsdWdpbjtcbiAgICB0aGlzLmlzVW5wYWNrZWQgPSB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuaXNVbnBhY2tlZCh0aGlzLmFwcCk7XG4gICAgdGhpcy5pc1Nob3dWZXJzaW9uID0gdGhpcy5zaG91bGRTaG93VmVyc2lvbigpO1xuICAgIGF3YWl0IHRoaXMuYXBwbGljYXRpb25VcGRhdGVDaGVjaygpO1xuICB9XG5cbiAgc2hvdWxkU2hvd1ZlcnNpb24oKSB7XG4gICAgcmV0dXJuICEhdGhpcy5hcHAubWFuaWZlc3Q/LnZlcnNpb247XG4gIH1cblxuICBkZXRhaWwoKSB7XG4gICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyaWdnZXJFdmVudChcbiAgICAgIFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLkVWRU5UUy5BUFBMSUNBVElPTl9DQVJELFxuICAgICAge1xuICAgICAgICBjb21wb25lbnQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLkNPTVBPTkVOVFMuQVBQTElDQVRJT05fQ0FSRCxcbiAgICAgICAgYWN0aW9uOiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5BQ1RJT05TLkVESVQsXG4gICAgICAgIHVybDogdGhpcy5DVVJSRU5UX0xPQ0FUSU9OXG4gICAgICB9XG4gICAgKTtcblxuICAgIGlmICh0aGlzLmlzTWljcm9zZXJ2aWNlKSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGAvZWNvc3lzdGVtL21pY3Jvc2VydmljZS9taWNyb3NlcnZpY2VzLyR7dGhpcy5hcHAuaWR9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNQYWNrYWdlKSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGAvZWNvc3lzdGVtL2V4dGVuc2lvbi9leHRlbnNpb25zLyR7dGhpcy5hcHAuaWR9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNGZWF0dXJlKSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGAvZWNvc3lzdGVtL2FwcGxpY2F0aW9uL2ZlYXR1cmVzLyR7dGhpcy5hcHAuaWR9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybChgL2Vjb3N5c3RlbS9hcHBsaWNhdGlvbi9hcHBsaWNhdGlvbnMvJHt0aGlzLmFwcC5pZH1gKTtcbiAgfVxuXG4gIG9wZW5BcHAoKSB7XG4gICAgdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLm9wZW5BcHAodGhpcy5hcHApO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuZGVsZXRlQXBwKHRoaXMuYXBwKTtcbiAgICAgIHRoaXMub25BcHBEZWxldGVkLmVtaXQoKTtcbiAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmlnZ2VyRXZlbnQoXG4gICAgICAgIFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLkVWRU5UUy5BUFBMSUNBVElPTl9DQVJELFxuICAgICAgICB7XG4gICAgICAgICAgY29tcG9uZW50OiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5DT01QT05FTlRTLkFQUExJQ0FUSU9OX0NBUkQsXG4gICAgICAgICAgYWN0aW9uOiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5BQ1RJT05TLkRFTEVURSxcbiAgICAgICAgICB1cmw6IHRoaXMuQ1VSUkVOVF9MT0NBVElPTlxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICBpZiAoZXgpIHtcbiAgICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShleCk7XG4gICAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmlnZ2VyRXZlbnQoXG4gICAgICAgICAgUFJPRFVDVF9FWFBFUklFTkNFX0VDT1NZU1RFTS5BUFBMSUNBVElPTlMuRVZFTlRTLkFQUExJQ0FUSU9OX0NBUkQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgY29tcG9uZW50OiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5DT01QT05FTlRTLkFQUExJQ0FUSU9OX0NBUkQsXG4gICAgICAgICAgICByZXN1bHQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLlJFU1VMVFMuU0VSVkVSX0ZBSUxVUkUsXG4gICAgICAgICAgICB1cmw6IHRoaXMuQ1VSUkVOVF9MT0NBVElPTlxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBjbG9uZSgpIHtcbiAgICBjb25zdCB3aXphcmRDb25maWc6IFdpemFyZENvbmZpZyA9IHtcbiAgICAgIGhlYWRlclRleHQ6ICdBZGQgQXBwbGljYXRpb24nLFxuICAgICAgaGVhZGVySWNvbjogJ2M4eS1hdG9tJ1xuICAgIH07XG5cbiAgICBjb25zdCBpbml0aWFsU3RhdGU6IFdpemFyZDxEdXBsaWNhdGVBcHBsaWNhdGlvbkNvbXBvbmVudD4gPSB7XG4gICAgICB3aXphcmRDb25maWcsXG4gICAgICBjb21wb25lbnRJbml0aWFsU3RhdGU6IHtcbiAgICAgICAgc2VsZWN0ZWRBcHA6IG5ldyBCZWhhdmlvclN1YmplY3QodGhpcy5hcHApXG4gICAgICB9LFxuICAgICAgaWQ6ICdkdXBsaWNhdGVBcHBsaWNhdGlvbidcbiAgICB9O1xuXG4gICAgY29uc3QgbW9kYWxPcHRpb25zOiBNb2RhbE9wdGlvbnM8V2l6YXJkQ29tcG9uZW50PiA9IHsgaW5pdGlhbFN0YXRlIH07XG5cbiAgICBjb25zdCBtb2RhbFJlZiA9IHRoaXMud2l6YXJkTW9kYWxTZXJ2aWNlLnNob3cobW9kYWxPcHRpb25zKTtcbiAgICBtb2RhbFJlZi5jb250ZW50Lm9uQ2xvc2Uuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMub25BcHBDbG9uZWQubmV4dCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyaWdnZXJFdmVudChcbiAgICAgIFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLkVWRU5UUy5BUFBMSUNBVElPTl9DQVJELFxuICAgICAge1xuICAgICAgICBjb21wb25lbnQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLkNPTVBPTkVOVFMuQVBQTElDQVRJT05fQ0FSRCxcbiAgICAgICAgYWN0aW9uOiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5BQ1RJT05TLkNMT05FLFxuICAgICAgICB1cmw6IHRoaXMuQ1VSUkVOVF9MT0NBVElPTlxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFwcGxpY2F0aW9uVXBkYXRlQ2hlY2soKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuYXBwLm1hbmlmZXN0Py5zb3VyY2UpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuYmx1ZXByaW50QXBwbGljYXRpb25WZXJzaW9uID0gKFxuICAgICAgICAgIGF3YWl0IHRoaXMuYXBwbGljYXRpb25TZXJ2aWNlLmxpc3RWZXJzaW9ucyh0aGlzLmFwcC5tYW5pZmVzdD8uc291cmNlKVxuICAgICAgICApLmRhdGE7XG5cbiAgICAgICAgdGhpcy5sYXRlc3RBcHBsaWNhdGlvblZlcnNpb24gPSB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuZ2V0QXBwbGljYXRpb25WZXJzaW9uT2JqZWN0QnlUYWcoXG4gICAgICAgICAgdGhpcy5ibHVlcHJpbnRBcHBsaWNhdGlvblZlcnNpb24sXG4gICAgICAgICAgJ2xhdGVzdCdcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zaG91bGRVcGdyYWRlUGFja2FnZSA9IHRoaXMuZWNvc3lzdGVtU2VydmljZS5zaG91bGRVcGdyYWRlUGFja2FnZShcbiAgICAgICAgICB0aGlzLmFwcC5tYW5pZmVzdD8udmVyc2lvbixcbiAgICAgICAgICB0aGlzLmxhdGVzdEFwcGxpY2F0aW9uVmVyc2lvblxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKCF0aGlzLmJsdWVwcmludEFwcGxpY2F0aW9uVmVyc2lvbikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFsZXJ0LmFkZFNlcnZlckZhaWx1cmUoZXJyb3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImNhcmQgcG9pbnRlciBjYXJkLS1kLWNvbCBub3RGZWF0dXJlXCJcbiAgZGF0YS1jeT1cImFwcGxpY2F0aW9uLWNhcmQtLWV4dGVuc2lvbnMtbGlzdFwiXG4gICpuZ0lmPVwiIWlzRmVhdHVyZVwiXG4+XG4gIDxkaXZcbiAgICBjbGFzcz1cImNhcmQtYmxvY2sgdGV4dC1jZW50ZXIgY2FyZC1jb2x1bW4tNDBcIlxuICAgIGRhdGEtY3k9XCJhcHBsaWNhdGlvbi1jYXJkLS1wYWNrYWdlLW5hbWVcIlxuICAgIChjbGljayk9XCJkZXRhaWwoKVwiXG4gID5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cImNhcmRfX3JpYmJvbiBidG4tY2xlYW5cIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJcbiAgICAgICAgKGFwcC5sYWJlbCB8fCBhcHAubWFuaWZlc3Q/LmxhYmVsIHwgdHJhbnNsYXRlUGFja2FnZUxhYmVsKSArXG4gICAgICAgICc6ICcgK1xuICAgICAgICAocGFja2FnZVR5cGVMYWJlbHNbcGFja2FnZVR5cGVdLnRvb2x0aXAgfCB0cmFuc2xhdGUpXG4gICAgICBcIlxuICAgICAgdG9vbHRpcD1cInt7IHBh