UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

88 lines 15.7 kB
import { Component, Output, EventEmitter } from '@angular/core'; import { LoginViews } from './login.model'; import { FetchClient } from '@c8y/client'; import { AppStateService } from '../common/ui-state.service'; import { LoginService } from './login.service'; import { AlertService } from '../alert/alert.service'; import { TranslateService } from '@ngx-translate/core'; import { gettext } from '../i18n/gettext'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; import * as i2 from "../common/ui-state.service"; import * as i3 from "./login.service"; import * as i4 from "../alert/alert.service"; import * as i5 from "@ngx-translate/core"; import * as i6 from "@angular/forms"; import * as i7 from "../i18n/c8y-translate.directive"; import * as i8 from "../forms/form-group.component"; import * as i9 from "../forms/required-input-placeholder.directive"; import * as i10 from "../i18n/c8y-translate.pipe"; /** * `TenantIdSetupComponent` is intended to be shown when tenant's id cannot be determined based on the current URL. * It asks the user to provide target tenant's id and then it fetches login options for this tenant. * In case of OAI-Secure login mode, login options will contain `domain` property set by backend. * The component will redirect user to this domain, preserving URL path and params. */ export class TenantIdSetupComponent { constructor(client, ui, loginService, alert, translateService) { this.client = client; this.ui = ui; this.loginService = loginService; this.alert = alert; this.translateService = translateService; this.onChangeView = new EventEmitter(); this.LOGIN_VIEWS = LoginViews; this.model = { tenant: '' }; } /** * Sets up login mode for particular tenant. In case of OAI-Secure will redirect user to tenant domain. */ async setupLoginMode() { this.client.tenant = this.model.tenant; try { await this.ui.refreshLoginOptions(); this.loginService.initLoginOptions(); this.redirectToCorrectDomain(); } catch (e) { if (e.res && e.res.status === 401) { this.alert.danger(this.translateService.instant(gettext('Could not find tenant with ID "{{ tenantId }}".'), { tenantId: this.model.tenant })); } else { this.alert.addServerFailure(e); } } } /** * Redirects to tenant domain when login mode contains domain. */ redirectToCorrectDomain() { const loginRedirectDomain = this.loginService.loginMode.loginRedirectDomain; if (loginRedirectDomain) { const alreadyOnCorrectDomain = window.location.href.includes(loginRedirectDomain); if (!alreadyOnCorrectDomain) { this.loginService.redirectToDomain(loginRedirectDomain); } else { this.onChangeView.emit({ view: LoginViews.Credentials, loginViewParams: { showTenant: true, disableTenant: true } }); } } else { this.onChangeView.emit({ view: LoginViews.Credentials }); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TenantIdSetupComponent, deps: [{ token: i1.FetchClient }, { token: i2.AppStateService }, { token: i3.LoginService }, { token: i4.AlertService }, { token: i5.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TenantIdSetupComponent, selector: "c8y-tenant-id-setup", outputs: { onChangeView: "onChangeView" }, ngImport: i0, template: "<form #tenantIdSetupForm=\"ngForm\" class=\"loginForm\" (ngSubmit)=\"setupLoginMode()\" novalidate>\n <div class=\"legend form-block center\" translate>Tenant setup</div>\n <c8y-form-group class=\"tenantField\" id=\"tenantField\">\n <label for=\"tenant\" translate>Tenant ID</label>\n <input\n [(ngModel)]=\"model.tenant\"\n #tenant=\"ngModel\"\n type=\"text\"\n name=\"tenant\"\n id=\"tenant\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} t12345\"\n placeholder-no-required-hint\n required\n />\n </c8y-form-group>\n\n <button\n title=\"{{ 'Apply' | translate }}\"\n type=\"submit\"\n class=\"btn btn-primary btn-lg btn-block form-group\"\n [disabled]=\"!tenantIdSetupForm.form.valid\"\n >\n {{ 'Apply' | translate }}\n </button>\n</form>\n", dependencies: [{ kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i8.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i9.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "pipe", type: i10.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TenantIdSetupComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-tenant-id-setup', template: "<form #tenantIdSetupForm=\"ngForm\" class=\"loginForm\" (ngSubmit)=\"setupLoginMode()\" novalidate>\n <div class=\"legend form-block center\" translate>Tenant setup</div>\n <c8y-form-group class=\"tenantField\" id=\"tenantField\">\n <label for=\"tenant\" translate>Tenant ID</label>\n <input\n [(ngModel)]=\"model.tenant\"\n #tenant=\"ngModel\"\n type=\"text\"\n name=\"tenant\"\n id=\"tenant\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} t12345\"\n placeholder-no-required-hint\n required\n />\n </c8y-form-group>\n\n <button\n title=\"{{ 'Apply' | translate }}\"\n type=\"submit\"\n class=\"btn btn-primary btn-lg btn-block form-group\"\n [disabled]=\"!tenantIdSetupForm.form.valid\"\n >\n {{ 'Apply' | translate }}\n </button>\n</form>\n" }] }], ctorParameters: () => [{ type: i1.FetchClient }, { type: i2.AppStateService }, { type: i3.LoginService }, { type: i4.AlertService }, { type: i5.TranslateService }], propDecorators: { onChangeView: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWlkLXNldHVwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2NvcmUvbG9naW4vdGVuYW50LWlkLXNldHVwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL2NvcmUvbG9naW4vdGVuYW50LWlkLXNldHVwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDMUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7Ozs7Ozs7QUFRMUM7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sc0JBQXNCO0lBT2pDLFlBQ1UsTUFBbUIsRUFDbkIsRUFBbUIsRUFDbkIsWUFBMEIsRUFDMUIsS0FBbUIsRUFDbkIsZ0JBQWtDO1FBSmxDLFdBQU0sR0FBTixNQUFNLENBQWE7UUFDbkIsT0FBRSxHQUFGLEVBQUUsQ0FBaUI7UUFDbkIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsVUFBSyxHQUFMLEtBQUssQ0FBYztRQUNuQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBWGxDLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM1QyxnQkFBVyxHQUFHLFVBQVUsQ0FBQztRQUN6QixVQUFLLEdBQUc7WUFDTixNQUFNLEVBQUUsRUFBRTtTQUNYLENBQUM7SUFRQyxDQUFDO0lBRUo7O09BRUc7SUFDSCxLQUFLLENBQUMsY0FBYztRQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUN2QyxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDakMsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUNmLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQzNCLE9BQU8sQ0FBQyxpREFBaUQsQ0FBQyxFQUMxRCxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUNoQyxDQUNGLENBQUM7WUFDSixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILHVCQUF1QjtRQUNyQixNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDO1FBQzVFLElBQUksbUJBQW1CLEVBQUUsQ0FBQztZQUN4QixNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDMUQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO29CQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLFdBQVc7b0JBQzVCLGVBQWUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRTtpQkFDM0QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7K0dBeERVLHNCQUFzQjttR0FBdEIsc0JBQXNCLHNHQ3JCbkMsZzRCQTRCQTs7NEZEUGEsc0JBQXNCO2tCQVpsQyxTQUFTOytCQUNFLHFCQUFxQjttTUFZckIsWUFBWTtzQkFBckIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IExvZ2luVmlld3MgfSBmcm9tICcuL2xvZ2luLm1vZGVsJztcbmltcG9ydCB7IEZldGNoQ2xpZW50IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQXBwU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3VpLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTG9naW5TZXJ2aWNlIH0gZnJvbSAnLi9sb2dpbi5zZXJ2aWNlJztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSB9IGZyb20gJy4uL2FsZXJ0L2FsZXJ0LnNlcnZpY2UnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgZ2V0dGV4dCB9IGZyb20gJy4uL2kxOG4vZ2V0dGV4dCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS10ZW5hbnQtaWQtc2V0dXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGVuYW50LWlkLXNldHVwLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVzOiBbXVxufSlcblxuLyoqXG4gKiBgVGVuYW50SWRTZXR1cENvbXBvbmVudGAgaXMgaW50ZW5kZWQgdG8gYmUgc2hvd24gd2hlbiB0ZW5hbnQncyBpZCBjYW5ub3QgYmUgZGV0ZXJtaW5lZCBiYXNlZCBvbiB0aGUgY3VycmVudCBVUkwuXG4gKiBJdCBhc2tzIHRoZSB1c2VyIHRvIHByb3ZpZGUgdGFyZ2V0IHRlbmFudCdzIGlkIGFuZCB0aGVuIGl0IGZldGNoZXMgbG9naW4gb3B0aW9ucyBmb3IgdGhpcyB0ZW5hbnQuXG4gKiBJbiBjYXNlIG9mIE9BSS1TZWN1cmUgbG9naW4gbW9kZSwgbG9naW4gb3B0aW9ucyB3aWxsIGNvbnRhaW4gYGRvbWFpbmAgcHJvcGVydHkgc2V0IGJ5IGJhY2tlbmQuXG4gKiBUaGUgY29tcG9uZW50IHdpbGwgcmVkaXJlY3QgdXNlciB0byB0aGlzIGRvbWFpbiwgcHJlc2VydmluZyBVUkwgcGF0aCBhbmQgcGFyYW1zLlxuICovXG5leHBvcnQgY2xhc3MgVGVuYW50SWRTZXR1cENvbXBvbmVudCB7XG4gIEBPdXRwdXQoKSBvbkNoYW5nZVZpZXcgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIExPR0lOX1ZJRVdTID0gTG9naW5WaWV3cztcbiAgbW9kZWwgPSB7XG4gICAgdGVuYW50OiAnJ1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY2xpZW50OiBGZXRjaENsaWVudCxcbiAgICBwcml2YXRlIHVpOiBBcHBTdGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBsb2dpblNlcnZpY2U6IExvZ2luU2VydmljZSxcbiAgICBwcml2YXRlIGFsZXJ0OiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogU2V0cyB1cCBsb2dpbiBtb2RlIGZvciBwYXJ0aWN1bGFyIHRlbmFudC4gSW4gY2FzZSBvZiBPQUktU2VjdXJlIHdpbGwgcmVkaXJlY3QgdXNlciB0byB0ZW5hbnQgZG9tYWluLlxuICAgKi9cbiAgYXN5bmMgc2V0dXBMb2dpbk1vZGUoKSB7XG4gICAgdGhpcy5jbGllbnQudGVuYW50ID0gdGhpcy5tb2RlbC50ZW5hbnQ7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMudWkucmVmcmVzaExvZ2luT3B0aW9ucygpO1xuICAgICAgdGhpcy5sb2dpblNlcnZpY2UuaW5pdExvZ2luT3B0aW9ucygpO1xuICAgICAgdGhpcy5yZWRpcmVjdFRvQ29ycmVjdERvbWFpbigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlLnJlcyAmJiBlLnJlcy5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgICB0aGlzLmFsZXJ0LmRhbmdlcihcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgICAgICAgIGdldHRleHQoJ0NvdWxkIG5vdCBmaW5kIHRlbmFudCB3aXRoIElEIFwie3sgdGVuYW50SWQgfX1cIi4nKSxcbiAgICAgICAgICAgIHsgdGVuYW50SWQ6IHRoaXMubW9kZWwudGVuYW50IH1cbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFsZXJ0LmFkZFNlcnZlckZhaWx1cmUoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZGlyZWN0cyB0byB0ZW5hbnQgZG9tYWluIHdoZW4gbG9naW4gbW9kZSBjb250YWlucyBkb21haW4uXG4gICAqL1xuICByZWRpcmVjdFRvQ29ycmVjdERvbWFpbigpIHtcbiAgICBjb25zdCBsb2dpblJlZGlyZWN0RG9tYWluID0gdGhpcy5sb2dpblNlcnZpY2UubG9naW5Nb2RlLmxvZ2luUmVkaXJlY3REb21haW47XG4gICAgaWYgKGxvZ2luUmVkaXJlY3REb21haW4pIHtcbiAgICAgIGNvbnN0IGFscmVhZHlPbkNvcnJlY3REb21haW4gPSB3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcyhsb2dpblJlZGlyZWN0RG9tYWluKTtcbiAgICAgIGlmICghYWxyZWFkeU9uQ29ycmVjdERvbWFpbikge1xuICAgICAgICB0aGlzLmxvZ2luU2VydmljZS5yZWRpcmVjdFRvRG9tYWluKGxvZ2luUmVkaXJlY3REb21haW4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkNoYW5nZVZpZXcuZW1pdCh7XG4gICAgICAgICAgdmlldzogTG9naW5WaWV3cy5DcmVkZW50aWFscyxcbiAgICAgICAgICBsb2dpblZpZXdQYXJhbXM6IHsgc2hvd1RlbmFudDogdHJ1ZSwgZGlzYWJsZVRlbmFudDogdHJ1ZSB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uQ2hhbmdlVmlldy5lbWl0KHsgdmlldzogTG9naW5WaWV3cy5DcmVkZW50aWFscyB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxmb3JtICN0ZW5hbnRJZFNldHVwRm9ybT1cIm5nRm9ybVwiIGNsYXNzPVwibG9naW5Gb3JtXCIgKG5nU3VibWl0KT1cInNldHVwTG9naW5Nb2RlKClcIiBub3ZhbGlkYXRlPlxuICA8ZGl2IGNsYXNzPVwibGVnZW5kIGZvcm0tYmxvY2sgY2VudGVyXCIgdHJhbnNsYXRlPlRlbmFudCBzZXR1cDwvZGl2PlxuICA8Yzh5LWZvcm0tZ3JvdXAgY2xhc3M9XCJ0ZW5hbnRGaWVsZFwiIGlkPVwidGVuYW50RmllbGRcIj5cbiAgICA8bGFiZWwgZm9yPVwidGVuYW50XCIgdHJhbnNsYXRlPlRlbmFudCBJRDwvbGFiZWw+XG4gICAgPGlucHV0XG4gICAgICBbKG5nTW9kZWwpXT1cIm1vZGVsLnRlbmFudFwiXG4gICAgICAjdGVuYW50PVwibmdNb2RlbFwiXG4gICAgICB0eXBlPVwidGV4dFwiXG4gICAgICBuYW1lPVwidGVuYW50XCJcbiAgICAgIGlkPVwidGVuYW50XCJcbiAgICAgIGF1dG9jYXBpdGFsaXplPVwib2ZmXCJcbiAgICAgIGF1dG9jb3JyZWN0PVwib2ZmXCJcbiAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ2UuZy4nIHwgdHJhbnNsYXRlIH19IHQxMjM0NVwiXG4gICAgICBwbGFjZWhvbGRlci1uby1yZXF1aXJlZC1oaW50XG4gICAgICByZXF1aXJlZFxuICAgIC8+XG4gIDwvYzh5LWZvcm0tZ3JvdXA+XG5cbiAgPGJ1dHRvblxuICAgIHRpdGxlPVwie3sgJ0FwcGx5JyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgYnRuLWxnIGJ0bi1ibG9jayBmb3JtLWdyb3VwXCJcbiAgICBbZGlzYWJsZWRdPVwiIXRlbmFudElkU2V0dXBGb3JtLmZvcm0udmFsaWRcIlxuICA+XG4gICAge3sgJ0FwcGx5JyB8IHRyYW5zbGF0ZSB9fVxuICA8L2J1dHRvbj5cbjwvZm9ybT5cbiJdfQ==