@versatiledatakit/data-pipelines
Version:
Data Pipelines help Data Engineers develop, deploy, run, and manage data processing workloads (called 'Data Job')
374 lines • 63.7 kB
JavaScript
/*
* Copyright 2023-2025 Broadcom
* SPDX-License-Identifier: Apache-2.0
*/
import { Component } from '@angular/core';
import { DatePipe } from '@angular/common';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { ClrDatagridSortOrder } from '@clr/angular';
import { ASC, CollectionsUtil, TaurusBaseComponent, URLStateManager } from '@versatiledatakit/shared';
import { DataJobUtil, ErrorUtil } from '../../../../../shared/utils';
import { FiltersSortManager } from '../../../../../commons';
import { JOB_EXECUTIONS_DATA_KEY, JOB_NAME_REQ_PARAM, ORDER_REQ_PARAM, TEAM_NAME_REQ_PARAM } from '../../../../../model';
import { TASK_LOAD_JOB_EXECUTIONS } from '../../../../../state/tasks';
import { LOAD_JOB_ERROR_CODES } from '../../../../../state/error-codes';
import { DataJobExecutionToGridDataJobExecution } from '../model/data-job-execution';
import { SORT_START_TIME_KEY, SUPPORTED_EXECUTIONS_FILTER_CRITERIA, SUPPORTED_EXECUTIONS_SORT_CRITERIA } from '../model/executions-filters.model';
import { ExecutionsTimePeriodCriteria } from './criteria/time-period';
import * as i0 from "@angular/core";
import * as i1 from "@versatiledatakit/shared";
import * as i2 from "@angular/router";
import * as i3 from "../../../../../services";
import * as i4 from "@angular/common";
import * as i5 from "../time-period-filter/time-period-filter.component";
import * as i6 from "@clr/angular";
import * as i7 from "../execution-status-chart/execution-status-chart.component";
import * as i8 from "../execution-duration-chart/execution-duration-chart.component";
import * as i9 from "../data-job-executions-grid/data-job-executions-grid.component";
function DataJobExecutionsPageComponent_ng_container_0_button_5_Template(rf, ctx) { if (rf & 1) {
const _r7 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 4);
i0.ɵɵlistener("click", function DataJobExecutionsPageComponent_ng_container_0_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r6 = i0.ɵɵnextContext(2); return ctx_r6.refresh(); });
i0.ɵɵelement(1, "clr-icon", 5);
i0.ɵɵelementEnd();
} }
function DataJobExecutionsPageComponent_ng_container_0_ng_container_6_lib_execution_status_chart_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "lib-execution-status-chart", 13);
} if (rf & 2) {
const ctx_r8 = i0.ɵɵnextContext(3);
i0.ɵɵproperty("jobExecutions", ctx_r8.filteredJobExecutions);
} }
function DataJobExecutionsPageComponent_ng_container_0_ng_container_6_lib_execution_duration_chart_5_Template(rf, ctx) { if (rf & 1) {
const _r11 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "lib-execution-duration-chart", 14);
i0.ɵɵlistener("executionIdFocused", function DataJobExecutionsPageComponent_ng_container_0_ng_container_6_lib_execution_duration_chart_5_Template_lib_execution_duration_chart_executionIdFocused_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r10 = i0.ɵɵnextContext(3); return ctx_r10.durationChartExecutionIdFocusChange($event); })("zoomPeriodChanged", function DataJobExecutionsPageComponent_ng_container_0_ng_container_6_lib_execution_duration_chart_5_Template_lib_execution_duration_chart_zoomPeriodChanged_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r12 = i0.ɵɵnextContext(3); return ctx_r12.durationChartZoomPeriodChange($event); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r9 = i0.ɵɵnextContext(3);
i0.ɵɵproperty("jobExecutions", ctx_r9.filteredJobExecutions)("chartZoomed", ctx_r9.isPeriodSelected);
} }
function DataJobExecutionsPageComponent_ng_container_0_ng_container_6_Template(rf, ctx) { if (rf & 1) {
const _r14 = i0.ɵɵgetCurrentView();
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "div", 6)(2, "div", 7);
i0.ɵɵtemplate(3, DataJobExecutionsPageComponent_ng_container_0_ng_container_6_lib_execution_status_chart_3_Template, 1, 1, "lib-execution-status-chart", 8);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "div", 9);
i0.ɵɵtemplate(5, DataJobExecutionsPageComponent_ng_container_0_ng_container_6_lib_execution_duration_chart_5_Template, 1, 2, "lib-execution-duration-chart", 10);
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(6, "div", 6)(7, "div", 11)(8, "lib-data-job-executions-grid", 12);
i0.ɵɵlistener("gridCriteriaAndComparatorChanged", function DataJobExecutionsPageComponent_ng_container_0_ng_container_6_Template_lib_data_job_executions_grid_gridCriteriaAndComparatorChanged_8_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r13 = i0.ɵɵnextContext(2); return ctx_r13.gridCriteriaAndComparatorChange($event); });
i0.ɵɵelementEnd()()();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r5 = i0.ɵɵnextContext(2);
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngIf", !ctx_r5.loading);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", !ctx_r5.loading);
i0.ɵɵadvance(3);
i0.ɵɵproperty("jobExecutions", ctx_r5.filteredJobExecutions)("loading", ctx_r5.loading)("filtersSortManager", ctx_r5.filtersSortManager)("highlightedExecutionId", ctx_r5.highlightedExecutionId);
} }
function DataJobExecutionsPageComponent_ng_container_0_Template(rf, ctx) { if (rf & 1) {
const _r16 = i0.ɵɵgetCurrentView();
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "div", 1)(2, "div")(3, "lib-time-period-filter", 2);
i0.ɵɵlistener("filterChanged", function DataJobExecutionsPageComponent_ng_container_0_Template_lib_time_period_filter_filterChanged_3_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r15 = i0.ɵɵnextContext(); return ctx_r15.timeFilterChange($event); });
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(4, "div");
i0.ɵɵtemplate(5, DataJobExecutionsPageComponent_ng_container_0_button_5_Template, 2, 0, "button", 3);
i0.ɵɵelementEnd()();
i0.ɵɵtemplate(6, DataJobExecutionsPageComponent_ng_container_0_ng_container_6_Template, 9, 6, "ng-container", 0);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵadvance(3);
i0.ɵɵproperty("loading", ctx_r0.loading)("minDateTime", ctx_r0.minJobExecutionTime)("filtersSortManager", ctx_r0.filtersSortManager)("selectedPeriodSerialized", ctx_r0.filtersSortManager.filterCriteria["timePeriod"])("selectedPeriod", ctx_r0.zoomedPeriod)("isComponentInErrorState", ctx_r0.isComponentInErrorState);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", !ctx_r0.loading);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx_r0.isComponentInErrorState && (ctx_r0.jobExecutions == null ? null : ctx_r0.jobExecutions.length) > 0);
} }
function DataJobExecutionsPageComponent_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "h3");
i0.ɵɵtext(2, "No executions found.");
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} }
function DataJobExecutionsPageComponent_ng_container_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelement(1, "shared-placeholder", 15);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("plural", true)("errorsQueue", ctx_r2.errors.records)("listenForErrorPatterns", ctx_r2.listenForErrorPatterns);
} }
function DataJobExecutionsPageComponent_ng_container_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "div", 16);
i0.ɵɵelement(2, "clr-spinner");
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} }
export class DataJobExecutionsPageComponent extends TaurusBaseComponent {
/**
* ** Constructor.
*/
constructor(componentService, navigationService, activatedRoute, routerService, dataJobsService, errorHandlerService, changeDetectorRef, router, location, datePipe) {
super(componentService, navigationService, activatedRoute);
this.routerService = routerService;
this.dataJobsService = dataJobsService;
this.errorHandlerService = errorHandlerService;
this.changeDetectorRef = changeDetectorRef;
this.router = router;
this.location = location;
this.datePipe = datePipe;
this.uuid = 'DataJobExecutionsPageComponent';
this.isJobEditable = false;
this.jobExecutions = [];
this.filteredJobExecutions = [];
this.loading = true;
this.initialLoading = true;
/**
* ** Selected DateTime period in time period filter.
*/
this.selectedPeriod = {
from: null,
to: null
};
/**
* ** Indicates whether time filter is chosen, period is selected.
*/
this.isPeriodSelected = false;
/**
* ** Zoomed DateTime period, in duration chart.
*/
this.zoomedPeriod = {
from: null,
to: null
};
/**
* ** Array of error code patterns that component should listen for in errors store.
*/
this.listenForErrorPatterns = [LOAD_JOB_ERROR_CODES[TASK_LOAD_JOB_EXECUTIONS].All];
/**
* ** Flag that indicates there is jobs executions load error.
*/
this.isComponentInErrorState = false;
this.urlStateManager = new URLStateManager(router.url.split('?')[0], location);
this.filtersSortManager = new FiltersSortManager(this.urlStateManager, SUPPORTED_EXECUTIONS_FILTER_CRITERIA, SUPPORTED_EXECUTIONS_SORT_CRITERIA);
}
doNavigateBack() {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.navigateBack({ '$.team': this.teamName }).then();
}
timeFilterChange(selectedPeriod) {
if (this.selectedPeriod.from === selectedPeriod.from && this.selectedPeriod.to === selectedPeriod.to) {
return;
}
this.selectedPeriod = selectedPeriod;
this.isPeriodSelected = this.selectedPeriod.from !== null && this.selectedPeriod.to !== null;
this._filterExecutions();
}
/**
* ** Executed whenever focus on execution id in duration chart changes.
*/
durationChartExecutionIdFocusChange(executionId) {
this.highlightedExecutionId = executionId;
}
durationChartZoomPeriodChange(zoomedPeriod) {
if (this.selectedPeriod.from === zoomedPeriod.from &&
this.selectedPeriod.to === zoomedPeriod.to &&
this.zoomedPeriod.from === zoomedPeriod.from &&
this.zoomedPeriod.to === zoomedPeriod.to) {
return;
}
this.zoomedPeriod = zoomedPeriod;
}
gridCriteriaAndComparatorChange($event) {
this.gridCriteriaAndComparator = $event;
this._filterExecutions();
}
refresh() {
this.fetchDataJobExecutions();
}
fetchDataJobExecutions() {
this.loading = true;
this.dataJobsService.loadJobExecutions(this.model
.withRequestParam(TEAM_NAME_REQ_PARAM, this.teamName)
.withRequestParam(JOB_NAME_REQ_PARAM, this.jobName)
.withRequestParam(ORDER_REQ_PARAM, {
property: 'startTime',
direction: ASC
}));
this.changeDetectorRef.markForCheck();
}
/**
* @inheritDoc
*/
onModelInit() {
let isInitialized = false;
this.subscriptions.push(this.routerService
.getState()
.pipe(distinctUntilChanged((a, b) => {
return CollectionsUtil.isEqual(a.queryParams, b.queryParams);
}))
.subscribe((state) => {
if (!isInitialized) {
isInitialized = true;
this._initialize(state);
}
else {
// pass query params for popped state and let manager extract known filters and sort
// action is needed for Browser backward/forward actions that trigger router navigation
// tested only for "locationToUrl" update strategy for URLStateManager
this.filtersSortManager.bulkUpdate(state.queryParams, true);
}
}));
}
/**
* @inheritDoc
*/
onModelLoad() {
this.loading = false;
this.initialLoading = false;
}
/**
* @inheritDoc
*/
onModelChange(model, task) {
if (task === TASK_LOAD_JOB_EXECUTIONS) {
const executions = model.getComponentState().data.get(JOB_EXECUTIONS_DATA_KEY);
if (executions) {
this.dataJobsService.notifyForJobExecutions([...executions]);
// eslint-disable-next-line @typescript-eslint/unbound-method
const runningExecution = executions.find(DataJobUtil.isJobRunningPredicate);
if (runningExecution) {
this.dataJobsService.notifyForRunningJobExecutionId(runningExecution.id);
}
}
}
}
/**
* @inheritDoc
*/
onModelError(model, _task, newErrorRecords) {
newErrorRecords.forEach((errorRecord) => {
const error = ErrorUtil.extractError(errorRecord.error);
this.errorHandlerService.processError(error);
});
}
/**
* @inheritDoc
*/
ngOnInit() {
// attach listener to ErrorStore and listen for Errors change
this.errors.onChange((store) => {
// if there is record for listened error code patterns set component in error state
this.isComponentInErrorState = store.hasCodePattern(...this.listenForErrorPatterns);
});
super.ngOnInit();
}
/**
* @inheritDoc
*/
ngOnDestroy() {
this.filtersSortManager.cancelScheduledBrowserUrlUpdate();
super.ngOnDestroy();
}
_initialize(state) {
const teamParamKey = state.getData('teamParamKey');
this.teamName = state.getParam(teamParamKey);
const jobParamKey = state.getData('jobParamKey');
this.jobName = state.getParam(jobParamKey);
this.isJobEditable = !!state.getData('editable');
// filters/sort manager have to be initialized before sending HTTP request to load executions
this._initializeFiltersSortManager(state);
this._subscribeForExecutions();
this.fetchDataJobExecutions();
}
_initializeFiltersSortManager(state) {
// update manager configuration
this.filtersSortManager.changeBaseUrl(state.absoluteRoutePath);
this.filtersSortManager.changeUpdateStrategy('locationToURL');
// update stored filters and sort criteria from Browser URL query params
this.filtersSortManager.bulkUpdate(state.queryParams);
// if there is no sort applied through Browser URL, apply default sorting by Start Time Descending
if (!this.filtersSortManager.hasAnySort()) {
this.filtersSortManager.setSort(SORT_START_TIME_KEY, ClrDatagridSortOrder.DESC);
}
// update Browser URL with replace state, normalized to only manager known criteria
this.filtersSortManager.updateBrowserUrl('replaceToURL', true);
}
_subscribeForExecutions() {
this.subscriptions.push(this.dataJobsService
.getNotifiedForJobExecutions()
.pipe(map(DataJobExecutionToGridDataJobExecution.convertToDataJobExecution(this.datePipe)))
.subscribe({
next: (values) => {
this.jobExecutions = values;
this._filterExecutions();
if (this.jobExecutions.length > 0) {
const oldestExecutionStartTime = [...this.jobExecutions]
.sort((ex1, ex2) => (ex1.startTime < ex2.startTime ? 1 : -1))
.pop().startTime;
const newMinJobExecutionsTime = new Date(oldestExecutionStartTime);
if (CollectionsUtil.isNil(this.minJobExecutionTime) ||
newMinJobExecutionsTime.getTime() - this.minJobExecutionTime.getTime() !== 0) {
this.minJobExecutionTime = newMinJobExecutionsTime;
}
}
else {
this.minJobExecutionTime = null;
}
},
error: (error) => {
console.error(error);
}
}));
}
_filterExecutions() {
let timePeriodCriteria;
let executionsFilteredAndSorted;
if (CollectionsUtil.isDefined(this.selectedPeriod.from) && CollectionsUtil.isDefined(this.selectedPeriod.to)) {
timePeriodCriteria = new ExecutionsTimePeriodCriteria(this.selectedPeriod.from, this.selectedPeriod.to);
// execute filter by time period
executionsFilteredAndSorted = timePeriodCriteria.meetCriteria(this.jobExecutions);
}
else {
executionsFilteredAndSorted = [...this.jobExecutions];
}
if (this.gridCriteriaAndComparator) {
if (this.gridCriteriaAndComparator.filter) {
executionsFilteredAndSorted = this.gridCriteriaAndComparator.filter.meetCriteria(executionsFilteredAndSorted);
}
if (this.gridCriteriaAndComparator.sort) {
executionsFilteredAndSorted = executionsFilteredAndSorted.sort(this.gridCriteriaAndComparator.sort.compare.bind(this.gridCriteriaAndComparator.sort));
}
}
this.filteredJobExecutions = executionsFilteredAndSorted;
this.minJobExecutionTime = new Date(this.minJobExecutionTime);
}
}
DataJobExecutionsPageComponent.ɵfac = function DataJobExecutionsPageComponent_Factory(t) { return new (t || DataJobExecutionsPageComponent)(i0.ɵɵdirectiveInject(i1.ComponentService), i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i2.ActivatedRoute), i0.ɵɵdirectiveInject(i1.RouterService), i0.ɵɵdirectiveInject(i3.DataJobsService), i0.ɵɵdirectiveInject(i1.ErrorHandlerService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i4.Location), i0.ɵɵdirectiveInject(i4.DatePipe)); };
DataJobExecutionsPageComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DataJobExecutionsPageComponent, selectors: [["lib-data-job-executions-page"]], features: [i0.ɵɵProvidersFeature([DatePipe]), i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 4, consts: [[4, "ngIf"], [1, "time-filter__container"], [3, "loading", "minDateTime", "filtersSortManager", "selectedPeriodSerialized", "selectedPeriod", "isComponentInErrorState", "filterChanged"], ["class", "btn btn-icon btn-link refresh", "data-cy", "data-pipelines-job-executions-refresh-btn", "aria-label", "refresh", 3, "click", 4, "ngIf"], ["data-cy", "data-pipelines-job-executions-refresh-btn", "aria-label", "refresh", 1, "btn", "btn-icon", "btn-link", "refresh", 3, "click"], ["shape", "refresh", "size", "14"], [1, "clr-row"], [1, "clr-col-2", "execution-statuses-chart"], [3, "jobExecutions", 4, "ngIf"], [1, "clr-col-10"], [3, "jobExecutions", "chartZoomed", "executionIdFocused", "zoomPeriodChanged", 4, "ngIf"], [1, "clr-col-12"], [3, "jobExecutions", "loading", "filtersSortManager", "highlightedExecutionId", "gridCriteriaAndComparatorChanged"], [3, "jobExecutions"], [3, "jobExecutions", "chartZoomed", "executionIdFocused", "zoomPeriodChanged"], ["errorContext", "Data Job Executions", 3, "plural", "errorsQueue", "listenForErrorPatterns"], [1, "job-executions__spinner"]], template: function DataJobExecutionsPageComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵtemplate(0, DataJobExecutionsPageComponent_ng_container_0_Template, 7, 8, "ng-container", 0);
i0.ɵɵtemplate(1, DataJobExecutionsPageComponent_ng_container_1_Template, 3, 0, "ng-container", 0);
i0.ɵɵtemplate(2, DataJobExecutionsPageComponent_ng_container_2_Template, 2, 3, "ng-container", 0);
i0.ɵɵtemplate(3, DataJobExecutionsPageComponent_ng_container_3_Template, 3, 0, "ng-container", 0);
} if (rf & 2) {
i0.ɵɵproperty("ngIf", !ctx.initialLoading);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx.isComponentInErrorState && (ctx.jobExecutions == null ? null : ctx.jobExecutions.length) === 0 && !ctx.loading);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.isComponentInErrorState && !ctx.loading);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.initialLoading || ctx.isComponentInErrorState && ctx.loading);
} }, directives: [i4.NgIf, i5.TimePeriodFilterComponent, i6.ClrIconCustomTag, i7.ExecutionStatusChartComponent, i8.ExecutionDurationChartComponent, i9.DataJobExecutionsGridComponent, i1.PlaceholderComponent, i6.ClrSpinner], styles: ["[_nghost-%COMP%]{position:relative;display:block;width:100%;height:100%}[_nghost-%COMP%] .time-filter__container[_ngcontent-%COMP%]{display:flex;align-items:center;flex:1;justify-content:flex-end;height:2.5rem}[_nghost-%COMP%] .execution-statuses-chart[_ngcontent-%COMP%]{padding-right:0!important}[_nghost-%COMP%] .job-executions__spinner[_ngcontent-%COMP%]{left:50%;position:absolute;top:50%;z-index:1000;transform:translate(-50%,-50%)}"] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DataJobExecutionsPageComponent, [{
type: Component,
args: [{ selector: 'lib-data-job-executions-page', providers: [DatePipe], template: "<!--\n ~ Copyright 2023-2025 Broadcom\n ~ SPDX-License-Identifier: Apache-2.0\n -->\n\n<ng-container *ngIf=\"!initialLoading\">\n <div class=\"time-filter__container\">\n <div>\n <!--\n - Time Period filter is the single source of truth for DateTime executions filtering.\n - Events emitted from Time Period filter component are used as min and max allowed values\n for executions start time.\n - Even when User do zoom selection in duration chart, values from the chart are emitted\n and then injected to Time Period filter, which on it's own set in the calendar choosers,\n and then emits event that is used to filter executions.\n -->\n <lib-time-period-filter\n [loading]=\"loading\"\n [minDateTime]=\"minJobExecutionTime\"\n [filtersSortManager]=\"filtersSortManager\"\n [selectedPeriodSerialized]=\"filtersSortManager.filterCriteria['timePeriod']\"\n [selectedPeriod]=\"zoomedPeriod\"\n [isComponentInErrorState]=\"isComponentInErrorState\"\n (filterChanged)=\"timeFilterChange($event)\"\n ></lib-time-period-filter>\n </div>\n <div>\n <button\n *ngIf=\"!loading\"\n class=\"btn btn-icon btn-link refresh\"\n data-cy=\"data-pipelines-job-executions-refresh-btn\"\n aria-label=\"refresh\"\n (click)=\"refresh()\"\n >\n <clr-icon shape=\"refresh\" size=\"14\"></clr-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!isComponentInErrorState && jobExecutions?.length > 0\">\n <div class=\"clr-row\">\n <div class=\"clr-col-2 execution-statuses-chart\">\n <lib-execution-status-chart\n *ngIf=\"!loading\"\n [jobExecutions]=\"filteredJobExecutions\"\n >\n </lib-execution-status-chart>\n </div>\n <div class=\"clr-col-10\">\n <lib-execution-duration-chart\n *ngIf=\"!loading\"\n [jobExecutions]=\"filteredJobExecutions\"\n [chartZoomed]=\"isPeriodSelected\"\n (executionIdFocused)=\"durationChartExecutionIdFocusChange($event)\"\n (zoomPeriodChanged)=\"durationChartZoomPeriodChange($event)\"\n >\n </lib-execution-duration-chart>\n </div>\n </div>\n <div class=\"clr-row\">\n <div class=\"clr-col-12\">\n <lib-data-job-executions-grid\n [jobExecutions]=\"filteredJobExecutions\"\n [loading]=\"loading\"\n [filtersSortManager]=\"filtersSortManager\"\n [highlightedExecutionId]=\"highlightedExecutionId\"\n (gridCriteriaAndComparatorChanged)=\"gridCriteriaAndComparatorChange($event)\"\n >\n </lib-data-job-executions-grid>\n </div>\n </div>\n </ng-container>\n</ng-container>\n\n<ng-container\n *ngIf=\"!isComponentInErrorState && jobExecutions?.length === 0 && !loading\"\n>\n <h3>No executions found.</h3>\n</ng-container>\n\n<ng-container *ngIf=\"isComponentInErrorState && !loading\">\n <shared-placeholder\n errorContext=\"Data Job Executions\"\n [plural]=\"true\"\n [errorsQueue]=\"errors.records\"\n [listenForErrorPatterns]=\"listenForErrorPatterns\"\n >\n </shared-placeholder>\n</ng-container>\n\n<ng-container *ngIf=\"initialLoading || (isComponentInErrorState && loading)\">\n <div class=\"job-executions__spinner\">\n <clr-spinner></clr-spinner>\n </div>\n</ng-container>\n", styles: ["/*!\n * Copyright 2023-2025 Broadcom\n * SPDX-License-Identifier: Apache-2.0\n */:host{position:relative;display:block;width:100%;height:100%}:host .time-filter__container{display:flex;align-items:center;flex:1;justify-content:flex-end;height:2.5rem}:host .execution-statuses-chart{padding-right:0!important}:host .job-executions__spinner{left:50%;position:absolute;top:50%;z-index:1000;transform:translate(-50%,-50%)}\n"] }]
}], function () { return [{ type: i1.ComponentService }, { type: i1.NavigationService }, { type: i2.ActivatedRoute }, { type: i1.RouterService }, { type: i3.DataJobsService }, { type: i1.ErrorHandlerService }, { type: i0.ChangeDetectorRef }, { type: i2.Router }, { type: i4.Location }, { type: i4.DatePipe }]; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1qb2ItZXhlY3V0aW9ucy1wYWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RhdGEtcGlwZWxpbmVzL3NyYy9saWIvY29tcG9uZW50cy9kYXRhLWpvYi9wYWdlcy9leGVjdXRpb25zL2RhdGEtam9iLWV4ZWN1dGlvbnMtcGFnZS9kYXRhLWpvYi1leGVjdXRpb25zLXBhZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGF0YS1waXBlbGluZXMvc3JjL2xpYi9jb21wb25lbnRzL2RhdGEtam9iL3BhZ2VzL2V4ZWN1dGlvbnMvZGF0YS1qb2ItZXhlY3V0aW9ucy1wYWdlL2RhdGEtam9iLWV4ZWN1dGlvbnMtcGFnZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQXFCLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDaEYsT0FBTyxFQUFFLFFBQVEsRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBR3JELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFcEQsT0FBTyxFQUNILEdBQUcsRUFDSCxlQUFlLEVBYWYsbUJBQW1CLEVBQ25CLGVBQWUsRUFDbEIsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXJFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTVELE9BQU8sRUFJSCx1QkFBdUIsRUFDdkIsa0JBQWtCLEVBQ2xCLGVBQWUsRUFDZixtQkFBbUIsRUFDdEIsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QixPQUFPLEVB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bUJBQW1CLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbEUsQ0FBQzs7NEdBM1ZRLDhCQUE4QjtpRkFBOUIsOEJBQThCLGtGQUY1QixDQUFDLFFBQVEsQ0FBQztRQ3ZFekIsaUdBbUVlO1FBRWYsaUdBSWU7UUFFZixpR0FRZTtRQUVmLGlHQUllOztRQXpGQSwwQ0FBcUI7UUFzRS9CLGVBQXlFO1FBQXpFLDBJQUF5RTtRQUsvRCxlQUF5QztRQUF6QyxrRUFBeUM7UUFVekMsZUFBNEQ7UUFBNUQsdUZBQTREOzt1RkRaOUQsOEJBQThCO2NBTjFDLFNBQVM7MkJBQ0ksOEJBQThCLGFBRzdCLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDIzLTIwMjUgQnJvYWRjb21cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgT25EZXN0cm95LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERhdGVQaXBlLCBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgQ2xyRGF0YWdyaWRTb3J0T3JkZXIgfSBmcm9tICdAY2xyL2FuZ3VsYXInO1xuXG5pbXBvcnQge1xuICAgIEFTQyxcbiAgICBDb2xsZWN0aW9uc1V0aWwsXG4gICAgQ29tcG9uZW50TW9kZWwsXG4gICAgQ29tcG9uZW50U2VydmljZSxcbiAgICBDcml0ZXJpYSxcbiAgICBFcnJvckhhbmRsZXJTZXJ2aWNlLFxuICAgIEVycm9yUmVjb3JkLFxuICAgIE5hdmlnYXRpb25TZXJ2aWNlLFxuICAgIE9uVGF1cnVzTW9kZWxDaGFuZ2UsXG4gICAgT25UYXVydXNNb2RlbEVycm9yLFxuICAgIE9uVGF1cnVzTW9kZWxJbml0LFxuICAgIE9uVGF1cnVzTW9kZWxMb2FkLFxuICAgIFJvdXRlclNlcnZpY2UsXG4gICAgUm91dGVTdGF0ZSxcbiAgICBUYXVydXNCYXNlQ29tcG9uZW50LFxuICAgIFVSTFN0YXRlTWFuYWdlclxufSBmcm9tICdAdmVyc2F0aWxlZGF0YWtpdC9zaGFyZWQnO1xuXG5pbXBvcnQgeyBEYXRhSm9iVXRpbCwgRXJyb3JVdGlsIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc2hhcmVkL3V0aWxzJztcblxuaW1wb3J0IHsgRmlsdGVyc1NvcnRNYW5hZ2VyIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vY29tbW9ucyc7XG5cbmltcG9ydCB7XG4gICAgRGF0YUpvYkV4ZWN1dGlvbk9yZGVyLFxuICAgIERhdGFKb2JFeGVjdXRpb25zLFxuICAgIERhdGFQaXBlbGluZXNSb3V0ZURhdGEsXG4gICAgSk9CX0VYRUNVVElPTlNfREFUQV9LRVksXG4gICAgSk9CX05BTUVfUkVRX1BBUkFNLFxuICAgIE9SREVSX1JFUV9QQVJBTSxcbiAgICBURUFNX05BTUVfUkVRX1BBUkFNXG59IGZyb20gJy4uLy4uLy4uLy4uLy4uL21vZGVsJztcblxuaW1wb3J0IHsgVEFTS19MT0FEX0pPQl9FWEVDVVRJT05TIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc3RhdGUvdGFza3MnO1xuXG5pbXBvcnQgeyBMT0FEX0pPQl9FUlJPUl9DT0RFUyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL3N0YXRlL2Vycm9yLWNvZGVzJztcblxuaW1wb3J0IHsgRGF0YUpvYnNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc2VydmljZXMnO1xuXG5pbXBvcnQgeyBEYXRhSm9iRXhlY3V0aW9uVG9HcmlkRGF0YUpvYkV4ZWN1dGlvbiwgR3JpZERhdGFKb2JFeGVjdXRpb24gfSBmcm9tICcuLi9tb2RlbC9kYXRhLWpvYi1leGVjdXRpb24nO1xuXG5pbXBvcnQge1xuICAgIEV4ZWN1dGlvbnNGaWx0ZXJDcml0ZXJpYSxcbiAgICBFeGVjdXRpb25zRmlsdGVyU29ydE9iamVjdCxcbiAgICBFeGVjdXRpb25zU29ydENyaXRlcmlhLFxuICAgIFNPUlRfU1RBUlRfVElNRV9LRVksXG4gICAgU1VQUE9SVEVEX0VYRUNVVElPTlNfRklMVEVSX0NSSVRFUklBLFxuICAgIFNVUFBPUlRFRF9FWEVDVVRJT05TX1NPUlRfQ1JJVEVSSUFcbn0gZnJvbSAnLi4vbW9kZWwvZXhlY3V0aW9ucy1maWx0ZXJzLm1vZGVsJztcblxuaW1wb3J0IHsgR3JpZENyaXRlcmlhQW5kQ29tcGFyYXRvciB9IGZyb20gJy4uL2RhdGEtam9iLWV4ZWN1dGlvbnMtZ3JpZCc7XG5cbmltcG9ydCB7IEV4ZWN1dGlvbnNUaW1lUGVyaW9kQ3JpdGVyaWEgfSBmcm9tICcuL2NyaXRlcmlhL3RpbWUtcGVyaW9kJztcblxuaW50ZXJmYWNlIFNlbGVjdGVkRGF0ZVRpbWVQZXJpb2Qge1xuICAgIGZyb206IERhdGU7XG4gICAgdG86IERhdGU7XG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLWRhdGEtam9iLWV4ZWN1dGlvbnMtcGFnZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2RhdGEtam9iLWV4ZWN1dGlvbnMtcGFnZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZGF0YS1qb2ItZXhlY3V0aW9ucy1wYWdlLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgcHJvdmlkZXJzOiBbRGF0ZVBpcGVdXG59KVxuZXhwb3J0IGNsYXNzIERhdGFKb2JFeGVjdXRpb25zUGFnZUNvbXBvbmVudFxuICAgIGV4dGVuZHMgVGF1cnVzQmFzZUNvbXBvbmVudFxuICAgIGltcGxlbWVudHMgT25UYXVydXNNb2RlbEluaXQsIE9uVGF1cnVzTW9kZWxMb2FkLCBPblRhdXJ1c01vZGVsQ2hhbmdlLCBPblRhdXJ1c01vZGVsRXJyb3IsIE9uSW5pdCwgT25EZXN0cm95XG57XG4gICAgcmVhZG9ubHkgdXVpZCA9ICdEYXRhSm9iRXhlY3V0aW9uc1BhZ2VDb21wb25lbnQnO1xuXG4gICAgdGVhbU5hbWU6IHN0cmluZztcbiAgICBqb2JOYW1lOiBzdHJpbmc7XG4gICAgaXNKb2JFZGl0YWJsZSA9IGZhbHNlO1xuXG4gICAgam9iRXhlY3V0aW9uczogR3JpZERhdGFKb2JFeGVjdXRpb25bXSA9IFtdO1xuICAgIGZpbHRlcmVkSm9iRXhlY3V0aW9uczogR3JpZERhdGFKb2JFeGVjdXRpb25bXSA9IFtdO1xuICAgIG1pbkpvYkV4ZWN1dGlvblRpbWU6IERhdGU7XG4gICAgbG9hZGluZyA9IHRydWU7XG4gICAgaW5pdGlhbExvYWRpbmcgPSB0cnVlO1xuXG4gICAgLyoqXG4gICAgICogKiogU2VsZWN0ZWQgRGF0ZVRpbWUgcGVyaW9kIGluIHRpbWUgcGVyaW9kIGZpbHRlci5cbiAgICAgKi9cbiAgICBzZWxlY3RlZFBlcmlvZDogU2VsZWN0ZWREYXRlVGltZVBlcmlvZCA9IHtcbiAgICAgICAgZnJvbTogbnVsbCxcbiAgICAgICAgdG86IG51bGxcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogKiogSW5kaWNhdGVzIHdoZXRoZXIgdGltZSBmaWx0ZXIgaXMgY2hvc2VuLCBwZXJpb2QgaXMgc2VsZWN0ZWQuXG4gICAgICovXG4gICAgaXNQZXJpb2RTZWxlY3RlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogKiogWm9vbWVkIERhdGVUaW1lIHBlcmlvZCwgaW4gZHVyYXRpb24gY2hhcnQuXG4gICAgICovXG4gICAgem9vbWVkUGVyaW9kOiBTZWxlY3RlZERhdGVUaW1lUGVyaW9kID0ge1xuICAgICAgICBmcm9tOiBudWxsLFxuICAgICAgICB0bzogbnVsbFxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAqKiBGb2N1c2VkIChoaWdobGlnaHRlZCkgZXhlY3V0aW9uIGlkIGluIGR1cmF0aW9uIGNoYXJ0LlxuICAgICAqL1xuICAgIGhpZ2hsaWdodGVkRXhlY3V0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqICoqIEdyaWQgQ3JpdGVyaWEgYW5kIENvbXBhcmF0b3IgZnJvbSBFeGVjdXRpb25zIERhdGEgR3JpZC5cbiAgICAgKi9cbiAgICBncmlkQ3JpdGVyaWFBbmRDb21wYXJhdG9yOiBHcmlkQ3JpdGVyaWFBbmRDb21wYXJhdG9yO1xuXG4gICAgLyoqXG4gICAgICogKiogQXJyYXkgb2YgZXJyb3IgY29kZSBwYXR0ZXJucyB0aGF0IGNvbXBvbmVudCBzaG91bGQgbGlzdGVuIGZvciBpbiBlcnJvcnMgc3RvcmUuXG4gICAgICovXG4gICAgbGlzdGVuRm9yRXJyb3JQYXR0ZXJuczogc3RyaW5nW10gPSBbTE9BRF9KT0JfRVJST1JfQ09ERVNbVEFTS19MT0FEX0pPQl9FWEVDVVRJT05TXS5BbGxdO1xuXG4gICAgLyoqXG4gICAgICogKiogRmxhZyB0aGF0IGluZGljYXRlcyB0aGVyZSBpcyBqb2JzIGV4ZWN1dGlvbnMgbG9hZCBlcnJvci5cbiAgICAgKi9cbiAgICBpc0NvbXBvbmVudEluRXJyb3JTdGF0ZSA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogKiogRXhlY3V0aW9ucyBmaWx0ZXJzIHNvcnQgbWFuYWdlciBmb3IgdGhpcyBwYWdlLCB0aGF0IGlzIGluamVjdGVkIHRvIGl0cyBjaGlsZHJlbi5cbiAgICAgKlxuICAgICAqICAgICAgLSBTaW5nbGV0b24gZm9yIHRoZSBwYWdlIGluc3RhbmNlIGluY2x1ZGluZyBpdHMgY2hpbGRyZW4uXG4gICAgICovXG4gICAgcmVhZG9ubHkgZmlsdGVyc1NvcnRNYW5hZ2VyOiBSZWFkb25seTxcbiAgICAgICAgRmlsdGVyc1NvcnRNYW5hZ2VyPEV4ZWN1dGlvbnNGaWx0ZXJDcml0ZXJpYSwgc3RyaW5nLCBFeGVjdXRpb25zU29ydENyaXRlcmlhLCBDbHJEYXRhZ3JpZFNvcnRPcmRlcj5cbiAgICA+O1xuXG4gICAgLyoqXG4gICAgICogKiogVXJsIHN0YXRlIG1hbmFnZXIgaW4gY29udGV4dCBvZiB0aGlzIHBhZ2UuXG4gICAgICpcbiAgICAgKiAgICAgIC0gU2luZ2xldG9uIGZvciB0aGUgcGFnZSBpbnN0YW5jZSBpbmNsdWRpbmcgaXRzIGNoaWxkcmVuLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgdXJsU3RhdGVNYW5hZ2VyOiBVUkxTdGF0ZU1hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiAqKiBDb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgY29tcG9uZW50U2VydmljZTogQ29tcG9uZW50U2VydmljZSxcbiAgICAgICAgbmF2aWdhdGlvblNlcnZpY2U6IE5hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyU2VydmljZTogUm91dGVyU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkYXRhSm9ic1NlcnZpY2U6IERhdGFKb2JzU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBlcnJvckhhbmRsZXJTZXJ2aWNlOiBFcnJvckhhbmRsZXJTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBsb2NhdGlvbjogTG9jYXRpb24sXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZGF0ZVBpcGU6IERhdGVQaXBlXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGNvbXBvbmVudFNlcnZpY2UsIG5hdmlnYXRpb25TZXJ2aWNlLCBhY3RpdmF0ZWRSb3V0ZSk7XG5cbiAgICAgICAgdGhpcy51cmxTdGF0ZU1hbmFnZXIgPSBuZXcgVVJMU3RhdGVNYW5hZ2VyKHJvdXRlci51cmwuc3BsaXQoJz8nKVswXSwgbG9jYXRpb24pO1xuICAgICAgICB0aGlzLmZpbHRlcnNTb3J0TWFuYWdlciA9IG5ldyBGaWx0ZXJzU29ydE1hbmFnZXIoXG4gICAgICAgICAgICB0aGlzLnVybFN0YXRlTWFuYWdlcixcbiAgICAgICAgICAgIFNVUFBPUlRFRF9FWEVDVVRJT05TX0ZJTFRFUl9DUklURVJJQSxcbiAgICAgICAgICAgIFNVUFBPUlRFRF9FWEVDVVRJT05TX1NPUlRfQ1JJVEVSSUFcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBkb05hdmlnYXRlQmFjaygpOiB2b2lkIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1mbG9hdGluZy1wcm9taXNlc1xuICAgICAgICB0aGlzLm5hdmlnYXRlQmFjayh7ICckLnRlYW0nOiB0aGlzLnRlYW1OYW1lIH0pLnRoZW4oKTtcbiAgICB9XG5cbiAgICB0aW1lRmlsdGVyQ2hhbmdlKHNlbGVjdGVkUGVyaW9kOiBTZWxlY3RlZERhdGVUaW1lUGVyaW9kKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkUGVyaW9kLmZyb20gPT09IHNlbGVjdGVkUGVyaW9kLmZyb20gJiYgdGhpcy5zZWxlY3RlZFBlcmlvZC50byA9PT0gc2VsZWN0ZWRQZXJpb2QudG8pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRQZXJpb2QgPSBzZWxlY3RlZFBlcmlvZDtcblxuICAgICAgICB0aGlzLmlzUGVyaW9kU2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkUGVyaW9kLmZyb20gIT09IG51bGwgJiYgdGhpcy5zZWxlY3RlZFBlcmlvZC50byAhPT0gbnVsbDtcblxuICAgICAgICB0aGlzLl9maWx0ZXJFeGVjdXRpb25zKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogRXhlY3V0ZWQgd2hlbmV2ZXIgZm9jdXMgb24gZXhlY3V0aW9uIGlkIGluIGR1cmF0aW9uIGNoYXJ0IGNoYW5nZXMuXG4gICAgICovXG4gICAgZHVyYXRpb25DaGFydEV4ZWN1dGlvbklkRm9jdXNDaGFuZ2UoZXhlY3V0aW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLmhpZ2hsaWdodGVkRXhlY3V0aW9uSWQgPSBleGVjdXRpb25JZDtcbiAgICB9XG5cbiAgICBkdXJhdGlvbkNoYXJ0Wm9vbVBlcmlvZENoYW5nZSh6b29tZWRQZXJpb2Q6IFNlbGVjdGVkRGF0ZVRpbWVQZXJpb2QpOiB2b2lkIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFBlcmlvZC5mcm9tID09PSB6b29tZWRQZXJpb2QuZnJvbSAmJlxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFBlcmlvZC50byA9PT0gem9vbWVkUGVyaW9kLnRvICYmXG4gICAgICAgICAgICB0aGlzLnpvb21lZFBlcmlvZC5mcm9tID09PSB6b29tZWRQZXJpb2QuZnJvbSAmJlxuICAgICAgICAgICAgdGhpcy56b29tZWRQZXJpb2QudG8gPT09IHpvb21lZFBlcmlvZC50b1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuem9vbWVkUGVyaW9kID0gem9vbWVkUGVyaW9kO1xuICAgIH1cblxuICAgIGdyaWRDcml0ZXJpYUFuZENvbXBhcmF0b3JDaGFuZ2UoJGV2ZW50OiBHcmlkQ3JpdGVyaWFBbmRDb21wYXJhdG9yKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZ3JpZENyaXRlcmlhQW5kQ29tcGFyYXRvciA9ICRldmVudDtcblxuICAgICAgICB0aGlzLl9maWx0ZXJFeGVjdXRpb25zKCk7XG4gICAgfVxuXG4gICAgcmVmcmVzaCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5mZXRjaERhdGFKb2JFeGVjdXRpb25zKCk7XG4gICAgfVxuXG4gICAgZmV0Y2hEYXRhSm9iRXhlY3V0aW9ucygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLmRhdGFKb2JzU2VydmljZS5sb2FkSm9iRXhlY3V0aW9ucyhcbiAgICAgICAgICAgIHRoaXMubW9kZWxcbiAgICAgICAgICAgICAgICAud2l0aFJlcXVlc3RQYXJhbShURUFNX05BTUVfUkVRX1BBUkFNLCB0aGlzLnRlYW1OYW1lKVxuICAgICAgICAgICAgICAgIC53aXRoUmVxdWVzdFBhcmFtKEpPQl9OQU1FX1JFUV9QQVJBTSwgdGhpcy5qb2JOYW1lKVxuICAgICAgICAgICAgICAgIC53aXRoUmVxdWVzdFBhcmFtKE9SREVSX1JFUV9QQVJBTSwge1xuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3N0YXJ0VGltZScsXG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogQVNDXG4gICAgICAgICAgICAgICAgfSBhcyBEYXRhSm9iRXhlY3V0aW9uT3JkZXIpXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaW5oZXJpdERvY1xuICAgICAqL1xuICAgIG9uTW9kZWxJbml0KCk6IHZvaWQge1xuICAgICAgICBsZXQgaXNJbml0aWFsaXplZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICAgICAgdGhpcy5yb3V0ZXJTZXJ2aWNlXG4gICAgICAgICAgICAgICAgLmdldFN0YXRlKClcbiAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9uc1V0aWwuaXNFcXVhbChhLnF1ZXJ5UGFyYW1zLCBiLnF1ZXJ5UGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoc3RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0luaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZShzdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXNzIHF1ZXJ5IHBhcmFtcyBmb3IgcG9wcGVkIHN0YXRlIGFuZCBsZXQgbWFuYWdlciBleHRyYWN0IGtub3duIGZpbHRlcnMgYW5kIHNvcnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFjdGlvbiBpcyBuZWVkZWQgZm9yIEJyb3dzZXIgYmFja3dhcmQvZm9yd2FyZCBhY3Rpb25zIHRoYXQgdHJpZ2dlciByb3V0ZXIgbmF2aWdhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGVzdGVkIG9ubHkgZm9yIFwibG9jYXRpb25Ub1VybFwiIHVwZGF0ZSBzdHJhdGVneSBmb3IgVVJMU3RhdGVNYW5hZ2VyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlcnNTb3J0TWFuYWdlci5idWxrVXBkYXRlKHN0YXRlLnF1ZXJ5UGFyYW1zIGFzIEV4ZWN1dGlvbnNGaWx0ZXJTb3J0T2JqZWN0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGluaGVyaXREb2NcbiAgICAgKi9cbiAgICBvbk1vZGVsTG9hZCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaW5pdGlhbExvYWRpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaW5oZXJpdERvY1xuICAgICAqL1xuICAgIG9uTW9kZWxDaGFuZ2UobW9kZWw6IENvbXBvbmVudE1vZGVsLCB0YXNrOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgI