UNPKG

@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).

154 lines 21.9 kB
import { Inject, Injectable } from '@angular/core'; import { BehaviorSubject, merge, Observable } from 'rxjs'; import { fromFetch } from 'rxjs/internal/observable/dom/fetch'; import { DSFR_CONFIG_TOKEN } from '../config/config-token'; import { Language } from '../services'; import { jsonPath2Value } from '../utils'; import { LABELS_BUNDLE_EN } from './i18n-labels-bundle-en'; import { LABELS_BUNDLE_FR } from './i18n-labels-bundle-fr'; import * as i0 from "@angular/core"; import * as i1 from "../services"; /** * Maintient le code langue de l'application et signale le changement de langue. */ export class DsfrI18nService { constructor(config, logger, langService) { this.logger = logger; this.langService = langService; /** * L'ensemble des bundles de libellés gérés par le service I18N. */ this.bundles = new Map(); this.completeLangChange = new BehaviorSubject(this.langService.lang); this.completeLangChange$ = this.completeLangChange.asObservable(); this.bundles.set(Language.FR, LABELS_BUNDLE_FR); this.bundles.set(Language.EN, LABELS_BUNDLE_EN); this.onLangChange(this.langService.lang); // défaut this.readMessagesFiles(config?.i18n).subscribe({ complete: () => this.startSubscribe(), }); } /** * Retourne la valeur de traduction dans `messages` partir d'un path json. * @param jsonPath le chemin dans le fichier de messages json de la langue courante * @return le message et si non trouvé le path json */ t(jsonPath) { return jsonPath2Value(this.currentBundle, jsonPath) ?? this.messageNotFound(this.langService.lang, jsonPath); } /** * Permet d'étendre les ressources d'internationalisation sur un périmètre de langue défini. * * @param lang Le code langue sur deux caractères en minuscules. * @param extension Le bundle contenant l'ensemble des libellés traduits dans la langue indiquée. */ extendsLabelsBundle(lang, extension) { const locale = lang.toLowerCase(); if (locale.length !== 2) { this.logger.warn("Le code langue n'est pas indiqué sur deux caractères, l'extension est ignorée"); return; } const existing = this.bundles.get(lang); if (existing) { //RPA: un jour viendra peut-être où la ligne ci-dessous ne compilera plus et ce serait une bonne chose // on aimerait en effet qu'une erreur soit levée par le compilateur TS car le type I18nBundle est actuellement // défini strictement (c'est juste un alias sur le type I18nBaseBundle) // ce jour là ajuster la définition du type I18nBundle const extendedBundle = { ...existing, ...extension }; this.bundles.set(lang, extendedBundle); // si on modifie le bundle de la langue courante, il faut mettre à jour le bundle courant if (this.langService.lang === lang) { this.currentBundle = extendedBundle; } } else { this.logger.warn(`Aucun bundle à étendre pour le code langue <${lang}>`); } } /** * Démarre l'abonnement au changement de langue. */ startSubscribe() { this.langService.langChange$.subscribe((code) => this.onLangChange(code)); } /** * Charge le bon fichier de messages selon le code langue, messages en anglais si non trouvé. */ onLangChange(code) { this.currentBundle = this.bundles?.get(code) ?? this.bundles?.get(Language.EN) ?? LABELS_BUNDLE_EN; this.completeLangChange.next(code); // indique la fin du chargement des bundles corrects } /** * Si message non trouvé, retourne le message en anglais pour les langues autres que les langues par défaut. */ messageNotFound(codeLang, jsonPath) { this.logger.warn(`Aucune traduction '${codeLang}' pour '${jsonPath}'`); // try fallback to english const englishFallback = codeLang !== Language.EN ? jsonPath2Value(this.bundles.get(Language.EN), jsonPath) : null; return englishFallback ?? jsonPath; } /** * Lit tous les fichiers de la configuration * @param i18nconfig Configuration i18n * @return événement complet sur l'observable quand tous les fichiers ont été lus, erreur ou non */ readMessagesFiles(i18nConfig) { const all = []; i18nConfig?.messagesFiles?.forEach((mf) => { const observable = fetchFile(mf.filePath); observable.subscribe({ next: (data) => { console.info(`Lecture du fichier ${mf.filePath}`); this.bundles.set(mf.code, data); }, error: (err) => { console.error(`Erreur ${err} dans la lecture du fichier ${mf.filePath}`); }, }); all.push(observable); }); return new Observable((subscriber) => { merge(...all).subscribe({ complete: () => subscriber.complete(), }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrI18nService, deps: [{ token: DSFR_CONFIG_TOKEN }, { token: i1.LoggerService }, { token: i1.LangService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrI18nService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrI18nService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [DSFR_CONFIG_TOKEN] }] }, { type: i1.LoggerService }, { type: i1.LangService }] }); /** * Lecture d'un fichier sur le serveur * @param filePath Chemin partiel du fichier * @param contentType text par défaut * @return Observable */ function fetchFile(filePath, contentType = 'text/plain') { const myHeaders = new Headers(); myHeaders.append('Content-Type', contentType); const myConfig = { headers: myHeaders }; return new Observable((subscriber) => { const fetchObs = fromFetch(filePath, myConfig).subscribe({ next: (response) => { if (response.ok) { response.json().then((data) => { subscriber.next(data); subscriber.complete(); }); } else { subscriber.error(response.status); subscriber.complete(); } }, error: (err) => subscriber.error(err), }); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL3NoYXJlZC9pMThuL2kxOG4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBRS9ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzNELE9BQU8sRUFBZSxRQUFRLEVBQWlCLE1BQU0sYUFBYSxDQUFDO0FBQ25FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDMUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7OztBQUczRDs7R0FFRztBQUVILE1BQU0sT0FBTyxlQUFlO0lBZ0IxQixZQUM2QixNQUFrQixFQUM1QixNQUFxQixFQUNyQixXQUF3QjtRQUR4QixXQUFNLEdBQU4sTUFBTSxDQUFlO1FBQ3JCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBYjNDOztXQUVHO1FBQ0ssWUFBTyxHQUFHLElBQUksR0FBRyxFQUEwQixDQUFDO1FBWWxELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLGVBQWUsQ0FBUyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENB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O0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBtZXJnZSwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZnJvbUZldGNoIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vYnNlcnZhYmxlL2RvbS9mZXRjaCc7XG5cbmltcG9ydCB7IERTRlJfQ09ORklHX1RPS0VOIH0gZnJvbSAnLi4vY29uZmlnL2NvbmZpZy10b2tlbic7XG5pbXBvcnQgeyBEc2ZyQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnL2NvbmZpZy5tb2RlbCc7XG5pbXBvcnQgeyBEc2ZySTE4bkNvbmZpZyB9IGZyb20gJy4uL2NvbmZpZy9pMThuLWNvbmZpZyc7XG5pbXBvcnQgeyBMYW5nU2VydmljZSwgTGFuZ3VhZ2UsIExvZ2dlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBqc29uUGF0aDJWYWx1ZSB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7IExBQkVMU19CVU5ETEVfRU4gfSBmcm9tICcuL2kxOG4tbGFiZWxzLWJ1bmRsZS1lbic7XG5pbXBvcnQgeyBMQUJFTFNfQlVORExFX0ZSIH0gZnJvbSAnLi9pMThuLWxhYmVscy1idW5kbGUtZnInO1xuaW1wb3J0IHsgRHNmckkxOG5CdW5kbGUsIERzZnJJMThuRXh0ZW5zaW9uQnVuZGxlIH0gZnJvbSAnLi9pMThuLXR5cGVzJztcblxuLyoqXG4gKiBNYWludGllbnQgbGUgY29kZSBsYW5ndWUgZGUgbCdhcHBsaWNhdGlvbiBldCBzaWduYWxlIGxlIGNoYW5nZW1lbnQgZGUgbGFuZ3VlLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIERzZnJJMThuU2VydmljZSB7XG4gIC8qKiBPYnNlcnZhYmxlIGF1IGNoYW5nZW1lbnQgZGUgbGEgbGFuZ3VlIChmaW4gZHUgY2hhcmdlbWVudCBkZXMgbm91dmVhdXggYnVuZGxlcykgKi9cbiAgY29tcGxldGVMYW5nQ2hhbmdlJDogT2JzZXJ2YWJsZTxzdHJpbmc+O1xuXG4gIHByaXZhdGUgY29tcGxldGVMYW5nQ2hhbmdlOiBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPjtcblxuICAvKipcbiAgICogTCdlbnNlbWJsZSBkZXMgYnVuZGxlcyBkZSBsaWJlbGzDqXMgZ8OpcsOpcyBwYXIgbGUgc2VydmljZSBJMThOLlxuICAgKi9cbiAgcHJpdmF0ZSBidW5kbGVzID0gbmV3IE1hcDxzdHJpbmcsIERzZnJJMThuQnVuZGxlPigpO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlcyAoSlNPTikgZGUgbGEgbGFuZ3VlIGNvdXJhbnRlLlxuICAgKi9cbiAgcHJpdmF0ZSBjdXJyZW50QnVuZGxlOiBEc2ZySTE4bkJ1bmRsZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERTRlJfQ09ORklHX1RPS0VOKSBjb25maWc6IERzZnJDb25maWcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBsYW5nU2VydmljZTogTGFuZ1NlcnZpY2UsXG4gICkge1xuICAgIHRoaXMuY29tcGxldGVMYW5nQ2hhbmdlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KHRoaXMubGFuZ1NlcnZpY2UubGFuZyk7XG4gICAgdGhpcy5jb21wbGV0ZUxhbmdDaGFuZ2UkID0gdGhpcy5jb21wbGV0ZUxhbmdDaGFuZ2UuYXNPYnNlcnZhYmxlKCk7XG5cbiAgICB0aGlzLmJ1bmRsZXMuc2V0KExhbmd1YWdlLkZSLCBMQUJFTFNfQlVORExFX0ZSKTtcbiAgICB0aGlzLmJ1bmRsZXMuc2V0KExhbmd1YWdlLkVOLCBMQUJFTFNfQlVORExFX0VOKTtcbiAgICB0aGlzLm9uTGFuZ0NoYW5nZSh0aGlzLmxhbmdTZXJ2aWNlLmxhbmcpOyAvLyBkw6lmYXV0XG4gICAgdGhpcy5yZWFkTWVzc2FnZXNGaWxlcyhjb25maWc/LmkxOG4pLnN1YnNjcmliZSh7XG4gICAgICBjb21wbGV0ZTogKCkgPT4gdGhpcy5zdGFydFN1YnNjcmliZSgpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldG91cm5lIGxhIHZhbGV1ciBkZSB0cmFkdWN0aW9uIGRhbnMgYG1lc3NhZ2VzYCBwYXJ0aXIgZCd1biBwYXRoIGpzb24uXG4gICAqIEBwYXJhbSBqc29uUGF0aCBsZSBjaGVtaW4gZGFucyBsZSBmaWNoaWVyIGRlIG1lc3NhZ2VzIGpzb24gZGUgbGEgbGFuZ3VlIGNvdXJhbnRlXG4gICAqIEByZXR1cm4gbGUgbWVzc2FnZSBldCBzaSBub24gdHJvdXbDqSBsZSBwYXRoIGpzb25cbiAgICovXG4gIHQoanNvblBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGpzb25QYXRoMlZhbHVlKHRoaXMuY3VycmVudEJ1bmRsZSwganNvblBhdGgpID8/IHRoaXMubWVzc2FnZU5vdEZvdW5kKHRoaXMubGFuZ1NlcnZpY2UubGFuZywganNvblBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcm1ldCBkJ8OpdGVuZHJlIGxlcyByZXNzb3VyY2VzIGQnaW50ZXJuYXRpb25hbGlzYXRpb24gc3VyIHVuIHDDqXJpbcOodHJlIGRlIGxhbmd1ZSBkw6lmaW5pLlxuICAgKlxuICAgKiBAcGFyYW0gbGFuZyBMZSBjb2RlIGxhbmd1ZSBzdXIgZGV1eCBjYXJhY3TDqHJlcyBlbiBtaW51c2N1bGVzLlxuICAgKiBAcGFyYW0gZXh0ZW5zaW9uIExlIGJ1bmRsZSBjb250ZW5hbnQgbCdlbnNlbWJsZSBkZXMgbGliZWxsw6lzIHRyYWR1aXRzIGRhbnMgbGEgbGFuZ3VlIGluZGlxdcOpZS5cbiAgICovXG4gIGV4dGVuZHNMYWJlbHNCdW5kbGUobGFuZzogc3RyaW5nLCBleHRlbnNpb246IERzZnJJMThuRXh0ZW5zaW9uQnVuZGxlKTogdm9pZCB7XG4gICAgY29uc3QgbG9jYWxlID0gbGFuZy50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChsb2NhbGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiTGUgY29kZSBsYW5ndWUgbidlc3QgcGFzIGluZGlxdcOpIHN1ciBkZXV4IGNhcmFjdMOocmVzLCBsJ2V4dGVuc2lvbiBlc3QgaWdub3LDqWVcIik7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZzogRHNmckkxOG5CdW5kbGUgfCB1bmRlZmluZWQgPSB0aGlzLmJ1bmRsZXMuZ2V0KGxhbmcpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgLy9SUEE6IHVuIGpvdXIgdmllbmRyYSBwZXV0LcOqdHJlIG/DuSBsYSBsaWduZSBjaS1kZXNzb3VzIG5lIGNvbXBpbGVyYSBwbHVzIGV0IGNlIHNlcmFpdCB1bmUgYm9ubmUgY2hvc2VcbiAgICAgIC8vIG9uIGFpbWVyYWl0IGVuIGVmZmV0IHF1J3VuZSBlcnJldXIgc29pdCBsZXbDqWUgcGFyIGxlIGNvbXBpbGF0ZXVyIFRTIGNhciBsZSB0eXBlIEkxOG5CdW5kbGUgZXN0IGFjdHVlbGxlbWVudFxuICAgICAgLy8gZMOpZmluaSBzdHJpY3RlbWVudCAoYydlc3QganVzdGUgdW4gYWxpYXMgc3VyIGxlIHR5cGUgSTE4bkJhc2VCdW5kbGUpXG4gICAgICAvLyBjZSBqb3VyIGzDoCBhanVzdGVyIGxhIGTDqWZpbml0aW9uIGR1IHR5cGUgSTE4bkJ1bmRsZVxuICAgICAgY29uc3QgZXh0ZW5kZWRCdW5kbGU6IERzZnJJMThuQnVuZGxlID0geyAuLi5leGlzdGluZywgLi4uZXh0ZW5zaW9uIH07XG4gICAgICB0aGlzLmJ1bmRsZXMuc2V0KGxhbmcsIGV4dGVuZGVkQnVuZGxlKTtcbiAgICAgIC8vIHNpIG9uIG1vZGlmaWUgbGUgYnVuZGxlIGRlIGxhIGxhbmd1ZSBjb3VyYW50ZSwgaWwgZmF1dCBtZXR0cmUgw6Agam91ciBsZSBidW5kbGUgY291cmFudFxuICAgICAgaWYgKHRoaXMubGFuZ1NlcnZpY2UubGFuZyA9PT0gbGFuZykge1xuICAgICAgICB0aGlzLmN1cnJlbnRCdW5kbGUgPSBleHRlbmRlZEJ1bmRsZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dnZXIud2FybihgQXVjdW4gYnVuZGxlIMOgIMOpdGVuZHJlIHBvdXIgbGUgY29kZSBsYW5ndWUgPCR7bGFuZ30+YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIETDqW1hcnJlIGwnYWJvbm5lbWVudCBhdSBjaGFuZ2VtZW50IGRlIGxhbmd1ZS5cbiAgICovXG4gIHByb3RlY3RlZCBzdGFydFN1YnNjcmliZSgpIHtcbiAgICB0aGlzLmxhbmdTZXJ2aWNlLmxhbmdDaGFuZ2UkLnN1YnNjcmliZSgoY29kZSkgPT4gdGhpcy5vbkxhbmdDaGFuZ2UoY29kZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoYXJnZSBsZSBib24gZmljaGllciBkZSBtZXNzYWdlcyBzZWxvbiBsZSBjb2RlIGxhbmd1ZSwgbWVzc2FnZXMgZW4gYW5nbGFpcyBzaSBub24gdHJvdXbDqS5cbiAgICovXG4gIHByb3RlY3RlZCBvbkxhbmdDaGFuZ2UoY29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50QnVuZGxlID0gdGhpcy5idW5kbGVzPy5nZXQoY29kZSkgPz8gdGhpcy5idW5kbGVzPy5nZXQoTGFuZ3VhZ2UuRU4pID8/IExBQkVMU19CVU5ETEVfRU47XG4gICAgdGhpcy5jb21wbGV0ZUxhbmdDaGFuZ2UubmV4dChjb2RlKTsgLy8gaW5kaXF1ZSBsYSBmaW4gZHUgY2hhcmdlbWVudCBkZXMgYnVuZGxlcyBjb3JyZWN0c1xuICB9XG5cbiAgLyoqXG4gICAqIFNpIG1lc3NhZ2Ugbm9uIHRyb3V2w6ksIHJldG91cm5lIGxlIG1lc3NhZ2UgZW4gYW5nbGFpcyBwb3VyIGxlcyBsYW5ndWVzIGF1dHJlcyBxdWUgbGVzIGxhbmd1ZXMgcGFyIGTDqWZhdXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgbWVzc2FnZU5vdEZvdW5kKGNvZGVMYW5nOiBzdHJpbmcsIGpzb25QYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHRoaXMubG9nZ2VyLndhcm4oYEF1Y3VuZSB0cmFkdWN0aW9uICcke2NvZGVMYW5nfScgcG91ciAnJHtqc29uUGF0aH0nYCk7XG4gICAgLy8gdHJ5IGZhbGxiYWNrIHRvIGVuZ2xpc2hcbiAgICBjb25zdCBlbmdsaXNoRmFsbGJhY2sgPSBjb2RlTGFuZyAhPT0gTGFuZ3VhZ2UuRU4gPyBqc29uUGF0aDJWYWx1ZSh0aGlzLmJ1bmRsZXMuZ2V0KExhbmd1YWdlLkVOKSwganNvblBhdGgpIDogbnVsbDtcblxuICAgIHJldHVybiBlbmdsaXNoRmFsbGJhY2sgPz8ganNvblBhdGg7XG4gIH1cblxuICAvKipcbiAgICogTGl0IHRvdXMgbGVzIGZpY2hpZXJzIGRlIGxhIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIGkxOG5jb25maWcgQ29uZmlndXJhdGlvbiBpMThuXG4gICAqIEByZXR1cm4gw6l2w6luZW1lbnQgY29tcGxldCBzdXIgbCdvYnNlcnZhYmxlIHF1YW5kIHRvdXMgbGVzIGZpY2hpZXJzIG9udCDDqXTDqSBsdXMsIGVycmV1ciBvdSBub25cbiAgICovXG4gIHByaXZhdGUgcmVhZE1lc3NhZ2VzRmlsZXMoaTE4bkNvbmZpZzogRHNmckkxOG5Db25maWcgfCB1bmRlZmluZWQpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCBhbGw6IE9ic2VydmFibGU8c3RyaW5nPltdID0gW107XG4gICAgaTE4bkNvbmZpZz8ubWVzc2FnZXNGaWxlcz8uZm9yRWFjaCgobWYpID0+IHtcbiAgICAgIGNvbnN0IG9ic2VydmFibGUgPSBmZXRjaEZpbGUobWYuZmlsZVBhdGgpO1xuICAgICAgb2JzZXJ2YWJsZS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgY29uc29sZS5pbmZvKGBMZWN0dXJlIGR1IGZpY2hpZXIgJHttZi5maWxlUGF0aH1gKTtcbiAgICAgICAgICB0aGlzLmJ1bmRsZXMuc2V0KG1mLmNvZGUsIGRhdGEpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycmV1ciAke2Vycn0gZGFucyBsYSBsZWN0dXJlIGR1IGZpY2hpZXIgJHttZi5maWxlUGF0aH1gKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYWxsLnB1c2gob2JzZXJ2YWJsZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8dm9pZD4oKHN1YnNjcmliZXIpID0+IHtcbiAgICAgIG1lcmdlKC4uLmFsbCkuc3Vic2NyaWJlKHtcbiAgICAgICAgY29tcGxldGU6ICgpID0+IHN1YnNjcmliZXIuY29tcGxldGUoKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogTGVjdHVyZSBkJ3VuIGZpY2hpZXIgc3VyIGxlIHNlcnZldXJcbiAqIEBwYXJhbSBmaWxlUGF0aCBDaGVtaW4gcGFydGllbCBkdSBmaWNoaWVyXG4gKiBAcGFyYW0gY29udGVudFR5cGUgdGV4dCBwYXIgZMOpZmF1dFxuICogQHJldHVybiBPYnNlcnZhYmxlXG4gKi9cbmZ1bmN0aW9uIGZldGNoRmlsZShmaWxlUGF0aDogc3RyaW5nLCBjb250ZW50VHlwZSA9ICd0ZXh0L3BsYWluJyk6IE9ic2VydmFibGU8YW55PiB7XG4gIGNvbnN0IG15SGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gIG15SGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsIGNvbnRlbnRUeXBlKTtcbiAgY29uc3QgbXlDb25maWcgPSB7IGhlYWRlcnM6IG15SGVhZGVycyB9O1xuXG4gIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxhbnk+KChzdWJzY3JpYmVyKSA9PiB7XG4gICAgY29uc3QgZmV0Y2hPYnMgPSBmcm9tRmV0Y2goZmlsZVBhdGgsIG15Q29uZmlnKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoZGF0YSk7XG4gICAgICAgICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3Vic2NyaWJlci5lcnJvcihyZXNwb25zZS5zdGF0dXMpO1xuICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiBzdWJzY3JpYmVyLmVycm9yKGVyciksXG4gICAgfSk7XG4gIH0pO1xufVxuIl19