ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
329 lines • 34.8 kB
JavaScript
import { __decorate } from "tslib";
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { ChangeDetectionStrategy, Component, forwardRef, inject, Input, ViewEncapsulation } from '@angular/core';
import { NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { of } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { parseExpression } from 'cron-parser';
import { NzDestroyService } from 'ng-zorro-antd/core/services';
import { InputBoolean } from 'ng-zorro-antd/core/util';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "ng-zorro-antd/i18n";
import * as i3 from "@angular/common";
import * as i4 from "./cron-expression-label.component";
import * as i5 from "./cron-expression-input.component";
import * as i6 from "./cron-expression-preview.component";
function labelsOfType(type) {
if (type === 'spring') {
return ['second', 'minute', 'hour', 'day', 'month', 'week'];
}
return ['minute', 'hour', 'day', 'month', 'week'];
}
export class NzCronExpressionComponent {
convertFormat(value) {
const values = value.split(' ');
const valueObject = this.labels.reduce((obj, label, idx) => {
obj[label] = values[idx];
return obj;
}, {});
this.validateForm.patchValue(valueObject);
}
writeValue(value) {
if (value) {
this.convertFormat(value);
}
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouch = fn;
}
validate() {
if (this.validateForm.valid) {
return of(null);
}
else {
return of({ error: true });
}
}
setDisabledState(isDisabled) {
this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || isDisabled;
this.isNzDisableFirstChange = false;
this.cdr.markForCheck();
}
constructor(formBuilder, cdr, i18n) {
this.formBuilder = formBuilder;
this.cdr = cdr;
this.i18n = i18n;
this.nzSize = 'default';
this.nzType = 'linux';
this.nzCollapseDisable = false;
this.nzExtra = null;
this.nzSemantic = null;
this.nzBorderless = false;
this.nzDisabled = false;
this.focus = false;
this.labelFocus = null;
this.labels = labelsOfType(this.nzType);
this.nextTimeList = [];
this.isNzDisableFirstChange = true;
this.destroy$ = inject(NzDestroyService);
this.onChange = () => { };
this.onTouch = () => null;
this.checkValid = (control) => {
if (control.value) {
try {
const cron = [];
this.labels.forEach(label => {
cron.push(control.value[label]);
});
parseExpression(cron.join(' '));
}
catch (err) {
return { error: true };
}
}
return null;
};
this.validateForm = this.formBuilder.nonNullable.group({
second: ['0', Validators.required],
minute: ['*', Validators.required],
hour: ['*', Validators.required],
day: ['*', Validators.required],
month: ['*', Validators.required],
week: ['*', Validators.required]
}, { validators: this.checkValid });
}
ngOnInit() {
this.i18n.localeChange.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.locale = this.i18n.getLocaleData('CronExpression');
this.cdr.markForCheck();
});
this.previewDate(this.validateForm.value);
this.validateForm.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
this.onChange(Object.values(value).join(' '));
this.previewDate(value);
this.cdr.markForCheck();
});
}
ngOnChanges(changes) {
const { nzType } = changes;
if (nzType) {
this.labels = labelsOfType(this.nzType);
if (this.nzType === 'spring') {
this.validateForm.controls.second.enable();
}
else {
this.validateForm.controls.second.disable();
}
}
}
previewDate(value) {
try {
this.interval = parseExpression(Object.values(value).join(' '));
this.nextTimeList = [
this.interval.next().toDate(),
this.interval.next().toDate(),
this.interval.next().toDate(),
this.interval.next().toDate(),
this.interval.next().toDate()
];
}
catch (err) {
return;
}
}
loadMorePreview() {
this.nextTimeList = [
...this.nextTimeList,
this.interval.next().toDate(),
this.interval.next().toDate(),
this.interval.next().toDate(),
this.interval.next().toDate(),
this.interval.next().toDate()
];
this.cdr.markForCheck();
}
focusEffect(value) {
this.focus = true;
this.labelFocus = value;
this.cdr.markForCheck();
}
blurEffect() {
this.focus = false;
this.labelFocus = null;
this.cdr.markForCheck();
}
getValue(item) {
this.validateForm.controls[item.label].patchValue(item.value);
this.cdr.markForCheck();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NzCronExpressionComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: i2.NzI18nService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.3", type: NzCronExpressionComponent, selector: "nz-cron-expression", inputs: { nzSize: "nzSize", nzType: "nzType", nzCollapseDisable: "nzCollapseDisable", nzExtra: "nzExtra", nzSemantic: "nzSemantic", nzBorderless: "nzBorderless", nzDisabled: "nzDisabled" }, providers: [
{
provide: NG_ASYNC_VALIDATORS,
useExisting: forwardRef(() => NzCronExpressionComponent),
multi: true
},
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzCronExpressionComponent),
multi: true
},
NzDestroyService
], exportAs: ["nzCronExpression"], usesOnChanges: true, ngImport: i0, template: `
<div class="ant-cron-expression">
<div class="ant-cron-expression-content">
<div
class="ant-input ant-cron-expression-input-group"
[class.ant-input-lg]="nzSize === 'large'"
[class.ant-input-sm]="nzSize === 'small'"
[class.ant-input-borderless]="nzBorderless"
[class.ant-cron-expression-input-group-focus]="focus && !nzBorderless"
[class.ant-input-status-error]="!validateForm.valid && !nzBorderless"
[class.ant-cron-expression-input-group-error-focus]="!validateForm.valid && focus && !nzBorderless"
[class.ant-input-disabled]="nzDisabled"
>
<ng-container *ngFor="let label of labels">
<nz-cron-expression-input
[value]="this.validateForm.controls[label].value"
[label]="label"
[disabled]="nzDisabled"
(focusEffect)="focusEffect($event)"
(blurEffect)="blurEffect()"
(getValue)="getValue($event)"
></nz-cron-expression-input>
</ng-container>
</div>
<div
class="ant-cron-expression-label-group"
[class.ant-input-lg]="nzSize === 'large'"
[class.ant-cron-expression-label-group-default]="nzSize === 'default'"
[class.ant-input-sm]="nzSize === 'small'"
>
<ng-container *ngFor="let label of labels">
<nz-cron-expression-label
[type]="label"
[labelFocus]="labelFocus"
[locale]="locale"
></nz-cron-expression-label>
</ng-container>
</div>
<nz-cron-expression-preview
*ngIf="!nzCollapseDisable"
[TimeList]="nextTimeList"
[visible]="validateForm.valid"
[locale]="locale"
[nzSemantic]="nzSemantic"
(loadMorePreview)="loadMorePreview()"
></nz-cron-expression-preview>
</div>
<div class="ant-cron-expression-map" *ngIf="nzExtra">
<ng-template [ngTemplateOutlet]="nzExtra"></ng-template>
</div>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.NzCronExpressionLabelComponent, selector: "nz-cron-expression-label", inputs: ["type", "locale", "labelFocus"], exportAs: ["nzCronExpressionLabel"] }, { kind: "component", type: i5.NzCronExpressionInputComponent, selector: "nz-cron-expression-input", inputs: ["value", "label", "disabled"], outputs: ["focusEffect", "blurEffect", "getValue"], exportAs: ["nzCronExpressionInput"] }, { kind: "component", type: i6.NzCronExpressionPreviewComponent, selector: "nz-cron-expression-preview", inputs: ["TimeList", "visible", "locale", "nzSemantic"], outputs: ["loadMorePreview"], exportAs: ["nzCronExpressionPreview"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
__decorate([
InputBoolean()
], NzCronExpressionComponent.prototype, "nzCollapseDisable", void 0);
__decorate([
InputBoolean()
], NzCronExpressionComponent.prototype, "nzBorderless", void 0);
__decorate([
InputBoolean()
], NzCronExpressionComponent.prototype, "nzDisabled", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NzCronExpressionComponent, decorators: [{
type: Component,
args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'nz-cron-expression',
exportAs: 'nzCronExpression',
template: `
<div class="ant-cron-expression">
<div class="ant-cron-expression-content">
<div
class="ant-input ant-cron-expression-input-group"
[class.ant-input-lg]="nzSize === 'large'"
[class.ant-input-sm]="nzSize === 'small'"
[class.ant-input-borderless]="nzBorderless"
[class.ant-cron-expression-input-group-focus]="focus && !nzBorderless"
[class.ant-input-status-error]="!validateForm.valid && !nzBorderless"
[class.ant-cron-expression-input-group-error-focus]="!validateForm.valid && focus && !nzBorderless"
[class.ant-input-disabled]="nzDisabled"
>
<ng-container *ngFor="let label of labels">
<nz-cron-expression-input
[value]="this.validateForm.controls[label].value"
[label]="label"
[disabled]="nzDisabled"
(focusEffect)="focusEffect($event)"
(blurEffect)="blurEffect()"
(getValue)="getValue($event)"
></nz-cron-expression-input>
</ng-container>
</div>
<div
class="ant-cron-expression-label-group"
[class.ant-input-lg]="nzSize === 'large'"
[class.ant-cron-expression-label-group-default]="nzSize === 'default'"
[class.ant-input-sm]="nzSize === 'small'"
>
<ng-container *ngFor="let label of labels">
<nz-cron-expression-label
[type]="label"
[labelFocus]="labelFocus"
[locale]="locale"
></nz-cron-expression-label>
</ng-container>
</div>
<nz-cron-expression-preview
*ngIf="!nzCollapseDisable"
[TimeList]="nextTimeList"
[visible]="validateForm.valid"
[locale]="locale"
[nzSemantic]="nzSemantic"
(loadMorePreview)="loadMorePreview()"
></nz-cron-expression-preview>
</div>
<div class="ant-cron-expression-map" *ngIf="nzExtra">
<ng-template [ngTemplateOutlet]="nzExtra"></ng-template>
</div>
</div>
`,
providers: [
{
provide: NG_ASYNC_VALIDATORS,
useExisting: forwardRef(() => NzCronExpressionComponent),
multi: true
},
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzCronExpressionComponent),
multi: true
},
NzDestroyService
]
}]
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: i2.NzI18nService }], propDecorators: { nzSize: [{
type: Input
}], nzType: [{
type: Input
}], nzCollapseDisable: [{
type: Input
}], nzExtra: [{
type: Input
}], nzSemantic: [{
type: Input
}], nzBorderless: [{
type: Input
}], nzDisabled: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvbi1leHByZXNzaW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvY3Jvbi1leHByZXNzaW9uL2Nyb24tZXhwcmVzc2lvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUtMLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBT0wsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUdqQixVQUFVLEVBQ1gsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQWtCLGVBQWUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUU5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUUvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7Ozs7Ozs7O0FBS3ZELFNBQVMsWUFBWSxDQUFDLElBQTBCO0lBQzlDLElBQUksSUFBSSxLQUFLLFFBQVEsRUFBRTtRQUNyQixPQUFPLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztLQUM3RDtJQUNELE9BQU8sQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQXlFRCxNQUFNLE9BQU8seUJBQXlCO0lBMEJwQyxhQUFhLENBQUMsS0FBYTtRQUN6QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hD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QUFDLEdBQUcsRUFBRSwwQkFBMEIsQ0FBQzs0QkFDeEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7d0JBQ0QsZ0JBQWdCO3FCQUNqQjtpQkFDRjs0SUFLVSxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNtQixpQkFBaUI7c0JBQXpDLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ21CLFlBQVk7c0JBQXBDLEtBQUs7Z0JBQ21CLFVBQVU7c0JBQWxDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgZm9yd2FyZFJlZixcbiAgaW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEFic3RyYWN0Q29udHJvbCxcbiAgQXN5bmNWYWxpZGF0b3IsXG4gIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICBGb3JtQnVpbGRlcixcbiAgRm9ybUNvbnRyb2wsXG4gIEZvcm1Hcm91cCxcbiAgTkdfQVNZTkNfVkFMSURBVE9SUyxcbiAgTkdfVkFMVUVfQUNDRVNTT1IsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIFZhbGlkYXRvckZuLFxuICBWYWxpZGF0b3JzXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IENyb25FeHByZXNzaW9uLCBwYXJzZUV4cHJlc3Npb24gfSBmcm9tICdjcm9uLXBhcnNlcic7XG5cbmltcG9ydCB7IE56RGVzdHJveVNlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvc2VydmljZXMnO1xuaW1wb3J0IHsgQm9vbGVhbklucHV0LCBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgSW5wdXRCb29sZWFuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuaW1wb3J0IHsgTnpDcm9uRXhwcmVzc2lvbkkxOG5JbnRlcmZhY2UsIE56STE4blNlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2kxOG4nO1xuXG5pbXBvcnQgeyBDcm9uLCBDcm9uQ2hhbmdlVHlwZSwgQ3JvblZhbHVlLCBOekNyb25FeHByZXNzaW9uU2l6ZSwgTnpDcm9uRXhwcmVzc2lvblR5cGUsIFRpbWVUeXBlIH0gZnJvbSAnLi90eXBpbmdzJztcblxuZnVuY3Rpb24gbGFiZWxzT2ZUeXBlKHR5cGU6IE56Q3JvbkV4cHJlc3Npb25UeXBlKTogVGltZVR5cGVbXSB7XG4gIGlmICh0eXBlID09PSAnc3ByaW5nJykge1xuICAgIHJldHVybiBbJ3NlY29uZCcsICdtaW51dGUnLCAnaG91cicsICdkYXknLCAnbW9udGgnLCAnd2VlayddO1xuICB9XG4gIHJldHVybiBbJ21pbnV0ZScsICdob3VyJywgJ2RheScsICdtb250aCcsICd3ZWVrJ107XG59XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICduei1jcm9uLWV4cHJlc3Npb24nLFxuICBleHBvcnRBczogJ256Q3JvbkV4cHJlc3Npb24nLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJhbnQtY3Jvbi1leHByZXNzaW9uXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LWNyb24tZXhwcmVzc2lvbi1jb250ZW50XCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImFudC1pbnB1dCBhbnQtY3Jvbi1leHByZXNzaW9uLWlucHV0LWdyb3VwXCJcbiAgICAgICAgICBbY2xhc3MuYW50LWlucHV0LWxnXT1cIm56U2l6ZSA9PT0gJ2xhcmdlJ1wiXG4gICAgICAgICAgW2NsYXNzLmFudC1pbnB1dC1zbV09XCJuelNpemUgPT09ICdzbWFsbCdcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtaW5wdXQtYm9yZGVybGVzc109XCJuekJvcmRlcmxlc3NcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtY3Jvbi1leHByZXNzaW9uLWlucHV0LWdyb3VwLWZvY3VzXT1cImZvY3VzICYmICFuekJvcmRlcmxlc3NcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtaW5wdXQtc3RhdHVzLWVycm9yXT1cIiF2YWxpZGF0ZUZvcm0udmFsaWQgJiYgIW56Qm9yZGVybGVzc1wiXG4gICAgICAgICAgW2NsYXNzLmFudC1jcm9uLWV4cHJlc3Npb24taW5wdXQtZ3JvdXAtZXJyb3ItZm9jdXNdPVwiIXZhbGlkYXRlRm9ybS52YWxpZCAmJiBmb2N1cyAmJiAhbnpCb3JkZXJsZXNzXCJcbiAgICAgICAgICBbY2xhc3MuYW50LWlucHV0LWRpc2FibGVkXT1cIm56RGlzYWJsZWRcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgbGFiZWwgb2YgbGFiZWxzXCI+XG4gICAgICAgICAgICA8bnotY3Jvbi1leHByZXNzaW9uLWlucHV0XG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJ0aGlzLnZhbGlkYXRlRm9ybS5jb250cm9sc1tsYWJlbF0udmFsdWVcIlxuICAgICAgICAgICAgICBbbGFiZWxdPVwibGFiZWxcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibnpEaXNhYmxlZFwiXG4gICAgICAgICAgICAgIChmb2N1c0VmZmVjdCk9XCJmb2N1c0VmZmVjdCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGJsdXJFZmZlY3QpPVwiYmx1ckVmZmVjdCgpXCJcbiAgICAgICAgICAgICAgKGdldFZhbHVlKT1cImdldFZhbHVlKCRldmVudClcIlxuICAgICAgICAgICAgPjwvbnotY3Jvbi1leHByZXNzaW9uLWlucHV0PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiYW50LWNyb24tZXhwcmVzc2lvbi1sYWJlbC1ncm91cFwiXG4gICAgICAgICAgW2NsYXNzLmFudC1pbnB1dC1sZ109XCJuelNpemUgPT09ICdsYXJnZSdcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtY3Jvbi1leHByZXNzaW9uLWxhYmVsLWdyb3VwLWRlZmF1bHRdPVwibnpTaXplID09PSAnZGVmYXVsdCdcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtaW5wdXQtc21dPVwibnpTaXplID09PSAnc21hbGwnXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGxhYmVsIG9mIGxhYmVsc1wiPlxuICAgICAgICAgICAgPG56LWNyb24tZXhwcmVzc2lvbi1sYWJlbFxuICAgICAgICAgICAgICBbdHlwZV09XCJsYWJlbFwiXG4gICAgICAgICAgICAgIFtsYWJlbEZvY3VzXT1cImxhYmVsRm9jdXNcIlxuICAgICAgICAgICAgICBbbG9jYWxlXT1cImxvY2FsZVwiXG4gICAgICAgICAgICA+PC9uei1jcm9uLWV4cHJlc3Npb24tbGFiZWw+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bnotY3Jvbi1leHByZXNzaW9uLXByZXZpZXdcbiAgICAgICAgICAqbmdJZj1cIiFuekNvbGxhcHNlRGlzYWJsZVwiXG4gICAgICAgICAgW1RpbWVMaXN0XT1cIm5leHRUaW1lTGlzdFwiXG4gICAgICAgICAgW3Zpc2libGVdPVwidmFsaWRhdGVGb3JtLnZhbGlkXCJcbiAgICAgICAgICBbbG9jYWxlXT1cImxvY2FsZVwiXG4gICAgICAgICAgW256U2VtYW50aWNdPVwibnpTZW1hbnRpY1wiXG4gICAgICAgICAgKGxvYWRNb3JlUHJldmlldyk9XCJsb2FkTW9yZVByZXZpZXcoKVwiXG4gICAgICAgID48L256LWNyb24tZXhwcmVzc2lvbi1wcmV2aWV3PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LWNyb24tZXhwcmVzc2lvbi1tYXBcIiAqbmdJZj1cIm56RXh0cmFcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm56RXh0cmFcIj48L25nLXRlbXBsYXRlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX0FTWU5DX1ZBTElEQVRPUlMsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOekNyb25FeHByZXNzaW9uQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSxcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE56Q3JvbkV4cHJlc3Npb25Db21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9LFxuICAgIE56RGVzdHJveVNlcnZpY2VcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBOekNyb25FeHByZXNzaW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBBc3luY1ZhbGlkYXRvciB7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekJvcmRlcmxlc3M6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256RGlzYWJsZWQ6IEJvb2xlYW5JbnB1dDtcblxuICBASW5wdXQoKSBuelNpemU6IE56Q3JvbkV4cHJlc3Npb25TaXplID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBuelR5cGU6IE56Q3JvbkV4cHJlc3Npb25UeXBlID0gJ2xpbnV4JztcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56Q29sbGFwc2VEaXNhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG56RXh0cmE/OiBUZW1wbGF0ZVJlZjx2b2lkPiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBuelNlbWFudGljOiBUZW1wbGF0ZVJlZjx2b2lkPiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpCb3JkZXJsZXNzID0gZmFsc2U7XG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuekRpc2FibGVkID0gZmFsc2U7XG5cbiAgbG9jYWxlITogTnpDcm9uRXhwcmVzc2lvbkkxOG5JbnRlcmZhY2U7XG4gIGZvY3VzOiBib29sZWFuID0gZmFsc2U7XG4gIGxhYmVsRm9jdXM6IFRpbWVUeXBlIHwgbnVsbCA9IG51bGw7XG4gIGxhYmVsczogVGltZVR5cGVbXSA9IGxhYmVsc09mVHlwZSh0aGlzLm56VHlwZSk7XG4gIGludGVydmFsITogQ3JvbkV4cHJlc3Npb248ZmFsc2U+O1xuICBuZXh0VGltZUxpc3Q6IERhdGVbXSA9IFtdO1xuICBwcml2YXRlIGlzTnpEaXNhYmxlRmlyc3RDaGFuZ2U6IGJvb2xlYW4gPSB0cnVlO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gaW5qZWN0KE56RGVzdHJveVNlcnZpY2UpO1xuXG4gIHZhbGlkYXRlRm9ybTogRm9ybUdyb3VwPFJlY29yZDxUaW1lVHlwZSwgRm9ybUNvbnRyb2w8Q3JvblZhbHVlPj4+O1xuXG4gIG9uQ2hhbmdlOiBOelNhZmVBbnkgPSAoKSA9PiB7fTtcbiAgb25Ub3VjaDogKCkgPT4gdm9pZCA9ICgpID0+IG51bGw7XG5cbiAgY29udmVydEZvcm1hdCh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWVzID0gdmFsdWUuc3BsaXQoJyAnKTtcbiAgICBjb25zdCB2YWx1ZU9iamVjdCA9IHRoaXMubGFiZWxzLnJlZHVjZSgob2JqLCBsYWJlbCwgaWR4KSA9PiB7XG4gICAgICBvYmpbbGFiZWxdID0gdmFsdWVzW2lkeF07XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH0sIHt9IGFzIENyb24pO1xuICAgIHRoaXMudmFsaWRhdGVGb3JtLnBhdGNoVmFsdWUodmFsdWVPYmplY3QpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5jb252ZXJ0Rm9ybWF0KHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBOelNhZmVBbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogTnpTYWZlQW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoID0gZm47XG4gIH1cblxuICB2YWxpZGF0ZSgpOiBPYnNlcnZhYmxlPFZhbGlkYXRpb25FcnJvcnMgfCBudWxsPiB7XG4gICAgaWYgKHRoaXMudmFsaWRhdGVGb3JtLnZhbGlkKSB7XG4gICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBvZih7IGVycm9yOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMubnpEaXNhYmxlZCA9ICh0aGlzLmlzTnpEaXNhYmxlRmlyc3RDaGFuZ2UgJiYgdGhpcy5uekRpc2FibGVkKSB8fCBpc0Rpc2FibGVkO1xuICAgIHRoaXMuaXNOekRpc2FibGVGaXJzdENoYW5nZSA9IGZhbHNlO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIsIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgcHJpdmF0ZSBpMThuOiBOekkxOG5TZXJ2aWNlKSB7XG4gICAgdGhpcy52YWxpZGF0ZUZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLm5vbk51bGxhYmxlLmdyb3VwKFxuICAgICAge1xuICAgICAgICBzZWNvbmQ6IFsnMCcsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICBtaW51dGU6IFsnKicsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICBob3VyOiBbJyonLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgZGF5OiBbJyonLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgbW9udGg6IFsnKicsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICB3ZWVrOiBbJyonLCBWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgICAgfSxcbiAgICAgIHsgdmFsaWRhdG9yczogdGhpcy5jaGVja1ZhbGlkIH1cbiAgICApO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pMThuLmxvY2FsZUNoYW5nZS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMubG9jYWxlID0gdGhpcy5pMThuLmdldExvY2FsZURhdGEoJ0Nyb25FeHByZXNzaW9uJyk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcblxuICAgIHRoaXMucHJldmlld0RhdGUodGhpcy52YWxpZGF0ZUZvcm0udmFsdWUpO1xuXG4gICAgdGhpcy52YWxpZGF0ZUZvcm0udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUodmFsdWUgPT4ge1xuICAgICAgdGhpcy5vbkNoYW5nZShPYmplY3QudmFsdWVzKHZhbHVlKS5qb2luKCcgJykpO1xuICAgICAgdGhpcy5wcmV2aWV3RGF0ZSh2YWx1ZSk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IG56VHlwZSB9ID0gY2hhbmdlcztcblxuICAgIGlmIChuelR5cGUpIHtcbiAgICAgIHRoaXMubGFiZWxzID0gbGFiZWxzT2ZUeXBlKHRoaXMubnpUeXBlKTtcblxuICAgICAgaWYgKHRoaXMubnpUeXBlID09PSAnc3ByaW5nJykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlRm9ybS5jb250cm9scy5zZWNvbmQuZW5hYmxlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbGlkYXRlRm9ybS5jb250cm9scy5zZWNvbmQuZGlzYWJsZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByZXZpZXdEYXRlKHZhbHVlOiBDcm9uKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuaW50ZXJ2YWwgPSBwYXJzZUV4cHJlc3Npb24oT2JqZWN0LnZhbHVlcyh2YWx1ZSkuam9pbignICcpKTtcbiAgICAgIHRoaXMubmV4dFRpbWVMaXN0ID0gW1xuICAgICAgICB0aGlzLmludGVydmFsLm5leHQoKS50b0RhdGUoKSxcbiAgICAgICAgdGhpcy5pbnRlcnZhbC5uZXh0KCkudG9EYXRlKCksXG4gICAgICAgIHRoaXMuaW50ZXJ2YWwubmV4dCgpLnRvRGF0ZSgpLFxuICAgICAgICB0aGlzLmludGVydmFsLm5leHQoKS50b0RhdGUoKSxcbiAgICAgICAgdGhpcy5pbnRlcnZhbC5uZXh0KCkudG9EYXRlKClcbiAgICAgIF07XG4gICAgfSBjYXRjaCAoZXJyOiBOelNhZmVBbnkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBsb2FkTW9yZVByZXZpZXcoKTogdm9pZCB7XG4gICAgdGhpcy5uZXh0VGltZUxpc3QgPSBbXG4gICAgICAuLi50aGlzLm5leHRUaW1lTGlzdCxcbiAgICAgIHRoaXMuaW50ZXJ2YWwubmV4dCgpLnRvRGF0ZSgpLFxuICAgICAgdGhpcy5pbnRlcnZhbC5uZXh0KCkudG9EYXRlKCksXG4gICAgICB0aGlzLmludGVydmFsLm5leHQoKS50b0RhdGUoKSxcbiAgICAgIHRoaXMuaW50ZXJ2YWwubmV4dCgpLnRvRGF0ZSgpLFxuICAgICAgdGhpcy5pbnRlcnZhbC5uZXh0KCkudG9EYXRlKClcbiAgICBdO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZm9jdXNFZmZlY3QodmFsdWU6IFRpbWVUeXBlKTogdm9pZCB7XG4gICAgdGhpcy5mb2N1cyA9IHRydWU7XG4gICAgdGhpcy5sYWJlbEZvY3VzID0gdmFsdWU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBibHVyRWZmZWN0KCk6IHZvaWQge1xuICAgIHRoaXMuZm9jdXMgPSBmYWxzZTtcbiAgICB0aGlzLmxhYmVsRm9jdXMgPSBudWxsO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZ2V0VmFsdWUoaXRlbTogQ3JvbkNoYW5nZVR5cGUpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlRm9ybS5jb250cm9sc1tpdGVtLmxhYmVsXS5wYXRjaFZhbHVlKGl0ZW0udmFsdWUpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgY2hlY2tWYWxpZDogVmFsaWRhdG9yRm4gPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgIGlmIChjb250cm9sLnZhbHVlKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjcm9uOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICB0aGlzLmxhYmVscy5mb3JFYWNoKGxhYmVsID0+IHtcbiAgICAgICAgICBjcm9uLnB1c2goY29udHJvbC52YWx1ZVtsYWJlbF0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcGFyc2VFeHByZXNzaW9uKGNyb24uam9pbignICcpKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgICByZXR1cm4geyBlcnJvcjogdHJ1ZSB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbn1cbiJdfQ==