@edugouvfr/ngx-dsfr
Version:
NgxDsfr est un portage Angular des éléments d'interface du Système de Design de l'État Français (DSFR).
137 lines • 33.4 kB
JavaScript
import { CommonModule } from '@angular/common';
import { Component, ContentChild, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
import { DsfrI18nPipe, DsfrSizeConst, newUniqueId } from '../../shared';
import { DsfrButtonComponent } from '../button';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class DsfrModalComponent {
/** @internal */
constructor(renderer2) {
this.renderer2 = renderer2;
/** Le tableau des actions à positionner dans la modale. */
// TODO Ne faudrait-il pas homogénéiser avec les tuiles et les cartes ?
this.actions = [];
/** Permet de ne pas fermer la modale automatiquement lorsqu'une action est exécutée. */
this.autoCloseOnAction = true;
/** Autorise la fermeture de la modale au click sur le fond. */
this.concealingBackdrop = true;
/**
* Le mode de contrôle vous permet, le cas échéant, de maintenir la capacité de la modale à être pilotée
* programmatiquement en absence de bouton de contrôle.
*
* @since 1.8.0
* @deprecated (since 1.14.0)
*/
this.controlMode = 'button';
/** Indique la classe d'icône à utiliser en haut à gauche. Par défaut `fr-icon-arrow-right-line` */
this.icon = 'fr-icon-arrow-right-line';
/** Type de balise HTML, dialog par défaut */
this.markup = 'dialog';
/** Positionnement de la modale en haut en mobile. */
this.mobileTop = false;
/** Signale l'ouverture de la modale. */
this.disclose = new EventEmitter();
/** Signale la fermeture de la modale. */
this.conceal = new EventEmitter();
this._size = DsfrSizeConst.MD;
this._unlisten = [];
this.updateSizeClasses();
}
get size() {
return this._size;
}
/**
* La taille de la modale.
* Valeurs possibles : `SM` (pour small), `MD` (pour medium), `LG` (pour large).
*/
set size(newSize) {
this._size = newSize;
this.updateSizeClasses();
}
ngOnInit() {
this.dialogId ??= newUniqueId();
this.titleElementId = newUniqueId();
}
ngAfterViewInit() {
this._unlisten.push(this.renderer2.listen(this.dsfrModal.nativeElement, 'dsfr.conceal', (e) => {
if (e.target === this.dsfrModal.nativeElement) {
const dialog = this.dsfrModal.nativeElement;
if (Boolean(dialog.getAttribute('open'))) {
this.conceal.emit();
}
}
}), this.renderer2.listen(this.dsfrModal.nativeElement, 'dsfr.disclose', (e) => {
if (e.target === this.dsfrModal.nativeElement) {
this.disclose.emit();
}
}));
}
ngOnDestroy() {
this._unlisten.forEach((unlistenFunc) => unlistenFunc());
}
/**
* Permet de déclencher programmatiquement l'ouverture de la modale.
*/
open() {
dsfr(this.dsfrModal.nativeElement).modal.disclose();
}
/**
* Permet de déclencher programmatiquement la fermeture de la modale.
*/
close() {
dsfr(this.dsfrModal.nativeElement).modal.conceal();
}
/** @internal */
performAction(action) {
if (action.callback) {
action.callback();
}
}
updateSizeClasses() {
this.sizeClasses = {
'fr-col-12': true,
'fr-col-md-4': this.size === DsfrSizeConst.SM,
'fr-col-md-8 fr-col-lg-6': this.size === DsfrSizeConst.MD,
'fr-col-md-8': this.size === DsfrSizeConst.LG,
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrModalComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DsfrModalComponent, isStandalone: true, selector: "dsfr-modal", inputs: { dialogId: "dialogId", titleModal: "titleModal", headingLevel: "headingLevel", actions: "actions", autoCloseOnAction: "autoCloseOnAction", concealingBackdrop: "concealingBackdrop", controlMode: "controlMode", icon: "icon", markup: "markup", mobileTop: "mobileTop", size: "size" }, outputs: { disclose: "disclose", conceal: "conceal" }, queries: [{ propertyName: "modalFooterTemplate", first: true, predicate: ["modalFooterTemplate"], descendants: true, static: true }], viewQueries: [{ propertyName: "dsfrModal", first: true, predicate: ["dsfrModal"], descendants: true }], ngImport: i0, template: "@if (markup === 'dialog') {\n <dialog\n [attr.aria-labelledby]=\"titleElementId\"\n [id]=\"dialogId\"\n class=\"fr-modal\"\n [class.fr-modal--top]=\"mobileTop\"\n [attr.data-fr-concealing-backdrop]=\"concealingBackdrop === false ? false : null\"\n #dsfrModal>\n <ng-container *ngTemplateOutlet=\"dialogTemplate\"></ng-container>\n </dialog>\n} @else {\n <div\n [attr.aria-labelledby]=\"titleElementId\"\n [id]=\"dialogId\"\n role=\"dialog\"\n class=\"fr-modal\"\n [class.fr-modal--top]=\"mobileTop\"\n [attr.data-fr-concealing-backdrop]=\"concealingBackdrop === false ? false : null\"\n #dsfrModal>\n <ng-container *ngTemplateOutlet=\"dialogTemplate\"></ng-container>\n </div>\n}\n\n<ng-template #dialogTemplate>\n <div class=\"fr-container fr-container--fluid fr-container-md\">\n <div class=\"fr-grid-row fr-grid-row--center\">\n <div [ngClass]=\"sizeClasses\">\n <div class=\"fr-modal__body\">\n <div class=\"fr-modal__header\">\n <button\n type=\"button\"\n class=\"fr-btn fr-btn--close\"\n [title]=\"'modal.ariaLabel' | dsfrI18n\"\n [attr.aria-controls]=\"dialogId\"\n data-testid=\"modal-btn-close\">\n {{ 'commons.close' | dsfrI18n }}\n </button>\n </div>\n <div class=\"fr-modal__content\">\n <!-- pas d'utilisation du composant edu-heading car H1 pr\u00E9sent -->\n @switch (headingLevel) {\n @case ('H2') {\n <h2 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h2>\n }\n @case ('H3') {\n <h3 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h3>\n }\n @case ('H4') {\n <h4 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h4>\n }\n @case ('H5') {\n <h5 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h5>\n }\n @case ('H6') {\n <h6 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h6>\n }\n @default {\n <h1 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h1>\n }\n }\n <ng-content></ng-content>\n </div>\n @if (actions && actions.length > 0) {\n <div class=\"fr-modal__footer\">\n <div\n class=\"fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-lg fr-btns-group--icon-left\">\n @for (action of actions; track action) {\n <dsfr-button\n [ariaControls]=\"autoCloseOnAction ? dialogId : ''\"\n [ariaLabel]=\"action.ariaLabel ?? ''\"\n [icon]=\"action.icon\"\n [label]=\"action.label\"\n [type]=\"action.type ?? 'button'\"\n [tooltipMessage]=\"action.tooltipMessage ?? ''\"\n [disabled]=\"action.disabled ?? false\"\n [uppercase]=\"action.uppercase ?? false\"\n [variant]=\"action.variant ?? 'primary'\"\n (click)=\"performAction(action)\">\n </dsfr-button>\n }\n </div>\n </div>\n }\n @if (modalFooterTemplate) {\n <div class=\"fr-modal__footer\">\n <ng-container *ngTemplateOutlet=\"modalFooterTemplate\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #titleTemplate>\n @if (icon) {\n <span class=\"{{ icon }} fr-icon--lg\" aria-hidden=\"true\"></span>\n }\n {{ titleModal }}\n</ng-template>\n", styles: [".fr-modal .fr-modal__footer dsfr-buttons-group{width:100%}.fr-modal .fr-modal__footer dsfr-button{width:100%}@media (min-width: 62em){.fr-modal .fr-btns-group--inline-lg dsfr-button{width:auto;max-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DsfrButtonComponent, selector: "dsfr-button", inputs: ["label", "type", "tooltipMessage", "variant", "buttonSize", "icon", "iconPosition", "disabled", "uppercase", "loader", "ariaLabel", "invertedOutlineContrast", "id", "buttonId", "ariaControls", "ariaPressed", "ariaHasPopup", "ariaExpanded", "tabIndex", "customClass", "buttonRole", "labelSrOnly", "size"] }, { kind: "pipe", type: DsfrI18nPipe, name: "dsfrI18n" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrModalComponent, decorators: [{
type: Component,
args: [{ selector: 'dsfr-modal', encapsulation: ViewEncapsulation.None, standalone: true, imports: [CommonModule, DsfrButtonComponent, DsfrI18nPipe], template: "@if (markup === 'dialog') {\n <dialog\n [attr.aria-labelledby]=\"titleElementId\"\n [id]=\"dialogId\"\n class=\"fr-modal\"\n [class.fr-modal--top]=\"mobileTop\"\n [attr.data-fr-concealing-backdrop]=\"concealingBackdrop === false ? false : null\"\n #dsfrModal>\n <ng-container *ngTemplateOutlet=\"dialogTemplate\"></ng-container>\n </dialog>\n} @else {\n <div\n [attr.aria-labelledby]=\"titleElementId\"\n [id]=\"dialogId\"\n role=\"dialog\"\n class=\"fr-modal\"\n [class.fr-modal--top]=\"mobileTop\"\n [attr.data-fr-concealing-backdrop]=\"concealingBackdrop === false ? false : null\"\n #dsfrModal>\n <ng-container *ngTemplateOutlet=\"dialogTemplate\"></ng-container>\n </div>\n}\n\n<ng-template #dialogTemplate>\n <div class=\"fr-container fr-container--fluid fr-container-md\">\n <div class=\"fr-grid-row fr-grid-row--center\">\n <div [ngClass]=\"sizeClasses\">\n <div class=\"fr-modal__body\">\n <div class=\"fr-modal__header\">\n <button\n type=\"button\"\n class=\"fr-btn fr-btn--close\"\n [title]=\"'modal.ariaLabel' | dsfrI18n\"\n [attr.aria-controls]=\"dialogId\"\n data-testid=\"modal-btn-close\">\n {{ 'commons.close' | dsfrI18n }}\n </button>\n </div>\n <div class=\"fr-modal__content\">\n <!-- pas d'utilisation du composant edu-heading car H1 pr\u00E9sent -->\n @switch (headingLevel) {\n @case ('H2') {\n <h2 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h2>\n }\n @case ('H3') {\n <h3 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h3>\n }\n @case ('H4') {\n <h4 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h4>\n }\n @case ('H5') {\n <h5 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h5>\n }\n @case ('H6') {\n <h6 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h6>\n }\n @default {\n <h1 [id]=\"titleElementId\" class=\"fr-modal__title\">\n <ng-container *ngTemplateOutlet=\"titleTemplate\"></ng-container>\n </h1>\n }\n }\n <ng-content></ng-content>\n </div>\n @if (actions && actions.length > 0) {\n <div class=\"fr-modal__footer\">\n <div\n class=\"fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-lg fr-btns-group--icon-left\">\n @for (action of actions; track action) {\n <dsfr-button\n [ariaControls]=\"autoCloseOnAction ? dialogId : ''\"\n [ariaLabel]=\"action.ariaLabel ?? ''\"\n [icon]=\"action.icon\"\n [label]=\"action.label\"\n [type]=\"action.type ?? 'button'\"\n [tooltipMessage]=\"action.tooltipMessage ?? ''\"\n [disabled]=\"action.disabled ?? false\"\n [uppercase]=\"action.uppercase ?? false\"\n [variant]=\"action.variant ?? 'primary'\"\n (click)=\"performAction(action)\">\n </dsfr-button>\n }\n </div>\n </div>\n }\n @if (modalFooterTemplate) {\n <div class=\"fr-modal__footer\">\n <ng-container *ngTemplateOutlet=\"modalFooterTemplate\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #titleTemplate>\n @if (icon) {\n <span class=\"{{ icon }} fr-icon--lg\" aria-hidden=\"true\"></span>\n }\n {{ titleModal }}\n</ng-template>\n", styles: [".fr-modal .fr-modal__footer dsfr-buttons-group{width:100%}.fr-modal .fr-modal__footer dsfr-button{width:100%}@media (min-width: 62em){.fr-modal .fr-btns-group--inline-lg dsfr-button{width:auto;max-width:100%}}\n"] }]
}], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { dialogId: [{
type: Input
}], titleModal: [{
type: Input
}], headingLevel: [{
type: Input
}], actions: [{
type: Input
}], autoCloseOnAction: [{
type: Input
}], concealingBackdrop: [{
type: Input
}], controlMode: [{
type: Input
}], icon: [{
type: Input
}], markup: [{
type: Input
}], mobileTop: [{
type: Input
}], disclose: [{
type: Output
}], conceal: [{
type: Output
}], dsfrModal: [{
type: ViewChild,
args: ['dsfrModal']
}], modalFooterTemplate: [{
type: ContentChild,
args: ['modalFooterTemplate', { static: true }]
}], size: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUVaLFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUdOLFNBQVMsRUFDVCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFvQixZQUFZLEVBQVksYUFBYSxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNwRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxXQUFXLENBQUM7OztBQWFoRCxNQUFNLE9BQU8sa0JBQWtCO0lBb0U3QixnQkFBZ0I7SUFDaEIsWUFBb0IsU0FBb0I7UUFBcEIsY0FBUyxHQUFULFNBQVMsQ0FBVztRQXZEeEMsMkRBQTJEO1FBQzNELHVFQUF1RTtRQUM5RCxZQUFPLEdBQXNCLEVBQUUsQ0FBQztRQUV6Qyx3RkFBd0Y7UUFDL0Usc0JBQWlCLEdBQUcsSUFBSSxDQUFDO1FBRWxDLCtEQUErRDtRQUN0RCx1QkFBa0IsR0FBRyxJQUFJLENBQUM7UUFFbkM7Ozs7OztXQU1HO1FBQ00sZ0JBQVcsR0FBeUIsUUFBUSxDQUFDO1FBRXRELG1HQUFtRztRQUMxRixTQUFJLEdBQVcsMEJBQTBCLENBQUM7UUFFbkQsNkNBQTZDO1FBQ3BDLFdBQU0sR0FBcUIsUUFBUSxDQUFDO1FBRTdDLHFEQUFxRDtRQUM1QyxjQUFTLEdB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QyxDQUFDO0lBQ0osQ0FBQzsrR0E3SVUsa0JBQWtCO21HQUFsQixrQkFBa0IsNm9CQzlCL0IsKzBJQWdIQSw0UURwRlksWUFBWSxvU0FBRSxtQkFBbUIsNldBQUUsWUFBWTs7NEZBRTlDLGtCQUFrQjtrQkFSOUIsU0FBUzsrQkFDRSxZQUFZLGlCQUdQLGlCQUFpQixDQUFDLElBQUksY0FDekIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG1CQUFtQixFQUFFLFlBQVksQ0FBQzs4RUFJakQsUUFBUTtzQkFBaEIsS0FBSztnQkFJRyxVQUFVO3NCQUFsQixLQUFLO2dCQU1HLFlBQVk7c0JBQXBCLEtBQUs7Z0JBSUcsT0FBTztzQkFBZixLQUFLO2dCQUdHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBU0csV0FBVztzQkFBbkIsS0FBSztnQkFHRyxJQUFJO3NCQUFaLEtBQUs7Z0JBR0csTUFBTTtzQkFBZCxLQUFLO2dCQUdHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0ksUUFBUTtzQkFBakIsTUFBTTtnQkFHRyxPQUFPO3NCQUFoQixNQUFNO2dCQUdpQixTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVc7Z0JBR2lDLG1CQUFtQjtzQkFBekUsWUFBWTt1QkFBQyxxQkFBcUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBNkJ4QyxJQUFJO3NCQUFoQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBSZW5kZXJlcjIsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERzZnJIZWFkaW5nTGV2ZWwsIERzZnJJMThuUGlwZSwgRHNmclNpemUsIERzZnJTaXplQ29uc3QsIG5ld1VuaXF1ZUlkIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IERzZnJCdXR0b25Db21wb25lbnQgfSBmcm9tICcuLi9idXR0b24nO1xuaW1wb3J0IHsgRHNmck1vZGFsQWN0aW9uIH0gZnJvbSAnLi9tb2RhbC1hY3Rpb24ubW9kZWwnO1xuXG5kZWNsYXJlIGZ1bmN0aW9uIGRzZnIoZWxlbTogSFRNTEVsZW1lbnQpOiBhbnk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RzZnItbW9kYWwnLFxuICB0ZW1wbGF0ZVVybDogJy4vbW9kYWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tb2RhbC5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBEc2ZyQnV0dG9uQ29tcG9uZW50LCBEc2ZySTE4blBpcGVdLFxufSlcbmV4cG9ydCBjbGFzcyBEc2ZyTW9kYWxDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8qKiBMJ2lkZW50aWZpYW50IHVuaXF1ZSBkZSBsJ8OpbMOpbWVudCA8ZGlhbG9nPi4gKi9cbiAgQElucHV0KCkgZGlhbG9nSWQ6IHN0cmluZztcblxuICAvKiogVGl0cmUgZGUgbGEgbW9kYWxlLiAqL1xuICAvLyBUT0RPIMOgIHJlbm9tbWVyIGhlYWRpbmcgKGVuIGTDqXByw6ljaWFudClcbiAgQElucHV0KCkgdGl0bGVNb2RhbDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMZSBuaXZlYXUgZGUgdGl0cmUgZGV2YW50IMOqdHJlIHV0aWxpc8OpICh0YWcgYGgxYCBwYXIgZMOpZmF1dCkuXG4gICAqIENldHRlIGJhbGlzZSBuZSBwcm9kdWl0IHBhcyBkZSBzdHlsZSwgbWFpcyBkZSBsYSBzdHJ1Y3R1cmUuXG4gICAqL1xuICBASW5wdXQoKSBoZWFkaW5nTGV2ZWw6IERzZnJIZWFkaW5nTGV2ZWwgfCB1bmRlZmluZWQ7XG5cbiAgLyoqIExlIHRhYmxlYXUgZGVzIGFjdGlvbnMgw6AgcG9zaXRpb25uZXIgZGFucyBsYSBtb2RhbGUuICovXG4gIC8vIFRPRE8gTmUgZmF1ZHJhaXQtaWwgcGFzIGhvbW9nw6luw6lpc2VyIGF2ZWMgbGVzIHR1aWxlcyBldCBsZXMgY2FydGVzID9cbiAgQElucHV0KCkgYWN0aW9uczogRHNmck1vZGFsQWN0aW9uW10gPSBbXTtcblxuICAvKiogUGVybWV0IGRlIG5lIHBhcyBmZXJtZXIgbGEgbW9kYWxlIGF1dG9tYXRpcXVlbWVudCBsb3JzcXUndW5lIGFjdGlvbiBlc3QgZXjDqWN1dMOpZS4gKi9cbiAgQElucHV0KCkgYXV0b0Nsb3NlT25BY3Rpb24gPSB0cnVlO1xuXG4gIC8qKiBBdXRvcmlzZSBsYSBmZXJtZXR1cmUgZGUgbGEgbW9kYWxlIGF1IGNsaWNrIHN1ciBsZSBmb25kLiAqL1xuICBASW5wdXQoKSBjb25jZWFsaW5nQmFja2Ryb3AgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBMZSBtb2RlIGRlIGNvbnRyw7RsZSB2b3VzIHBlcm1ldCwgbGUgY2FzIMOpY2jDqWFudCwgIGRlIG1haW50ZW5pciBsYSBjYXBhY2l0w6kgZGUgbGEgbW9kYWxlIMOgIMOqdHJlIHBpbG90w6llXG4gICAqIHByb2dyYW1tYXRpcXVlbWVudCBlbiBhYnNlbmNlIGRlIGJvdXRvbiBkZSBjb250csO0bGUuXG4gICAqXG4gICAqIEBzaW5jZSAxLjguMFxuICAgKiBAZGVwcmVjYXRlZCAoc2luY2UgMS4xNC4wKVxuICAgKi9cbiAgQElucHV0KCkgY29udHJvbE1vZGU6ICdidXR0b24nIHwgJ2R5bmFtaWMnID0gJ2J1dHRvbic7XG5cbiAgLyoqIEluZGlxdWUgbGEgY2xhc3NlIGQnaWPDtG5lIMOgIHV0aWxpc2VyIGVuIGhhdXQgw6AgZ2F1Y2hlLiBQYXIgZMOpZmF1dCBgZnItaWNvbi1hcnJvdy1yaWdodC1saW5lYCAqL1xuICBASW5wdXQoKSBpY29uOiBzdHJpbmcgPSAnZnItaWNvbi1hcnJvdy1yaWdodC1saW5lJztcblxuICAvKiogVHlwZSBkZSBiYWxpc2UgSFRNTCwgZGlhbG9nIHBhciBkw6lmYXV0ICovXG4gIEBJbnB1dCgpIG1hcmt1cDogJ2RpYWxvZycgfCAnZGl2JyA9ICdkaWFsb2cnO1xuXG4gIC8qKiBQb3NpdGlvbm5lbWVudCBkZSBsYSBtb2RhbGUgZW4gaGF1dCBlbiBtb2JpbGUuICovXG4gIEBJbnB1dCgpIG1vYmlsZVRvcCA9IGZhbHNlO1xuXG4gIC8qKiBTaWduYWxlIGwnb3V2ZXJ0dXJlIGRlIGxhIG1vZGFsZS4gKi9cbiAgQE91dHB1dCgpIGRpc2Nsb3NlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKiBTaWduYWxlIGxhIGZlcm1ldHVyZSBkZSBsYSBtb2RhbGUuICovXG4gIEBPdXRwdXQoKSBjb25jZWFsID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgQFZpZXdDaGlsZCgnZHNmck1vZGFsJykgZHNmck1vZGFsOiBFbGVtZW50UmVmO1xuXG4gIC8qKiBUZW1wbGF0ZSBkdSBwaWVkIGRlIGxhIG1vZGFsZSAoZG9pdCBjb250ZW5pciBkZXMgYm91dG9ucyBkJ2FjdGlvbnMpICovXG4gIEBDb250ZW50Q2hpbGQoJ21vZGFsRm9vdGVyVGVtcGxhdGUnLCB7IHN0YXRpYzogdHJ1ZSB9KSBtb2RhbEZvb3RlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIC8qKlxuICAgKiBMJ2lkZW50aWZpYW50IHVuaXF1ZSBkZSBsJ8OpbMOpbWVudCB0ZW5hbnQgdGl0cmUgZGVzY3JpcHRpZiBkZSBsYSBtb2RhbGUuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdGl0bGVFbGVtZW50SWQ6IHN0cmluZztcblxuICAvKiogQGludGVybmFsICovXG4gIHNpemVDbGFzc2VzOiB7IFtrbGFzczogc3RyaW5nXTogYm9vbGVhbiB9O1xuXG4gIHByaXZhdGUgX3NpemU6IERzZnJTaXplID0gRHNmclNpemVDb25zdC5NRDtcblxuICBwcml2YXRlIF91bmxpc3RlbjogeyAoKTogdm9pZCB9W10gPSBbXTtcblxuICAvKiogQGludGVybmFsICovXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXIyOiBSZW5kZXJlcjIpIHtcbiAgICB0aGlzLnVwZGF0ZVNpemVDbGFzc2VzKCk7XG4gIH1cblxuICBnZXQgc2l6ZSgpOiBEc2ZyU2l6ZSB7XG4gICAgcmV0dXJuIHRoaXMuX3NpemU7XG4gIH1cblxuICAvKipcbiAgICogTGEgdGFpbGxlIGRlIGxhIG1vZGFsZS5cbiAgICogVmFsZXVycyBwb3NzaWJsZXMgOiBgU01gIChwb3VyIHNtYWxsKSwgYE1EYCAocG91ciBtZWRpdW0pLCBgTEdgIChwb3VyIGxhcmdlKS5cbiAgICovXG4gIEBJbnB1dCgpIHNldCBzaXplKG5ld1NpemU6IERzZnJTaXplKSB7XG4gICAgdGhpcy5fc2l6ZSA9IG5ld1NpemU7XG4gICAgdGhpcy51cGRhdGVTaXplQ2xhc3NlcygpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5kaWFsb2dJZCA/Pz0gbmV3VW5pcXVlSWQoKTtcbiAgICB0aGlzLnRpdGxlRWxlbWVudElkID0gbmV3VW5pcXVlSWQoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLl91bmxpc3Rlbi5wdXNoKFxuICAgICAgdGhpcy5yZW5kZXJlcjIubGlzdGVuKHRoaXMuZHNmck1vZGFsLm5hdGl2ZUVsZW1lbnQsICdkc2ZyLmNvbmNlYWwnLCAoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKGUudGFyZ2V0ID09PSB0aGlzLmRzZnJNb2RhbC5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgZGlhbG9nOiBIVE1MRWxlbWVudCA9IHRoaXMuZHNmck1vZGFsLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgaWYgKEJvb2xlYW4oZGlhbG9nLmdldEF0dHJpYnV0ZSgnb3BlbicpKSkge1xuICAgICAgICAgICAgdGhpcy5jb25jZWFsLmVtaXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgdGhpcy5yZW5kZXJlcjIubGlzdGVuKHRoaXMuZHNmck1vZGFsLm5hdGl2ZUVsZW1lbnQsICdkc2ZyLmRpc2Nsb3NlJywgKGU6IEN1c3RvbUV2ZW50KSA9PiB7XG4gICAgICAgIGlmIChlLnRhcmdldCA9PT0gdGhpcy5kc2ZyTW9kYWwubmF0aXZlRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuZGlzY2xvc2UuZW1pdCgpO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fdW5saXN0ZW4uZm9yRWFjaCgodW5saXN0ZW5GdW5jKSA9PiB1bmxpc3RlbkZ1bmMoKSk7XG4gIH1cblxuICAvKipcbiAgICogUGVybWV0IGRlIGTDqWNsZW5jaGVyIHByb2dyYW1tYXRpcXVlbWVudCBsJ291dmVydHVyZSBkZSBsYSBtb2RhbGUuXG4gICAqL1xuICBvcGVuKCkge1xuICAgIGRzZnIodGhpcy5kc2ZyTW9kYWwubmF0aXZlRWxlbWVudCkubW9kYWwuZGlzY2xvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJtZXQgZGUgZMOpY2xlbmNoZXIgcHJvZ3JhbW1hdGlxdWVtZW50IGxhIGZlcm1ldHVyZSBkZSBsYSBtb2RhbGUuXG4gICAqL1xuICBjbG9zZSgpIHtcbiAgICBkc2ZyKHRoaXMuZHNmck1vZGFsLm5hdGl2ZUVsZW1lbnQpLm1vZGFsLmNvbmNlYWwoKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcGVyZm9ybUFjdGlvbihhY3Rpb246IERzZnJNb2RhbEFjdGlvbik6IHZvaWQge1xuICAgIGlmIChhY3Rpb24uY2FsbGJhY2spIHtcbiAgICAgIGFjdGlvbi5jYWxsYmFjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU2l6ZUNsYXNzZXMoKSB7XG4gICAgdGhpcy5zaXplQ2xhc3NlcyA9IHtcbiAgICAgICdmci1jb2wtMTInOiB0cnVlLFxuICAgICAgJ2ZyLWNvbC1tZC00JzogdGhpcy5zaXplID09PSBEc2ZyU2l6ZUNvbnN0LlNNLFxuICAgICAgJ2ZyLWNvbC1tZC04IGZyLWNvbC1sZy02JzogdGhpcy5zaXplID09PSBEc2ZyU2l6ZUNvbnN0Lk1ELFxuICAgICAgJ2ZyLWNvbC1tZC04JzogdGhpcy5zaXplID09PSBEc2ZyU2l6ZUNvbnN0LkxHLFxuICAgIH07XG4gIH1cbn1cbiIsIkBpZiAobWFya3VwID09PSAnZGlhbG9nJykge1xuICA8ZGlhbG9nXG4gICAgW2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cInRpdGxlRWxlbWVudElkXCJcbiAgICBbaWRdPVwiZGlhbG9nSWRcIlxuICAgIGNsYXNzPVwiZnItbW9kYWxcIlxuICAgIFtjbGFzcy5mci1tb2RhbC0tdG9wXT1cIm1vYmlsZVRvcFwiXG4gICAgW2F0dHIuZGF0YS1mci1jb25jZWFsaW5nLWJhY2tkcm9wXT1cImNvbmNlYWxpbmdCYWNrZHJvcCA9PT0gZmFsc2UgPyBmYWxzZSA6IG51bGxcIlxuICAgICNkc2ZyTW9kYWw+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRpYWxvZ1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gIDwvZGlhbG9nPlxufSBAZWxzZSB7XG4gIDxkaXZcbiAgICBbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwidGl0bGVFbGVtZW50SWRcIlxuICAgIFtpZF09XCJkaWFsb2dJZFwiXG4gICAgcm9sZT1cImRpYWxvZ1wiXG4gICAgY2xhc3M9XCJmci1tb2RhbFwiXG4gICAgW2NsYXNzLmZyLW1vZGFsLS10b3BdPVwibW9iaWxlVG9wXCJcbiAgICBbYXR0ci5kYXRhLWZyLWNvbmNlYWxpbmctYmFja2Ryb3BdPVwiY29uY2VhbGluZ0JhY2tkcm9wID09PSBmYWxzZSA/IGZhbHNlIDogbnVsbFwiXG4gICAgI2RzZnJNb2RhbD5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGlhbG9nVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG59XG5cbjxuZy10ZW1wbGF0ZSAjZGlhbG9nVGVtcGxhdGU+XG4gIDxkaXYgY2xhc3M9XCJmci1jb250YWluZXIgZnItY29udGFpbmVyLS1mbHVpZCBmci1jb250YWluZXItbWRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZnItZ3JpZC1yb3cgZnItZ3JpZC1yb3ctLWNlbnRlclwiPlxuICAgICAgPGRpdiBbbmdDbGFzc109XCJzaXplQ2xhc3Nlc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZnItbW9kYWxfX2JvZHlcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnItbW9kYWxfX2hlYWRlclwiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJmci1idG4gZnItYnRuLS1jbG9zZVwiXG4gICAgICAgICAgICAgIFt0aXRsZV09XCInbW9kYWwuYXJpYUxhYmVsJyB8IGRzZnJJMThuXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCJkaWFsb2dJZFwiXG4gICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwibW9kYWwtYnRuLWNsb3NlXCI+XG4gICAgICAgICAgICAgIHt7ICdjb21tb25zLmNsb3NlJyB8IGRzZnJJMThuIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnItbW9kYWxfX2NvbnRlbnRcIj5cbiAgICAgICAgICAgIDwhLS0gcGFzIGQndXRpbGlzYXRpb24gZHUgY29tcG9zYW50IGVkdS1oZWFkaW5nIGNhciBIMSBwcsOpc2VudCAtLT5cbiAgICAgICAgICAgIEBzd2l0Y2ggKGhlYWRpbmdMZXZlbCkge1xuICAgICAgICAgICAgICBAY2FzZSAoJ0gyJykge1xuICAgICAgICAgICAgICAgIDxoMiBbaWRdPVwidGl0bGVFbGVtZW50SWRcIiBjbGFzcz1cImZyLW1vZGFsX190aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRpdGxlVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2gyPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIEBjYXNlICgnSDMnKSB7XG4gICAgICAgICAgICAgICAgPGgzIFtpZF09XCJ0aXRsZUVsZW1lbnRJZFwiIGNsYXNzPVwiZnItbW9kYWxfX3RpdGxlXCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGl0bGVUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvaDM+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGNhc2UgKCdINCcpIHtcbiAgICAgICAgICAgICAgICA8aDQgW2lkXT1cInRpdGxlRWxlbWVudElkXCIgY2xhc3M9XCJmci1tb2RhbF9fdGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0aXRsZVRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9oND5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBAY2FzZSAoJ0g1Jykge1xuICAgICAgICAgICAgICAgIDxoNSBbaWRdPVwidGl0bGVFbGVtZW50SWRcIiBjbGFzcz1cImZyLW1vZGFsX190aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRpdGxlVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2g1PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIEBjYXNlICgnSDYnKSB7XG4gICAgICAgICAgICAgICAgPGg2IFtpZF09XCJ0aXRsZUVsZW1lbnRJZFwiIGNsYXNzPVwiZnItbW9kYWxfX3RpdGxlXCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGl0bGVUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvaDY+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgIDxoMSBbaWRdPVwidGl0bGVFbGVtZW50SWRcIiBjbGFzcz1cImZyLW1vZGFsX190aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRpdGxlVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2gxPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgQGlmIChhY3Rpb25zICYmIGFjdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZyLW1vZGFsX19mb290ZXJcIj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZnItYnRucy1ncm91cCBmci1idG5zLWdyb3VwLS1yaWdodCBmci1idG5zLWdyb3VwLS1pbmxpbmUtcmV2ZXJzZSBmci1idG5zLWdyb3VwLS1pbmxpbmUtbGcgZnItYnRucy1ncm91cC0taWNvbi1sZWZ0XCI+XG4gICAgICAgICAgICAgICAgQGZvciAoYWN0aW9uIG9mIGFjdGlvbnM7IHRyYWNrIGFjdGlvbikge1xuICAgICAgICAgICAgICAgICAgPGRzZnItYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIFthcmlhQ29udHJvbHNdPVwiYXV0b0Nsb3NlT25BY3Rpb24gPyBkaWFsb2dJZCA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgW2FyaWFMYWJlbF09XCJhY3Rpb24uYXJpYUxhYmVsID8/ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgW2ljb25dPVwiYWN0aW9uLmljb25cIlxuICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiYWN0aW9uLmxhYmVsXCJcbiAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiYWN0aW9uLnR5cGUgPz8gJ2J1dHRvbidcIlxuICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcE1lc3NhZ2VdPVwiYWN0aW9uLnRvb2x0aXBNZXNzYWdlID8/ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImFjdGlvbi5kaXNhYmxlZCA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgIFt1cHBlcmNhc2VdPVwiYWN0aW9uLnVwcGVyY2FzZSA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgIFt2YXJpYW50XT1cImFjdGlvbi52YXJpYW50ID8/ICdwcmltYXJ5J1wiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJwZXJmb3JtQWN0aW9uKGFjdGlvbilcIj5cbiAgICAgICAgICAgICAgICAgIDwvZHNmci1idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKG1vZGFsRm9vdGVyVGVtcGxhdGUpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmci1tb2RhbF9fZm9vdGVyXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtb2RhbEZvb3RlclRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICN0aXRsZVRlbXBsYXRlPlxuICBAaWYgKGljb24pIHtcbiAgICA8c3BhbiBjbGFzcz1cInt7IGljb24gfX0gZnItaWNvbi0tbGdcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L3NwYW4+XG4gIH1cbiAge3sgdGl0bGVNb2RhbCB9fVxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==