UNPKG

@jsverse/transloco-locale

Version:

The localization (l10n) library plugin for Transloco

149 lines 21.1 kB
import { DestroyRef, inject, Injectable } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { getBrowserCultureLang, TranslocoService } from '@jsverse/transloco'; import { BehaviorSubject } from 'rxjs'; import { distinctUntilChanged, filter, map } from 'rxjs/operators'; import { isLocaleFormat, toDate } from './helpers'; import { getDefaultOptions } from './shared'; import { TRANSLOCO_LOCALE_CONFIG, TRANSLOCO_LOCALE_CURRENCY_MAPPING, TRANSLOCO_LOCALE_DEFAULT_CURRENCY, TRANSLOCO_LOCALE_DEFAULT_LOCALE, TRANSLOCO_LOCALE_LANG_MAPPING, } from './transloco-locale.config'; import { TRANSLOCO_DATE_TRANSFORMER, TRANSLOCO_NUMBER_TRANSFORMER, } from './transloco-locale.transformers'; import * as i0 from "@angular/core"; export class TranslocoLocaleService { translocoService = inject(TranslocoService); langLocaleMapping = inject(TRANSLOCO_LOCALE_LANG_MAPPING); defaultLocale = inject(TRANSLOCO_LOCALE_DEFAULT_LOCALE); defaultCurrency = inject(TRANSLOCO_LOCALE_DEFAULT_CURRENCY); localeCurrencyMapping = inject(TRANSLOCO_LOCALE_CURRENCY_MAPPING); numberTransformer = inject(TRANSLOCO_NUMBER_TRANSFORMER); dateTransformer = inject(TRANSLOCO_DATE_TRANSFORMER); localeConfig = inject(TRANSLOCO_LOCALE_CONFIG); browserLocale = getBrowserCultureLang() || this.defaultLocale; _locale = ''; locale = new BehaviorSubject(this._locale); localeChanges$ = this.locale.pipe(distinctUntilChanged()); constructor() { inject(DestroyRef).onDestroy(() => { // Complete subjects to release observers if users forget to unsubscribe manually. // This is important in server-side rendering. this.locale.complete(); this.locale.unsubscribe(); }); // Initialize locale with fallback chain this.setLocale(this.initializeLocale()); // Subscribe to language changes this.translocoService.langChanges$ .pipe(map((lang) => this.toLocale(lang)), filter(Boolean), takeUntilDestroyed()) .subscribe((locale) => this.setLocale(locale)); } getDefaultLocale() { return this.defaultLocale; } getLocale() { return this._locale; } setLocale(locale) { if (!isLocaleFormat(locale)) { console.error(`${locale} isn't a valid locale format`); return; } this.locale.next(locale); this._locale = locale; } /** * Get the currency symbol for the currently set locale. */ getCurrencySymbol(locale = this.getLocale()) { const currency = this.localeCurrencyMapping[locale]; const numberFormat = new Intl.NumberFormat(locale, { style: 'currency', currencyDisplay: 'symbol', currency, minimumFractionDigits: 0, maximumFractionDigits: 0, }); const pivot = 0; return numberFormat .format(pivot) .split(pivot.toString()) .map((element) => element.trim()) .find((element) => !!element); } /** * Transform a date into the locale's date format. * * The date expression: a `Date` object, a number * (milliseconds since UTC epoch), or an ISO string (https://www.w3.org/TR/NOTE-datetime). * * @example * * localizeDate(new Date(2019, 9, 7, 12, 0, 0)) // 10/7/2019 * localizeDate(date, 'en-US', { dateStyle: 'medium', timeStyle: 'medium' }) // Sep 10, 2019, 10:46:12 PM * localizeDate(date) 'en-US', { timeZone: 'UTC', timeStyle: 'full' } // 7:40:32 PM Coordinated Universal Time * localizeDate(1, 'en-US', { dateStyle: 'medium' }) // Jan 1, 1970 * localizeDate('2019-02-08', 'en-US', { dateStyle: 'medium' }) // Feb 8, 2019 */ localizeDate(date, locale = this.getLocale(), options = {}) { const resolved = options ?? getDefaultOptions(locale, 'date', this.localeConfig); return this.dateTransformer.transform(toDate(date), locale, resolved); } /** * Transform a number into the locale's number format according to the number type. * * localizeNumber(1234567890, 'decimal') // 1,234,567,890 * localizeNumber(0.5, 'percent') // 50% * localizeNumber(1000, 'currency') // $1,000.00 */ localizeNumber(value, style, locale = this.getLocale(), options) { let resolved = options ?? getDefaultOptions(locale, style, this.localeConfig); if (style === 'currency') { resolved = { ...resolved, currency: resolved.currency || this._resolveCurrencyCode(locale), }; } return this.numberTransformer.transform(value, style, locale, resolved); } /** * @internal */ _resolveCurrencyCode(locale = this.getLocale()) { return this.localeCurrencyMapping[locale] || this.defaultCurrency; } toLocale(val) { if (this.langLocaleMapping[val]) { return this.langLocaleMapping[val]; } if (isLocaleFormat(val)) { return val; } return ''; } /* * Get the browser's language and validate. * If the browser's language is not set, it will fall back to the active language from TranslocoService. * If active language from TranslocoService is not valid, it will fall back to the default locale. * If the default locale is not valid, it will return the default locale as a string */ initializeLocale() { const browserLocale = this.toLocale(this.browserLocale); if (browserLocale) return browserLocale; const activeLang = this.translocoService.getActiveLang(); if (activeLang) { const locale = this.toLocale(activeLang); if (locale) return locale; } const defaultLocaleResolved = this.toLocale(this.defaultLocale); if (defaultLocaleResolved) return defaultLocaleResolved; return this.defaultLocale; // Fallback to a default locale } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslocoLocaleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslocoLocaleService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslocoLocaleService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLWxvY2FsZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy90cmFuc2xvY28tbG9jYWxlL3NyYy9saWIvdHJhbnNsb2NvLWxvY2FsZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzdDLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUNBQWlDLEVBQ2pDLGlDQUFpQyxFQUNqQywrQkFBK0IsRUFDL0IsNkJBQTZCLEdBQzlCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLDBCQUEwQixFQUMxQiw0QkFBNEIsR0FDN0IsTUFBTSxpQ0FBaUMsQ0FBQzs7QUFVekMsTUFBTSxPQUFPLHNCQUFzQjtJQUN6QixnQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM1QyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsNkJBQTZCLENBQUMsQ0FBQztJQUMxRCxhQUFhLEdBQUcsTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUM7SUFDeEQsZUFBZSxHQUFHLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQzVE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Q0FBQztZQUNoQyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsSUFBSSxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRDs7Ozs7T0FLRztJQUVLLGdCQUFnQjtRQUN0QixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN4RCxJQUFJLGFBQWE7WUFBRSxPQUFPLGFBQWEsQ0FBQztRQUV4QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekQsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDekMsSUFBSSxNQUFNO2dCQUFFLE9BQU8sTUFBTSxDQUFDO1FBQzVCLENBQUM7UUFFRCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2hFLElBQUkscUJBQXFCO1lBQUUsT0FBTyxxQkFBcUIsQ0FBQztRQUV4RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQywrQkFBK0I7SUFDNUQsQ0FBQzt1R0F4S1Usc0JBQXNCOzJHQUF0QixzQkFBc0IsY0FEVCxNQUFNOzsyRkFDbkIsc0JBQXNCO2tCQURsQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlc3Ryb3lSZWYsIGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZ2V0QnJvd3NlckN1bHR1cmVMYW5nLCBUcmFuc2xvY29TZXJ2aWNlIH0gZnJvbSAnQGpzdmVyc2UvdHJhbnNsb2NvJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBpc0xvY2FsZUZvcm1hdCwgdG9EYXRlIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7IGdldERlZmF1bHRPcHRpb25zIH0gZnJvbSAnLi9zaGFyZWQnO1xuaW1wb3J0IHtcbiAgVFJBTlNMT0NPX0xPQ0FMRV9DT05GSUcsXG4gIFRSQU5TTE9DT19MT0NBTEVfQ1VSUkVOQ1lfTUFQUElORyxcbiAgVFJBTlNMT0NPX0xPQ0FMRV9ERUZBVUxUX0NVUlJFTkNZLFxuICBUUkFOU0xPQ09fTE9DQUxFX0RFRkFVTFRfTE9DQUxFLFxuICBUUkFOU0xPQ09fTE9DQUxFX0xBTkdfTUFQUElORyxcbn0gZnJvbSAnLi90cmFuc2xvY28tbG9jYWxlLmNvbmZpZyc7XG5pbXBvcnQge1xuICBUUkFOU0xPQ09fREFURV9UUkFOU0ZPUk1FUixcbiAgVFJBTlNMT0NPX05VTUJFUl9UUkFOU0ZPUk1FUixcbn0gZnJvbSAnLi90cmFuc2xvY28tbG9jYWxlLnRyYW5zZm9ybWVycyc7XG5pbXBvcnQge1xuICBEYXRlRm9ybWF0T3B0aW9ucyxcbiAgTG9jYWxlLFxuICBMb2NhbGVDb25maWcsXG4gIE51bWJlclN0eWxlcyxcbiAgVmFsaWREYXRlLFxufSBmcm9tICcuL3RyYW5zbG9jby1sb2NhbGUudHlwZXMnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFRyYW5zbG9jb0xvY2FsZVNlcnZpY2Uge1xuICBwcml2YXRlIHRyYW5zbG9jb1NlcnZpY2UgPSBpbmplY3QoVHJhbnNsb2NvU2VydmljZSk7XG4gIHByaXZhdGUgbGFuZ0xvY2FsZU1hcHBpbmcgPSBpbmplY3QoVFJBTlNMT0NPX0xPQ0FMRV9MQU5HX01BUFBJTkcpO1xuICBwcml2YXRlIGRlZmF1bHRMb2NhbGUgPSBpbmplY3QoVFJBTlNMT0NPX0xPQ0FMRV9ERUZBVUxUX0xPQ0FMRSk7XG4gIHByaXZhdGUgZGVmYXVsdEN1cnJlbmN5ID0gaW5qZWN0KFRSQU5TTE9DT19MT0NBTEVfREVGQVVMVF9DVVJSRU5DWSk7XG4gIHByaXZhdGUgbG9jYWxlQ3VycmVuY3lNYXBwaW5nID0gaW5qZWN0KFRSQU5TTE9DT19MT0NBTEVfQ1VSUkVOQ1lfTUFQUElORyk7XG4gIHByaXZhdGUgbnVtYmVyVHJhbnNmb3JtZXIgPSBpbmplY3QoVFJBTlNMT0NPX05VTUJFUl9UUkFOU0ZPUk1FUik7XG4gIHByaXZhdGUgZGF0ZVRyYW5zZm9ybWVyID0gaW5qZWN0KFRSQU5TTE9DT19EQVRFX1RSQU5TRk9STUVSKTtcbiAgcHJpdmF0ZSBsb2NhbGVDb25maWc6IExvY2FsZUNvbmZpZyA9IGluamVjdChUUkFOU0xPQ09fTE9DQUxFX0NPTkZJRyk7XG4gIHByaXZhdGUgYnJvd3NlckxvY2FsZSA9IGdldEJyb3dzZXJDdWx0dXJlTGFuZygpIHx8IHRoaXMuZGVmYXVsdExvY2FsZTtcblxuICBwcml2YXRlIF9sb2NhbGUgPSAnJztcbiAgcHJpdmF0ZSBsb2NhbGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PExvY2FsZT4odGhpcy5fbG9jYWxlKTtcblxuICByZWFkb25seSBsb2NhbGVDaGFuZ2VzJCA9IHRoaXMubG9jYWxlLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaW5qZWN0KERlc3Ryb3lSZWYpLm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICAvLyBDb21wbGV0ZSBzdWJqZWN0cyB0byByZWxlYXNlIG9ic2VydmVycyBpZiB1c2VycyBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgbWFudWFsbHkuXG4gICAgICAvLyBUaGlzIGlzIGltcG9ydGFudCBpbiBzZXJ2ZXItc2lkZSByZW5kZXJpbmcuXG4gICAgICB0aGlzLmxvY2FsZS5jb21wbGV0ZSgpO1xuICAgICAgdGhpcy5sb2NhbGUudW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcblxuICAgIC8vIEluaXRpYWxpemUgbG9jYWxlIHdpdGggZmFsbGJhY2sgY2hhaW5cbiAgICB0aGlzLnNldExvY2FsZSh0aGlzLmluaXRpYWxpemVMb2NhbGUoKSk7XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gbGFuZ3VhZ2UgY2hhbmdlc1xuICAgIHRoaXMudHJhbnNsb2NvU2VydmljZS5sYW5nQ2hhbmdlcyRcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKGxhbmcpID0+IHRoaXMudG9Mb2NhbGUobGFuZykpLFxuICAgICAgICBmaWx0ZXIoQm9vbGVhbiksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgobG9jYWxlOiBMb2NhbGUpID0+IHRoaXMuc2V0TG9jYWxlKGxvY2FsZSkpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdExvY2FsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0TG9jYWxlO1xuICB9XG5cbiAgZ2V0TG9jYWxlKCkge1xuICAgIHJldHVybiB0aGlzLl9sb2NhbGU7XG4gIH1cblxuICBzZXRMb2NhbGUobG9jYWxlOiBMb2NhbGUpIHtcbiAgICBpZiAoIWlzTG9jYWxlRm9ybWF0KGxvY2FsZSkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bG9jYWxlfSBpc24ndCBhIHZhbGlkIGxvY2FsZSBmb3JtYXRgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxvY2FsZS5uZXh0KGxvY2FsZSk7XG4gICAgdGhpcy5fbG9jYWxlID0gbG9jYWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY3VycmVuY3kgc3ltYm9sIGZvciB0aGUgY3VycmVudGx5IHNldCBsb2NhbGUuXG4gICAqL1xuICBnZXRDdXJyZW5jeVN5bWJvbChsb2NhbGUgPSB0aGlzLmdldExvY2FsZSgpKSB7XG4gICAgY29uc3QgY3VycmVuY3kgPSB0aGlzLmxvY2FsZUN1cnJlbmN5TWFwcGluZ1tsb2NhbGVdO1xuICAgIGNvbnN0IG51bWJlckZvcm1hdCA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGUsIHtcbiAgICAgIHN0eWxlOiAnY3VycmVuY3knLFxuICAgICAgY3VycmVuY3lEaXNwbGF5OiAnc3ltYm9sJyxcbiAgICAgIGN1cnJlbmN5LFxuICAgICAgbWluaW11bUZyYWN0aW9uRGlnaXRzOiAwLFxuICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAwLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcGl2b3QgPSAwO1xuXG4gICAgcmV0dXJuIG51bWJlckZvcm1hdFxuICAgICAgLmZvcm1hdChwaXZvdClcbiAgICAgIC5zcGxpdChwaXZvdC50b1N0cmluZygpKVxuICAgICAgLm1hcCgoZWxlbWVudCkgPT4gZWxlbWVudC50cmltKCkpXG4gICAgICAuZmluZCgoZWxlbWVudCkgPT4gISFlbGVtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gYSBkYXRlIGludG8gdGhlIGxvY2FsZSdzIGRhdGUgZm9ybWF0LlxuICAgKlxuICAgKiBUaGUgZGF0ZSBleHByZXNzaW9uOiBhIGBEYXRlYCBvYmplY3QsIGEgbnVtYmVyXG4gICAqIChtaWxsaXNlY29uZHMgc2luY2UgVVRDIGVwb2NoKSwgb3IgYW4gSVNPIHN0cmluZyAoaHR0cHM6Ly93d3cudzMub3JnL1RSL05PVEUtZGF0ZXRpbWUpLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBsb2NhbGl6ZURhdGUobmV3IERhdGUoMjAxOSwgOSwgNywgMTIsIDAsIDApKSAvLyAxMC83LzIwMTlcbiAgICogbG9jYWxpemVEYXRlKGRhdGUsICdlbi1VUycsIHsgZGF0ZVN0eWxlOiAnbWVkaXVtJywgdGltZVN0eWxlOiAnbWVkaXVtJyB9KSAvLyBTZXAgMTAsIDIwMTksIDEwOjQ2OjEyIFBNXG4gICAqIGxvY2FsaXplRGF0ZShkYXRlKSAnZW4tVVMnLCB7IHRpbWVab25lOiAnVVRDJywgdGltZVN0eWxlOiAnZnVsbCcgfSAvLyA3OjQwOjMyIFBNIENvb3JkaW5hdGVkIFVuaXZlcnNhbCBUaW1lXG4gICAqIGxvY2FsaXplRGF0ZSgxLCAnZW4tVVMnLCB7IGRhdGVTdHlsZTogJ21lZGl1bScgfSkgLy8gSmFuIDEsIDE5NzBcbiAgICogbG9jYWxpemVEYXRlKCcyMDE5LTAyLTA4JywgJ2VuLVVTJywgeyBkYXRlU3R5bGU6ICdtZWRpdW0nIH0pIC8vIEZlYiA4LCAyMDE5XG4gICAqL1xuICBsb2NhbGl6ZURhdGUoXG4gICAgZGF0ZTogVmFsaWREYXRlLFxuICAgIGxvY2FsZTogTG9jYWxlID0gdGhpcy5nZXRMb2NhbGUoKSxcbiAgICBvcHRpb25zOiBEYXRlRm9ybWF0T3B0aW9ucyA9IHt9LFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IHJlc29sdmVkID1cbiAgICAgIG9wdGlvbnMgPz8gZ2V0RGVmYXVsdE9wdGlvbnMobG9jYWxlLCAnZGF0ZScsIHRoaXMubG9jYWxlQ29uZmlnKTtcblxuICAgIHJldHVybiB0aGlzLmRhdGVUcmFuc2Zvcm1lci50cmFuc2Zvcm0odG9EYXRlKGRhdGUpLCBsb2NhbGUsIHJlc29sdmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gYSBudW1iZXIgaW50byB0aGUgbG9jYWxlJ3MgbnVtYmVyIGZvcm1hdCBhY2NvcmRpbmcgdG8gdGhlIG51bWJlciB0eXBlLlxuICAgKlxuICAgKiBsb2NhbGl6ZU51bWJlcigxMjM0NTY3ODkwLCAnZGVjaW1hbCcpIC8vIDEsMjM0LDU2Nyw4OTBcbiAgICogbG9jYWxpemVOdW1iZXIoMC41LCAncGVyY2VudCcpIC8vIDUwJVxuICAgKiBsb2NhbGl6ZU51bWJlcigxMDAwLCAnY3VycmVuY3knKSAvLyAkMSwwMDAuMDBcbiAgICovXG4gIGxvY2FsaXplTnVtYmVyKFxuICAgIHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsXG4gICAgc3R5bGU6IE51bWJlclN0eWxlcyxcbiAgICBsb2NhbGU6IExvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKCksXG4gICAgb3B0aW9ucz86IEludGwuTnVtYmVyRm9ybWF0T3B0aW9ucyxcbiAgKTogc3RyaW5nIHtcbiAgICBsZXQgcmVzb2x2ZWQgPVxuICAgICAgb3B0aW9ucyA/PyBnZXREZWZhdWx0T3B0aW9ucyhsb2NhbGUsIHN0eWxlLCB0aGlzLmxvY2FsZUNvbmZpZyk7XG5cbiAgICBpZiAoc3R5bGUgPT09ICdjdXJyZW5jeScpIHtcbiAgICAgIHJlc29sdmVkID0ge1xuICAgICAgICAuLi5yZXNvbHZlZCxcbiAgICAgICAgY3VycmVuY3k6IHJlc29sdmVkLmN1cnJlbmN5IHx8IHRoaXMuX3Jlc29sdmVDdXJyZW5jeUNvZGUobG9jYWxlKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubnVtYmVyVHJhbnNmb3JtZXIudHJhbnNmb3JtKHZhbHVlLCBzdHlsZSwgbG9jYWxlLCByZXNvbHZlZCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfcmVzb2x2ZUN1cnJlbmN5Q29kZShsb2NhbGU6IExvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKCkpIHtcbiAgICByZXR1cm4gdGhpcy5sb2NhbGVDdXJyZW5jeU1hcHBpbmdbbG9jYWxlXSB8fCB0aGlzLmRlZmF1bHRDdXJyZW5jeTtcbiAgfVxuXG4gIHByaXZhdGUgdG9Mb2NhbGUodmFsOiBzdHJpbmcgfCBMb2NhbGUpOiBMb2NhbGUge1xuICAgIGlmICh0aGlzLmxhbmdMb2NhbGVNYXBwaW5nW3ZhbF0pIHtcbiAgICAgIHJldHVybiB0aGlzLmxhbmdMb2NhbGVNYXBwaW5nW3ZhbF07XG4gICAgfVxuXG4gICAgaWYgKGlzTG9jYWxlRm9ybWF0KHZhbCkpIHtcbiAgICAgIHJldHVybiB2YWw7XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLypcbiAgICogR2V0IHRoZSBicm93c2VyJ3MgbGFuZ3VhZ2UgYW5kIHZhbGlkYXRlLlxuICAgKiBJZiB0aGUgYnJvd3NlcidzIGxhbmd1YWdlIGlzIG5vdCBzZXQsIGl0IHdpbGwgZmFsbCBiYWNrIHRvIHRoZSBhY3RpdmUgbGFuZ3VhZ2UgZnJvbSBUcmFuc2xvY29TZXJ2aWNlLlxuICAgKiBJZiBhY3RpdmUgbGFuZ3VhZ2UgZnJvbSBUcmFuc2xvY29TZXJ2aWNlIGlzIG5vdCB2YWxpZCwgaXQgd2lsbCBmYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgbG9jYWxlLlxuICAgKiBJZiB0aGUgZGVmYXVsdCBsb2NhbGUgaXMgbm90IHZhbGlkLCBpdCB3aWxsIHJldHVybiB0aGUgZGVmYXVsdCBsb2NhbGUgYXMgYSBzdHJpbmdcbiAgICovXG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplTG9jYWxlKCk6IExvY2FsZSB7XG4gICAgY29uc3QgYnJvd3NlckxvY2FsZSA9IHRoaXMudG9Mb2NhbGUodGhpcy5icm93c2VyTG9jYWxlKTtcbiAgICBpZiAoYnJvd3NlckxvY2FsZSkgcmV0dXJuIGJyb3dzZXJMb2NhbGU7XG5cbiAgICBjb25zdCBhY3RpdmVMYW5nID0gdGhpcy50cmFuc2xvY29TZXJ2aWNlLmdldEFjdGl2ZUxhbmcoKTtcbiAgICBpZiAoYWN0aXZlTGFuZykge1xuICAgICAgY29uc3QgbG9jYWxlID0gdGhpcy50b0xvY2FsZShhY3RpdmVMYW5nKTtcbiAgICAgIGlmIChsb2NhbGUpIHJldHVybiBsb2NhbGU7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdExvY2FsZVJlc29sdmVkID0gdGhpcy50b0xvY2FsZSh0aGlzLmRlZmF1bHRMb2NhbGUpO1xuICAgIGlmIChkZWZhdWx0TG9jYWxlUmVzb2x2ZWQpIHJldHVybiBkZWZhdWx0TG9jYWxlUmVzb2x2ZWQ7XG5cbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0TG9jYWxlOyAvLyBGYWxsYmFjayB0byBhIGRlZmF1bHQgbG9jYWxlXG4gIH1cbn1cbiJdfQ==