@ui-tool/core
Version:
172 lines • 30.1 kB
JavaScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, InjectFlags, Input } from '@angular/core';
import { AbstractControl, NgControl } from '@angular/forms';
import { v4 as uuid } from 'uuid';
import { Subscription } from 'rxjs';
import { VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, VALIDATION_SUMMARIZER_SERVICE } from '../../../constants/injectors/validation-summarizer-injectors';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "./validation-summarizer-item/validation-summarizer-item.directive";
import * as i3 from "../../../pipes/sanitizers/to-trusted-html/to-trusted-html.pipe";
export class ValidationSummarizerComponent {
//#endregion
//#region Constructor
constructor(injector) {
this.injector = injector;
// tslint:disable-next-line:variable-name
this._maxValidationMessages = 0;
// Service resolve.
this.validationSummarizerService = injector.get(VALIDATION_SUMMARIZER_SERVICE, null, InjectFlags.Optional);
const validationSummarizerOptions = injector.get(VALIDATION_SUMMARIZER_OPTIONS_PROVIDER);
this._changeDetectorRef = injector.get(ChangeDetectorRef);
this._options = validationSummarizerOptions.getOption();
this._groupId = this._options.groupId || uuid();
this._maxValidationMessages = this._options.maximumMessages || 0;
this._visibilityHandler = this._options.visibilityHandler || null;
this.controlLabel = '';
this._control = null;
this.alternativeTemplate = null;
this._subscription = new Subscription();
}
//#endregion
//#region Accessors
// Id of group the validation summarizer belongs to.
// This can be used for identifying whether to apply validation summarizer item template builder or not.
get groupId() {
return this._groupId;
}
// Set item group id.
// tslint:disable-next-line:no-input-rename
set groupId(value) {
if (!value || !value.length) {
return;
}
this._groupId = value;
}
// Instance of the control that needs to be validated.
set ngControl(control) {
this._control = control;
// Unsubscribe subscription.
this._hookStatusChangesSubscription?.unsubscribe();
let statusChangesObservable = null;
if (this._control instanceof AbstractControl) {
statusChangesObservable = this._control.statusChanges;
}
else if (this._control instanceof NgControl) {
statusChangesObservable = this._control.statusChanges;
}
this._hookStatusChangesSubscription = statusChangesObservable?.subscribe(() => {
this._templateContext = this.getTemplateContext();
this._changeDetectorRef.markForCheck();
});
}
// Get the instance of control that needs to be validated.
get ngControl() {
return this._control;
}
// Get template context.
get templateContext() {
return this._templateContext;
}
// Maximum number of validation messages.
get maximumValidationMessages() {
return this._maxValidationMessages;
}
// Maximum number of validation messages.
set maximumValidationMessages(value) {
if (isNaN(value)) {
this._maxValidationMessages = 0;
return;
}
this._maxValidationMessages = value;
}
// tslint:disable-next-line:no-input-rename
set visibilityHandler(value) {
this._visibilityHandler = value;
}
get visibilityHandler() {
return this._visibilityHandler;
}
// Validation summarizer options.
get options() {
return this._options;
}
//#endregion
//#region Life cycle hooks
ngOnInit() {
this._templateContext = this.getTemplateContext();
this._changeDetectorRef.markForCheck();
}
ngOnDestroy() {
this._hookStatusChangesSubscription?.unsubscribe();
this._subscription?.unsubscribe();
}
//#endregion
//#region Methods
ableToDisplayValidationMessages(ngControl) {
if (!ngControl) {
return false;
}
// Visibility handler is defined.
if (this.visibilityHandler) {
return this.visibilityHandler(ngControl);
}
if (!ngControl) {
return false;
}
const ableToDisplay = ngControl.invalid && (ngControl.dirty || ngControl.touched) === true;
return true === ableToDisplay;
}
//#endregion
//#region Internal methods
loadValidationMessages(maximumValidationMessages) {
if (!this.validationSummarizerService || !this.ngControl) {
return [];
}
let messages = this.validationSummarizerService
.loadControlValidationMessages(this.controlLabel, this.ngControl);
if (!messages) {
return [];
}
if (!maximumValidationMessages || isNaN(maximumValidationMessages)) {
return messages;
}
if (maximumValidationMessages < 1) {
return messages;
}
messages = messages.slice(0, maximumValidationMessages);
return messages;
}
// Get validation template context.
getTemplateContext() {
return {
ngControl: this.ngControl,
controlLabel: this.controlLabel,
validationMessages: this.loadValidationMessages(this.maximumValidationMessages)
};
}
}
ValidationSummarizerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ValidationSummarizerComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
ValidationSummarizerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ValidationSummarizerComponent, selector: "cms-validation-summarizer", inputs: { groupId: ["group-id", "groupId"], ngControl: ["instance", "ngControl"], controlLabel: ["label", "controlLabel"], alternativeTemplate: ["validation-template", "alternativeTemplate"], maximumValidationMessages: ["maximum-messages", "maximumValidationMessages"], visibilityHandler: ["visibility-handler", "visibilityHandler"] }, ngImport: i0, template: "<!--Only displayed when control is available-->\n<ng-container *ngIf=\"ableToDisplayValidationMessages(ngControl)\"\n [ngSwitch]=\"options.useValidationItemBuilder\">\n\n <!--Use item template builder-->\n <ng-container *ngSwitchCase=\"true\">\n <ng-container *ngIf=\"templateContext.validationMessages && templateContext.validationMessages.length > 0\">\n <ng-template validationSummarizerItem\n [containerId]=\"groupId\"\n [validationMessages]=\"templateContext.validationMessages\"\n [ngControl]=\"ngControl\"\n [controlLabel]=\"controlLabel\"></ng-template>\n </ng-container>\n </ng-container>\n\n\n <!--Using item template-->\n <ng-container *ngSwitchDefault>\n <ng-template\n [ngTemplateOutlet]=\"alternativeTemplate || defaultTemplate\"\n [ngTemplateOutletContext]=\"templateContext\"\n >\n </ng-template>\n </ng-container>\n\n</ng-container>\n\n<!--Default validation summary template-->\n<ng-template\n #defaultTemplate\n let-ngControl=\"ngControl\"\n let-controlLabel=\"controlLabel\"\n let-validationMessages=\"validationMessages\"\n>\n <ul class=\"validation-summary\"\n *ngIf=\"validationMessages && validationMessages.length > 0\">\n <li *ngFor=\"let validationMessage of validationMessages;\"\n [innerHTML]=\"validationMessage.content | toTrustedHtml\">\n </li>\n </ul>\n</ng-template>\n", styles: ["ul.validation-summary{margin-top:5px}ul.validation-summary li{color:red}\n"], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2.ValidationSummarizerItemDirective, selector: "[validationSummarizerItem]", inputs: ["containerId", "validationMessages", "ngControl", "controlLabel"] }, { type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "toTrustedHtml": i3.ToTrustedHtmlPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ValidationSummarizerComponent, decorators: [{
type: Component,
args: [{ selector: 'cms-validation-summarizer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--Only displayed when control is available-->\n<ng-container *ngIf=\"ableToDisplayValidationMessages(ngControl)\"\n [ngSwitch]=\"options.useValidationItemBuilder\">\n\n <!--Use item template builder-->\n <ng-container *ngSwitchCase=\"true\">\n <ng-container *ngIf=\"templateContext.validationMessages && templateContext.validationMessages.length > 0\">\n <ng-template validationSummarizerItem\n [containerId]=\"groupId\"\n [validationMessages]=\"templateContext.validationMessages\"\n [ngControl]=\"ngControl\"\n [controlLabel]=\"controlLabel\"></ng-template>\n </ng-container>\n </ng-container>\n\n\n <!--Using item template-->\n <ng-container *ngSwitchDefault>\n <ng-template\n [ngTemplateOutlet]=\"alternativeTemplate || defaultTemplate\"\n [ngTemplateOutletContext]=\"templateContext\"\n >\n </ng-template>\n </ng-container>\n\n</ng-container>\n\n<!--Default validation summary template-->\n<ng-template\n #defaultTemplate\n let-ngControl=\"ngControl\"\n let-controlLabel=\"controlLabel\"\n let-validationMessages=\"validationMessages\"\n>\n <ul class=\"validation-summary\"\n *ngIf=\"validationMessages && validationMessages.length > 0\">\n <li *ngFor=\"let validationMessage of validationMessages;\"\n [innerHTML]=\"validationMessage.content | toTrustedHtml\">\n </li>\n </ul>\n</ng-template>\n", styles: ["ul.validation-summary{margin-top:5px}ul.validation-summary li{color:red}\n"] }]
}], ctorParameters: function () { return [{ type: i0.Injector }]; }, propDecorators: { groupId: [{
type: Input,
args: ['group-id']
}], ngControl: [{
type: Input,
args: ['instance']
}], controlLabel: [{
type: Input,
args: ['label']
}], alternativeTemplate: [{
type: Input,
args: ['validation-template']
}], maximumValidationMessages: [{
type: Input,
args: ['maximum-messages']
}], visibilityHandler: [{
type: Input,
args: ['visibility-handler']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1zdW1tYXJpemVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29yZS9zcmMvbW9kdWxlcy92YWxpZGF0b3IvdmFsaWRhdGlvbi1zdW1tYXJpemVyL3ZhbGlkYXRpb24tc3VtbWFyaXplci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvcmUvc3JjL21vZHVsZXMvdmFsaWRhdG9yL3ZhbGlkYXRpb24tc3VtbWFyaXplci92YWxpZGF0aW9uLXN1bW1hcml6ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFdBQVcsRUFFWCxLQUFLLEVBSU4sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGVBQWUsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUkxRCxPQUFPLEVBQUMsRUFBRSxJQUFJLElBQUksRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUVoQyxPQUFPLEVBQWEsWUFBWSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBQyxzQ0FBc0MsRUFBRSw2QkFBNkIsRUFBQyxNQUFNLDhEQUE4RCxDQUFDOzs7OztBQVVuSixNQUFNLE9BQU8sNkJBQTZCO0lBc0l4QyxZQUFZO0lBRVoscUJBQXFCO0lBRXJCLFlBQTZCLFFBQWtCO1FBQWxCLGFBQVEsR0FBUixRQUFRLENBQVU7UUEzSC9DLHlDQUF5QztRQUMvQiwyQkFBc0IsR0FBRyxDQUFDLENBQUM7UUE0SG5DLG1CQUFtQjtRQUNuQixJQUFJLENBQUMsMkJBQTJCLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsRUFDM0UsSUFBSSxFQUFFLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUU5QixNQUFNLDJCQUEyQixHQUFHLFFB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M0IsS0FBSzt1QkFBQyxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSW5qZWN0RmxhZ3MsXG4gIEluamVjdG9yLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIFRlbXBsYXRlUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBYnN0cmFjdENvbnRyb2wsIE5nQ29udHJvbH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtJVmFsaWRhdGlvblN1bW1hcml6ZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9pbnRlcmZhY2VzL3ZhbGlkYXRpb24tc3VtbWFyaXplcnMvdmFsaWRhdGlvbi1zdW1tYXJpemVyLXNlcnZpY2UuaW50ZXJmYWNlJztcbmltcG9ydCB7VmFsaWRhdGlvbk1lc3NhZ2V9IGZyb20gJy4uLy4uLy4uL21vZGVscy9pbXBsZW1lbnRhdGlvbnMvdmFsaWRhdGlvbi1zdW1tYXJpemVycy92YWxpZGF0aW9uLW1lc3NhZ2UnO1xuaW1wb3J0IHtJVmFsaWRhdGlvblN1bW1hcml6ZXJPcHRpb25zfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvaW50ZXJmYWNlcy92YWxpZGF0aW9uLXN1bW1hcml6ZXJzL3ZhbGlkYXRpb24tc3VtbWFyaXplci1vcHRpb25zLmludGVyZmFjZSc7XG5pbXBvcnQge3Y0IGFzIHV1aWR9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHtJVmFsaWRhdGlvblN1bW1hcml6ZXJNb2R1bGVPcHRpb25zfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvaW50ZXJmYWNlcy92YWxpZGF0aW9uLXN1bW1hcml6ZXJzL3ZhbGlkYXRpb24tc3VtbWFyaXplci1tb2R1bGUtb3B0aW9ucy5pbnRlcmZhY2UnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtWQUxJREFUSU9OX1NVTU1BUklaRVJfT1BUSU9OU19QUk9WSURFUiwgVkFMSURBVElPTl9TVU1NQVJJWkVSX1NFUlZJQ0V9IGZyb20gJy4uLy4uLy4uL2NvbnN0YW50cy9pbmplY3RvcnMvdmFsaWRhdGlvbi1zdW1tYXJpemVyLWluamVjdG9ycyc7XG5cblxuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdjbXMtdmFsaWRhdGlvbi1zdW1tYXJpemVyJyxcbiAgdGVtcGxhdGVVcmw6ICd2YWxpZGF0aW9uLXN1bW1hcml6ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsndmFsaWRhdGlvbi1zdW1tYXJpemVyLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25TdW1tYXJpemVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8vI3JlZ2lvbiBQcm9wZXJ0aWVzXG5cbiAgLy8gQ29udGV4dCBvZiB0ZW1wbGF0ZS5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSBfdGVtcGxhdGVDb250ZXh0OiBhbnk7XG5cbiAgLy8gQ29tcG9uZW50IGlkLlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFyaWFibGUtbmFtZVxuICBwcm90ZWN0ZWQgX2dyb3VwSWQ6IHN0cmluZztcblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFyaWFibGUtbmFtZVxuICBwcm90ZWN0ZWQgX2NvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB8IE5nQ29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJvdGVjdGVkIF9tYXhWYWxpZGF0aW9uTWVzc2FnZXMgPSAwO1xuXG4gIC8vIFZhbGlkYXRpb24gc3VtbWFyaXplciBvcHRpb25zLlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFyaWFibGUtbmFtZVxuICBwcm90ZWN0ZWQgX29wdGlvbnM6IElWYWxpZGF0aW9uU3VtbWFyaXplck1vZHVsZU9wdGlvbnM7XG5cbiAgLy8gU2VydmljZSBmb3IgdmFsaWRhdGluZyBjb250cm9scy5cbiAgcHJvdGVjdGVkIHZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZTogSVZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZSB8IG51bGw7XG5cbiAgLy8gSGFuZGxlciBmb3IgaGFuZGxpbmcgc3VtbWFyaXplciB2aXNpYmlsaXR5LlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFyaWFibGUtbmFtZVxuICBwcm90ZWN0ZWQgX3Zpc2liaWxpdHlIYW5kbGVyOiAoKG5nQ29udHJvbDogQWJzdHJhY3RDb250cm9sIHwgTmdDb250cm9sKSA9PiBib29sZWFuKSB8IG51bGw7XG5cbiAgLy8gSG9vayBzdGF0dXMgY2hhbmdlcyBzdWJzY3JpcHRpb25cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSBfaG9va1N0YXR1c0NoYW5nZXNTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZDtcblxuICAvLyBGb3IgbWFya2luZyBjb21wb25lbnQgYXMgY2hhbmdlZC5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmO1xuXG4gIC8vIFN1YnNjcmlwdGlvbiB3YXRjaCBsaXN0LlxuICBwcml2YXRlIHJlYWRvbmx5IF9zdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gQWNjZXNzb3JzXG5cbiAgLy8gSWQgb2YgZ3JvdXAgdGhlIHZhbGlkYXRpb24gc3VtbWFyaXplciBiZWxvbmdzIHRvLlxuICAvLyBUaGlzIGNhbiBiZSB1c2VkIGZvciBpZGVudGlmeWluZyB3aGV0aGVyIHRvIGFwcGx5IHZhbGlkYXRpb24gc3VtbWFyaXplciBpdGVtIHRlbXBsYXRlIGJ1aWxkZXIgb3Igbm90LlxuICBwdWJsaWMgZ2V0IGdyb3VwSWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fZ3JvdXBJZDtcbiAgfVxuXG4gIC8vIFNldCBpdGVtIGdyb3VwIGlkLlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8taW5wdXQtcmVuYW1lXG4gIEBJbnB1dCgnZ3JvdXAtaWQnKVxuICBwdWJsaWMgc2V0IGdyb3VwSWQodmFsdWU6IHN0cmluZykge1xuXG4gICAgaWYgKCF2YWx1ZSB8fCAhdmFsdWUubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fZ3JvdXBJZCA9IHZhbHVlO1xuICB9XG5cbiAgLy8gSW5zdGFuY2Ugb2YgdGhlIGNvbnRyb2wgdGhhdCBuZWVkcyB0byBiZSB2YWxpZGF0ZWQuXG4gIEBJbnB1dCgnaW5zdGFuY2UnKVxuICBwdWJsaWMgc2V0IG5nQ29udHJvbChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ0NvbnRyb2wgfCBudWxsIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fY29udHJvbCA9IGNvbnRyb2w7XG5cbiAgICAvLyBVbnN1YnNjcmliZSBzdWJzY3JpcHRpb24uXG4gICAgdGhpcy5faG9va1N0YXR1c0NoYW5nZXNTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG5cbiAgICBsZXQgc3RhdHVzQ2hhbmdlc09ic2VydmFibGU6IE9ic2VydmFibGU8YW55PiB8IG51bGwgPSBudWxsO1xuICAgIGlmICh0aGlzLl9jb250cm9sIGluc3RhbmNlb2YgQWJzdHJhY3RDb250cm9sKSB7XG4gICAgICBzdGF0dXNDaGFuZ2VzT2JzZXJ2YWJsZSA9ICh0aGlzLl9jb250cm9sIGFzIEFic3RyYWN0Q29udHJvbCkuc3RhdHVzQ2hhbmdlcztcbiAgICB9IGVsc2UgaWYgKHRoaXMuX2NvbnRyb2wgaW5zdGFuY2VvZiBOZ0NvbnRyb2wpIHtcbiAgICAgIHN0YXR1c0NoYW5nZXNPYnNlcnZhYmxlID0gKHRoaXMuX2NvbnRyb2wgYXMgTmdDb250cm9sKS5zdGF0dXNDaGFuZ2VzO1xuICAgIH1cblxuICAgIHRoaXMuX2hvb2tTdGF0dXNDaGFuZ2VzU3Vic2NyaXB0aW9uID0gc3RhdHVzQ2hhbmdlc09ic2VydmFibGU/LnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZUNvbnRleHQgPSB0aGlzLmdldFRlbXBsYXRlQ29udGV4dCgpO1xuICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBHZXQgdGhlIGluc3RhbmNlIG9mIGNvbnRyb2wgdGhhdCBuZWVkcyB0byBiZSB2YWxpZGF0ZWQuXG4gIHB1YmxpYyBnZXQgbmdDb250cm9sKCk6IEFic3RyYWN0Q29udHJvbCB8IE5nQ29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9jb250cm9sO1xuICB9XG5cbiAgLy8gTGFiZWwgb2YgY29udHJvbC5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWlucHV0LXJlbmFtZVxuICBASW5wdXQoJ2xhYmVsJylcbiAgcHVibGljIGNvbnRyb2xMYWJlbDogc3RyaW5nO1xuXG4gIC8vIEFsdGVybmF0aXZlIHRlbXBsYXRlIGZvciB2YWxpZGF0aW9uIHN1bW1hcnkuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1pbnB1dC1yZW5hbWVcbiAgQElucHV0KCd2YWxpZGF0aW9uLXRlbXBsYXRlJylcbiAgcHVibGljIGFsdGVybmF0aXZlVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsO1xuXG4gIC8vIEdldCB0ZW1wbGF0ZSBjb250ZXh0LlxuICBwdWJsaWMgZ2V0IHRlbXBsYXRlQ29udGV4dCgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLl90ZW1wbGF0ZUNvbnRleHQ7XG4gIH1cblxuICAvLyBNYXhpbXVtIG51bWJlciBvZiB2YWxpZGF0aW9uIG1lc3NhZ2VzLlxuICBwdWJsaWMgZ2V0IG1heGltdW1WYWxpZGF0aW9uTWVzc2FnZXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbWF4VmFsaWRhdGlvbk1lc3NhZ2VzO1xuICB9XG5cbiAgLy8gTWF4aW11bSBudW1iZXIgb2YgdmFsaWRhdGlvbiBtZXNzYWdlcy5cbiAgQElucHV0KCdtYXhpbXVtLW1lc3NhZ2VzJylcbiAgcHVibGljIHNldCBtYXhpbXVtVmFsaWRhdGlvbk1lc3NhZ2VzKHZhbHVlOiBudW1iZXIpIHtcbiAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICB0aGlzLl9tYXhWYWxpZGF0aW9uTWVzc2FnZXMgPSAwO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX21heFZhbGlkYXRpb25NZXNzYWdlcyA9IHZhbHVlO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWlucHV0LXJlbmFtZVxuICBASW5wdXQoJ3Zpc2liaWxpdHktaGFuZGxlcicpXG4gIHB1YmxpYyBzZXQgdmlzaWJpbGl0eUhhbmRsZXIodmFsdWU6ICgobmdDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ0NvbnRyb2wpID0+IGJvb2xlYW4pIHwgbnVsbCkge1xuICAgIHRoaXMuX3Zpc2liaWxpdHlIYW5kbGVyID0gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHZpc2liaWxpdHlIYW5kbGVyKCk6ICgobmdDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ0NvbnRyb2wpID0+IGJvb2xlYW4pIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3Zpc2liaWxpdHlIYW5kbGVyO1xuICB9XG5cbiAgLy8gVmFsaWRhdGlvbiBzdW1tYXJpemVyIG9wdGlvbnMuXG4gIHB1YmxpYyBnZXQgb3B0aW9ucygpOiBJVmFsaWRhdGlvblN1bW1hcml6ZXJPcHRpb25zIHtcbiAgICByZXR1cm4gdGhpcy5fb3B0aW9ucztcbiAgfVxuXG4gIC8vI2VuZHJlZ2lvblxuXG4gIC8vI3JlZ2lvbiBDb25zdHJ1Y3RvclxuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgaW5qZWN0b3I6IEluamVjdG9yKSB7XG5cbiAgICAvLyBTZXJ2aWNlIHJlc29sdmUuXG4gICAgdGhpcy52YWxpZGF0aW9uU3VtbWFyaXplclNlcnZpY2UgPSBpbmplY3Rvci5nZXQoVkFMSURBVElPTl9TVU1NQVJJWkVSX1NFUlZJQ0UsXG4gICAgICBudWxsLCBJbmplY3RGbGFncy5PcHRpb25hbCk7XG5cbiAgICBjb25zdCB2YWxpZGF0aW9uU3VtbWFyaXplck9wdGlvbnMgPSBpbmplY3Rvci5nZXQoVkFMSURBVElPTl9TVU1NQVJJWkVSX09QVElPTlNfUFJPVklERVIpO1xuICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmID0gaW5qZWN0b3IuZ2V0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAgIHRoaXMuX29wdGlvbnMgPSB2YWxpZGF0aW9uU3VtbWFyaXplck9wdGlvbnMuZ2V0T3B0aW9uKCk7XG5cbiAgICB0aGlzLl9ncm91cElkID0gdGhpcy5fb3B0aW9ucy5ncm91cElkIHx8IHV1aWQoKTtcbiAgICB0aGlzLl9tYXhWYWxpZGF0aW9uTWVzc2FnZXMgPSB0aGlzLl9vcHRpb25zLm1heGltdW1NZXNzYWdlcyB8fCAwO1xuICAgIHRoaXMuX3Zpc2liaWxpdHlIYW5kbGVyID0gdGhpcy5fb3B0aW9ucy52aXNpYmlsaXR5SGFuZGxlciB8fCBudWxsO1xuXG4gICAgdGhpcy5jb250cm9sTGFiZWwgPSAnJztcbiAgICB0aGlzLl9jb250cm9sID0gbnVsbDtcbiAgICB0aGlzLmFsdGVybmF0aXZlVGVtcGxhdGUgPSBudWxsO1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgfVxuXG4gIC8vI2VuZHJlZ2lvblxuXG4gIC8vI3JlZ2lvbiBMaWZlIGN5Y2xlIGhvb2tzXG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX3RlbXBsYXRlQ29udGV4dCA9IHRoaXMuZ2V0VGVtcGxhdGVDb250ZXh0KCk7XG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5faG9va1N0YXR1c0NoYW5nZXNTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG5cblxuICAvLyNyZWdpb24gTWV0aG9kc1xuXG4gIHB1YmxpYyBhYmxlVG9EaXNwbGF5VmFsaWRhdGlvbk1lc3NhZ2VzKG5nQ29udHJvbDogQWJzdHJhY3RDb250cm9sIHwgTmdDb250cm9sIHwgbnVsbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuXG4gICAgaWYgKCFuZ0NvbnRyb2wpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBWaXNpYmlsaXR5IGhhbmRsZXIgaXMgZGVmaW5lZC5cbiAgICBpZiAodGhpcy52aXNpYmlsaXR5SGFuZGxlcikge1xuICAgICAgcmV0dXJuIHRoaXMudmlzaWJpbGl0eUhhbmRsZXIobmdDb250cm9sKTtcbiAgICB9XG5cbiAgICBpZiAoIW5nQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGFibGVUb0Rpc3BsYXkgPSBuZ0NvbnRyb2wuaW52YWxpZCAmJiAobmdDb250cm9sLmRpcnR5IHx8IG5nQ29udHJvbC50b3VjaGVkKSA9PT0gdHJ1ZTtcbiAgICByZXR1cm4gdHJ1ZSA9PT0gYWJsZVRvRGlzcGxheTtcbiAgfVxuXG4gIC8vI2VuZHJlZ2lvblxuXG4gIC8vI3JlZ2lvbiBJbnRlcm5hbCBtZXRob2RzXG5cbiAgcHJvdGVjdGVkIGxvYWRWYWxpZGF0aW9uTWVzc2FnZXMobWF4aW11bVZhbGlkYXRpb25NZXNzYWdlczogbnVtYmVyIHwgbnVsbCk6IFZhbGlkYXRpb25NZXNzYWdlW10ge1xuXG4gICAgaWYgKCF0aGlzLnZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZSB8fCAhdGhpcy5uZ0NvbnRyb2wpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBsZXQgbWVzc2FnZXMgPSB0aGlzLnZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZVxuICAgICAgLmxvYWRDb250cm9sVmFsaWRhdGlvbk1lc3NhZ2VzKHRoaXMuY29udHJvbExhYmVsLCB0aGlzLm5nQ29udHJvbCk7XG5cbiAgICBpZiAoIW1lc3NhZ2VzKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKCFtYXhpbXVtVmFsaWRhdGlvbk1lc3NhZ2VzIHx8IGlzTmFOKG1heGltdW1WYWxpZGF0aW9uTWVzc2FnZXMpKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaWYgKG1heGltdW1WYWxpZGF0aW9uTWVzc2FnZXMgPCAxKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgbWVzc2FnZXMgPSBtZXNzYWdlcy5zbGljZSgwLCBtYXhpbXVtVmFsaWRhdGlvbk1lc3NhZ2VzKTtcbiAgICByZXR1cm4gbWVzc2FnZXM7XG4gIH1cblxuICAvLyBHZXQgdmFsaWRhdGlvbiB0ZW1wbGF0ZSBjb250ZXh0LlxuICBwcml2YXRlIGdldFRlbXBsYXRlQ29udGV4dCgpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBuZ0NvbnRyb2w6IHRoaXMubmdDb250cm9sLFxuICAgICAgY29udHJvbExhYmVsOiB0aGlzLmNvbnRyb2xMYWJlbCxcbiAgICAgIHZhbGlkYXRpb25NZXNzYWdlczogdGhpcy5sb2FkVmFsaWRhdGlvbk1lc3NhZ2VzKHRoaXMubWF4aW11bVZhbGlkYXRpb25NZXNzYWdlcylcbiAgICB9O1xuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG59XG4iLCI8IS0tT25seSBkaXNwbGF5ZWQgd2hlbiBjb250cm9sIGlzIGF2YWlsYWJsZS0tPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cImFibGVUb0Rpc3BsYXlWYWxpZGF0aW9uTWVzc2FnZXMobmdDb250cm9sKVwiXG4gICAgICAgICAgICAgIFtuZ1N3aXRjaF09XCJvcHRpb25zLnVzZVZhbGlkYXRpb25JdGVtQnVpbGRlclwiPlxuXG4gIDwhLS1Vc2UgaXRlbSB0ZW1wbGF0ZSBidWlsZGVyLS0+XG4gIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cInRydWVcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGVtcGxhdGVDb250ZXh0LnZhbGlkYXRpb25NZXNzYWdlcyAmJiB0ZW1wbGF0ZUNvbnRleHQudmFsaWRhdGlvbk1lc3NhZ2VzLmxlbmd0aCA+IDBcIj5cbiAgICAgIDxuZy10ZW1wbGF0ZSB2YWxpZGF0aW9uU3VtbWFyaXplckl0ZW1cbiAgICAgICAgICAgICAgICAgICBbY29udGFpbmVySWRdPVwiZ3JvdXBJZFwiXG4gICAgICAgICAgICAgICAgICAgW3ZhbGlkYXRpb25NZXNzYWdlc109XCJ0ZW1wbGF0ZUNvbnRleHQudmFsaWRhdGlvbk1lc3NhZ2VzXCJcbiAgICAgICAgICAgICAgICAgICBbbmdDb250cm9sXT1cIm5nQ29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgW2NvbnRyb2xMYWJlbF09XCJjb250cm9sTGFiZWxcIj48L25nLXRlbXBsYXRlPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cblxuXG4gIDwhLS1Vc2luZyBpdGVtIHRlbXBsYXRlLS0+XG4gIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD5cbiAgICA8bmctdGVtcGxhdGVcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImFsdGVybmF0aXZlVGVtcGxhdGUgfHwgZGVmYXVsdFRlbXBsYXRlXCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ0ZW1wbGF0ZUNvbnRleHRcIlxuICAgID5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L25nLWNvbnRhaW5lcj5cblxuPC9uZy1jb250YWluZXI+XG5cbjwhLS1EZWZhdWx0IHZhbGlkYXRpb24gc3VtbWFyeSB0ZW1wbGF0ZS0tPlxuPG5nLXRlbXBsYXRlXG4gICNkZWZhdWx0VGVtcGxhdGVcbiAgbGV0LW5nQ29udHJvbD1cIm5nQ29udHJvbFwiXG4gIGxldC1jb250cm9sTGFiZWw9XCJjb250cm9sTGFiZWxcIlxuICBsZXQtdmFsaWRhdGlvbk1lc3NhZ2VzPVwidmFsaWRhdGlvbk1lc3NhZ2VzXCJcbj5cbiAgPHVsIGNsYXNzPVwidmFsaWRhdGlvbi1zdW1tYXJ5XCJcbiAgICAgICpuZ0lmPVwidmFsaWRhdGlvbk1lc3NhZ2VzICYmIHZhbGlkYXRpb25NZXNzYWdlcy5sZW5ndGggPiAwXCI+XG4gICAgPGxpICpuZ0Zvcj1cImxldCB2YWxpZGF0aW9uTWVzc2FnZSBvZiB2YWxpZGF0aW9uTWVzc2FnZXM7XCJcbiAgICAgICAgW2lubmVySFRNTF09XCJ2YWxpZGF0aW9uTWVzc2FnZS5jb250ZW50IHwgdG9UcnVzdGVkSHRtbFwiPlxuICAgIDwvbGk+XG4gIDwvdWw+XG48L25nLXRlbXBsYXRlPlxuIl19