UNPKG

@spartacus/user

Version:

User feature library for Spartacus

153 lines 41.5 kB
import { Component } from '@angular/core'; import { FormControl, Validators, } from '@angular/forms'; import { GlobalMessageType, OAuthFlow, } from '@spartacus/core'; import { CustomFormValidators, sortTitles } from '@spartacus/storefront'; import { BehaviorSubject, combineLatest, Subscription } from 'rxjs'; import { filter, map } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@spartacus/user/profile/root"; import * as i2 from "@spartacus/core"; import * as i3 from "@angular/forms"; import * as i4 from "@spartacus/storefront"; import * as i5 from "@angular/common"; import * as i6 from "@angular/router"; export class RegisterComponent { constructor(userRegister, globalMessageService, fb, router, anonymousConsentsService, anonymousConsentsConfig, authConfigService) { this.userRegister = userRegister; this.globalMessageService = globalMessageService; this.fb = fb; this.router = router; this.anonymousConsentsService = anonymousConsentsService; this.anonymousConsentsConfig = anonymousConsentsConfig; this.authConfigService = authConfigService; this.isLoading$ = new BehaviorSubject(false); this.subscription = new Subscription(); this.registerForm = this.fb.group({ titleCode: [''], firstName: ['', Validators.required], lastName: ['', Validators.required], email: ['', [Validators.required, CustomFormValidators.emailValidator]], password: [ '', [Validators.required, CustomFormValidators.passwordValidator], ], passwordconf: ['', Validators.required], newsletter: new FormControl({ value: false, disabled: this.isConsentRequired(), }), termsandconditions: [false, Validators.requiredTrue], }, { validators: CustomFormValidators.passwordsMustMatch('password', 'passwordconf'), }); } ngOnInit() { var _a, _b, _c; this.titles$ = this.userRegister.getTitles().pipe(map((titles) => { return titles.sort(sortTitles); })); // TODO: Workaround: allow server for decide is titleCode mandatory (if yes, provide personalized message) this.subscription.add(this.globalMessageService .get() .pipe(filter((messages) => !!Object.keys(messages).length)) .subscribe((globalMessageEntities) => { const messages = globalMessageEntities && globalMessageEntities[GlobalMessageType.MSG_TYPE_ERROR]; if (messages && messages.some((message) => message === 'This field is required.')) { this.globalMessageService.remove(GlobalMessageType.MSG_TYPE_ERROR); this.globalMessageService.add({ key: 'register.titleRequired' }, GlobalMessageType.MSG_TYPE_ERROR); } })); const registerConsent = (_c = (_b = (_a = this.anonymousConsentsConfig) === null || _a === void 0 ? void 0 : _a.anonymousConsents) === null || _b === void 0 ? void 0 : _b.registerConsent) !== null && _c !== void 0 ? _c : ''; this.anonymousConsent$ = combineLatest([ this.anonymousConsentsService.getConsent(registerConsent), this.anonymousConsentsService.getTemplate(registerConsent), ]).pipe(map(([consent, template]) => { return { consent, template: (template === null || template === void 0 ? void 0 : template.description) ? template.description : '', }; })); this.subscription.add( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.registerForm.get('newsletter').valueChanges.subscribe(() => { this.toggleAnonymousConsent(); })); } submitForm() { if (this.registerForm.valid) { this.registerUser(); } else { this.registerForm.markAllAsTouched(); } } registerUser() { this.isLoading$.next(true); this.userRegister .register(this.collectDataFromRegisterForm(this.registerForm.value)) .subscribe({ next: () => this.onRegisterUserSuccess(), complete: () => this.isLoading$.next(false), }); } titleSelected(title) { this.registerForm['controls'].titleCode.setValue(title.code); } collectDataFromRegisterForm(formData) { const { firstName, lastName, email, password, titleCode } = formData; return { firstName, lastName, uid: email.toLowerCase(), password, titleCode, }; } isConsentGiven(consent) { return this.anonymousConsentsService.isConsentGiven(consent); } isConsentRequired() { var _a, _b, _c, _d; const requiredConsents = (_b = (_a = this.anonymousConsentsConfig) === null || _a === void 0 ? void 0 : _a.anonymousConsents) === null || _b === void 0 ? void 0 : _b.requiredConsents; const registerConsent = (_d = (_c = this.anonymousConsentsConfig) === null || _c === void 0 ? void 0 : _c.anonymousConsents) === null || _d === void 0 ? void 0 : _d.registerConsent; if (requiredConsents && registerConsent) { return requiredConsents.includes(registerConsent); } return false; } onRegisterUserSuccess() { if (this.authConfigService.getOAuthFlow() === OAuthFlow.ResourceOwnerPasswordFlow) { this.router.go('login'); } this.globalMessageService.add({ key: 'register.postRegisterMessage' }, GlobalMessageType.MSG_TYPE_CONFIRMATION); } toggleAnonymousConsent() { var _a, _b; const registerConsent = (_b = (_a = this.anonymousConsentsConfig) === null || _a === void 0 ? void 0 : _a.anonymousConsents) === null || _b === void 0 ? void 0 : _b.registerConsent; if (registerConsent) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion if (Boolean(this.registerForm.get('newsletter').value)) { this.anonymousConsentsService.giveConsent(registerConsent); } else { this.anonymousConsentsService.withdrawConsent(registerConsent); } } } ngOnDestroy() { this.subscription.unsubscribe(); } } RegisterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponent, deps: [{ token: i1.UserRegisterFacade }, { token: i2.GlobalMessageService }, { token: i3.FormBuilder }, { token: i2.RoutingService }, { token: i2.AnonymousConsentsService }, { token: i2.AnonymousConsentsConfig }, { token: i2.AuthConfigService }], target: i0.ɵɵFactoryTarget.Component }); RegisterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: RegisterComponent, selector: "cx-register", ngImport: i0, template: "<section\n class=\"cx-page-section container\"\n *ngIf=\"!(isLoading$ | async); else loading\"\n>\n <div class=\"row justify-content-center\">\n <div class=\"col-md-6\">\n <div class=\"cx-section\">\n <form (ngSubmit)=\"submitForm()\" [formGroup]=\"registerForm\">\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.title' | cxTranslate\n }}</span>\n <select formControlName=\"titleCode\" class=\"form-control\">\n <option selected value=\"\" disabled>\n {{ 'register.selectTitle' | cxTranslate }}\n </option>\n <option\n *ngFor=\"let title of titles$ | async\"\n [value]=\"title.code\"\n >\n {{ title.name }}\n </option>\n </select>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.firstName.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"text\"\n name=\"firstname\"\n placeholder=\"{{\n 'register.firstName.placeholder' | cxTranslate\n }}\"\n formControlName=\"firstName\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('firstName')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.lastName.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"text\"\n name=\"lastname\"\n placeholder=\"{{\n 'register.lastName.placeholder' | cxTranslate\n }}\"\n formControlName=\"lastName\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('lastName')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.emailAddress.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n placeholder=\"{{\n 'register.emailAddress.placeholder' | cxTranslate\n }}\"\n formControlName=\"email\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('email')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.password.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"password\"\n name=\"password\"\n placeholder=\"{{\n 'register.password.placeholder' | cxTranslate\n }}\"\n formControlName=\"password\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('password')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.confirmPassword.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"password\"\n name=\"confirmpassword\"\n placeholder=\"{{\n 'register.confirmPassword.placeholder' | cxTranslate\n }}\"\n formControlName=\"passwordconf\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('passwordconf')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <div class=\"form-check\">\n <label *ngIf=\"anonymousConsent$ | async as anonymousConsent\">\n <input\n type=\"checkbox\"\n name=\"newsletter\"\n class=\"form-check-input\"\n formControlName=\"newsletter\"\n [checked]=\"isConsentGiven(anonymousConsent.consent)\"\n />\n <span class=\"form-check-label\">\n {{ anonymousConsent.template }}\n </span>\n </label>\n </div>\n </div>\n\n <div class=\"form-group\">\n <div class=\"form-check\">\n <label>\n <input\n aria-required=\"true\"\n type=\"checkbox\"\n name=\"termsandconditions\"\n formControlName=\"termsandconditions\"\n />\n <span class=\"form-check-label\">\n {{ 'register.confirmThatRead' | cxTranslate }}\n <a\n [routerLink]=\"{ cxRoute: 'termsAndConditions' } | cxUrl\"\n target=\"_blank\"\n >\n {{ 'register.termsAndConditions' | cxTranslate }}\n </a>\n </span>\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('termsandconditions')\"\n ></cx-form-errors>\n </label>\n </div>\n </div>\n <button type=\"submit\" class=\"btn btn-block btn-primary\">\n {{ 'register.register' | cxTranslate }}\n </button>\n <a\n class=\"cx-login-link btn-link\"\n [routerLink]=\"{ cxRoute: 'login' } | cxUrl\"\n >{{ 'register.signIn' | cxTranslate }}</a\n >\n </form>\n </div>\n </div>\n </div>\n</section>\n\n<ng-template #loading>\n <div class=\"cx-spinner\"><cx-spinner></cx-spinner></div>\n</ng-template>\n", components: [{ type: i4.FormErrorsComponent, selector: "cx-form-errors", inputs: ["prefix", "translationParams", "control"] }, { type: i4.SpinnerComponent, selector: "cx-spinner" }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i6.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "async": i5.AsyncPipe, "cxTranslate": i2.TranslatePipe, "cxUrl": i2.UrlPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponent, decorators: [{ type: Component, args: [{ selector: 'cx-register', templateUrl: './register.component.html', }] }], ctorParameters: function () { return [{ type: i1.UserRegisterFacade }, { type: i2.GlobalMessageService }, { type: i3.FormBuilder }, { type: i2.RoutingService }, { type: i2.AnonymousConsentsService }, { type: i2.AnonymousConsentsConfig }, { type: i2.AuthConfigService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vZmVhdHVyZS1saWJzL3VzZXIvcHJvZmlsZS9jb21wb25lbnRzL3JlZ2lzdGVyL3JlZ2lzdGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2ZlYXR1cmUtbGlicy91c2VyL3Byb2ZpbGUvY29tcG9uZW50cy9yZWdpc3Rlci9yZWdpc3Rlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBRUwsV0FBVyxFQUVYLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFRTCxpQkFBaUIsRUFDakIsU0FBUyxHQUVWLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBTXpFLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFjLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRixPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7OztBQU03QyxNQUFNLE9BQU8saUJBQWlCO0lBcUM1QixZQUNZLFlBQWdDLEVBQ2hDLG9CQUEwQyxFQUMxQyxFQUFlLEVBQ2YsTUFBc0IsRUFDdEIsd0JBQWtELEVBQ2xELHVCQUFnRCxFQUNoRCxpQkFBb0M7UUFOcEMsaUJBQVksR0FBWixZQUFZLENBQW9CO1FBQ2hDLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUNmLFdBQU0sR0FBTixNQUFNLENBQWdCO1FBQ3RCLDZCQUF3QixHQUF4Qix3QkFBd0IsQ0FBMEI7UUFDbEQsNEJBQXVCLEdBQXZCLHVCQUF1QixDQUF5QjtRQUNoRCxzQkFB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QixDQUN4QyxDQUFDO0lBQ0osQ0FBQztJQUVELHNCQUFzQjs7UUFDcEIsTUFBTSxlQUFlLEdBQ25CLE1BQUEsTUFBQSxJQUFJLENBQUMsdUJBQXVCLDBDQUFFLGlCQUFpQiwwQ0FBRSxlQUFlLENBQUM7UUFFbkUsSUFBSSxlQUFlLEVBQUU7WUFDbkIsb0VBQW9FO1lBQ3BFLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBRSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUN2RCxJQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLENBQUM7YUFDaEU7U0FDRjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNsQyxDQUFDOzs4R0FwTFUsaUJBQWlCO2tHQUFqQixpQkFBaUIsbURDaEM5Qix5N05BME1BOzJGRDFLYSxpQkFBaUI7a0JBSjdCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGFBQWE7b0JBQ3ZCLFdBQVcsRUFBRSwyQkFBMkI7aUJBQ3pDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgRm9ybUJ1aWxkZXIsXG4gIEZvcm1Db250cm9sLFxuICBGb3JtR3JvdXAsXG4gIFZhbGlkYXRvcnMsXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIEFub255bW91c0NvbnNlbnQsXG4gIEFub255bW91c0NvbnNlbnRzQ29uZmlnLFxuICBBbm9ueW1vdXNDb25zZW50c1NlcnZpY2UsXG4gIEF1dGhDb25maWdTZXJ2aWNlLFxuICBDb25zZW50VGVtcGxhdGUsXG4gIEdsb2JhbE1lc3NhZ2VFbnRpdGllcyxcbiAgR2xvYmFsTWVzc2FnZVNlcnZpY2UsXG4gIEdsb2JhbE1lc3NhZ2VUeXBlLFxuICBPQXV0aEZsb3csXG4gIFJvdXRpbmdTZXJ2aWNlLFxufSBmcm9tICdAc3BhcnRhY3VzL2NvcmUnO1xuaW1wb3J0IHsgQ3VzdG9tRm9ybVZhbGlkYXRvcnMsIHNvcnRUaXRsZXMgfSBmcm9tICdAc3BhcnRhY3VzL3N0b3JlZnJvbnQnO1xuaW1wb3J0IHtcbiAgVGl0bGUsXG4gIFVzZXJSZWdpc3RlckZhY2FkZSxcbiAgVXNlclNpZ25VcCxcbn0gZnJvbSAnQHNwYXJ0YWN1cy91c2VyL3Byb2ZpbGUvcm9vdCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2N4LXJlZ2lzdGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3JlZ2lzdGVyLmNvbXBvbmVudC5odG1sJyxcbn0pXG5leHBvcnQgY2xhc3MgUmVnaXN0ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHRpdGxlcyQ6IE9ic2VydmFibGU8VGl0bGVbXT47XG5cbiAgaXNMb2FkaW5nJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIGFub255bW91c0NvbnNlbnQkOiBPYnNlcnZhYmxlPHtcbiAgICBjb25zZW50OiBBbm9ueW1vdXNDb25zZW50O1xuICAgIHRlbXBsYXRlOiBzdHJpbmc7XG4gIH0+O1xuXG4gIHJlZ2lzdGVyRm9ybTogRm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cChcbiAgICB7XG4gICAgICB0aXRsZUNvZGU6IFsnJ10sXG4gICAgICBmaXJzdE5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBsYXN0TmFtZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIGVtYWlsOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBDdXN0b21Gb3JtVmFsaWRhdG9ycy5lbWFpbFZhbGlkYXRvcl1dLFxuICAgICAgcGFzc3dvcmQ6IFtcbiAgICAgICAgJycsXG4gICAgICAgIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBDdXN0b21Gb3JtVmFsaWRhdG9ycy5wYXNzd29yZFZhbGlkYXRvcl0sXG4gICAgICBdLFxuICAgICAgcGFzc3dvcmRjb25mOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgbmV3c2xldHRlcjogbmV3IEZvcm1Db250cm9sKHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICBkaXNhYmxlZDogdGhpcy5pc0NvbnNlbnRSZXF1aXJlZCgpLFxuICAgICAgfSksXG4gICAgICB0ZXJtc2FuZGNvbmRpdGlvbnM6IFtmYWxzZSwgVmFsaWRhdG9ycy5yZXF1aXJlZFRydWVdLFxuICAgIH0sXG4gICAge1xuICAgICAgdmFsaWRhdG9yczogQ3VzdG9tRm9ybVZhbGlkYXRvcnMucGFzc3dvcmRzTXVzdE1hdGNoKFxuICAgICAgICAncGFzc3dvcmQnLFxuICAgICAgICAncGFzc3dvcmRjb25mJ1xuICAgICAgKSxcbiAgICB9XG4gICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHVzZXJSZWdpc3RlcjogVXNlclJlZ2lzdGVyRmFjYWRlLFxuICAgIHByb3RlY3RlZCBnbG9iYWxNZXNzYWdlU2VydmljZTogR2xvYmFsTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGZiOiBGb3JtQnVpbGRlcixcbiAgICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0aW5nU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgYW5vbnltb3VzQ29uc2VudHNTZXJ2aWNlOiBBbm9ueW1vdXNDb25zZW50c1NlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGFub255bW91c0NvbnNlbnRzQ29uZmlnOiBBbm9ueW1vdXNDb25zZW50c0NvbmZpZyxcbiAgICBwcm90ZWN0ZWQgYXV0aENvbmZpZ1NlcnZpY2U6IEF1dGhDb25maWdTZXJ2aWNlXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnRpdGxlcyQgPSB0aGlzLnVzZXJSZWdpc3Rlci5nZXRUaXRsZXMoKS5waXBlKFxuICAgICAgbWFwKCh0aXRsZXM6IFRpdGxlW10pID0+IHtcbiAgICAgICAgcmV0dXJuIHRpdGxlcy5zb3J0KHNvcnRUaXRsZXMpO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gVE9ETzogV29ya2Fyb3VuZDogYWxsb3cgc2VydmVyIGZvciBkZWNpZGUgaXMgdGl0bGVDb2RlIG1hbmRhdG9yeSAoaWYgeWVzLCBwcm92aWRlIHBlcnNvbmFsaXplZCBtZXNzYWdlKVxuICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMuZ2xvYmFsTWVzc2FnZVNlcnZpY2VcbiAgICAgICAgLmdldCgpXG4gICAgICAgIC5waXBlKGZpbHRlcigobWVzc2FnZXMpID0+ICEhT2JqZWN0LmtleXMobWVzc2FnZXMpLmxlbmd0aCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKGdsb2JhbE1lc3NhZ2VFbnRpdGllczogR2xvYmFsTWVzc2FnZUVudGl0aWVzKSA9PiB7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZXMgPVxuICAgICAgICAgICAgZ2xvYmFsTWVzc2FnZUVudGl0aWVzICYmXG4gICAgICAgICAgICBnbG9iYWxNZXNzYWdlRW50aXRpZXNbR2xvYmFsTWVzc2FnZVR5cGUuTVNHX1RZUEVfRVJST1JdO1xuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgbWVzc2FnZXMgJiZcbiAgICAgICAgICAgIG1lc3NhZ2VzLnNvbWUoKG1lc3NhZ2UpID0+IG1lc3NhZ2UgPT09ICdUaGlzIGZpZWxkIGlzIHJlcXVpcmVkLicpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmdsb2JhbE1lc3NhZ2VTZXJ2aWNlLnJlbW92ZShHbG9iYWxNZXNzYWdlVHlwZS5NU0dfVFlQRV9FUlJPUik7XG4gICAgICAgICAgICB0aGlzLmdsb2JhbE1lc3NhZ2VTZXJ2aWNlLmFkZChcbiAgICAgICAgICAgICAgeyBrZXk6ICdyZWdpc3Rlci50aXRsZVJlcXVpcmVkJyB9LFxuICAgICAgICAgICAgICBHbG9iYWxNZXNzYWdlVHlwZS5NU0dfVFlQRV9FUlJPUlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgKTtcblxuICAgIGNvbnN0IHJlZ2lzdGVyQ29uc2VudCA9XG4gICAgICB0aGlzLmFub255bW91c0NvbnNlbnRzQ29uZmlnPy5hbm9ueW1vdXNDb25zZW50cz8ucmVnaXN0ZXJDb25zZW50ID8/ICcnO1xuXG4gICAgdGhpcy5hbm9ueW1vdXNDb25zZW50JCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5hbm9ueW1vdXNDb25zZW50c1NlcnZpY2UuZ2V0Q29uc2VudChyZWdpc3RlckNvbnNlbnQpLFxuICAgICAgdGhpcy5hbm9ueW1vdXNDb25zZW50c1NlcnZpY2UuZ2V0VGVtcGxhdGUocmVnaXN0ZXJDb25zZW50KSxcbiAgICBdKS5waXBlKFxuICAgICAgbWFwKChbY29uc2VudCwgdGVtcGxhdGVdOiBbQW5vbnltb3VzQ29uc2VudCwgQ29uc2VudFRlbXBsYXRlXSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnNlbnQsXG4gICAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlPy5kZXNjcmlwdGlvbiA/IHRlbXBsYXRlLmRlc2NyaXB0aW9uIDogJycsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgdGhpcy5yZWdpc3RlckZvcm0uZ2V0KCduZXdzbGV0dGVyJykhLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnRvZ2dsZUFub255bW91c0NvbnNlbnQoKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHN1Ym1pdEZvcm0oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVnaXN0ZXJGb3JtLnZhbGlkKSB7XG4gICAgICB0aGlzLnJlZ2lzdGVyVXNlcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlZ2lzdGVyRm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJVc2VyKCk6IHZvaWQge1xuICAgIHRoaXMuaXNMb2FkaW5nJC5uZXh0KHRydWUpO1xuICAgIHRoaXMudXNlclJlZ2lzdGVyXG4gICAgICAucmVnaXN0ZXIodGhpcy5jb2xsZWN0RGF0YUZyb21SZWdpc3RlckZvcm0odGhpcy5yZWdpc3RlckZvcm0udmFsdWUpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICgpID0+IHRoaXMub25SZWdpc3RlclVzZXJTdWNjZXNzKCksXG4gICAgICAgIGNvbXBsZXRlOiAoKSA9PiB0aGlzLmlzTG9hZGluZyQubmV4dChmYWxzZSksXG4gICAgICB9KTtcbiAgfVxuXG4gIHRpdGxlU2VsZWN0ZWQodGl0bGU6IFRpdGxlKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpc3RlckZvcm1bJ2NvbnRyb2xzJ10udGl0bGVDb2RlLnNldFZhbHVlKHRpdGxlLmNvZGUpO1xuICB9XG5cbiAgY29sbGVjdERhdGFGcm9tUmVnaXN0ZXJGb3JtKGZvcm1EYXRhOiBhbnkpOiBVc2VyU2lnblVwIHtcbiAgICBjb25zdCB7IGZpcnN0TmFtZSwgbGFzdE5hbWUsIGVtYWlsLCBwYXNzd29yZCwgdGl0bGVDb2RlIH0gPSBmb3JtRGF0YTtcblxuICAgIHJldHVybiB7XG4gICAgICBmaXJzdE5hbWUsXG4gICAgICBsYXN0TmFtZSxcbiAgICAgIHVpZDogZW1haWwudG9Mb3dlckNhc2UoKSxcbiAgICAgIHBhc3N3b3JkLFxuICAgICAgdGl0bGVDb2RlLFxuICAgIH07XG4gIH1cblxuICBpc0NvbnNlbnRHaXZlbihjb25zZW50OiBBbm9ueW1vdXNDb25zZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYW5vbnltb3VzQ29uc2VudHNTZXJ2aWNlLmlzQ29uc2VudEdpdmVuKGNvbnNlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0NvbnNlbnRSZXF1aXJlZCgpOiBib29sZWFuIHtcbiAgICBjb25zdCByZXF1aXJlZENvbnNlbnRzID1cbiAgICAgIHRoaXMuYW5vbnltb3VzQ29uc2VudHNDb25maWc/LmFub255bW91c0NvbnNlbnRzPy5yZXF1aXJlZENvbnNlbnRzO1xuICAgIGNvbnN0IHJlZ2lzdGVyQ29uc2VudCA9XG4gICAgICB0aGlzLmFub255bW91c0NvbnNlbnRzQ29uZmlnPy5hbm9ueW1vdXNDb25zZW50cz8ucmVnaXN0ZXJDb25zZW50O1xuXG4gICAgaWYgKHJlcXVpcmVkQ29uc2VudHMgJiYgcmVnaXN0ZXJDb25zZW50KSB7XG4gICAgICByZXR1cm4gcmVxdWlyZWRDb25zZW50cy5pbmNsdWRlcyhyZWdpc3RlckNvbnNlbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25SZWdpc3RlclVzZXJTdWNjZXNzKCk6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHRoaXMuYXV0aENvbmZpZ1NlcnZpY2UuZ2V0T0F1dGhGbG93KCkgPT09XG4gICAgICBPQXV0aEZsb3cuUmVzb3VyY2VPd25lclBhc3N3b3JkRmxvd1xuICAgICkge1xuICAgICAgdGhpcy5yb3V0ZXIuZ28oJ2xvZ2luJyk7XG4gICAgfVxuICAgIHRoaXMuZ2xvYmFsTWVzc2FnZVNlcnZpY2UuYWRkKFxuICAgICAgeyBrZXk6ICdyZWdpc3Rlci5wb3N0UmVnaXN0ZXJNZXNzYWdlJyB9LFxuICAgICAgR2xvYmFsTWVzc2FnZVR5cGUuTVNHX1RZUEVfQ09ORklSTUFUSU9OXG4gICAgKTtcbiAgfVxuXG4gIHRvZ2dsZUFub255bW91c0NvbnNlbnQoKTogdm9pZCB7XG4gICAgY29uc3QgcmVnaXN0ZXJDb25zZW50ID1cbiAgICAgIHRoaXMuYW5vbnltb3VzQ29uc2VudHNDb25maWc/LmFub255bW91c0NvbnNlbnRzPy5yZWdpc3RlckNvbnNlbnQ7XG5cbiAgICBpZiAocmVnaXN0ZXJDb25zZW50KSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgaWYgKEJvb2xlYW4odGhpcy5yZWdpc3RlckZvcm0uZ2V0KCduZXdzbGV0dGVyJykhLnZhbHVlKSkge1xuICAgICAgICB0aGlzLmFub255bW91c0NvbnNlbnRzU2VydmljZS5naXZlQ29uc2VudChyZWdpc3RlckNvbnNlbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hbm9ueW1vdXNDb25zZW50c1NlcnZpY2Uud2l0aGRyYXdDb25zZW50KHJlZ2lzdGVyQ29uc2VudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxufVxuIiwiPHNlY3Rpb25cbiAgY2xhc3M9XCJjeC1wYWdlLXNlY3Rpb24gY29udGFpbmVyXCJcbiAgKm5nSWY9XCIhKGlzTG9hZGluZyQgfCBhc3luYyk7IGVsc2UgbG9hZGluZ1wiXG4+XG4gIDxkaXYgY2xhc3M9XCJyb3cganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgPGRpdiBjbGFzcz1cImN4LXNlY3Rpb25cIj5cbiAgICAgICAgPGZvcm0gKG5nU3VibWl0KT1cInN1Ym1pdEZvcm0oKVwiIFtmb3JtR3JvdXBdPVwicmVnaXN0ZXJGb3JtXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbC1jb250ZW50XCI+e3tcbiAgICAgICAgICAgICAgICAncmVnaXN0ZXIudGl0bGUnIHwgY3hUcmFuc2xhdGVcbiAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwidGl0bGVDb2RlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHNlbGVjdGVkIHZhbHVlPVwiXCIgZGlzYWJsZWQ+XG4gICAgICAgICAgICAgICAgICB7eyAncmVnaXN0ZXIuc2VsZWN0VGl0bGUnIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uXG4gICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgdGl0bGUgb2YgdGl0bGVzJCB8IGFzeW5jXCJcbiAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJ0aXRsZS5jb2RlXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7eyB0aXRsZS5uYW1lIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWwtY29udGVudFwiPnt7XG4gICAgICAgICAgICAgICAgJ3JlZ2lzdGVyLmZpcnN0TmFtZS5sYWJlbCcgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgYXJpYS1yZXF1aXJlZD1cInRydWVcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgbmFtZT1cImZpcnN0bmFtZVwiXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7e1xuICAgICAgICAgICAgICAgICAgJ3JlZ2lzdGVyLmZpcnN0TmFtZS5wbGFjZWhvbGRlcicgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJmaXJzdE5hbWVcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8Y3gtZm9ybS1lcnJvcnNcbiAgICAgICAgICAgICAgICBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIlxuICAgICAgICAgICAgICAgIGFyaWEtYXRvbWljPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgW2NvbnRyb2xdPVwicmVnaXN0ZXJGb3JtLmdldCgnZmlyc3ROYW1lJylcIlxuICAgICAgICAgICAgICA+PC9jeC1mb3JtLWVycm9ycz5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsLWNvbnRlbnRcIj57e1xuICAgICAgICAgICAgICAgICdyZWdpc3Rlci5sYXN0TmFtZS5sYWJlbCcgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgYXJpYS1yZXF1aXJlZD1cInRydWVcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgbmFtZT1cImxhc3RuYW1lXCJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7XG4gICAgICAgICAgICAgICAgICAncmVnaXN0ZXIubGFzdE5hbWUucGxhY2Vob2xkZXInIHwgY3hUcmFuc2xhdGVcbiAgICAgICAgICAgICAgICB9fVwiXG4gICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibGFzdE5hbWVcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8Y3gtZm9ybS1lcnJvcnNcbiAgICAgICAgICAgICAgICBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIlxuICAgICAgICAgICAgICAgIGFyaWEtYXRvbWljPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgW2NvbnRyb2xdPVwicmVnaXN0ZXJGb3JtLmdldCgnbGFzdE5hbWUnKVwiXG4gICAgICAgICAgICAgID48L2N4LWZvcm0tZXJyb3JzPlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWwtY29udGVudFwiPnt7XG4gICAgICAgICAgICAgICAgJ3JlZ2lzdGVyLmVtYWlsQWRkcmVzcy5sYWJlbCcgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgYXJpYS1yZXF1aXJlZD1cInRydWVcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwiZW1haWxcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7e1xuICAgICAgICAgICAgICAgICAgJ3JlZ2lzdGVyLmVtYWlsQWRkcmVzcy5wbGFjZWhvbGRlcicgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJlbWFpbFwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDxjeC1mb3JtLWVycm9yc1xuICAgICAgICAgICAgICAgIGFyaWEtbGl2ZT1cImFzc2VydGl2ZVwiXG4gICAgICAgICAgICAgICAgYXJpYS1hdG9taWM9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBbY29udHJvbF09XCJyZWdpc3RlckZvcm0uZ2V0KCdlbWFpbCcpXCJcbiAgICAgICAgICAgICAgPjwvY3gtZm9ybS1lcnJvcnM+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbC1jb250ZW50XCI+e3tcbiAgICAgICAgICAgICAgICAncmVnaXN0ZXIucGFzc3dvcmQubGFiZWwnIHwgY3hUcmFuc2xhdGVcbiAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIGFyaWEtcmVxdWlyZWQ9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgdHlwZT1cInBhc3N3b3JkXCJcbiAgICAgICAgICAgICAgICBuYW1lPVwicGFzc3dvcmRcIlxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3tcbiAgICAgICAgICAgICAgICAgICdyZWdpc3Rlci5wYXNzd29yZC5wbGFjZWhvbGRlcicgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJwYXNzd29yZFwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDxjeC1mb3JtLWVycm9yc1xuICAgICAgICAgICAgICAgIGFyaWEtbGl2ZT1cImFzc2VydGl2ZVwiXG4gICAgICAgICAgICAgICAgYXJpYS1hdG9taWM9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBbY29udHJvbF09XCJyZWdpc3RlckZvcm0uZ2V0KCdwYXNzd29yZCcpXCJcbiAgICAgICAgICAgICAgPjwvY3gtZm9ybS1lcnJvcnM+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbC1jb250ZW50XCI+e3tcbiAgICAgICAgICAgICAgICAncmVnaXN0ZXIuY29uZmlybVBhc3N3b3JkLmxhYmVsJyB8IGN4VHJhbnNsYXRlXG4gICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICBhcmlhLXJlcXVpcmVkPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgIHR5cGU9XCJwYXNzd29yZFwiXG4gICAgICAgICAgICAgICAgbmFtZT1cImNvbmZpcm1wYXNzd29yZFwiXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7e1xuICAgICAgICAgICAgICAgICAgJ3JlZ2lzdGVyLmNvbmZpcm1QYXNzd29yZC5wbGFjZWhvbGRlcicgfCBjeFRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJwYXNzd29yZGNvbmZcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8Y3gtZm9ybS1lcnJvcnNcbiAgICAgICAgICAgICAgICBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIlxuICAgICAgICAgICAgICAgIGFyaWEtYXRvbWljPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgW2NvbnRyb2xdPVwicmVnaXN0ZXJGb3JtLmdldCgncGFzc3dvcmRjb25mJylcIlxuICAgICAgICAgICAgICA+PC9jeC1mb3JtLWVycm9ycz5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgICAgICAgICAgICAgPGxhYmVsICpuZ0lmPVwiYW5vbnltb3VzQ29uc2VudCQgfCBhc3luYyBhcyBhbm9ueW1vdXNDb25zZW50XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cIm5ld3NsZXR0ZXJcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm5ld3NsZXR0ZXJcIlxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiaXNDb25zZW50R2l2ZW4oYW5vbnltb3VzQ29uc2VudC5jb25zZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGFub255bW91c0NvbnNlbnQudGVtcGxhdGUgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBhcmlhLXJlcXVpcmVkPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRlcm1zYW5kY29uZGl0aW9uc1wiXG4gICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJ0ZXJtc2FuZGNvbmRpdGlvbnNcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICB7eyAncmVnaXN0ZXIuY29uZmlybVRoYXRSZWFkJyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJ7IGN4Um91dGU6ICd0ZXJtc0FuZENvbmRpdGlvbnMnIH0gfCBjeFVybFwiXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIHt7ICdyZWdpc3Rlci50ZXJtc0FuZENvbmRpdGlvbnMnIHwgY3hUcmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGN4LWZvcm0tZXJyb3JzXG4gICAgICAgICAgICAgICAgICBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIlxuICAgICAgICAgICAgICAgICAgYXJpYS1hdG9taWM9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgIFtjb250cm9sXT1cInJlZ2lzdGVyRm9ybS5nZXQoJ3Rlcm1zYW5kY29uZGl0aW9ucycpXCJcbiAgICAgICAgICAgICAgICA+PC9jeC1mb3JtLWVycm9ycz5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwiYnRuIGJ0bi1ibG9jayBidG4tcHJpbWFyeVwiPlxuICAgICAgICAgICAge3sgJ3JlZ2lzdGVyLnJlZ2lzdGVyJyB8IGN4VHJhbnNsYXRlIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGFcbiAgICAgICAgICAgIGNsYXNzPVwiY3gtbG9naW4tbGluayBidG4tbGlua1wiXG4gICAgICAgICAgICBbcm91dGVyTGlua109XCJ7IGN4Um91dGU6ICdsb2dpbicgfSB8IGN4VXJsXCJcbiAgICAgICAgICAgID57eyAncmVnaXN0ZXIuc2lnbkluJyB8IGN4VHJhbnNsYXRlIH19PC9hXG4gICAgICAgICAgPlxuICAgICAgICA8L2Zvcm0+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3NlY3Rpb24+XG5cbjxuZy10ZW1wbGF0ZSAjbG9hZGluZz5cbiAgPGRpdiBjbGFzcz1cImN4LXNwaW5uZXJcIj48Y3gtc3Bpbm5lcj48L2N4LXNwaW5uZXI+PC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19