@edugouvfr/ngx-dsfr-ext
Version:
NgxDsfrExt est une extension au package @edugouvfr/ngx-dsfr (portage Angular des éléments DSFR)
262 lines • 61.1 kB
JavaScript
import { CommonModule } from '@angular/common';
import { Component, ContentChild, EventEmitter, Input, Output, Renderer2, TemplateRef, ViewChild, ViewEncapsulation, inject, } from '@angular/core';
import { DsfrI18nPipe, DsfrI18nService, Language, newUniqueId } from '@edugouvfr/ngx-dsfr';
import { Point } from '../shared/models/point';
import { MESSAGES_EN } from './i18n/messages.en';
import { MESSAGES_FR } from './i18n/messages.fr';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export const DEFAULT_INTERVAL = 5000;
// https://getbootstrap.com/docs/5.3/components/carousel/
export class DsfrCarouselComponent {
constructor() {
/** Défilement automatique, faux par défaut */
this.autoplay = false;
/** Indique si le carrousel boucle ou non, vrai par défaut. */
this.circular = true;
/* Le délai entre chaque slide. */
this.interval = DEFAULT_INTERVAL;
/** Indique si le carrousel doit réagir aux événements du clavier, vrai par défaut. */
this.keyboard = true;
/** Tableau de slides. */
this.slides = [];
/** Indique si le carrousel doit prendre en charge les interactions par balayage gauche/droite sur les appareils à écran tactile, vrai par défaut. */
this.touch = true;
/** Avec les contrôles de chaque côté des slides. */
this.withControls = true;
/** Avec des indicateurs d'avancement. */
this.withIndicators = true;
/** Avec des indicateurs d'avancement. */
this.inverse = true;
/** Afficher les indicateur et contrôles à l'intérieur de l'image */
this.withControlsInside = false;
/** Dans le cas de controlsInside à l'interieur, place les indicateur sur un fond noir en couleurs inversées */
this.reverseColorsIndicators = false;
/** Avec des labels. */
this.withCaptions = false;
/** Au changement de slide, emission de l'index du slide actif */
this.carouselChange = new EventEmitter();
/** @internal Le carousel est en pause et ne restart que si l'utilisateur clique explicitement sur play */
this.onPause = false;
/** @internal */
this.transition = true;
this.i18n = inject(DsfrI18nService);
/** Slide courant. */
this._current = 0;
this.renderer = inject(Renderer2);
this.i18n.extendsLabelsBundle(Language.EN, MESSAGES_EN);
this.i18n.extendsLabelsBundle(Language.FR, MESSAGES_FR);
}
/**
* @internal
* Duplique le premier et dernier slide pour l'effet de transition circulaire
*/
get visibleSlides() {
return [
this.slides[this.slides.length - 1], // Ajoute le dernier slide au début
...this.slides,
this.slides[0], // Ajoute le premier slide à la fin
];
}
get current() {
return this._current;
}
set current(value) {
if (value !== this._current) {
this._current = value;
this.carouselChange.emit(value);
}
if (this.disableTransition && this.circular) {
this.handleFirstLastTransition();
}
}
ngOnInit() {
this.carouselId ??= newUniqueId();
if (this.circular) {
// Gestion de l'effet de transition pour le premier et le dernier slide en version circulaire
this.transitionListener = this.renderer.listen(this.slidesContainer.nativeElement, 'transitionend', () => {
this.handleFirstLastTransition();
});
}
// Afficher le premier slide au chargement
this.renderer.setStyle(this.slidesContainer.nativeElement, 'transform', this.getTransform());
}
ngOnDestroy() {
// Nettoyer le listener à la destruction du composant
if (this.transitionListener) {
this.transitionListener();
}
}
ngAfterViewInit() {
if (this.autoplay)
this.startSlideshow();
}
/**
* Spécifique mobile
* @internal */
onTouchStart(event) {
this.startPoint = Point.fromEvent(event);
}
/**
* Spécifique mobile
* @internal */
onTouchEnd(event) {
if (this.touch) {
const endPoint = Point.fromEvent(event);
if (endPoint.x < this.startPoint.x - 32)
this.next();
else if (endPoint.x > this.startPoint.x + 32)
this.previous();
}
}
/** @internal */
onKeydown(event) {
// stop du défilement automatique pendant l'interaction utilisateur
if (this.autoplay)
this.stopSlideshow();
this.onPause = true;
if (!this.keyboard)
return;
event.stopPropagation();
switch (event.code) {
case 'ArrowLeft':
this.previous();
break;
case 'ArrowRight':
this.next();
break;
case 'Space':
this.toggleSlideshow();
break;
default:
}
}
/**
* Transition vers le slide précédent
* @internal */
previous(origin = 'user') {
if (this.current > 0 || this.circular) {
this.current--;
this.transition = true;
this.renderer.setStyle(this.slidesContainer.nativeElement, 'transform', this.getTransform());
}
if (origin === 'user' && this.autoplay)
this.startSlideshow();
}
/**
* Transition vers le slide suivant
* @internal */
next(origin = 'user') {
if (this.current < this.slides.length || this.circular) {
this.transition = true;
this.current++;
this.renderer.setStyle(this.slidesContainer.nativeElement, 'transform', this.getTransform());
}
if (origin === 'user' && this.autoplay)
this.startSlideshow();
if (!this.circular && (this.current === 0 || this.current === this.slides?.length - 1))
this.stopSlideshow();
}
/** @internal */
togglePlayPause() {
this.onPause = !this.onPause;
if (!this.onPause) {
this.startSlideshow();
}
else {
this.stopSlideshow();
}
}
/**
* @internal
* Lance le carousel si en autoplay et non explicitement sur pause
*/
startSlideshow() {
if (this.autoplay && !this.onPause) {
this.stopSlideshow();
this.timeoutId = setInterval(() => this.next('timer'), this.interval);
}
}
/**
* @internal
* Stoppe le carousel
*/
stopSlideshow() {
if (this.timeoutId && this.autoplay) {
clearTimeout(this.timeoutId);
this.timeoutId = undefined;
}
}
/** Effet de transition des slides */
getTransform() {
return `translate3d(${-((this.current + 1) * 100)}%, 0, 0)`;
}
toggleSlideshow() {
if (this.timeoutId)
this.stopSlideshow();
else
this.startSlideshow();
}
/**
* Gestion de l'affichage avant le premier et apres le dernier slide en mode circulaire
*/
handleFirstLastTransition() {
if (this.current >= this.slides.length) {
this.current = 0;
this.transition = false;
this.renderer.setStyle(this.slidesContainer.nativeElement, 'transform', this.getTransform());
}
else if (this.current < 0) {
this.current = this.slides.length - 1;
this.transition = false;
this.renderer.setStyle(this.slidesContainer.nativeElement, 'transform', this.getTransform());
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrCarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DsfrCarouselComponent, isStandalone: true, selector: "dsfrx-carousel, dsfr-ext-carousel", inputs: { carouselId: "carouselId", ariaLabel: "ariaLabel", autoplay: "autoplay", circular: "circular", interval: "interval", keyboard: "keyboard", slides: "slides", maxWidth: "maxWidth", touch: "touch", withControls: "withControls", withIndicators: "withIndicators", inverse: "inverse", withControlsInside: "withControlsInside", reverseColorsIndicators: "reverseColorsIndicators", withCaptions: "withCaptions", disableTransition: "disableTransition" }, outputs: { carouselChange: "carouselChange" }, queries: [{ propertyName: "templateSlide", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "slidesContainer", first: true, predicate: ["slidesContainer"], descendants: true, static: true }], ngImport: i0, template: "<section\n [id]=\"carouselId\"\n [attr.aria-label]=\"ariaLabel || null\"\n [ngStyle]=\"{ 'max-width': maxWidth ? maxWidth : '' }\"\n class=\"dsfrx-carousel\"\n [ngClass]=\"{ 'colors-reverse': reverseColorsIndicators && withControlsInside }\"\n aria-roledescription=\"carousel\"\n (keydown)=\"onKeydown($event)\"\n (mouseenter)=\"stopSlideshow()\"\n (mouseleave)=\"startSlideshow()\"\n (touchstart)=\"onTouchStart($event)\"\n (touchend)=\"onTouchEnd($event)\">\n <!-- Slides --------------------------------------------------------------------------------------------------------->\n <div\n #slidesContainer\n id=\"carousel-inner-{{ carouselId }}\"\n class=\"carousel-inner\"\n [attr.aria-live]=\"autoplay ? 'off' : 'polite'\"\n [style.transition]=\"transition && !disableTransition ? 'transform 0.5s ease-in-out' : 'none'\">\n @for (slide of visibleSlides; track slide; let i = $index) {\n <div\n class=\"carousel-item\"\n role=\"group\"\n aria-roledescription=\"slide\"\n [attr.aria-hidden]=\"i === 0 || i > slides.length ? true : null\"\n [attr.aria-label]=\"i > 0 && !(i > slides.length) ? i + ' of ' + slides.length : null\"\n class=\"slide\"\n [attr.aria-labelledBy]=\"withCaptions ? carouselId + '-' + i + '-caption' : undefined\"\n [class.active]=\"current + 1 === i\">\n <!-- En l'absence de template, affichage des images et titres -->\n @if (!templateSlide) {\n <img [src]=\"slide.imagePath\" [alt]=\"slide.alt || null\" />\n <!-- Captions ------------------------------------------------------------------------------------------------------->\n @if (withCaptions) {\n <div [id]=\"carouselId + '-' + i + '-caption'\" class=\"description\">\n @if (slide.caption) {\n <div class=\"caption\">{{ slide.caption }}</div>\n }\n @if (slide.content) {\n <div class=\"content\">{{ slide.content }}</div>\n }\n </div>\n }\n }\n <!-- Template -->\n <ng-template\n [ngTemplateOutlet]=\"templateSlide\"\n [ngTemplateOutletContext]=\"{ $implicit: slide, index: i }\"></ng-template>\n </div>\n }\n </div>\n\n @if (withControlsInside) {\n <!-- Contr\u00F4les ----->\n @if (withControls) {\n <div class=\"inside-controls\">\n <button\n type=\"button\"\n class=\"fr-pagination__link--prev control control--prev\"\n (click)=\"previous()\"\n [disabled]=\"circular ? undefined : current === 0\"\n [attr.aria-label]=\"'carousel.previousSlide' | dsfrI18n\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\">\n <span class=\"control-prev-icon\" aria-hidden=\"true\"></span>\n </button>\n <button\n type=\"button\"\n class=\"fr-pagination__link--next control control--next\"\n (click)=\"next()\"\n [disabled]=\"circular ? undefined : current === slides.length - 1\"\n [attr.aria-label]=\"'carousel.nextSlide' | dsfrI18n\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\">\n <span class=\"control-next-icon\" aria-hidden=\"true\"></span>\n </button>\n </div>\n }\n <!-- Indicateurs ----->\n @if (withIndicators) {\n <div class=\"indicators inside-controls\">\n <ng-container *ngTemplateOutlet=\"playPauseControl\"></ng-container>\n @for (slide of slides; track slide; let i = $index) {\n <div class=\"button\" [class.active]=\"current === i\"></div>\n }\n </div>\n }\n } @else {\n <!-- Controles bottom ------------------------------------------------------------------------------------------------>\n <div class=\"controls\">\n <ng-container *ngTemplateOutlet=\"playPauseControl\"></ng-container>\n <button\n (click)=\"previous()\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\"\n [attr.aria-label]=\"'carousel.previousSlide' | dsfrI18n\"\n [disabled]=\"circular ? undefined : current === 0\"\n class=\"fr-pagination__link fr-pagination__link--prev fr-pagination__link--lg-label\">\n <span class=\"label-sm\">{{ 'carousel.previous' | dsfrI18n }}</span>\n </button>\n <div class=\"indicators fr-pagination__link\">\n @for (slide of slides; track slide; let i = $index) {\n <div class=\"button\" [class.active]=\"current === i\"></div>\n }\n </div>\n <button\n [disabled]=\"circular ? undefined : current === slides.length - 1\"\n (click)=\"next()\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\"\n [attr.aria-label]=\"'carousel.nextSlide' | dsfrI18n\"\n class=\"fr-pagination__link fr-pagination__link--next fr-pagination__link--lg-label\">\n <span class=\"label-sm\">{{ 'carousel.next' | dsfrI18n }}</span>\n </button>\n </div>\n }\n</section>\n\n<!-- Controles play/pause ------------------------------------------------------------------------------------------------->\n<ng-template #playPauseControl>\n @if (autoplay) {\n <button\n type=\"button\"\n (click)=\"togglePlayPause()\"\n [class.fr-icon-pause]=\"!onPause\"\n [class.fr-icon-play]=\"onPause\"\n class=\"fr-btn fr-btn--sm rotation fr-btn--tertiary\"\n [attr.aria-label]=\"onPause ? ('carousel.play' | dsfrI18n) : ('carousel.pause' | dsfrI18n)\"></button>\n }\n</ng-template>\n", styles: [".dsfrx-carousel{position:relative;width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between}.dsfrx-carousel .carousel-inner{width:100%;display:flex}.dsfrx-carousel .slide{position:relative;min-width:100%;text-align:center;box-sizing:border-box}.dsfrx-carousel .slide.active{display:block}.dsfrx-carousel .slide img{max-width:100%}.dsfrx-carousel button.control{position:absolute;top:35%;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:10%;padding:0;text-align:center;background:0 0}.dsfrx-carousel button.control:hover{background-color:var(--hover-tint);border-radius:50%}.dsfrx-carousel button.control.control--prev{left:.25rem}.dsfrx-carousel button.control.control--prev:before{--icon-size: 2rem;margin:0;padding:0}.dsfrx-carousel button.control.control--next{right:.25rem}.dsfrx-carousel button.control.control--next:before{--icon-size: 2rem;margin:0;padding:0}.dsfrx-carousel .indicators.inside-controls{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:.75rem;margin-left:15%}.dsfrx-carousel .indicators.inside-controls .rotation{margin-right:2rem}.dsfrx-carousel .indicators .button{box-sizing:content-box;width:2rem;height:.375rem;padding:0;margin-right:.25rem;background-color:var(--background-contrast-grey);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:1;transition:opacity .6s ease}.dsfrx-carousel .indicators .button.active{background-color:var(--background-active-blue-france)}.dsfrx-carousel .controls{display:flex;align-items:center;justify-content:center;margin-top:.25rem;margin-bottom:.25rem}.dsfrx-carousel .controls .indicators{display:flex}.dsfrx-carousel .controls .fr-pagination__link{margin-bottom:0}.dsfrx-carousel .description{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;text-align:center}.dsfrx-carousel .description .caption{font-size:larger;font-weight:700;margin-bottom:.25rem}.dsfrx-carousel .description .caption,.dsfrx-carousel .description .content{background-color:#000000a6;padding:.25rem 1rem;color:#fff;width:fit-content;margin:0 auto}.dsfrx-carousel .description .content{margin-top:.5rem}.dsfrx-carousel.colors-reverse .inside-controls button.control{background-color:#000000a6;border-radius:50%}.dsfrx-carousel.colors-reverse .inside-controls button.control:hover{background-color:#000}.dsfrx-carousel.colors-reverse .inside-controls button.control:before{color:#fff}.dsfrx-carousel.colors-reverse .indicators.inside-controls{padding:.25rem;box-sizing:border-box;background-color:#000000a6;align-items:center}.dsfrx-carousel.colors-reverse .indicators.inside-controls .fr-btn,.dsfrx-carousel.colors-reverse .indicators.inside-controls .button.active{background-color:var(--blue-france-main-525)}.dsfrx-carousel.colors-reverse .indicators .player svg polygon{fill:#fff;stroke:#fff}.dsfrx-carousel.colors-reverse .indicators .player svg .pause{stroke-width:4;fill:transparent;stroke:transparent}.dsfrx-carousel.colors-reverse .indicators .player svg .play{stroke-width:1;fill:transparent;stroke:transparent}.dsfrx-carousel.colors-reverse .indicators .player .pause svg .pause{fill:#fff;stroke:#fff}.dsfrx-carousel.colors-reverse .indicators .player .play svg .play{fill:#fff;stroke:#fff}.dsfrx-carousel.colors-reverse .indicators .player .rotation:hover{background-color:transparent}.dsfrx-carousel.colors-reverse .indicators .player .rotation:hover svg{background-color:#000}.fr-icon-play:before,.fr-icon-play:after{-webkit-mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16.3944 12.0001L10 7.7371V16.263L16.3944 12.0001ZM19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z\"></path></svg>');mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16.3944 12.0001L10 7.7371V16.263L16.3944 12.0001ZM19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z\"></path></svg>')}.fr-icon-pause:before,.fr-icon-pause:after{-webkit-mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5H8V19H6V5ZM16 5H18V19H16V5Z\"></path></svg>');mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5H8V19H6V5ZM16 5H18V19H16V5Z\"></path></svg>')}@media (forced-colors: active){button.fr-pagination__link{border:1px solid buttontext}button.fr-pagination__link:before,button.fr-pagination__link:after{background-color:buttontext}.dsfrx-carousel .indicators .button{forced-color-adjust:none;background-color:graytext}.dsfrx-carousel .indicators .button.active{background-color:highlight}}\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: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: DsfrI18nPipe, name: "dsfrI18n" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrCarouselComponent, decorators: [{
type: Component,
args: [{ selector: 'dsfrx-carousel, dsfr-ext-carousel', standalone: true, imports: [CommonModule, DsfrI18nPipe], encapsulation: ViewEncapsulation.None, template: "<section\n [id]=\"carouselId\"\n [attr.aria-label]=\"ariaLabel || null\"\n [ngStyle]=\"{ 'max-width': maxWidth ? maxWidth : '' }\"\n class=\"dsfrx-carousel\"\n [ngClass]=\"{ 'colors-reverse': reverseColorsIndicators && withControlsInside }\"\n aria-roledescription=\"carousel\"\n (keydown)=\"onKeydown($event)\"\n (mouseenter)=\"stopSlideshow()\"\n (mouseleave)=\"startSlideshow()\"\n (touchstart)=\"onTouchStart($event)\"\n (touchend)=\"onTouchEnd($event)\">\n <!-- Slides --------------------------------------------------------------------------------------------------------->\n <div\n #slidesContainer\n id=\"carousel-inner-{{ carouselId }}\"\n class=\"carousel-inner\"\n [attr.aria-live]=\"autoplay ? 'off' : 'polite'\"\n [style.transition]=\"transition && !disableTransition ? 'transform 0.5s ease-in-out' : 'none'\">\n @for (slide of visibleSlides; track slide; let i = $index) {\n <div\n class=\"carousel-item\"\n role=\"group\"\n aria-roledescription=\"slide\"\n [attr.aria-hidden]=\"i === 0 || i > slides.length ? true : null\"\n [attr.aria-label]=\"i > 0 && !(i > slides.length) ? i + ' of ' + slides.length : null\"\n class=\"slide\"\n [attr.aria-labelledBy]=\"withCaptions ? carouselId + '-' + i + '-caption' : undefined\"\n [class.active]=\"current + 1 === i\">\n <!-- En l'absence de template, affichage des images et titres -->\n @if (!templateSlide) {\n <img [src]=\"slide.imagePath\" [alt]=\"slide.alt || null\" />\n <!-- Captions ------------------------------------------------------------------------------------------------------->\n @if (withCaptions) {\n <div [id]=\"carouselId + '-' + i + '-caption'\" class=\"description\">\n @if (slide.caption) {\n <div class=\"caption\">{{ slide.caption }}</div>\n }\n @if (slide.content) {\n <div class=\"content\">{{ slide.content }}</div>\n }\n </div>\n }\n }\n <!-- Template -->\n <ng-template\n [ngTemplateOutlet]=\"templateSlide\"\n [ngTemplateOutletContext]=\"{ $implicit: slide, index: i }\"></ng-template>\n </div>\n }\n </div>\n\n @if (withControlsInside) {\n <!-- Contr\u00F4les ----->\n @if (withControls) {\n <div class=\"inside-controls\">\n <button\n type=\"button\"\n class=\"fr-pagination__link--prev control control--prev\"\n (click)=\"previous()\"\n [disabled]=\"circular ? undefined : current === 0\"\n [attr.aria-label]=\"'carousel.previousSlide' | dsfrI18n\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\">\n <span class=\"control-prev-icon\" aria-hidden=\"true\"></span>\n </button>\n <button\n type=\"button\"\n class=\"fr-pagination__link--next control control--next\"\n (click)=\"next()\"\n [disabled]=\"circular ? undefined : current === slides.length - 1\"\n [attr.aria-label]=\"'carousel.nextSlide' | dsfrI18n\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\">\n <span class=\"control-next-icon\" aria-hidden=\"true\"></span>\n </button>\n </div>\n }\n <!-- Indicateurs ----->\n @if (withIndicators) {\n <div class=\"indicators inside-controls\">\n <ng-container *ngTemplateOutlet=\"playPauseControl\"></ng-container>\n @for (slide of slides; track slide; let i = $index) {\n <div class=\"button\" [class.active]=\"current === i\"></div>\n }\n </div>\n }\n } @else {\n <!-- Controles bottom ------------------------------------------------------------------------------------------------>\n <div class=\"controls\">\n <ng-container *ngTemplateOutlet=\"playPauseControl\"></ng-container>\n <button\n (click)=\"previous()\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\"\n [attr.aria-label]=\"'carousel.previousSlide' | dsfrI18n\"\n [disabled]=\"circular ? undefined : current === 0\"\n class=\"fr-pagination__link fr-pagination__link--prev fr-pagination__link--lg-label\">\n <span class=\"label-sm\">{{ 'carousel.previous' | dsfrI18n }}</span>\n </button>\n <div class=\"indicators fr-pagination__link\">\n @for (slide of slides; track slide; let i = $index) {\n <div class=\"button\" [class.active]=\"current === i\"></div>\n }\n </div>\n <button\n [disabled]=\"circular ? undefined : current === slides.length - 1\"\n (click)=\"next()\"\n [attr.aria-controls]=\"'carousel-inner-' + carouselId\"\n [attr.aria-label]=\"'carousel.nextSlide' | dsfrI18n\"\n class=\"fr-pagination__link fr-pagination__link--next fr-pagination__link--lg-label\">\n <span class=\"label-sm\">{{ 'carousel.next' | dsfrI18n }}</span>\n </button>\n </div>\n }\n</section>\n\n<!-- Controles play/pause ------------------------------------------------------------------------------------------------->\n<ng-template #playPauseControl>\n @if (autoplay) {\n <button\n type=\"button\"\n (click)=\"togglePlayPause()\"\n [class.fr-icon-pause]=\"!onPause\"\n [class.fr-icon-play]=\"onPause\"\n class=\"fr-btn fr-btn--sm rotation fr-btn--tertiary\"\n [attr.aria-label]=\"onPause ? ('carousel.play' | dsfrI18n) : ('carousel.pause' | dsfrI18n)\"></button>\n }\n</ng-template>\n", styles: [".dsfrx-carousel{position:relative;width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between}.dsfrx-carousel .carousel-inner{width:100%;display:flex}.dsfrx-carousel .slide{position:relative;min-width:100%;text-align:center;box-sizing:border-box}.dsfrx-carousel .slide.active{display:block}.dsfrx-carousel .slide img{max-width:100%}.dsfrx-carousel button.control{position:absolute;top:35%;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:10%;padding:0;text-align:center;background:0 0}.dsfrx-carousel button.control:hover{background-color:var(--hover-tint);border-radius:50%}.dsfrx-carousel button.control.control--prev{left:.25rem}.dsfrx-carousel button.control.control--prev:before{--icon-size: 2rem;margin:0;padding:0}.dsfrx-carousel button.control.control--next{right:.25rem}.dsfrx-carousel button.control.control--next:before{--icon-size: 2rem;margin:0;padding:0}.dsfrx-carousel .indicators.inside-controls{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:.75rem;margin-left:15%}.dsfrx-carousel .indicators.inside-controls .rotation{margin-right:2rem}.dsfrx-carousel .indicators .button{box-sizing:content-box;width:2rem;height:.375rem;padding:0;margin-right:.25rem;background-color:var(--background-contrast-grey);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:1;transition:opacity .6s ease}.dsfrx-carousel .indicators .button.active{background-color:var(--background-active-blue-france)}.dsfrx-carousel .controls{display:flex;align-items:center;justify-content:center;margin-top:.25rem;margin-bottom:.25rem}.dsfrx-carousel .controls .indicators{display:flex}.dsfrx-carousel .controls .fr-pagination__link{margin-bottom:0}.dsfrx-carousel .description{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;text-align:center}.dsfrx-carousel .description .caption{font-size:larger;font-weight:700;margin-bottom:.25rem}.dsfrx-carousel .description .caption,.dsfrx-carousel .description .content{background-color:#000000a6;padding:.25rem 1rem;color:#fff;width:fit-content;margin:0 auto}.dsfrx-carousel .description .content{margin-top:.5rem}.dsfrx-carousel.colors-reverse .inside-controls button.control{background-color:#000000a6;border-radius:50%}.dsfrx-carousel.colors-reverse .inside-controls button.control:hover{background-color:#000}.dsfrx-carousel.colors-reverse .inside-controls button.control:before{color:#fff}.dsfrx-carousel.colors-reverse .indicators.inside-controls{padding:.25rem;box-sizing:border-box;background-color:#000000a6;align-items:center}.dsfrx-carousel.colors-reverse .indicators.inside-controls .fr-btn,.dsfrx-carousel.colors-reverse .indicators.inside-controls .button.active{background-color:var(--blue-france-main-525)}.dsfrx-carousel.colors-reverse .indicators .player svg polygon{fill:#fff;stroke:#fff}.dsfrx-carousel.colors-reverse .indicators .player svg .pause{stroke-width:4;fill:transparent;stroke:transparent}.dsfrx-carousel.colors-reverse .indicators .player svg .play{stroke-width:1;fill:transparent;stroke:transparent}.dsfrx-carousel.colors-reverse .indicators .player .pause svg .pause{fill:#fff;stroke:#fff}.dsfrx-carousel.colors-reverse .indicators .player .play svg .play{fill:#fff;stroke:#fff}.dsfrx-carousel.colors-reverse .indicators .player .rotation:hover{background-color:transparent}.dsfrx-carousel.colors-reverse .indicators .player .rotation:hover svg{background-color:#000}.fr-icon-play:before,.fr-icon-play:after{-webkit-mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16.3944 12.0001L10 7.7371V16.263L16.3944 12.0001ZM19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z\"></path></svg>');mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16.3944 12.0001L10 7.7371V16.263L16.3944 12.0001ZM19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z\"></path></svg>')}.fr-icon-pause:before,.fr-icon-pause:after{-webkit-mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5H8V19H6V5ZM16 5H18V19H16V5Z\"></path></svg>');mask-image:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5H8V19H6V5ZM16 5H18V19H16V5Z\"></path></svg>')}@media (forced-colors: active){button.fr-pagination__link{border:1px solid buttontext}button.fr-pagination__link:before,button.fr-pagination__link:after{background-color:buttontext}.dsfrx-carousel .indicators .button{forced-color-adjust:none;background-color:graytext}.dsfrx-carousel .indicators .button.active{background-color:highlight}}\n"] }]
}], ctorParameters: () => [], propDecorators: { slidesContainer: [{
type: ViewChild,
args: ['slidesContainer', { static: true }]
}], templateSlide: [{
type: ContentChild,
args: [TemplateRef]
}], carouselId: [{
type: Input
}], ariaLabel: [{
type: Input
}], autoplay: [{
type: Input
}], circular: [{
type: Input
}], interval: [{
type: Input
}], keyboard: [{
type: Input
}], slides: [{
type: Input
}], maxWidth: [{
type: Input
}], touch: [{
type: Input
}], withControls: [{
type: Input
}], withIndicators: [{
type: Input
}], inverse: [{
type: Input
}], withControlsInside: [{
type: Input
}], reverseColorsIndicators: [{
type: Input
}], withCaptions: [{
type: Input
}], disableTransition: [{
type: Input
}], carouselChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItZXh0L3NyYy9saWIvY2Fyb3VzZWwvY2Fyb3VzZWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItZXh0L3NyYy9saWIvY2Fyb3VzZWwvY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUVaLFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixFQUNqQixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzNGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUUvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7QUFFakQsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQVcsSUFBSSxDQUFDO0FBRTdDLHlEQUF5RDtBQVN6RCxNQUFNLE9BQU8scUJBQXFCO0lBOEVoQztRQWpFQSw4Q0FBOEM7UUFDckMsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUVuQyw4REFBOEQ7UUFDckQsYUFBUSxHQUFHLElBQUksQ0FBQztRQUV6QixrQ0FBa0M7UUFDekIsYUFBUSxHQUFXLGdCQUFnQixDQUFDO1FBRTdDLHNGQUFzRjtRQUM3RSxhQUFRLEdBQUcsSUFBSSxDQUFDO1FBRXpCLHlCQUF5QjtRQUNoQixXQUFN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UztzQkFBakIsS0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR0csUUFBUTtzQkFBaEIsS0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLE1BQU07c0JBQWQsS0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLEtBQUs7c0JBQWIsS0FBSztnQkFHRyxZQUFZO3NCQUFwQixLQUFLO2dCQUdHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBR0csT0FBTztzQkFBZixLQUFLO2dCQUdHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFHRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBR0csWUFBWTtzQkFBcEIsS0FBSztnQkFHRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBR0ksY0FBYztzQkFBdkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERzZnJJMThuUGlwZSwgRHNmckkxOG5TZXJ2aWNlLCBMYW5ndWFnZSwgbmV3VW5pcXVlSWQgfSBmcm9tICdAZWR1Z291dmZyL25neC1kc2ZyJztcbmltcG9ydCB7IFBvaW50IH0gZnJvbSAnLi4vc2hhcmVkL21vZGVscy9wb2ludCc7XG5pbXBvcnQgeyBEc2ZyU2xpZGUgfSBmcm9tICcuL2Nhcm91c2VsLm1vZGVsJztcbmltcG9ydCB7IE1FU1NBR0VTX0VOIH0gZnJvbSAnLi9pMThuL21lc3NhZ2VzLmVuJztcbmltcG9ydCB7IE1FU1NBR0VTX0ZSIH0gZnJvbSAnLi9pMThuL21lc3NhZ2VzLmZyJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfSU5URVJWQUw6IG51bWJlciA9IDUwMDA7XG5cbi8vIGh0dHBzOi8vZ2V0Ym9vdHN0cmFwLmNvbS9kb2NzLzUuMy9jb21wb25lbnRzL2Nhcm91c2VsL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZHNmcngtY2Fyb3VzZWwsIGRzZnItZXh0LWNhcm91c2VsJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRHNmckkxOG5QaXBlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2Nhcm91c2VsLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2Fyb3VzZWwuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgRHNmckNhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICAvKiogQGludGVybmFsICovXG4gIEBWaWV3Q2hpbGQoJ3NsaWRlc0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pIHNsaWRlc0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAvKiogQGludGVybmFsICovXG4gIEBDb250ZW50Q2hpbGQoVGVtcGxhdGVSZWYpIHRlbXBsYXRlU2xpZGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgLyoqIElkZW50aWZpYW50IGR1IGNoYW1wLCBnw6luw6lyw6kgYXV0b21hdGlxdWVtZW50IHBhciBkw6lmYXV0LiAqL1xuICBASW5wdXQoKSBjYXJvdXNlbElkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqIEF0dHJpYnV0IGFyaWEtbGFiZWwgZHUgY29tcG9zYW50ICovXG4gIEBJbnB1dCgpIGFyaWFMYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKiBEw6lmaWxlbWVudCBhdXRvbWF0aXF1ZSwgZmF1eCBwYXIgZMOpZmF1dCAqL1xuICBASW5wdXQoKSBhdXRvcGxheTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBJbmRpcXVlIHNpIGxlIGNhcnJvdXNlbCBib3VjbGUgb3Ugbm9uLCB2cmFpIHBhciBkw6lmYXV0LiAqL1xuICBASW5wdXQoKSBjaXJjdWxhciA9IHRydWU7XG5cbiAgLyogTGUgZMOpbGFpIGVudHJlIGNoYXF1ZSBzbGlkZS4gKi9cbiAgQElucHV0KCkgaW50ZXJ2YWw6IG51bWJlciA9IERFRkFVTFRfSU5URVJWQUw7XG5cbiAgLyoqIEluZGlxdWUgc2kgbGUgY2Fycm91c2VsIGRvaXQgcsOpYWdpciBhdXggw6l2w6luZW1lbnRzIGR1IGNsYXZpZXIsIHZyYWkgcGFyIGTDqWZhdXQuICovXG4gIEBJbnB1dCgpIGtleWJvYXJkID0gdHJ1ZTtcblxuICAvKiogVGFibGVhdSBkZSBzbGlkZXMuICovXG4gIEBJbnB1dCgpIHNsaWRlczogRHNmclNsaWRlW10gPSBbXTtcblxuICAvKiogVGFpbGxlIG1heGltYWxlIGR1IGNvbnRhaW5lciBkZSBzbGlkZXMgKG9wdGlvbm5lbCkgKi9cbiAgQElucHV0KCkgbWF4V2lkdGg6IHN0cmluZztcblxuICAvKiogSW5kaXF1ZSBzaSBsZSBjYXJyb3VzZWwgZG9pdCBwcmVuZHJlIGVuIGNoYXJnZSBsZXMgaW50ZXJhY3Rpb25zIHBhciBiYWxheWFnZSBnYXVjaGUvZHJvaXRlIHN1ciBsZXMgYXBwYXJlaWxzIMOgIMOpY3JhbiB0YWN0aWxlLCB2cmFpIHBhciBkw6lmYXV0LiAqL1xuICBASW5wdXQoKSB0b3VjaCA9IHRydWU7XG5cbiAgLyoqIEF2ZWMgbGVzIGNvbnRyw7RsZXMgZGUgY2hhcXVlIGPDtHTDqSBkZXMgc2xpZGVzLiAqL1xuICBASW5wdXQoKSB3aXRoQ29udHJvbHM6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKiBBdmVjIGRlcyBpbmRpY2F0ZXVycyBkJ2F2YW5jZW1lbnQuICovXG4gIEBJbnB1dCgpIHdpdGhJbmRpY2F0b3JzOiBib29sZWFuID0gdHJ1ZTtcblxuICAvKiogQXZlYyBkZXMgaW5kaWNhdGV1cnMgZCdhdmFuY2VtZW50LiAqL1xuICBASW5wdXQoKSBpbnZlcnNlOiBib29sZWFuID0gdHJ1ZTtcblxuICAvKiogQWZmaWNoZXIgbGVzIGluZGljYXRldXIgZXQgY29udHLDtGxlcyDDoCBsJ2ludMOpcmlldXIgZGUgbCdpbWFnZSAqL1xuICBASW5wdXQoKSB3aXRoQ29udHJvbHNJbnNpZGU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogRGFucyBsZSBjYXMgZGUgY29udHJvbHNJbnNpZGUgw6AgbCdpbnRlcmlldXIsIHBsYWNlIGxlcyBpbmRpY2F0ZXVyIHN1ciB1biBmb25kIG5vaXIgZW4gY291bGV1cnMgaW52ZXJzw6llcyAqL1xuICBASW5wdXQoKSByZXZlcnNlQ29sb3JzSW5kaWNhdG9yczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBBdmVjIGRlcyBsYWJlbHMuICovXG4gIEBJbnB1dCgpIHdpdGhDYXB0aW9uczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBEw6lzYWN0aXZlciBsJ2FuaW1hdGlvbiBkZSB0cmFuc2l0aW9uICovXG4gIEBJbnB1dCgpIGRpc2FibGVUcmFuc2l0aW9uOiBib29sZWFuO1xuXG4gIC8qKiBBdSBjaGFuZ2VtZW50IGRlIHNsaWRlLCBlbWlzc2lvbiBkZSBsJ2luZGV4IGR1IHNsaWRlIGFjdGlmICovXG4gIEBPdXRwdXQoKSBjYXJvdXNlbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gIC8qKiBAaW50ZXJuYWwgTGUgY2Fyb3VzZWwgZXN0IGVuIHBhdXNlIGV0IG5lIHJlc3RhcnQgcXVlIHNpIGwndXRpbGlzYXRldXIgY2xpcXVlIGV4cGxpY2l0ZW1lbnQgc3VyIHBsYXkgKi9cbiAgcHVibGljIG9uUGF1c2U6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogQGludGVybmFsICovXG4gIHRyYW5zaXRpb24gPSB0cnVlO1xuXG4gIHByaXZhdGUgaTE4biA9IGluamVjdChEc2ZySTE4blNlcnZpY2UpO1xuXG4gIC8qKiBTbGlkZSBjb3VyYW50LiAqL1xuICBwcml2YXRlIF9jdXJyZW50ID0gMDtcblxuICAvKiogSWQgZHUgdGltZXIgKi9cbiAgcHJpdmF0ZSB0aW1lb3V0SWQ6IGFueTtcblxuICAvKiogRXbDqW5lbWVudHMgdG91Y2ggKi9cbiAgcHJpdmF0ZSBzdGFydFBvaW50OiBQb2ludDtcblxuICBwcml2YXRlIHJlbmRlcmVyID0gaW5qZWN0KFJlbmRlcmVyMik7XG4gIHByaXZhdGUgdHJhbnNpdGlvbkxpc3RlbmVyOiAoKSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaTE4bi5leHRlbmRzTGFiZWxzQnVuZGxlKExhbmd1YWdlLkVOLCBNRVNTQUdFU19FTik7XG4gICAgdGhpcy5pMThuLmV4dGVuZHNMYWJlbHNCdW5kbGUoTGFuZ3VhZ2UuRlIsIE1FU1NBR0VTX0ZSKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogRHVwbGlxdWUgbGUgcHJlbWllciBldCBkZXJuaWVyIHNsaWRlIHBvdXIgbCdlZmZldCBkZSB0cmFuc2l0aW9uIGNpcmN1bGFpcmVcbiAgICovXG4gIGdldCB2aXNpYmxlU2xpZGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLnNsaWRlc1t0aGlzLnNsaWRlcy5sZW5ndGggLSAxXSwgLy8gQWpvdXRlIGxlIGRlcm5pZXIgc2xpZGUgYXUgZMOpYnV0XG4gICAgICAuLi50aGlzLnNsaWRlcyxcbiAgICAgIHRoaXMuc2xpZGVzWzBdLCAvLyBBam91dGUgbGUgcHJlbWllciBzbGlkZSDDoCBsYSBmaW5cbiAgICBdO1xuICB9XG5cbiAgZ2V0IGN1cnJlbnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudDtcbiAgfVxuXG4gIHByaXZhdGUgc2V0IGN1cnJlbnQodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh2YWx1ZSAhPT0gdGhpcy5fY3VycmVudCkge1xuICAgICAgdGhpcy5fY3VycmVudCA9IHZhbHVlO1xuICAgICAgdGhpcy5jYXJvdXNlbENoYW5nZS5lbWl0KHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5kaXNhYmxlVHJhbnNpdGlvbiAmJiB0aGlzLmNpcmN1bGFyKSB7XG4gICAgICB0aGlzLmhhbmRsZUZpcnN0TGFzdFRyYW5zaXRpb24oKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5jYXJvdXNlbElkID8/PSBuZXdVbmlxdWVJZCgpO1xuICAgIGlmICh0aGlzLmNpcmN1bGFyKSB7XG4gICAgICAvLyBHZXN0aW9uIGRlIGwnZWZmZXQgZGUgdHJhbnNpdGlvbiBwb3VyIGxlIHByZW1pZXIgZXQgbGUgZGVybmllciBzbGlkZSBlbiB2ZXJzaW9uIGNpcmN1bGFpcmVcbiAgICAgIHRoaXMudHJhbnNpdGlvbkxpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy5zbGlkZXNDb250YWluZXIubmF0aXZlRWxlbWVudCwgJ3RyYW5zaXRpb25lbmQnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlRmlyc3RMYXN0VHJhbnNpdGlvbigpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQWZmaWNoZXIgbGUgcHJlbWllciBzbGlkZSBhdSBjaGFyZ2VtZW50XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLnNsaWRlc0NvbnRhaW5lci5uYXRpdmVFbGVtZW50LCAndHJhbnNmb3JtJywgdGhpcy5nZXRUcmFuc2Zvcm0oKSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgLy8gTmV0dG95ZXIgbGUgbGlzdGVuZXIgw6AgbGEgZGVzdHJ1Y3Rpb24gZHUgY29tcG9zYW50XG4gICAgaWYgKHRoaXMudHJhbnNpdGlvbkxpc3RlbmVyKSB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25MaXN0ZW5lcigpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXV0b3BsYXkpIHRoaXMuc3RhcnRTbGlkZXNob3coKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcMOpY2lmaXF1ZSBtb2JpbGVcbiAgICogQGludGVybmFsICovXG4gIHB1YmxpYyBvblRvdWNoU3RhcnQoZXZlbnQ6IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnN0YXJ0UG9pbnQgPSBQb2ludC5mcm9tRXZlbnQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNww6ljaWZpcXVlIG1vYmlsZVxuICAgKiBAaW50ZXJuYWwgKi9cbiAgcHVibGljIG9uVG91Y2hFbmQoZXZlbnQ6IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50b3VjaCkge1xuICAgICAgY29uc3QgZW5kUG9pbnQgPSBQb2ludC5mcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgaWYgKGVuZFBvaW50LnggPCB0aGlzLnN0YXJ0UG9pbnQueCAtIDMyKSB0aGlzLm5leHQoKTtcbiAgICAgIGVsc2UgaWYgKGVuZFBvaW50LnggPiB0aGlzLnN0YXJ0UG9pbnQueCArIDMyKSB0aGlzLnByZXZpb3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwdWJsaWMgb25LZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgLy8gc3RvcCBkdSBkw6lmaWxlbWVudCBhdXRvbWF0aXF1ZSBwZW5kYW50IGwnaW50ZXJhY3Rpb24gdXRpbGlzYXRldXJcbiAgICBpZiAodGhpcy5hdXRvcGxheSkgdGhpcy5zdG9wU2xpZGVzaG93KCk7XG4gICAgdGhpcy5vblBhdXNlID0gdHJ1ZTtcblxuICAgIGlmICghdGhpcy5rZXlib2FyZCkgcmV0dXJuO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgc3dpdGNoIChldmVudC5jb2RlKSB7XG4gICAgICBjYXNlICdBcnJvd0xlZnQnOlxuICAgICAgICB0aGlzLnByZXZpb3VzKCk7XG4gICAgICAgIGJyZWFr