@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).
102 lines • 33.4 kB
JavaScript
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { LinkDownloadComponent, PictogramComponent } from '../../shared';
import { DsfrBadgesGroupComponent } from '../badges-group';
import { DsfrPanelBackgroundConst, DsfrPanelBorderConst } from '../card';
import { BasePanelComponent } from '../card/base-panel.component';
import { DsfrLinkComponent } from '../link';
import { DsfrTagsGroupComponent } from '../tags-group';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class DsfrTileComponent extends BasePanelComponent {
constructor(_elementRef) {
super();
this._elementRef = _elementRef;
/**
* Chemin vers le répertoire racine contenant les pictogrammes illustratifs DSFR.
*/
this.artworkDirPath = 'artwork';
/**
* Ce boolean permet de ne pas afficher d'icône (flèche).
*/
this.noIcon = false;
/**
* Rotation d'une tuile sur breakpoint 'MD' ou 'LG' (au redimensionnement du contenu).
* 'fr-tile--horizontal@md|lg' si la tuile est verticale
* 'fr-tile--vertical@md|lg' si la tuile est horizontale
*/
this.rotateOn = undefined;
/** @deprecated utiliser `customBackground`. Active le fond de la tuile en gris clair. */
this.useGreyBackground = false;
/** Remplace le lien du bouton de download par un markup de bouton */
this.isDownloadButton = false;
/**
* Permet la gestion programmatique d'une navigation initiée au click sur le tile si l'input 'route' est valorisé.
* La valeur de la propriété 'route' sera transmise.
*/
this.tileSelect = new EventEmitter();
this.DsfrPanelBackground = DsfrPanelBackgroundConst;
this.DsfrPanelBorder = DsfrPanelBorderConst;
}
/** @deprecated (since 1.9.0) utiliser `detailBottom` à la place */
set detail(value) {
this.detailBottom = value;
}
ngAfterViewInit() {
// Supprimer les <p> detail et description si ils sont vides
// fixme : problème pour détecter que le slot est vide dans le template et ne pas afficher le <p>
this.removeEmptyElement(this._elementRef.nativeElement?.querySelector('.fr-tile__detail'));
this.removeEmptyElement(this._elementRef.nativeElement?.querySelector('.fr-tile__desc'));
}
/**
* Dans le cas d'une route, un événement `(routeSelect)` est émis avec la valeur de la route et
* l'événement initial n'est pas propagé.
*
* @internal
*/
onLinkSelect() {
// on propage l'output, pas besoin de gérer ici un éventuel preventDefault si usage de route, c'est géré en amont
if (this.route) {
this.tileSelect.emit(this.route);
}
}
removeEmptyElement(el) {
if (el && !el.textContent && el.children?.length === 0) {
el.remove();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrTileComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DsfrTileComponent, isStandalone: true, selector: "dsfr-tile", inputs: { artworkDirPath: "artworkDirPath", artworkFilePath: "artworkFilePath", imageAlt: "imageAlt", imagePath: "imagePath", noIcon: "noIcon", rotateOn: "rotateOn", useGreyBackground: "useGreyBackground", isDownloadButton: "isDownloadButton", detail: "detail" }, outputs: { tileSelect: "tileSelect" }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"fr-tile\"\n [ngClass]=\"{\n 'fr-enlarge-link': enlargeLink && hasLink(),\n 'fr-tile--download': download,\n 'fr-tile--grey': customBackground === DsfrPanelBackground.GREY || useGreyBackground,\n 'fr-tile--horizontal': horizontal,\n 'fr-tile--no-background': customBackground === DsfrPanelBackground.TRANSPARENT,\n 'fr-tile--no-border': customBorder === DsfrPanelBorder.NO_BORDER,\n 'fr-tile--no-icon': noIcon,\n 'fr-tile--shadow': customBorder === DsfrPanelBorder.SHADOW,\n 'fr-tile--sm': size === 'SM',\n 'fr-tile--vertical@md': horizontal && rotateOn === 'MD',\n 'fr-tile--vertical@lg': horizontal && rotateOn === 'LG',\n 'fr-enlarge-button': enlargeButton\n }\">\n <!-- Body -->\n <div class=\"fr-tile__body\">\n <div class=\"fr-tile__content\">\n <ng-container *ngTemplateOutlet=\"tileHeadingTemplate\"></ng-container>\n\n <p class=\"fr-tile__desc\">\n @if (description) {\n {{ description }}\n } @else {\n <ng-content select=\"[desc]\"></ng-content>\n }\n </p>\n\n <p class=\"fr-tile__detail\">\n @if (detailBottom) {\n {{ detailBottom }}\n } @else {\n <ng-content select=\"[detail]\"></ng-content>\n }\n </p>\n\n @if ((badges && badges.length) || (tags && tags.length)) {\n <div class=\"fr-tile__start\">\n @if (badges) {\n <dsfr-badges-group [badges]=\"badges\"></dsfr-badges-group>\n }\n @if (tags && !badges.length) {\n <dsfr-tags-group [tags]=\"tags\"></dsfr-tags-group>\n }\n </div>\n }\n </div>\n </div>\n\n <!--TODO : Deprecated image \u00E0 retirer en 2.0 -->\n @if (imagePath && !artworkFilePath && !download) {\n <div class=\"fr-tile__img\">\n <img [src]=\"imagePath\" class=\"fr-responsive-img\" [attr.alt]=\"imageAlt\" />\n <!-- L'alternative de l'image (attribut alt) doit \u00E0 priori rester vide car l'image est illustrative et ne doit pas \u00EAtre restitu\u00E9e aux technologies d\u2019assistance. Vous pouvez toutefois remplir l'alternative si vous estimer qu'elle apporte une information essentielle \u00E0 la compr\u00E9hension du contenu non pr\u00E9sente dans le texte -->\n </div>\n }\n\n <!-- Header --------------------------------------------------------------------------------------------------------->\n @if (artworkFilePath || download) {\n <div class=\"fr-tile__header\">\n <div class=\"fr-tile__pictogram\">\n <edu-pictogram\n [artworkDirPath]=\"artworkDirPath\"\n [artworkFilePath]=\"artworkFilePath\"\n [download]=\"download\"></edu-pictogram>\n </div>\n </div>\n }\n</div>\n\n<!-- Templates ----------------------------------------------------------------------------------------------------- -->\n\n<ng-template #tileHeadingTemplate>\n @switch (headingLevel) {\n @case ('H2') {\n <h2 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h2>\n }\n @default {\n <h3 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h3>\n }\n @case ('H4') {\n <h4 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h4>\n }\n @case ('H5') {\n <h5 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h5>\n }\n @case ('H6') {\n <h6 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h6>\n }\n }\n</ng-template>\n\n<ng-template #headingTemplate>\n <!-- Definition des templates directement ici pour une projection du slot correcte (pas de else)-->\n\n <!-- Titre simple -------------------------------------------------------->\n @if (!hasLink()) {\n @if (heading) {\n {{ heading }}\n } @else {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n }\n\n <!-- Lien --------------------------------------------------------------->\n @if (hasLink()) {\n <!-- Lien sans t\u00E9l\u00E9chargement -->\n @if (!download) {\n <dsfr-link\n [customClass]=\"'edu-link'\"\n [ariaLabel]=\"ariaLabel ?? ''\"\n [disabled]=\"disabled\"\n [label]=\"heading\"\n [link]=\"link\"\n [linkTarget]=\"linkTarget\"\n [route]=\"route\"\n [routePath]=\"routePath\"\n [routerLinkActive]=\"routerLinkActive ?? ''\"\n [routerLinkExtras]=\"routerLinkExtras\"\n [mode]=\"enlargeButton ? 'button' : 'link'\"\n (linkSelect)=\"onLinkSelect()\">\n @if (!heading) {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n </dsfr-link>\n } @else {\n <!-- Lien de t\u00E9l\u00E9chargement -->\n <edu-link-download\n [item]=\"itemLink\"\n [downloadDirect]=\"downloadDirect\"\n [downloadAssessFile]=\"downloadAssessFile\"\n [linkTarget]=\"linkTarget\"\n [langCode]=\"downloadLangCode\"\n [isButton]=\"isDownloadButton\"\n (linkSelect)=\"onLinkSelect()\"></edu-link-download>\n }\n }\n</ng-template>\n\n<!-- Template s\u00E9par\u00E9 pour avoir une seule d\u00E9finition du select heading (DO NOT DELETE) -->\n<ng-template #headingTemplateSlot>\n <ng-content select=\"[heading]\"></ng-content>\n</ng-template>\n", styles: [".fr-tile{height:100%}.fr-tile__start dsfr-badges-group .fr-badges-group,.fr-tile__start dsfr-badges-group .fr-tags-group,.fr-tile__start dsfr-tags-group .fr-badges-group,.fr-tile__start dsfr-tags-group .fr-tags-group{justify-content:center}.fr-tile__pictogram svg{width:100%;height: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: DsfrBadgesGroupComponent, selector: "dsfr-badges-group", inputs: ["badges", "small"] }, { kind: "component", type: DsfrTagsGroupComponent, selector: "dsfr-tags-group", inputs: ["tags", "mode"], outputs: ["tagSelect"] }, { kind: "component", type: DsfrLinkComponent, selector: "dsfr-link", inputs: ["ariaCurrent", "ariaLabel", "ariaControls", "customClass", "disabled", "icon", "iconPosition", "linkId", "label", "link", "linkTarget", "route", "routePath", "routerLinkActive", "routerLinkActiveOptions", "routerLinkExtras", "linkSize", "tooltipMessage", "mode", "ariaCurrentWhenActive", "size", "targetLink", "routerLink"], outputs: ["linkSelect"] }, { kind: "component", type: LinkDownloadComponent, selector: "edu-link-download", inputs: ["customClass", "downloadDirect", "downloadAssessFile", "langCode", "linkTarget", "isButton", "item"], outputs: ["linkSelect"] }, { kind: "component", type: PictogramComponent, selector: "edu-pictogram", inputs: ["artworkDirPath", "artworkFilePath", "download"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrTileComponent, decorators: [{
type: Component,
args: [{ selector: 'dsfr-tile', encapsulation: ViewEncapsulation.None, standalone: true, imports: [
CommonModule,
DsfrBadgesGroupComponent,
DsfrTagsGroupComponent,
DsfrLinkComponent,
LinkDownloadComponent,
PictogramComponent,
], template: "<div\n class=\"fr-tile\"\n [ngClass]=\"{\n 'fr-enlarge-link': enlargeLink && hasLink(),\n 'fr-tile--download': download,\n 'fr-tile--grey': customBackground === DsfrPanelBackground.GREY || useGreyBackground,\n 'fr-tile--horizontal': horizontal,\n 'fr-tile--no-background': customBackground === DsfrPanelBackground.TRANSPARENT,\n 'fr-tile--no-border': customBorder === DsfrPanelBorder.NO_BORDER,\n 'fr-tile--no-icon': noIcon,\n 'fr-tile--shadow': customBorder === DsfrPanelBorder.SHADOW,\n 'fr-tile--sm': size === 'SM',\n 'fr-tile--vertical@md': horizontal && rotateOn === 'MD',\n 'fr-tile--vertical@lg': horizontal && rotateOn === 'LG',\n 'fr-enlarge-button': enlargeButton\n }\">\n <!-- Body -->\n <div class=\"fr-tile__body\">\n <div class=\"fr-tile__content\">\n <ng-container *ngTemplateOutlet=\"tileHeadingTemplate\"></ng-container>\n\n <p class=\"fr-tile__desc\">\n @if (description) {\n {{ description }}\n } @else {\n <ng-content select=\"[desc]\"></ng-content>\n }\n </p>\n\n <p class=\"fr-tile__detail\">\n @if (detailBottom) {\n {{ detailBottom }}\n } @else {\n <ng-content select=\"[detail]\"></ng-content>\n }\n </p>\n\n @if ((badges && badges.length) || (tags && tags.length)) {\n <div class=\"fr-tile__start\">\n @if (badges) {\n <dsfr-badges-group [badges]=\"badges\"></dsfr-badges-group>\n }\n @if (tags && !badges.length) {\n <dsfr-tags-group [tags]=\"tags\"></dsfr-tags-group>\n }\n </div>\n }\n </div>\n </div>\n\n <!--TODO : Deprecated image \u00E0 retirer en 2.0 -->\n @if (imagePath && !artworkFilePath && !download) {\n <div class=\"fr-tile__img\">\n <img [src]=\"imagePath\" class=\"fr-responsive-img\" [attr.alt]=\"imageAlt\" />\n <!-- L'alternative de l'image (attribut alt) doit \u00E0 priori rester vide car l'image est illustrative et ne doit pas \u00EAtre restitu\u00E9e aux technologies d\u2019assistance. Vous pouvez toutefois remplir l'alternative si vous estimer qu'elle apporte une information essentielle \u00E0 la compr\u00E9hension du contenu non pr\u00E9sente dans le texte -->\n </div>\n }\n\n <!-- Header --------------------------------------------------------------------------------------------------------->\n @if (artworkFilePath || download) {\n <div class=\"fr-tile__header\">\n <div class=\"fr-tile__pictogram\">\n <edu-pictogram\n [artworkDirPath]=\"artworkDirPath\"\n [artworkFilePath]=\"artworkFilePath\"\n [download]=\"download\"></edu-pictogram>\n </div>\n </div>\n }\n</div>\n\n<!-- Templates ----------------------------------------------------------------------------------------------------- -->\n\n<ng-template #tileHeadingTemplate>\n @switch (headingLevel) {\n @case ('H2') {\n <h2 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h2>\n }\n @default {\n <h3 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h3>\n }\n @case ('H4') {\n <h4 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h4>\n }\n @case ('H5') {\n <h5 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h5>\n }\n @case ('H6') {\n <h6 class=\"fr-tile__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h6>\n }\n }\n</ng-template>\n\n<ng-template #headingTemplate>\n <!-- Definition des templates directement ici pour une projection du slot correcte (pas de else)-->\n\n <!-- Titre simple -------------------------------------------------------->\n @if (!hasLink()) {\n @if (heading) {\n {{ heading }}\n } @else {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n }\n\n <!-- Lien --------------------------------------------------------------->\n @if (hasLink()) {\n <!-- Lien sans t\u00E9l\u00E9chargement -->\n @if (!download) {\n <dsfr-link\n [customClass]=\"'edu-link'\"\n [ariaLabel]=\"ariaLabel ?? ''\"\n [disabled]=\"disabled\"\n [label]=\"heading\"\n [link]=\"link\"\n [linkTarget]=\"linkTarget\"\n [route]=\"route\"\n [routePath]=\"routePath\"\n [routerLinkActive]=\"routerLinkActive ?? ''\"\n [routerLinkExtras]=\"routerLinkExtras\"\n [mode]=\"enlargeButton ? 'button' : 'link'\"\n (linkSelect)=\"onLinkSelect()\">\n @if (!heading) {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n </dsfr-link>\n } @else {\n <!-- Lien de t\u00E9l\u00E9chargement -->\n <edu-link-download\n [item]=\"itemLink\"\n [downloadDirect]=\"downloadDirect\"\n [downloadAssessFile]=\"downloadAssessFile\"\n [linkTarget]=\"linkTarget\"\n [langCode]=\"downloadLangCode\"\n [isButton]=\"isDownloadButton\"\n (linkSelect)=\"onLinkSelect()\"></edu-link-download>\n }\n }\n</ng-template>\n\n<!-- Template s\u00E9par\u00E9 pour avoir une seule d\u00E9finition du select heading (DO NOT DELETE) -->\n<ng-template #headingTemplateSlot>\n <ng-content select=\"[heading]\"></ng-content>\n</ng-template>\n", styles: [".fr-tile{height:100%}.fr-tile__start dsfr-badges-group .fr-badges-group,.fr-tile__start dsfr-badges-group .fr-tags-group,.fr-tile__start dsfr-tags-group .fr-badges-group,.fr-tile__start dsfr-tags-group .fr-tags-group{justify-content:center}.fr-tile__pictogram svg{width:100%;height:100%}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { artworkDirPath: [{
type: Input
}], artworkFilePath: [{
type: Input
}], imageAlt: [{
type: Input
}], imagePath: [{
type: Input
}], noIcon: [{
type: Input
}], rotateOn: [{
type: Input
}], useGreyBackground: [{
type: Input
}], isDownloadButton: [{
type: Input
}], tileSelect: [{
type: Output
}], detail: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGlsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHNmci1jb21wb25lbnRzL3NyYy9saWIvY29tcG9uZW50cy90aWxlL3RpbGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvdGlsZS90aWxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQWlCLFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNySCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLG9CQUFvQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM1QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxlQUFlLENBQUM7OztBQWlCdkQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLGtCQUFrQjtJQTRDdkQsWUFBb0IsV0FBdUI7UUFDekMsS0FBSyxFQUFFLENBQUM7UUFEVSxnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQTNDM0M7O1dBRUc7UUFDTSxtQkFBYyxHQUFHLFNBQVMsQ0FBQztRQWFwQzs7V0FFRztRQUNNLFdBQU0sR0FBRyxLQUFLLENBQUM7UUFFeEI7Ozs7V0FJRztRQUNNLGFBQVEsR0FBNEIsU0FBUyxDQUFDO1FBRXZELHlGQUF5RjtRQUNoRixzQkFBaUIsR0FBWSxLQUFLLENBQUM7UUFFNUMscUVBQXFFO1FBQzVELHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUVsQzs7O1dBR0c7UUFDTyxlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUUvQix3QkFBbUIsR0FBRyx3QkFBd0IsQ0FBQztRQUMvQyxvQkFBZSxHQUFHLG9CQUFvQixDQUFDO0lBSTFELENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsSUFBYSxNQUFNLENBQUMsS0FBYTtRQUMvQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUM1QixDQUFDO0lBRUQsZUFBZTtRQUNiLDREQUE0RDtRQUM1RCxpR0FBaUc7UUFDakcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7UUFDM0YsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsWUFBWTtRQUNWLGlIQUFpSDtRQUNqSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLGtCQUFrQixDQUFDLEVBQWU7UUFDeEMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZELEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDOytHQTdFVSxpQkFBaUI7bUdBQWpCLGlCQUFpQiwyWUN4QjlCLGs2S0EwSkEsMFZEMUlJLFlBQVksb1NBQ1osd0JBQXdCLDJGQUN4QixzQkFBc0IsOEdBQ3RCLGlCQUFpQiw2WkFDakIscUJBQXFCLHNNQUNyQixrQkFBa0I7OzRGQUdULGlCQUFpQjtrQkFmN0IsU0FBUzsrQkFDRSxXQUFXLGlCQUdOLGlCQUFpQixDQUFDLElBQUksY0FDekIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osd0JBQXdCO3dCQUN4QixzQkFBc0I7d0JBQ3RCLGlCQUFpQjt3QkFDakIscUJBQXFCO3dCQUNyQixrQkFBa0I7cUJBQ25COytFQU1RLGNBQWM7c0JBQXRCLEtBQUs7Z0JBS0csZUFBZTtzQkFBdkIsS0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBS0csTUFBTTtzQkFBZCxLQUFLO2dCQU9HLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUdHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFNSSxVQUFVO3NCQUFuQixNQUFNO2dCQVVNLE1BQU07c0JBQWxCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaW5rRG93bmxvYWRDb21wb25lbnQsIFBpY3RvZ3JhbUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBEc2ZyQmFkZ2VzR3JvdXBDb21wb25lbnQgfSBmcm9tICcuLi9iYWRnZXMtZ3JvdXAnO1xuaW1wb3J0IHsgRHNmclBhbmVsQmFja2dyb3VuZENvbnN0LCBEc2ZyUGFuZWxCb3JkZXJDb25zdCB9IGZyb20gJy4uL2NhcmQnO1xuaW1wb3J0IHsgQmFzZVBhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi4vY2FyZC9iYXNlLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEc2ZyTGlua0NvbXBvbmVudCB9IGZyb20gJy4uL2xpbmsnO1xuaW1wb3J0IHsgRHNmclRhZ3NHcm91cENvbXBvbmVudCB9IGZyb20gJy4uL3RhZ3MtZ3JvdXAnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkc2ZyLXRpbGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGlsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RpbGUuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBEc2ZyQmFkZ2VzR3JvdXBDb21wb25lbnQsXG4gICAgRHNmclRhZ3NHcm91cENvbXBvbmVudCxcbiAgICBEc2ZyTGlua0NvbXBvbmVudCxcbiAgICBMaW5rRG93bmxvYWRDb21wb25lbnQsXG4gICAgUGljdG9ncmFtQ29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBEc2ZyVGlsZUNvbXBvbmVudCBleHRlbmRzIEJhc2VQYW5lbENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAvKipcbiAgICogQ2hlbWluIHZlcnMgbGUgcsOpcGVydG9pcmUgcmFjaW5lIGNvbnRlbmFudCBsZXMgcGljdG9ncmFtbWVzIGlsbHVzdHJhdGlmcyBEU0ZSLlxuICAgKi9cbiAgQElucHV0KCkgYXJ0d29ya0RpclBhdGggPSAnYXJ0d29yayc7XG5cbiAgLyoqXG4gICAqIENoZW1pbiByZWxhdGlmIMOgIGFydHdvcmtEaXJQYXRoIGTDqW5vdGFudCBsZSBmaWNoaWVyIGQnaWxsdXN0cmF0aW9uIMOgIHV0aWxpc2VyLlxuICAgKi9cbiAgQElucHV0KCkgYXJ0d29ya0ZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqIEBkZXByZWNhdGVkIChzaW5jZSAxLjUuMCkgKi9cbiAgQElucHV0KCkgaW1hZ2VBbHQ6IHN0cmluZztcblxuICAvKiogQGRlcHJlY2F0ZWQgKHNpbmNlIDEuNS4wKSB1dGlsaXNlciBgYXJ0d29ya0ZpbGVQYXRoYC4gUGF0aCBwb3VyIHNyYyBkJ2ltYWdlIGQnaWxsdXN0cmF0aW9uLiAqL1xuICBASW5wdXQoKSBpbWFnZVBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogQ2UgYm9vbGVhbiBwZXJtZXQgZGUgbmUgcGFzIGFmZmljaGVyIGQnaWPDtG5lIChmbMOoY2hlKS5cbiAgICovXG4gIEBJbnB1dCgpIG5vSWNvbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBSb3RhdGlvbiBkJ3VuZSB0dWlsZSBzdXIgYnJlYWtwb2ludCAnTUQnIG91ICdMRycgKGF1IHJlZGltZW5zaW9ubmVtZW50IGR1IGNvbnRlbnUpLlxuICAgKiAnZnItdGlsZS0taG9yaXpvbnRhbEBtZHxsZycgc2kgbGEgdHVpbGUgZXN0IHZlcnRpY2FsZVxuICAgKiAnZnItdGlsZS0tdmVydGljYWxAbWR8bGcnIHNpIGxhIHR1aWxlIGVzdCBob3Jpem9udGFsZVxuICAgKi9cbiAgQElucHV0KCkgcm90YXRlT246ICdNRCcgfCAnTEcnIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIC8qKiBAZGVwcmVjYXRlZCB1dGlsaXNlciBgY3VzdG9tQmFja2dyb3VuZGAuIEFjdGl2ZSBsZSBmb25kIGRlIGxhIHR1aWxlIGVuIGdyaXMgY2xhaXIuICovXG4gIEBJbnB1dCgpIHVzZUdyZXlCYWNrZ3JvdW5kOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIFJlbXBsYWNlIGxlIGxpZW4gZHUgYm91dG9uIGRlIGRvd25sb2FkIHBhciB1biBtYXJrdXAgZGUgYm91dG9uICovXG4gIEBJbnB1dCgpIGlzRG93bmxvYWRCdXR0b24gPSBmYWxzZTtcblxuICAvKipcbiAgICogUGVybWV0IGxhIGdlc3Rpb24gcHJvZ3JhbW1hdGlxdWUgZCd1bmUgbmF2aWdhdGlvbiBpbml0acOpZSBhdSBjbGljayBzdXIgbGUgdGlsZSBzaSBsJ2lucHV0ICdyb3V0ZScgZXN0IHZhbG9yaXPDqS5cbiAgICogTGEgdmFsZXVyIGRlIGxhIHByb3ByacOpdMOpICdyb3V0ZScgc2VyYSB0cmFuc21pc2UuXG4gICAqL1xuICBAT3V0cHV0KCkgdGlsZVNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBEc2ZyUGFuZWxCYWNrZ3JvdW5kID0gRHNmclBhbmVsQmFja2dyb3VuZENvbnN0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgRHNmclBhbmVsQm9yZGVyID0gRHNmclBhbmVsQm9yZGVyQ29uc3Q7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfZWxlbWVudFJlZjogRWxlbWVudFJlZikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgKHNpbmNlIDEuOS4wKSB1dGlsaXNlciBgZGV0YWlsQm90dG9tYCDDoCBsYSBwbGFjZSAqL1xuICBASW5wdXQoKSBzZXQgZGV0YWlsKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmRldGFpbEJvdHRvbSA9IHZhbHVlO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIC8vIFN1cHByaW1lciBsZXMgPHA+IGRldGFpbCBldCBkZXNjcmlwdGlvbiBzaSBpbHMgc29udCB2aWRlc1xuICAgIC8vIGZpeG1lIDogcHJvYmzDqG1lIHBvdXIgZMOpdGVjdGVyIHF1ZSBsZSBzbG90IGVzdCB2aWRlIGRhbnMgbGUgdGVtcGxhdGUgZXQgbmUgcGFzIGFmZmljaGVyIGxlIDxwPlxuICAgIHRoaXMucmVtb3ZlRW1wdHlFbGVtZW50KHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudD8ucXVlcnlTZWxlY3RvcignLmZyLXRpbGVfX2RldGFpbCcpKTtcbiAgICB0aGlzLnJlbW92ZUVtcHR5RWxlbWVudCh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3IoJy5mci10aWxlX19kZXNjJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIERhbnMgbGUgY2FzIGQndW5lIHJvdXRlLCB1biDDqXbDqW5lbWVudCBgKHJvdXRlU2VsZWN0KWAgZXN0IMOpbWlzIGF2ZWMgbGEgdmFsZXVyIGRlIGxhIHJvdXRlIGV0XG4gICAqIGwnw6l2w6luZW1lbnQgaW5pdGlhbCBuJ2VzdCBwYXMgcHJvcGFnw6kuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgb25MaW5rU2VsZWN0KCkge1xuICAgIC8vIG9uIHByb3BhZ2UgbCdvdXRwdXQsIHBhcyBiZXNvaW4gZGUgZ8OpcmVyIGljaSB1biDDqXZlbnR1ZWwgcHJldmVudERlZmF1bHQgc2kgdXNhZ2UgZGUgcm91dGUsIGMnZXN0IGfDqXLDqSBlbiBhbW9udFxuICAgIGlmICh0aGlzLnJvdXRlKSB7XG4gICAgICB0aGlzLnRpbGVTZWxlY3QuZW1pdCh0aGlzLnJvdXRlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUVtcHR5RWxlbWVudChlbDogSFRNTEVsZW1lbnQpIHtcbiAgICBpZiAoZWwgJiYgIWVsLnRleHRDb250ZW50ICYmIGVsLmNoaWxkcmVuPy5sZW5ndGggPT09IDApIHtcbiAgICAgIGVsLnJlbW92ZSgpO1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImZyLXRpbGVcIlxuICBbbmdDbGFzc109XCJ7XG4gICAgJ2ZyLWVubGFyZ2UtbGluayc6IGVubGFyZ2VMaW5rICYmIGhhc0xpbmsoKSxcbiAgICAnZnItdGlsZS0tZG93bmxvYWQnOiBkb3dubG9hZCxcbiAgICAnZnItdGlsZS0tZ3JleSc6IGN1c3RvbUJhY2tncm91bmQgPT09IERzZnJQYW5lbEJhY2tncm91bmQuR1JFWSB8fCB1c2VHcmV5QmFja2dyb3VuZCxcbiAgICAnZnItdGlsZS0taG9yaXpvbnRhbCc6IGhvcml6b250YWwsXG4gICAgJ2ZyLXRpbGUtLW5vLWJhY2tncm91bmQnOiBjdXN0b21CYWNrZ3JvdW5kID09PSBEc2ZyUGFuZWxCYWNrZ3JvdW5kLlRSQU5TUEFSRU5ULFxuICAgICdmci10aWxlLS1uby1ib3JkZXInOiBjdXN0b21Cb3JkZXIgPT09IERzZnJQYW5lbEJvcmRlci5OT19CT1JERVIsXG4gICAgJ2ZyLXRpbGUtLW5vLWljb24nOiBub0ljb24sXG4gICAgJ2ZyLXRpbGUtLXNoYWRvdyc6IGN1c3RvbUJvcmRlciA9PT0gRHNmclBhbmVsQm9yZGVyLlNIQURPVyxcbiAgICAnZnItdGlsZS0tc20nOiBzaXplID09PSAnU00nLFxuICAgICdmci10aWxlLS12ZXJ0aWNhbEBtZCc6IGhvcml6b250YWwgJiYgcm90YXRlT24gPT09ICdNRCcsXG4gICAgJ2ZyLXRpbGUtLXZlcnRpY2FsQGxnJzogaG9yaXpvbnRhbCAmJiByb3RhdGVPbiA9PT0gJ0xHJyxcbiAgICAnZnItZW5sYXJnZS1idXR0b24nOiBlbmxhcmdlQnV0dG9uXG4gIH1cIj5cbiAgPCEtLSBCb2R5IC0tPlxuICA8ZGl2IGNsYXNzPVwiZnItdGlsZV9fYm9keVwiPlxuICAgIDxkaXYgY2xhc3M9XCJmci10aWxlX19jb250ZW50XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGlsZUhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuXG4gICAgICA8cCBjbGFzcz1cImZyLXRpbGVfX2Rlc2NcIj5cbiAgICAgICAgQGlmIChkZXNjcmlwdGlvbikge1xuICAgICAgICAgIHt7IGRlc2NyaXB0aW9uIH19XG4gICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltkZXNjXVwiPjwvbmctY29udGVudD5cbiAgICAgICAgfVxuICAgICAgPC9wPlxuXG4gICAgICA8cCBjbGFzcz1cImZyLXRpbGVfX2RldGFpbFwiPlxuICAgICAgICBAaWYgKGRldGFpbEJvdHRvbSkge1xuICAgICAgICAgIHt7IGRldGFpbEJvdHRvbSB9fVxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbZGV0YWlsXVwiPjwvbmctY29udGVudD5cbiAgICAgICAgfVxuICAgICAgPC9wPlxuXG4gICAgICBAaWYgKChiYWRnZXMgJiYgYmFkZ2VzLmxlbmd0aCkgfHwgKHRhZ3MgJiYgdGFncy5sZW5ndGgpKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmci10aWxlX19zdGFydFwiPlxuICAgICAgICAgIEBpZiAoYmFkZ2VzKSB7XG4gICAgICAgICAgICA8ZHNmci1iYWRnZXMtZ3JvdXAgW2JhZGdlc109XCJiYWRnZXNcIj48L2RzZnItYmFkZ2VzLWdyb3VwPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKHRhZ3MgJiYgIWJhZGdlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIDxkc2ZyLXRhZ3MtZ3JvdXAgW3RhZ3NdPVwidGFnc1wiPjwvZHNmci10YWdzLWdyb3VwPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDwhLS1UT0RPIDogRGVwcmVjYXRlZCBpbWFnZSDDoCByZXRpcmVyIGVuIDIuMCAtLT5cbiAgQGlmIChpbWFnZVBhdGggJiYgIWFydHdvcmtGaWxlUGF0aCAmJiAhZG93bmxvYWQpIHtcbiAgICA8ZGl2IGNsYXNzPVwiZnItdGlsZV9faW1nXCI+XG4gICAgICA8aW1nIFtzcmNdPVwiaW1hZ2VQYXRoXCIgY2xhc3M9XCJmci1yZXNwb25zaXZlLWltZ1wiIFthdHRyLmFsdF09XCJpbWFnZUFsdFwiIC8+XG4gICAgICA8IS0tIEwnYWx0ZXJuYXRpdmUgZGUgbCdpbWFnZSAoYXR0cmlidXQgYWx0KSBkb2l0IMOgIHByaW9yaSByZXN0ZXIgdmlkZSBjYXIgbCdpbWFnZSBlc3QgaWxsdXN0cmF0aXZlIGV0IG5lIGRvaXQgcGFzIMOqdHJlIHJlc3RpdHXDqWUgYXV4IHRlY2hub2xvZ2llcyBk4oCZYXNzaXN0YW5jZS4gVm91cyBwb3V2ZXogdG91dGVmb2lzIHJlbXBsaXIgbCdhbHRlcm5hdGl2ZSBzaSB2b3VzIGVzdGltZXIgcXUnZWxsZSBhcHBvcnRlIHVuZSBpbmZvcm1hdGlvbiBlc3NlbnRpZWxsZSDDoCBsYSBjb21wcsOpaGVuc2lvbiBkdSBjb250ZW51IG5vbiBwcsOpc2VudGUgZGFucyBsZSB0ZXh0ZSAtLT5cbiAgICA8L2Rpdj5cbiAgfVxuXG4gIDwhLS0gSGVhZGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgQGlmIChhcnR3b3JrRmlsZVBhdGggfHwgZG93bmxvYWQpIHtcbiAgICA8ZGl2IGNsYXNzPVwiZnItdGlsZV9faGVhZGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZnItdGlsZV9fcGljdG9ncmFtXCI+XG4gICAgICAgIDxlZHUtcGljdG9ncmFtXG4gICAgICAgICAgW2FydHdvcmtEaXJQYXRoXT1cImFydHdvcmtEaXJQYXRoXCJcbiAgICAgICAgICBbYXJ0d29ya0ZpbGVQYXRoXT1cImFydHdvcmtGaWxlUGF0aFwiXG4gICAgICAgICAgW2Rvd25sb2FkXT1cImRvd25sb2FkXCI+PC9lZHUtcGljdG9ncmFtPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuXG48IS0tIFRlbXBsYXRlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAtLT5cblxuPG5nLXRlbXBsYXRlICN0aWxlSGVhZGluZ1RlbXBsYXRlPlxuICBAc3dpdGNoIChoZWFkaW5nTGV2ZWwpIHtcbiAgICBAY2FzZSAoJ0gyJykge1xuICAgICAgPGgyIGNsYXNzPVwiZnItdGlsZV9fdGl0bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9oMj5cbiAgICB9XG4gICAgQGRlZmF1bHQge1xuICAgICAgPGgzIGNsYXNzPVwiZnItdGlsZV9fdGl0bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9oMz5cbiAgICB9XG4gICAgQGNhc2UgKCdINCcpIHtcbiAgICAgIDxoNCBjbGFzcz1cImZyLXRpbGVfX3RpdGxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJoZWFkaW5nVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvaDQ+XG4gICAgfVxuICAgIEBjYXNlICgnSDUnKSB7XG4gICAgICA8aDUgY2xhc3M9XCJmci10aWxlX190aXRsZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaGVhZGluZ1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L2g1PlxuICAgIH1cbiAgICBAY2FzZSAoJ0g2Jykge1xuICAgICAgPGg2IGNsYXNzPVwiZnItdGlsZV9fdGl0bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9oNj5cbiAgICB9XG4gIH1cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjaGVhZGluZ1RlbXBsYXRlPlxuICA8IS0tIERlZmluaXRpb24gZGVzIHRlbXBsYXRlcyBkaXJlY3RlbWVudCBpY2kgcG91ciB1bmUgcHJvamVjdGlvbiBkdSBzbG90IGNvcnJlY3RlIChwYXMgZGUgZWxzZSktLT5cblxuICA8IS0tIFRpdHJlIHNpbXBsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgQGlmICghaGFzTGluaygpKSB7XG4gICAgQGlmIChoZWFkaW5nKSB7XG4gICAgICB7eyBoZWFkaW5nIH19XG4gICAgfSBAZWxzZSB7XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaGVhZGluZ1RlbXBsYXRlU2xvdFwiPjwvbmctY29udGFpbmVyPlxuICAgIH1cbiAgfVxuXG4gIDwhLS0gTGllbiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICBAaWYgKGhhc0xpbmsoKSkge1xuICAgIDwhLS0gTGllbiBzYW5zIHTDqWzDqWNoYXJnZW1lbnQgLS0+XG4gICAgQGlmICghZG93bmxvYWQpIHtcbiAgICAgIDxkc2ZyLWxpbmtcbiAgICAgICAgW2N1c3RvbUNsYXNzXT1cIidlZHUtbGluaydcIlxuICAgICAgICBbYXJpYUxhYmVsXT1cImFyaWFMYWJlbCA/PyAnJ1wiXG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgIFtsYWJlbF09XCJoZWFkaW5nXCJcbiAgICAgICAgW2xpbmtdPVwibGlua1wiXG4gICAgICAgIFtsaW5rVGFyZ2V0XT1cImxpbmtUYXJnZXRcIlxuICAgICAgICBbcm91dGVdPVwicm91dGVcIlxuICAgICAgICBbcm91dGVQYXRoXT1cInJvdXRlUGF0aFwiXG4gICAgICAgIFtyb3V0ZXJMaW5rQWN0aXZlXT1cInJvdXRlckxpbmtBY3RpdmUgPz8gJydcIlxuICAgICAgICBbcm91dGVyTGlua0V4dHJhc109XCJyb3V0ZXJMaW5rRXh0cmFzXCJcbiAgICAgICAgW21vZGVdPVwiZW5sYXJnZUJ1dHRvbiA/ICdidXR0b24nIDogJ2xpbmsnXCJcbiAgICAgICAgKGxpbmtTZWxlY3QpPVwib25MaW5rU2VsZWN0KClcIj5cbiAgICAgICAgQGlmICghaGVhZGluZykge1xuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJoZWFkaW5nVGVtcGxhdGVTbG90XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cbiAgICAgIDwvZHNmci1saW5rPlxuICAgIH0gQGVsc2Uge1xuICAgICAgPCEtLSBMaWVuIGRlIHTDqWzDqWNoYXJnZW1lbnQgLS0+XG4gICAgICA8ZWR1LWxpbmstZG93bmxvYWRcbiAgICAgICAgW2l0ZW1dPVwiaXRlbUxpbmtcIlxuICAgICAgICBbZG93bmxvYWREaXJlY3RdPVwiZG93bmxvYWREaXJlY3RcIlxuICAgICAgICBbZG93bmxvYWRBc3Nlc3NGaWxlXT1cImRvd25sb2FkQXNzZXNzRmlsZVwiXG4gICAgICAgIFtsaW5rVGFyZ2V0XT1cImxpbmtUYXJnZXRcIlxuICAgICAgICBbbGFuZ0NvZGVdPVwiZG93bmxvYWRMYW5nQ29kZVwiXG4gICAgICAgIFtpc0J1dHRvbl09XCJpc0Rvd25sb2FkQnV0dG9uXCJcbiAgICAgICAgKGxpbmtTZWxlY3QpPVwib25MaW5rU2VsZWN0KClcIj48L2VkdS1saW5rLWRvd25sb2FkPlxuICAgIH1cbiAgfVxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLSBUZW1wbGF0ZSBzw6lwYXLDqSBwb3VyIGF2b2lyIHVuZSBzZXVsZSBkw6lmaW5pdGlvbiBkdSBzZWxlY3QgaGVhZGluZyAoRE8gTk9UIERFTEVURSkgLS0+XG48bmctdGVtcGxhdGUgI2hlYWRpbmdUZW1wbGF0ZVNsb3Q+XG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIltoZWFkaW5nXVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG4iXX0=