UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

84 lines 19.8 kB
import { Component } from '@angular/core'; import { AppStateService } from '../common/ui-state.service'; import { TranslateService } from '../i18n/translate.service'; import { ModalService } from '../modal/modal.service'; import { gettext } from '../i18n/gettext'; import { UserPreferencesService } from '../common/user-preferences/user-preferences.service'; import { Status } from '../common/status.model'; import { Subject } from 'rxjs'; import { HeaderService } from '../header/header.service'; import { filter, first, takeUntil } from 'rxjs/operators'; import { ThemeSwitcherService } from './theme-switcher.service'; import * as i0 from "@angular/core"; import * as i1 from "../i18n/translate.service"; import * as i2 from "../common/ui-state.service"; import * as i3 from "../common/user-preferences/user-preferences.service"; import * as i4 from "../modal/modal.service"; import * as i5 from "../header/header.service"; import * as i6 from "./theme-switcher.service"; import * as i7 from "../common/icon.directive"; import * as i8 from "../i18n/c8y-translate.directive"; import * as i9 from "@angular/common"; import * as i10 from "@angular/forms"; import * as i11 from "../i18n/c8y-translate.pipe"; export class UiSettingsComponent { constructor(translate, state, ui, userPreferences, c8yModalService, headerService, themeSwitcher) { this.translate = translate; this.state = state; this.ui = ui; this.userPreferences = userPreferences; this.c8yModalService = c8yModalService; this.headerService = headerService; this.themeSwitcher = themeSwitcher; this.destroyed$ = new Subject(); this.currentLang = this.ui.state.lang; this.ui.state$ .pipe(filter(({ lang }) => lang !== this.currentLang), takeUntil(this.destroyed$), first()) .subscribe(({ lang }) => (this.currentLang = lang)); this.open$ = this.headerService.rightDrawerOpen$; } ngOnInit() { this.languages = this.state.state.langs.map(l => ({ lang: l, nativeLanguage: this.translate.getNativeLanguage(l) })); } ngOnDestroy() { this.destroyed$.next(); this.destroyed$.complete(); } async onLanguageChange(changedLang) { if (!changedLang) { return; } await this.translate.switchToLanguage(changedLang); if (await this.persistLanguage(changedLang)) { location.reload(); } } async persistLanguage(lang) { let shouldReload = true; try { await this.c8yModalService.confirm(gettext('Reload recommended'), gettext('To change the language in the entire application, we recommend you to reload the page. If you have any unsaved changes, you can reload later. How would you like to proceed?'), Status.WARNING, { ok: gettext('Reload now'), cancel: gettext('Reload later') }); } catch (ex) { shouldReload = false; } finally { this.translate.saveInLocalStorage(lang); await this.userPreferences.set('language', lang); this.currentLang = lang; } return shouldReload; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UiSettingsComponent, deps: [{ token: i1.TranslateService }, { token: i2.AppStateService }, { token: i2.AppStateService }, { token: i3.UserPreferencesService }, { token: i4.ModalService }, { token: i5.HeaderService }, { token: i6.ThemeSwitcherService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: UiSettingsComponent, selector: "c8y-ui-settings", ngImport: i0, template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"eyedropper\"></i>\n <span class=\"text-bold\">{{ 'UI settings' | translate }}</span>\n </div>\n\n <div\n class=\"p-l-16 p-r-16 p-b-16\"\n *ngIf=\"themeSwitcher.darkThemeAvailable$ | async\"\n >\n <p translate>Theme</p>\n <div\n class=\"c8y-switch-multistate\"\n *ngIf=\"themeSwitcher.userSelectedThemePreference$ | async as themePreference\"\n >\n <ng-container *ngFor=\"let themeOption of themeSwitcher.themeOptions; index as i\">\n <input\n [attr.aria-label]=\"themeOption.label\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n name=\"theme-switcher\"\n type=\"radio\"\n [id]=\"'theme-option-' + i\"\n [disabled]=\"themeSwitcher.disableThemeSelection$ | async\"\n [checked]=\"themePreference === themeOption.value\"\n (click)=\"themeSwitcher.changeUserPreference(themeOption.value)\"\n />\n <label\n title=\"{{ themeOption.label | translate }}\"\n [for]=\"'theme-option-' + i\"\n >\n <i [c8yIcon]=\"themeOption.icon\"></i>\n </label>\n </ng-container>\n <div class=\"c8y-switch-multistate__handle\"></div>\n </div>\n </div>\n\n <div class=\"form-group p-l-16 p-r-16\">\n <label\n for=\"userLang\"\n translate\n >\n Language\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n #selectLang\n [ngModel]=\"currentLang\"\n (change)=\"onLanguageChange(selectLang.value)\"\n >\n <option\n *ngFor=\"let language of languages\"\n [value]=\"language.lang\"\n >\n {{ language.nativeLanguage }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i7.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i8.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i10.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i10.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i10.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i11.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i9.AsyncPipe, name: "async" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UiSettingsComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-ui-settings', template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"eyedropper\"></i>\n <span class=\"text-bold\">{{ 'UI settings' | translate }}</span>\n </div>\n\n <div\n class=\"p-l-16 p-r-16 p-b-16\"\n *ngIf=\"themeSwitcher.darkThemeAvailable$ | async\"\n >\n <p translate>Theme</p>\n <div\n class=\"c8y-switch-multistate\"\n *ngIf=\"themeSwitcher.userSelectedThemePreference$ | async as themePreference\"\n >\n <ng-container *ngFor=\"let themeOption of themeSwitcher.themeOptions; index as i\">\n <input\n [attr.aria-label]=\"themeOption.label\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n name=\"theme-switcher\"\n type=\"radio\"\n [id]=\"'theme-option-' + i\"\n [disabled]=\"themeSwitcher.disableThemeSelection$ | async\"\n [checked]=\"themePreference === themeOption.value\"\n (click)=\"themeSwitcher.changeUserPreference(themeOption.value)\"\n />\n <label\n title=\"{{ themeOption.label | translate }}\"\n [for]=\"'theme-option-' + i\"\n >\n <i [c8yIcon]=\"themeOption.icon\"></i>\n </label>\n </ng-container>\n <div class=\"c8y-switch-multistate__handle\"></div>\n </div>\n </div>\n\n <div class=\"form-group p-l-16 p-r-16\">\n <label\n for=\"userLang\"\n translate\n >\n Language\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n #selectLang\n [ngModel]=\"currentLang\"\n (change)=\"onLanguageChange(selectLang.value)\"\n >\n <option\n *ngFor=\"let language of languages\"\n [value]=\"language.lang\"\n >\n {{ language.nativeLanguage }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.TranslateService }, { type: i2.AppStateService }, { type: i2.AppStateService }, { type: i3.UserPreferencesService }, { type: i4.ModalService }, { type: i5.HeaderService }, { type: i6.ThemeSwitcherService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktc2V0dGluZ3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS91aS1zZXR0aW5ncy91aS1zZXR0aW5ncy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb3JlL3VpLXNldHRpbmdzL3VpLXNldHRpbmdzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQzdGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7OztBQU1oRSxNQUFNLE9BQU8sbUJBQW1CO0lBTTlCLFlBQ1UsU0FBMkIsRUFDM0IsS0FBc0IsRUFDdEIsRUFBbUIsRUFDbkIsZUFBdUMsRUFDdkMsZUFBNkIsRUFDN0IsYUFBNEIsRUFDN0IsYUFBbUM7UUFObEMsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFDM0IsVUFBSyxHQUFMLEtBQUssQ0FBaUI7UUFDdEIsT0FBRSxHQUFG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IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25EZXN0cm95LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFwcFN0YXRlU2VydmljZSB9IGZyb20gJy4uL2NvbW1vbi91aS1zdGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi9pMThuL3RyYW5zbGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IE1vZGFsU2VydmljZSB9IGZyb20gJy4uL21vZGFsL21vZGFsLnNlcnZpY2UnO1xuaW1wb3J0IHsgZ2V0dGV4dCB9IGZyb20gJy4uL2kxOG4vZ2V0dGV4dCc7XG5pbXBvcnQgeyBVc2VyUHJlZmVyZW5jZXNTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3VzZXItcHJlZmVyZW5jZXMvdXNlci1wcmVmZXJlbmNlcy5zZXJ2aWNlJztcbmltcG9ydCB7IFN0YXR1cyB9IGZyb20gJy4uL2NvbW1vbi9zdGF0dXMubW9kZWwnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSGVhZGVyU2VydmljZSB9IGZyb20gJy4uL2hlYWRlci9oZWFkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBmaWx0ZXIsIGZpcnN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUaGVtZVN3aXRjaGVyU2VydmljZSB9IGZyb20gJy4vdGhlbWUtc3dpdGNoZXIuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS11aS1zZXR0aW5ncycsXG4gIHRlbXBsYXRlVXJsOiAnLi91aS1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgVWlTZXR0aW5nc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgb3BlbiQ6IE9ic2VydmFibGU8Ym9vbGVhbj47XG4gIGN1cnJlbnRMYW5nOiBzdHJpbmc7XG4gIGxhbmd1YWdlczogeyBsYW5nOiBzdHJpbmc7IG5hdGl2ZUxhbmd1YWdlOiBzdHJpbmcgfVtdO1xuICBwcml2YXRlIGRlc3Ryb3llZCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgc3RhdGU6IEFwcFN0YXRlU2VydmljZSxcbiAgICBwcml2YXRlIHVpOiBBcHBTdGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB1c2VyUHJlZmVyZW5jZXM6IFVzZXJQcmVmZXJlbmNlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjOHlNb2RhbFNlcnZpY2U6IE1vZGFsU2VydmljZSxcbiAgICBwcml2YXRlIGhlYWRlclNlcnZpY2U6IEhlYWRlclNlcnZpY2UsXG4gICAgcHVibGljIHRoZW1lU3dpdGNoZXI6IFRoZW1lU3dpdGNoZXJTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuY3VycmVudExhbmcgPSB0aGlzLnVpLnN0YXRlLmxhbmc7XG4gICAgdGhpcy51aS5zdGF0ZSRcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoKHsgbGFuZyB9KSA9PiBsYW5nICE9PSB0aGlzLmN1cnJlbnRMYW5nKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJCksXG4gICAgICAgIGZpcnN0KClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKHsgbGFuZyB9KSA9PiAodGhpcy5jdXJyZW50TGFuZyA9IGxhbmcpKTtcbiAgICB0aGlzLm9wZW4kID0gdGhpcy5oZWFkZXJTZXJ2aWNlLnJpZ2h0RHJhd2VyT3BlbiQ7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmxhbmd1YWdlcyA9ICh0aGlzLnN0YXRlLnN0YXRlLmxhbmdzIGFzIHN0cmluZ1tdKS5tYXAobCA9PiAoe1xuICAgICAgbGFuZzogbCxcbiAgICAgIG5hdGl2ZUxhbmd1YWdlOiB0aGlzLnRyYW5zbGF0ZS5nZXROYXRpdmVMYW5ndWFnZShsKVxuICAgIH0pKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveWVkJC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBhc3luYyBvbkxhbmd1YWdlQ2hhbmdlKGNoYW5nZWRMYW5nOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWNoYW5nZWRMYW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IHRoaXMudHJhbnNsYXRlLnN3aXRjaFRvTGFuZ3VhZ2UoY2hhbmdlZExhbmcpO1xuICAgIGlmIChhd2FpdCB0aGlzLnBlcnNpc3RMYW5ndWFnZShjaGFuZ2VkTGFuZykpIHtcbiAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHBlcnNpc3RMYW5ndWFnZShsYW5nOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgc2hvdWxkUmVsb2FkID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jOHlNb2RhbFNlcnZpY2UuY29uZmlybShcbiAgICAgICAgZ2V0dGV4dCgnUmVsb2FkIHJlY29tbWVuZGVkJyksXG4gICAgICAgIGdldHRleHQoXG4gICAgICAgICAgJ1RvIGNoYW5nZSB0aGUgbGFuZ3VhZ2UgaW4gdGhlIGVudGlyZSBhcHBsaWNhdGlvbiwgd2UgcmVjb21tZW5kIHlvdSB0byByZWxvYWQgdGhlIHBhZ2UuIElmIHlvdSBoYXZlIGFueSB1bnNhdmVkIGNoYW5nZXMsIHlvdSBjYW4gcmVsb2FkIGxhdGVyLiBIb3cgd291bGQgeW91IGxpa2UgdG8gcHJvY2VlZD8nXG4gICAgICAgICksXG4gICAgICAgIFN0YXR1cy5XQVJOSU5HLFxuICAgICAgICB7XG4gICAgICAgICAgb2s6IGdldHRleHQoJ1JlbG9hZCBub3cnKSxcbiAgICAgICAgICBjYW5jZWw6IGdldHRleHQoJ1JlbG9hZCBsYXRlcicpXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHNob3VsZFJlbG9hZCA9IGZhbHNlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnRyYW5zbGF0ZS5zYXZlSW5Mb2NhbFN0b3JhZ2UobGFuZyk7XG4gICAgICBhd2FpdCB0aGlzLnVzZXJQcmVmZXJlbmNlcy5zZXQoJ2xhbmd1YWdlJywgbGFuZyk7XG4gICAgICB0aGlzLmN1cnJlbnRMYW5nID0gbGFuZztcbiAgICB9XG4gICAgcmV0dXJuIHNob3VsZFJlbG9hZDtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInNlcGFyYXRvci10b3AgcC10LTggcC1iLThcIj5cbiAgPGRpdiBjbGFzcz1cImM4eS1yaWdodC1kcmF3ZXJfX2l0ZW0gc3RpY2t5LXRvcFwiPlxuICAgIDxpIGM4eUljb249XCJleWVkcm9wcGVyXCI+PC9pPlxuICAgIDxzcGFuIGNsYXNzPVwidGV4dC1ib2xkXCI+e3sgJ1VJIHNldHRpbmdzJyB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPGRpdlxuICAgIGNsYXNzPVwicC1sLTE2IHAtci0xNiBwLWItMTZcIlxuICAgICpuZ0lmPVwidGhlbWVTd2l0Y2hlci5kYXJrVGhlbWVBdmFpbGFibGUkIHwgYXN5bmNcIlxuICA+XG4gICAgPHAgdHJhbnNsYXRlPlRoZW1lPC9wPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiYzh5LXN3aXRjaC1tdWx0aXN0YXRlXCJcbiAgICAgICpuZ0lmPVwidGhlbWVTd2l0Y2hlci51c2VyU2VsZWN0ZWRUaGVtZVByZWZlcmVuY2UkIHwgYXN5bmMgYXMgdGhlbWVQcmVmZXJlbmNlXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB0aGVtZU9wdGlvbiBvZiB0aGVtZVN3aXRjaGVyLnRoZW1lT3B0aW9uczsgaW5kZXggYXMgaVwiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInRoZW1lT3B0aW9uLmxhYmVsXCJcbiAgICAgICAgICB0YWJpbmRleD1cInt7IChvcGVuJCB8IGFzeW5jKSA/ICcwJyA6ICctMScgfX1cIlxuICAgICAgICAgIG5hbWU9XCJ0aGVtZS1zd2l0Y2hlclwiXG4gICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICBbaWRdPVwiJ3RoZW1lLW9wdGlvbi0nICsgaVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cInRoZW1lU3dpdGNoZXIuZGlzYWJsZVRoZW1lU2VsZWN0aW9uJCB8IGFzeW5jXCJcbiAgICAgICAgICBbY2hlY2tlZF09XCJ0aGVtZVByZWZlcmVuY2UgPT09IHRoZW1lT3B0aW9uLnZhbHVlXCJcbiAgICAgICAgICAoY2xpY2spPVwidGhlbWVTd2l0Y2hlci5jaGFuZ2VVc2VyUHJlZmVyZW5jZSh0aGVtZU9wdGlvbi52YWx1ZSlcIlxuICAgICAgICAvPlxuICAgICAgICA8bGFiZWxcbiAgICAgICAgICB0aXRsZT1cInt7IHRoZW1lT3B0aW9uLmxhYmVsIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICBbZm9yXT1cIid0aGVtZS1vcHRpb24tJyArIGlcIlxuICAgICAgICA+XG4gICAgICAgICAgPGkgW2M4eUljb25dPVwidGhlbWVPcHRpb24uaWNvblwiPjwvaT5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPGRpdiBjbGFzcz1cImM4eS1zd2l0Y2gtbXVsdGlzdGF0ZV9faGFuZGxlXCI+PC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHAtbC0xNiBwLXItMTZcIj5cbiAgICA8bGFiZWxcbiAgICAgIGZvcj1cInVzZXJMYW5nXCJcbiAgICAgIHRyYW5zbGF0ZVxuICAgID5cbiAgICAgIExhbmd1YWdlXG4gICAgPC9sYWJlbD5cbiAgICA8ZGl2IGNsYXNzPVwiYzh5LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICA8c2VsZWN0XG4gICAgICAgIGlkPVwidXNlckxhbmdcIlxuICAgICAgICB0YWJpbmRleD1cInt7IChvcGVuJCB8IGFzeW5jKSA/ICcwJyA6ICctMScgfX1cIlxuICAgICAgICAjc2VsZWN0TGFuZ1xuICAgICAgICBbbmdNb2RlbF09XCJjdXJyZW50TGFuZ1wiXG4gICAgICAgIChjaGFuZ2UpPVwib25MYW5ndWFnZUNoYW5nZShzZWxlY3RMYW5nLnZhbHVlKVwiXG4gICAgICA+XG4gICAgICAgIDxvcHRpb25cbiAgICAgICAgICAqbmdGb3I9XCJsZXQgbGFuZ3VhZ2Ugb2YgbGFuZ3VhZ2VzXCJcbiAgICAgICAgICBbdmFsdWVdPVwibGFuZ3VhZ2UubGFuZ1wiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBsYW5ndWFnZS5uYXRpdmVMYW5ndWFnZSB9fVxuICAgICAgICA8L29wdGlvbj5cbiAgICAgIDwvc2VsZWN0PlxuICAgICAgPHNwYW4+PC9zcGFuPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19