@edugouvfr/ngx-dsfr-ext
Version:
NgxDsfrExt est une extension au package @edugouvfr/ngx-dsfr (portage Angular des éléments DSFR)
183 lines • 27.9 kB
JavaScript
import { A11yModule } from '@angular/cdk/a11y';
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
import { DsfrButtonModule, DsfrI18nPipe, Language, newUniqueId, } from '@edugouvfr/ngx-dsfr';
import { Subscription } from 'rxjs';
import { EduClickOutsideDirective } from '../../shared';
import { DateUtils } from '../../shared/utils/date/date-utils';
import { DsfrCalendarComponent } from '../calendar.component';
import { MESSAGES_EN } from '../i18n/messages.en';
import { MESSAGES_FR } from '../i18n/messages.fr';
import * as i0 from "@angular/core";
import * as i1 from "@edugouvfr/ngx-dsfr";
import * as i2 from "@angular/cdk/a11y";
export class DsfrCalendarModalComponent {
constructor(elementRef, i18n, logger) {
this.elementRef = elementRef;
this.i18n = i18n;
this.logger = logger;
/**
* Date minimale inclue. Doit être au format IS0-8601 : AAAA-MM-JJ.
* Ce paramètre peut être utilisé seul ou avec la propriété max.
*/
this.min = '';
/**
* Date maximale inclue. Doit être au format IS0-8601 : AAAA-MM-JJ.
* Ce paramètre peut être utilisé seul ou avec la propriété min.
*/
this.max = '';
/**
* Valeur de l'attribut aria-label du bouton d'ouverture de la modale.
*/
this.ariaLabel = '';
/**
* Message du `tooltip` (attribut `title` du bouton) ou ajout d'un `span` en `sr-only` si pas de label.
*/
this.tooltipMessage = '';
/**
* Valeur de l'attribut disabled du bouton d'ouverture de la modale.
*/
this.disabled = false;
/**
* Emission de la date au format DsfrDateEvent
*/
this.dateChange = new EventEmitter();
/**
* Id aléatoire, unique, de la modale (le calendrier)
*/
this.modalId = newUniqueId();
this.isOpen = false;
this.dialogTitle = '';
this.translatedMonths = [];
this._value = '';
this.currentMonthIndex = 0;
this.currentYear = 0;
this.subscription = new Subscription();
this.i18n.extendsLabelsBundle(Language.EN, MESSAGES_EN);
this.i18n.extendsLabelsBundle(Language.FR, MESSAGES_FR);
const langChange$ = this.i18n.completeLangChange$.subscribe(() => this.onLangChange());
this.updateMonthIndexAndYear();
this.updateDialogTitle();
this.subscription.add(langChange$);
}
get value() {
return this._value;
}
/**
* Valeur initial de la date.
* La valeur doit prendre la forme dd/mm/yyyy pour la locale fr et mm/dd/yyyy pour la locale en.
*/
set value(value) {
if (value && DateUtils.isValidDefaultString(value)) {
this._value = value;
this.updateMonthIndexAndYear(value);
}
}
ngAfterViewInit() {
const nativeElt = this.elementRef.nativeElement;
this.dialogTriggerBtnNode = nativeElt.querySelector('.fr-btn');
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
/**
* Gère le clic en dehors de la modale
*/
onCalendarOutside() {
if (this.isOpen) {
this.close(false);
}
}
handleTriggerBtnClick() {
this.isOpen = true;
}
handleDataChange(dateEvent) {
if (!dateEvent.date || !dateEvent.value) {
return;
}
this.value = dateEvent.value;
this.dateChange.emit(dateEvent);
this.close();
}
handleModalKeydown(keyEvent) {
if (keyEvent.key === 'Escape') {
keyEvent.stopPropagation();
keyEvent.preventDefault();
this.close();
}
}
handleCancelButton() {
this.close();
}
/**
* Met à jour le titre de la dialog (visuellement caché) pour les besoins d'accessibilité.
*/
updateDialogTitle() {
this.dialogTitle = `${this.i18n.t('calendar.modal.title')}${this.translatedMonths[this.currentMonthIndex]} ${this.currentYear}`;
}
/**
* Ferme la modale.
*
* Positionne le focus sur le bouton d'ouverture de la modale si besoin.
*
* @param focusTriggerBtn Permet de savoir si le focus doit être donné au bouton d'ouverture de la modale
*/
close(focusTriggerBtn = true) {
if (!this.modal) {
return;
}
// Pour être raccord avec la directive click-outside : on enlève 'data-expanded'
this.modal.nativeElement.removeAttribute('data-expanded');
this.isOpen = false;
if (focusTriggerBtn) {
this.dialogTriggerBtnNode.focus();
}
}
updateMonthTranslations() {
this.translatedMonths = DateUtils.arr(this.i18n, this.logger, 'calendar.months');
}
/**
* Gestion du changement de langue dans le composant.
*
* @param code Code de la locale à prendre en compte
*/
onLangChange() {
this.updateMonthTranslations();
this.updateDialogTitle();
}
/**
* Mise à jour des valeurs des deux listes déroulantes, mois et année.
*/
updateMonthIndexAndYear(date) {
this.currentMonthIndex = date ? new Date(date).getMonth() : new Date().getMonth();
this.currentYear = date ? new Date(date).getFullYear() : new Date().getFullYear();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrCalendarModalComponent, deps: [{ token: i0.ElementRef }, { token: i1.DsfrI18nService }, { token: i1.LoggerService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DsfrCalendarModalComponent, isStandalone: true, selector: "dsfr-ext-calendar-modal, dsfrx-calendar-modal", inputs: { min: "min", max: "max", ariaLabel: "ariaLabel", tooltipMessage: "tooltipMessage", disabled: "disabled", value: "value" }, outputs: { dateChange: "dateChange" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }, { propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true }], ngImport: i0, template: "<dsfr-button\n type=\"button\"\n variant=\"primary\"\n size=\"MD\"\n icon=\"fr-icon-calendar-2-line\"\n [tooltipMessage]=\"tooltipMessage\"\n [disabled]=\"disabled\"\n [ariaLabel]=\"ariaLabel\"\n (click)=\"handleTriggerBtnClick()\"></dsfr-button>\n\n@if (isOpen) {\n <div\n data-expanded=\"true\"\n class=\"dsfrx-datepicker-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n clickOutside\n cdkTrapFocus\n #modal\n [id]=\"modalId\"\n [attr.aria-label]=\"'calendar.modal.ariaLabel' | dsfrI18n\"\n (keydown)=\"handleModalKeydown($event)\"\n (clickOutsideEvent)=\"onCalendarOutside()\">\n <h2 id=\"id-grid-label\" class=\"fr-sr-only\" aria-live=\"polite\" [attr.aria-label]=\"dialogTitle\"></h2>\n <dsfr-ext-calendar\n [value]=\"value\"\n [max]=\"max\"\n [min]=\"min\"\n [autofocus]=\"true\"\n ariaLabelledBy=\"id-grid-label\"\n (dateChange)=\"handleDataChange($event)\"\n #calendar></dsfr-ext-calendar>\n <div class=\"dialog-ok-cancel-group\">\n <button\n type=\"button\"\n class=\"dialog-button fr-btn fr-btn--secondary fr-btn--sm\"\n value=\"cancel\"\n data-testid=\"datepicker-cancel-btn\"\n (click)=\"handleCancelButton()\">\n {{ 'calendar.cancel' | dsfrI18n }}\n </button>\n </div>\n </div>\n}\n", styles: [".dsfrx-datepicker-dialog{position:absolute;z-index:2;width:320px;clear:both;border:1px solid rgba(0,0,0,.1);margin-top:.15em;border-radius:5px;padding:0;background-color:var(--background-default-grey);filter:drop-shadow(0 2px 6px rgba(0,0,18,.16))}\n"], dependencies: [{ kind: "component", type: DsfrCalendarComponent, selector: "dsfr-ext-calendar, dsfrx-calendar", inputs: ["value", "autofocus", "ariaLabelledBy", "min", "max"], outputs: ["dateChange", "calendarChange"] }, { kind: "directive", type: EduClickOutsideDirective, selector: "[clickOutside]", outputs: ["clickOutsideEvent"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i2.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: DsfrButtonModule }, { kind: "component", type: i1.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: DsfrCalendarModalComponent, decorators: [{
type: Component,
args: [{ selector: 'dsfr-ext-calendar-modal, dsfrx-calendar-modal', encapsulation: ViewEncapsulation.None, standalone: true, imports: [DsfrCalendarComponent, EduClickOutsideDirective, A11yModule, DsfrButtonModule, DsfrI18nPipe], template: "<dsfr-button\n type=\"button\"\n variant=\"primary\"\n size=\"MD\"\n icon=\"fr-icon-calendar-2-line\"\n [tooltipMessage]=\"tooltipMessage\"\n [disabled]=\"disabled\"\n [ariaLabel]=\"ariaLabel\"\n (click)=\"handleTriggerBtnClick()\"></dsfr-button>\n\n@if (isOpen) {\n <div\n data-expanded=\"true\"\n class=\"dsfrx-datepicker-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n clickOutside\n cdkTrapFocus\n #modal\n [id]=\"modalId\"\n [attr.aria-label]=\"'calendar.modal.ariaLabel' | dsfrI18n\"\n (keydown)=\"handleModalKeydown($event)\"\n (clickOutsideEvent)=\"onCalendarOutside()\">\n <h2 id=\"id-grid-label\" class=\"fr-sr-only\" aria-live=\"polite\" [attr.aria-label]=\"dialogTitle\"></h2>\n <dsfr-ext-calendar\n [value]=\"value\"\n [max]=\"max\"\n [min]=\"min\"\n [autofocus]=\"true\"\n ariaLabelledBy=\"id-grid-label\"\n (dateChange)=\"handleDataChange($event)\"\n #calendar></dsfr-ext-calendar>\n <div class=\"dialog-ok-cancel-group\">\n <button\n type=\"button\"\n class=\"dialog-button fr-btn fr-btn--secondary fr-btn--sm\"\n value=\"cancel\"\n data-testid=\"datepicker-cancel-btn\"\n (click)=\"handleCancelButton()\">\n {{ 'calendar.cancel' | dsfrI18n }}\n </button>\n </div>\n </div>\n}\n", styles: [".dsfrx-datepicker-dialog{position:absolute;z-index:2;width:320px;clear:both;border:1px solid rgba(0,0,0,.1);margin-top:.15em;border-radius:5px;padding:0;background-color:var(--background-default-grey);filter:drop-shadow(0 2px 6px rgba(0,0,18,.16))}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.DsfrI18nService }, { type: i1.LoggerService }], propDecorators: { min: [{
type: Input
}], max: [{
type: Input
}], ariaLabel: [{
type: Input,
args: [{ required: true }]
}], tooltipMessage: [{
type: Input,
args: [{ required: true }]
}], disabled: [{
type: Input
}], dateChange: [{
type: Output
}], modal: [{
type: ViewChild,
args: ['modal']
}], calendar: [{
type: ViewChild,
args: ['calendar']
}], value: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItbW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItZXh0L3NyYy9saWIvY2FsZW5kYXIvY2FsZW5kYXItbW9kYWwvY2FsZW5kYXItbW9kYWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItZXh0L3NyYy9saWIvY2FsZW5kYXIvY2FsZW5kYXItbW9kYWwvY2FsZW5kYXItbW9kYWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRS9DLE9BQU8sRUFFTCxTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLFlBQVksRUFFWixRQUFRLEVBRVIsV0FBVyxHQUNaLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFeEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQy9ELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7Ozs7QUFVbEQsTUFBTSxPQUFPLDBCQUEwQjtJQW1EckMsWUFDVSxVQUFzQixFQUN0QixJQUFxQixFQUNyQixNQUFxQjtRQUZyQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLFNBQUksR0FBSixJQUFJLENBQWlCO1FB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bXBvcnQgeyBBMTF5TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2ExMXknO1xuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIERzZnJCdXR0b25Nb2R1bGUsXG4gIERzZnJJMThuUGlwZSxcbiAgRHNmckkxOG5TZXJ2aWNlLFxuICBMYW5ndWFnZSxcbiAgTG9nZ2VyU2VydmljZSxcbiAgbmV3VW5pcXVlSWQsXG59IGZyb20gJ0BlZHVnb3V2ZnIvbmd4LWRzZnInO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBFZHVDbGlja091dHNpZGVEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgRHNmckRhdGVFdmVudCB9IGZyb20gJy4uLy4uL3NoYXJlZC9tb2RlbHMvZGF0ZS1ldmVudCc7XG5pbXBvcnQgeyBEYXRlVXRpbHMgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMvZGF0ZS9kYXRlLXV0aWxzJztcbmltcG9ydCB7IERzZnJDYWxlbmRhckNvbXBvbmVudCB9IGZyb20gJy4uL2NhbGVuZGFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNRVNTQUdFU19FTiB9IGZyb20gJy4uL2kxOG4vbWVzc2FnZXMuZW4nO1xuaW1wb3J0IHsgTUVTU0FHRVNfRlIgfSBmcm9tICcuLi9pMThuL21lc3NhZ2VzLmZyJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZHNmci1leHQtY2FsZW5kYXItbW9kYWwsIGRzZnJ4LWNhbGVuZGFyLW1vZGFsJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLW1vZGFsLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2FsZW5kYXItbW9kYWwuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0RzZnJDYWxlbmRhckNvbXBvbmVudCwgRWR1Q2xpY2tPdXRzaWRlRGlyZWN0aXZlLCBBMTF5TW9kdWxlLCBEc2ZyQnV0dG9uTW9kdWxlLCBEc2ZySTE4blBpcGVdLFxufSlcbmV4cG9ydCBjbGFzcyBEc2ZyQ2FsZW5kYXJNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBEYXRlIG1pbmltYWxlIGluY2x1ZS4gRG9pdCDDqnRyZSBhdSBmb3JtYXQgSVMwLTg2MDEgOiBBQUFBLU1NLUpKLlxuICAgKiBDZSBwYXJhbcOodHJlIHBldXQgw6p0cmUgdXRpbGlzw6kgc2V1bCBvdSBhdmVjIGxhIHByb3ByacOpdMOpIG1heC5cbiAgICovXG4gIEBJbnB1dCgpIG1pbiA9ICcnO1xuXG4gIC8qKlxuICAgKiBEYXRlIG1heGltYWxlIGluY2x1ZS4gRG9pdCDDqnRyZSBhdSBmb3JtYXQgSVMwLTg2MDEgOiBBQUFBLU1NLUpKLlxuICAgKiBDZSBwYXJhbcOodHJlIHBldXQgw6p0cmUgdXRpbGlzw6kgc2V1bCBvdSBhdmVjIGxhIHByb3ByacOpdMOpIG1pbi5cbiAgICovXG4gIEBJbnB1dCgpIG1heCA9ICcnO1xuXG4gIC8qKlxuICAgKiBWYWxldXIgZGUgbCdhdHRyaWJ1dCBhcmlhLWxhYmVsIGR1IGJvdXRvbiBkJ291dmVydHVyZSBkZSBsYSBtb2RhbGUuXG4gICAqL1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBhcmlhTGFiZWwgPSAnJztcblxuICAvKipcbiAgICogTWVzc2FnZSBkdSBgdG9vbHRpcGAgKGF0dHJpYnV0IGB0aXRsZWAgZHUgYm91dG9uKSBvdSBham91dCBkJ3VuIGBzcGFuYCBlbiBgc3Itb25seWAgc2kgcGFzIGRlIGxhYmVsLlxuICAgKi9cbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgdG9vbHRpcE1lc3NhZ2UgPSAnJztcblxuICAvKipcbiAgICogVmFsZXVyIGRlIGwnYXR0cmlidXQgZGlzYWJsZWQgZHUgYm91dG9uIGQnb3V2ZXJ0dXJlIGRlIGxhIG1vZGFsZS5cbiAgICovXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEVtaXNzaW9uIGRlIGxhIGRhdGUgYXUgZm9ybWF0IERzZnJEYXRlRXZlbnRcbiAgICovXG4gIEBPdXRwdXQoKSBkYXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEc2ZyRGF0ZUV2ZW50PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ21vZGFsJykgcHJvdGVjdGVkIG1vZGFsOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgnY2FsZW5kYXInKSBwcm90ZWN0ZWQgY2FsZW5kYXI6IERzZnJDYWxlbmRhckNvbXBvbmVudDtcblxuICAvKipcbiAgICogSWQgYWzDqWF0b2lyZSwgdW5pcXVlLCBkZSBsYSBtb2RhbGUgKGxlIGNhbGVuZHJpZXIpXG4gICAqL1xuICBwcm90ZWN0ZWQgbW9kYWxJZCA9IG5ld1VuaXF1ZUlkKCk7XG4gIHByb3RlY3RlZCBpc09wZW4gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGRpYWxvZ1RpdGxlID0gJyc7XG4gIHByb3RlY3RlZCB0cmFuc2xhdGVkTW9udGhzOiBzdHJpbmdbXSA9IFtdO1xuICBwcm90ZWN0ZWQgZGlhbG9nVHJpZ2dlckJ0bk5vZGU6IEhUTUxCdXR0b25FbGVtZW50O1xuXG4gIHByaXZhdGUgX3ZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgcHJpdmF0ZSBjdXJyZW50TW9udGhJbmRleCA9IDA7XG4gIHByaXZhdGUgY3VycmVudFllYXIgPSAwO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIGkxOG46IERzZnJJMThuU2VydmljZSxcbiAgICBwcml2YXRlIGxvZ2dlcjogTG9nZ2VyU2VydmljZSxcbiAgKSB7XG4gICAgdGhpcy5pMThuLmV4dGVuZHNMYWJlbHNCdW5kbGUoTGFuZ3VhZ2UuRU4sIE1FU1NBR0VTX0VOKTtcbiAgICB0aGlzLmkxOG4uZXh0ZW5kc0xhYmVsc0J1bmRsZShMYW5ndWFnZS5GUiwgTUVTU0FHRVNfRlIpO1xuICAgIGNvbnN0IGxhbmdDaGFuZ2UkID0gdGhpcy5pMThuLmNvbXBsZXRlTGFuZ0NoYW5nZSQuc3Vic2NyaWJlKCgpID0+IHRoaXMub25MYW5nQ2hhbmdlKCkpO1xuICAgIHRoaXMudXBkYXRlTW9udGhJbmRleEFuZFllYXIoKTtcbiAgICB0aGlzLnVwZGF0ZURpYWxvZ1RpdGxlKCk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQobGFuZ0NoYW5nZSQpO1xuICB9XG5cbiAgZ2V0IHZhbHVlKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGV1ciBpbml0aWFsIGRlIGxhIGRhdGUuXG4gICAqIExhIHZhbGV1ciBkb2l0IHByZW5kcmUgbGEgZm9ybWUgZGQvbW0veXl5eSBwb3VyIGxhIGxvY2FsZSBmciBldCBtbS9kZC95eXl5IHBvdXIgbGEgbG9jYWxlIGVuLlxuICAgKi9cbiAgQElucHV0KCkgc2V0IHZhbHVlKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAodmFsdWUgJiYgRGF0ZVV0aWxzLmlzVmFsaWREZWZhdWx0U3RyaW5nKHZhbHVlKSkge1xuICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRoaXMudXBkYXRlTW9udGhJbmRleEFuZFllYXIodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCBuYXRpdmVFbHQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLmRpYWxvZ1RyaWdnZXJCdG5Ob2RlID0gbmF0aXZlRWx0LnF1ZXJ5U2VsZWN0b3IoJy5mci1idG4nKSBhcyBIVE1MQnV0dG9uRWxlbWVudDtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKipcbiAgICogR8OocmUgbGUgY2xpYyBlbiBkZWhvcnMgZGUgbGEgbW9kYWxlXG4gICAqL1xuICBwcm90ZWN0ZWQgb25DYWxlbmRhck91dHNpZGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICB0aGlzLmNsb3NlKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlVHJpZ2dlckJ0bkNsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMuaXNPcGVuID0gdHJ1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVEYXRhQ2hhbmdlKGRhdGVFdmVudDogRHNmckRhdGVFdmVudCk6IHZvaWQge1xuICAgIGlmICghZGF0ZUV2ZW50LmRhdGUgfHwgIWRhdGVFdmVudC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWUgPSBkYXRlRXZlbnQudmFsdWU7XG4gICAgdGhpcy5kYXRlQ2hhbmdlLmVtaXQoZGF0ZUV2ZW50KTtcblxuICAgIHRoaXMuY2xvc2UoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVNb2RhbEtleWRvd24oa2V5RXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoa2V5RXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAga2V5RXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBrZXlFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVDYW5jZWxCdXR0b24oKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldCDDoCBqb3VyIGxlIHRpdHJlIGRlIGxhIGRpYWxvZyAodmlzdWVsbGVtZW50IGNhY2jDqSkgcG91ciBsZXMgYmVzb2lucyBkJ2FjY2Vzc2liaWxpdMOpLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVEaWFsb2dUaXRsZSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpYWxvZ1RpdGxlID0gYCR7dGhpcy5pMThuLnQoJ2NhbGVuZGFyLm1vZGFsLnRpdGxlJyl9JHt0aGlzLnRyYW5zbGF0ZWRNb250aHNbdGhpcy5jdXJyZW50TW9udGhJbmRleF19ICR7dGhpcy5jdXJyZW50WWVhcn1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEZlcm1lIGxhIG1vZGFsZS5cbiAgICpcbiAgICogUG9zaXRpb25uZSBsZSBmb2N1cyBzdXIgbGUgYm91dG9uIGQnb3V2ZXJ0dXJlIGRlIGxhIG1vZGFsZSBzaSBiZXNvaW4uXG4gICAqXG4gICAqIEBwYXJhbSBmb2N1c1RyaWdnZXJCdG4gUGVybWV0IGRlIHNhdm9pciBzaSBsZSBmb2N1cyBkb2l0IMOqdHJlIGRvbm7DqSBhdSBib3V0b24gZCdvdXZlcnR1cmUgZGUgbGEgbW9kYWxlXG4gICAqL1xuICBwcml2YXRlIGNsb3NlKGZvY3VzVHJpZ2dlckJ0biA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubW9kYWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBQb3VyIMOqdHJlIHJhY2NvcmQgYXZlYyBsYSBkaXJlY3RpdmUgY2xpY2stb3V0c2lkZSA6IG9uIGVubMOodmUgJ2RhdGEtZXhwYW5kZWQnXG4gICAgdGhpcy5tb2RhbC5uYXRpdmVFbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1leHBhbmRlZCcpO1xuXG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcblxuICAgIGlmIChmb2N1c1RyaWdnZXJCdG4pIHtcbiAgICAgIHRoaXMuZGlhbG9nVHJpZ2dlckJ0bk5vZGUuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZU1vbnRoVHJhbnNsYXRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMudHJhbnNsYXRlZE1vbnRocyA9IERhdGVVdGlscy5hcnIodGhpcy5pMThuLCB0aGlzLmxvZ2dlciwgJ2NhbGVuZGFyLm1vbnRocycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlc3Rpb24gZHUgY2hhbmdlbWVudCBkZSBsYW5ndWUgZGFucyBsZSBjb21wb3NhbnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb2RlIENvZGUgZGUgbGEgbG9jYWxlIMOgIHByZW5kcmUgZW4gY29tcHRlXG4gICAqL1xuICBwcml2YXRlIG9uTGFuZ0NoYW5nZSgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZU1vbnRoVHJhbnNsYXRpb25zKCk7XG4gICAgdGhpcy51cGRhdGVEaWFsb2dUaXRsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1pc2Ugw6Agam91ciBkZXMgdmFsZXVycyBkZXMgZGV1eCBsaXN0ZXMgZMOpcm91bGFudGVzLCBtb2lzIGV0IGFubsOpZS5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlTW9udGhJbmRleEFuZFllYXIoZGF0ZT86IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudE1vbnRoSW5kZXggPSBkYXRlID8gbmV3IERhdGUoZGF0ZSkuZ2V0TW9udGgoKSA6IG5ldyBEYXRlKCkuZ2V0TW9udGgoKTtcbiAgICB0aGlzLmN1cnJlbnRZZWFyID0gZGF0ZSA/IG5ldyBEYXRlKGRhdGUpLmdldEZ1bGxZZWFyKCkgOiBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCk7XG4gIH1cbn1cbiIsIjxkc2ZyLWJ1dHRvblxuICB0eXBlPVwiYnV0dG9uXCJcbiAgdmFyaWFudD1cInByaW1hcnlcIlxuICBzaXplPVwiTURcIlxuICBpY29uPVwiZnItaWNvbi1jYWxlbmRhci0yLWxpbmVcIlxuICBbdG9vbHRpcE1lc3NhZ2VdPVwidG9vbHRpcE1lc3NhZ2VcIlxuICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICBbYXJpYUxhYmVsXT1cImFyaWFMYWJlbFwiXG4gIChjbGljayk9XCJoYW5kbGVUcmlnZ2VyQnRuQ2xpY2soKVwiPjwvZHNmci1idXR0b24+XG5cbkBpZiAoaXNPcGVuKSB7XG4gIDxkaXZcbiAgICBkYXRhLWV4cGFuZGVkPVwidHJ1ZVwiXG4gICAgY2xhc3M9XCJkc2ZyeC1kYXRlcGlja2VyLWRpYWxvZ1wiXG4gICAgcm9sZT1cImRpYWxvZ1wiXG4gICAgYXJpYS1tb2RhbD1cInRydWVcIlxuICAgIGNsaWNrT3V0c2lkZVxuICAgIGNka1RyYXBGb2N1c1xuICAgICNtb2RhbFxuICAgIFtpZF09XCJtb2RhbElkXCJcbiAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidjYWxlbmRhci5tb2RhbC5hcmlhTGFiZWwnIHwgZHNmckkxOG5cIlxuICAgIChrZXlkb3duKT1cImhhbmRsZU1vZGFsS2V5ZG93bigkZXZlbnQpXCJcbiAgICAoY2xpY2tPdXRzaWRlRXZlbnQpPVwib25DYWxlbmRhck91dHNpZGUoKVwiPlxuICAgIDxoMiBpZD1cImlkLWdyaWQtbGFiZWxcIiBjbGFzcz1cImZyLXNyLW9ubHlcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImRpYWxvZ1RpdGxlXCI+PC9oMj5cbiAgICA8ZHNmci1leHQtY2FsZW5kYXJcbiAgICAgIFt2YWx1ZV09XCJ2YWx1ZVwiXG4gICAgICBbbWF4XT1cIm1heFwiXG4gICAgICBbbWluXT1cIm1pblwiXG4gICAgICBbYXV0b2ZvY3VzXT1cInRydWVcIlxuICAgICAgYXJpYUxhYmVsbGVkQnk9XCJpZC1ncmlkLWxhYmVsXCJcbiAgICAgIChkYXRlQ2hhbmdlKT1cImhhbmRsZURhdGFDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAjY2FsZW5kYXI+PC9kc2ZyLWV4dC1jYWxlbmRhcj5cbiAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLW9rLWNhbmNlbC1ncm91cFwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJkaWFsb2ctYnV0dG9uIGZyLWJ0biBmci1idG4tLXNlY29uZGFyeSBmci1idG4tLXNtXCJcbiAgICAgICAgdmFsdWU9XCJjYW5jZWxcIlxuICAgICAgICBkYXRhLXRlc3RpZD1cImRhdGVwaWNrZXItY2FuY2VsLWJ0blwiXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVDYW5jZWxCdXR0b24oKVwiPlxuICAgICAgICB7eyAnY2FsZW5kYXIuY2FuY2VsJyB8IGRzZnJJMThuIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG59XG4iXX0=