UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

186 lines 51.9 kB
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { OperationBulkGeneralStatus } from '@c8y/client'; import { AlertService, gettext, ListItemComponent, ModalService, Status } from '@c8y/ngx-components'; import { BulkOperationsService } from '@c8y/ngx-components/operations/bulk-operations-service'; import { BULK_OPERATION_EVENT } from '@c8y/ngx-components/operations/product-experience'; import { assign, cloneDeep, find, values } from 'lodash-es'; import { BsModalService } from 'ngx-bootstrap/modal'; import { BULK_OPERATION_STATUS_OPTIONS } from './bulk-operation-list-item.model'; import { BulkOperationListItemService } from './bulk-operation-list-item.service'; import { BulkOperationsRescheduleModalComponent } from './modals/bulk-operations-reschedule-modal.component'; import * as i0 from "@angular/core"; import * as i1 from "./bulk-operation-list-item.service"; import * as i2 from "@c8y/ngx-components/operations/bulk-operations-service"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "ngx-bootstrap/modal"; import * as i5 from "@angular/common"; import * as i6 from "ngx-bootstrap/popover"; import * as i7 from "ngx-bootstrap/tooltip"; import * as i8 from "@c8y/ngx-components/operations/operations-list-item-details"; export class BulkOperationListItemComponent { constructor(bulkOperationListItemService, bulkOperationsService, modal, alert, bsModalService) { this.bulkOperationListItemService = bulkOperationListItemService; this.bulkOperationsService = bulkOperationsService; this.modal = modal; this.alert = alert; this.bsModalService = bsModalService; this.BULK_OPERATION_EVENT = BULK_OPERATION_EVENT; this.detailsCollapsed = true; this.readOnly = false; this.showFailedOperation = new EventEmitter(); this.reload = new EventEmitter(); this.refreshLoading = false; this.bulkOperationGeneralStatus = OperationBulkGeneralStatus; this.BULK_OPERATION_STATUS_OPTIONS = BULK_OPERATION_STATUS_OPTIONS; this.finishDatePopoverText = gettext('Approximate date, estimated based on the bulk operation settings.'); this.progressBarClass = 'progress'; this.progressBarStatus = 0; } ngOnInit() { this.finishDate = this.calculateFinishDateMs(); this.setProgressBar(); } getOperationStatusOptions() { const statusOptions = values(BULK_OPERATION_STATUS_OPTIONS); return find(statusOptions, options => options.generalStatuses.includes(this.bulkOperation.generalStatus)); } ngOnChanges(changes) { if (changes.bulkOperation && !changes.bulkOperation.firstChange) { this.setProgressBar(); } } calculateFinishDateMs() { const startDateMs = new Date(this.bulkOperation.startDate).getTime(); const creationRampMs = this.bulkOperation.creationRamp * 1000; return startDateMs + creationRampMs * this.bulkOperation.progress.all; } progressBarProgressFn() { return (((this.bulkOperation.progress.successful + this.bulkOperation.progress.failed) / this.bulkOperation.progress.all) * 100); } setProgressBar() { const staticContentOfClass = 'progress-bar progress-striped active progress-bar'; const progressBarState = { EXECUTING: { progressBarClass: 'progress progress-striped active', progressBarColor: `${staticContentOfClass}-primary`, progressBarStatus: this.progressBarProgressFn() }, EXECUTING_WITH_ERROR: { progressBarClass: 'progress progress-striped active', progressBarColor: `${staticContentOfClass}-danger`, progressBarStatus: this.progressBarProgressFn() }, FAILED: { progressBarClass: 'progress', progressBarColor: `${staticContentOfClass}-danger`, progressBarStatus: 100 }, SUCCESSFUL: { progressBarClass: 'progress', progressBarColor: `${staticContentOfClass}-success`, progressBarStatus: 100 } }; assign(this, progressBarState[this.bulkOperation.generalStatus]); } editSchedule() { const rescheduledOperation = cloneDeep(this.bulkOperation); const initialState = { bulkOperation: rescheduledOperation }; const modalOptions = { initialState, class: 'modal-sm', ariaDescribedby: 'modal-body', ariaLabelledBy: 'modal-title', backdrop: 'static' }; this.bsModalRef = this.bsModalService.show(BulkOperationsRescheduleModalComponent, modalOptions); } async cancelBulkOperation() { try { await this.modal.confirm(gettext('Cancel bulk operation'), gettext('You are about to cancel the bulk operation. Do you want to proceed?'), Status.DANGER, {}, {}, { eventName: BULK_OPERATION_EVENT }); await this.bulkOperationsService.deleteBulkOperation(this.bulkOperation.id); this.reload.emit(); this.alert.success(gettext('Operation canceled.')); } catch (er) { this.alert.addServerFailure(er); } } retryFailedOperation() { const clonedBulk = cloneDeep(this.bulkOperation); // change the id to failedparentId similar to the logic in deviceBulkControl.service.js delete clonedBulk.groupId; clonedBulk.failedParentId = this.bulkOperation.id; // show reschdedule modal: const initialState = { bulkOperation: clonedBulk, isRetryOperation: true }; const modalOptions = { initialState, class: 'modal-sm', backdrop: 'static' }; this.bsModalRef = this.bsModalService.show(BulkOperationsRescheduleModalComponent, modalOptions); this.bsModalRef.content.closeSubject.subscribe(() => { this.reload.emit(); }); } async setToSuccessful() { try { await this.modal.confirm(gettext('Set manually bulk operation to SUCCESSFUL'), gettext('You are about to change the bulk operation status to SUCCESSFUL. Do you want to proceed?'), Status.DANGER, {}, {}, { eventName: BULK_OPERATION_EVENT }); await this.bulkOperationsService.updateBulkOperation({ id: this.bulkOperation.id, generalStatus: OperationBulkGeneralStatus.SUCCESSFUL }); this.reload.emit(); this.alert.success(gettext('Operation status changed to SUCCESSFUL.')); } catch (er) { this.alert.addServerFailure(er); } } openFailedOperation(failedParentId) { this.showFailedOperation.emit(failedParentId); } isStatusScheduled() { return this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.SCHEDULED; } isStatusExecutingOrExecutingWithError() { return (this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.EXECUTING || this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.EXECUTING_WITH_ERROR); } allOperationsCreated() { return (this.bulkOperation.progress.all === this.bulkOperation.progress.executing + this.bulkOperation.progress.failed + this.bulkOperation.progress.pending + this.bulkOperation.progress.successful); } isStatusCanceled() { return this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.CANCELED; } isStatusFailed() { return this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.FAILED; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BulkOperationListItemComponent, deps: [{ token: i1.BulkOperationListItemService }, { token: i2.BulkOperationsService }, { token: i3.ModalService }, { token: i3.AlertService }, { token: i4.BsModalService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BulkOperationListItemComponent, selector: "c8y-bulk-operation-list-item", inputs: { bulkOperation: "bulkOperation", detailsCollapsed: "detailsCollapsed", readOnly: "readOnly" }, outputs: { showFailedOperation: "showFailedOperation", reload: "reload" }, viewQueries: [{ propertyName: "listItem", first: true, predicate: ["listItem"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<c8y-li\n class=\"c8y-list__item--double-actions\"\n [ngClass]=\"{ 'c8y-list__item--no-expand': !detailsCollapsed }\"\n [collapsed]=\"detailsCollapsed\"\n #listItem\n id=\"{{ bulkOperation.id }}\"\n>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"getOperationStatusOptions().icon\"\n [ngClass]=\"getOperationStatusOptions().styleClass\"\n [tooltip]=\"getOperationStatusOptions().label | translate\"\n ></i>\n </c8y-li-icon>\n <div [ngClass]=\"{ 'content-flex-58': !readOnly, 'content-flex-50': readOnly }\">\n <div class=\"col-5\">\n <button\n class=\"btn-clean\"\n type=\"button\"\n title=\"{{ bulkOperation.id }} - {{\n bulkOperation.operationPrototype.description | translate\n }}\"\n (click)=\"listItem.toggleCollapsed()\"\n >\n <span class=\"text-truncate\">\n <strong class=\"text-muted m-r-4\">{{ bulkOperation.id }}</strong>\n {{ bulkOperation.operationPrototype.description | translate }}\n </span>\n </button>\n </div>\n <div class=\"flex-grow\">\n <div class=\"m-t-8 visible-xs\"></div>\n <hr *ngIf=\"isStatusCanceled(); else statusNotCanceled\" class=\"m-t-16 m-b-0 visible-xs\" />\n <ng-template #statusNotCanceled>\n <div\n [class]=\"progressBarClass\"\n title=\"{{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\"\n >\n <div\n [class]=\"progressBarColor\"\n role=\"progressbar\"\n [attr.aria-label]=\"'Progress' | translate\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [style.width.%]=\"progressBarStatus\"\n >\n <span *ngIf=\"progressBarStatus !== 0\">\n {{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\n </span>\n </div>\n </div>\n </ng-template>\n </div>\n <div class=\"col-4\">\n <div class=\"p-t-8 visible-xs\"></div>\n <small *ngIf=\"bulkOperation.progress.successful > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"check-circle\" class=\"text-success m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountSuccessful: bulkOperation.progress.successful }\"\n >\n {{ bulkOperationsCountSuccessful }} successful\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.failed > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"warning\" class=\"text-danger m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountFailed: bulkOperation.progress.failed }\"\n >\n {{ bulkOperationsCountFailed }} failed\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.executing > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"refresh\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountExecuting: bulkOperation.progress.executing }\"\n >\n {{ bulkOperationsCountExecuting }} executing\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.pending > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"clock-o\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountPending: bulkOperation.progress.pending }\"\n >\n {{ bulkOperationsCountPending }} pending\n </span>\n </small>\n </div>\n </div>\n <div class=\"c8y-list__item__footer\">\n <div class=\"m-r-16\">\n <span class=\"text-label-small m-r-4\" translate>Start</span>\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>\n {{ bulkOperation.startDate | c8yDate }}\n </span>\n </small>\n </div>\n <div class=\"m-r-16\" *ngIf=\"bulkOperationGeneralStatus.CANCELED !== bulkOperation.generalStatus\">\n <span class=\"text-label-small m-r-4\" translate>Finish</span>\n\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>{{ finishDate | c8yDate }}</span>\n </small>\n <button\n class=\"btn-help btn-help--sm\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ finishDatePopoverText | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n *ngIf=\"isStatusScheduled() || isStatusExecutingOrExecutingWithError()\"\n ></button>\n </div>\n </div>\n <ng-container *ngIf=\"!readOnly\">\n <c8y-li-action\n *ngIf=\"isStatusScheduled()\"\n label=\"{{ 'Edit schedule' | translate }}\"\n (click)=\"editSchedule()\"\n icon=\"pencil\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"\n isStatusScheduled() || (isStatusExecutingOrExecutingWithError() && !allOperationsCreated())\n \"\n label=\"{{ 'Cancel bulk operation' | translate }}\"\n (click)=\"cancelBulkOperation()\"\n icon=\"remove\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Retry failed operations' | translate }}\"\n (click)=\"retryFailedOperation()\"\n icon=\"repeat\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Set operation to SUCCESSFUL' | translate }}\"\n (click)=\"setToSuccessful()\"\n icon=\"check-circle\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n </ng-container>\n <c8y-li-collapse class=\"m-b-16\">\n <c8y-operation-details-tabs\n *ngIf=\"!listItem.collapsed\"\n [operation]=\"bulkOperation\"\n [readOnly]=\"readOnly\"\n (onRetryFailedOperations)=\"retryFailedOperation()\"\n (showFailedOperation)=\"openFailedOperation($event)\"\n [bulkOperationModalDetailsService]=\"bulkOperationListItemService\"\n ></c8y-operation-details-tabs>\n </c8y-li-collapse>\n</c8y-li>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3.ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "component", type: i3.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "directive", type: i3.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: i6.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { 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: "component", type: i8.OperationDetailsTabsComponent, selector: "c8y-operation-details-tabs", inputs: ["operation", "readOnly", "bulkOperationModalDetailsService"], outputs: ["onRetryFailedOperations", "showFailedOperation"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }, { kind: "pipe", type: i3.NumberPipe, name: "c8yNumber" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BulkOperationListItemComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-bulk-operation-list-item', template: "<c8y-li\n class=\"c8y-list__item--double-actions\"\n [ngClass]=\"{ 'c8y-list__item--no-expand': !detailsCollapsed }\"\n [collapsed]=\"detailsCollapsed\"\n #listItem\n id=\"{{ bulkOperation.id }}\"\n>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"getOperationStatusOptions().icon\"\n [ngClass]=\"getOperationStatusOptions().styleClass\"\n [tooltip]=\"getOperationStatusOptions().label | translate\"\n ></i>\n </c8y-li-icon>\n <div [ngClass]=\"{ 'content-flex-58': !readOnly, 'content-flex-50': readOnly }\">\n <div class=\"col-5\">\n <button\n class=\"btn-clean\"\n type=\"button\"\n title=\"{{ bulkOperation.id }} - {{\n bulkOperation.operationPrototype.description | translate\n }}\"\n (click)=\"listItem.toggleCollapsed()\"\n >\n <span class=\"text-truncate\">\n <strong class=\"text-muted m-r-4\">{{ bulkOperation.id }}</strong>\n {{ bulkOperation.operationPrototype.description | translate }}\n </span>\n </button>\n </div>\n <div class=\"flex-grow\">\n <div class=\"m-t-8 visible-xs\"></div>\n <hr *ngIf=\"isStatusCanceled(); else statusNotCanceled\" class=\"m-t-16 m-b-0 visible-xs\" />\n <ng-template #statusNotCanceled>\n <div\n [class]=\"progressBarClass\"\n title=\"{{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\"\n >\n <div\n [class]=\"progressBarColor\"\n role=\"progressbar\"\n [attr.aria-label]=\"'Progress' | translate\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [style.width.%]=\"progressBarStatus\"\n >\n <span *ngIf=\"progressBarStatus !== 0\">\n {{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\n </span>\n </div>\n </div>\n </ng-template>\n </div>\n <div class=\"col-4\">\n <div class=\"p-t-8 visible-xs\"></div>\n <small *ngIf=\"bulkOperation.progress.successful > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"check-circle\" class=\"text-success m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountSuccessful: bulkOperation.progress.successful }\"\n >\n {{ bulkOperationsCountSuccessful }} successful\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.failed > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"warning\" class=\"text-danger m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountFailed: bulkOperation.progress.failed }\"\n >\n {{ bulkOperationsCountFailed }} failed\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.executing > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"refresh\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountExecuting: bulkOperation.progress.executing }\"\n >\n {{ bulkOperationsCountExecuting }} executing\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.pending > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"clock-o\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountPending: bulkOperation.progress.pending }\"\n >\n {{ bulkOperationsCountPending }} pending\n </span>\n </small>\n </div>\n </div>\n <div class=\"c8y-list__item__footer\">\n <div class=\"m-r-16\">\n <span class=\"text-label-small m-r-4\" translate>Start</span>\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>\n {{ bulkOperation.startDate | c8yDate }}\n </span>\n </small>\n </div>\n <div class=\"m-r-16\" *ngIf=\"bulkOperationGeneralStatus.CANCELED !== bulkOperation.generalStatus\">\n <span class=\"text-label-small m-r-4\" translate>Finish</span>\n\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>{{ finishDate | c8yDate }}</span>\n </small>\n <button\n class=\"btn-help btn-help--sm\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ finishDatePopoverText | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n *ngIf=\"isStatusScheduled() || isStatusExecutingOrExecutingWithError()\"\n ></button>\n </div>\n </div>\n <ng-container *ngIf=\"!readOnly\">\n <c8y-li-action\n *ngIf=\"isStatusScheduled()\"\n label=\"{{ 'Edit schedule' | translate }}\"\n (click)=\"editSchedule()\"\n icon=\"pencil\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"\n isStatusScheduled() || (isStatusExecutingOrExecutingWithError() && !allOperationsCreated())\n \"\n label=\"{{ 'Cancel bulk operation' | translate }}\"\n (click)=\"cancelBulkOperation()\"\n icon=\"remove\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Retry failed operations' | translate }}\"\n (click)=\"retryFailedOperation()\"\n icon=\"repeat\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Set operation to SUCCESSFUL' | translate }}\"\n (click)=\"setToSuccessful()\"\n icon=\"check-circle\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n </ng-container>\n <c8y-li-collapse class=\"m-b-16\">\n <c8y-operation-details-tabs\n *ngIf=\"!listItem.collapsed\"\n [operation]=\"bulkOperation\"\n [readOnly]=\"readOnly\"\n (onRetryFailedOperations)=\"retryFailedOperation()\"\n (showFailedOperation)=\"openFailedOperation($event)\"\n [bulkOperationModalDetailsService]=\"bulkOperationListItemService\"\n ></c8y-operation-details-tabs>\n </c8y-li-collapse>\n</c8y-li>\n" }] }], ctorParameters: () => [{ type: i1.BulkOperationListItemService }, { type: i2.BulkOperationsService }, { type: i3.ModalService }, { type: i3.AlertService }, { type: i4.BsModalService }], propDecorators: { bulkOperation: [{ type: Input }], detailsCollapsed: [{ type: Input }], readOnly: [{ type: Input }], showFailedOperation: [{ type: Output }], reload: [{ type: Output }], listItem: [{ type: ViewChild, args: ['listItem', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVsay1vcGVyYXRpb24tbGlzdC1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL29wZXJhdGlvbnMvYnVsay1vcGVyYXRpb24tbGlzdC1pdGVtL2J1bGstb3BlcmF0aW9uLWxpc3QtaXRlbS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9vcGVyYXRpb25zL2J1bGstb3BlcmF0aW9uLWxpc3QtaXRlbS9idWxrLW9wZXJhdGlvbi1saXN0LWl0ZW0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFFTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFrQiwwQkFBMEIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6RSxPQUFPLEVBQ0wsWUFBWSxFQUNaLE9BQU8sRUFDUCxpQkFBaUIsRUFDakIsWUFBWSxFQUNaLE1BQU0sRUFDUCxNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdEQUF3RCxDQUFDO0FBQy9GLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDNUQsT0FBTyxFQUFjLGNBQWMsRUFBZ0IsTUFBTSxxQkFBcUIsQ0FBQztBQUMvRSxPQUFPLEVBQ0wsNkJBQTZCLEVBRTlCLE1BQU0sa0NBQWtDLENBQUM7QUFDMUMsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDbEYsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0scURBQXFELENBQUM7Ozs7Ozs7Ozs7QUFNN0csTUFBTSxPQUFPLDhCQUE4QjtJQXdCekMsWUFDUyw0QkFBMEQsRUFDekQscUJB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QyxRQUFRLENBQUMsTUFBTTtnQkFDbEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsT0FBTztnQkFDbkMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUN6QyxDQUFDO0lBQ0osQ0FBQztJQUVELGdCQUFnQjtRQUNkLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEtBQUssSUFBSSxDQUFDLDBCQUEwQixDQUFDLFFBQVEsQ0FBQztJQUN2RixDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEtBQUssSUFBSSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQztJQUNyRixDQUFDOytHQTlNVSw4QkFBOEI7bUdBQTlCLDhCQUE4QixnWUNqQzNDLHV4TUE4S0E7OzRGRDdJYSw4QkFBOEI7a0JBSjFDLFNBQVM7K0JBQ0UsOEJBQThCO3dOQU14QyxhQUFhO3NCQURaLEtBQUs7Z0JBR04sZ0JBQWdCO3NCQURmLEtBQUs7Z0JBR04sUUFBUTtzQkFEUCxLQUFLO2dCQUVJLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ2tDLFFBQVE7c0JBQWhELFNBQVM7dUJBQUMsVUFBVSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSU9wZXJhdGlvbkJ1bGssIE9wZXJhdGlvbkJ1bGtHZW5lcmFsU3RhdHVzIH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHtcbiAgQWxlcnRTZXJ2aWNlLFxuICBnZXR0ZXh0LFxuICBMaXN0SXRlbUNvbXBvbmVudCxcbiAgTW9kYWxTZXJ2aWNlLFxuICBTdGF0dXNcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBCdWxrT3BlcmF0aW9uc1NlcnZpY2UgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL29wZXJhdGlvbnMvYnVsay1vcGVyYXRpb25zLXNlcnZpY2UnO1xuaW1wb3J0IHsgQlVMS19PUEVSQVRJT05fRVZFTlQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL29wZXJhdGlvbnMvcHJvZHVjdC1leHBlcmllbmNlJztcbmltcG9ydCB7IGFzc2lnbiwgY2xvbmVEZWVwLCBmaW5kLCB2YWx1ZXMgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgQnNNb2RhbFJlZiwgQnNNb2RhbFNlcnZpY2UsIE1vZGFsT3B0aW9ucyB9IGZyb20gJ25neC1ib290c3RyYXAvbW9kYWwnO1xuaW1wb3J0IHtcbiAgQlVMS19PUEVSQVRJT05fU1RBVFVTX09QVElPTlMsXG4gIE9wZXJhdGlvblN0YXR1c09wdGlvbnNNYXBcbn0gZnJvbSAnLi9idWxrLW9wZXJhdGlvbi1saXN0LWl0ZW0ubW9kZWwnO1xuaW1wb3J0IHsgQnVsa09wZXJhdGlvbkxpc3RJdGVtU2VydmljZSB9IGZyb20gJy4vYnVsay1vcGVyYXRpb24tbGlzdC1pdGVtLnNlcnZpY2UnO1xuaW1wb3J0IHsgQnVsa09wZXJhdGlvbnNSZXNjaGVkdWxlTW9kYWxDb21wb25lbnQgfSBmcm9tICcuL21vZGFscy9idWxrLW9wZXJhdGlvbnMtcmVzY2hlZHVsZS1tb2RhbC5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktYnVsay1vcGVyYXRpb24tbGlzdC1pdGVtJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2J1bGstb3BlcmF0aW9uLWxpc3QtaXRlbS5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgQnVsa09wZXJhdGlvbkxpc3RJdGVtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBCVUxLX09QRVJBVElPTl9FVkVOVCA9IEJVTEtfT1BFUkFUSU9OX0VWRU5UO1xuICBASW5wdXQoKVxuICBidWxrT3BlcmF0aW9uOiBQYXJ0aWFsPElPcGVyYXRpb25CdWxrPjtcbiAgQElucHV0KClcbiAgZGV0YWlsc0NvbGxhcHNlZCA9IHRydWU7XG4gIEBJbnB1dCgpXG4gIHJlYWRPbmx5ID0gZmFsc2U7XG4gIEBPdXRwdXQoKSBzaG93RmFpbGVkT3BlcmF0aW9uID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcmVsb2FkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQFZpZXdDaGlsZCgnbGlzdEl0ZW0nLCB7IHN0YXRpYzogdHJ1ZSB9KSBsaXN0SXRlbTogTGlzdEl0ZW1Db21wb25lbnQ7XG4gIGljb25DbGFzczogc3RyaW5nO1xuICBmaW5pc2hEYXRlOiBudW1iZXI7XG4gIHJlZnJlc2hMb2FkaW5nID0gZmFsc2U7XG4gIGJ1bGtPcGVyYXRpb25HZW5lcmFsU3RhdHVzID0gT3BlcmF0aW9uQnVsa0dlbmVyYWxTdGF0dXM7XG4gIEJVTEtfT1BFUkFUSU9OX1NUQVRVU19PUFRJT05TOiBPcGVyYXRpb25TdGF0dXNPcHRpb25zTWFwID0gQlVMS19PUEVSQVRJT05fU1RBVFVTX09QVElPTlM7XG4gIGJzTW9kYWxSZWY6IEJzTW9kYWxSZWY7XG4gIGZpbmlzaERhdGVQb3BvdmVyVGV4dDogc3RyaW5nID0gZ2V0dGV4dChcbiAgICAnQXBwcm94aW1hdGUgZGF0ZSwgZXN0aW1hdGVkIGJhc2VkIG9uIHRoZSBidWxrIG9wZXJhdGlvbiBzZXR0aW5ncy4nXG4gICk7XG4gIHByb2dyZXNzQmFyQ2xhc3MgPSAncHJvZ3Jlc3MnO1xuICBwcm9ncmVzc0JhckNvbG9yOiBzdHJpbmc7XG4gIHByb2dyZXNzQmFyU3RhdHVzID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYnVsa09wZXJhdGlvbkxpc3RJdGVtU2VydmljZTogQnVsa09wZXJhdGlvbkxpc3RJdGVtU2VydmljZSxcbiAgICBwcml2YXRlIGJ1bGtPcGVyYXRpb25zU2VydmljZTogQnVsa09wZXJhdGlvbnNTZXJ2aWNlLFxuICAgIHByaXZhdGUgbW9kYWw6IE1vZGFsU2VydmljZSxcbiAgICBwcml2YXRlIGFsZXJ0OiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBic01vZGFsU2VydmljZTogQnNNb2RhbFNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZmluaXNoRGF0ZSA9IHRoaXMuY2FsY3VsYXRlRmluaXNoRGF0ZU1zKCk7XG4gICAgdGhpcy5zZXRQcm9ncmVzc0JhcigpO1xuICB9XG5cbiAgZ2V0T3BlcmF0aW9uU3RhdHVzT3B0aW9ucygpIHtcbiAgICBjb25zdCBzdGF0dXNPcHRpb25zID0gdmFsdWVzKEJVTEtfT1BFUkFUSU9OX1NUQVRVU19PUFRJT05TKTtcbiAgICByZXR1cm4gZmluZChzdGF0dXNPcHRpb25zLCBvcHRpb25zID0+XG4gICAgICBvcHRpb25zLmdlbmVyYWxTdGF0dXNlcy5pbmNsdWRlcyh0aGlzLmJ1bGtPcGVyYXRpb24uZ2VuZXJhbFN0YXR1cylcbiAgICApO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzLmJ1bGtPcGVyYXRpb24gJiYgIWNoYW5nZXMuYnVsa09wZXJhdGlvbi5maXJzdENoYW5nZSkge1xuICAgICAgdGhpcy5zZXRQcm9ncmVzc0JhcigpO1xuICAgIH1cbiAgfVxuICBjYWxjdWxhdGVGaW5pc2hEYXRlTXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBzdGFydERhdGVNczogbnVtYmVyID0gbmV3IERhdGUodGhpcy5idWxrT3BlcmF0aW9uLnN0YXJ0RGF0ZSkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGNyZWF0aW9uUmFtcE1zOiBudW1iZXIgPSB0aGlzLmJ1bGtPcGVyYXRpb24uY3JlYXRpb25SYW1wICogMTAwMDtcblxuICAgIHJldHVybiBzdGFydERhdGVNcyArIGNyZWF0aW9uUmFtcE1zICogdGhpcy5idWxrT3BlcmF0aW9uLnByb2dyZXNzLmFsbDtcbiAgfVxuXG4gIHByb2dyZXNzQmFyUHJvZ3Jlc3NGbigpIHtcbiAgICByZXR1cm4gKFxuICAgICAgKCh0aGlzLmJ1bGtPcGVyYXRpb24ucHJvZ3Jlc3Muc3VjY2Vzc2Z1bCArIHRoaXMuYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5mYWlsZWQpIC9cbiAgICAgICAgdGhpcy5idWxrT3BlcmF0aW9uLnByb2dyZXNzLmFsbCkgKlxuICAgICAgMTAwXG4gICAgKTtcbiAgfVxuXG4gIHNldFByb2dyZXNzQmFyKCkge1xuICAgIGNvbnN0IHN0YXRpY0NvbnRlbnRPZkNsYXNzID0gJ3Byb2dyZXNzLWJhciBwcm9ncmVzcy1zdHJpcGVkIGFjdGl2ZSBwcm9ncmVzcy1iYXInO1xuXG4gICAgY29uc3QgcHJvZ3Jlc3NCYXJTdGF0ZSA9IHtcbiAgICAgIEVYRUNVVElORzoge1xuICAgICAgICBwcm9ncmVzc0JhckNsYXNzOiAncHJvZ3Jlc3MgcHJvZ3Jlc3Mtc3RyaXBlZCBhY3RpdmUnLFxuICAgICAgICBwcm9ncmVzc0JhckNvbG9yOiBgJHtzdGF0aWNDb250ZW50T2ZDbGFzc30tcHJpbWFyeWAsXG4gICAgICAgIHByb2dyZXNzQmFyU3RhdHVzOiB0aGlzLnByb2dyZXNzQmFyUHJvZ3Jlc3NGbigpXG4gICAgICB9LFxuICAgICAgRVhFQ1VUSU5HX1dJVEhfRVJST1I6IHtcbiAgICAgICAgcHJvZ3Jlc3NCYXJDbGFzczogJ3Byb2dyZXNzIHByb2dyZXNzLXN0cmlwZWQgYWN0aXZlJyxcbiAgICAgICAgcHJvZ3Jlc3NCYXJDb2xvcjogYCR7c3RhdGljQ29udGVudE9mQ2xhc3N9LWRhbmdlcmAsXG4gICAgICAgIHByb2dyZXNzQmFyU3RhdHVzOiB0aGlzLnByb2dyZXNzQmFyUHJvZ3Jlc3NGbigpXG4gICAgICB9LFxuICAgICAgRkFJTEVEOiB7XG4gICAgICAgIHByb2dyZXNzQmFyQ2xhc3M6ICdwcm9ncmVzcycsXG4gICAgICAgIHByb2dyZXNzQmFyQ29sb3I6IGAke3N0YXRpY0NvbnRlbnRPZkNsYXNzfS1kYW5nZXJgLFxuICAgICAgICBwcm9ncmVzc0JhclN0YXR1czogMTAwXG4gICAgICB9LFxuICAgICAgU1VDQ0VTU0ZVTDoge1xuICAgICAgICBwcm9ncmVzc0JhckNsYXNzOiAncHJvZ3Jlc3MnLFxuICAgICAgICBwcm9ncmVzc0JhckNvbG9yOiBgJHtzdGF0aWNDb250ZW50T2ZDbGFzc30tc3VjY2Vzc2AsXG4gICAgICAgIHByb2dyZXNzQmFyU3RhdHVzOiAxMDBcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgYXNzaWduKHRoaXMsIHByb2dyZXNzQmFyU3RhdGVbdGhpcy5idWxrT3BlcmF0aW9uLmdlbmVyYWxTdGF0dXNdKTtcbiAgfVxuXG4gIGVkaXRTY2hlZHVsZSgpIHtcbiAgICBjb25zdCByZXNjaGVkdWxlZE9wZXJhdGlvbiA9IGNsb25lRGVlcCh0aGlzLmJ1bGtPcGVyYXRpb24pO1xuICAgIGNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgICAgIGJ1bGtPcGVyYXRpb246IHJlc2NoZWR1bGVkT3BlcmF0aW9uXG4gICAgfTtcbiAgICBjb25zdCBtb2RhbE9wdGlvbnMgPSB7XG4gICAgICBpbml0aWFsU3RhdGUsXG4gICAgICBjbGFzczogJ21vZGFsLXNtJyxcbiAgICAgIGFyaWFEZXNjcmliZWRieTogJ21vZGFsLWJvZHknLFxuICAgICAgYXJpYUxhYmVsbGVkQnk6ICdtb2RhbC10aXRsZScsXG4gICAgICBiYWNrZHJvcDogJ3N0YXRpYydcbiAgICB9IGFzIE1vZGFsT3B0aW9ucztcbiAgICB0aGlzLmJzTW9kYWxSZWYgPSB0aGlzLmJzTW9kYWxTZXJ2aWNlLnNob3coXG4gICAgICBCdWxrT3BlcmF0aW9uc1Jlc2NoZWR1bGVNb2RhbENvbXBvbmVudCxcbiAgICAgIG1vZGFsT3B0aW9uc1xuICAgICk7XG4gIH1cblxuICBhc3luYyBjYW5jZWxCdWxrT3BlcmF0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLm1vZGFsLmNvbmZpcm0oXG4gICAgICAgIGdldHRleHQoJ0NhbmNlbCBidWxrIG9wZXJhdGlvbicpLFxuICAgICAgICBnZXR0ZXh0KCdZb3UgYXJlIGFib3V0IHRvIGNhbmNlbCB0aGUgYnVsayBvcGVyYXRpb24uIERvIHlvdSB3YW50IHRvIHByb2NlZWQ/JyksXG4gICAgICAgIFN0YXR1cy5EQU5HRVIsXG4gICAgICAgIHt9LFxuICAgICAgICB7fSxcbiAgICAgICAgeyBldmVudE5hbWU6IEJVTEtfT1BFUkFUSU9OX0VWRU5UIH1cbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmJ1bGtPcGVyYXRpb25zU2VydmljZS5kZWxldGVCdWxrT3BlcmF0aW9uKHRoaXMuYnVsa09wZXJhdGlvbi5pZCk7XG4gICAgICB0aGlzLnJlbG9hZC5lbWl0KCk7XG4gICAgICB0aGlzLmFsZXJ0LnN1Y2Nlc3MoZ2V0dGV4dCgnT3BlcmF0aW9uIGNhbmNlbGVkLicpKTtcbiAgICB9IGNhdGNoIChlcikge1xuICAgICAgdGhpcy5hbGVydC5hZGRTZXJ2ZXJGYWlsdXJlKGVyKTtcbiAgICB9XG4gIH1cblxuICByZXRyeUZhaWxlZE9wZXJhdGlvbigpIHtcbiAgICBjb25zdCBjbG9uZWRCdWxrID0gY2xvbmVEZWVwKHRoaXMuYnVsa09wZXJhdGlvbik7XG5cbiAgICAvLyBjaGFuZ2UgdGhlIGlkIHRvIGZhaWxlZHBhcmVudElkIHNpbWlsYXIgdG8gdGhlIGxvZ2ljIGluIGRldmljZUJ1bGtDb250cm9sLnNlcnZpY2UuanNcbiAgICBkZWxldGUgY2xvbmVkQnVsay5ncm91cElkO1xuICAgIGNsb25lZEJ1bGsuZmFpbGVkUGFyZW50SWQgPSB0aGlzLmJ1bGtPcGVyYXRpb24uaWQ7XG5cbiAgICAvLyBzaG93IHJlc2NoZGVkdWxlIG1vZGFsOlxuICAgIGNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgICAgIGJ1bGtPcGVyYXRpb246IGNsb25lZEJ1bGssXG4gICAgICBpc1JldHJ5T3BlcmF0aW9uOiB0cnVlXG4gICAgfTtcbiAgICBjb25zdCBtb2RhbE9wdGlvbnMgPSB7IGluaXRpYWxTdGF0ZSwgY2xhc3M6ICdtb2RhbC1zbScsIGJhY2tkcm9wOiAnc3RhdGljJyB9IGFzIE1vZGFsT3B0aW9ucztcbiAgICB0aGlzLmJzTW9kYWxSZWYgPSB0aGlzLmJzTW9kYWxTZXJ2aWNlLnNob3coXG4gICAgICBCdWxrT3BlcmF0aW9uc1Jlc2NoZWR1bGVNb2RhbENvbXBvbmVudCxcbiAgICAgIG1vZGFsT3B0aW9uc1xuICAgICk7XG4gICAgdGhpcy5ic01vZGFsUmVmLmNvbnRlbnQuY2xvc2VTdWJqZWN0LnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZC5lbWl0KCk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzZXRUb1N1Y2Nlc3NmdWwoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMubW9kYWwuY29uZmlybShcbiAgICAgICAgZ2V0dGV4dCgnU2V0IG1hbnVhbGx5IGJ1bGsgb3BlcmF0aW9uIHRvIFNVQ0NFU1NGVUwnKSxcbiAgICAgICAgZ2V0dGV4dChcbiAgICAgICAgICAnWW91IGFyZSBhYm91dCB0byBjaGFuZ2UgdGhlIGJ1bGsgb3BlcmF0aW9uIHN0YXR1cyB0byBTVUNDRVNTRlVMLiBEbyB5b3Ugd2FudCB0byBwcm9jZWVkPydcbiAgICAgICAgKSxcbiAgICAgICAgU3RhdHVzLkRBTkdFUixcbiAgICAgICAge30sXG4gICAgICAgIHt9LFxuICAgICAgICB7IGV2ZW50TmFtZTogQlVMS19PUEVSQVRJT05fRVZFTlQgfVxuICAgICAgKTtcblxuICAgICAgYXdhaXQgdGhpcy5idWxrT3BlcmF0aW9uc1NlcnZpY2UudXBkYXRlQnVsa09wZXJhdGlvbih7XG4gICAgICAgIGlkOiB0aGlzLmJ1bGtPcGVyYXRpb24uaWQsXG4gICAgICAgIGdlbmVyYWxTdGF0dXM6IE9wZXJhdGlvbkJ1bGtHZW5lcmFsU3RhdHVzLlNVQ0NFU1NGVUxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yZWxvYWQuZW1pdCgpO1xuICAgICAgdGhpcy5hbGVydC5zdWNjZXNzKGdldHRleHQoJ09wZXJhdGlvbiBzdGF0dXMgY2hhbmdlZCB0byBTVUNDRVNTRlVMLicpKTtcbiAgICB9IGNhdGNoIChlcikge1xuICAgICAgdGhpcy5hbGVydC5hZGRTZXJ2ZXJGYWlsdXJlKGVyKTtcbiAgICB9XG4gIH1cblxuICBvcGVuRmFpbGVkT3BlcmF0aW9uKGZhaWxlZFBhcmVudElkKSB7XG4gICAgdGhpcy5zaG93RmFpbGVkT3BlcmF0aW9uLmVtaXQoZmFpbGVkUGFyZW50SWQpO1xuICB9XG5cbiAgaXNTdGF0dXNTY2hlZHVsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYnVsa09wZXJhdGlvbi5nZW5lcmFsU3RhdHVzID09PSB0aGlzLmJ1bGtPcGVyYXRpb25HZW5lcmFsU3RhdHVzLlNDSEVEVUxFRDtcbiAgfVxuXG4gIGlzU3RhdHVzRXhlY3V0aW5nT3JFeGVjdXRpbmdXaXRoRXJyb3IoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuYnVsa09wZXJhdGlvbi5nZW5lcmFsU3RhdHVzID09PSB0aGlzLmJ1bGtPcGVyYXRpb25HZW5lcmFsU3RhdHVzLkVYRUNVVElORyB8fFxuICAgICAgdGhpcy5idWxrT3BlcmF0aW9uLmdlbmVyYWxTdGF0dXMgPT09IHRoaXMuYnVsa09wZXJhdGlvbkdlbmVyYWxTdGF0dXMuRVhFQ1VUSU5HX1dJVEhfRVJST1JcbiAgICApO1xuICB9XG5cbiAgYWxsT3BlcmF0aW9uc0NyZWF0ZWQoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5hbGwgPT09XG4gICAgICB0aGlzLmJ1bGtPcGVyYXRpb24ucHJvZ3Jlc3MuZXhlY3V0aW5nICtcbiAgICAgICAgdGhpcy5idWxrT3BlcmF0aW9uLnByb2dyZXNzLmZhaWxlZCArXG4gICAgICAgIHRoaXMuYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5wZW5kaW5nICtcbiAgICAgICAgdGhpcy5idWxrT3BlcmF0aW9uLnByb2dyZXNzLnN1Y2Nlc3NmdWxcbiAgICApO1xuICB9XG5cbiAgaXNTdGF0dXNDYW5jZWxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5idWxrT3BlcmF0aW9uLmdlbmVyYWxTdGF0dXMgPT09IHRoaXMuYnVsa09wZXJhdGlvbkdlbmVyYWxTdGF0dXMuQ0FOQ0VMRUQ7XG4gIH1cblxuICBpc1N0YXR1c0ZhaWxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5idWxrT3BlcmF0aW9uLmdlbmVyYWxTdGF0dXMgPT09IHRoaXMuYnVsa09wZXJhdGlvbkdlbmVyYWxTdGF0dXMuRkFJTEVEO1xuICB9XG59XG4iLCI8Yzh5LWxpXG4gIGNsYXNzPVwiYzh5LWxpc3RfX2l0ZW0tLWRvdWJsZS1hY3Rpb25zXCJcbiAgW25nQ2xhc3NdPVwieyAnYzh5LWxpc3RfX2l0ZW0tLW5vLWV4cGFuZCc6ICFkZXRhaWxzQ29sbGFwc2VkIH1cIlxuICBbY29sbGFwc2VkXT1cImRldGFpbHNDb2xsYXBzZWRcIlxuICAjbGlzdEl0ZW1cbiAgaWQ9XCJ7eyBidWxrT3BlcmF0aW9uLmlkIH19XCJcbj5cbiAgPGM4eS1saS1pY29uPlxuICAgIDxpXG4gICAgICBbYzh5SWNvbl09XCJnZXRPcGVyYXRpb25TdGF0dXNPcHRpb25zKCkuaWNvblwiXG4gICAgICBbbmdDbGFzc109XCJnZXRPcGVyYXRpb25TdGF0dXNPcHRpb25zKCkuc3R5bGVDbGFzc1wiXG4gICAgICBbdG9vbHRpcF09XCJnZXRPcGVyYXRpb25TdGF0dXNPcHRpb25zKCkubGFiZWwgfCB0cmFuc2xhdGVcIlxuICAgID48L2k+XG4gIDwvYzh5LWxpLWljb24+XG4gIDxkaXYgW25nQ2xhc3NdPVwieyAnY29udGVudC1mbGV4LTU4JzogIXJlYWRPbmx5LCAnY29udGVudC1mbGV4LTUwJzogcmVhZE9ubHkgfVwiPlxuICAgIDxkaXYgY2xhc3M9XCJjb2wtNVwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImJ0bi1jbGVhblwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICB0aXRsZT1cInt7IGJ1bGtPcGVyYXRpb24uaWQgfX0gLSB7e1xuICAgICAgICAgIGJ1bGtPcGVyYXRpb24ub3BlcmF0aW9uUHJvdG90eXBlLmRlc2NyaXB0aW9uIHwgdHJhbnNsYXRlXG4gICAgICAgIH19XCJcbiAgICAgICAgKGNsaWNrKT1cImxpc3RJdGVtLnRvZ2dsZUNvbGxhcHNlZCgpXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCI+XG4gICAgICAgICAgPHN0cm9uZyBjbGFzcz1cInRleHQtbXV0ZWQgbS1yLTRcIj57eyBidWxrT3BlcmF0aW9uLmlkIH19PC9zdHJvbmc+XG4gICAgICAgICAge3sgYnVsa09wZXJhdGlvbi5vcGVyYXRpb25Qcm90b3R5cGUuZGVzY3JpcHRpb24gfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZsZXgtZ3Jvd1wiPlxuICAgICAgPGRpdiBjbGFzcz1cIm0tdC04IHZpc2libGUteHNcIj48L2Rpdj5cbiAgICAgIDxociAqbmdJZj1cImlzU3RhdHVzQ2FuY2VsZWQoKTsgZWxzZSBzdGF0dXNOb3RDYW5jZWxlZFwiIGNsYXNzPVwibS10LTE2IG0tYi0wIHZpc2libGUteHNcIiAvPlxuICAgICAgPG5nLXRlbXBsYXRlICNzdGF0dXNOb3RDYW5jZWxlZD5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIFtjbGFzc109XCJwcm9ncmVzc0JhckNsYXNzXCJcbiAgICAgICAgICB0aXRsZT1cInt7IHByb2dyZXNzQmFyU3RhdHVzIHwgYzh5TnVtYmVyOiAnZmxvb3InOicxLjAtMCcgfX0lXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIFtjbGFzc109XCJwcm9ncmVzc0JhckNvbG9yXCJcbiAgICAgICAgICAgIHJvbGU9XCJwcm9ncmVzc2JhclwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidQcm9ncmVzcycgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgYXJpYS12YWx1ZW5vdz1cIjBcIlxuICAgICAgICAgICAgYXJpYS12YWx1ZW1pbj1cIjBcIlxuICAgICAgICAgICAgYXJpYS12YWx1ZW1heD1cIjEwMFwiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJwcm9ncmVzc0JhclN0YXR1c1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJwcm9ncmVzc0JhclN0YXR1cyAhPT0gMFwiPlxuICAgICAgICAgICAgICB7eyBwcm9ncmVzc0JhclN0YXR1cyB8IGM4eU51bWJlcjogJ2Zsb29yJzonMS4wLTAnIH19JVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImNvbC00XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwicC10LTggdmlzaWJsZS14c1wiPjwvZGl2PlxuICAgICAgPHNtYWxsICpuZ0lmPVwiYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5zdWNjZXNzZnVsID4gMFwiIGNsYXNzPVwibS1yLTggaWNvbi1mbGV4XCI+XG4gICAgICAgIDxpIGM4eUljb249XCJjaGVjay1jaXJjbGVcIiBjbGFzcz1cInRleHQtc3VjY2VzcyBtLXItNFwiPjwvaT5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBuZ05vbkJpbmRhYmxlXG4gICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgICAgW3RyYW5zbGF0ZVBhcmFtc109XCJ7IGJ1bGtPcGVyYXRpb25zQ291bnRTdWNjZXNzZnVsOiBidWxrT3BlcmF0aW9uLnByb2dyZXNzLnN1Y2Nlc3NmdWwgfVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBidWxrT3BlcmF0aW9uc0NvdW50U3VjY2Vzc2Z1bCB9fSBzdWNjZXNzZnVsXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvc21hbGw+XG4gICAgICA8c21hbGwgKm5nSWY9XCJidWxrT3BlcmF0aW9uLnByb2dyZXNzLmZhaWxlZCA+IDBcIiBjbGFzcz1cIm0tci04IGljb24tZmxleFwiPlxuICAgICAgICA8aSBjOHlJY29uPVwid2FybmluZ1wiIGNsYXNzPVwidGV4dC1kYW5nZXIgbS1yLTRcIj48L2k+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgbmdOb25CaW5kYWJsZVxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgIFt0cmFuc2xhdGVQYXJhbXNdPVwieyBidWxrT3BlcmF0aW9uc0NvdW50RmFpbGVkOiBidWxrT3BlcmF0aW9uLnByb2dyZXNzLmZhaWxlZCB9XCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7IGJ1bGtPcGVyYXRpb25zQ291bnRGYWlsZWQgfX0gZmFpbGVkXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvc21hbGw+XG4gICAgICA8c21hbGwgKm5nSWY9XCJidWxrT3BlcmF0aW9uLnByb2dyZXNzLmV4ZWN1dGluZyA+IDBcIiBjbGFzcz1cIm0tci04IGljb24tZmxleFwiPlxuICAgICAgICA8aSBjOHlJY29uPVwicmVmcmVzaFwiIGNsYXNzPVwidGV4dC1wcmltYXJ5IG0tci00XCI+PC9pPlxuICAgICAgICA8c3BhblxuICAgICAgICAgIG5nTm9uQmluZGFibGVcbiAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgICBbdHJhbnNsYXRlUGFyYW1zXT1cInsgYnVsa09wZXJhdGlvbnNDb3VudEV4ZWN1dGluZzogYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5leGVjdXRpbmcgfVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBidWxrT3BlcmF0aW9uc0NvdW50RXhlY3V0aW5nIH19IGV4ZWN1dGluZ1xuICAgICAgICA8L3NwYW4+XG4gICAgICA8L3NtYWxsPlxuICAgICAgPHNtYWxsICpuZ0lmPVwiYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5wZW5kaW5nID4gMFwiIGNsYXNzPVwibS1yLTggaWNvbi1mbGV4XCI+XG4gICAgICAgIDxpIGM4eUljb249XCJjbG9jay1vXCIgY2xhc3M9XCJ0ZXh0LXByaW1hcnkgbS1yLTRcIj48L2k+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgbmdOb25CaW5kYWJsZVxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgIFt0cmFuc2xhdGVQYXJhbXNdPVwieyBidWxrT3BlcmF0aW9uc0NvdW50UGVuZGluZzogYnVsa09wZXJhdGlvbi5wcm9ncmVzcy5wZW5kaW5nIH1cIlxuICAgICAgICA+XG4gICAgICAgICAge3sgYnVsa09wZXJhdGlvbnNDb3VudFBlbmRpbmcgfX0gcGVuZGluZ1xuICAgICAgICA8L3NwYW4+XG4gICAgICA8L3NtYWxsPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImM4eS1saXN0X19pdGVtX19mb290ZXJcIj5cbiAgICA8ZGl2IGNsYXNzPVwibS1yLTE2XCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRleHQtbGFiZWwtc21hbGwgbS1yLTRcIiB0cmFuc2xhdGU+U3RhcnQ8L3NwYW4+XG4gICAgICA8c21hbGwgY2xhc3M9XCJpY29uLWZsZXhcIj5cbiAgICAgICAgPGkgYzh5SWNvbj1cImNhbGVuZGFyXCIgY2xhc3M9XCJtLXItNFwiPjwvaT5cbiAgICAgICAgPHNwYW4+XG4gICAgICAgICAge3sgYnVsa09wZXJhdGlvbi5zdGFydERhdGUgfCBjOHlEYXRlIH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvc21hbGw+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm0tci0xNlwiICpuZ0lmPVwiYnVsa09wZXJhdGlvbkdlbmVyYWxTdGF0dXMuQ0FOQ0VMRUQgIT09IGJ1bGtPcGVyYXRpb24uZ2VuZXJhbFN0YXR1c1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxhYmVsLXNtYWxsIG0tci00XCIgdHJhbnNsYXRlPkZpbmlzaDwvc3Bhbj5cblxuICAgICAgPHNtYWxsIGNsYXNzPVwiaWNvbi1mbGV4XCI+XG4gICAgICAgIDxpIGM4eUljb249XCJjYWxlbmRhclwiIGNsYXNzPVwibS1yLTRcIj48L2k+XG4gICAgICAgIDxzcGFuPnt7IGZpbmlzaERhdGUgfCBjOHlEYXRlIH19PC9zcGFuPlxuICAgICAgPC9zbWFsbD5cbiAgICAgIDxidXR0b25cbiAgICAgICAgY2xhc3M9XCJidG4taGVscCBidG4taGVscC0tc21cIlxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInSGVscCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICBwb3BvdmVyPVwie3sgZmluaXNoRGF0ZVBvcG92ZXJUZXh0IHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgcGxhY2VtZW50PVwicmlnaHRcIlxuICAgICAgICB0cmlnZ2Vycz1cImZvY3VzXCJcbiAgICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICAgICpuZ0lmPVwiaXNTdGF0dXNTY2hlZHVsZWQoKSB8fCBpc1N0YXR1c0V4ZWN1dGluZ09yRXhlY3V0aW5nV2l0aEVycm9yKClcIlxuICAgICAgPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFyZWFkT25seVwiPlxuICAgIDxjOHktbGktYWN0aW9uXG4gICAgICAqbmdJZj1cImlzU3RhdHVzU2NoZWR1bGVkKClcIlxuICAgICAgbGFiZWw9XCJ7eyAnRWRpdCBzY2hlZHVsZScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgKGNsaWNrKT1cImVkaXRTY2hlZHVsZSgpXCJcbiAgICAgIGljb249XCJwZW5jaWxcIlxuICAgICAgYzh5UHJvZHVjdEV4cGVyaWVuY2VcbiAgICAgIFthY3Rpb